admin管理员组

文章数量:1642150

在分析AF_PACKET raw socket实现时,我们从创建socket入手来分析, 本篇我们从收包流程入手来分析。在分析协议栈报文接收IP层分析时,我们知道IP层把报文交给raw sock的入口函数是raw_local_deliver。我们从这个函数来看看是如何把一个报文提交给raw socket的。

1、raw_local_deliver函数

int raw_local_deliver(struct sk_buff *skb, int protocol)  //该protocol为ip头中的协议
{
	int hash;
	struct sock *raw_sk;

	hash = protocol & (RAW_HTABLE_SIZE - 1);	//根据协议类型计算出hash值,hash值共256个,所以不同的ip协议不会重叠
	raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);	//得到sock,这个sock一定是在创建的时候放到raw_v4_hashinfo中的

	/* 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))	//sock不为空,则把报文提交给sock
		raw_sk = NULL;

	return raw_sk != NULL;

}
2、raw_v4_input函数

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的sock链表
	if (hlist_empty(head))
		goto out;

	net = dev_net(skb->dev);
	sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,	//sock是否能够接收报文,匹配ip源地址、ip目的地址等
			     iph->saddr, iph->daddr,
			     skb->dev->ifindex);

	while (sk) {		//第一个如果不匹配,后续则不再处理,所以次序很重要,对raw socket肯定是能够匹配的报文的
		delivered = 1;
		if ((iph->pr

本文标签: 源码原理SocketRAWAFINET