荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jjk (UNIX+C+XML+?? 傻了?), 信区: Linux
标  题: ARP的发送函数分析(转寄)
发信站: 荔园晨风BBS站 (Mon Apr 22 19:48:06 2002), 转信

【 以下文字转载自 jjk 的信箱 】
【 原文由 jjk.bbs@apue.dhs.org 所发表 】
发信人: tl (tl), 信区: UKP
标  题: ARP的发送函数分析
发信站: UNIX编程 (2002年04月16日20:53:02 星期二), 转信

作者:硅谷农民<mailto:ggnm@kerneldiary.net>

void arp_send(int type, int ptype, u32 dest_ip,
       struct net_device *dev, u32 src_ip,
       unsigned char *dest_hw, unsigned char *src_hw,
       unsigned char *target_hw)
   当系统的网络驱动程序收到一个arp包的时候,调用这个函数处理。简单来说,arp_
rev
发回本机器或者它代理的其他机器的网卡硬件地址(mac address),并且将发送者的网
卡硬件地址放
在自己的缓存(arp cache)中。
实现过程:
 (1) 分配一个sk_buff,用来构造ARP包,除了必要的空间以外,还预留了15字节作备用

   调用skb_reserve空出前面的15字节和网络包头部。
    skb = alloc_skb(sizeof(struct arphdr)+ 2*(dev->addr_len+4)
                + dev->hard_header_len + 15, GFP_ATOMIC);
    if (skb == NULL)
        return;
    skb_reserve(skb, (dev->hard_header_len+15)&~15);
    skb->nh.raw = skb->data;
    arp = (struct arphdr *) skb_put(skb,sizeof(struct arphdr) + 2*(dev->addr
_len+4));
    skb->dev = dev;
    skb->protocol = __constant_htons (ETH_P_ARP);
 + 如果从参数传进来的源硬件地址为空的话,则设为设备的硬件地址;
   如果从参数传进来的目的硬件地址为空的话,则设为广播地址。
    if (src_hw == NULL)
        src_hw = dev->dev_addr;
    if (dest_hw == NULL)
        dest_hw = dev->broadcast;
 + 调用网卡设备本身的MAC头部构造函数,填好这个ARP包的ethernet目的硬件地址和源
硬件地址。
   ethernet的缺省构造函数为eth_header,请参见net_init.c中的ether_setup函数。

    if (dev->hard_header &&
        dev->hard_header(skb,dev,ptype,dest_hw,src_hw,skb->len) < 0)
            goto out;
 + 填写ARP包的硬件地址类型(ethernet :1)和协议地址的类型(ip :0x800)。
    arp->ar_hrd = htons(dev->type);
    arp->ar_pro = __constant_htons(ETH_P_IP);
 + 填写硬件地址长度(一般为6 字节)和协议地址长度(4 字节);
   填写arp包的类型,arp请求为1,arp应答为2。
    arp->ar_hln = dev->addr_len;
    arp->ar_pln = 4;
    arp->ar_op = htons(type);
 填写arp包的数据,包括源ethernet地址(sha)、源ip地址(sip)、目的ethernet地址(t
ha)和目的ip地址(tip)。
    arp_ptr=(unsigned char *)(arp+1);
    memcpy(arp_ptr, src_hw, dev->addr_len);
    arp_ptr+=dev->addr_len;
    memcpy(arp_ptr, &src_ip,4);
    arp_ptr+=4;
    if (target_hw != NULL)
        memcpy(arp_ptr, target_hw, dev->addr_len);
    else
        memset(arp_ptr, 0, dev->addr_len);
    arp_ptr+=dev->addr_len;
    memcpy(arp_ptr, &dest_ip, 4);
+ 最后,调用dev_queue_xmit将这个ARP包放在发送队列中准备发送。
    dev_queue_xmit(skb);
--------------------------------------------------
硅谷农民,日出而作,一分耕耘,一分收获。

--

    欲慰韶华携吴钩,剑雪刀霜遣风流。
    一蓑烟雨平生事,道无狂嚣亦无愁!

※ 来源:·UNIX编程 apue.dhs.org·[FROM: 166.111.160.6] --
※ 转寄:·UNIX编程 apue.dhs.org·[FROM: 210.39.3.50]
--
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.146]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店