123173Smckusick /* 229135Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 332787Sbostic * All rights reserved. 423173Smckusick * 544472Sbostic * %sccs.include.redist.c% 632787Sbostic * 7*54716Ssklower * @(#)if_ether.h 7.8 (Berkeley) 07/06/92 823173Smckusick */ 99744Ssam 109744Ssam /* 119744Ssam * Structure of a 10Mb/s Ethernet header. 129744Ssam */ 139746Ssam struct ether_header { 1418641Skarels u_char ether_dhost[6]; 1518641Skarels u_char ether_shost[6]; 169746Ssam u_short ether_type; 179744Ssam }; 189744Ssam 19*54716Ssklower #define ETHERTYPE_PUP 0x0200 /* PUP protocol */ 20*54716Ssklower #define ETHERTYPE_IP 0x0800 /* IP protocol */ 21*54716Ssklower #define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ 22*54716Ssklower #define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ 239744Ssam 249744Ssam /* 2518641Skarels * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have 2625891Skarels * (type-ETHERTYPE_TRAIL)*512 bytes of data followed 2725891Skarels * by an ETHER type (as given above) and then the (variable-length) header. 289744Ssam */ 2918641Skarels #define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */ 3018641Skarels #define ETHERTYPE_NTRAILER 16 319746Ssam 329746Ssam #define ETHERMTU 1500 339746Ssam #define ETHERMIN (60-14) 3411573Ssam 35*54716Ssklower #ifdef KERNEL 3611573Ssam /* 37*54716Ssklower * Macro to map an IP multicast address to an Ethernet multicast address. 38*54716Ssklower * The high-order 25 bits of the Ethernet address are statically assigned, 39*54716Ssklower * and the low-order 23 bits are taken from the low end of the IP address. 40*54716Ssklower */ 41*54716Ssklower #define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \ 42*54716Ssklower /* struct in_addr *ipaddr; */ \ 43*54716Ssklower /* u_char enaddr[6]; */ \ 44*54716Ssklower { \ 45*54716Ssklower (enaddr)[0] = 0x01; \ 46*54716Ssklower (enaddr)[1] = 0x00; \ 47*54716Ssklower (enaddr)[2] = 0x5e; \ 48*54716Ssklower (enaddr)[3] = ((u_char *)ipaddr)[1] & 0x7f; \ 49*54716Ssklower (enaddr)[4] = ((u_char *)ipaddr)[2]; \ 50*54716Ssklower (enaddr)[5] = ((u_char *)ipaddr)[3]; \ 51*54716Ssklower } 52*54716Ssklower #endif 53*54716Ssklower 54*54716Ssklower /* 5511573Ssam * Ethernet Address Resolution Protocol. 5611573Ssam * 5711573Ssam * See RFC 826 for protocol description. Structure below is adapted 5811573Ssam * to resolving internet addresses. Field names used correspond to 5911573Ssam * RFC 826. 6011573Ssam */ 6111573Ssam struct ether_arp { 6225891Skarels struct arphdr ea_hdr; /* fixed-size header */ 6318641Skarels u_char arp_sha[6]; /* sender hardware address */ 6418641Skarels u_char arp_spa[4]; /* sender protocol address */ 6518641Skarels u_char arp_tha[6]; /* target hardware address */ 6618641Skarels u_char arp_tpa[4]; /* target protocol address */ 6711573Ssam }; 6825891Skarels #define arp_hrd ea_hdr.ar_hrd 6925891Skarels #define arp_pro ea_hdr.ar_pro 7025891Skarels #define arp_hln ea_hdr.ar_hln 7125891Skarels #define arp_pln ea_hdr.ar_pln 7225891Skarels #define arp_op ea_hdr.ar_op 7311573Ssam 7425891Skarels 7511573Ssam /* 7611573Ssam * Structure shared between the ethernet driver modules and 7711573Ssam * the address resolution code. For example, each ec_softc or il_softc 7811573Ssam * begins with this structure. 7911573Ssam */ 8011573Ssam struct arpcom { 8118641Skarels struct ifnet ac_if; /* network-visible interface */ 8218641Skarels u_char ac_enaddr[6]; /* ethernet hardware address */ 83*54716Ssklower struct in_addr ac_ipaddr; /* copy of ip address- XXX */ 84*54716Ssklower struct ether_multi *ac_multiaddrs; /* list of ether multicast addrs */ 85*54716Ssklower int ac_multicnt; /* length of ac_multiaddrs list */ 8611573Ssam }; 8711573Ssam 8816211Skarels /* 8916211Skarels * Internet to ethernet address resolution table. 9016211Skarels */ 9116211Skarels struct arptab { 9216211Skarels struct in_addr at_iaddr; /* internet address */ 9318641Skarels u_char at_enaddr[6]; /* ethernet address */ 9416211Skarels u_char at_timer; /* minutes since last reference */ 9516211Skarels u_char at_flags; /* flags */ 9624804Skarels struct mbuf *at_hold; /* last packet until resolved/timeout */ 97*54716Ssklower }; /* XXX: only used to define SIOCGARP, which is no longer supported */ 9816211Skarels 9950136Ssklower struct llinfo_arp { 10050136Ssklower struct llinfo_arp *la_next; 10150136Ssklower struct llinfo_arp *la_prev; 10250136Ssklower struct rtentry *la_rt; 10350136Ssklower struct mbuf *la_hold; /* last packet until resolved/timeout */ 10450136Ssklower long la_asked; /* last time we QUERIED for this addr */ 10550136Ssklower #define la_timer la_rt->rt_rmx.rmx_expire /* deletion time in seconds */ 10650136Ssklower }; 10750136Ssklower 10850136Ssklower struct sockaddr_inarp { 10950136Ssklower u_char sin_len; 11050136Ssklower u_char sin_family; 11150136Ssklower u_short sin_port; 11250136Ssklower struct in_addr sin_addr; 11350136Ssklower struct in_addr sin_srcaddr; 11450136Ssklower u_short sin_tos; 11550136Ssklower u_short sin_other; 11650136Ssklower #define SIN_PROXY 1 11750136Ssklower }; 118*54716Ssklower /* 119*54716Ssklower * IP and ethernet specific routing flags 120*54716Ssklower */ 121*54716Ssklower #define RTF_USETRAILERS RTF_PROTO1 /* use trailers */ 122*54716Ssklower #define RTF_ANNOUNCE RTF_PROTO2 /* announce new arp entry */ 12350136Ssklower 12412459Ssam #ifdef KERNEL 12536819Skarels u_char etherbroadcastaddr[6]; 126*54716Ssklower #if defined(ISO) && !defined(MULTICAST) 127*54716Ssklower #define MULTICAST 1 128*54716Ssklower #endif 129*54716Ssklower #ifdef MULTICAST 130*54716Ssklower u_char ether_ipmulticast_min[6]; 131*54716Ssklower u_char ether_ipmulticast_max[6]; 132*54716Ssklower #endif 133*54716Ssklower 13452275Storek struct llinfo_arp *arptnew __P((struct in_addr *)); 13550136Ssklower struct llinfo_arp llinfo_arp; /* head of the llinfo queue */ 13652275Storek int ether_output __P((struct ifnet *, struct mbuf *, struct sockaddr *, 13752275Storek struct rtentry *)); 13852275Storek int ether_input __P((struct ifnet *, struct ether_header *, struct mbuf *)); 13952275Storek char *ether_sprintf __P((u_char *)); 140*54716Ssklower void arp_rtrequest __P((int, struct rtentry *, struct sockaddr *)); 14150136Ssklower struct ifqueue arpintrq; 14252275Storek 14352275Storek /* XXX These probably belong elsewhere */ 14452275Storek void in_arpinput __P((struct mbuf *)); 14552275Storek void arpwhohas __P((struct arpcom *, struct in_addr *)); 146*54716Ssklower 147*54716Ssklower #ifdef MULTICAST 148*54716Ssklower /* 149*54716Ssklower * Ethernet multicast address structure. There is one of these for each 150*54716Ssklower * multicast address or range of multicast addresses that we are supposed 151*54716Ssklower * to listen to on a particular interface. They are kept in a linked list, 152*54716Ssklower * rooted in the interface's arpcom structure. (This really has nothing to 153*54716Ssklower * do with ARP, or with the Internet address family, but this appears to be 154*54716Ssklower * the minimally-disrupting place to put it.) 155*54716Ssklower */ 156*54716Ssklower struct ether_multi { 157*54716Ssklower u_char enm_addrlo[6]; /* low or only address of range */ 158*54716Ssklower u_char enm_addrhi[6]; /* high or only address of range */ 159*54716Ssklower struct arpcom *enm_ac; /* back pointer to arpcom */ 160*54716Ssklower u_int enm_refcount; /* no. claims to this addr/range */ 161*54716Ssklower struct ether_multi *enm_next; /* ptr to next ether_multi */ 162*54716Ssklower }; 163*54716Ssklower 164*54716Ssklower #ifdef KERNEL 165*54716Ssklower /* 166*54716Ssklower * Structure used by macros below to remember position when stepping through 167*54716Ssklower * all of the ether_multi records. 168*54716Ssklower */ 169*54716Ssklower struct ether_multistep { 170*54716Ssklower struct ether_multi *e_enm; 171*54716Ssklower }; 172*54716Ssklower 173*54716Ssklower /* 174*54716Ssklower * Macro for looking up the ether_multi record for a given range of Ethernet 175*54716Ssklower * multicast addresses connected to a given arpcom structure. If no matching 176*54716Ssklower * record is found, "enm" returns NULL. 177*54716Ssklower */ 178*54716Ssklower #define ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm) \ 179*54716Ssklower /* u_char addrlo[6]; */ \ 180*54716Ssklower /* u_char addrhi[6]; */ \ 181*54716Ssklower /* struct arpcom *ac; */ \ 182*54716Ssklower /* struct ether_multi *enm; */ \ 183*54716Ssklower { \ 184*54716Ssklower for ((enm) = (ac)->ac_multiaddrs; \ 185*54716Ssklower (enm) != NULL && \ 186*54716Ssklower (bcmp((enm)->enm_addrlo, (addrlo), 6) != 0 || \ 187*54716Ssklower bcmp((enm)->enm_addrhi, (addrhi), 6) != 0); \ 188*54716Ssklower (enm) = (enm)->enm_next); \ 189*54716Ssklower } 190*54716Ssklower 191*54716Ssklower /* 192*54716Ssklower * Macro to step through all of the ether_multi records, one at a time. 193*54716Ssklower * The current position is remembered in "step", which the caller must 194*54716Ssklower * provide. ETHER_FIRST_MULTI(), below, must be called to initialize "step" 195*54716Ssklower * and get the first record. Both macros return a NULL "enm" when there 196*54716Ssklower * are no remaining records. 197*54716Ssklower */ 198*54716Ssklower #define ETHER_NEXT_MULTI(step, enm) \ 199*54716Ssklower /* struct ether_multistep step; */ \ 200*54716Ssklower /* struct ether_multi *enm; */ \ 201*54716Ssklower { \ 202*54716Ssklower if (((enm) = (step).e_enm) != NULL) \ 203*54716Ssklower (step).e_enm = (enm)->enm_next; \ 204*54716Ssklower } 205*54716Ssklower 206*54716Ssklower #define ETHER_FIRST_MULTI(step, ac, enm) \ 207*54716Ssklower /* struct ether_multistep step; */ \ 208*54716Ssklower /* struct arpcom *ac; */ \ 209*54716Ssklower /* struct ether_multi *enm; */ \ 210*54716Ssklower { \ 211*54716Ssklower (step).e_enm = (ac)->ac_multiaddrs; \ 212*54716Ssklower ETHER_NEXT_MULTI((step), (enm)); \ 213*54716Ssklower } 21411573Ssam #endif 215*54716Ssklower #endif 216*54716Ssklower #endif 217