ng_ksocket.c revision 96972
150276Speter
2178866Srafan/*
350276Speter * ng_ksocket.c
450276Speter *
550276Speter * Copyright (c) 1996-1999 Whistle Communications, Inc.
650276Speter * All rights reserved.
750276Speter *
850276Speter * Subject to the following obligations and disclaimer of warranty, use and
950276Speter * redistribution of this software, in source or object code forms, with or
1050276Speter * without modifications are expressly permitted by Whistle Communications;
1150276Speter * provided, however, that:
1250276Speter * 1. Any and all reproductions of the source or object code must include the
1350276Speter *    copyright notice above and the following disclaimer of warranties; and
1450276Speter * 2. No rights are granted, in any manner or form, to use Whistle
1550276Speter *    Communications, Inc. trademarks, including the mark "WHISTLE
1650276Speter *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
1750276Speter *    such appears in the above copyright notice or in the software.
1850276Speter *
1950276Speter * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
2050276Speter * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
2150276Speter * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
2250276Speter * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
2350276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
2450276Speter * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
2550276Speter * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
2650276Speter * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
2750276Speter * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
2850276Speter * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
2950276Speter * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30166124Srafan * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
3150276Speter * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
3250276Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3350276Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3450276Speter * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
35184989Srafan * OF SUCH DAMAGE.
3650276Speter *
37166124Srafan * Author: Archie Cobbs <archie@freebsd.org>
38166124Srafan *
39166124Srafan * $FreeBSD: head/sys/netgraph/ng_ksocket.c 96972 2002-05-20 05:41:09Z tanimura $
40166124Srafan * $Whistle: ng_ksocket.c,v 1.1 1999/11/16 20:04:40 archie Exp $
41174993Srafan */
42166124Srafan
43166124Srafan/*
44166124Srafan * Kernel socket node type.  This node type is basically a kernel-mode
45166124Srafan * version of a socket... kindof like the reverse of the socket node type.
4650276Speter */
47166124Srafan
48166124Srafan#include <sys/param.h>
49166124Srafan#include <sys/systm.h>
50166124Srafan#include <sys/kernel.h>
51166124Srafan#include <sys/mbuf.h>
52166124Srafan#include <sys/proc.h>
53166124Srafan#include <sys/malloc.h>
54166124Srafan#include <sys/ctype.h>
55166124Srafan#include <sys/protosw.h>
56166124Srafan#include <sys/errno.h>
57184989Srafan#include <sys/socket.h>
58174993Srafan#include <sys/socketvar.h>
59178866Srafan#include <sys/uio.h>
60166124Srafan#include <sys/un.h>
61166124Srafan
62166124Srafan#include <netgraph/ng_message.h>
63166124Srafan#include <netgraph/netgraph.h>
64166124Srafan#include <netgraph/ng_parse.h>
65166124Srafan#include <netgraph/ng_ksocket.h>
66166124Srafan
67166124Srafan#include <netinet/in.h>
68166124Srafan#include <netatalk/at.h>
69166124Srafan
70166124Srafan#ifdef NG_SEPARATE_MALLOC
71166124SrafanMALLOC_DEFINE(M_NETGRAPH_KSOCKET, "netgraph_ksock", "netgraph ksock node ");
72166124Srafan#else
73166124Srafan#define M_NETGRAPH_KSOCKET M_NETGRAPH
74166124Srafan#endif
75166124Srafan
76166124Srafan#define OFFSETOF(s, e) ((char *)&((s *)0)->e - (char *)((s *)0))
77166124Srafan#define SADATA_OFFSET	(OFFSETOF(struct sockaddr, sa_data))
78166124Srafan
79166124Srafan/* Node private data */
80184989Srafanstruct ng_ksocket_private {
81166124Srafan	node_p		node;
82166124Srafan	hook_p		hook;
83166124Srafan	struct socket	*so;
8450276Speter	LIST_HEAD(, ng_ksocket_private)	embryos;
8550276Speter	LIST_ENTRY(ng_ksocket_private)	siblings;
8650276Speter	u_int32_t	flags;
8750276Speter	u_int32_t	response_token;
8876726Speter	ng_ID_t		response_addr;
8950276Speter};
9050276Spetertypedef struct ng_ksocket_private *priv_p;
91166124Srafan
9262449Speter/* Flags for priv_p */
93166124Srafan#define	KSF_CONNECTING	0x00000001	/* Waiting for connection complete */
9450276Speter#define	KSF_ACCEPTING	0x00000002	/* Waiting for accept complete */
9550276Speter#define	KSF_EOFSEEN	0x00000004	/* Have sent 0-length EOF mbuf */
9662449Speter#define	KSF_CLONED	0x00000008	/* Cloned from an accepting socket */
9762449Speter#define	KSF_EMBRYONIC	0x00000010	/* Cloned node with no hooks yet */
98166124Srafan#define	KSF_SENDING	0x00000020	/* Sending on socket */
99166124Srafan
100166124Srafan/* Netgraph node methods */
101166124Srafanstatic ng_constructor_t	ng_ksocket_constructor;
102174993Srafanstatic ng_rcvmsg_t	ng_ksocket_rcvmsg;
10350276Speterstatic ng_shutdown_t	ng_ksocket_shutdown;
104174993Srafanstatic ng_newhook_t	ng_ksocket_newhook;
105174993Srafanstatic ng_rcvdata_t	ng_ksocket_rcvdata;
10662449Speterstatic ng_connect_t	ng_ksocket_connect;
10750276Speterstatic ng_disconnect_t	ng_ksocket_disconnect;
10850276Speter
10962449Speter/* Alias structure */
11062449Speterstruct ng_ksocket_alias {
11150276Speter	const char	*name;
11262449Speter	const int	value;
11362449Speter	const int	family;
11450276Speter};
11562449Speter
11662449Speter/* Protocol family aliases */
11762449Speterstatic const struct ng_ksocket_alias ng_ksocket_families[] = {
11850276Speter	{ "local",	PF_LOCAL	},
11962449Speter	{ "inet",	PF_INET		},
12050276Speter	{ "inet6",	PF_INET6	},
12162449Speter	{ "atalk",	PF_APPLETALK	},
12262449Speter	{ "ipx",	PF_IPX		},
12362449Speter	{ "atm",	PF_ATM		},
12450276Speter	{ NULL,		-1		},
12562449Speter};
12662449Speter
12762449Speter/* Socket type aliases */
12862449Speterstatic const struct ng_ksocket_alias ng_ksocket_types[] = {
12962449Speter	{ "stream",	SOCK_STREAM	},
13062449Speter	{ "dgram",	SOCK_DGRAM	},
13162449Speter	{ "raw",	SOCK_RAW	},
13262449Speter	{ "rdm",	SOCK_RDM	},
13350276Speter	{ "seqpacket",	SOCK_SEQPACKET	},
13462449Speter	{ NULL,		-1		},
135166124Srafan};
136166124Srafan
137166124Srafan/* Protocol aliases */
13862449Speterstatic const struct ng_ksocket_alias ng_ksocket_protos[] = {
139166124Srafan	{ "ip",		IPPROTO_IP,		PF_INET		},
140166124Srafan	{ "raw",	IPPROTO_RAW,		PF_INET		},
141166124Srafan	{ "icmp",	IPPROTO_ICMP,		PF_INET		},
14250276Speter	{ "igmp",	IPPROTO_IGMP,		PF_INET		},
14362449Speter	{ "tcp",	IPPROTO_TCP,		PF_INET		},
144166124Srafan	{ "udp",	IPPROTO_UDP,		PF_INET		},
145166124Srafan	{ "gre",	IPPROTO_GRE,		PF_INET		},
146166124Srafan	{ "esp",	IPPROTO_ESP,		PF_INET		},
14762449Speter	{ "ah",		IPPROTO_AH,		PF_INET		},
148166124Srafan	{ "swipe",	IPPROTO_SWIPE,		PF_INET		},
149166124Srafan	{ "encap",	IPPROTO_ENCAP,		PF_INET		},
15062449Speter	{ "divert",	IPPROTO_DIVERT,		PF_INET		},
151166124Srafan	{ "ddp",	ATPROTO_DDP,		PF_APPLETALK	},
15250276Speter	{ "aarp",	ATPROTO_AARP,		PF_APPLETALK	},
153166124Srafan	{ NULL,		-1					},
154166124Srafan};
155166124Srafan
156166124Srafan/* Helper functions */
157166124Srafanstatic int	ng_ksocket_check_accept(priv_p);
158166124Srafanstatic void	ng_ksocket_finish_accept(priv_p);
159166124Srafanstatic void	ng_ksocket_incoming(struct socket *so, void *arg, int waitflag);
160166124Srafanstatic int	ng_ksocket_parse(const struct ng_ksocket_alias *aliases,
161166124Srafan			const char *s, int family);
162166124Srafanstatic void	ng_ksocket_incoming2(node_p node, hook_p hook,
163166124Srafan			void *arg1, int waitflag);
164166124Srafan
165166124Srafan/************************************************************************
16697049Speter			STRUCT SOCKADDR PARSE TYPE
167166124Srafan ************************************************************************/
168166124Srafan
169166124Srafan/* Get the length of the data portion of a generic struct sockaddr */
170166124Srafanstatic int
17162449Speterng_parse_generic_sockdata_getLength(const struct ng_parse_type *type,
172166124Srafan	const u_char *start, const u_char *buf)
173166124Srafan{
174166124Srafan	const struct sockaddr *sa;
17550276Speter
176166124Srafan	sa = (const struct sockaddr *)(buf - SADATA_OFFSET);
177166124Srafan	return (sa->sa_len < SADATA_OFFSET) ? 0 : sa->sa_len - SADATA_OFFSET;
178166124Srafan}
179166124Srafan
180166124Srafan/* Type for the variable length data portion of a generic struct sockaddr */
181166124Srafanstatic const struct ng_parse_type ng_ksocket_generic_sockdata_type = {
18262449Speter	&ng_parse_bytearray_type,
183166124Srafan	&ng_parse_generic_sockdata_getLength
184166124Srafan};
18562449Speter
186166124Srafan/* Type for a generic struct sockaddr */
18762449Speterstatic const struct ng_parse_struct_info ng_parse_generic_sockaddr_type_info = {
188166124Srafan	{
18950276Speter	  { "len",	&ng_parse_uint8_type			},
190166124Srafan	  { "family",	&ng_parse_uint8_type			},
19162449Speter	  { "data",	&ng_ksocket_generic_sockdata_type	},
19250276Speter	  { NULL }
19362449Speter	}
194166124Srafan};
195166124Srafanstatic const struct ng_parse_type ng_ksocket_generic_sockaddr_type = {
196166124Srafan	&ng_parse_struct_type,
197166124Srafan	&ng_parse_generic_sockaddr_type_info
198166124Srafan};
199166124Srafan
200166124Srafan/* Convert a struct sockaddr from ASCII to binary.  If its a protocol
201166124Srafan   family that we specially handle, do that, otherwise defer to the
202166124Srafan   generic parse type ng_ksocket_generic_sockaddr_type. */
203166124Srafanstatic int
204166124Srafanng_ksocket_sockaddr_parse(const struct ng_parse_type *type,
205166124Srafan	const char *s, int *off, const u_char *const start,
206166124Srafan	u_char *const buf, int *buflen)
207166124Srafan{
208166124Srafan	struct sockaddr *const sa = (struct sockaddr *)buf;
209166124Srafan	enum ng_parse_token tok;
210166124Srafan	char fambuf[32];
211166124Srafan	int family, len;
21262449Speter	char *t;
21362449Speter
21462449Speter	/* If next token is a left curly brace, use generic parse type */
21562449Speter	if ((tok = ng_parse_get_token(s, off, &len)) == T_LBRACE) {
21662449Speter		return (*ng_ksocket_generic_sockaddr_type.supertype->parse)
21750276Speter		    (&ng_ksocket_generic_sockaddr_type,
21862449Speter		    s, off, start, buf, buflen);
21962449Speter	}
22062449Speter
22162449Speter	/* Get socket address family followed by a slash */
22262449Speter	while (isspace(s[*off]))
22350276Speter		(*off)++;
22462449Speter	if ((t = index(s + *off, '/')) == NULL)
22562449Speter		return (EINVAL);
22662449Speter	if ((len = t - (s + *off)) > sizeof(fambuf) - 1)
22762449Speter		return (EINVAL);
22850276Speter	strncpy(fambuf, s + *off, len);
229166124Srafan	fambuf[len] = '\0';
230166124Srafan	*off += len + 1;
231166124Srafan	if ((family = ng_ksocket_parse(ng_ksocket_families, fambuf, 0)) == -1)
232166124Srafan		return (EINVAL);
233166124Srafan
234166124Srafan	/* Set family */
23550276Speter	if (*buflen < SADATA_OFFSET)
236166124Srafan		return (ERANGE);
237166124Srafan	sa->sa_family = family;
238166124Srafan
239166124Srafan	/* Set family-specific data and length */
240174993Srafan	switch (sa->sa_family) {
24162449Speter	case PF_LOCAL:		/* Get pathname */
242174993Srafan	    {
243174993Srafan		const int pathoff = OFFSETOF(struct sockaddr_un, sun_path);
24450276Speter		struct sockaddr_un *const sun = (struct sockaddr_un *)sa;
24562449Speter		int toklen, pathlen;
24650276Speter		char *path;
247
248		if ((path = ng_get_string_token(s, off, &toklen, NULL)) == NULL)
249			return (EINVAL);
250		pathlen = strlen(path);
251		if (pathlen > SOCK_MAXADDRLEN) {
252			FREE(path, M_NETGRAPH_KSOCKET);
253			return (E2BIG);
254		}
255		if (*buflen < pathoff + pathlen) {
256			FREE(path, M_NETGRAPH_KSOCKET);
257			return (ERANGE);
258		}
259		*off += toklen;
260		bcopy(path, sun->sun_path, pathlen);
261		sun->sun_len = pathoff + pathlen;
262		FREE(path, M_NETGRAPH_KSOCKET);
263		break;
264	    }
265
266	case PF_INET:		/* Get an IP address with optional port */
267	    {
268		struct sockaddr_in *const sin = (struct sockaddr_in *)sa;
269		int i;
270
271		/* Parse this: <ipaddress>[:port] */
272		for (i = 0; i < 4; i++) {
273			u_long val;
274			char *eptr;
275
276			val = strtoul(s + *off, &eptr, 10);
277			if (val > 0xff || eptr == s + *off)
278				return (EINVAL);
279			*off += (eptr - (s + *off));
280			((u_char *)&sin->sin_addr)[i] = (u_char)val;
281			if (i < 3) {
282				if (s[*off] != '.')
283					return (EINVAL);
284				(*off)++;
285			} else if (s[*off] == ':') {
286				(*off)++;
287				val = strtoul(s + *off, &eptr, 10);
288				if (val > 0xffff || eptr == s + *off)
289					return (EINVAL);
290				*off += (eptr - (s + *off));
291				sin->sin_port = htons(val);
292			} else
293				sin->sin_port = 0;
294		}
295		bzero(&sin->sin_zero, sizeof(sin->sin_zero));
296		sin->sin_len = sizeof(*sin);
297		break;
298	    }
299
300#if 0
301	case PF_APPLETALK:	/* XXX implement these someday */
302	case PF_INET6:
303	case PF_IPX:
304#endif
305
306	default:
307		return (EINVAL);
308	}
309
310	/* Done */
311	*buflen = sa->sa_len;
312	return (0);
313}
314
315/* Convert a struct sockaddr from binary to ASCII */
316static int
317ng_ksocket_sockaddr_unparse(const struct ng_parse_type *type,
318	const u_char *data, int *off, char *cbuf, int cbuflen)
319{
320	const struct sockaddr *sa = (const struct sockaddr *)(data + *off);
321	int slen = 0;
322
323	/* Output socket address, either in special or generic format */
324	switch (sa->sa_family) {
325	case PF_LOCAL:
326	    {
327		const int pathoff = OFFSETOF(struct sockaddr_un, sun_path);
328		const struct sockaddr_un *sun = (const struct sockaddr_un *)sa;
329		const int pathlen = sun->sun_len - pathoff;
330		char pathbuf[SOCK_MAXADDRLEN + 1];
331		char *pathtoken;
332
333		bcopy(sun->sun_path, pathbuf, pathlen);
334		if ((pathtoken = ng_encode_string(pathbuf, pathlen)) == NULL)
335			return (ENOMEM);
336		slen += snprintf(cbuf, cbuflen, "local/%s", pathtoken);
337		FREE(pathtoken, M_NETGRAPH_KSOCKET);
338		if (slen >= cbuflen)
339			return (ERANGE);
340		*off += sun->sun_len;
341		return (0);
342	    }
343
344	case PF_INET:
345	    {
346		const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
347
348		slen += snprintf(cbuf, cbuflen, "inet/%d.%d.%d.%d",
349		  ((const u_char *)&sin->sin_addr)[0],
350		  ((const u_char *)&sin->sin_addr)[1],
351		  ((const u_char *)&sin->sin_addr)[2],
352		  ((const u_char *)&sin->sin_addr)[3]);
353		if (sin->sin_port != 0) {
354			slen += snprintf(cbuf + strlen(cbuf),
355			    cbuflen - strlen(cbuf), ":%d",
356			    (u_int)ntohs(sin->sin_port));
357		}
358		if (slen >= cbuflen)
359			return (ERANGE);
360		*off += sizeof(*sin);
361		return(0);
362	    }
363
364#if 0
365	case PF_APPLETALK:	/* XXX implement these someday */
366	case PF_INET6:
367	case PF_IPX:
368#endif
369
370	default:
371		return (*ng_ksocket_generic_sockaddr_type.supertype->unparse)
372		    (&ng_ksocket_generic_sockaddr_type,
373		    data, off, cbuf, cbuflen);
374	}
375}
376
377/* Parse type for struct sockaddr */
378static const struct ng_parse_type ng_ksocket_sockaddr_type = {
379	NULL,
380	NULL,
381	NULL,
382	&ng_ksocket_sockaddr_parse,
383	&ng_ksocket_sockaddr_unparse,
384	NULL		/* no such thing as a default struct sockaddr */
385};
386
387/************************************************************************
388		STRUCT NG_KSOCKET_SOCKOPT PARSE TYPE
389 ************************************************************************/
390
391/* Get length of the struct ng_ksocket_sockopt value field, which is the
392   just the excess of the message argument portion over the length of
393   the struct ng_ksocket_sockopt. */
394static int
395ng_parse_sockoptval_getLength(const struct ng_parse_type *type,
396	const u_char *start, const u_char *buf)
397{
398	static const int offset = OFFSETOF(struct ng_ksocket_sockopt, value);
399	const struct ng_ksocket_sockopt *sopt;
400	const struct ng_mesg *msg;
401
402	sopt = (const struct ng_ksocket_sockopt *)(buf - offset);
403	msg = (const struct ng_mesg *)((const u_char *)sopt - sizeof(*msg));
404	return msg->header.arglen - sizeof(*sopt);
405}
406
407/* Parse type for the option value part of a struct ng_ksocket_sockopt
408   XXX Eventually, we should handle the different socket options specially.
409   XXX This would avoid byte order problems, eg an integer value of 1 is
410   XXX going to be "[1]" for little endian or "[3=1]" for big endian. */
411static const struct ng_parse_type ng_ksocket_sockoptval_type = {
412	&ng_parse_bytearray_type,
413	&ng_parse_sockoptval_getLength
414};
415
416/* Parse type for struct ng_ksocket_sockopt */
417static const struct ng_parse_struct_info ng_ksocket_sockopt_type_info
418	= NG_KSOCKET_SOCKOPT_INFO(&ng_ksocket_sockoptval_type);
419static const struct ng_parse_type ng_ksocket_sockopt_type = {
420	&ng_parse_struct_type,
421	&ng_ksocket_sockopt_type_info,
422};
423
424/* Parse type for struct ng_ksocket_accept */
425static const struct ng_parse_struct_info ng_ksocket_accept_type_info
426	= NGM_KSOCKET_ACCEPT_INFO;
427static const struct ng_parse_type ng_ksocket_accept_type = {
428	&ng_parse_struct_type,
429	&ng_ksocket_accept_type_info
430};
431
432/* List of commands and how to convert arguments to/from ASCII */
433static const struct ng_cmdlist ng_ksocket_cmds[] = {
434	{
435	  NGM_KSOCKET_COOKIE,
436	  NGM_KSOCKET_BIND,
437	  "bind",
438	  &ng_ksocket_sockaddr_type,
439	  NULL
440	},
441	{
442	  NGM_KSOCKET_COOKIE,
443	  NGM_KSOCKET_LISTEN,
444	  "listen",
445	  &ng_parse_int32_type,
446	  NULL
447	},
448	{
449	  NGM_KSOCKET_COOKIE,
450	  NGM_KSOCKET_ACCEPT,
451	  "accept",
452	  NULL,
453	  &ng_ksocket_accept_type
454	},
455	{
456	  NGM_KSOCKET_COOKIE,
457	  NGM_KSOCKET_CONNECT,
458	  "connect",
459	  &ng_ksocket_sockaddr_type,
460	  &ng_parse_int32_type
461	},
462	{
463	  NGM_KSOCKET_COOKIE,
464	  NGM_KSOCKET_GETNAME,
465	  "getname",
466	  NULL,
467	  &ng_ksocket_sockaddr_type
468	},
469	{
470	  NGM_KSOCKET_COOKIE,
471	  NGM_KSOCKET_GETPEERNAME,
472	  "getpeername",
473	  NULL,
474	  &ng_ksocket_sockaddr_type
475	},
476	{
477	  NGM_KSOCKET_COOKIE,
478	  NGM_KSOCKET_SETOPT,
479	  "setopt",
480	  &ng_ksocket_sockopt_type,
481	  NULL
482	},
483	{
484	  NGM_KSOCKET_COOKIE,
485	  NGM_KSOCKET_GETOPT,
486	  "getopt",
487	  &ng_ksocket_sockopt_type,
488	  &ng_ksocket_sockopt_type
489	},
490	{ 0 }
491};
492
493/* Node type descriptor */
494static struct ng_type ng_ksocket_typestruct = {
495	NG_ABI_VERSION,
496	NG_KSOCKET_NODE_TYPE,
497	NULL,
498	ng_ksocket_constructor,
499	ng_ksocket_rcvmsg,
500	ng_ksocket_shutdown,
501	ng_ksocket_newhook,
502	NULL,
503	ng_ksocket_connect,
504	ng_ksocket_rcvdata,
505	ng_ksocket_disconnect,
506	ng_ksocket_cmds
507};
508NETGRAPH_INIT(ksocket, &ng_ksocket_typestruct);
509
510#define ERROUT(x)			\
511	do {				\
512		error = (x);		\
513		goto done;		\
514	} while (0)
515#define ERROUT_SOCK(x)			\
516	do {				\
517		error = (x);		\
518		SOCK_UNLOCK(so);	\
519		goto done;		\
520	} while (0)
521
522/************************************************************************
523			NETGRAPH NODE STUFF
524 ************************************************************************/
525
526/*
527 * Node type constructor
528 * The NODE part is assumed to be all set up.
529 * There is already a reference to the node for us.
530 */
531static int
532ng_ksocket_constructor(node_p node)
533{
534	priv_p priv;
535
536	/* Allocate private structure */
537	MALLOC(priv, priv_p, sizeof(*priv),
538	    M_NETGRAPH_KSOCKET, M_NOWAIT | M_ZERO);
539	if (priv == NULL)
540		return (ENOMEM);
541
542	LIST_INIT(&priv->embryos);
543	/* cross link them */
544	priv->node = node;
545	NG_NODE_SET_PRIVATE(node, priv);
546
547	/* Done */
548	return (0);
549}
550
551/*
552 * Give our OK for a hook to be added. The hook name is of the
553 * form "<family>/<type>/<proto>" where the three components may
554 * be decimal numbers or else aliases from the above lists.
555 *
556 * Connecting a hook amounts to opening the socket.  Disconnecting
557 * the hook closes the socket and destroys the node as well.
558 */
559static int
560ng_ksocket_newhook(node_p node, hook_p hook, const char *name0)
561{
562	struct thread *td = curthread ? curthread : &thread0;	/* XXX broken */
563	const priv_p priv = NG_NODE_PRIVATE(node);
564	char *s1, *s2, name[NG_HOOKLEN+1];
565	int family, type, protocol, error;
566
567	/* Check if we're already connected */
568	if (priv->hook != NULL)
569		return (EISCONN);
570
571	if (priv->flags & KSF_CLONED) {
572		if (priv->flags & KSF_EMBRYONIC) {
573			/* Remove ourselves from our parent's embryo list */
574			LIST_REMOVE(priv, siblings);
575			priv->flags &= ~KSF_EMBRYONIC;
576		}
577	} else {
578		/* Extract family, type, and protocol from hook name */
579		snprintf(name, sizeof(name), "%s", name0);
580		s1 = name;
581		if ((s2 = index(s1, '/')) == NULL)
582			return (EINVAL);
583		*s2++ = '\0';
584		family = ng_ksocket_parse(ng_ksocket_families, s1, 0);
585		if (family == -1)
586			return (EINVAL);
587		s1 = s2;
588		if ((s2 = index(s1, '/')) == NULL)
589			return (EINVAL);
590		*s2++ = '\0';
591		type = ng_ksocket_parse(ng_ksocket_types, s1, 0);
592		if (type == -1)
593			return (EINVAL);
594		s1 = s2;
595		protocol = ng_ksocket_parse(ng_ksocket_protos, s1, family);
596		if (protocol == -1)
597			return (EINVAL);
598
599		/* Create the socket */
600		error = socreate(family, &priv->so, type, protocol,
601		   td->td_ucred, td);
602		if (error != 0)
603			return (error);
604
605		/* XXX call soreserve() ? */
606
607	}
608
609	/* OK */
610	priv->hook = hook;
611	return(0);
612}
613
614static int
615ng_ksocket_connect(hook_p hook)
616{
617	node_p node = NG_HOOK_NODE(hook);
618	const priv_p priv = NG_NODE_PRIVATE(node);
619	struct socket *const so = priv->so;
620
621	/* Add our hook for incoming data and other events */
622	priv->so->so_upcallarg = (caddr_t)node;
623	priv->so->so_upcall = ng_ksocket_incoming;
624	priv->so->so_rcv.sb_flags |= SB_UPCALL;
625	priv->so->so_snd.sb_flags |= SB_UPCALL;
626	SOCK_LOCK(priv->so);
627	priv->so->so_state |= SS_NBIO;
628	SOCK_UNLOCK(priv->so);
629	/*
630	 * --Original comment--
631	 * On a cloned socket we may have already received one or more
632	 * upcalls which we couldn't handle without a hook.  Handle
633	 * those now.
634	 * We cannot call the upcall function directly
635	 * from here, because until this function has returned our
636	 * hook isn't connected.
637	 *
638	 * ---meta comment for -current ---
639	 * XXX This is dubius.
640	 * Upcalls between the time that the hook was
641	 * first created and now (on another processesor) will
642	 * be earlier on the queue than the request to finalise the hook.
643	 * By the time the hook is finalised,
644	 * The queued upcalls will have happenned and the code
645	 * will have discarded them because of a lack of a hook.
646	 * (socket not open).
647	 *
648	 * This is a bad byproduct of the complicated way in which hooks
649	 * are now created (3 daisy chained async events).
650	 *
651	 * Since we are a netgraph operation
652	 * We know that we hold a lock on this node. This forces the
653	 * request we make below to be queued rather than implemented
654	 * immediatly which will cause the upcall function to be called a bit
655	 * later.
656	 * However, as we will run any waiting queued operations immediatly
657	 * after doing this one, if we have not finalised the other end
658	 * of the hook, those queued operations will fail.
659	 */
660	if (priv->flags & KSF_CLONED) {
661		ng_send_fn(node, NULL, &ng_ksocket_incoming2, so, M_NOWAIT);
662	}
663
664	return (0);
665}
666
667/*
668 * Receive a control message
669 */
670static int
671ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook)
672{
673	struct thread *td = curthread ? curthread : &thread0;	/* XXX broken */
674	const priv_p priv = NG_NODE_PRIVATE(node);
675	struct socket *const so = priv->so;
676	struct ng_mesg *resp = NULL;
677	int error = 0;
678	struct ng_mesg *msg;
679	ng_ID_t raddr;
680
681	NGI_GET_MSG(item, msg);
682	switch (msg->header.typecookie) {
683	case NGM_KSOCKET_COOKIE:
684		switch (msg->header.cmd) {
685		case NGM_KSOCKET_BIND:
686		    {
687			struct sockaddr *const sa
688			    = (struct sockaddr *)msg->data;
689
690			/* Sanity check */
691			if (msg->header.arglen < SADATA_OFFSET
692			    || msg->header.arglen < sa->sa_len)
693				ERROUT(EINVAL);
694			if (so == NULL)
695				ERROUT(ENXIO);
696
697			/* Bind */
698			error = sobind(so, sa, td);
699			break;
700		    }
701		case NGM_KSOCKET_LISTEN:
702		    {
703			/* Sanity check */
704			if (msg->header.arglen != sizeof(int32_t))
705				ERROUT(EINVAL);
706			if (so == NULL)
707				ERROUT(ENXIO);
708
709			/* Listen */
710			error = solisten(so, *((int32_t *)msg->data), td);
711			break;
712		    }
713
714		case NGM_KSOCKET_ACCEPT:
715		    {
716			/* Sanity check */
717			if (msg->header.arglen != 0)
718				ERROUT(EINVAL);
719			if (so == NULL)
720				ERROUT(ENXIO);
721
722			/* Make sure the socket is capable of accepting */
723			SOCK_LOCK(so);
724			if (!(so->so_options & SO_ACCEPTCONN))
725				ERROUT_SOCK(EINVAL);
726			SOCK_UNLOCK(so);
727			if (priv->flags & KSF_ACCEPTING)
728				ERROUT(EALREADY);
729
730			error = ng_ksocket_check_accept(priv);
731			if (error != 0 && error != EWOULDBLOCK)
732				ERROUT(error);
733
734			/*
735			 * If a connection is already complete, take it.
736			 * Otherwise let the upcall function deal with
737			 * the connection when it comes in.
738			 */
739			priv->response_token = msg->header.token;
740			raddr = priv->response_addr;
741			if (error == 0) {
742				ng_ksocket_finish_accept(priv);
743			} else
744				priv->flags |= KSF_ACCEPTING;
745			break;
746		    }
747
748		case NGM_KSOCKET_CONNECT:
749		    {
750			struct sockaddr *const sa
751			    = (struct sockaddr *)msg->data;
752
753			/* Sanity check */
754			if (msg->header.arglen < SADATA_OFFSET
755			    || msg->header.arglen < sa->sa_len)
756				ERROUT(EINVAL);
757			if (so == NULL)
758				ERROUT(ENXIO);
759
760			/* Do connect */
761			SOCK_LOCK(so);
762			if ((so->so_state & SS_ISCONNECTING) != 0)
763				ERROUT_SOCK(EALREADY);
764			SOCK_UNLOCK(so);
765			if ((error = soconnect(so, sa, td)) != 0) {
766				SOCK_LOCK(so);
767				so->so_state &= ~SS_ISCONNECTING;
768				ERROUT_SOCK(error);
769			}
770			SOCK_LOCK(so);
771			if ((so->so_state & SS_ISCONNECTING) != 0) {
772				/* We will notify the sender when we connect */
773				priv->response_token = msg->header.token;
774				raddr = priv->response_addr;
775				priv->flags |= KSF_CONNECTING;
776				ERROUT_SOCK(EINPROGRESS);
777			}
778			SOCK_UNLOCK(so);
779			break;
780		    }
781
782		case NGM_KSOCKET_GETNAME:
783		case NGM_KSOCKET_GETPEERNAME:
784		    {
785			int (*func)(struct socket *so, struct sockaddr **nam);
786			struct sockaddr *sa = NULL;
787			int len;
788
789			/* Sanity check */
790			if (msg->header.arglen != 0)
791				ERROUT(EINVAL);
792			if (so == NULL)
793				ERROUT(ENXIO);
794
795			/* Get function */
796			if (msg->header.cmd == NGM_KSOCKET_GETPEERNAME) {
797				SOCK_LOCK(so);
798				if ((so->so_state
799				    & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
800					ERROUT_SOCK(ENOTCONN);
801				SOCK_UNLOCK(so);
802				func = so->so_proto->pr_usrreqs->pru_peeraddr;
803			} else
804				func = so->so_proto->pr_usrreqs->pru_sockaddr;
805
806			/* Get local or peer address */
807			if ((error = (*func)(so, &sa)) != 0)
808				goto bail;
809			len = (sa == NULL) ? 0 : sa->sa_len;
810
811			/* Send it back in a response */
812			NG_MKRESPONSE(resp, msg, len, M_NOWAIT);
813			if (resp == NULL) {
814				error = ENOMEM;
815				goto bail;
816			}
817			bcopy(sa, resp->data, len);
818
819		bail:
820			/* Cleanup */
821			if (sa != NULL)
822				FREE(sa, M_SONAME);
823			break;
824		    }
825
826		case NGM_KSOCKET_GETOPT:
827		    {
828			struct ng_ksocket_sockopt *ksopt =
829			    (struct ng_ksocket_sockopt *)msg->data;
830			struct sockopt sopt;
831
832			/* Sanity check */
833			if (msg->header.arglen != sizeof(*ksopt))
834				ERROUT(EINVAL);
835			if (so == NULL)
836				ERROUT(ENXIO);
837
838			/* Get response with room for option value */
839			NG_MKRESPONSE(resp, msg, sizeof(*ksopt)
840			    + NG_KSOCKET_MAX_OPTLEN, M_NOWAIT);
841			if (resp == NULL)
842				ERROUT(ENOMEM);
843
844			/* Get socket option, and put value in the response */
845			sopt.sopt_dir = SOPT_GET;
846			sopt.sopt_level = ksopt->level;
847			sopt.sopt_name = ksopt->name;
848			sopt.sopt_td = NULL;
849			sopt.sopt_valsize = NG_KSOCKET_MAX_OPTLEN;
850			ksopt = (struct ng_ksocket_sockopt *)resp->data;
851			sopt.sopt_val = ksopt->value;
852			if ((error = sogetopt(so, &sopt)) != 0) {
853				NG_FREE_MSG(resp);
854				break;
855			}
856
857			/* Set actual value length */
858			resp->header.arglen = sizeof(*ksopt)
859			    + sopt.sopt_valsize;
860			break;
861		    }
862
863		case NGM_KSOCKET_SETOPT:
864		    {
865			struct ng_ksocket_sockopt *const ksopt =
866			    (struct ng_ksocket_sockopt *)msg->data;
867			const int valsize = msg->header.arglen - sizeof(*ksopt);
868			struct sockopt sopt;
869
870			/* Sanity check */
871			if (valsize < 0)
872				ERROUT(EINVAL);
873			if (so == NULL)
874				ERROUT(ENXIO);
875
876			/* Set socket option */
877			sopt.sopt_dir = SOPT_SET;
878			sopt.sopt_level = ksopt->level;
879			sopt.sopt_name = ksopt->name;
880			sopt.sopt_val = ksopt->value;
881			sopt.sopt_valsize = valsize;
882			sopt.sopt_td = NULL;
883			error = sosetopt(so, &sopt);
884			break;
885		    }
886
887		default:
888			error = EINVAL;
889			break;
890		}
891		break;
892	default:
893		error = EINVAL;
894		break;
895	}
896done:
897	NG_RESPOND_MSG(error, node, item, resp);
898	NG_FREE_MSG(msg);
899	return (error);
900}
901
902/*
903 * Receive incoming data on our hook.  Send it out the socket.
904 */
905static int
906ng_ksocket_rcvdata(hook_p hook, item_p item)
907{
908	struct thread *td = curthread ? curthread : &thread0;	/* XXX broken */
909	const node_p node = NG_HOOK_NODE(hook);
910	const priv_p priv = NG_NODE_PRIVATE(node);
911	struct socket *const so = priv->so;
912	struct sockaddr *sa = NULL;
913	meta_p meta;
914	int error;
915	struct mbuf *m;
916
917	/* Avoid reentrantly sending on the socket */
918	if ((priv->flags & KSF_SENDING) != 0) {
919		NG_FREE_ITEM(item);
920		return (EDEADLK);
921	}
922
923	/* Extract data and meta information */
924	NGI_GET_M(item, m);
925	NGI_GET_META(item, meta);
926	NG_FREE_ITEM(item);
927
928	/* If any meta info, look for peer socket address */
929	if (meta != NULL) {
930		struct meta_field_header *field;
931
932		/* Look for peer socket address */
933		for (field = &meta->options[0];
934		    (caddr_t)field < (caddr_t)meta + meta->used_len;
935		    field = (struct meta_field_header *)
936		      ((caddr_t)field + field->len)) {
937			if (field->cookie != NGM_KSOCKET_COOKIE
938			    || field->type != NG_KSOCKET_META_SOCKADDR)
939				continue;
940			sa = (struct sockaddr *)field->data;
941			break;
942		}
943	}
944
945	/* Send packet */
946	priv->flags |= KSF_SENDING;
947	error = (*so->so_proto->pr_usrreqs->pru_sosend)(so, sa, 0, m, 0, 0, td);
948	priv->flags &= ~KSF_SENDING;
949
950	/* Clean up and exit */
951	NG_FREE_META(meta);
952	return (error);
953}
954
955/*
956 * Destroy node
957 */
958static int
959ng_ksocket_shutdown(node_p node)
960{
961	const priv_p priv = NG_NODE_PRIVATE(node);
962	priv_p embryo;
963
964	/* Close our socket (if any) */
965	if (priv->so != NULL) {
966		priv->so->so_upcall = NULL;
967		priv->so->so_rcv.sb_flags &= ~SB_UPCALL;
968		priv->so->so_snd.sb_flags &= ~SB_UPCALL;
969		soclose(priv->so);
970		priv->so = NULL;
971	}
972
973	/* If we are an embryo, take ourselves out of the parent's list */
974	if (priv->flags & KSF_EMBRYONIC) {
975		LIST_REMOVE(priv, siblings);
976		priv->flags &= ~KSF_EMBRYONIC;
977	}
978
979	/* Remove any embryonic children we have */
980	while (!LIST_EMPTY(&priv->embryos)) {
981		embryo = LIST_FIRST(&priv->embryos);
982		ng_rmnode_self(embryo->node);
983	}
984
985	/* Take down netgraph node */
986	bzero(priv, sizeof(*priv));
987	FREE(priv, M_NETGRAPH_KSOCKET);
988	NG_NODE_SET_PRIVATE(node, NULL);
989	NG_NODE_UNREF(node);		/* let the node escape */
990	return (0);
991}
992
993/*
994 * Hook disconnection
995 */
996static int
997ng_ksocket_disconnect(hook_p hook)
998{
999	KASSERT(NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0,
1000	    ("%s: numhooks=%d?", __func__,
1001	    NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook))));
1002	if (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))
1003		ng_rmnode_self(NG_HOOK_NODE(hook));
1004	return (0);
1005}
1006
1007/************************************************************************
1008			HELPER STUFF
1009 ************************************************************************/
1010/*
1011 * You should no-longer "just call" a netgraph node function
1012 * from an external asynchronous event.
1013 * This is because in doing so you are ignoring the locking on the netgraph
1014 * nodes. Instead call your function via
1015 * "int ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn,
1016 *	 void *arg1, int arg2);"
1017 * this will call the function you chose, but will first do all the
1018 * locking rigmarole. Your function MAY only be called at some distant future
1019 * time (several millisecs away) so don't give it any arguments
1020 * that may be revoked soon (e.g. on your stack).
1021 * In this case even the 'so' argument is doubtful.
1022 * While the function request is being processed the node
1023 * has an extra reference and as such will not disappear until
1024 * the request has at least been done, but the 'so' may not be so lucky.
1025 * handle this by checking the validity of the node in the target function
1026 * before dereferencing the socket pointer.
1027 */
1028
1029static void
1030ng_ksocket_incoming(struct socket *so, void *arg, int waitflag)
1031{
1032	const node_p node = arg;
1033
1034	ng_send_fn(node, NULL, &ng_ksocket_incoming2, so, waitflag);
1035}
1036
1037
1038/*
1039 * When incoming data is appended to the socket, we get notified here.
1040 * This is also called whenever a significant event occurs for the socket.
1041 * We know that HOOK is NULL. Because of how we were called we know we have a
1042 * lock on this node an are participating inthe netgraph locking.
1043 * Our original caller may have queued this even some time ago and
1044 * we cannot trust that he even still exists. The node however is being
1045 * held with a reference by the queueing code, at least until we finish,
1046 * even if it has been zapped, so first check it's validiy
1047 * before we trust the socket (which was derived from it).
1048 */
1049static void
1050ng_ksocket_incoming2(node_p node, hook_p hook, void *arg1, int waitflag)
1051{
1052	struct socket *so = arg1;
1053	const priv_p priv = NG_NODE_PRIVATE(node);
1054	struct mbuf *m;
1055	struct ng_mesg *response;
1056	struct uio auio;
1057	int s, flags, error;
1058
1059	s = splnet();
1060
1061	/* Sanity check */
1062	if (NG_NODE_NOT_VALID(node)) {
1063		splx(s);
1064		return;
1065	}
1066	/* so = priv->so; *//* XXX could have derived this like so */
1067	KASSERT(so == priv->so, ("%s: wrong socket", __func__));
1068
1069	/* Check whether a pending connect operation has completed */
1070	if (priv->flags & KSF_CONNECTING) {
1071		SOCK_LOCK(so);
1072		if ((error = so->so_error) != 0) {
1073			so->so_error = 0;
1074			so->so_state &= ~SS_ISCONNECTING;
1075		}
1076		if (!(so->so_state & SS_ISCONNECTING)) {
1077			SOCK_UNLOCK(so);
1078			NG_MKMESSAGE(response, NGM_KSOCKET_COOKIE,
1079			    NGM_KSOCKET_CONNECT, sizeof(int32_t), waitflag);
1080			if (response != NULL) {
1081				response->header.flags |= NGF_RESP;
1082				response->header.token = priv->response_token;
1083				*(int32_t *)response->data = error;
1084				/*
1085				 * send an async "response" message
1086				 * to the node that set us up
1087				 * (if it still exists)
1088				 */
1089				NG_SEND_MSG_ID(error, node, response,
1090						priv->response_addr, NULL);
1091			}
1092			priv->flags &= ~KSF_CONNECTING;
1093		} else
1094			SOCK_UNLOCK(so);
1095	}
1096
1097	/* Check whether a pending accept operation has completed */
1098	if (priv->flags & KSF_ACCEPTING) {
1099		error = ng_ksocket_check_accept(priv);
1100		if (error != EWOULDBLOCK)
1101			priv->flags &= ~KSF_ACCEPTING;
1102		if (error == 0)
1103			ng_ksocket_finish_accept(priv);
1104	}
1105
1106	/*
1107	 * If we don't have a hook, we must handle data events later.  When
1108	 * the hook gets created and is connected, this upcall function
1109	 * will be called again.
1110	 */
1111	if (priv->hook == NULL) {
1112		splx(s);
1113		return;
1114	}
1115
1116	/* Read and forward available mbuf's */
1117	auio.uio_td = NULL;
1118	auio.uio_resid = 1000000000;
1119	flags = MSG_DONTWAIT;
1120	while (1) {
1121		struct sockaddr *sa = NULL;
1122		meta_p meta = NULL;
1123		struct mbuf *n;
1124		int sostate;
1125
1126		/* Try to get next packet from socket */
1127		SOCK_LOCK(so);
1128		sostate = so->so_state & SS_ISCONNECTED;
1129		SOCK_UNLOCK(so);
1130		if ((error = (*so->so_proto->pr_usrreqs->pru_soreceive)
1131		    (so, sostate ? NULL : &sa,
1132		    &auio, &m, (struct mbuf **)0, &flags)) != 0)
1133			break;
1134
1135		/* See if we got anything */
1136		if (m == NULL) {
1137			if (sa != NULL)
1138				FREE(sa, M_SONAME);
1139			break;
1140		}
1141
1142		/* Don't trust the various socket layers to get the
1143		   packet header and length correct (eg. kern/15175) */
1144		for (n = m, m->m_pkthdr.len = 0; n != NULL; n = n->m_next)
1145			m->m_pkthdr.len += n->m_len;
1146
1147		/* Put peer's socket address (if any) into a meta info blob */
1148		if (sa != NULL) {
1149			struct meta_field_header *mhead;
1150			u_int len;
1151
1152			len = sizeof(*meta) + sizeof(*mhead) + sa->sa_len;
1153			MALLOC(meta, meta_p, len, M_NETGRAPH_META, M_NOWAIT);
1154			if (meta == NULL) {
1155				FREE(sa, M_SONAME);
1156				goto sendit;
1157			}
1158			mhead = &meta->options[0];
1159			bzero(meta, sizeof(*meta));
1160			bzero(mhead, sizeof(*mhead));
1161			meta->allocated_len = len;
1162			meta->used_len = len;
1163			mhead->cookie = NGM_KSOCKET_COOKIE;
1164			mhead->type = NG_KSOCKET_META_SOCKADDR;
1165			mhead->len = sizeof(*mhead) + sa->sa_len;
1166			bcopy(sa, mhead->data, sa->sa_len);
1167			FREE(sa, M_SONAME);
1168		}
1169
1170sendit:		/* Forward data with optional peer sockaddr as meta info */
1171		NG_SEND_DATA(error, priv->hook, m, meta);
1172	}
1173
1174	/*
1175	 * If the peer has closed the connection, forward a 0-length mbuf
1176	 * to indicate end-of-file.
1177	 */
1178	SOCK_LOCK(so);
1179	if (so->so_state & SS_CANTRCVMORE && !(priv->flags & KSF_EOFSEEN)) {
1180		SOCK_UNLOCK(so);
1181		MGETHDR(m, waitflag, MT_DATA);
1182		if (m != NULL) {
1183			m->m_len = m->m_pkthdr.len = 0;
1184			NG_SEND_DATA_ONLY(error, priv->hook, m);
1185		}
1186		priv->flags |= KSF_EOFSEEN;
1187	} else
1188		SOCK_UNLOCK(so);
1189	splx(s);
1190}
1191
1192/*
1193 * Check for a completed incoming connection and return 0 if one is found.
1194 * Otherwise return the appropriate error code.
1195 */
1196static int
1197ng_ksocket_check_accept(priv_p priv)
1198{
1199	struct socket *const head = priv->so;
1200	int error;
1201
1202	if ((error = head->so_error) != 0) {
1203		head->so_error = 0;
1204		return error;
1205	}
1206	if (TAILQ_EMPTY(&head->so_comp)) {
1207		SOCK_LOCK(head);
1208		if (head->so_state & SS_CANTRCVMORE) {
1209			SOCK_UNLOCK(head);
1210			return ECONNABORTED;
1211		}
1212		SOCK_UNLOCK(head);
1213		return EWOULDBLOCK;
1214	}
1215	return 0;
1216}
1217
1218/*
1219 * Handle the first completed incoming connection, assumed to be already
1220 * on the socket's so_comp queue.
1221 */
1222static void
1223ng_ksocket_finish_accept(priv_p priv)
1224{
1225	struct socket *const head = priv->so;
1226	struct socket *so;
1227	struct sockaddr *sa = NULL;
1228	struct ng_mesg *resp;
1229	struct ng_ksocket_accept *resp_data;
1230	node_p node;
1231	priv_p priv2;
1232	int len;
1233	int error;
1234
1235	so = TAILQ_FIRST(&head->so_comp);
1236	if (so == NULL)		/* Should never happen */
1237		return;
1238	TAILQ_REMOVE(&head->so_comp, so, so_list);
1239	head->so_qlen--;
1240
1241	/* XXX KNOTE(&head->so_rcv.sb_sel.si_note, 0); */
1242
1243	SOCK_LOCK(so);
1244	so->so_state &= ~SS_COMP;
1245	so->so_state |= SS_NBIO;
1246	SOCK_UNLOCK(so);
1247	so->so_head = NULL;
1248
1249	soaccept(so, &sa);
1250
1251	len = OFFSETOF(struct ng_ksocket_accept, addr);
1252	if (sa != NULL)
1253		len += sa->sa_len;
1254
1255	NG_MKMESSAGE(resp, NGM_KSOCKET_COOKIE, NGM_KSOCKET_ACCEPT, len,
1256	    M_NOWAIT);
1257	if (resp == NULL) {
1258		soclose(so);
1259		goto out;
1260	}
1261	resp->header.flags |= NGF_RESP;
1262	resp->header.token = priv->response_token;
1263
1264	/* Clone a ksocket node to wrap the new socket */
1265        error = ng_make_node_common(&ng_ksocket_typestruct, &node);
1266        if (error) {
1267		FREE(resp, M_NETGRAPH);
1268		soclose(so);
1269		goto out;
1270	}
1271
1272	if (ng_ksocket_constructor(node) != 0) {
1273		NG_NODE_UNREF(node);
1274		FREE(resp, M_NETGRAPH);
1275		soclose(so);
1276		goto out;
1277	}
1278
1279	priv2 = NG_NODE_PRIVATE(node);
1280	priv2->so = so;
1281	priv2->flags |= KSF_CLONED | KSF_EMBRYONIC;
1282
1283	/*
1284	 * Insert the cloned node into a list of embryonic children
1285	 * on the parent node.  When a hook is created on the cloned
1286	 * node it will be removed from this list.  When the parent
1287	 * is destroyed it will destroy any embryonic children it has.
1288	 */
1289	LIST_INSERT_HEAD(&priv->embryos, priv2, siblings);
1290
1291	so->so_upcallarg = (caddr_t)node;
1292	so->so_upcall = ng_ksocket_incoming;
1293	so->so_rcv.sb_flags |= SB_UPCALL;
1294	so->so_snd.sb_flags |= SB_UPCALL;
1295
1296	/* Fill in the response data and send it or return it to the caller */
1297	resp_data = (struct ng_ksocket_accept *)resp->data;
1298	resp_data->nodeid = NG_NODE_ID(node);
1299	if (sa != NULL)
1300		bcopy(sa, &resp_data->addr, sa->sa_len);
1301	NG_SEND_MSG_ID(error, node, resp, priv->response_addr, NULL);
1302
1303out:
1304	if (sa != NULL)
1305		FREE(sa, M_SONAME);
1306}
1307
1308/*
1309 * Parse out either an integer value or an alias.
1310 */
1311static int
1312ng_ksocket_parse(const struct ng_ksocket_alias *aliases,
1313	const char *s, int family)
1314{
1315	int k, val;
1316	char *eptr;
1317
1318	/* Try aliases */
1319	for (k = 0; aliases[k].name != NULL; k++) {
1320		if (strcmp(s, aliases[k].name) == 0
1321		    && aliases[k].family == family)
1322			return aliases[k].value;
1323	}
1324
1325	/* Try parsing as a number */
1326	val = (int)strtoul(s, &eptr, 10);
1327	if (val < 0 || *eptr != '\0')
1328		return (-1);
1329	return (val);
1330}
1331
1332