最近在看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 */
-
};
目前为止,就读明白这些,有了新进展,一定会分享的哈~~
阅读(7403) | 评论(0) | 转发(0) |