00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "src/common/shared.hpp"
00011 #include "src/arch/x86/rtc.hpp"
00012 #include "src/collection/avltree.hpp"
00013 #include "src/collection/option.hpp"
00014 #include "src/ipc/lock.hpp"
00015 #include "src/common/prng.hpp"
00016 #include "src/memory/memset.hpp"
00017 #include "src/memory/align.hpp"
00018 #include "src/memory/heap.hpp"
00019 #include "src/thread/timer.hpp"
00020 #include "src/net/arp.hpp"
00021 #include "src/net/ip.hpp"
00022 #include "src/net/3c556.hpp"
00023
00024
00028 #define ARP_REBOOT_PACKET 1
00029
00030 #define ARP_REBOOT_DESTINATION 0x0300000E
00031 #define ARP_FREEZE_DESTINATION 0x0300000F
00032
00033
00037 namespace Net {
00038 namespace Arp {
00039
00040 struct Memory::Heap::heapbox arp_heapbox;
00041
00042
00043 struct arp_ethernet_packet {
00044 short hw_type;
00045 short prot_type;
00046 char hw_size;
00047 char prot_size;
00048 short opcode;
00049 struct ethernet_address sender_eth;
00050 struct ip_address sender_ip;
00051 struct ethernet_address target_eth;
00052 struct ip_address target_ip;
00053 } __attribute__ ((packed));
00054
00055 void arp_transmit(struct netif *nif,
00056 short opcode,
00057 struct ethernet_addr packet_destination,
00058 struct ethernet_addr sender_eth, struct ip_address sender_ip,
00059 struct ethernet_address target_eth, struct ip_address target_ip);
00060
00065 void arp_transmit(struct netif *nif, short opcode, struct ethernet_address destination_eth, struct ethernet_address target_eth, struct ip_address target_ip) {
00066 struct netbuf *nb;
00067 nb = netbuf_alloc(sizeof(struct arp_ethernet_packet));
00068 #if 0
00069 dbPrintInt((uint32)nb->data);
00070 dbSetRow(0);
00071 #endif
00072 struct arp_ethernet_packet *arp = reinterpret_cast<struct arp_ethernet_packet*>(nb->data);
00073 arp->hw_type=htons(0x0001);
00074 arp->prot_type=htons(0x0800);
00075 arp->hw_size=6;
00076 arp->prot_size=4;
00077 arp->opcode=htons(opcode);
00078 arp->sender_eth=nif->eth_addr;
00079 arp->sender_ip=nif->ip_addr;
00080 arp->target_eth=target_eth;
00081 arp->target_ip=target_ip;
00082 testifdbg( nb->len != 0);
00083 eth_transmit(nif, destination_eth, 0x0806, nb);
00084 }
00085
00086 void arp_transmit_request(struct netif *nif, struct ethernet_address destination_eth, struct ip_address target_ip) {
00087 arp_transmit(nif, 0x0001, destination_eth, ethernet_address(0,0,0,0,0,0), target_ip);
00088 #if 0
00089 struct netbuf *nb;
00090 nb = netbuf_alloc(sizeof(struct arp_ethernet_packet));
00091 struct arp_ethernet_packet *arp = reinterpret_cast<struct arp_ethernet_packet*>(nb->data);
00092 arp->hw_type=htons(0x0001);
00093 arp->prot_type=htons(0x0800);
00094 arp->hw_size=6;
00095 arp->prot_size=4;
00096 arp->opcode=htons(0x0001);
00097 arp->sender_eth=nif->eth_addr;
00098 arp->sender_ip=nif->ip_addr;
00099 arp->target_eth=ethernet_address(0,0,0,0,0,0);
00100 arp->target_ip=ip_addr;
00101 eth_transmit(nif, ethernet_address(0xFF,0xFF,0xFF,0xFF,0xFF,0xFF), 0x0806, nb);
00102 #endif
00103 }
00104
00105 void arp_transmit_reply(struct netif *nif, struct ethernet_address target_eth, struct ip_address target_ip) {
00106 arp_transmit(nif, 0x0002, target_eth, target_eth, target_ip);
00107 }
00108
00109 #if 0
00110 struct arp_entry {
00111 struct netif *nif;
00112 struct Collection::Option<struct ethernet_address> eth_addr;
00113 struct ip_address ip_addr;
00114 uint64 expire;
00115 uint64 retry;
00116 uint32 retries;
00117 };
00118
00119 int inline arp_entry_cmp(struct arp_entry a, struct arp_entry b) {
00120 return Collection::generic_cmp<uint64>(a.retry, b.retry);
00121 }
00122
00123 struct Collection::AvlTree<struct arp_entry, arp_entry_cmp> *arp_cache;
00124 class IPC::Lock::lock_t arp_cache_lock(const_cast<char*>("arp cache"));
00125
00126 void arp_cache_insert(struct netif *nif, struct ip_address ip, struct ethernet_address eth) {
00127 arp_cache_lock.lock();
00128 struct arp_entry arp;
00129 arp.nif = nif;
00130 arp.eth_addr = Collection::Option<struct ethernet_address>(eth);
00131 arp.ip_addr = ip;
00132 arp.retry = arp.expire = Arch::x86::RTC::up_time + DEF_SECOND*3;
00133 arp.retries=0;
00134 arp_cache->insert(arp);
00135
00136 lnDbg;
00137
00138 arp_cache_lock.ulock();
00139 }
00140
00141
00142 int arpTimer(int a, int b) {
00143 arp_cache_lock.lock();
00144 struct arp_entry arp;
00145 struct Collection::Option<struct arp_entry> arp_opt;
00146 uint64 time = Arch::x86::RTC::up_time;
00147
00148 struct Collection::AvlTree<struct arp_entry, arp_entry_cmp> arp_pom;
00149
00150 for (arp_opt = arp_cache->findMin();
00151 !arp_opt.isNone() && arp_opt.get().retry <= time;
00152 arp_opt = arp_cache->findMin()) {
00153 arp = arp_opt.get();
00154 arp_cache->remove(arp);
00155 if (arp.expire > time)
00156 arp_pom.insert(arp);
00157 }
00158
00159
00160 for (arp_opt = arp_pom.findMin();
00161 !arp_opt.isNone();
00162 arp_opt = arp_pom.findMin()) {
00163 arp = arp_opt.get();
00164 arp_pom.remove(arp);
00166 arp_transmit_request(arp.nif, ethernet_address(0xff,0xff,0xff,0xff,0xff,0xff), arp.ip_addr);
00167 if (arp.retries == 1)
00168 arp.retry += PRNG::nextUint32(200);
00169 if (arp.retries == 2)
00170 arp.retry += PRNG::nextUint32(1024);
00171 if (arp.retries == 3)
00172 arp.retry += PRNG::nextUint32(1024*5);
00173 if (arp.retries >= 4)
00174 arp.retry += PRNG::nextUint32(1024*arp.retries*5);
00175 if (arp.retry < arp.expire)
00176 arp_cache->insert(arp);
00177 arp.retries ++;
00178 }
00179
00180 arp_cache_lock.ulock();
00181
00182 return 1;
00183 }
00184 #endif
00185
00186
00187 using namespace Collection;
00188
00189 int arp_entry_cmp(struct arp_entry a, struct arp_entry b) {
00190 return generic_cmp<uint32>(a.ip_addr.ip, b.ip_addr.ip);
00191 }
00192
00193 struct AvlTree<struct arp_entry,arp_entry_cmp> *arp_cache;
00194 struct IPC::Lock::lock_t arp_cache_lock(const_cast<char*>("arp_cache"));
00195
00196 void arp_cache_insert(struct netif *nif, struct ip_address ip_addr, struct ethernet_address eth_addr) {
00197 arp_cache_lock.lock();
00198 struct arp_entry arp;
00199 arp.ip_addr=ip_addr;
00200 if (arp_cache->find(arp).isNone()==false) {
00201 arp_cache_lock.ulock();
00202 return ;
00203 }
00204
00205 assert(arp.ip_addr.ip == ip_addr.ip);
00206 arp.nif=nif;
00207 arp.eth_addr=eth_addr;
00208
00209
00211
00212 arp_cache->insert(arp);
00213
00214 arp_cache_lock.ulock();
00215 uint32 fl;
00216 ENTER_CRITICAL(fl);
00217 #if 0
00218 do {
00219 struct arp_entry a;
00220 a.eth_addr.d[0]=0x22;
00221 a.ip_addr=0x03000001;
00222 struct ethernet_address e= arp_get_cached_ether(a.ip_addr).get();
00223 e = arp_cache->find(a).get().eth_addr;
00224
00225 for (int i=0;i<6;i++)
00226 kprintf("%x:",e.d[i]);
00227 kprintf("\n");
00228 arp_cache->write();
00229 } while(0);
00230 for(;;);
00231 #endif
00232 Net::IP::ip_onNewArpEntry(arp);
00233 }
00234
00235 struct Option<struct ethernet_address> arp_get_cached_ether(struct ip_address ip) {
00236 struct arp_entry arp;
00237 arp.ip_addr=ip;
00238 struct Option<struct arp_entry> opt = arp_cache->find(arp);
00239 if (opt.isNone())
00240 return Option<struct ethernet_address>();
00241 return Option<struct ethernet_address>(opt.get().eth_addr);
00242 }
00243
00244 int arp_request_timer(struct arp_entry *arp, int T) {
00245 if (arp_get_cached_ether(arp->ip_addr).isNone() == false) {
00246 arp_heapbox.free(arp);
00247 return 0;
00248 }
00249
00250 if (T > 2*2*2*2*2*2*100)
00251 return 0;
00252
00253 arp_transmit_request(arp->nif, ethernet_address(0xff,0xff,0xff,0xff,0xff,0xff), arp->ip_addr );
00254 Thread::Timer::add(reinterpret_cast<int(*)(int,int)>(arp_request_timer), T/2+T+PRNG::nextUint32(T/2), reinterpret_cast<uint32>(arp), T/2+T+PRNG::nextUint32(T/2) );
00255
00256
00257 return 0;
00258 }
00259
00260 struct Option<struct ethernet_address> arp_get_ether(struct ip_address ip) {
00261 struct Option<struct ethernet_address> opt;
00262 opt = arp_get_cached_ether(ip);
00263 if (opt.isNone() == false)
00264 return opt;
00265 struct arp_entry *arp = static_cast<struct arp_entry*>(arp_heapbox.malloc(sizeof(struct arp_entry),1,"arp entry",null));
00266 arp->ip_addr= ip;
00268 arp->nif=e3c556_nif;
00269 Thread::Timer::add(reinterpret_cast<int(*)(int,int)>(arp_request_timer), 1, reinterpret_cast<uint32>(arp), 100);
00270 return Option<struct ethernet_address>();
00271 }
00272 #if 0
00273 int arpTimer(int a, int b) {
00274 return 0;
00275 }
00276 #endif
00277
00278
00279 void init() {
00280 allocate_heapbox(&arp_heapbox, "arp");
00281 arp_cache = new AvlTree<struct arp_entry, arp_entry_cmp>;
00282 }
00283
00284 using namespace Collection;
00285
00286 struct AvlTree<uint32,generic_cmp<uint32> > *arp_pom;
00287
00288 void processArpPacket(struct netbuf *nb) {
00289 struct arp_ethernet_packet *arp;
00290 arp = reinterpret_cast<struct arp_ethernet_packet*>(&nb->data[14]);
00291
00292
00293 if (arp->hw_type==htons(0x0001) && arp->prot_type==htons(0x0800) && arp->hw_size==6 && arp->prot_size==4) {
00294 #if ARP_REBOOT_PACKET
00295
00298 if (arp->target_ip.ip == ip_address(ARP_REBOOT_DESTINATION).ip) {
00300 complain("special ARP packet forces to reboot");
00301 reboot();
00302 }
00303 if (arp->target_ip.ip == ip_address(ARP_FREEZE_DESTINATION).ip) {
00304 complain("special ARP packet forces to freeze");
00305 asm volatile("cli\nhlt");
00306 }
00307
00309 #endif
00310
00311 if (arp->target_ip.ip==nb->nif->ip_addr.ip) {
00312 if (arp->opcode == htons(0x0001)) {
00313
00314 if (arp_pom == null)
00315 arp_pom = new Collection::AvlTree<uint32, generic_cmp<uint32> >;
00316
00317 if (arp_pom->find(arp->sender_ip.ip).isNone()) {
00318 arp_transmit_reply(nb->nif, arp->sender_eth, arp->sender_ip);
00319 Thread::Timer::avltree_insert_with_timer(200, arp_pom, arp->sender_ip.ip);
00320
00322 arp_cache_insert(nb->nif, arp->sender_ip, arp->sender_eth);
00323 }
00324 } else if (arp->opcode == htons(0x0002)) {
00325
00327 arp_cache_insert(nb->nif, arp->sender_ip, arp->sender_eth);
00328 }
00329 }
00330 }
00331
00332
00333 netbuf_free(nb);
00334 }
00335
00336 struct Collection::Option<struct ethernet_address> arp_get_cached_ether(struct ip_address ip);
00337 struct Collection::Option<struct ethernet_address> arp_get_ether(struct ip_address ip);
00338
00339 }
00340 }
00341