Rev 4332 | Rev 4351 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4332 | Rev 4350 | ||
---|---|---|---|
Line 64... | Line 64... | ||
64 | #include "../nil_module.h" |
64 | #include "../nil_module.h" |
65 | 65 | ||
66 | #include "eth.h" |
66 | #include "eth.h" |
67 | #include "eth_header.h" |
67 | #include "eth_header.h" |
68 | 68 | ||
- | 69 | /** Reserved packet prefix length. |
|
- | 70 | */ |
|
69 | #define ETH_PREFIX ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t )) |
71 | #define ETH_PREFIX ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t )) |
- | 72 | ||
- | 73 | /** Reserved packet suffix length. |
|
- | 74 | */ |
|
70 | #define ETH_SUFFIX sizeof( eth_fcs_t ) |
75 | #define ETH_SUFFIX sizeof( eth_fcs_t ) |
- | 76 | ||
- | 77 | /** Maximum packet content length. |
|
- | 78 | */ |
|
71 | #define ETH_MAX_CONTENT 1500 |
79 | #define ETH_MAX_CONTENT 1500 |
- | 80 | ||
- | 81 | /** Minimum packet content length. |
|
- | 82 | */ |
|
72 | #define ETH_MIN_CONTENT 46 |
83 | #define ETH_MIN_CONTENT 46 |
- | 84 | ||
- | 85 | /** Maximum tagged packet content length. |
|
- | 86 | */ |
|
73 | #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 )) |
87 | #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 )) |
- | 88 | ||
- | 89 | /** Minimum tagged packet content length. |
|
- | 90 | */ |
|
74 | #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 )) |
91 | #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 )) |
75 | 92 | ||
- | 93 | /** Dummy flag shift value. |
|
- | 94 | */ |
|
76 | #define ETH_DUMMY_SHIFT 0 |
95 | #define ETH_DUMMY_SHIFT 0 |
- | 96 | ||
- | 97 | /** Mode flag shift value. |
|
- | 98 | */ |
|
77 | #define ETH_MODE_SHIFT 1 |
99 | #define ETH_MODE_SHIFT 1 |
78 | 100 | ||
79 | /** Dummy device flag. |
101 | /** Dummy device flag. |
80 | * Preamble and FCS are mandatory part of the packets. |
102 | * Preamble and FCS are mandatory part of the packets. |
81 | */ |
103 | */ |
82 | #define ETH_DUMMY ( 1 << ETH_DUMMY_SHIFT ) |
104 | #define ETH_DUMMY ( 1 << ETH_DUMMY_SHIFT ) |
- | 105 | ||
- | 106 | /** Returns the dummy flag. |
|
- | 107 | * @see ETH_DUMMY |
|
- | 108 | */ |
|
83 | #define IS_DUMMY( flags ) (( flags ) & ETH_DUMMY ) |
109 | #define IS_DUMMY( flags ) (( flags ) & ETH_DUMMY ) |
84 | 110 | ||
85 | /** Device mode flags. |
111 | /** Device mode flags. |
86 | * @see ETH_DIX |
112 | * @see ETH_DIX |
87 | * @see ETH_8023_2_LSAP |
113 | * @see ETH_8023_2_LSAP |
88 | * @see ETH_8023_2_SNAP |
114 | * @see ETH_8023_2_SNAP |
89 | */ |
115 | */ |
90 | #define ETH_MODE_MASK ( 3 << ETH_MODE_SHIFT ) |
116 | #define ETH_MODE_MASK ( 3 << ETH_MODE_SHIFT ) |
- | 117 | ||
- | 118 | /** DIX Ethernet mode flag. |
|
- | 119 | */ |
|
91 | #define ETH_DIX ( 1 << ETH_MODE_SHIFT ) |
120 | #define ETH_DIX ( 1 << ETH_MODE_SHIFT ) |
- | 121 | ||
- | 122 | /** Returns whether the DIX Ethernet mode flag is set. |
|
- | 123 | * @param flags The ethernet flags. Input parameter. |
|
- | 124 | * @see ETH_DIX |
|
- | 125 | */ |
|
92 | #define IS_DIX( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_DIX ) |
126 | #define IS_DIX( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_DIX ) |
- | 127 | ||
- | 128 | /** 802.3 + 802.2 + LSAP mode flag. |
|
- | 129 | */ |
|
93 | #define ETH_8023_2_LSAP ( 2 << ETH_MODE_SHIFT ) |
130 | #define ETH_8023_2_LSAP ( 2 << ETH_MODE_SHIFT ) |
- | 131 | ||
- | 132 | /** Returns whether the 802.3 + 802.2 + LSAP mode flag is set. |
|
- | 133 | * @param flags The ethernet flags. Input parameter. |
|
- | 134 | * @see ETH_8023_2_LSAP |
|
- | 135 | */ |
|
94 | #define IS_8023_2_LSAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_LSAP ) |
136 | #define IS_8023_2_LSAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_LSAP ) |
- | 137 | ||
- | 138 | /** 802.3 + 802.2 + LSAP + SNAP mode flag. |
|
- | 139 | */ |
|
95 | #define ETH_8023_2_SNAP ( 3 << ETH_MODE_SHIFT ) |
140 | #define ETH_8023_2_SNAP ( 3 << ETH_MODE_SHIFT ) |
- | 141 | ||
- | 142 | /** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. |
|
- | 143 | * @param flags The ethernet flags. Input parameter. |
|
- | 144 | * @see ETH_8023_2_SNAP |
|
- | 145 | */ |
|
96 | #define IS_8023_2_SNAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_SNAP ) |
146 | #define IS_8023_2_SNAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_SNAP ) |
97 | 147 | ||
- | 148 | /** Type definition of the ethernet address type. |
|
- | 149 | * @see eth_addr_type |
|
- | 150 | */ |
|
98 | typedef enum eth_addr_type eth_addr_type_t; |
151 | typedef enum eth_addr_type eth_addr_type_t; |
- | 152 | ||
- | 153 | /** Type definition of the ethernet address type pointer. |
|
- | 154 | * @see eth_addr_type |
|
- | 155 | */ |
|
99 | typedef eth_addr_type_t * eth_addr_type_ref; |
156 | typedef eth_addr_type_t * eth_addr_type_ref; |
100 | 157 | ||
- | 158 | /** Ethernet address type. |
|
- | 159 | */ |
|
101 | enum eth_addr_type{ |
160 | enum eth_addr_type{ |
- | 161 | /** Local address. |
|
- | 162 | */ |
|
102 | ETH_LOCAL_ADDR, |
163 | ETH_LOCAL_ADDR, |
- | 164 | /** Broadcast address. |
|
- | 165 | */ |
|
103 | ETH_BROADCAST_ADDR |
166 | ETH_BROADCAST_ADDR |
104 | }; |
167 | }; |
105 | 168 | ||
106 | /** Ethernet global data. |
169 | /** Ethernet module global data. |
107 | */ |
170 | */ |
108 | eth_globals_t eth_globals; |
171 | eth_globals_t eth_globals; |
109 | 172 | ||
110 | /** Processes IPC messages from the registered device driver modules in an infinite loop. |
173 | /** Processes IPC messages from the registered device driver modules in an infinite loop. |
111 | * @param iid The message identifier. Input parameter. |
174 | * @param iid The message identifier. Input parameter. |
112 | * @param icall The message parameters. Input/output parameter. |
175 | * @param icall The message parameters. Input/output parameter. |
113 | */ |
176 | */ |
114 | void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
177 | void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
115 | 178 | ||
- | 179 | /** Registers new device or updates the MTU of an existing one. |
|
- | 180 | * Determines the device local hardware address. |
|
- | 181 | * @param device_id The new device identifier. Input parameter. |
|
- | 182 | * @param service The device driver service. Input parameter. |
|
- | 183 | * @param mtu The device maximum transmission unit. Input parameter. |
|
- | 184 | * @returns EOK on success. |
|
116 | DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t ) |
185 | * @returns EEXIST if the device with the different service exists. |
117 | - | ||
118 | INT_MAP_IMPLEMENT( eth_protos, eth_proto_t ) |
186 | * @returns ENOMEM if there is not enough memory left. |
- | 187 | * @returns Other error codes as defined for the net_get_device_conf_req() function. |
|
- | 188 | * @returns Other error codes as defined for the netif_bind_service() function. |
|
- | 189 | * @returns Other error codes as defined for the netif_get_addr() function. |
|
119 | 190 | */ |
|
120 | int eth_device_message( device_id_t device_id, services_t service, size_t mtu ); |
191 | int eth_device_message( device_id_t device_id, services_t service, size_t mtu ); |
- | 192 | ||
- | 193 | /** Registers receiving module service. |
|
- | 194 | * Passes received packets for this service. |
|
121 | int nil_receive_msg( int nil_phone, device_id_t device_id, packet_t packet ); |
195 | * @param service The module service. Input parameter. |
- | 196 | * @param phone The service phone. Input parameter. |
|
- | 197 | * @returns EOK on success. |
|
- | 198 | * @returns ENOENT if the service is not known. |
|
- | 199 | * @returns ENOMEM if there is not enough memory left. |
|
- | 200 | */ |
|
122 | int nil_register_message( services_t service, int phone ); |
201 | int nil_register_message( services_t service, int phone ); |
- | 202 | ||
- | 203 | /** Returns the device packet dimensions for sending. |
|
- | 204 | * @param device_id The device identifier. Input parameter. |
|
- | 205 | * @param addr_len The minimum reserved address length. Output parameter. |
|
- | 206 | * @param prefix The minimum reserved prefix size. Output parameter. |
|
- | 207 | * @param content The maximum content size. Output parameter. |
|
- | 208 | * @param suffix The minimum reserved suffix size. Output parameter. |
|
- | 209 | * @returns EOK on success. |
|
- | 210 | * @returns EBADMEM if either one of the parameters is NULL. |
|
- | 211 | * @returns ENOENT if there is no such device. |
|
- | 212 | */ |
|
123 | int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ); |
213 | int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ); |
- | 214 | ||
- | 215 | /** Returns the device hardware address. |
|
- | 216 | * @param device_id The device identifier. Input parameter. |
|
- | 217 | * @param type Type of the desired address. Input parameter |
|
- | 218 | * @param address The device hardware address. Output parameter. |
|
- | 219 | * @returns EOK on success. |
|
- | 220 | * @returns EBADMEM if the address parameter is NULL. |
|
- | 221 | * @returns ENOENT if there no such device. |
|
- | 222 | */ |
|
124 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ); |
223 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ); |
- | 224 | ||
- | 225 | /** Sends the packet queue. |
|
- | 226 | * Sends only packet successfully processed by the eth_prepare_packet() function. |
|
- | 227 | * @param device_id The device identifier. Input parameter. |
|
- | 228 | * @param packet The packet queue. Input parameter. |
|
- | 229 | * @param sender The sending module service. Input parameter. |
|
- | 230 | * @returns EOK on success. |
|
- | 231 | * @returns ENOENT if there no such device. |
|
- | 232 | * @returns EINVAL if the service parameter is not known. |
|
- | 233 | */ |
|
125 | int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
234 | int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
- | 235 | ||
- | 236 | /** Processes the received packet and chooses the target registered module. |
|
- | 237 | * @param flags The device flags. Input parameter. |
|
- | 238 | * @param packet The packet. Input parameter. |
|
- | 239 | * @returns The target registered module. |
|
- | 240 | * @returns NULL if the packet is not long enough. |
|
- | 241 | * @returns NULL if the packet is too long. |
|
- | 242 | * @returns NULL if the raw ethernet protocol is used. |
|
- | 243 | * @returns NULL if the dummy device FCS checksum is invalid. |
|
- | 244 | * @returns NULL if the packet address length is not big enough. |
|
- | 245 | */ |
|
126 | eth_proto_ref eth_process_packet( int flags, packet_t packet ); |
246 | eth_proto_ref eth_process_packet( int flags, packet_t packet ); |
- | 247 | ||
- | 248 | /** Prepares the packet for sending. |
|
- | 249 | * @param flags The device flags. Input parameter. |
|
- | 250 | * @param packet The packet. Input parameter. |
|
- | 251 | * @param src_addr The source hardware address. Input parameter. |
|
- | 252 | * @param ethertype The ethernet protocol type. Input parameter. |
|
- | 253 | * @param mtu The device maximum transmission unit. Input parameter. |
|
- | 254 | * @returns EOK on success. |
|
- | 255 | * @returns EINVAL if the packet addresses length is not long enough. |
|
- | 256 | * @returns EINVAL if the packet is bigger than the device MTU. |
|
- | 257 | * @returns ENOMEM if there is not enough memory in the packet. |
|
- | 258 | */ |
|
127 | int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype ); |
259 | int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype ); |
128 | 260 | ||
- | 261 | DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t ) |
|
- | 262 | ||
- | 263 | INT_MAP_IMPLEMENT( eth_protos, eth_proto_t ) |
|
- | 264 | ||
129 | int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){ |
265 | int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){ |
130 | int index; |
266 | int index; |
131 | eth_proto_ref proto; |
267 | eth_proto_ref proto; |
132 | 268 | ||
133 | //TODO clear device if off? |
269 | //TODO clear device if off? |
Line 329... | Line 465... | ||
329 | } |
465 | } |
330 | 466 | ||
331 | int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ |
467 | int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ |
332 | eth_device_ref device; |
468 | eth_device_ref device; |
333 | 469 | ||
334 | if( !( addr_len && prefix && content && suffix )) return EINVAL; |
470 | if( !( addr_len && prefix && content && suffix )) return EBADMEM; |
335 | rwlock_read_lock( & eth_globals.devices_lock ); |
471 | rwlock_read_lock( & eth_globals.devices_lock ); |
336 | device = eth_devices_find( & eth_globals.devices, device_id ); |
472 | device = eth_devices_find( & eth_globals.devices, device_id ); |
337 | if( ! device ){ |
473 | if( ! device ){ |
338 | rwlock_read_unlock( & eth_globals.devices_lock ); |
474 | rwlock_read_unlock( & eth_globals.devices_lock ); |
339 | return ENOENT; |
475 | return ENOENT; |
Line 347... | Line 483... | ||
347 | } |
483 | } |
348 | 484 | ||
349 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ){ |
485 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ){ |
350 | eth_device_ref device; |
486 | eth_device_ref device; |
351 | 487 | ||
352 | if( ! address ) return EINVAL; |
488 | if( ! address ) return EBADMEM; |
353 | if( type == ETH_BROADCAST_ADDR ){ |
489 | if( type == ETH_BROADCAST_ADDR ){ |
354 | * address = eth_globals.broadcast_addr; |
490 | * address = eth_globals.broadcast_addr; |
355 | }else{ |
491 | }else{ |
356 | rwlock_read_lock( & eth_globals.devices_lock ); |
492 | rwlock_read_lock( & eth_globals.devices_lock ); |
357 | device = eth_devices_find( & eth_globals.devices, device_id ); |
493 | device = eth_devices_find( & eth_globals.devices, device_id ); |
Line 412... | Line 548... | ||
412 | 548 | ||
413 | length = packet_get_addr( packet, & src, & dest ); |
549 | length = packet_get_addr( packet, & src, & dest ); |
414 | if( length < 0 ) return length; |
550 | if( length < 0 ) return length; |
415 | if( length < ETH_ADDR ) return EINVAL; |
551 | if( length < ETH_ADDR ) return EINVAL; |
416 | length = packet_get_data_length( packet ); |
552 | length = packet_get_data_length( packet ); |
- | 553 | //TODO smaller than MTU! |
|
417 | if( length > ETH_MAX_TAGGED_CONTENT( flags )) return EINVAL; |
554 | if( length > ETH_MAX_TAGGED_CONTENT( flags )) return EINVAL; |
418 | if( length < ETH_MIN_TAGGED_CONTENT( flags )){ |
555 | if( length < ETH_MIN_TAGGED_CONTENT( flags )){ |
419 | padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
556 | padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
420 | if( ! padding ) return ENOMEM; |
557 | if( ! padding ) return ENOMEM; |
421 | bzero( padding, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
558 | bzero( padding, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |