static void apply_csum16(int csum_id) { int j, i = csum_id; size_t csum_max = packet_dyn[i].slen; for (j = 0; j < csum_max; ++j) { uint16_t sum = 0; struct csum16 *csum = &packet_dyn[i].csum[j]; fmemset(&packets[i].payload[csum->off], 0, sizeof(sum)); switch (csum->which) { case CSUM_IP: if (csum->to >= packets[i].len) csum->to = packets[i].len - 1; sum = calc_csum(packets[i].payload + csum->from, csum->to - csum->from + 1, 0); break; case CSUM_UDP: sum = p4_csum((void *) packets[i].payload + csum->from, packets[i].payload + csum->to, (packets[i].len - csum->to), IPPROTO_UDP); break; case CSUM_TCP: sum = p4_csum((void *) packets[i].payload + csum->from, packets[i].payload + csum->to, (packets[i].len - csum->to), IPPROTO_TCP); break; } fmemcpy(&packets[i].payload[csum->off], &sum, sizeof(sum)); } }
static void udp_csum_update(struct proto_hdr *hdr) { struct proto_hdr *lower; uint16_t total_len; uint16_t csum; if (hdr->is_csum_valid) return; if (proto_hdr_field_is_set(hdr, UDP_CSUM)) return; lower = proto_lower_header(hdr); if (!lower) return; total_len = packet_get(hdr->pkt_id)->len - hdr->pkt_offset; proto_hdr_field_set_default_be16(hdr, UDP_CSUM, 0); switch (lower->ops->id) { case PROTO_IP4: csum = p4_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr), total_len, IPPROTO_UDP); break; case PROTO_IP6: csum = p6_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr), total_len, IPPROTO_UDP); break; default: csum = 0; break; } proto_hdr_field_set_default_be16(hdr, UDP_CSUM, bswap_16(csum)); hdr->is_csum_valid = true; }