1 /* 2 * Copyright (c) 2014 Chris Anderson 3 * 4 * Use of this source code is governed by a MIT-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/MIT 7 */ 8 9 #include "minip-internal.h" 10 11 /* XXX alternate implementation, merge */ ones_sum16(uint32_t sum,const void * _buf,int len)12uint16_t ones_sum16(uint32_t sum, const void *_buf, int len) { 13 const uint16_t *buf = _buf; 14 15 while (len >= 2) { 16 sum += *buf++; 17 if (sum & 0x80000000) 18 sum = (sum & 0xffff) + (sum >> 16); 19 len -= 2; 20 } 21 22 if (len) { 23 uint16_t temp = htons((*(uint8_t *)buf) << 8); 24 sum += temp; 25 } 26 27 while (sum >> 16) 28 sum = (sum & 0xffff) + (sum >> 16); 29 30 return sum; 31 } 32 rfc1701_chksum(const uint8_t * buf,size_t len)33uint16_t rfc1701_chksum(const uint8_t *buf, size_t len) { 34 uint32_t total = 0; 35 uint16_t chksum = 0; 36 const uint16_t *p = (const uint16_t *) buf; 37 38 // Length is in bytes 39 for (size_t i = 0; i < len / 2; i++ ) { 40 total += p[i]; 41 } 42 43 chksum = (total & 0xFFFF) + (total >> 16); 44 chksum = ~chksum; 45 46 return chksum; 47 } 48 49 #if MINIP_USE_UDP_CHECKSUM rfc768_chksum(struct ipv4_hdr * ipv4,struct udp_hdr * udp)50uint16_t rfc768_chksum(struct ipv4_hdr *ipv4, struct udp_hdr *udp) { 51 uint32_t total = 0; 52 uint16_t chksum = 0; 53 size_t len = ntohs(udp->len); 54 uint16_t *p; 55 56 p = (uint16_t *)ipv4->src_addr; 57 total += htons(p[0]); 58 total += htons(p[1]); 59 60 p = (uint16_t *)ipv4->dst_addr; 61 total += htons(p[0]); 62 total += htons(p[1]); 63 64 p = (const uint16_t *)udp->data; 65 for (size_t i = 0; i < len / 2; i++ ) { 66 total += p[i]; 67 } 68 69 total += IP_PROTO_UDP; 70 total += udp->len; 71 total += udp->src_port; 72 total += udp->dst_port; 73 total += ipv4->len; 74 75 chksum = (total & 0xFFFF) + (total >> 16); 76 chksum = ~chksum; 77 78 return chksum; 79 } 80 #endif 81