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