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