Linux内核--网络栈实现分析(九)--传输层之UDP协议(下)

发表于:2013-1-05 09:37

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:闫明    来源:51Testing软件测试网采编

分享:

  udp_send()函数

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);
}

  这样要发送的数据填充的sk_buff结构中之后再对UDP数据包添加IP数据报头和MAC帧的首部。最后调用IP层的发送函数发送数据包。

  本文转载自:http://blog.csdn.net/yming0221/article/details/7492423

相关链接:

Linux内核--网络协议栈深入分析(一)--与sk_buff有关的几个重要的数据结构

Linux内核--网络栈实现分析(二)--数据包的传递过程(上)

Linux内核--网络栈实现分析(三)--驱动程序层+链路层(上)

Linux内核--网络栈实现分析(四)--网络层之IP协议(上)

Linux内核--网络栈实现分析(五)--传输层之UDP协议(上)

Linux内核--网络栈实现分析(六)--应用层获取数据包(上)

Linux内核--网络栈实现分析(七)--数据包的传递过程(下)

Linux内核--网络栈实现分析(八)--应用层发送数据(下)

22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号