本文分析基於Linux Kernel 3.2.1
Linux內核中協議族有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;
- };