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 }
|
1.2.18