00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "src/collection/list.hpp"
00011 #include "src/common/shared.hpp"
00012 #include "src/common/kmalloc.hpp"
00013 #include "src/memory/memset.hpp"
00014 #include "src/memory/align.hpp"
00015 #include "src/memory/heap.hpp"
00016 #include "src/memory/pager.hpp"
00017 #include "src/arch/x86/pcibios.hpp"
00018 #include "src/arch/x86/interr.hpp"
00019 #include "src/arch/x86/gdt.hpp"
00020 #include "src/tty/teletype.hpp"
00021 #include "src/net/3c556.hpp"
00022 #include "src/net/net.hpp"
00023 #include "src/net/arp.hpp"
00024 #include "src/net/ip.hpp"
00025 #include "src/thread/process.hpp"
00026 #include "src/thread/scheduler.hpp"
00027 #include "src/thread/timer.hpp"
00028 #include "src/ipc/lock.hpp"
00029
00030
00036
00037
00038 extern int e3c556_irq(struct Arch::x86::Interr::except2_t *code);
00039
00040
00041
00042
00043
00044
00045 void print(struct Net::ip_address ip) {
00046 uint8 *d = reinterpret_cast<uint8*>(&ip.ip);
00047 kprintf("%d.%d.%d.%d", d[0],d[1],d[2],d[3]);
00048 }
00049
00050 void print(struct Net::ethernet_address eth) {
00051 for (int i=0;i<6;i++) {
00052 if (eth.d[i] < 16) {
00053 if (i!=5)
00054 kprintf("0%x:", eth.d[i]);
00055 else
00056 kprintf("0%x", eth.d[5]);
00057 } else {
00058 if (i!=5)
00059 kprintf("%x:", eth.d[i]);
00060 else
00061 kprintf("%x", eth.d[5]);
00062 }
00063 }
00064 }
00065
00069 #define PRINT_NETBUF_PACKET_BYTES 80
00070
00073 void print(struct Net::netbuf nb) {
00074 prin("(netbuf: len=", nb.len, ", nif=", (nb.nif!=null?nb.nif->name:"null"),", dt=");
00075 char ltrs[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
00076 int i;
00077 for (i=0; i<MIN(nb.len, PRINT_NETBUF_PACKET_BYTES); i++) {
00078 if (nb.data[i]<16) putch('0');
00079 else putch(ltrs[nb.data[i]>>4]);
00080 putch(ltrs[nb.data[i]&0xf]);
00081 putch(' ');
00082
00083
00084 }
00085 if (i < nb.len)
00086 print("...");
00087 putch(')');
00088 }
00089
00090
00091 namespace Net {
00092
00093 #if 0
00094
00103 struct size_and_frame *size_and_frame_curr;
00104 #endif
00105
00106 struct stack_t frame_stack;
00107
00108 struct Collection::List<struct netif> netif_list;
00109
00110 class IPC::Lock::lock_t frame_stack_lock;
00111
00112 uint16 htons(uint16 hostshort) {
00113 return (hostshort << 8) + (hostshort >> 8);
00114 }
00115 uint16 ntohs(uint16 netshort) {
00116 return (netshort << 8) + (netshort >> 8);
00117 }
00118
00119 uint32 htonl(uint32 hostlong) {
00120 return (hostlong >> 24) + ((hostlong & 0x00FF0000) >> 8) + ((hostlong & 0x0000FF00)<<8) + ((hostlong & 0x000000FF)<<24);
00121 }
00122
00123 uint32 ntohl(uint32 netlong) {
00124 return (netlong >> 24) + ((netlong & 0x00FF0000) >> 16) + ((netlong & 0x0000FF00)>>8) + ((netlong & 0x000000FF));
00125 }
00126
00127
00133 void EthernetFrameReceptionThread() {
00134
00135 #if 1
00136 while(1) {
00137 struct Collection::List<struct netif>::ListNode *nif;
00138 for (nif= netif_list.head; nif; nif= nif->next) {
00139
00140 nif->v.poll(nif->v.netbuf_curr->data, &nif->v.netbuf_curr->len);
00141 }
00142 Thread::sleep(10);
00143 }
00144
00145
00146 #endif
00147
00148
00149 Thread::ThreadKill((Thread::thread_t*)current_thread);
00150 #if 0
00151 size_and_frame_curr= static_cast<struct size_and_frame*>(kmalloc(sizeof(size_and_frame), "ethernet frame"));
00152 while (1) {
00153 if (e3c556_poll(size_and_frame_curr->frame,&size_and_frame_curr->len)==1) {
00154 frame_stack_lock.lock2();
00155 frame_stack.push(reinterpret_cast<uint32>(size_and_frame_curr));
00156 #if 0
00157 for (int i=0;i<15;i++)
00158 kprintf("%x ", static_cast<uint8>(size_and_frame_curr->frame[i]));
00159 kprintf("\n");
00160 #endif
00161
00162
00163 size_and_frame_curr= static_cast<struct size_and_frame*>(kmalloc(sizeof(size_and_frame),"ethernet frame"));
00164 frame_stack_lock.ulock();
00165 }
00166 Thread::sleep(100);
00167 }
00168 #endif
00169 }
00170 #if DEBUG_ETH_TIMES
00171 volatile uint32 __debug_eth_time;
00172 inline void eth_dbg_write(char *name) {
00173 kprintf("%s: %x\n", name, Arch::x86::RTC::up_time-__debug_eth_time);
00174 __debug_eth_time= Arch::x86::RTC::up_time;
00175 }
00176 #else
00177 #define eth_dbg_write(...) do {} while(0)
00178 #endif
00179
00180 void EthernetFrameDemultiplexingThread() {
00181 while(1) {
00182 struct netbuf *nb;
00183 while (Net::eth_poll(&nb) == 1) {
00184 testif(nb!=null);
00185 testif(nb->data!=null);
00186 testif(nb->nif!=null);
00187 if (nb->len > 1518) {
00188 println(*nb);
00189 complain("frame length erroneus");
00190 }
00191
00192 #if 0
00193 int i;
00194 for (i=6;i<11;i++) {
00195 kprintf("%x%x:", (uint8)nb->data[i]>>8, (uint8)nb->data[i]&0xf);
00196 }
00197 kprintf("%x%x", (uint8)nb->data[i]>>8, (uint8)nb->data[i]&0xf);
00198 kprintf("\n");
00199 #endif
00200 bool drop_packet=true;
00201
00202 #if 0
00203 for (i=0;i<14;i++)
00204 kprintf(">%x:",(uint8)nb->data[i]);
00205
00206 kprintf("--%x\n", nb->data[0]==0xFF);
00207 #endif
00208
00209
00210 if (nb->data[0] == 0xFF && nb->data[1] == 0xFF && nb->data[2] == 0xFF &&
00211 nb->data[3] == 0xFF && nb->data[4] == 0xFF && nb->data[5] == 0xFF) {
00212 if (nb->data[12] == 0x08 && nb->data[13] == 0x06) {
00213
00214 drop_packet=false;
00215 Net::Arp::processArpPacket(nb);
00216 }
00217 }
00218 #if 0
00219 kprintf("-> %x\n", nb->nif);
00220 for (i = 0;i<6;i++) {
00221 kprintf("($%x:", nb->nif->eth_addr.d[i]);
00222 kprintf("$%x:", nb->data[i]);
00223 kprintf("$%x) ", nb->data[i]==nb->nif->eth_addr.d[i]);
00224 }
00225 kprintf("\n");
00226 #endif
00227 #if 0
00228
00229 kprintf(" - 2 - %x %x\n",
00230 nb->data[0] == nb->nif->eth_addr.d[0] && nb->data[1] == nb->nif->eth_addr.d[1] && nb->data[2] == nb->nif->eth_addr.d[1],
00231 (nb->data[0] == nb->nif->eth_addr.d[0]) && (nb->data[1] == nb->nif->eth_addr.d[1]) && (nb->data[2] == nb->nif->eth_addr.d[1])
00232 );
00233
00234
00235 #endif
00236
00237 if (nb->data[0] == nb->nif->eth_addr.d[0] && nb->data[1] == nb->nif->eth_addr.d[1] &&
00238 nb->data[2] == nb->nif->eth_addr.d[2] && nb->data[3] == nb->nif->eth_addr.d[3] &&
00239 nb->data[4] == nb->nif->eth_addr.d[4] && nb->data[5] == nb->nif->eth_addr.d[5]) {
00240 if (nb->data[12] == 0x08 && nb->data[13] == 0x06) {
00241 drop_packet= false;
00242 Net::Arp::processArpPacket(nb);
00243 }
00244 if (nb->data[12] == 0x08 && nb->data[13] == 0x00) {
00245 drop_packet=false;
00246 Net::IP::onIpReception(nb);
00247 }
00248 }
00249
00250 if (drop_packet)
00251
00252 netbuf_free(nb);
00253 }
00254 Thread::sleep(1);
00255 }
00256 }
00257
00258
00259 struct Memory::Heap::heapbox pbuf_heapbox;
00260
00261 struct netbuf *netbuf_alloc(uint32 datasize) {
00262 struct netbuf *nb= static_cast<struct netbuf*>(Memory::Heap::heap0.malloc(sizeof(struct netbuf),1,"netbuf",null));
00263 nb->data= static_cast<uint8*>(Memory::Heap::heap0.malloc(datasize,1,"netbuf::data",null));
00264 nb->next=null;
00265 nb->len=datasize;
00266 nb->freeptr=nb->data;
00267 testifdbg(nb!=null);
00268 testifdbg(nb->data!=null);
00269 return nb;
00270 }
00271
00272 void netbuf_free(struct netbuf *nb) {
00273 Memory::Heap::heap0.free(nb->data);
00274
00275 Memory::Heap::heap0.free(nb);
00276 }
00277
00278
00279
00280 struct packet_t *pbuf_alloc(uint32 capacity) {
00281 struct packet_t *p;
00282 p = static_cast<struct packet_t*>(pbuf_heapbox.malloc(sizeof(struct packet_t),1,"pbuf",null));
00283 p->capacity=capacity;
00284 p->buf = static_cast<uint8*>(pbuf_heapbox.malloc(capacity,1,"pbuf->buf",null));
00285 p->off=0;
00286 p->end=0;
00287
00288 return p;
00289 }
00290
00291 void pbuf_free(struct packet_t *&p) {
00292 testif(p!=null);
00293 testif(p->buf!=null);
00294 pbuf_heapbox.free(p->buf);
00295 pbuf_heapbox.free(p);
00296 p=null;
00297 }
00300 void init()
00301 {
00302 Memory::Heap::allocate_heapbox(&pbuf_heapbox, "pbuf");
00303 if (init_3c556() == 0)
00304 return;
00305
00306
00307
00308 frame_stack.nw(null,0);
00309 frame_stack.setExpandable();
00310
00311
00312
00313 Thread::kernel_process.create_thread(true, (uint32)&EthernetFrameReceptionThread, 4, 2, const_cast<char*>("net ether reception"));
00314 Thread::kernel_process.create_thread(true, (uint32)&EthernetFrameDemultiplexingThread, 4, 2, const_cast<char*>("net ether demulti"));
00315
00316
00317 #if 0
00318 char x[20];
00319 char d[6]={0x13, 0x25, 0x37, 0x49,0x5b, 0x6d};
00320 x[4]='?';
00321 x[5]='!';
00322
00323 for (int i=0;i<2;i++) {
00324 e3c556_transmit(d, 13, 123, x);
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 #endif
00338 }
00339
00340
00341
00345 int init_3c556() {
00346 struct bios32_service_directory_struct *b32;
00347 uint32 cseg_size, base_addr, offset;
00348 b32= find_bios32_service_directory_header();
00349 if (b32==NULL) { kprintf("The BIOS32 service directory is unavaillable.\n"); return 0;}
00350
00351 if (bios32_service(b32, 0x49435024, &cseg_size, &offset, &base_addr)==-1)
00352 { kprintf("PCI32 service is unavaillable! *shivers*\n"); return 0;}
00353 if (!pci32_installation_check(offset+base_addr))
00354 { kprintf("PCI32 installation check failed\n"); return 0;}
00355
00356 uint32 vendor_no, foo,bar,bus_no;
00357 uint8 bu_,de_;
00358 int flag=0;
00359 Pci32_Addr=offset+base_addr;
00360 kprintf("num\t\tclass\tsubclass\tvendor\tdevice\n");
00361 for (bus_no=0;bus_no<3;bus_no++)
00362 for (bar=0; bar <0x20;bar++)
00363 {
00364 if (pci32_read_configuration_dword(&vendor_no, offset+base_addr, bus_no, bar, 0, PCI32_DEVICEID))
00365 if (vendor_no==0xffffffff)
00366 continue;
00367 if (LOWORD(vendor_no)==0x10b7)
00368 if (HIWORD(vendor_no)==0x6055)
00369 {bu_=bus_no; de_=bar;flag=1;}
00370 pci32_read_configuration_dword(&foo, offset+base_addr,bus_no, bar, 0, PCI32_CLASS);
00371 if (PCI_BASECLASS(foo) == 0xff)
00372 continue;
00373
00374 kprintf("(%d:%d:0) \t", bus_no, bar);
00375 kprintf("%s\t%s\t", pci32_base_class_name(PCI_BASECLASS(foo)),
00376 pci32_sub_class_name(PCI_BASECLASS(foo),PCI_SUBCLASS(foo)));
00377 kprintf("%s\t%x", pci32_vendor_name(LOWORD(vendor_no)), HIWORD(vendor_no));
00378 kprintf("\n");
00379 }
00380 if (flag == 1) {
00381 Arch::x86::Interr::add2interr_chain(0x2b, &e3c556_irq);
00382 struct Net::netif nif;
00383 nif.ip_addr=Net::IP::my_ip_address();
00384 nif.netmask=Net::IP::my_netmask();
00385 nif.name[0]='e';
00386 nif.name[1]='t';
00387 nif.name[2]='h';
00388 nif.name[3]='0';
00389 nif.name[4]='\0';
00390 nif.transmit= reinterpret_cast<void (*) (uint8*,uint32,uint32,uint8*)>(e3c556_transmit);
00391 nif.poll= reinterpret_cast<int(*)(uint8*,uint32*)>(e3c556_poll) ;
00392 netif_list.push_front( nif );
00394 netif_list.head->v.netbuf_curr->nif= &netif_list.head->v;
00395 e3c556_probe(bu_,de_,&netif_list.head->v);
00396 }
00397 return flag;
00398 }
00399
00400
00401
00402
00404 struct netbuf * onFramesReceived ( struct netif *nif ) {
00405 eth_dbg_write("\n\non-recv");
00406
00407 frame_stack_lock.lock2();
00408 #if 0
00409 if (size_and_frame_curr->len != 0) {
00410 frame_stack.push(reinterpret_cast<uint32>(size_and_frame_curr));
00411 size_and_frame_curr = static_cast<struct size_and_frame*>(kmalloc(sizeof(struct size_and_frame),"packet buffer"));
00412 }
00413 #endif
00414 #if DUMP_INBOUND_ETHERNET_FRAMES
00415 kprintf(" [ in: ");
00416 int i;
00417 for (i=0;i<MIN(DUMP_INBOUND_ETHERNET_FRAMES_BYTES,nif->netbuf_curr->len);i++)
00418 kprintf("%x ", (uint8) nif->netbuf_curr->data[i]);
00419 if (i < nif->netbuf_curr->len)
00420 kprintf(" ... ");
00421 kprintf(" ] \n");
00422 #endif
00423
00424 if (nif->netbuf_curr->len != 0) {
00425 frame_stack.push(reinterpret_cast<uint32>(nif->netbuf_curr));
00426 nif->netbuf_curr = netbuf_alloc(1518);
00427 nif->netbuf_curr->nif=nif;
00428 }
00429 frame_stack_lock.ulock();
00430
00431
00432 return nif->netbuf_curr;
00433 }
00434
00438 int eth_poll(struct netbuf **nb) {
00439 frame_stack_lock.lock2();
00440 if (frame_stack.lgth() == 0) {
00441 frame_stack_lock.ulock();
00442 return 0;
00443 }
00444
00445 *nb = reinterpret_cast<struct netbuf*>(frame_stack.pop());
00446
00447 frame_stack_lock.ulock();
00448
00449 return 1;
00450 }
00451
00452 void onFramesTransmitted(struct netif *nif) {
00453 nif->outbound_lock.lock();
00454 struct outbound_packet out= nif->outbound.pop_back();
00456 netbuf_free(out.nb);
00457
00458
00459
00460
00461 if (!nif->outbound.isEmpty()) {
00462 out = nif->outbound.get_front();
00463 nif->outbound_lock.ulock();
00464 #if DUMP_OUTBOUND_ETHERNET_FRAMES
00465 kprintf("[ out: ");
00466 uint32 i;
00467 for (i=0; i<MIN(DUMP_OUTBOUND_ETHERNET_FRAMES_BYTES, out.nb->len);i++)
00468 kprintf("%x ", (uint8)out.nb->data[i]);
00469 if (i < out.nb->len)
00470 kprintf(" ... ");
00471 kprintf("]\n");
00472 #endif
00473 out.nb->len = MAX(46, out.nb->len);
00474 nif->transmit(out.eth_addr.d, out.t, out.nb->len, out.nb->data);
00475 return ;
00476 }
00477
00478 nif->outbound_lock.ulock();
00479 return ;
00480
00481 }
00482
00488 void eth_transmit(struct netif *nif, struct ethernet_address eth_addr, unsigned int t, struct netbuf *nb) {
00489 uint32 fl;
00490
00491 asm volatile("pushf\npopl %0\ncli" : "=g" (fl));
00492 nif->outbound_lock.lock();
00493 bool empty = nif->outbound.isEmpty();
00494 nif->outbound.push_front(outbound_packet(eth_addr,t,nb));
00497 if (empty) {
00498 #if DUMP_OUTBOUND_ETHERNET_FRAMES
00499 kprintf("[ out: ");
00500 uint32 i;
00501 for (i=0; i<MIN(DUMP_OUTBOUND_ETHERNET_FRAMES_BYTES, nb->len);i++)
00502 kprintf("%x ", (uint8)nb->data[i]);
00503 if (i < nb->len)
00504 kprintf(" .... ");
00505 kprintf("]\n");
00506 #endif
00507 nb->len = MAX(46, nb->len);
00508 nif->transmit(eth_addr.d, t, nb->len, nb->data);
00509 }
00510
00511 nif->outbound_lock.ulock();
00512 asm volatile("pushl %0\npopf" : :"g"(fl));
00513 }
00514 #if 0
00515 typedef uint16 u16;
00516 typedef uint32 u32;
00517 u16 ip_sum_calc(u16 len_ip_header, u16 buff[])
00518 {
00519 u16 word16;
00520 u32 sum=0;
00521 u16 i;
00522
00523
00524
00525 for (i=0;i<len_ip_header;i=i+2){
00526 word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
00527 sum = sum + (u32) word16;
00528 }
00529
00530
00531 while (sum>>16)
00532 sum = (sum & 0xFFFF)+(sum >> 16);
00533
00534
00535 sum = ~sum;
00536
00537 return ((u16) sum);
00538 }
00539 #endif
00540
00541
00542 uint16 count_checksum16(uint16 *data, uint32 len) {
00543 uint32 ret=0;
00544 for (uint32 i = 0; i<(len&0xFFFFFFFE);i=i+2) {
00545 ret += data[i/2];
00546 if (ret > 0xffff)
00547 ret -= 0xffff;
00548 }
00549 if (len & 1)
00550 ret += ((uint8*)data)[len-1];
00551 if (ret > 0xffff)
00552 ret -= 0xffff;
00553
00554 #if 0
00555 for (int i=0;i<len;i++) {;prin(((uint8*)data)[i], ":");} println();
00556 #endif
00557 if (ret == 0xFFFF)
00558 return 0xFFFF;
00559 return ~(uint16)ret;
00560 }
00561
00562 #if 0
00563 stack_t frame_stack;
00566 void store_frame(char *packet, uint32 packetlen) {
00567 frame_stack.push(10);
00568
00569 }
00570 #endif
00571
00572
00573 }
00574