V1.53 ((socket 1 of 2) updated IP/TCP and XNS sources for 4.3BSD)

Keith Bostic bostic at OKEEFFE.BERKELEY.EDU
Tue Apr 5 13:18:29 AEST 1988


Subject: (socket 1 of 2) updated IP/TCP and XNS sources for 4.3BSD
Index: sys 4.3BSD

Description:
	This is number 8 of 11 total articles posted to the newsgroup
	comp.bugs.4bsd.ucb-fixes.  This archive is number 1 of the 2
	articles that make up the socket 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:
#
#	README
#	h
#	h/domain.h
#	h/protosw.h
#	h/socket.h
#	h/un.h
#	h/unpcb.h
#	net
#	net/af.c
#	net/af.h
#	net/if.c
#	net/if.h
#	net/if_arp.h
#	net/if_loop.c
#	net/netisr.h
#	net/raw_cb.c
#	net/raw_cb.h
#	net/raw_usrreq.c
#
echo x - README
sed 's/^X//' >README << 'END-of-README'
XThis is the description of a release of updated networking software
Xfor the 4.3BSD distribution from the University of California, Berkeley.
XThese changes are part of the current Berkeley operating system and
Xwill be included in future tape releases.  This release is being
Xmade available by anonymous FTP from the ARPANET and on the Usenet
Xnewsgroup comp.bugs.4bsd.ucb-fixes.
X
XThe major changes in this release are in the TCP send policy.
XBecause the improvements in the send policy could significantly
Xreduce congestion on the ARPANET and the NSFNET, all sites with
Xdirect or indirect connections to long-haul nets are urged to upgrade
Xas quickly as possible.  Vendors supplying TCP products based on 4.2BSD
Xor 4.3BSD are strongly urged to update as quickly as possible.  Vendors
Xusing other TCP implementations should consider the use of the new algorithms
Xas well, and may find the current Berkeley source code useful as a guide
Xto their implementation.
X
XThe FTP release consists of five files: tcp.tar, inet.tar, netns.tar,
Xsocket.tar and imp.tar.  They are all present on host ucbarpa.Berkeley.EDU
Xin the directory pub/4.3.  (Each is also available in compressed form,
Xindicated by a trailing ".Z".)  Each archive file includes a copy of this
Xfile (called README).
X
XThe first file, tcp.tar, contains sources for the current version of TCP,
Xincluding the slow start algorithm and other work by Van Jacobson of LBL
Xand a retransmission timer algorithm suggested by Phil Karn.  It is designed
Xto replace the 4.3BSD TCP, although it also has #ifdef's for installation
Xin a 4.2-based system (including SunOS versions up to 3.6).  The changes made
Xsince the release of 4.3 dramatically improve performance over slow and/or
Xlossy networks such as the ARPANET/Milnet and Satnet, and also reduce the
Xnumber of unnecessary retransmissions nearly to zero.  Performance on
Xfast, local-area networks is also somewhat improved, especially on faster
Xprocessors when larger buffers are used.  Several new bug fixes have
Xalso been made.  The file TCP_INSTALL contains some hints on configuring
XTCP for systems other than standard 4.3BSD and 4.2BSD.
X
XThe second file, inet.tar, contains sources for IP, ICMP, UDP and common
Xinternet code (all of the netinet directory except the TCP sources).
XIt also includes a few files from the sys and h directories that have
Xbeen changed since the 4.3BSD release.  There are changes in the processing
Xof IP record-route and timestamp options and in handling of certain broadcast
XUDP requests.  The mbuf allocation routines include a fix for a race and
Xchanges to call the protocol drain routines when appropriate, and will
Xno longer panic when new allocation requests discover that the mbuf map
Xhas been exhausted.  A recent problem in the code for fragmenting IP packets
Xwith options is fixed.  The complete source for the netstat program is also
Xincluded in inet.tar.  It will be usable only on 4.3BSD systems without
Xmodification.  (Note: there are two versions of main.c and host.c in
Xthe netstat directory.  Unless you are installing the new imp code,
Xyou must use main.c.oldimp and host.c.oldimp.)
X
XThe combination of tcp.tar and inet.tar is sufficient to upgrade a 4.3BSD
Xsystem to the current level of IP/TCP.  It is strongly recommended that
X4.3BSD sites that are connected to the Internet, directly or indirectly,
Xas well as 4.3BSD gateway sites, should upgrade as quickly as possible.
X
XThe third file, netns.tar, contains the current version of the Xerox NS
Xprotocols from the netns source directory.  The Sequenced Packet Protocol
Xhas modifications similar to those in TCP, as well as several bug fixes.
XSites that use XNS must upgrade it at the same time as TCP, as the old
XXNS code used the old tcp_timer.h.
X
XThe fourth file, socket.tar, includes the remainder of the socket and generic
Xnetwork source files.  These files are identical to those in the 4.3BSD
Xrelease.  They are provided for completeness for those who do not have access
Xto the original 4.3BSD sources.  They are not required for installation
Xof the TCP and other internet fixes in a 4.3BSD system, nor for installation
Xof the new internet code into most 4.2BSD-derived systems.  They may
Xbe useful for upgrading the socket or network code in a 4.2BSD-derived
Xsystem.  We cannot provide any assistance in such upgrades, but we
Xare interested in hearing about any successful upgrades.
X
XThe fifth file, imp.tar, includes recent modifications to the code for
Xhandling an ARPANET/Milnet IMP using an AHIP (1822) interface.  It was not
Xquite ready for distribution when the rest of the update was finished, and
Xmay not be present in the anonymous FTP area immediately.  If you want
Xit, check back later or watch for an announcement on the tcp-ip mailing
Xlist.
X
XNote that the Berkeley network source code is *not* public-domain.
XHowever, as it contains no code licensed by AT&T or others, it is owned
Xby the Regents of the University of California, Berkeley.  It is provided
Xas-is, without any warranty, for any purpose.  It may be used, modified or
Xredistributed in source or binary forms, as long as due credit is given
Xto the University and the University copyright notices are retained.
X
XThese sources may be updated from time to time as improvements or additions
Xare made.  The next update will include support for IP multicast done
Xby Steve Deering at Stanford.  Updates will be announced on the tcp-ip
Xmailing list, which is redistributed on Usenet.
X
X	Mike Karels	karels at Berkeley.EDU
X	Van Jacobson	van at lbl-csam.arpa
END-of-README
echo c - h
mkdir h > /dev/null 2>&1
echo x - h/domain.h
sed 's/^X//' >h/domain.h << 'END-of-h/domain.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 *	@(#)domain.h	7.2 (Berkeley) 12/30/87
X */
X
X/*
X * Structure per communications domain.
X */
Xstruct	domain {
X	int	dom_family;		/* AF_xxx */
X	char	*dom_name;
X	int	(*dom_init)();		/* initialize domain data structures */
X	int	(*dom_externalize)();	/* externalize access rights */
X	int	(*dom_dispose)();	/* dispose of internalized rights */
X	struct	protosw *dom_protosw, *dom_protoswNPROTOSW;
X	struct	domain *dom_next;
X};
X
X#ifdef KERNEL
Xstruct	domain *domains;
X#endif
END-of-h/domain.h
echo x - h/protosw.h
sed 's/^X//' >h/protosw.h << 'END-of-h/protosw.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 *	@(#)protosw.h	7.2 (Berkeley) 12/30/87
X */
X
X/*
X * Protocol switch table.
X *
X * Each protocol has a handle initializing one of these structures,
X * which is used for protocol-protocol and system-protocol communication.
X *
X * A protocol is called through the pr_init entry before any other.
X * Thereafter it is called every 200ms through the pr_fasttimo entry and
X * every 500ms through the pr_slowtimo for timer based actions.
X * The system will call the pr_drain entry if it is low on space and
X * this should throw away any non-critical data.
X *
X * Protocols pass data between themselves as chains of mbufs using
X * the pr_input and pr_output hooks.  Pr_input passes data up (towards
X * UNIX) and pr_output passes it down (towards the imps); control
X * information passes up and down on pr_ctlinput and pr_ctloutput.
X * The protocol is responsible for the space occupied by any the
X * arguments to these entries and must dispose it.
X *
X * The userreq routine interfaces protocols to the system and is
X * described below.
X */
Xstruct protosw {
X	short	pr_type;		/* socket type used for */
X	struct	domain *pr_domain;	/* domain protocol a member of */
X	short	pr_protocol;		/* protocol number */
X	short	pr_flags;		/* see below */
X/* protocol-protocol hooks */
X	int	(*pr_input)();		/* input to protocol (from below) */
X	int	(*pr_output)();		/* output to protocol (from above) */
X	int	(*pr_ctlinput)();	/* control input (from below) */
X	int	(*pr_ctloutput)();	/* control output (from above) */
X/* user-protocol hook */
X	int	(*pr_usrreq)();		/* user request: see list below */
X/* utility hooks */
X	int	(*pr_init)();		/* initialization hook */
X	int	(*pr_fasttimo)();	/* fast timeout (200ms) */
X	int	(*pr_slowtimo)();	/* slow timeout (500ms) */
X	int	(*pr_drain)();		/* flush any excess space possible */
X};
X
X#define	PR_SLOWHZ	2		/* 2 slow timeouts per second */
X#define	PR_FASTHZ	5		/* 5 fast timeouts per second */
X
X/*
X * Values for pr_flags
X */
X#define	PR_ATOMIC	0x01		/* exchange atomic messages only */
X#define	PR_ADDR		0x02		/* addresses given with messages */
X/* in the current implementation, PR_ADDR needs PR_ATOMIC to work */
X#define	PR_CONNREQUIRED	0x04		/* connection required by protocol */
X#define	PR_WANTRCVD	0x08		/* want PRU_RCVD calls */
X#define	PR_RIGHTS	0x10		/* passes capabilities */
X
X/*
X * The arguments to usrreq are:
X *	(*protosw[].pr_usrreq)(up, req, m, nam, opt);
X * where up is a (struct socket *), req is one of these requests,
X * m is a optional mbuf chain containing a message,
X * nam is an optional mbuf chain containing an address,
X * and opt is a pointer to a socketopt structure or nil.
X * The protocol is responsible for disposal of the mbuf chain m,
X * the caller is responsible for any space held by nam and opt.
X * A non-zero return from usrreq gives an
X * UNIX error number which should be passed to higher level software.
X */
X#define	PRU_ATTACH		0	/* attach protocol to up */
X#define	PRU_DETACH		1	/* detach protocol from up */
X#define	PRU_BIND		2	/* bind socket to address */
X#define	PRU_LISTEN		3	/* listen for connection */
X#define	PRU_CONNECT		4	/* establish connection to peer */
X#define	PRU_ACCEPT		5	/* accept connection from peer */
X#define	PRU_DISCONNECT		6	/* disconnect from peer */
X#define	PRU_SHUTDOWN		7	/* won't send any more data */
X#define	PRU_RCVD		8	/* have taken data; more room now */
X#define	PRU_SEND		9	/* send this data */
X#define	PRU_ABORT		10	/* abort (fast DISCONNECT, DETATCH) */
X#define	PRU_CONTROL		11	/* control operations on protocol */
X#define	PRU_SENSE		12	/* return status into m */
X#define	PRU_RCVOOB		13	/* retrieve out of band data */
X#define	PRU_SENDOOB		14	/* send out of band data */
X#define	PRU_SOCKADDR		15	/* fetch socket's address */
X#define	PRU_PEERADDR		16	/* fetch peer's address */
X#define	PRU_CONNECT2		17	/* connect two sockets */
X/* begin for protocols internal use */
X#define	PRU_FASTTIMO		18	/* 200ms timeout */
X#define	PRU_SLOWTIMO		19	/* 500ms timeout */
X#define	PRU_PROTORCV		20	/* receive from below */
X#define	PRU_PROTOSEND		21	/* send to below */
X
X#define	PRU_NREQ		21
X
X#ifdef PRUREQUESTS
Xchar *prurequests[] = {
X	"ATTACH",	"DETACH",	"BIND",		"LISTEN",
X	"CONNECT",	"ACCEPT",	"DISCONNECT",	"SHUTDOWN",
X	"RCVD",		"SEND",		"ABORT",	"CONTROL",
X	"SENSE",	"RCVOOB",	"SENDOOB",	"SOCKADDR",
X	"PEERADDR",	"CONNECT2",	"FASTTIMO",	"SLOWTIMO",
X	"PROTORCV",	"PROTOSEND",
X};
X#endif
X
X/*
X * The arguments to the ctlinput routine are
X *	(*protosw[].pr_ctlinput)(cmd, arg);
X * where cmd is one of the commands below, and arg is
X * an optional argument (caddr_t).
X *
X * N.B. The IMP code, in particular, pressumes the values
X *      of some of the commands; change with extreme care.
X * TODO:
X *	spread out codes so new ICMP codes can be
X *	accomodated more easily
X */
X#define	PRC_IFDOWN		0	/* interface transition */
X#define	PRC_ROUTEDEAD		1	/* select new route if possible */
X#define	PRC_QUENCH		4	/* some said to slow down */
X#define	PRC_MSGSIZE		5	/* message size forced drop */
X#define	PRC_HOSTDEAD		6	/* normally from IMP */
X#define	PRC_HOSTUNREACH		7	/* ditto */
X#define	PRC_UNREACH_NET		8	/* no route to network */
X#define	PRC_UNREACH_HOST	9	/* no route to host */
X#define	PRC_UNREACH_PROTOCOL	10	/* dst says bad protocol */
X#define	PRC_UNREACH_PORT	11	/* bad port # */
X#define	PRC_UNREACH_NEEDFRAG	12	/* IP_DF caused drop */
X#define	PRC_UNREACH_SRCFAIL	13	/* source route failed */
X#define	PRC_REDIRECT_NET	14	/* net routing redirect */
X#define	PRC_REDIRECT_HOST	15	/* host routing redirect */
X#define	PRC_REDIRECT_TOSNET	16	/* redirect for type of service & net */
X#define	PRC_REDIRECT_TOSHOST	17	/* redirect for tos & host */
X#define	PRC_TIMXCEED_INTRANS	18	/* packet lifetime expired in transit */
X#define	PRC_TIMXCEED_REASS	19	/* lifetime expired on reass q */
X#define	PRC_PARAMPROB		20	/* header incorrect */
X
X#define	PRC_NCMDS		21
X
X#ifdef PRCREQUESTS
Xchar	*prcrequests[] = {
X	"IFDOWN", "ROUTEDEAD", "#2", "#3",
X	"QUENCH", "MSGSIZE", "HOSTDEAD", "HOSTUNREACH",
X	"NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
X	"FRAG-UNREACH", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
X	"TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
X	"PARAMPROB"
X};
X#endif
X
X/*
X * The arguments to ctloutput are:
X *	(*protosw[].pr_ctloutput)(req, so, level, optname, optval);
X * req is one of the actions listed below, so is a (struct socket *),
X * level is an indication of which protocol layer the option is intended.
X * optname is a protocol dependent socket option request,
X * optval is a pointer to a mbuf-chain pointer, for value-return results.
X * The protocol is responsible for disposal of the mbuf chain *optval
X * if supplied,
X * the caller is responsible for any space held by *optval, when returned.
X * A non-zero return from usrreq gives an
X * UNIX error number which should be passed to higher level software.
X */
X#define	PRCO_GETOPT	0
X#define	PRCO_SETOPT	1
X
X#define	PRCO_NCMDS	2
X
X#ifdef PRCOREQUESTS
Xchar	*prcorequests[] = {
X	"GETOPT", "SETOPT",
X};
X#endif
X
X#ifdef KERNEL
Xextern	struct protosw *pffindproto(), *pffindtype();
X#endif
END-of-h/protosw.h
echo x - h/socket.h
sed 's/^X//' >h/socket.h << 'END-of-h/socket.h'
X/*
X * Copyright (c) 1982, 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 *	@(#)socket.h	7.2 (Berkeley) 12/30/87
X */
X
X/*
X * Definitions related to sockets: types, address families, options.
X */
X
X/*
X * Types
X */
X#define	SOCK_STREAM	1		/* stream socket */
X#define	SOCK_DGRAM	2		/* datagram socket */
X#define	SOCK_RAW	3		/* raw-protocol interface */
X#define	SOCK_RDM	4		/* reliably-delivered message */
X#define	SOCK_SEQPACKET	5		/* sequenced packet stream */
X
X/*
X * Option flags per-socket.
X */
X#define	SO_DEBUG	0x0001		/* turn on debugging info recording */
X#define	SO_ACCEPTCONN	0x0002		/* socket has had listen() */
X#define	SO_REUSEADDR	0x0004		/* allow local address reuse */
X#define	SO_KEEPALIVE	0x0008		/* keep connections alive */
X#define	SO_DONTROUTE	0x0010		/* just use interface addresses */
X#define	SO_BROADCAST	0x0020		/* permit sending of broadcast msgs */
X#define	SO_USELOOPBACK	0x0040		/* bypass hardware when possible */
X#define	SO_LINGER	0x0080		/* linger on close if data present */
X#define	SO_OOBINLINE	0x0100		/* leave received OOB data in line */
X
X/*
X * Additional options, not kept in so_options.
X */
X#define SO_SNDBUF	0x1001		/* send buffer size */
X#define SO_RCVBUF	0x1002		/* receive buffer size */
X#define SO_SNDLOWAT	0x1003		/* send low-water mark */
X#define SO_RCVLOWAT	0x1004		/* receive low-water mark */
X#define SO_SNDTIMEO	0x1005		/* send timeout */
X#define SO_RCVTIMEO	0x1006		/* receive timeout */
X#define	SO_ERROR	0x1007		/* get error status and clear */
X#define	SO_TYPE		0x1008		/* get socket type */
X
X/*
X * Structure used for manipulating linger option.
X */
Xstruct	linger {
X	int	l_onoff;		/* option on/off */
X	int	l_linger;		/* linger time */
X};
X
X/*
X * Level number for (get/set)sockopt() to apply to socket itself.
X */
X#define	SOL_SOCKET	0xffff		/* options for socket level */
X
X/*
X * Address families.
X */
X#define	AF_UNSPEC	0		/* unspecified */
X#define	AF_UNIX		1		/* local to host (pipes, portals) */
X#define	AF_INET		2		/* internetwork: UDP, TCP, etc. */
X#define	AF_IMPLINK	3		/* arpanet imp addresses */
X#define	AF_PUP		4		/* pup protocols: e.g. BSP */
X#define	AF_CHAOS	5		/* mit CHAOS protocols */
X#define	AF_NS		6		/* XEROX NS protocols */
X#define	AF_NBS		7		/* nbs protocols */
X#define	AF_ECMA		8		/* european computer manufacturers */
X#define	AF_DATAKIT	9		/* datakit protocols */
X#define	AF_CCITT	10		/* CCITT protocols, X.25 etc */
X#define	AF_SNA		11		/* IBM SNA */
X#define AF_DECnet	12		/* DECnet */
X#define AF_DLI		13		/* Direct data link interface */
X#define AF_LAT		14		/* LAT */
X#define	AF_HYLINK	15		/* NSC Hyperchannel */
X#define	AF_APPLETALK	16		/* Apple Talk */
X
X#define	AF_MAX		17
X
X/*
X * Structure used by kernel to store most
X * addresses.
X */
Xstruct sockaddr {
X	u_short	sa_family;		/* address family */
X	char	sa_data[14];		/* up to 14 bytes of direct address */
X};
X
X/*
X * Structure used by kernel to pass protocol
X * information in raw sockets.
X */
Xstruct sockproto {
X	u_short	sp_family;		/* address family */
X	u_short	sp_protocol;		/* protocol */
X};
X
X/*
X * Protocol families, same as address families for now.
X */
X#define	PF_UNSPEC	AF_UNSPEC
X#define	PF_UNIX		AF_UNIX
X#define	PF_INET		AF_INET
X#define	PF_IMPLINK	AF_IMPLINK
X#define	PF_PUP		AF_PUP
X#define	PF_CHAOS	AF_CHAOS
X#define	PF_NS		AF_NS
X#define	PF_NBS		AF_NBS
X#define	PF_ECMA		AF_ECMA
X#define	PF_DATAKIT	AF_DATAKIT
X#define	PF_CCITT	AF_CCITT
X#define	PF_SNA		AF_SNA
X#define PF_DECnet	AF_DECnet
X#define PF_DLI		AF_DLI
X#define PF_LAT		AF_LAT
X#define	PF_HYLINK	AF_HYLINK
X#define	PF_APPLETALK	AF_APPLETALK
X
X#define	PF_MAX		AF_MAX
X
X/*
X * Maximum queue length specifiable by listen.
X */
X#define	SOMAXCONN	5
X
X/*
X * Message header for recvmsg and sendmsg calls.
X */
Xstruct msghdr {
X	caddr_t	msg_name;		/* optional address */
X	int	msg_namelen;		/* size of address */
X	struct	iovec *msg_iov;		/* scatter/gather array */
X	int	msg_iovlen;		/* # elements in msg_iov */
X	caddr_t	msg_accrights;		/* access rights sent/received */
X	int	msg_accrightslen;
X};
X
X#define	MSG_OOB		0x1		/* process out-of-band data */
X#define	MSG_PEEK	0x2		/* peek at incoming message */
X#define	MSG_DONTROUTE	0x4		/* send without using routing tables */
X
X#define	MSG_MAXIOVLEN	16
END-of-h/socket.h
echo x - h/un.h
sed 's/^X//' >h/un.h << 'END-of-h/un.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 *	@(#)un.h	7.2 (Berkeley) 12/30/87
X */
X
X/*
X * Definitions for UNIX IPC domain.
X */
Xstruct	sockaddr_un {
X	short	sun_family;		/* AF_UNIX */
X	char	sun_path[108];		/* path name (gag) */
X};
X
X#ifdef KERNEL
Xint	unp_discard();
X#endif
END-of-h/un.h
echo x - h/unpcb.h
sed 's/^X//' >h/unpcb.h << 'END-of-h/unpcb.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 *	@(#)unpcb.h	7.2 (Berkeley) 1/7/88
X */
X
X/*
X * Protocol control block for an active
X * instance of a UNIX internal protocol.
X *
X * A socket may be associated with an inode in the
X * file system.  If so, the unp_inode pointer holds
X * a reference count to this inode, which should be irele'd
X * when the socket goes away.
X *
X * A socket may be connected to another socket, in which
X * case the control block of the socket to which it is connected
X * is given by unp_conn.
X *
X * A socket may be referenced by a number of sockets (e.g. several
X * sockets may be connected to a datagram socket.)  These sockets
X * are in a linked list starting with unp_refs, linked through
X * unp_nextref and null-terminated.  Note that a socket may be referenced
X * by a number of other sockets and may also reference a socket (not
X * necessarily one which is referencing it).  This generates
X * the need for unp_refs and unp_nextref to be separate fields.
X *
X * Stream sockets keep copies of receive sockbuf sb_cc and sb_mbcnt
X * so that changes in the sockbuf may be computed to modify
X * back pressure on the sender accordingly.
X */
Xstruct	unpcb {
X	struct	socket *unp_socket;	/* pointer back to socket */
X	struct	inode *unp_inode;	/* if associated with file */
X	ino_t	unp_ino;		/* fake inode number */
X	struct	unpcb *unp_conn;	/* control block of connected socket */
X	struct	unpcb *unp_refs;	/* referencing socket linked list */
X	struct 	unpcb *unp_nextref;	/* link in unp_refs list */
X	struct	mbuf *unp_addr;		/* bound address of socket */
X	int	unp_cc;			/* copy of rcv.sb_cc */
X	int	unp_mbcnt;		/* copy of rcv.sb_mbcnt */
X};
X
X#define	sotounpcb(so)	((struct unpcb *)((so)->so_pcb))
END-of-h/unpcb.h
echo c - net
mkdir net > /dev/null 2>&1
echo x - net/af.c
sed 's/^X//' >net/af.c << 'END-of-net/af.c'
X/*
X * Copyright (c) 1983, 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 *	@(#)af.c	7.3 (Berkeley) 12/30/87
X */
X
X#include "param.h"
X#include "mbuf.h"
X#include "protosw.h"
X#include "socket.h"
X#include "socketvar.h"
X#include "af.h"
X
X/*
X * Address family support routines
X */
Xint	null_hash(), null_netmatch();
X#define	AFNULL \
X	{ null_hash,	null_netmatch }
X
X#ifdef INET
Xextern int inet_hash(), inet_netmatch();
X#define	AFINET \
X	{ inet_hash,	inet_netmatch }
X#else
X#define	AFINET	AFNULL
X#endif
X
X#ifdef NS
Xextern int ns_hash(), ns_netmatch();
X#define	AFNS \
X	{ ns_hash,	ns_netmatch }
X#else
X#define	AFNS	AFNULL
X#endif
X
Xstruct afswitch afswitch[AF_MAX] = {
X	AFNULL,	AFNULL,	AFINET,	AFINET,	AFNULL,
X	AFNULL,	AFNS,	AFNULL,	AFNULL,	AFNULL,
X	AFNULL, AFNULL, AFNULL, AFNULL, AFNULL,
X	AFNULL, AFNULL,					/* through 16 */
X};
X
Xnull_init()
X{
X	register struct afswitch *af;
X
X	for (af = afswitch; af < &afswitch[AF_MAX]; af++)
X		if (af->af_hash == (int (*)())NULL) {
X			af->af_hash = null_hash;
X			af->af_netmatch = null_netmatch;
X		}
X}
X
X/*ARGSUSED*/
Xnull_hash(addr, hp)
X	struct sockaddr *addr;
X	struct afhash *hp;
X{
X
X	hp->afh_nethash = hp->afh_hosthash = 0;
X}
X
X/*ARGSUSED*/
Xnull_netmatch(a1, a2)
X	struct sockaddr *a1, *a2;
X{
X
X	return (0);
X}
END-of-net/af.c
echo x - net/af.h
sed 's/^X//' >net/af.h << 'END-of-net/af.h'
X/*
X * Copyright (c) 1980, 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 *	@(#)af.h	7.2 (Berkeley) 12/30/87
X */
X
X/*
X * Address family routines,
X * used in handling generic sockaddr structures.
X *
X * Hash routine is called
X *	af_hash(addr, h);
X *	struct sockaddr *addr; struct afhash *h;
X * producing an afhash structure for addr.
X *
X * Netmatch routine is called
X *	af_netmatch(addr1, addr2);
X * where addr1 and addr2 are sockaddr *.  Returns 1 if network
X * values match, 0 otherwise.
X */
Xstruct afswitch {
X	int	(*af_hash)();
X	int	(*af_netmatch)();
X};
X
Xstruct afhash {
X	u_int	afh_hosthash;
X	u_int	afh_nethash;
X};
X
X#ifdef KERNEL
Xstruct	afswitch afswitch[];
X#endif
END-of-net/af.h
echo x - net/if.c
sed 's/^X//' >net/if.c << 'END-of-net/if.c'
X/*
X * Copyright (c) 1980, 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 *	%W% (Berkeley) %G%
X */
X
X#include "param.h"
X#include "mbuf.h"
X#include "systm.h"
X#include "socket.h"
X#include "socketvar.h"
X#include "protosw.h"
X#include "dir.h"
X#include "user.h"
X#include "kernel.h"
X#include "ioctl.h"
X#include "errno.h"
X
X#include "if.h"
X#include "af.h"
X
X#include "ether.h"
X
Xint	ifqmaxlen = IFQ_MAXLEN;
X
X/*
X * Network interface utility routines.
X *
X * Routines with ifa_ifwith* names take sockaddr *'s as
X * parameters.
X */
X
Xifinit()
X{
X	register struct ifnet *ifp;
X
X	for (ifp = ifnet; ifp; ifp = ifp->if_next)
X		if (ifp->if_snd.ifq_maxlen == 0)
X			ifp->if_snd.ifq_maxlen = ifqmaxlen;
X	if_slowtimo();
X}
X
X#ifdef vax
X/*
X * Call each interface on a Unibus reset.
X */
Xifubareset(uban)
X	int uban;
X{
X	register struct ifnet *ifp;
X
X	for (ifp = ifnet; ifp; ifp = ifp->if_next)
X		if (ifp->if_reset)
X			(*ifp->if_reset)(ifp->if_unit, uban);
X}
X#endif
X
X/*
X * Attach an interface to the
X * list of "active" interfaces.
X */
Xif_attach(ifp)
X	struct ifnet *ifp;
X{
X	register struct ifnet **p = &ifnet;
X
X	while (*p)
X		p = &((*p)->if_next);
X	*p = ifp;
X}
X
X/*
X * Locate an interface based on a complete address.
X */
X/*ARGSUSED*/
Xstruct ifaddr *
Xifa_ifwithaddr(addr)
X	struct sockaddr *addr;
X{
X	register struct ifnet *ifp;
X	register struct ifaddr *ifa;
X
X#define	equal(a1, a2) \
X	(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
X	for (ifp = ifnet; ifp; ifp = ifp->if_next)
X	    for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
X		if (ifa->ifa_addr.sa_family != addr->sa_family)
X			continue;
X		if (equal(&ifa->ifa_addr, addr))
X			return (ifa);
X		if ((ifp->if_flags & IFF_BROADCAST) &&
X		    equal(&ifa->ifa_broadaddr, addr))
X			return (ifa);
X	}
X	return ((struct ifaddr *)0);
X}
X/*
X * Locate the point to point interface with a given destination address.
X */
X/*ARGSUSED*/
Xstruct ifaddr *
Xifa_ifwithdstaddr(addr)
X	struct sockaddr *addr;
X{
X	register struct ifnet *ifp;
X	register struct ifaddr *ifa;
X
X	for (ifp = ifnet; ifp; ifp = ifp->if_next) 
X	    if (ifp->if_flags & IFF_POINTOPOINT)
X		for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
X			if (ifa->ifa_addr.sa_family != addr->sa_family)
X				continue;
X			if (equal(&ifa->ifa_dstaddr, addr))
X				return (ifa);
X	}
X	return ((struct ifaddr *)0);
X}
X
X/*
X * Find an interface on a specific network.  If many, choice
X * is first found.
X */
Xstruct ifaddr *
Xifa_ifwithnet(addr)
X	register struct sockaddr *addr;
X{
X	register struct ifnet *ifp;
X	register struct ifaddr *ifa;
X	register u_int af = addr->sa_family;
X	register int (*netmatch)();
X
X	if (af >= AF_MAX)
X		return (0);
X	netmatch = afswitch[af].af_netmatch;
X	for (ifp = ifnet; ifp; ifp = ifp->if_next)
X	    for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
X		if (ifa->ifa_addr.sa_family != addr->sa_family)
X			continue;
X		if ((*netmatch)(&ifa->ifa_addr, addr))
X			return (ifa);
X	}
X	return ((struct ifaddr *)0);
X}
X
X#ifdef notdef
X/*
X * Find an interface using a specific address family
X */
Xstruct ifaddr *
Xifa_ifwithaf(af)
X	register int af;
X{
X	register struct ifnet *ifp;
X	register struct ifaddr *ifa;
X
X	for (ifp = ifnet; ifp; ifp = ifp->if_next)
X	    for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
X		if (ifa->ifa_addr.sa_family == af)
X			return (ifa);
X	return ((struct ifaddr *)0);
X}
X#endif
X
X/*
X * Mark an interface down and notify protocols of
X * the transition.
X * NOTE: must be called at splnet or eqivalent.
X */
Xif_down(ifp)
X	register struct ifnet *ifp;
X{
X	register struct ifaddr *ifa;
X
X	ifp->if_flags &= ~IFF_UP;
X	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
X		pfctlinput(PRC_IFDOWN, &ifa->ifa_addr);
X	if_qflush(&ifp->if_snd);
X}
X
X/*
X * Flush an interface queue.
X */
Xif_qflush(ifq)
X	register struct ifqueue *ifq;
X{
X	register struct mbuf *m, *n;
X
X	n = ifq->ifq_head;
X	while (m = n) {
X		n = m->m_act;
X		m_freem(m);
X	}
X	ifq->ifq_head = 0;
X	ifq->ifq_tail = 0;
X	ifq->ifq_len = 0;
X}
X
X/*
X * Handle interface watchdog timer routines.  Called
X * from softclock, we decrement timers (if set) and
X * call the appropriate interface routine on expiration.
X */
Xif_slowtimo()
X{
X	register struct ifnet *ifp;
X
X	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
X		if (ifp->if_timer == 0 || --ifp->if_timer)
X			continue;
X		if (ifp->if_watchdog)
X			(*ifp->if_watchdog)(ifp->if_unit);
X	}
X	timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ);
X}
X
X/*
X * Map interface name to
X * interface structure pointer.
X */
Xstruct ifnet *
Xifunit(name)
X	register char *name;
X{
X	register char *cp;
X	register struct ifnet *ifp;
X	int unit;
X
X	for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
X		if (*cp >= '0' && *cp <= '9')
X			break;
X	if (*cp == '\0' || cp == name + IFNAMSIZ)
X		return ((struct ifnet *)0);
X	unit = *cp - '0';
X	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
X		if (bcmp(ifp->if_name, name, (unsigned)(cp - name)))
X			continue;
X		if (unit == ifp->if_unit)
X			break;
X	}
X	return (ifp);
X}
X
X/*
X * Interface ioctls.
X */
Xifioctl(so, cmd, data)
X	struct socket *so;
X	int cmd;
X	caddr_t data;
X{
X	register struct ifnet *ifp;
X	register struct ifreq *ifr;
X
X	switch (cmd) {
X
X	case SIOCGIFCONF:
X		return (ifconf(cmd, data));
X
X#if defined(INET) && NETHER > 0
X	case SIOCSARP:
X	case SIOCDARP:
X		if (!suser())
X			return (u.u_error);
X		/* FALL THROUGH */
X	case SIOCGARP:
X		return (arpioctl(cmd, data));
X#endif
X	}
X	ifr = (struct ifreq *)data;
X	ifp = ifunit(ifr->ifr_name);
X	if (ifp == 0)
X		return (ENXIO);
X	switch (cmd) {
X
X	case SIOCGIFFLAGS:
X		ifr->ifr_flags = ifp->if_flags;
X		break;
X
X	case SIOCGIFMETRIC:
X		ifr->ifr_metric = ifp->if_metric;
X		break;
X
X	case SIOCSIFFLAGS:
X		if (!suser())
X			return (u.u_error);
X		if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
X			int s = splimp();
X			if_down(ifp);
X			splx(s);
X		}
X		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
X			(ifr->ifr_flags &~ IFF_CANTCHANGE);
X		if (ifp->if_ioctl)
X			(void) (*ifp->if_ioctl)(ifp, cmd, data);
X		break;
X
X	case SIOCSIFMETRIC:
X		if (!suser())
X			return (u.u_error);
X		ifp->if_metric = ifr->ifr_metric;
X		break;
X
X	default:
X		if (so->so_proto == 0)
X			return (EOPNOTSUPP);
X		return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
X			cmd, data, ifp));
X	}
X	return (0);
X}
X
X/*
X * Return interface configuration
X * of system.  List may be used
X * in later ioctl's (above) to get
X * other information.
X */
X/*ARGSUSED*/
Xifconf(cmd, data)
X	int cmd;
X	caddr_t data;
X{
X	register struct ifconf *ifc = (struct ifconf *)data;
X	register struct ifnet *ifp = ifnet;
X	register struct ifaddr *ifa;
X	register char *cp, *ep;
X	struct ifreq ifr, *ifrp;
X	int space = ifc->ifc_len, error = 0;
X
X	ifrp = ifc->ifc_req;
X	ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2;
X	for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {
X		bcopy(ifp->if_name, ifr.ifr_name, sizeof (ifr.ifr_name) - 2);
X		for (cp = ifr.ifr_name; cp < ep && *cp; cp++)
X			;
X		*cp++ = '0' + ifp->if_unit; *cp = '\0';
X		if ((ifa = ifp->if_addrlist) == 0) {
X			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
X			error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr));
X			if (error)
X				break;
X			space -= sizeof (ifr), ifrp++;
X		} else 
X		    for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) {
X			ifr.ifr_addr = ifa->ifa_addr;
X			error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr));
X			if (error)
X				break;
X			space -= sizeof (ifr), ifrp++;
X		}
X	}
X	ifc->ifc_len -= space;
X	return (error);
X}
END-of-net/if.c
echo x - net/if.h
sed 's/^X//' >net/if.h << 'END-of-net/if.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.h	7.2 (Berkeley) 12/30/87
X */
X
X/*
X * Structures defining a network interface, providing a packet
X * transport mechanism (ala level 0 of the PUP protocols).
X *
X * Each interface accepts output datagrams of a specified maximum
X * length, and provides higher level routines with input datagrams
X * received from its medium.
X *
X * Output occurs when the routine if_output is called, with three parameters:
X *	(*ifp->if_output)(ifp, m, dst)
X * Here m is the mbuf chain to be sent and dst is the destination address.
X * The output routine encapsulates the supplied datagram if necessary,
X * and then transmits it on its medium.
X *
X * On input, each interface unwraps the data received by it, and either
X * places it on the input queue of a internetwork datagram routine
X * and posts the associated software interrupt, or passes the datagram to a raw
X * packet input routine.
X *
X * Routines exist for locating interfaces by their addresses
X * or for locating a interface on a certain network, as well as more general
X * routing and gateway routines maintaining information used to locate
X * interfaces.  These routines live in the files if.c and route.c
X */
X
X/*
X * Structure defining a queue for a network interface.
X *
X * (Would like to call this struct ``if'', but C isn't PL/1.)
X */
Xstruct ifnet {
X	char	*if_name;		/* name, e.g. ``en'' or ``lo'' */
X	short	if_unit;		/* sub-unit for lower level driver */
X	short	if_mtu;			/* maximum transmission unit */
X	short	if_flags;		/* up/down, broadcast, etc. */
X	short	if_timer;		/* time 'til if_watchdog called */
X	int	if_metric;		/* routing metric (external only) */
X	struct	ifaddr *if_addrlist;	/* linked list of addresses per if */
X	struct	ifqueue {
X		struct	mbuf *ifq_head;
X		struct	mbuf *ifq_tail;
X		int	ifq_len;
X		int	ifq_maxlen;
X		int	ifq_drops;
X	} if_snd;			/* output queue */
X/* procedure handles */
X	int	(*if_init)();		/* init routine */
X	int	(*if_output)();		/* output routine */
X	int	(*if_ioctl)();		/* ioctl routine */
X	int	(*if_reset)();		/* bus reset routine */
X	int	(*if_watchdog)();	/* timer routine */
X/* generic interface statistics */
X	int	if_ipackets;		/* packets received on interface */
X	int	if_ierrors;		/* input errors on interface */
X	int	if_opackets;		/* packets sent on interface */
X	int	if_oerrors;		/* output errors on interface */
X	int	if_collisions;		/* collisions on csma interfaces */
X/* end statistics */
X	struct	ifnet *if_next;
X};
X
X#define	IFF_UP		0x1		/* interface is up */
X#define	IFF_BROADCAST	0x2		/* broadcast address valid */
X#define	IFF_DEBUG	0x4		/* turn on debugging */
X#define	IFF_LOOPBACK	0x8		/* is a loopback net */
X#define	IFF_POINTOPOINT	0x10		/* interface is point-to-point link */
X#define	IFF_NOTRAILERS	0x20		/* avoid use of trailers */
X#define	IFF_RUNNING	0x40		/* resources allocated */
X#define	IFF_NOARP	0x80		/* no address resolution protocol */
X/* next two not supported now, but reserved: */
X#define	IFF_PROMISC	0x100		/* receive all packets */
X#define	IFF_ALLMULTI	0x200		/* receive all multicast packets */
X/* flags set internally only: */
X#define	IFF_CANTCHANGE	(IFF_BROADCAST | IFF_POINTOPOINT | IFF_RUNNING)
X
X/*
X * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
X * input routines have queues of messages stored on ifqueue structures
X * (defined above).  Entries are added to and deleted from these structures
X * by these macros, which should be called with ipl raised to splimp().
X */
X#define	IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
X#define	IF_DROP(ifq)		((ifq)->ifq_drops++)
X#define	IF_ENQUEUE(ifq, m) { \
X	(m)->m_act = 0; \
X	if ((ifq)->ifq_tail == 0) \
X		(ifq)->ifq_head = m; \
X	else \
X		(ifq)->ifq_tail->m_act = m; \
X	(ifq)->ifq_tail = m; \
X	(ifq)->ifq_len++; \
X}
X#define	IF_PREPEND(ifq, m) { \
X	(m)->m_act = (ifq)->ifq_head; \
X	if ((ifq)->ifq_tail == 0) \
X		(ifq)->ifq_tail = (m); \
X	(ifq)->ifq_head = (m); \
X	(ifq)->ifq_len++; \
X}
X/*
X * Packets destined for level-1 protocol input routines
X * have a pointer to the receiving interface prepended to the data.
X * IF_DEQUEUEIF extracts and returns this pointer when dequeueing the packet.
X * IF_ADJ should be used otherwise to adjust for its presence.
X */
X#define	IF_ADJ(m) { \
X	(m)->m_off += sizeof(struct ifnet *); \
X	(m)->m_len -= sizeof(struct ifnet *); \
X	if ((m)->m_len == 0) { \
X		struct mbuf *n; \
X		MFREE((m), n); \
X		(m) = n; \
X	} \
X}
X#define	IF_DEQUEUEIF(ifq, m, ifp) { \
X	(m) = (ifq)->ifq_head; \
X	if (m) { \
X		if (((ifq)->ifq_head = (m)->m_act) == 0) \
X			(ifq)->ifq_tail = 0; \
X		(m)->m_act = 0; \
X		(ifq)->ifq_len--; \
X		(ifp) = *(mtod((m), struct ifnet **)); \
X		IF_ADJ(m); \
X	} \
X}
X#define	IF_DEQUEUE(ifq, m) { \
X	(m) = (ifq)->ifq_head; \
X	if (m) { \
X		if (((ifq)->ifq_head = (m)->m_act) == 0) \
X			(ifq)->ifq_tail = 0; \
X		(m)->m_act = 0; \
X		(ifq)->ifq_len--; \
X	} \
X}
X
X#define	IFQ_MAXLEN	50
X#define	IFNET_SLOWHZ	1		/* granularity is 1 second */
X
X/*
X * The ifaddr structure contains information about one address
X * of an interface.  They are maintained by the different address families,
X * are allocated and attached when an address is set, and are linked
X * together so all addresses for an interface can be located.
X */
Xstruct ifaddr {
X	struct	sockaddr ifa_addr;	/* address of interface */
X	union {
X		struct	sockaddr ifu_broadaddr;
X		struct	sockaddr ifu_dstaddr;
X	} ifa_ifu;
X#define	ifa_broadaddr	ifa_ifu.ifu_broadaddr	/* broadcast address */
X#define	ifa_dstaddr	ifa_ifu.ifu_dstaddr	/* other end of p-to-p link */
X	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
X	struct	ifaddr *ifa_next;	/* next address for interface */
X};
X
X/*
X * Interface request structure used for socket
X * ioctl's.  All interface ioctl's must have parameter
X * definitions which begin with ifr_name.  The
X * remainder may be interface specific.
X */
Xstruct	ifreq {
X#define	IFNAMSIZ	16
X	char	ifr_name[IFNAMSIZ];		/* if name, e.g. "en0" */
X	union {
X		struct	sockaddr ifru_addr;
X		struct	sockaddr ifru_dstaddr;
X		struct	sockaddr ifru_broadaddr;
X		short	ifru_flags;
X		int	ifru_metric;
X		caddr_t	ifru_data;
X	} ifr_ifru;
X#define	ifr_addr	ifr_ifru.ifru_addr	/* address */
X#define	ifr_dstaddr	ifr_ifru.ifru_dstaddr	/* other end of p-to-p link */
X#define	ifr_broadaddr	ifr_ifru.ifru_broadaddr	/* broadcast address */
X#define	ifr_flags	ifr_ifru.ifru_flags	/* flags */
X#define	ifr_metric	ifr_ifru.ifru_metric	/* metric */
X#define	ifr_data	ifr_ifru.ifru_data	/* for use by interface */
X};
X
X/*
X * Structure used in SIOCGIFCONF request.
X * Used to retrieve interface configuration
X * for machine (useful for programs which
X * must know all networks accessible).
X */
Xstruct	ifconf {
X	int	ifc_len;		/* size of associated buffer */
X	union {
X		caddr_t	ifcu_buf;
X		struct	ifreq *ifcu_req;
X	} ifc_ifcu;
X#define	ifc_buf	ifc_ifcu.ifcu_buf	/* buffer address */
X#define	ifc_req	ifc_ifcu.ifcu_req	/* array of structures returned */
X};
X
X#ifdef KERNEL
X#include "../net/if_arp.h"
Xstruct	ifqueue rawintrq;		/* raw packet input queue */
Xstruct	ifnet *ifnet;
Xstruct	ifaddr *ifa_ifwithaddr(), *ifa_ifwithnet();
Xstruct	ifaddr *ifa_ifwithdstaddr();
X#else KERNEL
X#include <net/if_arp.h>
X#endif KERNEL
END-of-net/if.h
echo x - net/if_arp.h
sed 's/^X//' >net/if_arp.h << 'END-of-net/if_arp.h'
X/*
X * Copyright (c) 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_arp.h	7.2 (Berkeley) 12/30/87
X */
X
X/*
X * Address Resolution Protocol.
X *
X * See RFC 826 for protocol description.  ARP packets are variable
X * in size; the arphdr structure defines the fixed-length portion.
X * Protocol type values are the same as those for 10 Mb/s Ethernet.
X * It is followed by the variable-sized fields ar_sha, arp_spa,
X * arp_tha and arp_tpa in that order, according to the lengths
X * specified.  Field names used correspond to RFC 826.
X */
Xstruct	arphdr {
X	u_short	ar_hrd;		/* format of hardware address */
X#define ARPHRD_ETHER 	1	/* ethernet hardware address */
X	u_short	ar_pro;		/* format of protocol address */
X	u_char	ar_hln;		/* length of hardware address */
X	u_char	ar_pln;		/* length of protocol address */
X	u_short	ar_op;		/* one of: */
X#define	ARPOP_REQUEST	1	/* request to resolve address */
X#define	ARPOP_REPLY	2	/* response to previous request */
X/*
X * The remaining fields are variable in size,
X * according to the sizes above.
X */
X/*	u_char	ar_sha[];	/* sender hardware address */
X/*	u_char	ar_spa[];	/* sender protocol address */
X/*	u_char	ar_tha[];	/* target hardware address */
X/*	u_char	ar_tpa[];	/* target protocol address */
X};
X
X/*
X * ARP ioctl request
X */
Xstruct arpreq {
X	struct	sockaddr arp_pa;		/* protocol address */
X	struct	sockaddr arp_ha;		/* hardware address */
X	int	arp_flags;			/* flags */
X};
X/*  arp_flags and at_flags field values */
X#define	ATF_INUSE	0x01	/* entry in use */
X#define ATF_COM		0x02	/* completed entry (enaddr valid) */
X#define	ATF_PERM	0x04	/* permanent entry */
X#define	ATF_PUBL	0x08	/* publish entry (respond for other host) */
X#define	ATF_USETRAILERS	0x10	/* has requested trailers */
END-of-net/if_arp.h
echo x - net/if_loop.c
sed 's/^X//' >net/if_loop.c << 'END-of-net/if_loop.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_loop.c	7.3 (Berkeley) 12/30/87
X */
X
X/*
X * Loopback interface driver for protocol testing and timing.
X */
X
X#include "param.h"
X#include "systm.h"
X#include "mbuf.h"
X#include "socket.h"
X#include "errno.h"
X#include "ioctl.h"
X
X#include "../net/if.h"
X#include "../net/netisr.h"
X#include "../net/route.h"
X
X#include "../machine/mtpr.h"
X
X#ifdef	INET
X#include "../netinet/in.h"
X#include "../netinet/in_systm.h"
X#include "../netinet/in_var.h"
X#include "../netinet/ip.h"
X#endif
X
X#ifdef NS
X#include "../netns/ns.h"
X#include "../netns/ns_if.h"
X#endif
X
X#define	LOMTU	(1024+512)
X
Xstruct	ifnet loif;
Xint	looutput(), loioctl();
X
Xloattach()
X{
X	register struct ifnet *ifp = &loif;
X
X	ifp->if_name = "lo";
X	ifp->if_mtu = LOMTU;
X	ifp->if_flags = IFF_LOOPBACK;
X	ifp->if_ioctl = loioctl;
X	ifp->if_output = looutput;
X	if_attach(ifp);
X}
X
Xlooutput(ifp, m0, dst)
X	struct ifnet *ifp;
X	register struct mbuf *m0;
X	struct sockaddr *dst;
X{
X	int s;
X	register struct ifqueue *ifq;
X	struct mbuf *m;
X
X	/*
X	 * Place interface pointer before the data
X	 * for the receiving protocol.
X	 */
X	if (m0->m_off <= MMAXOFF &&
X	    m0->m_off >= MMINOFF + sizeof(struct ifnet *)) {
X		m0->m_off -= sizeof(struct ifnet *);
X		m0->m_len += sizeof(struct ifnet *);
X	} else {
X		MGET(m, M_DONTWAIT, MT_HEADER);
X		if (m == (struct mbuf *)0)
X			return (ENOBUFS);
X		m->m_off = MMINOFF;
X		m->m_len = sizeof(struct ifnet *);
X		m->m_next = m0;
X		m0 = m;
X	}
X	*(mtod(m0, struct ifnet **)) = ifp;
X	s = splimp();
X	ifp->if_opackets++;
X	switch (dst->sa_family) {
X
X#ifdef INET
X	case AF_INET:
X		ifq = &ipintrq;
X		if (IF_QFULL(ifq)) {
X			IF_DROP(ifq);
X			m_freem(m0);
X			splx(s);
X			return (ENOBUFS);
X		}
X		IF_ENQUEUE(ifq, m0);
X		schednetisr(NETISR_IP);
X		break;
X#endif
X#ifdef NS
X	case AF_NS:
X		ifq = &nsintrq;
X		if (IF_QFULL(ifq)) {
X			IF_DROP(ifq);
X			m_freem(m0);
X			splx(s);
X			return (ENOBUFS);
X		}
X		IF_ENQUEUE(ifq, m0);
X		schednetisr(NETISR_NS);
X		break;
X#endif
X	default:
X		splx(s);
X		printf("lo%d: can't handle af%d\n", ifp->if_unit,
X			dst->sa_family);
X		m_freem(m0);
X		return (EAFNOSUPPORT);
X	}
X	ifp->if_ipackets++;
X	splx(s);
X	return (0);
X}
X
X/*
X * Process an ioctl request.
X */
X/* ARGSUSED */
Xloioctl(ifp, cmd, data)
X	register struct ifnet *ifp;
X	int cmd;
X	caddr_t data;
X{
X	int error = 0;
X
X	switch (cmd) {
X
X	case SIOCSIFADDR:
X		ifp->if_flags |= IFF_UP;
X		/*
X		 * Everything else is done at a higher level.
X		 */
X		break;
X
X	default:
X		error = EINVAL;
X	}
X	return (error);
X}
END-of-net/if_loop.c
echo x - net/netisr.h
sed 's/^X//' >net/netisr.h << 'END-of-net/netisr.h'
X/*
X * Copyright (c) 1980, 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 *	@(#)netisr.h	7.3 (Berkeley) 12/30/87
X */
X
X/*
X * The networking code runs off software interrupts.
X *
X * You can switch into the network by doing splnet() and return by splx().
X * The software interrupt level for the network is higher than the software
X * level for the clock (so you can enter the network in routines called
X * at timeout time).
X */
X#if defined(vax) || defined(tahoe)
X#define	setsoftnet()	mtpr(SIRR, 12)
X#endif
X
X/*
X * Each ``pup-level-1'' input queue has a bit in a ``netisr'' status
X * word which is used to de-multiplex a single software
X * interrupt used for scheduling the network code to calls
X * on the lowest level routine of each protocol.
X */
X#define	NETISR_RAW	0		/* same as AF_UNSPEC */
X#define	NETISR_IP	2		/* same as AF_INET */
X#define	NETISR_IMP	3		/* same as AF_IMPLINK */
X#define	NETISR_NS	6		/* same as AF_NS */
X
X#define	schednetisr(anisr)	{ netisr |= 1<<(anisr); setsoftnet(); }
X
X#ifndef LOCORE
X#ifdef KERNEL
Xint	netisr;				/* scheduling bits for network */
X#endif
X#endif
END-of-net/netisr.h
echo x - net/raw_cb.c
sed 's/^X//' >net/raw_cb.c << 'END-of-net/raw_cb.c'
X/*
X * Copyright (c) 1980, 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 *	@(#)raw_cb.c	7.4 (Berkeley) 12/30/87
X */
X
X#include "param.h"
X#include "systm.h"
X#include "mbuf.h"
X#include "socket.h"
X#include "socketvar.h"
X#include "domain.h"
X#include "protosw.h"
X#include "errno.h"
X
X#include "if.h"
X#include "route.h"
X#include "raw_cb.h"
X#include "../netinet/in.h"
X
X#include "../machine/mtpr.h"
X
X/*
X * Routines to manage the raw protocol control blocks. 
X *
X * TODO:
X *	hash lookups by protocol family/protocol + address family
X *	take care of unique address problems per AF?
X *	redo address binding to allow wildcards
X */
X
X/*
X * Allocate a control block and a nominal amount
X * of buffer space for the socket.
X */
Xraw_attach(so, proto)
X	register struct socket *so;
X	int proto;
X{
X	struct mbuf *m;
X	register struct rawcb *rp;
X
X	m = m_getclr(M_DONTWAIT, MT_PCB);
X	if (m == 0)
X		return (ENOBUFS);
X	if (sbreserve(&so->so_snd, RAWSNDQ) == 0)
X		goto bad;
X	if (sbreserve(&so->so_rcv, RAWRCVQ) == 0)
X		goto bad2;
X	rp = mtod(m, struct rawcb *);
X	rp->rcb_socket = so;
X	so->so_pcb = (caddr_t)rp;
X	rp->rcb_pcb = 0;
X	rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
X	rp->rcb_proto.sp_protocol = proto;
X	insque(rp, &rawcb);
X	return (0);
Xbad2:
X	sbrelease(&so->so_snd);
Xbad:
X	(void) m_free(m);
X	return (ENOBUFS);
X}
X
X/*
X * Detach the raw connection block and discard
X * socket resources.
X */
Xraw_detach(rp)
X	register struct rawcb *rp;
X{
X	struct socket *so = rp->rcb_socket;
X
X	if (rp->rcb_route.ro_rt)
X		rtfree(rp->rcb_route.ro_rt);
X	so->so_pcb = 0;
X	sofree(so);
X	remque(rp);
X	if (rp->rcb_options)
X		m_freem(rp->rcb_options);
X	m_freem(dtom(rp));
X}
X
X/*
X * Disconnect and possibly release resources.
X */
Xraw_disconnect(rp)
X	struct rawcb *rp;
X{
X
X	rp->rcb_flags &= ~RAW_FADDR;
X	if (rp->rcb_socket->so_state & SS_NOFDREF)
X		raw_detach(rp);
X}
X
Xraw_bind(so, nam)
X	register struct socket *so;
X	struct mbuf *nam;
X{
X	struct sockaddr *addr = mtod(nam, struct sockaddr *);
X	register struct rawcb *rp;
X
X	if (ifnet == 0)
X		return (EADDRNOTAVAIL);
X/* BEGIN DUBIOUS */
X	/*
X	 * Should we verify address not already in use?
X	 * Some say yes, others no.
X	 */
X	switch (addr->sa_family) {
X
X#ifdef INET
X	case AF_IMPLINK:
X	case AF_INET: {
X		if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
X		    ifa_ifwithaddr(addr) == 0)
X			return (EADDRNOTAVAIL);
X		break;
X	}
X#endif
X
X	default:
X		return (EAFNOSUPPORT);
X	}
X/* END DUBIOUS */
X	rp = sotorawcb(so);
X	bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
X	rp->rcb_flags |= RAW_LADDR;
X	return (0);
X}
X
X/*
X * Associate a peer's address with a
X * raw connection block.
X */
Xraw_connaddr(rp, nam)
X	struct rawcb *rp;
X	struct mbuf *nam;
X{
X	struct sockaddr *addr = mtod(nam, struct sockaddr *);
X
X	bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
X	rp->rcb_flags |= RAW_FADDR;
X}
END-of-net/raw_cb.c
echo x - net/raw_cb.h
sed 's/^X//' >net/raw_cb.h << 'END-of-net/raw_cb.h'
X/*
X * Copyright (c) 1980, 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 *	@(#)raw_cb.h	7.2 (Berkeley) 12/30/87
X */
X
X/*
X * Raw protocol interface control block.  Used
X * to tie a socket to the generic raw interface.
X */
Xstruct rawcb {
X	struct	rawcb *rcb_next;	/* doubly linked list */
X	struct	rawcb *rcb_prev;
X	struct	socket *rcb_socket;	/* back pointer to socket */
X	struct	sockaddr rcb_faddr;	/* destination address */
X	struct	sockaddr rcb_laddr;	/* socket's address */
X	struct	sockproto rcb_proto;	/* protocol family, protocol */
X	caddr_t	rcb_pcb;		/* protocol specific stuff */
X	struct	mbuf *rcb_options;	/* protocol specific options */
X	struct	route rcb_route;	/* routing information */
X	short	rcb_flags;
X};
X
X/*
X * Since we can't interpret canonical addresses,
X * we mark an address present in the flags field.
X */
X#define	RAW_LADDR	01
X#define	RAW_FADDR	02
X#define	RAW_DONTROUTE	04		/* no routing, default */
X
X#define	sotorawcb(so)		((struct rawcb *)(so)->so_pcb)
X
X/*
X * Nominal space allocated to a raw socket.
X */
X#define	RAWSNDQ		2048
X#define	RAWRCVQ		2048
X
X/*
X * Format of raw interface header prepended by
X * raw_input after call from protocol specific
X * input routine.
X */
Xstruct raw_header {
X	struct	sockproto raw_proto;	/* format of packet */
X	struct	sockaddr raw_dst;	/* dst address for rawintr */
X	struct	sockaddr raw_src;	/* src address for sbappendaddr */
X};
X
X#ifdef KERNEL
Xstruct rawcb rawcb;			/* head of list */
X#endif
END-of-net/raw_cb.h
echo x - net/raw_usrreq.c
sed 's/^X//' >net/raw_usrreq.c << 'END-of-net/raw_usrreq.c'
X/*
X * Copyright (c) 1980, 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 *	@(#)raw_usrreq.c	7.3 (Berkeley) 12/30/87
X */
X
X#include "param.h"
X#include "mbuf.h"
X#include "domain.h"
X#include "protosw.h"
X#include "socket.h"
X#include "socketvar.h"
X#include "errno.h"
X
X#include "if.h"
X#include "route.h"
X#include "netisr.h"
X#include "raw_cb.h"
X
X#include "../machine/mtpr.h"
X
X/*
X * Initialize raw connection block q.
X */
Xraw_init()
X{
X
X	rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
X	rawintrq.ifq_maxlen = IFQ_MAXLEN;
X}
X
X/*
X * Raw protocol interface.
X */
Xraw_input(m0, proto, src, dst)
X	struct mbuf *m0;
X	struct sockproto *proto;
X	struct sockaddr *src, *dst;
X{
X	register struct mbuf *m;
X	struct raw_header *rh;
X	int s;
X
X	/*
X	 * Rip off an mbuf for a generic header.
X	 */
X	m = m_get(M_DONTWAIT, MT_HEADER);
X	if (m == 0) {
X		m_freem(m0);
X		return;
X	}
X	m->m_next = m0;
X	m->m_len = sizeof(struct raw_header);
X	rh = mtod(m, struct raw_header *);
X	rh->raw_dst = *dst;
X	rh->raw_src = *src;
X	rh->raw_proto = *proto;
X
X	/*
X	 * Header now contains enough info to decide
X	 * which socket to place packet in (if any).
X	 * Queue it up for the raw protocol process
X	 * running at software interrupt level.
X	 */
X	s = splimp();
X	if (IF_QFULL(&rawintrq))
X		m_freem(m);
X	else
X		IF_ENQUEUE(&rawintrq, m);
X	splx(s);
X	schednetisr(NETISR_RAW);
X}
X
X/*
X * Raw protocol input routine.  Process packets entered
X * into the queue at interrupt time.  Find the socket
X * associated with the packet(s) and move them over.  If
X * nothing exists for this packet, drop it.
X */
Xrawintr()
X{
X	int s;
X	struct mbuf *m;
X	register struct rawcb *rp;
X	register struct raw_header *rh;
X	struct socket *last;
X
Xnext:
X	s = splimp();
X	IF_DEQUEUE(&rawintrq, m);
X	splx(s);
X	if (m == 0)
X		return;
X	rh = mtod(m, struct raw_header *);
X	last = 0;
X	for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
X		if (rp->rcb_proto.sp_family != rh->raw_proto.sp_family)
X			continue;
X		if (rp->rcb_proto.sp_protocol  &&
X		    rp->rcb_proto.sp_protocol != rh->raw_proto.sp_protocol)
X			continue;
X		/*
X		 * We assume the lower level routines have
X		 * placed the address in a canonical format
X		 * suitable for a structure comparison.
X		 */
X#define equal(a1, a2) \
X	(bcmp((caddr_t)&(a1), (caddr_t)&(a2), sizeof (struct sockaddr)) == 0)
X		if ((rp->rcb_flags & RAW_LADDR) &&
X		    !equal(rp->rcb_laddr, rh->raw_dst))
X			continue;
X		if ((rp->rcb_flags & RAW_FADDR) &&
X		    !equal(rp->rcb_faddr, rh->raw_src))
X			continue;
X		if (last) {
X			struct mbuf *n;
X			if (n = m_copy(m->m_next, 0, (int)M_COPYALL)) {
X				if (sbappendaddr(&last->so_rcv, &rh->raw_src,
X				    n, (struct mbuf *)0) == 0)
X					/* should notify about lost packet */
X					m_freem(n);
X				else
X					sorwakeup(last);
X			}
X		}
X		last = rp->rcb_socket;
X	}
X	if (last) {
X		if (sbappendaddr(&last->so_rcv, &rh->raw_src,
X		    m->m_next, (struct mbuf *)0) == 0)
X			m_freem(m->m_next);
X		else
X			sorwakeup(last);
X		(void) m_free(m);		/* header */
X	} else
X		m_freem(m);
X	goto next;
X}
X
X/*ARGSUSED*/
Xraw_ctlinput(cmd, arg)
X	int cmd;
X	struct sockaddr *arg;
X{
X
X	if (cmd < 0 || cmd > PRC_NCMDS)
X		return;
X	/* INCOMPLETE */
X}
X
X/*ARGSUSED*/
Xraw_usrreq(so, req, m, nam, rights)
X	struct socket *so;
X	int req;
X	struct mbuf *m, *nam, *rights;
X{
X	register struct rawcb *rp = sotorawcb(so);
X	register int error = 0;
X
X	if (req == PRU_CONTROL)
X		return (EOPNOTSUPP);
X	if (rights && rights->m_len) {
X		error = EOPNOTSUPP;
X		goto release;
X	}
X	if (rp == 0 && req != PRU_ATTACH) {
X		error = EINVAL;
X		goto release;
X	}
X	switch (req) {
X
X	/*
X	 * Allocate a raw control block and fill in the
X	 * necessary info to allow packets to be routed to
X	 * the appropriate raw interface routine.
X	 */
X	case PRU_ATTACH:
X		if ((so->so_state & SS_PRIV) == 0) {
X			error = EACCES;
X			break;
X		}
X		if (rp) {
X			error = EINVAL;
X			break;
X		}
X		error = raw_attach(so, (int)nam);
X		break;
X
X	/*
X	 * Destroy state just before socket deallocation.
X	 * Flush data or not depending on the options.
X	 */
X	case PRU_DETACH:
X		if (rp == 0) {
X			error = ENOTCONN;
X			break;
X		}
X		raw_detach(rp);
X		break;
X
X	/*
X	 * If a socket isn't bound to a single address,
X	 * the raw input routine will hand it anything
X	 * within that protocol family (assuming there's
X	 * nothing else around it should go to). 
X	 */
X	case PRU_CONNECT:
X		if (rp->rcb_flags & RAW_FADDR) {
X			error = EISCONN;
X			break;
X		}
X		raw_connaddr(rp, nam);
X		soisconnected(so);
X		break;
X
X	case PRU_CONNECT2:
X		error = EOPNOTSUPP;
X		goto release;
X
X	case PRU_BIND:
X		if (rp->rcb_flags & RAW_LADDR) {
X			error = EINVAL;			/* XXX */
X			break;
X		}
X		error = raw_bind(so, nam);
X		break;
X
X	case PRU_DISCONNECT:
X		if ((rp->rcb_flags & RAW_FADDR) == 0) {
X			error = ENOTCONN;
X			break;
X		}
X		raw_disconnect(rp);
X		soisdisconnected(so);
X		break;
X
X	/*
X	 * Mark the connection as being incapable of further input.
X	 */
X	case PRU_SHUTDOWN:
X		socantsendmore(so);
X		break;
X
X	/*
X	 * Ship a packet out.  The appropriate raw output
X	 * routine handles any massaging necessary.
X	 */
X	case PRU_SEND:
X		if (nam) {
X			if (rp->rcb_flags & RAW_FADDR) {
X				error = EISCONN;
X				break;
X			}
X			raw_connaddr(rp, nam);
X		} else if ((rp->rcb_flags & RAW_FADDR) == 0) {
X			error = ENOTCONN;
X			break;
X		}
X		error = (*so->so_proto->pr_output)(m, so);
X		m = NULL;
X		if (nam)
X			rp->rcb_flags &= ~RAW_FADDR;
X		break;
X
X	case PRU_ABORT:
X		raw_disconnect(rp);
X		sofree(so);
X		soisdisconnected(so);
X		break;
X
X	case PRU_SENSE:
X		/*
X		 * stat: don't bother with a blocksize.
X		 */
X		return (0);
X
X	/*
X	 * Not supported.
X	 */
X	case PRU_RCVOOB:
X	case PRU_RCVD:
X		return(EOPNOTSUPP);
X
X	case PRU_LISTEN:
X	case PRU_ACCEPT:
X	case PRU_SENDOOB:
X		error = EOPNOTSUPP;
X		break;
X
X	case PRU_SOCKADDR:
X		bcopy((caddr_t)&rp->rcb_laddr, mtod(nam, caddr_t),
X		    sizeof (struct sockaddr));
X		nam->m_len = sizeof (struct sockaddr);
X		break;
X
X	case PRU_PEERADDR:
X		bcopy((caddr_t)&rp->rcb_faddr, mtod(nam, caddr_t),
X		    sizeof (struct sockaddr));
X		nam->m_len = sizeof (struct sockaddr);
X		break;
X
X	default:
X		panic("raw_usrreq");
X	}
Xrelease:
X	if (m != NULL)
X		m_freem(m);
X	return (error);
X}
END-of-net/raw_usrreq.c
exit



More information about the Comp.bugs.4bsd.ucb-fixes mailing list