unsigned ci_ip_checksum(const ci_ip4_hdr* ip) { const ci_uint16* p = (const ci_uint16*) ip; unsigned csum; int bytes; csum = p[0]; csum += p[1]; csum += p[2]; csum += p[3]; csum += p[4]; /* omit ip_check_be16 */ csum += p[6]; csum += p[7]; csum += p[8]; csum += p[9]; bytes = CI_IP4_IHL(ip); if(CI_UNLIKELY( bytes > 20 )) { p += 10; bytes -= 20; do { csum += *p++; bytes -= 2; } while( bytes ); } return ci_ip_hdr_csum_finish(csum); }
ci_inline void ci_udp_recvmsg_fill_msghdr(ci_netif* ni, ci_msghdr* msg, const ci_ip_pkt_fmt* pkt, ci_sock_cmn* s) { #ifndef __KERNEL__ const ci_udp_hdr* udp; const ci_ip4_hdr* ip; if( msg != NULL ) { if( msg->msg_name != NULL ) { if( pkt->flags & CI_PKT_FLAG_RX_INDIRECT ) pkt = PKT_CHK_NNL(ni, pkt->frag_next); ip = oo_ip_hdr_const(pkt); udp = (const ci_udp_hdr*) ((char*) ip + CI_IP4_IHL(ip)); ci_addr_to_user(CI_SA(msg->msg_name), &msg->msg_namelen, s->domain, udp->udp_source_be16, ip->ip_saddr_be32); } } #endif }