Changeset 89c57b6 in mainline for uspace/srv/net/nil/eth/eth.c
- Timestamp:
- 2011-04-13T14:45:41Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 88634420
- Parents:
- cefb126 (diff), 17279ead (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/nil/eth/eth.c
rcefb126 r89c57b6 40 40 #include <mem.h> 41 41 #include <stdio.h> 42 #include <byteorder.h> 42 43 #include <str.h> 43 44 #include <ipc/ipc.h> 44 #include <errno.h> 45 #include <ipc/nil.h> 46 #include <ipc/net.h> 45 47 #include <ipc/services.h> 46 47 #include <net_err.h> 48 #include <net_messages.h> 49 #include <net_modules.h> 50 #include <net_byteorder.h> 48 #include <net/modules.h> 51 49 #include <net_checksum.h> 52 50 #include <ethernet_lsap.h> 53 51 #include <ethernet_protocols.h> 54 52 #include <protocol_map.h> 55 #include <net _device.h>56 #include <netif_ interface.h>53 #include <net/device.h> 54 #include <netif_remote.h> 57 55 #include <net_interface.h> 58 #include <nil_interface.h> 59 #include <il_interface.h> 56 #include <il_remote.h> 60 57 #include <adt/measured_strings.h> 61 #include <packet /packet_client.h>58 #include <packet_client.h> 62 59 #include <packet_remote.h> 63 #include <nil_ local.h>60 #include <nil_skel.h> 64 61 65 62 #include "eth.h" 66 #include "eth_header.h" 67 68 /** The module name. 69 */ 63 64 /** The module name. */ 70 65 #define NAME "eth" 71 66 72 /** Reserved packet prefix length. 73 */ 74 #define ETH_PREFIX (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t)) 75 76 /** Reserved packet suffix length. 77 */ 78 #define ETH_SUFFIX sizeof(eth_fcs_t) 79 80 /** Maximum packet content length. 81 */ 82 #define ETH_MAX_CONTENT 1500u 83 84 /** Minimum packet content length. 85 */ 86 #define ETH_MIN_CONTENT 46u 87 88 /** Maximum tagged packet content length. 89 */ 90 #define ETH_MAX_TAGGED_CONTENT(flags) (ETH_MAX_CONTENT - ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? sizeof(eth_header_lsap_t) : 0) - (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 91 92 /** Minimum tagged packet content length. 93 */ 94 #define ETH_MIN_TAGGED_CONTENT(flags) (ETH_MIN_CONTENT - ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? sizeof(eth_header_lsap_t) : 0) - (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 95 96 /** Dummy flag shift value. 97 */ 98 #define ETH_DUMMY_SHIFT 0 99 100 /** Mode flag shift value. 101 */ 102 #define ETH_MODE_SHIFT 1 67 /** Reserved packet prefix length. */ 68 #define ETH_PREFIX \ 69 (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + \ 70 sizeof(eth_header_snap_t)) 71 72 /** Reserved packet suffix length. */ 73 #define ETH_SUFFIX (sizeof(eth_fcs_t)) 74 75 /** Maximum packet content length. */ 76 #define ETH_MAX_CONTENT 1500u 77 78 /** Minimum packet content length. */ 79 #define ETH_MIN_CONTENT 46u 80 81 /** Maximum tagged packet content length. */ 82 #define ETH_MAX_TAGGED_CONTENT(flags) \ 83 (ETH_MAX_CONTENT - \ 84 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 85 sizeof(eth_header_lsap_t) : 0) - \ 86 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 87 88 /** Minimum tagged packet content length. */ 89 #define ETH_MIN_TAGGED_CONTENT(flags) \ 90 (ETH_MIN_CONTENT - \ 91 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 92 sizeof(eth_header_lsap_t) : 0) - \ 93 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 94 95 /** Dummy flag shift value. */ 96 #define ETH_DUMMY_SHIFT 0 97 98 /** Mode flag shift value. */ 99 #define ETH_MODE_SHIFT 1 103 100 104 101 /** Dummy device flag. 105 * 106 */ 107 #define ETH_DUMMY 102 * Preamble and FCS are mandatory part of the packets. 103 */ 104 #define ETH_DUMMY (1 << ETH_DUMMY_SHIFT) 108 105 109 106 /** Returns the dummy flag. 110 * 111 */ 112 #define IS_DUMMY(flags) ((flags) Ð_DUMMY)107 * @see ETH_DUMMY 108 */ 109 #define IS_DUMMY(flags) ((flags) & ETH_DUMMY) 113 110 114 111 /** Device mode flags. 115 * @see ETH_DIX 116 * @see ETH_8023_2_LSAP 117 * @see ETH_8023_2_SNAP 118 */ 119 #define ETH_MODE_MASK (3 << ETH_MODE_SHIFT) 120 121 /** DIX Ethernet mode flag. 122 */ 123 #define ETH_DIX (1 << ETH_MODE_SHIFT) 124 125 /** Returns whether the DIX Ethernet mode flag is set. 126 * @param[in] flags The ethernet flags. 127 * @see ETH_DIX 128 */ 129 #define IS_DIX(flags) (((flags) Ð_MODE_MASK) == ETH_DIX) 130 131 /** 802.3 + 802.2 + LSAP mode flag. 132 */ 133 #define ETH_8023_2_LSAP (2 << ETH_MODE_SHIFT) 134 135 /** Returns whether the 802.3 + 802.2 + LSAP mode flag is set. 136 * @param[in] flags The ethernet flags. 137 * @see ETH_8023_2_LSAP 138 */ 139 #define IS_8023_2_LSAP(flags) (((flags) Ð_MODE_MASK) == ETH_8023_2_LSAP) 140 141 /** 802.3 + 802.2 + LSAP + SNAP mode flag. 142 */ 143 #define ETH_8023_2_SNAP (3 << ETH_MODE_SHIFT) 144 145 /** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. 146 * @param[in] flags The ethernet flags. 147 * @see ETH_8023_2_SNAP 148 */ 149 #define IS_8023_2_SNAP(flags) (((flags) Ð_MODE_MASK) == ETH_8023_2_SNAP) 112 * @see ETH_DIX 113 * @see ETH_8023_2_LSAP 114 * @see ETH_8023_2_SNAP 115 */ 116 #define ETH_MODE_MASK (3 << ETH_MODE_SHIFT) 117 118 /** DIX Ethernet mode flag. */ 119 #define ETH_DIX (1 << ETH_MODE_SHIFT) 120 121 /** Return whether the DIX Ethernet mode flag is set. 122 * 123 * @param[in] flags Ethernet flags. 124 * @see ETH_DIX 125 * 126 */ 127 #define IS_DIX(flags) (((flags) & ETH_MODE_MASK) == ETH_DIX) 128 129 /** 802.3 + 802.2 + LSAP mode flag. */ 130 #define ETH_8023_2_LSAP (2 << ETH_MODE_SHIFT) 131 132 /** Return whether the 802.3 + 802.2 + LSAP mode flag is set. 133 * 134 * @param[in] flags Ethernet flags. 135 * @see ETH_8023_2_LSAP 136 * 137 */ 138 #define IS_8023_2_LSAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP) 139 140 /** 802.3 + 802.2 + LSAP + SNAP mode flag. */ 141 #define ETH_8023_2_SNAP (3 << ETH_MODE_SHIFT) 142 143 /** Return whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. 144 * 145 * @param[in] flags Ethernet flags. 146 * @see ETH_8023_2_SNAP 147 * 148 */ 149 #define IS_8023_2_SNAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP) 150 150 151 151 /** Type definition of the ethernet address type. 152 * @see eth_addr_type 153 */ 154 typedef enum eth_addr_type eth_addr_type_t; 155 156 /** Type definition of the ethernet address type pointer. 157 * @see eth_addr_type 158 */ 159 typedef eth_addr_type_t * eth_addr_type_ref; 160 161 /** Ethernet address type. 162 */ 163 enum eth_addr_type{ 164 /** Local address. 165 */ 152 * @see eth_addr_type 153 */ 154 typedef enum eth_addr_type eth_addr_type_t; 155 156 /** Ethernet address type. */ 157 enum eth_addr_type { 158 /** Local address. */ 166 159 ETH_LOCAL_ADDR, 167 /** Broadcast address. 168 */ 160 /** Broadcast address. */ 169 161 ETH_BROADCAST_ADDR 170 162 }; 171 163 172 /** Ethernet module global data. 173 */ 174 eth_globals_t eth_globals; 175 176 /** @name Message processing functions 177 */ 178 /*@{*/ 179 180 /** Processes IPC messages from the registered device driver modules in an infinite loop. 181 * @param[in] iid The message identifier. 182 * @param[in,out] icall The message parameters. 183 */ 184 void eth_receiver(ipc_callid_t iid, ipc_call_t * icall); 185 186 /** Registers new device or updates the MTU of an existing one. 187 * Determines the device local hardware address. 188 * @param[in] device_id The new device identifier. 189 * @param[in] service The device driver service. 190 * @param[in] mtu The device maximum transmission unit. 191 * @returns EOK on success. 192 * @returns EEXIST if the device with the different service exists. 193 * @returns ENOMEM if there is not enough memory left. 194 * @returns Other error codes as defined for the net_get_device_conf_req() function. 195 * @returns Other error codes as defined for the netif_bind_service() function. 196 * @returns Other error codes as defined for the netif_get_addr_req() function. 197 */ 198 int eth_device_message(device_id_t device_id, services_t service, size_t mtu); 199 200 /** Registers receiving module service. 201 * Passes received packets for this service. 202 * @param[in] service The module service. 203 * @param[in] phone The service phone. 204 * @returns EOK on success. 205 * @returns ENOENT if the service is not known. 206 * @returns ENOMEM if there is not enough memory left. 207 */ 208 int eth_register_message(services_t service, int phone); 209 210 /** Returns the device packet dimensions for sending. 211 * @param[in] device_id The device identifier. 212 * @param[out] addr_len The minimum reserved address length. 213 * @param[out] prefix The minimum reserved prefix size. 214 * @param[out] content The maximum content size. 215 * @param[out] suffix The minimum reserved suffix size. 216 * @returns EOK on success. 217 * @returns EBADMEM if either one of the parameters is NULL. 218 * @returns ENOENT if there is no such device. 219 */ 220 int eth_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix); 221 222 /** Returns the device hardware address. 223 * @param[in] device_id The device identifier. 224 * @param[in] type Type of the desired address. 225 * @param[out] address The device hardware address. 226 * @returns EOK on success. 227 * @returns EBADMEM if the address parameter is NULL. 228 * @returns ENOENT if there no such device. 229 */ 230 int eth_addr_message(device_id_t device_id, eth_addr_type_t type, measured_string_ref * address); 231 232 /** Sends the packet queue. 233 * Sends only packet successfully processed by the eth_prepare_packet() function. 234 * @param[in] device_id The device identifier. 235 * @param[in] packet The packet queue. 236 * @param[in] sender The sending module service. 237 * @returns EOK on success. 238 * @returns ENOENT if there no such device. 239 * @returns EINVAL if the service parameter is not known. 240 */ 241 int eth_send_message(device_id_t device_id, packet_t packet, services_t sender); 242 243 /*@}*/ 244 245 /** Processes the received packet and chooses the target registered module. 246 * @param[in] flags The device flags. 247 * @param[in] packet The packet. 248 * @returns The target registered module. 249 * @returns NULL if the packet is not long enough. 250 * @returns NULL if the packet is too long. 251 * @returns NULL if the raw ethernet protocol is used. 252 * @returns NULL if the dummy device FCS checksum is invalid. 253 * @returns NULL if the packet address length is not big enough. 254 */ 255 eth_proto_ref eth_process_packet(int flags, packet_t packet); 256 257 /** Prepares the packet for sending. 258 * @param[in] flags The device flags. 259 * @param[in] packet The packet. 260 * @param[in] src_addr The source hardware address. 261 * @param[in] ethertype The ethernet protocol type. 262 * @param[in] mtu The device maximum transmission unit. 263 * @returns EOK on success. 264 * @returns EINVAL if the packet addresses length is not long enough. 265 * @returns EINVAL if the packet is bigger than the device MTU. 266 * @returns ENOMEM if there is not enough memory in the packet. 267 */ 268 int eth_prepare_packet(int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu); 269 270 DEVICE_MAP_IMPLEMENT(eth_devices, eth_device_t) 271 272 INT_MAP_IMPLEMENT(eth_protos, eth_proto_t) 273 274 int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state){ 164 /** Ethernet module global data. */ 165 eth_globals_t eth_globals; 166 167 DEVICE_MAP_IMPLEMENT(eth_devices, eth_device_t); 168 INT_MAP_IMPLEMENT(eth_protos, eth_proto_t); 169 170 int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state) 171 { 275 172 int index; 276 eth_proto_ refproto;173 eth_proto_t *proto; 277 174 278 175 fibril_rwlock_read_lock(ð_globals.protos_lock); 279 for(index = eth_protos_count(ð_globals.protos) - 1; index >= 0; -- index){ 176 for (index = eth_protos_count(ð_globals.protos) - 1; index >= 0; 177 index--) { 280 178 proto = eth_protos_get_index(ð_globals.protos, index); 281 if(proto && proto->phone){ 282 il_device_state_msg(proto->phone, device_id, state, proto->service); 179 if (proto && proto->phone) { 180 il_device_state_msg(proto->phone, device_id, state, 181 proto->service); 283 182 } 284 183 } 285 184 fibril_rwlock_read_unlock(ð_globals.protos_lock); 185 286 186 return EOK; 287 187 } 288 188 289 int nil_initialize(int net_phone){ 290 ERROR_DECLARE; 189 int nil_initialize(int net_phone) 190 { 191 int rc; 291 192 292 193 fibril_rwlock_initialize(ð_globals.devices_lock); 293 194 fibril_rwlock_initialize(ð_globals.protos_lock); 195 294 196 fibril_rwlock_write_lock(ð_globals.devices_lock); 295 197 fibril_rwlock_write_lock(ð_globals.protos_lock); 296 198 eth_globals.net_phone = net_phone; 297 eth_globals.broadcast_addr = measured_string_create_bulk("\xFF\xFF\xFF\xFF\xFF\xFF", CONVERT_SIZE(uint8_t, char, ETH_ADDR)); 298 if(! eth_globals.broadcast_addr){ 299 return ENOMEM; 300 } 301 ERROR_PROPAGATE(eth_devices_initialize(ð_globals.devices)); 302 if(ERROR_OCCURRED(eth_protos_initialize(ð_globals.protos))){ 303 eth_devices_destroy(ð_globals.devices); 304 return ERROR_CODE; 305 } 199 200 eth_globals.broadcast_addr = 201 measured_string_create_bulk((uint8_t *) "\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ADDR); 202 if (!eth_globals.broadcast_addr) { 203 rc = ENOMEM; 204 goto out; 205 } 206 207 rc = eth_devices_initialize(ð_globals.devices); 208 if (rc != EOK) { 209 free(eth_globals.broadcast_addr); 210 goto out; 211 } 212 213 rc = eth_protos_initialize(ð_globals.protos); 214 if (rc != EOK) { 215 free(eth_globals.broadcast_addr); 216 eth_devices_destroy(ð_globals.devices, free); 217 } 218 out: 306 219 fibril_rwlock_write_unlock(ð_globals.protos_lock); 307 220 fibril_rwlock_write_unlock(ð_globals.devices_lock); 308 return EOK; 309 } 310 311 int eth_device_message(device_id_t device_id, services_t service, size_t mtu){ 312 ERROR_DECLARE; 313 314 eth_device_ref device; 221 222 return rc; 223 } 224 225 /** Processes IPC messages from the registered device driver modules in an 226 * infinite loop. 227 * 228 * @param[in] iid The message identifier. 229 * @param[in,out] icall The message parameters. 230 */ 231 static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall) 232 { 233 packet_t *packet; 234 int rc; 235 236 while (true) { 237 switch (IPC_GET_IMETHOD(*icall)) { 238 case NET_NIL_DEVICE_STATE: 239 nil_device_state_msg_local(0, IPC_GET_DEVICE(*icall), 240 IPC_GET_STATE(*icall)); 241 async_answer_0(iid, EOK); 242 break; 243 case NET_NIL_RECEIVED: 244 rc = packet_translate_remote(eth_globals.net_phone, 245 &packet, IPC_GET_PACKET(*icall)); 246 if (rc == EOK) 247 rc = nil_received_msg_local(0, 248 IPC_GET_DEVICE(*icall), packet, 0); 249 250 async_answer_0(iid, (sysarg_t) rc); 251 break; 252 default: 253 async_answer_0(iid, (sysarg_t) ENOTSUP); 254 } 255 256 iid = async_get_call(icall); 257 } 258 } 259 260 /** Registers new device or updates the MTU of an existing one. 261 * 262 * Determines the device local hardware address. 263 * 264 * @param[in] device_id The new device identifier. 265 * @param[in] service The device driver service. 266 * @param[in] mtu The device maximum transmission unit. 267 * @return EOK on success. 268 * @return EEXIST if the device with the different service exists. 269 * @return ENOMEM if there is not enough memory left. 270 * @return Other error codes as defined for the 271 * net_get_device_conf_req() function. 272 * @return Other error codes as defined for the 273 * netif_bind_service() function. 274 * @return Other error codes as defined for the 275 * netif_get_addr_req() function. 276 */ 277 static int eth_device_message(device_id_t device_id, services_t service, 278 size_t mtu) 279 { 280 eth_device_t *device; 315 281 int index; 316 measured_string_t names[2] = {{str_dup("ETH_MODE"), 8}, {str_dup("ETH_DUMMY"), 9}}; 317 measured_string_ref configuration; 282 measured_string_t names[2] = { 283 { 284 (uint8_t *) "ETH_MODE", 285 8 286 }, 287 { 288 (uint8_t *) "ETH_DUMMY", 289 9 290 } 291 }; 292 measured_string_t *configuration; 318 293 size_t count = sizeof(names) / sizeof(measured_string_t); 319 char * data; 320 eth_proto_ref proto; 294 uint8_t *data; 295 eth_proto_t *proto; 296 int rc; 321 297 322 298 fibril_rwlock_write_lock(ð_globals.devices_lock); 323 / / an existing device?299 /* An existing device? */ 324 300 device = eth_devices_find(ð_globals.devices, device_id); 325 if (device){326 if (device->service != service){301 if (device) { 302 if (device->service != service) { 327 303 printf("Device %d already exists\n", device->device_id); 328 304 fibril_rwlock_write_unlock(ð_globals.devices_lock); 329 305 return EEXIST; 330 }else{ 331 // update mtu 332 if((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))){ 333 device->mtu = mtu; 334 }else{ 335 device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags); 306 } 307 308 /* Update mtu */ 309 if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))) 310 device->mtu = mtu; 311 else 312 device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags); 313 314 printf("Device %d already exists:\tMTU\t= %zu\n", 315 device->device_id, device->mtu); 316 fibril_rwlock_write_unlock(ð_globals.devices_lock); 317 318 /* Notify all upper layer modules */ 319 fibril_rwlock_read_lock(ð_globals.protos_lock); 320 for (index = 0; index < eth_protos_count(ð_globals.protos); 321 index++) { 322 proto = eth_protos_get_index(ð_globals.protos, 323 index); 324 if (proto->phone) { 325 il_mtu_changed_msg(proto->phone, 326 device->device_id, device->mtu, 327 proto->service); 336 328 } 337 printf("Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu); 338 fibril_rwlock_write_unlock(ð_globals.devices_lock); 339 // notify all upper layer modules 340 fibril_rwlock_read_lock(ð_globals.protos_lock); 341 for(index = 0; index < eth_protos_count(ð_globals.protos); ++ index){ 342 proto = eth_protos_get_index(ð_globals.protos, index); 343 if (proto->phone){ 344 il_mtu_changed_msg(proto->phone, device->device_id, device->mtu, proto->service); 345 } 346 } 347 fibril_rwlock_read_unlock(ð_globals.protos_lock); 348 return EOK; 349 } 350 }else{ 351 // create a new device 352 device = (eth_device_ref) malloc(sizeof(eth_device_t)); 353 if(! device){ 354 return ENOMEM; 355 } 356 device->device_id = device_id; 357 device->service = service; 358 device->flags = 0; 359 if((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))){ 360 device->mtu = mtu; 361 }else{ 362 device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags); 363 } 364 configuration = &names[0]; 365 if(ERROR_OCCURRED(net_get_device_conf_req(eth_globals.net_phone, device->device_id, &configuration, count, &data))){ 366 fibril_rwlock_write_unlock(ð_globals.devices_lock); 367 free(device); 368 return ERROR_CODE; 369 } 370 if(configuration){ 371 if(! str_lcmp(configuration[0].value, "DIX", configuration[0].length)){ 372 device->flags |= ETH_DIX; 373 }else if(! str_lcmp(configuration[0].value, "8023_2_LSAP", configuration[0].length)){ 374 device->flags |= ETH_8023_2_LSAP; 375 }else device->flags |= ETH_8023_2_SNAP; 376 if((configuration[1].value) && (configuration[1].value[0] == 'y')){ 377 device->flags |= ETH_DUMMY; 378 } 379 net_free_settings(configuration, data); 380 }else{ 329 } 330 331 fibril_rwlock_read_unlock(ð_globals.protos_lock); 332 return EOK; 333 } 334 335 /* Create a new device */ 336 device = (eth_device_t *) malloc(sizeof(eth_device_t)); 337 if (!device) 338 return ENOMEM; 339 340 device->device_id = device_id; 341 device->service = service; 342 device->flags = 0; 343 if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))) 344 device->mtu = mtu; 345 else 346 device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags); 347 348 configuration = &names[0]; 349 rc = net_get_device_conf_req(eth_globals.net_phone, device->device_id, 350 &configuration, count, &data); 351 if (rc != EOK) { 352 fibril_rwlock_write_unlock(ð_globals.devices_lock); 353 free(device); 354 return rc; 355 } 356 357 if (configuration) { 358 if (!str_lcmp((char *) configuration[0].value, "DIX", 359 configuration[0].length)) { 360 device->flags |= ETH_DIX; 361 } else if(!str_lcmp((char *) configuration[0].value, "8023_2_LSAP", 362 configuration[0].length)) { 363 device->flags |= ETH_8023_2_LSAP; 364 } else { 381 365 device->flags |= ETH_8023_2_SNAP; 382 366 } 383 // bind the device driver 384 device->phone = netif_bind_service(device->service, device->device_id, SERVICE_ETHERNET, eth_receiver); 385 if(device->phone < 0){ 386 fibril_rwlock_write_unlock(ð_globals.devices_lock); 387 free(device); 388 return device->phone; 389 } 390 // get hardware address 391 if(ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, &device->addr, &device->addr_data))){ 392 fibril_rwlock_write_unlock(ð_globals.devices_lock); 393 free(device); 394 return ERROR_CODE; 395 } 396 // add to the cache 397 index = eth_devices_add(ð_globals.devices, device->device_id, device); 398 if(index < 0){ 399 fibril_rwlock_write_unlock(ð_globals.devices_lock); 400 free(device->addr); 401 free(device->addr_data); 402 free(device); 403 return index; 404 } 405 printf("%s: Device registered (id: %d, service: %d: mtu: %d, " 406 "mac: %x:%x:%x:%x:%x:%x, flags: 0x%x)\n", 407 NAME, device->device_id, device->service, device->mtu, 408 device->addr_data[0], device->addr_data[1], 409 device->addr_data[2], device->addr_data[3], 410 device->addr_data[4], device->addr_data[5], device->flags); 411 } 367 368 if (configuration[1].value && 369 (configuration[1].value[0] == 'y')) { 370 device->flags |= ETH_DUMMY; 371 } 372 net_free_settings(configuration, data); 373 } else { 374 device->flags |= ETH_8023_2_SNAP; 375 } 376 377 /* Bind the device driver */ 378 device->phone = netif_bind_service(device->service, device->device_id, 379 SERVICE_ETHERNET, eth_receiver); 380 if (device->phone < 0) { 381 fibril_rwlock_write_unlock(ð_globals.devices_lock); 382 free(device); 383 return device->phone; 384 } 385 386 /* Get hardware address */ 387 rc = netif_get_addr_req(device->phone, device->device_id, &device->addr, 388 &device->addr_data); 389 if (rc != EOK) { 390 fibril_rwlock_write_unlock(ð_globals.devices_lock); 391 free(device); 392 return rc; 393 } 394 395 /* Add to the cache */ 396 index = eth_devices_add(ð_globals.devices, device->device_id, 397 device); 398 if (index < 0) { 399 fibril_rwlock_write_unlock(ð_globals.devices_lock); 400 free(device->addr); 401 free(device->addr_data); 402 free(device); 403 return index; 404 } 405 406 printf("%s: Device registered (id: %d, service: %d: mtu: %zu, " 407 "mac: %02x:%02x:%02x:%02x:%02x:%02x, flags: 0x%x)\n", 408 NAME, device->device_id, device->service, device->mtu, 409 device->addr_data[0], device->addr_data[1], 410 device->addr_data[2], device->addr_data[3], 411 device->addr_data[4], device->addr_data[5], device->flags); 412 412 413 fibril_rwlock_write_unlock(ð_globals.devices_lock); 413 414 return EOK; 414 415 } 415 416 416 eth_proto_ref eth_process_packet(int flags, packet_t packet){ 417 ERROR_DECLARE; 418 419 eth_header_snap_ref header; 417 /** Processes the received packet and chooses the target registered module. 418 * 419 * @param[in] flags The device flags. 420 * @param[in] packet The packet. 421 * @return The target registered module. 422 * @return NULL if the packet is not long enough. 423 * @return NULL if the packet is too long. 424 * @return NULL if the raw ethernet protocol is used. 425 * @return NULL if the dummy device FCS checksum is invalid. 426 * @return NULL if the packet address length is not big enough. 427 */ 428 static eth_proto_t *eth_process_packet(int flags, packet_t *packet) 429 { 430 eth_header_snap_t *header; 420 431 size_t length; 421 432 eth_type_t type; 422 433 size_t prefix; 423 434 size_t suffix; 424 eth_fcs_ref fcs; 425 uint8_t * data; 435 eth_fcs_t *fcs; 436 uint8_t *data; 437 int rc; 426 438 427 439 length = packet_get_data_length(packet); 428 if(IS_DUMMY(flags)){ 440 441 if (IS_DUMMY(flags)) 429 442 packet_trim(packet, sizeof(eth_preamble_t), 0); 430 } 431 if(length < sizeof(eth_header_t) + ETH_MIN_CONTENT + (IS_DUMMY(flags) ? ETH_SUFFIX : 0)) return NULL; 443 if (length < sizeof(eth_header_t) + ETH_MIN_CONTENT + 444 (IS_DUMMY(flags) ? ETH_SUFFIX : 0)) 445 return NULL; 446 432 447 data = packet_get_data(packet); 433 header = (eth_header_snap_ ref) data;448 header = (eth_header_snap_t *) data; 434 449 type = ntohs(header->header.ethertype); 435 if(type >= ETH_MIN_PROTO){ 436 // DIX Ethernet 450 451 if (type >= ETH_MIN_PROTO) { 452 /* DIX Ethernet */ 437 453 prefix = sizeof(eth_header_t); 438 454 suffix = 0; 439 fcs = (eth_fcs_ ref) data + length - sizeof(eth_fcs_t);455 fcs = (eth_fcs_t *) data + length - sizeof(eth_fcs_t); 440 456 length -= sizeof(eth_fcs_t); 441 } else if(type <= ETH_MAX_CONTENT){442 / / translate "LSAP" values443 if ((header->lsap.dsap == ETH_LSAP_GLSAP) && (header->lsap.ssap == ETH_LSAP_GLSAP)){444 // raw packet445 / / discard457 } else if(type <= ETH_MAX_CONTENT) { 458 /* Translate "LSAP" values */ 459 if ((header->lsap.dsap == ETH_LSAP_GLSAP) && 460 (header->lsap.ssap == ETH_LSAP_GLSAP)) { 461 /* Raw packet -- discard */ 446 462 return NULL; 447 }else if((header->lsap.dsap == ETH_LSAP_SNAP) && (header->lsap.ssap == ETH_LSAP_SNAP)){ 448 // IEEE 802.3 + 802.2 + LSAP + SNAP 449 // organization code not supported 463 } else if((header->lsap.dsap == ETH_LSAP_SNAP) && 464 (header->lsap.ssap == ETH_LSAP_SNAP)) { 465 /* 466 * IEEE 802.3 + 802.2 + LSAP + SNAP 467 * organization code not supported 468 */ 450 469 type = ntohs(header->snap.ethertype); 451 prefix = sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t); 452 }else{ 453 // IEEE 802.3 + 802.2 LSAP 470 prefix = sizeof(eth_header_t) + 471 sizeof(eth_header_lsap_t) + 472 sizeof(eth_header_snap_t); 473 } else { 474 /* IEEE 802.3 + 802.2 LSAP */ 454 475 type = lsap_map(header->lsap.dsap); 455 prefix = sizeof(eth_header_t) + sizeof(eth_header_lsap_t); 456 } 457 suffix = (type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0u; 458 fcs = (eth_fcs_ref) data + prefix + type + suffix; 476 prefix = sizeof(eth_header_t) + 477 sizeof(eth_header_lsap_t); 478 } 479 480 suffix = (type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0U; 481 fcs = (eth_fcs_t *) data + prefix + type + suffix; 459 482 suffix += length - prefix - type; 460 483 length = prefix + type + suffix; 461 } else{462 / / invalid length/type, should not occurr484 } else { 485 /* Invalid length/type, should not occur */ 463 486 return NULL; 464 487 } 465 if(IS_DUMMY(flags)){ 466 if((~ compute_crc32(~ 0u, data, length * 8)) != ntohl(*fcs)){ 488 489 if (IS_DUMMY(flags)) { 490 if (~compute_crc32(~0U, data, length * 8) != ntohl(*fcs)) 467 491 return NULL; 468 }469 492 suffix += sizeof(eth_fcs_t); 470 493 } 471 if(ERROR_OCCURRED(packet_set_addr(packet, header->header.source_address, header->header.destination_address, ETH_ADDR)) 472 || ERROR_OCCURRED(packet_trim(packet, prefix, suffix))){ 494 495 rc = packet_set_addr(packet, header->header.source_address, 496 header->header.destination_address, ETH_ADDR); 497 if (rc != EOK) 473 498 return NULL; 474 } 499 500 rc = packet_trim(packet, prefix, suffix); 501 if (rc != EOK) 502 return NULL; 503 475 504 return eth_protos_find(ð_globals.protos, type); 476 505 } 477 506 478 int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){ 479 eth_proto_ref proto; 480 packet_t next; 481 eth_device_ref device; 507 int nil_received_msg_local(int nil_phone, device_id_t device_id, 508 packet_t *packet, services_t target) 509 { 510 eth_proto_t *proto; 511 packet_t *next; 512 eth_device_t *device; 482 513 int flags; 483 514 484 515 fibril_rwlock_read_lock(ð_globals.devices_lock); 485 516 device = eth_devices_find(ð_globals.devices, device_id); 486 if (! device){517 if (!device) { 487 518 fibril_rwlock_read_unlock(ð_globals.devices_lock); 488 519 return ENOENT; 489 520 } 521 490 522 flags = device->flags; 491 523 fibril_rwlock_read_unlock(ð_globals.devices_lock); 524 492 525 fibril_rwlock_read_lock(ð_globals.protos_lock); 493 do {526 do { 494 527 next = pq_detach(packet); 495 528 proto = eth_process_packet(flags, packet); 496 if(proto){ 497 il_received_msg(proto->phone, device_id, packet, proto->service); 498 }else{ 499 // drop invalid/unknown 500 pq_release_remote(eth_globals.net_phone, packet_get_id(packet)); 529 if (proto) { 530 il_received_msg(proto->phone, device_id, packet, 531 proto->service); 532 } else { 533 /* Drop invalid/unknown */ 534 pq_release_remote(eth_globals.net_phone, 535 packet_get_id(packet)); 501 536 } 502 537 packet = next; 503 }while(packet); 538 } while(packet); 539 504 540 fibril_rwlock_read_unlock(ð_globals.protos_lock); 505 541 return EOK; 506 542 } 507 543 508 int eth_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){ 509 eth_device_ref device; 510 511 if(!(addr_len && prefix && content && suffix)){ 544 /** Returns the device packet dimensions for sending. 545 * 546 * @param[in] device_id The device identifier. 547 * @param[out] addr_len The minimum reserved address length. 548 * @param[out] prefix The minimum reserved prefix size. 549 * @param[out] content The maximum content size. 550 * @param[out] suffix The minimum reserved suffix size. 551 * @return EOK on success. 552 * @return EBADMEM if either one of the parameters is NULL. 553 * @return ENOENT if there is no such device. 554 */ 555 static int eth_packet_space_message(device_id_t device_id, size_t *addr_len, 556 size_t *prefix, size_t *content, size_t *suffix) 557 { 558 eth_device_t *device; 559 560 if (!addr_len || !prefix || !content || !suffix) 512 561 return EBADMEM; 513 }562 514 563 fibril_rwlock_read_lock(ð_globals.devices_lock); 515 564 device = eth_devices_find(ð_globals.devices, device_id); 516 if (! device){565 if (!device) { 517 566 fibril_rwlock_read_unlock(ð_globals.devices_lock); 518 567 return ENOENT; 519 568 } 569 520 570 *content = device->mtu; 521 571 fibril_rwlock_read_unlock(ð_globals.devices_lock); 572 522 573 *addr_len = ETH_ADDR; 523 574 *prefix = ETH_PREFIX; 524 575 *suffix = ETH_MIN_CONTENT + ETH_SUFFIX; 576 525 577 return EOK; 526 578 } 527 579 528 int eth_addr_message(device_id_t device_id, eth_addr_type_t type, measured_string_ref * address){ 529 eth_device_ref device; 530 531 if(! address){ 580 /** Returns the device hardware address. 581 * 582 * @param[in] device_id The device identifier. 583 * @param[in] type Type of the desired address. 584 * @param[out] address The device hardware address. 585 * @return EOK on success. 586 * @return EBADMEM if the address parameter is NULL. 587 * @return ENOENT if there no such device. 588 */ 589 static int eth_addr_message(device_id_t device_id, eth_addr_type_t type, 590 measured_string_t **address) 591 { 592 eth_device_t *device; 593 594 if (!address) 532 595 return EBADMEM; 533 } 534 if (type == ETH_BROADCAST_ADDR){596 597 if (type == ETH_BROADCAST_ADDR) { 535 598 *address = eth_globals.broadcast_addr; 536 } else{599 } else { 537 600 fibril_rwlock_read_lock(ð_globals.devices_lock); 538 601 device = eth_devices_find(ð_globals.devices, device_id); 539 if (! device){602 if (!device) { 540 603 fibril_rwlock_read_unlock(ð_globals.devices_lock); 541 604 return ENOENT; … … 544 607 fibril_rwlock_read_unlock(ð_globals.devices_lock); 545 608 } 609 546 610 return (*address) ? EOK : ENOENT; 547 611 } 548 612 549 int eth_register_message(services_t service, int phone){ 550 eth_proto_ref proto; 613 /** Registers receiving module service. 614 * 615 * Passes received packets for this service. 616 * 617 * @param[in] service The module service. 618 * @param[in] phone The service phone. 619 * @return EOK on success. 620 * @return ENOENT if the service is not known. 621 * @return ENOMEM if there is not enough memory left. 622 */ 623 static int eth_register_message(services_t service, int phone) 624 { 625 eth_proto_t *proto; 551 626 int protocol; 552 627 int index; 553 628 554 629 protocol = protocol_map(SERVICE_ETHERNET, service); 555 if (! protocol){630 if (!protocol) 556 631 return ENOENT; 557 } 632 558 633 fibril_rwlock_write_lock(ð_globals.protos_lock); 559 634 proto = eth_protos_find(ð_globals.protos, protocol); 560 if (proto){635 if (proto) { 561 636 proto->phone = phone; 562 637 fibril_rwlock_write_unlock(ð_globals.protos_lock); 563 638 return EOK; 564 } else{565 proto = (eth_proto_ ref) malloc(sizeof(eth_proto_t));566 if (! proto){639 } else { 640 proto = (eth_proto_t *) malloc(sizeof(eth_proto_t)); 641 if (!proto) { 567 642 fibril_rwlock_write_unlock(ð_globals.protos_lock); 568 643 return ENOMEM; 569 644 } 645 570 646 proto->service = service; 571 647 proto->protocol = protocol; 572 648 proto->phone = phone; 649 573 650 index = eth_protos_add(ð_globals.protos, protocol, proto); 574 if (index < 0){651 if (index < 0) { 575 652 fibril_rwlock_write_unlock(ð_globals.protos_lock); 576 653 free(proto); … … 579 656 } 580 657 581 printf("%s: Protocol registered (protocol: %d, service: %d, phone: %d)\n",582 NAME, proto->protocol, proto->service, proto->phone);658 printf("%s: Protocol registered (protocol: %d, service: %d, phone: " 659 "%d)\n", NAME, proto->protocol, proto->service, proto->phone); 583 660 584 661 fibril_rwlock_write_unlock(ð_globals.protos_lock); … … 586 663 } 587 664 588 int eth_prepare_packet(int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu){ 589 eth_header_snap_ref header; 590 eth_header_lsap_ref header_lsap; 591 eth_header_ref header_dix; 592 eth_fcs_ref fcs; 593 uint8_t * src; 594 uint8_t * dest; 665 /** Prepares the packet for sending. 666 * 667 * @param[in] flags The device flags. 668 * @param[in] packet The packet. 669 * @param[in] src_addr The source hardware address. 670 * @param[in] ethertype The ethernet protocol type. 671 * @param[in] mtu The device maximum transmission unit. 672 * @return EOK on success. 673 * @return EINVAL if the packet addresses length is not long 674 * enough. 675 * @return EINVAL if the packet is bigger than the device MTU. 676 * @return ENOMEM if there is not enough memory in the packet. 677 */ 678 static int 679 eth_prepare_packet(int flags, packet_t *packet, uint8_t *src_addr, int ethertype, 680 size_t mtu) 681 { 682 eth_header_snap_t *header; 683 eth_header_lsap_t *header_lsap; 684 eth_header_t *header_dix; 685 eth_fcs_t *fcs; 686 uint8_t *src; 687 uint8_t *dest; 595 688 size_t length; 596 689 int i; 597 void * 598 eth_preamble_ refpreamble;690 void *padding; 691 eth_preamble_t *preamble; 599 692 600 693 i = packet_get_addr(packet, &src, &dest); 601 if (i < 0){694 if (i < 0) 602 695 return i; 603 } 604 if(i != ETH_ADDR){ 696 if (i != ETH_ADDR) 605 697 return EINVAL; 606 } 698 607 699 length = packet_get_data_length(packet); 608 if (length > mtu){700 if (length > mtu) 609 701 return EINVAL; 610 } 611 if(length < ETH_MIN_TAGGED_CONTENT(flags)){ 612 padding = packet_suffix(packet, ETH_MIN_TAGGED_CONTENT(flags) - length); 613 if(! padding){ 702 703 if (length < ETH_MIN_TAGGED_CONTENT(flags)) { 704 padding = packet_suffix(packet, 705 ETH_MIN_TAGGED_CONTENT(flags) - length); 706 if (!padding) 614 707 return ENOMEM; 615 } 708 616 709 bzero(padding, ETH_MIN_TAGGED_CONTENT(flags) - length); 617 710 } 618 if(IS_DIX(flags)){ 711 712 if (IS_DIX(flags)) { 619 713 header_dix = PACKET_PREFIX(packet, eth_header_t); 620 if (! header_dix){714 if (!header_dix) 621 715 return ENOMEM; 622 }716 623 717 header_dix->ethertype = (uint16_t) ethertype; 624 718 memcpy(header_dix->source_address, src_addr, ETH_ADDR); 625 719 memcpy(header_dix->destination_address, dest, ETH_ADDR); 626 720 src = &header_dix->destination_address[0]; 627 } else if(IS_8023_2_LSAP(flags)){721 } else if(IS_8023_2_LSAP(flags)) { 628 722 header_lsap = PACKET_PREFIX(packet, eth_header_lsap_t); 629 if (! header_lsap){723 if (!header_lsap) 630 724 return ENOMEM; 631 } 632 header_lsap->header.ethertype = htons(length + sizeof(eth_header_lsap_t)); 725 726 header_lsap->header.ethertype = htons(length + 727 sizeof(eth_header_lsap_t)); 633 728 header_lsap->lsap.dsap = lsap_unmap(ntohs(ethertype)); 634 729 header_lsap->lsap.ssap = header_lsap->lsap.dsap; … … 637 732 memcpy(header_lsap->header.destination_address, dest, ETH_ADDR); 638 733 src = &header_lsap->header.destination_address[0]; 639 } else if(IS_8023_2_SNAP(flags)){734 } else if(IS_8023_2_SNAP(flags)) { 640 735 header = PACKET_PREFIX(packet, eth_header_snap_t); 641 if (! header){736 if (!header) 642 737 return ENOMEM; 643 } 644 header->header.ethertype = htons(length + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t)); 738 739 header->header.ethertype = htons(length + 740 sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t)); 645 741 header->lsap.dsap = (uint16_t) ETH_LSAP_SNAP; 646 742 header->lsap.ssap = header->lsap.dsap; 647 743 header->lsap.ctrl = IEEE_8023_2_UI; 648 for(i = 0; i < 3; ++ i){ 744 745 for (i = 0; i < 3; ++ i) 649 746 header->snap.protocol[i] = 0; 650 }747 651 748 header->snap.ethertype = (uint16_t) ethertype; 652 749 memcpy(header->header.source_address, src_addr, ETH_ADDR); … … 654 751 src = &header->header.destination_address[0]; 655 752 } 656 if(IS_DUMMY(flags)){ 753 754 if (IS_DUMMY(flags)) { 657 755 preamble = PACKET_PREFIX(packet, eth_preamble_t); 658 if (! preamble){756 if (!preamble) 659 757 return ENOMEM; 660 }661 for (i = 0; i < 7; ++ i){758 759 for (i = 0; i < 7; ++ i) 662 760 preamble->preamble[i] = ETH_PREAMBLE; 663 }761 664 762 preamble->sfd = ETH_SFD; 763 665 764 fcs = PACKET_SUFFIX(packet, eth_fcs_t); 666 if (! fcs){765 if (!fcs) 667 766 return ENOMEM; 668 } 669 *fcs = htonl(~ compute_crc32(~ 0u, src, length * 8)); 670 } 767 768 *fcs = htonl(~compute_crc32(~0U, src, length * 8)); 769 } 770 671 771 return EOK; 672 772 } 673 773 674 int eth_send_message(device_id_t device_id, packet_t packet, services_t sender){ 675 ERROR_DECLARE; 676 677 eth_device_ref device; 678 packet_t next; 679 packet_t tmp; 774 /** Sends the packet queue. 775 * 776 * Sends only packet successfully processed by the eth_prepare_packet() 777 * function. 778 * 779 * @param[in] device_id The device identifier. 780 * @param[in] packet The packet queue. 781 * @param[in] sender The sending module service. 782 * @return EOK on success. 783 * @return ENOENT if there no such device. 784 * @return EINVAL if the service parameter is not known. 785 */ 786 static int eth_send_message(device_id_t device_id, packet_t *packet, 787 services_t sender) 788 { 789 eth_device_t *device; 790 packet_t *next; 791 packet_t *tmp; 680 792 int ethertype; 793 int rc; 681 794 682 795 ethertype = htons(protocol_map(SERVICE_ETHERNET, sender)); 683 if (! ethertype){796 if (!ethertype) { 684 797 pq_release_remote(eth_globals.net_phone, packet_get_id(packet)); 685 798 return EINVAL; 686 799 } 800 687 801 fibril_rwlock_read_lock(ð_globals.devices_lock); 688 802 device = eth_devices_find(ð_globals.devices, device_id); 689 if (! device){803 if (!device) { 690 804 fibril_rwlock_read_unlock(ð_globals.devices_lock); 691 805 return ENOENT; 692 806 } 693 // process packet queue 807 808 /* Process packet queue */ 694 809 next = packet; 695 do{ 696 if(ERROR_OCCURRED(eth_prepare_packet(device->flags, next, (uint8_t *) device->addr->value, ethertype, device->mtu))){ 697 // release invalid packet 810 do { 811 rc = eth_prepare_packet(device->flags, next, 812 (uint8_t *) device->addr->value, ethertype, device->mtu); 813 if (rc != EOK) { 814 /* Release invalid packet */ 698 815 tmp = pq_detach(next); 699 if (next == packet){816 if (next == packet) 700 817 packet = tmp; 701 }702 pq_release_remote(eth_globals.net_phone,packet_get_id(next));818 pq_release_remote(eth_globals.net_phone, 819 packet_get_id(next)); 703 820 next = tmp; 704 } else{821 } else { 705 822 next = pq_next(next); 706 823 } 707 }while(next); 708 // send packet queue 709 if(packet){ 710 netif_send_msg(device->phone, device_id, packet, SERVICE_ETHERNET); 711 } 824 } while(next); 825 826 /* Send packet queue */ 827 if (packet) { 828 netif_send_msg(device->phone, device_id, packet, 829 SERVICE_ETHERNET); 830 } 831 712 832 fibril_rwlock_read_unlock(ð_globals.devices_lock); 713 833 return EOK; 714 834 } 715 835 716 int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call, 717 ipc_call_t *answer, int *answer_count) 718 { 719 ERROR_DECLARE; 720 721 measured_string_ref address; 722 packet_t packet; 836 int nil_module_message(ipc_callid_t callid, ipc_call_t *call, 837 ipc_call_t *answer, size_t *answer_count) 838 { 839 measured_string_t *address; 840 packet_t *packet; 723 841 size_t addrlen; 724 842 size_t prefix; 725 843 size_t suffix; 726 844 size_t content; 845 int rc; 727 846 728 847 *answer_count = 0; 729 switch (IPC_GET_METHOD(*call)) { 730 case IPC_M_PHONE_HUNGUP: 848 switch (IPC_GET_IMETHOD(*call)) { 849 case IPC_M_PHONE_HUNGUP: 850 return EOK; 851 852 case NET_NIL_DEVICE: 853 return eth_device_message(IPC_GET_DEVICE(*call), 854 IPC_GET_SERVICE(*call), IPC_GET_MTU(*call)); 855 case NET_NIL_SEND: 856 rc = packet_translate_remote(eth_globals.net_phone, &packet, 857 IPC_GET_PACKET(*call)); 858 if (rc != EOK) 859 return rc; 860 return eth_send_message(IPC_GET_DEVICE(*call), packet, 861 IPC_GET_SERVICE(*call)); 862 case NET_NIL_PACKET_SPACE: 863 rc = eth_packet_space_message(IPC_GET_DEVICE(*call), &addrlen, 864 &prefix, &content, &suffix); 865 if (rc != EOK) 866 return rc; 867 IPC_SET_ADDR(*answer, addrlen); 868 IPC_SET_PREFIX(*answer, prefix); 869 IPC_SET_CONTENT(*answer, content); 870 IPC_SET_SUFFIX(*answer, suffix); 871 *answer_count = 4; 872 return EOK; 873 case NET_NIL_ADDR: 874 rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_LOCAL_ADDR, 875 &address); 876 if (rc != EOK) 877 return rc; 878 return measured_strings_reply(address, 1); 879 case NET_NIL_BROADCAST_ADDR: 880 rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_BROADCAST_ADDR, 881 &address); 882 if (rc != EOK) 731 883 return EOK; 732 case NET_NIL_DEVICE: 733 return eth_device_message(IPC_GET_DEVICE(call), 734 IPC_GET_SERVICE(call), IPC_GET_MTU(call)); 735 case NET_NIL_SEND: 736 ERROR_PROPAGATE(packet_translate_remote(eth_globals.net_phone, &packet, 737 IPC_GET_PACKET(call))); 738 return eth_send_message(IPC_GET_DEVICE(call), packet, 739 IPC_GET_SERVICE(call)); 740 case NET_NIL_PACKET_SPACE: 741 ERROR_PROPAGATE(eth_packet_space_message(IPC_GET_DEVICE(call), 742 &addrlen, &prefix, &content, &suffix)); 743 IPC_SET_ADDR(answer, addrlen); 744 IPC_SET_PREFIX(answer, prefix); 745 IPC_SET_CONTENT(answer, content); 746 IPC_SET_SUFFIX(answer, suffix); 747 *answer_count = 4; 748 return EOK; 749 case NET_NIL_ADDR: 750 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 751 ETH_LOCAL_ADDR, &address)); 752 return measured_strings_reply(address, 1); 753 case NET_NIL_BROADCAST_ADDR: 754 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 755 ETH_BROADCAST_ADDR, &address)); 756 return measured_strings_reply(address, 1); 757 case IPC_M_CONNECT_TO_ME: 758 return eth_register_message(NIL_GET_PROTO(call), 759 IPC_GET_PHONE(call)); 884 return measured_strings_reply(address, 1); 885 case IPC_M_CONNECT_TO_ME: 886 return eth_register_message(NIL_GET_PROTO(*call), 887 IPC_GET_PHONE(*call)); 760 888 } 761 889 … … 763 891 } 764 892 765 void eth_receiver(ipc_callid_t iid, ipc_call_t * icall){766 ERROR_DECLARE;767 768 packet_t packet;769 770 while(true){771 // printf("message %d - %d\n", IPC_GET_METHOD(*icall), NET_NIL_FIRST);772 switch(IPC_GET_METHOD(*icall)){773 case NET_NIL_DEVICE_STATE:774 nil_device_state_msg_local(0, IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));775 ipc_answer_0(iid, EOK);776 break;777 case NET_NIL_RECEIVED:778 if(! ERROR_OCCURRED(packet_translate_remote(eth_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){779 ERROR_CODE = nil_received_msg_local(0, IPC_GET_DEVICE(icall), packet, 0);780 }781 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);782 break;783 default:784 ipc_answer_0(iid, (ipcarg_t) ENOTSUP);785 }786 iid = async_get_call(icall);787 }788 }789 790 #ifndef CONFIG_NETIF_NIL_BUNDLE791 792 /** Default thread for new connections.793 *794 * @param[in] iid The initial message identifier.795 * @param[in] icall The initial message call structure.796 *797 */798 static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)799 {800 /*801 * Accept the connection802 * - Answer the first IPC_M_CONNECT_ME_TO call.803 */804 ipc_answer_0(iid, EOK);805 806 while(true) {807 ipc_call_t answer;808 int answer_count;809 810 /* Clear the answer structure */811 refresh_answer(&answer, &answer_count);812 813 /* Fetch the next message */814 ipc_call_t call;815 ipc_callid_t callid = async_get_call(&call);816 817 /* Process the message */818 int res = nil_module_message_standalone(NAME, callid, &call, &answer,819 &answer_count);820 821 /* End if said to either by the message or the processing result */822 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))823 return;824 825 /* Answer the message */826 answer_call(callid, res, &answer, answer_count);827 }828 }829 830 893 int main(int argc, char *argv[]) 831 894 { 832 ERROR_DECLARE;833 834 895 /* Start the module */ 835 if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection))) 836 return ERROR_CODE; 837 838 return EOK; 839 } 840 841 #endif /* CONFIG_NETIF_NIL_BUNDLE */ 896 return nil_module_start(SERVICE_ETHERNET); 897 } 842 898 843 899 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.