#include #include #include #include #define ipv4_addr(o1, o2, o3, o4) __constant_htonl( \ (o1) << 24 | \ (o2) << 16 | \ (o3) << 8 | \ (o4)) static struct iphdr ip = { .version = 4, .ihl = 5, .id = __constant_htons(0xcda3), .frag_off = 0x40, .ttl = 64, .protocol = IPPROTO_UDP, }; static uint16_t ip_checksum(uint16_t *buf, size_t len) { unsigned long sum = 0; int i; for (i = 0; i < len; i++) { sum += htons(buf[i]); if (sum & 0x80000000) sum = (sum & 0xFFFF) + (sum >> 16); } while (sum >> 16) sum = (sum & 0xFFFF) + (sum >> 16); return htons(~sum); } static void calc_csum_print(struct iphdr *ip) { ip->check = 0; ip->check = ip_checksum((uint16_t *)ip, ip->ihl * 2); printf("chk: %hx\n", ip->check); } int main(void) { ip.saddr = ipv4_addr(192, 168, 0, 1); ip.daddr = ipv4_addr(10, 0, 20, 1); calc_csum_print(&ip); ip.saddr = ipv4_addr(0, 1, 192, 168); calc_csum_print(&ip); ip.daddr = ipv4_addr(20, 1, 10, 0); calc_csum_print(&ip); ip.saddr = ipv4_addr(10, 0, 20, 1); ip.daddr = ipv4_addr(192, 168, 0, 1); calc_csum_print(&ip); return 0; }