《TCP/IP详解,卷2:实现》读书笔记-接口分析

    熟悉了mbuf的结构后,我们进入接口层,所谓接口,就是指在一个特定网络上硬件与设备驱动器之间的接口。BSD设计将网络协议和连接到一个系统的网络设备的驱动器间提供一个与硬件无关的编程接口。

    提到接口,首先需要介绍ifnet结构,结构ifnet中包含所有接口的通用信息。在系统初始化期间,分别为每个网络设备分配一个独立的ifnet结构。每个ifnet结构有一个列表,它包含这个设备的一个或多个协议地址。函数if_attach在系统初始化期间构造这个链表。if_addrlist指向这个接口的ifaddr结构列表。每个ifaddr结构存储一个要用这个接口通信的协议的地址信息。如果读过我以前的mbuf的分析,是不是感觉数据结构上非常相似呀,幸福的家庭都是一样的:) 

 

struct  ifnet {
        
/* 实现信息 */
    
char      * if_name;         /*  字符串,标识接口的类型  */
    
struct     ifnet  * if_next;         /*  把所有接口的ifnet结构链接成一个链表,这个链表在系统初始化期间构造  */
    
struct     ifaddr  * if_addrlist;     /*  指向这个接口的ifaddr结构列表  */
        
int     if_pcount;         /*  监听者的数目  */
    caddr_t    if_bpf;            
/*  分组过滤器结构  */
    u_short    if_index;        
/*  在内核中唯一地标识这个接口   */
    
short     if_unit;         /*  标识多个相同类型的实例  */
    
short     if_timer;         /*  以秒为单位记录时间,直到内核为此接口调用函数if_watchdog为止  */
    
short     if_flags;         /*  接口的操作状态和属性,譬如接口正在工作和用于广播  */
    
struct     if_data {
        
/*  硬件信息  */
        u_char    ifi_type;    
/*  指明接口支持的硬件地址类型,如以太网,令牌环  */
        u_char    ifi_addrlen;    
/*  数据链路地址的长度  */
        u_char    ifi_hdrlen;    
/*  由硬件附加给任何分组的首部的长度  */
        u_long    ifi_mtu;    
/*  接口在一次输出操作中能传输的最大数据单元的字节数,如以太网是1500  */
        u_long    ifi_metric;    
/*  routing metric,通常为0  */
        u_long    ifi_baudrate;    
/*  指定接口的传输速率  */
        
/*  接口统计  */
        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;
        
/*  函数指针,在系统初始化时,每个设备驱动程序初始化它自己的ifnet结构  */
    
int     ( * if_init)         /*  初始化接口  */
        __P((
int ));
    
int     ( * if_output)         /*  对输出分组进行排队  */
        __P((
struct  ifnet  * struct  mbuf  * struct  sockaddr  * ,
             
struct  rtentry  * ));
    
int     ( * if_start)         /*  启动分组的传输  */
        __P((
struct  ifnet  * ));
    
int     ( * if_done)         /*  传输完成后的清除  */
        __P((
struct  ifnet  * ));    
    
int     ( * if_ioctl)         /*  IO控制命令  */
        __P((
struct  ifnet  * int , caddr_t));
    
int     ( * if_reset)    
        __P((
int ));         /*  复位接口设备  */
    
int     ( * if_watchdog)         /*  周期性监控接口  */
        __P((
int ));
        
/*  输出队列  */
    
struct     ifqueue {
        
struct     mbuf  * ifq_head;  /*  指向队列的第一个分组  */
        
struct     mbuf  * ifq_tail;  /*  指向队列最后一个分组  */
        
int     ifq_len;         /*  当前队列中分组的数目  */
        
int     ifq_maxlen;      /*  是队列中允许的缓存最大个数  */
        
int     ifq_drops;       /*  因为队列满而丢弃的分组数  */
    } if_snd;            
};

我们要看的下一个结构是接口地址结构,ifaddr。每个接口维护一个ifaddr结构的链表,因为一些数据链路,如以太网,支持多于一个的协议。一个单独的ifaddr结构描述每个分配给接口的地址,通常每个协议一个地址。支持多地址的另一个原因是很多协议,包括TCP/IP,支持为单个物理接口指派多个地址。

结构ifaddr通过ifa_next把分配给一个接口的所有地址链接起来,它还包括一个指回接口的ifnet结构的指针ifa_ifp。下图显示了结构ifnet与ifaddr之间的关系:

struct  sockaddr {
    u_char    sa_len;            
/*  sockaddr的长度  */
    u_char    sa_family;        
/*  地址族,如AF_INET  */
    
char     sa_data[ 14 ];         /*  具体地址数组  */
};

struct  ifaddr {
    
struct     sockaddr  * ifa_addr;     /*  指向接口的一个协议地址  */
    
struct     sockaddr  * ifa_dstaddr;     /*  指向一个点对点链路上的另一端的接口协议地址或指向一个广播网中分配给接口的广播地址(如以太网)  */
#define     ifa_broadaddr    ifa_dstaddr    
    
struct     sockaddr  * ifa_netmask;     /*  指向一个位掩码,地址中表示网络部分的比特在掩码中被设置为1,地址中表示主机的部分被设置为0  */
    
struct     ifnet  * ifa_ifp;         /*  指回接口的ifnet结构的指针  */
    
struct     ifaddr  * ifa_next;     /*  接口的下一个地址  */
    
void     ( * ifa_rtrequest)();     /*  支持接口的路由查找  */
    u_short    ifa_flags;        
/*  支持接口的路由查找  */
    
short     ifa_refcnt;         /*  统计对结构ifaddr的引用  */
    
int     ifa_metric;         /*  支持接口的路由查找  */
#ifdef notdef
    
struct     rtentry  * ifa_rt;    
#endif
};

 

ifnet结构

你可能感兴趣的:(《TCP/IP详解,卷2:实现》读书笔记-接口分析)