diff -rNu uml-utilities-20040406/uml_router/Makefile uml-utilities-20040406-psock/uml_router/Makefile
--- uml-utilities-20040406/uml_router/Makefile	2003-02-08 05:04:39.000000000 +0100
+++ uml-utilities-20040406-psock/uml_router/Makefile	2004-08-13 17:01:17.000000000 +0200
@@ -1,14 +1,18 @@
 TUNTAP = $(shell [ -e /usr/include/linux/if_tun.h ] && echo -DTUNTAP)
+PSOCK = $(shell [ -e /usr/include/linux/if_packet.h ] && echo -DPSOCK)
 
-OBJS = hash.o port.o uml_switch.o 
+OBJS = hash.o port.o uml_switch.o
 BIN = uml_switch
-CFLAGS = -g -Wall $(TUNTAP)
+CFLAGS = -g -Wall $(TUNTAP) $(PSOCK)
 
 BIN_DIR ?= /usr/bin
 
 ifneq ($(TUNTAP),)
 	OBJS += tuntap.o
 endif
+ifneq ($(TUNTAP),)
+	OBJS += psock.o
+endif
 
 all : $(BIN)
 
Files uml-utilities-20040406/uml_router/core and uml-utilities-20040406-psock/uml_router/core differ
Files uml-utilities-20040406/uml_router/hash.o and uml-utilities-20040406-psock/uml_router/hash.o differ
diff -rNu uml-utilities-20040406/uml_router/port.c uml-utilities-20040406-psock/uml_router/port.c
--- uml-utilities-20040406/uml_router/port.c	2003-03-12 16:19:03.000000000 +0100
+++ uml-utilities-20040406-psock/uml_router/port.c	2004-08-17 09:03:18.000000000 +0200
@@ -4,6 +4,7 @@
 #include <errno.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <linux/if_packet.h>
 #include "switch.h"
 #include "hash.h"
 #include "port.h"
@@ -107,7 +108,8 @@
       (*p->sender)(p->control, packet, len, p->data);
     }
   }
-  else (*target->sender)(target->control, packet, len, target->data);
+  else if (target != port)
+	(*target->sender)(target->control, packet, len, target->data);
 }
 
 static void handle_data(int fd, int hub, struct packet *packet, int len, 
@@ -129,6 +131,33 @@
   send_dst(p, packet, len, hub);  
 }
 
+static int match_psock(int port_fd, int data_fd, void *port_data, 
+		     int port_data_len, void *data)
+{
+  return(port_fd == data_fd);
+}
+
+void handle_psock_data(int fd, int hub)
+{
+  struct sockaddr_ll      from;
+  socklen_t               fromlen;
+  struct packet packet;
+  int len;
+
+  fromlen = sizeof (from);
+  len = recvfrom(fd, &packet, sizeof (packet),
+				 MSG_TRUNC, (struct sockaddr *) &from, &fromlen);
+
+  if(len < 0){
+    if(errno != EAGAIN) perror("Reading psock data");
+    return;
+  }
+  if (from.sll_pkttype == PACKET_OUTGOING)
+	return;
+
+  handle_data(fd, hub, &packet, len, NULL, match_psock);
+}
+
 static int match_tap(int port_fd, int data_fd, void *port_data, 
 		     int port_data_len, void *data)
 {
diff -rNu uml-utilities-20040406/uml_router/port.h uml-utilities-20040406-psock/uml_router/port.h
--- uml-utilities-20040406/uml_router/port.h	2002-04-10 15:07:02.000000000 +0200
+++ uml-utilities-20040406-psock/uml_router/port.h	2004-08-13 17:02:57.000000000 +0200
@@ -16,5 +16,6 @@
 		      int data_len);
 extern void handle_tap_data(int fd, int hub);
 extern void handle_sock_data(int fd, int hub);
+extern void handle_psock_data(int fd, int hub);
 
 #endif
Files uml-utilities-20040406/uml_router/port.o and uml-utilities-20040406-psock/uml_router/port.o differ
diff -rNu uml-utilities-20040406/uml_router/psock.c uml-utilities-20040406-psock/uml_router/psock.c
--- uml-utilities-20040406/uml_router/psock.c	1970-01-01 01:00:00.000000000 +0100
+++ uml-utilities-20040406-psock/uml_router/psock.c	2004-08-16 09:53:13.000000000 +0200
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/if_ether.h>
+#include <netinet/in.h>
+#include <linux/if_packet.h>
+#include "port.h"
+
+static int ifindex;
+
+static void send_psock(int fd, void *packet, int len, void *unused)
+{
+  struct sockaddr_ll      sll;
+  int n;
+
+  memset(&sll, 0, sizeof(sll));
+  sll.sll_family          = AF_PACKET;
+  sll.sll_ifindex         = ifindex;
+  memcpy (sll.sll_addr, packet + 6, 6);
+  sll.sll_protocol = *(uint16_t *)(packet + 12);
+
+  n = sendto (fd, packet, len, 0,
+			  (struct sockaddr *)&sll,
+			  sizeof (struct sockaddr_ll));
+
+  if(n != len){
+    if(errno != EAGAIN) perror("send_psock");
+  }
+}
+
+int open_psock(char *dev)
+{
+  struct sockaddr_ll      sll;
+  struct ifreq ifr;
+  int fd, err;
+
+  fd = socket (AF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
+  if(fd < 0) {
+    perror("Failed to open device");
+    return(-1);
+  }
+
+  strcpy (ifr.ifr_name, dev);
+
+  if (ioctl (fd, SIOCGIFINDEX, &ifr) == -1) {
+	  return -1;
+  }
+
+  ifindex = ifr.ifr_ifindex;
+
+  memset(&sll, 0, sizeof(sll));
+  sll.sll_family          = AF_PACKET;
+  sll.sll_ifindex         = ifr.ifr_ifindex;
+  sll.sll_protocol        = htons(ETH_P_ALL);
+  if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) {
+    perror("Failed to bind");
+    return -1;
+  }
+  err = setup_port(fd, send_psock, NULL, 0);
+  if(err) return(err);
+  return(fd);
+}
+
diff -rNu uml-utilities-20040406/uml_router/psock.h uml-utilities-20040406-psock/uml_router/psock.h
--- uml-utilities-20040406/uml_router/psock.h	1970-01-01 01:00:00.000000000 +0100
+++ uml-utilities-20040406-psock/uml_router/psock.h	2004-08-13 17:01:55.000000000 +0200
@@ -0,0 +1,11 @@
+/* Copyright 2002 Jeff Dike
+ * Licensed under the GPL
+ */
+
+#ifndef __PSOCK_H__
+#define __PSOCK_H__
+
+extern int open_psock(char *dev);
+extern void handle_psock(int fd, int hub);
+
+#endif
Files uml-utilities-20040406/uml_router/psock.o and uml-utilities-20040406-psock/uml_router/psock.o differ
Files uml-utilities-20040406/uml_router/tuntap.o and uml-utilities-20040406-psock/uml_router/tuntap.o differ
Files uml-utilities-20040406/uml_router/uml_switch and uml-utilities-20040406-psock/uml_router/uml_switch differ
diff -rNu uml-utilities-20040406/uml_router/uml_switch.c uml-utilities-20040406-psock/uml_router/uml_switch.c
--- uml-utilities-20040406/uml_router/uml_switch.c	2003-08-15 21:03:58.000000000 +0200
+++ uml-utilities-20040406-psock/uml_router/uml_switch.c	2004-08-18 09:32:05.000000000 +0200
@@ -19,6 +19,9 @@
 #ifdef TUNTAP
 #include "tuntap.h"
 #endif
+#ifdef PSOCK
+#include "psock.h"
+#endif
 
 #ifdef notdef
 #include <stddef.h>
@@ -386,14 +389,17 @@
 static void Usage(void)
 {
   char *tap_str = "";
-
+  char *pcap_str = "";
 #ifdef TUNTAP
   tap_str = "[ -tap tap-device ]";
 #endif
+#ifdef PCAP
+  pcap_str = "[ -pcap pcap-device ]";
+#endif
 
-  fprintf(stderr, "Usage : %s [ -unix control-socket ] [ -hub ] %s\n"
+  fprintf(stderr, "Usage : %s [ -unix control-socket ] [ -hub ] %s %s\n"
 	  "or : %s -compat-v0 [ -unix control-socket data-socket ] "
-	  "[ -hub ] %s\n", prog, tap_str, prog, tap_str);
+	  "[ -hub ] %s %s\n", prog, tap_str, pcap_str, prog, tap_str, pcap_str);
 
   exit(1);
 }
@@ -401,10 +407,13 @@
 int main(int argc, char **argv)
 {
   int connect_fd, data_fd, n, i, new, one = 1, daemonize = 0;
-  char *tap_dev = NULL;
+  char *tap_dev = NULL, *psock_dev;
 #ifdef TUNTAP
   int tap_fd  = -1;
 #endif
+#ifdef PSOCK
+  int psock_fd = -1;
+#endif
 
   prog = argv[0];
   argv++;
@@ -436,6 +445,18 @@
       Usage();
 #endif      
     }
+    else if(!strcmp(argv[0], "-psock")){
+#ifdef PSOCK
+      if(argc < 2) 
+	Usage();
+      psock_dev = argv[1];
+      argv += 2;
+      argc -= 2;
+#else
+      fprintf(stderr, "-psock isn't supported since PSOCK isn't enabled\n");
+      Usage();
+#endif      
+    }
     else if(!strcmp(argv[0], "-hub")){
       printf("%s will be a hub instead of a switch\n", prog);
       hub = 1;
@@ -489,7 +510,6 @@
 
   if(signal(SIGINT, sig_handler) < 0)
     perror("Setting handler for SIGINT");
-  hash_init();
 
   if(compat_v0) 
     printf("%s attached to unix sockets '%s' and '%s'", prog, ctl_socket,
@@ -512,6 +532,11 @@
   if(tap_fd > -1) add_fd(tap_fd);
 #endif
 
+#ifdef PSOCK
+  if(psock_dev != NULL) psock_fd = open_psock (psock_dev);
+  if(psock_fd >-1) add_fd (psock_fd);
+#endif
+
   if (daemonize && daemon(0, 1)) {
     perror("daemon");
     exit(1);
@@ -555,6 +580,9 @@
 #ifdef TUNTAP
       else if(fds[i].fd == tap_fd) handle_tap_data(tap_fd, hub);
 #endif
+#ifdef PSOCK
+      else if(fds[i].fd == psock_fd) handle_psock_data(psock_fd, hub);
+#endif
       else {
 	new = handle_port(fds[i].fd);
 	if(new) new_port(fds[i].fd, data_fd);
Files uml-utilities-20040406/uml_router/uml_switch.o and uml-utilities-20040406-psock/uml_router/uml_switch.o differ
diff -rNu uml-utilities-20040406/uml_router/uml_switch.sgml uml-utilities-20040406-psock/uml_router/uml_switch.sgml
--- uml-utilities-20040406/uml_router/uml_switch.sgml	2004-08-19 17:05:14.000000000 +0200
+++ uml-utilities-20040406-psock/uml_router/uml_switch.sgml	2004-08-13 17:05:27.000000000 +0200
@@ -57,6 +57,7 @@
       <arg><option>-unix</option> <replaceable>control_socket</replaceable> <replaceable>data_socket</replaceable></arg>
       <arg><option>-hub</option></arg>
       <arg><option>-tap <replaceable>tun device</replaceable></option></arg>
+      <arg><option>-pcap <replaceable>pcap device</replaceable></option></arg>
       <arg><option>-compat-v0</option></arg>
       <arg><option>-daemon</option></arg>
     </cmdsynopsis>
@@ -108,6 +109,12 @@
         </listitem>
       </varlistentry>
       <varlistentry>
+        <term><option>-pcap <replaceable>pcap device</replaceable></option></term>
+        <listitem>
+          <para>Sends and recieves packets on ethernetdevice.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
         <term><option>-compat-v0</option></term>
         <listitem>
           <para>Specify control protocol version 0 compatibility.</para>

