/* * $Id: getlladdr.c,v 1.1.1.1 2003/06/25 10:52:55 fjoe Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include void getlladdr(const char *if_name) { static int initialized = 0; static size_t needed; static char *buf; int found = 0; char *lim, *next; if (!initialized) { int mib[6]; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; /* address family */ mib[4] = NET_RT_IFLIST; mib[5] = 0; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) errx(1, "iflist-sysctl-estimate"); if ((buf = malloc(needed)) == NULL) errx(1, "malloc"); if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) errx(1, "actual retrieval of interface table"); initialized = 1; } lim = buf + needed; next = buf; while (next < lim) { struct sockaddr_dl *sdl; struct if_msghdr *ifm; ifm = (struct if_msghdr *)next; if (ifm->ifm_type == RTM_IFINFO) sdl = (struct sockaddr_dl *)(ifm + 1); else { fprintf(stderr, "out of sync parsing NET_RT_IFLIST\n"); fprintf(stderr, "expected %d, got %d\n", RTM_IFINFO, ifm->ifm_type); fprintf(stderr, "msglen = %d\n", ifm->ifm_msglen); fprintf(stderr, "buf:%p, next:%p, lim:%p\n", buf, next, lim); exit (1); } next += ifm->ifm_msglen; if (if_name == NULL || !strncmp(sdl->sdl_data, if_name, sdl->sdl_nlen)) { if (sdl->sdl_alen > 0) { int i; printf("%.*s: ", sdl->sdl_nlen, sdl->sdl_data); for (i = 0; i < sdl->sdl_alen; i++) { if (i > 0) putchar(':'); printf("%02x", (u_int8_t) sdl->sdl_data[sdl->sdl_nlen + i]); } putchar('\n'); } else { printf("%.*s: \n", sdl->sdl_nlen, sdl->sdl_data); } if (if_name != NULL) { found = 1; break; } } } if (if_name != NULL && !found) printf("%s: not found\n", if_name); } int main(int argc, char *argv[]) { if (argc < 2) getlladdr(NULL); for (argv++; *argv; argv++) getlladdr(*argv); return 0; }