本文分析基于Linux Kernel 3.2.1Linux内核中协议族有INET协议族,UNIX协议族等,我们还是以INET协议族为例。更多请查看 Linux内核--网络内核实现分析下面是内核中的协议族声明:
- /* Supported address families. */
- #define AF_UNSPEC 0
- #define AF_UNIX 1 /* Unix domain sockets */
- #define AF_LOCAL 1 /* POSIX name for AF_UNIX */
- #define AF_INET 2 /* Internet IP Protocol */
- #define AF_AX25 3 /* Amateur Radio AX.25 */
- #define AF_IPX 4 /* Novell IPX */
- #define AF_APPLETALK 5 /* AppleTalk DDP */
- #define AF_NETROM 6 /* Amateur Radio NET/ROM */
- #define AF_BRIDGE 7 /* Multiprotocol bridge */
- #define AF_ATMPVC 8 /* ATM PVCs */
- #define AF_X25 9 /* Reserved for X.25 project */
- #define AF_INET6 10 /* IP version 6 */
- #define AF_ROSE 11 /* Amateur Radio X.25 PLP */
- #define AF_DECnet 12 /* Reserved for DECnet project */
- #define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/
- #define AF_SECURITY 14 /* Security callback pseudo AF */
- #define AF_KEY 15 /* PF_KEY key management API */
- #define AF_NETLINK 16
- #define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */
- #define AF_PACKET 17 /* Packet family */
- #define AF_ASH 18 /* Ash */
- #define AF_ECONET 19 /* Acorn Econet */
- #define AF_ATMSVC 20 /* ATM SVCs */
- #define AF_RDS 21 /* RDS sockets */
- #define AF_SNA 22 /* Linux SNA Project (nutters!) */
- #define AF_IRDA 23 /* IRDA sockets */
- #define AF_PPPOX 24 /* PPPoX sockets */
- #define AF_WANPIPE 25 /* Wanpipe API Sockets */
- #define AF_LLC 26 /* Linux LLC */
- #define AF_CAN 29 /* Controller Area Network */
- #define AF_TIPC 30 /* TIPC sockets */
- #define AF_BLUETOOTH 31 /* Bluetooth sockets */
- #define AF_IUCV 32 /* IUCV sockets */
- #define AF_RXRPC 33 /* RxRPC sockets */
- #define AF_ISDN 34 /* mISDN sockets */
- #define AF_PHONET 35 /* Phonet sockets */
- #define AF_IEEE802154 36 /* IEEE802154 sockets */
- #define AF_CAIF 37 /* CAIF sockets */
- #define AF_ALG 38 /* Algorithm sockets */
- #define AF_NFC 39 /* NFC sockets */
- #define AF_MAX 40 /* For now.. */
内核中的PF_***和AF_***其实可以混用,它的宏定义如下:
- /* Protocol families, same as address families. */
- #define PF_UNSPEC AF_UNSPEC
- #define PF_UNIX AF_UNIX
- #define PF_LOCAL AF_LOCAL
- #define PF_INET AF_INET
- #define PF_AX25 AF_AX25
- #define PF_IPX AF_IPX
- #define PF_APPLETALK AF_APPLETALK
- #define PF_NETROM AF_NETROM
- #define PF_BRIDGE AF_BRIDGE
- #define PF_ATMPVC AF_ATMPVC
- #define PF_X25 AF_X25
- #define PF_INET6 AF_INET6
- #define PF_ROSE AF_ROSE
- #define PF_DECnet AF_DECnet
- #define PF_NETBEUI AF_NETBEUI
- #define PF_SECURITY AF_SECURITY
- #define PF_KEY AF_KEY
- #define PF_NETLINK AF_NETLINK
- #define PF_ROUTE AF_ROUTE
- #define PF_PACKET AF_PACKET
- #define PF_ASH AF_ASH
- #define PF_ECONET AF_ECONET
- #define PF_ATMSVC AF_ATMSVC
- #define PF_RDS AF_RDS
- #define PF_SNA AF_SNA
- #define PF_IRDA AF_IRDA
- #define PF_PPPOX AF_PPPOX
- #define PF_WANPIPE AF_WANPIPE
- #define PF_LLC AF_LLC
- #define PF_CAN AF_CAN
- #define PF_TIPC AF_TIPC
- #define PF_BLUETOOTH AF_BLUETOOTH
- #define PF_IUCV AF_IUCV
- #define PF_RXRPC AF_RXRPC
- #define PF_ISDN AF_ISDN
- #define PF_PHONET AF_PHONET
- #define PF_IEEE802154 AF_IEEE802154
- #define PF_CAIF AF_CAIF
- #define PF_ALG AF_ALG
- #define PF_NFC AF_NFC
- #define PF_MAX AF_MAX
以后的分析就是以INET协议族为例来分析的。 下面的结构体就是在系统初始化时用来管理协议族初始化的结构体:
- struct net_proto_family {
- int family;
- int (*create)(struct net *net, struct socket *sock,
- int protocol, int kern);
- struct module *owner;
- };
第一个属性就是协议族的宏定义,如PF_INET; 第二个属性就是协议族对应的初始化函数指针;INET协议族对应该结构的定义如下:
- static const struct net_proto_family inet_family_ops = {
- .family = PF_INET,
- .create = inet_create,
- .owner = THIS_MODULE,
- };
下面结构体是协议族操作集结构体定义:
- struct proto_ops {
- int family;
- struct module *owner;
- int (*release) (struct socket *sock);
- int (*bind) (struct socket *sock,
- struct sockaddr *myaddr,
- int sockaddr_len);
- int (*connect) (struct socket *sock,
- struct sockaddr *vaddr,
- int sockaddr_len, int flags);
- int (*socketpair)(struct socket *sock1,
- struct socket *sock2);
- int (*accept) (struct socket *sock,
- struct socket *newsock, int flags);
- int (*getname) (struct socket *sock,
- struct sockaddr *addr,
- int *sockaddr_len, int peer);
- unsigned int (*poll) (struct file *file, struct socket *sock,
- struct poll_table_struct *wait);
- int (*ioctl) (struct socket *sock, unsigned int cmd,
- unsigned long arg);
- #ifdef CONFIG_COMPAT
- int (*compat_ioctl) (struct socket *sock, unsigned int cmd,
- unsigned long arg);
- #endif
- int (*listen) (struct socket *sock, int len);
- int (*shutdown) (struct socket *sock, int flags);
- int (*setsockopt)(struct socket *sock, int level,
- int optname, char __user *optval, unsigned int optlen);
- int (*getsockopt)(struct socket *sock, int level,
- int optname, char __user *optval, int __user *optlen);
- #ifdef CONFIG_COMPAT
- int (*compat_setsockopt)(struct socket *sock, int level,
- int optname, char __user *optval, unsigned int optlen);
- int (*compat_getsockopt)(struct socket *sock, int level,
- int optname, char __user *optval, int __user *optlen);
- #endif
- int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
- struct msghdr *m, size_t total_len);
- int (*recvmsg) (struct kiocb *iocb, struct socket *sock,
- struct msghdr *m, size_t total_len,
- int flags);
- int (*mmap) (struct file *file, struct socket *sock,
- struct vm_area_struct * vma);
- ssize_t (*sendpage) (struct socket *sock, struct page *page,
- int offset, size_t size, int flags);
- ssize_t (*splice_read)(struct socket *sock, loff_t *ppos,
- struct pipe_inode_info *pipe, size_t len, unsigned int flags);
- };
INET协议族中TCP和UDP协议对应的上述操作集的定义不同: TCP协议z在INET层操作集inet_stream_ops
- const struct proto_ops inet_stream_ops = {
- .family = PF_INET,
- .owner = THIS_MODULE,
- .release = inet_release,
- .bind = inet_bind,
- .connect = inet_stream_connect,
- .socketpair = sock_no_socketpair,
- .accept = inet_accept,
- .getname = inet_getname,
- .poll = tcp_poll,
- .ioctl = inet_ioctl,
- .listen = inet_listen,
- .shutdown = inet_shutdown,
- .setsockopt = sock_common_setsockopt,
- .getsockopt = sock_common_getsockopt,
- .sendmsg = inet_sendmsg,
- .recvmsg = inet_recvmsg,
- .mmap = sock_no_mmap,
- .sendpage = inet_sendpage,
- .splice_read = tcp_splice_read,
- #ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
- .compat_ioctl = inet_compat_ioctl,
- #endif
- };
UDP协议在INET层操作集inet_dgram_ops
- const struct proto_ops inet_dgram_ops = {
- .family = PF_INET,
- .owner = THIS_MODULE,
- .release = inet_release,
- .bind = inet_bind,
- .connect = inet_dgram_connect,
- .socketpair = sock_no_socketpair,
- .accept = sock_no_accept,
- .getname = inet_getname,
- .poll = udp_poll,
- .ioctl = inet_ioctl,
- .listen = sock_no_listen,
- .shutdown = inet_shutdown,
- .setsockopt = sock_common_setsockopt,
- .getsockopt = sock_common_getsockopt,
- .sendmsg = inet_sendmsg,
- .recvmsg = inet_recvmsg,
- .mmap = sock_no_mmap,
- .sendpage = inet_sendpage,
- #ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
- .compat_ioctl = inet_compat_ioctl,
- #endif
- };
上面两个操作集是属于INET协议族层次,可以由协议族层套接字socket来管理,下面是协议族层析的套接字结构体(BSD Socket)定义:
- /**
- * struct socket - general BSD socket
- * @state: socket state (%SS_CONNECTED, etc)
- * @type: socket type (%SOCK_STREAM, etc)
- * @flags: socket flags (%SOCK_ASYNC_NOSPACE, etc)
- * @ops: protocol specific socket operations
- * @file: File back pointer for gc
- * @sk: internal networking protocol agnostic socket representation
- * @wq: wait queue for several uses
- */
- struct socket {
- socket_state state;
-
- kmemcheck_bitfield_begin(type);
- short type;
- kmemcheck_bitfield_end(type);
-
- unsigned long flags;
-
- struct socket_wq __rcu *wq;
-
- struct file *file;
- struct sock *sk;
- const struct proto_ops *ops;
- };