čtvrtek 20. října 2011

Turn your laptop into Wi-Fi AP with hostapd

Sometimes it can be useful to turn your laptop into Wi-Fi AP and quickly share your resources (e.g. internet connection) to others. This can make you new friends especially during conferences and similar events :). Of course supported HW is needed to get this work. Current status of linux drivers can be checked on the Linux Wireless drivers status page. Look for AP mode and cfg80211 - this is the preferred combination. But several non mac80211 drivers can also be used with the hostapd. For more details visit the hostapd homepage. If your HW is supported, the easiest way is probably to use the dnsmasq and hostapd. In Fedora install them by:

# yum install dnsmasq hostapd

Simple script to set things up

You can use the following script for going on the air quickly (it is prepared for mac80211 drivers, others would require editing):

#!/bin/bash

WANIF="eth0"     # Interface connected to internet
LANIF="wlan0"    # Interface that will serve the LAN, e.g. Wi-Fi card
COUNTRYCODE="CZ" # regulationary ISO/IEC 3166-1 Alpha-2 countrycode
MODE="g"         # mode a,b,g
CHANNEL="11"     # channel to use
ESSID="MY_NET"   # SSID to use
KEY="my_pass"    # password to use
LANIP="192.168.101.1"            # IP to use on your LAN interface
DHCP_POOL_START="192.168.101.3"  # First IP to assign to clients
DHCP_POOL_END="192.168.101.254"  # Last IP to assign to clients

# Enable packet forwarding
sysctl -w net.ipv4.ip_forward=1
# Enable handling of dynamic IPs (e.g. on WANIF)
sysctl -w net.ipv4.ip_dynaddr=1
ifconfig $LANIF $LANIP

# Start hostpad
hostapd -BP /var/run/hostapd.pid <(cat <<:end
interface=$LANIF
driver=nl80211
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
debug=0
dump_file=/tmp/hostapd.dump
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
country_code=$COUNTRYCODE
CHANNEL=$CHANNEL
ssid=$ESSID
hw_MODE=$MODE
# 1 to enable only clients with MAC listed in accept_mac_file
macaddr_acl=0
#accept_mac_file=/etc/hostapd/hostapd.accept
auth_algs=1
# Workaround for WinXP (only if only broadcast keys are used)
eapol_KEY_index_workaround=0
# Beacon interval in 1.024 ms
beacon_int=100

# Wireless Multimedia Extension/Wi-Fi Multimedia needed for
# IEEE 802.11n (HT)
wmm_enabled=1
# 1 to enable 802.11n
ieee80211n=0

# WEP/WPA/WPA2 bitmask, 0 for open/WEP, 1 for WPA, 2 for WPA2
wpa=2

# WPA2 settings
wpa_passphrase=$KEY
wpa_KEY_mgmt=WPA-PSK
rsn_pairwise=CCMP

# WEP settings
# WEP key length should be 5 (40 bit), 13 (64 bit) or
# 16 (128 bit) chars
#wep_KEY0="$KEY"
#wep_default_KEY=0
:end
)

dnsmasq -i $LANIF --dhcp-range=$DHCP_POOL_START,$DHCP_POOL_END

# FWD: Allow all connections OUT and only existing and related IN
iptables -I FORWARD -i $WANIF -o $LANIF -m state \
  --state ESTABLISHED,RELATED -j ACCEPT
iptables -I FORWARD -i $LANIF -o $WANIF -j ACCEPT

# Enabling SNAT (MASQUERADE) functionality on $WANIF
iptables -t nat -I POSTROUTING -o $WANIF -j MASQUERADE

For permanent setup it is better to transfer your hostapd settings into /etc/hostapd/hostapd.conf and your dnsmasq settings into /etc/dnsmasq.conf. Then you will be able to start and manage the services through sysvinit / systemd or whatever your system uses. Finally, for permantent setup you will also need to add the two sysctls (in Fedora to /etc/sysctl.conf) and iptables rules (in Fedora to /etc/sysconfig/iptables).

Ralink cards

Personally I tried this on my netbook with integrated 802.11n card (rt2800pci). There is quick howto on the rt2x00 project page. But it didn't work for me - the client was unable to associate and I was getting in the log: "IEEE 802.11: did not acknowledge association response". I found the resolution of this problem on the Ez nem egy blog. The author stated there that the driver is unable to ack several frames, but the hostapd needs them to be acked. The simple hack is to patch the hostapd to blindly assume it gets acked. I used the following patch (it differs from the original one from the above link by not logging the errors):

diff -up src/ap/ieee802_11.c.orig src/ap/ieee802_11.c
--- src/ap/ieee802_11.c.orig 2010-09-07 17:43:39.000000000 +0200
+++ src/ap/ieee802_11.c 2011-10-08 21:02:17.000000000 +0200
@@ -1475,13 +1475,6 @@ static void handle_auth_cb(struct hostap
  u16 auth_alg, auth_transaction, status_code;
  struct sta_info *sta;
 
- if (!ok) {
-  hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
-          HOSTAPD_LEVEL_NOTICE,
-          "did not acknowledge authentication response");
-  return;
- }
-
  if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
   printf("handle_auth_cb - too short payload (len=%lu)\n",
          (unsigned long) len);
@@ -1518,13 +1511,6 @@ static void handle_assoc_cb(struct hosta
  int new_assoc = 1;
  struct ieee80211_ht_capabilities ht_cap;
 
- if (!ok) {
-  hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
-          HOSTAPD_LEVEL_DEBUG,
-          "did not acknowledge association response");
-  return;
- }
-
  if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
           sizeof(mgmt->u.assoc_resp))) {
   printf("handle_assoc_cb(reassoc=%d) - too short payload "
Then it worked like a charm.

I also tried the rt73usb based dongle. This one shouldn't work according to rt2x00 project page, because they don't know how to get the status messages (ACK/FAIL) for sent packets from the HW. I think there should be a way how to get the ACKs, because the Windows driver works OK. The simple association hack from the above is not enough here, probably more blindly acks would be needed. This is really dirty solution, so I give it up for today. I will look on this more deep later.

Žádné komentáře:

Okomentovat