Changeset 6067284 in mainline
- Timestamp:
- 2010-10-27T19:51:12Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d2b1040
- Parents:
- 30b2d02
- Location:
- uspace/srv/net/nil/eth
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/nil/eth/eth.c
r30b2d02 r6067284 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){ 196 int nil_initialize(int net_phone) 197 { 290 198 ERROR_DECLARE; 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 ERROR_CODE = ENOMEM; 211 goto out; 212 } 213 if (ERROR_OCCURRED(eth_devices_initialize(ð_globals.devices))) 214 goto out; 215 if (ERROR_OCCURRED(eth_protos_initialize(ð_globals.protos))) 303 216 eth_devices_destroy(ð_globals.devices); 304 return ERROR_CODE; 305 } 217 out: 306 218 fibril_rwlock_write_unlock(ð_globals.protos_lock); 307 219 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){ 220 221 return ERROR_CODE; 222 } 223 224 /** Processes IPC messages from the registered device driver modules in an 225 * infinite loop. 226 * 227 * @param[in] iid The message identifier. 228 * @param[in,out] icall The message parameters. 229 */ 230 static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall) 231 { 232 ERROR_DECLARE; 233 234 packet_t packet; 235 236 while (true) { 237 switch (IPC_GET_METHOD(*icall)) { 238 case NET_NIL_DEVICE_STATE: 239 nil_device_state_msg_local(0, IPC_GET_DEVICE(icall), 240 IPC_GET_STATE(icall)); 241 ipc_answer_0(iid, EOK); 242 break; 243 case NET_NIL_RECEIVED: 244 if (ERROR_NONE(packet_translate_remote( 245 eth_globals.net_phone, &packet, 246 IPC_GET_PACKET(icall)))) { 247 ERROR_CODE = nil_received_msg_local(0, 248 IPC_GET_DEVICE(icall), packet, 0); 249 } 250 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE); 251 break; 252 default: 253 ipc_answer_0(iid, (ipcarg_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 * @returns EOK on success. 268 * @returns EEXIST if the device with the different service exists. 269 * @returns ENOMEM if there is not enough memory left. 270 * @returns Other error codes as defined for the 271 * net_get_device_conf_req() function. 272 * @returns Other error codes as defined for the 273 * netif_bind_service() function. 274 * @returns Other error codes as defined for the 275 * netif_get_addr_req() function. 276 */ 277 static int 278 eth_device_message(device_id_t device_id, services_t service, size_t mtu) 279 { 312 280 ERROR_DECLARE; 313 281 314 282 eth_device_ref device; 315 283 int index; 316 measured_string_t names[2] = {{str_dup("ETH_MODE"), 8}, {str_dup("ETH_DUMMY"), 9}}; 284 measured_string_t names[2] = { 285 { 286 str_dup("ETH_MODE"), 287 8 288 }, 289 { 290 str_dup("ETH_DUMMY"), 291 9 292 } 293 }; 317 294 measured_string_ref configuration; 318 295 size_t count = sizeof(names) / sizeof(measured_string_t); 319 char * 296 char *data; 320 297 eth_proto_ref proto; 321 298 … … 323 300 // an existing device? 324 301 device = eth_devices_find(ð_globals.devices, device_id); 325 if (device){326 if (device->service != service){302 if (device) { 303 if (device->service != service) { 327 304 printf("Device %d already exists\n", device->device_id); 328 305 fibril_rwlock_write_unlock(ð_globals.devices_lock); 329 306 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); 307 } 308 309 // update mtu 310 if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))) 311 device->mtu = mtu; 312 else 313 device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags); 314 315 printf("Device %d already exists:\tMTU\t= %d\n", 316 device->device_id, device->mtu); 317 fibril_rwlock_write_unlock(ð_globals.devices_lock); 318 319 // notify all upper layer modules 320 fibril_rwlock_read_lock(ð_globals.protos_lock); 321 for (index = 0; index < eth_protos_count(ð_globals.protos); 322 index++) { 323 proto = eth_protos_get_index(ð_globals.protos, 324 index); 325 if (proto->phone) { 326 il_mtu_changed_msg(proto->phone, 327 device->device_id, device->mtu, 328 proto->service); 336 329 } 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{ 330 } 331 fibril_rwlock_read_unlock(ð_globals.protos_lock); 332 return EOK; 333 } 334 335 // create a new device 336 device = (eth_device_ref) 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 if (ERROR_OCCURRED(net_get_device_conf_req(eth_globals.net_phone, 350 device->device_id, &configuration, count, &data))) { 351 fibril_rwlock_write_unlock(ð_globals.devices_lock); 352 free(device); 353 return ERROR_CODE; 354 } 355 if (configuration) { 356 if (!str_lcmp(configuration[0].value, "DIX", 357 configuration[0].length)) { 358 device->flags |= ETH_DIX; 359 } else if(!str_lcmp(configuration[0].value, "8023_2_LSAP", 360 configuration[0].length)) { 361 device->flags |= ETH_8023_2_LSAP; 362 } else { 381 363 device->flags |= ETH_8023_2_SNAP; 382 364 } 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 } 365 366 if (configuration[1].value && 367 (configuration[1].value[0] == 'y')) { 368 device->flags |= ETH_DUMMY; 369 } 370 net_free_settings(configuration, data); 371 } else { 372 device->flags |= ETH_8023_2_SNAP; 373 } 374 375 // bind the device driver 376 device->phone = netif_bind_service(device->service, device->device_id, 377 SERVICE_ETHERNET, eth_receiver); 378 if (device->phone < 0) { 379 fibril_rwlock_write_unlock(ð_globals.devices_lock); 380 free(device); 381 return device->phone; 382 } 383 384 // get hardware address 385 if (ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, 386 &device->addr, &device->addr_data))) { 387 fibril_rwlock_write_unlock(ð_globals.devices_lock); 388 free(device); 389 return ERROR_CODE; 390 } 391 392 // add to the cache 393 index = eth_devices_add(ð_globals.devices, device->device_id, 394 device); 395 if (index < 0) { 396 fibril_rwlock_write_unlock(ð_globals.devices_lock); 397 free(device->addr); 398 free(device->addr_data); 399 free(device); 400 return index; 401 } 402 403 printf("%s: Device registered (id: %d, service: %d: mtu: %d, " 404 "mac: %x:%x:%x:%x:%x:%x, flags: 0x%x)\n", 405 NAME, device->device_id, device->service, device->mtu, 406 device->addr_data[0], device->addr_data[1], 407 device->addr_data[2], device->addr_data[3], 408 device->addr_data[4], device->addr_data[5], device->flags); 409 412 410 fibril_rwlock_write_unlock(ð_globals.devices_lock); 413 411 return EOK; 414 412 } 415 413 416 eth_proto_ref eth_process_packet(int flags, packet_t packet){ 414 /** Processes the received packet and chooses the target registered module. 415 * 416 * @param[in] flags The device flags. 417 * @param[in] packet The packet. 418 * @returns The target registered module. 419 * @returns NULL if the packet is not long enough. 420 * @returns NULL if the packet is too long. 421 * @returns NULL if the raw ethernet protocol is used. 422 * @returns NULL if the dummy device FCS checksum is invalid. 423 * @returns NULL if the packet address length is not big enough. 424 */ 425 static eth_proto_ref eth_process_packet(int flags, packet_t packet) 426 { 417 427 ERROR_DECLARE; 418 428 … … 426 436 427 437 length = packet_get_data_length(packet); 428 if(IS_DUMMY(flags)){ 438 439 if (IS_DUMMY(flags)) 429 440 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; 441 if (length < sizeof(eth_header_t) + ETH_MIN_CONTENT + 442 (IS_DUMMY(flags) ? ETH_SUFFIX : 0)) 443 return NULL; 444 432 445 data = packet_get_data(packet); 433 446 header = (eth_header_snap_ref) data; 434 447 type = ntohs(header->header.ethertype); 435 if(type >= ETH_MIN_PROTO){ 448 449 if (type >= ETH_MIN_PROTO) { 436 450 // DIX Ethernet 437 451 prefix = sizeof(eth_header_t); … … 439 453 fcs = (eth_fcs_ref) data + length - sizeof(eth_fcs_t); 440 454 length -= sizeof(eth_fcs_t); 441 } else if(type <= ETH_MAX_CONTENT){455 } else if(type <= ETH_MAX_CONTENT) { 442 456 // translate "LSAP" values 443 if((header->lsap.dsap == ETH_LSAP_GLSAP) && (header->lsap.ssap == ETH_LSAP_GLSAP)){ 457 if ((header->lsap.dsap == ETH_LSAP_GLSAP) && 458 (header->lsap.ssap == ETH_LSAP_GLSAP)) { 444 459 // raw packet 445 460 // discard 446 461 return NULL; 447 }else if((header->lsap.dsap == ETH_LSAP_SNAP) && (header->lsap.ssap == ETH_LSAP_SNAP)){ 462 } else if((header->lsap.dsap == ETH_LSAP_SNAP) && 463 (header->lsap.ssap == ETH_LSAP_SNAP)) { 448 464 // IEEE 802.3 + 802.2 + LSAP + SNAP 449 465 // organization code not supported 450 466 type = ntohs(header->snap.ethertype); 451 prefix = sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t); 452 }else{ 467 prefix = sizeof(eth_header_t) + 468 sizeof(eth_header_lsap_t) + 469 sizeof(eth_header_snap_t); 470 } else { 453 471 // IEEE 802.3 + 802.2 LSAP 454 472 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; 473 prefix = sizeof(eth_header_t) + 474 sizeof(eth_header_lsap_t); 475 } 476 suffix = (type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0U; 458 477 fcs = (eth_fcs_ref) data + prefix + type + suffix; 459 478 suffix += length - prefix - type; 460 479 length = prefix + type + suffix; 461 } else{480 } else { 462 481 // invalid length/type, should not occurr 463 482 return NULL; 464 483 } 465 if(IS_DUMMY(flags)){ 466 if((~ compute_crc32(~ 0u, data, length * 8)) != ntohl(*fcs)){ 484 485 if (IS_DUMMY(flags)) { 486 if ((~compute_crc32(~0U, data, length * 8)) != ntohl(*fcs)) 467 487 return NULL; 468 }469 488 suffix += sizeof(eth_fcs_t); 470 489 } 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))){ 490 491 if (ERROR_OCCURRED(packet_set_addr(packet, 492 header->header.source_address, header->header.destination_address, 493 ETH_ADDR)) || ERROR_OCCURRED(packet_trim(packet, prefix, suffix))) { 473 494 return NULL; 474 495 } 496 475 497 return eth_protos_find(ð_globals.protos, type); 476 498 } 477 499 478 int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){ 500 int 501 nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, 502 services_t target) 503 { 479 504 eth_proto_ref proto; 480 505 packet_t next; … … 484 509 fibril_rwlock_read_lock(ð_globals.devices_lock); 485 510 device = eth_devices_find(ð_globals.devices, device_id); 486 if (! device){511 if (!device) { 487 512 fibril_rwlock_read_unlock(ð_globals.devices_lock); 488 513 return ENOENT; … … 490 515 flags = device->flags; 491 516 fibril_rwlock_read_unlock(ð_globals.devices_lock); 517 492 518 fibril_rwlock_read_lock(ð_globals.protos_lock); 493 do {519 do { 494 520 next = pq_detach(packet); 495 521 proto = eth_process_packet(flags, packet); 496 if(proto){ 497 il_received_msg(proto->phone, device_id, packet, proto->service); 498 }else{ 522 if (proto) { 523 il_received_msg(proto->phone, device_id, packet, 524 proto->service); 525 } else { 499 526 // drop invalid/unknown 500 pq_release_remote(eth_globals.net_phone, packet_get_id(packet)); 527 pq_release_remote(eth_globals.net_phone, 528 packet_get_id(packet)); 501 529 } 502 530 packet = next; 503 } while(packet);531 } while(packet); 504 532 fibril_rwlock_read_unlock(ð_globals.protos_lock); 533 505 534 return EOK; 506 535 } 507 536 508 int eth_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){ 537 /** Returns the device packet dimensions for sending. 538 * 539 * @param[in] device_id The device identifier. 540 * @param[out] addr_len The minimum reserved address length. 541 * @param[out] prefix The minimum reserved prefix size. 542 * @param[out] content The maximum content size. 543 * @param[out] suffix The minimum reserved suffix size. 544 * @returns EOK on success. 545 * @returns EBADMEM if either one of the parameters is NULL. 546 * @returns ENOENT if there is no such device. 547 */ 548 static int 549 eth_packet_space_message(device_id_t device_id, size_t *addr_len, 550 size_t *prefix, size_t *content, size_t *suffix) 551 { 509 552 eth_device_ref device; 510 553 511 if (!(addr_len && prefix && content && suffix)){554 if (!addr_len || !prefix || !content || !suffix) 512 555 return EBADMEM; 513 }556 514 557 fibril_rwlock_read_lock(ð_globals.devices_lock); 515 558 device = eth_devices_find(ð_globals.devices, device_id); 516 if (! device){559 if (!device) { 517 560 fibril_rwlock_read_unlock(ð_globals.devices_lock); 518 561 return ENOENT; … … 520 563 *content = device->mtu; 521 564 fibril_rwlock_read_unlock(ð_globals.devices_lock); 565 522 566 *addr_len = ETH_ADDR; 523 567 *prefix = ETH_PREFIX; … … 526 570 } 527 571 528 int eth_addr_message(device_id_t device_id, eth_addr_type_t type, measured_string_ref * address){ 572 /** Returns the device hardware address. 573 * 574 * @param[in] device_id The device identifier. 575 * @param[in] type Type of the desired address. 576 * @param[out] address The device hardware address. 577 * @returns EOK on success. 578 * @returns EBADMEM if the address parameter is NULL. 579 * @returns ENOENT if there no such device. 580 */ 581 static int 582 eth_addr_message(device_id_t device_id, eth_addr_type_t type, 583 measured_string_ref *address) 584 { 529 585 eth_device_ref device; 530 586 531 if (! address){587 if (!address) 532 588 return EBADMEM; 533 } 534 if (type == ETH_BROADCAST_ADDR){589 590 if (type == ETH_BROADCAST_ADDR) { 535 591 *address = eth_globals.broadcast_addr; 536 } else{592 } else { 537 593 fibril_rwlock_read_lock(ð_globals.devices_lock); 538 594 device = eth_devices_find(ð_globals.devices, device_id); 539 if (! device){595 if (!device) { 540 596 fibril_rwlock_read_unlock(ð_globals.devices_lock); 541 597 return ENOENT; … … 544 600 fibril_rwlock_read_unlock(ð_globals.devices_lock); 545 601 } 602 546 603 return (*address) ? EOK : ENOENT; 547 604 } 548 605 549 int eth_register_message(services_t service, int phone){ 606 /** Registers receiving module service. 607 * 608 * Passes received packets for this service. 609 * 610 * @param[in] service The module service. 611 * @param[in] phone The service phone. 612 * @returns EOK on success. 613 * @returns ENOENT if the service is not known. 614 * @returns ENOMEM if there is not enough memory left. 615 */ 616 static int eth_register_message(services_t service, int phone) 617 { 550 618 eth_proto_ref proto; 551 619 int protocol; … … 553 621 554 622 protocol = protocol_map(SERVICE_ETHERNET, service); 555 if (! protocol){623 if (!protocol) 556 624 return ENOENT; 557 } 625 558 626 fibril_rwlock_write_lock(ð_globals.protos_lock); 559 627 proto = eth_protos_find(ð_globals.protos, protocol); 560 if (proto){628 if (proto) { 561 629 proto->phone = phone; 562 630 fibril_rwlock_write_unlock(ð_globals.protos_lock); 563 631 return EOK; 564 } else{632 } else { 565 633 proto = (eth_proto_ref) malloc(sizeof(eth_proto_t)); 566 if (! proto){634 if (!proto) { 567 635 fibril_rwlock_write_unlock(ð_globals.protos_lock); 568 636 return ENOMEM; … … 572 640 proto->phone = phone; 573 641 index = eth_protos_add(ð_globals.protos, protocol, proto); 574 if (index < 0){642 if (index < 0) { 575 643 fibril_rwlock_write_unlock(ð_globals.protos_lock); 576 644 free(proto); … … 579 647 } 580 648 581 printf("%s: Protocol registered (protocol: %d, service: %d, phone: %d)\n",582 NAME, proto->protocol, proto->service, proto->phone);649 printf("%s: Protocol registered (protocol: %d, service: %d, phone: " 650 "%d)\n", NAME, proto->protocol, proto->service, proto->phone); 583 651 584 652 fibril_rwlock_write_unlock(ð_globals.protos_lock); … … 586 654 } 587 655 588 int eth_prepare_packet(int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu){ 656 /** Prepares the packet for sending. 657 * 658 * @param[in] flags The device flags. 659 * @param[in] packet The packet. 660 * @param[in] src_addr The source hardware address. 661 * @param[in] ethertype The ethernet protocol type. 662 * @param[in] mtu The device maximum transmission unit. 663 * @returns EOK on success. 664 * @returns EINVAL if the packet addresses length is not long 665 * enough. 666 * @returns EINVAL if the packet is bigger than the device MTU. 667 * @returns ENOMEM if there is not enough memory in the packet. 668 */ 669 static int 670 eth_prepare_packet(int flags, packet_t packet, uint8_t *src_addr, int ethertype, 671 size_t mtu) 672 { 589 673 eth_header_snap_ref header; 590 674 eth_header_lsap_ref header_lsap; 591 675 eth_header_ref header_dix; 592 676 eth_fcs_ref fcs; 593 uint8_t * 594 uint8_t * 677 uint8_t *src; 678 uint8_t *dest; 595 679 size_t length; 596 680 int i; 597 void * 681 void *padding; 598 682 eth_preamble_ref preamble; 599 683 600 684 i = packet_get_addr(packet, &src, &dest); 601 if (i < 0){685 if (i < 0) 602 686 return i; 603 } 604 if(i != ETH_ADDR){ 687 if (i != ETH_ADDR) 605 688 return EINVAL; 606 } 689 607 690 length = packet_get_data_length(packet); 608 if (length > mtu){691 if (length > mtu) 609 692 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){ 693 694 if (length < ETH_MIN_TAGGED_CONTENT(flags)) { 695 padding = packet_suffix(packet, 696 ETH_MIN_TAGGED_CONTENT(flags) - length); 697 if (!padding) 614 698 return ENOMEM; 615 }616 699 bzero(padding, ETH_MIN_TAGGED_CONTENT(flags) - length); 617 700 } 618 if(IS_DIX(flags)){ 701 702 if (IS_DIX(flags)) { 619 703 header_dix = PACKET_PREFIX(packet, eth_header_t); 620 if (! header_dix){704 if (!header_dix) 621 705 return ENOMEM; 622 }706 623 707 header_dix->ethertype = (uint16_t) ethertype; 624 708 memcpy(header_dix->source_address, src_addr, ETH_ADDR); 625 709 memcpy(header_dix->destination_address, dest, ETH_ADDR); 626 710 src = &header_dix->destination_address[0]; 627 } else if(IS_8023_2_LSAP(flags)){711 } else if(IS_8023_2_LSAP(flags)) { 628 712 header_lsap = PACKET_PREFIX(packet, eth_header_lsap_t); 629 if (! header_lsap){713 if (!header_lsap) 630 714 return ENOMEM; 631 } 632 header_lsap->header.ethertype = htons(length + sizeof(eth_header_lsap_t)); 715 716 header_lsap->header.ethertype = htons(length + 717 sizeof(eth_header_lsap_t)); 633 718 header_lsap->lsap.dsap = lsap_unmap(ntohs(ethertype)); 634 719 header_lsap->lsap.ssap = header_lsap->lsap.dsap; … … 637 722 memcpy(header_lsap->header.destination_address, dest, ETH_ADDR); 638 723 src = &header_lsap->header.destination_address[0]; 639 } else if(IS_8023_2_SNAP(flags)){724 } else if(IS_8023_2_SNAP(flags)) { 640 725 header = PACKET_PREFIX(packet, eth_header_snap_t); 641 if (! header){726 if (!header) 642 727 return ENOMEM; 643 } 644 header->header.ethertype = htons(length + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t)); 728 729 header->header.ethertype = htons(length + 730 sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t)); 645 731 header->lsap.dsap = (uint16_t) ETH_LSAP_SNAP; 646 732 header->lsap.ssap = header->lsap.dsap; 647 733 header->lsap.ctrl = IEEE_8023_2_UI; 648 for(i = 0; i < 3; ++ i){ 734 735 for (i = 0; i < 3; ++ i) 649 736 header->snap.protocol[i] = 0; 650 }737 651 738 header->snap.ethertype = (uint16_t) ethertype; 652 739 memcpy(header->header.source_address, src_addr, ETH_ADDR); … … 654 741 src = &header->header.destination_address[0]; 655 742 } 656 if(IS_DUMMY(flags)){ 743 744 if (IS_DUMMY(flags)) { 657 745 preamble = PACKET_PREFIX(packet, eth_preamble_t); 658 if (! preamble){746 if (!preamble) 659 747 return ENOMEM; 660 }661 for (i = 0; i < 7; ++ i){748 749 for (i = 0; i < 7; ++ i) 662 750 preamble->preamble[i] = ETH_PREAMBLE; 663 }751 664 752 preamble->sfd = ETH_SFD; 753 665 754 fcs = PACKET_SUFFIX(packet, eth_fcs_t); 666 if (! fcs){755 if (!fcs) 667 756 return ENOMEM; 668 } 669 *fcs = htonl(~ compute_crc32(~ 0u, src, length * 8)); 670 } 757 758 *fcs = htonl(~compute_crc32(~0U, src, length * 8)); 759 } 760 671 761 return EOK; 672 762 } 673 763 674 int eth_send_message(device_id_t device_id, packet_t packet, services_t sender){ 764 /** Sends the packet queue. 765 * 766 * Sends only packet successfully processed by the eth_prepare_packet() 767 * function. 768 * 769 * @param[in] device_id The device identifier. 770 * @param[in] packet The packet queue. 771 * @param[in] sender The sending module service. 772 * @returns EOK on success. 773 * @returns ENOENT if there no such device. 774 * @returns EINVAL if the service parameter is not known. 775 */ 776 static int 777 eth_send_message(device_id_t device_id, packet_t packet, services_t sender) 778 { 675 779 ERROR_DECLARE; 676 780 … … 681 785 682 786 ethertype = htons(protocol_map(SERVICE_ETHERNET, sender)); 683 if (! ethertype){787 if (!ethertype) { 684 788 pq_release_remote(eth_globals.net_phone, packet_get_id(packet)); 685 789 return EINVAL; 686 790 } 791 687 792 fibril_rwlock_read_lock(ð_globals.devices_lock); 688 793 device = eth_devices_find(ð_globals.devices, device_id); 689 if (! device){794 if (!device) { 690 795 fibril_rwlock_read_unlock(ð_globals.devices_lock); 691 796 return ENOENT; 692 797 } 798 693 799 // process packet queue 694 800 next = packet; 695 do{ 696 if(ERROR_OCCURRED(eth_prepare_packet(device->flags, next, (uint8_t *) device->addr->value, ethertype, device->mtu))){ 801 do { 802 if (ERROR_OCCURRED(eth_prepare_packet(device->flags, next, 803 (uint8_t *) device->addr->value, ethertype, device->mtu))) { 697 804 // release invalid packet 698 805 tmp = pq_detach(next); 699 if (next == packet){806 if (next == packet) 700 807 packet = tmp; 701 }702 pq_release_remote(eth_globals.net_phone,packet_get_id(next));808 pq_release_remote(eth_globals.net_phone, 809 packet_get_id(next)); 703 810 next = tmp; 704 } else{811 } else { 705 812 next = pq_next(next); 706 813 } 707 }while(next); 814 } while(next); 815 708 816 // send packet queue 709 if(packet){ 710 netif_send_msg(device->phone, device_id, packet, SERVICE_ETHERNET); 817 if (packet) { 818 netif_send_msg(device->phone, device_id, packet, 819 SERVICE_ETHERNET); 711 820 } 712 821 fibril_rwlock_read_unlock(ð_globals.devices_lock); 822 713 823 return EOK; 714 824 } 715 825 716 int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call, 826 int 827 nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call, 717 828 ipc_call_t *answer, int *answer_count) 718 829 { … … 728 839 *answer_count = 0; 729 840 switch (IPC_GET_METHOD(*call)) { 730 case IPC_M_PHONE_HUNGUP: 731 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)); 841 case IPC_M_PHONE_HUNGUP: 842 return EOK; 843 844 case NET_NIL_DEVICE: 845 return eth_device_message(IPC_GET_DEVICE(call), 846 IPC_GET_SERVICE(call), IPC_GET_MTU(call)); 847 case NET_NIL_SEND: 848 ERROR_PROPAGATE(packet_translate_remote(eth_globals.net_phone, 849 &packet, IPC_GET_PACKET(call))); 850 return eth_send_message(IPC_GET_DEVICE(call), packet, 851 IPC_GET_SERVICE(call)); 852 case NET_NIL_PACKET_SPACE: 853 ERROR_PROPAGATE(eth_packet_space_message(IPC_GET_DEVICE(call), 854 &addrlen, &prefix, &content, &suffix)); 855 IPC_SET_ADDR(answer, addrlen); 856 IPC_SET_PREFIX(answer, prefix); 857 IPC_SET_CONTENT(answer, content); 858 IPC_SET_SUFFIX(answer, suffix); 859 *answer_count = 4; 860 return EOK; 861 case NET_NIL_ADDR: 862 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 863 ETH_LOCAL_ADDR, &address)); 864 return measured_strings_reply(address, 1); 865 case NET_NIL_BROADCAST_ADDR: 866 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 867 ETH_BROADCAST_ADDR, &address)); 868 return measured_strings_reply(address, 1); 869 case IPC_M_CONNECT_TO_ME: 870 return eth_register_message(NIL_GET_PROTO(call), 871 IPC_GET_PHONE(call)); 760 872 } 761 873 … … 763 875 } 764 876 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 877 /** Default thread for new connections. 791 878 * 792 * @param[in] iid 793 * @param[in] icall 879 * @param[in] iid The initial message identifier. 880 * @param[in] icall The initial message call structure. 794 881 * 795 882 */ … … 802 889 ipc_answer_0(iid, EOK); 803 890 804 while (true) {891 while (true) { 805 892 ipc_call_t answer; 806 893 int answer_count; … … 814 901 815 902 /* 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)) 903 int res = nil_module_message_standalone(NAME, callid, &call, 904 &answer, &answer_count); 905 906 /* 907 * End if told to either by the message or the processing 908 * result. 909 */ 910 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || 911 (res == EHANGUP)) 821 912 return; 822 913 … … 831 922 832 923 /* Start the module */ 833 if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection))) 834 return ERROR_CODE; 835 924 ERROR_PROPAGATE(nil_module_start_standalone(nil_client_connection)); 836 925 return EOK; 837 926 } -
uspace/srv/net/nil/eth/eth.h
r30b2d02 r6067284 32 32 33 33 /** @file 34 * 34 * Ethernet module. 35 35 */ 36 36 37 #ifndef __NET_ETH_H__38 #define __NET_ETH_H__37 #ifndef NET_ETH_H_ 38 #define NET_ETH_H_ 39 39 40 40 #include <fibril_synch.h> … … 45 45 46 46 /** Type definition of the Ethernet global data. 47 * 47 * @see eth_globals 48 48 */ 49 typedef struct eth_globals 49 typedef struct eth_globals eth_globals_t; 50 50 51 51 /** Type definition of the Ethernet device specific data. 52 * 52 * @see eth_device 53 53 */ 54 typedef struct eth_device 54 typedef struct eth_device eth_device_t; 55 55 56 56 /** Type definition of the Ethernet device specific data pointer. 57 * 57 * @see eth_device 58 58 */ 59 typedef eth_device_t * 59 typedef eth_device_t *eth_device_ref; 60 60 61 61 /** Type definition of the Ethernet protocol specific data. 62 * 62 * @see eth_proto 63 63 */ 64 typedef struct eth_proto 64 typedef struct eth_proto eth_proto_t; 65 65 66 66 /** Type definition of the Ethernet protocol specific data pointer. 67 * 67 * @see eth_proto 68 68 */ 69 typedef eth_proto_t * 69 typedef eth_proto_t *eth_proto_ref; 70 70 71 71 /** Ethernet device map. 72 * 73 * 72 * Maps devices to the Ethernet device specific data. 73 * @see device.h 74 74 */ 75 DEVICE_MAP_DECLARE(eth_devices, eth_device_t) 75 DEVICE_MAP_DECLARE(eth_devices, eth_device_t); 76 76 77 77 /** Ethernet protocol map. 78 * 79 * 78 * Maps protocol identifiers to the Ethernet protocol specific data. 79 * @see int_map.h 80 80 */ 81 INT_MAP_DECLARE(eth_protos, eth_proto_t) 81 INT_MAP_DECLARE(eth_protos, eth_proto_t); 82 82 83 /** Ethernet device specific data. 84 */ 85 struct eth_device{ 86 /** Device identifier. 87 */ 83 /** Ethernet device specific data. */ 84 struct eth_device { 85 /** Device identifier. */ 88 86 device_id_t device_id; 89 /** Device driver service. 90 */ 87 /** Device driver service. */ 91 88 services_t service; 92 /** Driver phone. 93 */ 89 /** Driver phone. */ 94 90 int phone; 95 /** Maximal transmission unit. 96 */ 91 /** Maximal transmission unit. */ 97 92 size_t mtu; 98 /** Various device flags. 99 * @see ETH_DUMMY 100 * @see ETH_MODE_MASK 93 94 /** 95 * Various device flags. 96 * @see ETH_DUMMY 97 * @see ETH_MODE_MASK 101 98 */ 102 99 int flags; 103 /** Actual device hardware address.104 */100 101 /** Actual device hardware address. */ 105 102 measured_string_ref addr; 106 /** Actual device hardware address data. 107 */ 108 char * addr_data; 103 /** Actual device hardware address data. */ 104 char *addr_data; 109 105 }; 110 106 111 /** Ethernet protocol specific data. 112 */ 113 struct eth_proto{ 114 /** Protocol service. 115 */ 107 /** Ethernet protocol specific data. */ 108 struct eth_proto { 109 /** Protocol service. */ 116 110 services_t service; 117 /** Protocol identifier. 118 */ 111 /** Protocol identifier. */ 119 112 int protocol; 120 /** Protocol module phone. 121 */ 113 /** Protocol module phone. */ 122 114 int phone; 123 115 }; 124 116 125 /** Ethernet global data. 126 */ 127 struct eth_globals{ 128 /** Networking module phone. 129 */ 117 /** Ethernet global data. */ 118 struct eth_globals { 119 /** Networking module phone. */ 130 120 int net_phone; 131 /** Safety lock for devices. 132 */ 121 /** Safety lock for devices. */ 133 122 fibril_rwlock_t devices_lock; 134 /** All known Ethernet devices. 135 */ 123 /** All known Ethernet devices. */ 136 124 eth_devices_t devices; 137 /** Safety lock for protocols. 138 */ 125 /** Safety lock for protocols. */ 139 126 fibril_rwlock_t protos_lock; 140 /** Protocol map. 141 * Service phone map for each protocol. 127 128 /** 129 * Protocol map. 130 * Service phone map for each protocol. 142 131 */ 143 132 eth_protos_t protos; 144 /** Broadcast device hardware address.145 */133 134 /** Broadcast device hardware address. */ 146 135 measured_string_ref broadcast_addr; 147 136 }; -
uspace/srv/net/nil/eth/eth_header.h
r30b2d02 r6067284 32 32 33 33 /** @file 34 * 35 * Based on the IEEE~802.3-200536 */ 37 38 #ifndef __NET_ETH_HEADER_H__39 #define __NET_ETH_HEADER_H__34 * Ethernet protocol header definitions. 35 * Based on the IEEE 802.3-2005 36 */ 37 38 #ifndef NET_ETH_HEADER_H_ 39 #define NET_ETH_HEADER_H_ 40 40 41 41 #include <sys/types.h> 42 42 43 /** Ethernet address length. 44 */ 45 #define ETH_ADDR 6 46 47 /** Ethernet header preamble value. 48 */ 43 /** Ethernet address length. */ 44 #define ETH_ADDR 6 45 46 /** Ethernet header preamble value. */ 49 47 #define ETH_PREAMBLE 0x55 50 48 51 /** Ethernet header start of frame value. 52 */ 53 #define ETH_SFD 0xD5 54 55 /** IEEE 802.2 unordered information control field. 56 */ 49 /** Ethernet header start of frame value. */ 50 #define ETH_SFD 0xD5 51 52 /** IEEE 802.2 unordered information control field. */ 57 53 #define IEEE_8023_2_UI 0x03 58 54 59 55 /** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions. 60 * @see eth_header_snap 61 */ 62 typedef struct eth_header_snap eth_header_snap_t; 63 64 /** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions pointer. 65 * @see eth_header_snap 66 */ 67 typedef eth_header_snap_t * eth_header_snap_ref; 56 * @see eth_header_snap 57 */ 58 typedef struct eth_header_snap eth_header_snap_t; 59 60 /** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions 61 * pointer. 62 * 63 * @see eth_header_snap 64 */ 65 typedef eth_header_snap_t *eth_header_snap_ref; 68 66 69 67 /** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions. 70 * 71 */ 72 typedef struct eth_header_lsap 68 * @see eth_header_lsap 69 */ 70 typedef struct eth_header_lsap eth_header_lsap_t; 73 71 74 72 /** Type definition of the Ethernet header IEEE 802.3 + 802.2 extension pointer. 75 * 76 */ 77 typedef eth_header_lsap_t * 73 * @see eth_header_lsap 74 */ 75 typedef eth_header_lsap_t *eth_header_lsap_ref; 78 76 79 77 /** Type definition of the Ethernet header LSAP extension. 80 * 81 */ 82 typedef struct eth_ieee_lsap 78 * @see eth_ieee_lsap 79 */ 80 typedef struct eth_ieee_lsap eth_ieee_lsap_t; 83 81 84 82 /** Type definition of the Ethernet header LSAP extension pointer. 85 * 86 */ 87 typedef eth_ieee_lsap_t * 83 * @see eth_ieee_lsap 84 */ 85 typedef eth_ieee_lsap_t *eth_ieee_lsap_ref; 88 86 89 87 /** Type definition of the Ethernet header SNAP extension. 90 * 91 */ 92 typedef struct eth_snap 88 * @see eth_snap 89 */ 90 typedef struct eth_snap eth_snap_t; 93 91 94 92 /** Type definition of the Ethernet header SNAP extension pointer. 95 * 96 */ 97 typedef eth_snap_t * 93 * @see eth_snap 94 */ 95 typedef eth_snap_t *eth_snap_ref; 98 96 99 97 /** Type definition of the Ethernet header preamble. 100 * 101 */ 102 typedef struct eth_preamble 98 * @see preamble 99 */ 100 typedef struct eth_preamble eth_preamble_t; 103 101 104 102 /** Type definition of the Ethernet header preamble pointer. 105 * 106 */ 107 typedef eth_preamble_t * 103 * @see eth_preamble 104 */ 105 typedef eth_preamble_t *eth_preamble_ref; 108 106 109 107 /** Type definition of the Ethernet header. 110 * 111 */ 112 typedef struct eth_header 108 * @see eth_header 109 */ 110 typedef struct eth_header eth_header_t; 113 111 114 112 /** Type definition of the Ethernet header pointer. 115 * 116 */ 117 typedef eth_header_t * 118 119 /** Ethernet header Link Service Access Point extension. 120 */ 121 struct eth_ieee_lsap{ 122 /** Destination Service Access Point identifier.113 * @see eth_header 114 */ 115 typedef eth_header_t *eth_header_ref; 116 117 /** Ethernet header Link Service Access Point extension. */ 118 struct eth_ieee_lsap { 119 /** 120 * Destination Service Access Point identifier. 123 121 * The possible values are assigned by an IEEE committee. 124 122 */ 125 123 uint8_t dsap; 126 /** Source Service Access Point identifier. 124 125 /** 126 * Source Service Access Point identifier. 127 127 * The possible values are assigned by an IEEE committee. 128 128 */ 129 129 uint8_t ssap; 130 /** Control parameter. 130 131 /** 132 * Control parameter. 131 133 * The possible values are assigned by an IEEE committee. 132 134 */ … … 134 136 } __attribute__ ((packed)); 135 137 136 /** Ethernet header SNAP extension. 137 */ 138 struct eth_snap{ 139 /** Protocol identifier or organization code. 140 */ 138 /** Ethernet header SNAP extension. */ 139 struct eth_snap { 140 /** Protocol identifier or organization code. */ 141 141 uint8_t protocol[3]; 142 /** Ethernet protocol identifier in the network byte order (big endian). 143 * @see ethernet_protocols.h 142 143 /** 144 * Ethernet protocol identifier in the network byte order (big endian). 145 * @see ethernet_protocols.h 144 146 */ 145 147 uint16_t ethertype; … … 147 149 148 150 /** Ethernet header preamble. 149 * Used for dummy devices. 150 */ 151 struct eth_preamble{ 152 /** Controlling preamble used for the frame transmission synchronization. 153 * All should be set to ETH_PREAMBLE. 151 * 152 * Used for dummy devices. 153 */ 154 struct eth_preamble { 155 /** 156 * Controlling preamble used for the frame transmission synchronization. 157 * All should be set to ETH_PREAMBLE. 154 158 */ 155 159 uint8_t preamble[7]; 156 /** Start of Frame Delimiter used for the frame transmission synchronization. 157 * Should be set to ETH_SFD. 160 161 /** 162 * Start of Frame Delimiter used for the frame transmission 163 * synchronization. 164 * Should be set to ETH_SFD. 158 165 */ 159 166 uint8_t sfd; 160 167 } __attribute__ ((packed)); 161 168 162 /** Ethernet header. 163 */ 164 struct eth_header{ 165 /** Destination host Ethernet address (MAC address). 166 */ 169 /** Ethernet header. */ 170 struct eth_header { 171 /** Destination host Ethernet address (MAC address). */ 167 172 uint8_t destination_address[ETH_ADDR]; 168 /** Source host Ethernet address (MAC address). 169 */ 173 /** Source host Ethernet address (MAC address). */ 170 174 uint8_t source_address[ETH_ADDR]; 171 /** Ethernet protocol identifier in the network byte order (big endian). 172 * @see ethernet_protocols.h 175 176 /** 177 * Ethernet protocol identifier in the network byte order (big endian). 178 * @see ethernet_protocols.h 173 179 */ 174 180 uint16_t ethertype; 175 181 } __attribute__ ((packed)); 176 182 177 /** Ethernet header IEEE 802.3 + 802.2 extension. 178 */ 179 struct eth_header_lsap{ 180 /** Ethernet header. 181 */ 183 /** Ethernet header IEEE 802.3 + 802.2 extension. */ 184 struct eth_header_lsap { 185 /** Ethernet header. */ 182 186 eth_header_t header; 183 /** LSAP extension. 184 * If DSAP and SSAP are set to ETH_LSAP_SNAP the SNAP extension is being used. 185 * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet without any extensions is being used and the frame content starts rigth after the two fields. 187 188 /** 189 * LSAP extension. 190 * If DSAP and SSAP are set to ETH_LSAP_SNAP the SNAP extension is being 191 * used. 192 * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet 193 * without any extensions is being used and the frame content starts 194 * rigth after the two fields. 186 195 */ 187 196 eth_ieee_lsap_t lsap; 188 197 } __attribute__ ((packed)); 189 198 190 /** Ethernet header IEEE 802.3 + 802.2 + SNAP extensions. 191 */ 192 struct eth_header_snap{ 193 /** Ethernet header. 194 */ 199 /** Ethernet header IEEE 802.3 + 802.2 + SNAP extensions. */ 200 struct eth_header_snap { 201 /** Ethernet header. */ 195 202 eth_header_t header; 196 /** LSAP extension. 197 * If DSAP and SSAP are set to ETH_LSAP_SNAP the SNAP extension is being used. 198 * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet without any extensions is being used and the frame content starts rigth after the two fields. 203 204 /** 205 * LSAP extension. 206 * If DSAP and SSAP are set to ETH_LSAP_SNAP the SNAP extension is being 207 * used. 208 * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet 209 * without any extensions is being used and the frame content starts 210 * rigth after the two fields. 199 211 */ 200 212 eth_ieee_lsap_t lsap; 201 /** SNAP extension.202 */213 214 /** SNAP extension. */ 203 215 eth_snap_t snap; 204 216 } __attribute__ ((packed)); 205 217 206 /** Ethernet Frame Check Sequence. 207 */ 208 typedef uint32_t eth_fcs_t; 209 210 /** Ethernet Frame Check Sequence pointer. 211 */ 212 typedef eth_fcs_t * eth_fcs_ref; 218 /** Ethernet Frame Check Sequence. */ 219 typedef uint32_t eth_fcs_t; 220 221 /** Ethernet Frame Check Sequence pointer. */ 222 typedef eth_fcs_t *eth_fcs_ref; 213 223 214 224 #endif -
uspace/srv/net/nil/eth/eth_module.c
r30b2d02 r6067284 36 36 */ 37 37 38 #include "eth.h" 39 38 40 #include <async.h> 39 41 #include <stdio.h> … … 48 50 #include <nil_local.h> 49 51 50 #include "eth.h"51 52 52 int nil_module_start_standalone(async_client_conn_t client_connection) 53 53 { … … 59 59 60 60 ipcarg_t phonehash; 61 if (ERROR_OCCURRED(nil_initialize(net_phone)) 62 ||ERROR_OCCURRED(REGISTER_ME(SERVICE_ETHERNET, &phonehash))) {61 if (ERROR_OCCURRED(nil_initialize(net_phone)) || 62 ERROR_OCCURRED(REGISTER_ME(SERVICE_ETHERNET, &phonehash))) { 63 63 pm_destroy(); 64 64 return ERROR_CODE; … … 71 71 } 72 72 73 int nil_module_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call, 74 ipc_call_t *answer, int *answer_count) 73 int 74 nil_module_message_standalone(const char *name, ipc_callid_t callid, 75 ipc_call_t *call, ipc_call_t *answer, int *answer_count) 75 76 { 76 77 return nil_message_standalone(name, callid, call, answer, answer_count);
Note:
See TracChangeset
for help on using the changeset viewer.