🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.bugs.4bsd.ucb-fixes
1 messages
1 total messages Started by Keith Bostic Tue, 05 Apr 1988 03:18
V1.49 ((inet 3 of 4) updated IP/TCP and XNS sources for 4.3BSD)
#56
Author: Keith Bostic
Date: Tue, 05 Apr 1988 03:18
2099 lines
59633 bytes
Subject: (inet 3 of 4) updated IP/TCP and XNS sources for 4.3BSD
Index: sys 4.3BSD

Description:
	This is number 4 of 11 total articles posted to the newsgroup
	comp.bugs.4bsd.ucb-fixes.  This archive is number 3 of the 4
	articles that make up the inet posting.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	netinet
#	netinet/icmp_var.h
#	netinet/if_ether.c
#	netinet/if_ether.h
#	netinet/in.c
#	netinet/in.h
#	netinet/in_cksum.c
#	netinet/in_pcb.c
#	netinet/in_pcb.h
#	netinet/in_proto.c
#	netinet/in_systm.h
#	netinet/in_var.h
#
echo c - netinet
mkdir netinet > /dev/null 2>&1
echo x - netinet/icmp_var.h
sed 's/^X//' >netinet/icmp_var.h << 'END-of-netinet/icmp_var.h'
X/*
X * Copyright (c) 1982, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)icmp_var.h	7.3 (Berkeley) 12/7/87
X */
X
X/*
X * Variables related to this implementation
X * of the internet control message protocol.
X */
Xstruct	icmpstat {
X/* statistics related to icmp packets generated */
X	int	icps_error;		/* # of calls to icmp_error */
X	int	icps_oldshort;		/* no error 'cuz old ip too short */
X	int	icps_oldicmp;		/* no error 'cuz old was icmp */
X	int	icps_outhist[ICMP_MAXTYPE + 1];
X/* statistics related to input messages processed */
X 	int	icps_badcode;		/* icmp_code out of range */
X	int	icps_tooshort;		/* packet < ICMP_MINLEN */
X	int	icps_checksum;		/* bad checksum */
X	int	icps_badlen;		/* calculated bound mismatch */
X	int	icps_reflect;		/* number of responses */
X	int	icps_inhist[ICMP_MAXTYPE + 1];
X};
X
X#ifdef KERNEL
Xstruct	icmpstat icmpstat;
X#endif
END-of-netinet/icmp_var.h
echo x - netinet/if_ether.c
sed 's/^X//' >netinet/if_ether.c << 'END-of-netinet/if_ether.c'
X/*
X * Copyright (c) 1982, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)if_ether.c	7.6 (Berkeley) 12/7/87
X */
X
X/*
X * Ethernet address resolution protocol.
X * TODO:
X *	run at splnet (add ARP protocol intr.)
X *	link entries onto hash chains, keep free list
X *	add "inuse/lock" bit (or ref. count) along with valid bit
X */
X
X#include "param.h"
X#include "systm.h"
X#include "mbuf.h"
X#include "socket.h"
X#include "time.h"
X#include "kernel.h"
X#include "errno.h"
X#include "ioctl.h"
X#include "syslog.h"
X
X#include "../net/if.h"
X#include "in.h"
X#include "in_systm.h"
X#include "ip.h"
X#include "if_ether.h"
X
X#ifdef GATEWAY
X#define	ARPTAB_BSIZ	16		/* bucket size */
X#define	ARPTAB_NB	37		/* number of buckets */
X#else
X#define	ARPTAB_BSIZ	9		/* bucket size */
X#define	ARPTAB_NB	19		/* number of buckets */
X#endif
X#define	ARPTAB_SIZE	(ARPTAB_BSIZ * ARPTAB_NB)
Xstruct	arptab arptab[ARPTAB_SIZE];
Xint	arptab_size = ARPTAB_SIZE;	/* for arp command */
X
X/*
X * ARP trailer negotiation.  Trailer protocol is not IP specific,
X * but ARP request/response use IP addresses.
X */
X#define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
X
X#define	ARPTAB_HASH(a) \
X	((u_long)(a) % ARPTAB_NB)
X
X#define	ARPTAB_LOOK(at,addr) { \
X	register n; \
X	at = &arptab[ARPTAB_HASH(addr) * ARPTAB_BSIZ]; \
X	for (n = 0 ; n < ARPTAB_BSIZ ; n++,at++) \
X		if (at->at_iaddr.s_addr == addr) \
X			break; \
X	if (n >= ARPTAB_BSIZ) \
X		at = 0; \
X}
X
X/* timer values */
X#define	ARPT_AGE	(60*1)	/* aging timer, 1 min. */
X#define	ARPT_KILLC	20	/* kill completed entry in 20 mins. */
X#define	ARPT_KILLI	3	/* kill incomplete entry in 3 minutes */
X
Xu_char	etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
Xextern struct ifnet loif;
X
X/*
X * Timeout routine.  Age arp_tab entries once a minute.
X */
Xarptimer()
X{
X	register struct arptab *at;
X	register i;
X
X	timeout(arptimer, (caddr_t)0, ARPT_AGE * hz);
X	at = &arptab[0];
X	for (i = 0; i < ARPTAB_SIZE; i++, at++) {
X		if (at->at_flags == 0 || (at->at_flags & ATF_PERM))
X			continue;
X		if (++at->at_timer < ((at->at_flags&ATF_COM) ?
X		    ARPT_KILLC : ARPT_KILLI))
X			continue;
X		/* timer has expired, clear entry */
X		arptfree(at);
X	}
X}
X
X/*
X * Broadcast an ARP packet, asking who has addr on interface ac.
X */
Xarpwhohas(ac, addr)
X	register struct arpcom *ac;
X	struct in_addr *addr;
X{
X	register struct mbuf *m;
X	register struct ether_header *eh;
X	register struct ether_arp *ea;
X	struct sockaddr sa;
X
X	if ((m = m_get(M_DONTWAIT, MT_DATA)) == NULL)
X		return;
X	m->m_len = sizeof *ea;
X	m->m_off = MMAXOFF - m->m_len;
X	ea = mtod(m, struct ether_arp *);
X	eh = (struct ether_header *)sa.sa_data;
X	bzero((caddr_t)ea, sizeof (*ea));
X	bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
X	    sizeof(eh->ether_dhost));
X	eh->ether_type = ETHERTYPE_ARP;		/* if_output will swap */
X	ea->arp_hrd = htons(ARPHRD_ETHER);
X	ea->arp_pro = htons(ETHERTYPE_IP);
X	ea->arp_hln = sizeof(ea->arp_sha);	/* hardware address length */
X	ea->arp_pln = sizeof(ea->arp_spa);	/* protocol address length */
X	ea->arp_op = htons(ARPOP_REQUEST);
X	bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
X	   sizeof(ea->arp_sha));
X	bcopy((caddr_t)&ac->ac_ipaddr, (caddr_t)ea->arp_spa,
X	   sizeof(ea->arp_spa));
X	bcopy((caddr_t)addr, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa));
X	sa.sa_family = AF_UNSPEC;
X	(*ac->ac_if.if_output)(&ac->ac_if, m, &sa);
X}
X
Xint	useloopback = 1;	/* use loopback interface for local traffic */
X
X/*
X * Resolve an IP address into an ethernet address.  If success, 
X * desten is filled in.  If there is no entry in arptab,
X * set one up and broadcast a request for the IP address.
X * Hold onto this mbuf and resend it once the address
X * is finally resolved.  A return value of 1 indicates
X * that desten has been filled in and the packet should be sent
X * normally; a 0 return indicates that the packet has been
X * taken over here, either now or for later transmission.
X *
X * We do some (conservative) locking here at splimp, since
X * arptab is also altered from input interrupt service (ecintr/ilintr
X * calls arpinput when ETHERTYPE_ARP packets come in).
X */
Xarpresolve(ac, m, destip, desten, usetrailers)
X	register struct arpcom *ac;
X	struct mbuf *m;
X	register struct in_addr *destip;
X	register u_char *desten;
X	int *usetrailers;
X{
X	register struct arptab *at;
X	struct sockaddr_in sin;
X	u_long lna;
X	int s;
X
X	*usetrailers = 0;
X	if (in_broadcast(*destip)) {	/* broadcast address */
X		bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten,
X		    sizeof(etherbroadcastaddr));
X		return (1);
X	}
X	lna = in_lnaof(*destip);
X	/* if for us, use software loopback driver if up */
X	if (destip->s_addr == ac->ac_ipaddr.s_addr) {
X		/*
X		 * This test used to be
X		 *	if (loif.if_flags & IFF_UP)
X		 * It allowed local traffic to be forced
X		 * through the hardware by configuring the loopback down.
X		 * However, it causes problems during network configuration
X		 * for boards that can't receive packets they send.
X		 * It is now necessary to clear "useloopback"
X		 * to force traffic out to the hardware.
X		 */
X		if (useloopback) {
X			sin.sin_family = AF_INET;
X			sin.sin_addr = *destip;
X			(void) looutput(&loif, m, (struct sockaddr *)&sin);
X			/*
X			 * The packet has already been sent and freed.
X			 */
X			return (0);
X		} else {
X			bcopy((caddr_t)ac->ac_enaddr, (caddr_t)desten,
X			    sizeof(ac->ac_enaddr));
X			return (1);
X		}
X	}
X	s = splimp();
X	ARPTAB_LOOK(at, destip->s_addr);
X	if (at == 0) {			/* not found */
X		if (ac->ac_if.if_flags & IFF_NOARP) {
X			bcopy((caddr_t)ac->ac_enaddr, (caddr_t)desten, 3);
X			desten[3] = (lna >> 16) & 0x7f;
X			desten[4] = (lna >> 8) & 0xff;
X			desten[5] = lna & 0xff;
X			splx(s);
X			return (1);
X		} else {
X			at = arptnew(destip);
X			if (at == 0)
X				panic("arpresolve: no free entry");
X			at->at_hold = m;
X			arpwhohas(ac, destip);
X			splx(s);
X			return (0);
X		}
X	}
X	at->at_timer = 0;		/* restart the timer */
X	if (at->at_flags & ATF_COM) {	/* entry IS complete */
X		bcopy((caddr_t)at->at_enaddr, (caddr_t)desten,
X		    sizeof(at->at_enaddr));
X		if (at->at_flags & ATF_USETRAILERS)
X			*usetrailers = 1;
X		splx(s);
X		return (1);
X	}
X	/*
X	 * There is an arptab entry, but no ethernet address
X	 * response yet.  Replace the held mbuf with this
X	 * latest one.
X	 */
X	if (at->at_hold)
X		m_freem(at->at_hold);
X	at->at_hold = m;
X	arpwhohas(ac, destip);		/* ask again */
X	splx(s);
X	return (0);
X}
X
X/*
X * Called from 10 Mb/s Ethernet interrupt handlers
X * when ether packet type ETHERTYPE_ARP
X * is received.  Common length and type checks are done here,
X * then the protocol-specific routine is called.
X */
Xarpinput(ac, m)
X	struct arpcom *ac;
X	struct mbuf *m;
X{
X	register struct arphdr *ar;
X
X	if (ac->ac_if.if_flags & IFF_NOARP)
X		goto out;
X	IF_ADJ(m);
X	if (m->m_len < sizeof(struct arphdr))
X		goto out;
X	ar = mtod(m, struct arphdr *);
X	if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
X		goto out;
X	if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln)
X		goto out;
X
X	switch (ntohs(ar->ar_pro)) {
X
X	case ETHERTYPE_IP:
X	case ETHERTYPE_IPTRAILERS:
X		in_arpinput(ac, m);
X		return;
X
X	default:
X		break;
X	}
Xout:
X	m_freem(m);
X}
X
X/*
X * ARP for Internet protocols on 10 Mb/s Ethernet.
X * Algorithm is that given in RFC 826.
X * In addition, a sanity check is performed on the sender
X * protocol address, to catch impersonators.
X * We also handle negotiations for use of trailer protocol:
X * ARP replies for protocol type ETHERTYPE_TRAIL are sent
X * along with IP replies if we want trailers sent to us,
X * and also send them in response to IP replies.
X * This allows either end to announce the desire to receive
X * trailer packets.
X * We reply to requests for ETHERTYPE_TRAIL protocol as well,
X * but don't normally send requests.
X */
Xin_arpinput(ac, m)
X	register struct arpcom *ac;
X	struct mbuf *m;
X{
X	register struct ether_arp *ea;
X	struct ether_header *eh;
X	register struct arptab *at;  /* same as "merge" flag */
X	struct mbuf *mcopy = 0;
X	struct sockaddr_in sin;
X	struct sockaddr sa;
X	struct in_addr isaddr, itaddr, myaddr;
X	int proto, op, s, completed = 0;
X
X	myaddr = ac->ac_ipaddr;
X	ea = mtod(m, struct ether_arp *);
X	proto = ntohs(ea->arp_pro);
X	op = ntohs(ea->arp_op);
X	bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof (isaddr));
X	bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof (itaddr));
X	if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr,
X	  sizeof (ea->arp_sha)))
X		goto out;	/* it's from me, ignore it. */
X	if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr,
X	    sizeof (ea->arp_sha))) {
X		log(LOG_ERR,
X		    "arp: ether address is broadcast for IP address %x!\n",
X		    ntohl(isaddr.s_addr));
X		goto out;
X	}
X	if (isaddr.s_addr == myaddr.s_addr) {
X		log(LOG_ERR, "%s: %s\n",
X			"duplicate IP address!! sent from ethernet address",
X			ether_sprintf(ea->arp_sha));
X		itaddr = myaddr;
X		if (op == ARPOP_REQUEST)
X			goto reply;
X		goto out;
X	}
X	s = splimp();
X	ARPTAB_LOOK(at, isaddr.s_addr);
X	if (at) {
X		bcopy((caddr_t)ea->arp_sha, (caddr_t)at->at_enaddr,
X		    sizeof(ea->arp_sha));
X		if ((at->at_flags & ATF_COM) == 0)
X			completed = 1;
X		at->at_flags |= ATF_COM;
X		if (at->at_hold) {
X			sin.sin_family = AF_INET;
X			sin.sin_addr = isaddr;
X			(*ac->ac_if.if_output)(&ac->ac_if, 
X			    at->at_hold, (struct sockaddr *)&sin);
X			at->at_hold = 0;
X		}
X	}
X	if (at == 0 && itaddr.s_addr == myaddr.s_addr) {
X		/* ensure we have a table entry */
X		if (at = arptnew(&isaddr)) {
X			bcopy((caddr_t)ea->arp_sha, (caddr_t)at->at_enaddr,
X			    sizeof(ea->arp_sha));
X			completed = 1;
X			at->at_flags |= ATF_COM;
X		}
X	}
X	splx(s);
Xreply:
X	switch (proto) {
X
X	case ETHERTYPE_IPTRAILERS:
X		/* partner says trailers are OK */
X		if (at)
X			at->at_flags |= ATF_USETRAILERS;
X		/*
X		 * Reply to request iff we want trailers.
X		 */
X		if (op != ARPOP_REQUEST || ac->ac_if.if_flags & IFF_NOTRAILERS)
X			goto out;
X		break;
X
X	case ETHERTYPE_IP:
X		/*
X		 * Reply if this is an IP request,
X		 * or if we want to send a trailer response.
X		 * Send the latter only to the IP response
X		 * that completes the current ARP entry.
X		 */
X		if (op != ARPOP_REQUEST &&
X		    (completed == 0 || ac->ac_if.if_flags & IFF_NOTRAILERS))
X			goto out;
X	}
X	if (itaddr.s_addr == myaddr.s_addr) {
X		/* I am the target */
X		bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
X		    sizeof(ea->arp_sha));
X		bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
X		    sizeof(ea->arp_sha));
X	} else {
X		ARPTAB_LOOK(at, itaddr.s_addr);
X		if (at == NULL || (at->at_flags & ATF_PUBL) == 0)
X			goto out;
X		bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
X		    sizeof(ea->arp_sha));
X		bcopy((caddr_t)at->at_enaddr, (caddr_t)ea->arp_sha,
X		    sizeof(ea->arp_sha));
X	}
X
X	bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa,
X	    sizeof(ea->arp_spa));
X	bcopy((caddr_t)&itaddr, (caddr_t)ea->arp_spa,
X	    sizeof(ea->arp_spa));
X	ea->arp_op = htons(ARPOP_REPLY); 
X	/*
X	 * If incoming packet was an IP reply,
X	 * we are sending a reply for type IPTRAILERS.
X	 * If we are sending a reply for type IP
X	 * and we want to receive trailers,
X	 * send a trailer reply as well.
X	 */
X	if (op == ARPOP_REPLY)
X		ea->arp_pro = htons(ETHERTYPE_IPTRAILERS);
X	else if (proto == ETHERTYPE_IP &&
X	    (ac->ac_if.if_flags & IFF_NOTRAILERS) == 0)
X		mcopy = m_copy(m, 0, (int)M_COPYALL);
X	eh = (struct ether_header *)sa.sa_data;
X	bcopy((caddr_t)ea->arp_tha, (caddr_t)eh->ether_dhost,
X	    sizeof(eh->ether_dhost));
X	eh->ether_type = ETHERTYPE_ARP;
X	sa.sa_family = AF_UNSPEC;
X	(*ac->ac_if.if_output)(&ac->ac_if, m, &sa);
X	if (mcopy) {
X		ea = mtod(mcopy, struct ether_arp *);
X		ea->arp_pro = htons(ETHERTYPE_IPTRAILERS);
X		(*ac->ac_if.if_output)(&ac->ac_if, mcopy, &sa);
X	}
X	return;
Xout:
X	m_freem(m);
X	return;
X}
X
X/*
X * Free an arptab entry.
X */
Xarptfree(at)
X	register struct arptab *at;
X{
X	int s = splimp();
X
X	if (at->at_hold)
X		m_freem(at->at_hold);
X	at->at_hold = 0;
X	at->at_timer = at->at_flags = 0;
X	at->at_iaddr.s_addr = 0;
X	splx(s);
X}
X
X/*
X * Enter a new address in arptab, pushing out the oldest entry 
X * from the bucket if there is no room.
X * This always succeeds since no bucket can be completely filled
X * with permanent entries (except from arpioctl when testing whether
X * another permanent entry will fit).
X * MUST BE CALLED AT SPLIMP.
X */
Xstruct arptab *
Xarptnew(addr)
X	struct in_addr *addr;
X{
X	register n;
X	int oldest = -1;
X	register struct arptab *at, *ato = NULL;
X	static int first = 1;
X
X	if (first) {
X		first = 0;
X		timeout(arptimer, (caddr_t)0, hz);
X	}
X	at = &arptab[ARPTAB_HASH(addr->s_addr) * ARPTAB_BSIZ];
X	for (n = 0; n < ARPTAB_BSIZ; n++,at++) {
X		if (at->at_flags == 0)
X			goto out;	 /* found an empty entry */
X		if (at->at_flags & ATF_PERM)
X			continue;
X		if ((int) at->at_timer > oldest) {
X			oldest = at->at_timer;
X			ato = at;
X		}
X	}
X	if (ato == NULL)
X		return (NULL);
X	at = ato;
X	arptfree(at);
Xout:
X	at->at_iaddr = *addr;
X	at->at_flags = ATF_INUSE;
X	return (at);
X}
X
Xarpioctl(cmd, data)
X	int cmd;
X	caddr_t data;
X{
X	register struct arpreq *ar = (struct arpreq *)data;
X	register struct arptab *at;
X	register struct sockaddr_in *sin;
X	int s;
X
X	if (ar->arp_pa.sa_family != AF_INET ||
X	    ar->arp_ha.sa_family != AF_UNSPEC)
X		return (EAFNOSUPPORT);
X	sin = (struct sockaddr_in *)&ar->arp_pa;
X	s = splimp();
X	ARPTAB_LOOK(at, sin->sin_addr.s_addr);
X	if (at == NULL) {		/* not found */
X		if (cmd != SIOCSARP) {
X			splx(s);
X			return (ENXIO);
X		}
X		if (ifa_ifwithnet(&ar->arp_pa) == NULL) {
X			splx(s);
X			return (ENETUNREACH);
X		}
X	}
X	switch (cmd) {
X
X	case SIOCSARP:		/* set entry */
X		if (at == NULL) {
X			at = arptnew(&sin->sin_addr);
X			if (at == NULL) {
X				splx(s);
X				return (EADDRNOTAVAIL);
X			}
X			if (ar->arp_flags & ATF_PERM) {
X			/* never make all entries in a bucket permanent */
X				register struct arptab *tat;
X				
X				/* try to re-allocate */
X				tat = arptnew(&sin->sin_addr);
X				if (tat == NULL) {
X					arptfree(at);
X					splx(s);
X					return (EADDRNOTAVAIL);
X				}
X				arptfree(tat);
X			}
X		}
X		bcopy((caddr_t)ar->arp_ha.sa_data, (caddr_t)at->at_enaddr,
X		    sizeof(at->at_enaddr));
X		at->at_flags = ATF_COM | ATF_INUSE |
X			(ar->arp_flags & (ATF_PERM|ATF_PUBL|ATF_USETRAILERS));
X		at->at_timer = 0;
X		break;
X
X	case SIOCDARP:		/* delete entry */
X		arptfree(at);
X		break;
X
X	case SIOCGARP:		/* get entry */
X		bcopy((caddr_t)at->at_enaddr, (caddr_t)ar->arp_ha.sa_data,
X		    sizeof(at->at_enaddr));
X		ar->arp_flags = at->at_flags;
X		break;
X	}
X	splx(s);
X	return (0);
X}
X
X/*
X * Convert Ethernet address to printable (loggable) representation.
X */
Xchar *
Xether_sprintf(ap)
X	register u_char *ap;
X{
X	register i;
X	static char etherbuf[18];
X	register char *cp = etherbuf;
X	static char digits[] = "0123456789abcdef";
X
X	for (i = 0; i < 6; i++) {
X		*cp++ = digits[*ap >> 4];
X		*cp++ = digits[*ap++ & 0xf];
X		*cp++ = ':';
X	}
X	*--cp = 0;
X	return (etherbuf);
X}
END-of-netinet/if_ether.c
echo x - netinet/if_ether.h
sed 's/^X//' >netinet/if_ether.h << 'END-of-netinet/if_ether.h'
X/*
X * Copyright (c) 1982, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)if_ether.h	7.2 (Berkeley) 12/7/87
X */
X
X/*
X * Structure of a 10Mb/s Ethernet header.
X */
Xstruct	ether_header {
X	u_char	ether_dhost[6];
X	u_char	ether_shost[6];
X	u_short	ether_type;
X};
X
X#define	ETHERTYPE_PUP	0x0200		/* PUP protocol */
X#define	ETHERTYPE_IP	0x0800		/* IP protocol */
X#define ETHERTYPE_ARP	0x0806		/* Addr. resolution protocol */
X
X/*
X * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
X * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
X * by an ETHER type (as given above) and then the (variable-length) header.
X */
X#define	ETHERTYPE_TRAIL		0x1000		/* Trailer packet */
X#define	ETHERTYPE_NTRAILER	16
X
X#define	ETHERMTU	1500
X#define	ETHERMIN	(60-14)
X
X/*
X * Ethernet Address Resolution Protocol.
X *
X * See RFC 826 for protocol description.  Structure below is adapted
X * to resolving internet addresses.  Field names used correspond to 
X * RFC 826.
X */
Xstruct	ether_arp {
X	struct	arphdr ea_hdr;	/* fixed-size header */
X	u_char	arp_sha[6];	/* sender hardware address */
X	u_char	arp_spa[4];	/* sender protocol address */
X	u_char	arp_tha[6];	/* target hardware address */
X	u_char	arp_tpa[4];	/* target protocol address */
X};
X#define	arp_hrd	ea_hdr.ar_hrd
X#define	arp_pro	ea_hdr.ar_pro
X#define	arp_hln	ea_hdr.ar_hln
X#define	arp_pln	ea_hdr.ar_pln
X#define	arp_op	ea_hdr.ar_op
X
X
X/*
X * Structure shared between the ethernet driver modules and
X * the address resolution code.  For example, each ec_softc or il_softc
X * begins with this structure.
X */
Xstruct	arpcom {
X	struct 	ifnet ac_if;		/* network-visible interface */
X	u_char	ac_enaddr[6];		/* ethernet hardware address */
X	struct in_addr ac_ipaddr;	/* copy of ip address- XXX */
X};
X
X/*
X * Internet to ethernet address resolution table.
X */
Xstruct	arptab {
X	struct	in_addr at_iaddr;	/* internet address */
X	u_char	at_enaddr[6];		/* ethernet address */
X	u_char	at_timer;		/* minutes since last reference */
X	u_char	at_flags;		/* flags */
X	struct	mbuf *at_hold;		/* last packet until resolved/timeout */
X};
X
X#ifdef	KERNEL
Xu_char etherbroadcastaddr[6];
Xstruct	arptab *arptnew();
Xchar *ether_sprintf();
X#endif
END-of-netinet/if_ether.h
echo x - netinet/in.c
sed 's/^X//' >netinet/in.c << 'END-of-netinet/in.c'
X/*
X * Copyright (c) 1982, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)in.c	7.7 (Berkeley) 4/3/88
X */
X
X#include "param.h"
X#include "ioctl.h"
X#include "mbuf.h"
X#include "protosw.h"
X#include "socket.h"
X#include "socketvar.h"
X#include "uio.h"
X#include "dir.h"
X#include "user.h"
X#include "in_systm.h"
X#include "../net/if.h"
X#include "../net/route.h"
X#include "../net/af.h"
X#include "in.h"
X#include "in_var.h"
X
X#ifdef INET
Xinet_hash(sin, hp)
X	register struct sockaddr_in *sin;
X	struct afhash *hp;
X{
X	register u_long n;
X
X	n = in_netof(sin->sin_addr);
X	if (n)
X	    while ((n & 0xff) == 0)
X		n >>= 8;
X	hp->afh_nethash = n;
X	hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);
X}
X
Xinet_netmatch(sin1, sin2)
X	struct sockaddr_in *sin1, *sin2;
X{
X
X	return (in_netof(sin1->sin_addr) == in_netof(sin2->sin_addr));
X}
X
X/*
X * Formulate an Internet address from network + host.
X */
Xstruct in_addr
Xin_makeaddr(net, host)
X	u_long net, host;
X{
X	register struct in_ifaddr *ia;
X	register u_long mask;
X	u_long addr;
X
X	if (IN_CLASSA(net))
X		mask = IN_CLASSA_HOST;
X	else if (IN_CLASSB(net))
X		mask = IN_CLASSB_HOST;
X	else
X		mask = IN_CLASSC_HOST;
X	for (ia = in_ifaddr; ia; ia = ia->ia_next)
X		if ((ia->ia_netmask & net) == ia->ia_net) {
X			mask = ~ia->ia_subnetmask;
X			break;
X		}
X	addr = htonl(net | (host & mask));
X	return (*(struct in_addr *)&addr);
X}
X
X/*
X * Return the network number from an internet address.
X */
Xu_long
Xin_netof(in)
X	struct in_addr in;
X{
X	register u_long i = ntohl(in.s_addr);
X	register u_long net;
X	register struct in_ifaddr *ia;
X
X	if (IN_CLASSA(i))
X		net = i & IN_CLASSA_NET;
X	else if (IN_CLASSB(i))
X		net = i & IN_CLASSB_NET;
X	else if (IN_CLASSC(i))
X		net = i & IN_CLASSC_NET;
X	else
X		return (0);
X
X	/*
X	 * Check whether network is a subnet;
X	 * if so, return subnet number.
X	 */
X	for (ia = in_ifaddr; ia; ia = ia->ia_next)
X		if (net == ia->ia_net)
X			return (i & ia->ia_subnetmask);
X	return (net);
X}
X
X/*
X * Return the host portion of an internet address.
X */
Xu_long
Xin_lnaof(in)
X	struct in_addr in;
X{
X	register u_long i = ntohl(in.s_addr);
X	register u_long net, host;
X	register struct in_ifaddr *ia;
X
X	if (IN_CLASSA(i)) {
X		net = i & IN_CLASSA_NET;
X		host = i & IN_CLASSA_HOST;
X	} else if (IN_CLASSB(i)) {
X		net = i & IN_CLASSB_NET;
X		host = i & IN_CLASSB_HOST;
X	} else if (IN_CLASSC(i)) {
X		net = i & IN_CLASSC_NET;
X		host = i & IN_CLASSC_HOST;
X	} else
X		return (i);
X
X	/*
X	 * Check whether network is a subnet;
X	 * if so, use the modified interpretation of `host'.
X	 */
X	for (ia = in_ifaddr; ia; ia = ia->ia_next)
X		if (net == ia->ia_net)
X			return (host &~ ia->ia_subnetmask);
X	return (host);
X}
X
X#ifndef SUBNETSARELOCAL
X#define	SUBNETSARELOCAL	1
X#endif
Xint subnetsarelocal = SUBNETSARELOCAL;
X/*
X * Return 1 if an internet address is for a ``local'' host
X * (one to which we have a connection).  If subnetsarelocal
X * is true, this includes other subnets of the local net.
X * Otherwise, it includes only the directly-connected (sub)nets.
X */
Xin_localaddr(in)
X	struct in_addr in;
X{
X	register u_long i = ntohl(in.s_addr);
X	register struct in_ifaddr *ia;
X
X	if (subnetsarelocal) {
X		for (ia = in_ifaddr; ia; ia = ia->ia_next)
X			if ((i & ia->ia_netmask) == ia->ia_net)
X				return (1);
X	} else {
X		for (ia = in_ifaddr; ia; ia = ia->ia_next)
X			if ((i & ia->ia_subnetmask) == ia->ia_subnet)
X				return (1);
X	}
X	return (0);
X}
X
X/*
X * Determine whether an IP address is in a reserved set of addresses
X * that may not be forwarded, or whether datagrams to that destination
X * may be forwarded.
X */
Xin_canforward(in)
X	struct in_addr in;
X{
X	register u_long i = ntohl(in.s_addr);
X	register u_long net;
X
X	if (IN_EXPERIMENTAL(i))
X		return (0);
X	if (IN_CLASSA(i)) {
X		net = i & IN_CLASSA_NET;
X		if (net == 0 || net == IN_LOOPBACKNET)
X			return (0);
X	}
X	return (1);
X}
X
Xint	in_interfaces;		/* number of external internet interfaces */
Xextern	struct ifnet loif;
X
X/*
X * Generic internet control operations (ioctl's).
X * Ifp is 0 if not an interface-specific ioctl.
X */
X/* ARGSUSED */
Xin_control(so, cmd, data, ifp)
X	struct socket *so;
X	int cmd;
X	caddr_t data;
X	register struct ifnet *ifp;
X{
X	register struct ifreq *ifr = (struct ifreq *)data;
X	register struct in_ifaddr *ia = 0;
X	struct ifaddr *ifa;
X	struct mbuf *m;
X	int error;
X
X	/*
X	 * Find address for this interface, if it exists.
X	 */
X	if (ifp)
X		for (ia = in_ifaddr; ia; ia = ia->ia_next)
X			if (ia->ia_ifp == ifp)
X				break;
X
X	switch (cmd) {
X
X	case SIOCSIFADDR:
X	case SIOCSIFNETMASK:
X	case SIOCSIFDSTADDR:
X		if (!suser())
X			return (u.u_error);
X
X		if (ifp == 0)
X			panic("in_control");
X		if (ia == (struct in_ifaddr *)0) {
X			m = m_getclr(M_WAIT, MT_IFADDR);
X			if (m == (struct mbuf *)NULL)
X				return (ENOBUFS);
X			if (ia = in_ifaddr) {
X				for ( ; ia->ia_next; ia = ia->ia_next)
X					;
X				ia->ia_next = mtod(m, struct in_ifaddr *);
X			} else
X				in_ifaddr = mtod(m, struct in_ifaddr *);
X			ia = mtod(m, struct in_ifaddr *);
X			if (ifa = ifp->if_addrlist) {
X				for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
X					;
X				ifa->ifa_next = (struct ifaddr *) ia;
X			} else
X				ifp->if_addrlist = (struct ifaddr *) ia;
X			ia->ia_ifp = ifp;
X			IA_SIN(ia)->sin_family = AF_INET;
X			if (ifp != &loif)
X				in_interfaces++;
X		}
X		break;
X
X	case SIOCSIFBRDADDR:
X		if (!suser())
X			return (u.u_error);
X		/* FALLTHROUGH */
X
X	default:
X		if (ia == (struct in_ifaddr *)0)
X			return (EADDRNOTAVAIL);
X		break;
X	}
X
X	switch (cmd) {
X
X	case SIOCGIFADDR:
X		ifr->ifr_addr = ia->ia_addr;
X		break;
X
X	case SIOCGIFBRDADDR:
X		if ((ifp->if_flags & IFF_BROADCAST) == 0)
X			return (EINVAL);
X		ifr->ifr_dstaddr = ia->ia_broadaddr;
X		break;
X
X	case SIOCGIFDSTADDR:
X		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
X			return (EINVAL);
X		ifr->ifr_dstaddr = ia->ia_dstaddr;
X		break;
X
X	case SIOCGIFNETMASK:
X#define	satosin(sa)	((struct sockaddr_in *)(sa))
X		satosin(&ifr->ifr_addr)->sin_family = AF_INET;
X		satosin(&ifr->ifr_addr)->sin_addr.s_addr = htonl(ia->ia_subnetmask);
X		break;
X
X	case SIOCSIFDSTADDR:
X	    {
X		struct sockaddr oldaddr;
X
X		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
X			return (EINVAL);
X		oldaddr = ia->ia_dstaddr;
X		ia->ia_dstaddr = ifr->ifr_dstaddr;
X		if (ifp->if_ioctl &&
X		    (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia))) {
X			ia->ia_dstaddr = oldaddr;
X			return (error);
X		}
X		if (ia->ia_flags & IFA_ROUTE) {
X			rtinit(&oldaddr, &ia->ia_addr, (int)SIOCDELRT,
X			    RTF_HOST);
X			rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT,
X			    RTF_HOST|RTF_UP);
X		}
X	    }
X		break;
X
X	case SIOCSIFBRDADDR:
X		if ((ifp->if_flags & IFF_BROADCAST) == 0)
X			return (EINVAL);
X		ia->ia_broadaddr = ifr->ifr_broadaddr;
X		break;
X
X	case SIOCSIFADDR:
X		return (in_ifinit(ifp, ia, &ifr->ifr_addr));
X
X	case SIOCSIFNETMASK:
X		ia->ia_subnetmask = ntohl(satosin(&ifr->ifr_addr)->sin_addr.s_addr);
X		break;
X
X	default:
X		if (ifp == 0 || ifp->if_ioctl == 0)
X			return (EOPNOTSUPP);
X		return ((*ifp->if_ioctl)(ifp, cmd, data));
X	}
X	return (0);
X}
X
X/*
X * Initialize an interface's internet address
X * and routing table entry.
X */
Xin_ifinit(ifp, ia, sin)
X	register struct ifnet *ifp;
X	register struct in_ifaddr *ia;
X	struct sockaddr_in *sin;
X{
X	register u_long i = ntohl(sin->sin_addr.s_addr);
X	struct sockaddr oldaddr;
X	struct sockaddr_in netaddr;
X	int s = splimp(), error;
X
X	oldaddr = ia->ia_addr;
X	ia->ia_addr = *(struct sockaddr *)sin;
X
X	/*
X	 * Give the interface a chance to initialize
X	 * if this is its first address,
X	 * and to validate the address if necessary.
X	 */
X	if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
X		splx(s);
X		ia->ia_addr = oldaddr;
X		return (error);
X	}
X
X	/*
X	 * Delete any previous route for an old address.
X	 */
X	bzero((caddr_t)&netaddr, sizeof (netaddr));
X	netaddr.sin_family = AF_INET;
X	if (ia->ia_flags & IFA_ROUTE) {
X		if (ifp->if_flags & IFF_LOOPBACK)
X			rtinit(&oldaddr, &oldaddr, (int)SIOCDELRT, RTF_HOST);
X		else if (ifp->if_flags & IFF_POINTOPOINT)
X			rtinit(&ia->ia_dstaddr, &oldaddr, (int)SIOCDELRT,
X			    RTF_HOST);
X		else {
X			netaddr.sin_addr = in_makeaddr(ia->ia_subnet,
X			    INADDR_ANY);
X			rtinit((struct sockaddr *)&netaddr, &oldaddr, 
X			    (int)SIOCDELRT, 0);
X		}
X		ia->ia_flags &= ~IFA_ROUTE;
X	}
X	if (IN_CLASSA(i))
X		ia->ia_netmask = IN_CLASSA_NET;
X	else if (IN_CLASSB(i))
X		ia->ia_netmask = IN_CLASSB_NET;
X	else
X		ia->ia_netmask = IN_CLASSC_NET;
X	ia->ia_net = i & ia->ia_netmask;
X	/*
X	 * The subnet mask includes at least the standard network part,
X	 * but may already have been set to a larger value.
X	 */
X	ia->ia_subnetmask |= ia->ia_netmask;
X	ia->ia_subnet = i & ia->ia_subnetmask;
X	if (ifp->if_flags & IFF_BROADCAST) {
X		ia->ia_broadaddr.sa_family = AF_INET;
X		((struct sockaddr_in *)(&ia->ia_broadaddr))->sin_addr =
X			in_makeaddr(ia->ia_subnet, INADDR_BROADCAST);
X		ia->ia_netbroadcast.s_addr =
X		    htonl(ia->ia_net | (INADDR_BROADCAST &~ ia->ia_netmask));
X	}
X	/*
X	 * Add route for the network.
X	 */
X	if (ifp->if_flags & IFF_LOOPBACK)
X		rtinit(&ia->ia_addr, &ia->ia_addr, (int)SIOCADDRT,
X		    RTF_HOST|RTF_UP);
X	else if (ifp->if_flags & IFF_POINTOPOINT)
X		rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT,
X		    RTF_HOST|RTF_UP);
X	else {
X		netaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY);
X		rtinit((struct sockaddr *)&netaddr, &ia->ia_addr,
X		    (int)SIOCADDRT, RTF_UP);
X	}
X	ia->ia_flags |= IFA_ROUTE;
X	splx(s);
X	return (0);
X}
X
X/*
X * Return address info for specified internet network.
X */
Xstruct in_ifaddr *
Xin_iaonnetof(net)
X	u_long net;
X{
X	register struct in_ifaddr *ia;
X
X	for (ia = in_ifaddr; ia; ia = ia->ia_next)
X		if (ia->ia_subnet == net)
X			return (ia);
X	return ((struct in_ifaddr *)0);
X}
X
X/*
X * Return 1 if the address might be a local broadcast address.
X */
Xin_broadcast(in)
X	struct in_addr in;
X{
X	register struct in_ifaddr *ia;
X	u_long t;
X
X	/*
X	 * Look through the list of addresses for a match
X	 * with a broadcast address.
X	 */
X	for (ia = in_ifaddr; ia; ia = ia->ia_next)
X	    if (ia->ia_ifp->if_flags & IFF_BROADCAST) {
X		if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr == in.s_addr)
X		     return (1);
X		/*
X		 * Check for old-style (host 0) broadcast.
X		 */
X		if ((t = ntohl(in.s_addr)) == ia->ia_subnet || t == ia->ia_net)
X		    return (1);
X	}
X	if (in.s_addr == INADDR_BROADCAST || in.s_addr == INADDR_ANY)
X		return (1);
X	return (0);
X}
X#endif
END-of-netinet/in.c
echo x - netinet/in.h
sed 's/^X//' >netinet/in.h << 'END-of-netinet/in.h'
X/*
X * Copyright (c) 1982, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)in.h	7.5 (Berkeley) 2/22/88
X */
X
X/*
X * Constants and structures defined by the internet system,
X * Per RFC 790, September 1981.
X */
X
X/*
X * Protocols
X */
X#define	IPPROTO_IP		0		/* dummy for IP */
X#define	IPPROTO_ICMP		1		/* control message protocol */
X#define	IPPROTO_GGP		3		/* gateway^2 (deprecated) */
X#define	IPPROTO_TCP		6		/* tcp */
X#define	IPPROTO_EGP		8		/* exterior gateway protocol */
X#define	IPPROTO_PUP		12		/* pup */
X#define	IPPROTO_UDP		17		/* user datagram protocol */
X#define	IPPROTO_IDP		22		/* xns idp */
X
X#define	IPPROTO_RAW		255		/* raw IP packet */
X#define	IPPROTO_MAX		256
X
X
X/*
X * Ports < IPPORT_RESERVED are reserved for
X * privileged processes (e.g. root).
X * Ports > IPPORT_USERRESERVED are reserved
X * for servers, not necessarily privileged.
X */
X#define	IPPORT_RESERVED		1024
X#define	IPPORT_USERRESERVED	5000
X
X/*
X * Link numbers
X */
X#define	IMPLINK_IP		155
X#define	IMPLINK_LOWEXPER	156
X#define	IMPLINK_HIGHEXPER	158
X
X/*
X * Internet address (a structure for historical reasons)
X */
Xstruct in_addr {
X	u_long s_addr;
X};
X
X/*
X * Definitions of bits in internet address integers.
X * On subnets, the decomposition of addresses to host and net parts
X * is done according to subnet mask, not the masks here.
X */
X#define	IN_CLASSA(i)		(((long)(i) & 0x80000000) == 0)
X#define	IN_CLASSA_NET		0xff000000
X#define	IN_CLASSA_NSHIFT	24
X#define	IN_CLASSA_HOST		0x00ffffff
X#define	IN_CLASSA_MAX		128
X
X#define	IN_CLASSB(i)		(((long)(i) & 0xc0000000) == 0x80000000)
X#define	IN_CLASSB_NET		0xffff0000
X#define	IN_CLASSB_NSHIFT	16
X#define	IN_CLASSB_HOST		0x0000ffff
X#define	IN_CLASSB_MAX		65536
X
X#define	IN_CLASSC(i)		(((long)(i) & 0xe0000000) == 0xc0000000)
X#define	IN_CLASSC_NET		0xffffff00
X#define	IN_CLASSC_NSHIFT	8
X#define	IN_CLASSC_HOST		0x000000ff
X
X#define	IN_CLASSD(i)		(((long)(i) & 0xf0000000) == 0xe0000000)
X#define	IN_MULTICAST(i)		IN_CLASSD(i)
X
X#define	IN_EXPERIMENTAL(i)	(((long)(i) & 0xe0000000) == 0xe0000000)
X#define	IN_BADCLASS(i)		(((long)(i) & 0xf0000000) == 0xf0000000)
X
X#define	INADDR_ANY		(u_long)0x00000000
X#define	INADDR_BROADCAST	(u_long)0xffffffff	/* must be masked */
X#ifndef KERNEL
X#define	INADDR_NONE		0xffffffff		/* -1 return */
X#endif
X
X#define	IN_LOOPBACKNET		127			/* official! */
X
X/*
X * Socket address, internet style.
X */
Xstruct sockaddr_in {
X	short	sin_family;
X	u_short	sin_port;
X	struct	in_addr sin_addr;
X	char	sin_zero[8];
X};
X
X/*
X * Options for use with [gs]etsockopt at the IP level.
X */
X#define	IP_OPTIONS	1		/* set/get IP per-packet options */
X
X#ifdef KERNEL
Xextern	struct domain inetdomain;
Xextern	struct protosw inetsw[];
Xstruct	in_addr in_makeaddr();
Xu_long	in_netof(), in_lnaof();
X#endif
END-of-netinet/in.h
echo x - netinet/in_cksum.c
sed 's/^X//' >netinet/in_cksum.c << 'END-of-netinet/in_cksum.c'
X/*
X * Copyright (c) 1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)in_cksum.c	7.1 (Berkeley) 3/29/88
X */
X
X#include "../h/types.h"
X#include "../h/mbuf.h"
X
X/*
X * Checksum routine for Internet Protocol family headers (Portable Version).
X *
X * This routine is very heavily used in the network
X * code and should be modified for each CPU to be as fast as possible.
X */
X
X#define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
X#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
X
Xin_cksum_c(m, len)
X	register struct mbuf *m;
X	register int len;
X{
X	register u_short *w;
X	register int sum = 0;
X	register int mlen = 0;
X	int byte_swapped = 0;
X
X	union {
X		char	c[2];
X		u_short	s;
X	} s_util;
X	union {
X		u_short s[2];
X		long	l;
X	} l_util;
X
X	for (;m && len; m = m->m_next) {
X		if (m->m_len == 0)
X			continue;
X		w = mtod(m, u_short *);
X		if (mlen == -1) {
X			/*
X			 * The first byte of this mbuf is the continuation
X			 * of a word spanning between this mbuf and the
X			 * last mbuf.
X			 *
X			 * s_util.c[0] is already saved when scanning previous 
X			 * mbuf.
X			 */
X			s_util.c[1] = *(char *)w;
X			sum += s_util.s;
X			w = (u_short *)((char *)w + 1);
X			mlen = m->m_len - 1;
X			len--;
X		} else
X			mlen = m->m_len;
X		if (len < mlen)
X			mlen = len;
X		len -= mlen;
X		/*
X		 * Force to even boundary.
X		 */
X		if ((1 & (int) w) && (mlen > 0)) {
X			REDUCE;
X			sum <<= 8;
X			s_util.c[0] = *(u_char *)w;
X			w = (u_short *)((char *)w + 1);
X			mlen--;
X			byte_swapped = 1;
X		}
X		/*
X		 * Unroll the loop to make overhead from
X		 * branches &c small.
X		 */
X		while ((mlen -= 32) >= 0) {
X			sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
X			sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
X			sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
X			sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
X			w += 16;
X		}
X		mlen += 32;
X		while ((mlen -= 8) >= 0) {
X			sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
X			w += 4;
X		}
X		mlen += 8;
X		if (mlen == 0 && byte_swapped == 0)
X			continue;
X		REDUCE;
X		while ((mlen -= 2) >= 0) {
X			sum += *w++;
X		}
X		if (byte_swapped) {
X			REDUCE;
X			sum <<= 8;
X			byte_swapped = 0;
X			if (mlen == -1) {
X				s_util.c[1] = *(char *)w;
X				sum += s_util.s;
X				mlen = 0;
X			} else
X				mlen = -1;
X		} else if (mlen == -1)
X			s_util.c[0] = *(char *)w;
X	}
X	if (len)
X		printf("cksum: out of data\n");
X	if (mlen == -1) {
X		/* The last mbuf has odd # of bytes. Follow the
X		   standard (the odd byte may be shifted left by 8 bits
X		   or not as determined by endian-ness of the machine) */
X		s_util.c[1] = 0;
X		sum += s_util.s;
X	}
X	REDUCE;
X	return (~sum & 0xffff);
X}
END-of-netinet/in_cksum.c
echo x - netinet/in_pcb.c
sed 's/^X//' >netinet/in_pcb.c << 'END-of-netinet/in_pcb.c'
X/*
X * Copyright (c) 1982, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)in_pcb.c	7.6 (Berkeley) 12/7/87
X */
X
X#include "param.h"
X#include "systm.h"
X#include "dir.h"
X#include "user.h"
X#include "mbuf.h"
X#include "socket.h"
X#include "socketvar.h"
X#include "ioctl.h"
X#include "in.h"
X#include "in_systm.h"
X#include "../net/if.h"
X#include "../net/route.h"
X#include "in_pcb.h"
X#include "in_var.h"
X#include "protosw.h"
X
Xstruct	in_addr zeroin_addr;
X
Xin_pcballoc(so, head)
X	struct socket *so;
X	struct inpcb *head;
X{
X	struct mbuf *m;
X	register struct inpcb *inp;
X
X	m = m_getclr(M_DONTWAIT, MT_PCB);
X	if (m == NULL)
X		return (ENOBUFS);
X	inp = mtod(m, struct inpcb *);
X	inp->inp_head = head;
X	inp->inp_socket = so;
X	insque(inp, head);
X	so->so_pcb = (caddr_t)inp;
X	return (0);
X}
X	
Xin_pcbbind(inp, nam)
X	register struct inpcb *inp;
X	struct mbuf *nam;
X{
X	register struct socket *so = inp->inp_socket;
X	register struct inpcb *head = inp->inp_head;
X	register struct sockaddr_in *sin;
X	u_short lport = 0;
X
X	if (in_ifaddr == 0)
X		return (EADDRNOTAVAIL);
X	if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY)
X		return (EINVAL);
X	if (nam == 0)
X		goto noname;
X	sin = mtod(nam, struct sockaddr_in *);
X	if (nam->m_len != sizeof (*sin))
X		return (EINVAL);
X	if (sin->sin_addr.s_addr != INADDR_ANY) {
X		int tport = sin->sin_port;
X
X		sin->sin_port = 0;		/* yech... */
X		if (ifa_ifwithaddr((struct sockaddr *)sin) == 0)
X			return (EADDRNOTAVAIL);
X		sin->sin_port = tport;
X	}
X	lport = sin->sin_port;
X	if (lport) {
X		u_short aport = ntohs(lport);
X		int wild = 0;
X
X		/* GROSS */
X		if (aport < IPPORT_RESERVED && u.u_uid != 0)
X			return (EACCES);
X		/* even GROSSER, but this is the Internet */
X		if ((so->so_options & SO_REUSEADDR) == 0 &&
X		    ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
X		     (so->so_options & SO_ACCEPTCONN) == 0))
X			wild = INPLOOKUP_WILDCARD;
X		if (in_pcblookup(head,
X		    zeroin_addr, 0, sin->sin_addr, lport, wild))
X			return (EADDRINUSE);
X	}
X	inp->inp_laddr = sin->sin_addr;
Xnoname:
X	if (lport == 0)
X		do {
X			if (head->inp_lport++ < IPPORT_RESERVED ||
X			    head->inp_lport > IPPORT_USERRESERVED)
X				head->inp_lport = IPPORT_RESERVED;
X			lport = htons(head->inp_lport);
X		} while (in_pcblookup(head,
X			    zeroin_addr, 0, inp->inp_laddr, lport, 0));
X	inp->inp_lport = lport;
X	return (0);
X}
X
X/*
X * Connect from a socket to a specified address.
X * Both address and port must be specified in argument sin.
X * If don't have a local address for this socket yet,
X * then pick one.
X */
Xin_pcbconnect(inp, nam)
X	register struct inpcb *inp;
X	struct mbuf *nam;
X{
X	struct in_ifaddr *ia;
X	struct sockaddr_in *ifaddr;
X	register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
X
X	if (nam->m_len != sizeof (*sin))
X		return (EINVAL);
X	if (sin->sin_family != AF_INET)
X		return (EAFNOSUPPORT);
X	if (sin->sin_port == 0)
X		return (EADDRNOTAVAIL);
X	if (in_ifaddr) {
X		/*
X		 * If the destination address is INADDR_ANY,
X		 * use the primary local address.
X		 * If the supplied address is INADDR_BROADCAST,
X		 * and the primary interface supports broadcast,
X		 * choose the broadcast address for that interface.
X		 */
X#define	satosin(sa)	((struct sockaddr_in *)(sa))
X		if (sin->sin_addr.s_addr == INADDR_ANY)
X		    sin->sin_addr = IA_SIN(in_ifaddr)->sin_addr;
X		else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST &&
X		  (in_ifaddr->ia_ifp->if_flags & IFF_BROADCAST))
X		    sin->sin_addr = satosin(&in_ifaddr->ia_broadaddr)->sin_addr;
X	}
X	if (inp->inp_laddr.s_addr == INADDR_ANY) {
X		register struct route *ro;
X		struct ifnet *ifp;
X
X		ia = (struct in_ifaddr *)0;
X		/* 
X		 * If route is known or can be allocated now,
X		 * our src addr is taken from the i/f, else punt.
X		 */
X		ro = &inp->inp_route;
X		if (ro->ro_rt &&
X		    (satosin(&ro->ro_dst)->sin_addr.s_addr !=
X			sin->sin_addr.s_addr || 
X		    inp->inp_socket->so_options & SO_DONTROUTE)) {
X			RTFREE(ro->ro_rt);
X			ro->ro_rt = (struct rtentry *)0;
X		}
X		if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
X		    (ro->ro_rt == (struct rtentry *)0 ||
X		    ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
X			/* No route yet, so try to acquire one */
X			ro->ro_dst.sa_family = AF_INET;
X			((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
X				sin->sin_addr;
X			rtalloc(ro);
X		}
X		/*
X		 * If we found a route, use the address
X		 * corresponding to the outgoing interface
X		 * unless it is the loopback (in case a route
X		 * to our address on another net goes to loopback).
X		 */
X		if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp) &&
X		    (ifp->if_flags & IFF_LOOPBACK) == 0)
X			for (ia = in_ifaddr; ia; ia = ia->ia_next)
X				if (ia->ia_ifp == ifp)
X					break;
X		if (ia == 0) {
X			int fport = sin->sin_port;
X
X			sin->sin_port = 0;
X			ia = (struct in_ifaddr *)
X			    ifa_ifwithdstaddr((struct sockaddr *)sin);
X			sin->sin_port = fport;
X			if (ia == 0)
X				ia = in_iaonnetof(in_netof(sin->sin_addr));
X			if (ia == 0)
X				ia = in_ifaddr;
X			if (ia == 0)
X				return (EADDRNOTAVAIL);
X		}
X		ifaddr = (struct sockaddr_in *)&ia->ia_addr;
X	}
X	if (in_pcblookup(inp->inp_head,
X	    sin->sin_addr,
X	    sin->sin_port,
X	    inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr,
X	    inp->inp_lport,
X	    0))
X		return (EADDRINUSE);
X	if (inp->inp_laddr.s_addr == INADDR_ANY) {
X		if (inp->inp_lport == 0)
X			(void)in_pcbbind(inp, (struct mbuf *)0);
X		inp->inp_laddr = ifaddr->sin_addr;
X	}
X	inp->inp_faddr = sin->sin_addr;
X	inp->inp_fport = sin->sin_port;
X	return (0);
X}
X
Xin_pcbdisconnect(inp)
X	struct inpcb *inp;
X{
X
X	inp->inp_faddr.s_addr = INADDR_ANY;
X	inp->inp_fport = 0;
X	if (inp->inp_socket->so_state & SS_NOFDREF)
X		in_pcbdetach(inp);
X}
X
Xin_pcbdetach(inp)
X	struct inpcb *inp;
X{
X	struct socket *so = inp->inp_socket;
X
X	so->so_pcb = 0;
X	sofree(so);
X	if (inp->inp_options)
X		(void)m_free(inp->inp_options);
X	if (inp->inp_route.ro_rt)
X		rtfree(inp->inp_route.ro_rt);
X	remque(inp);
X	(void) m_free(dtom(inp));
X}
X
Xin_setsockaddr(inp, nam)
X	register struct inpcb *inp;
X	struct mbuf *nam;
X{
X	register struct sockaddr_in *sin;
X	
X	nam->m_len = sizeof (*sin);
X	sin = mtod(nam, struct sockaddr_in *);
X	bzero((caddr_t)sin, sizeof (*sin));
X	sin->sin_family = AF_INET;
X	sin->sin_port = inp->inp_lport;
X	sin->sin_addr = inp->inp_laddr;
X}
X
Xin_setpeeraddr(inp, nam)
X	struct inpcb *inp;
X	struct mbuf *nam;
X{
X	register struct sockaddr_in *sin;
X	
X	nam->m_len = sizeof (*sin);
X	sin = mtod(nam, struct sockaddr_in *);
X	bzero((caddr_t)sin, sizeof (*sin));
X	sin->sin_family = AF_INET;
X	sin->sin_port = inp->inp_fport;
X	sin->sin_addr = inp->inp_faddr;
X}
X
X/*
X * Pass some notification to all connections of a protocol
X * associated with address dst.  Call the protocol specific
X * routine (if any) to handle each connection.
X */
Xin_pcbnotify(head, dst, errno, notify)
X	struct inpcb *head;
X	register struct in_addr *dst;
X	int errno, (*notify)();
X{
X	register struct inpcb *inp, *oinp;
X	int s = splimp();
X
X	for (inp = head->inp_next; inp != head;) {
X		if (inp->inp_faddr.s_addr != dst->s_addr ||
X		    inp->inp_socket == 0) {
X			inp = inp->inp_next;
X			continue;
X		}
X		if (errno) 
X			inp->inp_socket->so_error = errno;
X		oinp = inp;
X		inp = inp->inp_next;
X		if (notify)
X			(*notify)(oinp);
X	}
X	splx(s);
X}
X
X/*
X * Check for alternatives when higher level complains
X * about service problems.  For now, invalidate cached
X * routing information.  If the route was created dynamically
X * (by a redirect), time to try a default gateway again.
X */
Xin_losing(inp)
X	struct inpcb *inp;
X{
X	register struct rtentry *rt;
X
X	if ((rt = inp->inp_route.ro_rt)) {
X		if (rt->rt_flags & RTF_DYNAMIC)
X			(void) rtrequest((int)SIOCDELRT, rt);
X		rtfree(rt);
X		inp->inp_route.ro_rt = 0;
X		/*
X		 * A new route can be allocated
X		 * the next time output is attempted.
X		 */
X	}
X}
X
X/*
X * After a routing change, flush old routing
X * and allocate a (hopefully) better one.
X */
Xin_rtchange(inp)
X	register struct inpcb *inp;
X{
X	if (inp->inp_route.ro_rt) {
X		rtfree(inp->inp_route.ro_rt);
X		inp->inp_route.ro_rt = 0;
X		/*
X		 * A new route can be allocated the next time
X		 * output is attempted.
X		 */
X	}
X}
X
Xstruct inpcb *
Xin_pcblookup(head, faddr, fport, laddr, lport, flags)
X	struct inpcb *head;
X	struct in_addr faddr, laddr;
X	u_short fport, lport;
X	int flags;
X{
X	register struct inpcb *inp, *match = 0;
X	int matchwild = 3, wildcard;
X
X	for (inp = head->inp_next; inp != head; inp = inp->inp_next) {
X		if (inp->inp_lport != lport)
X			continue;
X		wildcard = 0;
X		if (inp->inp_laddr.s_addr != INADDR_ANY) {
X			if (laddr.s_addr == INADDR_ANY)
X				wildcard++;
X			else if (inp->inp_laddr.s_addr != laddr.s_addr)
X				continue;
X		} else {
X			if (laddr.s_addr != INADDR_ANY)
X				wildcard++;
X		}
X		if (inp->inp_faddr.s_addr != INADDR_ANY) {
X			if (faddr.s_addr == INADDR_ANY)
X				wildcard++;
X			else if (inp->inp_faddr.s_addr != faddr.s_addr ||
X			    inp->inp_fport != fport)
X				continue;
X		} else {
X			if (faddr.s_addr != INADDR_ANY)
X				wildcard++;
X		}
X		if (wildcard && (flags & INPLOOKUP_WILDCARD) == 0)
X			continue;
X		if (wildcard < matchwild) {
X			match = inp;
X			matchwild = wildcard;
X			if (matchwild == 0)
X				break;
X		}
X	}
X	return (match);
X}
END-of-netinet/in_pcb.c
echo x - netinet/in_pcb.h
sed 's/^X//' >netinet/in_pcb.h << 'END-of-netinet/in_pcb.h'
X/*
X * Copyright (c) 1982, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)in_pcb.h	7.2 (Berkeley) 12/7/87
X */
X
X/*
X * Common structure pcb for internet protocol implementation.
X * Here are stored pointers to local and foreign host table
X * entries, local and foreign socket numbers, and pointers
X * up (to a socket structure) and down (to a protocol-specific)
X * control block.
X */
Xstruct inpcb {
X	struct	inpcb *inp_next,*inp_prev;
X					/* pointers to other pcb's */
X	struct	inpcb *inp_head;	/* pointer back to chain of inpcb's
X					   for this protocol */
X	struct	in_addr inp_faddr;	/* foreign host table entry */
X	u_short	inp_fport;		/* foreign port */
X	struct	in_addr inp_laddr;	/* local host table entry */
X	u_short	inp_lport;		/* local port */
X	struct	socket *inp_socket;	/* back pointer to socket */
X	caddr_t	inp_ppcb;		/* pointer to per-protocol pcb */
X	struct	route inp_route;	/* placeholder for routing entry */
X	struct	mbuf *inp_options;	/* IP options */
X};
X
X#define	INPLOOKUP_WILDCARD	1
X#define	INPLOOKUP_SETLOCAL	2
X
X#define	sotoinpcb(so)	((struct inpcb *)(so)->so_pcb)
X
X#ifdef KERNEL
Xstruct	inpcb *in_pcblookup();
X#endif
END-of-netinet/in_pcb.h
echo x - netinet/in_proto.c
sed 's/^X//' >netinet/in_proto.c << 'END-of-netinet/in_proto.c'
X/*
X * Copyright (c) 1982, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)in_proto.c	7.2 (Berkeley) 12/7/87
X */
X
X#include "param.h"
X#include "socket.h"
X#include "protosw.h"
X#include "domain.h"
X#include "mbuf.h"
X
X#include "in.h"
X#include "in_systm.h"
X
X/*
X * TCP/IP protocol family: IP, ICMP, UDP, TCP.
X */
Xint	ip_output(),ip_ctloutput();
Xint	ip_init(),ip_slowtimo(),ip_drain();
Xint	icmp_input();
Xint	udp_input(),udp_ctlinput();
Xint	udp_usrreq();
Xint	udp_init();
Xint	tcp_input(),tcp_ctlinput();
Xint	tcp_usrreq(),tcp_ctloutput();
Xint	tcp_init(),tcp_fasttimo(),tcp_slowtimo(),tcp_drain();
Xint	rip_input(),rip_output(),rip_ctloutput();
Xextern	int raw_usrreq();
X/*
X * IMP protocol family: raw interface.
X * Using the raw interface entry to get the timer routine
X * in is a kludge.
X */
X#include "imp.h"
X#if NIMP > 0
Xint	rimp_output(), hostslowtimo();
X#endif
X
X#ifdef NSIP
Xint	idpip_input(), nsip_ctlinput();
X#endif
X
Xextern	struct domain inetdomain;
X
Xstruct protosw inetsw[] = {
X{ 0,		&inetdomain,	0,		0,
X  0,		ip_output,	0,		0,
X  0,
X  ip_init,	0,		ip_slowtimo,	ip_drain,
X},
X{ SOCK_DGRAM,	&inetdomain,	IPPROTO_UDP,	PR_ATOMIC|PR_ADDR,
X  udp_input,	0,		udp_ctlinput,	ip_ctloutput,
X  udp_usrreq,
X  udp_init,	0,		0,		0,
X},
X{ SOCK_STREAM,	&inetdomain,	IPPROTO_TCP,	PR_CONNREQUIRED|PR_WANTRCVD,
X  tcp_input,	0,		tcp_ctlinput,	tcp_ctloutput,
X  tcp_usrreq,
X  tcp_init,	tcp_fasttimo,	tcp_slowtimo,	tcp_drain,
X},
X{ SOCK_RAW,	&inetdomain,	IPPROTO_RAW,	PR_ATOMIC|PR_ADDR,
X  rip_input,	rip_output,	0,		rip_ctloutput,
X  raw_usrreq,
X  0,		0,		0,		0,
X},
X{ SOCK_RAW,	&inetdomain,	IPPROTO_ICMP,	PR_ATOMIC|PR_ADDR,
X  icmp_input,	rip_output,	0,		rip_ctloutput,
X  raw_usrreq,
X  0,		0,		0,		0,
X},
X#ifdef NSIP
X{ SOCK_RAW,	&inetdomain,	IPPROTO_IDP,	PR_ATOMIC|PR_ADDR,
X  idpip_input,	rip_output,	nsip_ctlinput,	0,
X  raw_usrreq,
X  0,		0,		0,		0,
X},
X#endif
X	/* raw wildcard */
X{ SOCK_RAW,	&inetdomain,	0,		PR_ATOMIC|PR_ADDR,
X  rip_input,	rip_output,	0,		rip_ctloutput,
X  raw_usrreq,
X  0,		0,		0,		0,
X},
X};
X
Xstruct domain inetdomain =
X    { AF_INET, "internet", 0, 0, 0, 
X      inetsw, &inetsw[sizeof(inetsw)/sizeof(inetsw[0])] };
X
X#if NIMP > 0
Xextern	struct domain impdomain;
X
Xstruct protosw impsw[] = {
X{ SOCK_RAW,	&impdomain,	0,		PR_ATOMIC|PR_ADDR,
X  0,		rimp_output,	0,		0,
X  raw_usrreq,
X  0,		0,		hostslowtimo,	0,
X},
X};
X
Xstruct domain impdomain =
X    { AF_IMPLINK, "imp", 0, 0, 0,
X      impsw, &impsw[sizeof (impsw)/sizeof(impsw[0])] };
X#endif
X
X#include "hy.h"
X#if NHY > 0
X/*
X * HYPERchannel protocol family: raw interface.
X */
Xint	rhy_output();
Xextern	struct domain hydomain;
X
Xstruct protosw hysw[] = {
X{ SOCK_RAW,	&hydomain,	0,		PR_ATOMIC|PR_ADDR,
X  0,		rhy_output,	0,		0,
X  raw_usrreq,
X  0,		0,		0,		0,
X},
X};
X
Xstruct domain hydomain =
X    { AF_HYLINK, "hy", 0, 0, 0, hysw, &hysw[sizeof (hysw)/sizeof(hysw[0])] };
X#endif
END-of-netinet/in_proto.c
echo x - netinet/in_systm.h
sed 's/^X//' >netinet/in_systm.h << 'END-of-netinet/in_systm.h'
X/*
X * Copyright (c) 1982, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)in_systm.h	7.2 (Berkeley) 12/7/87
X */
X
X/*
X * Miscellaneous internetwork
X * definitions for kernel.
X */
X
X/*
X * Network types.
X *
X * Internally the system keeps counters in the headers with the bytes
X * swapped so that VAX instructions will work on them.  It reverses
X * the bytes before transmission at each protocol level.  The n_ types
X * represent the types with the bytes in ``high-ender'' order.
X */
Xtypedef u_short n_short;		/* short as received from the net */
Xtypedef u_long	n_long;			/* long as received from the net */
X
Xtypedef	u_long	n_time;			/* ms since 00:00 GMT, byte rev */
X
X#ifdef KERNEL
Xn_time	iptime();
X#endif
END-of-netinet/in_systm.h
echo x - netinet/in_var.h
sed 's/^X//' >netinet/in_var.h << 'END-of-netinet/in_var.h'
X/*
X * Copyright (c) 1985, 1986 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X *
X *	@(#)in_var.h	7.2 (Berkeley) 12/7/87
X */
X
X/*
X * Interface address, Internet version.  One of these structures
X * is allocated for each interface with an Internet address.
X * The ifaddr structure contains the protocol-independent part
X * of the structure and is assumed to be first.
X */
Xstruct in_ifaddr {
X	struct	ifaddr ia_ifa;		/* protocol-independent info */
X#define	ia_addr	ia_ifa.ifa_addr
X#define	ia_broadaddr	ia_ifa.ifa_broadaddr
X#define	ia_dstaddr	ia_ifa.ifa_dstaddr
X#define	ia_ifp		ia_ifa.ifa_ifp
X	u_long	ia_net;			/* network number of interface */
X	u_long	ia_netmask;		/* mask of net part */
X	u_long	ia_subnet;		/* subnet number, including net */
X	u_long	ia_subnetmask;		/* mask of net + subnet */
X	struct	in_addr ia_netbroadcast; /* broadcast addr for (logical) net */
X	int	ia_flags;
X	struct	in_ifaddr *ia_next;	/* next in list of internet addresses */
X};
X/*
X * Given a pointer to an in_ifaddr (ifaddr),
X * return a pointer to the addr as a sockadd_in.
X */
X#define	IA_SIN(ia) ((struct sockaddr_in *)(&((struct in_ifaddr *)ia)->ia_addr))
X/*
X * ia_flags
X */
X#define	IFA_ROUTE	0x01		/* routing entry installed */
X
X#ifdef	KERNEL
Xstruct	in_ifaddr *in_ifaddr;
Xstruct	in_ifaddr *in_iaonnetof();
Xstruct	ifqueue	ipintrq;		/* ip packet input queue */
X#endif
END-of-netinet/in_var.h
exit
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads