ARP输入 之 arp_rcv
2024-09-05 07:49:55
概述
arp_rcv是ARP包的入口函数,ARP模块在二层注册了类型为ETH_P_ARP的数据包回调函数arp_rcv,当收到ARP包时,二层进行分发,调用arp_rcv;
arp_rcv对ARP输入包的合法性进行检查,然后经过netfilter的ARP_IN钩子点,之后调用arp_process处理输出包;
源码分析
/*
* Called once on startup.
*/ static struct packet_type arp_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_ARP),
.func = arp_rcv,
};
/*
* Receive an arp request from the device layer.
*/ static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
const struct arphdr *arp; /* do not tweak dropwatch on an ARP we will ignore */
/* 不支持ARP,非本机包,回环包,不处理 */
if (dev->flags & IFF_NOARP ||
skb->pkt_type == PACKET_OTHERHOST ||
skb->pkt_type == PACKET_LOOPBACK)
goto consumeskb; /* skb如果是共享的,则克隆一个 */
skb = skb_share_check(skb, GFP_ATOMIC);
if (!skb)
goto out_of_mem; /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
/* 检查arp包完整性 */
if (!pskb_may_pull(skb, arp_hdr_len(dev)))
goto freeskb; /* 获取arp头 */
arp = arp_hdr(skb); /* 地址长度和协议长度检查 */
if (arp->ar_hln != dev->addr_len || arp->ar_pln != )
goto freeskb; /* 清空neighCB */
memset(NEIGH_CB(skb), , sizeof(struct neighbour_cb)); /* 经过NF的ARP_IN钩子点,然后调用arp_process */
return NF_HOOK(NFPROTO_ARP, NF_ARP_IN,
dev_net(dev), NULL, skb, dev, NULL,
arp_process); consumeskb:
consume_skb(skb);
return NET_RX_SUCCESS;
freeskb:
kfree_skb(skb);
out_of_mem:
return NET_RX_DROP;
}
最新文章
- 【2014-05-06】C++ 设计模式----单例模式
- json提交数据到服务端
- 《转》.NET开源核心运行时,且行且珍惜
- const 与 readonly 知多少
- MySQL 에서 root 암호 변경하기
- 2014年12月23日00:42:54——PS4
- CSS中 清除浮动解决“包含问题”
- git bash 出现vim的时候怎么退出
- 【NOIP2017 OFO】
- cf581F 依赖背包+临时数组 好题
- 使用VSFTPD传输文件
- 第二章 JavaScript案例(中)
- BZOJ3590 SNOI2013Quare(状压dp)
- Fedora 全局代理上网设置
- [leetcode]Path Sum II @ Python
- 调整的R方_如何选择回归模型
- shell 遍历
- photoshop:制作sprite拼贴图片
- iOS常识名词解释 2016/04/05
- Navicat 连接MySQL 8.0.11 出现2059错误