# 2.11BSD#431 - /usr/src/sys/netinet/in.c

##### Functions

    in_broadcast      X
    in_canforward     X
    in_control        X
    in_iaonnetof      X
    in_ifinit         X
    in_lnaof          X
    in_localaddr      X
    in_makeaddr       X
    in_netof          X
    inet_hash         X
    inet_netmatch     X

##### Variables

    subnetsarelocal   X

##### Macros

    SUBNETSARELOCAL   X
    satosin           X

       1: /*
       2:  * Copyright (c) 1982, 1986 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted
       6:  * provided that this notice is preserved and that due credit is given
       7:  * to the University of California at Berkeley. The name of the University
       8:  * may not be used to endorse or promote products derived from this
       9:  * software without specific prior written permission. This software
      10:  * is provided ``as is'' without express or implied warranty.
      11:  *
      12:  *	@(#)in.c	7.7.1 (2.11BSD) 1995/10/10
      13:  */
      14:
      15: #include "param.h"
      16: #include "ioctl.h"
      17: #include "mbuf.h"
      18: #include "domain.h"
      19: #include "protosw.h"
      20: #include "socket.h"
      21: #include "socketvar.h"
      22: #include "user.h"
      23: #include "in_systm.h"
      24: #include "../net/if.h"
      25: #include "../net/route.h"
      26: #include "../net/af.h"
      27: #include "in.h"
      28: #include "in_var.h"
      29:
      30: #ifdef INET
      31: inet_hash(sin, hp)
      32:     register struct sockaddr_in *sin;
      33:     struct afhash *hp;
      34: {
      35:     register u_long n;
      36:
      37:     n = in_netof(sin->sin_addr);
      38:     if (n)
      39:         while ((n & 0xffL) == 0L)
      40:         n >>= 8;
      41:     hp->afh_nethash = n;
      42:     hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);
      43: }
      44:
      45: inet_netmatch(sin1, sin2)
      46:     struct sockaddr_in *sin1, *sin2;
      47: {
      48:
      49:     return (in_netof(sin1->sin_addr) == in_netof(sin2->sin_addr));
      50: }
      51:
      52: /*
      53:  * Formulate an Internet address from network + host.
      54:  */
      55: struct in_addr
      56: in_makeaddr(net, host)
      57:     u_long net, host;
      58: {
      59:     register struct in_ifaddr *ia;
      60:     register u_long mask;
      61:     u_long addr;
      62:
      63:     if (IN_CLASSA(net))
      64:         mask = IN_CLASSA_HOST;
      65:     else if (IN_CLASSB(net))
      66:         mask = IN_CLASSB_HOST;
      67:     else
      68:         mask = IN_CLASSC_HOST;
      69:     for (ia = in_ifaddr; ia; ia = ia->ia_next)
      70:         if ((ia->ia_netmask & net) == ia->ia_net) {
      71:             mask = ~ia->ia_subnetmask;
      72:             break;
      73:         }
      74:     addr = htonl(net | (host & mask));
      75:     return (*(struct in_addr *)&addr);
      76: }
      77:
      78: /*
      79:  * Return the network number from an internet address.
      80:  */
      81: u_long
      82: in_netof(in)
      83:     struct in_addr in;
      84: {
      85:     register u_long i = ntohl(in.s_addr);
      86:     register u_long net;
      87:     register struct in_ifaddr *ia;
      88:
      89:     if (IN_CLASSA(i))
      90:         net = i & IN_CLASSA_NET;
      91:     else if (IN_CLASSB(i))
      92:         net = i & IN_CLASSB_NET;
      93:     else if (IN_CLASSC(i))
      94:         net = i & IN_CLASSC_NET;
      95:     else
      96:         return (0);
      97:
      98:     /*
      99: 	 * Check whether network is a subnet;
     100: 	 * if so, return subnet number.
     101: 	 */
     102:     for (ia = in_ifaddr; ia; ia = ia->ia_next)
     103:         if (net == ia->ia_net)
     104:             return (i & ia->ia_subnetmask);
     105:     return (net);
     106: }
     107:
     108: /*
     109:  * Return the host portion of an internet address.
     110:  */
     111: u_long
     112: in_lnaof(in)
     113:     struct in_addr in;
     114: {
     115:     register u_long i = ntohl(in.s_addr);
     116:     register u_long net, host;
     117:     register struct in_ifaddr *ia;
     118:
     119:     if (IN_CLASSA(i)) {
     120:         net = i & IN_CLASSA_NET;
     121:         host = i & IN_CLASSA_HOST;
     122:     } else if (IN_CLASSB(i)) {
     123:         net = i & IN_CLASSB_NET;
     124:         host = i & IN_CLASSB_HOST;
     125:     } else if (IN_CLASSC(i)) {
     126:         net = i & IN_CLASSC_NET;
     127:         host = i & IN_CLASSC_HOST;
     128:     } else
     129:         return (i);
     130:
     131:     /*
     132: 	 * Check whether network is a subnet;
     133: 	 * if so, use the modified interpretation of `host'.
     134: 	 */
     135:     for (ia = in_ifaddr; ia; ia = ia->ia_next)
     136:         if (net == ia->ia_net)
     137:             return (host &~ ia->ia_subnetmask);
     138:     return (host);
     139: }
     140:
     141: #ifndef SUBNETSARELOCAL
     142: #define SUBNETSARELOCAL 1
     143: #endif
     144: int subnetsarelocal = SUBNETSARELOCAL;
     145: /*
     146:  * Return 1 if an internet address is for a ``local'' host
     147:  * (one to which we have a connection).  If subnetsarelocal
     148:  * is true, this includes other subnets of the local net.
     149:  * Otherwise, it includes only the directly-connected (sub)nets.
     150:  */
     151: in_localaddr(in)
     152:     struct in_addr in;
     153: {
     154:     register u_long i = ntohl(in.s_addr);
     155:     register struct in_ifaddr *ia;
     156:
     157:     if (subnetsarelocal) {
     158:         for (ia = in_ifaddr; ia; ia = ia->ia_next)
     159:             if ((i & ia->ia_netmask) == ia->ia_net)
     160:                 return (1);
     161:     } else {
     162:         for (ia = in_ifaddr; ia; ia = ia->ia_next)
     163:             if ((i & ia->ia_subnetmask) == ia->ia_subnet)
     164:                 return (1);
     165:     }
     166:     return (0);
     167: }
     168:
     169: /*
     170:  * Determine whether an IP address is in a reserved set of addresses
     171:  * that may not be forwarded, or whether datagrams to that destination
     172:  * may be forwarded.
     173:  */
     174: in_canforward(in)
     175:     struct in_addr in;
     176: {
     177:     register u_long i = ntohl(in.s_addr);
     178:     register u_long net;
     179:
     180:     if (IN_EXPERIMENTAL(i))
     181:         return (0);
     182:     if (IN_CLASSA(i)) {
     183:         net = i & IN_CLASSA_NET;
     184:         if (net == 0 || net == IN_LOOPBACKNET)
     185:             return (0);
     186:     }
     187:     return (1);
     188: }
     189:
     190: extern  struct ifnet loif;
     191:
     192: /*
     193:  * Generic internet control operations (ioctl's).
     194:  * Ifp is 0 if not an interface-specific ioctl.
     195:  */
     196: /* ARGSUSED */
     197: in_control(so, cmd, data, ifp)
     198:     struct socket *so;
     199:     int cmd;
     200:     caddr_t data;
     201:     register struct ifnet *ifp;
     202: {
     203:     register struct ifreq *ifr = (struct ifreq *)data;
     204:     register struct in_ifaddr *ia = 0;
     205:     struct ifaddr *ifa;
     206:     struct mbuf *m;
     207:     int error;
     208:
     209:     /*
     210: 	 * Find address for this interface, if it exists.
     211: 	 */
     212:     if (ifp)
     213:         for (ia = in_ifaddr; ia; ia = ia->ia_next)
     214:             if (ia->ia_ifp == ifp)
     215:                 break;
     216:
     217:     switch (cmd) {
     218:
     219:     case SIOCSIFADDR:
     220:     case SIOCSIFNETMASK:
     221:     case SIOCSIFDSTADDR:
     222:         if (!suser())
     223:             return (u.u_error);
     224:
     225:         if (ifp == 0)
     226:             panic("in_control");
     227:         if (ia == (struct in_ifaddr *)0) {
     228:             m = m_getclr(M_WAIT, MT_IFADDR);
     229:             if (m == (struct mbuf *)NULL)
     230:                 return (ENOBUFS);
     231:             if (ia = in_ifaddr) {
     232:                 for ( ; ia->ia_next; ia = ia->ia_next)
     233:                     ;
     234:                 ia->ia_next = mtod(m, struct in_ifaddr *);
     235:             } else
     236:                 in_ifaddr = mtod(m, struct in_ifaddr *);
     237:             ia = mtod(m, struct in_ifaddr *);
     238:             if (ifa = ifp->if_addrlist) {
     239:                 for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
     240:                     ;
     241:                 ifa->ifa_next = (struct ifaddr *) ia;
     242:             } else
     243:                 ifp->if_addrlist = (struct ifaddr *) ia;
     244:             ia->ia_ifp = ifp;
     245:             IA_SIN(ia)->sin_family = AF_INET;
     246:         }
     247:         break;
     248:
     249:     case SIOCSIFBRDADDR:
     250:         if (!suser())
     251:             return (u.u_error);
     252:         /* FALLTHROUGH */
     253:
     254:     default:
     255:         if (ia == (struct in_ifaddr *)0)
     256:             return (EADDRNOTAVAIL);
     257:         break;
     258:     }
     259:
     260:     switch (cmd) {
     261:
     262:     case SIOCGIFADDR:
     263:         ifr->ifr_addr = ia->ia_addr;
     264:         break;
     265:
     266:     case SIOCGIFBRDADDR:
     267:         if ((ifp->if_flags & IFF_BROADCAST) == 0)
     268:             return (EINVAL);
     269:         ifr->ifr_dstaddr = ia->ia_broadaddr;
     270:         break;
     271:
     272:     case SIOCGIFDSTADDR:
     273:         if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
     274:             return (EINVAL);
     275:         ifr->ifr_dstaddr = ia->ia_dstaddr;
     276:         break;
     277:
     278:     case SIOCGIFNETMASK:
     279: #define satosin(sa) ((struct sockaddr_in *)(sa))
     280:         satosin(&ifr->ifr_addr)->sin_family = AF_INET;
     281:         satosin(&ifr->ifr_addr)->sin_addr.s_addr = htonl(ia->ia_subnetmask);
     282:         break;
     283:
     284:     case SIOCSIFDSTADDR:
     285:         {
     286:         struct sockaddr oldaddr;
     287:
     288:         if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
     289:             return (EINVAL);
     290:         oldaddr = ia->ia_dstaddr;
     291:         ia->ia_dstaddr = ifr->ifr_dstaddr;
     292:         if (ifp->if_ioctl &&
     293:             (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia))) {
     294:             ia->ia_dstaddr = oldaddr;
     295:             return (error);
     296:         }
     297:         if (ia->ia_flags & IFA_ROUTE) {
     298:             rtinit(&oldaddr, &ia->ia_addr, (int)SIOCDELRT,
     299:                 RTF_HOST);
     300:             rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT,
     301:                 RTF_HOST|RTF_UP);
     302:         }
     303:         }
     304:         break;
     305:
     306:     case SIOCSIFBRDADDR:
     307:         if ((ifp->if_flags & IFF_BROADCAST) == 0)
     308:             return (EINVAL);
     309:         ia->ia_broadaddr = ifr->ifr_broadaddr;
     310:         break;
     311:
     312:     case SIOCSIFADDR:
     313:         return (in_ifinit(ifp, ia, &ifr->ifr_addr));
     314:
     315:     case SIOCSIFNETMASK:
     316:         ia->ia_subnetmask = ntohl(satosin(&ifr->ifr_addr)->sin_addr.s_addr);
     317:         break;
     318:
     319:     default:
     320:         if (ifp == 0 || ifp->if_ioctl == 0)
     321:             return (EOPNOTSUPP);
     322:         return ((*ifp->if_ioctl)(ifp, cmd, data));
     323:     }
     324:     return (0);
     325: }
     326:
     327: /*
     328:  * Initialize an interface's internet address
     329:  * and routing table entry.
     330:  */
     331: in_ifinit(ifp, ia, sin)
     332:     register struct ifnet *ifp;
     333:     register struct in_ifaddr *ia;
     334:     struct sockaddr_in *sin;
     335: {
     336:     register u_long i = ntohl(sin->sin_addr.s_addr);
     337:     struct sockaddr oldaddr;
     338:     struct sockaddr_in netaddr;
     339:     int s = splimp(), error;
     340:
     341:     oldaddr = ia->ia_addr;
     342:     ia->ia_addr = *(struct sockaddr *)sin;
     343:
     344:     /*
     345: 	 * Give the interface a chance to initialize
     346: 	 * if this is its first address,
     347: 	 * and to validate the address if necessary.
     348: 	 */
     349:     if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
     350:         splx(s);
     351:         ia->ia_addr = oldaddr;
     352:         return (error);
     353:     }
     354:
     355:     /*
     356: 	 * Delete any previous route for an old address.
     357: 	 */
     358:     bzero((caddr_t)&netaddr, sizeof (netaddr));
     359:     netaddr.sin_family = AF_INET;
     360:     if (ia->ia_flags & IFA_ROUTE) {
     361:         if (ifp->if_flags & IFF_LOOPBACK)
     362:             rtinit(&oldaddr, &oldaddr, (int)SIOCDELRT, RTF_HOST);
     363:         else if (ifp->if_flags & IFF_POINTOPOINT)
     364:             rtinit(&ia->ia_dstaddr, &oldaddr, (int)SIOCDELRT,
     365:                 RTF_HOST);
     366:         else {
     367:             netaddr.sin_addr = in_makeaddr(ia->ia_subnet,
     368:                 INADDR_ANY);
     369:             rtinit((struct sockaddr *)&netaddr, &oldaddr,
     370:                 (int)SIOCDELRT, 0);
     371:         }
     372:         ia->ia_flags &= ~IFA_ROUTE;
     373:     }
     374:     if (IN_CLASSA(i))
     375:         ia->ia_netmask = IN_CLASSA_NET;
     376:     else if (IN_CLASSB(i))
     377:         ia->ia_netmask = IN_CLASSB_NET;
     378:     else
     379:         ia->ia_netmask = IN_CLASSC_NET;
     380:     ia->ia_net = i & ia->ia_netmask;
     381:     /*
     382: 	 * The subnet mask includes at least the standard network part,
     383: 	 * but may already have been set to a larger value.
     384: 	 */
     385:     ia->ia_subnetmask |= ia->ia_netmask;
     386:     ia->ia_subnet = i & ia->ia_subnetmask;
     387:     if (ifp->if_flags & IFF_BROADCAST) {
     388:         ia->ia_broadaddr.sa_family = AF_INET;
     389:         ((struct sockaddr_in *)(&ia->ia_broadaddr))->sin_addr =
     390:             in_makeaddr(ia->ia_subnet, INADDR_BROADCAST);
     391:         ia->ia_netbroadcast.s_addr =
     392:             htonl(ia->ia_net | (INADDR_BROADCAST &~ ia->ia_netmask));
     393:     }
     394:     /*
     395: 	 * Add route for the network.
     396: 	 */
     397:     if (ifp->if_flags & IFF_LOOPBACK)
     398:         rtinit(&ia->ia_addr, &ia->ia_addr, (int)SIOCADDRT,
     399:             RTF_HOST|RTF_UP);
     400:     else if (ifp->if_flags & IFF_POINTOPOINT)
     401:         rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT,
     402:             RTF_HOST|RTF_UP);
     403:     else {
     404:         netaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY);
     405:         rtinit((struct sockaddr *)&netaddr, &ia->ia_addr,
     406:             (int)SIOCADDRT, RTF_UP);
     407:     }
     408:     ia->ia_flags |= IFA_ROUTE;
     409:     splx(s);
     410:     return (0);
     411: }
     412:
     413: /*
     414:  * Return address info for specified internet network.
     415:  */
     416: struct in_ifaddr *
     417: in_iaonnetof(net)
     418:     u_long net;
     419: {
     420:     register struct in_ifaddr *ia;
     421:
     422:     for (ia = in_ifaddr; ia; ia = ia->ia_next)
     423:         if (ia->ia_subnet == net)
     424:             return (ia);
     425:     return ((struct in_ifaddr *)0);
     426: }
     427:
     428: /*
     429:  * Return 1 if the address might be a local broadcast address.
     430:  */
     431: in_broadcast(in)
     432:     struct in_addr in;
     433: {
     434:     register struct in_ifaddr *ia;
     435:     u_long t;
     436:
     437:     /*
     438: 	 * Look through the list of addresses for a match
     439: 	 * with a broadcast address.
     440: 	 */
     441:     for (ia = in_ifaddr; ia; ia = ia->ia_next)
     442:         if (ia->ia_ifp->if_flags & IFF_BROADCAST) {
     443:         if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr == in.s_addr)
     444:              return (1);
     445:         /*
     446: 		 * Check for old-style (host 0) broadcast.
     447: 		 */
     448:         if ((t = ntohl(in.s_addr)) == ia->ia_subnet || t == ia->ia_net)
     449:             return (1);
     450:     }
     451:     if (in.s_addr == INADDR_BROADCAST || in.s_addr == INADDR_ANY)
     452:         return (1);
     453:     return (0);
     454: }
     455: #endif

#### Defined functions

in_broadcast defined in line 431; never used
in_canforward defined in line 174; never used
in_control defined in line 197; never used
in_iaonnetof defined in line 416; never used
in_ifinit defined in line 331; used 1 times

- in line 313

in_lnaof defined in line 111; never used
in_localaddr defined in line 151; never used
in_makeaddr defined in line 55; used 3 times

- in line 367, 390, 404

in_netof defined in line 81; used 3 times

- in line 37, 49(2)

inet_hash defined in line 31; never used
inet_netmatch defined in line 45; never used

#### Defined variables

subnetsarelocal defined in line 144; used 1 times

- in line 157

#### Defined macros

SUBNETSARELOCAL defined in line 142; used 2 times

- in line 141-144(2)

satosin defined in line 279; used 4 times

- in line 280-281(2), 316, 443

Last modified: 1995-10-11 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1987 |