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