Data Structures | |||||||||
struct | ethernet | ||||||||
An ethernet packet structure. More... | |||||||||
Typedefs | |||||||||
typedef ethernet | ethernet_t | ||||||||
An ethernet packet structure. | |||||||||
Functions | |||||||||
void | to_eth_layer (ethernet_t *packet, size_t len) | ||||||||
Process an ethernet packet received from the physical layer.
| |||||||||
int | send_eth_packet (const uint8_t *to, const void *data, size_t len, uint16_t type) | ||||||||
Send an ethernet packet to the physiscal layer.
| |||||||||
bool | is_eth_promisc () | ||||||||
Check if the ethernet device has been configured in promiscuous mode.
| |||||||||
void | ifconfig (char *cmd) | ||||||||
This is the "ifconfig" command for the shell.
|
|
An ethernet packet structure.
|
|
This is the "ifconfig" command for the shell.
Definition at line 273 of file eth.c.
00274 { 00275 uint8_t ip_dot[STR_MAX_LENGTH]; 00276 in_addr_t ip, netmask; 00277 00278 // Skip initial spaces into the parameters string // 00279 while (*cmd == ' ') cmd++; 00280 if (*cmd == '\0') 00281 { 00282 // Simply print current ethernet configuration // 00283 rtl8139_dump_info(rtl); 00284 return; 00285 } 00286 if ( strstr(cmd, "up") ) 00287 { 00288 if ( rtl != NULL ) 00289 { 00290 kprintf("\n\rRTL8139 is already up!"); 00291 if ( strstr(cmd, "promisc") ) 00292 rtl8139_promisc(get_rtl8139_device(), TRUE); 00293 else 00294 rtl8139_promisc(get_rtl8139_device(), FALSE); 00295 kprintf("\n\rRTL8139: promiscuous mode %s\n\r", 00296 (get_rtl8139_device()->promisc) ? "ENABLED" : "DISABLED"); 00297 return; 00298 } 00299 00300 // Get the host IP and netmask // 00301 kprintf("\n\rIP address: "); 00302 gets(ip_dot); 00303 if ( !inet_aton(ip_dot, &ip) ) 00304 { 00305 // Set the IP to default value // 00306 ip = DEFAULT_IP_ADDR; 00307 } 00308 kprintf("\rNetmask : "); 00309 gets(ip_dot); 00310 if ( !inet_aton(ip_dot, &netmask) ) 00311 { 00312 // Set the netmask to default value // 00313 netmask = DEFAULT_NETMASK_ADDR; 00314 } 00315 00316 // Set the host ip and netmask addresses // 00317 set_host_ip_net(ip, netmask); 00318 // Initialize the ethernet buffer // 00319 eth_init_buffer(); 00320 // Reset the ARP cache // 00321 arp_reset_cache(); 00322 00323 // Open the TCP module // 00324 tcp_module_init(); 00325 00326 // Initialize the RTL8139 device // 00327 switch( rtl8139_init(strstr(cmd, "promisc") ? TRUE : FALSE) ) 00328 { 00329 case ( 0 ): 00330 // --- SUCCESS --- // 00331 // Dump the ethernet card informations // 00332 rtl8139_dump_info(rtl); 00333 // Create the ethernet receiver thread // 00334 eth_recv_thread1 = 00335 create_process( 00336 ð_recv_daemon, ð_recv_daemon, 00337 0, "eth_recvd1", KERNEL_PRIVILEGE); 00338 eth_recv_thread2 = 00339 create_process( 00340 ð_recv_daemon, ð_recv_daemon, 00341 0, "eth_recvd2", KERNEL_PRIVILEGE); 00342 break; 00343 00344 case ( -ENXIO ): 00345 // --- DEVICE NOT FOUND --- // 00346 // Null the host ip and netmask // 00347 set_host_ip_net(0, 0); 00348 // Destroy the ethernet buffer // 00349 kfree( eth_recv_buf ); 00350 // Print the error message // 00351 kprintf("\n\rRTL8139: cannot find an ethernet card!\n\r"); 00352 break; 00353 00354 case ( -EIO ): 00355 // --- I/O ERROR --- // 00356 // Null the host ip and netmask // 00357 set_host_ip_net(0, 0); 00358 // Destroy the ethernet buffer // 00359 kfree( eth_recv_buf ); 00360 // Print the error message // 00361 kprintf("\n\rRTL8139: I/O error!\n\r"); 00362 break; 00363 } 00364 return; 00365 } 00366 if ( strstr(cmd, "down") ) 00367 { 00368 kprintf("\n\rRTL8139: shutting down eth0 device..."); 00369 00370 // Close the TCP module // 00371 tcp_module_close(); 00372 00373 // Destroy the ethernet buffer // 00374 kfree( eth_recv_buf ); 00375 // Kill the ethernet receiver thread // 00376 kill(eth_recv_thread1->pid); 00377 kill(eth_recv_thread2->pid); 00378 // Reset the ARP cache // 00379 arp_reset_cache(); 00380 // Close the RTL8139 interface // 00381 rtl8139_close(&rtl); 00382 kprintf("\n\r"); 00383 return; 00384 } 00385 00386 // Command unknown! // 00387 kprintf("\n\rerror: %s unknown!\n\r", cmd); 00388 } |
|
Check if the ethernet device has been configured in promiscuous mode.
Definition at line 261 of file eth.c.
00262 { 00263 return( get_rtl8139_device()->promisc ); 00264 } |
|
Send an ethernet packet to the physiscal layer.
Definition at line 206 of file eth.c.
00207 { 00208 uint8_t *packet; 00209 uint8_t *mac_addr; 00210 00211 // Analyze the packet length (must be less than ETH_MTU) // 00212 // TODO: if the packet length if great than ETH_MTU // 00213 // perform a packet fragmentation. // 00214 len = MIN(len, ETH_MTU); 00215 00216 // Create the ethernet packet // 00217 packet = kmalloc( MAX(len+ETH_HEAD_LEN, ETH_MIN_LEN) ); 00218 if (!packet) 00219 return(-ENOMEM); 00220 00221 // Get the local mac address // 00222 if ( (mac_addr = get_eth_mac_addr()) == NULL ) 00223 // No such device or address! // 00224 return(-ENXIO); 00225 00226 // Add the ethernet header to the packet // 00227 memcpy(packet, to, ETH_ADDR_LEN); 00228 memcpy(packet + ETH_ADDR_LEN, mac_addr, ETH_ADDR_LEN); 00229 memcpy(packet + 2 * ETH_ADDR_LEN, &type, sizeof(uint16_t)); 00230 00231 // Copy the data into the packet // 00232 memcpy(packet + ETH_HEAD_LEN, data, len); 00233 00234 // Adjust the packet length including the size of the header // 00235 len += ETH_HEAD_LEN; 00236 00237 // Auto-pad! Send a minimum payload (another 4 bytes are // 00238 // sent automatically for the FCS, totalling to 64 bytes) // 00239 // It is the minimum length of an ethernet packet. // 00240 while (len < ETH_MIN_LEN) 00241 packet[len++] = '\0'; 00242 00243 // Go to the physical layer // 00244 len = send_rtl8139_packet(get_rtl8139_device(), packet, len); 00245 00246 // Free the memory of the packet // 00247 kfree(packet); 00248 00249 // Return the bytes transmitted at this level // 00250 return(len); 00251 } |
|
Process an ethernet packet received from the physical layer.
Definition at line 153 of file eth.c.
00154 { 00155 DOWN(ð_recv_buf->mutex); 00156 00157 #ifdef ETH_DEBUG 00158 // Strip the ethernet header // 00159 kprintf("\n\rMAC DEST = %02x:%02x:%02x:%02x:%02x:%02x", 00160 packet->dst[0], packet->dst[1], packet->dst[2], 00161 packet->dst[3], packet->dst[4], packet->dst[5]); 00162 kprintf("\n\rMAC SOURCE = %02x:%02x:%02x:%02x:%02x:%02x", 00163 packet->src[0], packet->src[1], packet->src[2], 00164 packet->src[3], packet->src[4], packet->src[5]); 00165 kprintf("\n\rPACK TYPE = %04x", ntohs(packet->type)); 00166 kprintf("\n\rTOT LENGTH = %u bytes", len); 00167 #endif 00168 00169 // Store the packet data into the send buffer // 00170 memcpy( 00171 eth_recv_buf->packet[eth_recv_buf->write].data, 00172 packet, 00173 len = MIN(len, ETH_FRAME_LEN) 00174 ); 00175 // Store the packet length // 00176 eth_recv_buf->packet[eth_recv_buf->write].length = len; 00177 // Update the recv buffer write pointer // 00178 eth_recv_buf->write = (eth_recv_buf->write + 1) % ETH_RECV_BUF_DIM; 00179 00180 if (eth_recv_buf->count <= ETH_RECV_BUF_DIM) 00181 // Update the packet counter // 00182 (eth_recv_buf->count)++; 00183 else 00184 // The oldest packet has been overwritten, so update // 00185 // also the read pointer // 00186 eth_recv_buf->read = (eth_recv_buf->read + 1) % ETH_RECV_BUF_DIM; 00187 00188 UP(ð_recv_buf->mutex); 00189 00190 // Wakeup the receive daemons // 00191 wakeup_task( eth_recv_thread1 ); 00192 wakeup_task( eth_recv_thread2 ); 00193 } |