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