]> Zhao Yanbai Git Server - minix.git/commitdiff
Minix 3 version
authorPhilip Homburg <philip@cs.vu.nl>
Thu, 2 Oct 2008 13:45:46 +0000 (13:45 +0000)
committerPhilip Homburg <philip@cs.vu.nl>
Thu, 2 Oct 2008 13:45:46 +0000 (13:45 +0000)
19 files changed:
commands/swifi/Makefile
commands/swifi/do_swifi [new file with mode: 0644]
commands/swifi/do_swifi_bug1 [new file with mode: 0644]
commands/swifi/extra.c [new file with mode: 0644]
commands/swifi/extra.h [new file with mode: 0644]
commands/swifi/fault_model.c
commands/swifi/read_nlist.c [new file with mode: 0644]
commands/swifi/rnd.c [new file with mode: 0644]
commands/swifi/rs.restart_imm [new file with mode: 0755]
commands/swifi/run_swifi [new file with mode: 0644]
commands/swifi/run_swifi-x [new file with mode: 0644]
commands/swifi/run_t1 [new file with mode: 0755]
commands/swifi/run_t1a [new file with mode: 0755]
commands/swifi/run_t1b [new file with mode: 0755]
commands/swifi/run_t2 [new file with mode: 0755]
commands/swifi/run_t2a [new file with mode: 0755]
commands/swifi/run_t2b [new file with mode: 0755]
commands/swifi/socket.c [new file with mode: 0644]
commands/swifi/systest.c [new file with mode: 0644]

index def034b7c42214db19d308aff22a3c4a1d7eb5e8..7197e0dbf2f89220c6f8906c8c4a1361d66aeb7b 100644 (file)
@@ -1,25 +1,20 @@
-#
-# Makefile for the nooks.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
+OBJ=systest.o fault_model.o extra.o db_sym.o db_disasm.o db_access.o read_nlist.o
+OBJ_RND=rnd.o
+OBJ_SOCKET=socket.o
 
-O_TARGET := swifi.o
+DEFINES=-DCONFIG_SWIFI
+CFLAGS=$(DEFINES)
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
+all:   swifi rnd socket
 
-export-objs = swifi-ksyms.o
+swifi: $(OBJ)
+       $(CC) -o swifi $(OBJ)
 
-obj-$(CONFIG_SWIFI) +=  db_sym.o db_disasm.o db_access.o \
-                       random.o fault_model.o swifi-ksyms.o
+rnd:   $(OBJ_RND)
+       $(CC) -o $@ $(OBJ_RND)
 
-# db_interface.o 
-
-include $(TOPDIR)/Rules.make
-
-fastdep:
+socket:        $(OBJ_SOCKET)
+       $(CC) -o $@ $(OBJ_SOCKET)
 
+clean:
+       rm -f swifi $(OBJ)
diff --git a/commands/swifi/do_swifi b/commands/swifi/do_swifi
new file mode 100644 (file)
index 0000000..3616c90
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+pid=`ps ax | grep fxp | grep usr.sbin | sed 's,^[      ]*,,;s,[        ].*,,`
+echo "pid = $pid"
+./swifi -f /usr/build/drivers/fxp/fxp $pid 26 100 4
diff --git a/commands/swifi/do_swifi_bug1 b/commands/swifi/do_swifi_bug1
new file mode 100644 (file)
index 0000000..bd5c825
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+pid=`ps ax | grep fxp | grep usr.sbin | sed 's,^[      ]*,,;s,[        ].*,,`
+echo "pid = $pid"
+./swifi -f /usr/build/drivers/fxp/fxp $pid 8 100 4
diff --git a/commands/swifi/extra.c b/commands/swifi/extra.c
new file mode 100644 (file)
index 0000000..b8233f6
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+Declaration for Linux kernel compatibility
+*/
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+
+#include "extra.h"
+
+pid_t victim_pid= -1;
+char *victim_exe= NULL;
+
+#define TRAP_BIT       (0x80000000)
+
+static struct nlist *exe_nlist;
+static int exe_nlist_n;
+
+/* unsigned long __get_free_page(int type) { assert(0); } */
+/* void *kmalloc(size_t size, int type) { assert(0); } */
+void free_page(unsigned long page) { assert(0); }
+/* void kfree(void *mem) { assert(0); } */
+void vfree(void *mem) { assert(0); }
+
+size_t strncpy_from_user(char *addr, const char *user_name, size_t size)
+{ assert(0); }
+
+/* void lock_kernel(void) { assert(0); } */
+/* void unlock_kernel(void) { assert(0); } */
+void __asm__(char *str) { assert(0); }
+
+extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
+{ assert(0); }
+
+#if 0
+void kallsyms_sections(void *infop,
+       int (*fp)(void *token, const char *modname, const char *secname,
+             ElfW(Addr) secstart, ElfW(Addr) secend, ElfW(Word) secflags))
+{ assert(0); }
+#endif
+
+unsigned long __generic_copy_to_user(void *x, const void *y, unsigned long z)
+{ assert(0); }
+unsigned long __generic_copy_from_user(void *x, const void *y, unsigned long z)
+{ assert(0); }
+
+/* void read_lock(struct lock *lock) { assert(0); } */
+/* void read_unlock(struct lock *lock) { assert(0); } */
+void udelay(unsigned long usecs) { assert(0); }
+int copy_to_user(void * result_record, void *res, size_t size)
+{
+       memcpy(result_record, res, size);
+       return 0;
+}
+
+void panic(char *str) { assert(0); }
+
+void printk(char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+}
+
+int kallsyms_address_to_symbol(db_expr_t off,
+    const char * *mod_name, unsigned long *mod_start, unsigned long *mod_end, 
+    const char * *sec_name, unsigned long *sec_start, unsigned long *sec_end, 
+    const char * *sym_name, unsigned long *sym_start, unsigned long *sym_end)
+{
+       static char name[sizeof(((struct nlist *)0)->n_name)+1];
+
+       int i;
+       unsigned long btext, etext;
+       struct nlist *below, *above;
+
+       off &= ~TRAP_BIT;
+       load_nlist(victim_exe, &btext, &etext);
+       below= above= NULL;
+       for (i= 0; i<exe_nlist_n; i++)
+       {
+               if ((exe_nlist[i].n_sclass & N_SECT) != N_TEXT)
+                       continue;
+               if (exe_nlist[i].n_value <= off)
+               {
+                       if (!below || exe_nlist[i].n_value > below->n_value)
+                               below= &exe_nlist[i];
+               }
+               if (exe_nlist[i].n_value > off)
+               {
+                       if (!above || exe_nlist[i].n_value < above->n_value)
+                               above= &exe_nlist[i];
+               }
+       }
+#if 0
+       if (below)
+       {
+               printf("found '%.*s' at 0x%x\n", sizeof(below->n_name),
+                       below->n_name, below->n_value);
+       }
+       if (above)
+       {
+               printf("found '%.*s' at 0x%x\n", sizeof(above->n_name),
+                       above->n_name, above->n_value);
+       }
+#endif
+
+       btext |= TRAP_BIT;
+       etext |= TRAP_BIT;
+
+       *mod_name = victim_exe;
+       *mod_start = btext;
+       *mod_end = etext;
+       *sec_name = ".text";
+       *sec_start = btext;
+       *sec_end = etext;
+
+       assert(below && above);
+
+       memcpy(name, below->n_name, sizeof(below->n_name));
+       name[sizeof(below->n_name)]= '\0';
+       *sym_name= name;
+
+       *sym_start= below->n_value | TRAP_BIT;
+       *sym_end= above->n_value | TRAP_BIT;
+
+       return 1;
+}
+
+struct module *module_list;
+struct task_struct *task_list;
+struct lock tasklist_lock;
+
+unsigned long text_read_ul(void *addr)
+{
+       int i;
+       unsigned long value;
+
+       for (i= 0; i<sizeof(value); i++)
+       {
+               ((unsigned char *)&value)[i]= text_read_ub((char *)addr+i);
+       }
+       return value;
+}
+
+unsigned char text_read_ub(void *addr)
+{
+       int v;
+       unsigned long vaddr;
+
+       vaddr= (unsigned long)addr;
+       vaddr &= ~TRAP_BIT;
+       v= ptrace(T_READB_INS, victim_pid, vaddr, 0);
+       if (v < 0)
+       {
+               fprintf(stderr,
+       "text_read_ub: trace T_READB_INS failed on pid %d, addr 0x%x: %s\n",
+                       victim_pid, vaddr, strerror(errno));
+               exit(1);
+       }
+       return v;
+}
+
+void text_write_ul(void *addr, unsigned long value)
+{
+       int i;
+
+       for (i= 0; i<sizeof(value); i++)
+       {
+               text_write_ub((char *)addr+i, ((unsigned char *)&value)[i]);
+       }
+}
+
+void text_write_ub(void *addr, unsigned char value)
+{
+       int v;
+       unsigned long vaddr;
+
+       vaddr= (unsigned long)addr;
+       vaddr &= ~TRAP_BIT;
+       v= ptrace(T_WRITEB_INS, victim_pid, vaddr, value);
+       if (v < 0)
+       {
+               fprintf(stderr,
+       "text_read_ub: trace T_WRITEB_INS failed on pid %d, addr 0x%x: %s\n",
+                       victim_pid, vaddr, strerror(errno));
+               exit(1);
+       }
+}
+
+void load_nlist(exe_name, btextp, etextp)
+char *exe_name;
+unsigned long *btextp;
+unsigned long *etextp;
+{
+       int i;
+       unsigned long btext, etext;
+
+       if (!exe_nlist)
+       {
+               exe_nlist_n= read_nlist(exe_name, &exe_nlist);
+               if (exe_nlist_n <= 0)
+               {
+                       if (exe_nlist_n == -1)
+                       {
+                               fprintf(stderr,
+                               "error reading name list from '%s': %s\n",
+                                       exe_name, strerror(errno));
+                       }
+                       else
+                               fprintf(stderr, "no name list in '%s'\n",
+                                       exe_name);
+                       exit(1);
+               }
+       }
+
+       if (!btextp && !etextp)
+               return;
+
+       etext= 0;
+       btext= (unsigned long)-1;
+       for (i= 0; i<exe_nlist_n; i++)
+       {
+               if ((exe_nlist[i].n_sclass & N_SECT) != N_TEXT)
+                       continue;
+               if (exe_nlist[i].n_value < btext)
+                       btext= exe_nlist[i].n_value;
+               if (exe_nlist[i].n_value > etext)
+                       etext= exe_nlist[i].n_value;
+       }
+
+       if (btext >= etext)
+       {
+               fprintf(stderr, "Bad btext (0x%x) or etext (0x%x) in %d\n",
+                       btext, etext, exe_name);
+               exit(1);
+       }
+
+       btext |= TRAP_BIT;
+       etext |= TRAP_BIT;
+
+       if (btextp)
+               *btextp= btext;
+       if (etextp)
+               *etextp= etext;
+}
diff --git a/commands/swifi/extra.h b/commands/swifi/extra.h
new file mode 100644 (file)
index 0000000..ddd4b24
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+Compatibility with the linux kernel environment 
+*/
+
+#include <a.out.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+
+#if 0
+struct module
+{
+       struct module *next;
+       char *name;
+};
+extern struct module *module_list;
+#endif
+
+struct thread
+{
+       unsigned long esp;
+};
+
+struct task_struct
+{
+       struct thread thread;
+       struct task_struct *next;
+};
+
+unsigned long __get_free_page(int type);
+void *kmalloc(size_t size, int type);
+#define GFP_KERNEL 1
+void free_page(unsigned long page);
+void kfree(void *mem);
+void vfree(void *mem);
+
+size_t strncpy_from_user(char *addr, const char *user_name, size_t size);
+
+void lock_kernel(void);
+void unlock_kernel(void);
+
+void __asm__(char *str);
+
+#define for_each_task(t) for(t= task_list; t; t=t->next)
+extern struct task_struct *task_list;
+
+typedef struct { int foo; } pgprot_t;
+extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot);
+
+#define ElfW(type) Elf_ ## type
+typedef unsigned long Elf_Addr;
+typedef unsigned long Elf_Word;
+
+void kallsyms_sections(void *infop,
+       int (*fp)(void *token, const char *modname, const char *secname,
+             ElfW(Addr) secstart, ElfW(Addr) secend, ElfW(Word) secflags));
+
+unsigned long __generic_copy_to_user(void *, const void *, unsigned long);
+unsigned long __generic_copy_from_user(void *, const void *, unsigned long);
+
+struct lock { int dummy; };
+extern struct lock tasklist_lock;
+void read_lock(struct lock *lock);
+void read_unlock(struct lock *lock);
+
+void udelay(unsigned long usecs);
+
+int copy_to_user(void * result_record, void *res, size_t size);
+
+void panic(char *str);
+
+#define PAGE_SIZE      (0x1000)
+#define PAGE_MASK      (0x0fff)
+#define PAGE_OFFSET    0       /* What does this do? */
+#define TASK_SIZE      0       /* What does this do? */
+
+void printk(char *fmt, ...);
+
+#include "ddb.h"
+#include "db_machdep.h"
+int kallsyms_address_to_symbol(db_expr_t off,
+    const char * *mod_name, unsigned long *mod_start, unsigned long *mod_end, 
+    const char * *sec_name, unsigned long *sec_start, unsigned long *sec_end, 
+    const char * *sym_name, unsigned long *sym_start, unsigned long *sym_end);
+
+int read_nlist(const char *filenamer, struct nlist **nlist_table);
+
+unsigned long text_read_ul(void *addr);
+unsigned char text_read_ub(void *addr);
+void text_write_ul(void *addr, unsigned long value);
+void text_write_ub(void *addr, unsigned char value);
+
+extern pid_t victim_pid;
+extern char *victim_exe;
+
+void load_nlist(char *exe_name, unsigned long *btextp, unsigned long *etextp);
index 79326e94611b89ffa541516657ef7ce216d1322c..0576031bd59049922aa6fdf33bcf4fd4ad16cc17 100644 (file)
@@ -44,6 +44,7 @@
  * - use after free
  */
 
+#if 0
 #include <linux/kernel.h>
 #include <linux/kallsyms.h>
 #include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/delay.h>
 #include <asm/page.h>
+#endif
 #include "ddb.h"
 #include "db_sym.h"
 #include "swifi.h"
 
+#include "extra.h"
+
 
 #define CRASH_INTERVAL 8192
 #define FI_MASK                        0xfff
@@ -75,7 +79,7 @@ unsigned long faultType;
 unsigned long numFaults;
 char *crashAddr=0;                     /* track current malloc */
 int crashToggle=1;
-int text_fault(struct module * module, pswifi_result_t res);
+int text_fault(char *mod_name, pswifi_result_t res);
 int stack_fault(pswifi_result_t res);
 int heap_fault(pswifi_result_t res);
 int direct_fault(int fault_address, int fault_content, pswifi_result_t res);
@@ -90,12 +94,15 @@ do { \
       printk( KERN_ALERT "SWIFI: " fmt, ## args); \
 } while (0)
 #else
-#define PDEBUG(fmt, args...)
+#include <stdio.h>
+#define PDEBUG(args) /* (printf args) */
 #endif
 
+#define inline
 
 #ifdef CONFIG_SWIFI
 
+#if 0
 static inline long
 get_mod_name(const char *user_name, char **buf)
 {
@@ -125,6 +132,7 @@ put_mod_name(char *buf)
 {
        free_page((unsigned long)buf);
 }
+#endif
 
 long 
 sys_inject_fault(char * module_name,
@@ -138,7 +146,9 @@ sys_inject_fault(char * module_name,
   unsigned long fault_address = 0; 
   unsigned long fault_data = 0 ; 
   char * kern_name = NULL;
+#if 0
   struct module * mod = NULL;
+#endif
   int found = 0;
   pswifi_result_t res = NULL;
 
@@ -146,27 +156,30 @@ sys_inject_fault(char * module_name,
     result = -E2BIG;
     goto Cleanup;
   }
-  res = (pswifi_result_t) kmalloc((1+argNumFaults) * sizeof(swifi_result_t), 
-                                 GFP_KERNEL);
+  res = (pswifi_result_t) malloc((1+argNumFaults) * sizeof(swifi_result_t));
   if (res == NULL) {
     result = -ENOMEM;
     goto Cleanup;
   }
   memset(res, 0, (1 + argNumFaults) * sizeof(swifi_result_t));
   
-  //
+  /*
   // Capture the name of the module from usermode
-  //
+  */
 
+#if 0
   result = get_mod_name(module_name, &kern_name);
   if (result < 0) {
     goto Cleanup;
   }
+#endif
 
+  kern_name= module_name;
 
 
 
 
+#if 0
     lock_kernel();
 
     for (mod = module_list; mod ; mod = mod->next) {
@@ -180,6 +193,7 @@ sys_inject_fault(char * module_name,
       result = -ENOENT;
       goto Cleanup;
     }
+#endif
                
   numFaults = argNumFaults;
   faultType = argFaultType;
@@ -204,16 +218,16 @@ sys_inject_fault(char * module_name,
   } else if (faultType == DIRECT_FAULT) {
     fault_address = numFaults;
     fault_data = randomSeed;
-    PDEBUG("sys inject fault, type %ld, addr=%lx, flip bit%lx\n", 
-          faultType, fault_address, fault_data);
+    PDEBUG(("sys inject fault, type %ld, addr=%lx, flip bit%lx\n", 
+          faultType, fault_address, fault_data));
   } else if (faultType == DIRECT_FAULT1) {
     fault_address = numFaults;
     fault_data = randomSeed;
-    PDEBUG("sys inject fault, type %ld, addr=%lx, zero bytes %lx\n", 
-          faultType, fault_address, fault_data);
+    PDEBUG(("sys inject fault, type %ld, addr=%lx, zero bytes %lx\n", 
+          faultType, fault_address, fault_data));
   } else {
-    PDEBUG("sys inject fault, type %ld, seed=%ld, fault=%ld, config=%ld\n", 
-          faultType, randomSeed, numFaults, config);
+    PDEBUG(("sys inject fault, type %ld, seed=%ld, fault=%ld\n", 
+          faultType, randomSeed, numFaults));
   }
   faultInjected=1;
   
@@ -232,7 +246,7 @@ sys_inject_fault(char * module_name,
   switch(faultType)
     {
     case TEXT_FAULT: 
-      result = text_fault(mod, res); 
+      result = text_fault(module_name, res); 
       break;
     case STACK_FAULT: 
       result = stack_fault(res); 
@@ -249,7 +263,7 @@ sys_inject_fault(char * module_name,
     case LOOP_FAULT: 
     case INTERFACE_FAULT: 
     case IRQ_FAULT:
-      result = text_fault(mod, res); 
+      result = text_fault(module_name, res); 
       break;
     case FREE_FAULT: 
     case BCOPY_FAULT: 
@@ -295,36 +309,38 @@ sys_inject_fault(char * module_name,
        
        addr1 = (unsigned long *) 0xf0212000;
        addr2 = (unsigned long *) 0xf0212010;
-       PDEBUG("%p=%lx, %p=%lx\n", addr1, *addr1, addr2, *addr2);
+       PDEBUG(("%p=%lx, %p=%lx\n", addr1, *addr1, addr2, *addr2));
        __asm__ ("movl $0xf0212000, %eax\n\t" \
                 "movl $6, 0(%eax)\n\t" \
                 "movl $6, 4(%eax)\n\t");
        addr1 = (unsigned long *) 0xf0212000;
        addr2 = (unsigned long *) 0xf0212010;
-       PDEBUG("after injecting fault\n");
-       PDEBUG("%p=%lx, %p=%lx\n", addr1, *addr1, addr2, *addr2);
+       PDEBUG(("after injecting fault\n"));
+       PDEBUG(("%p=%lx, %p=%lx\n", addr1, *addr1, addr2, *addr2));
        result = 0;
        break;
       }
     
     case DEBUGGER_FAULT: 
-      PDEBUG("Debugger fault"); 
+      PDEBUG(("Debugger fault"));
       __asm__ ("movl %cr4, %ecx\n\t" \
               "movl $42, %ecx; .byte 0x0f, 0x32\n\t" \
               "movl $377, %ecx; .byte 0x0f, 0x32\n\t");
       result = 0;
       break;
-    default: PDEBUG("unknown fault type %ld\n", faultType); break;
+    default: PDEBUG(("unknown fault type %ld\n", faultType)); break;
     }
   if (copy_to_user(result_record, res, argNumFaults * sizeof(swifi_result_t))) {
     result = -EFAULT;
   }
  Cleanup:
+#if 0
   if (kern_name != NULL) {
     put_mod_name(kern_name);
   }
+#endif
   if (res != NULL) {
-    kfree(res);
+    free(res);
   }
 
   return (result);
@@ -334,10 +350,10 @@ int while1(void)
 {
   int i=0;
 
-  PDEBUG("entering into while 1 loop\n");
+  PDEBUG(("entering into while 1 loop\n"));
   while(1) { 
     udelay(20000); 
-    PDEBUG("delay %4d secs, cpl=0x%x, ipend=0x%x\n", i+=5, 20, 30); 
+    PDEBUG(("delay %4d secs, cpl=0x%x, ipend=0x%x\n", i+=5, 20, 30)); 
     if(i>(100 * 2500)) 
       break;
   }
@@ -353,7 +369,7 @@ int direct_fault(int fault_address, int fault_content, pswifi_result_t res)
 
   addr = (unsigned long *) (PAGE_OFFSET + fault_address);
 
-  PDEBUG("%p:0x%lx => ", addr, *addr);
+  PDEBUG(("%p:0x%lx => ", addr, *addr));
   
   flip_bit = 1 << fault_content;
 
@@ -364,7 +380,7 @@ int direct_fault(int fault_address, int fault_content, pswifi_result_t res)
   if (injectFault) {
     *addr = (*addr) ^ flip_bit; 
   }
-  PDEBUG("%lx\n", *addr);
+  PDEBUG(("%lx\n", *addr));
   return(0);
 }
 
@@ -375,7 +391,7 @@ int direct_fault1(int fault_address, int fault_content, pswifi_result_t res)
 
   addr = (unsigned long *) (PAGE_OFFSET + fault_address);
   
-  PDEBUG("%p:%lx => ", addr, *addr);
+  PDEBUG(("%p:%lx => ", addr, *addr));
   
   
   data = *addr;
@@ -398,7 +414,7 @@ int direct_fault1(int fault_address, int fault_content, pswifi_result_t res)
     *addr = data;
   }
 
-  PDEBUG("%lx\n", *addr);
+  PDEBUG(("%lx\n", *addr));
   
     
   return(0);
@@ -407,7 +423,9 @@ int direct_fault1(int fault_address, int fault_content, pswifi_result_t res)
 
 
 
+/*
 #include <linux/sched.h>
+*/
 
 #define MAX_NUM_TASKS 20
 
@@ -421,14 +439,18 @@ find_task(void)
 
   
   do {
+#if 0
     read_lock(&tasklist_lock);
+#endif
     for_each_task(task) { 
       if (--i == 0) {
        result = task;
        break;
       }
     }
+#if 0
     read_unlock(&tasklist_lock);
+#endif
   } while ((i > 0) && (i != j));
 
   return(result);
@@ -450,15 +472,15 @@ stack_fault(pswifi_result_t res)
 
     size = (unsigned long) task + TASK_SIZE - task->thread.esp; 
 
-    PDEBUG("stack range=%lx-%lx\n", 
+    PDEBUG(("stack range=%lx-%lx\n", 
           (unsigned long) task->thread.esp, 
-          (unsigned long) task + TASK_SIZE);
+          (unsigned long) task + TASK_SIZE));
 
     addr = (unsigned long *) ((long) task->thread.esp + 
                              (random()&~0x3)%size);  
     taddr=(unsigned long) addr;
     flip_bit = random() & 0x1f;
-    PDEBUG("%lx:%lx flip bit %d => ", taddr, *addr, flip_bit);
+    PDEBUG(("%lx:%lx flip bit %d => ", taddr, *addr, flip_bit));
     flip_bit = 1 << flip_bit;
     res[count].address = taddr;
     res[count].old = *addr;
@@ -466,17 +488,18 @@ stack_fault(pswifi_result_t res)
     if (injectFault) {
       *addr = ((*addr)^flip_bit); 
     }
-    PDEBUG("%lx\n", *addr);
+    PDEBUG(("%lx\n", *addr));
     count++;
   }
   return(0);
 }
 
 
-//
+
+/*
 // Instead of dealing with heaps directly, we look at the area cache of pages 
 // and vm pages and find an address there.
-//
+*/
 
 
 int heap_fault(pswifi_result_t res)
@@ -538,8 +561,8 @@ do_fault_copy_from_user (void *kaddr, const void *udaddr, unsigned long len,
          i = random() & 0xc00; 
        }
       }
-      PDEBUG("copyin: %p to %p, len=%ld overrun=%d, Intvl=%ld, inj=%ld\n", 
-            udaddr, kaddr, len, i, crashInterval, faultInjected);
+      PDEBUG(("copyin: %p to %p, len=%ld overrun=%d, Intvl=%ld, inj=%ld\n", 
+            udaddr, kaddr, len, i, crashInterval, faultInjected));
       if (faultInjected++ <numFaults) {
        len += i;
       } else {
@@ -581,8 +604,8 @@ do_fault_copy_to_user(void *udaddr, const void *kaddr, unsigned long len,
          i = random() & 0xc00; 
        }
       }
-      PDEBUG("copyout: %p to %p, len=%ld overrun=%d, Intvl=%ld, inj=%ld\n",
-            kaddr, udaddr, len, i, crashInterval, faultInjected);
+      PDEBUG(("copyout: %p to %p, len=%ld overrun=%d, Intvl=%ld, inj=%ld\n",
+            kaddr, udaddr, len, i, crashInterval, faultInjected));
       if (faultInjected++ <numFaults) {
        len+=i;
       } else  {
@@ -642,8 +665,8 @@ swifi_memcpy_fn (void *to, void *from, size_t len)
        }
       }
     
-      PDEBUG("memcpy: %p to %p, len=%d overrun=%d, Intvl=%ld, inj=%ld\n", 
-            from, to, len, i, crashInterval, faultInjected);
+      PDEBUG(("memcpy: %p to %p, len=%d overrun=%d, Intvl=%ld, inj=%ld\n", 
+            from, to, len, i, crashInterval, faultInjected));
       if(faultInjected++ <numFaults) len+=i;
       else faultInjected=0;
       i=1;
@@ -680,8 +703,8 @@ swifi_memmove_fn (void *to, void *from, size_t len)
        }
       }
     
-      PDEBUG("memmove: %p to %p, len=%d overrun=%d, Intvl=%ld, inj=%ld\n", 
-            from, to, len, i, crashInterval, faultInjected);
+      PDEBUG(("memmove: %p to %p, len=%d overrun=%d, Intvl=%ld, inj=%ld\n", 
+            from, to, len, i, crashInterval, faultInjected));
       if(faultInjected++ <numFaults) len+=i;
       else faultInjected=0;
       i=1;
@@ -723,8 +746,8 @@ do_fault_kfree(void *addr, void (* kfree_fn)(const void *))
       /* alternate between premature freeing and non-free */
       if(crashToggle) {
        if(crashAddr) { 
-         PDEBUG("malloc : freeing %p prematurely\n", 
-                crashAddr);
+         PDEBUG(("malloc : freeing %p prematurely\n", 
+                crashAddr));
          kfree_fn(crashAddr);
          kfree_fn(addr);
          crashAddr=0;
@@ -736,7 +759,7 @@ do_fault_kfree(void *addr, void (* kfree_fn)(const void *))
          }
        } 
       } else {
-       PDEBUG("free: don't free %p\n", addr); 
+       PDEBUG(("free: don't free %p\n", addr));
        if(faultInjected++ > numFaults) {
          faultInjected=0;
        }
@@ -752,11 +775,13 @@ do_fault_kfree(void *addr, void (* kfree_fn)(const void *))
   }
 }
 
+#if 0
 void
 swifi_kfree(const void *addr)
 {
   do_fault_kfree((void *) addr, kfree);
 }
+#endif
 
 
 void do_vfree(const void * addr)
@@ -782,7 +807,7 @@ do_fault_kmalloc(size_t size,
   if (faultInjected && (faultType==ALLOC_FAULT)) {
     crashCount++;
     if(crashCount>=crashInterval) {   
-      PDEBUG("kmalloc : returning null\n");
+      PDEBUG(("kmalloc : returning null\n"));
       crashCount=0;
       crashInterval = CRASH_INTERVAL + (random()&FI_MASK);
       if (faultInjected++ > numFaults) {
@@ -797,11 +822,13 @@ do_fault_kmalloc(size_t size,
 }
 
 
+#if 0
 void *
 swifi_kmalloc(size_t size, int flags)
 {
   return(do_fault_kmalloc(size, flags, kmalloc));
 }
+#endif
 
 
 
@@ -815,7 +842,7 @@ void * do_fault_vmalloc(unsigned long size,
   if (faultInjected && (faultType==ALLOC_FAULT)) {
     crashCount++;
     if(crashCount>=crashInterval) {   
-      PDEBUG("vmalloc : returning null\n");
+      PDEBUG(("vmalloc : returning null\n"));
       crashCount=0;
       crashInterval = CRASH_INTERVAL + (random()&FI_MASK);
       if (faultInjected++ > numFaults) {
@@ -836,6 +863,7 @@ swifi___vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
  
 
 
+#if 0
 typedef struct section_callback {
   const char * module_name;
   const char * section_name;
@@ -861,22 +889,20 @@ text_section_callback(void *token,
   }
   return(0);
 }
+#endif
 
 
-
-
-
-int text_fault(struct module * mod, pswifi_result_t res)
+int text_fault(char *mod_name, pswifi_result_t res)
 {   
   unsigned long *addr, text_size, offset, page, taddr;
   unsigned long btext, etext;
 
   int count, flip_bit=0, len, rc;
   unsigned char *c;
+#if 0
   struct module * module;
   section_callback_t info;
-
-  //
+#endif
 
 #define MAX_NUM_MODULES 10
 
@@ -885,21 +911,30 @@ int text_fault(struct module * mod, pswifi_result_t res)
   for(count=0; count<numFaults; count++) {
     int i = 1 + (random() % MAX_NUM_MODULES);
     int j = i;
+#if 0
     module = mod;
+#endif
 
+#if 0
     info.module_name = module->name;
+    info.module_name = "<module-name>";
     info.section_name = ".text";
 
     kallsyms_sections(&info, text_section_callback);
     if (info.sec_start == 0 ) {
       return(-1);
     }
+#endif
 
+    load_nlist(mod_name, &btext, &etext);
+
+#if 0
     btext = info.sec_start;
     etext = info.sec_end;
+#endif
     text_size = etext - btext;
     
-    PDEBUG("text=%lx-%lx, size=%lx\n", btext, etext, text_size);
+    PDEBUG(("text=%lx-%lx, size=%lx\n", btext, etext, text_size));
     
     addr = (unsigned long *) 
       (btext + ((unsigned long) (random()&~0xf) % text_size)); 
@@ -923,7 +958,11 @@ int text_fault(struct module * mod, pswifi_result_t res)
        continue;
       }
     }
-    PDEBUG("target addr=%lx, instr addr=%p, %lx=>", taddr, addr, *addr); 
+
+printf("len = %d\n", len);
+
+    PDEBUG(("target addr=%lx, instr addr=%p, %lx=>", taddr, addr,
+       text_read_ul(addr))); 
       
     offset = (unsigned long) addr&PAGE_MASK;
     page = (unsigned long) addr&~PAGE_MASK;
@@ -933,19 +972,19 @@ int text_fault(struct module * mod, pswifi_result_t res)
      */
       
     res[count].address = taddr;
-    res[count].old = *addr;
-    res[count].new = *addr;
+    res[count].old = text_read_ul(addr);
+    res[count].new = text_read_ul(addr);
 
     if (faultType==TEXT_FAULT) {
 
       flip_bit = random() & 0x1f;
-      PDEBUG("flip bit %d => ", flip_bit);
+      PDEBUG(("flip bit %d => ", flip_bit));
       flip_bit = 1 << flip_bit;
 
-      res[count].new = (*addr) ^ flip_bit;
+      res[count].new = text_read_ul(addr) ^ flip_bit;
       
       if (injectFault) {
-       *addr = ((*addr)^flip_bit); 
+       text_write_ul(addr, text_read_ul(addr)^flip_bit); 
       }
 
     } else if (faultType==NOP_FAULT || 
@@ -961,7 +1000,7 @@ int text_fault(struct module * mod, pswifi_result_t res)
          ((unsigned char *) &res[count].new)[j] = NOP;
        }
        if (injectFault) {
-         *c=NOP;
+         text_write_ub(c, NOP);
        }       
 
        c++;
@@ -971,7 +1010,7 @@ int text_fault(struct module * mod, pswifi_result_t res)
       int prefix;
       c=(unsigned char *) addr;
       do {
-       switch (*c) {
+       switch (text_read_ub(c)) {
        case 0x66: case 0x67: case 0x26: case 0x36:
        case 0x2e: case 0x3e: case 0x64: case 0x65:
        case 0xf0: case 0xf2: case 0xf3:
@@ -985,35 +1024,56 @@ int text_fault(struct module * mod, pswifi_result_t res)
          c++;
        }
       } while (prefix);
-      if(*c>=0xd8 && *c<=0xdf) {
+      if(text_read_ub(c)>=0xd8 && text_read_ub(c)<=0xdf) {
        /* don't mess with fp instruction, yet.
         * but there shouldn't be any fp instr in kernel.
         */
-       PDEBUG("floating point instruction, bailing out\n");
+       PDEBUG(("floating point instruction, bailing out\n"));
        i--;
        continue;
-      } else if(*c==0x0f) {
+      } else if(text_read_ub(c)==0x0f) {
        c++;
       }
-      if(*c==0x0f) {
+      if(text_read_ub(c)==0x0f) {
        c++;
       }
       c++;
       len = len-((long) c - (long) addr);
+      if (len == 0)
+      {
+       printf("tex_fault: len = %d\n", len);
+       count--;
+       continue;
+      }
+if (len == 0)
+{
+       int i;
+
+       printf(
+       "text_fault: bad length at address 0x%x, c = 0x%x, fault type %d\n",
+               addr, c, faultType);
+       printf("bytes:");
+       for (i= 0; i<16; i++)
+               printf(" 0x%02x", text_read_ub((char *)addr+i));
+       printf("\n");
+       abort();
+       *(int *)-4 = 0;
+}
       flip_bit = random() % (len*8);
-      PDEBUG("flip bit %d (len=%d) => ", flip_bit, len);
+      PDEBUG(("flip bit %d (len=%d) => ", flip_bit, len));
       for(j=0; j<len; j++) {
        /* go to the right byte */
        if(flip_bit<8) {
          flip_bit = 1 << flip_bit;
 
          if (j < sizeof(unsigned long)) {
-           ((unsigned char *) &res[count].new)[j] = (*c) ^ flip_bit;
+           ((unsigned char *) &res[count].new)[j] =
+               (text_read_ub(c) ^ flip_bit);
          }
 
 
          if (injectFault) {
-           *c=(*c^flip_bit);
+           text_write_ub(c, (text_read_ub(c)^flip_bit));
          }
 
          j=len;
@@ -1029,7 +1089,7 @@ int text_fault(struct module * mod, pswifi_result_t res)
       int prefix;
       c=(unsigned char *) addr;
       do {
-       switch (*c) {
+       switch (text_read_ub(c)) {
        case 0x66: case 0x67: case 0x26: case 0x36:
        case 0x2e: case 0x3e: case 0x64: case 0x65:
        case 0xf0: case 0xf2: case 0xf3:
@@ -1043,21 +1103,21 @@ int text_fault(struct module * mod, pswifi_result_t res)
          c++;
        }
       } while (prefix);
-      if(*c>=0xd8 && *c<=0xdf) {
+      if(text_read_ub(c)>=0xd8 && text_read_ub(c)<=0xdf) {
        /* don't mess with fp instruction, yet */
-       PDEBUG("floating point instruction, bailing out\n");
+       PDEBUG(("floating point instruction, bailing out\n"));
        i--;
        continue;
-      } else if(*c==0x0f) {
+      } else if(text_read_ub(c)==0x0f) {
        c++;
       }
-      if(*c==0x0f) {
+      if(text_read_ub(c)==0x0f) {
        c++;
       }
       c++;
       len = len-((long) c - (long) addr);
       flip_bit = random() % (len*8-4);
-      PDEBUG("flip bit %d (len=%d) => ", flip_bit, len);
+      PDEBUG(("flip bit %d (len=%d) => ", flip_bit, len));
 
       /* mod/rm byte is special */
 
@@ -1066,11 +1126,11 @@ int text_fault(struct module * mod, pswifi_result_t res)
 
        rc = c - (unsigned char *) addr;
        if (rc < sizeof(unsigned long)) {
-         ((unsigned char *) &res[count].new)[rc] = (*c) ^ flip_bit;
+         ((unsigned char *) &res[count].new)[rc] = text_read_ub(c) ^ flip_bit;
          
        }
        if (injectFault) {
-         *c=(*c^flip_bit);
+         text_write_ub(c, text_read_ub(c)^flip_bit);
        }
 
       }
@@ -1084,11 +1144,12 @@ int text_fault(struct module * mod, pswifi_result_t res)
 
          rc = (c - (unsigned char *) addr);
          if (rc < sizeof(unsigned long)) {
-           ((unsigned char *) &res[count].new)[rc] = (*c) ^ flip_bit;
+           ((unsigned char *) &res[count].new)[rc] =
+               text_read_ub(c) ^ flip_bit;
            
          }
          if (injectFault) {
-           *c=(*c^flip_bit);
+           text_write_ub(c, text_read_ub(c)^flip_bit);
          }
 
          j=len;
@@ -1099,7 +1160,7 @@ int text_fault(struct module * mod, pswifi_result_t res)
     } else if(faultType==LOOP_FAULT) {
       c=(unsigned char *) addr;
       /* replace rep with repe, and vice versa */
-       if(*c==0xf3) {
+       if(text_read_ub(c)==0xf3) {
          if (j < sizeof(unsigned long)) {
            ((unsigned char *) &res[count].new)[j] = NOP;
          }
@@ -1110,81 +1171,82 @@ int text_fault(struct module * mod, pswifi_result_t res)
            
          }
          if (injectFault) {
-           *c=0xf2;
+           text_write_ub(c, 0xf2);
          }
-       } else if(*c==0xf2) {
+       } else if(text_read_ub(c)==0xf2) {
          rc = (c - (unsigned char *) addr);
          if (rc < sizeof(unsigned long)) {
            ((unsigned char *) &res[count].new)[rc] = 0xf3;
            
          }
          if (injectFault) {
-           *c=0xf3;
+           text_write_ub(c, 0xf3);
          }
-       } else if( ((*c)&0xf0)==0x70 ) {
+       } else if( (text_read_ub(c)&0xf0)==0x70 ) {
          /* if we've jxx imm8 instruction, 
           * incl even byte instruction, eg jo (70) to jno (71)
           * decl odd byte instruction,  eg jnle (7f) to jle (7e)
           */ 
-         if(*c%2 == 0) { 
+         if(text_read_ub(c)%2 == 0) { 
            rc = (c - (unsigned char *) addr);
            if (rc < sizeof(unsigned long)) {
-             ((unsigned char *) &res[count].new)[rc] = (*c) + 1;
+             ((unsigned char *) &res[count].new)[rc] = text_read_ub(c) + 1;
            
            }
 
            if (injectFault) {
-             *c = *c+1;
+             text_write_ub(c, text_read_ub(c)+1);
            }
          }  else {
 
            rc = (c - (unsigned char *) addr);
            if (rc < sizeof(unsigned long)) {
-             ((unsigned char *) &res[count].new)[rc] = (*c) - 1;
+             ((unsigned char *) &res[count].new)[rc] = text_read_ub(c) - 1;
              
            }
 
            if (injectFault) {
-             *c = *c-1;
+             text_write_ub(c, text_read_ub(c)-1);
            }
          }
-       } else if(*c==0x66 || *c==0x67) {       /* override prefix */
+       } else if(text_read_ub(c)==0x66 || text_read_ub(c)==0x67)       { 
+               /* override prefix */
          c++;
-       } else if(*(c++)==0xf && ((*c)&0xf0)==0x80 ) {
+       } else if(text_read_ub(c++)==0xf && (text_read_ub(c)&0xf0)==0x80 ) {
          /* if we've jxx imm16/32 instruction, 
           * incl even byte instruction, eg jo (80) to jno (81)
           * decl odd byte instruction,  eg jnle (8f) to jle (8e)
           */ 
-         if(*c%2 == 0) {
+         if(text_read_ub(c)%2 == 0) {
            rc = (c - (unsigned char *) addr);
            if (rc < sizeof(unsigned long)) {
-             ((unsigned char *) &res[count].new)[rc] = (*c) + 1;
+             ((unsigned char *) &res[count].new)[rc] = text_read_ub(c) + 1;
              
            }
            if (injectFault) {
-             *c = *c+1;
+             text_write_ub(c, text_read_ub(c)+1);
            }
          } else {
            rc = (c - (unsigned char *) addr);
            if (rc < sizeof(unsigned long)) {
-             ((unsigned char *) &res[count].new)[rc] = (*c) -1;
+             ((unsigned char *) &res[count].new)[rc] = text_read_ub(c) -1;
              
            }
 
            if (injectFault) {
-             *c = *c-1;
+             text_write_ub(c, text_read_ub(c)-1);
            }
          }
        }
       
     }
-    PDEBUG("%lx\n", *addr);
+    PDEBUG(("%lx\n", text_read_ul(addr)));
   }
   return(0);
 }
 
 
-#else // CONFIG_SWIFI
+#else /* CONFIG_SWIFI */
 
 long
 sys_inject_fault(char * module_name,
@@ -1197,5 +1259,4 @@ sys_inject_fault(char * module_name,
   return(0);
 }
 
-#endif // CONFIG_SWIFI
-
+#endif /* CONFIG_SWIFI */
diff --git a/commands/swifi/read_nlist.c b/commands/swifi/read_nlist.c
new file mode 100644 (file)
index 0000000..1c50df3
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+read_nlist.c
+
+Read the symbol table of an executable into memory. 
+
+Created:       Mar 6, 1992 by Philip Homburg
+*/
+
+#include <sys/types.h>
+#include <assert.h>
+#include <a.out.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "extra.h"
+
+#define USE_OLD_NLIST  1
+
+static u16_t le16 _ARGS(( u16_t *word_p ));
+static u32_t le32 _ARGS(( u32_t *word_p ));
+static u16_t be16 _ARGS(( u16_t *word_p ));
+static u32_t be32 _ARGS(( u32_t *word_p ));
+
+static u16_t le16(word_p)
+u16_t *word_p;
+{
+       return (((u8_t *)word_p)[0] << 0) | (((u8_t *)word_p)[1] << 8);
+}
+
+static u16_t be16(word_p)
+u16_t *word_p;
+{
+       return (((u8_t *)word_p)[1] << 0) | (((u8_t *)word_p)[0] << 8);
+}
+
+static u32_t le32(dword_p)
+u32_t *dword_p;
+{
+       return le16(&((u16_t *)dword_p)[0]) |
+               ((u32_t)le16(&((u16_t *)dword_p)[1]) << 16);
+}
+
+static u32_t be32(dword_p)
+u32_t *dword_p;
+{
+       return be16(&((u16_t *)dword_p)[1]) |
+               ((u32_t)be16(&((u16_t *)dword_p)[0]) << 16);
+}
+
+#ifndef USE_OLD_NLIST
+struct old_nlist
+{
+       char n_name[8];
+       long n_value;
+       unsigned char n_sclass;
+       unsigned char n_numaux;
+       unsigned char n_type;
+};
+
+/* Low bits of storage class (section). */
+#define O_N_SECT            07    /* section mask */
+#define O_N_UNDF            00    /* undefined */
+#define O_N_ABS             01    /* absolute */
+#define O_N_TEXT            02    /* text */
+#define O_N_DATA            03    /* data */
+#define O_N_BSS             04    /* bss */
+#define O_N_COMM            05    /* (common) */
+
+/* High bits of storage class. */
+#define O_N_CLASS         0370    /* storage class mask */
+#define O_C_NULL
+#define O_C_EXT           0020    /* external symbol */
+#define O_C_STAT          0030    /* static */
+#endif
+
+int read_nlist(filename, nlist_table)
+const char *filename;  
+struct nlist **nlist_table;
+{
+       int r, n_entries, save_err;
+       u32_t (*cnv32) _ARGS(( u32_t *addr ));
+       u16_t (*cnv16) _ARGS(( u16_t *addr ));
+       struct nlist *nlist_p, *nlist_ptr;
+       int exec_fd;
+       struct exec exec_header;
+#ifndef USE_OLD_NLIST
+       struct old_nlist *old_nlist, *old_nlist_p;
+       void *old_nlist_end;
+#endif
+       char *str_tab, *str_base, *str_null;
+       u32_t string_siz;
+
+       exec_fd= open(filename, O_RDONLY);
+       if (exec_fd == -1)                      /* No executable present */
+       {
+               return -1;
+       }
+
+       r= read(exec_fd, (char *)&exec_header, A_MINHDR);
+       if (r != A_MINHDR)
+       {
+               if (r != -1)
+                       errno= ENOEXEC;
+               return -1;
+       }
+       if (BADMAG(exec_header))
+       {
+               errno= ENOEXEC;
+               return -1;
+       }
+       switch(exec_header.a_cpu & 3)
+       {
+       case 0: /* little endian */
+               cnv32= le32;
+               cnv16= le16;
+               break;
+       case 3: /* big endian */
+               cnv32= be32;
+               cnv16= be16;
+               break;
+       default:
+               errno= ENOEXEC;
+               return -1;
+       }
+       exec_header.a_version= cnv16((u16_t *)&exec_header.a_version);
+       exec_header.a_text= cnv32((u32_t *)&exec_header.a_text);
+       exec_header.a_data= cnv32((u32_t *)&exec_header.a_data);
+       exec_header.a_bss= cnv32((u32_t *)&exec_header.a_bss);
+       exec_header.a_entry= cnv32((u32_t *)&exec_header.a_entry);
+       exec_header.a_total= cnv32((u32_t *)&exec_header.a_total);
+       exec_header.a_syms= cnv32((u32_t *)&exec_header.a_syms);
+       exec_header.a_trsize= cnv32((u32_t *)&exec_header.a_trsize);
+       exec_header.a_drsize= cnv32((u32_t *)&exec_header.a_drsize);
+       exec_header.a_tbase= cnv32((u32_t *)&exec_header.a_tbase);
+       exec_header.a_dbase= cnv32((u32_t *)&exec_header.a_dbase);
+
+       if (!exec_header.a_syms)
+               return 0;
+               
+       if (exec_header.a_flags & A_NSYM)
+       {
+#if USE_OLD_NLIST
+               errno= EINVAL;
+               return -1;
+#else
+               r= lseek(exec_fd, A_SYMPOS(exec_header)+exec_header.a_syms,
+                       SEEK_SET);
+               if (r == -1)
+               {
+                       return -1;
+               }
+               r= read(exec_fd, (char *)&string_siz, 4);
+               if (r != 4)
+                       return -1;
+               string_siz= cnv32(&string_siz)-4;
+               nlist_p= malloc(exec_header.a_syms + string_siz+1);
+               if (!nlist_p)
+               {
+                       errno= ENOMEM;
+                       return -1;
+               }
+               r= lseek(exec_fd, A_SYMPOS(exec_header)+exec_header.a_syms+4,
+                       SEEK_SET);
+               if (r == -1)
+               {
+                       save_err= errno;
+                       free(nlist_p);
+                       errno= save_err;
+                       return -1;
+               }
+               r= read(exec_fd, ((char *)nlist_p)+exec_header.a_syms,
+                       string_siz);
+               if (r != string_siz)
+               {
+                       save_err= errno;
+                       free(nlist_p);
+                       errno= save_err;
+                       return -1;
+               }
+               r= lseek(exec_fd, A_SYMPOS(exec_header), SEEK_SET);
+               if (r == -1)
+               {
+                       save_err= errno;
+                       free(nlist_p);
+                       errno= save_err;
+                       return -1;
+               }
+               r= read(exec_fd, ((char *)nlist_p), exec_header.a_syms);
+               if (r != exec_header.a_syms)
+               {
+                       save_err= errno;
+                       free(nlist_p);
+                       errno= save_err;
+                       return -1;
+               }
+               str_base= ((char *)nlist_p) + exec_header.a_syms -4;
+               str_null= (char *)nlist_p + exec_header.a_syms + string_siz;
+               *str_null= '\0';
+               for (nlist_ptr= nlist_p; (char *)nlist_ptr+1 <= str_base+4;
+                                                               nlist_ptr++)
+               {
+                       nlist_ptr->n_desc= le16((u16_t *)&nlist_ptr->n_desc);
+                       nlist_ptr->n_value= le32(&nlist_ptr->n_value);
+                       if (nlist_ptr->n_un.n_strx)
+                               nlist_ptr->n_un.n_name= str_base+
+                                       cnv32((u32_t *)&nlist_ptr->n_un.n_strx);
+                       else
+                               nlist_ptr->n_un.n_name= str_null;
+               }
+               *nlist_table= nlist_p;
+               return nlist_ptr-nlist_p;
+#endif
+       }
+       else
+       {
+               r= lseek(exec_fd, A_SYMPOS(exec_header), SEEK_SET);
+               if (r == -1)
+               {
+                       return -1;
+               }
+               
+#if USE_OLD_NLIST
+               n_entries= exec_header.a_syms/sizeof(struct nlist);
+               nlist_p= malloc(exec_header.a_syms);
+               if (!nlist_p)
+               {
+                       free(nlist_p);
+                       errno= ENOMEM;
+                       return -1;
+               }
+               r= read(exec_fd, (char *)nlist_p, exec_header.a_syms);
+               if (r != exec_header.a_syms)
+               {
+                       save_err= errno;
+                       free(nlist_p);
+                       errno= save_err;
+                       return -1;
+               }
+
+               *nlist_table= nlist_p;
+               return n_entries;
+#else
+               n_entries= exec_header.a_syms/sizeof(struct old_nlist)+1;
+               nlist_p= NULL;
+               old_nlist= NULL;
+
+               nlist_p= malloc(n_entries * (sizeof(struct nlist)+
+                       sizeof(old_nlist->n_name)+1));
+               old_nlist= malloc(exec_header.a_syms);
+               if (!old_nlist || !nlist_p)
+               {
+                       if (nlist_p)
+                               free(nlist_p);
+                       if (old_nlist)
+                               free(old_nlist);
+                       errno= ENOMEM;
+                       return -1;
+               }
+               r= read(exec_fd, (char *)old_nlist, exec_header.a_syms);
+               if (r != exec_header.a_syms)
+               {
+                       save_err= errno;
+                       free(nlist_p);
+                       free(old_nlist);
+                       errno= save_err;
+                       return -1;
+               }
+
+               old_nlist_end= (char *)old_nlist+exec_header.a_syms;
+               str_tab= (char *)&nlist_p[n_entries];
+               n_entries= 0;
+               for (old_nlist_p= old_nlist; 
+                       (void *)(old_nlist_p+1)<=old_nlist_end; old_nlist_p++)
+               {
+                       switch(old_nlist_p->n_sclass & O_N_SECT)
+                       {
+                       case O_N_UNDF:
+                               nlist_p[n_entries].n_type= N_UNDF;
+                               break;
+                       case O_N_ABS:
+                               nlist_p[n_entries].n_type= N_ABS;
+                               break;
+                       case O_N_TEXT:
+                               nlist_p[n_entries].n_type= N_TEXT;
+                               break;
+                       case O_N_DATA:
+                               nlist_p[n_entries].n_type= N_DATA;
+                               break;
+                       case O_N_BSS:
+                               nlist_p[n_entries].n_type= N_BSS;
+                               break;
+                       case O_N_COMM:
+                               nlist_p[n_entries].n_type= N_COMM;
+                               break;
+                       default:
+                               continue;
+                       }
+                       switch(old_nlist_p->n_sclass & O_N_CLASS)
+                       {
+                       case O_C_EXT:
+                               nlist_p[n_entries].n_type |= N_EXT;
+                       case O_C_STAT:
+                               break;
+                       default:
+                               continue;
+                       }
+                       nlist_p[n_entries].n_value= 
+                               cnv32((u32_t *)&old_nlist_p->n_value);
+                       nlist_p[n_entries].n_un.n_name= str_tab;
+                       memcpy(str_tab, old_nlist_p->n_name, 
+                               sizeof(old_nlist_p->n_name));
+                       str_tab += sizeof(old_nlist_p->n_name);
+                       *str_tab++= '\0';
+                       n_entries++;
+               }
+               free(old_nlist);
+               nlist_p= realloc(nlist_p, str_tab-(char *)nlist_p);
+               *nlist_table= nlist_p;
+               return n_entries;
+#endif
+       }
+}
+
+/*
+ * $PchId: read_nlist.c,v 1.5 1996/04/11 07:47:38 philip Exp $
+ */
diff --git a/commands/swifi/rnd.c b/commands/swifi/rnd.c
new file mode 100644 (file)
index 0000000..4412e2f
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+rnd.c
+
+Generate random numbers
+*/
+
+#define _POSIX_SOURCE
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static char *progname;
+
+static void fatal(char *fmt, ...);
+static void usage(void);
+
+int main(int argc, char *argv[])
+{
+       int c, i, count;
+       unsigned long n, v, high, modulus;
+       unsigned seed;
+       char *check;
+       char *c_arg, *m_arg, *s_arg;
+
+       (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
+
+       c_arg= m_arg= s_arg= NULL;
+       while (c= getopt(argc, argv, "?c:m:s:"), c != -1)
+       {
+               switch(c)
+               {
+               case 'c': c_arg= optarg; break;
+               case 'm': m_arg= optarg; break;
+               case 's': s_arg= optarg; break;
+               default:
+                       fatal("getopt failed: '%c'", c);
+               }
+       }
+       if (optind != argc)
+               usage();
+       if (c_arg)
+       {
+               count= strtol(c_arg, &check, 0);
+               if (check[0] != '\0')
+                       fatal("bad count '%s'", c_arg);
+       }
+       else
+               count= 1;
+       if (m_arg)
+       {
+               modulus= strtoul(m_arg, &check, 0);
+               if (check[0] != '\0' || modulus == 0)
+                       fatal("bad modulus '%s'", m_arg);
+               n= 0x80000000UL / modulus;
+               if (n == 0)
+                       fatal("bad modulus %lu (too big)", modulus);
+               high= n * modulus;
+       }
+       else
+               modulus= high= 0x80000000UL;
+       if (s_arg)
+       {
+               seed= strtol(s_arg, &check, 0);
+               if (check[0] != '\0')
+                       fatal("bad seed '%s'", s_arg);
+               srandom(seed);
+       }
+
+       for (i= 0; i<count; i++)
+       {
+               do
+               {
+                       v= random();
+               } while (v > high);
+
+               printf("%lu\n", v % modulus);
+       }
+}
+
+static void fatal(char *fmt, ...)
+{
+       va_list ap;
+
+       fprintf(stderr, "%s: ", progname);
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, "\n");
+       exit(1);
+}
+
+static void usage(void)
+{
+       fprintf(stderr, "Usage: rnd [-c <count>] [-m <modulus>] [-s <seed>]\n");
+       exit(1);
+}
diff --git a/commands/swifi/rs.restart_imm b/commands/swifi/rs.restart_imm
new file mode 100755 (executable)
index 0000000..815a842
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# 'Recovery' script immediately restarts.
+echo "Arguments: $@" >/dev/console
+service restart "$1"
diff --git a/commands/swifi/run_swifi b/commands/swifi/run_swifi
new file mode 100644 (file)
index 0000000..8553419
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+LABEL=dp8390
+EXEDIR=/usr/build/drivers/dp8390
+EXE=$EXEDIR/$LABEL
+
+:>log
+
+do_one()
+{
+       # $1 = test-nr, $2 = count, $3 = seed
+       pid=''
+       while [ X"$pid" = X ]
+       do
+               pid=`ps ax | grep $LABEL | grep -v grep |
+                       sed 's,^[       ]*,,;s,[        ].*,,`
+               if [ X"$pid" != X ]
+               then
+                       break
+               fi
+               sleep 10
+       done
+       echo pid = $pid
+       ./swifi -f $EXE $pid $1 $2 $3 >/tmp/out
+       sleep 1
+       kill -0 $pid &&
+               echo "driver failed to die, params: test $1, count $2, seed $3"
+}
+
+one_round()
+{
+       # $1 = count, $2 = seed
+       count=$1
+       seed=$2
+       echo "Seed: $seed" >> log
+       sync
+       do_one 6 $count $seed   # Source fault
+       do_one 5 $count $seed   # Destination fault
+       do_one 8 $count $seed   # Pointer fault
+       do_one 14 $count $seed  # Interface fault
+       do_one 12 $count $seed  # Loop fault
+       do_one 0 $count $seed   # Text fault
+       do_one 4 $count $seed   # Nop fault
+}
+
+# Start our own driver.
+service down $LABEL
+sleep 10       # Allow driver to die
+service up $EXE -script `pwd`/rs.restart_imm -config /etc/drivers.conf -period 3HZ
+
+i=0
+i=4000
+while [ $i -lt 10000 ]
+do
+       echo "Seed: $i"
+       one_round 100 $i
+       i=`expr $i + 1`
+done
diff --git a/commands/swifi/run_swifi-x b/commands/swifi/run_swifi-x
new file mode 100644 (file)
index 0000000..14b0934
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/sh
+do_one()
+{
+       # $1 = test-nr, $2 = count, $3 = seed
+       pid=''
+       while [ X"$pid" = X ]
+       do
+               pid=`ps ax | grep dp8390 | grep usr.sbin |
+                       sed 's,^[       ]*,,;s,[        ].*,,`
+               sleep 1
+       done
+       echo pid = $pid
+       ./swifi -f /usr/build/drivers/dp8390/dp8390 $pid $1 $2 $3 >/tmp/out
+       sleep 5
+       kill -0 $pid &&
+               echo "driver failed to die, params: test $1, count $2, seed $3"
+}
+
+one_round()
+{
+       # $1 = count, $2 = seed
+       count=$1
+       seed=$2
+       do_one 6 $count $seed   # Source fault
+       do_one 5 $count $seed   # Destination fault
+       do_one 8 $count $seed   # Pointer fault
+       do_one 14 $count $seed  # Interface fault
+       do_one 12 $count $seed  # Loop fault
+       do_one 0 $count $seed   # Text fault
+       do_one 4 $count $seed   # Nop fault
+}
+
+i=4
+while [ $i -lt 100 ]
+do
+       echo "Seed: $i"
+       one_round 100 $i
+       i=`expr $i + 1`
+done
diff --git a/commands/swifi/run_t1 b/commands/swifi/run_t1
new file mode 100755 (executable)
index 0000000..1bb2d52
--- /dev/null
@@ -0,0 +1,122 @@
+#!/bin/sh
+
+LABEL=es1371
+EXEDIR=/usr/build/drivers/es1371
+#LABEL=fxp
+#EXEDIR=/usr/build/drivers/fxp
+EXE=$EXEDIR/$LABEL
+DEV="-dev /dev/audio"
+
+:>log
+
+do_one()
+{
+       # $1 = test-nr, $2 = count, $3 = seed
+       pid=''
+       while [ X"$pid" = X ]
+       do
+               ps ax | grep $LABEL | grep -v grep
+               pid=`ps ax | grep $LABEL | grep -v grep |
+                       sort -n | tail -1 |
+                       sed 's,^[       ]*,,;s,[        ].*,,`
+               if [ X"$pid" != X ]
+               then
+                       break
+               fi
+               sleep 10
+       done
+       echo pid = $pid
+       ./swifi -f $EXE $pid $1 $2 $3 >/tmp/out
+       sleep 1
+       kill -0 $pid &&
+               echo "driver failed to die, params: test $1, count $2, seed $3"
+}
+
+one_round()
+{
+       # $1 = count, $2 = seed
+       count=$1
+       seed=$2
+       echo "Seed: $seed" >> log
+       sync
+       do_one 6 $count $seed   # Source fault
+       do_one 5 $count $seed   # Destination fault
+       do_one 8 $count $seed   # Pointer fault
+       do_one 14 $count $seed  # Interface fault
+       do_one 12 $count $seed  # Loop fault
+       do_one 0 $count $seed   # Text fault
+       do_one 4 $count $seed   # Nop fault
+}
+
+usage()
+{
+       echo "Usage: run_t1 <count> <type> <seed>" >&2
+       echo \
+"Valid types are: source destination pointer interface loop text nop random" >&2
+       exit 1
+}
+
+select_from()
+{
+       # $1 = index, $2... = choices
+       index="$1"
+       index=`expr "$index" + 1`
+       shift
+       v=`eval echo '$'$index`
+       echo "$v"
+}
+
+random_type()
+{
+       # $1 = seed
+       seed="$1"
+       r=`./rnd -m 7 -s "$seed"`
+       select_from "$r" 6 5 8 14 12 0 4
+}
+
+if [ $# -ne 3 ]; then usage; fi
+count="$1"
+type="$2"
+seed="$3"
+
+case "$type" in
+source)                type_arg=6
+;;
+destination)   type_arg=5
+;;
+pointer)       type_arg=8
+;;
+interface)     type_arg=14
+;;
+loop)          type_arg=12
+;;
+text)          type_arg=0
+;;
+nop)           type_arg=4
+;;
+random)                
+;;
+*)
+       usage
+esac
+
+# Start our own driver.
+service down $LABEL
+sleep 2        # Allow driver to die
+service -i up $EXE -script `pwd`/rs.restart_imm -config /etc/drivers.conf -period 3HZ $DEV
+
+i=0
+while [ $i -lt "$count" ]
+do
+       echo "Seed: $seed"
+       if [ "$type" = "random" ]
+       then
+               type_arg=`random_type $seed`
+       fi
+       do_one "$type_arg" 100 $seed
+       i=`expr $i + 1`
+       seed=`expr $seed + 1`
+done
+
+# Restart the driver
+service refresh $LABEL
diff --git a/commands/swifi/run_t1a b/commands/swifi/run_t1a
new file mode 100755 (executable)
index 0000000..efa0665
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+set -x
+
+if [ $# -ne 2 ]; then usage; fi
+type="$1"
+run="$2"
+
+count=1000
+
+# Rotate syslog
+LOGFILE=/var/log/messages
+mv $LOGFILE $LOGFILE.prev
+(cd /var/log && : > messages)
+kill -1 `ps ax | grep syslogd | grep -v grep |
+       sed 's,^[        ]*,,;s,[        ].*,,'`
+
+./run_t1 $count $type `expr $run \* 1000` 2>&1 | 
+       tee results/1.$type.$run.out
+
+cp $LOGFILE results/1.$type.$run.log
+
+
diff --git a/commands/swifi/run_t1b b/commands/swifi/run_t1b
new file mode 100755 (executable)
index 0000000..2a513c4
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+run=0
+
+./run_t1a interface $run
+
+./run_t1a source $run
+./run_t1a destination $run
+./run_t1a pointer $run
+./run_t1a interface $run
+./run_t1a loop $run
+./run_t1a text $run
+./run_t1a nop $run
+./run_t1a random $run
diff --git a/commands/swifi/run_t2 b/commands/swifi/run_t2
new file mode 100755 (executable)
index 0000000..debdf57
--- /dev/null
@@ -0,0 +1,146 @@
+#!/bin/sh
+
+LABEL=dp8390
+EXEDIR=/usr/build/drivers/dp8390
+EXE=$EXEDIR/$LABEL
+DAYTIME_HOST=jetsam.cs.vu.nl
+FAULTS_PER_BLOCK=1
+
+:>log
+
+fault_blocks=0
+connect_blocks=0
+dont_connect=0
+
+do_one()
+{
+       # $1 = test-nr, $2 = count, $3 = seed
+       pid=''
+       while [ X"$pid" = X ]
+       do
+               pid=`ps ax | grep $LABEL | grep -v grep |
+                       sed 's,^[       ]*,,;s,[        ].*,,`
+               if [ X"$pid" != X ]
+               then
+                       break
+               fi
+               sleep 10
+       done
+       echo pid = $pid
+       ./swifi -f $EXE $pid $1 $2 $3 >/tmp/out
+       sleep 1
+       fault_blocks=`expr $fault_blocks + 1`
+       if kill -0 $pid 
+       then
+               if [ $dont_connect -eq 0 ]
+               then
+                       if ./socket -t 10 $DAYTIME_HOST daytime < /dev/null
+                       then
+                               connect_blocks=`expr $connect_blocks + 1`
+                       else
+                               dont_connect=1
+                       fi
+               fi
+               echo "driver failed to die, params: test $1, count $2, seed $3"
+       else
+               connect_blocks=`expr $connect_blocks + 1`
+               echo "driver crashed after $fault_blocks blocks"
+               echo "driver failed to connect after $connect_blocks blocks"
+               fault_blocks=0
+               connect_blocks=0
+               dont_connect=0
+       fi
+}
+
+one_round()
+{
+       # $1 = count, $2 = seed
+       count=$1
+       seed=$2
+       echo "Seed: $seed" >> log
+       sync
+       do_one 6 $count $seed   # Source fault
+       do_one 5 $count $seed   # Destination fault
+       do_one 8 $count $seed   # Pointer fault
+       do_one 14 $count $seed  # Interface fault
+       do_one 12 $count $seed  # Loop fault
+       do_one 0 $count $seed   # Text fault
+       do_one 4 $count $seed   # Nop fault
+}
+
+usage()
+{
+       echo "Usage: run_t2 <count> <type> <seed>" >&2
+       echo \
+"Valid types are: source destination pointer interface loop text nop random" >&2
+       exit 1
+}
+
+select_from()
+{
+       # $1 = index, $2... = choices
+       index="$1"
+       index=`expr "$index" + 1`
+       shift
+       v=`eval echo '$'$index`
+       echo "$v"
+}
+
+random_type()
+{
+       # $1 = seed
+       seed="$1"
+       r=`./rnd -m 7 -s "$seed"`
+       select_from "$r" 6 5 8 14 12 0 4
+}
+
+if [ $# -ne 3 ]; then usage; fi
+count="$1"
+type="$2"
+seed="$3"
+
+case "$type" in
+source)                type_arg=6
+;;
+destination)   type_arg=5
+;;
+pointer)       type_arg=8
+;;
+interface)     type_arg=14
+;;
+loop)          type_arg=12
+;;
+text)          type_arg=0
+;;
+nop)           type_arg=4
+;;
+random)                
+;;
+*)
+       usage
+esac
+
+# Start our own driver.
+service down $LABEL
+sleep 10       # Allow driver to die
+service up $EXE -script `pwd`/rs.restart_imm -config /etc/drivers.conf -period 3HZ
+
+i=0
+while [ $i -lt "$count" ]
+do
+       echo "Seed: $seed"
+       if [ "$type" = "random" ]
+       then
+               type_arg=`random_type $seed`
+       fi
+       do_one "$type_arg" $FAULTS_PER_BLOCK $seed
+       i=`expr $i + 1`
+       seed=`expr $seed + 1`
+done
+
+connect_blocks=`expr $connect_blocks + 1`
+echo "driver crashed after $fault_blocks blocks"
+echo "driver failed to connect after $connect_blocks blocks"
+
+# Restart the driver
+service refresh $LABEL
diff --git a/commands/swifi/run_t2a b/commands/swifi/run_t2a
new file mode 100755 (executable)
index 0000000..8af4b06
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+set -x
+
+if [ $# -ne 2 ]; then usage; fi
+type="$1"
+run="$2"
+
+count=10000
+
+# Rotate syslog
+LOGFILE=/var/log/messages
+mv $LOGFILE $LOGFILE.prev
+(cd /var/log && : > messages)
+kill -1 `ps ax | grep syslogd | grep -v grep |
+       sed 's,^[        ]*,,;s,[        ].*,,'`
+
+./run_t2 $count $type `expr $run \* 1000` 2>&1 | 
+       tee results/2.$type.$run.out
+
+cp $LOGFILE results/2.$type.$run.log
+
+
diff --git a/commands/swifi/run_t2b b/commands/swifi/run_t2b
new file mode 100755 (executable)
index 0000000..a488288
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+run=0
+
+./run_t2a interface $run
+exit
+
+./run_t2a source $run
+./run_t2a destination $run
+./run_t2a pointer $run
+#./run_t2a interface $run
+./run_t2a loop $run
+#./run_t2a text $run
+#./run_t2a nop $run
+#./run_t2a random $run
diff --git a/commands/swifi/socket.c b/commands/swifi/socket.c
new file mode 100644 (file)
index 0000000..324b7f1
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+socket.c
+
+Created:       Feb 2001 by Philip Homburg <philip@f-mnx.phicoh.com>
+
+Open a TCP connection
+*/
+
+#define _POSIX_C_SOURCE 2
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+
+#include <net/hton.h>
+#include <net/netlib.h>
+#include <net/gen/in.h>
+#include <net/gen/inet.h>
+#include <net/gen/netdb.h>
+#include <net/gen/socket.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+
+#define BUF_SIZE       10240
+
+char *progname;
+int tcpfd= -1;
+char buf[BUF_SIZE];
+static int bulk= 0;
+static int push= 0;
+static int stdout_issocket= 0;
+static int timeout;
+
+static void do_conn(char *hostname, char *portname);
+static void alrm_conn(int sig);
+static void alrm_io(int sig);
+static void fullduplex(void);
+static void fatal(char *msg, ...);
+static void usage(void);
+
+int main(int argc, char *argv[])
+{
+       int c;
+       char *hostname;
+       char *portname;
+       char *check;
+       int B_flag, P_flag, s_flag;
+       char *t_arg;
+
+       (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
+
+       B_flag= 0;
+       P_flag= 0;
+       s_flag= 0;
+       t_arg= NULL;
+       while (c= getopt(argc, argv, "BPst:?"), c != -1)
+       {
+               switch(c)
+               {
+               case 'B':       B_flag= 1; break;
+               case 'P':       P_flag= 1; break;
+               case 's':       s_flag= 1; break;
+               case 't':       t_arg= optarg; break;
+               case '?':       usage();
+               default:
+                       fatal("getopt failed: '%c'", c);
+               }
+       }
+       if (t_arg)
+       {
+               timeout= strtol(t_arg, &check, 0);
+               if (check[0] != '\0')
+                       fatal("unable to parse timeout '%s'\n", t_arg);
+               if (timeout <= 0)
+                       fatal("bad timeout '%d'\n", timeout);
+       }
+       else
+               timeout= 0;
+
+       if (optind+2 != argc)
+               usage();
+       hostname= argv[optind++];
+       portname= argv[optind++];
+
+       bulk= B_flag;
+       push= P_flag;
+       stdout_issocket= s_flag;
+
+       do_conn(hostname, portname);
+
+       /* XXX */
+       if (timeout)
+       {
+               signal(SIGALRM, alrm_io);
+               alarm(timeout);
+       }
+
+       fullduplex();
+       exit(0);
+}
+
+static void do_conn(char *hostname, char *portname)
+{
+       ipaddr_t addr;
+       tcpport_t port;
+       struct hostent *he;
+       struct servent *se;
+       char *tcp_device, *check;
+       nwio_tcpconf_t tcpconf;
+       nwio_tcpcl_t tcpcl;
+       nwio_tcpopt_t tcpopt;
+
+       if (!inet_aton(hostname, &addr))
+       {
+               he= gethostbyname(hostname);
+               if (he == NULL)
+                       fatal("unknown hostname '%s'", hostname);
+               if (he->h_addrtype != AF_INET || he->h_length != sizeof(addr))
+                       fatal("bad address for '%s'", hostname);
+               memcpy(&addr, he->h_addr, sizeof(addr));
+       }
+
+       port= strtol(portname, &check, 0);
+       if (check[0] != 0)
+       {
+               se= getservbyname(portname, "tcp");
+               if (se == NULL)
+                       fatal("unkown port '%s'", portname);
+               port= ntohs(se->s_port);
+       }
+
+       tcp_device= getenv("TCP_DEVICE");
+       if (tcp_device == NULL) tcp_device= TCP_DEVICE;
+
+       tcpfd= open(tcp_device, O_RDWR);
+       if (tcpfd == -1)
+               fatal("unable to open '%s': %s", tcp_device, strerror(errno));
+       tcpconf.nwtc_flags= NWTC_EXCL | NWTC_LP_SEL | NWTC_SET_RA |
+               NWTC_SET_RP;
+       tcpconf.nwtc_remaddr= addr;
+       tcpconf.nwtc_remport= htons(port);;
+       if (ioctl(tcpfd, NWIOSTCPCONF, &tcpconf) == -1)
+               fatal("NWIOSTCPCONF failed: %s", strerror(errno));
+
+       if (timeout)
+       {
+               signal(SIGALRM, alrm_conn);
+               alarm(timeout);
+       }
+
+       tcpcl.nwtcl_flags= 0;
+       if (ioctl(tcpfd, NWIOTCPCONN, &tcpcl) == -1)
+       {
+               fatal("unable to connect to %s:%u: %s", inet_ntoa(addr),
+                       ntohs(tcpconf.nwtc_remport), strerror(errno));
+       }
+
+       alarm(0);
+
+       if (bulk)
+       {
+               tcpopt.nwto_flags= NWTO_BULK;
+               if (ioctl(tcpfd, NWIOSTCPOPT, &tcpopt) == -1)
+                       fatal("NWIOSTCPOPT failed: %s", strerror(errno));
+       }
+}
+
+static void alrm_conn(int sig)
+{
+       fatal("timeout during connect");
+}
+
+static void alrm_io(int sig)
+{
+       fatal("timeout during io");
+}
+
+static void fullduplex(void)
+{
+       pid_t cpid;
+       int o, r, s, s_errno, loc;
+
+       cpid= fork();
+       switch(cpid)
+       {
+       case -1:        fatal("fork failed: %s", strerror(errno));
+       case 0:
+               /* Read from TCP, write to stdout. */
+               for (;;)
+               {
+                       r= read(tcpfd, buf, BUF_SIZE);
+                       if (r == 0)
+                               break;
+                       if (r == -1)
+                       {
+                               r= errno;
+                               if (stdout_issocket)
+                                       ioctl(1, NWIOTCPSHUTDOWN, NULL);
+                               fatal("error reading from TCP conn.: %s",
+                                       strerror(errno));
+                       }
+                       s= r; 
+                       for (o= 0; o<s; o += r)
+                       {
+                               r= write(1, buf+o, s-o);
+                               if (r <= 0)
+                               {
+                                       fatal("error writing to stdout: %s",
+                                               r == 0 ? "EOF" :
+                                               strerror(errno));
+                               }
+                       }
+               }
+               if (stdout_issocket)
+               {
+                       r= ioctl(1, NWIOTCPSHUTDOWN, NULL);
+                       if (r == -1)
+                       {
+                               fatal("NWIOTCPSHUTDOWN failed on stdout: %s",
+                                       strerror(errno));
+                       }
+               }
+               exit(0);
+       default:
+               break;
+       }
+
+       /* Read from stdin, write to TCP. */
+       for (;;)
+       {
+               r= read(0, buf, BUF_SIZE);
+               if (r == 0)
+                       break;
+               if (r == -1)
+               {
+                       s_errno= errno;
+                       kill(cpid, SIGTERM);
+                       fatal("error reading from stdin: %s",
+                               strerror(s_errno));
+               }
+               s= r; 
+               for (o= 0; o<s; o += r)
+               {
+                       r= write(tcpfd, buf+o, s-o);
+                       if (r <= 0)
+                       {
+                               s_errno= errno;
+                               kill(cpid, SIGTERM);
+                               fatal("error writing to TCP conn.: %s",
+                                       r == 0 ? "EOF" :
+                                       strerror(s_errno));
+                       }
+               }
+               if (push)
+                       ioctl(tcpfd, NWIOTCPPUSH, NULL);
+       }
+       if (ioctl(tcpfd, NWIOTCPSHUTDOWN, NULL) == -1)
+       {
+               s_errno= errno;
+               kill(cpid, SIGTERM);
+               fatal("unable to shut down TCP conn.: %s", strerror(s_errno));
+       }
+
+       r= waitpid(cpid, &loc, 0);
+       if (r == -1)
+       {
+               s_errno= errno;
+               kill(cpid, SIGTERM);
+               fatal("waitpid failed: %s", strerror(s_errno));
+       }
+       if (WIFEXITED(loc))
+               exit(WEXITSTATUS(loc));
+       kill(getpid(), WTERMSIG(loc));
+       exit(1);
+}
+
+static void fatal(char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       fprintf(stderr, "%s: ", progname);
+       vfprintf(stderr, fmt, ap);
+       fprintf(stderr, "\n");
+       va_end(ap);
+       exit(1);
+}
+
+static void usage(void)
+{
+       fprintf(stderr, "Usage: %s [-BPs] [-t timeout] hostname portname\n",
+               progname);
+       exit(1);
+}
+
+/*
+ * $PchId: socket.c,v 1.3 2005/01/31 22:33:20 philip Exp $
+ */
diff --git a/commands/swifi/systest.c b/commands/swifi/systest.c
new file mode 100644 (file)
index 0000000..66277c7
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * systest.c -- Test code for nooks system calls
+ *
+ * Copyright (C) 2002 Mike Swift
+ *
+ * The source code in this file can be freely used, adapted,
+ * and redistributed in source or binary form, so long as an
+ * acknowledgment appears in derived source files.  
+ * No warranty is attached;
+ * we cannot take responsibility for errors or fitness for use.
+ *
+ */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#if 0
+#include <asm/unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#define swifi_inject_fault sys_inject_fault
+
+#include "swifi-user.h"
+#include "extra.h"
+
+
+#if 0
+_syscall6(long, swifi_inject_fault, 
+         char *, module_name,
+         unsigned long, faultType,
+         unsigned long, randSeed,
+         unsigned long, numFaults,
+         void *, result,
+         unsigned long, do_inject);
+#endif
+
+int
+main(int argc, char * argv[])
+{
+  char * module_name = NULL;
+  int i;
+  long result = 0;
+  unsigned int cmd = 0;
+  unsigned long arg = 0;
+  unsigned long seed = 157;
+  swifi_result_t * res = NULL;
+
+  if (argc < 2) {
+    goto Usage;
+  }
+
+  for (i = 1; i < argc; i++ ) {
+    if (strcmp(argv[i], "-f") == 0) {
+      if (argc <= i+5) {
+       goto Usage;
+      }
+      module_name = victim_exe = argv[++i];
+      sscanf(argv[++i],"%u", &victim_pid);
+      sscanf(argv[++i],"%u", &cmd);
+      sscanf(argv[++i],"%lu", &arg);
+      sscanf(argv[++i],"%lu", &seed);
+    } else {
+      printf("Unknown command %s\n", argv[i]);
+      goto Usage;
+    }
+  }
+
+  res = malloc(arg * sizeof(swifi_result_t));
+  if (res == NULL) {
+    printf("Out of memory\n");
+    goto Cleanup;
+  }
+
+  memset(res, 0, sizeof(res));
+
+  /*
+  // Find out where the faults will be injected
+  */
+  
+  result = swifi_inject_fault(module_name, 
+                             cmd,         /* fault type */
+                             seed,           /* random seed */
+                             arg,         /* numFaults */
+                             res,
+                             0);  /* don't inject now */
+  
+  for (i = 0; (i < arg) && (res[i].address != 0) ; i++) {
+    printf("Changed 0x%lx from 0x%lx to 0x%lx\n",
+          res[i].address,
+          res[i].old,
+          res[i].new);
+  }
+  
+  /*
+  // do the injection
+  */
+  
+
+  result = swifi_inject_fault(module_name, 
+                             cmd,         /* fault type */
+                             seed,           /* random seed */
+                             arg,         /* numFaults */
+                             res,
+                             1);  /* do inject now */
+
+  printf("swifi_inject_fault returned %ld (%d)\n", result,errno);
+
+
+
+ Cleanup:
+  if (res != NULL) {
+    free(res);
+  }
+  return(0);
+
+ Usage:
+  printf("Usage: %s -f module_name pid fault-type fault-count seed\n", argv[0]);
+  goto Cleanup;
+}
+
+