WiFi Access Point with 4G Uplink on Raspberry Pi

Using Vodafone K5150 LTE modem

This how-to describes how to setup Raspberry Pi running Raspbian Wheezy as a WiFi access point with Internet access using attached Vodafone K5150 LTE modem.

Written by borek@lupomesky.cz.

Contents

1. Prerequisites and an Outline of the Solution

This how-to uses following hardware. You might successfully use different hardware, but this is what following setups were tested on.

Raspberry Pi running Raspbian Wheezy (get Wheezy here), updated to the lastest version of all packages

Vodafone K5150 LTE-capable USB-attached modem

WiFi adapter with driver using the mac80211 framework, I have tested this on D-Link DWA-127

powered USB 2.0 hub, you can try without (since only two USB ports are required), but I haven't even contemplated going without one, RasPi is quite sensitive about excessive power loads from its USB ports)

K5150 modem (made by Huawei) behaves as an USB ethernet adapter using fairly standard protocol that is supported by Linux. This means there are no ttys and no AT commands like you are used to with other modems. The network drivers are already present in standard Raspbian Wheezy distribution and they work fine. So far so good. The first hurdle to overcome is the fact, that when the modem is plugged into a USB host, it pretends to be a USB mass storage device, that contains Windows drivers. Therefore, the first step has to be switching the modem's USB mode. This is done with utility called usb_modeswitch.

When the modem is in the proper mode, it's time to tell it to unlock the SIM card, to get some info about the network and eventually to connect to some APN (access point name). Traditionally, this is done with AT commands, but as we already said, there are no AT commands here, the modem behaves as a kind of ethernet NIC! As it turns out, the modem operations are performed with something called MBIM. MBIM (Mobile Broadband Interface Model) is a USB IF protocol that is fairly new and not supported on Raspbian by default, but required library and tools can be compiled from sources.

Once we can get the modem to establish the connection, the things get fairly straightforward: DHCP is used to get IP address, gateway address and provider's DNS servers. The rest is usual Linux network setup, which takes extensive use of the ifupdown framework. The wireless interface is setup with static address, hostapd service provides WiFi access point with WPA encryption/authentication, iptables perform required NAT, ISC dhcpd provides clients with IP addresses, BIND9 serves as caching name server.

2. USB Mode Switching

To switch the K5150 modem from USB Mass Storage to modem mode, usb-modeswitch utility is used. Unfortunately, the package available in Raspbian Wheezy is too old to be useful and we need to compile the newest version of usb-modeswitch from the official page.

Install package libusb-1.0-0 and libusb-1.0-0-dev.

root@raspberrpi# apt-get install libusb-1.0-0 libusb-1.0-0-dev

Download both usb-modeswitch and usb-modeswitch-data packages and unpack them.

root@raspberrypi:~# tar xjf usb-modeswitch-2.2.0.tar.bz2 root@raspberrypi:~# tar xjf usb-modeswitch-data-20140529.tar.bz2

Enter the usb-modeswitch directory and do make and on success make install.

root@raspberrypi:~/usb-modeswitch-2.2.0# make cc -o usb_modeswitch usb_modeswitch.c -Wall `pkg-config --libs --cflags libusb-1.0` sed 's_!/usr/bin/tclsh_!'"/usr/bin/tclsh"'_' < usb_modeswitch.tcl > usb_modeswitch_dispatcher root@raspberrypi:~/usb-modeswitch-2.2.0# make install sed 's_!/usr/bin/tclsh_!'"/usr/bin/tclsh"'_' < usb_modeswitch.tcl > usb_modeswitch_dispatcher install -D --mode=755 usb_modeswitch /usr/sbin/usb_modeswitch install -D --mode=755 usb_modeswitch.sh /lib/udev/usb_modeswitch install -D --mode=644 usb_modeswitch.conf /etc/usb_modeswitch.conf install -D --mode=644 usb_modeswitch.1 /usr/share/man/man1/usb_modeswitch.1 install -D --mode=644 usb_modeswitch_dispatcher.1 /usr/share/man/man1/usb_modeswitch_dispatcher.1 install -D --mode=755 usb_modeswitch_dispatcher /usr/sbin/usb_modeswitch_dispatcher install -d /var/lib/usb_modeswitch test -d /etc/init -a -e /sbin/initctl && install --mode=644 usb-modeswitch-upstart.conf /etc/init || test 1 test -d /etc/systemd/system -a -e /usr/bin/systemctl && install --mode=644 usb_modeswitch@.service /etc/systemd/system || test 1

Enter the usb-modeswitch-data directory and do make install.

root@raspberrypi:~/usb-modeswitch-2.2.0# cd ~/usb-modeswitch-data-20140529 root@raspberrypi:~/usb-modeswitch-data-20140529# make install install -d /usr/share/usb_modeswitch install -d /etc/usb_modeswitch.d install -D --mode=644 40-usb_modeswitch.rules /lib/udev/rules.d/40-usb_modeswitch.rules install --mode=644 -t /usr/share/usb_modeswitch ./usb_modeswitch.d/*

If everything went well, the mode of the K5150 modem should be switched upon plugging it into the system. Network interface wwan0 should appear as well as /dev/cdc-wdm0 special device.

root@raspberrypi:~# ifconfig wwan0 wwan0 Link encap:Ethernet HWaddr d2:6d:e5:9f:e5:e4 UP BROADCAST NOARP MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0 MiB) TX bytes:0 (0 MiB) root@raspberrypi:~# ls -l /dev/cdc-wdm0 crw------- 1 root root 180, 176 Sep 19 06:11 /dev/cdc-wdm0

3. libmbim Installation

libmbim implements the MBIM that is used to control the modem. It also contains command line tools mbimcli that can be used to issue commands from the command line.

Install libgudev-1.0-dev, this will cause installation of several additional packages:

root@raspberrypi:~# apt-get install libgudev-1.0-dev

Download most recent stable release source of libmbim from the official website of the project. Unpack the tarball, enter the directory, perform ./configure, make and make install.

root@raspberrypi:~# xz -d libmbim-1.10.0.tar.xz root@raspberrypi:~# tar xf libmbim-1.10.0.tar root@raspberrypi:~# cd libmbim-1.10.0 root@raspberrypi:~/libmbim-1.10.0# ./configure checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking whether UID '0' is supported by ustar format... yes checking whether GID '0' is supported by ustar format... yes checking how to create a ustar tar archive... gnutar checking whether to enable maintainer-specific portions of Makefiles... yes checking whether make supports nested variables... (cached) yes checking for gcc... gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ISO C89... none needed checking whether gcc understands -c and -o together... yes checking for style of include used by make... GNU checking dependency style of gcc... gcc3 checking build system type... armv6l-unknown-linux-gnueabihf checking host system type... armv6l-unknown-linux-gnueabihf checking how to print strings... printf checking for a sed that does not truncate output... /bin/sed checking for grep that handles long lines and -e... /bin/grep checking for egrep... /bin/grep -E checking for fgrep... /bin/grep -F checking for ld used by gcc... /usr/bin/ld checking if the linker (/usr/bin/ld) is GNU ld... yes checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B checking the name lister (/usr/bin/nm -B) interface... BSD nm checking whether ln -s works... yes checking the maximum length of command line arguments... 1572864 checking whether the shell understands some XSI constructs... yes checking whether the shell understands "+="... yes checking how to convert armv6l-unknown-linux-gnueabihf file names to armv6l-unkn own-linux-gnueabihf format... func_convert_file_noop checking how to convert armv6l-unknown-linux-gnueabihf file names to toolchain f ormat... func_convert_file_noop checking for /usr/bin/ld option to reload object files... -r checking for objdump... objdump checking how to recognize dependent libraries... pass_all checking for dlltool... no checking how to associate runtime and link libraries... printf %s

checking for ar... ar checking for archiver @FILE support... @ checking for strip... strip checking for ranlib... ranlib checking command to parse /usr/bin/nm -B output from gcc object... ok checking for sysroot... no checking for mt... mt checking if mt is a manifest tool... no checking how to run the C preprocessor... gcc -E checking for ANSI C header files... yes checking for sys/types.h... yes checking for sys/stat.h... yes checking for stdlib.h... yes checking for string.h... yes checking for memory.h... yes checking for strings.h... yes checking for inttypes.h... yes checking for stdint.h... yes checking for unistd.h... yes checking for dlfcn.h... yes checking for objdir... .libs checking if gcc supports -fno-rtti -fno-exceptions... no checking for gcc option to produce PIC... -fPIC -DPIC checking if gcc PIC flag -fPIC -DPIC works... yes checking if gcc static flag -static works... yes checking if gcc supports -c -o file.o... yes checking if gcc supports -c -o file.o... (cached) yes checking whether the gcc linker (/usr/bin/ld) supports shared libraries... yes checking whether -lc should be explicitly linked in... no checking dynamic linker characteristics... GNU/Linux ld.so checking how to hardcode library paths into programs... immediate checking whether stripping libraries is possible... yes checking if libtool supports shared libraries... yes checking whether to build shared libraries... yes checking whether to build static libraries... yes checking for more warnings... yes checking whether gcc understands -Wmissing-declarations... yes checking whether gcc understands -Wmissing-prototypes... yes checking whether gcc understands -Wdeclaration-after-statement... yes checking whether gcc understands -Wstrict-prototypes... yes checking whether gcc understands -fno-strict-aliasing... yes checking whether gcc understands -Wno-deprecated-declarations... yes checking whether gcc understands -Wint-to-pointer-cast... yes checking whether gcc understands -Wfloat-equal... yes checking whether gcc understands -Wno-unused-parameter... yes checking whether gcc understands -Wno-sign-compare... yes checking whether gcc understands -Wunused-but-set-variable... yes checking whether gcc understands -Wundef... yes checking whether gcc understands -Wimplicit-function-declaration... yes checking whether gcc understands -Wpointer-arith... yes checking whether gcc understands -Winit-self... yes checking whether gcc understands -Wshadow... yes checking whether gcc understands -Wmissing-include-dirs... yes checking whether gcc understands -Waggregate-return... yes checking whether gcc understands -Wformat-security... yes checking for pkg-config... /usr/bin/pkg-config checking pkg-config is at least version 0.9.0... yes checking for LIBMBIM_GLIB... yes checking for MBIMCLI... yes checking for MBIMPROXY... yes checking for gtk-doc... no configure: WARNING: You will not be able to create source packages with 'make dist' because gtk-doc >= 1.0 is not found. checking for gtkdoc-check... no checking for gtkdoc-check... no checking for gtkdoc-rebase... no checking for gtkdoc-mkpdf... no checking whether to build gtk-doc documentation... no checking for GTKDOC_DEPS... yes checking for help2man... false checking that generated files are newer than configure... done configure: creating ./config.status config.status: creating Makefile config.status: creating build-aux/Makefile config.status: creating build-aux/templates/Makefile config.status: creating build-aux/mbim-codegen/Makefile config.status: creating data/Makefile config.status: creating data/pkg-config/Makefile config.status: creating data/pkg-config/mbim-glib.pc config.status: creating src/Makefile config.status: creating src/libmbim-glib/Makefile config.status: creating src/libmbim-glib/mbim-version.h config.status: creating src/libmbim-glib/generated/Makefile config.status: creating src/libmbim-glib/test/Makefile config.status: creating src/mbimcli/Makefile config.status: creating src/mbim-proxy/Makefile config.status: creating utils/Makefile config.status: creating docs/Makefile config.status: creating docs/reference/Makefile config.status: creating docs/reference/libmbim-glib/Makefile config.status: creating docs/reference/libmbim-glib/version.xml config.status: creating docs/man/Makefile config.status: creating config.h config.status: executing depfiles commands config.status: executing libtool commands libmbim 1.10.0 ============================================== compiler: gcc cflags: -Wall -std=gnu89 -g -O2 -Wmissing-declarations -Wmissing-prototypes -Wdeclaration-after-statement -Wstrict-prototypes -fno-strict-aliasing -Wno-deprecated-declarations -Wint-to-pointer-cast -Wfloat-equal -Wno-unused-parameter -Wno-sign-compare -Wunused-but-set-variable -Wundef -Wimplicit-function-declaration -Wpointer-arith -Winit-self -Wshadow -Wmissing-include-dirs -Waggregate-return -Wformat-security -Werror Maintainer mode: yes Documentation: no root@raspberrypi:~/libmbim-1.10.0# make make all-recursive make[1]: Entering directory '/root/libmbim-1.10.0' Making all in . make[2]: Entering directory '/root/libmbim-1.10.0' make[2]: Leaving directory '/root/libmbim-1.10.0' Making all in build-aux make[2]: Entering directory '/root/libmbim-1.10.0/build-aux' Making all in templates make[3]: Entering directory '/root/libmbim-1.10.0/build-aux/templates' make[3]: Nothing to be done for 'all'. make[3]: Leaving directory '/root/libmbim-1.10.0/build-aux/templates' Making all in mbim-codegen make[3]: Entering directory '/root/libmbim-1.10.0/build-aux/mbim-codegen' make[3]: Nothing to be done for 'all'. make[3]: Leaving directory '/root/libmbim-1.10.0/build-aux/mbim-codegen' make[3]: Entering directory '/root/libmbim-1.10.0/build-aux' make[3]: Nothing to be done for 'all-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/build-aux' make[2]: Leaving directory '/root/libmbim-1.10.0/build-aux' Making all in data make[2]: Entering directory '/root/libmbim-1.10.0/data' Making all in . make[3]: Entering directory '/root/libmbim-1.10.0/data' make[3]: Nothing to be done for 'all-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/data' Making all in pkg-config make[3]: Entering directory '/root/libmbim-1.10.0/data/pkg-config' make[3]: Nothing to be done for 'all'. make[3]: Leaving directory '/root/libmbim-1.10.0/data/pkg-config' make[2]: Leaving directory '/root/libmbim-1.10.0/data' Making all in src make[2]: Entering directory '/root/libmbim-1.10.0/src' Making all in libmbim-glib make[3]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib' Making all in generated make[4]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' GEN mbim-error-types.h GEN mbim-enum-types.h GEN mbim-basic-connect.h GEN mbim-sms.h GEN mbim-ussd.h GEN mbim-auth.h GEN mbim-phonebook.h GEN mbim-stk.h GEN mbim-dss.h GEN mbim-ms-firmware-id.h GEN mbim-ms-host-shutdown.h GEN mbim-proxy-control.h GEN mbim-error-types.c GEN mbim-error-quarks.c GEN mbim-enum-types.c make all-am make[5]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' CC libmbim_glib_generated_la-mbim-error-types.lo CC libmbim_glib_generated_la-mbim-error-quarks.lo CC libmbim_glib_generated_la-mbim-enum-types.lo CC libmbim_glib_generated_la-mbim-basic-connect.lo CC libmbim_glib_generated_la-mbim-sms.lo CC libmbim_glib_generated_la-mbim-ussd.lo CC libmbim_glib_generated_la-mbim-auth.lo CC libmbim_glib_generated_la-mbim-phonebook.lo CC libmbim_glib_generated_la-mbim-stk.lo CC libmbim_glib_generated_la-mbim-dss.lo CC libmbim_glib_generated_la-mbim-ms-firmware-id.lo CC libmbim_glib_generated_la-mbim-ms-host-shutdown.lo CC libmbim_glib_generated_la-mbim-proxy-control.lo CCLD libmbim-glib-generated.la make[5]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' make[4]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' Making all in . make[4]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib' CC libmbim_glib_core_la-mbim-utils.lo CC libmbim_glib_core_la-mbim-uuid.lo CC libmbim_glib_core_la-mbim-cid.lo CC libmbim_glib_core_la-mbim-message.lo CC libmbim_glib_core_la-mbim-device.lo CC libmbim_glib_core_la-mbim-compat.lo CC libmbim_glib_core_la-mbim-proxy.lo CC libmbim_glib_core_la-mbim-proxy-helpers.lo CCLD libmbim-glib-core.la CCLD libmbim-glib.la make[4]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib' Making all in test make[4]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib/test' CC test_uuid-test-uuid.o CCLD test-uuid CC test_cid-test-cid.o CCLD test-cid CC test_message-test-message.o CCLD test-message CC test_fragment-test-fragment.o CCLD test-fragment CC test_message_parser-test-message-parser.o CCLD test-message-parser CC test_message_builder-test-message-builder.o CCLD test-message-builder CC test_proxy_helpers-test-proxy-helpers.o CC test_proxy_helpers-mbim-proxy-helpers.o CCLD test-proxy-helpers make[4]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib/test' make[3]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib' Making all in mbimcli make[3]: Entering directory '/root/libmbim-1.10.0/src/mbimcli' CC mbimcli-mbimcli.o CC mbimcli-mbimcli-helpers.o CC mbimcli-mbimcli-basic-connect.o CC mbimcli-mbimcli-phonebook.o CC mbimcli-mbimcli-dss.o CC mbimcli-mbimcli-ms-firmware-id.o CC mbimcli-mbimcli-ms-host-shutdown.o CCLD mbimcli make[3]: Leaving directory '/root/libmbim-1.10.0/src/mbimcli' Making all in mbim-proxy make[3]: Entering directory '/root/libmbim-1.10.0/src/mbim-proxy' CC mbim_proxy-mbim-proxy.o CCLD mbim-proxy make[3]: Leaving directory '/root/libmbim-1.10.0/src/mbim-proxy' make[3]: Entering directory '/root/libmbim-1.10.0/src' make[3]: Nothing to be done for 'all-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/src' make[2]: Leaving directory '/root/libmbim-1.10.0/src' Making all in utils make[2]: Entering directory '/root/libmbim-1.10.0/utils' GEN mbim-network make[2]: Leaving directory '/root/libmbim-1.10.0/utils' Making all in docs make[2]: Entering directory '/root/libmbim-1.10.0/docs' Making all in reference make[3]: Entering directory '/root/libmbim-1.10.0/docs/reference' Making all in libmbim-glib make[4]: Entering directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' GEN libmbim-glib-sections.mstamp make all-am make[5]: Entering directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' make[5]: Nothing to be done for 'all-am'. make[5]: Leaving directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' make[4]: Leaving directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' make[4]: Entering directory '/root/libmbim-1.10.0/docs/reference' make[4]: Nothing to be done for 'all-am'. make[4]: Leaving directory '/root/libmbim-1.10.0/docs/reference' make[3]: Leaving directory '/root/libmbim-1.10.0/docs/reference' Making all in man make[3]: Entering directory '/root/libmbim-1.10.0/docs/man' make[3]: Nothing to be done for 'all'. make[3]: Leaving directory '/root/libmbim-1.10.0/docs/man' make[3]: Entering directory '/root/libmbim-1.10.0/docs' make[3]: Nothing to be done for 'all-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/docs' make[2]: Leaving directory '/root/libmbim-1.10.0/docs' make[1]: Leaving directory '/root/libmbim-1.10.0' root@raspberrypi:~/libmbim-1.10.0# make install Making install in . make[1]: Entering directory '/root/libmbim-1.10.0' make[2]: Entering directory '/root/libmbim-1.10.0' make[2]: Nothing to be done for 'install-exec-am'. make[2]: Nothing to be done for 'install-data-am'. make[2]: Leaving directory '/root/libmbim-1.10.0' make[1]: Leaving directory '/root/libmbim-1.10.0' Making install in build-aux make[1]: Entering directory '/root/libmbim-1.10.0/build-aux' Making install in templates make[2]: Entering directory '/root/libmbim-1.10.0/build-aux/templates' make[3]: Entering directory '/root/libmbim-1.10.0/build-aux/templates' make[3]: Nothing to be done for 'install-exec-am'. make[3]: Nothing to be done for 'install-data-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/build-aux/templates' make[2]: Leaving directory '/root/libmbim-1.10.0/build-aux/templates' Making install in mbim-codegen make[2]: Entering directory '/root/libmbim-1.10.0/build-aux/mbim-codegen' make[3]: Entering directory '/root/libmbim-1.10.0/build-aux/mbim-codegen' make[3]: Nothing to be done for 'install-exec-am'. make[3]: Nothing to be done for 'install-data-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/build-aux/mbim-codegen' make[2]: Leaving directory '/root/libmbim-1.10.0/build-aux/mbim-codegen' make[2]: Entering directory '/root/libmbim-1.10.0/build-aux' make[3]: Entering directory '/root/libmbim-1.10.0/build-aux' make[3]: Nothing to be done for 'install-exec-am'. make[3]: Nothing to be done for 'install-data-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/build-aux' make[2]: Leaving directory '/root/libmbim-1.10.0/build-aux' make[1]: Leaving directory '/root/libmbim-1.10.0/build-aux' Making install in data make[1]: Entering directory '/root/libmbim-1.10.0/data' Making install in . make[2]: Entering directory '/root/libmbim-1.10.0/data' make[3]: Entering directory '/root/libmbim-1.10.0/data' make[3]: Nothing to be done for 'install-exec-am'. make[3]: Nothing to be done for 'install-data-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/data' make[2]: Leaving directory '/root/libmbim-1.10.0/data' Making install in pkg-config make[2]: Entering directory '/root/libmbim-1.10.0/data/pkg-config' make[3]: Entering directory '/root/libmbim-1.10.0/data/pkg-config' make[3]: Nothing to be done for 'install-exec-am'. /bin/mkdir -p '/usr/local/lib/pkgconfig' /usr/bin/install -c -m 644 mbim-glib.pc '/usr/local/lib/pkgconfig' make[3]: Leaving directory '/root/libmbim-1.10.0/data/pkg-config' make[2]: Leaving directory '/root/libmbim-1.10.0/data/pkg-config' make[1]: Leaving directory '/root/libmbim-1.10.0/data' Making install in src make[1]: Entering directory '/root/libmbim-1.10.0/src' Making install in libmbim-glib make[2]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib' Making install in generated make[3]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' make install-am make[4]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' make[5]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' make[5]: Nothing to be done for 'install-exec-am'. /bin/mkdir -p '/usr/local/include/libmbim-glib' /usr/bin/install -c -m 644 mbim-error-types.h mbim-enum-types.h mbim-basic-connect.h mbim-sms.h mbim-ussd.h mbim-auth.h mbim-phonebook.h mbim-stk.h mbim-dss.h mbim-ms-firmware-id.h mbim-ms-host-shutdown.h mbim-proxy-control.h '/usr/local/include/libmbim-glib' make[5]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' make[4]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' make[3]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib/generated' Making install in . make[3]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib' make[4]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib' /bin/mkdir -p '/usr/local/lib' /bin/bash ../../libtool --mode=install /usr/bin/install -c libmbim-glib.la '/usr/local/lib' libtool: install: /usr/bin/install -c .libs/libmbim-glib.so.4.0.0 /usr/local/lib/libmbim-glib.so.4.0.0 libtool: install: (cd /usr/local/lib && { ln -s -f libmbim-glib.so.4.0.0 libmbim-glib.so.4 || { rm -f libmbim-glib.so.4 && ln -s libmbim-glib.so.4.0.0 libmbim-glib.so.4; }; }) libtool: install: (cd /usr/local/lib && { ln -s -f libmbim-glib.so.4.0.0 libmbim-glib.so || { rm -f libmbim-glib.so && ln -s libmbim-glib.so.4.0.0 libmbim-glib.so; }; }) libtool: install: /usr/bin/install -c .libs/libmbim-glib.lai /usr/local/lib/libmbim-glib.la libtool: install: /usr/bin/install -c .libs/libmbim-glib.a /usr/local/lib/libmbim-glib.a libtool: install: chmod 644 /usr/local/lib/libmbim-glib.a libtool: install: ranlib /usr/local/lib/libmbim-glib.a libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/sbin" ldconfig -n /usr/local/lib ---------------------------------------------------------------------- Libraries have been installed in: /usr/local/lib If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the `-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the `LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the `LD_RUN_PATH' environment variable during linking - use the `-Wl,-rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to `/etc/ld.so.conf' See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages. ---------------------------------------------------------------------- /bin/mkdir -p '/usr/local/include/libmbim-glib' /usr/bin/install -c -m 644 libmbim-glib.h mbim-version.h mbim-errors.h mbim-enums.h mbim-utils.h mbim-uuid.h mbim-cid.h mbim-message.h mbim-device.h mbim-compat.h mbim-proxy.h '/usr/local/include/libmbim-glib' make[4]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib' make[3]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib' Making install in test make[3]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib/test' make[4]: Entering directory '/root/libmbim-1.10.0/src/libmbim-glib/test' make[4]: Nothing to be done for 'install-exec-am'. make[4]: Nothing to be done for 'install-data-am'. make[4]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib/test' make[3]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib/test' make[2]: Leaving directory '/root/libmbim-1.10.0/src/libmbim-glib' Making install in mbimcli make[2]: Entering directory '/root/libmbim-1.10.0/src/mbimcli' make[3]: Entering directory '/root/libmbim-1.10.0/src/mbimcli' /bin/mkdir -p '/usr/local/bin' /bin/bash ../../libtool --mode=install /usr/bin/install -c mbimcli '/usr/local/bin' libtool: install: /usr/bin/install -c .libs/mbimcli /usr/local/bin/mbimcli make[3]: Nothing to be done for 'install-data-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/src/mbimcli' make[2]: Leaving directory '/root/libmbim-1.10.0/src/mbimcli' Making install in mbim-proxy make[2]: Entering directory '/root/libmbim-1.10.0/src/mbim-proxy' make[3]: Entering directory '/root/libmbim-1.10.0/src/mbim-proxy' /bin/mkdir -p '/usr/local/libexec' /bin/bash ../../libtool --mode=install /usr/bin/install -c mbim-proxy '/usr/local/libexec' libtool: install: /usr/bin/install -c .libs/mbim-proxy /usr/local/libexec/mbim-proxy make[3]: Nothing to be done for 'install-data-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/src/mbim-proxy' make[2]: Leaving directory '/root/libmbim-1.10.0/src/mbim-proxy' make[2]: Entering directory '/root/libmbim-1.10.0/src' make[3]: Entering directory '/root/libmbim-1.10.0/src' make[3]: Nothing to be done for 'install-exec-am'. make[3]: Nothing to be done for 'install-data-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/src' make[2]: Leaving directory '/root/libmbim-1.10.0/src' make[1]: Leaving directory '/root/libmbim-1.10.0/src' Making install in utils make[1]: Entering directory '/root/libmbim-1.10.0/utils' make[2]: Entering directory '/root/libmbim-1.10.0/utils' /bin/mkdir -p '/usr/local/bin' /usr/bin/install -c mbim-network '/usr/local/bin' make[2]: Nothing to be done for 'install-data-am'. make[2]: Leaving directory '/root/libmbim-1.10.0/utils' make[1]: Leaving directory '/root/libmbim-1.10.0/utils' Making install in docs make[1]: Entering directory '/root/libmbim-1.10.0/docs' Making install in reference make[2]: Entering directory '/root/libmbim-1.10.0/docs/reference' Making install in libmbim-glib make[3]: Entering directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' make install-am make[4]: Entering directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' make[5]: Entering directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' make[5]: Nothing to be done for 'install-exec-am'. /usr/bin/install -c -m 644 ./html/annotation-glossary.html /usr/bin/install -c -m 644 ./html/api-index-full.html /usr/bin/install -c -m 644 ./html/ch01.html /usr/bin/install -c -m 644 ./html/ch02.html /usr/bin/install -c -m 644 ./html/ch03.html /usr/bin/install -c -m 644 ./html/ch04.html /usr/bin/install -c -m 644 ./html/home.png /usr/bin/install -c -m 644 ./html/index.html /usr/bin/install -c -m 644 ./html/index.sgml /usr/bin/install -c -m 644 ./html/left-insensitive.png /usr/bin/install -c -m 644 ./html/left.png /usr/bin/install -c -m 644 ./html/libmbim-glib-Auth.html /usr/bin/install -c -m 644 ./html/libmbim-glib-Basic-Connect.html /usr/bin/install -c -m 644 ./html/libmbim-glib-Command-IDs.html /usr/bin/install -c -m 644 ./html/libmbim-glib-Common-utilities.html /usr/bin/install -c -m 644 ./html/libmbim-glib-Deprecated-API.html /usr/bin/install -c -m 644 ./html/libmbim-glib.devhelp2 /usr/bin/install -c -m 644 ./html/libmbim-glib-DSS.html /usr/bin/install -c -m 644 ./html/libmbim-glib-Enumerations-and-Flags.html /usr/bin/install -c -m 644 ./html/libmbim-glib-Errors.html /usr/bin/install -c -m 644 ./html/libmbim-glib-MS-Firmware-ID.html /usr/bin/install -c -m 644 ./html/libmbim-glib-MS-Host-Shutdown.html /usr/bin/install -c -m 644 ./html/libmbim-glib-Phonebook.html /usr/bin/install -c -m 644 ./html/libmbim-glib-SMS.html /usr/bin/install -c -m 644 ./html/libmbim-glib-STK.html /usr/bin/install -c -m 644 ./html/libmbim-glib-USSD.html /usr/bin/install -c -m 644 ./html/libmbim-glib-UUIDs.html /usr/bin/install -c -m 644 ./html/libmbim-glib-Version-checks.html /usr/bin/install -c -m 644 ./html/MbimDevice.html /usr/bin/install -c -m 644 ./html/MbimMessage.html /usr/bin/install -c -m 644 ./html/MbimProxy.html /usr/bin/install -c -m 644 ./html/object-tree.html /usr/bin/install -c -m 644 ./html/right-insensitive.png /usr/bin/install -c -m 644 ./html/right.png /usr/bin/install -c -m 644 ./html/style.css /usr/bin/install -c -m 644 ./html/up-insensitive.png /usr/bin/install -c -m 644 ./html/up.png make[5]: Leaving directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' make[4]: Leaving directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' make[3]: Leaving directory '/root/libmbim-1.10.0/docs/reference/libmbim-glib' make[3]: Entering directory '/root/libmbim-1.10.0/docs/reference' make[4]: Entering directory '/root/libmbim-1.10.0/docs/reference' make[4]: Nothing to be done for 'install-exec-am'. make[4]: Nothing to be done for 'install-data-am'. make[4]: Leaving directory '/root/libmbim-1.10.0/docs/reference' make[3]: Leaving directory '/root/libmbim-1.10.0/docs/reference' make[2]: Leaving directory '/root/libmbim-1.10.0/docs/reference' Making install in man make[2]: Entering directory '/root/libmbim-1.10.0/docs/man' make[3]: Entering directory '/root/libmbim-1.10.0/docs/man' make[3]: Nothing to be done for 'install-exec-am'. /bin/mkdir -p '/usr/local/share/man/man1' /usr/bin/install -c -m 644 mbimcli.1 mbim-network.1 '/usr/local/share/man/man1' make[3]: Leaving directory '/root/libmbim-1.10.0/docs/man' make[2]: Leaving directory '/root/libmbim-1.10.0/docs/man' make[2]: Entering directory '/root/libmbim-1.10.0/docs' make[3]: Entering directory '/root/libmbim-1.10.0/docs' make[3]: Nothing to be done for 'install-exec-am'. make[3]: Nothing to be done for 'install-data-am'. make[3]: Leaving directory '/root/libmbim-1.10.0/docs' make[2]: Leaving directory '/root/libmbim-1.10.0/docs' make[1]: Leaving directory '/root/libmbim-1.10.0/docs'

If the above process went right, you now should be able to run mbimcli tool (run ldconfig to make sure the libraries load correctly).

root@raspberrypi:~# ldconfig root@raspberrypi:~# mbimcli error: no device path specified

4. Configuring the Modem To Connect Automatically

Now we have all the software compontents to make the modem actually connect. Note: The sequence of MBIM commands to activate the connection was mostly discovered empirically, it is possible it's really not the correct way to do things; but at least it seems to work. In particular, the disconnecting procedure is problematic, since it takes quite long to execute. I strongly suggest that you just unplug the modem instead of using ifdown wwan0.

Create directory /etc/ap where we will put all our scripts we're going to use.

Create file /etc/ap/lte-dongle.sh with the content listed below and make it executable with chmod a+x:

#!/bin/bash CNT=10 get_state() { mbimcli -d /dev/cdc-wdm0 --query-registration-state \ | perl -ne "/Register state:\\s'(.+)'/ && print \$1;" } if [ "$IFACE" != "wwan0" ]; then exit 0; fi if [ "$MODE" = "start" ]; then if [ "$IF_MOBILE_PIN" ]; then mbimcli -d /dev/cdc-wdm0 --enter-pin=$IF_MOBILE_PIN fi while [ $(get_state) != "home" ]; do CNT=$[ $CNT - 1 ] if [ $CNT -eq 0 ]; then exit fi sleep 2; done; mbimcli -d /dev/cdc-wdm0 --attach-packet-service mbimcli -d /dev/cdc-wdm0 --connect=$IF_MOBILE_APN --no-close else mbimcli -d /dev/cdc-wdm0 --noop mbimcli -d /dev/cdc-wdm0 --disconnect fi

Create symlinks called lte-dongle in both /etc/network/if-pre-up.d/ and /etc/network/if-down.d pointing to /etc/ap/lte-dongle.sh.

root@raspberrypi:~# cd /etc/network/if-pre-up.d/ root@raspberrypi:/etc/network/if-pre-up.d# ln -s /etc/ap/lte-dongle.sh lte-dongle root@raspberrypi:/etc/network/if-pre-up.d# cd ../if-down.d/ root@raspberrypi:/etc/network/if-down.d# ln -s /etc/ap/lte-dongle.sh lte-dongle

Add following piece of text into /etc/network/interfaces (change the APN and SIM card PIN if they don't match the default, omit the "mobile-pin" line if the PIN is disabled):

allow-hotplug wwan0 iface wwan0 inet dhcp mobile-apn internet mobile-pin 1234

Also, we do not want ifplugd to handle the interface (it's really only relevant for real ethernet interfaces). Therefore, modify /etc/default/ifplugd so that it only aplies to eth0 interface.

HOTPLUG_INTERFACES="eth0"

At this point, plugging the modem into the RasPi should automatically unlock the SIM card, attach to the packet network, establish the network connection and obtain IP address with DHCP. Visually, the LED on the modem will start to blink green, then it will blink violet and eventually as the connection gets established, it will be permanently lit in violet (note: violet colour means LTE connection, if the connection is 3G the colour is blue, if only EDGE is available, the colour will remain green). The whole process takes 10-15 seconds. If connection process succeeds, you should see that the wwan0 interface got an IP address and default route was added into the routing table:

root@raspberrypi:~# ifconfig wwan0 wwan0 Link encap:Ethernet HWaddr d2:6d:e5:9f:e5:e4 inet addr:10.45.42.121 Bcast:10.45.42.123 Mask:255.255.255.252 UP BROADCAST RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:336929 errors:0 dropped:0 overruns:0 frame:0 TX packets:208796 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:441326250 (420.8 MiB) TX bytes:203671452 (194.2 MiB) root@raspberrypi:~# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.45.42.122 0.0.0.0 UG 0 0 0 wwan0 10.45.42.120 0.0.0.0 255.255.255.252 U 0 0 0 wwan0

At this point, the RasPi has full Internet connection going. The next part will deal with making this connection available over WiFi access point.

5. Configuring the Access Point

The rest of this document deals with configuring an access point and related services. If you only need the connection for the Raspberry itself, you can stop reading here, the remaining is not relevant for you.

First of all we need to configure our local wireless LAN interface. Therefore plug in the WiFi adapter and verify, that you can see the wlan0 interface.

root@raspberrypi:~# ifconfig wlan0 wlan0 Link encap:Ethernet HWaddr bc:f6:85:65:0d:0a UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:594626 errors:0 dropped:0 overruns:0 frame:0 TX packets:834038 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:69163176 (65.9 MiB) TX bytes:923126804 (880.3 MiB)

OK, it's there, so let's add an IP address to it. I will use 192.168.101.0/24 as the hotspot network address. The IP address on the wlan0 interface will be static, since it will be the default gateway for wireless clients. Add following block of text into /etc/network/interfaces while removing previous config pertaining to interface wlan0:

allow-hotplug wlan0 iface wlan0 inet static address 192.168.101.1 netmask 255.255.255.0

Now removing and reinserting the WiFi adapter should also autoconfigure it with our IP address. Check this again with ifconfig command:

root@raspberrypi:~# ifconfig wlan0 wlan0 Link encap:Ethernet HWaddr bc:f6:85:65:0d:0a inet addr:192.168.101.1 Bcast:192.168.101.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:594626 errors:0 dropped:0 overruns:0 frame:0 TX packets:834038 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:69163176 (65.9 MiB) TX bytes:923126804 (880.3 MiB)

If this works, we can proceed to installing the actual access point software, which is available in hostapd package. Install it as usual:

root@raspberrypi:~# apt-get install hostapd

Now unpack the default configuration provided by the package and put it into /etc/hostapd directory:

root@raspberrypi:~# zcat /usr/share/doc/hostapd/examples/hostapd.conf.gz >/etc/hostapd/hostapd.conf

In /etc/default/hostapd, change this one line as shown below. Note, that this definition won't be used during actual operation in our setup, we do this only for testing purposes so that we can start hostapd manually by the service command.

DAEMON_CONF="/etc/hostapd/hostapd.conf"

We will be starting hostapd after the WiFi adapter is plugged in, therefore we want to make sure that hostapd doesn't come up after system boot. Issue following command:

root@raspberrypi:~# update-rc.d hostapd disable update-rc.d: using dependency based boot sequencing insserv: warning: current start runlevel(s) (empty) of script `hostapd' overrides LSB defaults (2 3 4 5). insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `hostapd' overrides LSB defaults (0 1 6).

The hostapd configuration can be quite involved, but for our purposes, it is actually quite simple. Here is listing of the configuration file lines I modified. Leave the rest as it is.

interface=wlan0 driver=nl80211 ssid=RPi_AP country_code=CZ channel=6 auth_algs=1 wpa=2 wpa_passphrase=myPa$$w0rd wpa_pairwise=TKIP rsn_pairwise=CCMP

Few words about this config: driver should be nl80211 unless your wireless adapter doesn't use the mac80211 framework. It is possible to run hostapd on such adapters, but it requires some modification, or even recompilation of hostapd. It might be easier to just get supported wireless adapter. ssid is what you will see when you scan wireless networks on any device. This should be unique in your place. country_code can perhaps be safely omitted, though it doesn't hurt to set it. channel defines what wifi channel will the AP run on; ideally, it should be channel that doesn't collide with other access points in your vicinity. wpa enables WPA authentication and encryption; value of 2 means WPA2, value of 1 means older WPA; you should use WPA2 unless you have old device that for some reason doesn't support WPA2. wpa_passpharse defines the password the clients need to supply to connect to the AP.

Now that we have the hostapd configured, we should probably verify, that it works as it is supposed to. Therefore start the service manually:

root@raspberrypi:~# service hostapd start

And verify that it is running and that you can see the AP SSID being visible on a WiFi client (such as your smartphone or notebook). You can connect to the AP, but you won't get IP address. But if you see the SSID on air, chances are that the hostapd is working correctly and that we can proceed to further configurations. For now, stop the hostapd service.

root@raspberrypi:~# service hostapd stop

To make hostapd start automatically after the WiFi adapter is plugged in, add highlighted line into /etc/network/interface, into the iface wlan0 stanza:

iface wlan0 inet static address 192.168.101.1 netmask 255.255.255.0 hostapd /etc/hostapd/hostapd.conf

Also, move the hostapd script (actually a symlink) from /etc/network/if-post-down.d to /etc/network/if-down.d. The reason for this is, that the if-post-down.d scripts don't get executed when the physical network device is unplugged from the system.

root@raspberrypi:~# cd /etc/network/if-post-down.d/ root@raspberrypi:/etc/network/if-post-down.d# mv hostapd ../if-down.d/

Additionally, I had to modify the script itself: in the last case "$PHASE" block in the script, replace post-down) with pre-down). This is a result of moving the script into different directory.

Now you can try plugging the WiFi adapter again and checking if the hostapd starts running and broadcasting the configured SSID. Then unplug the adapter again and check if the hostapd got stopped correctly using the ps ax command. If everything is working correctly, we will now move on to configuring additional services required by the clients.

6. Configuring IP Services

6.1 DHCP Server

Install isc-dhcp-server package:

root@raspberrypi:~# apt-get install isc-dhcp-server

In file /etc/default/isc-dhcp-server change this line to make the dhcp server listen on the wireless interface.

INTERFACES="wlan0"

Configure the dhcp server in /etc/dhcp/dhcpd.conf:

ddns-update-style none; default-lease-time 600; max-lease-time 7200; authoritative; log-facility local7; subnet 192.168.101.0 netmask 255.255.255.0 { range 192.168.101.100 192.168.101.254; option routers 192.168.101.1; option broadcast-address 192.168.101.255; option domain-name "local"; option domain-name-servers 192.168.101.1; }

Note, that we give client our local WiFi interface as DNS server, because in the next step we will configure local caching nameserver. You can use public DNS server or mobile provider's DNS server instead and skip the nameserver installation.

Sadly, ISC dhcpd does not seem to support dynamic interfaces, all interfaces it listens on must be present when it starts otherwise it will finish with error. This is of course a problem with our hot plugged WiFi adapter. Therefore, we disable automatic start up on system boot:

root@raspberrypi:~# update-rc.d isc-dhcp-server disable update-rc.d: using dependency based boot sequencing insserv: warning: current start runlevel(s) (empty) of script `isc-dhcp-server' overrides LSB defaults (2 3 4 5). insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `isc-dhcp-server' overrides LSB defaults (0 1 6).

The dhcpd start will occur when the wlan0 interface is brought up. This is achieved by adding these two lines to iface wlan0 stanza in /etc/network/interfaces file:

iface wlan0 inet static up service isc-dhcp-server start down service isc-dhcp-server stop

Again, check the setup by trying to manually start the dhcp server to see if it comes up. You can also try connecting with a wireless client to see if it gets an IP address.

6.2 Caching Nameserver

This step can be skipped if you want to use external DNS server (either provider's one or some public DNS server such as Google or OpenDNS). I prefer to run my own recursing name server.

Install package bind9 in the usual way:

root@raspberrypi:~# apt-get install bind9

In file /etc/bind/named.conf.options add these two lins in the options scope. They will enable listening on all private interfaces, but will disallow listening on the wwan0 interface (as my provider assigns it IP address from the 10/8 block); also serving IPv6 requests is completely disabled.

listen-on { !10/8; 127.0.0.1; 192.168.0.0/16; }; listen-on-v6 { none; };

BIND should be running (the installation normally starts it), so now only reload it to activate our setup.

root@raspberrypi:~# service bind9 reload Reloading domain name service...: bind9.

Make sure the name server starts after the system boot:

root@raspberrypi:~# update-rc.d bind9 enable update-rc.d: using dependency based boot sequencing

If you want the Raspberry Pi itself to prefer the local nameserver for its DNS queries, uncomment following line in /etc/dhcp/dhclient.conf:

prepend domain-name-servers 127.0.0.1;

6.3 Enable Forwarding and Network Address Translation

Uncomment following line in /etc/sysctl.conf:

net.ipv4.ip_forward=1

This will activate IP forwarding on boot up; to enable it immediately, issue following command:

root@raspberrypi:~# sysctl net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1

Now we need to implement Network Address Translation (NAT) so that clients on the WiFi AP will be hidden behind the single IP address the mobile provider gave us. Update /etc/network/interfaces to look like this (new lines are highlighted, only wlan0 and wwan0 stanzas shown).

allow-hotplug wlan0 iface wlan0 inet static address 192.168.101.1 netmask 255.255.255.0 hostapd /etc/hostapd/hostapd.conf up service isc-dhcp-server start down service isc-dhcp-server stop ipv4-nat-inside true ipv4-nat-outif wwan0 allow-hotplug wwan0 iface wwan0 inet dhcp mobile-apn internet mobile-pin 1234 ipv4-nat-outside true

The ipv4-nat- parameters are custom parameters we will use in our custom ifupdown scripts that will bring up NAT dynamically when need. Don't forget that the files must be executable, use chmod a+x on them.

Create file /etc/ap/nat-outside.sh:

#!/bin/bash if [ "$IF_IPV4_NAT_OUTSIDE" != "true" ]; then exit 0 fi if [ "$MODE" = "start" ]; then OP="-A" else OP="-D" fi iptables -t nat $OP POSTROUTING -o $IFACE -j MASQUERADE iptables -t nat $OP POSTROUTING -o $IFACE -j MASQUERADE

Create file /etc/ap/nat-inside.sh:

#!/bin/bash if [ "$IF_IPV4_NAT_INSIDE" != "true" ]; then exit 0 fi if [ "$MODE" = "start" ]; then OP="-A" else OP="-D" fi iptables $OP FORWARD \ -i $IF_IPV4_NAT_OUTIF -o $IFACE \ -m state --state RELATED,ESTABLISHED -j ACCEPT iptables $OP FORWARD \ -i $IFACE -o $IF_IPV4_NAT_OUTIF \ -j ACCEPT

Now we create symlinks to both of these files in both /etc/network/if-up.d and /etc/network/if-down.d.

root@raspberrypi:~# cd /etc/network/if-up.d root@raspberrypi:/etc/network/if-up.d# ln -s /etc/ap/nat-outside.sh nat-outside root@raspberrypi:/etc/network/if-up.d# ln -s /etc/ap/nat-inside.sh nat-inside root@raspberrypi:/etc/network/if-up.d# cd ../if-down.d/ root@raspberrypi:/etc/network/if-down.d# ln -s /etc/ap/nat-outside.sh nat-outside root@raspberrypi:/etc/network/if-down.d# ln -s /etc/ap/nat-inside.sh nat-inside

And that's it! Our access point that shares 4G connection should be finished and ready to run!

Outstanding Issues