X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/b9ce6c7ab8014c04e9c9f4a72e9bd539716919ef..d360c192f460b2b2669e4ab61d385f5777bd15be:/usr/src/sys/netinet/in.c diff --git a/usr/src/sys/netinet/in.c b/usr/src/sys/netinet/in.c index e026b07d37..5085f9ee70 100644 --- a/usr/src/sys/netinet/in.c +++ b/usr/src/sys/netinet/in.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1982 Regents of the University of California. + * Copyright (c) 1982, 1986 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * - * @(#)in.c 6.12 (Berkeley) %G% + * @(#)in.c 7.2 (Berkeley) %G% */ #include "param.h" @@ -101,6 +101,7 @@ in_netof(in) /* * Return the host portion of an internet address. */ +u_long in_lnaof(in) struct in_addr in; { @@ -129,9 +130,15 @@ in_lnaof(in) return (host); } +#ifndef SUBNETSARELOCAL +#define SUBNETSARELOCAL 1 +#endif +int subnetsarelocal = SUBNETSARELOCAL; /* * Return 1 if an internet address is for a ``local'' host - * (one to which we have a connection through a local logical net). + * (one to which we have a connection). If subnetsarelocal + * is true, this includes other subnets of the local net. + * Otherwise, it includes only the directly-connected (sub)nets. */ in_localaddr(in) struct in_addr in; @@ -148,7 +155,7 @@ in_localaddr(in) net = i & IN_CLASSC_NET; for (ia = in_ifaddr; ia; ia = ia->ia_next) - if (net == ia->ia_net) + if (net == (subnetsarelocal ? ia->ia_net : ia->ia_subnet)) return (1); return (0); } @@ -186,6 +193,7 @@ in_control(so, cmd, data, ifp) case SIOCSIFADDR: case SIOCSIFNETMASK: + case SIOCSIFDSTADDR: if (!suser()) return (u.u_error); @@ -216,7 +224,6 @@ in_control(so, cmd, data, ifp) break; case SIOCSIFBRDADDR: - case SIOCSIFDSTADDR: if (!suser()) return (u.u_error); /* FALLTHROUGH */ @@ -252,12 +259,25 @@ in_control(so, cmd, data, ifp) break; case SIOCSIFDSTADDR: + { + struct sockaddr oldaddr; + if ((ifp->if_flags & IFF_POINTOPOINT) == 0) return (EINVAL); + oldaddr = ia->ia_dstaddr; + ia->ia_dstaddr = ifr->ifr_dstaddr; if (ifp->if_ioctl && - (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia))) + (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia))) { + ia->ia_dstaddr = oldaddr; return (error); - ia->ia_dstaddr = ifr->ifr_dstaddr; + } + if (ia->ia_flags & IFA_ROUTE) { + rtinit(&oldaddr, &ia->ia_addr, (int)SIOCDELRT, + RTF_HOST); + rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT, + RTF_HOST|RTF_UP); + } + } break; case SIOCSIFBRDADDR: @@ -297,10 +317,11 @@ in_ifinit(ifp, ia, sin) struct sockaddr_in *sin; { register u_long i = ntohl(sin->sin_addr.s_addr); - struct sockaddr_in tmpaddr; + struct sockaddr oldaddr; + struct sockaddr_in netaddr; int s = splimp(), error; - tmpaddr = *(struct sockaddr_in *)&ia->ia_addr; + oldaddr = ia->ia_addr; ia->ia_addr = *(struct sockaddr *)sin; /* @@ -310,23 +331,27 @@ in_ifinit(ifp, ia, sin) */ if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) { splx(s); - ia->ia_addr = *(struct sockaddr *)&tmpaddr; + ia->ia_addr = oldaddr; return (error); } - bzero((caddr_t)&tmpaddr, sizeof (tmpaddr)); - tmpaddr.sin_family = AF_INET; /* * Delete any previous route for an old address. */ + bzero((caddr_t)&netaddr, sizeof (netaddr)); + netaddr.sin_family = AF_INET; if (ia->ia_flags & IFA_ROUTE) { - if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { - tmpaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY); - rtinit((struct sockaddr *)&tmpaddr, &ia->ia_addr, + if (ifp->if_flags & IFF_LOOPBACK) + rtinit(&oldaddr, &oldaddr, (int)SIOCDELRT, RTF_HOST); + else if (ifp->if_flags & IFF_POINTOPOINT) + rtinit(&ia->ia_dstaddr, &oldaddr, (int)SIOCDELRT, + RTF_HOST); + else { + netaddr.sin_addr = in_makeaddr(ia->ia_subnet, + INADDR_ANY); + rtinit((struct sockaddr *)&netaddr, &oldaddr, (int)SIOCDELRT, 0); - } else - rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr, - (int)SIOCDELRT, RTF_HOST); + } ia->ia_flags &= ~IFA_ROUTE; } if (IN_CLASSA(i)) @@ -353,13 +378,17 @@ in_ifinit(ifp, ia, sin) /* * Add route for the network. */ - if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { - tmpaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY); - rtinit((struct sockaddr *)&tmpaddr, &ia->ia_addr, - (int)SIOCADDRT, RTF_UP); - } else - rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr, - (int)SIOCADDRT, RTF_HOST|RTF_UP); + if (ifp->if_flags & IFF_LOOPBACK) + rtinit(&ia->ia_addr, &ia->ia_addr, (int)SIOCADDRT, + RTF_HOST|RTF_UP); + else if (ifp->if_flags & IFF_POINTOPOINT) + rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT, + RTF_HOST|RTF_UP); + else { + netaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY); + rtinit((struct sockaddr *)&netaddr, &ia->ia_addr, + (int)SIOCADDRT, RTF_UP); + } ia->ia_flags |= IFA_ROUTE; return (0); }