Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

Ethernet Layer
[Networking]


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.
Parameters:
packet  The ethernet packet received.
len  The size of the packet.


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.
Parameters:
to  The destination ethernet address (MAC).
data  The buffer of data to be sent.
len  The size of the buffer of data to be sent.
type  The packet type.
Returns:
  • The number of bytes sent in case of success.
  • -ENOMEM cannot allocate the packet structure.
  • -ENXIO no ethernet device found.


bool is_eth_promisc ()
 Check if the ethernet device has been configured in promiscuous mode.
Returns:
  • TRUE the ethernet card is in promiscuous mode;
  • FALSE the ethernet card is not in promiscuous mode.


void ifconfig (char *cmd)
 This is the "ifconfig" command for the shell.
Parameters:
cmd  A string of command parameters.



Detailed Description

The ethernet layer.

Typedef Documentation

typedef struct ethernet ethernet_t
 

An ethernet packet structure.


Function Documentation

void ifconfig char *    cmd
 

This is the "ifconfig" command for the shell.

Parameters:
cmd  A string of command parameters.

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                                         &eth_recv_daemon, &eth_recv_daemon,
00337                                         0, "eth_recvd1", KERNEL_PRIVILEGE);
00338                         eth_recv_thread2 =
00339                                 create_process(
00340                                         &eth_recv_daemon, &eth_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 }

bool is_eth_promisc  
 

Check if the ethernet device has been configured in promiscuous mode.

Returns:
  • TRUE the ethernet card is in promiscuous mode;
  • FALSE the ethernet card is not in promiscuous mode.

Definition at line 261 of file eth.c.

00262 {
00263         return( get_rtl8139_device()->promisc );
00264 }

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.

Parameters:
to  The destination ethernet address (MAC).
data  The buffer of data to be sent.
len  The size of the buffer of data to be sent.
type  The packet type.
Returns:
  • The number of bytes sent in case of success.
  • -ENOMEM cannot allocate the packet structure.
  • -ENXIO no ethernet device found.

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 }

void to_eth_layer ethernet_t   packet,
size_t    len
 

Process an ethernet packet received from the physical layer.

Parameters:
packet  The ethernet packet received.
len  The size of the packet.

Definition at line 153 of file eth.c.

00154 {
00155         DOWN(&eth_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(&eth_recv_buf->mutex);
00189 
00190         // Wakeup the receive daemons                                   //
00191         wakeup_task( eth_recv_thread1 );
00192         wakeup_task( eth_recv_thread2 );
00193 }


Generated on Fri Feb 20 15:32:22 2004 for Minirighi by doxygen1.2.18