static int udp_send(struct sock *sk, //要发送的数据包使用的协议对用的sock结构 struct sockaddr_in *sin,//目的端的标准的网络接口地址 unsigned char *from,//要发送的数据所在地址 int len,//发送数据的长度 int rt) { struct sk_buff *skb; struct device *dev; struct udphdr *uh; unsigned char *buff; unsigned long saddr; int size, tmp; int ttl; /* * Allocate an sk_buff copy of the packet. */ size = sk->prot->max_header + len;//计算大小为UDP最长表头+ 数据长度 skb = sock_alloc_send_skb(sk, size, 0, &tmp);//根据要发送的数据分配sk_buff结构空间并对当前套接字状态检查
if (skb == NULL) return tmp;
skb->sk = NULL; /* to avoid changing sk->saddr */ skb->free = 1; skb->localroute = sk->localroute|(rt&MSG_DONTROUTE);
/* * Now build the IP and MAC header. */ buff = skb->data;//将skb中的数据指针赋值给buff指针 saddr = sk->saddr;//本地地址 dev = NULL; ttl = sk->ip_ttl;//生存时间 #ifdef CONFIG_IP_MULTICAST if (MULTICAST(sin->sin_addr.s_addr)) ttl = sk->ip_mc_ttl; #endif tmp = sk->prot->build_header(skb, saddr, sin->sin_addr.s_addr, &dev, IPPROTO_UDP, sk->opt, skb->mem_len,sk->ip_tos,ttl);//调用ip_build_header()创建IP报头和调用ip_send()创建MAC首部
skb->sk=sk; /* So memory is freed correctly */ /* * Unable to put a header on the packet. */ if (tmp < 0 ) { sk->prot->wfree(sk, skb->mem_addr, skb->mem_len); return(tmp); } buff += tmp; saddr = skb->saddr; /*dev->pa_addr;*/ skb->len = tmp + sizeof(struct udphdr) + len; /* len + UDP + IP + MAC */ skb->dev = dev; /* * Fill in the UDP header. 填写UDP的报头 */ uh = (struct udphdr *) buff; uh->len = htons(len + sizeof(struct udphdr));//数据包长度 uh->source = sk->dummy_th.source;//本地端口 uh->dest = sin->sin_port;//远端端口 buff = (unsigned char *) (uh + 1);
/* * Copy the user data. */ memcpy_fromfs(buff, from, len);//复制用户数据
/* * Set up the UDP checksum. */ udp_send_check(uh, saddr, sin->sin_addr.s_addr, skb->len - tmp, sk);//计算UDP报头的校验和
/* * Send the datagram to the interface. */ udp_statistics.UdpOutDatagrams++; sk->prot->queue_xmit(sk, dev, skb, 1);//调用IP层函数发送数据 return(len); } |