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