Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1235981
  • 博文数量: 389
  • 博客积分: 2874
  • 博客等级: 少校
  • 技术积分: 3577
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 10:34
文章分类

全部博文(389)

文章存档

2020年(2)

2018年(39)

2017年(27)

2016年(3)

2015年(55)

2014年(92)

2013年(54)

2012年(53)

2011年(64)

分类: LINUX

2011-04-22 17:32:18

 
[转载] Linux的TCP/IP协议栈阅读笔记(2)

发信人: AngelFalls (TRY IT), 信区: SysInternals
标 题: [转载] Linux的TCP/IP协议栈阅读笔记(2)
发信站: 武汉白云黄鹤站 (Wed Oct 4 01:36:16 2000), 转信

【 以下文字转载自 Security 讨论区 】
【 原文由 AngelFalls 所发表 】
下面来看看IPv4协议和PACKET协议的初始化过程。



首先看PACKET协议,首先我们假定PACKET协议是编译在核心里面的,

而不是一个MODULE,这样得到packet_proto_init函数在net/packet/af_packet.c

里面是这样的:

void __init packet_proto_init(struct net_proto *pro)

{

sock_register(&packet_family_ops);

register_netdevice_notifier(&packet_netdev_notifier);

}



其中sock_register函数在net/socket.c里面,就是简单的设置前面

说的net_families数组中间对应的值:

int sock_register(struct net_proto_family *ops)

{

if (ops->family >= NPROTO) {

printk(KERN_CRIT "protocol %d >= NPROTO(%d)\n",

ops->family, NPROTO);

return -ENOBUFS;

}

net_families[ops->family]=ops;

return 0;

}



这里要说明的是packet_netdev_notifier是一个struct notifier_block

类型,这个struct是在include/linux/notifier.h里面的:

struct notifier_block

{

int (*notifier_call)(struct notifier_block *self, unsigned long, void *);

struct notifier_block *next;

int priority;

};



而register_netdevice_notifier函数在net/core/dev.c里面,是这样的:

int register_netdevice_notifier(struct notifier_block *nb)

{

return notifier_chain_register(&netdev_chain, nb);

}



而notifier_chain_register函数在include/linux/notifier.h里面,是

这样的:

extern __inline__ int notifier_chain_register(

struct notifier_block **list, struct notifier_block *n)

{

while(*list)

{

if(n->priority > (*list)->priority)

break;

list= &((*list)->next);

}

n->next = *list;

*list=n;

return 0;

}

显然就是根据每个block的优先级把这个block排列在一个block的链表里

面,在notifier_chain_register函数里面我们可以发现这个链表是

netdev_chain。实际上这个链表的作用就是在每个interface打开,关闭

状态改变或者外界调用相应的ioctl的时候通知这个链表上面的所有相关

的设备,而每一个协议都调用register_netdevice_notifier注册了一个

netdev_notifier的结构体,这样就可以在interface改变的时候得到通知

了(通过调用每个notifier_call函数)。



下面来看inet_proto_init函数,这个函数在net/ipv4/af_inet.c中间,

里面也有很多ifdef的编译选项,假定下面几个是没有定义的:

CONFIG_NET_IPIP,CONFIG_NET_IPGRE,CONFIG_IP_FIREWALL,

CONFIG_IP_MASQUERADE,CONFIG_IP_MROUTE

假定下面几个是定义了的:

CONFIG_INET_RARP,CONFIG_PROC_FS

下面是整理后的代码:

(void) sock_register(&inet_family_ops);

for(p = inet_protocol_base; p != NULL;) {

struct inet_protocol *tmp=(struct inet_protocol *)p->next;

inet_add_protocol(p);

printk("%s%s",p->name,tmp?", ":"\n");

p = tmp;

}



arp_init();

ip_init();

tcp_v4_init(&inet_family_ops);

tcp_init();

icmp_init(&inet_family_ops);



rarp_ioctl_hook = rarp_ioctl;

proc_net_register(&proc_net_rarp);

proc_net_register(&proc_net_raw);

proc_net_register(&proc_net_snmp);

proc_net_register(&proc_net_netstat);

proc_net_register(&proc_net_sockstat);

proc_net_register(&proc_net_tcp);

proc_net_register(&proc_net_udp);

阅读(1352) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~