in.c revision 1.83 1 /* $NetBSD: in.c,v 1.83 2003/06/13 07:59:57 onoe Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 /*-
33 * Copyright (c) 1998 The NetBSD Foundation, Inc.
34 * All rights reserved.
35 *
36 * This code is derived from software contributed to The NetBSD Foundation
37 * by Public Access Networks Corporation ("Panix"). It was developed under
38 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by the NetBSD
51 * Foundation, Inc. and its contributors.
52 * 4. Neither the name of The NetBSD Foundation nor the names of its
53 * contributors may be used to endorse or promote products derived
54 * from this software without specific prior written permission.
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
57 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
58 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
59 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
60 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
61 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
62 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
64 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
66 * POSSIBILITY OF SUCH DAMAGE.
67 */
68
69 /*
70 * Copyright (c) 1982, 1986, 1991, 1993
71 * The Regents of the University of California. All rights reserved.
72 *
73 * Redistribution and use in source and binary forms, with or without
74 * modification, are permitted provided that the following conditions
75 * are met:
76 * 1. Redistributions of source code must retain the above copyright
77 * notice, this list of conditions and the following disclaimer.
78 * 2. Redistributions in binary form must reproduce the above copyright
79 * notice, this list of conditions and the following disclaimer in the
80 * documentation and/or other materials provided with the distribution.
81 * 3. All advertising materials mentioning features or use of this software
82 * must display the following acknowledgement:
83 * This product includes software developed by the University of
84 * California, Berkeley and its contributors.
85 * 4. Neither the name of the University nor the names of its contributors
86 * may be used to endorse or promote products derived from this software
87 * without specific prior written permission.
88 *
89 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
90 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
91 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
92 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
93 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
94 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
95 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
96 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
97 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
98 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
99 * SUCH DAMAGE.
100 *
101 * @(#)in.c 8.4 (Berkeley) 1/9/95
102 */
103
104 #include <sys/cdefs.h>
105 __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.83 2003/06/13 07:59:57 onoe Exp $");
106
107 #include "opt_inet.h"
108 #include "opt_inet_conf.h"
109 #include "opt_mrouting.h"
110
111 #include <sys/param.h>
112 #include <sys/ioctl.h>
113 #include <sys/errno.h>
114 #include <sys/malloc.h>
115 #include <sys/socket.h>
116 #include <sys/socketvar.h>
117 #include <sys/systm.h>
118 #include <sys/proc.h>
119 #include <sys/syslog.h>
120
121 #include <net/if.h>
122 #include <net/route.h>
123
124 #include <net/if_ether.h>
125
126 #include <netinet/in_systm.h>
127 #include <netinet/in.h>
128 #include <netinet/in_var.h>
129 #include <netinet/if_inarp.h>
130 #include <netinet/ip_mroute.h>
131 #include <netinet/igmp_var.h>
132
133 #ifdef INET
134
135 static u_int in_mask2len __P((struct in_addr *));
136 static void in_len2mask __P((struct in_addr *, u_int));
137 static int in_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
138 struct ifnet *, struct proc *));
139
140 static int in_addprefix __P((struct in_ifaddr *, int));
141 static int in_scrubprefix __P((struct in_ifaddr *));
142
143 #ifndef SUBNETSARELOCAL
144 #define SUBNETSARELOCAL 1
145 #endif
146
147 #ifndef HOSTZEROBROADCAST
148 #define HOSTZEROBROADCAST 1
149 #endif
150
151 int subnetsarelocal = SUBNETSARELOCAL;
152 int hostzeroisbroadcast = HOSTZEROBROADCAST;
153
154 /*
155 * This list is used to keep track of in_multi chains which belong to
156 * deleted interface addresses. We use in_ifaddr so that a chain head
157 * won't be deallocated until all multicast address record are deleted.
158 */
159 static TAILQ_HEAD(, in_ifaddr) in_mk = TAILQ_HEAD_INITIALIZER(in_mk);
160
161 /*
162 * Return 1 if an internet address is for a ``local'' host
163 * (one to which we have a connection). If subnetsarelocal
164 * is true, this includes other subnets of the local net.
165 * Otherwise, it includes only the directly-connected (sub)nets.
166 */
167 int
168 in_localaddr(in)
169 struct in_addr in;
170 {
171 struct in_ifaddr *ia;
172
173 if (subnetsarelocal) {
174 TAILQ_FOREACH(ia, &in_ifaddr, ia_list)
175 if ((in.s_addr & ia->ia_netmask) == ia->ia_net)
176 return (1);
177 } else {
178 TAILQ_FOREACH(ia, &in_ifaddr, ia_list)
179 if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet)
180 return (1);
181 }
182 return (0);
183 }
184
185 /*
186 * Determine whether an IP address is in a reserved set of addresses
187 * that may not be forwarded, or whether datagrams to that destination
188 * may be forwarded.
189 */
190 int
191 in_canforward(in)
192 struct in_addr in;
193 {
194 u_int32_t net;
195
196 if (IN_EXPERIMENTAL(in.s_addr) || IN_MULTICAST(in.s_addr))
197 return (0);
198 if (IN_CLASSA(in.s_addr)) {
199 net = in.s_addr & IN_CLASSA_NET;
200 if (net == 0 || net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
201 return (0);
202 }
203 return (1);
204 }
205
206 /*
207 * Trim a mask in a sockaddr
208 */
209 void
210 in_socktrim(ap)
211 struct sockaddr_in *ap;
212 {
213 char *cplim = (char *) &ap->sin_addr;
214 char *cp = (char *) (&ap->sin_addr + 1);
215
216 ap->sin_len = 0;
217 while (--cp >= cplim)
218 if (*cp) {
219 (ap)->sin_len = cp - (char *) (ap) + 1;
220 break;
221 }
222 }
223
224 /*
225 * Routine to take an Internet address and convert into a
226 * "dotted quad" representation for printing.
227 */
228 const char *
229 in_fmtaddr(addr)
230 struct in_addr addr;
231 {
232 static char buf[sizeof("123.456.789.123")];
233
234 addr.s_addr = ntohl(addr.s_addr);
235
236 sprintf(buf, "%d.%d.%d.%d",
237 (addr.s_addr >> 24) & 0xFF,
238 (addr.s_addr >> 16) & 0xFF,
239 (addr.s_addr >> 8) & 0xFF,
240 (addr.s_addr >> 0) & 0xFF);
241 return buf;
242 }
243
244 /*
245 * Maintain the "in_maxmtu" variable, which is the largest
246 * mtu for non-local interfaces with AF_INET addresses assigned
247 * to them that are up.
248 */
249 unsigned long in_maxmtu;
250
251 void
252 in_setmaxmtu()
253 {
254 struct in_ifaddr *ia;
255 struct ifnet *ifp;
256 unsigned long maxmtu = 0;
257
258 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
259 if ((ifp = ia->ia_ifp) == 0)
260 continue;
261 if ((ifp->if_flags & (IFF_UP|IFF_LOOPBACK)) != IFF_UP)
262 continue;
263 if (ifp->if_mtu > maxmtu)
264 maxmtu = ifp->if_mtu;
265 }
266 if (maxmtu)
267 in_maxmtu = maxmtu;
268 }
269
270 static u_int
271 in_mask2len(mask)
272 struct in_addr *mask;
273 {
274 u_int x, y;
275 u_char *p;
276
277 p = (u_char *)mask;
278 for (x = 0; x < sizeof(*mask); x++) {
279 if (p[x] != 0xff)
280 break;
281 }
282 y = 0;
283 if (x < sizeof(*mask)) {
284 for (y = 0; y < 8; y++) {
285 if ((p[x] & (0x80 >> y)) == 0)
286 break;
287 }
288 }
289 return x * 8 + y;
290 }
291
292 static void
293 in_len2mask(mask, len)
294 struct in_addr *mask;
295 u_int len;
296 {
297 u_int i;
298 u_char *p;
299
300 p = (u_char *)mask;
301 bzero(mask, sizeof(*mask));
302 for (i = 0; i < len / 8; i++)
303 p[i] = 0xff;
304 if (len % 8)
305 p[i] = (0xff00 >> (len % 8)) & 0xff;
306 }
307
308 /*
309 * Generic internet control operations (ioctl's).
310 * Ifp is 0 if not an interface-specific ioctl.
311 */
312 /* ARGSUSED */
313 int
314 in_control(so, cmd, data, ifp, p)
315 struct socket *so;
316 u_long cmd;
317 caddr_t data;
318 struct ifnet *ifp;
319 struct proc *p;
320 {
321 struct ifreq *ifr = (struct ifreq *)data;
322 struct in_ifaddr *ia = 0;
323 struct in_aliasreq *ifra = (struct in_aliasreq *)data;
324 struct sockaddr_in oldaddr;
325 int error, hostIsNew, maskIsNew;
326
327 switch (cmd) {
328 case SIOCALIFADDR:
329 case SIOCDLIFADDR:
330 if (p == 0 || (error = suser(p->p_ucred, &p->p_acflag)))
331 return (EPERM);
332 /*fall through*/
333 case SIOCGLIFADDR:
334 if (!ifp)
335 return EINVAL;
336 return in_lifaddr_ioctl(so, cmd, data, ifp, p);
337 }
338
339 /*
340 * Find address for this interface, if it exists.
341 */
342 if (ifp)
343 IFP_TO_IA(ifp, ia);
344
345 switch (cmd) {
346
347 case SIOCAIFADDR:
348 case SIOCDIFADDR:
349 case SIOCGIFALIAS:
350 if (ifra->ifra_addr.sin_family == AF_INET)
351 LIST_FOREACH(ia,
352 &IN_IFADDR_HASH(ifra->ifra_addr.sin_addr.s_addr),
353 ia_hash) {
354 if (ia->ia_ifp == ifp &&
355 in_hosteq(ia->ia_addr.sin_addr,
356 ifra->ifra_addr.sin_addr))
357 break;
358 }
359 if (cmd == SIOCDIFADDR) {
360 if (ia == 0)
361 return (EADDRNOTAVAIL);
362 #if 1 /*def COMPAT_43*/
363 if (ifra->ifra_addr.sin_family == AF_UNSPEC)
364 ifra->ifra_addr.sin_family = AF_INET;
365 #endif
366 }
367 /* FALLTHROUGH */
368 case SIOCSIFADDR:
369 case SIOCSIFDSTADDR:
370 if (ifra->ifra_addr.sin_family != AF_INET)
371 return (EAFNOSUPPORT);
372 /* FALLTHROUGH */
373 case SIOCSIFNETMASK:
374 if (ifp == 0)
375 panic("in_control");
376
377 if (cmd == SIOCGIFALIAS)
378 break;
379
380 if (p == 0 || (error = suser(p->p_ucred, &p->p_acflag)))
381 return (EPERM);
382
383 if (ia == 0) {
384 MALLOC(ia, struct in_ifaddr *, sizeof(*ia),
385 M_IFADDR, M_WAITOK);
386 if (ia == 0)
387 return (ENOBUFS);
388 bzero((caddr_t)ia, sizeof *ia);
389 TAILQ_INSERT_TAIL(&in_ifaddr, ia, ia_list);
390 IFAREF(&ia->ia_ifa);
391 TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa,
392 ifa_list);
393 IFAREF(&ia->ia_ifa);
394 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
395 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
396 ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
397 ia->ia_sockmask.sin_len = 8;
398 if (ifp->if_flags & IFF_BROADCAST) {
399 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
400 ia->ia_broadaddr.sin_family = AF_INET;
401 }
402 ia->ia_ifp = ifp;
403 LIST_INIT(&ia->ia_multiaddrs);
404 }
405 break;
406
407 case SIOCSIFBRDADDR:
408 if (p == 0 || (error = suser(p->p_ucred, &p->p_acflag)))
409 return (EPERM);
410 /* FALLTHROUGH */
411
412 case SIOCGIFADDR:
413 case SIOCGIFNETMASK:
414 case SIOCGIFDSTADDR:
415 case SIOCGIFBRDADDR:
416 if (ia == 0)
417 return (EADDRNOTAVAIL);
418 break;
419 }
420 switch (cmd) {
421
422 case SIOCGIFADDR:
423 *satosin(&ifr->ifr_addr) = ia->ia_addr;
424 break;
425
426 case SIOCGIFBRDADDR:
427 if ((ifp->if_flags & IFF_BROADCAST) == 0)
428 return (EINVAL);
429 *satosin(&ifr->ifr_dstaddr) = ia->ia_broadaddr;
430 break;
431
432 case SIOCGIFDSTADDR:
433 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
434 return (EINVAL);
435 *satosin(&ifr->ifr_dstaddr) = ia->ia_dstaddr;
436 break;
437
438 case SIOCGIFNETMASK:
439 *satosin(&ifr->ifr_addr) = ia->ia_sockmask;
440 break;
441
442 case SIOCSIFDSTADDR:
443 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
444 return (EINVAL);
445 oldaddr = ia->ia_dstaddr;
446 ia->ia_dstaddr = *satosin(&ifr->ifr_dstaddr);
447 if (ifp->if_ioctl && (error = (*ifp->if_ioctl)
448 (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
449 ia->ia_dstaddr = oldaddr;
450 return (error);
451 }
452 if (ia->ia_flags & IFA_ROUTE) {
453 ia->ia_ifa.ifa_dstaddr = sintosa(&oldaddr);
454 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
455 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
456 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
457 }
458 break;
459
460 case SIOCSIFBRDADDR:
461 if ((ifp->if_flags & IFF_BROADCAST) == 0)
462 return (EINVAL);
463 ia->ia_broadaddr = *satosin(&ifr->ifr_broadaddr);
464 break;
465
466 case SIOCSIFADDR:
467 error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1);
468 return error;
469
470 case SIOCSIFNETMASK:
471 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr =
472 ifra->ifra_addr.sin_addr.s_addr;
473 break;
474
475 case SIOCAIFADDR:
476 maskIsNew = 0;
477 hostIsNew = 1;
478 error = 0;
479 if (ia->ia_addr.sin_family == AF_INET) {
480 if (ifra->ifra_addr.sin_len == 0) {
481 ifra->ifra_addr = ia->ia_addr;
482 hostIsNew = 0;
483 } else if (in_hosteq(ia->ia_addr.sin_addr, ifra->ifra_addr.sin_addr))
484 hostIsNew = 0;
485 }
486 if (ifra->ifra_mask.sin_len) {
487 in_ifscrub(ifp, ia);
488 ia->ia_sockmask = ifra->ifra_mask;
489 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr;
490 maskIsNew = 1;
491 }
492 if ((ifp->if_flags & IFF_POINTOPOINT) &&
493 (ifra->ifra_dstaddr.sin_family == AF_INET)) {
494 in_ifscrub(ifp, ia);
495 ia->ia_dstaddr = ifra->ifra_dstaddr;
496 maskIsNew = 1; /* We lie; but the effect's the same */
497 }
498 if (ifra->ifra_addr.sin_family == AF_INET &&
499 (hostIsNew || maskIsNew)) {
500 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
501 }
502 if ((ifp->if_flags & IFF_BROADCAST) &&
503 (ifra->ifra_broadaddr.sin_family == AF_INET))
504 ia->ia_broadaddr = ifra->ifra_broadaddr;
505 return (error);
506
507 case SIOCGIFALIAS:
508 ifra->ifra_mask = ia->ia_sockmask;
509 if ((ifp->if_flags & IFF_POINTOPOINT) &&
510 (ia->ia_dstaddr.sin_family == AF_INET))
511 ifra->ifra_dstaddr = ia->ia_dstaddr;
512 else if ((ifp->if_flags & IFF_BROADCAST) &&
513 (ia->ia_broadaddr.sin_family == AF_INET))
514 ifra->ifra_broadaddr = ia->ia_broadaddr;
515 else
516 bzero(&ifra->ifra_broadaddr,
517 sizeof(ifra->ifra_broadaddr));
518 return 0;
519
520 case SIOCDIFADDR:
521 in_purgeaddr(&ia->ia_ifa, ifp);
522 break;
523
524 #ifdef MROUTING
525 case SIOCGETVIFCNT:
526 case SIOCGETSGCNT:
527 return (mrt_ioctl(so, cmd, data));
528 #endif /* MROUTING */
529
530 default:
531 if (ifp == 0 || ifp->if_ioctl == 0)
532 return (EOPNOTSUPP);
533 error = (*ifp->if_ioctl)(ifp, cmd, data);
534 in_setmaxmtu();
535 return (error);
536 }
537 return (0);
538 }
539
540 void
541 in_purgeaddr(ifa, ifp)
542 struct ifaddr *ifa;
543 struct ifnet *ifp;
544 {
545 struct in_ifaddr *ia = (void *) ifa;
546
547 in_ifscrub(ifp, ia);
548 LIST_REMOVE(ia, ia_hash);
549 TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
550 IFAFREE(&ia->ia_ifa);
551 TAILQ_REMOVE(&in_ifaddr, ia, ia_list);
552 if (ia->ia_allhosts != NULL)
553 in_delmulti(ia->ia_allhosts);
554 if (LIST_FIRST(&ia->ia_multiaddrs) != NULL &&
555 /*
556 * If the interface is going away, don't bother to save
557 * the multicast entries.
558 */
559 ifp->if_output != if_nulloutput)
560 in_savemkludge(ia);
561 IFAFREE(&ia->ia_ifa);
562 in_setmaxmtu();
563 }
564
565 void
566 in_purgeif(ifp)
567 struct ifnet *ifp;
568 {
569 struct ifaddr *ifa, *nifa;
570
571 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa) {
572 nifa = TAILQ_NEXT(ifa, ifa_list);
573 if (ifa->ifa_addr->sa_family != AF_INET)
574 continue;
575 in_purgeaddr(ifa, ifp);
576 }
577 in_purgemkludge(ifp);
578 }
579
580 /*
581 * SIOC[GAD]LIFADDR.
582 * SIOCGLIFADDR: get first address. (???)
583 * SIOCGLIFADDR with IFLR_PREFIX:
584 * get first address that matches the specified prefix.
585 * SIOCALIFADDR: add the specified address.
586 * SIOCALIFADDR with IFLR_PREFIX:
587 * EINVAL since we can't deduce hostid part of the address.
588 * SIOCDLIFADDR: delete the specified address.
589 * SIOCDLIFADDR with IFLR_PREFIX:
590 * delete the first address that matches the specified prefix.
591 * return values:
592 * EINVAL on invalid parameters
593 * EADDRNOTAVAIL on prefix match failed/specified address not found
594 * other values may be returned from in_ioctl()
595 */
596 static int
597 in_lifaddr_ioctl(so, cmd, data, ifp, p)
598 struct socket *so;
599 u_long cmd;
600 caddr_t data;
601 struct ifnet *ifp;
602 struct proc *p;
603 {
604 struct if_laddrreq *iflr = (struct if_laddrreq *)data;
605 struct ifaddr *ifa;
606 struct sockaddr *sa;
607
608 /* sanity checks */
609 if (!data || !ifp) {
610 panic("invalid argument to in_lifaddr_ioctl");
611 /*NOTRECHED*/
612 }
613
614 switch (cmd) {
615 case SIOCGLIFADDR:
616 /* address must be specified on GET with IFLR_PREFIX */
617 if ((iflr->flags & IFLR_PREFIX) == 0)
618 break;
619 /*FALLTHROUGH*/
620 case SIOCALIFADDR:
621 case SIOCDLIFADDR:
622 /* address must be specified on ADD and DELETE */
623 sa = (struct sockaddr *)&iflr->addr;
624 if (sa->sa_family != AF_INET)
625 return EINVAL;
626 if (sa->sa_len != sizeof(struct sockaddr_in))
627 return EINVAL;
628 /* XXX need improvement */
629 sa = (struct sockaddr *)&iflr->dstaddr;
630 if (sa->sa_family
631 && sa->sa_family != AF_INET)
632 return EINVAL;
633 if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in))
634 return EINVAL;
635 break;
636 default: /*shouldn't happen*/
637 #if 0
638 panic("invalid cmd to in_lifaddr_ioctl");
639 /*NOTREACHED*/
640 #else
641 return EOPNOTSUPP;
642 #endif
643 }
644 if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
645 return EINVAL;
646
647 switch (cmd) {
648 case SIOCALIFADDR:
649 {
650 struct in_aliasreq ifra;
651
652 if (iflr->flags & IFLR_PREFIX)
653 return EINVAL;
654
655 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
656 bzero(&ifra, sizeof(ifra));
657 bcopy(iflr->iflr_name, ifra.ifra_name,
658 sizeof(ifra.ifra_name));
659
660 bcopy(&iflr->addr, &ifra.ifra_addr,
661 ((struct sockaddr *)&iflr->addr)->sa_len);
662
663 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /*XXX*/
664 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
665 ((struct sockaddr *)&iflr->dstaddr)->sa_len);
666 }
667
668 ifra.ifra_mask.sin_family = AF_INET;
669 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
670 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
671
672 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, p);
673 }
674 case SIOCGLIFADDR:
675 case SIOCDLIFADDR:
676 {
677 struct in_ifaddr *ia;
678 struct in_addr mask, candidate, match;
679 struct sockaddr_in *sin;
680 int cmp;
681
682 bzero(&mask, sizeof(mask));
683 if (iflr->flags & IFLR_PREFIX) {
684 /* lookup a prefix rather than address. */
685 in_len2mask(&mask, iflr->prefixlen);
686
687 sin = (struct sockaddr_in *)&iflr->addr;
688 match.s_addr = sin->sin_addr.s_addr;
689 match.s_addr &= mask.s_addr;
690
691 /* if you set extra bits, that's wrong */
692 if (match.s_addr != sin->sin_addr.s_addr)
693 return EINVAL;
694
695 cmp = 1;
696 } else {
697 if (cmd == SIOCGLIFADDR) {
698 /* on getting an address, take the 1st match */
699 cmp = 0; /*XXX*/
700 } else {
701 /* on deleting an address, do exact match */
702 in_len2mask(&mask, 32);
703 sin = (struct sockaddr_in *)&iflr->addr;
704 match.s_addr = sin->sin_addr.s_addr;
705
706 cmp = 1;
707 }
708 }
709
710 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
711 if (ifa->ifa_addr->sa_family != AF_INET6)
712 continue;
713 if (!cmp)
714 break;
715 candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
716 candidate.s_addr &= mask.s_addr;
717 if (candidate.s_addr == match.s_addr)
718 break;
719 }
720 if (!ifa)
721 return EADDRNOTAVAIL;
722 ia = (struct in_ifaddr *)ifa;
723
724 if (cmd == SIOCGLIFADDR) {
725 /* fill in the if_laddrreq structure */
726 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
727
728 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
729 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
730 ia->ia_dstaddr.sin_len);
731 } else
732 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
733
734 iflr->prefixlen =
735 in_mask2len(&ia->ia_sockmask.sin_addr);
736
737 iflr->flags = 0; /*XXX*/
738
739 return 0;
740 } else {
741 struct in_aliasreq ifra;
742
743 /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
744 bzero(&ifra, sizeof(ifra));
745 bcopy(iflr->iflr_name, ifra.ifra_name,
746 sizeof(ifra.ifra_name));
747
748 bcopy(&ia->ia_addr, &ifra.ifra_addr,
749 ia->ia_addr.sin_len);
750 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
751 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
752 ia->ia_dstaddr.sin_len);
753 }
754 bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
755 ia->ia_sockmask.sin_len);
756
757 return in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
758 ifp, p);
759 }
760 }
761 }
762
763 return EOPNOTSUPP; /*just for safety*/
764 }
765
766 /*
767 * Delete any existing route for an interface.
768 */
769 void
770 in_ifscrub(ifp, ia)
771 struct ifnet *ifp;
772 struct in_ifaddr *ia;
773 {
774
775 in_scrubprefix(ia);
776 }
777
778 /*
779 * Initialize an interface's internet address
780 * and routing table entry.
781 */
782 int
783 in_ifinit(ifp, ia, sin, scrub)
784 struct ifnet *ifp;
785 struct in_ifaddr *ia;
786 struct sockaddr_in *sin;
787 int scrub;
788 {
789 u_int32_t i = sin->sin_addr.s_addr;
790 struct sockaddr_in oldaddr;
791 int s = splnet(), flags = RTF_UP, error;
792
793 /*
794 * Set up new addresses.
795 */
796 oldaddr = ia->ia_addr;
797 if (ia->ia_addr.sin_family == AF_INET)
798 LIST_REMOVE(ia, ia_hash);
799 ia->ia_addr = *sin;
800 LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
801
802 /*
803 * Give the interface a chance to initialize
804 * if this is its first address,
805 * and to validate the address if necessary.
806 */
807 if (ifp->if_ioctl &&
808 (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia)))
809 goto bad;
810 splx(s);
811 if (scrub) {
812 ia->ia_ifa.ifa_addr = sintosa(&oldaddr);
813 in_ifscrub(ifp, ia);
814 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
815 }
816
817 if (IN_CLASSA(i))
818 ia->ia_netmask = IN_CLASSA_NET;
819 else if (IN_CLASSB(i))
820 ia->ia_netmask = IN_CLASSB_NET;
821 else
822 ia->ia_netmask = IN_CLASSC_NET;
823 /*
824 * The subnet mask usually includes at least the standard network part,
825 * but may may be smaller in the case of supernetting.
826 * If it is set, we believe it.
827 */
828 if (ia->ia_subnetmask == 0) {
829 ia->ia_subnetmask = ia->ia_netmask;
830 ia->ia_sockmask.sin_addr.s_addr = ia->ia_subnetmask;
831 } else
832 ia->ia_netmask &= ia->ia_subnetmask;
833
834 ia->ia_net = i & ia->ia_netmask;
835 ia->ia_subnet = i & ia->ia_subnetmask;
836 in_socktrim(&ia->ia_sockmask);
837 /* re-calculate the "in_maxmtu" value */
838 in_setmaxmtu();
839 /*
840 * Add route for the network.
841 */
842 ia->ia_ifa.ifa_metric = ifp->if_metric;
843 if (ifp->if_flags & IFF_BROADCAST) {
844 ia->ia_broadaddr.sin_addr.s_addr =
845 ia->ia_subnet | ~ia->ia_subnetmask;
846 ia->ia_netbroadcast.s_addr =
847 ia->ia_net | ~ia->ia_netmask;
848 } else if (ifp->if_flags & IFF_LOOPBACK) {
849 ia->ia_dstaddr = ia->ia_addr;
850 flags |= RTF_HOST;
851 } else if (ifp->if_flags & IFF_POINTOPOINT) {
852 if (ia->ia_dstaddr.sin_family != AF_INET)
853 return (0);
854 flags |= RTF_HOST;
855 }
856 error = in_addprefix(ia, flags);
857 /*
858 * recover multicast kludge entry, if there is.
859 */
860 if (ifp->if_flags & IFF_MULTICAST)
861 in_restoremkludge(ia, ifp);
862 /*
863 * If the interface supports multicast, join the "all hosts"
864 * multicast group on that interface.
865 */
866 if ((ifp->if_flags & IFF_MULTICAST) != 0 && ia->ia_allhosts == NULL) {
867 struct in_addr addr;
868
869 addr.s_addr = INADDR_ALLHOSTS_GROUP;
870 ia->ia_allhosts = in_addmulti(&addr, ifp);
871 }
872 return (error);
873 bad:
874 splx(s);
875 LIST_REMOVE(ia, ia_hash);
876 ia->ia_addr = oldaddr;
877 if (ia->ia_addr.sin_family == AF_INET)
878 LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr),
879 ia, ia_hash);
880 return (error);
881 }
882
883 #define rtinitflags(x) \
884 ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
885 ? RTF_HOST : 0)
886
887 /*
888 * add a route to prefix ("connected route" in cisco terminology).
889 * does nothing if there's some interface address with the same prefix already.
890 */
891 static int
892 in_addprefix(target, flags)
893 struct in_ifaddr *target;
894 int flags;
895 {
896 struct in_ifaddr *ia;
897 struct in_addr prefix, mask, p;
898 int error;
899
900 if ((flags & RTF_HOST) != 0)
901 prefix = target->ia_dstaddr.sin_addr;
902 else
903 prefix = target->ia_addr.sin_addr;
904 mask = target->ia_sockmask.sin_addr;
905 prefix.s_addr &= mask.s_addr;
906
907 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
908 /* easy one first */
909 if (mask.s_addr != ia->ia_sockmask.sin_addr.s_addr)
910 continue;
911
912 if (rtinitflags(ia))
913 p = ia->ia_dstaddr.sin_addr;
914 else
915 p = ia->ia_addr.sin_addr;
916 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
917 if (prefix.s_addr != p.s_addr)
918 continue;
919
920 /*
921 * if we got a matching prefix route inserted by other
922 * interface address, we don't need to bother
923 */
924 if (ia->ia_flags & IFA_ROUTE)
925 return 0;
926 }
927
928 /*
929 * noone seem to have prefix route. insert it.
930 */
931 error = rtinit(&target->ia_ifa, (int)RTM_ADD, flags);
932 if (!error)
933 target->ia_flags |= IFA_ROUTE;
934 return error;
935 }
936
937 /*
938 * remove a route to prefix ("connected route" in cisco terminology).
939 * re-installs the route by using another interface address, if there's one
940 * with the same prefix (otherwise we lose the route mistakenly).
941 */
942 static int
943 in_scrubprefix(target)
944 struct in_ifaddr *target;
945 {
946 struct in_ifaddr *ia;
947 struct in_addr prefix, mask, p;
948 int error;
949
950 if ((target->ia_flags & IFA_ROUTE) == 0)
951 return 0;
952
953 if (rtinitflags(target))
954 prefix = target->ia_dstaddr.sin_addr;
955 else
956 prefix = target->ia_addr.sin_addr;
957 mask = target->ia_sockmask.sin_addr;
958 prefix.s_addr &= mask.s_addr;
959
960 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
961 /* easy one first */
962 if (mask.s_addr != ia->ia_sockmask.sin_addr.s_addr)
963 continue;
964
965 if (rtinitflags(ia))
966 p = ia->ia_dstaddr.sin_addr;
967 else
968 p = ia->ia_addr.sin_addr;
969 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
970 if (prefix.s_addr != p.s_addr)
971 continue;
972
973 /*
974 * if we got a matching prefix route, move IFA_ROUTE to him
975 */
976 if ((ia->ia_flags & IFA_ROUTE) == 0) {
977 rtinit(&(target->ia_ifa), (int)RTM_DELETE,
978 rtinitflags(target));
979 target->ia_flags &= ~IFA_ROUTE;
980
981 error = rtinit(&ia->ia_ifa, (int)RTM_ADD,
982 rtinitflags(ia) | RTF_UP);
983 if (error == 0)
984 ia->ia_flags |= IFA_ROUTE;
985 return error;
986 }
987 }
988
989 /*
990 * noone seem to have prefix route. remove it.
991 */
992 rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
993 target->ia_flags &= ~IFA_ROUTE;
994 return 0;
995 }
996
997 #undef rtinitflags
998
999 /*
1000 * Return 1 if the address might be a local broadcast address.
1001 */
1002 int
1003 in_broadcast(in, ifp)
1004 struct in_addr in;
1005 struct ifnet *ifp;
1006 {
1007 struct ifaddr *ifa;
1008
1009 if (in.s_addr == INADDR_BROADCAST ||
1010 in_nullhost(in))
1011 return 1;
1012 if ((ifp->if_flags & IFF_BROADCAST) == 0)
1013 return 0;
1014 /*
1015 * Look through the list of addresses for a match
1016 * with a broadcast address.
1017 */
1018 #define ia (ifatoia(ifa))
1019 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1020 if (ifa->ifa_addr->sa_family == AF_INET &&
1021 !in_hosteq(in, ia->ia_addr.sin_addr) &&
1022 (in_hosteq(in, ia->ia_broadaddr.sin_addr) ||
1023 in_hosteq(in, ia->ia_netbroadcast) ||
1024 (hostzeroisbroadcast &&
1025 /*
1026 * Check for old-style (host 0) broadcast.
1027 */
1028 (in.s_addr == ia->ia_subnet ||
1029 in.s_addr == ia->ia_net))))
1030 return 1;
1031 return (0);
1032 #undef ia
1033 }
1034
1035 /*
1036 * Multicast address kludge:
1037 * If there were any multicast addresses attached to this interface address,
1038 * either move them to another address on this interface, or save them until
1039 * such time as this interface is reconfigured for IPv4.
1040 */
1041 void
1042 in_savemkludge(oia)
1043 struct in_ifaddr *oia;
1044 {
1045 struct in_ifaddr *ia;
1046 struct in_multi *inm, *next;
1047
1048 IFP_TO_IA(oia->ia_ifp, ia);
1049 if (ia) { /* there is another address */
1050 for (inm = LIST_FIRST(&oia->ia_multiaddrs); inm; inm = next){
1051 next = LIST_NEXT(inm, inm_list);
1052 LIST_REMOVE(inm, inm_list);
1053 IFAFREE(&inm->inm_ia->ia_ifa);
1054 IFAREF(&ia->ia_ifa);
1055 inm->inm_ia = ia;
1056 LIST_INSERT_HEAD(&ia->ia_multiaddrs, inm, inm_list);
1057 }
1058 } else { /* last address on this if deleted, save */
1059 TAILQ_INSERT_TAIL(&in_mk, oia, ia_list);
1060 IFAREF(&oia->ia_ifa);
1061 }
1062 }
1063
1064 /*
1065 * Continuation of multicast address hack:
1066 * If there was a multicast group list previously saved for this interface,
1067 * then we re-attach it to the first address configured on the i/f.
1068 */
1069 void
1070 in_restoremkludge(ia, ifp)
1071 struct in_ifaddr *ia;
1072 struct ifnet *ifp;
1073 {
1074 struct in_ifaddr *oia;
1075
1076 for (oia = TAILQ_FIRST(&in_mk); oia != NULL;
1077 oia = TAILQ_NEXT(oia, ia_list)) {
1078 if (oia->ia_ifp == ifp) {
1079 struct in_multi *inm, *next;
1080
1081 for (inm = LIST_FIRST(&oia->ia_multiaddrs);
1082 inm != NULL; inm = next) {
1083 next = LIST_NEXT(inm, inm_list);
1084 LIST_REMOVE(inm, inm_list);
1085 IFAFREE(&inm->inm_ia->ia_ifa);
1086 IFAREF(&ia->ia_ifa);
1087 inm->inm_ia = ia;
1088 LIST_INSERT_HEAD(&ia->ia_multiaddrs,
1089 inm, inm_list);
1090 }
1091 TAILQ_REMOVE(&in_mk, oia, ia_list);
1092 IFAFREE(&oia->ia_ifa);
1093 break;
1094 }
1095 }
1096 }
1097
1098 void
1099 in_purgemkludge(ifp)
1100 struct ifnet *ifp;
1101 {
1102 struct in_ifaddr *oia;
1103
1104 for (oia = TAILQ_FIRST(&in_mk); oia != NULL;
1105 oia = TAILQ_NEXT(oia, ia_list)) {
1106 if (oia->ia_ifp != ifp)
1107 continue;
1108
1109 /*
1110 * Leaving from all multicast groups joined through
1111 * this interface is done via in_pcbpurgeif().
1112 */
1113
1114 TAILQ_REMOVE(&in_mk, oia, ia_list);
1115 IFAFREE(&oia->ia_ifa);
1116 break;
1117 }
1118 }
1119
1120 /*
1121 * Add an address to the list of IP multicast addresses for a given interface.
1122 */
1123 struct in_multi *
1124 in_addmulti(ap, ifp)
1125 struct in_addr *ap;
1126 struct ifnet *ifp;
1127 {
1128 struct in_multi *inm;
1129 struct ifreq ifr;
1130 struct in_ifaddr *ia;
1131 int s = splsoftnet();
1132
1133 /*
1134 * See if address already in list.
1135 */
1136 IN_LOOKUP_MULTI(*ap, ifp, inm);
1137 if (inm != NULL) {
1138 /*
1139 * Found it; just increment the reference count.
1140 */
1141 ++inm->inm_refcount;
1142 } else {
1143 /*
1144 * New address; allocate a new multicast record
1145 * and link it into the interface's multicast list.
1146 */
1147 inm = (struct in_multi *)malloc(sizeof(*inm),
1148 M_IPMADDR, M_NOWAIT);
1149 if (inm == NULL) {
1150 splx(s);
1151 return (NULL);
1152 }
1153 inm->inm_addr = *ap;
1154 inm->inm_ifp = ifp;
1155 inm->inm_refcount = 1;
1156 IFP_TO_IA(ifp, ia);
1157 if (ia == NULL) {
1158 free(inm, M_IPMADDR);
1159 splx(s);
1160 return (NULL);
1161 }
1162 inm->inm_ia = ia;
1163 IFAREF(&inm->inm_ia->ia_ifa);
1164 LIST_INSERT_HEAD(&ia->ia_multiaddrs, inm, inm_list);
1165 /*
1166 * Ask the network driver to update its multicast reception
1167 * filter appropriately for the new address.
1168 */
1169 satosin(&ifr.ifr_addr)->sin_len = sizeof(struct sockaddr_in);
1170 satosin(&ifr.ifr_addr)->sin_family = AF_INET;
1171 satosin(&ifr.ifr_addr)->sin_addr = *ap;
1172 if ((ifp->if_ioctl == NULL) ||
1173 (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
1174 LIST_REMOVE(inm, inm_list);
1175 free(inm, M_IPMADDR);
1176 splx(s);
1177 return (NULL);
1178 }
1179 /*
1180 * Let IGMP know that we have joined a new IP multicast group.
1181 */
1182 igmp_joingroup(inm);
1183 }
1184 splx(s);
1185 return (inm);
1186 }
1187
1188 /*
1189 * Delete a multicast address record.
1190 */
1191 void
1192 in_delmulti(inm)
1193 struct in_multi *inm;
1194 {
1195 struct ifreq ifr;
1196 int s = splsoftnet();
1197
1198 if (--inm->inm_refcount == 0) {
1199 /*
1200 * No remaining claims to this record; let IGMP know that
1201 * we are leaving the multicast group.
1202 */
1203 igmp_leavegroup(inm);
1204 /*
1205 * Unlink from list.
1206 */
1207 LIST_REMOVE(inm, inm_list);
1208 IFAFREE(&inm->inm_ia->ia_ifa);
1209 /*
1210 * Notify the network driver to update its multicast reception
1211 * filter.
1212 */
1213 satosin(&ifr.ifr_addr)->sin_family = AF_INET;
1214 satosin(&ifr.ifr_addr)->sin_addr = inm->inm_addr;
1215 (*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI,
1216 (caddr_t)&ifr);
1217 free(inm, M_IPMADDR);
1218 }
1219 splx(s);
1220 }
1221 #endif
1222