admin管理员组

文章数量:1642164

在接收数据时,在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 !&

本文标签: 数据ipRAWSocket