Skip to content

Instantly share code, notes, and snippets.

@zanppa
Created March 11, 2020 21:06
Show Gist options
  • Select an option

  • Save zanppa/a62903959377d9395e865592d19b11b8 to your computer and use it in GitHub Desktop.

Select an option

Save zanppa/a62903959377d9395e865592d19b11b8 to your computer and use it in GitHub Desktop.
Convert Raspberry PI Zero W to an USB wifi adapter gadget
# /etc/dhcp/dhcpd.conf
# Very basic dhcp daemon configuration for the USB interface
default-lease-time 600;
max-lease-time 7200;
# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;
# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;
# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;
# Subnet declaration
subnet 192.168.20.0 netmask 255.255.255.0 {
option routers 192.168.20.1;
option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.0.20;
range 192.168.20.10 192.168.20.10;
}
#!/bin/sh
#
# This script creates an Ethernet gadget using the
# CDC / ECM (Ethernet Control Model) interface and
# then shares the wlan0 to usb0 (with NAT)
# and starts a dhcp server on usb0
# Load libcomposite
modprobe libcomposite
# Create a gadget called usb-gadgets
cd /sys/kernel/config/usb_gadget/
mkdir -p usb-gadgets
cd usb-gadgets
# Configure the gadget
# ==========================
# Configure our gadget details
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
# Set serial number, manufacturer and product name here
echo "0123456789abcdef" > strings/0x409/serialnumber
echo "Pi Zero USB Gadget" > strings/0x409/manufacturer
echo "Pi Zero USB Gadget" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
# This describes the only configuration, free text
echo "Config 1: Test gadget" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower
# =====================================
# Create gadget functions
# Ethernet gadget
# -------------------------
F_TYPE=ecm # ECM gadget
F_NAME=usb0 # Freely selectable name
mkdir -p functions/$F_TYPE.$F_NAME
# Set configuration, see e.g.
# https://github.com/torvalds/linux/blob/master/Documentation/ABI/testing/configfs-usb-gadget-ecm
# MAC addresses, comment out for random addresses
# first byte of address must be even
HOST="32:70:05:18:ff:7a" # "HostPC"
SELF="32:70:05:18:ff:7b" # "Ethernet Gadget"
#echo $HOST > functions/$F_TYPE.$F_NAME/host_addr
#echo $SELF > functions/$F_TYPE.$F_NAME/dev_addr
# Interface name, by default will be usb0
#echo usb0 > functions/$F_TYPE.$F_NAME/ifname
# Link the function under the (only) configuration
ln -s functions/$F_TYPE.$F_NAME configs/c.1/
# End ethernet gadget
# ------------------------
# End functions
# ========================
# Enable gadgets
ls /sys/class/udc > UDC
# Internet connection shating
# Shares wlan0 over other connections
# Enable ipv4 forwarding
sysctl -w net.ipv4.ip_forward=1
sysctl -p
# Flush rules (flush all / flush only nat related)
#iptables -X
#iptables -F
iptables -t nat -X
iptables -t nat -F
# Enable NAT forwarding
iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -I POSTROUTING -o wlan0 -j MASQUERADE
# Configure static IP address for the usb interface
ifconfig usb0 up
ifconfig usb0 192.168.20.1 netmask 255.255.255.0
# Enable incoming connections for DHCP
iptables -I INPUT -p udp --dport 67 -i usb0 -j ACCEPT
# Forward all TCP ports, except 22 (ssh), from wlan0 to usb0
iptables -t nat -A PREROUTING -p tcp -i wlan0 --dport 1:21 -j DNAT --to 192.168.20.10
iptables -t nat -A PREROUTING -p tcp -i wlan0 --dport 23:65535 -j DNAT --to 192.168.20.10
# Flush dhcp lease cache
if [ -f "/var/lib/dhcp/dhcpd.leases~" ]; then rm /var/lib/dhcp/dhcpd.leases~; fi
echo "" > /var/lib/dhcp/dhcpd.leases
# Launch (Restart) DCHP server
#systemctl restart isc-dhcp-server
if [ -f "/var/run/dhcpd.pid" ]; then kill `cat /var/run/dhcpd.pid`; fi
dhcpd -q -4 -cf /etc/dhcp/dhcpd.conf usb0
@zanppa
Copy link
Author

zanppa commented Mar 11, 2020

Even though the gadget is dynamically created using configfs, it is necessary to add dtoverlay=dwc2 to /boot/config.txt.

The dhcp server requires isc-dhcp-server package. The service should be disabled by default, by running sudo systemctl disable isc-dhcp-server and sudo systemctl mask isc-dhcp-server.

Note that the dhcpd config expects local DNS server at 192.168.0.20, change that to some external one if needed, e.g. Comodo DNS at 8.26.56.26.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment