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
/*以下定义接口私有信息*/
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章