1af57ed9fSAtsushi Murai /* 2af57ed9fSAtsushi Murai * PPP Routing related Module 3af57ed9fSAtsushi Murai * 4af57ed9fSAtsushi Murai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5af57ed9fSAtsushi Murai * 6af57ed9fSAtsushi Murai * Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd. 7af57ed9fSAtsushi Murai * 8af57ed9fSAtsushi Murai * Redistribution and use in source and binary forms are permitted 9af57ed9fSAtsushi Murai * provided that the above copyright notice and this paragraph are 10af57ed9fSAtsushi Murai * duplicated in all such forms and that any documentation, 11af57ed9fSAtsushi Murai * advertising materials, and other materials related to such 12af57ed9fSAtsushi Murai * distribution and use acknowledge that the software was developed 13af57ed9fSAtsushi Murai * by the Internet Initiative Japan, Inc. The name of the 14af57ed9fSAtsushi Murai * IIJ may not be used to endorse or promote products derived 15af57ed9fSAtsushi Murai * from this software without specific prior written permission. 16af57ed9fSAtsushi Murai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17af57ed9fSAtsushi Murai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18af57ed9fSAtsushi Murai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19af57ed9fSAtsushi Murai * 20215a4696SAtsushi Murai * $Id: route.c,v 1.3 1995/05/30 03:50:56 rgrimes Exp $ 2153c9f6c0SAtsushi Murai * 22af57ed9fSAtsushi Murai */ 23af57ed9fSAtsushi Murai #include <sys/types.h> 24af57ed9fSAtsushi Murai #include <machine/endian.h> 25af57ed9fSAtsushi Murai #include <sys/param.h> 26af57ed9fSAtsushi Murai #include <sys/socket.h> 27af57ed9fSAtsushi Murai #include <net/route.h> 28af57ed9fSAtsushi Murai #include <sys/ioctl.h> 29af57ed9fSAtsushi Murai #include <net/if.h> 30af57ed9fSAtsushi Murai #include <errno.h> 31af57ed9fSAtsushi Murai #include <netinet/in_systm.h> 32af57ed9fSAtsushi Murai #include <netinet/in.h> 33af57ed9fSAtsushi Murai #include <arpa/inet.h> 3453c9f6c0SAtsushi Murai #if (BSD >= 199306) 35af57ed9fSAtsushi Murai #include <sys/sysctl.h> 36af57ed9fSAtsushi Murai #else 37af57ed9fSAtsushi Murai #include <sys/kinfo.h> 38af57ed9fSAtsushi Murai #endif 39af57ed9fSAtsushi Murai #include <stdlib.h> 40af57ed9fSAtsushi Murai #include <stdio.h> 41af57ed9fSAtsushi Murai #include <string.h> 42af57ed9fSAtsushi Murai #include <unistd.h> 43215a4696SAtsushi Murai #include "log.h" 44af57ed9fSAtsushi Murai 45af57ed9fSAtsushi Murai static int IfIndex; 46af57ed9fSAtsushi Murai 47af57ed9fSAtsushi Murai struct rtmsg { 48af57ed9fSAtsushi Murai struct rt_msghdr m_rtm; 49af57ed9fSAtsushi Murai char m_space[64]; 50af57ed9fSAtsushi Murai }; 51af57ed9fSAtsushi Murai 52af57ed9fSAtsushi Murai static int seqno; 53af57ed9fSAtsushi Murai 54af57ed9fSAtsushi Murai void 55af57ed9fSAtsushi Murai OsSetRoute(cmd, dst, gateway, mask) 56af57ed9fSAtsushi Murai int cmd; 57af57ed9fSAtsushi Murai struct in_addr dst; 58af57ed9fSAtsushi Murai struct in_addr gateway; 59af57ed9fSAtsushi Murai struct in_addr mask; 60af57ed9fSAtsushi Murai { 61af57ed9fSAtsushi Murai struct rtmsg rtmes; 62af57ed9fSAtsushi Murai int s, nb, wb; 63af57ed9fSAtsushi Murai char *cp; 64af57ed9fSAtsushi Murai u_long *lp; 65af57ed9fSAtsushi Murai struct sockaddr_in rtdata; 66af57ed9fSAtsushi Murai 67af57ed9fSAtsushi Murai s = socket(PF_ROUTE, SOCK_RAW, 0); 68af57ed9fSAtsushi Murai if (s < 0) 69af57ed9fSAtsushi Murai logprintf("socket\n"); 70af57ed9fSAtsushi Murai 71af57ed9fSAtsushi Murai bzero(&rtmes, sizeof(rtmes)); 72af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_version = RTM_VERSION; 73af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_type = cmd; 74af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_addrs = RTA_DST | RTA_NETMASK; 75af57ed9fSAtsushi Murai if (cmd == RTM_ADD) rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY; 76af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_seq = ++seqno; 77af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_pid = getpid(); 78af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY; 79af57ed9fSAtsushi Murai 80af57ed9fSAtsushi Murai bzero(&rtdata, sizeof(rtdata)); 81af57ed9fSAtsushi Murai rtdata.sin_len = 16; 82af57ed9fSAtsushi Murai rtdata.sin_family = AF_INET; 83af57ed9fSAtsushi Murai rtdata.sin_port = 0; 84af57ed9fSAtsushi Murai rtdata.sin_addr = dst; 85af57ed9fSAtsushi Murai 86af57ed9fSAtsushi Murai cp = rtmes.m_space; 87af57ed9fSAtsushi Murai bcopy(&rtdata, cp, 16); 88af57ed9fSAtsushi Murai cp += 16; 89af57ed9fSAtsushi Murai if (gateway.s_addr) { 90af57ed9fSAtsushi Murai rtdata.sin_addr = gateway; 91af57ed9fSAtsushi Murai bcopy(&rtdata, cp, 16); 92af57ed9fSAtsushi Murai cp += 16; 93af57ed9fSAtsushi Murai } 94af57ed9fSAtsushi Murai 95af57ed9fSAtsushi Murai if (dst.s_addr == INADDR_ANY) 96af57ed9fSAtsushi Murai mask.s_addr = INADDR_ANY; 97af57ed9fSAtsushi Murai 98af57ed9fSAtsushi Murai lp = (u_long *)cp; 99af57ed9fSAtsushi Murai 100af57ed9fSAtsushi Murai if (mask.s_addr) { 101af57ed9fSAtsushi Murai *lp++ = 8; 102af57ed9fSAtsushi Murai cp += sizeof(int); 103af57ed9fSAtsushi Murai *lp = mask.s_addr; 104af57ed9fSAtsushi Murai } else 105af57ed9fSAtsushi Murai *lp = 0; 106af57ed9fSAtsushi Murai cp += sizeof(u_long); 107af57ed9fSAtsushi Murai 108af57ed9fSAtsushi Murai nb = cp - (char *)&rtmes; 109af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_msglen = nb; 110af57ed9fSAtsushi Murai wb = write(s, &rtmes, nb); 111af57ed9fSAtsushi Murai if (wb < 0) { 112215a4696SAtsushi Murai LogPrintf(LOG_TCPIP, "Already set route addr dst=%x, gateway=%x\n" 113215a4696SAtsushi Murai ,dst.s_addr, gateway.s_addr); 114af57ed9fSAtsushi Murai } 115af57ed9fSAtsushi Murai #ifdef DEBUG 116af57ed9fSAtsushi Murai logprintf("wrote %d: dst = %x, gateway = %x\n", nb, dst.s_addr, gateway.s_addr); 117af57ed9fSAtsushi Murai #endif 118af57ed9fSAtsushi Murai close(s); 119af57ed9fSAtsushi Murai } 120af57ed9fSAtsushi Murai 121af57ed9fSAtsushi Murai static void 122af57ed9fSAtsushi Murai p_sockaddr(sa, width) 123af57ed9fSAtsushi Murai struct sockaddr *sa; 124af57ed9fSAtsushi Murai int width; 125af57ed9fSAtsushi Murai { 126af57ed9fSAtsushi Murai register char *cp; 127af57ed9fSAtsushi Murai register struct sockaddr_in *sin = (struct sockaddr_in *)sa; 128af57ed9fSAtsushi Murai 129af57ed9fSAtsushi Murai cp = (sin->sin_addr.s_addr == 0) ? "default" : 130af57ed9fSAtsushi Murai inet_ntoa(sin->sin_addr); 131af57ed9fSAtsushi Murai printf("%-*.*s ", width, width, cp); 132af57ed9fSAtsushi Murai } 133af57ed9fSAtsushi Murai 134af57ed9fSAtsushi Murai struct bits { 135af57ed9fSAtsushi Murai short b_mask; 136af57ed9fSAtsushi Murai char b_val; 137af57ed9fSAtsushi Murai } bits[] = { 138af57ed9fSAtsushi Murai { RTF_UP, 'U' }, 139af57ed9fSAtsushi Murai { RTF_GATEWAY, 'G' }, 140af57ed9fSAtsushi Murai { RTF_HOST, 'H' }, 141af57ed9fSAtsushi Murai { RTF_DYNAMIC, 'D' }, 142af57ed9fSAtsushi Murai { RTF_MODIFIED, 'M' }, 143af57ed9fSAtsushi Murai { RTF_CLONING, 'C' }, 144af57ed9fSAtsushi Murai { RTF_XRESOLVE, 'X' }, 145af57ed9fSAtsushi Murai { RTF_LLINFO, 'L' }, 146af57ed9fSAtsushi Murai { RTF_REJECT, 'R' }, 147af57ed9fSAtsushi Murai { 0 } 148af57ed9fSAtsushi Murai }; 149af57ed9fSAtsushi Murai 150af57ed9fSAtsushi Murai static void 151af57ed9fSAtsushi Murai p_flags(f, format) 152af57ed9fSAtsushi Murai register int f; 153af57ed9fSAtsushi Murai char *format; 154af57ed9fSAtsushi Murai { 155af57ed9fSAtsushi Murai char name[33], *flags; 156af57ed9fSAtsushi Murai register struct bits *p = bits; 157af57ed9fSAtsushi Murai 158af57ed9fSAtsushi Murai for (flags = name; p->b_mask; p++) 159af57ed9fSAtsushi Murai if (p->b_mask & f) 160af57ed9fSAtsushi Murai *flags++ = p->b_val; 161af57ed9fSAtsushi Murai *flags = '\0'; 162af57ed9fSAtsushi Murai printf(format, name); 163af57ed9fSAtsushi Murai } 164af57ed9fSAtsushi Murai 165af57ed9fSAtsushi Murai int 166af57ed9fSAtsushi Murai ShowRoute() 167af57ed9fSAtsushi Murai { 168af57ed9fSAtsushi Murai struct rt_msghdr *rtm; 169af57ed9fSAtsushi Murai struct sockaddr *sa; 170af57ed9fSAtsushi Murai char *sp, *ep, *cp; 171af57ed9fSAtsushi Murai u_char *wp; 172af57ed9fSAtsushi Murai int *lp; 173af57ed9fSAtsushi Murai int needed, nb; 174af57ed9fSAtsushi Murai u_long mask; 17553c9f6c0SAtsushi Murai #if (BSD >= 199306) 176af57ed9fSAtsushi Murai int mib[6]; 177af57ed9fSAtsushi Murai #endif 178af57ed9fSAtsushi Murai 17953c9f6c0SAtsushi Murai #if (BSD >= 199306) 180af57ed9fSAtsushi Murai mib[0] = CTL_NET; 181af57ed9fSAtsushi Murai mib[1] = PF_ROUTE; 18253c9f6c0SAtsushi Murai mib[2] = 0; 18353c9f6c0SAtsushi Murai mib[3] = 0; 184af57ed9fSAtsushi Murai mib[4] = NET_RT_DUMP; 18553c9f6c0SAtsushi Murai mib[5] = 0; 18653c9f6c0SAtsushi Murai if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { 18753c9f6c0SAtsushi Murai perror("sysctl-estimate"); 18853c9f6c0SAtsushi Murai return(1); 18953c9f6c0SAtsushi Murai } 190af57ed9fSAtsushi Murai #else 191af57ed9fSAtsushi Murai needed = getkerninfo(KINFO_RT_DUMP, 0, 0, 0); 192af57ed9fSAtsushi Murai #endif 193af57ed9fSAtsushi Murai if (needed < 0) 194af57ed9fSAtsushi Murai return(1); 195af57ed9fSAtsushi Murai sp = malloc(needed); 196af57ed9fSAtsushi Murai if (sp == NULL) 197af57ed9fSAtsushi Murai return(1); 19853c9f6c0SAtsushi Murai #if (BSD >= 199306) 19953c9f6c0SAtsushi Murai if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) { 20053c9f6c0SAtsushi Murai perror("sysctl-getroute"); 201af57ed9fSAtsushi Murai return(1); 20253c9f6c0SAtsushi Murai } 203af57ed9fSAtsushi Murai #else 204af57ed9fSAtsushi Murai if (getkerninfo(KINFO_RT_DUMP, sp, &needed, 0) < 0) 205af57ed9fSAtsushi Murai return(1); 206af57ed9fSAtsushi Murai #endif 207af57ed9fSAtsushi Murai ep = sp + needed; 208af57ed9fSAtsushi Murai 209af57ed9fSAtsushi Murai for (cp = sp; cp < ep; cp += rtm->rtm_msglen) { 210af57ed9fSAtsushi Murai rtm = (struct rt_msghdr *)cp; 211af57ed9fSAtsushi Murai sa = (struct sockaddr *)(rtm + 1); 212af57ed9fSAtsushi Murai mask = 0xffffffff; 213af57ed9fSAtsushi Murai if (rtm->rtm_addrs == RTA_DST) 214af57ed9fSAtsushi Murai p_sockaddr(sa, 36); 215af57ed9fSAtsushi Murai else { 216af57ed9fSAtsushi Murai wp = (u_char *)cp + rtm->rtm_msglen; 217af57ed9fSAtsushi Murai p_sockaddr(sa, 16); 218af57ed9fSAtsushi Murai if (sa->sa_len == 0) 219af57ed9fSAtsushi Murai sa->sa_len = sizeof(long); 220af57ed9fSAtsushi Murai sa = (struct sockaddr *)(sa->sa_len + (char *)sa); 221af57ed9fSAtsushi Murai p_sockaddr(sa, 18); 222af57ed9fSAtsushi Murai lp = (int *)(sa->sa_len + (char *)sa); 223af57ed9fSAtsushi Murai if ((char *)lp < (char *)wp && *lp) { 224af57ed9fSAtsushi Murai #ifdef DEBUG 225af57ed9fSAtsushi Murai logprintf(" flag = %x, rest = %d", rtm->rtm_flags, *lp); 226af57ed9fSAtsushi Murai #endif 227af57ed9fSAtsushi Murai wp = (u_char *)(lp + 1); 228af57ed9fSAtsushi Murai mask = 0; 229af57ed9fSAtsushi Murai for (nb = *lp; nb > 4; nb--) { 230af57ed9fSAtsushi Murai mask <<= 8; 231af57ed9fSAtsushi Murai mask |= *wp++; 232af57ed9fSAtsushi Murai } 233af57ed9fSAtsushi Murai for (nb = 8 - *lp; nb > 0; nb--) 234af57ed9fSAtsushi Murai mask <<= 8; 235af57ed9fSAtsushi Murai } 236af57ed9fSAtsushi Murai } 237af57ed9fSAtsushi Murai printf("%08x ", mask); 238af57ed9fSAtsushi Murai p_flags(rtm->rtm_flags & (RTF_UP|RTF_GATEWAY|RTF_HOST), "%-6.6s "); 239af57ed9fSAtsushi Murai printf("(%d)\n", rtm->rtm_index); 240af57ed9fSAtsushi Murai } 241af57ed9fSAtsushi Murai 242af57ed9fSAtsushi Murai return(1); 243af57ed9fSAtsushi Murai } 244af57ed9fSAtsushi Murai 245af57ed9fSAtsushi Murai /* 246af57ed9fSAtsushi Murai * Delete routes associated with our interface 247af57ed9fSAtsushi Murai */ 248af57ed9fSAtsushi Murai void 249af57ed9fSAtsushi Murai DeleteIfRoutes(all) 250af57ed9fSAtsushi Murai int all; 251af57ed9fSAtsushi Murai { 252af57ed9fSAtsushi Murai struct rt_msghdr *rtm; 253af57ed9fSAtsushi Murai struct sockaddr *sa; 254af57ed9fSAtsushi Murai struct in_addr dstnet, gateway; 255af57ed9fSAtsushi Murai int needed; 256af57ed9fSAtsushi Murai char *sp, *cp, *ep; 257af57ed9fSAtsushi Murai u_long mask; 258af57ed9fSAtsushi Murai int *lp, nb; 259af57ed9fSAtsushi Murai u_char *wp; 26053c9f6c0SAtsushi Murai #if (BSD >= 199306) 261af57ed9fSAtsushi Murai int mib[6]; 262af57ed9fSAtsushi Murai #endif 263af57ed9fSAtsushi Murai 264af57ed9fSAtsushi Murai #ifdef DEBUG 265af57ed9fSAtsushi Murai logprintf("DeleteIfRoutes (%d)\n", IfIndex); 266af57ed9fSAtsushi Murai #endif 26753c9f6c0SAtsushi Murai #if (BSD >= 199306) 268af57ed9fSAtsushi Murai mib[0] = CTL_NET; 269af57ed9fSAtsushi Murai mib[1] = PF_ROUTE; 27053c9f6c0SAtsushi Murai mib[2] = 0; 27153c9f6c0SAtsushi Murai mib[3] = 0; 272af57ed9fSAtsushi Murai mib[4] = NET_RT_DUMP; 27353c9f6c0SAtsushi Murai mib[5] = 0; 27453c9f6c0SAtsushi Murai if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { 27553c9f6c0SAtsushi Murai perror("sysctl-estimate"); 27653c9f6c0SAtsushi Murai return; 27753c9f6c0SAtsushi Murai } 278af57ed9fSAtsushi Murai #else 279af57ed9fSAtsushi Murai needed = getkerninfo(KINFO_RT_DUMP, 0, 0, 0); 280af57ed9fSAtsushi Murai #endif 28153c9f6c0SAtsushi Murai 282af57ed9fSAtsushi Murai if (needed < 0) 283af57ed9fSAtsushi Murai return; 284af57ed9fSAtsushi Murai 285af57ed9fSAtsushi Murai sp = malloc(needed); 286af57ed9fSAtsushi Murai if (sp == NULL) 287af57ed9fSAtsushi Murai return; 288af57ed9fSAtsushi Murai 28953c9f6c0SAtsushi Murai #if (BSD >= 199306) 290af57ed9fSAtsushi Murai if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) { 291af57ed9fSAtsushi Murai free(sp); 29253c9f6c0SAtsushi Murai perror("sysctl-getroute"); 293af57ed9fSAtsushi Murai return; 294af57ed9fSAtsushi Murai } 295af57ed9fSAtsushi Murai #else 296af57ed9fSAtsushi Murai if (getkerninfo(KINFO_RT_DUMP, sp, &needed, 0) < 0) { 297af57ed9fSAtsushi Murai free(sp); 298af57ed9fSAtsushi Murai return; 299af57ed9fSAtsushi Murai } 300af57ed9fSAtsushi Murai #endif 301af57ed9fSAtsushi Murai ep = sp + needed; 302af57ed9fSAtsushi Murai 303af57ed9fSAtsushi Murai for (cp = sp; cp < ep; cp += rtm->rtm_msglen) { 304af57ed9fSAtsushi Murai rtm = (struct rt_msghdr *)cp; 305af57ed9fSAtsushi Murai sa = (struct sockaddr *)(rtm + 1); 306af57ed9fSAtsushi Murai #ifdef DEBUG 307af57ed9fSAtsushi Murai logprintf("addrs: %x, index: %d, flags: %x, dstnet: %x\n", 308af57ed9fSAtsushi Murai rtm->rtm_addrs, rtm->rtm_index, rtm->rtm_flags, 309af57ed9fSAtsushi Murai ((struct sockaddr_in *)sa)->sin_addr); 310af57ed9fSAtsushi Murai #endif 311af57ed9fSAtsushi Murai if (rtm->rtm_addrs != RTA_DST && 312af57ed9fSAtsushi Murai (rtm->rtm_index == IfIndex) && 313af57ed9fSAtsushi Murai (all || (rtm->rtm_flags & RTF_GATEWAY))) { 314af57ed9fSAtsushi Murai dstnet = ((struct sockaddr_in *)sa)->sin_addr; 315af57ed9fSAtsushi Murai wp = (u_char *)cp + rtm->rtm_msglen; 316af57ed9fSAtsushi Murai if (sa->sa_len == 0) 317af57ed9fSAtsushi Murai sa->sa_len = sizeof(long); 318af57ed9fSAtsushi Murai sa = (struct sockaddr *)(sa->sa_len + (char *)sa); 319af57ed9fSAtsushi Murai gateway = ((struct sockaddr_in *)sa)->sin_addr; 320af57ed9fSAtsushi Murai lp = (int *)(sa->sa_len + (char *)sa); 321af57ed9fSAtsushi Murai mask = 0; 322af57ed9fSAtsushi Murai if ((char *)lp < (char *)wp && *lp) { 323af57ed9fSAtsushi Murai #ifdef DEBUG 324af57ed9fSAtsushi Murai printf(" flag = %x, rest = %d", rtm->rtm_flags, *lp); 325af57ed9fSAtsushi Murai #endif 326af57ed9fSAtsushi Murai wp = (u_char *)(lp + 1); 327af57ed9fSAtsushi Murai for (nb = *lp; nb > 4; nb--) { 328af57ed9fSAtsushi Murai mask <<= 8; 329af57ed9fSAtsushi Murai mask |= *wp++; 330af57ed9fSAtsushi Murai } 331af57ed9fSAtsushi Murai for (nb = 8 - *lp; nb > 0; nb--) 332af57ed9fSAtsushi Murai mask <<= 8; 333af57ed9fSAtsushi Murai } 334af57ed9fSAtsushi Murai #ifdef DEBUG 335af57ed9fSAtsushi Murai logprintf("## %s ", inet_ntoa(dstnet)); 336af57ed9fSAtsushi Murai logprintf(" %s %d\n", inet_ntoa(gateway), rtm->rtm_index); 337af57ed9fSAtsushi Murai #endif 338af57ed9fSAtsushi Murai if (dstnet.s_addr == INADDR_ANY) { 339af57ed9fSAtsushi Murai gateway.s_addr = INADDR_ANY; 340af57ed9fSAtsushi Murai mask = INADDR_ANY; 341af57ed9fSAtsushi Murai } 342af57ed9fSAtsushi Murai OsSetRoute(RTM_DELETE, dstnet, gateway, htonl(mask)); 343af57ed9fSAtsushi Murai } 344af57ed9fSAtsushi Murai #ifdef DEBUG 345af57ed9fSAtsushi Murai else if (rtm->rtm_index == IfIndex) { 346af57ed9fSAtsushi Murai logprintf("??? addrs: %x, flags = %x\n", rtm->rtm_addrs, rtm->rtm_flags); 347af57ed9fSAtsushi Murai } 348af57ed9fSAtsushi Murai #endif 349af57ed9fSAtsushi Murai } 350af57ed9fSAtsushi Murai free(sp); 351af57ed9fSAtsushi Murai } 352af57ed9fSAtsushi Murai 353af57ed9fSAtsushi Murai int 354af57ed9fSAtsushi Murai GetIfIndex(name) 355af57ed9fSAtsushi Murai char *name; 356af57ed9fSAtsushi Murai { 357af57ed9fSAtsushi Murai struct ifreq *ifrp; 358af57ed9fSAtsushi Murai int s, len, elen, index; 359af57ed9fSAtsushi Murai struct ifconf ifconfs; 360af57ed9fSAtsushi Murai struct ifreq reqbuf[32]; 361af57ed9fSAtsushi Murai 362af57ed9fSAtsushi Murai s = socket(AF_INET, SOCK_DGRAM, 0); 363af57ed9fSAtsushi Murai if (s < 0) { 364af57ed9fSAtsushi Murai perror("socket"); 365af57ed9fSAtsushi Murai return(-1); 366af57ed9fSAtsushi Murai } 367af57ed9fSAtsushi Murai 368af57ed9fSAtsushi Murai ifconfs.ifc_len = sizeof(reqbuf); 369af57ed9fSAtsushi Murai ifconfs.ifc_buf = (caddr_t)reqbuf; 370af57ed9fSAtsushi Murai if (ioctl(s, SIOCGIFCONF, &ifconfs) < 0) { 371af57ed9fSAtsushi Murai perror("IFCONF"); 372af57ed9fSAtsushi Murai return(-1); 373af57ed9fSAtsushi Murai } 374af57ed9fSAtsushi Murai 375af57ed9fSAtsushi Murai ifrp = ifconfs.ifc_req; 376af57ed9fSAtsushi Murai 377af57ed9fSAtsushi Murai index = 1; 378af57ed9fSAtsushi Murai for (len = ifconfs.ifc_len; len > 0; len -= sizeof(struct ifreq)) { 379af57ed9fSAtsushi Murai elen = ifrp->ifr_addr.sa_len - sizeof(struct sockaddr); 380af57ed9fSAtsushi Murai if (ifrp->ifr_addr.sa_family == AF_LINK) { 381af57ed9fSAtsushi Murai #ifdef DEBUG 382af57ed9fSAtsushi Murai logprintf("%d: %-*.*s, %d, %d\n", index, IFNAMSIZ, IFNAMSIZ, ifrp->ifr_name, 383af57ed9fSAtsushi Murai ifrp->ifr_addr.sa_family, elen); 384af57ed9fSAtsushi Murai #endif 385af57ed9fSAtsushi Murai if (strcmp(ifrp->ifr_name, name) == 0) { 386af57ed9fSAtsushi Murai IfIndex = index; 387af57ed9fSAtsushi Murai return(index); 388af57ed9fSAtsushi Murai } 389af57ed9fSAtsushi Murai index++; 390af57ed9fSAtsushi Murai } 391af57ed9fSAtsushi Murai 392af57ed9fSAtsushi Murai len -= elen; 393af57ed9fSAtsushi Murai ifrp = (struct ifreq *)((char *)ifrp + elen); 394af57ed9fSAtsushi Murai ifrp++; 395af57ed9fSAtsushi Murai } 396af57ed9fSAtsushi Murai 397af57ed9fSAtsushi Murai close(s); 398af57ed9fSAtsushi Murai return(-1); 399af57ed9fSAtsushi Murai } 400