📄 in.c
字号:
/* $Id: in.c,v 1.2 1996/01/16 14:22:07 chris Exp $ *//* * Copyright (c) 1982, 1986, 1991 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)in.c 7.17 (Berkeley) 4/20/91 */#include "param.h"#include "ioctl.h"#include "mbuf.h"#include "socket.h"#include "socketvar.h"#include "in_systm.h"#include "net/if.h"#include "net/route.h"#include "net/af.h"#include "in.h"#include "in_var.h"#ifdef INET/* * 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 (net == ia->ia_net) return (i & ia->ia_subnetmask); return (net);}/* * Compute and save network mask as sockaddr from an internet address. */in_sockmaskof(in, sockmask) struct in_addr in; register struct sockaddr_in *sockmask;{ register u_long net; register u_long mask; { register u_long i = ntohl(in.s_addr); if (i == 0) net = 0, mask = 0; else if (IN_CLASSA(i)) net = i & IN_CLASSA_NET, mask = IN_CLASSA_NET; else if (IN_CLASSB(i)) net = i & IN_CLASSB_NET, mask = IN_CLASSB_NET; else if (IN_CLASSC(i)) net = i & IN_CLASSC_NET, mask = IN_CLASSC_NET; else net = i, mask = -1; } { register struct in_ifaddr *ia; /* * Check whether network is a subnet; * if so, return subnet number. */ for (ia = in_ifaddr; ia; ia = ia->ia_next) if (net == ia->ia_net) mask = ia->ia_subnetmask; } { register char *cpbase = (char *)&(sockmask->sin_addr); register char *cp = (char *)(1 + &(sockmask->sin_addr)); sockmask->sin_addr.s_addr = htonl(mask); sockmask->sin_len = 0; while (--cp >= cpbase) if (*cp) { sockmask->sin_len = 1 + cp - (caddr_t)sockmask; break; } }}/* * 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; 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'. */ for (ia = in_ifaddr; ia; ia = ia->ia_next) if (net == ia->ia_net) return (host &~ ia->ia_subnetmask); return (host);}#ifndef SUBNETSARELOCAL#define SUBNETSARELOCAL 1#endif#ifdef PROMconst int subnetsarelocal = SUBNETSARELOCAL;#elseint subnetsarelocal = SUBNETSARELOCAL;#endif/* * 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; if (subnetsarelocal) { for (ia = in_ifaddr; ia; ia = ia->ia_next) if ((i & ia->ia_netmask) == ia->ia_net) return (1); } else { for (ia = in_ifaddr; ia; ia = ia->ia_next) if ((i & ia->ia_subnetmask) == 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; register struct ifaddr *ifa; struct in_ifaddr *oia; struct in_aliasreq *ifra = (struct in_aliasreq *)data; struct mbuf *m; struct sockaddr_in oldaddr; int error, hostIsNew, maskIsNew; u_long i; /* * 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 SIOCAIFADDR: case SIOCDIFADDR: if (ifra->ifra_addr.sin_family == AF_INET) for (oia = ia; ia; ia = ia->ia_next) { if (ia->ia_ifp == ifp && ia->ia_addr.sin_addr.s_addr == ifra->ifra_addr.sin_addr.s_addr) break; } if (cmd == SIOCDIFADDR && ia == 0) return (EADDRNOTAVAIL); /* FALLTHROUGH */ case SIOCSIFADDR: case SIOCSIFNETMASK: case SIOCSIFDSTADDR: if ((so->so_state & SS_PRIV) == 0) return (EPERM); if (ifp == 0) panic("in_control"); if (ia == (struct in_ifaddr *)0) { m = m_getclr(M_WAIT, MT_IFADDR); if (m == (struct mbuf *)NULL) return (ENOBUFS); if (ia = in_ifaddr) { for ( ; ia->ia_next; ia = ia->ia_next) ; ia->ia_next = mtod(m, struct in_ifaddr *); } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -