最近在看tcp/ip v2,发现看完前几章之后,脑子里面一坨。。。呵呵哒,惨不忍睹啊,不过还是有点小收获,在这里跟各位看官分享一下网络相关的各个数据结构以及之间关系,拍砖的请自备工具。。。
俗话说,一图胜千言(也有人说,没图你说个xx。。。),先上图:

今天这篇文章的任务就是将上面的这张图给大家说清楚:
我将从水平和垂直两个维度来讲解这张图片:
第一行,表示的是整个机器上面,所有的网络硬件在内核当中的数据结构,在系统初始化期间,分别为每个网络设备分配一个独立的ifnet{}结构(其中,以太网卡貌似支持热插拔检测),每个ifnet{}结构的下面,连接着位于其上的一个或多个协议地址,ifnet{}的各个字段如下所示:
点击(此处)折叠或打开
- struct ifnet {
- char *if_name; /* name, e.g. ``en'' or ``lo'' */
- struct ifnet *if_next; /* all struct ifnets are chained */
- struct ifaddr *if_addrlist; /* linked list of addresses per if */
- int if_pcount; /* number of promiscuous listeners */
- caddr_t if_bpf; /* packet filter structure */
- u_short if_index; /* numeric abbreviation for this if */
- short if_unit; /* sub-unit for lower level driver */
- short if_timer; /* time 'til if_watchdog called */
- short if_flags; /* up/down, broadcast, etc. */
- struct if_data {
- /* generic interface information */
- u_char ifi_type; /* ethernet, tokenring, etc */
- u_char ifi_addrlen; /* media address length */
- u_char ifi_hdrlen; /* media header length */
- u_long ifi_mtu; /* maximum transmission unit */
- u_long ifi_metric; /* routing metric (external only) */
- u_long ifi_baudrate; /* linespeed */
- /* volatile statistics */
- u_long ifi_ipackets; /* packets received on interface */
- u_long ifi_ierrors; /* input errors on interface */
- u_long ifi_opackets; /* packets sent on interface */
- u_long ifi_oerrors; /* output errors on interface */
- u_long ifi_collisions; /* collisions on csma interfaces */
- u_long ifi_ibytes; /* total number of octets received */
- u_long ifi_obytes; /* total number of octets sent */
- u_long ifi_imcasts; /* packets received via multicast */
- u_long ifi_omcasts; /* packets sent via multicast */
- u_long ifi_iqdrops; /* dropped on input, this interface */
- u_long ifi_noproto; /* destined for unsupported protocol */
- struct timeval ifi_lastchange;/* last updated */
- } if_data;
- /* procedure handles */
- int (*if_init) /* init routine */
- __P((int));
- int (*if_output) /* output routine (enqueue) */
- __P((struct ifnet *, struct mbuf *, struct sockaddr *,
- struct rtentry *));
- int (*if_start) /* initiate output routine */
- __P((struct ifnet *));
- int (*if_done) /* output complete routine */
- __P((struct ifnet *)); /* (XXX not used; fake prototype) */
- int (*if_ioctl) /* ioctl routine */
- __P((struct ifnet *, int, caddr_t));
- int (*if_reset)
- __P((int)); /* new autoconfig will permit removal */
- int (*if_watchdog) /* timer routine */
- __P((int));
- struct ifqueue {
- struct mbuf *ifq_head;
- struct mbuf *ifq_tail;
- int ifq_len;
- int ifq_maxlen;
- int ifq_drops;
- } if_snd; /* output queue */
- };
它使用if_next指针将系统中所有检测到的interface连接起来,组成一个单向链表,链表的头指针由全局变量ifnet表示,每一个ifnet{}结构中,有一个if_addrlist指针,分别对应,位于该interface上的所有协议的地址列表(如链路层,网络层等等);if_netaddrs指向一个数组,数组中的每一个元素,指向一个链路层地址结构if_addr{}, 其定义如下:
点击(此处)折叠或打开
- struct ifaddr {
- struct sockaddr *ifa_addr; /* address of interface */
- struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */
- #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
- struct sockaddr *ifa_netmask; /* used to determine subnet */
- struct ifnet *ifa_ifp; /* back-pointer to interface */
- struct ifaddr *ifa_next; /* next address for interface */
- void (*ifa_rtrequest)(); /* check or clean routes (+ or -)'d */
- u_short ifa_flags; /* mostly rt_flags for cloning */
- short ifa_refcnt; /* extra to malloc for link info */
- int ifa_metric; /* cost of going out this interface */
- #ifdef notdef
- struct rtentry *ifa_rt; /* XXXX for ROUTETOIF ????? */
- #endif
- };
在往下,就是in_ifaddrs指针了,它指向一个单向链表,链表中的每一项就是该主机对应的一个网络地址,且每一个网络地址必须对应一个ifnet{}结构,每一个项由一个in_ifaddr{}机构表示,如下图所示:
点击(此处)折叠或打开
- struct in_ifaddr {
- struct ifaddr ia_ifa; /* protocol-independent info */
- #define ia_ifp ia_ifa.ifa_ifp
- #define ia_flags ia_ifa.ifa_flags
- /* ia_{,sub}net{,mask} in host order */
- u_long ia_net; /* network number of interface */
- u_long ia_netmask; /* mask of net part */
- u_long ia_subnet; /* subnet number, including net */
- u_long ia_subnetmask; /* mask of subnet part */
- struct in_addr ia_netbroadcast; /* to recognize net broadcasts */
- struct in_ifaddr *ia_next; /* next in list of internet addresses */
- struct sockaddr_in ia_addr; /* reserve space for interface name */
- struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
- #define ia_broadaddr ia_dstaddr
- struct sockaddr_in ia_sockmask; /* reserve space for general netmask */
- struct in_multi *ia_multiaddrs; /* list of multicast addresses */
- };
目前为止,就读明白这些,有了新进展,一定会分享的哈~~