[转载] 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);
|
阅读(1410) | 评论(0) | 转发(0) |