From 4c4ccd2a75ea821b397b1c527da3fc9778711cfa Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Sun, 17 May 2009 16:20:58 +0200 Subject: [PATCH] rtl8139, arp packet reception, ipv4 + arp integration --- arch/x86/rtl8139.cpp | 11 ++++++----- manes/start.cpp | 11 ++++------- resources/arp.cpp | 25 +++++++++++++------------ resources/arp.h | 15 +++++++-------- resources/ethernet.cpp | 3 ++- resources/ipv4.cpp | 11 +++++++++-- resources/ipv4.h | 15 +++++++++++++++ 7 files changed, 56 insertions(+), 35 deletions(-) diff --git a/arch/x86/rtl8139.cpp b/arch/x86/rtl8139.cpp index 453465b..511cbd0 100644 --- a/arch/x86/rtl8139.cpp +++ b/arch/x86/rtl8139.cpp @@ -15,9 +15,10 @@ void rtl8139::irq_handler() { if (status & 1) outw(id.ioport + isr, 0xffff); else { //if (status & 4) - delegate rec; - rec.method(this, &rtl8139::receive_packet); - manes::manec::get()->get("/asnych_tasks")->add_task(rec); + receive_packet(); + //delegate rec; + //rec.method(this, &rtl8139::receive_packet); + //manes::manec::get()->get("/asnych_tasks")->add_task(rec); } unlock_irqs(id.irq); @@ -70,8 +71,8 @@ void rtl8139::receive_packet() { u16 size; asm ("movw (%%eax), %%cx\n" : "=c" (size) : "a" ((u32)pkg + 2)); u8* buf = (u8*)0x200000; //new u8[size]; - asm ("rep; movsb\n" :: "c" (0x80), "S" (pkg), "D" (buf)); -asm("cli\nhlt"::"a"(0xb4654)); + asm ("rep; movsb\n" :: "c" (0x80), "S" (pkg), "D" (buf) : "memory"); + pkg = (packet*)buf; outl(id.ioport + capr, pkg->size); diff --git a/manes/start.cpp b/manes/start.cpp index eb19432..87972e5 100644 --- a/manes/start.cpp +++ b/manes/start.cpp @@ -160,18 +160,15 @@ extern "C" void _start() { ethernet eth; eth.set_nic(faar); - arp a; - a.set_link_layer(ð); - a.get_haddr(2 + (1 << 8) + (168 << 16) + (192 << 24)); - - char buff[] = "Hello World! This is Quarn OS 0.0.95-dev on the air!"; - ipv4 ip; ip.set_link_layer(ð); + ip.configure_ipv4(192 << 24 | 168 << 16 | 1 << 8 | 50, 255 << 24 | 255 << 16 | 255 << 8, 192 << 24 | 168 << 16 | 1 << 8 | 1); icmp ping; ping.set_ipv4(&ip); - ping.ping(192 << 24 | 168 << 16 | 1 << 8 | 2); +// ping.ping(192 << 24 | 168 << 16 | 1 << 8 | 2); + +// ping.ping(192 << 24 | 168 << 16 | 1 << 8 | 2); while(1); p floppy = main->get("/fdc"); p fs_floppy = main->get("/fat"); diff --git a/resources/arp.cpp b/resources/arp.cpp index 8c03f4e..ae871c6 100644 --- a/resources/arp.cpp +++ b/resources/arp.cpp @@ -26,21 +26,22 @@ mac_addr arp::get_haddr(ipv4_addr ipaddr) { pkg->tpa = to_be32(ipaddr); mac_addr broadcast = mac_addr::from_be(0xffffffff, 0xffff); - network->send_data(broadcast, 0x806, (void*)pkg, sizeof(arp_packet)); + network->send_data(broadcast, et_arp, (void*)pkg, sizeof(arp_packet)); -// arp_table::arp_record *rec = record; + arp_table::arp_record *rec = 0; do { - while (check_received()) __asm__("pause"); + while (!received) __asm__("hlt"); received = false; - // rec = table.get(ipaddr); - //rec = record; - } while (get_record() == 0); - asm("cli\nhlt"::"a"(get_record()->haddr.last_be32()), "b"(0xdaaf)); - return get_record()->haddr; + + rec = table.get(ipaddr); + } while (rec == 0); + + return rec->haddr; } void arp::receive_packet(arp_packet *pkg) { + asm("cli\nhlt"::"a"((u32)from_be16(pkg->oper))); if (from_be16(pkg->oper) == request) { if (from_be32(pkg->tpa) != my_paddr) return; @@ -65,7 +66,7 @@ void arp::receive_packet(arp_packet *pkg) { rpl->tha1 = mac.last_be32(); rpl->tpa = pkg->spa; - network->send_data(mac, 0x806, (void*)rpl, sizeof(arp_packet)); + network->send_data(mac, et_arp, (void*)rpl, sizeof(arp_packet)); } else if (from_be16(pkg->oper) == reply) { arp_table::arp_record *rec = new arp_table::arp_record; @@ -73,13 +74,13 @@ void arp::receive_packet(arp_packet *pkg) { rec->paddr = from_be32(pkg->spa); rec->haddr = mac_addr::from_be(pkg->sha0, pkg->sha1); - record = rec; - // table.add(rec); + table.add(rec); received = true; } } void arp::receive_data(void *buf, int length) { - receive_packet((arp_packet*)buf); + if (length >= sizeof(arp_packet)) + receive_packet((arp_packet*)buf); } diff --git a/resources/arp.h b/resources/arp.h index 3a397ad..38d534a 100644 --- a/resources/arp.h +++ b/resources/arp.h @@ -15,6 +15,11 @@ namespace resources { private: link_layer *network; + /* EtherType */ + enum { + et_arp = 0x806 + }; + enum { ethernet = 1 }; @@ -45,13 +50,7 @@ namespace resources { volatile bool received; - bool check_received() { - return received; - } - volatile arp_table::arp_record * volatile record; - arp_table::arp_record *get_record() { - return (arp_table::arp_record*)record; - } + arp_table table; void receive_data(void *, int); @@ -63,7 +62,7 @@ namespace resources { delegate rec; rec.method(this, &arp::receive_data); - x->add_handler(0x806, rec); + x->add_handler(et_arp, rec); } void set_ipv4(ipv4_addr); diff --git a/resources/ethernet.cpp b/resources/ethernet.cpp index 13a3a4d..f249877 100644 --- a/resources/ethernet.cpp +++ b/resources/ethernet.cpp @@ -41,7 +41,8 @@ void ethernet::receive_data(void *buffer, int size) { mac_addr addr = mac_addr::from_be(frm->dst0, frm->dst1); mac_addr broadcast = mac_addr::from_be(0xffffffff, 0xffff); - if (get_haddr() != addr && get_haddr() != broadcast) + if (get_haddr() != addr && addr != broadcast) +// asm("cli\nhlt"::"a"(0xbad),"b"(addr.last_be32())); return; int type = from_be16(frm->type); diff --git a/resources/ipv4.cpp b/resources/ipv4.cpp index 1efa353..ba22599 100644 --- a/resources/ipv4.cpp +++ b/resources/ipv4.cpp @@ -5,6 +5,8 @@ using namespace resources; void ipv4::set_link_layer(p x) { + arp_prot.set_link_layer(x); + network = x; my_ip = 192 << 24 | 168 << 16 | 1 << 8 | 50; } @@ -37,6 +39,11 @@ void ipv4::send_data(u32 addr, protocol prot, void *buff, int size) { memcpy((void*)&pkg[1], buff, size); - mac_addr broadcast = mac_addr::from_be(0xffffffff, 0xffff); - network->send_data(broadcast, 0x800, (void*)pkg, sizeof(ipv4_packet) + size); + mac_addr haddr; + if ((addr & mask) == (my_ip & mask)) + haddr = arp_prot.get_haddr(addr); + else + haddr = arp_prot.get_haddr(gateway); + + network->send_data(haddr, 0x800, (void*)pkg, sizeof(ipv4_packet) + size); } diff --git a/resources/ipv4.h b/resources/ipv4.h index 6384fc2..b2df7ae 100644 --- a/resources/ipv4.h +++ b/resources/ipv4.h @@ -2,13 +2,18 @@ #define _IPV4_H_ #include "link_layer.h" +#include "arp.h" namespace resources { class ipv4 { private: link_layer *network; + arp arp_prot; + u32 my_ip; + u32 mask; + u32 gateway; struct ipv4_packet { u8 version_size; @@ -23,6 +28,10 @@ namespace resources { u32 dst; //u32 opt; } __attribute__((packed)); + + protected: +// void receive_data(void *buf, int length); + public: enum protocol { icmp = 1, @@ -30,6 +39,12 @@ namespace resources { udp = 17 }; + void configure_ipv4(u32 ip, u32 netmask, u32 gate) { + my_ip = ip; + mask = netmask; + gateway = gate; + } + void set_link_layer(p x); void send_data(u32 addr, protocol prot, void *buff, int size); }; -- 2.11.4.GIT