00001
00002
00003
00004
00005
00006
00007
00008 #include <const.h>
00009 #include <errno.h>
00010 #include <stdio.h>
00011 #include <string.h>
00012
00013 #include <arch/mem.h>
00014 #include <arch/i386.h>
00015
00016 #include <kernel/clock.h>
00017 #include <kernel/console.h>
00018 #include <kernel/kmalloc.h>
00019 #include <kernel/task.h>
00020
00021 #include <net/arp.h>
00022 #include <net/ip.h>
00023 #include <net/network.h>
00024 #include <net/rtl8139.h>
00025 #include <net/tcp.h>
00026
00027 #include <net/eth.h>
00028
00029 extern rtl8139_t *rtl;
00030
00031
00032 eth_buf_t *eth_recv_buf=NULL;
00033
00034
00035 task_t *eth_recv_thread1=NULL,
00036
00037 *eth_recv_thread2=NULL;
00038
00039
00040
00041
00042 void eth_init_buffer()
00043 {
00044
00045 eth_recv_buf = kmalloc(sizeof(eth_buf_t));
00046
00047
00048 memset(eth_recv_buf, 0, sizeof(eth_buf_t));
00049
00050
00051 INIT_MUTEX(ð_recv_buf->mutex);
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 int recv_eth_packet(ethernet_t *buf, size_t len, int flags)
00068 {
00069 dword IF = GET_IF();
00070
00071
00072 while(TRUE)
00073 {
00074 DOWN(ð_recv_buf->mutex);
00075
00076 if ( eth_recv_buf->count==0 )
00077 {
00078 UP(ð_recv_buf->mutex);
00079 sleep_task( get_curr_task() );
00080 enable();
00081 idle();
00082 }
00083 else
00084
00085 break;
00086 }
00087
00088
00089
00090 memcpy(
00091 buf,
00092 eth_recv_buf->packet[eth_recv_buf->read].data,
00093 len = MIN(len, eth_recv_buf->packet[eth_recv_buf->read].length)
00094 );
00095
00096 eth_recv_buf->read = (eth_recv_buf->read + 1) % ETH_RECV_BUF_DIM;
00097 (eth_recv_buf->count)--;
00098
00099 UP(ð_recv_buf->mutex);
00100 SET_IF(IF);
00101
00102
00103 return( len );
00104 }
00105
00106
00107
00108
00109 void eth_recv_daemon()
00110 {
00111 unsigned i;
00112 size_t len;
00113 union
00114 {
00115 uint8_t raw[ETH_FRAME_LEN];
00116 ethernet_t eth;
00117 } packet;
00118
00119 while(TRUE)
00120 {
00121
00122 memset(packet.raw, 0, sizeof(packet.raw));
00123
00124 len = recv_eth_packet(&packet.eth, sizeof(packet.raw), 0);
00125
00126
00127 switch( ntohs(packet.eth.type) )
00128 {
00129 case ETH_FRAME_ARP:
00130 to_arp_layer((arp_t *)(packet.eth.data));
00131 break;
00132
00133 case ETH_FRAME_IP:
00134 to_ip_layer((ip_t *)(packet.eth.data));
00135 break;
00136
00137 default:
00138
00139 kprintf("\n\rPACK TYPE = UNKNOWN (%04X)", htons(packet.eth.type));
00140
00141 kprintf("\n\rDUMP:\n\r");
00142 for (i=0; i<len; i++)
00143 kprintf("%02X ", packet.eth.data[i]);
00144 break;
00145 }
00146 }
00147 }
00148
00149
00150
00151
00152
00153 void to_eth_layer(ethernet_t *packet, size_t len)
00154 {
00155 DOWN(ð_recv_buf->mutex);
00156
00157 #ifdef ETH_DEBUG
00158
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
00170 memcpy(
00171 eth_recv_buf->packet[eth_recv_buf->write].data,
00172 packet,
00173 len = MIN(len, ETH_FRAME_LEN)
00174 );
00175
00176 eth_recv_buf->packet[eth_recv_buf->write].length = len;
00177
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
00182 (eth_recv_buf->count)++;
00183 else
00184
00185
00186 eth_recv_buf->read = (eth_recv_buf->read + 1) % ETH_RECV_BUF_DIM;
00187
00188 UP(ð_recv_buf->mutex);
00189
00190
00191 wakeup_task( eth_recv_thread1 );
00192 wakeup_task( eth_recv_thread2 );
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 int send_eth_packet(const uint8_t *to, const void *data, size_t len, uint16_t type)
00207 {
00208 uint8_t *packet;
00209 uint8_t *mac_addr;
00210
00211
00212
00213
00214 len = MIN(len, ETH_MTU);
00215
00216
00217 packet = kmalloc( MAX(len+ETH_HEAD_LEN, ETH_MIN_LEN) );
00218 if (!packet)
00219 return(-ENOMEM);
00220
00221
00222 if ( (mac_addr = get_eth_mac_addr()) == NULL )
00223
00224 return(-ENXIO);
00225
00226
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
00232 memcpy(packet + ETH_HEAD_LEN, data, len);
00233
00234
00235 len += ETH_HEAD_LEN;
00236
00237
00238
00239
00240 while (len < ETH_MIN_LEN)
00241 packet[len++] = '\0';
00242
00243
00244 len = send_rtl8139_packet(get_rtl8139_device(), packet, len);
00245
00246
00247 kfree(packet);
00248
00249
00250 return(len);
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 bool is_eth_promisc()
00262 {
00263 return( get_rtl8139_device()->promisc );
00264 }
00265
00266
00267 #define DEFAULT_IP_ADDR ( IP_ADDRESS(10, 0, 0, 2) )
00268
00269 #define DEFAULT_NETMASK_ADDR ( IP_ADDRESS(255, 0, 0, 0) )
00270
00271
00272
00273 void ifconfig(char *cmd)
00274 {
00275 uint8_t ip_dot[STR_MAX_LENGTH];
00276 in_addr_t ip, netmask;
00277
00278
00279 while (*cmd == ' ') cmd++;
00280 if (*cmd == '\0')
00281 {
00282
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
00301 kprintf("\n\rIP address: ");
00302 gets(ip_dot);
00303 if ( !inet_aton(ip_dot, &ip) )
00304 {
00305
00306 ip = DEFAULT_IP_ADDR;
00307 }
00308 kprintf("\rNetmask : ");
00309 gets(ip_dot);
00310 if ( !inet_aton(ip_dot, &netmask) )
00311 {
00312
00313 netmask = DEFAULT_NETMASK_ADDR;
00314 }
00315
00316
00317 set_host_ip_net(ip, netmask);
00318
00319 eth_init_buffer();
00320
00321 arp_reset_cache();
00322
00323
00324 tcp_module_init();
00325
00326
00327 switch( rtl8139_init(strstr(cmd, "promisc") ? TRUE : FALSE) )
00328 {
00329 case ( 0 ):
00330
00331
00332 rtl8139_dump_info(rtl);
00333
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
00346
00347 set_host_ip_net(0, 0);
00348
00349 kfree( eth_recv_buf );
00350
00351 kprintf("\n\rRTL8139: cannot find an ethernet card!\n\r");
00352 break;
00353
00354 case ( -EIO ):
00355
00356
00357 set_host_ip_net(0, 0);
00358
00359 kfree( eth_recv_buf );
00360
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
00371 tcp_module_close();
00372
00373
00374 kfree( eth_recv_buf );
00375
00376 kill(eth_recv_thread1->pid);
00377 kill(eth_recv_thread2->pid);
00378
00379 arp_reset_cache();
00380
00381 rtl8139_close(&rtl);
00382 kprintf("\n\r");
00383 return;
00384 }
00385
00386
00387 kprintf("\n\rerror: %s unknown!\n\r", cmd);
00388 }