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