📄 in.c
字号:
#ifndef lintstatic char *sccsid = "@(#)in.c 4.1 (ULTRIX) 7/2/90";#endif lint/************************************************************************ * * * Copyright (c) 1985 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * Modification History * * 8-Nov-89 Ursula Sinkewicz * Remove lk_ifnet and lk_in_ifaddr to coincides with * changes to slip. * * 9-June-89 Ursula Sinkewicz * Added changes for asymmetric network drivers. * * 27-Mar-89 Ursula Sinkewicz * Lower ipl of lk_ifnet, lk_in_ifaddr, lk_retentry as * per lp changes 3//16/89. * * 3-Mar-89 Ursula Sinkewicz * Pmax/smp merge. Added CLASSA/B checks in in_localaddr. * * 13-Feb-89 Ursula Sinkewicz * Changed kmalloc flag to nowait. Added assertions of * lk_in_ifaddr and lk_ifnet. * * 15-Jan-88 lp * Merge of final 43BSD changes. * * Larry Cohen - 09/16/85 * * Add 43bsd alpha tape changes for subnet routing * * * * Larry Cohen - 01/17/86 * * Add boolean: net_conservative. If set then a different * * subnet will be viewed as non-local in in_localaddr(). * * This will result in tcp using the default maxseg size * * instead of the mtu of the local interface. * * * * Marc Teitelbaum and Fred Templin - 08/21/86 * * Added 4.3BSD beta tape enhancements. "in_interfaces" * * to count number of physical interfaces attached. Also, * * new code for SICSIFBRDADDR ioctl to init * * "ia_netbroadcast" * * * * 12/16/86 - lp * * Bugfix for changing addr. * * * * * ************************************************************************//* * 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 7.5 (Berkeley) 6/4/87 */#include "../h/param.h"#include "../h/ioctl.h"#include "../h/mbuf.h"#include "../h/protosw.h"#include "../h/socket.h"#include "../h/socketvar.h"#include "../h/uio.h"#include "../h/dir.h"#include "../h/cpudata.h"#include "../h/user.h"#include "../h/buf.h"#include "../h/conf.h"#include "../h/proc.h"#include "../h/smp_lock.h"#include "../net/netinet/in_systm.h"#include "../net/net/if.h"#include "../net/net/route.h"#include "../net/net/af.h"#include "../net/netinet/in.h"#include "../net/netinet/in_var.h"struct lock_t lk_in_ifaddr; /* smp */#ifdef INETinet_hash(sin, hp) register struct sockaddr_in *sin; struct afhash *hp;{ register u_long n; n = in_netof(sin->sin_addr); if (n) while ((n & 0xff) == 0) n >>= 8; hp->afh_nethash = n; hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);}inet_netmatch(sin1, sin2) struct sockaddr_in *sin1, *sin2;{ return (in_netof(sin1->sin_addr) == in_netof(sin2->sin_addr));}/* * Formulate an Internet address from network + host. */struct in_addrin_makeaddr(net, host) u_long net, host;{ register struct in_ifaddr *ia; register u_long mask; u_long addr; if (IN_CLASSA(net)) mask = IN_CLASSA_HOST; else if (IN_CLASSB(net)) mask = IN_CLASSB_HOST; else mask = IN_CLASSC_HOST; for (ia = in_ifaddr; ia; ia = ia->ia_next) if ((ia->ia_netmask & net) == ia->ia_net) { mask = ~ia->ia_subnetmask; break; } addr = htonl(net | (host & mask)); return (*(struct in_addr *)&addr);}/* * Return the network number from an internet address. */u_longin_netof(in) struct in_addr in;{ register u_long i = ntohl(in.s_addr); register u_long net; register struct in_ifaddr *ia; if (IN_CLASSA(i)) net = i & IN_CLASSA_NET; else if (IN_CLASSB(i)) net = i & IN_CLASSB_NET; else if (IN_CLASSC(i)) net = i & IN_CLASSC_NET; else return (0); /* * Check whether network is a subnet; * if so, return subnet number. */ for (ia = in_ifaddr; ia; ia = ia->ia_next) if ((ia->ia_netmask & net) == ia->ia_net){ return (i & ia->ia_subnetmask); } return (net);}/* * Return the host portion of an internet address. */u_longin_lnaof(in) struct in_addr in;{ register u_long i = ntohl(in.s_addr); register u_long net, host; register struct in_ifaddr *ia; u_long host_return; if (IN_CLASSA(i)) { net = i & IN_CLASSA_NET; host = i & IN_CLASSA_HOST; } else if (IN_CLASSB(i)) { net = i & IN_CLASSB_NET; host = i & IN_CLASSB_HOST; } else if (IN_CLASSC(i)) { net = i & IN_CLASSC_NET; host = i & IN_CLASSC_HOST; } else return (i); /* * Check whether network is a subnet; * if so, use the modified interpretation of `host'. *//* NO LOCK */ for (ia = in_ifaddr; ia; ia = ia->ia_next) if ((ia->ia_netmask & net) == ia->ia_net){ host_return = host &~ ia->ia_subnetmask; return (host_return); } return (host);}#ifndef SUBNETSARELOCAL#define SUBNETSARELOCAL 1#endifint subnetsarelocal = SUBNETSARELOCAL;/* * Return 1 if an internet address is for a ``local'' host * (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;{ register u_long i = ntohl(in.s_addr); register struct in_ifaddr *ia; u_long net; if (IN_CLASSA(i)) net = i & IN_CLASSA_NET; else if (IN_CLASSB(i)) net = i & IN_CLASSB_NET; else net = i & IN_CLASSC_NET; for (ia = in_ifaddr; ia; ia = ia->ia_next) if (net == (subnetsarelocal ? ia->ia_net : ia->ia_subnet)){ return (1); } return (0);}/* * Determine whether an IP address is in a reserved set of addresses * that may not be forwarded, or whether datagrams to that destination * may be forwarded. */in_canforward(in) struct in_addr in;{ register u_long i = ntohl(in.s_addr); register u_long net; if (IN_EXPERIMENTAL(i)) return (0); if (IN_CLASSA(i)) { net = i & IN_CLASSA_NET; if (net == 0 || net == IN_LOOPBACKNET) return (0); } return (1);}int in_interfaces; /* number of external internet interfaces */extern struct ifnet loif;/* * Generic internet control operations (ioctl's). * Ifp is 0 if not an interface-specific ioctl. *//* ARGSUSED */in_control(so, cmd, data, ifp) struct socket *so; int cmd; caddr_t data; register struct ifnet *ifp;{ register struct ifreq *ifr = (struct ifreq *)data; register struct in_ifaddr *ia = 0; u_long tmp; struct ifaddr *ifa; struct mbuf *m; int error; int saveaffinity; /* support for nonsmp dvrs. 8.9.88.us */ /* * Find address for this interface, if it exists. */ if (ifp){ for (ia = in_ifaddr; ia; ia = ia->ia_next) if (ia->ia_ifp == ifp) break; } switch (cmd) { case SIOCSIFADDR: case SIOCSIFNETMASK: case SIOCSIFDSTADDR:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -