BSD接口層關鍵數據結構

struct ifnet {

    void    *if_softc;        /* pointer to driver state 指向設備驅動控制體*/

    char    *if_name;        /* name, e.g. ``en'' or ``lo'' */

    TAILQ_ENTRY(ifnet) if_link;     /* all struct ifnets are chained 構建一個接口鏈表*/

    struct    ifaddrhead if_addrhead;    /* linked list of addresses per if 接口的ifaddr地址鏈表*/

        char    if_xname[IFNAMSIZ];     /* external name (name + unit) */

        int    if_pcount;        /* number of promiscuous listeners 用於分組過濾器*/

    struct    bpf_if *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 以秒爲單位記錄時間,直到內核爲此接口調用函數 i f _ w a t c h d o g爲止。*/

    short    if_flags;        /* up/down, broadcast, etc. 接口狀態標識*/

    int    if_ipending;        /* interrupts pending */

    void    *if_linkmib;        /* link-type-specific MIB data */

    size_t    if_linkmiblen;        /* length of above data */

    struct    if_data if_data;

#define    if_mtu        if_data.ifi_mtu   //是接口傳輸單元的最大值

#define    if_type        if_data.ifi_type  //指明接口支持的硬件地址類型

#define if_physical    if_data.ifi_physical

#define    if_addrlen    if_data.ifi_addrlen//是數據鏈路地址的長度

#define    if_hdrlen    if_data.ifi_hdrlen//是由硬件附加給任何分組的首部的長度

#define    if_metric    if_data.ifi_metric//通常爲0

#define    if_baudrate    if_data.ifi_baudrate//指定接口的傳輸速率,只有S L I P接口才設置它

#define    if_hwassist    if_data.ifi_hwassist

#define    if_ipackets    if_data.ifi_ipackets//以下是snmp統計信息

#define    if_ierrors    if_data.ifi_ierrors

#define    if_opackets    if_data.ifi_opackets

#define    if_oerrors    if_data.ifi_oerrors

#define    if_collisions    if_data.ifi_collisions

#define    if_ibytes    if_data.ifi_ibytes

#define    if_obytes    if_data.ifi_obytes

#define    if_imcasts    if_data.ifi_imcasts

#define    if_omcasts    if_data.ifi_omcasts

#define    if_iqdrops    if_data.ifi_iqdrops

#define    if_noproto    if_data.ifi_noproto

#define    if_lastchange    if_data.ifi_lastchange

#define if_recvquota    if_data.ifi_recvquota

#define    if_xmitquota    if_data.ifi_xmitquota

    struct    ifmultihead if_multiaddrs; /* multicast addresses configured 接口多播地址表*/

    int    if_amcount;        /* number of all-multicast requests */

/* procedure handles

包含指向標準接口層函數的指針,它們把設備專用的細節從網絡層分離出來。每個網絡接口實現這些適用於特定設備的函數

*/

    int    (*if_output)        /* output routine (enqueue)對要傳輸的輸出分組進行排隊 */

        __P((struct ifnet *, struct mbuf *, struct sockaddr *,

             struct rtentry *));

    void    (*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 處理I / O控制命令*/

        __P((struct ifnet *, u_long, caddr_t));

    void    (*if_watchdog)        /* timer routine 週期性接口例程*/

        __P((struct ifnet *));

    int    (*if_poll_recv)        /* polled receive routine */

        __P((struct ifnet *, int *));

    int    (*if_poll_xmit)        /* polled transmit routine */

        __P((struct ifnet *, int *));

    void    (*if_poll_intren)    /* polled interrupt reenable routine */

        __P((struct ifnet *));

    void    (*if_poll_slowinput)    /* input routine for slow devices */

        __P((struct ifnet *, struct mbuf *));

    void    (*if_init)        /* Init routine 初始化接口*/

        __P((void *));

    int    (*if_resolvemulti)    /* validate/resolve multicast */

        __P((struct ifnet *, struct sockaddr **, struct sockaddr *));

    struct    ifqueue if_snd;        /* output queue 接口輸出隊列*/

    struct    ifqueue *if_poll_slowq;    /* input queue for slow devices */

    struct    ifprefixhead if_prefixhead; /* list of prefixes per if */

};

image

   

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 位掩碼,它用於選擇i f a _ a d d r中的網絡部分*/

    struct    if_data if_data;    /* not all members are meaningful */

    struct    ifnet *ifa_ifp;        /* back-pointer to interface */

    TAILQ_ENTRY(ifaddr) ifa_link;    /* queue macro glue */

    void    (*ifa_rtrequest)    /* check or clean routes (+ or -)'d */

        __P((int, struct rtentry *, struct sockaddr *));

    u_short    ifa_flags;        /* mostly rt_flags for cloning */

    u_int    ifa_refcnt;        /* references to this structure */

    int    ifa_metric;        /* cost of going out this interface */

#ifdef notdef

    struct    rtentry *ifa_rt;    /* XXXX for ROUTETOIF ????? */

#endif

    int (*ifa_claim_addr)        /* check if an addr goes to this if */

        __P((struct ifaddr *, struct sockaddr *));

};

 

一個接口的編址信息不僅僅只包括一個主機地址。 N e t / 3在通用的s o c k a d d r結構中維護
主機地址、廣播地址和網絡掩碼。通過使用一個通用的結構,將硬件與協議專用的地址細節
相對於接口層隱藏起來

struct sockaddr {
    u_char        sa_len;        /* total length */
    sa_family_t    sa_family;    /* address family */
    char        sa_data[30];    /* actually longer; address value */
};

每個協議定義一個專用的s o c k a d d r結構,該結構
複製成員s a _ l e n和s a _ f a m i l y,但按那個協議的要
求來定義成員s a _ d a t a。

 

/*以太鏈路層地址存儲結構*/

struct sockaddr_dl {
    u_char    sdl_len;    /* Total length of sockaddr */
    u_char    sdl_family;    /* AF_LINK */
    u_short    sdl_index;    /* if != 0, system given index for interface */
    u_char    sdl_type;    /* interface type */
    u_char    sdl_nlen;    /* interface name length, no trailing 0 reqd. */
    u_char    sdl_alen;    /* link level address length */
    u_char    sdl_slen;    /* link layer selector length */
    char    sdl_data[12];    /* minimum work area, can be larger;
                   contains both if name and ll address */
    u_short    sdl_rcf;    /* source routing control */
    u_short    sdl_route[16];    /* source routing information */
};

#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))

 

結構i f n e t和i f a d d r包含適用於所有網絡接口和協議地址的通用信息。爲了容納其他設
備和協議專用信息,每個設備定義了並且每個協議分配了一個專用化版本的 i f n e t和i f a d d r
結構。這些專用化的結構總是包含一個 i f n e t或i f a d d r結構作爲它們的第一個成員,這樣
無須考慮其他專用信息就能訪問這些公共信息。

image

struct    arpcom {
    /*
     * The ifnet struct _must_ be at the head of this structure.
     */
    struct     ifnet ac_if;        /* network-visible interface */
    u_char    ac_enaddr[6];        /* ethernet hardware address */
    int    ac_multicnt;        /* length of ac_multiaddrs list */
    void    *ac_netgraph;        /* ng_ether(4) netgraph node info */
};

/*
 * Ethernet status, per interface.
 */
struct le_softc {
    struct arpcom le_ac;		/* Common Ethernet/ARP Structure */
#define le_if le_ac.ac_if
#define le_if le_ac.ac_enaddr
/*以下定義接口私有信息*/
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章