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:[email protected]
https://www.fsora.ru (waits for FreeBSD 8.0-RELEASE)
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);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[email protected]"