/** * @brief Calculate the UDP checksum dependent on the network protocol * * @note If the checksum turns out to be 0x0000, the function returns 0xffff * as specified in RFC768 * * @param[in] pkt pointer to the packet in the packet buffer * @param[in] pseudo_hdr pointer to the network layer header * @param[in] payload pointer to the payload * * @return the checksum of the pkt in host byte order * @return 0 on error */ static uint16_t _calc_csum(ng_pktsnip_t *hdr, ng_pktsnip_t *pseudo_hdr, ng_pktsnip_t *payload) { uint16_t csum = 0; uint16_t len = (uint16_t)hdr->size; /* process the payload */ while (payload && payload != hdr) { csum = ng_inet_csum(csum, (uint8_t *)(payload->data), payload->size); len += (uint16_t)payload->size; payload = payload->next; } /* process applicable UDP header bytes */ csum = ng_inet_csum(csum, (uint8_t *)hdr->data, sizeof(ng_udp_hdr_t)); switch (pseudo_hdr->type) { #ifdef MODULE_NG_IPV6 case NG_NETTYPE_IPV6: csum = ng_ipv6_hdr_inet_csum(csum, pseudo_hdr->data, NG_PROTNUM_UDP, len); break; #endif default: (void)len; return 0; } /* return inverted results */ return ~csum; }
static inline uint16_t _calc_csum(ng_pktsnip_t *hdr, ng_pktsnip_t *pseudo_hdr, ng_pktsnip_t *payload) { uint16_t csum = 0; uint16_t len = (uint16_t)hdr->size; while (payload && (payload != hdr)) { csum = ng_inet_csum(csum, payload->data, payload->size); len += (uint16_t)payload->size; payload = payload->next; } csum = ng_inet_csum(csum, hdr->data, hdr->size); csum = ng_ipv6_hdr_inet_csum(csum, pseudo_hdr->data, NG_PROTNUM_ICMPV6, len); return ~csum; }