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