1 void
2 ether_ifattach(ifp)
3 register struct ifnet *ifp;
4 {
5 register struct ifaddr *ifa;
6 register struct sockaddr_dl *sdl;
7
8 ifp->if_type = IFT_ETHER;
9 ifp->if_addrlen = 6;
10 ifp->if_hdrlen = 14;
11 ifp->if_mtu = ETHERMTU;
12 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
13 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
14 sdl->sdl_family == AF_LINK) {
15 sdl->sdl_type = IFT_ETHER;
16 sdl->sdl_alen = ifp->if_addrlen;
17 bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
18 LLADDR(sdl), ifp->if_addrlen);
19 break;
20 }
21 }
//开始前要先解释一下LLADDR()宏。下面是它的源代码。
#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
1. ((s)->sdl_data + (s)->sdl_nlen):取得sockaddr_dl结构的sdl_data[12]的首地址,然后加上nlen从而指针指向以链路层地址(这里假设是以太网地址)。所以现在这个地址是以太网地址在sdl_data[12]数组的起始地址。
2.(caddr_t)这个前面说过是核心地址,一般是char*。所以这是把 1 中的地址转型为char*然后可以被bcopy作为目的地址使用。