IP层实现4-raw socket 接收数据

本文详细探讨了Linux内核在IP层如何通过raw socket接收数据的过程,涉及函数包括ip_local_deliver_finish、raw_local_deliver等,讲解了数据从网络层到raw socket的传递路径,以及最终如何将数据放入socket接收队列。
摘要由CSDN通过智能技术生成

在接收数据时,在ip_local_deliver_finish函数中会先调用raw_local_deliver,将数据包提交到raw socket中去,下面就是提交过程:

[ net/ipv4/raw.c ]

int raw_local_deliver(struct sk_buff *skb, int protocol)
{
	int hash;
	struct sock *raw_sk;

	/* 所有的raw socket都挂在全局数组raw_v4_hashinfo上
	 * 每种协议都有一个列表
	 */
	hash = protocol & (RAW_HTABLE_SIZE - 1);	// 通过协议得到数组下标
	raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);

	/* If there maybe a raw socket we must check - if not we
	 * don't care less
	 */
	if (raw_sk && !raw_v4_input(skb, ip_hdr(skb), hash))
		raw_sk = NULL;

	return raw_sk != NULL;

}
当中调用的函数:

[ net/ipv4/raw.c ]

/* IP input processing comes here for RAW socket delivery.
 * Caller owns SKB, so we must make clones.
 *
 * RFC 1122: SHOULD pass TOS value up to the transport layer.
 * -> It does. And not only TOS, but all IP header.
 */
static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
{
	struct sock *sk;
	struct hlist_head *head;
	int delivered = 0;
	struct net *net;

	read_lock(&raw_v4_hashinfo.lock);
	head = &raw_v4_hashinfo.ht[hash];	// hash由skb的协议决定。得到协议对应的row socket
	if (hlist_empty(head))
		goto out;

	net = dev_net(skb->dev);	// 网络
	/* 得到关联的socket
	 * 根据IP层的上层协议,目的和源地址,接收数据的设备号
	 */
	sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
			     iph->saddr, iph->daddr,
			     skb->dev->ifindex);

	while (sk) {
		delivered = 1;
		/* 协议不是ICMP
		 * 数据包不是ICMP要过滤的数据包
		 */
		if (iph->protocol !&
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值