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 * 20927145beSBrian Somers * $Id: route.c,v 1.13 1997/05/10 01:22:18 brian Exp $ 2153c9f6c0SAtsushi Murai * 22af57ed9fSAtsushi Murai */ 23af57ed9fSAtsushi Murai #include <sys/types.h> 24af57ed9fSAtsushi Murai #include <machine/endian.h> 25628d2ac1SGarrett Wollman #include <sys/ioctl.h> 26af57ed9fSAtsushi Murai #include <sys/param.h> 27af57ed9fSAtsushi Murai #include <sys/socket.h> 28af57ed9fSAtsushi Murai #include <sys/sysctl.h> 29628d2ac1SGarrett Wollman #include <sys/time.h> 30628d2ac1SGarrett Wollman 31628d2ac1SGarrett Wollman #include <errno.h> 32af57ed9fSAtsushi Murai #include <stdlib.h> 33af57ed9fSAtsushi Murai #include <stdio.h> 34af57ed9fSAtsushi Murai #include <string.h> 35af57ed9fSAtsushi Murai #include <unistd.h> 36628d2ac1SGarrett Wollman 37628d2ac1SGarrett Wollman #include <net/route.h> 38628d2ac1SGarrett Wollman #include <net/if.h> 39628d2ac1SGarrett Wollman #include <netinet/in_systm.h> 40628d2ac1SGarrett Wollman #include <netinet/in.h> 41628d2ac1SGarrett Wollman #include <arpa/inet.h> 42628d2ac1SGarrett Wollman 43215a4696SAtsushi Murai #include "log.h" 44927145beSBrian Somers #include "loadalias.h" 45927145beSBrian Somers #include "vars.h" 46af57ed9fSAtsushi Murai 47af57ed9fSAtsushi Murai static int IfIndex; 48af57ed9fSAtsushi Murai 49af57ed9fSAtsushi Murai struct rtmsg { 50af57ed9fSAtsushi Murai struct rt_msghdr m_rtm; 51af57ed9fSAtsushi Murai char m_space[64]; 52af57ed9fSAtsushi Murai }; 53af57ed9fSAtsushi Murai 54af57ed9fSAtsushi Murai static int seqno; 55af57ed9fSAtsushi Murai 56af57ed9fSAtsushi Murai void 57af57ed9fSAtsushi Murai OsSetRoute(cmd, dst, gateway, mask) 58af57ed9fSAtsushi Murai int cmd; 59af57ed9fSAtsushi Murai struct in_addr dst; 60af57ed9fSAtsushi Murai struct in_addr gateway; 61af57ed9fSAtsushi Murai struct in_addr mask; 62af57ed9fSAtsushi Murai { 63af57ed9fSAtsushi Murai struct rtmsg rtmes; 64af57ed9fSAtsushi Murai int s, nb, wb; 65af57ed9fSAtsushi Murai char *cp; 66af57ed9fSAtsushi Murai u_long *lp; 67af57ed9fSAtsushi Murai struct sockaddr_in rtdata; 68af57ed9fSAtsushi Murai 69af57ed9fSAtsushi Murai s = socket(PF_ROUTE, SOCK_RAW, 0); 70af57ed9fSAtsushi Murai if (s < 0) 71927145beSBrian Somers LogPrintf(LogERROR, "socket: %s", strerror(errno)); 72af57ed9fSAtsushi Murai 73af57ed9fSAtsushi Murai bzero(&rtmes, sizeof(rtmes)); 74af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_version = RTM_VERSION; 75af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_type = cmd; 76af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_addrs = RTA_DST | RTA_NETMASK; 77af57ed9fSAtsushi Murai if (cmd == RTM_ADD) rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY; 78af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_seq = ++seqno; 79af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_pid = getpid(); 802db86e5bSPeter Wemm rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; 81af57ed9fSAtsushi Murai 82af57ed9fSAtsushi Murai bzero(&rtdata, sizeof(rtdata)); 83af57ed9fSAtsushi Murai rtdata.sin_len = 16; 84af57ed9fSAtsushi Murai rtdata.sin_family = AF_INET; 85af57ed9fSAtsushi Murai rtdata.sin_port = 0; 86af57ed9fSAtsushi Murai rtdata.sin_addr = dst; 87af57ed9fSAtsushi Murai 88af57ed9fSAtsushi Murai cp = rtmes.m_space; 89af57ed9fSAtsushi Murai bcopy(&rtdata, cp, 16); 90af57ed9fSAtsushi Murai cp += 16; 91af57ed9fSAtsushi Murai if (gateway.s_addr) { 92af57ed9fSAtsushi Murai rtdata.sin_addr = gateway; 93af57ed9fSAtsushi Murai bcopy(&rtdata, cp, 16); 94af57ed9fSAtsushi Murai cp += 16; 95af57ed9fSAtsushi Murai } 96af57ed9fSAtsushi Murai 97af57ed9fSAtsushi Murai if (dst.s_addr == INADDR_ANY) 98af57ed9fSAtsushi Murai mask.s_addr = INADDR_ANY; 99af57ed9fSAtsushi Murai 100af57ed9fSAtsushi Murai lp = (u_long *)cp; 101af57ed9fSAtsushi Murai 102af57ed9fSAtsushi Murai if (mask.s_addr) { 103af57ed9fSAtsushi Murai *lp++ = 8; 104af57ed9fSAtsushi Murai cp += sizeof(int); 105af57ed9fSAtsushi Murai *lp = mask.s_addr; 106af57ed9fSAtsushi Murai } else 107af57ed9fSAtsushi Murai *lp = 0; 108af57ed9fSAtsushi Murai cp += sizeof(u_long); 109af57ed9fSAtsushi Murai 110af57ed9fSAtsushi Murai nb = cp - (char *)&rtmes; 111af57ed9fSAtsushi Murai rtmes.m_rtm.rtm_msglen = nb; 112af57ed9fSAtsushi Murai wb = write(s, &rtmes, nb); 113af57ed9fSAtsushi Murai if (wb < 0) { 114927145beSBrian Somers LogPrintf(LogTCPIP, "Already set route addr dst=%x, gateway=%x\n" 115215a4696SAtsushi Murai ,dst.s_addr, gateway.s_addr); 116af57ed9fSAtsushi Murai } 117927145beSBrian Somers LogPrintf(LogDEBUG, "wrote %d: dst = %x, gateway = %x\n", nb, 118927145beSBrian Somers dst.s_addr, gateway.s_addr); 119af57ed9fSAtsushi Murai close(s); 120af57ed9fSAtsushi Murai } 121af57ed9fSAtsushi Murai 122af57ed9fSAtsushi Murai static void 123af57ed9fSAtsushi Murai p_sockaddr(sa, width) 124af57ed9fSAtsushi Murai struct sockaddr *sa; 125af57ed9fSAtsushi Murai int width; 126af57ed9fSAtsushi Murai { 127927145beSBrian Somers if (VarTerm) { 128af57ed9fSAtsushi Murai register char *cp; 129af57ed9fSAtsushi Murai register struct sockaddr_in *sin = (struct sockaddr_in *)sa; 130af57ed9fSAtsushi Murai 131af57ed9fSAtsushi Murai cp = (sin->sin_addr.s_addr == 0) ? "default" : 132af57ed9fSAtsushi Murai inet_ntoa(sin->sin_addr); 133927145beSBrian Somers fprintf(VarTerm, "%-*.*s ", width, width, cp); 134927145beSBrian Somers } 135af57ed9fSAtsushi Murai } 136af57ed9fSAtsushi Murai 137af57ed9fSAtsushi Murai struct bits { 138af57ed9fSAtsushi Murai short b_mask; 139af57ed9fSAtsushi Murai char b_val; 140af57ed9fSAtsushi Murai } bits[] = { 141af57ed9fSAtsushi Murai { RTF_UP, 'U' }, 142af57ed9fSAtsushi Murai { RTF_GATEWAY, 'G' }, 143af57ed9fSAtsushi Murai { RTF_HOST, 'H' }, 144af57ed9fSAtsushi Murai { RTF_DYNAMIC, 'D' }, 145af57ed9fSAtsushi Murai { RTF_MODIFIED, 'M' }, 146af57ed9fSAtsushi Murai { RTF_CLONING, 'C' }, 147af57ed9fSAtsushi Murai { RTF_XRESOLVE, 'X' }, 148af57ed9fSAtsushi Murai { RTF_LLINFO, 'L' }, 149af57ed9fSAtsushi Murai { RTF_REJECT, 'R' }, 150af57ed9fSAtsushi Murai { 0 } 151af57ed9fSAtsushi Murai }; 152af57ed9fSAtsushi Murai 153af57ed9fSAtsushi Murai static void 154af57ed9fSAtsushi Murai p_flags(f, format) 155af57ed9fSAtsushi Murai register int f; 156af57ed9fSAtsushi Murai char *format; 157af57ed9fSAtsushi Murai { 158927145beSBrian Somers if (VarTerm) { 159af57ed9fSAtsushi Murai char name[33], *flags; 160af57ed9fSAtsushi Murai register struct bits *p = bits; 161af57ed9fSAtsushi Murai 162af57ed9fSAtsushi Murai for (flags = name; p->b_mask; p++) 163af57ed9fSAtsushi Murai if (p->b_mask & f) 164af57ed9fSAtsushi Murai *flags++ = p->b_val; 165af57ed9fSAtsushi Murai *flags = '\0'; 166927145beSBrian Somers fprintf(VarTerm, format, name); 167927145beSBrian Somers } 168af57ed9fSAtsushi Murai } 169af57ed9fSAtsushi Murai 170af57ed9fSAtsushi Murai int 171af57ed9fSAtsushi Murai ShowRoute() 172af57ed9fSAtsushi Murai { 173af57ed9fSAtsushi Murai struct rt_msghdr *rtm; 174af57ed9fSAtsushi Murai struct sockaddr *sa; 175af57ed9fSAtsushi Murai char *sp, *ep, *cp; 176af57ed9fSAtsushi Murai u_char *wp; 177af57ed9fSAtsushi Murai int *lp; 178af57ed9fSAtsushi Murai int needed, nb; 179af57ed9fSAtsushi Murai u_long mask; 180af57ed9fSAtsushi Murai int mib[6]; 181af57ed9fSAtsushi Murai 182927145beSBrian Somers if (!VarTerm) 183927145beSBrian Somers return 1; 184927145beSBrian Somers 185af57ed9fSAtsushi Murai mib[0] = CTL_NET; 186af57ed9fSAtsushi Murai mib[1] = PF_ROUTE; 18753c9f6c0SAtsushi Murai mib[2] = 0; 18853c9f6c0SAtsushi Murai mib[3] = 0; 189af57ed9fSAtsushi Murai mib[4] = NET_RT_DUMP; 19053c9f6c0SAtsushi Murai mib[5] = 0; 19153c9f6c0SAtsushi Murai if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { 192927145beSBrian Somers LogPrintf(LogERROR, "sysctl: estimate: %s", strerror(errno)); 19353c9f6c0SAtsushi Murai return(1); 19453c9f6c0SAtsushi Murai } 195927145beSBrian Somers 196af57ed9fSAtsushi Murai if (needed < 0) 197af57ed9fSAtsushi Murai return(1); 198af57ed9fSAtsushi Murai sp = malloc(needed); 199af57ed9fSAtsushi Murai if (sp == NULL) 200af57ed9fSAtsushi Murai return(1); 20153c9f6c0SAtsushi Murai if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) { 202927145beSBrian Somers LogPrintf(LogERROR, "sysctl: getroute: %s", strerror(errno)); 203b0cdb3ceSJordan K. Hubbard free(sp); 204af57ed9fSAtsushi Murai return(1); 20553c9f6c0SAtsushi Murai } 206927145beSBrian Somers 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) { 224927145beSBrian Somers LogPrintf(LogDEBUG, " flag = %x, rest = %d", rtm->rtm_flags, *lp); 225af57ed9fSAtsushi Murai wp = (u_char *)(lp + 1); 226af57ed9fSAtsushi Murai mask = 0; 227b0cdb3ceSJordan K. Hubbard for (nb = *(char *)lp; nb > 4; nb--) { 228af57ed9fSAtsushi Murai mask <<= 8; 229af57ed9fSAtsushi Murai mask |= *wp++; 230af57ed9fSAtsushi Murai } 231b0cdb3ceSJordan K. Hubbard for (nb = 8 - *(char *)lp; nb > 0; nb--) 232af57ed9fSAtsushi Murai mask <<= 8; 233af57ed9fSAtsushi Murai } 234af57ed9fSAtsushi Murai } 235927145beSBrian Somers fprintf(VarTerm, "%08lx ", mask); 236af57ed9fSAtsushi Murai p_flags(rtm->rtm_flags & (RTF_UP|RTF_GATEWAY|RTF_HOST), "%-6.6s "); 237927145beSBrian Somers fprintf(VarTerm, "(%d)\n", rtm->rtm_index); 238af57ed9fSAtsushi Murai } 239b0cdb3ceSJordan K. Hubbard free(sp); 240927145beSBrian Somers return 0; 241af57ed9fSAtsushi Murai } 242af57ed9fSAtsushi Murai 243af57ed9fSAtsushi Murai /* 244af57ed9fSAtsushi Murai * Delete routes associated with our interface 245af57ed9fSAtsushi Murai */ 246af57ed9fSAtsushi Murai void 247af57ed9fSAtsushi Murai DeleteIfRoutes(all) 248af57ed9fSAtsushi Murai int all; 249af57ed9fSAtsushi Murai { 250af57ed9fSAtsushi Murai struct rt_msghdr *rtm; 251af57ed9fSAtsushi Murai struct sockaddr *sa; 2529c749ffbSPoul-Henning Kamp struct in_addr dstnet, gateway, maddr; 253af57ed9fSAtsushi Murai int needed; 254af57ed9fSAtsushi Murai char *sp, *cp, *ep; 255af57ed9fSAtsushi Murai u_long mask; 256af57ed9fSAtsushi Murai int *lp, nb; 257af57ed9fSAtsushi Murai u_char *wp; 258af57ed9fSAtsushi Murai int mib[6]; 259af57ed9fSAtsushi Murai 260927145beSBrian Somers LogPrintf(LogDEBUG, "DeleteIfRoutes (%d)\n", IfIndex); 261927145beSBrian Somers 262af57ed9fSAtsushi Murai mib[0] = CTL_NET; 263af57ed9fSAtsushi Murai mib[1] = PF_ROUTE; 26453c9f6c0SAtsushi Murai mib[2] = 0; 26553c9f6c0SAtsushi Murai mib[3] = 0; 266af57ed9fSAtsushi Murai mib[4] = NET_RT_DUMP; 26753c9f6c0SAtsushi Murai mib[5] = 0; 26853c9f6c0SAtsushi Murai if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { 269927145beSBrian Somers LogPrintf(LogERROR, "sysctl: estimate: %s", strerror(errno)); 27053c9f6c0SAtsushi Murai return; 27153c9f6c0SAtsushi Murai } 27253c9f6c0SAtsushi Murai 273af57ed9fSAtsushi Murai if (needed < 0) 274af57ed9fSAtsushi Murai return; 275af57ed9fSAtsushi Murai 276af57ed9fSAtsushi Murai sp = malloc(needed); 277af57ed9fSAtsushi Murai if (sp == NULL) 278af57ed9fSAtsushi Murai return; 279af57ed9fSAtsushi Murai 280af57ed9fSAtsushi Murai if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) { 281927145beSBrian Somers LogPrintf(LogERROR, "sysctl: getroute: %s", strerror(errno)); 282af57ed9fSAtsushi Murai free(sp); 283af57ed9fSAtsushi Murai return; 284af57ed9fSAtsushi Murai } 285af57ed9fSAtsushi Murai ep = sp + needed; 286af57ed9fSAtsushi Murai 287af57ed9fSAtsushi Murai for (cp = sp; cp < ep; cp += rtm->rtm_msglen) { 288af57ed9fSAtsushi Murai rtm = (struct rt_msghdr *)cp; 289af57ed9fSAtsushi Murai sa = (struct sockaddr *)(rtm + 1); 290927145beSBrian Somers LogPrintf(LogDEBUG, "DeleteIfRoutes: addrs: %x, index: %d, flags: %x," 291927145beSBrian Somers " dstnet: %x\n", 292af57ed9fSAtsushi Murai rtm->rtm_addrs, rtm->rtm_index, rtm->rtm_flags, 293af57ed9fSAtsushi Murai ((struct sockaddr_in *)sa)->sin_addr); 294af57ed9fSAtsushi Murai if (rtm->rtm_addrs != RTA_DST && 295af57ed9fSAtsushi Murai (rtm->rtm_index == IfIndex) && 296af57ed9fSAtsushi Murai (all || (rtm->rtm_flags & RTF_GATEWAY))) { 297af57ed9fSAtsushi Murai dstnet = ((struct sockaddr_in *)sa)->sin_addr; 298af57ed9fSAtsushi Murai wp = (u_char *)cp + rtm->rtm_msglen; 299af57ed9fSAtsushi Murai if (sa->sa_len == 0) 300af57ed9fSAtsushi Murai sa->sa_len = sizeof(long); 301af57ed9fSAtsushi Murai sa = (struct sockaddr *)(sa->sa_len + (char *)sa); 302af57ed9fSAtsushi Murai gateway = ((struct sockaddr_in *)sa)->sin_addr; 303af57ed9fSAtsushi Murai lp = (int *)(sa->sa_len + (char *)sa); 304af57ed9fSAtsushi Murai mask = 0; 305af57ed9fSAtsushi Murai if ((char *)lp < (char *)wp && *lp) { 306927145beSBrian Somers LogPrintf(LogDEBUG, "DeleteIfRoutes: flag = %x, rest = %d", 307927145beSBrian Somers rtm->rtm_flags, *lp); 308af57ed9fSAtsushi Murai wp = (u_char *)(lp + 1); 309af57ed9fSAtsushi Murai for (nb = *lp; nb > 4; nb--) { 310af57ed9fSAtsushi Murai mask <<= 8; 311af57ed9fSAtsushi Murai mask |= *wp++; 312af57ed9fSAtsushi Murai } 313af57ed9fSAtsushi Murai for (nb = 8 - *lp; nb > 0; nb--) 314af57ed9fSAtsushi Murai mask <<= 8; 315af57ed9fSAtsushi Murai } 316927145beSBrian Somers LogPrintf(LogDEBUG, "DeleteIfRoutes: Dest: %s\n", inet_ntoa(dstnet)); 317927145beSBrian Somers LogPrintf(LogDEBUG, "DeleteIfRoutes: Gw: %s\n", inet_ntoa(gateway)); 318927145beSBrian Somers LogPrintf(LogDEBUG, "DeleteIfRoutes: Index: %d\n", rtm->rtm_index); 319af57ed9fSAtsushi Murai if (dstnet.s_addr == INADDR_ANY) { 320af57ed9fSAtsushi Murai gateway.s_addr = INADDR_ANY; 321af57ed9fSAtsushi Murai mask = INADDR_ANY; 322af57ed9fSAtsushi Murai } 3239c749ffbSPoul-Henning Kamp maddr.s_addr = htonl(mask); 3249c749ffbSPoul-Henning Kamp OsSetRoute(RTM_DELETE, dstnet, gateway, maddr); 325af57ed9fSAtsushi Murai } 326927145beSBrian Somers else if(rtm->rtm_index == IfIndex) 327927145beSBrian Somers LogPrintf(LogDEBUG, "DeleteIfRoutes: Ignoring (looking for index %d)\n", 328927145beSBrian Somers IfIndex); 329af57ed9fSAtsushi Murai } 330af57ed9fSAtsushi Murai free(sp); 331af57ed9fSAtsushi Murai } 332af57ed9fSAtsushi Murai 333d8e55738SJordan K. Hubbard /* 334d8e55738SJordan K. Hubbard * 960603 - Modified to use dynamic buffer allocator as in ifconfig 335d8e55738SJordan K. Hubbard */ 336d8e55738SJordan K. Hubbard 337af57ed9fSAtsushi Murai int 338af57ed9fSAtsushi Murai GetIfIndex(name) 339af57ed9fSAtsushi Murai char *name; 340af57ed9fSAtsushi Murai { 341d8e55738SJordan K. Hubbard char *buffer; 342af57ed9fSAtsushi Murai struct ifreq *ifrp; 343af57ed9fSAtsushi Murai int s, len, elen, index; 344af57ed9fSAtsushi Murai struct ifconf ifconfs; 345d8e55738SJordan K. Hubbard /* struct ifreq reqbuf[256]; -- obsoleted :) */ 346d8e55738SJordan K. Hubbard int oldbufsize, bufsize = sizeof(struct ifreq); 347af57ed9fSAtsushi Murai 348af57ed9fSAtsushi Murai s = socket(AF_INET, SOCK_DGRAM, 0); 349af57ed9fSAtsushi Murai if (s < 0) { 350927145beSBrian Somers LogPrintf(LogERROR, "socket: %s", strerror(errno)); 351af57ed9fSAtsushi Murai return(-1); 352af57ed9fSAtsushi Murai } 353af57ed9fSAtsushi Murai 354d8e55738SJordan K. Hubbard buffer = malloc(bufsize); /* allocate first buffer */ 355d8e55738SJordan K. Hubbard ifconfs.ifc_len = bufsize; /* Initial setting */ 356d8e55738SJordan K. Hubbard /* 357d8e55738SJordan K. Hubbard * Iterate through here until we don't get many more data 358d8e55738SJordan K. Hubbard */ 359d8e55738SJordan K. Hubbard 360d8e55738SJordan K. Hubbard do { 361d8e55738SJordan K. Hubbard oldbufsize = ifconfs.ifc_len; 362d8e55738SJordan K. Hubbard bufsize += 1+sizeof(struct ifreq); 363d8e55738SJordan K. Hubbard buffer = realloc((void *)buffer, bufsize); /* Make it bigger */ 364927145beSBrian Somers LogPrintf(LogDEBUG, "GetIfIndex: Growing buffer to %d\n", bufsize); 365d8e55738SJordan K. Hubbard ifconfs.ifc_len = bufsize; 366d8e55738SJordan K. Hubbard ifconfs.ifc_buf = buffer; 367af57ed9fSAtsushi Murai if (ioctl(s, SIOCGIFCONF, &ifconfs) < 0) { 368927145beSBrian Somers LogPrintf(LogERROR, "ioctl(SIOCGIFCONF): %s", strerror(errno)); 369d8e55738SJordan K. Hubbard free(buffer); 370af57ed9fSAtsushi Murai return(-1); 371af57ed9fSAtsushi Murai } 372d8e55738SJordan K. Hubbard } while (ifconfs.ifc_len > oldbufsize); 373af57ed9fSAtsushi Murai 374af57ed9fSAtsushi Murai ifrp = ifconfs.ifc_req; 375af57ed9fSAtsushi Murai 376af57ed9fSAtsushi Murai index = 1; 377af57ed9fSAtsushi Murai for (len = ifconfs.ifc_len; len > 0; len -= sizeof(struct ifreq)) { 378af57ed9fSAtsushi Murai elen = ifrp->ifr_addr.sa_len - sizeof(struct sockaddr); 379af57ed9fSAtsushi Murai if (ifrp->ifr_addr.sa_family == AF_LINK) { 380927145beSBrian Somers LogPrintf(LogDEBUG, "GetIfIndex: %d: %-*.*s, %d, %d\n", 381927145beSBrian Somers index, IFNAMSIZ, IFNAMSIZ, ifrp->ifr_name, 382af57ed9fSAtsushi Murai ifrp->ifr_addr.sa_family, elen); 383af57ed9fSAtsushi Murai if (strcmp(ifrp->ifr_name, name) == 0) { 384af57ed9fSAtsushi Murai IfIndex = index; 385d8e55738SJordan K. Hubbard free(buffer); 386af57ed9fSAtsushi Murai return(index); 387af57ed9fSAtsushi Murai } 388af57ed9fSAtsushi Murai index++; 389af57ed9fSAtsushi Murai } 390af57ed9fSAtsushi Murai 391af57ed9fSAtsushi Murai len -= elen; 392af57ed9fSAtsushi Murai ifrp = (struct ifreq *)((char *)ifrp + elen); 393af57ed9fSAtsushi Murai ifrp++; 394af57ed9fSAtsushi Murai } 395af57ed9fSAtsushi Murai 396af57ed9fSAtsushi Murai close(s); 397d8e55738SJordan K. Hubbard free(buffer); 398af57ed9fSAtsushi Murai return(-1); 399af57ed9fSAtsushi Murai } 400