eth.c (5495B)
1 /* $Id: //depot/blt/srv/network/protocol/eth/eth.c#1 $ 2 ** 3 ** Copyright 1999 Sidney Cammeresi 4 ** All rights reserved. 5 ** 6 ** Redistribution and use in source and binary forms, with or without 7 ** modification, are permitted provided that the following conditions 8 ** are met: 9 ** 1. Redistributions of source code must retain the above copyright 10 ** notice, this list of conditions, and the following disclaimer. 11 ** 2. Redistributions in binary form must reproduce the above copyright 12 ** notice, this list of conditions, and the following disclaimer in the 13 ** documentation and/or other materials provided with the distribution. 14 ** 3. The name of the author may not be used to endorse or promote products 15 ** derived from this software without specific prior written permission. 16 ** 17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 e* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <dlfcn.h> 32 #include <blt/qsem.h> 33 #include <blt/network/eth.h> 34 #include <blt/network/mbuf.h> 35 #include <blt/network/module.h> 36 37 eth_drv_t *drvlist = NULL; 38 eth_dev_t *devlist = NULL; 39 eth_prot_t *protlist = NULL; 40 41 static qsem_t *eth_input_lock_sem, *eth_input_length_sem; 42 static qsem_t *eth_output_lock_sem, *eth_output_length_sem; 43 static struct mbuf *eth_input_queue = NULL, *eth_output_queue = NULL; 44 static void eth_input_thread (void); 45 static void eth_output_thread (void); 46 47 int _init (void) 48 { 49 eth_input_lock_sem = qsem_create (1); 50 eth_input_length_sem = qsem_create (0); 51 thr_create (eth_input_thread, 0, "network:eth:input"); 52 eth_output_lock_sem = qsem_create (1); 53 eth_output_length_sem = qsem_create (0); 54 thr_create (eth_output_thread, 0, "network:eth:output"); 55 return 1; 56 } 57 58 void _fini (void) 59 { 60 } 61 62 void register_eth_driver (eth_drv_t *drv) 63 { 64 drv->next = drvlist; 65 drvlist = drv; 66 } 67 68 void unregister_eth_driver (eth_drv_t *drv) 69 { 70 } 71 72 void register_eth_device (eth_dev_t *dev) 73 { 74 dev->next = devlist; 75 devlist = dev; 76 } 77 78 void unregister_eth_device (eth_dev_t *dev) 79 { 80 } 81 82 void register_eth_protocol (eth_prot_t *prot) 83 { 84 prot->next = protlist; 85 protlist = prot; 86 } 87 88 void unregister_eth_protocol (eth_prot_t *prot) 89 { 90 } 91 92 void eth_input (struct mbuf *mbuf) 93 { 94 struct mbuf *m; 95 96 qsem_acquire (eth_input_lock_sem); 97 if (eth_input_queue == NULL) 98 { 99 eth_input_queue = mbuf; 100 mbuf->m_nextpkt = NULL; 101 } 102 else 103 { 104 m = eth_input_queue; 105 while (m->m_nextpkt != NULL) 106 m = m->m_nextpkt; 107 m->m_nextpkt = mbuf; 108 } 109 qsem_release (eth_input_lock_sem); 110 qsem_release (eth_input_length_sem); 111 } 112 113 static void eth_input_thread (void) 114 { 115 struct mbuf *mbuf, *mbuf_header; 116 eth_prot_t *prot; 117 ether_header *header; 118 119 for (;;) 120 { 121 qsem_acquire (eth_input_length_sem); 122 qsem_acquire (eth_input_lock_sem); 123 mbuf_header = eth_input_queue; 124 eth_input_queue = eth_input_queue->m_nextpkt; 125 qsem_release (eth_input_lock_sem); 126 127 mbuf = mbuf_header->m_next; 128 header = (ether_header *) mbuf->m_data; 129 #if 0 130 printf ("eth_input_thread prot: %x src: %X:%X:%X:%X:%X:%X dst: " 131 "%X:%X:%X:%X:%X:%X\n", header->frame_type, header->src[0], 132 header->src[1], header->src[2], header->src[3], header->src[4], 133 header->src[5], header->dst[0], header->dst[1], header->dst[2], 134 header->dst[3], header->dst[4], header->dst[5]); 135 #endif 136 prot = protlist; 137 while (prot != NULL) 138 if (prot->num == header->frame_type) 139 { 140 prot->input (mbuf_header); 141 break; 142 } 143 else 144 prot = prot->next; 145 } 146 } 147 148 void eth_output (struct mbuf *mbuf) 149 { 150 struct mbuf *m; 151 152 qsem_acquire (eth_output_lock_sem); 153 if (eth_output_queue == NULL) 154 { 155 eth_output_queue = mbuf; 156 mbuf->m_nextpkt = NULL; 157 } 158 else 159 { 160 m = eth_output_queue; 161 while (m->m_nextpkt != NULL) 162 m = m->m_nextpkt; 163 m->m_nextpkt = mbuf; 164 } 165 qsem_release (eth_output_lock_sem); 166 qsem_release (eth_output_length_sem); 167 } 168 169 static void eth_output_thread (void) 170 { 171 struct mbuf *mbuf; 172 173 for (;;) 174 { 175 qsem_acquire (eth_output_length_sem); 176 qsem_acquire (eth_output_lock_sem); 177 mbuf = eth_output_queue; 178 eth_output_queue = eth_input_queue->m_nextpkt; 179 qsem_release (eth_output_lock_sem); 180 printf ("eth_output_thread\n"); 181 } 182 } 183 184 void eth_config (eth_dev_t *dev, const char *prot, int state, const char *data) 185 { 186 char *devname; 187 int len; 188 int (*config_up)(const char *, void (*)(struct mbuf *), const char *); 189 module_t *mod; 190 191 mod = modlist; 192 while (mod != NULL) 193 if (!strcmp (mod->name, prot)) 194 { 195 printf ("network: %s%d: interface %s, ", dev->dev_driver->name, 196 dev->dev_num, state ? "up" : "down"); 197 devname = malloc (len = 16); 198 snprintf (devname, len, "%s%d", dev->dev_driver->name, 199 dev->dev_num); 200 config_up = dlsym (mod->handle, "ipv4_config_up"); /* XXX */ 201 if (config_up != NULL) 202 (*config_up) (devname, eth_output, data); 203 return; 204 } 205 else 206 mod = mod->next; 207 printf ("network: %s%d: unknown protocol %s\n", dev->dev_driver->name, 208 dev->dev_num, prot); 209 } 210