Added (hacky) ne2k functionality. Modified syscall server for udp.
authorPaul Pearce <pearce@eecs.berkeley.edu>
Thu, 1 Oct 2009 05:53:25 +0000 (01:53 -0400)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 1 Oct 2009 20:09:52 +0000 (22:09 +0200)
With this commit we can now do remote system calls entirely inside a VM.
Yay.

The majority of this commit is a new ne2k.c/h that allows packet sending
and receiving. In support of this was a new nic_common.c/h framework
that broke some of the common def's and vars into a central location
and syscall.c now relies upon this.

Newlib_backend now keys off of __NETWORK__ when deciding how to ship out
syscalls.

Modified the syscall server to work with UDP. Added new generic read/write
functions for the pipe and pty methods, as the udp method needs more
complicated functionality than just read().

Note: Not tested with ivy. Not tested with old RealTek nic in hardware.
This is mainly a WIP commit.

19 files changed:
.gitignore
kern/arch/i386/Makefrag
kern/arch/i386/ne2k.c
kern/arch/i386/ne2k.h
kern/arch/i386/nic_common.c [new file with mode: 0644]
kern/arch/i386/nic_common.h [new file with mode: 0644]
kern/arch/i386/rl8168.c
kern/arch/i386/rl8168.h
kern/src/syscall.c
tools/syscall_server/Makefile
tools/syscall_server/pipe.c [new file with mode: 0644]
tools/syscall_server/pipe_init.c [deleted file]
tools/syscall_server/pty.c [new file with mode: 0644]
tools/syscall_server/pty_init.c [deleted file]
tools/syscall_server/syscall_server.c
tools/syscall_server/syscall_server.h
tools/syscall_server/udp.c [new file with mode: 0644]
user/apps/parlib/run_binary.c
user/parlib/src/i386/newlib_backend.c

index 229eaac..3d522ad 100644 (file)
@@ -23,3 +23,6 @@ kern/src/arch
 doc/rosdoc
 sim/
 tools/.*
+tools/syscall_server/syscall_server_*
+tools/syscall_server/sandbox/
+tools/syscall_server/apps/*
index 9ffe2f7..347cf95 100644 (file)
@@ -31,5 +31,6 @@ KERN_ARCH_SRCFILES := $(KERN_ARCH_SRC_DIR)/entry.S \
                       $(KERN_ARCH_SRC_DIR)/ioapic.c \
                       $(KERN_ARCH_SRC_DIR)/rl8168.c \
                       $(KERN_ARCH_SRC_DIR)/ne2k.c \
+                      $(KERN_ARCH_SRC_DIR)/nic_common.c \
                       $(KERN_ARCH_SRC_DIR)/init.c \
                       $(KERN_ARCH_SRC_DIR)/env.c
index 8634f8c..8811c34 100644 (file)
 /** @file
  * @brief NE2K Driver Sketch
  *
- * EXPERIMENTAL. DO NOT USE IF YOU DONT KNOW WHAT YOU ARE DOING
+ * EXPERIMENTAL.
  *
- * This driver will attempt to detect a ne2k device and run some interrupt
- * tests. This is used for ioapic debugging in simulation
+ * Rough driver. Appears to work in QEMU. Probably completely broken under heavy load.
  *
  * @author Paul Pearce <pearce@eecs.berkeley.edu>
  *
  * @todo Everything
  */
 
+#define NE2K_RESET_R_ADDR 0x1f
+#define NE2K_PG0_RW_CR 0x00
+#define NE2K_PG0_RW_ISR 0x07
+#define NE2K_PG0_W_IMR 0x0F
+#define NE2K_PG0_W_PSTRT 0x1
+#define NE2K_PG0_W_PSTP 0x2
+#define NE2K_PG0_W_RCR 0xC
+#define NE2K_PG0_R_RSR 0xC
+#define NE2K_PG0_R_TSR 0x4
+#define NE2K_PG0_W_TCR 0xD
+#define NE2K_PG1_RW_PAR 0x1
+#define NE2K_PG0_W_RSAR0 0x08
+#define NE2K_PG0_W_RSAR1 0x09
+#define NE2K_PG0_W_RBCR0 0x0A
+#define NE2K_PG0_W_RBCR1 0x0B
+#define NE2K_PG0_W_TBCR0 0x05
+#define NE2K_PG0_W_TBCR1 0x06
+#define NE2K_PG0_W_TPSR  0x04
+#define NE2K_PG0_W_DCR 0x0E
+#define NE2K_PG1_RW_CURR 0x07
+#define NE2K_PG0_RW_BNRY 0x03
+
+#define NE2K_PAGE_SIZE 256
+
+#define NE2K_PMEM_START   (16*1024)
+#define NE2K_PMEM_SIZE   (32*1024)
+#define NE2K_NUM_PAGES                 ((NE2K_PMEM_SIZE - NE2K_PMEM_START) / NE2K_PAGE_SIZE)
+#define NE2K_NUM_RECV_PAGES    (NE2K_NUM_PAGES / 2)
+#define NE2K_NUM_SEND_PAGES    (NE2K_NUM_PAGES / 2)
+#define NE2K_FIRST_RECV_PAGE   (NE2K_PMEM_START / NE2K_PAGE_SIZE)
+#define NE2K_LAST_RECV_PAGE    NE2K_FIRST_RECV_PAGE + NE2K_NUM_RECV_PAGES
+#define NE2K_FIRST_SEND_PAGE   NE2K_LAST_RECV_PAGE + 1
+
+
 extern uint32_t eth_up; // Fix this                               
 uint32_t ne2k_irq;      // And this
 uint32_t ne2k_io_base_addr;
+char device_mac[6];
+
+void* base_page;
+uint32_t num_pages = 0;
+
+extern char* (*packet_wrap)(const char *CT(len) data, size_t len);
+extern int (*send_frame)(const char *CT(len) data, size_t len);
 
 
 void ne2k_init() {
        
        if (ne2k_scan_pci() < 0) return;
-       ne2k_setup_interrupts();
+       ne2k_mem_alloc();
        ne2k_configure_nic();
+       ne2k_read_mac();
+       //ne2k_test_interrupts();
+
+       packet_wrap = &ne2k_packet_wrap;
+       send_frame = &ne2k_send_frame;
+
+        ne2k_setup_interrupts();
+
        eth_up = 1;
        
        return;
@@ -121,30 +169,29 @@ int ne2k_scan_pci() {
 void ne2k_configure_nic() {
        
        ne2k_debug("-->Configuring Device.\n");
-
-        // Reset
-       inb(ne2k_io_base_addr + 0x1f);
+       
+       // Reset. Yes reading from this addr resets it
+       inb(ne2k_io_base_addr + NE2K_RESET_R_ADDR);
 
        // Configure
-        outb(ne2k_io_base_addr + 0x00, 0x22);
-        outb(ne2k_io_base_addr + 0x07, 0xFF);
-       outb(ne2k_io_base_addr + 0x0F, 0xFF);
+       outb(ne2k_io_base_addr + NE2K_PG0_RW_CR,  0x22);
+       outb(ne2k_io_base_addr + NE2K_PG0_W_PSTRT,  NE2K_FIRST_RECV_PAGE);
+        outb(ne2k_io_base_addr + NE2K_PG0_RW_BNRY, NE2K_FIRST_RECV_PAGE + 1);
 
-        uint8_t isr = inb(ne2k_io_base_addr + 0x07);
-        //cprintf("isr: %x\n", isr);
+        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, (0x22 & 0x3F) | 0x40);
+       outb(ne2k_io_base_addr + NE2K_PG1_RW_CURR, NE2K_FIRST_RECV_PAGE + 2);
+       outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, 0x22);
+       outb(ne2k_io_base_addr + NE2K_PG0_W_PSTP, NE2K_LAST_RECV_PAGE);
+       outb(ne2k_io_base_addr + NE2K_PG0_W_DCR, 0x94); 
+       outb(ne2k_io_base_addr + NE2K_PG0_RW_CR,  0x22);
+       
+       outb(ne2k_io_base_addr + NE2K_PG0_W_RCR,  0xDF);
+       outb(ne2k_io_base_addr + NE2K_PG0_W_TCR,  0xE0);
+       
 
+       //uint8_t isr = inb(ne2k_io_base_addr + 0x07);
+       //cprintf("isr: %x\n", isr);
 
-       cprintf("Generating Interrupt...\n");
-       outb(ne2k_io_base_addr + 0x0A, 0x00);
-       outb(ne2k_io_base_addr + 0x0B, 0x00);
-       outb(ne2k_io_base_addr + 0x00, 0x0A);
-       udelay(10000000);
-
-        cprintf("Generating Interrupt again...\n");
-        outb(ne2k_io_base_addr + 0x0A, 0x00);
-        outb(ne2k_io_base_addr + 0x0B, 0x00);
-        outb(ne2k_io_base_addr + 0x00, 0x0A);
-        udelay(10000000);
        
        return;
 }
@@ -156,26 +203,366 @@ void ne2k_setup_interrupts() {
        ne2k_debug("-->Setting interrupts.\n");
        
        // Kernel based interrupt stuff
-#ifdef __IVY__
        register_interrupt_handler(interrupt_handlers, KERNEL_IRQ_OFFSET + ne2k_irq, ne2k_interrupt_handler, (void *)0);
-#else
-       register_interrupt_handler(interrupt_handlers, KERNEL_IRQ_OFFSET + ne2k_irq, ne2k_interrupt_handler, 0);
-#endif
-
        
        ioapic_route_irq(ne2k_irq, 6);  
        
+       outb(ne2k_io_base_addr + NE2K_PG0_RW_ISR, 0xFF);
+       outb(ne2k_io_base_addr + NE2K_PG0_W_IMR,  0xFF);
+       
        return;
 }
 
+void ne2k_mem_alloc() {
+       
+       num_pages = NE2K_NUM_PAGES;
+       base_page = kmalloc(num_pages * NE2K_PAGE_SIZE, 0);
+       
+}
+
+void ne2k_read_mac() {
+
+       uint8_t cr = inb(ne2k_io_base_addr + NE2K_PG0_RW_CR);
+       
+       // Set correct bits
+       outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, 0xA);
+       outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR0, 0x0);
+        outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR1, 0x0);
+        outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR0, 0x6);
+        outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR1, 0x0);
+
+
+       for (int i = 0; i < 6; i++)
+               device_mac[i] = inb(ne2k_io_base_addr + 0x10) & inb(ne2k_io_base_addr + 0x10);
+
+       // Set page 1
+        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, (cr & 0x3F) | 0x40);
+
+       for (int i = 0; i < 6; i++) 
+           outb(ne2k_io_base_addr + NE2K_PG1_RW_PAR + i, device_mac[i]);
+
+       
+       ne2k_debug("-->DEVICE MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", 0xFF & device_mac[0], 0xFF & device_mac[1],        
+                                                                   0xFF & device_mac[2], 0xFF & device_mac[3], 
+                                                                0xFF & device_mac[4], 0xFF & device_mac[5]);
+       // Restore old setting.
+       outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, cr);
+       return;
+}
+
+void ne2k_test_interrupts() {
+       
+       cprintf("Generating Interrupt...\n");
+       outb(ne2k_io_base_addr + 0x0A, 0x00);
+       outb(ne2k_io_base_addr + 0x0B, 0x00);
+       outb(ne2k_io_base_addr + 0x00, 0x0A);
+       udelay(10000000);
+
+       cprintf("Generating Interrupt again...\n");
+       outb(ne2k_io_base_addr + 0x0A, 0x00);
+       outb(ne2k_io_base_addr + 0x0B, 0x00);
+       outb(ne2k_io_base_addr + 0x00, 0x0A);
+       udelay(10000000);
+       
+}
+
 // We need to evaluate this routine in terms of concurrency.
 // We also need to figure out whats up with different core interrupts
 void ne2k_interrupt_handler(trapframe_t *tf, void* data) {
        
-       cprintf("\nNE2K interrupt on core %u!\n", lapic_get_id());
+       ne2k_interrupt_debug("\nNE2K interrupt on core %u!\n", lapic_get_id());
        uint8_t isr= inb(ne2k_io_base_addr + 0x07);
-       cprintf("isr: %x\n", isr);
-       outb(ne2k_io_base_addr + 0x07, isr);
+       ne2k_interrupt_debug("isr: %x\n", isr);
+       
+       if (isr & 0x1) {
+               ne2k_interrupt_debug("-->Packet received.\n");
+               ne2k_handle_rx_packet();
+       }
+
 
+       outb(ne2k_io_base_addr + 0x07, isr);
+       //ne2k_handle_rx_packet();
        return;                         
 }
+
+void ne2k_handle_rx_packet() {
+
+        uint8_t bound = inb(ne2k_io_base_addr + NE2K_PG0_RW_BNRY);
+
+        uint8_t cr = inb(ne2k_io_base_addr + NE2K_PG0_RW_CR);
+        // Set page 1
+        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, (cr & 0x3F) | 0x40);
+
+       uint8_t next = inb(ne2k_io_base_addr + NE2K_PG1_RW_CURR);
+
+       // Restore old setting.
+        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, cr);
+
+        uint8_t start = NE2K_FIRST_RECV_PAGE;
+        uint8_t stop = NE2K_LAST_RECV_PAGE;
+
+       // Broken mult packets?
+       if (((bound + 1) == next) || (((bound + 1) == stop) && (start == next))) {
+               return;
+       }
+
+       uint32_t kmalloc_size;
+
+       if (MAX_FRAME_SIZE % NE2K_PAGE_SIZE) {
+               kmalloc_size = ((MAX_FRAME_SIZE / NE2K_PAGE_SIZE) + 1) * NE2K_PAGE_SIZE;
+       } else {
+               kmalloc_size = MAX_FRAME_SIZE;
+       }
+       
+       char *rx_buffer = kmalloc(kmalloc_size, 0);
+       
+       if (rx_buffer == NULL) panic ("Can't allocate page for incoming packet.");
+
+        uint8_t curr = bound + 1;
+
+//cprintf("reading from: %x\n", curr);
+
+       uint8_t header[4];
+       uint16_t packet_len = 0xFFFF;
+       uint16_t page_count = 0;
+       for (int i = 0; i < (MAX_FRAME_SIZE / NE2K_PAGE_SIZE); i++) {
+               if (curr == stop)
+                       curr = start;                   
+
+               outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR0, 0x0);
+               outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR1, curr);
+
+
+               // Fix this. Its hard coded to 256
+               outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR0, 0);
+               outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR1, 0x1);
+       
+
+               outb(ne2k_io_base_addr + NE2K_PG0_RW_CR, 0x0A);
+
+               for (int j = 0; j < NE2K_PAGE_SIZE; j++) {
+                       uint8_t val = inb(ne2k_io_base_addr + 0x10);
+                       if ((i == 0) && (j < 4)) {
+//                             cprintf("header %u %x\n", j, (uint8_t)val);
+                               header[j] = val;
+                       } 
+                       rx_buffer[i*NE2K_PAGE_SIZE + j] = val;
+               }
+
+
+               if (i == 0) {
+                       packet_len = ((uint16_t)header[3] << 8) | (uint16_t)header[2];
+//             cprintf("header 2 %u header 3 %u header 3 shifted %u\n", (uint16_t)header[2], (uint16_t)header[3], (uint16_t)header[3] << 8);
+//             cprintf("packet len: %u\n", packet_len);
+                       if (packet_len % NE2K_PAGE_SIZE) {
+                               page_count = (packet_len / NE2K_PAGE_SIZE) + 1;
+                       } else {
+                               page_count = (packet_len / NE2K_PAGE_SIZE);
+                       }
+               }
+               
+               if ((i + 1) == page_count)
+                       break;
+
+               curr++;
+
+               
+       }
+//cprintf("last page: %x\n", curr);
+       outb(ne2k_io_base_addr + NE2K_PG0_RW_BNRY, curr);
+       
+
+       // Hack for UDP syscall hack. 
+       // This is a quick hack to let us deal with where to put packets coming in. This is not concurrency friendly
+       // In the event that we get 2 incoming frames for our syscall test (shouldnt happen)
+       // We cant process more until another packet comes in. This is ugly, but this code goes away as soon as we integrate a real stack.
+       // This keys off the source port, fix it for dest port. 
+       // Also this may access packet regions that are wrong. If someone addresses empty packet for our interface
+       // and the bits that happened to be in memory before are the right port, this will trigger. this is bad
+       // but since syscalls are a hack for only 1 machine connected, we dont care for now.
+       
+       if (*((uint16_t*)(rx_buffer + 40)) == 0x9bad) {
+               
+
+               extern int packet_waiting;      
+               extern int packet_buffer_size;
+               extern int packet_buffer_pos;
+               extern char* packet_buffer;
+               extern char* packet_buffer_orig;
+
+               if (packet_waiting) return;
+               
+               // So ugly I want to cry
+               packet_buffer_size = *((uint16_t*)(rx_buffer + 42)); 
+               packet_buffer_size = (((uint16_t)packet_buffer_size & 0xff00) >> 8) |  (((uint16_t)packet_buffer_size & 0x00ff) << 8);          
+               packet_buffer_size = packet_buffer_size - 8;    
+
+               packet_buffer = rx_buffer + PACKET_HEADER_SIZE + 4;
+
+               packet_buffer_orig = rx_buffer;
+               packet_buffer_pos = 0;
+               
+               packet_waiting = 1;
+                                               
+               return;
+       }
+       
+       // END HACKY STUFF
+               
+       kfree(rx_buffer);
+       
+       return;
+}
+
+// copied with love (and modification) from tcp/ip illistrated vl 2 1995 pg 236
+// bsd licenced
+uint16_t cksum(char *ip, int len) {
+       
+       uint32_t sum = 0;  /* assume 32 bit long, 16 bit short */
+
+       while(len > 1){
+             sum += *((uint16_t*) ip);
+            ip = ip + 2;
+             if(sum & 0x80000000)   /* if high order bit set, fold */
+               sum = (sum & 0xFFFF) + (sum >> 16);
+             len -= 2;
+           }
+
+           if(len)       /* take care of left over byte */
+             sum += (uint16_t) *(uint8_t *)ip;
+          
+           while(sum>>16)
+             sum = (sum & 0xFFFF) + (sum >> 16);
+
+           return ~sum;
+         }
+
+
+// Main routine to send a frame. May be completely broken.
+int ne2k_send_frame(const char *data, size_t len) {
+
+
+       if (data == NULL)
+               return -1;
+       if (len == 0)
+               return 0;
+
+
+       if (len > MAX_FRAME_SIZE) {
+               ne2k_frame_debug("-->Frame Too Large!\n");
+               return -1;
+       }
+
+        outb(ne2k_io_base_addr + NE2K_PG0_W_IMR,  0x00);
+
+
+       // The TPSR takes a page #
+       // The RSAR takes a byte offset, but since a page is 256 bits
+       // and we are writing on page boundries, the low bits are 0, and
+       // the high bits are a page #
+       outb(ne2k_io_base_addr + NE2K_PG0_W_TPSR, NE2K_FIRST_SEND_PAGE);
+        outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR0, 0x0);
+        outb(ne2k_io_base_addr + NE2K_PG0_W_RSAR1, NE2K_FIRST_SEND_PAGE);
+
+       
+       outb(ne2k_io_base_addr + NE2K_PG0_W_TBCR0, len & 0xFF);
+        outb(ne2k_io_base_addr + NE2K_PG0_W_TBCR1, len >> 8);
+
+        outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR0, len & 0xFF);
+        outb(ne2k_io_base_addr + NE2K_PG0_W_RBCR1, len >> 8);
+
+       
+       outb(ne2k_io_base_addr + NE2K_PG0_RW_CR,  0x12);
+       
+
+       for (int i = 0; i<len; i = i + 1) {
+               outb(ne2k_io_base_addr + 0x10, *(uint8_t*)(data + i));
+               //printk("sent: %x\n", *(uint8_t*)(data + i));
+       }
+       
+       while(( inb(ne2k_io_base_addr + 0x07) & 0x40) == 0);
+
+        outb(ne2k_io_base_addr + 0x07,  0x40);
+
+        outb(ne2k_io_base_addr + NE2K_PG0_W_IMR,  0xFF);
+
+        outb(ne2k_io_base_addr + NE2K_PG0_RW_CR,  0x1E);
+       
+       
+       return len;
+}
+
+// This function is a complete hack for syscalls until we get a stack.
+// the day I delete this monstrosity of code I will be a happy man --Paul
+char *ne2k_packet_wrap(const char* data, size_t len) {
+       
+       #define htons(A) ((((uint16_t)(A) & 0xff00) >> 8) | \
+                           (((uint16_t)(A) & 0x00ff) << 8))
+       #define htonl(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \
+                           (((uint32_t)(A) & 0x00ff0000) >> 8)  | \
+                           (((uint32_t)(A) & 0x0000ff00) << 8)  | \
+                           (((uint32_t)(A) & 0x000000ff) << 24))
+       #define ntohs  htons
+       #define ntohl  htohl
+       if ((len == 0) || (data == NULL))
+               return NULL;
+       // Hard coded to paul's laptop's mac
+       //Format for Makelocal file: -DUSER_MAC_ADDRESS="{0x00, 0x23, 0x32, 0xd5, 0xae, 0x82}"
+       char dest_mac_address[6] = USER_MAC_ADDRESS;
+       
+       
+       uint32_t source_ip = 0xC0A8000A; // 192.168.0.10
+       uint32_t dest_ip   = 0xC0A8000B; // 192.168.0.11
+  
+       
+       if (len > MAX_PACKET_DATA) {
+               ne2k_frame_debug("Bad packet size for packet wrapping");
+               return NULL;
+       }
+       
+       struct eth_packet* wrap_buffer = kmalloc(MAX_PACKET_SIZE, 0);
+       
+       if (wrap_buffer == NULL) {
+               ne2k_frame_debug("Can't allocate page for packet wrapping");
+               return NULL;
+       }
+       
+       struct ETH_Header *eth_header = &wrap_buffer->eth_head.eth_head;
+       struct IP_Header *ip_header = &wrap_buffer->eth_head.ip_head;
+       struct UDP_Header *udp_header = &wrap_buffer->eth_head.udp_head;
+       
+       // Setup eth data
+       for (int i = 0; i < 6; i++) 
+               eth_header->dest_mac[i] = dest_mac_address[i];
+               
+       for (int i = 0; i < 6; i++) 
+               eth_header->source_mac[i] = device_mac[i];
+               
+       eth_header->eth_type = htons(0x0800);
+       
+       // Setup IP data
+       ip_header->ip_opts0 = htonl((4<<28) | (5 << 24) | (len + 28));
+       ip_header->ip_opts1 = 0;
+       //ip_header->ip_opts2 = 0x4f2f110a;
+        ip_header->ip_opts2 = 0x0000110a;
+
+       ip_header->source_ip = htonl(source_ip);
+       ip_header->dest_ip = htonl(dest_ip);
+       
+
+       ip_header->ip_opts2 =   ip_header->ip_opts2 | 
+                               ((uint32_t)cksum((char*)ip_header, sizeof(struct IP_Header)) << 16);
+       // Setup UDP Data
+       udp_header->source_port = htons(44443);
+       udp_header->dest_port = htons(44444);
+       udp_header->length = htons(8 + len);
+       udp_header->checksum = 0;
+       
+       memcpy (&wrap_buffer->data[0], data, len);
+       
+       return (char *CT(PACKET_HEADER_SIZE + len))wrap_buffer; 
+}
index 8a4b9e5..35b8308 100644 (file)
@@ -4,10 +4,11 @@
 #include <ros/common.h>
 #include <trap.h>
 #include <pmap.h>
+#include <arch/nic_common.h>
 
 #define ne2k_debug(...)  cprintf(__VA_ARGS__)  
 #define ne2k_interrupt_debug(...) //cprintf(__VA_ARGS__)  
-#define ne2k_frame_debug(...)  cprintf(__VA_ARGS__)  
+#define ne2k_frame_debug(...) // cprintf(__VA_ARGS__)  
 
 #define NIC_IRQ_CPU                    5
 
@@ -23,7 +24,12 @@ int ne2k_scan_pci();
 void ne2k_configure_nic();
 void ne2k_setup_interrupts();
 void ne2k_interrupt_handler(trapframe_t *tf, void* data);
-
+void ne2k_mem_alloc();
+void ne2k_read_mac();
+void ne2k_test_interrupts();
+void ne2k_handle_rx_packet();
+int ne2k_send_frame(const char *data, size_t len);
+char *ne2k_packet_wrap(const char* data, size_t len);
 
 
 #endif /* !ROS_INC_NE2K_H */
diff --git a/kern/arch/i386/nic_common.c b/kern/arch/i386/nic_common.c
new file mode 100644 (file)
index 0000000..aa525a6
--- /dev/null
@@ -0,0 +1,26 @@
+/** @file
+ * @brief Common Nic Variables
+ *
+ * See Info below 
+ *
+ * @author Paul Pearce <pearce@eecs.berkeley.edu>
+ *
+ */
+
+#ifdef __SHARC__
+#pragma nosharc
+#endif
+
+#include <arch/nic_common.h>
+
+uint8_t eth_up = 0; 
+
+// Hacky stuff for syscall hack. Go away.
+int packet_waiting;
+int packet_buffer_size;
+char *CT(MAX_FRAME_SIZE - PACKET_HEADER_SIZE) packet_buffer;
+char *CT(MAX_FRAME_SIZE) packet_buffer_orig;
+int packet_buffer_pos = 0;
+
+char* (*packet_wrap)(const char *CT(len) data, size_t len);
+int (*send_frame)(const char *CT(len) data, size_t len);
diff --git a/kern/arch/i386/nic_common.h b/kern/arch/i386/nic_common.h
new file mode 100644 (file)
index 0000000..0387bcd
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef ROS_INC_NIC_COMMON_H
+#define ROS_INC_NIC_COMMON_H
+
+#include <ros/common.h>
+#include <trap.h>
+#include <pmap.h>
+
+
+// Basic packet sizing
+// TODO handle jumbo packets
+#define ETHERNET_ENCAP_SIZE    18
+#define MTU                    1500    
+#define MAX_FRAME_SIZE         ETHERNET_ENCAP_SIZE + MTU       
+       
+// v----- Evil line ------v
+// Hacky stuff for syscalls go away.
+
+struct ETH_Header
+{
+       char dest_mac[6];
+       char source_mac[6];
+       uint16_t eth_type;
+};
+
+
+struct IP_Header
+{
+       uint32_t ip_opts0;
+       uint32_t ip_opts1;
+       uint32_t ip_opts2;
+       uint32_t source_ip;
+       uint32_t dest_ip;
+};
+
+struct UDP_Header
+{
+       uint16_t source_port;
+       uint16_t dest_port;
+       uint16_t length;
+       uint16_t checksum;
+};     
+
+#define MINIMUM_PACKET_SIZE 14 // kinda evil. probably evil.
+#define MAX_PACKET_SIZE                MTU
+
+#define PACKET_HEADER_SIZE  sizeof(struct packet_header) //IP UDP ETH
+#define MAX_PACKET_DATA                MAX_FRAME_SIZE - PACKET_HEADER_SIZE
+// This number needs verification! Also, this is a huge hack, as the driver shouldnt care about UDP/IP etc.
+
+struct packet_header {
+       struct ETH_Header eth_head;
+       struct IP_Header ip_head;
+       struct UDP_Header udp_head;
+} __attribute__((packed));
+
+struct eth_packet {
+       struct packet_header eth_head;
+       char data[MTU-PACKET_HEADER_SIZE];
+} __attribute__((packed));
+
+
+// ^----- Evil line ------^
+
+#endif /* !ROS_INC_NIC_COMMON_H */
index d62546f..f69277f 100644 (file)
@@ -99,23 +99,27 @@ unsigned long tx_des_pa;
 uint32_t rx_des_cur = 0;
 uint32_t tx_des_cur = 0;
 
-uint8_t eth_up = 0; // TODO: This needs to be somewhere global.
+extern int eth_up;
+extern int packet_waiting;
+extern int packet_buffer_size;
+extern char *CT(MAX_FRAME_SIZE - PACKET_HEADER_SIZE) packet_buffer;
+extern char *CT(MAX_FRAME_SIZE) packet_buffer_orig;
+extern int packet_buffer_pos;
+
+extern char* (*packet_wrap)(const char *CT(len) data, size_t len);
+extern int (*send_frame)(const char *CT(len) data, size_t len);
 
-// Hacky stuff for syscall hack. Go away.
-int packet_waiting;
-int packet_buffer_size;
-char *CT(MAX_FRAME_SIZE - PACKET_HEADER_SIZE) packet_buffer;
-char *CT(MAX_FRAME_SIZE) packet_buffer_orig;
-int packet_buffer_pos = 0;
-// End hacky stuff
 
 void rl8168_init() {
-       
+
        if (rl8168_scan_pci() < 0) return;
        rl8168_read_mac();
        rl8168_setup_descriptors();
        rl8168_configure();
        rl8168_setup_interrupts();
+       packet_wrap = &rl8168_packet_wrap;
+        send_frame = &rl8168_send_frame;
+
        eth_up = 1;
        
        //Trigger sw based nic interrupt
@@ -689,7 +693,7 @@ char *rl8168_packet_wrap(const char* data, size_t len) {
                return NULL;
        }
        
-       struct rl8168_packet* wrap_buffer = kmalloc(MAX_PACKET_SIZE, 0);
+       struct eth_packet* wrap_buffer = kmalloc(MAX_PACKET_SIZE, 0);
        
        if (wrap_buffer == NULL) {
                rl8168_frame_debug("Can't allocate page for packet wrapping");
@@ -697,9 +701,9 @@ char *rl8168_packet_wrap(const char* data, size_t len) {
        }
        
 
-       struct ETH_Header *eth_header = &wrap_buffer->rl8168_head.eth_head;
-       struct IP_Header *ip_header = &wrap_buffer->rl8168_head.ip_head;
-       struct UDP_Header *udp_header = &wrap_buffer->rl8168_head.udp_head;
+       struct ETH_Header *eth_header = &wrap_buffer->eth_head.eth_head;
+       struct IP_Header *ip_header = &wrap_buffer->eth_head.ip_head;
+       struct UDP_Header *udp_header = &wrap_buffer->eth_head.udp_head;
        
        // Setup eth data
        for (int i = 0; i < 6; i++) 
index df3f7df..c9977fe 100644 (file)
@@ -4,16 +4,12 @@
 #include <ros/common.h>
 #include <trap.h>
 #include <pmap.h>
+#include <arch/nic_common.h>
 
 #define rl8168_debug(...)  //cprintf(__VA_ARGS__)  
 #define rl8168_interrupt_debug(...) //cprintf(__VA_ARGS__)  
 #define rl8168_frame_debug(...)  //cprintf(__VA_ARGS__)  
 
-// We need to provide some global interface for sending and receiving packets to a generic interface
-//  for now, that is this set of Macros! They aren't in caps since the final inteface shoudn't be.
-#define packet_wrap rl8168_packet_wrap
-#define send_frame rl8168_send_frame
-
 #define NE2K_IRQ_CPU           5
 
 #define REALTEK_VENDOR_ID   0x10ec
 // Offset used for indexing IRQs
 #define KERNEL_IRQ_OFFSET      32
 
-// Basic packet sizing
-// TODO handle jumbo packets
-#define ETHERNET_ENCAP_SIZE    18
-#define MTU                                    1500    
-#define MAX_FRAME_SIZE         ETHERNET_ENCAP_SIZE + MTU       
-       
 // Realtek Descriptor Related Sizing
 #define NUM_TX_DESCRIPTORS     1024
 #define NUM_RX_DESCRIPTORS     1024
 // ^----- Good line ------^
 
 // v----- Evil line ------v
-// Hacky stuff for syscalls go away.
-
-struct ETH_Header
-{
-       char dest_mac[6];
-       char source_mac[6];
-       uint16_t eth_type;
-};
-
-
-struct IP_Header
-{
-       uint32_t ip_opts0;
-       uint32_t ip_opts1;
-       uint32_t ip_opts2;
-       uint32_t source_ip;
-       uint32_t dest_ip;
-};
-
-struct UDP_Header
-{
-       uint16_t source_port;
-       uint16_t dest_port;
-       uint16_t length;
-       uint16_t checksum;
-};     
-
-#define MINIMUM_PACKET_SIZE 14 // kinda evil. probably evil.
-#define MAX_PACKET_SIZE                MTU
-
-#define PACKET_HEADER_SIZE  sizeof(struct rl8168_header) //IP UDP ETH
-#define MAX_PACKET_DATA                MAX_FRAME_SIZE - PACKET_HEADER_SIZE
-// This number needs verification! Also, this is a huge hack, as the driver shouldnt care about UDP/IP etc.
-
-struct rl8168_header {
-       struct ETH_Header eth_head;
-       struct IP_Header ip_head;
-       struct UDP_Header udp_head;
-} __attribute__((packed));
-
-struct rl8168_packet {
-       struct rl8168_header rl8168_head;
-       char data[MTU-PACKET_HEADER_SIZE];
-} __attribute__((packed));
 
 char *CT(PACKET_HEADER_SIZE + len)
 rl8168_packet_wrap(const char *CT(len) data, size_t len);
 
-
 // ^----- Evil line ------^
 
 // v----- Good line ------v
index fd44226..604f9fa 100644 (file)
@@ -24,7 +24,9 @@
 #include <kfs.h> // eventually replace this with vfs.h
 
 #ifdef __NETWORK__
-#include <arch/rl8168.h>
+#include <arch/nic_common.h>
+extern char* (*packet_wrap)(const char *CT(len) data, size_t len);
+extern int (*send_frame)(const char *CT(len) data, size_t len);
 #endif
 
 static void sys_yield(struct proc *p);
index 9ee32a2..7c2e3c7 100644 (file)
@@ -4,7 +4,7 @@ V = @
 SYSCALL_SERVER_OBJS = newlib_trans.o syscall_server.o
 SYSCALL_SERVER_HEADS = syscall_server.h newlib_trans.h
 
-all: syscall_server_pty syscall_server_pipe
+all: syscall_server_udp syscall_server_pty syscall_server_pipe
        $(V)rm -rf *.o
 
 .syscall_server_pipe.in: 
@@ -21,16 +21,21 @@ syscall_server_pipes: .syscall_server_pipe.in .syscall_server_pipe.out
        @echo + cc [SYSCALL_SERVER] $<
        $(V)$(CC) -c $(CFLAGS) -o $@ $<
 
-SYSCALL_SERVER_PTY_OBJS = $(SYSCALL_SERVER_OBJS) pty_init.o
+SYSCALL_SERVER_PTY_OBJS = $(SYSCALL_SERVER_OBJS) pty.o
 syscall_server_pty: $(SYSCALL_SERVER_PTY_OBJS)
        @echo + cc [SYSCALL_SERVER] $@
        $(V)$(CC) $(CFLAGS) -o $@ $(SYSCALL_SERVER_PTY_OBJS)
         
-SYSCALL_SERVER_PIPE_OBJS = $(SYSCALL_SERVER_OBJS) pipe_init.o
+SYSCALL_SERVER_PIPE_OBJS = $(SYSCALL_SERVER_OBJS) pipe.o
 syscall_server_pipe: $(SYSCALL_SERVER_PIPE_OBJS) syscall_server_pipes
        @echo + cc [SYSCALL_SERVER] $@
        $(V)$(CC) $(CFLAGS) -o $@ $(SYSCALL_SERVER_PIPE_OBJS)
 
+SYSCALL_SERVER_UDP_OBJS = $(SYSCALL_SERVER_OBJS) udp.o
+syscall_server_udp: $(SYSCALL_SERVER_UDP_OBJS)
+       @echo + cc [SYSCALL_SERVER] $@
+       $(V)$(CC) $(CFLAGS) -o $@ $(SYSCALL_SERVER_UDP_OBJS)
+
 clean:
        rm -rf *.o
        rm -rf syscall_server_*
diff --git a/tools/syscall_server/pipe.c b/tools/syscall_server/pipe.c
new file mode 100644 (file)
index 0000000..b522ae3
--- /dev/null
@@ -0,0 +1,35 @@
+#include <fcntl.h>
+#include <stdio.h>
+
+// These definitions seem backwards, but they are not.
+//  They are assigned from the persepctive of how qemu sees them
+#define SYSCALL_SERVER_PIPE_IN  ".syscall_server_pipe.out"
+#define SYSCALL_SERVER_PIPE_OUT ".syscall_server_pipe.in"
+
+int init_syscall_server(int* fd_read, int* fd_write) {
+
+       printf("Waiting for other end of pipe to connect...\n");
+       int write = open(SYSCALL_SERVER_PIPE_OUT, O_WRONLY);
+       if(write < 0)
+               return write;
+
+       int read = open(SYSCALL_SERVER_PIPE_IN, O_RDONLY);
+       if(read < 0) {
+               close(write);
+               return read;
+       }
+
+    *fd_read = read;
+       *fd_write = write;
+    return read+write;
+}
+
+int read_syscall_server(int fd, char* buf, int len) {
+       return read(fd, buf, len);
+}
+
+int write_syscall_server(int fd, char* buf, int len, int bytes_to_follow) {
+       return write(fd, buf, len);
+}
+
+
diff --git a/tools/syscall_server/pipe_init.c b/tools/syscall_server/pipe_init.c
deleted file mode 100644 (file)
index 0555cfb..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <fcntl.h>
-#include <stdio.h>
-
-// These definitions seem backwards, but they are not.
-//  They are assigned from the persepctive of how qemu sees them
-#define SYSCALL_SERVER_PIPE_IN  ".syscall_server_pipe.out"
-#define SYSCALL_SERVER_PIPE_OUT ".syscall_server_pipe.in"
-
-int init_syscall_server(int* fd_read, int* fd_write) {
-
-       printf("Waiting for other end of pipe to connect...\n");
-       int write = open(SYSCALL_SERVER_PIPE_OUT, O_WRONLY);
-       if(write < 0)
-               return write;
-
-       int read = open(SYSCALL_SERVER_PIPE_IN, O_RDONLY);
-       if(read < 0) {
-               close(write);
-               return read;
-       }
-
-    *fd_read = read;
-       *fd_write = write;
-    return read+write;
-}
diff --git a/tools/syscall_server/pty.c b/tools/syscall_server/pty.c
new file mode 100644 (file)
index 0000000..48d8e8d
--- /dev/null
@@ -0,0 +1,34 @@
+#define _XOPEN_SOURCE 600
+#include <stdlib.h>
+#include <fcntl.h>
+
+#define SYSCALL_SERVER_PTY ".syscall_server_pty"
+
+int init_syscall_server(int* fd_read, int* fd_write) {
+       // File descriptor of our open serial port
+       
+       int fd = posix_openpt(O_RDWR | O_NOCTTY);
+       if(fd < 0)
+               return fd;
+       grantpt (fd);
+    unlockpt (fd);
+       char* pty_dev = ptsname(fd);
+       
+       //Output the newly allocated slave device into a file
+       int pty_fd = open(SYSCALL_SERVER_PTY, 
+                         O_RDWR | O_CREAT | O_TRUNC, 
+                         S_IRUSR | S_IWUSR);
+       write(pty_fd, pty_dev, strnlen(pty_dev));
+       *fd_read = *fd_write = fd;
+       return fd;
+}
+
+int read_syscall_server(int fd, char* buf, int len) {
+        return read(fd, buf, len);
+}
+
+int write_syscall_server(int fd, char* buf, int len, int bytes_to_follow) {
+        return write(fd, buf, len);
+}
+
+
diff --git a/tools/syscall_server/pty_init.c b/tools/syscall_server/pty_init.c
deleted file mode 100644 (file)
index 6896774..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#define _XOPEN_SOURCE 600
-#include <stdlib.h>
-#include <fcntl.h>
-
-#define SYSCALL_SERVER_PTY ".syscall_server_pty"
-
-int init_syscall_server(int* fd_read, int* fd_write) {
-       // File descriptor of our open serial port
-       
-       int fd = posix_openpt(O_RDWR | O_NOCTTY);
-       if(fd < 0)
-               return fd;
-       grantpt (fd);
-    unlockpt (fd);
-       char* pty_dev = ptsname(fd);
-       
-       //Output the newly allocated slave device into a file
-       int pty_fd = open(SYSCALL_SERVER_PTY, 
-                         O_RDWR | O_CREAT | O_TRUNC, 
-                         S_IRUSR | S_IWUSR);
-       write(pty_fd, pty_dev, strnlen(pty_dev));
-       *fd_read = *fd_write = fd;
-       return fd;
-}
index 25623df..25ed62b 100644 (file)
@@ -20,7 +20,7 @@ int main()
 // Poll for incoming messages and send responses. 
 void run_server() 
 {
-       // Struct for reading the syscall over the serial port
+       // Struct for reading the syscall over the channel
        syscall_req_t syscall_req;
        syscall_rsp_t syscall_rsp;
        
@@ -30,7 +30,7 @@ void run_server()
                error(ret, "Could not open file desciptors for communication\n");
 
        printf("Server started....");
-       // Continuously read in data from the serial port socket
+       // Continuously read in data from the channel socket
        while(1) {
                syscall_req.payload_len = 0;
                syscall_req.payload = NULL;
@@ -87,19 +87,19 @@ void read_syscall_req_header(int fd, syscall_req_t* req)
        // Try to read the syscall id from the socket.
        // If no data available, spin until there is
        int bytes_read = 0;
-       bytes_read = read_from_serial(fd, &req->header, sizeof(req->header.id), 0);
+       bytes_read = read_from_channel(fd, &req->header, sizeof(req->header.id), 0);
 
        // If no data, or the ID we got is bad, terminate process.
        uint32_t id = req->header.id;
        if ((bytes_read < 0) || (id < 0) || (id > NUM_SYSCALLS)) {
-               perror("Problems reading the id from the serial port...");
+               perror("Problems reading the id from the channel...");
        }
 
        // Otherwise, start grabbing the rest of the data
-       bytes_read = read_from_serial(fd, &req->header.subheader, 
+       bytes_read = read_from_channel(fd, &req->header.subheader, 
                                   sizeof(req->header.subheader) , 0);
        if(bytes_read < 0)
-               error(fd, "Problems reading header from the serial port...");
+               error(fd, "Problems reading header from the channel...");
 }
 
 void read_syscall_req_payload(int fd, syscall_req_t* req) {
@@ -110,18 +110,18 @@ void read_syscall_req_payload(int fd, syscall_req_t* req) {
        if (req->payload == NULL) 
                error(fd, "No free memory!");
 
-       int bytes_read = read_from_serial(fd, req->payload, req->payload_len, 0);
+       int bytes_read = read_from_channel(fd, req->payload, req->payload_len, 0);
        if (bytes_read < 0)
-               error(fd, "Problems reading payload from serial port");
+               error(fd, "Problems reading payload from channel");
 }
 
 // Read len bytes from the given socket to the buffer.
 // If peek is 0, will wait indefinitely until that much data is read.
 // If peek is 1, if no data is available, will return immediately.
-int read_from_serial(int fd, void* buf, int len, int peek) 
+int read_from_channel(int fd, void* buf, int len, int peek) 
 {
        int total_read = 0;
-       int just_read = read(fd, buf, len);
+       int just_read = read_syscall_server(fd, buf, len);
 
        if (just_read < 0) return just_read;
        if (just_read == 0 && peek) return just_read;
@@ -129,7 +129,7 @@ int read_from_serial(int fd, void* buf, int len, int peek)
        total_read += just_read;
 
        while (total_read != len) {
-               just_read = read(fd, buf + total_read, len - total_read);
+               just_read = read_syscall_server(fd, buf + total_read, len - total_read);
                if (just_read < 0) return just_read;
                total_read += just_read;
        }
@@ -139,7 +139,7 @@ int read_from_serial(int fd, void* buf, int len, int peek)
 // Send CONNECTION_TERMINATED over the FD (if possible)
 void error(int fd, const char* s)
 {
-       fprintf(stderr, "Error: Spawned Process, FD: %i\n",fd);
+       fprintf(stderr, "Error: FD: %i\n",fd);
        perror(s);
     fprintf(stderr, "Sending CONNECTION_TERMINATED.... \n");
        close(fd);
@@ -194,7 +194,7 @@ void write_syscall_rsp(int fd, syscall_rsp_t* rsp)
 
 void write_syscall_rsp_header(int fd, syscall_rsp_t* rsp) 
 {
-       int written = write(fd, &rsp->header, sizeof(syscall_rsp_header_t));
+       int written = write_syscall_server(fd, &rsp->header, sizeof(syscall_rsp_header_t), rsp->payload_len);
        if (written < 0)
                error(fd, "Problems writing the syscall response header...");   
 }
@@ -204,7 +204,7 @@ void write_syscall_rsp_payload(int fd, syscall_rsp_t* rsp)
        if(rsp->payload_len == 0)
                return;
 
-       int written = write(fd, rsp->payload, rsp->payload_len);
+       int written = write_syscall_server(fd, rsp->payload, rsp->payload_len, 0);
        if (written < 0)
                error(fd, "Problems writing the syscall response payload...");  
        if (written < rsp->payload_len)
index 4fa88fb..68ed685 100644 (file)
@@ -127,7 +127,7 @@ void read_syscall_req_payload(int fd, syscall_req_t* req);
 void write_syscall_rsp(int fd, syscall_rsp_t* rsp);
 void write_syscall_rsp_header(int fd, syscall_rsp_t* rsp);
 void write_syscall_rsp_payload(int fd, syscall_rsp_t* rsp);
-int read_from_serial(int fd, void* buf, int len, int peek); 
+int read_from_channel(int fd, void* buf, int len, int peek); 
 void error(int fd, const char* s);
 char* sandbox_file_name(char* name, uint32_t len);
 
diff --git a/tools/syscall_server/udp.c b/tools/syscall_server/udp.c
new file mode 100644 (file)
index 0000000..8e99d13
--- /dev/null
@@ -0,0 +1,142 @@
+#include <fcntl.h>
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#define UDP_ARR_SIZE 4096
+
+int port = 44444;
+char udp_arr[UDP_ARR_SIZE];
+int udp_buf_len = 0;
+int udp_cur_pos = 0;
+struct sockaddr_in ret_addr;
+
+
+int init_syscall_server(int* fd_read, int* fd_write) {
+
+       int listen_socket;
+
+       // Address structures
+       struct sockaddr_in server_addr;
+
+       // Size of our address structure
+       unsigned int addr_len = sizeof(struct sockaddr_in);
+
+       if ((listen_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+       {
+               printf("Error: PORT: %i. Could not create socket.\n", port);
+               exit(1);
+       }
+
+       // Setup sockaddr_in
+       server_addr.sin_family = AF_INET;
+       server_addr.sin_port = htons(port);
+       server_addr.sin_addr.s_addr=INADDR_ANY;
+       bzero(&(server_addr.sin_zero), 8);      // This is apparently a source of bugs? Who knew.
+
+       // Bind to the given port.
+       if (bind(listen_socket, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)))
+       {
+               printf("Error: Spawned Process, PORT: %i. Could not bind to port.\n", port);
+               exit(1);
+       }
+
+       struct hostent *hp;
+       hp = gethostbyname("192.168.0.10");
+       memset(&ret_addr, 0, sizeof(ret_addr));
+       ret_addr.sin_family = AF_INET;
+       memcpy(&ret_addr.sin_addr, hp->h_addr, hp->h_length);
+       ret_addr.sin_port = htons(44443);
+
+       *fd_read = listen_socket;
+       *fd_write = listen_socket;
+       
+       return listen_socket + listen_socket;
+
+}
+
+int read_syscall_server(int fd, char* buf, int len) {
+
+       if (udp_buf_len == 0) {
+               udp_buf_len = recvfrom(fd, udp_arr, UDP_ARR_SIZE, 0, 0, 0);
+
+               if (udp_buf_len== 0)
+                       return -1;
+       }
+
+       if ((udp_cur_pos + len) > udp_buf_len)
+               return -1;
+
+       memcpy(buf, udp_arr + udp_cur_pos, len);
+
+       udp_cur_pos = udp_cur_pos + len;
+
+       if (udp_cur_pos == udp_buf_len) {
+               udp_cur_pos = 0;
+               udp_buf_len = 0;
+       }
+
+       return len;
+
+}
+
+int write_syscall_server(int fd, char* buf, int len, int bytes_to_follow) {
+
+       static int bytes_buffered = 0;
+       static char* internal_buffer = NULL;
+       static int buffer_size = 0;
+       
+       if (bytes_to_follow != 0) {
+
+               if (internal_buffer != NULL) {
+                       printf("Called buffered write after a buffered write. Illegal.\n");
+                       exit(1);
+               }
+
+               internal_buffer = malloc(len + bytes_to_follow);
+
+               if (internal_buffer == NULL) {
+                       printf("Could not malloc send buffer.\n");
+                       exit(1);
+               }
+
+               buffer_size = len + bytes_to_follow;
+
+               memcpy(internal_buffer, buf, len);
+
+               bytes_buffered = len;
+
+               return bytes_buffered;
+
+       } else if (bytes_buffered == 0) {
+               return sendto(fd, buf, len, 0, (struct sockaddr *)&ret_addr, sizeof(ret_addr));
+       } else {
+
+               if ((len + bytes_buffered) != buffer_size) {
+                       printf("Buffered size does not match actual size\n");
+                       exit(1);
+               }
+
+               if (internal_buffer == NULL) {
+                       printf("Bytes bufferd out of sync with buffer\n");
+                       exit(1);
+               }
+
+               memcpy(internal_buffer + bytes_buffered, buf, len);
+
+               int ret_val = sendto(fd, internal_buffer, len + bytes_buffered, 0, 
+                                    (struct sockaddr *)&ret_addr, sizeof(ret_addr));
+               
+               free(internal_buffer);
+               internal_buffer = NULL;
+               bytes_buffered = 0;
+               buffer_size = 0;
+
+               return ret_val;
+
+       }
+}
index 5efbbdb..3904367 100644 (file)
@@ -14,7 +14,7 @@ extern char * readline(const char *prompt);
 uint8_t* binary_buf;
 
 static void fd_error() {
-       fprintf(stderr, "Error: Unable to run remote binary: %s\n", strerror(errno));
+       fprintf(stderr, "Error: Unable to run remote binary (fd error): %s\n", strerror(errno));
 }
 
 static void malloc_error() {
@@ -24,7 +24,7 @@ static void malloc_error() {
 static void read_error(void* buf, int fd) {
        free(binary_buf);
        close(fd);
-       fprintf(stderr, "Error: Unable to run remote binary: %s\n", strerror(errno));
+       fprintf(stderr, "Error: Unable to run remote binary (read error): %s\n", strerror(errno));
 }
 
 static void realloc_error(void* buf, int fd) {
@@ -42,7 +42,7 @@ void run_binary()
        }
 
        char * file_name = malloc(strlen(readline_result) + 8);
-       sprintf(file_name, "./test/%s", readline_result);
+       sprintf(file_name, "./apps/%s", readline_result);
        int fd = open(file_name, O_RDONLY, 0);
        if(fd < 0) { fd_error(); return; };
        
index 492075b..ca1c6d5 100644 (file)
@@ -380,9 +380,11 @@ int read_from_channel(char * buf, int len, int peek)
        //                      Also, watch out for CONNECTION TERMINATED
        int total_read = 0;
 
-       //int just_read = sys_serial_read(buf, len);
-       int just_read = sys_serial_read(buf, len);
-
+       #ifdef __NETWORK__
+               int just_read = sys_eth_read(buf, len);
+       #else
+               int just_read = sys_serial_read(buf, len);
+       #endif
 
        if (just_read < 0) return just_read;
        if (just_read == 0 && peek) return just_read;
@@ -390,9 +392,13 @@ int read_from_channel(char * buf, int len, int peek)
        total_read += just_read;
 
        while (total_read != len) {
-               //just_read = sys_serial_read(buf + total_read, len - total_read);
-               just_read = sys_serial_read(buf + total_read, len - total_read);
                
+               #ifdef __NETWORK__
+                       just_read = sys_eth_read(buf + total_read, len - total_read);
+               #else
+                       just_read = sys_serial_read(buf + total_read, len - total_read);
+               #endif
+       
                if (just_read == -1) return -1;
                total_read += just_read;
        }
@@ -673,7 +679,9 @@ ssize_t write(int file, const void *ptr, size_t len)
  */
 int write_to_channel(char * msg, int len)
 {
-       //return sys_serial_write((char*)msg, len);
-       return sys_serial_write(msg, len);
-       
+       #ifdef __NETWORK__
+               return sys_eth_write(msg, len);
+       #else
+               return sys_serial_write(msg, len);
+       #endif
 }