xref: /freebsd/usr.sbin/ppp/route.c (revision b0cdb3ce11c88c81039eb3bb464d4355e928b04e)
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  *
20b0cdb3ceSJordan K. Hubbard  * $Id: route.c,v 1.8 1996/10/06 13:32:35 jkh 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();
782db86e5bSPeter Wemm   rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
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) {
1129c749ffbSPoul-Henning Kamp      LogPrintf(LOG_TCPIP_BIT, "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");
201b0cdb3ceSJordan K. Hubbard     free(sp);
202af57ed9fSAtsushi Murai     return(1);
20353c9f6c0SAtsushi Murai   }
204af57ed9fSAtsushi Murai #else
205af57ed9fSAtsushi Murai   if (getkerninfo(KINFO_RT_DUMP, sp, &needed, 0) < 0)
206b0cdb3ceSJordan K. Hubbard     free(sp);
207af57ed9fSAtsushi Murai     return(1);
208af57ed9fSAtsushi Murai #endif
209af57ed9fSAtsushi Murai   ep = sp + needed;
210af57ed9fSAtsushi Murai 
211af57ed9fSAtsushi Murai   for (cp = sp; cp < ep; cp += rtm->rtm_msglen) {
212af57ed9fSAtsushi Murai     rtm = (struct rt_msghdr *)cp;
213af57ed9fSAtsushi Murai     sa = (struct sockaddr *)(rtm + 1);
214af57ed9fSAtsushi Murai     mask = 0xffffffff;
215af57ed9fSAtsushi Murai     if (rtm->rtm_addrs == RTA_DST)
216af57ed9fSAtsushi Murai       p_sockaddr(sa, 36);
217af57ed9fSAtsushi Murai     else {
218af57ed9fSAtsushi Murai       wp = (u_char *)cp + rtm->rtm_msglen;
219af57ed9fSAtsushi Murai       p_sockaddr(sa, 16);
220af57ed9fSAtsushi Murai       if (sa->sa_len == 0)
221af57ed9fSAtsushi Murai 	sa->sa_len = sizeof(long);
222af57ed9fSAtsushi Murai       sa = (struct sockaddr *)(sa->sa_len + (char *)sa);
223af57ed9fSAtsushi Murai       p_sockaddr(sa, 18);
224af57ed9fSAtsushi Murai       lp = (int *)(sa->sa_len + (char *)sa);
225af57ed9fSAtsushi Murai       if ((char *)lp < (char *)wp && *lp) {
226af57ed9fSAtsushi Murai #ifdef DEBUG
227af57ed9fSAtsushi Murai 	logprintf(" flag = %x, rest = %d", rtm->rtm_flags, *lp);
228af57ed9fSAtsushi Murai #endif
229af57ed9fSAtsushi Murai 	wp = (u_char *)(lp + 1);
230af57ed9fSAtsushi Murai 	mask = 0;
231b0cdb3ceSJordan K. Hubbard 	for (nb = *(char *)lp; nb > 4; nb--) {
232af57ed9fSAtsushi Murai 	  mask <<= 8;
233af57ed9fSAtsushi Murai 	  mask |= *wp++;
234af57ed9fSAtsushi Murai 	}
235b0cdb3ceSJordan K. Hubbard 	for (nb = 8 - *(char *)lp; nb > 0; nb--)
236af57ed9fSAtsushi Murai 	  mask <<= 8;
237af57ed9fSAtsushi Murai       }
238af57ed9fSAtsushi Murai     }
239ed6a16c1SPoul-Henning Kamp     printf("%08lx  ", mask);
240af57ed9fSAtsushi Murai     p_flags(rtm->rtm_flags & (RTF_UP|RTF_GATEWAY|RTF_HOST), "%-6.6s ");
241af57ed9fSAtsushi Murai     printf("(%d)\n", rtm->rtm_index);
242af57ed9fSAtsushi Murai   }
243b0cdb3ceSJordan K. Hubbard   free(sp);
244af57ed9fSAtsushi Murai   return(1);
245af57ed9fSAtsushi Murai }
246af57ed9fSAtsushi Murai 
247af57ed9fSAtsushi Murai /*
248af57ed9fSAtsushi Murai  *  Delete routes associated with our interface
249af57ed9fSAtsushi Murai  */
250af57ed9fSAtsushi Murai void
251af57ed9fSAtsushi Murai DeleteIfRoutes(all)
252af57ed9fSAtsushi Murai int all;
253af57ed9fSAtsushi Murai {
254af57ed9fSAtsushi Murai   struct rt_msghdr *rtm;
255af57ed9fSAtsushi Murai   struct sockaddr *sa;
2569c749ffbSPoul-Henning Kamp   struct in_addr dstnet, gateway, maddr;
257af57ed9fSAtsushi Murai   int needed;
258af57ed9fSAtsushi Murai   char *sp, *cp, *ep;
259af57ed9fSAtsushi Murai   u_long mask;
260af57ed9fSAtsushi Murai   int *lp, nb;
261af57ed9fSAtsushi Murai   u_char *wp;
26253c9f6c0SAtsushi Murai #if (BSD >= 199306)
263af57ed9fSAtsushi Murai   int mib[6];
264af57ed9fSAtsushi Murai #endif
265af57ed9fSAtsushi Murai 
266af57ed9fSAtsushi Murai #ifdef DEBUG
267af57ed9fSAtsushi Murai   logprintf("DeleteIfRoutes (%d)\n", IfIndex);
268af57ed9fSAtsushi Murai #endif
26953c9f6c0SAtsushi Murai #if (BSD >= 199306)
270af57ed9fSAtsushi Murai   mib[0] = CTL_NET;
271af57ed9fSAtsushi Murai   mib[1] = PF_ROUTE;
27253c9f6c0SAtsushi Murai   mib[2] = 0;
27353c9f6c0SAtsushi Murai   mib[3] = 0;
274af57ed9fSAtsushi Murai   mib[4] = NET_RT_DUMP;
27553c9f6c0SAtsushi Murai   mib[5] = 0;
27653c9f6c0SAtsushi Murai   if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
27753c9f6c0SAtsushi Murai     perror("sysctl-estimate");
27853c9f6c0SAtsushi Murai     return;
27953c9f6c0SAtsushi Murai   }
280af57ed9fSAtsushi Murai #else
281af57ed9fSAtsushi Murai   needed = getkerninfo(KINFO_RT_DUMP, 0, 0, 0);
282af57ed9fSAtsushi Murai #endif
28353c9f6c0SAtsushi Murai 
284af57ed9fSAtsushi Murai   if (needed < 0)
285af57ed9fSAtsushi Murai     return;
286af57ed9fSAtsushi Murai 
287af57ed9fSAtsushi Murai   sp = malloc(needed);
288af57ed9fSAtsushi Murai   if (sp == NULL)
289af57ed9fSAtsushi Murai     return;
290af57ed9fSAtsushi Murai 
29153c9f6c0SAtsushi Murai #if (BSD >= 199306)
292af57ed9fSAtsushi Murai   if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) {
293af57ed9fSAtsushi Murai     free(sp);
29453c9f6c0SAtsushi Murai     perror("sysctl-getroute");
295af57ed9fSAtsushi Murai     return;
296af57ed9fSAtsushi Murai   }
297af57ed9fSAtsushi Murai #else
298af57ed9fSAtsushi Murai   if (getkerninfo(KINFO_RT_DUMP, sp, &needed, 0) < 0) {
299af57ed9fSAtsushi Murai     free(sp);
300af57ed9fSAtsushi Murai     return;
301af57ed9fSAtsushi Murai   }
302af57ed9fSAtsushi Murai #endif
303af57ed9fSAtsushi Murai   ep = sp + needed;
304af57ed9fSAtsushi Murai 
305af57ed9fSAtsushi Murai   for (cp = sp; cp < ep; cp += rtm->rtm_msglen) {
306af57ed9fSAtsushi Murai     rtm = (struct rt_msghdr *)cp;
307af57ed9fSAtsushi Murai     sa = (struct sockaddr *)(rtm + 1);
308af57ed9fSAtsushi Murai #ifdef DEBUG
309af57ed9fSAtsushi Murai     logprintf("addrs: %x, index: %d, flags: %x, dstnet: %x\n",
310af57ed9fSAtsushi Murai 	rtm->rtm_addrs, rtm->rtm_index, rtm->rtm_flags,
311af57ed9fSAtsushi Murai 	((struct sockaddr_in *)sa)->sin_addr);
312af57ed9fSAtsushi Murai #endif
313af57ed9fSAtsushi Murai     if (rtm->rtm_addrs != RTA_DST &&
314af57ed9fSAtsushi Murai        (rtm->rtm_index == IfIndex) &&
315af57ed9fSAtsushi Murai        (all || (rtm->rtm_flags & RTF_GATEWAY))) {
316af57ed9fSAtsushi Murai       dstnet = ((struct sockaddr_in *)sa)->sin_addr;
317af57ed9fSAtsushi Murai       wp = (u_char *)cp + rtm->rtm_msglen;
318af57ed9fSAtsushi Murai       if (sa->sa_len == 0)
319af57ed9fSAtsushi Murai 	sa->sa_len = sizeof(long);
320af57ed9fSAtsushi Murai       sa = (struct sockaddr *)(sa->sa_len + (char *)sa);
321af57ed9fSAtsushi Murai       gateway = ((struct sockaddr_in *)sa)->sin_addr;
322af57ed9fSAtsushi Murai       lp = (int *)(sa->sa_len + (char *)sa);
323af57ed9fSAtsushi Murai       mask = 0;
324af57ed9fSAtsushi Murai       if ((char *)lp < (char *)wp && *lp) {
325af57ed9fSAtsushi Murai #ifdef DEBUG
326af57ed9fSAtsushi Murai 	printf(" flag = %x, rest = %d", rtm->rtm_flags, *lp);
327af57ed9fSAtsushi Murai #endif
328af57ed9fSAtsushi Murai 	wp = (u_char *)(lp + 1);
329af57ed9fSAtsushi Murai 	for (nb = *lp; nb > 4; nb--) {
330af57ed9fSAtsushi Murai 	  mask <<= 8;
331af57ed9fSAtsushi Murai 	  mask |= *wp++;
332af57ed9fSAtsushi Murai 	}
333af57ed9fSAtsushi Murai 	for (nb = 8 - *lp; nb > 0; nb--)
334af57ed9fSAtsushi Murai 	  mask <<= 8;
335af57ed9fSAtsushi Murai       }
336af57ed9fSAtsushi Murai #ifdef DEBUG
337af57ed9fSAtsushi Murai       logprintf("## %s ", inet_ntoa(dstnet));
338af57ed9fSAtsushi Murai       logprintf(" %s  %d\n", inet_ntoa(gateway), rtm->rtm_index);
339af57ed9fSAtsushi Murai #endif
340af57ed9fSAtsushi Murai       if (dstnet.s_addr == INADDR_ANY) {
341af57ed9fSAtsushi Murai         gateway.s_addr = INADDR_ANY;
342af57ed9fSAtsushi Murai         mask = INADDR_ANY;
343af57ed9fSAtsushi Murai       }
3449c749ffbSPoul-Henning Kamp       maddr.s_addr = htonl(mask);
3459c749ffbSPoul-Henning Kamp       OsSetRoute(RTM_DELETE, dstnet, gateway, maddr);
346af57ed9fSAtsushi Murai     }
347af57ed9fSAtsushi Murai #ifdef DEBUG
348af57ed9fSAtsushi Murai     else if (rtm->rtm_index == IfIndex) {
349af57ed9fSAtsushi Murai       logprintf("??? addrs: %x, flags = %x\n", rtm->rtm_addrs, rtm->rtm_flags);
350af57ed9fSAtsushi Murai     }
351af57ed9fSAtsushi Murai #endif
352af57ed9fSAtsushi Murai   }
353af57ed9fSAtsushi Murai   free(sp);
354af57ed9fSAtsushi Murai }
355af57ed9fSAtsushi Murai 
356d8e55738SJordan K. Hubbard  /*
357d8e55738SJordan K. Hubbard   * 960603 - Modified to use dynamic buffer allocator as in ifconfig
358d8e55738SJordan K. Hubbard   */
359d8e55738SJordan K. Hubbard 
360af57ed9fSAtsushi Murai int
361af57ed9fSAtsushi Murai GetIfIndex(name)
362af57ed9fSAtsushi Murai char *name;
363af57ed9fSAtsushi Murai {
364d8e55738SJordan K. Hubbard   char *buffer;
365af57ed9fSAtsushi Murai   struct ifreq *ifrp;
366af57ed9fSAtsushi Murai   int s, len, elen, index;
367af57ed9fSAtsushi Murai   struct ifconf ifconfs;
368d8e55738SJordan K. Hubbard   /* struct ifreq reqbuf[256]; -- obsoleted :) */
369d8e55738SJordan K. Hubbard   int oldbufsize, bufsize = sizeof(struct ifreq);
370af57ed9fSAtsushi Murai 
371af57ed9fSAtsushi Murai   s = socket(AF_INET, SOCK_DGRAM, 0);
372af57ed9fSAtsushi Murai   if (s < 0) {
373af57ed9fSAtsushi Murai     perror("socket");
374af57ed9fSAtsushi Murai     return(-1);
375af57ed9fSAtsushi Murai   }
376af57ed9fSAtsushi Murai 
377d8e55738SJordan K. Hubbard   buffer = malloc(bufsize);   /* allocate first buffer */
378d8e55738SJordan K. Hubbard   ifconfs.ifc_len = bufsize;  /* Initial setting */
379d8e55738SJordan K. Hubbard   /*
380d8e55738SJordan K. Hubbard    * Iterate through here until we don't get many more data
381d8e55738SJordan K. Hubbard    */
382d8e55738SJordan K. Hubbard 
383d8e55738SJordan K. Hubbard   do {
384d8e55738SJordan K. Hubbard       oldbufsize = ifconfs.ifc_len;
385d8e55738SJordan K. Hubbard       bufsize += 1+sizeof(struct ifreq);
386d8e55738SJordan K. Hubbard       buffer = realloc((void *)buffer, bufsize);      /* Make it bigger */
387d8e55738SJordan K. Hubbard #ifdef DEBUG
388d8e55738SJordan K. Hubbard       logprintf ("Growing buffer to %d\n", bufsize);
389d8e55738SJordan K. Hubbard #endif
390d8e55738SJordan K. Hubbard       ifconfs.ifc_len = bufsize;
391d8e55738SJordan K. Hubbard       ifconfs.ifc_buf = buffer;
392af57ed9fSAtsushi Murai       if (ioctl(s, SIOCGIFCONF, &ifconfs) < 0) {
393af57ed9fSAtsushi Murai           perror("IFCONF");
394d8e55738SJordan K. Hubbard           free(buffer);
395af57ed9fSAtsushi Murai           return(-1);
396af57ed9fSAtsushi Murai       }
397d8e55738SJordan K. Hubbard   } while (ifconfs.ifc_len > oldbufsize);
398af57ed9fSAtsushi Murai 
399af57ed9fSAtsushi Murai   ifrp = ifconfs.ifc_req;
400af57ed9fSAtsushi Murai 
401af57ed9fSAtsushi Murai   index = 1;
402af57ed9fSAtsushi Murai   for (len = ifconfs.ifc_len; len > 0; len -= sizeof(struct ifreq)) {
403af57ed9fSAtsushi Murai     elen = ifrp->ifr_addr.sa_len - sizeof(struct sockaddr);
404af57ed9fSAtsushi Murai     if (ifrp->ifr_addr.sa_family == AF_LINK) {
405af57ed9fSAtsushi Murai #ifdef DEBUG
406af57ed9fSAtsushi Murai       logprintf("%d: %-*.*s, %d, %d\n", index, IFNAMSIZ, IFNAMSIZ, ifrp->ifr_name,
407af57ed9fSAtsushi Murai 	   ifrp->ifr_addr.sa_family, elen);
408af57ed9fSAtsushi Murai #endif
409af57ed9fSAtsushi Murai       if (strcmp(ifrp->ifr_name, name) == 0) {
410af57ed9fSAtsushi Murai         IfIndex = index;
411d8e55738SJordan K. Hubbard       free(buffer);
412af57ed9fSAtsushi Murai         return(index);
413af57ed9fSAtsushi Murai       }
414af57ed9fSAtsushi Murai       index++;
415af57ed9fSAtsushi Murai     }
416af57ed9fSAtsushi Murai 
417af57ed9fSAtsushi Murai     len -= elen;
418af57ed9fSAtsushi Murai     ifrp = (struct ifreq *)((char *)ifrp + elen);
419af57ed9fSAtsushi Murai     ifrp++;
420af57ed9fSAtsushi Murai   }
421af57ed9fSAtsushi Murai 
422af57ed9fSAtsushi Murai   close(s);
423d8e55738SJordan K. Hubbard   free(buffer);
424af57ed9fSAtsushi Murai   return(-1);
425af57ed9fSAtsushi Murai }
426