xref: /minix3/minix/net/lwip/lnksock.c (revision ef8d499e2d2af900e9b2ab297171d7b088652482)
1*ef8d499eSDavid van Moolenbroek /* LWIP service - lnksock.c - link sockets */
2*ef8d499eSDavid van Moolenbroek /*
3*ef8d499eSDavid van Moolenbroek  * This module contains absolutely minimal support for AF_LINK type sockets,
4*ef8d499eSDavid van Moolenbroek  * because for now we need them only to support a specific set of IOCTLs, as
5*ef8d499eSDavid van Moolenbroek  * required by for example ifconfig(8).
6*ef8d499eSDavid van Moolenbroek  */
7*ef8d499eSDavid van Moolenbroek 
8*ef8d499eSDavid van Moolenbroek #include "lwip.h"
9*ef8d499eSDavid van Moolenbroek 
10*ef8d499eSDavid van Moolenbroek /* The number of link sockets. */
11*ef8d499eSDavid van Moolenbroek #define NR_LNKSOCK	4
12*ef8d499eSDavid van Moolenbroek 
13*ef8d499eSDavid van Moolenbroek static struct lnksock {
14*ef8d499eSDavid van Moolenbroek 	struct sock lnk_sock;		/* socket object, MUST be first */
15*ef8d499eSDavid van Moolenbroek 	SIMPLEQ_ENTRY(lnksock) lnk_next; /* next in free list */
16*ef8d499eSDavid van Moolenbroek } lnk_array[NR_LNKSOCK];
17*ef8d499eSDavid van Moolenbroek 
18*ef8d499eSDavid van Moolenbroek static SIMPLEQ_HEAD(, lnksock) lnk_freelist;	/* list of free link sockets */
19*ef8d499eSDavid van Moolenbroek 
20*ef8d499eSDavid van Moolenbroek static const struct sockevent_ops lnksock_ops;
21*ef8d499eSDavid van Moolenbroek 
22*ef8d499eSDavid van Moolenbroek /*
23*ef8d499eSDavid van Moolenbroek  * Initialize the link sockets module.
24*ef8d499eSDavid van Moolenbroek  */
25*ef8d499eSDavid van Moolenbroek void
lnksock_init(void)26*ef8d499eSDavid van Moolenbroek lnksock_init(void)
27*ef8d499eSDavid van Moolenbroek {
28*ef8d499eSDavid van Moolenbroek 	unsigned int slot;
29*ef8d499eSDavid van Moolenbroek 
30*ef8d499eSDavid van Moolenbroek 	/* Initialize the list of free link sockets. */
31*ef8d499eSDavid van Moolenbroek 	SIMPLEQ_INIT(&lnk_freelist);
32*ef8d499eSDavid van Moolenbroek 
33*ef8d499eSDavid van Moolenbroek 	for (slot = 0; slot < __arraycount(lnk_array); slot++)
34*ef8d499eSDavid van Moolenbroek 		SIMPLEQ_INSERT_TAIL(&lnk_freelist, &lnk_array[slot], lnk_next);
35*ef8d499eSDavid van Moolenbroek }
36*ef8d499eSDavid van Moolenbroek 
37*ef8d499eSDavid van Moolenbroek /*
38*ef8d499eSDavid van Moolenbroek  * Create a link socket.
39*ef8d499eSDavid van Moolenbroek  */
40*ef8d499eSDavid van Moolenbroek sockid_t
lnksock_socket(int type,int protocol,struct sock ** sockp,const struct sockevent_ops ** ops)41*ef8d499eSDavid van Moolenbroek lnksock_socket(int type, int protocol, struct sock ** sockp,
42*ef8d499eSDavid van Moolenbroek 	const struct sockevent_ops ** ops)
43*ef8d499eSDavid van Moolenbroek {
44*ef8d499eSDavid van Moolenbroek 	struct lnksock *lnk;
45*ef8d499eSDavid van Moolenbroek 
46*ef8d499eSDavid van Moolenbroek 	if (type != SOCK_DGRAM)
47*ef8d499eSDavid van Moolenbroek 		return EPROTOTYPE;
48*ef8d499eSDavid van Moolenbroek 
49*ef8d499eSDavid van Moolenbroek 	if (protocol != 0)
50*ef8d499eSDavid van Moolenbroek 		return EPROTONOSUPPORT;
51*ef8d499eSDavid van Moolenbroek 
52*ef8d499eSDavid van Moolenbroek 	if (SIMPLEQ_EMPTY(&lnk_freelist))
53*ef8d499eSDavid van Moolenbroek 		return ENOBUFS;
54*ef8d499eSDavid van Moolenbroek 
55*ef8d499eSDavid van Moolenbroek 	lnk = SIMPLEQ_FIRST(&lnk_freelist);
56*ef8d499eSDavid van Moolenbroek 	SIMPLEQ_REMOVE_HEAD(&lnk_freelist, lnk_next);
57*ef8d499eSDavid van Moolenbroek 
58*ef8d499eSDavid van Moolenbroek 	*sockp = &lnk->lnk_sock;
59*ef8d499eSDavid van Moolenbroek 	*ops = &lnksock_ops;
60*ef8d499eSDavid van Moolenbroek 	return SOCKID_LNK | (sockid_t)(lnk - lnk_array);
61*ef8d499eSDavid van Moolenbroek }
62*ef8d499eSDavid van Moolenbroek 
63*ef8d499eSDavid van Moolenbroek /*
64*ef8d499eSDavid van Moolenbroek  * Free up a closed link socket.
65*ef8d499eSDavid van Moolenbroek  */
66*ef8d499eSDavid van Moolenbroek static void
lnksock_free(struct sock * sock)67*ef8d499eSDavid van Moolenbroek lnksock_free(struct sock * sock)
68*ef8d499eSDavid van Moolenbroek {
69*ef8d499eSDavid van Moolenbroek 	struct lnksock *lnk = (struct lnksock *)sock;
70*ef8d499eSDavid van Moolenbroek 
71*ef8d499eSDavid van Moolenbroek 	SIMPLEQ_INSERT_HEAD(&lnk_freelist, lnk, lnk_next);
72*ef8d499eSDavid van Moolenbroek }
73*ef8d499eSDavid van Moolenbroek 
74*ef8d499eSDavid van Moolenbroek static const struct sockevent_ops lnksock_ops = {
75*ef8d499eSDavid van Moolenbroek 	.sop_ioctl		= ifconf_ioctl,
76*ef8d499eSDavid van Moolenbroek 	.sop_free		= lnksock_free
77*ef8d499eSDavid van Moolenbroek };
78