- 论坛徽章:
- 0
|
在收到udp报文后
我的理解是会先进行校验和计算(伪头,头部,数据),校验和正确再进行后续操作,入队列
但在协议栈代码中[2.6.34 kernel]
udp_rcv() -> __udp4_lib_rcv()中,只有udp4_csum_init()初始化了校验和,但并没有判断校验和是否正确,所以一定会调用
__udp_lib_lookup_skb()和udp_queue_rcv_skb()开始udp的接收。这样的话,即使udp的校验和是错误的,协议栈也会接收,我哪里理解错了吗?- int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
- int proto)
- {
- struct sock *sk;
- struct udphdr *uh;
- unsigned short ulen;
- struct rtable *rt = skb_rtable(skb);
- __be32 saddr, daddr;
- struct net *net = dev_net(skb->dev);
- /*
- * Validate the packet.
- */
- if (!pskb_may_pull(skb, sizeof(struct udphdr)))
- goto drop; /* No space for header. */
- uh = udp_hdr(skb);
- ulen = ntohs(uh->len);
- saddr = ip_hdr(skb)->saddr;
- daddr = ip_hdr(skb)->daddr;
- if (ulen > skb->len)
- goto short_packet;
- if (proto == IPPROTO_UDP) {
- /* UDP validates ulen. */
- if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
- goto short_packet;
- uh = udp_hdr(skb);
- }
- if (udp4_csum_init(skb, uh, proto))
- goto csum_error;
- if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
- return __udp4_lib_mcast_deliver(net, skb, uh,
- saddr, daddr, udptable);
- sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
- if (sk != NULL) {
- int ret = udp_queue_rcv_skb(sk, skb);
- sock_put(sk);
- /* a return value > 0 means to resubmit the input, but
- * it wants the return to be -protocol, or 0
- */
- if (ret > 0)
- return -ret;
- return 0;
- }
- if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
- goto drop;
- nf_reset(skb);
- /* No socket. Drop packet silently, if checksum is wrong */
- if (udp_lib_checksum_complete(skb))
- goto csum_error;
- UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
- 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;
复制代码 |
|