socket广播校验和怎么计算?
我用udp校验和的函数来实现,怎么不对?
该udp校验和的函数计算的值在udp通信中是正确的。
[解决办法]
/*udp层的数据接收udp层的数据接收,对于socket而言,就是接收队列的入队操作。在ip层中,如果是本地数据,则会交由ip_local_deliver_finish()函数处理,它会根据传输层协议的类型,交由相应的处理函数,对于udp协议而言,就是udp_rcv():*/[Copy to clipboard] [ - ]CODE:/** All we need to do is get the socket, and then do a checksum. */int udp_rcv(struct sk_buff *skb){struct sock *sk;struct udphdr *uh;unsigned short ulen;dst;saddr;daddr;len;/** 数据包至少应有UDP首部长度.*/if (!pskb_may_pull(skb, sizeof(struct udphdr)))goto no_header;/*获取udp首部指针*/h.uh;/* 数据长度,含首部长度 */len);/* 数据包长度不够:UDP长度比skb长度小,意味着数据的丢失,而udp长度比udp首部还要小,好像这个不太可能,除非封包出错 ^o^*/len || ulen goto short_packet;/* 截去udp报文后面的多余报文 */if (pskb_trim(skb, ulen))goto short_packet;/* 开始udp校验和计算,主要查依赖于skb的ip_summumed字段的设置来决定是否需要进行校验和计算 */if (udp_checksum_init(skb, uh, ulen, saddr, daddr) goto csum_error;/* 转换多播或广播处理例程 */rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))return udp_v4_mcast_deliver(skb, uh, saddr, daddr);/* 查找数据段对应的socket结构的sk */ifindex);if (sk != NULL) {/* 找到了,数据包进入UDP的socket的接收队列*/int ret = udp_queue_rcv_skb(sk, skb);sock_put(sk);0 means to resubmit the input, but* it it wants the return to be -protocol, or 0*/0)return -ret;return 0;}if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))goto drop;/* 没有对应的socket. 如果校验和错误,则丢弃它 */if (udp_checksum_complete(skb))goto csum_error;/* 发送一个目的不可达报文 */UDP_INC_STATS_BH(UDP_MIB_NOPORTS);icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);/** Hmm. We got an UDP packet to a port to which we* don't wanna listen. Ignore it.*/kfree_skb(skb);return(0);short_packet:NETDEBUG(if (net_ratelimit())printk(KERN_DEBUG "UDP: short packet: From %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n",NIPQUAD(saddr),source),ulen,len,NIPQUAD(daddr),dest)));no_header:UDP_INC_STATS_BH(UDP_MIB_INERRORS);kfree_skb(skb);return(0);csum_error:/* * RFC1122: OK. Discards the bad packet silently (as far as * the network is concerned, anyway) as per 4.1.3.4 (MUST).
[解决办法]
你写的什么代码?自己用sock_raw吗?