1 /* $OpenBSD: in.c,v 1.49 2007/07/20 19:00:35 claudio Exp $ */
2 /* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */
3
4 /*
5 * Copyright (C) 2001 WIDE Project. 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) 1982, 1986, 1991, 1993
34 * The Regents of the University of California. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)in.c 8.2 (Berkeley) 11/15/93
61 */
62
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/ioctl.h>
66 #include <sys/malloc.h>
67 #include <sys/socket.h>
68 #include <sys/socketvar.h>
69
70 #include <net/if.h>
71 #include <net/route.h>
72
73 #include "carp.h"
74 #if NCARP > 0
75 #include <net/if_types.h>
76 #endif
77
78 #include <netinet/in.h>
79 #include <netinet/in_var.h>
80 #include <netinet/igmp_var.h>
81
82 #ifdef MROUTING
83 #include <netinet/ip_mroute.h>
84 #endif
85
86 #include "ether.h"
87
88 #ifdef INET
89
90 int in_mask2len(struct in_addr *);
91 void in_len2mask(struct in_addr *, int);
92 int in_lifaddr_ioctl(struct socket *, u_long, caddr_t,
93 struct ifnet *);
94
95 int in_addprefix(struct in_ifaddr *, int);
96 int in_scrubprefix(struct in_ifaddr *);
97
98 #ifndef SUBNETSARELOCAL
99 #define SUBNETSARELOCAL 0
100 #endif
101
102 #ifndef HOSTZEROBROADCAST
103 #define HOSTZEROBROADCAST 1
104 #endif
105
106 int subnetsarelocal = SUBNETSARELOCAL;
107 int hostzeroisbroadcast = HOSTZEROBROADCAST;
108
109 /*
110 * Return 1 if an internet address is for a ``local'' host
111 * (one to which we have a connection). If subnetsarelocal
112 * is true, this includes other subnets of the local net.
113 * Otherwise, it includes only the directly-connected (sub)nets.
114 */
115 int
116 in_localaddr(in)
117 struct in_addr in;
118 {
119 struct in_ifaddr *ia;
120
121 if (subnetsarelocal) {
122 TAILQ_FOREACH(ia, &in_ifaddr, ia_list)
123 if ((in.s_addr & ia->ia_netmask) == ia->ia_net)
124 return (1);
125 } else {
126 TAILQ_FOREACH(ia, &in_ifaddr, ia_list)
127 if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet)
128 return (1);
129 }
130 return (0);
131 }
132
133 /*
134 * Determine whether an IP address is in a reserved set of addresses
135 * that may not be forwarded, or whether datagrams to that destination
136 * may be forwarded.
137 */
138 int
139 in_canforward(in)
140 struct in_addr in;
141 {
142 u_int32_t net;
143
144 if (IN_EXPERIMENTAL(in.s_addr) || IN_MULTICAST(in.s_addr))
145 return (0);
146 if (IN_CLASSA(in.s_addr)) {
147 net = in.s_addr & IN_CLASSA_NET;
148 if (net == 0 || net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
149 return (0);
150 }
151 return (1);
152 }
153
154 /*
155 * Trim a mask in a sockaddr
156 */
157 void
158 in_socktrim(ap)
159 struct sockaddr_in *ap;
160 {
161 char *cplim = (char *) &ap->sin_addr;
162 char *cp = (char *) (&ap->sin_addr + 1);
163
164 ap->sin_len = 0;
165 while (--cp >= cplim)
166 if (*cp) {
167 (ap)->sin_len = cp - (char *) (ap) + 1;
168 break;
169 }
170 }
171
172 int
173 in_mask2len(mask)
174 struct in_addr *mask;
175 {
176 int x, y;
177 u_char *p;
178
179 p = (u_char *)mask;
180 for (x = 0; x < sizeof(*mask); x++) {
181 if (p[x] != 0xff)
182 break;
183 }
184 y = 0;
185 if (x < sizeof(*mask)) {
186 for (y = 0; y < 8; y++) {
187 if ((p[x] & (0x80 >> y)) == 0)
188 break;
189 }
190 }
191 return x * 8 + y;
192 }
193
194 void
195 in_len2mask(mask, len)
196 struct in_addr *mask;
197 int len;
198 {
199 int i;
200 u_char *p;
201
202 p = (u_char *)mask;
203 bzero(mask, sizeof(*mask));
204 for (i = 0; i < len / 8; i++)
205 p[i] = 0xff;
206 if (len % 8)
207 p[i] = (0xff00 >> (len % 8)) & 0xff;
208 }
209
210 int in_interfaces; /* number of external internet interfaces */
211
212 /*
213 * Generic internet control operations (ioctl's).
214 * Ifp is 0 if not an interface-specific ioctl.
215 */
216 /* ARGSUSED */
217 int
218 in_control(so, cmd, data, ifp)
219 struct socket *so;
220 u_long cmd;
221 caddr_t data;
222 struct ifnet *ifp;
223 {
224 struct ifreq *ifr = (struct ifreq *)data;
225 struct in_ifaddr *ia = 0;
226 struct in_aliasreq *ifra = (struct in_aliasreq *)data;
227 struct sockaddr_in oldaddr;
228 int error, hostIsNew, maskIsNew;
229 int newifaddr;
230 int s;
231
232 switch (cmd) {
233 case SIOCALIFADDR:
234 case SIOCDLIFADDR:
235 if ((so->so_state & SS_PRIV) == 0)
236 return (EPERM);
237 /* FALLTHROUGH */
238 case SIOCGLIFADDR:
239 if (!ifp)
240 return EINVAL;
241 return in_lifaddr_ioctl(so, cmd, data, ifp);
242 }
243
244 /*
245 * Find address for this interface, if it exists.
246 */
247 if (ifp)
248 TAILQ_FOREACH(ia, &in_ifaddr, ia_list)
249 if (ia->ia_ifp == ifp)
250 break;
251
252 switch (cmd) {
253
254 case SIOCAIFADDR:
255 case SIOCDIFADDR:
256 if (ifra->ifra_addr.sin_family == AF_INET)
257 for (; ia != TAILQ_END(&in_ifaddr);
258 ia = TAILQ_NEXT(ia, ia_list)) {
259 if (ia->ia_ifp == ifp &&
260 ia->ia_addr.sin_addr.s_addr ==
261 ifra->ifra_addr.sin_addr.s_addr)
262 break;
263 }
264 if (cmd == SIOCDIFADDR && ia == 0)
265 return (EADDRNOTAVAIL);
266 /* FALLTHROUGH */
267 case SIOCSIFADDR:
268 case SIOCSIFNETMASK:
269 case SIOCSIFDSTADDR:
270 if ((so->so_state & SS_PRIV) == 0)
271 return (EPERM);
272
273 if (ifp == 0)
274 panic("in_control");
275 if (ia == (struct in_ifaddr *)0) {
276 ia = (struct in_ifaddr *)
277 malloc(sizeof *ia, M_IFADDR, M_WAITOK);
278 bzero((caddr_t)ia, sizeof *ia);
279 s = splsoftnet();
280 TAILQ_INSERT_TAIL(&in_ifaddr, ia, ia_list);
281 TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia,
282 ifa_list);
283 ia->ia_addr.sin_family = AF_INET;
284 ia->ia_addr.sin_len = sizeof(ia->ia_addr);
285 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
286 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
287 ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
288 ia->ia_sockmask.sin_len = 8;
289 if (ifp->if_flags & IFF_BROADCAST) {
290 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
291 ia->ia_broadaddr.sin_family = AF_INET;
292 }
293 ia->ia_ifp = ifp;
294 LIST_INIT(&ia->ia_multiaddrs);
295 if ((ifp->if_flags & IFF_LOOPBACK) == 0)
296 in_interfaces++;
297 splx(s);
298
299 newifaddr = 1;
300 } else
301 newifaddr = 0;
302 break;
303
304 case SIOCSIFBRDADDR:
305 if ((so->so_state & SS_PRIV) == 0)
306 return (EPERM);
307 /* FALLTHROUGH */
308
309 case SIOCGIFADDR:
310 case SIOCGIFNETMASK:
311 case SIOCGIFDSTADDR:
312 case SIOCGIFBRDADDR:
313 if (ia && satosin(&ifr->ifr_addr)->sin_addr.s_addr) {
314 struct in_ifaddr *ia2;
315
316 for (ia2 = ia; ia2 != TAILQ_END(&in_ifaddr);
317 ia2 = TAILQ_NEXT(ia2, ia_list)) {
318 if (ia2->ia_ifp == ifp &&
319 ia2->ia_addr.sin_addr.s_addr ==
320 satosin(&ifr->ifr_addr)->sin_addr.s_addr)
321 break;
322 }
323 if (ia2 && ia2->ia_ifp == ifp)
324 ia = ia2;
325 }
326 if (ia == (struct in_ifaddr *)0)
327 return (EADDRNOTAVAIL);
328 break;
329 }
330 switch (cmd) {
331
332 case SIOCGIFADDR:
333 *satosin(&ifr->ifr_addr) = ia->ia_addr;
334 break;
335
336 case SIOCGIFBRDADDR:
337 if ((ifp->if_flags & IFF_BROADCAST) == 0)
338 return (EINVAL);
339 *satosin(&ifr->ifr_dstaddr) = ia->ia_broadaddr;
340 break;
341
342 case SIOCGIFDSTADDR:
343 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
344 return (EINVAL);
345 *satosin(&ifr->ifr_dstaddr) = ia->ia_dstaddr;
346 break;
347
348 case SIOCGIFNETMASK:
349 *satosin(&ifr->ifr_addr) = ia->ia_sockmask;
350 break;
351
352 case SIOCSIFDSTADDR:
353 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
354 return (EINVAL);
355 s = splsoftnet();
356 oldaddr = ia->ia_dstaddr;
357 ia->ia_dstaddr = *satosin(&ifr->ifr_dstaddr);
358 if (ifp->if_ioctl && (error = (*ifp->if_ioctl)
359 (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
360 ia->ia_dstaddr = oldaddr;
361 splx(s);
362 return (error);
363 }
364 if (ia->ia_flags & IFA_ROUTE) {
365 ia->ia_ifa.ifa_dstaddr = sintosa(&oldaddr);
366 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
367 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
368 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
369 }
370 splx(s);
371 break;
372
373 case SIOCSIFBRDADDR:
374 if ((ifp->if_flags & IFF_BROADCAST) == 0)
375 return (EINVAL);
376 ia->ia_broadaddr = *satosin(&ifr->ifr_broadaddr);
377 break;
378
379 case SIOCSIFADDR:
380 s = splsoftnet();
381 error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1);
382 if (!error)
383 dohooks(ifp->if_addrhooks, 0);
384 else if (newifaddr) {
385 splx(s);
386 goto cleanup;
387 }
388 splx(s);
389 return error;
390
391 case SIOCSIFNETMASK:
392 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr =
393 ifra->ifra_addr.sin_addr.s_addr;
394 break;
395
396 case SIOCAIFADDR:
397 maskIsNew = 0;
398 hostIsNew = 1;
399 error = 0;
400 s = splsoftnet();
401 if (ia->ia_addr.sin_family == AF_INET) {
402 if (ifra->ifra_addr.sin_len == 0) {
403 ifra->ifra_addr = ia->ia_addr;
404 hostIsNew = 0;
405 } else if (ifra->ifra_addr.sin_addr.s_addr ==
406 ia->ia_addr.sin_addr.s_addr)
407 hostIsNew = 0;
408 }
409 if (ifra->ifra_mask.sin_len) {
410 in_ifscrub(ifp, ia);
411 ia->ia_sockmask = ifra->ifra_mask;
412 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr;
413 maskIsNew = 1;
414 }
415 if ((ifp->if_flags & IFF_POINTOPOINT) &&
416 (ifra->ifra_dstaddr.sin_family == AF_INET)) {
417 in_ifscrub(ifp, ia);
418 ia->ia_dstaddr = ifra->ifra_dstaddr;
419 maskIsNew = 1; /* We lie; but the effect's the same */
420 }
421 if (ifra->ifra_addr.sin_family == AF_INET &&
422 (hostIsNew || maskIsNew)) {
423 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
424 }
425 if ((ifp->if_flags & IFF_BROADCAST) &&
426 (ifra->ifra_broadaddr.sin_family == AF_INET))
427 ia->ia_broadaddr = ifra->ifra_broadaddr;
428 if (!error)
429 dohooks(ifp->if_addrhooks, 0);
430 else if (newifaddr) {
431 splx(s);
432 goto cleanup;
433 }
434 splx(s);
435 return (error);
436
437 case SIOCDIFADDR: {
438
439 error = 0;
440 cleanup:
441 /*
442 * Even if the individual steps were safe, shouldn't
443 * these kinds of changes happen atomically? What
444 * should happen to a packet that was routed after
445 * the scrub but before the other steps?
446 */
447 s = splsoftnet();
448 in_ifscrub(ifp, ia);
449 TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
450 TAILQ_REMOVE(&in_ifaddr, ia, ia_list);
451 if (ia->ia_allhosts != NULL) {
452 in_delmulti(ia->ia_allhosts);
453 ia->ia_allhosts = NULL;
454 }
455 IFAFREE((&ia->ia_ifa));
456 dohooks(ifp->if_addrhooks, 0);
457 splx(s);
458 return (error);
459 }
460
461 #ifdef MROUTING
462 case SIOCGETVIFCNT:
463 case SIOCGETSGCNT:
464 return (mrt_ioctl(so, cmd, data));
465 #endif /* MROUTING */
466
467 default:
468 if (ifp == 0 || ifp->if_ioctl == 0)
469 return (EOPNOTSUPP);
470 return ((*ifp->if_ioctl)(ifp, cmd, data));
471 }
472 return (0);
473 }
474
475 /*
476 * SIOC[GAD]LIFADDR.
477 * SIOCGLIFADDR: get first address. (???)
478 * SIOCGLIFADDR with IFLR_PREFIX:
479 * get first address that matches the specified prefix.
480 * SIOCALIFADDR: add the specified address.
481 * SIOCALIFADDR with IFLR_PREFIX:
482 * EINVAL since we can't deduce hostid part of the address.
483 * SIOCDLIFADDR: delete the specified address.
484 * SIOCDLIFADDR with IFLR_PREFIX:
485 * delete the first address that matches the specified prefix.
486 * return values:
487 * EINVAL on invalid parameters
488 * EADDRNOTAVAIL on prefix match failed/specified address not found
489 * other values may be returned from in_ioctl()
490 */
491 int
492 in_lifaddr_ioctl(so, cmd, data, ifp)
493 struct socket *so;
494 u_long cmd;
495 caddr_t data;
496 struct ifnet *ifp;
497 {
498 struct if_laddrreq *iflr = (struct if_laddrreq *)data;
499 struct ifaddr *ifa;
500 struct sockaddr *sa;
501
502 /* sanity checks */
503 if (!data || !ifp) {
504 panic("invalid argument to in_lifaddr_ioctl");
505 /*NOTRECHED*/
506 }
507
508 switch (cmd) {
509 case SIOCGLIFADDR:
510 /* address must be specified on GET with IFLR_PREFIX */
511 if ((iflr->flags & IFLR_PREFIX) == 0)
512 break;
513 /*FALLTHROUGH*/
514 case SIOCALIFADDR:
515 case SIOCDLIFADDR:
516 /* address must be specified on ADD and DELETE */
517 sa = (struct sockaddr *)&iflr->addr;
518 if (sa->sa_family != AF_INET)
519 return EINVAL;
520 if (sa->sa_len != sizeof(struct sockaddr_in))
521 return EINVAL;
522 /* XXX need improvement */
523 sa = (struct sockaddr *)&iflr->dstaddr;
524 if (sa->sa_family
525 && sa->sa_family != AF_INET)
526 return EINVAL;
527 if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in))
528 return EINVAL;
529 break;
530 default: /*shouldn't happen*/
531 #if 0
532 panic("invalid cmd to in_lifaddr_ioctl");
533 /*NOTREACHED*/
534 #else
535 return EOPNOTSUPP;
536 #endif
537 }
538 if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
539 return EINVAL;
540
541 switch (cmd) {
542 case SIOCALIFADDR:
543 {
544 struct in_aliasreq ifra;
545
546 if (iflr->flags & IFLR_PREFIX)
547 return EINVAL;
548
549 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR). */
550 bzero(&ifra, sizeof(ifra));
551 bcopy(iflr->iflr_name, ifra.ifra_name,
552 sizeof(ifra.ifra_name));
553
554 bcopy(&iflr->addr, &ifra.ifra_addr,
555 ((struct sockaddr *)&iflr->addr)->sa_len);
556
557 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /*XXX*/
558 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
559 ((struct sockaddr *)&iflr->dstaddr)->sa_len);
560 }
561
562 ifra.ifra_mask.sin_family = AF_INET;
563 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
564 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
565
566 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp);
567 }
568 case SIOCGLIFADDR:
569 case SIOCDLIFADDR:
570 {
571 struct in_ifaddr *ia;
572 struct in_addr mask, candidate, match;
573 struct sockaddr_in *sin;
574 int cmp;
575
576 bzero(&mask, sizeof(mask));
577 if (iflr->flags & IFLR_PREFIX) {
578 /* lookup a prefix rather than address. */
579 in_len2mask(&mask, iflr->prefixlen);
580
581 sin = (struct sockaddr_in *)&iflr->addr;
582 match.s_addr = sin->sin_addr.s_addr;
583 match.s_addr &= mask.s_addr;
584
585 /* if you set extra bits, that's wrong */
586 if (match.s_addr != sin->sin_addr.s_addr)
587 return EINVAL;
588
589 cmp = 1;
590 } else {
591 if (cmd == SIOCGLIFADDR) {
592 /* on getting an address, take the 1st match */
593 cmp = 0; /*XXX*/
594 } else {
595 /* on deleting an address, do exact match */
596 in_len2mask(&mask, 32);
597 sin = (struct sockaddr_in *)&iflr->addr;
598 match.s_addr = sin->sin_addr.s_addr;
599
600 cmp = 1;
601 }
602 }
603
604 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
605 if (ifa->ifa_addr->sa_family != AF_INET)
606 continue;
607 if (!cmp)
608 break;
609 candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
610 candidate.s_addr &= mask.s_addr;
611 if (candidate.s_addr == match.s_addr)
612 break;
613 }
614 if (!ifa)
615 return EADDRNOTAVAIL;
616 ia = (struct in_ifaddr *)ifa;
617
618 if (cmd == SIOCGLIFADDR) {
619 /* fill in the if_laddrreq structure */
620 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
621
622 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
623 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
624 ia->ia_dstaddr.sin_len);
625 } else
626 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
627
628 iflr->prefixlen =
629 in_mask2len(&ia->ia_sockmask.sin_addr);
630
631 iflr->flags = 0; /*XXX*/
632
633 return 0;
634 } else {
635 struct in_aliasreq ifra;
636
637 /* fill in_aliasreq and do ioctl(SIOCDIFADDR) */
638 bzero(&ifra, sizeof(ifra));
639 bcopy(iflr->iflr_name, ifra.ifra_name,
640 sizeof(ifra.ifra_name));
641
642 bcopy(&ia->ia_addr, &ifra.ifra_addr,
643 ia->ia_addr.sin_len);
644 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
645 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
646 ia->ia_dstaddr.sin_len);
647 }
648 bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
649 ia->ia_sockmask.sin_len);
650
651 return in_control(so, SIOCDIFADDR, (caddr_t)&ifra, ifp);
652 }
653 }
654 }
655
656 return EOPNOTSUPP; /*just for safety*/
657 }
658
659 /*
660 * Delete any existing route for an interface.
661 */
662 void
663 in_ifscrub(ifp, ia)
664 struct ifnet *ifp;
665 struct in_ifaddr *ia;
666 {
667 in_scrubprefix(ia);
668 }
669
670 /*
671 * Initialize an interface's internet address
672 * and routing table entry.
673 */
674 int
675 in_ifinit(ifp, ia, sin, scrub)
676 struct ifnet *ifp;
677 struct in_ifaddr *ia;
678 struct sockaddr_in *sin;
679 int scrub;
680 {
681 u_int32_t i = sin->sin_addr.s_addr;
682 struct sockaddr_in oldaddr;
683 int s = splnet(), flags = RTF_UP, error;
684
685 oldaddr = ia->ia_addr;
686 ia->ia_addr = *sin;
687 /*
688 * Give the interface a chance to initialize
689 * if this is its first address,
690 * and to validate the address if necessary.
691 */
692 if (ifp->if_ioctl &&
693 (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
694 ia->ia_addr = oldaddr;
695 splx(s);
696 return (error);
697 }
698 splx(s);
699
700 /*
701 * How should a packet be routed during
702 * an address change--and is it safe?
703 * Is the "ifp" even in a consistent state?
704 * Be safe for now.
705 */
706 splassert(IPL_SOFTNET);
707
708 if (scrub) {
709 ia->ia_ifa.ifa_addr = sintosa(&oldaddr);
710 in_ifscrub(ifp, ia);
711 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
712 }
713 if (IN_CLASSA(i))
714 ia->ia_netmask = IN_CLASSA_NET;
715 else if (IN_CLASSB(i))
716 ia->ia_netmask = IN_CLASSB_NET;
717 else
718 ia->ia_netmask = IN_CLASSC_NET;
719 /*
720 * The subnet mask usually includes at least the standard network part,
721 * but may may be smaller in the case of supernetting.
722 * If it is set, we believe it.
723 */
724 if (ia->ia_subnetmask == 0) {
725 ia->ia_subnetmask = ia->ia_netmask;
726 ia->ia_sockmask.sin_addr.s_addr = ia->ia_subnetmask;
727 } else
728 ia->ia_netmask &= ia->ia_subnetmask;
729 ia->ia_net = i & ia->ia_netmask;
730 ia->ia_subnet = i & ia->ia_subnetmask;
731 in_socktrim(&ia->ia_sockmask);
732 /*
733 * Add route for the network.
734 */
735 ia->ia_ifa.ifa_metric = ifp->if_metric;
736 if (ifp->if_flags & IFF_BROADCAST) {
737 ia->ia_broadaddr.sin_addr.s_addr =
738 ia->ia_subnet | ~ia->ia_subnetmask;
739 ia->ia_netbroadcast.s_addr =
740 ia->ia_net | ~ia->ia_netmask;
741 } else if (ifp->if_flags & IFF_LOOPBACK) {
742 ia->ia_dstaddr = ia->ia_addr;
743 flags |= RTF_HOST;
744 } else if (ifp->if_flags & IFF_POINTOPOINT) {
745 if (ia->ia_dstaddr.sin_family != AF_INET)
746 return (0);
747 flags |= RTF_HOST;
748 }
749 error = in_addprefix(ia, flags);
750 /*
751 * If the interface supports multicast, join the "all hosts"
752 * multicast group on that interface.
753 */
754 if ((ifp->if_flags & IFF_MULTICAST) && ia->ia_allhosts == NULL) {
755 struct in_addr addr;
756
757 addr.s_addr = INADDR_ALLHOSTS_GROUP;
758 ia->ia_allhosts = in_addmulti(&addr, ifp);
759 }
760 return (error);
761 }
762
763 #define rtinitflags(x) \
764 ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
765 ? RTF_HOST : 0)
766
767 /*
768 * add a route to prefix ("connected route" in cisco terminology).
769 * does nothing if there's some interface address with the same prefix already.
770 */
771 int
772 in_addprefix(target, flags)
773 struct in_ifaddr *target;
774 int flags;
775 {
776 struct in_ifaddr *ia;
777 struct in_addr prefix, mask, p;
778 int error;
779
780 if ((flags & RTF_HOST) != 0)
781 prefix = target->ia_dstaddr.sin_addr;
782 else {
783 prefix = target->ia_addr.sin_addr;
784 mask = target->ia_sockmask.sin_addr;
785 prefix.s_addr &= mask.s_addr;
786 }
787
788 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
789 if (rtinitflags(ia)) {
790 p = ia->ia_dstaddr.sin_addr;
791 if (prefix.s_addr != p.s_addr)
792 continue;
793 } else {
794 p = ia->ia_addr.sin_addr;
795 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
796 if (prefix.s_addr != p.s_addr ||
797 mask.s_addr != ia->ia_sockmask.sin_addr.s_addr)
798 continue;
799 }
800 if ((ia->ia_flags & IFA_ROUTE) == 0)
801 continue;
802 #if NCARP > 0
803 /* move to a real interface instead of carp interface */
804 if (ia->ia_ifp->if_type == IFT_CARP &&
805 target->ia_ifp->if_type != IFT_CARP) {
806 rtinit(&(ia->ia_ifa), (int)RTM_DELETE,
807 rtinitflags(ia));
808 ia->ia_flags &= ~IFA_ROUTE;
809 break;
810 }
811 #endif
812 /*
813 * if we got a matching prefix route inserted by other
814 * interface adderss, we don't need to bother
815 */
816 return 0;
817 }
818
819 /*
820 * noone seem to have prefix route. insert it.
821 */
822 error = rtinit(&target->ia_ifa, (int)RTM_ADD, flags);
823 if (!error)
824 target->ia_flags |= IFA_ROUTE;
825 return error;
826 }
827
828 /*
829 * remove a route to prefix ("connected route" in cisco terminology).
830 * re-installs the route by using another interface address, if there's one
831 * with the same prefix (otherwise we lose the route mistakenly).
832 */
833 int
834 in_scrubprefix(target)
835 struct in_ifaddr *target;
836 {
837 struct in_ifaddr *ia;
838 struct in_addr prefix, mask, p;
839 int error;
840
841 if ((target->ia_flags & IFA_ROUTE) == 0)
842 return 0;
843
844 if (rtinitflags(target))
845 prefix = target->ia_dstaddr.sin_addr;
846 else {
847 prefix = target->ia_addr.sin_addr;
848 mask = target->ia_sockmask.sin_addr;
849 prefix.s_addr &= mask.s_addr;
850 }
851
852 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
853 if (rtinitflags(ia))
854 p = ia->ia_dstaddr.sin_addr;
855 else {
856 p = ia->ia_addr.sin_addr;
857 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
858 }
859
860 if (prefix.s_addr != p.s_addr)
861 continue;
862
863 /*
864 * if we got a matching prefix route, move IFA_ROUTE to him
865 */
866 if ((ia->ia_flags & IFA_ROUTE) == 0) {
867 rtinit(&(target->ia_ifa), (int)RTM_DELETE,
868 rtinitflags(target));
869 target->ia_flags &= ~IFA_ROUTE;
870
871 error = rtinit(&ia->ia_ifa, (int)RTM_ADD,
872 rtinitflags(ia) | RTF_UP);
873 if (error == 0)
874 ia->ia_flags |= IFA_ROUTE;
875 return error;
876 }
877 }
878
879 /*
880 * noone seem to have prefix route. remove it.
881 */
882 rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
883 target->ia_flags &= ~IFA_ROUTE;
884 return 0;
885 }
886
887 #undef rtinitflags
888
889 /*
890 * Return 1 if the address might be a local broadcast address.
891 */
892 int
893 in_broadcast(in, ifp)
894 struct in_addr in;
895 struct ifnet *ifp;
896 {
897 struct ifnet *ifn, *if_first, *if_target;
898 struct ifaddr *ifa;
899
900 if (in.s_addr == INADDR_BROADCAST ||
901 in.s_addr == INADDR_ANY)
902 return 1;
903
904 if (ifp == NULL) {
905 if_first = TAILQ_FIRST(&ifnet);
906 if_target = 0;
907 } else {
908 if_first = ifp;
909 if_target = TAILQ_NEXT(ifp, if_list);
910 }
911
912 #define ia (ifatoia(ifa))
913 /*
914 * Look through the list of addresses for a match
915 * with a broadcast address.
916 * If ifp is NULL, check against all the interfaces.
917 */
918 for (ifn = if_first; ifn != if_target; ifn = TAILQ_NEXT(ifn, if_list)) {
919 if ((ifn->if_flags & IFF_BROADCAST) == 0)
920 continue;
921 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list)
922 if (ifa->ifa_addr->sa_family == AF_INET &&
923 in.s_addr != ia->ia_addr.sin_addr.s_addr &&
924 (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
925 in.s_addr == ia->ia_netbroadcast.s_addr ||
926 (hostzeroisbroadcast &&
927 /*
928 * Check for old-style (host 0) broadcast.
929 */
930 (in.s_addr == ia->ia_subnet ||
931 in.s_addr == ia->ia_net))))
932 return 1;
933 }
934 return (0);
935 #undef ia
936 }
937
938 /*
939 * Add an address to the list of IP multicast addresses for a given interface.
940 */
941 struct in_multi *
942 in_addmulti(ap, ifp)
943 struct in_addr *ap;
944 struct ifnet *ifp;
945 {
946 struct in_multi *inm;
947 struct ifreq ifr;
948 struct in_ifaddr *ia;
949 int s = splsoftnet();
950
951 /*
952 * See if address already in list.
953 */
954 IN_LOOKUP_MULTI(*ap, ifp, inm);
955 if (inm != NULL) {
956 /*
957 * Found it; just increment the reference count.
958 */
959 ++inm->inm_refcount;
960 } else {
961 /*
962 * New address; allocate a new multicast record
963 * and link it into the interface's multicast list.
964 */
965 inm = (struct in_multi *)malloc(sizeof(*inm),
966 M_IPMADDR, M_NOWAIT);
967 if (inm == NULL) {
968 splx(s);
969 return (NULL);
970 }
971 inm->inm_addr = *ap;
972 inm->inm_refcount = 1;
973 IFP_TO_IA(ifp, ia);
974 if (ia == NULL) {
975 free(inm, M_IPMADDR);
976 splx(s);
977 return (NULL);
978 }
979 inm->inm_ia = ia;
980 ia->ia_ifa.ifa_refcnt++;
981 LIST_INSERT_HEAD(&ia->ia_multiaddrs, inm, inm_list);
982 /*
983 * Ask the network driver to update its multicast reception
984 * filter appropriately for the new address.
985 */
986 satosin(&ifr.ifr_addr)->sin_len = sizeof(struct sockaddr_in);
987 satosin(&ifr.ifr_addr)->sin_family = AF_INET;
988 satosin(&ifr.ifr_addr)->sin_addr = *ap;
989 if ((ifp->if_ioctl == NULL) ||
990 (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
991 LIST_REMOVE(inm, inm_list);
992 IFAFREE(&inm->inm_ia->ia_ifa);
993 free(inm, M_IPMADDR);
994 splx(s);
995 return (NULL);
996 }
997 /*
998 * Let IGMP know that we have joined a new IP multicast group.
999 */
1000 igmp_joingroup(inm);
1001 }
1002 splx(s);
1003 return (inm);
1004 }
1005
1006 /*
1007 * Delete a multicast address record.
1008 */
1009 void
1010 in_delmulti(inm)
1011 struct in_multi *inm;
1012 {
1013 struct ifreq ifr;
1014 struct ifnet *ifp;
1015 int s = splsoftnet();
1016
1017 if (--inm->inm_refcount == 0) {
1018 /*
1019 * No remaining claims to this record; let IGMP know that
1020 * we are leaving the multicast group.
1021 */
1022 igmp_leavegroup(inm);
1023 /*
1024 * Unlink from list.
1025 */
1026 LIST_REMOVE(inm, inm_list);
1027 ifp = inm->inm_ia->ia_ifp;
1028 IFAFREE(&inm->inm_ia->ia_ifa);
1029
1030 if (ifp) {
1031 /*
1032 * Notify the network driver to update its multicast
1033 * reception filter.
1034 */
1035 satosin(&ifr.ifr_addr)->sin_family = AF_INET;
1036 satosin(&ifr.ifr_addr)->sin_addr = inm->inm_addr;
1037 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
1038 }
1039 free(inm, M_IPMADDR);
1040 }
1041 splx(s);
1042 }
1043
1044 #endif