15 uint16_t Identifcation;
16 uint16_t FragmentInfo; // rsvd:dont:more:[13]offset/8
19 uint16_t HeaderChecksum;
23 } __attribute__((packed)) tIPv4Hdr;
26 uint16_t IP_Checksum(uint16_t Prev, size_t Length, const void *Data)
28 const uint16_t *words = Data;
30 for( int i = 0; i < Length/2; i ++ )
36 ret += ntohs(*(uint8_t*)words);
39 ret = (ret & 0xFFFF) + (ret >> 16);
44 void IP_Send(int IfNum, int AF, const void *Src, const void *Dst, uint8_t proto,
45 int BufCount, size_t BufLens[], const void *Bufs[])
47 size_t total_length = 0;
49 size_t out_buflens[BufCount+1];
50 const void *out_bufs[BufCount+1];
52 for( int i = 0; i < BufCount; i ++ )
54 total_length += BufLens[i];
55 out_buflens[1+i] = BufLens[i];
56 out_bufs[1+i] = Bufs[i];
62 hdr.VerLen = (4 << 4) | (sizeof(hdr)/4);
64 hdr.TotalLength = htons(sizeof(hdr) + total_length);
65 hdr.Identifcation = 0; // TODO: WTF is this?
66 hdr.FragmentInfo = htons(0);
67 hdr.TTL = 18; // TODO: Progammable TTL
69 hdr.HeaderChecksum = 0;
70 memcpy(hdr.SrcAddr, Src, 4);
71 memcpy(hdr.DstAddr, Dst, 4);
73 hdr.HeaderChecksum = htons( IP_Checksum(IP_CHECKSUM_START, sizeof(hdr), &hdr) );
75 out_buflens[0] = sizeof(hdr);
78 // TODO: Don't hard-code MAC addresses
79 Link_Send(IfNum, BLOB(HOST_MAC), BLOB(TEST_MAC), ETHER_PROTO_IPV4,
80 1+BufCount, out_buflens, out_bufs);
83 TEST_WARN("Invalid AF(%i) in IP_Send", AF);
87 bool IP_Pkt_Check(size_t len, const void *data, size_t *ofs_out, int AF, const void *Src, const void *Dst, uint8_t proto)
91 if( !Link_Pkt_Check(len, data, &ofs, BLOB(TEST_MAC), BLOB(HOST_MAC), ETHER_PROTO_IPV4) )
95 memcpy(&hdr, (const uint8_t*)data + ofs, sizeof(hdr));
96 TEST_ASSERT_REL(hdr.VerLen >> 4, ==, 4);
101 TEST_WARN("Invalid AF(%i) in IP_Pkt_Check", AF);