Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Nov 2009 22:53:38 +0300
From:      Alexander Samarin <sasha.devel@gmail.com>
To:        freebsd-usb <freebsd-usb@freebsd.org>
Subject:   [madwimax] madwimax-0.1.1 patch for FreeBSD 8 (very buggy)
Message-ID:  <1258055618.4944.22.camel@eien>

next in thread | raw e-mail | index | archive | help

--=-2hMIDVie/8bJzZRguGDl
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit

HOWTO:

yume$ fetch "ftp://ftp.enikasoft.ru/pub/madwimax-freebsd8.patch"
yume$ fetch "http://madwimax.googlecode.com/files/madwimax-0.1.1.tar.gz"
yume$ tar xf madwimax-0.1.1.tar.gz

yume$ cd madwimax-0.1.1
yume$ export libusb1_CFLAGS="-I/usr/include"
yume$ export libusb1_LIBS="-L/usr/lib -lusb"
yume$ ./configure --without-man-pages
yume$ echo '#define MADWIMAX_VERSION_MACRO "madwimax-0.1.1-freebsd"' > \
        include/madwimax_version.h
yume$ cd src
yume$ patch < ../../madwimax-freebsd8.patch
yume$ make

yume$ su
yume# kldload if_tap
yume# ./madwimax
...
Allocated tap interface: tap0
...

On other console:

yume$ su
yume# dhclient tap0
yume# cat /var/db/dhclient.leases.tap
...
  option routers XXX.XXX.XXX.XXX;
  option domain-name-servers YYY.YYY.YYY.YYY;
...
yume# route delete default
yume# route add default XXX.XXX.XXX.XXX
yume# echo "nameserver YYY.YYY.YYY.YYY" > /etc/resolv.conf



Tested on FreeBSD 8.0-RC2 i386; modem Samsung SWC-U200.
Usually works fine (ping normal - less than 1% packet loss; http ok)
Sometimes crashes in libusb:

yume# ./madwimax
...
Allocated tap interface: tap0
zsh: segmentation fault (core dumped)  ./madwimax
yume# gdb ./madwimax madwimax.core
GNU gdb 6.1.1 [FreeBSD]
...
Core was generated by `madwimax'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libthr.so.3...done.
Loaded symbols for /lib/libthr.so.3
Reading symbols from /usr/lib/libusb.so.2...done.
Loaded symbols for /usr/lib/libusb.so.2
Reading symbols from /lib/libc.so.7...done.
Loaded symbols for /lib/libc.so.7
Reading symbols from /libexec/ld-elf.so.1...done.
Loaded symbols for /libexec/ld-elf.so.1
#0  libusb10_submit_transfer_sub (pdev=0x28209480, endpoint=4 '\004') at
libusb10.c:1116
1116 if (sxfer->rem_len)
[New Thread 28201140 (LWP 100077)]
(gdb) bt
#0  libusb10_submit_transfer_sub (pdev=0x28209480, endpoint=4 '\004') at
libusb10.c:1116
#1  0x280acf23 in libusb_cancel_transfer (uxfer=0x282250c8) at
libusb10.c:1297
#2  0x280ac615 in libusb10_do_transfer (devh=0x28209480,
endpoint=Variable "endpoint" is not available.
) at libusb10_io.c:509
#3  0x280ac757 in libusb_bulk_transfer (devh=0x28209480,
endpoint=Variable "endpoint" is not available.
) at libusb10_io.c:552
#4  0x08049874 in set_data (data=0xbfbfab80 "WC\024", size=26) at
wimax.c:224
#5  0x0804a914 in main (argc=1, argv=0x280ad160) at wimax.c:652
(gdb) print *pxfer0 
$1 = {pdev = 0x28209480, callback = 0x280ad160
<libusb10_bulk_intr_proxy>, priv_sc0 = 0x28209480,
  priv_sc1 = 0x0, ppBuffer = 0x28226094, pLength = 0x28226090,
maxTotalLength = 16384,
  maxFrames = 1, nFrames = 1, aFrames = 1, timeout = 0, timeComplete =
0, trIndex = 16,
  maxPacketLen = 512, flags = 0 '\0', status = 1 '\001', is_opened = 1
'\001',
  is_pending = 1 '\001', is_cancel = 1 '\001', is_draining = 0 '\0',
is_restart = 0 '\0'}
(gdb) print *pxfer1
$2 = {pdev = 0x28209480, callback = 0x280b0380 <dummy_callback>,
priv_sc0 = 0x0,
  priv_sc1 = 0x0, ppBuffer = 0x0, pLength = 0x0, maxTotalLength = 0,
  maxFrames = 0, nFrames = 0, aFrames = 0, timeout = 0, timeComplete =
0, trIndex = 17,
  maxPacketLen = 0, flags = 0 '\0', status = 0 '\0', is_opened = 0 '\0',
  is_pending = 0 '\0', is_cancel = 0 '\0', is_draining = 0 '\0',
is_restart = 0 '\0'}
(gdb) print *sxfer 
Variable "sxfer" is not available.

Near libusb10.c:1116:
1115 sxfer = libusb20_tr_get_priv_sc1(pxfer0);
1116 if (sxfer->rem_len)

Near libusb20.c:258:
257 void   *
258 libusb20_tr_get_priv_sc1(struct libusb20_transfer *xfer)
259 {
260 return (xfer->priv_sc1);
261 }

Because of pxfer0->priv_sc1 is NULL from core dump, I think that it is
a libusb implementation bug.



PS:
Also I've commented this call at wimax.c:847:

847 //libusb_cancel_transfer(req_transfer);

because of segmentation fault when program going to terminate.
(this is inside exit_release_resources() function)


--
Best regards,  Alexander Samarin
    mailto:sasha@enikasoft.ru
    https://www.fsora.ru (waits for FreeBSD 8.0-RELEASE)



--=-2hMIDVie/8bJzZRguGDl
Content-Disposition: attachment; filename="madwimax-freebsd8.patch"
Content-Type: text/x-patch; name="madwimax-freebsd8.patch"; charset="UTF-8"
Content-Transfer-Encoding: 7bit

diff -u src-old/tap_dev.c src/tap_dev.c
--- src-old/tap_dev.c	2009-07-04 07:54:13.000000000 +0400
+++ src/tap_dev.c	2009-11-12 10:37:56.000000000 +0300
@@ -28,10 +28,18 @@
 
 #include <sys/ioctl.h>
 #include <sys/socket.h>
+#if defined(__linux__)
 #include <linux/if.h>
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/if_tun.h>
+#elif defined(__FreeBSD__)
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_tap.h>
+#include <net/if_tun.h>
+#endif
 
 #include "wimax.h"
 
@@ -83,14 +91,21 @@
 	struct ifreq ifr;
 	int fd;
 
+#if defined(__linux__)
 	if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
+#elif defined(__FreeBSD__)
+	if ((fd = open(istun ? "/dev/tun" : "/dev/tap", O_RDWR)) < 0)
+#endif
 		return tun_open_common0(dev, istun);
 
 	memset(&ifr, 0, sizeof(ifr));
+#if defined(__linux__)
 	ifr.ifr_flags = (istun ? IFF_TUN : IFF_TAP) | IFF_NO_PI;
+#endif
 	if (*dev)
 		strncpy(ifr.ifr_name, dev, IFNAMSIZ);
 
+#if defined(__linux__)
 	if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
 		if (errno == EBADFD) {
 			/* Try old ioctl */
@@ -99,8 +114,12 @@
 		} else
 			goto failed;
 	}
-
 	strcpy(dev, ifr.ifr_name);
+#elif defined(__FreeBSD__)
+	//if (ioctl(fd, SIOCGIFNAME, (void *) &ifr) < 0)
+	//	goto failed;
+	strcpy(dev, fdevname(fd));
+#endif
 	return fd;
 
 failed:
@@ -111,7 +130,28 @@
 
 int tap_open(char *dev) { return tun_open_common(dev, 0); }
 
-int tap_close(int fd, char *dev) { return close(fd); }
+int tap_close(int fd, char *dev) {
+	int res = close(fd);
+	
+#if defined(__FreeBSD__)
+	// We need to destroy tun/tap interface like `ifconfig tunN destroy`
+	struct ifreq ifr;
+	
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+	
+	if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+		res = fd;
+		perror("socket");
+	} else {
+		if ((res = ioctl(fd, SIOCIFDESTROY, &ifr)) < 0) {
+			perror("ioctl(SIOCIFDESTROY)");
+		}
+		close(fd);
+	}
+#endif
+	return res;
+}
 
 /* Read/write frames from TAP device */
 int tap_write(int fd, const void *buf, int len) { return write(fd, buf, len); }
@@ -133,6 +173,7 @@
 
 	fd = socket(PF_INET, SOCK_DGRAM, 0);
 
+#if defined(__linux__)
 	/* Fill in the structure */
 	safe_strncpy(ifr.ifr_name, dev, IFNAMSIZ);
 	ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
@@ -143,6 +184,17 @@
 		perror("SIOCSIFHWADDR");
 		return -1;
 	}
+#elif defined(__FreeBSD__)
+    memset(&ifr, 0, sizeof(ifr));
+    safe_strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+    ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+    ifr.ifr_addr.sa_family = AF_LINK;
+    memcpy(&ifr.ifr_addr.sa_data, hwaddr, ETHER_ADDR_LEN);
+	if (ioctl(fd, SIOCSIFLLADDR, &ifr) < 0) {
+		perror("SIOCSIFLLADDR");
+		return -1;
+	}
+#endif
 
 	close(fd);
 	return 0;
diff -u src-old/wimax.c src/wimax.c
--- src-old/wimax.c	2009-07-04 07:54:13.000000000 +0400
+++ src/wimax.c	2009-11-12 10:29:19.000000000 +0300
@@ -38,6 +38,39 @@
 #include "wimax.h"
 #include "tap_dev.h"
 
+#ifndef libusb_cpu_to_le16
+#define libusb_cpu_to_le16(x) ({ \
+    union { \
+        uint8_t  b8[2]; \
+        uint16_t b16; \
+    } _tmp; \
+    uint16_t _tmp2 = (uint16_t)(x); \
+    _tmp.b8[1] = _tmp2 >> 8; \
+    _tmp.b8[0] = _tmp2 & 0xff; \
+    _tmp.b16; \
+})
+#endif /* !defined(libusb_cpu_to_le16) */
+
+#ifndef libusb_le16_to_cpu
+#define libusb_le16_to_cpu libusb_cpu_to_le16
+#endif /* !defined(libusb_le16_to_cpu) */
+
+#if defined(__FreeBSD__)
+static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
+    libusb_device_handle *dev_handle, unsigned char endpoint,
+    unsigned char *buffer, int length, libusb_transfer_cb_fn callback,
+    void *user_data, unsigned int timeout)
+{
+    transfer->dev_handle = dev_handle;
+    transfer->endpoint = endpoint;
+    transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
+    transfer->timeout = timeout;
+    transfer->buffer = buffer;
+    transfer->length = length;
+    transfer->user_data = user_data;
+    transfer->callback = callback;
+}
+#endif
 
 /* variables for the command-line parameters */
 static int daemonize = 0;
@@ -103,7 +136,11 @@
 static unsigned char read_buffer[MAX_PACKET_LEN];
 
 static int tap_fd = -1;
+#if defined(__linux__)
 static char tap_dev[20] = "wimax%d";
+#elif defined(__FreeBSD__)
+static char tap_dev[20] = "";
+#endif
 static int tap_if_up = 0;
 
 static nfds_t nfds;
@@ -806,7 +843,8 @@
 	}
 	if(ctx != NULL) {
 		if(req_transfer != NULL) {
-			libusb_cancel_transfer(req_transfer);
+			// FIXME: segfault here on: FreeBSD 8.0-RC2 i386
+			//libusb_cancel_transfer(req_transfer);
 			libusb_free_transfer(req_transfer);
 		}
 		libusb_set_pollfd_notifiers(ctx, NULL, NULL, NULL);

--=-2hMIDVie/8bJzZRguGDl--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1258055618.4944.22.camel>