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>