struct inet_protosw

struct inet_protosw {
    struct list_head         list;
    unsigned short           type;
    int                      protocol;
    struct proto             *prot;
    const struct proto_ops --*ops;   
    int                      capability;
    char                     no_check;
    unsigned char            flags;
};

    协议(协议族)的映射完成了,现在要进行服务的映射了。上层当然不可能知道下层的什么协议能对应特定的服务,所以这种映射自然由协议族自己完成。在TCP/IP协议族里,这种映射是通过struct list_head inetsw[SOCK_MAX](net/ipv4/af_inet.c)进行映射的。在谈论这个数组之前我们来看另外一个数组inetsw_array[]
--------------------------------------------
/usr/src/linux/net/ipv4/af_inet.c
static struct inet_protosw inetsw_array[] =
{
    {
        .type       = SOCK_STREAM,
        .protocol   = IPPROTO_TCP,
        .prot       = &tcp_prot,             //与协议类型相关的操作集
        .ops        = &inet_stream_ops,      //与服务类型相关的操作集
        .capability = -1,
        .no_check   = 0,
        .flags      = INET_PROTOSW_PERMANENT | INET_PROTOSW_ICSK,
    },

    {
        .type       = SOCK_DGRAM,
        .protocol   = IPPROTO_UDP,
        .prot       = &udp_prot,
        .ops        = &inet_dgram_ops,
        .capability = -1,
        .no_check   = UDP_CSUM_DEFAULT,
        .flags      = INET_PROTOSW_PERMANENT,
    },


    {
        .type       = SOCK_RAW,
        .protocol   = IPPROTO_IP,   /* wild card */
        .prot       = &raw_prot,
        .ops        = &inet_sockraw_ops,
        .capability = CAP_NET_RAW,
        .no_check   = UDP_CSUM_DEFAULT,
        .flags      = INET_PROTOSW_REUSE,
    }
};

    我们看到,SOCK_STREAM映射到了TCP协议,SOCK_DGRAM映射到了UDP协议,SOCK_RAW映射到了IP协议。现在只要把inetsw_array[]里的三项添加到数组inetsw[SOCK_MAX]就可以了,添加是通过函数inet_register_protosw()实现的。在inet_init()(net/ipv4/af_inet.c)里完成了这些工作。


--------------------------------------------
inet_protosw->type
    type是指套接字的类型,也就是系统调用socket的第二个参数,inet域支持的套接字类型有SOCK_STREAM(流套接字),它是一个有序的,可靠的,基于连接的双向字节流;SOCK_DGRAM(数据报套接字),该类型的套接字是不可靠的,无连接的,有可能乱序的;SOCK_RAW(原始套接字),所谓原始,是因为该类型的套接字不提供传输层的服务,协议栈只为该类型的套接字自动添加网络层首部,常用于网络层的附属协议(ICMP, IGMP等)。

inet_protosw->protocol
    protocol是一个传输层协议号,传输层的协议包括IPPROTO_TCP,IPPROTO_UDP;或者对于SOCK_RAW来讲,它是一个通配协议号IPPROTO_IP,用于通配网络层的附属协议ICMP,IGMP等。对于传输层协议来讲,IPPROTO_TCP对应的套接字类型总是SOCK_STREAM,IPPRTO_UDP对应的套接字类型总是STREAM_DGRAM,所以在socket系统调用时,可以不必指定协议号,而直接使用通配符IPPROTO_IP。

inet_protosw->prot
    prot是一个传输层协议绑定的操作集,比如对于IPPROTO_TCP,它就是tcp_prot,对于IPPROTO_UDP,它就是udp_prot。而对于类型为SOCK_RAW的套接字,它没有相应的传输层协议,而是用于通配所有的网络层附属协议,所以,prot就是所有网络层附属协议共用的一个操作集raw_prot。

inet_protosw->ops
    ops是套接字类型绑定的操作集,对应于SOCK_STREAM, SOCK_DGRAM, SOCK_RAW,操作集分别为inet_stream_ops,inet_dgram_ops,inet_sockraw_ops。

inet_protosw->capability
    capability是操作这类别套接字所需要的权限,除了原始套接字需要CAP_NET_RAW权限之外,其它两类套接字不需要特殊权限(-1)。

inet_protosw->flags
    flags的可能取值如下:
    #define INET_PROTOSW_REUSE         0x01
    #define INET_PROTOSW_PERMANENT     0x02
    #define INET_PROTOSW_ICSK          0x04

    inetsw是一个链表数组,每一项都是一个struct inet_protosw结构体的链表,总共有SOCK_MAX项,在inet_init函数对INET域进行初始化的时候,调用函数inet_register_protosw()把数组inetsw_array中定义的套接字类型全部注册到inetsw数组中,相同套接字类型,不同协议类型的在数组的同一项,以套接字类型为索引,在系统实际使用的时候,只使用inetsw,而不使用inetsw_array,目前inet域不存在相同套接字类型的多个协议(原始套接字使用通配符,所以也不存在这个问题)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值