+ short if_flags; /* up/down, broadcast, etc. */
+ short if_timer; /* time 'til if_watchdog called */
+ int if_metric; /* routing metric (external only) */
+ struct ifaddr *if_addrlist; /* linked list of addresses per if */
+ struct ifqueue {
+ struct mbuf *ifq_head;
+ struct mbuf *ifq_tail;
+ int ifq_len;
+ int ifq_maxlen;
+ int ifq_drops;
+ } if_snd; /* output queue */
+/* procedure handles */
+ int (*if_init)(); /* init routine */
+ int (*if_output)(); /* output routine */
+ int (*if_ioctl)(); /* ioctl routine */
+ int (*if_reset)(); /* bus reset routine */
+ int (*if_watchdog)(); /* timer routine */
+/* generic interface statistics */
+ int if_ipackets; /* packets received on interface */
+ int if_ierrors; /* input errors on interface */
+ int if_opackets; /* packets sent on interface */
+ int if_oerrors; /* output errors on interface */
+ int if_collisions; /* collisions on csma interfaces */
+/* end statistics */
+ struct ifnet *if_next;
+};
+
+#define IFF_UP 0x1 /* interface is up */
+#define IFF_BROADCAST 0x2 /* broadcast address valid */
+#define IFF_DEBUG 0x4 /* turn on debugging */
+#define IFF_LOOPBACK 0x8 /* is a loopback net */
+#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
+#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
+#define IFF_RUNNING 0x40 /* resources allocated */
+#define IFF_NOARP 0x80 /* no address resolution protocol */
+/* next two not supported now, but reserved: */
+#define IFF_PROMISC 0x100 /* receive all packets */
+#define IFF_ALLMULTI 0x200 /* receive all multicast packets */
+/* flags set internally only: */
+#define IFF_CANTCHANGE (IFF_BROADCAST | IFF_POINTOPOINT | IFF_RUNNING)
+
+/*
+ * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
+ * input routines have queues of messages stored on ifqueue structures
+ * (defined above). Entries are added to and deleted from these structures
+ * by these macros, which should be called with ipl raised to splimp().
+ */
+#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
+#define IF_DROP(ifq) ((ifq)->ifq_drops++)
+#define IF_ENQUEUE(ifq, m) { \
+ (m)->m_act = 0; \
+ if ((ifq)->ifq_tail == 0) \
+ (ifq)->ifq_head = m; \
+ else \
+ (ifq)->ifq_tail->m_act = m; \
+ (ifq)->ifq_tail = m; \
+ (ifq)->ifq_len++; \
+}
+#define IF_PREPEND(ifq, m) { \
+ (m)->m_act = (ifq)->ifq_head; \
+ if ((ifq)->ifq_tail == 0) \
+ (ifq)->ifq_tail = (m); \
+ (ifq)->ifq_head = (m); \
+ (ifq)->ifq_len++; \
+}
+/*
+ * Packets destined for level-1 protocol input routines
+ * have a pointer to the receiving interface prepended to the data.
+ * IF_DEQUEUEIF extracts and returns this pointer when dequeueing the packet.
+ * IF_ADJ should be used otherwise to adjust for its presence.
+ */
+#define IF_ADJ(m) { \
+ (m)->m_off += sizeof(struct ifnet *); \
+ (m)->m_len -= sizeof(struct ifnet *); \
+ if ((m)->m_len == 0) { \
+ struct mbuf *n; \
+ MFREE((m), n); \
+ (m) = n; \
+ } \
+}
+#define IF_DEQUEUEIF(ifq, m, ifp) { \
+ (m) = (ifq)->ifq_head; \
+ if (m) { \
+ if (((ifq)->ifq_head = (m)->m_act) == 0) \
+ (ifq)->ifq_tail = 0; \
+ (m)->m_act = 0; \
+ (ifq)->ifq_len--; \
+ (ifp) = *(mtod((m), struct ifnet **)); \
+ IF_ADJ(m); \
+ } \
+}
+#define IF_DEQUEUE(ifq, m) { \
+ (m) = (ifq)->ifq_head; \
+ if (m) { \
+ if (((ifq)->ifq_head = (m)->m_act) == 0) \
+ (ifq)->ifq_tail = 0; \
+ (m)->m_act = 0; \
+ (ifq)->ifq_len--; \
+ } \
+}
+
+#define IFQ_MAXLEN 50
+#define IFNET_SLOWHZ 1 /* granularity is 1 second */
+
+/*
+ * The ifaddr structure contains information about one address
+ * of an interface. They are maintained by the different address families,
+ * are allocated and attached when an address is set, and are linked
+ * together so all addresses for an interface can be located.
+ */
+struct ifaddr {
+ struct sockaddr ifa_addr; /* address of interface */
+ union {
+ struct sockaddr ifu_broadaddr;
+ struct sockaddr ifu_dstaddr;
+ } ifa_ifu;
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr /* broadcast address */
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr /* other end of p-to-p link */
+ struct ifnet *ifa_ifp; /* back-pointer to interface */
+ struct ifaddr *ifa_next; /* next address for interface */