├── Dockerfile ├── LICENSE ├── README.md ├── feeds.conf ├── files ├── etc │ ├── config │ │ ├── alfred │ │ ├── autoupdater │ │ ├── batman-adv │ │ ├── dhcp │ │ ├── fastd │ │ ├── firewall │ │ ├── freifunk │ │ ├── simple-radvd │ │ ├── simple-tc │ │ └── uhttpd │ ├── crontabs │ │ └── root │ ├── firewall.user │ ├── hotplug.d │ │ ├── iface │ │ │ ├── 30-fastd │ │ │ └── 40-mesh-on-wan │ │ └── net │ │ │ └── 60-freifunk-ula │ ├── httpd.conf │ ├── init.d │ │ └── freifunk_init │ ├── sysupgrade.conf │ └── uci-defaults │ │ └── 50_freifunk-setup ├── lib │ └── ff_shared.sh ├── usr │ └── sbin │ │ ├── calc_speed.sh │ │ ├── print_map.sh │ │ └── print_service.sh └── www │ ├── freifunk │ ├── cgi-bin │ │ ├── data │ │ └── status │ ├── index.css │ └── index.html │ └── lan │ ├── cgi-bin │ ├── home │ ├── misc │ ├── network │ ├── password │ ├── settings │ ├── ssh_keys │ └── upgrade │ ├── home.html │ ├── home.js │ ├── index.html │ ├── network.html │ ├── network.js │ ├── password.html │ ├── password.js │ ├── settings.html │ ├── settings.js │ ├── shared.js │ ├── ssh_keys.html │ ├── ssh_keys.js │ ├── style.css │ ├── translations.js │ ├── upgrade.html │ ├── upgrade.js │ ├── wifiscan.html │ └── wifiscan.js ├── package ├── autoupdater │ ├── Makefile │ ├── README.md │ ├── files │ │ ├── etc │ │ │ └── config │ │ │ │ └── autoupdater │ │ └── usr │ │ │ └── sbin │ │ │ └── autoupdater │ └── manifest.sample ├── freifunk │ └── Makefile ├── simple-radvd │ ├── Makefile │ ├── files │ │ └── etc │ │ │ ├── config │ │ │ └── simple-radvd │ │ │ └── init.d │ │ │ └── simple-radvd │ └── src │ │ ├── Makefile │ │ └── simple-radvd.c ├── simple-tc │ ├── Makefile │ ├── files │ │ └── etc │ │ │ ├── config │ │ │ └── simple-tc │ │ │ ├── hotplug.d │ │ │ └── net │ │ │ │ └── 50-simple-tc │ │ │ ├── modules-boot.d │ │ │ └── 30-simple-tc │ │ │ └── modules.d │ │ │ └── 30-simple-tc │ └── src │ │ ├── Makefile │ │ ├── include │ │ └── linux │ │ │ ├── pkt_cls.h │ │ │ ├── pkt_sched.h │ │ │ └── rtnetlink.h │ │ └── simple-tc.c └── sockread │ ├── Makefile │ └── src │ ├── Makefile │ └── main.c └── patches ├── openwrt ├── 0001-procd-add-support-for-alternative-rc.d-directories.patch ├── 0002-base-files-disable-reset-button-handling.patch ├── 0003-libjson-c-Add-support-for-custom-format-strings-for-.patch ├── 0004-dropbear-add-a-failsafe-mode-that-will-always-allow-.patch ├── 0005-kernel-ebtables-add-support-for-ICMP-IGMP-type-match.patch ├── 0006-build-set-TARGET_ROOTFS_PARTSIZE-to-make-combined-im.patch ├── 0007-ipq-wifi-add-BDF-for-Aruba-AP-303.patch ├── 0008-ipq40xx-add-support-for-Aruba-AP-303.patch ├── 0009-ath79-enable-GL-AR750S-NOR-variant-from-master.patch ├── 0010-tools-add-zstd.patch ├── 0011-build-compress-kernel-debuginfo-using-zstd.patch ├── 0012-mac80211-rt2800-enable-MFP-support-unconditionally.patch ├── 0013-mt76-mt76x0-disable-GTK-offloading.patch ├── 0014-mt76-mt7603-add-additional-EEPROM-chip-ID.patch ├── 0015-config-config-build-extend-small-flash-option.patch └── 0016-include-target-remove-ppp-and-opkg-by-default.patch ├── packages ├── 0001-fastd-update-to-v19.patch └── 0002-ecdsautils-verify-fix-signature-verification-CVE-2022-24884.patch └── routing └── 0001-alfred-adjust-intervals.patch /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:11 2 | RUN apt-get update; \ 3 | apt-get install --no-install-recommends -y subversion g++ zlib1g-dev build-essential git python time libncurses5-dev gawk gettext unzip file libssl-dev wget; \ 4 | apt-get install --no-install-recommends -y ca-certificates; \ 5 | apt-get clean; \ 6 | rm -vrf /var/lib/apt/lists/* 7 | 8 | ENV FORCE_UNSAFE_CONFIGURE=1 9 | RUN \ 10 | git clone https://git.openwrt.org/openwrt/openwrt.git; \ 11 | cd openwrt; \ 12 | git reset --hard 6fc02f2a45e151ce16677d6131251af86ab4fc06; \ 13 | \ 14 | git clone -b v2.3.1 https://github.com/ffulm/firmware.git; \ 15 | cp -rf firmware/files firmware/package firmware/feeds.conf .; \ 16 | \ 17 | ./scripts/feeds update -a; \ 18 | ./scripts/feeds install -a; \ 19 | \ 20 | git am --whitespace=nowarn firmware/patches/openwrt/*.patch; \ 21 | \ 22 | cd feeds/routing; \ 23 | git am --whitespace=nowarn ../../firmware/patches/routing/*.patch; \ 24 | cd ../../; \ 25 | \ 26 | cd feeds/packages; \ 27 | git am --whitespace=nowarn ../../firmware/patches/packages/*.patch; \ 28 | cd ../../; \ 29 | \ 30 | rm -rf firmware tmp; 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) <2012> 2 | (Source https://en.wikipedia.org/wiki/MIT_License) 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 | software and associated documentation files (the "Software"), to deal in the Software 6 | without restriction, including without limitation the rights to use, copy, modify, merge, 7 | publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 8 | to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or 11 | substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 14 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 15 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 16 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 17 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 18 | DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Firmware for Freifunk Ulm 2 | ========================= 3 | 4 | The firmware turns a common wireless router into a mesh networking device. 5 | It connects to similar routers in the area and builds a Wifi-mesh network 6 | but also opens an access point for computers to connect over Wifi. 7 | Included is Internet connectivity and a web interface. 8 | 9 | [Precompiled firmware images](https://firmware.freifunk-ulm.de/ "Precompiled firmware images") are available on our server. All other released versions here on github are out-of-date. 10 | 11 | # Build instructions 12 | 13 | To build the firmware yourself there are two possibilities: Use a Dockerfile to create the build environment or do it by hand. 14 | 15 | ## Use Dockerfile 16 | First of all, we need Docker: 17 | ```bash 18 | sudo apt install docker.io 19 | ``` 20 | To use the Dockerfile, get it from github by cloning this repository or just download it. 21 | In the folder which contains the Dockerfile do the following: 22 | ```bash 23 | # 1) Create image from Dockerfile. This contains all the tools and sources we need 24 | docker build -t ffulm . 25 | 26 | # 2) Run image 27 | mkdir /tmp/ffulm-build 28 | docker run --rm -it -v /tmp/ffulm-build:/openwrt/bin/targets ffulm 29 | 30 | # 3) Start build process 31 | cd /openwrt 32 | make menuconfig 33 | ## do the changes necessary 34 | make 35 | exit 36 | ``` 37 | After exit, the docker container started in 2 will be deleted. 38 | Steps 2 and 3 can be done multiple times to create more than 1 firmware image. 39 | 40 | ## Do it by hand 41 | You need a Unix console to enter commands into. 42 | Install dependencies for the build environment (Debian/Ubuntu): 43 | 44 | ```bash 45 | sudo apt install g++ zlib1g-dev build-essential git python time 46 | sudo apt install libncurses5-dev gawk gettext unzip file libssl-dev wget 47 | ``` 48 | Build commands for the console: 49 | 50 | ```bash 51 | git clone https://git.openwrt.org/openwrt/openwrt.git 52 | cd openwrt 53 | git reset --hard 6fc02f2a45e151ce16677d6131251af86ab4fc06 54 | 55 | git clone -b v2.3.1 https://github.com/ffulm/firmware.git 56 | cp -rf firmware/files firmware/package firmware/feeds.conf . 57 | 58 | ./scripts/feeds update -a 59 | ./scripts/feeds install -a 60 | 61 | git am --whitespace=nowarn firmware/patches/openwrt/*.patch 62 | 63 | cd feeds/routing 64 | git am --whitespace=nowarn ../../firmware/patches/routing/*.patch 65 | cd ../../ 66 | 67 | cd feeds/packages 68 | git am --whitespace=nowarn ../../firmware/patches/packages/*.patch 69 | cd ../../ 70 | 71 | rm -rf firmware tmp 72 | 73 | make menuconfig 74 | ``` 75 | Now select the right "Target System" and "Target Profile" for your AP model: 76 | 77 | For example, for the TL-WR841ND v3, select: 78 | * `Target System => Atheros AR7xxx/AR9xxx` 79 | * `Target Profile => <*> TP-LINK TL-WR842N/ND v3` 80 | 81 | Or in case you have the Ubiquiti UniFi Outdoor, select: 82 | * `Target System => Atheros AR7xxx/AR9xxx` 83 | * `Target Profile => <*> Ubiquiti UniFi Outdoor` 84 | 85 | For other models you can lookup the "Target System" in the LEDE 86 | [hardware table](https://lede-project.org/toh/start). Your AP model 87 | should now be visible in the "Target Profile" list. 88 | 89 | Now start the build process. This takes some time: 90 | 91 | ```bash 92 | make 93 | ``` 94 | *You have the opportunity to compile the firmware on more CPU Threads. 95 | E.g. for 4 threads type* `make -j4` . 96 | 97 | The **firmware image** files can now be found under the `bin/targets` folder. Use the firmware update functionality of your router and upload the factory image file to flash it with the Freifunk firmware. The sysupgrade images are for updates. 98 | 99 | * Use `openwrt-[chip]-[model]-squashfs-factory.bin` for use with the vendor firmware. 100 | * Use `openwrt-[chip]-[model]-squashfs-sysupgrade.bin` for use with OpenWrt based firmware. 101 | 102 | **Many routers have not been tested yet, but may work.** 103 | ***Give it a try! :-)*** 104 | -------------------------------------------------------------------------------- /feeds.conf: -------------------------------------------------------------------------------- 1 | src-git packages https://git.openwrt.org/feed/packages.git^2974079d3db786fe5da00c10f1d80e79b0112093 2 | src-git luci https://git.openwrt.org/project/luci.git;openwrt-19.07 3 | src-git routing https://git.openwrt.org/feed/routing.git^02b4dbfcb7b8f8b566940847d22d5a6f229d2e66 4 | src-git telephony https://git.openwrt.org/feed/telephony.git;openwrt-19.07 -------------------------------------------------------------------------------- /files/etc/config/alfred: -------------------------------------------------------------------------------- 1 | 2 | config 'alfred' 'alfred' 3 | option interface 'br-freifunk' 4 | option mode 'slave' 5 | option batmanif 'bat0' 6 | option start_vis '0' 7 | option run_facters '0' 8 | -------------------------------------------------------------------------------- /files/etc/config/autoupdater: -------------------------------------------------------------------------------- 1 | config autoupdater settings 2 | option enabled 1 3 | option branch "stable" 4 | 5 | config branch stable 6 | # The branch name given in the manifest 7 | option name 'stable' 8 | 9 | list mirror 'http://[fdef:17a0:fff1:300::4]/freifunk/firmware/autoupdater' 10 | list mirror 'http://[fdef:17a0:fff1:300::5]/freifunk/firmware/autoupdater' 11 | 12 | # Delay execution of the autoupdater for at most fetch_delay seconds. 13 | # This spreads the load of the server when all nodes start 14 | # the autoupdater at the same time. 15 | option fetch_delay 1000 16 | 17 | # Delay sysupgrade for apply_delay seconds. 18 | # This gives other nodes behind this one time to fetch the update 19 | # themselves before the update is performed. 20 | option apply_delay 0 21 | 22 | # Minimum valid signatures required to perform the update 23 | option good_signatures 2 24 | 25 | # List of public keys 26 | list pubkey '4320668c6858faa064d2f205c538bafb7b042600eef6a7503258d7355d01e4f8' #mwarning 27 | list pubkey '65c273c3fab43f81b8620d30700a30ed49d8035c3072941cadd94f1339a7e850' #foschum 28 | list pubkey '1ac49f73f9de9943634b2cf25e2212e67f654dbb0c8a913743ef3087d35f7b0a' #mk070' 29 | list pubkey '761cf21ec0161173469e6adbc04247d4c9085dc3a7ecb4a462ef7ef9a7123e7b' #flo 30 | -------------------------------------------------------------------------------- /files/etc/config/batman-adv: -------------------------------------------------------------------------------- 1 | 2 | config mesh 'bat0' 3 | option orig_interval 30000 4 | option multicast_mode 1 5 | option distributed_arp_table 1 6 | option bridge_loop_avoidance 1 7 | option aggregated_ogms 1 8 | option gw_mode 'client' 9 | option routing_algo 'BATMAN_V' 10 | -------------------------------------------------------------------------------- /files/etc/config/dhcp: -------------------------------------------------------------------------------- 1 | 2 | config dnsmasq 3 | option domainneeded '1' 4 | option boguspriv '1' 5 | option filterwin2k '0' 6 | option localise_queries '1' 7 | option rebind_protection '1' 8 | option rebind_localhost '1' 9 | option expandhosts '1' 10 | option nonegcache '0' 11 | option authoritative '1' 12 | option readethers '1' 13 | option leasefile '/tmp/dhcp.leases' 14 | option resolvfile '/tmp/resolv.conf.auto' 15 | option localservice '1' 16 | option add_local_domain '0' 17 | option add_local_hostname '0' 18 | 19 | config odhcpd 'odhcpd' 20 | option maindhcp '0' 21 | option leasefile '/tmp/hosts/odhcpd' 22 | option leasetrigger '/usr/sbin/odhcpd-update' 23 | 24 | config dhcp lan 25 | option interface lan 26 | option start 100 27 | option limit 150 28 | option leasetime 2h 29 | list dhcp_option '3,192.168.133.1' 30 | list dhcp_option '6,192.168.133.1' 31 | option ndp relay 32 | 33 | config dhcp wan 34 | option interface wan 35 | option ignore 1 36 | 37 | config dhcp freifunk 38 | option interface freifunk 39 | option ignore 1 40 | -------------------------------------------------------------------------------- /files/etc/config/fastd: -------------------------------------------------------------------------------- 1 | 2 | config fastd 'default' 3 | option enabled 1 4 | option syslog_level 'warn' 5 | option bind 'any interface "br-wan"' 6 | list method 'salsa2012+umac' 7 | option secure_handshakes 1 8 | option hide_ip_addresses '1' 9 | option hide_mac_addresses '1' 10 | option status_socket '/var/run/fastd.status' 11 | option mode 'tap' 12 | option interface 'fastd_mesh' 13 | option mtu 1406 14 | option forward 0 15 | option secret 'generate' 16 | option packet_mark 1 17 | 18 | config peer_group 'backbone' 19 | option enabled '1' 20 | option net 'default' 21 | option peer_limit '1' 22 | 23 | config peer 'vpn10' 24 | option enabled 1 25 | option net 'default' 26 | option group 'backbone' 27 | option key 'ecd1a0709beee71f796ca0d5a9de1e6e098de9a88c1fc230d48991114f8bb8d2' 28 | list remote 'ipv6 "vpn10.freifunk-ulm.de" port 1244' 29 | list remote 'ipv4 "vpn10.freifunk-ulm.de" port 1244' 30 | option float 0 31 | 32 | config peer 'vpn11' 33 | option enabled 1 34 | option net 'default' 35 | option group 'backbone' 36 | option key 'd70fc192561ae5acac3b6db8edca32abff0d27300f65bd9e7501148888a943bc' 37 | list remote 'ipv6 "vpn11.freifunk-ulm.de" port 1244' 38 | list remote 'ipv4 "vpn11.freifunk-ulm.de" port 1244' 39 | option float 0 40 | 41 | config peer 'vpn12' 42 | option enabled 1 43 | option net 'default' 44 | option group 'backbone' 45 | option key '211e6902eeb97bde95ba9ec3bd520afb43879f0197782cafa8bf07639a8b78d5' 46 | list remote 'ipv6 "vpn12.freifunk-ulm.de" port 1244' 47 | list remote 'ipv4 "vpn12.freifunk-ulm.de" port 1244' 48 | option float 0 49 | 50 | config peer 'vpn13' 51 | option enabled 1 52 | option net 'default' 53 | option group 'backbone' 54 | option key 'b85904d97f0e049249b5467257bc9293e7a0cf59de4fdbf811e0d4c6c7561368' 55 | list remote 'ipv6 "vpn13.freifunk-ulm.de" port 1244' 56 | list remote 'ipv4 "vpn13.freifunk-ulm.de" port 1244' 57 | option float 0 58 | 59 | config peer 'vpn14' 60 | option enabled 1 61 | option net 'default' 62 | option group 'backbone' 63 | option key 'fd5dd4744bf5828d5112a1698175743d82214f5b798663b3fcb7c4ff337c6ac4' 64 | list remote 'ipv6 "vpn14.freifunk-ulm.de" port 1244' 65 | list remote 'ipv4 "vpn14.freifunk-ulm.de" port 1244' 66 | option float 0 67 | 68 | config peer 'fw10' 69 | option enabled 1 70 | option net 'default' 71 | option group 'backbone' 72 | option key '0e2cde8a1af07a1c897665ec232f5a151f463cdbc2a08fa5a08791c8d69417f9' 73 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1420' 74 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1420' 75 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1421' 76 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1421' 77 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1422' 78 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1422' 79 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1423' 80 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1423' 81 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1424' 82 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1424' 83 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1425' 84 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1425' 85 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1426' 86 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1426' 87 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1427' 88 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1427' 89 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1428' 90 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1428' 91 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1429' 92 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1429' 93 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1430' 94 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1430' 95 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1431' 96 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1431' 97 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1432' 98 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1432' 99 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1433' 100 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1433' 101 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1434' 102 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1434' 103 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1435' 104 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1435' 105 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1436' 106 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1436' 107 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1437' 108 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1437' 109 | list remote 'ipv6 "fw10.freifunk-ulm.de" port 1438' 110 | list remote 'ipv4 "fw10.freifunk-ulm.de" port 1438' 111 | option float 0 112 | 113 | config peer 'vpn20' 114 | option enabled 1 115 | option net 'default' 116 | option group 'backbone' 117 | option key '7baefe328d479981a3d81878168f952cbae9d7e300bf51b37cd366b79917b95d' 118 | list remote 'ipv6 "vpn20.freifunk-ulm.de" port 1244' 119 | list remote 'ipv4 "vpn20.freifunk-ulm.de" port 1244' 120 | option float 0 121 | 122 | config peer 'vpn21' 123 | option enabled 1 124 | option net 'default' 125 | option group 'backbone' 126 | option key 'e02a26a8ac835c649f1376336599a2ef71f7eec7a53e2dc3f71106bd058b6c22' 127 | list remote 'ipv6 "vpn21.freifunk-ulm.de" port 1244' 128 | list remote 'ipv4 "vpn21.freifunk-ulm.de" port 1244' 129 | option float 0 130 | 131 | config peer 'vpn22' 132 | option enabled 1 133 | option net 'default' 134 | option group 'backbone' 135 | option key '0de69176cd3b4dd61a048af882022a25c82b37c7235ae6409b30a45af42b6888' 136 | list remote 'ipv6 "vpn22.freifunk-ulm.de" port 1244' 137 | list remote 'ipv4 "vpn22.freifunk-ulm.de" port 1244' 138 | option float 0 139 | 140 | config peer 'vpn23' 141 | option enabled 1 142 | option net 'default' 143 | option group 'backbone' 144 | option key '831f18e475169317d074d014082b72cba7dec79e40b94c00324736764702ce52' 145 | list remote 'ipv6 "vpn23.freifunk-ulm.de" port 1244' 146 | list remote 'ipv4 "vpn23.freifunk-ulm.de" port 1244' 147 | option float 0 148 | 149 | config peer 'vpn24' 150 | option enabled 1 151 | option net 'default' 152 | option group 'backbone' 153 | option key 'e2898b23593c8c16976881d183f27a264f862853e298ad75ef3601190f0528f7' 154 | list remote 'ipv6 "vpn24.freifunk-ulm.de" port 1244' 155 | list remote 'ipv4 "vpn24.freifunk-ulm.de" port 1244' 156 | option float 0 157 | 158 | config peer 'fw20' 159 | option enabled 1 160 | option net 'default' 161 | option group 'backbone' 162 | option key '15187b08aa0a9ad494d77320ce176d335e185d57e270c5d361cbca2d61665d74' 163 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1420' 164 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1420' 165 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1421' 166 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1421' 167 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1422' 168 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1422' 169 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1423' 170 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1423' 171 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1424' 172 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1424' 173 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1425' 174 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1425' 175 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1426' 176 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1426' 177 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1427' 178 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1427' 179 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1428' 180 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1428' 181 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1429' 182 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1429' 183 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1430' 184 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1430' 185 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1431' 186 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1431' 187 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1432' 188 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1432' 189 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1433' 190 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1433' 191 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1434' 192 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1434' 193 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1435' 194 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1435' 195 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1436' 196 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1436' 197 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1437' 198 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1437' 199 | list remote 'ipv6 "fw20.freifunk-ulm.de" port 1438' 200 | list remote 'ipv4 "fw20.freifunk-ulm.de" port 1438' 201 | option float 0 202 | 203 | -------------------------------------------------------------------------------- /files/etc/config/firewall: -------------------------------------------------------------------------------- 1 | config defaults 2 | option syn_flood 1 3 | option input ACCEPT 4 | option output ACCEPT 5 | option forward REJECT 6 | # Uncomment this line to disable ipv6 rules 7 | # option disable_ipv6 1 8 | 9 | config zone 10 | option name lan 11 | list network 'lan' 12 | option input ACCEPT 13 | option output ACCEPT 14 | option forward ACCEPT 15 | 16 | config zone 17 | option name wan 18 | list network 'wan' 19 | list network 'wan6' 20 | option input REJECT 21 | option output ACCEPT 22 | option forward REJECT 23 | option masq 1 24 | option mtu_fix 1 25 | 26 | config forwarding 27 | option src lan 28 | option dest wan 29 | 30 | # We need to accept udp packets on port 68, 31 | # see https://dev.openwrt.org/ticket/4108 32 | config rule 33 | option name Allow-DHCP-Renew 34 | option src wan 35 | option proto udp 36 | option dest_port 68 37 | option target ACCEPT 38 | option family ipv4 39 | 40 | # Allow IPv4 ping 41 | config rule 42 | option name Allow-Ping 43 | option src wan 44 | option proto icmp 45 | option icmp_type echo-request 46 | option family ipv4 47 | option target ACCEPT 48 | 49 | config rule 50 | option name Allow-IGMP 51 | option src wan 52 | option proto igmp 53 | option family ipv4 54 | option target ACCEPT 55 | 56 | # Allow DHCPv6 replies 57 | # see https://dev.openwrt.org/ticket/10381 58 | config rule 59 | option name Allow-DHCPv6 60 | option src wan 61 | option proto udp 62 | option src_ip fe80::/10 63 | option src_port 547 64 | option dest_ip fe80::/10 65 | option dest_port 546 66 | option family ipv6 67 | option target ACCEPT 68 | 69 | config rule 70 | option name Allow-MLD 71 | option src wan 72 | option proto icmp 73 | option src_ip fe80::/10 74 | list icmp_type '130/0' 75 | list icmp_type '131/0' 76 | list icmp_type '132/0' 77 | list icmp_type '143/0' 78 | option family ipv6 79 | option target ACCEPT 80 | 81 | # Allow essential incoming IPv6 ICMP traffic 82 | config rule 83 | option name Allow-ICMPv6-Input 84 | option src wan 85 | option proto icmp 86 | list icmp_type echo-request 87 | list icmp_type echo-reply 88 | list icmp_type destination-unreachable 89 | list icmp_type packet-too-big 90 | list icmp_type time-exceeded 91 | list icmp_type bad-header 92 | list icmp_type unknown-header-type 93 | list icmp_type router-solicitation 94 | list icmp_type neighbour-solicitation 95 | list icmp_type router-advertisement 96 | list icmp_type neighbour-advertisement 97 | option limit 1000/sec 98 | option family ipv6 99 | option target ACCEPT 100 | 101 | # Allow essential forwarded IPv6 ICMP traffic 102 | config rule 103 | option name Allow-ICMPv6-Forward 104 | option src wan 105 | option dest * 106 | option proto icmp 107 | list icmp_type echo-request 108 | list icmp_type echo-reply 109 | list icmp_type destination-unreachable 110 | list icmp_type packet-too-big 111 | list icmp_type time-exceeded 112 | list icmp_type bad-header 113 | list icmp_type unknown-header-type 114 | option limit 1000/sec 115 | option family ipv6 116 | option target ACCEPT 117 | 118 | # include a file with users custom iptables rules 119 | config include 120 | option path /etc/firewall.user 121 | 122 | # 123 | #Additional rules to the LEDE default firewall entries above. 124 | # 125 | 126 | config zone 127 | option name freifunk 128 | list network freifunk 129 | list network freifunk6 130 | option input ACCEPT 131 | option output ACCEPT 132 | option forward REJECT 133 | option masq 1 134 | 135 | config forwarding 136 | option src lan 137 | option dest freifunk 138 | 139 | 140 | ### 141 | ### Example 1: forward port 20-21 to ftp-server on my lan network 142 | ### 143 | 144 | #config redirect 145 | # option src freifunk 146 | # option src_dport 20-21 147 | # option proto tcp 148 | # option dest lan 149 | # option dest_ip 192.168.1.5 150 | 151 | ### 152 | ### Example 2: forward port 445 to smb-server on my lan network 153 | ### 154 | 155 | #config redirect 156 | # option src freifunk 157 | # option src_dport 445 158 | # option proto tcp 159 | # option dest lan 160 | # option dest_ip 192.168.1.5 161 | -------------------------------------------------------------------------------- /files/etc/config/freifunk: -------------------------------------------------------------------------------- 1 | 2 | config settings 3 | option name '' 4 | option latitude '' 5 | option longitude '' 6 | option contact '' 7 | option community 'ulm' 8 | option version '2.3.1' 9 | option publish_map 'basic' 10 | option allow_access_from 'lan' 11 | option service_link '' 12 | option service_label '' 13 | option service_display_max 0 14 | option default_mesh_id 'ffulm_mesh' 15 | option mesh_on_wan '0' 16 | option community_url 'http://freifunk-ulm.de' 17 | option first_boot '1' 18 | -------------------------------------------------------------------------------- /files/etc/config/simple-radvd: -------------------------------------------------------------------------------- 1 | 2 | config interface 3 | option ifname 'br-freifunk' 4 | list prefix 'fdef:17a0:fff1:300::/64' 5 | 6 | config interface 7 | option ifname 'br-lan' 8 | list prefix 'fdef:17a0:fff1:300::/64' 9 | -------------------------------------------------------------------------------- /files/etc/config/simple-tc: -------------------------------------------------------------------------------- 1 | 2 | config interface 3 | option enabled '0' 4 | option ifname 'fastd_mesh' 5 | option limit_egress '1000' # 1000 Kbit/s 6 | option limit_ingress '5000' # 5000 Kbit/s 7 | -------------------------------------------------------------------------------- /files/etc/config/uhttpd: -------------------------------------------------------------------------------- 1 | 2 | config uhttpd freifunk 3 | list listen_http 80 4 | option home '/www/freifunk' 5 | option rfc1918_filter 1 6 | option cgi_prefix '/cgi-bin' 7 | option script_timeout 60 8 | option network_timeout 30 9 | option tcp_keepalive 1 10 | option config '_' 11 | 12 | config uhttpd lan 13 | list listen_https 443 14 | option home '/www/lan' 15 | option rfc1918_filter 1 16 | option cert '/etc/uhttpd.crt' 17 | option key '/etc/uhttpd.key' 18 | option cgi_prefix /cgi-bin 19 | option script_timeout 60 20 | option network_timeout 30 21 | option tcp_keepalive 1 22 | option config '/etc/httpd.conf' 23 | 24 | 25 | # Certificate defaults for px5g key generator 26 | config cert px5g 27 | 28 | # Validity time 29 | option days 1400 30 | 31 | # RSA key size 32 | option bits 2048 33 | 34 | # Common name 35 | option commonname 'LEDE' 36 | -------------------------------------------------------------------------------- /files/etc/crontabs/root: -------------------------------------------------------------------------------- 1 | # Check for new firmware every 6 hours 2 | 0 */6 * * * /usr/sbin/autoupdater 3 | # Publish map data 4 | */5 * * * * /usr/sbin/print_map.sh -p 5 | # Publish service data 6 | */5 * * * * /usr/sbin/print_service.sh -p 7 | # Reboot every 5 days at 04:05 8 | 5 4 */5 * * /sbin/reboot 9 | -------------------------------------------------------------------------------- /files/etc/firewall.user: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Solves MTU problem with bad ISPs 4 | iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 5 | 6 | # Clear ebtables 7 | ebtables -F 8 | ebtables -X 9 | 10 | # Drop router advertisments from this router 11 | ebtables -A OUTPUT --logical-out br-freifunk -o bat0 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type router-advertisement -j DROP 12 | ebtables -A FORWARD --logical-out br-freifunk -o bat0 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type router-advertisement -j DROP 13 | 14 | # Create chain (drop packets at end) 15 | ebtables -N MULTICAST_OUT -P DROP 16 | 17 | # Filter multicast/broadcast on bat0 into chain 18 | ebtables -A FORWARD --logical-out br-freifunk -o bat0 -d Multicast -j MULTICAST_OUT 19 | ebtables -A OUTPUT --logical-out br-freifunk -o bat0 -d Multicast -j MULTICAST_OUT 20 | ebtables -A FORWARD --logical-out br-freifunk -o bat0 -d Broadcast -j MULTICAST_OUT 21 | ebtables -A OUTPUT --logical-out br-freifunk -o bat0 -d Broadcast -j MULTICAST_OUT 22 | 23 | # Limit multicast packets 24 | ebtables -A MULTICAST_OUT --limit 100/sec 25 | 26 | # Allow DHCP requests (IPv4) 27 | ebtables -A MULTICAST_OUT -p IPv4 --ip-protocol udp --ip-sport 68 -j RETURN 28 | 29 | # Allow ICMP (IPv6) 30 | ebtables -A MULTICAST_OUT -p IPv6 --ip6-protocol ipv6-icmp -j RETURN 31 | 32 | # Allow Alfred 33 | ebtables -A MULTICAST_OUT -p IPv6 -d Multicast --ip6-destination ff02::1 --ip6-proto udp --ip6-dport 16962 -j RETURN 34 | 35 | # Allow IGMP/ICMP (IPv4) 36 | ebtables -A MULTICAST_OUT -p IPv4 --ip-protocol igmp -j RETURN 37 | ebtables -A MULTICAST_OUT -p IPv4 --ip-protocol icmp -j RETURN 38 | 39 | # Drop funny ARP packets (IPv4) 40 | ebtables -A MULTICAST_OUT -p ARP --arp-opcode Reply --arp-ip-src 0.0.0.0 -j DROP 41 | ebtables -A MULTICAST_OUT -p ARP --arp-opcode Request --arp-ip-dst 0.0.0.0 -j DROP 42 | 43 | # Allow normal ARP (IPv4) 44 | ebtables -A MULTICAST_OUT -p ARP -j RETURN 45 | -------------------------------------------------------------------------------- /files/etc/hotplug.d/iface/30-fastd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | [ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ] || exit 0 5 | 6 | uci set fastd.default.bind="any interface \"$DEVICE\"" 7 | 8 | /etc/init.d/fastd start 9 | -------------------------------------------------------------------------------- /files/etc/hotplug.d/iface/40-mesh-on-wan: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Block batman-adv packets on wifi interfaces used for wan. 4 | # Only needed to ease wifi airtime when mesh on wan is activated. 5 | 6 | [ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ] || exit 0 7 | 8 | ifnames=`ls /sys/class/net/br-wan/ | awk '/lower_wlan/ {print substr($1,7)}'` 9 | 10 | [ -n "$ifnames" ] || exit 0 11 | 12 | for ifname in $ifnames; do 13 | ebtables -A FORWARD -p 0x4305 -o $ifname -j DROP 14 | ebtables -A OUTPUT -p 0x4305 -o $ifname -j DROP 15 | done 16 | 17 | -------------------------------------------------------------------------------- /files/etc/hotplug.d/net/60-freifunk-ula: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Make sure that the ULA address is based on the 4 | # MAC address of the primary batman-adv interface. 5 | 6 | # This makes the node reachable by the MAC address 7 | # used by batman-adv and therefore the map. 8 | 9 | if [ "$INTERFACE" = "bat0" ]; then 10 | . /lib/ff_shared.sh 11 | 12 | macaddr="$(batctl neighbors | awk -F'[/ ]' '{print $7; exit;}')" 13 | prefix="$(uci get network.globals.ula_prefix)" 14 | ipaddr="$(ula_addr $prefix $macaddr)" 15 | ip a a "$ipaddr/64" dev br-freifunk 16 | fi 17 | -------------------------------------------------------------------------------- /files/etc/httpd.conf: -------------------------------------------------------------------------------- 1 | # Use root password for http login 2 | /:root:$p$root 3 | -------------------------------------------------------------------------------- /files/etc/init.d/freifunk_init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=19 4 | 5 | 6 | #allow/block access via ssh/https from lan/wan/freifunk 7 | set_access() { 8 | local src port default_target target 9 | local from=`uci -q get freifunk.@settings[0].allow_access_from` 10 | 11 | echo "(I) Freifunk: allow_access_from: '$from'" 12 | 13 | #remove existing rules 14 | for src in wan lan freifunk; do 15 | for port in 22 443; do 16 | local s="firewall.${src}${port}" 17 | uci -q delete $s 18 | done 19 | done 20 | 21 | find_default_target() { 22 | local s="$1" src="$2" name 23 | 24 | config_get name "$s" 'name' 25 | if [ "$src" == "$name" ]; then 26 | config_get default_target "$s" 'input' 27 | return 1 28 | fi 29 | } 30 | 31 | #add rule to allow/reject ssh/https access 32 | config_load firewall 33 | for src in wan lan freifunk; do 34 | default_target="" 35 | config_foreach find_default_target 'zone' $src 36 | list_contains from "$src" && target=ACCEPT || target=REJECT 37 | [ "$target" = "$default_target" ] && continue 38 | for port in 22 443; do 39 | local s="firewall.${src}${port}" 40 | uci set $s=rule 41 | uci set $s.src=$src 42 | uci set $s.dest_port=$port 43 | uci set $s.target=$target 44 | uci set $s.proto=tcp 45 | done 46 | done 47 | } 48 | 49 | random_mac() { 50 | echo -n 02; dd bs=1 count=5 if=/dev/random 2>/dev/null | hexdump -v -e '/1 ":%02x"' 51 | } 52 | 53 | # batman-adv wants unique MAC addresses for each interface 54 | set_macs() { 55 | network_set_macaddr() { 56 | local proto 57 | 58 | config_get proto "$1" "proto" 59 | 60 | if [ "$proto" = "batadv" ]; then 61 | uci set network.$1.macaddr="$(random_mac)" 62 | fi 63 | } 64 | 65 | wireless_set_macaddr() { 66 | uci set wireless.$1.macaddr="$(random_mac)" 67 | } 68 | 69 | config_load network 70 | config_foreach network_set_macaddr interface 71 | 72 | config_load wireless 73 | config_foreach wireless_set_macaddr wifi-iface 74 | } 75 | 76 | set_hostname() 77 | { 78 | local hostname="$(uci -q get system.@system[0].hostname)" 79 | local name="$(uci -q get freifunk.@settings[0].name)" 80 | 81 | #sanitize name 82 | name="$(echo -n \"$name\" | sed -e 's/[^A-Za-z0-9]//g' -e 's/^[0-9]//g')" 83 | 84 | if [ -n "$name" -a "$hostname" != "$name" ]; then 85 | uci set system.@system[0].hostname="$name" 86 | uci commit system 87 | 88 | uci set network.wan.hostname="$name" 89 | uci commit network 90 | fi 91 | } 92 | 93 | start() 94 | { 95 | exec >/tmp/freifunk_init.log 2>&1 96 | 97 | echo "(I) Freifunk: start freifunk_init" 98 | 99 | #set_macs 100 | set_access 101 | set_hostname 102 | 103 | echo "(I) Freifunk: done freifunk_init" 104 | } 105 | -------------------------------------------------------------------------------- /files/etc/sysupgrade.conf: -------------------------------------------------------------------------------- 1 | # Keep SSL keys on sysupgrade 2 | /etc/uhttpd.crt 3 | /etc/uhttpd.key 4 | 5 | # Keep SSH authorized keys on sysupgrade 6 | /etc/dropbear/authorized_keys 7 | -------------------------------------------------------------------------------- /files/lib/ff_shared.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #create an IPv6 ULA-address based on EUI-64 4 | ula_addr() 5 | { 6 | local prefix a prefix="$1" mac="$2" invert=${3:-0} 7 | 8 | if [ $invert -eq 1 ]; then 9 | # translate to local administered mac 10 | a=${mac%%:*} #cut out first hex 11 | a=$((0x$a ^ 2)) #invert second least significant bit 12 | a=$(printf '%02x\n' $a) #convert back to hex 13 | mac="$a:${mac#*:}" #reassemble mac 14 | fi 15 | 16 | mac=${mac//:/} # remove ':' 17 | mac=${mac:0:6}fffe${mac:6:6} # insert ffee 18 | mac=$(echo $mac | sed 's/..../&:/g') # insert ':' 19 | 20 | # assemble IPv6 address 21 | echo "${prefix%%::*}:${mac%?}" 22 | } 23 | -------------------------------------------------------------------------------- /files/usr/sbin/calc_speed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Calculate up/down speed and record data volume on given network interfaces. 4 | 5 | net="$1" 6 | td="$2" 7 | 8 | if [ -n "$net" -a -n "$td" ]; then 9 | bytes1="$(cat /var/${td}_data_${net} 2> /dev/null)" 10 | time1="$(date +%s -r /var/${td}_data_${net} 2> /dev/null)" 11 | 12 | bytes2="$(cat /sys/class/net/$net/statistics/${td}_bytes)" 13 | time2="$(date +%s)" 14 | 15 | # Only calculate new speed after at least one second has passed 16 | if [ "$time1" != "$time2" ]; then 17 | # Remember data volume for next time 18 | echo -n "$bytes2" > /var/${td}_data_${net} 19 | fi 20 | 21 | speed="$(expr \( $bytes2 - $bytes1 \) / \( $time2 - $time1 \) 2> /dev/null)" 22 | echo "${speed:-0}" 23 | else 24 | echo "Usage: $0 [tx|rx]" 25 | fi 26 | -------------------------------------------------------------------------------- /files/usr/sbin/print_map.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #Print out local connection data for map creation 4 | 5 | memory_usage() 6 | { 7 | meminfo=$(cat /proc/meminfo) 8 | free=$(echo "$meminfo" | awk /^MemFree:/'{print($2)}') 9 | buffers=$(echo "$meminfo" | awk /^Buffers:/'{print($2)}') 10 | cached=$(echo "$meminfo" | awk /^Cached:/'{print($2)}') 11 | total=$(echo "$meminfo" | awk /^MemTotal:/'{print($2)}') 12 | echo $free $buffers $cached $total | awk '{ printf("%f", 1 - ($1 + $2 + $3) / $4)}' 13 | } 14 | 15 | rootfs_usage() 16 | { 17 | df / | awk 'BEGIN {val=100} NR==2 {val=$5} END { printf("%.2f", val/100) }' 18 | } 19 | 20 | print_basic() { 21 | local community="$(uci -q get freifunk.@settings[0].community 2> /dev/null)" 22 | local version="$(uci -q get freifunk.@settings[0].version 2> /dev/null)" 23 | local name="$(uci -q get freifunk.@settings[0].name 2> /dev/null)" 24 | local longitude="$(uci -q get freifunk.@settings[0].longitude 2> /dev/null)" 25 | local latitude="$(uci -q get freifunk.@settings[0].latitude 2> /dev/null)" 26 | local contact="$(uci -q get freifunk.@settings[0].contact 2> /dev/null)" 27 | local autoupdater_enabled="$(uci -q get autoupdater.settings.enabled 2> /dev/null)" 28 | local autoupdater_branch="$(uci -q get autoupdater.settings.branch 2> /dev/null)" 29 | 30 | [ -n "$contact" ] && echo -n "\"contact\" : \"$contact\", " 31 | [ -n "$name" ] && echo -n "\"name\" : \"$name\", " 32 | [ -n "$version" ] && echo -n "\"firmware\" : \"ffulm-$version\", " 33 | [ -n "$community" ] && echo -n "\"community\" : \"$community\", " 34 | 35 | if [ "$autoupdater_enabled" = "1" ]; then 36 | echo -n "\"autoupdater\" : \"$autoupdater_branch\", " 37 | fi 38 | 39 | if [ -n "$longitude" -a -n "$latitude" ]; then 40 | echo -n "\"longitude\" : $longitude, " 41 | echo -n "\"latitude\" : $latitude, " 42 | fi 43 | 44 | echo -n "\"model\" : \"$(cat /tmp/sysinfo/model)\", " 45 | echo -n "\"using_gateway\" : \"$(sockread /var/run/fastd.status < /dev/null 2> /dev/null | grep established | sed 's/\(.*\)"name": "\([^"]*\)"\(.*\)established\(.*\)/\2/g')\", " 46 | echo -n "\"links\" : [" 47 | 48 | printLink() { echo -n "{ \"smac\" : \"$(cat /sys/class/net/$3/address)\", \"dmac\" : \"$1\", \"qual\" : $2 }"; } 49 | IFS=" 50 | " 51 | nd=0 52 | for entry in $(batctl neighbors -H 2> /dev/null | awk -F '[][)( \t]+' '/^[a-f0-9]/{ print($1, $3, $4) }'); do 53 | [ $nd -eq 0 ] && nd=1 || echo -n ", " 54 | IFS=" " 55 | printLink $entry 56 | done 57 | 58 | echo -n '], ' 59 | 60 | batctl translocal -H 2> /dev/null | awk -v macs="$(cat /sys/class/net/*/address)" 'BEGIN{c=0} {if (index(macs, $1) == 0){ c+=1 }} END {printf("\"clientcount\" : %d", c)}' 61 | } 62 | 63 | print_more() { 64 | echo -n "\"loadavg\" : $(uptime | awk '{print($NF)}'), " 65 | echo -n "\"uptime\" : $(awk '{print(int($1))}' /proc/uptime), " 66 | 67 | print_basic 68 | } 69 | 70 | print_all() { 71 | local prefix="$(uci -q get network.globals.ula_prefix)" 72 | echo -n "\"rootfs_usage\" : $(rootfs_usage), " 73 | echo -n "\"memory_usage\" : $(memory_usage), " 74 | echo -n "\"addresses\" : [" 75 | ip -6 address show dev br-freifunk 2> /dev/null | grep -v "$prefix" | tr '/' ' ' | awk 'BEGIN{i=0} /inet/ { if($2 !~ /^fe80/) { printf("%s\"%s\"", (i ? ", " : ""), $2); i=1; }}' 76 | echo -n "], " 77 | 78 | print_more 79 | } 80 | 81 | print() { 82 | echo -n "{" 83 | 84 | case $1 in 85 | "basic") 86 | print_basic 87 | ;; 88 | "more") 89 | print_more 90 | ;; 91 | "all") 92 | print_all 93 | ;; 94 | *) 95 | ;; 96 | esac 97 | 98 | echo -n '}' 99 | } 100 | 101 | 102 | map_level="$(uci -q get freifunk.@settings[0].publish_map 2> /dev/null)" 103 | 104 | if [ "$1" = "-p" ]; then 105 | [ $map_level = "none" ] && exit 0 106 | 107 | content="$(print $map_level)" 108 | if [ -n "$content" ]; then 109 | #make sure alfred is running 110 | pidof alfred > /dev/null || /etc/init.d/alfred start 111 | 112 | #publish content via alfred 113 | echo "$content" | alfred -s 64 114 | echo "map published" 115 | else 116 | echo "nothing published" 117 | fi 118 | else 119 | print $map_level 120 | fi 121 | -------------------------------------------------------------------------------- /files/usr/sbin/print_service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #Print a link that is displayed on other routers status page 4 | 5 | print() { 6 | local link="$(uci -q get freifunk.@settings[0].service_link)" 7 | local label="$(uci -q get freifunk.@settings[0].service_label)" 8 | if [ -n "$link" -a -n "$label" ]; then 9 | echo "{ \"link\" : \"$link\", \"label\" : \"$label\" }" 10 | fi 11 | } 12 | 13 | if [ "$1" = "-p" ]; then 14 | content="$(print)" 15 | if [ -n "$content" ]; then 16 | #make sure alfred is running 17 | pidof alfred > /dev/null || /etc/init.d/alfred start 18 | 19 | #publish content via alfred 20 | echo "$content" | alfred -s 91 21 | echo "service published" 22 | else 23 | echo "nothing published" 24 | fi 25 | else 26 | print 27 | fi 28 | -------------------------------------------------------------------------------- /files/www/freifunk/cgi-bin/data: -------------------------------------------------------------------------------- 1 | #!/usr/bin/haserl 2 | <% 3 | # CORS response 4 | echo -en "Access-Control-Allow-Origin: *\r\n" 5 | echo -en "content-type: text/plain\r\n\r\n" 6 | 7 | /usr/sbin/print_map.sh 8 | %> 9 | 10 | -------------------------------------------------------------------------------- /files/www/freifunk/cgi-bin/status: -------------------------------------------------------------------------------- 1 | #!/usr/bin/haserl 2 | <% echo -en "content-type: text/html\r\n\r\n" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | <% 10 | name="$(uci -q get freifunk.@settings[0].name)" 11 | echo -n "Freifunk${name:+ - $name}" 12 | %> 13 | 14 | 15 | 16 | 19 |
20 | 43 |
44 |
45 |

<% uci -q get freifunk.@settings[0].name | tr -d '\n' %>

46 |

Firmware Version <% uci -q get freifunk.@settings[0].version | tr -d '\n' %>

47 |
48 |
49 |
50 |
51 |

Neighboring nodes

52 |

<% (batctl neighbors -H 2> /dev/null | grep -v '^No' | cut -c -17 | sort | uniq | wc -l) %>

53 |
54 |
55 |

All nodes

56 |

<% echo -n $((`batctl transglobal -H 2> /dev/null | grep '^ [^ ]' | cut -b 39-55 | sort | uniq | wc -l`+1)) %>

57 |
58 |
59 |

Local clients

60 |

<% 61 | echo -n $(batctl translocal -H 2> /dev/null | awk -v macs="$(cat /sys/class/net/*/address)" 'BEGIN{c=0} {if (index(macs, $1) == 0){ c+=1; }} END {print(c)}') 62 | %> 63 |

64 |
65 |
66 |
67 | 68 | <% 69 | . /lib/ff_shared.sh 70 | 71 | echo '
' 72 | echo '

Neighboring nodes:

' 73 | echo '
    ' 74 | 75 | macs="$(batctl neighbors | tail -n +3 | grep -v '^No' | cut -c -17 | sort | uniq)" 76 | if [ -n "$macs" ]; then 77 | prefix="$(uci get network.globals.ula_prefix)" 78 | i=1 79 | for mac in $macs; do 80 | echo "
  • Neighboring node $i

  • " 81 | i=$((i+1)) 82 | done 83 | else 84 | echo '
  • No neighbors found.

  • ' 85 | fi 86 | 87 | echo '
' 88 | echo '
' 89 | 90 | 91 | max=$(uci -q get freifunk.@settings[0].service_display_max) 92 | if [ -n "$max" -a "$max" != "0" ]; then 93 | addr_prefix="${ula_prefix%%::*}:" 94 | 95 | echo '
' 96 | echo '

List of local offers in the free radio network:

' 97 | echo '
    ' 98 | link_list=$( 99 | printf "$(alfred -r 91 | head -$max)" | awk -F'["\\]+' -v addr_prefix="$addr_prefix" '{ if($5 == "link" && match($7, "^[][ #[:alnum:]_\/.:]{1,128}$") && $9 == "label" && match($11, "^[][ [:alnum:]_\/.:]{1,32}$") && match($7, addr_prefix "|\.ff[a-z]{0,3}")) printf("
  • %s

  • \n", $7, $11) }' 100 | ) 101 | [ -n "$link_list" ] && echo "$link_list" || echo '
  • No offers found.

  • ' 102 | echo '
' 103 | echo '
' 104 | fi 105 | %> 106 | 107 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /files/www/freifunk/index.css: -------------------------------------------------------------------------------- 1 | 2 | * { 3 | -webkit-box-sizing: border-box; 4 | -moz-box-sizing: border-box; 5 | box-sizing: border-box; 6 | } 7 | 8 | body { 9 | font: 13px verdana, arial, 'Bitstream Vera Sans', helvetica, sans-serif; 10 | margin: 0; 11 | padding: 0; 12 | line-height: 1.7em; 13 | } 14 | 15 | h1, h2, h3, h4, h5, h6, label { 16 | color: #34495e; 17 | } 18 | 19 | h2 { 20 | font-size: 1.5em; 21 | } 22 | 23 | h3 { 24 | font-size: 1.17em; 25 | } 26 | 27 | .header { 28 | color: #333; 29 | text-align: center; 30 | border-bottom: 1px solid #eee; 31 | } 32 | 33 | .header h1 { 34 | font-size: 3em; 35 | font-weight: 300; 36 | overflow: auto; 37 | padding: 0.5em 0 0.5em; 38 | } 39 | 40 | .header h2 { 41 | font-weight: 300; 42 | color: #ccc; 43 | margin-top: 1em; 44 | } 45 | 46 | .pure-g { 47 | text-align: center; 48 | font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif; 49 | display: -webkit-flex; 50 | -webkit-flex-flow: row wrap; 51 | } 52 | 53 | .pure-u-md-1-3 { 54 | letter-spacing: normal; 55 | word-spacing: normal; 56 | vertical-align: top; 57 | width: 33.3333%; 58 | overflow: auto; 59 | } 60 | 61 | .menu { 62 | padding: 0.5em 0.5em 0.5em; 63 | display: inline-block; 64 | border: 0; 65 | border-bottom: 1px solid #b7b7b7; 66 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.10); 67 | text-align: left; 68 | background: #2d3e50; 69 | top: 0; 70 | left: 0; 71 | width: 100%; 72 | } 73 | 74 | .community { 75 | text-transform: uppercase; 76 | } 77 | 78 | .menu li { 79 | list-style-type: none; 80 | } 81 | 82 | .menu li a:hover, .menu li a:focus { 83 | background: none; 84 | color: #AECFE5; 85 | } 86 | 87 | .menu .community { 88 | color: white; 89 | font-weight: 400; 90 | font-size: 120%; 91 | } 92 | 93 | .menu li a { 94 | padding: 5px 20px; 95 | } 96 | 97 | .menu a { 98 | color: #6FBEF3; 99 | border: 1px solid transparent; 100 | border-left: 0; 101 | border-right: 0; 102 | } 103 | 104 | .menu a, .menu .community { 105 | display: block; 106 | line-height: 1.5em; 107 | text-decoration: none; 108 | padding: 5px 20px; 109 | white-space: nowrap; 110 | } 111 | 112 | .menu > .community { 113 | display: inline-block; 114 | margin: 0; 115 | vertical-align: middle; 116 | } 117 | 118 | a { 119 | color: #23527c; 120 | text-decoration: none; 121 | } 122 | 123 | .menu ul { 124 | display: inline-block; 125 | vertical-align: middle; 126 | top: 0; 127 | left: 0; 128 | margin: 0; 129 | padding: 0; 130 | z-index: 1; 131 | float: right; 132 | } 133 | 134 | .menu li { 135 | display: inline-block; 136 | vertical-align: middle; 137 | } 138 | 139 | .content { 140 | max-width: 800px; 141 | margin: 0 auto 50px; 142 | line-height: 1.6em; 143 | color: #444; 144 | } 145 | 146 | .content-subhead { 147 | margin: 50px 0 20px 0; 148 | font-weight: 300; 149 | color: #888; 150 | } 151 | 152 | .login-button { 153 | background-color: #1f8dd6; 154 | color: white; 155 | padding: 0.5em 2em; 156 | border-radius: 5px; 157 | border: 0; 158 | display: inline-block; 159 | line-height: normal; 160 | white-space: nowrap; 161 | vertical-align: baseline; 162 | text-align: center; 163 | cursor: pointer; 164 | user-select: none; 165 | } 166 | -------------------------------------------------------------------------------- /files/www/freifunk/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Redirecting... 12 | 13 | 14 | -------------------------------------------------------------------------------- /files/www/lan/cgi-bin/home: -------------------------------------------------------------------------------- 1 | #!/usr/bin/haserl 2 | <% 3 | echo -en "content-type: text/plain\r\n\r\n" 4 | 5 | . /lib/functions/network.sh 6 | 7 | addr() { 8 | local addr="$(ip -$1 address show dev $2 2> /dev/null | tr '/' ' '| awk '/inet/{ printf("%s ", $2); }')" 9 | echo "${addr:--}" 10 | } 11 | 12 | default_gw() { 13 | local prefix 14 | if [ $1 -eq 6 ]; then 15 | prefix="::/0" 16 | else 17 | prefix="0/0" 18 | fi 19 | ip -$1 route list $prefix dev $2 2> /dev/null | awk '{print($3); exit(0)}' 20 | } 21 | 22 | memory_usage_percent() { 23 | meminfo=$(cat /proc/meminfo) 24 | free=$(echo "$meminfo" | awk /^MemFree:/'{print($2)}') 25 | buffers=$(echo "$meminfo" | awk /^Buffers:/'{print($2)}') 26 | cached=$(echo "$meminfo" | awk /^Cached:/'{print($2)}') 27 | total=$(echo "$meminfo" | awk /^MemTotal:/'{print($2)}') 28 | echo $free $buffers $cached $total | awk '{ printf("%u%%", 100 * (1 - ($1 + $2 + $3) / $4))}' 29 | } 30 | 31 | rootfs_usage_percent() { 32 | df / | awk '/^overlay/{print($5); exit;}' 33 | } 34 | 35 | print() { 36 | echo " option $1 '$2'" 37 | } 38 | 39 | printList() { 40 | for item in $2; do 41 | echo " list $1 '$item'" 42 | done 43 | } 44 | 45 | vpn_server() { 46 | local vpn=$(sockread /var/run/fastd.status < /dev/null 2> /dev/null | grep 'established' | sed 's/\(.*\)"name": "\([^"]*\)"\(.*\)established\(.*\)/\2/g') 47 | echo "${vpn:--}" 48 | } 49 | 50 | #get physical device by config section 51 | wan="" lan="" freifunk="" 52 | network_get_physdev wan 'wan' 53 | network_get_physdev lan 'lan' 54 | network_get_physdev freifunk 'freifunk' 55 | 56 | #include LEDE version 57 | . /etc/openwrt_release 58 | 59 | echo "package misc" 60 | echo "config data 'data'" 61 | print 'mac' "$(uci -q get network.freifunk.macaddr)" 62 | printList 'freifunk_addr4' "$(addr 4 $freifunk)" 63 | printList 'freifunk_addr6' "$(addr 6 $freifunk)" 64 | printList 'lan_addr4' "$(addr 4 $lan)" 65 | printList 'lan_addr6' "$(addr 6 $lan)" 66 | printList 'wan_addr4' "$(addr 4 $wan)" 67 | printList 'wan_addr6' "$(addr 6 $wan)" 68 | 69 | up="$(uptime)" 70 | uptime="${up%%,*}" 71 | print 'load' "${up##*:}" 72 | print 'uptime' "${uptime##*up}" 73 | print 'memory_usage' "$(memory_usage_percent)" 74 | print 'rootfs_usage' "$(rootfs_usage_percent)" 75 | print 'uname' "$(uname -s -m -r)" 76 | print 'date' "$(date)" 77 | print 'vpn_server' "$(vpn_server)" 78 | 79 | if [ -n "$(default_gw 4 $wan)" -o -n "$(default_gw 6 $wan)" ]; then 80 | print 'has_internet' 'Ja' 81 | else 82 | print 'has_internet' 'Nein' 83 | fi 84 | 85 | print 'node_count' "$((`batctl transglobal -H 2> /dev/null | grep '^ [^ ]' | cut -b 39-55 | sort | uniq | wc -l`+1))" 86 | print 'neigh_count' "$(batctl neighbors -H 2> /dev/null | cut -c -17 | sort | uniq | wc -l)" 87 | print 'firmware_version' "$(uci -q get freifunk.@settings[0].version)" 88 | print 'fastd_version' "$(fastd --version 2> /dev/null | cut -d' ' -f 2)" 89 | print 'batman_version' "$(batctl -v 2> /dev/null | awk -F '[][ \t]+' '{print($4); exit;}')" 90 | print 'openwrt_version' "$DISTRIB_RELEASE" 91 | name="$(uci -q get freifunk.@settings[0].name)" 92 | print 'name' "${name:--}" 93 | print 'model' "$(cat /tmp/sysinfo/model 2> /dev/null)" 94 | print 'freifunk_user_count' "$(batctl translocal -H 2> /dev/null | grep -c 'W')" 95 | print 'lan_user_count' "$(cat /tmp/dhcp.lan.leases 2> /dev/null | sed '/^[0-9][0-9]* .* 192/!d' | wc -l)" 96 | 97 | print 'lan_rx_speed' "$(calc_speed.sh $lan rx 2> /dev/null)" 98 | print 'lan_tx_speed' "$(calc_speed.sh $lan tx 2> /dev/null)" 99 | print 'freifunk_rx_speed' "$(calc_speed.sh $freifunk rx 2> /dev/null)" 100 | print 'freifunk_tx_speed' "$(calc_speed.sh $freifunk tx 2> /dev/null)" 101 | print 'wan_rx_speed' "$(calc_speed.sh $wan rx 2> /dev/null)" 102 | print 'wan_tx_speed' "$(calc_speed.sh $wan tx 2> /dev/null)" 103 | 104 | print 'lan_rx_data' "$(cat /var/rx_data_$lan 2> /dev/null)" 105 | print 'lan_tx_data' "$(cat /var/tx_data_$lan 2> /dev/null)" 106 | print 'freifunk_rx_data' "$(cat /var/rx_data_$freifunk 2> /dev/null)" 107 | print 'freifunk_tx_data' "$(cat /var/tx_data_$freifunk 2> /dev/null)" 108 | print 'wan_rx_data' "$(cat /var/rx_data_$wan 2> /dev/null)" 109 | print 'wan_tx_data' "$(cat /var/tx_data_$wan 2> /dev/null)" 110 | %> 111 | -------------------------------------------------------------------------------- /files/www/lan/cgi-bin/misc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/haserl 2 | <% 3 | echo -en "content-type: text/plain\r\n\r\n" 4 | 5 | case $GET_func in 6 | reboot) 7 | reboot 8 | echo "Please wait. Restart is done ..." 9 | ;; 10 | wifi_status) 11 | ubus call network.wireless status 12 | ;; 13 | wifiscan) 14 | iw dev "$GET_device" scan 2> /dev/null | grep '^BSS \|SSID\|primary channel:\|signal\|capability\|MESH ID' 15 | ;; 16 | set_config_file) 17 | file_name="$GET_name" 18 | file_data="$GET_data" 19 | 20 | if echo "$file_data" > "/etc/config/$file_name" 2> /dev/null; then 21 | echo "Settings were saved. Please restart." 22 | else 23 | echo "When saving an error has occurred. Please restart." 24 | fi 25 | ;; 26 | name) 27 | uci -q get freifunk.@settings[0].name 28 | ;; 29 | *) 30 | echo "Error: Unknown command: '$GET_func'" 31 | ;; 32 | esac 33 | %> 34 | -------------------------------------------------------------------------------- /files/www/lan/cgi-bin/network: -------------------------------------------------------------------------------- 1 | #!/usr/bin/haserl 2 | <% 3 | echo -en "content-type: text/plain\r\n\r\n" 4 | 5 | . /lib/functions.sh 6 | 7 | case "$GET_func" in 8 | get_settings) 9 | uci -qn export freifunk 10 | uci -qn export wireless 11 | uci -qn export network 12 | 13 | #get the tagged port of the switch 14 | echo "package misc" 15 | echo "config data 'data'" 16 | 17 | port="$(swconfig dev switch0 help 2> /dev/null | sed -rn 's/.*\(cpu @ ([0-9])\).*/\1/p')" 18 | echo " option tagged_port '$port'" 19 | 20 | model="$(cat /tmp/sysinfo/model | tr '[A-Z]' '[a-z]' | sed -r 's/[^a-z0-9]+/-/g;s/-$//' 2> /dev/null)" 21 | echo " option model '$model'" 22 | ;; 23 | *) 24 | echo "Error: Unknown command: '$GET_func'" 25 | ;; 26 | esac 27 | %> 28 | -------------------------------------------------------------------------------- /files/www/lan/cgi-bin/password: -------------------------------------------------------------------------------- 1 | #!/usr/bin/haserl 2 | <% 3 | echo -en "content-type: text/plain\r\n\r\n" 4 | 5 | pass1="$GET_pass1" 6 | pass2="$GET_pass2" 7 | 8 | (echo "$pass1"; sleep 1; echo "$pass2") | passwd &> /dev/null 9 | if [ $? -eq 0 ]; then 10 | #force instant password change 11 | /etc/init.d/uhttpd restart 2> /dev/null 12 | else 13 | echo "An error has occurred." 14 | fi 15 | 16 | %> 17 | -------------------------------------------------------------------------------- /files/www/lan/cgi-bin/settings: -------------------------------------------------------------------------------- 1 | #!/usr/bin/haserl 2 | <% 3 | echo -en "content-type: text/plain\r\n\r\n" 4 | 5 | . /lib/functions.sh 6 | 7 | case "$GET_func" in 8 | get_settings) 9 | uci -qn export freifunk 10 | uci -qn export autoupdater 11 | uci -qn export simple-tc 12 | uci -qn export autoupdater 13 | uci -qn export fastd 14 | 15 | ula_prefix="$(uci -q get network.globals.ula_prefix)" 16 | echo "package network" 17 | echo "config globals 'globals'" 18 | echo " option ula_prefix '$ula_prefix'" 19 | ;; 20 | *) 21 | echo "Error: Unknown command: '$GET_func'" 22 | ;; 23 | esac 24 | %> 25 | -------------------------------------------------------------------------------- /files/www/lan/cgi-bin/ssh_keys: -------------------------------------------------------------------------------- 1 | #!/usr/bin/haserl 2 | <% 3 | echo -en "content-type: text/plain\r\n\r\n" 4 | 5 | case $GET_func in 6 | get_authorized_keys) 7 | cat /etc/dropbear/authorized_keys 2> /dev/null 8 | ;; 9 | set_authorized_keys) 10 | echo "$GET_data" > /etc/dropbear/authorized_keys 2> /dev/null 11 | echo 'Update durchgeführt.' 12 | ;; 13 | *) 14 | echo "Fehler: Unbekanntes Kommando: '$GET_func'" 15 | ;; 16 | esac 17 | 18 | %> -------------------------------------------------------------------------------- /files/www/lan/cgi-bin/upgrade: -------------------------------------------------------------------------------- 1 | #!/usr/bin/haserl --upload-dir=/tmp --upload-limit=12000 2 | <% 3 | echo -en "content-type: text/plain\r\n\r\n" 4 | 5 | case "${GET_func:-$POST_func}" in 6 | apply_firmware) 7 | path="$POST_firmware" 8 | keep="$POST_keep_config" 9 | 10 | if [ ! -f "$path" ]; then 11 | echo "Error: File not found." 12 | exit 1 13 | fi 14 | 15 | if [ "$keep" = "yes" ]; then 16 | args="" 17 | else 18 | args="-n" 19 | fi 20 | 21 | echo "Start update ...." 22 | 23 | #apply OpenWrt or vendor image 24 | echo 3 > /proc/sys/vm/drop_caches 25 | sysupgrade $args $path 26 | ;; 27 | lookup_upgrade) 28 | autoupdater -c 2>&1 29 | ;; 30 | lookup_and_apply_upgrade) 31 | autoupdater -f 2>&1 32 | ;; 33 | restore_firmware) 34 | echo "All changes will be reset ..." 35 | echo y | firstboot 36 | echo "Router is restarting ..." 37 | reboot 38 | ;; 39 | *) 40 | echo "Error: Unknown command: '$GET_func'" 41 | ;; 42 | esac 43 | %> 44 | -------------------------------------------------------------------------------- /files/www/lan/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Home 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
?
16 |
?
17 |
?
18 |
?
19 |
?
20 |
?
21 |
?
22 |
?
23 |
?
24 |
?
25 |
?
26 |
?
27 |
28 | 29 |
30 | 31 |
?
32 |
??
33 |
??
34 |
?
35 |
?
36 |
37 | 38 |
39 | 40 |
?
41 |
??
42 |
??
43 |
?
44 |
?
45 |
46 | 47 |
48 | 49 |
?
50 |
??
51 |
??
52 |
?
53 |
?
54 |
55 | 56 |
57 | Software 58 |
?
59 |
?
60 |
?
61 |
?
62 |
63 | 64 | 65 | -------------------------------------------------------------------------------- /files/www/lan/home.js: -------------------------------------------------------------------------------- 1 | 2 | function formatSize(bytes) { 3 | if (typeof bytes === 'undefined' || bytes == '') { 4 | return '-'; 5 | } else if (bytes < 1000) { 6 | return bytes + ' B'; 7 | } else if (bytes < 1000*1000) { 8 | return (bytes/ 1000.0).toFixed(0) + ' K'; 9 | } else if (bytes < 1000*1000*1000) { 10 | return (bytes/1000.0/1000.0).toFixed(1) + ' M'; 11 | } else { 12 | return (bytes/1000.0/1000.0/1000.0).toFixed(2) + ' G'; 13 | } 14 | } 15 | 16 | function formatSpeed(bytes) { 17 | var fmt = formatSize(bytes); 18 | return (fmt == '-') ? '-' : (fmt + '/s'); 19 | } 20 | 21 | function init() { 22 | send('/cgi-bin/home', { }, function(data) { 23 | var obj = fromUCI(data).misc.data; 24 | for (var key in obj) { 25 | var value = obj[key]; 26 | 27 | if (key == 'stype') { 28 | continue; 29 | } 30 | 31 | // for data volume 32 | if (key.endsWith('_data')) { 33 | value = formatSize(value); 34 | } 35 | 36 | // for transfer speed 37 | if (key.endsWith('_speed')) { 38 | value = formatSpeed(value); 39 | } 40 | 41 | //for addresses 42 | if (typeof(value) == 'object') { 43 | value = '' 44 | } 45 | 46 | setText(key, value); 47 | } 48 | tr(); 49 | }); 50 | 51 | addHelp($('system'), 'tr_system_help'); 52 | addHelp($('freifunk'), 'tr_mesh_help'); 53 | addHelp($('lan'), 'tr_lan_help'); 54 | addHelp($('wan'), 'tr_wan_help'); 55 | addHelp($('software'), 'tr_software_help'); 56 | addHelp($('freifunk_user_count'), 'tr_user_count_hours_help'); 57 | addHelp($('lan_user_count'), 'tr_user_count_hours_help'); 58 | addHelp($('vpn_server'), 'tr_vpn_help'); 59 | } 60 | -------------------------------------------------------------------------------- /files/www/lan/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Freifunk 6 | 7 | 8 | 9 | 10 | 11 | 140 | 141 | 142 | 143 | 146 | 147 | 168 |
169 |

170 | 
171 | 
172 | 173 |
174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /files/www/lan/network.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Network 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /files/www/lan/password.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Password 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 | 17 |
18 |
19 | 20 |
21 |
22 |
23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /files/www/lan/password.js: -------------------------------------------------------------------------------- 1 | 2 | function init() { 3 | $('p1').focus(); 4 | tr(); 5 | } 6 | 7 | function apply() 8 | { 9 | p1 = $('p1').value; 10 | p2 = $('p2').value; 11 | 12 | $('p1').value = ''; 13 | $('p2').value = ''; 14 | 15 | if (p1 != p2) { 16 | setText('msg', tr('tr_password_different')); 17 | return; 18 | } else { 19 | setText('msg', tr('tr_password_changed')); 20 | } 21 | 22 | send('/cgi-bin/password', { func : 'set_password', pass1 : p1, pass2 : p2 }, function(data) { 23 | setText('msg', data); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /files/www/lan/settings.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Settings 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | 24 | 25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /files/www/lan/settings.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * All required uci packages are stored variable uci. 4 | * The GUI code displayes and manipulated this variable. 5 | */ 6 | var uci = {}; 7 | var gid = 0; 8 | 9 | 10 | function init() 11 | { 12 | send('/cgi-bin/settings', { func : 'get_settings' }, function(data) { 13 | uci = fromUCI(data); 14 | rebuild_general(); 15 | adv_apply(); 16 | tr(); 17 | }); 18 | } 19 | 20 | function updateFrom(src) 21 | { 22 | var obj = {}; 23 | collect_inputs(src, obj); 24 | for (var name in obj) 25 | { 26 | var value = obj[name]; 27 | var path = name.split('#'); 28 | 29 | var pkg = path[0]; 30 | var sec = path[1]; 31 | var opt = path[2]; 32 | 33 | uci[pkg].pchanged = true; 34 | uci[pkg][sec][opt] = value 35 | } 36 | } 37 | 38 | function getChangeModeAction(ifname) 39 | { 40 | return function(e) { 41 | var src = (e.target || e.srcElement); 42 | var mode = (src.data || src.value); 43 | delNetSection(ifname); 44 | addNetSection(ifname, mode); 45 | }; 46 | } 47 | 48 | function appendSetting(p, path, value, mode) 49 | { 50 | var id = path.join('#'); 51 | var b; 52 | var cfg = path[0] 53 | var name = path[path.length-1]; 54 | switch (name) 55 | { 56 | case 'latitude': 57 | b = append_input(p, 'tr_latitude', id, value); 58 | b.lastChild.placeholder = '52.xxx'; 59 | addInputCheck(b.lastChild, /^$|^[1-9]\d{0,2}\.\d{1,8}$/, 'tr_invalid_gps'); 60 | addHelp(b, 'tr_gps_help'); 61 | break; 62 | case 'longitude': 63 | b = append_input(p, 'tr_longitude', id, value); 64 | b.lastChild.placeholder = '8.xxx'; 65 | addInputCheck(b.lastChild, /^$|^[1-9]\d{0,2}\.\d{1,8}$/, 'tr_invalid_gps'); 66 | addHelp(b, 'tr_gps_help'); 67 | break; 68 | case 'name': 69 | b = append_input(p, 'tr_node_name', id, value); 70 | b.lastChild.placeholder = 'MyRouter'; 71 | addInputCheck(b.lastChild, /^$|^[\-\^'\w\.\:\[\]\(\)\/ &@\+\u0080-\u00FF]{0,32}$/, 'tr_invalid_input'); 72 | addHelp(b, 'tr_node_name_help'); 73 | break; 74 | case 'contact': 75 | b = append_input(p, 'tr_contact_details', id, value); 76 | b.lastChild.placeholder = 'info@example.com'; 77 | addInputCheck(b.lastChild, /^$|^[\-\^'\w\.\:\[\]\(\)\/ &@\+\u0080-\u00FF]{0,50}$/, 'tr_invalid_input'); 78 | addHelp(b, 'tr_contact_help'); 79 | break; 80 | case 'community_url': 81 | b = append_input(p, 'tr_community_site', id, value); 82 | b.lastChild.placeholder = 'http://example.de'; 83 | b.classList.add('adv_hide'); 84 | addInputCheck(b.lastChild, /^$|^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/, 'Ung\xfcltige URL.'); 85 | addHelp(b, 'tr_website_help'); 86 | break; 87 | case 'enabled': 88 | if (cfg == 'autoupdater') { 89 | b = append_radio(p, 'tr_autoupdater', id, value, [['tr_on', '1'], ['tr_off', '0']]); 90 | addHelp(b, 'tr_autoupdater_help'); 91 | } 92 | if (cfg == 'simple-tc') { 93 | b = append_radio(p, 'tr_bandwidth_ctl', id, value, [['tr_on', '1'], ['tr_off', '0']]); 94 | addHelp(b, 'tr_bandwidth_control_help'); 95 | } 96 | if (cfg == 'fastd') { 97 | b = append_radio(p, 'tr_vpn', id, value, [['tr_on', '1'], ['tr_off', '0']]); 98 | addHelp(b, 'tr_fastd_help'); 99 | b.classList.add('adv_hide'); 100 | } 101 | break; 102 | case 'publish_map': 103 | b = append_radio(p, 'tr_contribute_map', id, value, [['tr_none', 'none'], ['tr_basic', 'basic'], ['tr_more', 'more'], ['tr_all', 'all']]); 104 | addHelp(b, 'tr_contribute_map_help'); 105 | break; 106 | case 'limit_egress': 107 | b = append_input(p, 'tr_freifunk_upload', id, value); 108 | addInputCheck(b.lastChild, /^\d+$/, 'tr_invalid_input'); 109 | addHelp(b, 'tr_max_upload_help'); 110 | break; 111 | case 'limit_ingress': 112 | b = append_input(p, 'tr_freifunk_download', id, value); 113 | addInputCheck(b.lastChild, /^\d+$/, 'tr_invalid_input'); 114 | addHelp(b, 'tr_max_download_help'); 115 | break; 116 | case 'allow_access_from': 117 | b = append_check(p, 'tr_access', id, split(value), [['WAN','wan'], ['LAN','lan'], ['Freifunk','freifunk']]); 118 | addHelp(b, 'tr_access_help'); 119 | break; 120 | case 'service_link': 121 | var ula_prefix = uci['network']['globals']['ula_prefix']; 122 | var addr_prefix = ula_prefix.replace(/:\/[0-9]+$/,''); //cut off ':/64' 123 | var regexp = new RegExp('^$|((?=.*'+addr_prefix+'|.*\.ff[a-z]{0,3})(?=^.{0,128}$))'); 124 | 125 | b = append_input(p, 'tr_service_link', id, value); 126 | b.lastChild.placeholder = 'http://['+addr_prefix+':1]/index.html'; 127 | addInputCheck(b.lastChild, regexp, 'tr_invalid_input'); 128 | addHelp(b, 'tr_external_ref_help'); 129 | break; 130 | case 'service_label': 131 | b = append_input(p, 'tr_service_name', id, value); 132 | b.lastChild.placeholder = 'MyWebseite'; 133 | addInputCheck(b.lastChild, /^$|^[\[\]\(\) \w&\/.:\u0080-\u00FF]{0,32}$/, 'tr_invalid_input'); 134 | addHelp(b, 'tr_service_name_help'); 135 | break; 136 | case 'service_display_max': 137 | b = append_input(p, 'tr_max_entries', id, value); 138 | addInputCheck(b.lastChild, /^\d+$/, 'tr_invalid_input'); 139 | addHelp(b, 'tr_max_entries_help'); 140 | break; 141 | case 'community': 142 | b = append_input(p, 'tr_community', id, value); 143 | b.classList.add('adv_hide'); 144 | addInputCheck(b.lastChild, /^[a-z0-9_\-]{3,30}$/, 'tr_invalid_input'); 145 | addHelp(b, 'tr_community_help'); 146 | break; 147 | default: 148 | return; 149 | } 150 | 151 | b.id = id; //needed for updateFrom 152 | b.onchange = function() { 153 | updateFrom(b); 154 | }; 155 | 156 | return b; 157 | } 158 | 159 | function rebuild_general() 160 | { 161 | var gfs = $('general'); 162 | var rfs = $('resource'); 163 | var tfs = $('traffic'); 164 | 165 | removeChilds(gfs); 166 | removeChilds(rfs); 167 | removeChilds(tfs); 168 | 169 | if ('freifunk' in uci) { 170 | var f = uci.freifunk; 171 | var i = firstSectionID(f, 'settings'); 172 | appendSetting(gfs, ['freifunk', i, 'name'], f[i]['name']); 173 | appendSetting(gfs, ['freifunk', i, 'latitude'], f[i]['latitude']); 174 | appendSetting(gfs, ['freifunk', i, 'longitude'], f[i]['longitude']); 175 | appendSetting(gfs, ['freifunk', i, 'contact'], f[i]['contact']); 176 | appendSetting(rfs, ['freifunk', i, 'community_url'], f[i]['community_url']); 177 | appendSetting(rfs, ['freifunk', i, 'community'], f[i]['community']); 178 | appendSetting(gfs, ['freifunk', i, 'publish_map'], f[i]['publish_map']); 179 | appendSetting(gfs, ['freifunk', i, 'allow_access_from'], f[i]['allow_access_from']); 180 | appendSetting(rfs, ['freifunk', i, 'service_label'], f[i]['service_label']); 181 | appendSetting(rfs, ['freifunk', i, 'service_link'], f[i]['service_link']); 182 | appendSetting(rfs, ['freifunk', i, 'service_display_max'], f[i]['service_display_max']); 183 | } 184 | 185 | if ('autoupdater' in uci) { 186 | var a = uci.autoupdater; 187 | var i = firstSectionID(a, 'autoupdater'); 188 | appendSetting(gfs, ['autoupdater', i, 'enabled'], a[i]['enabled']); 189 | } 190 | 191 | if ('simple-tc' in uci) { 192 | var t = uci['simple-tc']; 193 | var i = firstSectionID(t, 'interface'); 194 | appendSetting(tfs, ['simple-tc', i, 'enabled'], t[i]['enabled']); 195 | appendSetting(tfs, ['simple-tc', i, 'limit_ingress'], t[i]['limit_ingress']); 196 | appendSetting(tfs, ['simple-tc', i, 'limit_egress'], t[i]['limit_egress']); 197 | } 198 | 199 | if ('fastd' in uci) { 200 | var a = uci.fastd; 201 | var i = firstSectionID(a, 'fastd'); 202 | appendSetting(gfs, ['fastd', i, 'enabled'], a[i]['enabled']); 203 | } 204 | } 205 | 206 | function save_data() 207 | { 208 | for (var name in uci) 209 | { 210 | var obj = uci[name]; 211 | if (!obj.pchanged) 212 | continue; 213 | var data = toUCI(obj); 214 | send('/cgi-bin/misc', { func : 'set_config_file', name : name, data : data }, 215 | function(data) { 216 | $('msg').textContent = data; 217 | $('msg').focus(); 218 | init(); 219 | } 220 | ); 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /files/www/lan/shared.js: -------------------------------------------------------------------------------- 1 | 2 | function $(id) { return document.getElementById(id); } 3 | function show(e) { e.style.display = 'block'; } 4 | function hide(e) { e.style.display = 'none'; } 5 | function setText(id, txt) { $(id).innerHTML = txt; } 6 | function inArray(item, array) { return array.indexOf(item) != -1; } 7 | 8 | function split(str) 9 | { 10 | if (typeof str != 'string') { 11 | return []; 12 | } 13 | var a = str.match(/[^\s]+/g); 14 | return (a ? a : []); 15 | } 16 | 17 | function uniq(arr) 18 | { 19 | var obj = {}; 20 | for (var i in arr) obj[arr[i]] = 0; 21 | return Object.keys(obj); 22 | } 23 | 24 | //remove an item from a string list 25 | function removeItem(str, item) 26 | { 27 | var array = split(str); 28 | for (var i in array) { 29 | if (array[i] === item) { 30 | array.splice(i, 1); 31 | } 32 | } 33 | return array.join(' '); 34 | } 35 | 36 | function addItem(str, item) 37 | { 38 | var array = split(str); 39 | for (var i in array) { 40 | if (array[i] === item) { 41 | return str; 42 | } 43 | } 44 | array.push(item); 45 | return array.sort().join(' '); 46 | } 47 | 48 | function replaceItem(str, old_item, new_item) 49 | { 50 | var array = split(str); 51 | for (var i in array) { 52 | if (array[i] == old_item) { 53 | array[i] = new_item; 54 | } 55 | } 56 | return array.join(' '); 57 | } 58 | 59 | function addHelp(elem, text) { 60 | var help = $('help'); 61 | 62 | if (help) { 63 | elem.onmouseover = function(e) { 64 | help.style.top = (e.clientY-20)+'px'; 65 | help.style.left = (e.clientX+80)+'px'; 66 | help.textContent = tr(text); 67 | show(help); 68 | }; 69 | 70 | elem.onmouseout = function() { 71 | help.textContent = ''; 72 | hide(help); 73 | }; 74 | } 75 | } 76 | 77 | //to config file syntax 78 | function toUCI(pkg_obj) 79 | { 80 | var str = '\n'; 81 | for (var sid in pkg_obj) 82 | { 83 | if (sid == 'pchanged') { 84 | continue; 85 | } 86 | 87 | var options = pkg_obj[sid]; 88 | var sname = (sid.substring(0, 3) != 'cfg') ? (' \''+sid+'\'') : ''; 89 | str += 'config '+options.stype+sname+'\n'; 90 | for (var oname in options) { 91 | if (oname == 'stype'){ 92 | continue; 93 | } 94 | var value = options[oname]; 95 | if (typeof value == 'object') { 96 | for (var i in value) 97 | str += ' list '+oname+' \''+value[i]+'\'\n'; 98 | } 99 | else 100 | str += ' option '+oname+' \''+value+'\'\n'; 101 | } 102 | str += '\n'; 103 | } 104 | return str; 105 | } 106 | 107 | // parses output from one or multiple 108 | // calls like 'uci -qn export foo' 109 | function fromUCI(pkgs_str) 110 | { 111 | var pkg_objs = {}; 112 | var pkg; 113 | var cfg; 114 | 115 | var lines = pkgs_str.split('\n'); 116 | for (var i = 0; i < lines.length; ++i) { 117 | var line = lines[i]; 118 | var items = split(line); 119 | 120 | if (items.length < 2) { 121 | continue; 122 | } 123 | 124 | switch(items[0]) 125 | { 126 | case 'package': 127 | pkg = { pchanged : false }; 128 | pkg_objs[items[1]] = pkg; 129 | break; 130 | case 'config': 131 | var val = (items.length == 3) ? line.match(/'(.*)'/)[1] : ('cfg'+(++gid)); 132 | cfg = { stype : items[1] }; 133 | pkg[val] = cfg; 134 | break; 135 | case 'option': 136 | var val = line.match(/'(.*)'/)[1]; 137 | cfg[items[1]] = val; 138 | break; 139 | case 'list': 140 | var val = line.match(/'(.*)'/)[1]; 141 | if (!(items[1] in cfg)) cfg[items[1]] = []; 142 | cfg[items[1]].push(val); 143 | break; 144 | } 145 | } 146 | return pkg_objs; 147 | } 148 | 149 | function firstSectionID(obj, stype) 150 | { 151 | for (var id in obj) { 152 | if (obj[id].stype == stype) { 153 | return id; 154 | } 155 | } 156 | } 157 | 158 | function config_foreach(objs, stype, func) 159 | { 160 | for (var key in objs) { 161 | var obj = objs[key]; 162 | if ((obj['stype'] == stype || stype == '*') && func(key, obj)) { 163 | return true; 164 | } 165 | } 166 | return false; 167 | } 168 | 169 | function config_find(objs, mobj) 170 | { 171 | for (var key in objs) { 172 | var obj = objs[key]; 173 | var found = true; 174 | for (mkey in mobj) { 175 | if (obj[mkey] != mobj[mkey]) { 176 | found = false; 177 | break; 178 | } 179 | } 180 | if (found) 181 | return obj; 182 | } 183 | return null; 184 | } 185 | 186 | function params(obj) 187 | { 188 | var str = ''; 189 | for (var key in obj) { 190 | if (str.length) str += '&'; 191 | else str += '?'; 192 | str += encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]); 193 | } 194 | return str.replace(/%20/g, '+'); 195 | } 196 | 197 | function send(url, obj, func) 198 | { 199 | url += params(obj); 200 | jx.load(url, func, 'text'); 201 | } 202 | 203 | function onDesc(e, tag, func) 204 | { 205 | for (var i = 0; i < e.childNodes.length; ++i) { 206 | var c = e.childNodes[i]; 207 | if (c.tagName == tag && func(c) == false) return; 208 | onDesc(c, tag, func); 209 | } 210 | } 211 | 212 | function onChilds(e, tag, func) 213 | { 214 | for (var i = 0; i < e.childNodes.length; ++i) { 215 | var c = e.childNodes[i]; 216 | if (c.tagName == tag && func(c) == false) return; 217 | } 218 | } 219 | 220 | function onParents(e, tag, func) 221 | { 222 | while (e != document) { 223 | e = e.parentNode; 224 | if (e.tagName == tag && func(e) == false) return; 225 | } 226 | } 227 | 228 | function removeChilds(p) 229 | { 230 | while (p.hasChildNodes()) 231 | p.removeChild(p.firstChild); 232 | } 233 | 234 | function checkName(name) 235 | { 236 | if (/[\w_]{2,12}/.test(name)) 237 | return true; 238 | 239 | alert(tr(tr_invalid_name) + " " + name); 240 | return false; 241 | } 242 | 243 | //prepend input check 244 | function addInputCheck(input, regex, msg) 245 | { 246 | var prev_value = input.value; 247 | var prev_onchange = input.onchange; 248 | input.onchange = function(e) { 249 | if (regex.test(input.value)) { 250 | if (prev_onchange) 251 | prev_onchange(e); 252 | return; 253 | } 254 | alert(tr(msg)); 255 | input.value = prev_value; 256 | e.stopPropagation(); 257 | }; 258 | } 259 | 260 | function collect_inputs(p, obj) 261 | { 262 | if (p.tagName == 'SELECT') 263 | obj[p.name] = p.value; 264 | if (p.tagName == 'INPUT') 265 | if (p.type == 'text' || p.type == 'password' || (p.type == 'radio' && p.checked)) 266 | obj[p.name] = p.value 267 | else if (p.type == 'checkbox' && p.checked) 268 | { 269 | var v = obj[p.name]; 270 | v = (typeof v == 'undefined') ? (p.data || p.value) : (v + ' ' + (p.data || p.value)); 271 | obj[p.name] = v; 272 | } 273 | 274 | for (var i = 0; i < p.childNodes.length; ++i) 275 | collect_inputs(p.childNodes[i], obj); 276 | } 277 | 278 | // Set text and optional translation class id 279 | function opt_tr(e, value) { 280 | e.textContent = value; 281 | if (value.startsWith('tr_')) { 282 | e.classList.add(value); 283 | } 284 | } 285 | 286 | function append(parent, tag, id) 287 | { 288 | var e = document.createElement(tag); 289 | if (id) e.id = id; 290 | parent.appendChild(e); 291 | return e; 292 | } 293 | 294 | function append_section(parent, title, id) 295 | { 296 | var fs = append(parent, 'fieldset'); 297 | var lg = append(fs, 'legend'); 298 | opt_tr(lg, title); 299 | 300 | if (id) fs.id = id; 301 | return fs; 302 | } 303 | 304 | function append_button(parent, text, onclick) 305 | { 306 | var button = append(parent, 'button'); 307 | button.type = 'button'; 308 | button.onclick = onclick; 309 | opt_tr(button, text); 310 | return button; 311 | } 312 | 313 | function append_label(parent, title, value) 314 | { 315 | var div = append(parent, 'div'); 316 | var label = append(div, 'label'); 317 | var span = append(div, 'span'); 318 | 319 | opt_tr(label, title); 320 | opt_tr(span, value); 321 | 322 | return div; 323 | } 324 | 325 | /* 326 | 327 | */ 328 | function append_options(parent, name, selected, choices) 329 | { 330 | var select = append(parent, 'select'); 331 | select.style.minWidth = '5em'; 332 | select.name = name; 333 | for (var i in choices) 334 | { 335 | var s = (typeof choices[i] != 'object'); 336 | var choice_text = '' + (s ? choices[i] : choices[i][0]); 337 | var choice_value = '' + (s ? choices[i] : choices[i][1]); 338 | 339 | var option = append(select, 'option'); 340 | option.value = choice_value; 341 | option.selected = (choice_value == selected) ? 'selected' : ''; 342 | opt_tr(option, choice_text); 343 | } 344 | return select; 345 | } 346 | 347 | function append_selection(parent, title, name, selected, choices) 348 | { 349 | var p = append(parent, 'div'); 350 | var label = append(p, 'label'); 351 | 352 | p.className = 'select_option'; 353 | opt_tr(label, title); 354 | 355 | append_options(p, name, selected, choices); 356 | return p; 357 | } 358 | 359 | // Append an input field. 360 | // E.g. append_input(parent, 'Name', 'name_string', 'MyName') 361 | function append_input(parent, title, name, value) 362 | { 363 | var div = append(parent, 'div'); 364 | var label = append(div, 'label'); 365 | var input = append(div, 'input'); 366 | 367 | opt_tr(label, title); 368 | 369 | input.value = (typeof value == 'undefined') ? '' : value; 370 | input.name = name; 371 | input.type = 'text'; 372 | 373 | return div; 374 | } 375 | 376 | // Append a radio field. 377 | // E.g. append_radio(parent, 'Enabled', 'enabled', 0, [['Yes', 1], ['No', 0]) 378 | function append_radio(parent, title, name, selected, choices) { 379 | return _selection('radio', parent, title, name, [selected], choices); 380 | } 381 | 382 | // Append a checkbox field. 383 | // E.g. append_check(parent, 'Enabled', 'enabled', ['grass'], [['Grass', 'grass'], ['Butter', 'butter']]) 384 | function append_check(parent, title, name, selected, choices) { 385 | return _selection('checkbox', parent, title, name, selected, choices); 386 | } 387 | 388 | function _selection(type, parent, title, name, selected, choices) 389 | { 390 | var p = append(parent, 'div'); 391 | var label = append(p, 'label'); 392 | var span = append(p, 'span'); 393 | 394 | p.className = 'radio_option'; 395 | opt_tr(label, title); 396 | 397 | for (var i in choices) { 398 | var s = (typeof choices[i] == 'string'); 399 | var choice_text = '' + (s ? choices[i] : choices[i][0]); 400 | var choice_value = '' + (s ? choices[i] : choices[i][1]); 401 | var choice_help = s ? undefined : choices[i][2]; 402 | 403 | var div = append(span, 'div'); 404 | var input = append(div, 'input'); 405 | var label = append(div, 'label'); 406 | 407 | input.name = name; 408 | input.value = choice_value; 409 | input.data = choice_value; //for IE :-( 410 | input.type = type; 411 | 412 | if (inArray(choice_value, selected)) { 413 | input.checked = 'checked' 414 | } 415 | 416 | opt_tr(label, choice_text); 417 | 418 | if (choice_text == '_') { 419 | hide(div); 420 | } 421 | 422 | if (choice_help) { 423 | addHelp(label, choice_help); 424 | } 425 | } 426 | return p; 427 | } 428 | 429 | //from jx_compressed.js 430 | jx={getHTTPObject:function(){var A=false;if (typeof ActiveXObject!='undefined'){try{A=new ActiveXObject('Msxml2.XMLHTTP')}catch(C){try{A=new ActiveXObject('Microsoft.XMLHTTP')}catch(B){A=false}}}else{if (window.XMLHttpRequest){try{A=new XMLHttpRequest()}catch(C){A=false}}}return A},load:function(url,callback,format){var http=this.init();if (!http||!url){return }if (!format){var format='text'}format=format.toLowerCase();var now='uid='+new Date().getTime();url+=(url.indexOf('?')+1)?'&':'?';url+=now;http.open('GET',url,true);http.onreadystatechange=function(){if (http.readyState==4){if (http.status==200){var result='';if (http.responseText){result=http.responseText}if (format.charAt(0)=='j'){result=result.replace(/[\n\r]/g,'');result=eval('('+result+')')}if (callback){callback(result)}}else{alert(http.statusText)}}};http.send(null)},init:function(){return this.getHTTPObject()}} 431 | -------------------------------------------------------------------------------- /files/www/lan/ssh_keys.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SSH Keys 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /files/www/lan/ssh_keys.js: -------------------------------------------------------------------------------- 1 | 2 | function init() { 3 | send('/cgi-bin/ssh_keys', { func : 'get_authorized_keys' }, function(reply) { 4 | $('ssh_keys').value = reply; 5 | verify_keys(); 6 | }); 7 | 8 | $('ssh_keys_submit_button').onclick = function() { 9 | var keys = $('ssh_keys').value; 10 | send("/cgi-bin/ssh_keys", { func : 'set_authorized_keys', data: keys }, function(reply) { 11 | setText('msg', reply); 12 | }); 13 | } 14 | 15 | tr(); 16 | } 17 | 18 | function verify_keys() { 19 | var regex = /^(ssh-rsa [\w\/+=]{60,} [\w@.=]+[\n]*)*$/; 20 | var keys = $('ssh_keys').value; 21 | $('ssh_keys_submit_button').disabled = keys.match(regex) ? '' : 'disabled'; 22 | } 23 | -------------------------------------------------------------------------------- /files/www/lan/style.css: -------------------------------------------------------------------------------- 1 | 2 | /* common */ 3 | 4 | * { margin: 0; padding: 0; } 5 | 6 | a { text-decoration: none; } 7 | 8 | li { list-style-type: none; } 9 | 10 | html { 11 | font: 90%/1.3 arial,sans-serif; 12 | background: #fafafa; 13 | } 14 | 15 | body { 16 | font: normal 16px verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif; 17 | color: #34495e; 18 | } 19 | 20 | /* specific */ 21 | 22 | .mac { 23 | color: #0033CC; 24 | cursor: help; 25 | } 26 | 27 | .adv_hide { 28 | display: none 29 | } 30 | 31 | #nds_files label { 32 | width: 18em; 33 | } 34 | 35 | #nds_macs { 36 | margin-bottom: 2em; 37 | } 38 | 39 | #wifiscan table { 40 | text-align: center; 41 | } 42 | 43 | #wifiscan_table { 44 | border: none; 45 | white-space: nowrap; 46 | } 47 | 48 | #wifiscan_table td { 49 | padding: 2px 10px; 50 | } 51 | 52 | #wifiscan td:nth-of-type(1) { 53 | text-align: left; 54 | } 55 | 56 | #help { 57 | padding: 5px; 58 | height: 0px; 59 | position: absolute; 60 | min-height: 50px; 61 | background-color: #f2f2f2; 62 | display:none; 63 | border: 2px dotted grey; 64 | } 65 | 66 | #msg { 67 | margin-left: 0.5em; 68 | } 69 | 70 | /* forms */ 71 | 72 | legend { 73 | color: #0b77b7; 74 | font-size: 1.2em; 75 | } 76 | 77 | label { 78 | float: left; 79 | width: 12em; 80 | text-align: right; 81 | margin-right: 1em; 82 | white-space: nowrap; 83 | } 84 | 85 | fieldset { 86 | border: 1px solid #ddd; 87 | padding: 0.5em; 88 | margin: 0.5em; 89 | width: 90%; 90 | max-width: 38em; 91 | } 92 | 93 | fieldset fieldset { 94 | width: auto; 95 | } 96 | 97 | fieldset * { 98 | padding: 0.1em 0; 99 | clear: both; 100 | } 101 | 102 | fieldset div > * { 103 | display: inline-block; 104 | vertical-align: middle; 105 | } 106 | 107 | fieldset div label { 108 | margin-left: 0.1em; 109 | } 110 | 111 | input { 112 | padding: 0.15em; 113 | width: 15em; 114 | border: 1px solid #ddd; 115 | background: #fafafa; 116 | font: bold 0.95em arial, sans-serif; 117 | -moz-border-radius: 0.4em; 118 | -khtml-border-radius: 0.4em; 119 | } 120 | 121 | input[type='radio'], input[type='checkbox'] { 122 | margin-right: 0.3em; 123 | } 124 | 125 | input:hover, input:focus { 126 | border-color: #c5c5c5; 127 | background: #f6f6f6; 128 | } 129 | 130 | select { 131 | min-width: 4em; 132 | } 133 | 134 | option { 135 | padding-right: 1em; 136 | } 137 | 138 | button { 139 | border: 1px solid #888; 140 | border-radius: 4px; 141 | 142 | font-size: 16px; 143 | font-weight: bold; 144 | text-align: center; 145 | 146 | text-shadow: 1px 1px 0 rgba(255,255,255,.67); 147 | line-height: 2; 148 | padding: 0 1em; 149 | height: 2em; 150 | box-shadow:1px 1px 0 rgba(255,255,255,.5) inset, -1px -1px 0 rgba(255,255,255,.5) inset; 151 | background-color: rgb(179, 208, 230); 152 | 153 | -moz-user-select: none; 154 | -webkit-user-select: none; 155 | 156 | background-image: -moz-linear-gradient( 157 | top, rgba(255,255,255,.75), 158 | rgba(255,255,255,.33) 50%, 159 | transparent 50%, 160 | transparent 100% 161 | ); 162 | 163 | background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, 164 | from(rgba(255,255,255,.75)), 165 | color-stop(0.5, rgba(255,255,255,.33)), 166 | color-stop(0.5, transparent), 167 | to(transparent) 168 | ); 169 | } 170 | 171 | #body > button { 172 | margin: 0.5em; 173 | } 174 | 175 | .radio_option div { 176 | float: left; 177 | white-space: nowrap; 178 | clear: none; 179 | } 180 | 181 | .radio_option div label, .radio_option div input { 182 | vertical-align: middle; 183 | display: inline; 184 | float: none; 185 | width: auto; 186 | background: none; 187 | border: none; 188 | } 189 | 190 | .select_option label { 191 | font-size: 1em; 192 | } 193 | 194 | /* navigation */ 195 | 196 | #globalnav { 197 | list-style-type: none; 198 | margin: 0; 199 | padding: 0; 200 | overflow: hidden; 201 | background-color: #333; 202 | border-bottom: 1px solid #b7b7b7; 203 | box-shadow: 0 1px 1px rgba(0,0,0, 0.10); 204 | } 205 | 206 | #globalnav li { 207 | float: left; 208 | } 209 | 210 | #globalnav li a { 211 | display: inline-block; 212 | color: #f2f2f2; 213 | text-align: center; 214 | padding: 14px 16px; 215 | text-decoration: none; 216 | transition: 0.3s; 217 | font-size: 17px; 218 | } 219 | 220 | #globalnav fieldset > div { 221 | margin: 0.3em 0; 222 | } 223 | 224 | #globalnav li select { 225 | margin: 0.6em; 226 | } 227 | 228 | #globalnav li a:hover { 229 | background-color: #555; 230 | } 231 | 232 | #globalnav li.icon { 233 | display: none; 234 | } 235 | 236 | @media screen and (max-width:680px) { 237 | #globalnav li:not(:first-child) { 238 | display: none; 239 | } 240 | 241 | #globalnav li.icon { 242 | float: right; 243 | display: inline-block; 244 | } 245 | 246 | #globalnav.responsive { 247 | position: relative; 248 | } 249 | 250 | #globalnav.responsive li.icon { 251 | position: absolute; 252 | right: 0; 253 | top: 0; 254 | } 255 | 256 | #globalnav.responsive li { 257 | float: none; 258 | display: inline; 259 | } 260 | 261 | #globalnav.responsive li a { 262 | display: block; 263 | text-align: left; 264 | } 265 | } 266 | 267 | @media screen and (max-width: 600px) { 268 | fieldset div > label { 269 | width: auto; 270 | font-style: italic; 271 | } 272 | fieldset div > span { 273 | float: right; 274 | } 275 | } 276 | 277 | #footer img { 278 | width: 100%; 279 | } 280 | -------------------------------------------------------------------------------- /files/www/lan/translations.js: -------------------------------------------------------------------------------- 1 | 2 | var translations = { 3 | en: { 4 | tr_home: 'Home', 5 | tr_settings: 'Settings', 6 | tr_network: 'Network', 7 | tr_wifi_scan: 'WLAN-Scan', 8 | tr_upgrade: 'Upgrade', 9 | tr_upgrade_in_progress: 'Upgrade in progress!', 10 | tr_password: 'Password', 11 | tr_state: 'State:', 12 | tr_restart: 'Restart', 13 | tr_logout: 'Logout', 14 | tr_extended_on: 'Extended: On', 15 | tr_extended_off: 'Extended: Off', 16 | tr_general_settings: 'General Settings', 17 | tr_announce: 'Announce contents', 18 | tr_bandwidth_ctl: 'Bandwidth Control', 19 | tr_bandwidth_help: 'The internet bandwidth on the WAN used for the free wireless network can be limited here.', 20 | tr_ssh_keys_help: 'Manage the list of authorized keys for SSH access (/etc/dropbear/authorized_keys).', 21 | tr_ssh_keys: 'SSH Keys', 22 | tr_save: 'Save', 23 | tr_yes: 'Yes', 24 | tr_no: 'No', 25 | tr_disabled: 'Disabled', 26 | tr_on: 'On', 27 | tr_off: 'Off', 28 | tr_none: 'None', 29 | tr_basic: 'Basic', 30 | tr_more: 'More', 31 | tr_all: 'All', 32 | tr_lan_help: 'LAN: Enables a private, password-protected Wi-Fi network with access to its own Internet connection.', 33 | tr_freifunk_help: 'Freifunk: The Wi-Fi access to the free wireless network.', 34 | tr_mesh_help: 'Mesh: The Wi-Fi network which routers use to communicate with each other', 35 | tr_wan_help: 'WAN: Enables Internet access via another, traditional router.', 36 | tr_country: 'Country', 37 | tr_inactive: 'Inactive', 38 | tr_unknown: 'Unknown', 39 | tr_individual_ports: 'Individual ports of the router, that are not identified as part of the switch or Wi-Fi.', 40 | tr_ports: 'Ports', 41 | tr_other: 'Other', 42 | tr_delete: 'Delete', 43 | tr_freifunk_upload: 'Freifunk Upload:', 44 | tr_freifunk_download: 'Freifunk Download:', 45 | tr_access: 'SSH/HTTPS Access:', 46 | tr_vpn:'Fastd VPN', 47 | tr_autoupdater: 'Autoupdater', 48 | tr_wifi_help: 'Does the interface work? For example, some wireless drivers may not be able to be access point and mesh at the same time.', 49 | tr_contribute_map: 'Contribute to map:', 50 | tr_community_site: 'Community Site', 51 | tr_node_name_help: 'The name of this node on the public node map.', 52 | tr_contact_help: 'Contact details for the public node map and status page. If you want to be contacted by other people (for example, \'info@example.com \').', 53 | tr_gps_help: 'GPS coordinates of this node on the public node map.', 54 | tr_website_help: 'Website of the community this node belongs to.', 55 | tr_invalid_input: 'Invalid input.', 56 | tr_contact_details: 'Contact details:', 57 | tr_service_link: 'Service Link:', 58 | tr_invalid_gps: 'Invalid input. Please use only up to 8 fractional digits, no commas or leading zeros.', 59 | tr_access_help: 'Allow access to the configuration via various ports / networks.', 60 | tr_channel_help: 'The channel on which the wireless card is transmitting its packets. Please keep in mind that routers can not see each other, if both sides are transmitting on different channels. The first channel is therefore recommended.', 61 | tr_announce: 'Announce contents', 62 | tr_autoupdater_help: 'The Autoupdater automatically updates the firmware to the latest version.', 63 | tr_latitude: 'Latitude:', 64 | tr_longitude: 'longitude:', 65 | tr_node_name: 'Node name:', 66 | tr_service_name: 'Service Name', 67 | tr_service_name_help: 'A name of the specified network resource. For example, \'My website\'.', 68 | tr_community: 'Community:', 69 | tr_system_help: 'Device overview.', 70 | tr_mesh_help: 'The public community network.', 71 | tr_lan_help: 'The private LAN network.', 72 | tr_wan_help: 'The WAN network to reach the Internet.', 73 | tr_software_help: 'Some installed software versions.', 74 | tr_user_count_hours_help: 'Number of users of this router during the last two hours.', 75 | tr_vpn_help: 'VPN-Server on the Internet, this node is connected to.', 76 | tr_bandwidth_control_help: 'Bandwidth control for the upload / download via the free wireless network via your own internet connection.', 77 | tr_max_upload_help: 'Maximum upload in kbps for bandwidth control.', 78 | tr_max_download_help: 'Maximum download in kbps for bandwidth control.', 79 | tr_try_server: 'Attempting to reach update servers. Please wait ...', 80 | tr_manual_update: 'Manual update', 81 | tr_really_reset: 'Reset all settings?', 82 | tr_really_update: 'Should an update be carried out?', 83 | tr_search: 'Search', 84 | tr_search_update: 'Search and update', 85 | tr_error: 'Error', 86 | tr_active: 'Active', 87 | tr_send: 'Send', 88 | tr_select_image: 'Select image', 89 | tr_keep_config: 'Maintain configuration', 90 | tr_use_image_help: 'Here a firmware image can be used (* -sysupgrade.bin) or the firmware of the router manufacturer.', 91 | tr_community_help: 'The identifier of the community which this node belongs to.', 92 | tr_encryption: 'Encryption', 93 | tr_search_firmware: 'Search most recent firmware', 94 | tr_reset_router: 'Reset', 95 | tr_reset: 'Reset to defaults', 96 | tr_password_different: 'The passwords are not identical.', 97 | tr_password_changed: 'The password will be changed. Please reload the page.', 98 | tr_new_password: 'New Password:', 99 | tr_confirm: 'Confirm:', 100 | tr_not_supported: 'This mode of operation is not supported by this chipset!', 101 | tr_transmission_power_help: 'The transmission power in dBm. Radiation power = transmission power - cable attenuation + antenna gain. \nOther values must be entered manually. Attention! When replacing the antennas, the transmission power must be adjusted accordingly!', 102 | tr_transmission_power: 'Transmission power', 103 | tr_mode_help: 'Log into another network (client) or allow other devices to log in (access point).', 104 | tr_mode: 'Mode:', 105 | tr_no_port_config: 'No port configuration possible.', 106 | tr_mesh_on_lan_help: 'This feature sends the mesh packets to the network at the WAN port. Please note that these broadcast packages have a negative impact on WAN network Wi-Fi access points.', 107 | tr_max_entries: 'Max entries', 108 | tr_max_entries_help: 'Maximum number of entries displayed on your own status page.', 109 | tr_updates_help: 'The Freifunk community offers new firmware versions for the routers.\nThese contain bug fixes and new features.', 110 | tr_fastd_help: 'Establish a VPN connection to the server over WAN (via fastd).', 111 | tr_start_scan: 'Start Scan', 112 | tr_password_format: 'Please use only one password with at least eight visible characters.', 113 | tr_external_ref_help: 'A reference to an _internal_ network resource.', 114 | tr_password_help: 'The password secures access to this web interface, as well as direct access to the router via SSH. The username is \'root\'.', 115 | tr_name: 'Name', 116 | tr_bssid: 'BSS-ID', 117 | tr_channel: 'Channel', 118 | tr_signal: 'Signal', 119 | tr_type: 'Type', 120 | tr_system: 'System', 121 | tr_name: 'Name:', 122 | tr_model: 'Model:', 123 | tr_mac_address: 'MAC-Address:', 124 | tr_all_nodes: 'All nodes:', 125 | tr_neighbor_nodes: 'Neighboring nodes:', 126 | tr_vpn_server: 'VPN Server:', 127 | tr_uptime: 'Uptime:', 128 | tr_cpu: 'CPU:', 129 | tr_ram: 'RAM:', 130 | tr_flash: 'Flash:', 131 | tr_usage: 'System:', 132 | tr_time: 'Time of day:', 133 | tr_users: 'User:', 134 | tr_has_internet: 'Internet available:', 135 | tr_speed: 'Speed:', 136 | tr_transferred: 'Transfered:', 137 | tr_ipv4_addr: 'IPv4 Addresses:', 138 | tr_ipv6_addr: 'IPv6 Addresses:', 139 | tr_invalid_name: 'Name is invalid:', 140 | tr_mac_address_help: 'The MAC-address identifies the node. If the value is empty, the router will select one itself.', 141 | tr_announce_help: 'Each router can display an entry on the status page of all other routers. This should help to find content in the free radio network.', 142 | tr_wifi_wan_error: 'WAN over Wi-Fi only works, if this is used as the only connection for WAN! Please correct.', 143 | tr_reset_router_help: 'All settings will be reset and the router will restart.', 144 | tr_switches_help: 'Configuration of the router\'s ports. Please heed that in a standard configuration, access to this config page is only possible via \'LAN\' ports.', 145 | tr_net_freifunk: 'Network: Freifunk', 146 | tr_net_wan: 'Network: WAN', 147 | tr_net_lan: 'Network: LAN', 148 | tr_firmware_version: 'Firmware Version:', 149 | tr_os_version: 'OpenWrt Version:', 150 | tr_mesh_version: 'Batman-Adv Version:', 151 | tr_vpn_version: 'Fastd Version:', 152 | tr_restart_really: 'Restart the router?', 153 | tr_mesh_id: 'Mesh ID:', 154 | tr_ssid: 'SSID:', 155 | tr_mesh_on_wan: 'Mesh-On-WAN:' 156 | }, 157 | de: { 158 | tr_home: 'Übersicht', 159 | tr_settings: 'Einstellungen', 160 | tr_network: 'Netzwerk', 161 | tr_wifi_scan: 'WLAN-Scan', 162 | tr_upgrade: 'Upgrade', 163 | tr_upgrade_in_progress: 'Upgrade wird durchgeführt!', 164 | tr_password: 'Passwort', 165 | tr_restart: 'Neustart', 166 | tr_logout: 'Abmelden', 167 | tr_extended_on: 'Erweiterte Optionen: An', 168 | tr_extended_off: 'Erweiterte Optionen: Aus', 169 | tr_general_settings: 'Allgemeine Einstellungen', 170 | tr_announce: 'Inhalte verkünden', 171 | tr_bandwidth_ctl: 'Bandbreitenkontrolle', 172 | tr_bandwidth_help: 'Die für das Freifunknetz beanspruchte Internet-Bandbreite am WAN kann hier begrenzt werden.', 173 | tr_ssh_keys_help: 'Verwalte die Liste der authorisierten SSH Schlüssel (/etc/dropbear/authorized_keys).', 174 | tr_ssh_keys: 'SSH Schlüssel', 175 | tr_save: 'Speichern', 176 | tr_yes: 'Ja', 177 | tr_no: 'Nein', 178 | tr_disabled: 'Deaktiviert', 179 | tr_on: 'An', 180 | tr_off: 'Aus', 181 | tr_none: 'Nichts', 182 | tr_basic: 'Basis', 183 | tr_more: 'Mehr', 184 | tr_all: 'Alles', 185 | tr_lan_help: 'LAN: Aktiviert ein privates, passwortgeschütztes WLAN-Netz mit Zugang zum eigenen Internetanschluss.', 186 | tr_freifunk_help: 'Freifunk: Der WLAN-Zugang zum Freifunk-Netz.', 187 | tr_mesh_help: 'Mesh: Das WLAN-Netz, über das die Router untereinander kommunizieren.', 188 | tr_wan_help: 'WAN: Ermöglicht den Internetzugang eines anderen, herkömmlichen Routers zu nutzen.', 189 | tr_country: 'Land', 190 | tr_inactive: 'Inaktiv', 191 | tr_unknown: 'Unbekannt', 192 | tr_individual_ports: 'Einzelne Anschlüsse des Router, die nicht als Teil des Switches oder WLANs zu identifizieren sind.', 193 | tr_ports: 'Anschlüsse', 194 | tr_other: 'Sonstiges', 195 | tr_delete: 'Löschen', 196 | tr_freifunk_upload: 'Freifunk Upload:', 197 | tr_freifunk_download: 'Freifunk Download:', 198 | tr_access: 'SSH/HTTPS Zugriff:', 199 | tr_vpn:'Fastd VPN', 200 | tr_autoupdater: 'Autoupdater', 201 | tr_wifi_help: 'Funktioniert der Anschluss? Manche WLAN-Treiber können z.B nicht Accesspoint und ein Mesh gleichzeitig aufspannen.', 202 | tr_contribute_map: 'Zur Karte beitragen:', 203 | tr_community_site: 'Community-Webseite', 204 | tr_node_name_help: 'Der Name dieses Knotens auf der öffentlichen Freifunk-Karte.', 205 | tr_contact_help: 'Kontaktdaten für die öffentliche Freifunk-Karte und Statusseite. Falls ihr euch von anderen Leuten kontaktieren lassen wollt (z.B. \'info@example.com\').', 206 | tr_gps_help: 'GPS-Koordinaten dieses Knotens auf der öffentlichen Freifunk-Karte.', 207 | tr_website_help: 'Webseite der Community, zu der dieser Knoten gehört.', 208 | tr_invalid_input: 'Ungültige Eingabe.', 209 | tr_contact_details: 'Kontaktdaten:', 210 | tr_service_link: 'Service Link:', 211 | tr_invalid_gps: 'Ungültige Eingabe. Bitte nur maximal 8 Nachkommastellen, keine Kommas und führende Nullen verwenden.', 212 | tr_access_help: 'Zugang zur Konfiguration über verschiedene Anschlüsse/Netzwerke ermöglichen.', 213 | tr_channel_help: 'Der Kanal, auf dem die WLAN-Karte sendet. Bitte denk daran, dass sich Router nicht sehen können, wenn beide Seiten auf unterschiedlichen Kanälen funken. Der erste Kanal ist daher zu empfehlen.', 214 | tr_announce: 'Inhalte verkünden', 215 | tr_autoupdater_help: 'Der Autoupdater aktualisiert die Firmware automatisch auf die neueste Version.', 216 | tr_latitude: 'Breitengrad:', 217 | tr_longitude: 'Längengrad:', 218 | tr_node_name: 'Knotenname:', 219 | tr_service_name: 'Service Name', 220 | tr_service_name_help: 'Ein Name für die Resource. Z.B. \'Meine Webseite\'.', 221 | tr_community: 'Community:', 222 | tr_system_help: 'Eine Übersicht über den Router.', 223 | tr_mesh_help: 'Das öffentliche Freifunknetz.', 224 | tr_lan_help: 'Das private Netz bzw. LAN.', 225 | tr_wan_help: 'Das Netz, über welches das Internet erreicht wird.', 226 | tr_software_help: 'Einige installierte Softwareversionen.', 227 | tr_user_count_hours_help: 'Die Anzahl der Nutzer an diesem Router in den letzten zwei Stunden.', 228 | tr_vpn_help: 'Der VPN-Server im Internet, mit dem der Knoten verbunden ist.', 229 | tr_bandwidth_control_help: 'Bandbreitenkontrolle für den Upload-/Download über das Freifunknetz über den eigenen Internetanschluss.', 230 | tr_max_upload_help: 'Maximaler Upload in KBit/s für die Bandbreitenkontrolle.', 231 | tr_max_download_help: 'Maximaler Download in KBit/s für die Bandbreitenkontrolle.', 232 | tr_try_server: 'Versuche Updateserver zu erreichen. Bitte warten ...', 233 | tr_manual_update: 'Manuelles Update', 234 | tr_really_reset: 'Sollen alle Einstellungen zurückgesetzt werden?', 235 | tr_really_update: 'Soll ein Update durchgeführt werden?', 236 | tr_search: 'Suchen', 237 | tr_search_update: 'Suchen und Aktualisieren', 238 | tr_password: 'Passwort', 239 | tr_state: 'Status:', 240 | tr_error: 'Fehler', 241 | tr_active: 'Aktiv', 242 | tr_community_help: 'Der Bezeichner der Community, zu der dieser Knoten gehört.', 243 | tr_send: 'Senden', 244 | tr_select_image: 'Auswählen', 245 | tr_keep_config: 'Konfiguration beibehalten', 246 | tr_use_image_help: 'Hier kann ein Freifunk-Image verwendet werden (*-sysupgrade.bin) oder die Firmware des Routerherstellers.', 247 | tr_encryption: 'Verschlüsselung', 248 | tr_search_firmware: 'Aktuelle Firmware suchen', 249 | tr_reset_router: 'Router Zurücksetzen', 250 | tr_reset: 'Zurücksetzen', 251 | tr_password_different: 'Die Passwörter sind nicht identisch.', 252 | tr_password_changed: 'Das Passwort wird geändert. Bitte die Seite neu laden.', 253 | tr_new_password: 'Neues Passwort:', 254 | tr_confirm: 'Bestätigung:', 255 | tr_not_supported: 'Diese Betriebsweise wird von diesem Chipsatz nicht unterstützt!', 256 | tr_transmission_power_help: 'Die Sendeleistung in dBm. Strahlungsleistung = Sendeleistung - Kabeldämpfung + Antennengewinn.\nAndere Werte müssen manuell eingetragen werden. Achtung! Beim Tausch der Antennen muss die Sendeleistung entsprechend angepasst werden!', 257 | tr_transmission_power: 'Sendeleistung', 258 | tr_mode_help: 'In einem anderen Netz anmelden (Client) oder das Anmelden anderer Geräte zulassen (Access Point).', 259 | tr_mode: 'Modus:', 260 | tr_no_port_config: 'Keine Port-Konfiguration möglich.', 261 | tr_mesh_on_lan_help: 'Diese Funktion schickt die Mesh-Pakete auf das Netz am WAN-Anschluss. Bitte beachten, dass diese Broadcast-Pakete im WAN-Netz befindliche WLAN Access Points negativ beeinflusst.', 262 | tr_max_entries: 'Max. Einträge', 263 | tr_max_entries_help: 'Maximale Anzahl der auf der eigenen Statusseite angezeigten Einträge.', 264 | tr_updates_help: 'Die Freifunk-Community bietet neue Firmware-Versionen für die Router an.\nDiese enthalten Fehlerbereinigungen und neue Funktionen.', 265 | tr_fastd_help: 'Eine VPN-Verbindung zum Server über WAN aufbauen (per fastd).', 266 | tr_start_scan: 'Scan starten', 267 | tr_password_format: 'Bitte nur ein Passwort aus mindestens acht sichbaren Zeichen verwenden.', 268 | tr_external_ref_help: 'Ein Verweis auf eine _interne_ Netzwerkresource.', 269 | tr_password_help: 'Das Passwort sichert den Zugriff auf diese Weboberfläche ab, sowie den Direktzugriff auf den Router via SSH. Der Benutzername lautet \'root\'.', 270 | tr_name: 'Name', 271 | tr_bssid: 'BSS-ID', 272 | tr_channel: 'Kanal', 273 | tr_signal: 'Signal', 274 | tr_system: 'System', 275 | tr_type: 'Typ', 276 | tr_name: 'Name:', 277 | tr_model: 'Modell:', 278 | tr_mac_address: 'MAC-Addresse:', 279 | tr_all_nodes: 'Alle Knoten:', 280 | tr_neighbor_nodes: 'Nachbarknoten:', 281 | tr_vpn_server: 'VPN Server:', 282 | tr_uptime: 'Laufzeit', 283 | tr_cpu: 'CPU:', 284 | tr_ram: 'RAM:', 285 | tr_flash: 'Flash:', 286 | tr_usage: 'System:', 287 | tr_time: 'Uhrzeit:', 288 | tr_users: 'Nutzer:', 289 | tr_has_internet: 'Internet Vorhanden:', 290 | tr_speed: 'Geschwindigkeit:', 291 | tr_transferred: 'Übertragen:', 292 | tr_ipv4_addr: 'IPv4 Adressen:', 293 | tr_ipv6_addr: 'IPv6 Addressen:', 294 | tr_invalid_name: 'Name ist ungültig:', 295 | tr_reset_router_help: 'Alle Einstellungen werden zurückgesetzt und der Router startet neu.', 296 | tr_mac_address_help: 'Die MAC-Adresse identifiziert den Knoten. Bei einem leeren Wert wählt der Router selber einen aus.', 297 | tr_wifi_wan_error: 'WAN über WLAN funktioniert nur, wenn dieser als einziger Anschluss für WAN verwendet wird! Bitte korrigieren.', 298 | tr_announce_help: 'Jeder Router kann einen Eintrag auf der Statusseite aller anderen Router anzeigen lassen. Dies soll helfen, Inhalte im Freifunknetz zu finden.', 299 | tr_switches_help: 'Konfiguration der Anschlüsse/Ports am Router. Bitte darauf achten, dass der Zugang auf diese Seite normalerweise nur über auf \'LAN\' gestellte Anschlüsse möglich ist.', 300 | tr_net_freifunk: 'Netzwerk: Freifunk', 301 | tr_net_wan: 'Netzwerk: WAN', 302 | tr_net_lan: 'Netzwerk: LAN', 303 | tr_firmware_version: 'Firmware Version:', 304 | tr_os_version: 'OpenWrt Version:', 305 | tr_mesh_version: 'Batman-Adv Version:', 306 | tr_vpn_version: 'Fastd Version:', 307 | tr_restart_really: 'Wirklich Neustarten?', 308 | tr_mesh_id: 'Mesh ID:', 309 | tr_ssid: 'SSID:', 310 | tr_mesh_on_wan: 'Mesh-On-WAN:' 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /files/www/lan/upgrade.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Upgrade 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 | 17 | 18 |
19 |
20 |
21 |
22 | 23 |
24 | 25 |
26 |
27 |
28 |
29 | 30 |
31 |
32 |
33 | 39 |
40 | 41 | 42 |
43 |
44 |
45 |
46 |
47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /files/www/lan/upgrade.js: -------------------------------------------------------------------------------- 1 | 2 | function init() { 3 | tr(); 4 | } 5 | 6 | function restore_firmware() { 7 | if (!confirm(tr("tr_really_reset"))) { 8 | return; 9 | } 10 | 11 | send("/cgi-bin/upgrade", { func : 'restore_firmware' }, function(text) { 12 | setText('msg', text); 13 | }); 14 | } 15 | 16 | function lookup_upgrade() { 17 | setText('msg', tr('tr_try_server')); 18 | send("/cgi-bin/upgrade", { func : 'lookup_upgrade' }, function(text) { 19 | setText('msg', text); 20 | }); 21 | } 22 | 23 | function lookup_and_apply_upgrade() { 24 | if (!confirm(tr("tr_really_update"))) { 25 | return; 26 | } 27 | 28 | setText('msg', tr('tr_manual_update')); 29 | send("/cgi-bin/upgrade", { func : 'lookup_and_apply_upgrade' }, function(text) { 30 | if (text.length == 0) { 31 | setText('msg', tr('tr_upgrade_in_progress')); 32 | } else { 33 | setText('msg', text); 34 | } 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /files/www/lan/wifiscan.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WLAN-Scan 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /files/www/lan/wifiscan.js: -------------------------------------------------------------------------------- 1 | 2 | function fetch(regex, data) 3 | { 4 | var result = data.match(regex); 5 | return result ? result[1] : ''; 6 | } 7 | 8 | function append_td(tr, value) { 9 | append(tr, 'td').textContent = value ? value : '?'; 10 | } 11 | 12 | function signalToQuality(signal) { 13 | var dBm = parseFloat(signal); 14 | if (dBm <= -100) { 15 | return 0; 16 | } else if (dBm >= -50) { 17 | return 100; 18 | } else { 19 | return (2 * (dBm + 100)); 20 | } 21 | } 22 | 23 | function wifi_scan() 24 | { 25 | var s = $('wifiscan_selection'); 26 | var device = s.options[s.selectedIndex].value; 27 | 28 | send('/cgi-bin/misc', {func:'wifiscan', device:device}, function(data) { 29 | var tbody = $('wifiscan_tbody'); 30 | removeChilds(tbody); 31 | 32 | data = data.replace(/BSS /g, '|BSS '); 33 | var items = data.split('|').filter(Boolean); 34 | for (var i = 0; i < items.length; ++i) { 35 | var item = items[i]; 36 | var ssid = fetch(/SSID: (.*)\n/, item); 37 | var bss = fetch(/BSS (..:..:..:..:..:..).*\n/, item); 38 | var channel = fetch(/channel: (.*)\n/, item); 39 | var signal = fetch(/signal: (.*)\n/, item); 40 | var capability = fetch(/capability: (.*)\n/, item); 41 | var mesh_id = fetch(/MESH ID: (.*)\n/, item); 42 | 43 | var tr = append(tbody, 'tr'); 44 | append_td(tr, mesh_id ? mesh_id : ssid); 45 | append_td(tr, bss); 46 | append_td(tr, channel); 47 | append_td(tr, signal + ' (' + signalToQuality(signal) + '%)'); 48 | 49 | //determine the wifi mode 50 | if (mesh_id) { 51 | append_td(tr, ' 802.11s'); 52 | } else if (/IBSS/.test(capability)) { 53 | append_td(tr, ' AdHoc'); 54 | } else if (/ESS/.test(capability)) { 55 | append_td(tr, ' AccessPoint'); 56 | } else { 57 | append_td(tr, ' ???'); 58 | } 59 | } 60 | 61 | var table = $('wifiscan_table'); 62 | show(table); 63 | }); 64 | } 65 | 66 | function add_list_entry(device, ifname) { 67 | var list = $('wifiscan_selection'); 68 | var o = append(list, 'option'); 69 | o.style.paddingRight = '1em'; 70 | o.textContent = device; 71 | o.value = ifname; 72 | } 73 | 74 | /* 75 | * Create a selection of wireless devices 76 | */ 77 | function init() { 78 | send('/cgi-bin/misc', {func:'wifi_status'}, function(data) { 79 | var data = JSON.parse(data); 80 | for (var device in data) { 81 | var interfaces = data[device].interfaces; 82 | if (interfaces.length == 0) { 83 | continue; 84 | } 85 | for (var interface in interfaces) { 86 | var ifname = interfaces[interface].ifname; 87 | if (typeof(ifname) == 'string') { 88 | add_list_entry(device, ifname); 89 | } 90 | } 91 | } 92 | tr(); 93 | }); 94 | } 95 | -------------------------------------------------------------------------------- /package/autoupdater/Makefile: -------------------------------------------------------------------------------- 1 | #Based on gluon-updater 2 | include $(TOPDIR)/rules.mk 3 | 4 | PKG_NAME:=autoupdater 5 | PKG_VERSION:=0.1 6 | PKG_RELEASE:=1.1 7 | 8 | PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) 9 | 10 | include $(INCLUDE_DIR)/package.mk 11 | 12 | define Package/autoupdater 13 | SECTION:=admin 14 | CATEGORY:=Administration 15 | DEPENDS:=+ecdsautils +@BUSYBOX_DEFAULT_SHA512SUM 16 | TITLE:=Automatically update firmware 17 | endef 18 | 19 | define Build/Prepare 20 | mkdir -p $(PKG_BUILD_DIR) 21 | endef 22 | 23 | define Build/Configure 24 | endef 25 | 26 | define Build/Compile 27 | endef 28 | 29 | define Package/autoupdater/install 30 | $(CP) ./files/* $(1)/ 31 | chmod +x $(1)/usr/sbin/autoupdater 32 | endef 33 | 34 | $(eval $(call BuildPackage,autoupdater)) 35 | -------------------------------------------------------------------------------- /package/autoupdater/README.md: -------------------------------------------------------------------------------- 1 | Models 2 | ====== 3 | 4 | Ubiquity 5 | -------- 6 | 7 | ubiquity-nanostation-m (dual ethernet) 8 | ubiquity-bullet-m (single ethernet: Bullet M, Nanostation loco M) 9 | 10 | TP-Link 11 | ------- 12 | 13 | tp-link-tl-mr3020 14 | tp-link-tl-mr3040 15 | tp-link-tl-mr3220 16 | tp-link-tl-mr3420 17 | tp-link-tl-wdr3600-v1 18 | tp-link-tl-wdr4300-v1 19 | tp-link-tl-wdr4310-v1 20 | tp-link-tl-wr740n-nd-v1 21 | tp-link-tl-wr740n-nd-v3 22 | tp-link-tl-wr740n-nd-v4 23 | tp-link-tl-wr741n-nd-v1 24 | tp-link-tl-wr741n-nd-v2 25 | tp-link-tl-wr741n-nd-v4 26 | tp-link-tl-wr841n-nd-v8 27 | tp-link-tl-wr841n-nd-v1.5 28 | tp-link-tl-wr841n-nd-v3 29 | tp-link-tl-wr841n-nd-v5 30 | tp-link-tl-wr841n-nd-v7 31 | tp-link-tl-wr842n-nd-v1 32 | tp-link-tl-wr941n-nd-v2 33 | tp-link-tl-wr941n-nd-v3 34 | tp-link-tl-wr941n-nd-v4 35 | tp-link-tl-wr1043n-nd-v1 36 | -------------------------------------------------------------------------------- /package/autoupdater/files/etc/config/autoupdater: -------------------------------------------------------------------------------- 1 | #config autoupdater settings 2 | # option enabled 1 3 | # option branch "stable" 4 | 5 | #config branch stable 6 | # The branch name given in the manifest 7 | # option name 'stable' 8 | 9 | # list mirror 'http://[fdef:ffc0:3dd7::8]/~freifunk/firmware/autoupdate' 10 | 11 | #Delay excution of the autoupdater for at most fetch_delay seconds. 12 | #This spreads the load of the server when all nodes start 13 | #the autoupdater at the same time. 14 | # option fetch_delay 1000 15 | 16 | #Delay sysupgrade for apply_delay seconds. 17 | #This gives other nodes behind this one time to fetch the update 18 | #themselves before the update is performed. 19 | # option apply_delay 6000 20 | 21 | # Minimum valid signatures required to perform the update 22 | # option good_signatures 2 23 | 24 | # List of public keys 25 | # list pubkey 'beea7da92ed0c19563b6c259162b4cb471aa2fdf9d3939d05fea2cf498ea7642' 26 | # list pubkey 'c75c9390cf5d7cc49a388d35f831ca379060cf7bca8c6e3d2d1ea31604597c42' 27 | # list pubkey '03e9514f137f0467c0f0ac108892c0da2b71f1039b30f863331cbd5701abd042' 28 | -------------------------------------------------------------------------------- /package/autoupdater/files/usr/sbin/autoupdater: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | BRANCH=$(uci get autoupdater.settings.branch) 5 | 6 | force=0 7 | check=0 8 | 9 | [ "$1" = "-f" ] && force=1 10 | [ "$1" = "-c" ] && force=1 && check=1 11 | 12 | if [ $force != 1 -a $(uci get autoupdater.settings.enabled) != 1 ]; then 13 | echo "autoupdater is disabled" 14 | exit 0 15 | fi 16 | 17 | FETCH_DELAY=$(uci -q get autoupdater.${BRANCH}.fetch_delay) 18 | FETCH_DELAY=${FETCH_DELAY-0} 19 | APPLY_DELAY=$(uci -q get autoupdater.${BRANCH}.apply_delay) 20 | APPLY_DELAY=${APPLY_DELAY-0} 21 | 22 | BRANCH_NAME=$(uci get autoupdater.${BRANCH}.name) 23 | MIRRORS=$(for mirror in $(uci get autoupdater.${BRANCH}.mirror); do \ 24 | hexdump -n1 -e '/1 "%d '"$mirror"'\n"' /dev/urandom; \ 25 | done | sort -n | cut -d' ' -f2) 26 | PUBKEYS=$(uci get autoupdater.${BRANCH}.pubkey) 27 | GOOD_SIGNATURES=$(uci get autoupdater.${BRANCH}.good_signatures) 28 | 29 | # returns 0 when $1 is a higher version number than $2 30 | newer_than() { 31 | vnum() { 32 | local major="${1:-0}" minor="${2:-0}" patch="${3:-0}" 33 | echo $((major * 10000 + minor * 100 + patch)) 34 | } 35 | local OLD_IFS="$IFS" 36 | IFS="." 37 | local v1=$(vnum $1) 38 | local v2=$(vnum $2) 39 | IFS="$OLD_IFS" 40 | 41 | [ $v1 -gt $v2 ] 42 | } 43 | 44 | fetch_manifest() { 45 | local MIRROR=$1 46 | local manifest=$2 47 | 48 | wget -T 120 -O$manifest "$MIRROR"/manifest &> /dev/null 49 | 50 | if test $? -ne 0; then 51 | echo "Couldn't fetch manifest from $MIRROR" >&2 52 | return 1 53 | fi 54 | 55 | return 0 56 | } 57 | 58 | verify_manifest() { 59 | local manifest=$1 60 | local manifest_upper=$2 61 | local manifest_lower=$(mktemp) 62 | awk "BEGIN { sep=0 } 63 | /^---\$/ { sep=1; next } 64 | { if(sep==0) print > \"$manifest_upper\"; 65 | else print > \"$manifest_lower\"}" \ 66 | $manifest 67 | 68 | local signatures="" 69 | while read sig; do 70 | echo "$sig" | grep -q "^[0-9a-f]\{128\}$" 71 | if test $? -ne 0; then 72 | continue 73 | fi 74 | signatures="$signatures -s $sig" 75 | done < $manifest_lower 76 | 77 | local pubkeys="" 78 | for key in $PUBKEYS; do 79 | pubkeys="$pubkeys -p $key" 80 | done 81 | 82 | rm -f $manifest_lower 83 | 84 | ecdsaverify -n $GOOD_SIGNATURES $pubkeys $signatures $manifest_upper 85 | 86 | if test $? -ne 0; then 87 | echo "Not enough valid signatures!" >&2 88 | return 1 89 | fi 90 | 91 | return 0 92 | } 93 | 94 | analyse_manifest() { 95 | local manifest_upper=$1 96 | 97 | grep -q "^BRANCH=${BRANCH_NAME}$" $manifest_upper 98 | 99 | if test $? -ne 0; then 100 | echo "Wrong branch. We are on ${BRANCH_NAME}" >&2 101 | return 1 102 | fi 103 | 104 | local my_firmware 105 | my_firmware=$(grep -m1 "^${my_model} " $manifest_upper) 106 | 107 | if test $? -ne 0; then 108 | echo "No matching firmware found (model ${my_model})" >&2 109 | 110 | # report back missing model 111 | #wget -T 3 --spider "${MIRROR}/request_image.sh?model=${my_model}" -O /dev/null &> /dev/null 112 | return 1 113 | fi 114 | 115 | fw_version=$(echo "${my_firmware}" | cut -d' ' -f2) 116 | fw_checksum=$(echo "${my_firmware}" | cut -d' ' -f3) 117 | fw_file=$(echo "${my_firmware}" | cut -d' ' -f4) 118 | 119 | return 0 120 | } 121 | 122 | fetch_firmware() { 123 | local MIRROR=$1 124 | local fw_image=$2 125 | 126 | wget -T 120 -O$fw_image "${MIRROR}/${fw_file}" &> /dev/null 127 | 128 | if test $? -ne 0; then 129 | echo "Cannot contact update server: $MIRROR" >&2 130 | return 1 131 | fi 132 | 133 | return 0 134 | } 135 | 136 | autoupdate() { 137 | local MIRROR=$1 138 | 139 | local manifest=$(mktemp) 140 | fetch_manifest $MIRROR $manifest || { rm -f $manifest; return 1; } 141 | 142 | local manifest_upper=$(mktemp) 143 | verify_manifest $manifest $manifest_upper || { rm -f $manifest $manifest_upper; return 1; } 144 | rm -f $manifest 145 | 146 | analyse_manifest $manifest_upper || { rm -f $manifest_upper; return 1; } 147 | rm -f $manifest_upper 148 | 149 | if newer_than "$(echo $fw_version | tr -dc '.0-9')" "$(echo $my_version | tr -dc '.0-9')"; then 150 | echo "New version available: $fw_version" 151 | 152 | [ $check -eq 1 ] && return 0 153 | 154 | # drop caches to make room for firmware image 155 | sync 156 | sysctl -w vm.drop_caches=3 157 | 158 | local fw_image=$(mktemp) 159 | fetch_firmware $MIRROR $fw_image || { rm -f $fw_image; return 1; } 160 | 161 | image_sha512=$(sha512sum "$fw_image" | awk '{print $1}') 162 | if [ "$image_sha512" != "$fw_checksum" ]; then 163 | echo "Invalid image checksum" >&2 164 | rm -f $fw_image 165 | return 1 166 | fi 167 | echo "Upgrading firmware." 168 | [ $force -eq 0 ] && sleep $APPLY_DELAY 169 | sysupgrade "${fw_image}" 170 | else 171 | echo "No new firmware available" >&2 172 | fi 173 | 174 | return 0 175 | } 176 | 177 | trap 'echo Signal ignored.' INT TERM PIPE 178 | 179 | my_model="$(cat /tmp/sysinfo/model | tr '[A-Z]' '[a-z]' | sed -r 's/[^a-z0-9]+/-/g;s/-$//')" 180 | my_version="$(uci -q get freifunk.@settings[0].version)" 181 | 182 | lock_dir=/var/lock/autoupdater.lock 183 | mkdir $lock_dir || { echo "Autoupdater already running" >&2; exit 1; } 184 | 185 | # wait up to 15 minutes to spread the load for the server 186 | [ $force -eq 0 ] && sleep $(awk -v val=$FETCH_DELAY 'BEGIN{srand(); print(int(val * rand()));}') 187 | 188 | for mirror in $MIRRORS; do 189 | 190 | autoupdate $mirror && break 191 | 192 | unset fw_version 193 | unset fw_checksum 194 | unset fw_file 195 | 196 | done 197 | 198 | rmdir $lock_dir 199 | -------------------------------------------------------------------------------- /package/autoupdater/manifest.sample: -------------------------------------------------------------------------------- 1 | BRANCH=stable 2 | 3 | # model ver sha512sum filename 4 | tp-link-tl-wdr4300-v1 0.4 c300c2b80a8863506cf3b19359873c596d87af3183c4826462dfb5aa69bec7ce65e3db23a9f6f779fd0f3cc50db5d57070c2b62942abf4fb0e08ae4cb48191a0 gluon-0.4-tp-link-tl-wdr4300-v1-sysupgrade.bin 5 | 6 | # after three dashes follow the ecdsa signatures of everything above the dashes 7 | --- 8 | 49030b7b394e0bd204e0faf17f2d2b2756b503c9d682b135deea42b34a09010bff139cbf7513be3f9f8aae126b7f6ff3a7bfe862a798eae9b005d75abbba770a 9 | -------------------------------------------------------------------------------- /package/freifunk/Makefile: -------------------------------------------------------------------------------- 1 | include $(TOPDIR)/rules.mk 2 | 3 | PKG_NAME:=freifunk 4 | PKG_VERSION:=1.0.0 5 | PKG_RELEASE:=1 6 | 7 | PKG_BUILD_DIR:=$(BUILD_DIR)/freifunk 8 | 9 | include $(INCLUDE_DIR)/package.mk 10 | 11 | define Package/freifunk-basic 12 | SECTION:=base 13 | CATEGORY:=Freifunk 14 | DEFAULT:=y 15 | TITLE:= Freifunk-Ulm Basic 16 | URL:=http://freifunk-ulm.de 17 | DEPENDS:=+kmod-batman-adv +batctl +alfred +sockread \ 18 | +uhttpd +haserl +px5g +libustream-mbedtls \ 19 | +fastd +ip +simple-radvd +@SMALL_FLASH \ 20 | +ebtables +kmod-ebtables-ipv4 +kmod-ebtables-ipv6 \ 21 | +haveged +autoupdater +simple-tc +@ATH_USER_REGD 22 | endef 23 | 24 | define Build/Prepare 25 | echo "all: " > $(PKG_BUILD_DIR)/Makefile 26 | endef 27 | 28 | define Package/freifunk-basic/install 29 | #nothing to do here 30 | endef 31 | 32 | define Package/freifunk/conffiles 33 | /etc/config/freifunk 34 | endef 35 | 36 | define Package/freifunk-debug 37 | SECTION:=base 38 | CATEGORY:=Freifunk 39 | DEFAULT:=n 40 | TITLE:=With debug tools 41 | DEPENDS:=+freifunk-basic \ 42 | +@KMOD_BATMAN_ADV_DEBUG_LOG +iperf +tcpdump-mini 43 | endef 44 | 45 | define Package/freifunk-usb-storage 46 | SECTION:=base 47 | CATEGORY:=Freifunk 48 | DEFAULT:=n 49 | TITLE:=With USB storage packages 50 | DEPENDS:=+freifunk-basic \ 51 | +kmod-usb-storage +block-mount \ 52 | +kmod-fs-ext4 +kmod-fs-vfat \ 53 | +kmod-nls-cp437 +kmod-nls-iso8859-1 54 | endef 55 | 56 | define Package/freifunk-usb-3g 57 | SECTION:=base 58 | CATEGORY:=Freifunk 59 | DEFAULT:=n 60 | TITLE:=With 3G USB dongle packages 61 | DEPENDS:=+freifunk-basic \ 62 | +comgt +kmod-usb-serial +kmod-usb-serial-option \ 63 | +kmod-usb-serial-wwan +usb-modeswitch 64 | endef 65 | 66 | $(eval $(call BuildPackage,freifunk-basic)) 67 | $(eval $(call BuildPackage,freifunk-debug)) 68 | $(eval $(call BuildPackage,freifunk-usb-storage)) 69 | $(eval $(call BuildPackage,freifunk-usb-3g)) 70 | -------------------------------------------------------------------------------- /package/simple-radvd/Makefile: -------------------------------------------------------------------------------- 1 | include $(TOPDIR)/rules.mk 2 | 3 | #This package is identical to the gluon-radvd package from the Gluon Project 4 | 5 | PKG_NAME:=simple-radvd 6 | PKG_VERSION:=4 7 | 8 | PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) 9 | 10 | include $(INCLUDE_DIR)/package.mk 11 | 12 | define Package/simple-radvd 13 | SECTION:=net 14 | CATEGORY:=Network 15 | TITLE:=Advertise an IPv6 prefix from the node 16 | DEPENDS:=+librt 17 | endef 18 | 19 | define Package/simple-radvd/description 20 | Advertise an IPv6 prefix from the node 21 | endef 22 | 23 | define Build/Prepare 24 | mkdir -p $(PKG_BUILD_DIR) 25 | $(CP) ./src/* $(PKG_BUILD_DIR)/ 26 | endef 27 | 28 | define Build/Configure 29 | endef 30 | 31 | define Build/Compile 32 | CFLAGS="$(TARGET_CFLAGS)" CPPFLAGS="$(TARGET_CPPFLAGS)" $(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS) 33 | endef 34 | 35 | define Package/simple-radvd/install 36 | $(CP) ./files/* $(1)/ 37 | $(INSTALL_DIR) $(1)/usr/sbin 38 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/simple-radvd $(1)/usr/sbin/ 39 | endef 40 | 41 | $(eval $(call BuildPackage,simple-radvd)) 42 | -------------------------------------------------------------------------------- /package/simple-radvd/files/etc/config/simple-radvd: -------------------------------------------------------------------------------- 1 | 2 | config interface 3 | option network 'lan' 4 | #option ifname 'br-lan' 5 | list prefix 'fd12:3456:7890:abcd::/64' 6 | -------------------------------------------------------------------------------- /package/simple-radvd/files/etc/init.d/simple-radvd: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=50 4 | 5 | USE_PROCD=1 6 | 7 | start_instance() { 8 | local cfg="$1" ifname network args 9 | 10 | config_get ifname $cfg 'ifname' 11 | config_get network $cfg 'network' 12 | 13 | if [ -n "$network" ]; then 14 | network_get_device 'ifname' "$network" 15 | fi 16 | 17 | if [ -z "$ifname" ]; then 18 | echo "No valid interface or network name." 19 | exit 1 20 | fi 21 | 22 | args="$args -i $ifname" 23 | 24 | append_prefix() { 25 | args="$args -p $1" 26 | } 27 | config_list_foreach $cfg prefix append_prefix 28 | 29 | procd_open_instance 30 | procd_set_param command /usr/sbin/simple-radvd $args 31 | procd_set_param respawn 32 | procd_close_instance 33 | } 34 | 35 | start_service() { 36 | config_load simple-radvd 37 | config_foreach start_instance interface 38 | } 39 | -------------------------------------------------------------------------------- /package/simple-radvd/src/Makefile: -------------------------------------------------------------------------------- 1 | all: simple-radvd 2 | 3 | simple-radvd: simple-radvd.c 4 | $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) -lrt 5 | -------------------------------------------------------------------------------- /package/simple-tc/Makefile: -------------------------------------------------------------------------------- 1 | #Also known as gluon-simple-tc 2 | include $(TOPDIR)/rules.mk 3 | 4 | PKG_NAME:=simple-tc 5 | PKG_VERSION:=5 6 | 7 | PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) 8 | 9 | include $(INCLUDE_DIR)/package.mk 10 | 11 | define Package/simple-tc 12 | SECTION:=net 13 | CATEGORY:=Network 14 | TITLE:=Bandwidth limit support 15 | DEPENDS:=+kmod-sched +libnl-tiny 16 | endef 17 | 18 | define Package/simple-tc/description 19 | Simple support for upload and download limits 20 | endef 21 | 22 | define Build/Prepare 23 | mkdir -p $(PKG_BUILD_DIR) 24 | $(CP) ./src/* $(PKG_BUILD_DIR)/ 25 | endef 26 | 27 | define Build/Configure 28 | endef 29 | 30 | 31 | TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/libnl-tiny 32 | 33 | define Build/Compile 34 | CFLAGS="$(TARGET_CFLAGS)" CPPFLAGS="$(TARGET_CPPFLAGS)" $(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS) 35 | endef 36 | 37 | define Package/simple-tc/install 38 | $(CP) ./files/* $(1)/ 39 | $(INSTALL_DIR) $(1)/usr/sbin 40 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/simple-tc $(1)/usr/sbin/ 41 | endef 42 | 43 | $(eval $(call BuildPackage,simple-tc)) 44 | -------------------------------------------------------------------------------- /package/simple-tc/files/etc/config/simple-tc: -------------------------------------------------------------------------------- 1 | # Example config 2 | 3 | config interface 'example' 4 | option enabled '0' 5 | option ifname 'eth0' 6 | option limit_egress '1000' # 1000 Kbit/s 7 | option limit_ingress '5000' # 5000 Kbit/s 8 | -------------------------------------------------------------------------------- /package/simple-tc/files/etc/hotplug.d/net/50-simple-tc: -------------------------------------------------------------------------------- 1 | [ "$ACTION" = 'add' ] || exit 0 2 | 3 | config_load simple-tc 4 | 5 | 6 | tc_interface() { 7 | local iface="$1" 8 | 9 | config_get ifname "$iface" ifname 10 | 11 | [ "$INTERFACE" = "$ifname" ] || return 12 | 13 | config_get_bool enabled "$iface" enabled 0 14 | 15 | [ "$enabled" -eq 1 ] || return 16 | 17 | config_get limit_ingress "$iface" limit_ingress 18 | config_get limit_egress "$iface" limit_egress 19 | 20 | [ "$limit_ingress" ] || limit_ingress=- 21 | [ "$limit_egress" ] || limit_egress=- 22 | 23 | simple-tc "$INTERFACE" "$limit_ingress" "$limit_egress" 24 | } 25 | 26 | config_foreach tc_interface 'interface' 27 | -------------------------------------------------------------------------------- /package/simple-tc/files/etc/modules-boot.d/30-simple-tc: -------------------------------------------------------------------------------- 1 | ../modules.d/30-simple-tc -------------------------------------------------------------------------------- /package/simple-tc/files/etc/modules.d/30-simple-tc: -------------------------------------------------------------------------------- 1 | sch_ingress 2 | sch_tbf 3 | cls_basic 4 | act_police 5 | -------------------------------------------------------------------------------- /package/simple-tc/src/Makefile: -------------------------------------------------------------------------------- 1 | all: simple-tc 2 | 3 | simple-tc: simple-tc.c 4 | $(CC) -Iinclude $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) -lnl-tiny 5 | -------------------------------------------------------------------------------- /package/simple-tc/src/include/linux/pkt_cls.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_PKT_CLS_H 2 | #define __LINUX_PKT_CLS_H 3 | 4 | #include 5 | #include 6 | 7 | /* I think i could have done better macros ; for now this is stolen from 8 | * some arch/mips code - jhs 9 | */ 10 | #define _TC_MAKE32(x) ((x)) 11 | 12 | #define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n)) 13 | #define _TC_MAKEMASK(v,n) (_TC_MAKE32((_TC_MAKE32(1)<<(v))-1) << _TC_MAKE32(n)) 14 | #define _TC_MAKEVALUE(v,n) (_TC_MAKE32(v) << _TC_MAKE32(n)) 15 | #define _TC_GETVALUE(v,n,m) ((_TC_MAKE32(v) & _TC_MAKE32(m)) >> _TC_MAKE32(n)) 16 | 17 | /* verdict bit breakdown 18 | * 19 | bit 0: when set -> this packet has been munged already 20 | 21 | bit 1: when set -> It is ok to munge this packet 22 | 23 | bit 2,3,4,5: Reclassify counter - sort of reverse TTL - if exceeded 24 | assume loop 25 | 26 | bit 6,7: Where this packet was last seen 27 | 0: Above the transmit example at the socket level 28 | 1: on the Ingress 29 | 2: on the Egress 30 | 31 | bit 8: when set --> Request not to classify on ingress. 32 | 33 | bits 9,10,11: redirect counter - redirect TTL. Loop avoidance 34 | 35 | * 36 | * */ 37 | 38 | #define TC_MUNGED _TC_MAKEMASK1(0) 39 | #define SET_TC_MUNGED(v) ( TC_MUNGED | (v & ~TC_MUNGED)) 40 | #define CLR_TC_MUNGED(v) ( v & ~TC_MUNGED) 41 | 42 | #define TC_OK2MUNGE _TC_MAKEMASK1(1) 43 | #define SET_TC_OK2MUNGE(v) ( TC_OK2MUNGE | (v & ~TC_OK2MUNGE)) 44 | #define CLR_TC_OK2MUNGE(v) ( v & ~TC_OK2MUNGE) 45 | 46 | #define S_TC_VERD _TC_MAKE32(2) 47 | #define M_TC_VERD _TC_MAKEMASK(4,S_TC_VERD) 48 | #define G_TC_VERD(x) _TC_GETVALUE(x,S_TC_VERD,M_TC_VERD) 49 | #define V_TC_VERD(x) _TC_MAKEVALUE(x,S_TC_VERD) 50 | #define SET_TC_VERD(v,n) ((V_TC_VERD(n)) | (v & ~M_TC_VERD)) 51 | 52 | #define S_TC_FROM _TC_MAKE32(6) 53 | #define M_TC_FROM _TC_MAKEMASK(2,S_TC_FROM) 54 | #define G_TC_FROM(x) _TC_GETVALUE(x,S_TC_FROM,M_TC_FROM) 55 | #define V_TC_FROM(x) _TC_MAKEVALUE(x,S_TC_FROM) 56 | #define SET_TC_FROM(v,n) ((V_TC_FROM(n)) | (v & ~M_TC_FROM)) 57 | #define AT_STACK 0x0 58 | #define AT_INGRESS 0x1 59 | #define AT_EGRESS 0x2 60 | 61 | #define TC_NCLS _TC_MAKEMASK1(8) 62 | #define SET_TC_NCLS(v) ( TC_NCLS | (v & ~TC_NCLS)) 63 | #define CLR_TC_NCLS(v) ( v & ~TC_NCLS) 64 | 65 | #define S_TC_RTTL _TC_MAKE32(9) 66 | #define M_TC_RTTL _TC_MAKEMASK(3,S_TC_RTTL) 67 | #define G_TC_RTTL(x) _TC_GETVALUE(x,S_TC_RTTL,M_TC_RTTL) 68 | #define V_TC_RTTL(x) _TC_MAKEVALUE(x,S_TC_RTTL) 69 | #define SET_TC_RTTL(v,n) ((V_TC_RTTL(n)) | (v & ~M_TC_RTTL)) 70 | 71 | #define S_TC_AT _TC_MAKE32(12) 72 | #define M_TC_AT _TC_MAKEMASK(2,S_TC_AT) 73 | #define G_TC_AT(x) _TC_GETVALUE(x,S_TC_AT,M_TC_AT) 74 | #define V_TC_AT(x) _TC_MAKEVALUE(x,S_TC_AT) 75 | #define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT)) 76 | 77 | /* Action attributes */ 78 | enum { 79 | TCA_ACT_UNSPEC, 80 | TCA_ACT_KIND, 81 | TCA_ACT_OPTIONS, 82 | TCA_ACT_INDEX, 83 | TCA_ACT_STATS, 84 | __TCA_ACT_MAX 85 | }; 86 | 87 | #define TCA_ACT_MAX __TCA_ACT_MAX 88 | #define TCA_OLD_COMPAT (TCA_ACT_MAX+1) 89 | #define TCA_ACT_MAX_PRIO 32 90 | #define TCA_ACT_BIND 1 91 | #define TCA_ACT_NOBIND 0 92 | #define TCA_ACT_UNBIND 1 93 | #define TCA_ACT_NOUNBIND 0 94 | #define TCA_ACT_REPLACE 1 95 | #define TCA_ACT_NOREPLACE 0 96 | #define MAX_REC_LOOP 4 97 | #define MAX_RED_LOOP 4 98 | 99 | #define TC_ACT_UNSPEC (-1) 100 | #define TC_ACT_OK 0 101 | #define TC_ACT_RECLASSIFY 1 102 | #define TC_ACT_SHOT 2 103 | #define TC_ACT_PIPE 3 104 | #define TC_ACT_STOLEN 4 105 | #define TC_ACT_QUEUED 5 106 | #define TC_ACT_REPEAT 6 107 | #define TC_ACT_JUMP 0x10000000 108 | 109 | /* Action type identifiers*/ 110 | enum { 111 | TCA_ID_UNSPEC=0, 112 | TCA_ID_POLICE=1, 113 | /* other actions go here */ 114 | __TCA_ID_MAX=255 115 | }; 116 | 117 | #define TCA_ID_MAX __TCA_ID_MAX 118 | 119 | struct tc_police { 120 | __u32 index; 121 | int action; 122 | #define TC_POLICE_UNSPEC TC_ACT_UNSPEC 123 | #define TC_POLICE_OK TC_ACT_OK 124 | #define TC_POLICE_RECLASSIFY TC_ACT_RECLASSIFY 125 | #define TC_POLICE_SHOT TC_ACT_SHOT 126 | #define TC_POLICE_PIPE TC_ACT_PIPE 127 | 128 | __u32 limit; 129 | __u32 burst; 130 | __u32 mtu; 131 | struct tc_ratespec rate; 132 | struct tc_ratespec peakrate; 133 | int refcnt; 134 | int bindcnt; 135 | __u32 capab; 136 | }; 137 | 138 | struct tcf_t { 139 | __u64 install; 140 | __u64 lastuse; 141 | __u64 expires; 142 | }; 143 | 144 | struct tc_cnt { 145 | int refcnt; 146 | int bindcnt; 147 | }; 148 | 149 | #define tc_gen \ 150 | __u32 index; \ 151 | __u32 capab; \ 152 | int action; \ 153 | int refcnt; \ 154 | int bindcnt 155 | 156 | enum { 157 | TCA_POLICE_UNSPEC, 158 | TCA_POLICE_TBF, 159 | TCA_POLICE_RATE, 160 | TCA_POLICE_PEAKRATE, 161 | TCA_POLICE_AVRATE, 162 | TCA_POLICE_RESULT, 163 | __TCA_POLICE_MAX 164 | #define TCA_POLICE_RESULT TCA_POLICE_RESULT 165 | }; 166 | 167 | #define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1) 168 | 169 | /* U32 filters */ 170 | 171 | #define TC_U32_HTID(h) ((h)&0xFFF00000) 172 | #define TC_U32_USERHTID(h) (TC_U32_HTID(h)>>20) 173 | #define TC_U32_HASH(h) (((h)>>12)&0xFF) 174 | #define TC_U32_NODE(h) ((h)&0xFFF) 175 | #define TC_U32_KEY(h) ((h)&0xFFFFF) 176 | #define TC_U32_UNSPEC 0 177 | #define TC_U32_ROOT (0xFFF00000) 178 | 179 | enum { 180 | TCA_U32_UNSPEC, 181 | TCA_U32_CLASSID, 182 | TCA_U32_HASH, 183 | TCA_U32_LINK, 184 | TCA_U32_DIVISOR, 185 | TCA_U32_SEL, 186 | TCA_U32_POLICE, 187 | TCA_U32_ACT, 188 | TCA_U32_INDEV, 189 | TCA_U32_PCNT, 190 | TCA_U32_MARK, 191 | __TCA_U32_MAX 192 | }; 193 | 194 | #define TCA_U32_MAX (__TCA_U32_MAX - 1) 195 | 196 | struct tc_u32_key { 197 | __be32 mask; 198 | __be32 val; 199 | int off; 200 | int offmask; 201 | }; 202 | 203 | struct tc_u32_sel { 204 | unsigned char flags; 205 | unsigned char offshift; 206 | unsigned char nkeys; 207 | 208 | __be16 offmask; 209 | __u16 off; 210 | short offoff; 211 | 212 | short hoff; 213 | __be32 hmask; 214 | struct tc_u32_key keys[0]; 215 | }; 216 | 217 | struct tc_u32_mark { 218 | __u32 val; 219 | __u32 mask; 220 | __u32 success; 221 | }; 222 | 223 | struct tc_u32_pcnt { 224 | __u64 rcnt; 225 | __u64 rhit; 226 | __u64 kcnts[0]; 227 | }; 228 | 229 | /* Flags */ 230 | 231 | #define TC_U32_TERMINAL 1 232 | #define TC_U32_OFFSET 2 233 | #define TC_U32_VAROFFSET 4 234 | #define TC_U32_EAT 8 235 | 236 | #define TC_U32_MAXDEPTH 8 237 | 238 | 239 | /* RSVP filter */ 240 | 241 | enum { 242 | TCA_RSVP_UNSPEC, 243 | TCA_RSVP_CLASSID, 244 | TCA_RSVP_DST, 245 | TCA_RSVP_SRC, 246 | TCA_RSVP_PINFO, 247 | TCA_RSVP_POLICE, 248 | TCA_RSVP_ACT, 249 | __TCA_RSVP_MAX 250 | }; 251 | 252 | #define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1 ) 253 | 254 | struct tc_rsvp_gpi { 255 | __u32 key; 256 | __u32 mask; 257 | int offset; 258 | }; 259 | 260 | struct tc_rsvp_pinfo { 261 | struct tc_rsvp_gpi dpi; 262 | struct tc_rsvp_gpi spi; 263 | __u8 protocol; 264 | __u8 tunnelid; 265 | __u8 tunnelhdr; 266 | __u8 pad; 267 | }; 268 | 269 | /* ROUTE filter */ 270 | 271 | enum { 272 | TCA_ROUTE4_UNSPEC, 273 | TCA_ROUTE4_CLASSID, 274 | TCA_ROUTE4_TO, 275 | TCA_ROUTE4_FROM, 276 | TCA_ROUTE4_IIF, 277 | TCA_ROUTE4_POLICE, 278 | TCA_ROUTE4_ACT, 279 | __TCA_ROUTE4_MAX 280 | }; 281 | 282 | #define TCA_ROUTE4_MAX (__TCA_ROUTE4_MAX - 1) 283 | 284 | 285 | /* FW filter */ 286 | 287 | enum { 288 | TCA_FW_UNSPEC, 289 | TCA_FW_CLASSID, 290 | TCA_FW_POLICE, 291 | TCA_FW_INDEV, /* used by CONFIG_NET_CLS_IND */ 292 | TCA_FW_ACT, /* used by CONFIG_NET_CLS_ACT */ 293 | TCA_FW_MASK, 294 | __TCA_FW_MAX 295 | }; 296 | 297 | #define TCA_FW_MAX (__TCA_FW_MAX - 1) 298 | 299 | /* TC index filter */ 300 | 301 | enum { 302 | TCA_TCINDEX_UNSPEC, 303 | TCA_TCINDEX_HASH, 304 | TCA_TCINDEX_MASK, 305 | TCA_TCINDEX_SHIFT, 306 | TCA_TCINDEX_FALL_THROUGH, 307 | TCA_TCINDEX_CLASSID, 308 | TCA_TCINDEX_POLICE, 309 | TCA_TCINDEX_ACT, 310 | __TCA_TCINDEX_MAX 311 | }; 312 | 313 | #define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1) 314 | 315 | /* Flow filter */ 316 | 317 | enum { 318 | FLOW_KEY_SRC, 319 | FLOW_KEY_DST, 320 | FLOW_KEY_PROTO, 321 | FLOW_KEY_PROTO_SRC, 322 | FLOW_KEY_PROTO_DST, 323 | FLOW_KEY_IIF, 324 | FLOW_KEY_PRIORITY, 325 | FLOW_KEY_MARK, 326 | FLOW_KEY_NFCT, 327 | FLOW_KEY_NFCT_SRC, 328 | FLOW_KEY_NFCT_DST, 329 | FLOW_KEY_NFCT_PROTO_SRC, 330 | FLOW_KEY_NFCT_PROTO_DST, 331 | FLOW_KEY_RTCLASSID, 332 | FLOW_KEY_SKUID, 333 | FLOW_KEY_SKGID, 334 | FLOW_KEY_VLAN_TAG, 335 | FLOW_KEY_RXHASH, 336 | __FLOW_KEY_MAX, 337 | }; 338 | 339 | #define FLOW_KEY_MAX (__FLOW_KEY_MAX - 1) 340 | 341 | enum { 342 | FLOW_MODE_MAP, 343 | FLOW_MODE_HASH, 344 | }; 345 | 346 | enum { 347 | TCA_FLOW_UNSPEC, 348 | TCA_FLOW_KEYS, 349 | TCA_FLOW_MODE, 350 | TCA_FLOW_BASECLASS, 351 | TCA_FLOW_RSHIFT, 352 | TCA_FLOW_ADDEND, 353 | TCA_FLOW_MASK, 354 | TCA_FLOW_XOR, 355 | TCA_FLOW_DIVISOR, 356 | TCA_FLOW_ACT, 357 | TCA_FLOW_POLICE, 358 | TCA_FLOW_EMATCHES, 359 | TCA_FLOW_PERTURB, 360 | __TCA_FLOW_MAX 361 | }; 362 | 363 | #define TCA_FLOW_MAX (__TCA_FLOW_MAX - 1) 364 | 365 | /* Basic filter */ 366 | 367 | enum { 368 | TCA_BASIC_UNSPEC, 369 | TCA_BASIC_CLASSID, 370 | TCA_BASIC_EMATCHES, 371 | TCA_BASIC_ACT, 372 | TCA_BASIC_POLICE, 373 | __TCA_BASIC_MAX 374 | }; 375 | 376 | #define TCA_BASIC_MAX (__TCA_BASIC_MAX - 1) 377 | 378 | 379 | /* Cgroup classifier */ 380 | 381 | enum { 382 | TCA_CGROUP_UNSPEC, 383 | TCA_CGROUP_ACT, 384 | TCA_CGROUP_POLICE, 385 | TCA_CGROUP_EMATCHES, 386 | __TCA_CGROUP_MAX, 387 | }; 388 | 389 | #define TCA_CGROUP_MAX (__TCA_CGROUP_MAX - 1) 390 | 391 | /* BPF classifier */ 392 | 393 | enum { 394 | TCA_BPF_UNSPEC, 395 | TCA_BPF_ACT, 396 | TCA_BPF_POLICE, 397 | TCA_BPF_CLASSID, 398 | TCA_BPF_OPS_LEN, 399 | TCA_BPF_OPS, 400 | __TCA_BPF_MAX, 401 | }; 402 | 403 | #define TCA_BPF_MAX (__TCA_BPF_MAX - 1) 404 | 405 | /* Extended Matches */ 406 | 407 | struct tcf_ematch_tree_hdr { 408 | __u16 nmatches; 409 | __u16 progid; 410 | }; 411 | 412 | enum { 413 | TCA_EMATCH_TREE_UNSPEC, 414 | TCA_EMATCH_TREE_HDR, 415 | TCA_EMATCH_TREE_LIST, 416 | __TCA_EMATCH_TREE_MAX 417 | }; 418 | #define TCA_EMATCH_TREE_MAX (__TCA_EMATCH_TREE_MAX - 1) 419 | 420 | struct tcf_ematch_hdr { 421 | __u16 matchid; 422 | __u16 kind; 423 | __u16 flags; 424 | __u16 pad; /* currently unused */ 425 | }; 426 | 427 | /* 0 1 428 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 429 | * +-----------------------+-+-+---+ 430 | * | Unused |S|I| R | 431 | * +-----------------------+-+-+---+ 432 | * 433 | * R(2) ::= relation to next ematch 434 | * where: 0 0 END (last ematch) 435 | * 0 1 AND 436 | * 1 0 OR 437 | * 1 1 Unused (invalid) 438 | * I(1) ::= invert result 439 | * S(1) ::= simple payload 440 | */ 441 | #define TCF_EM_REL_END 0 442 | #define TCF_EM_REL_AND (1<<0) 443 | #define TCF_EM_REL_OR (1<<1) 444 | #define TCF_EM_INVERT (1<<2) 445 | #define TCF_EM_SIMPLE (1<<3) 446 | 447 | #define TCF_EM_REL_MASK 3 448 | #define TCF_EM_REL_VALID(v) (((v) & TCF_EM_REL_MASK) != TCF_EM_REL_MASK) 449 | 450 | enum { 451 | TCF_LAYER_LINK, 452 | TCF_LAYER_NETWORK, 453 | TCF_LAYER_TRANSPORT, 454 | __TCF_LAYER_MAX 455 | }; 456 | #define TCF_LAYER_MAX (__TCF_LAYER_MAX - 1) 457 | 458 | /* Ematch type assignments 459 | * 1..32767 Reserved for ematches inside kernel tree 460 | * 32768..65535 Free to use, not reliable 461 | */ 462 | #define TCF_EM_CONTAINER 0 463 | #define TCF_EM_CMP 1 464 | #define TCF_EM_NBYTE 2 465 | #define TCF_EM_U32 3 466 | #define TCF_EM_META 4 467 | #define TCF_EM_TEXT 5 468 | #define TCF_EM_VLAN 6 469 | #define TCF_EM_CANID 7 470 | #define TCF_EM_IPSET 8 471 | #define TCF_EM_MAX 8 472 | 473 | enum { 474 | TCF_EM_PROG_TC 475 | }; 476 | 477 | enum { 478 | TCF_EM_OPND_EQ, 479 | TCF_EM_OPND_GT, 480 | TCF_EM_OPND_LT 481 | }; 482 | 483 | #endif 484 | -------------------------------------------------------------------------------- /package/simple-tc/src/simple-tc.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014, Matthias Schiffer 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | 27 | #define _GNU_SOURCE 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | 48 | #include 49 | #include 50 | #include 51 | 52 | 53 | static struct nl_cb *cb; 54 | static struct nl_sock *sock; 55 | static double ticks; 56 | 57 | static unsigned ifindex; 58 | 59 | static bool nlexpect; 60 | static int nlerror; 61 | 62 | 63 | static inline void exit_errno(const char *message) { 64 | fprintf(stderr, "error: %s: %s\n", message, strerror(errno)); 65 | exit(1); 66 | } 67 | 68 | static inline void warn_errno(const char *message) { 69 | fprintf(stderr, "warning: %s: %s\n", message, strerror(errno)); 70 | } 71 | 72 | 73 | static void read_psched(void) { 74 | uint32_t clock_res; 75 | uint32_t t2us; 76 | uint32_t us2t; 77 | 78 | FILE *f = fopen("/proc/net/psched", "r"); 79 | if (!f || fscanf(f, "%08x %08x %08x", &t2us, &us2t, &clock_res) != 3) 80 | exit_errno("error reading /proc/net/psched"); 81 | fclose(f); 82 | 83 | /* compatibility hack from iproute... */ 84 | if (clock_res == 1000000000) 85 | t2us = us2t; 86 | 87 | ticks = (double)t2us / us2t * clock_res; 88 | } 89 | 90 | 91 | static struct nl_msg * prepare_tcmsg(int type, int flags, uint32_t parent, uint32_t handle, uint32_t info) { 92 | struct nl_msg *msg = nlmsg_alloc_simple(type, flags); 93 | if (!msg) 94 | exit_errno("nlmsg_alloc_simple"); 95 | 96 | struct tcmsg tcmsg; 97 | memset(&tcmsg, 0, sizeof(tcmsg)); 98 | 99 | tcmsg.tcm_family = AF_UNSPEC; 100 | tcmsg.tcm_ifindex = ifindex; 101 | tcmsg.tcm_parent = parent; 102 | tcmsg.tcm_handle = handle; 103 | tcmsg.tcm_info = info; 104 | 105 | nlmsg_append(msg, &tcmsg, sizeof(tcmsg), NLMSG_ALIGNTO); 106 | 107 | return msg; 108 | } 109 | 110 | 111 | static int error_handler(struct sockaddr_nl *nla __attribute__((unused)), struct nlmsgerr *nlerr, void *arg __attribute__((unused))) { 112 | if (!nlexpect || (nlerr->error != -ENOENT && nlerr->error != -EINVAL)) 113 | nlerror = -nlerr->error; 114 | 115 | return NL_STOP; 116 | } 117 | 118 | static bool do_send(struct nl_msg *msg, bool expect) { 119 | nlerror = 0; 120 | nlexpect = expect; 121 | 122 | nl_send_auto_complete(sock, msg); 123 | nlmsg_free(msg); 124 | nl_wait_for_ack(sock); 125 | 126 | if (nlerror) { 127 | errno = nlerror; 128 | warn_errno("netlink"); 129 | return false; 130 | } 131 | 132 | return true; 133 | } 134 | 135 | 136 | static inline unsigned get_xmittime(double rate, unsigned size) { 137 | return ticks * (size/rate); 138 | } 139 | 140 | 141 | static void complete_rate(struct tc_ratespec *r, uint32_t rtab[256]) { 142 | r->linklayer = TC_LINKLAYER_ETHERNET; 143 | r->cell_align = -1; 144 | r->cell_log = 3; 145 | 146 | unsigned i; 147 | for (i = 0; i < 256; i++) 148 | rtab[i] = get_xmittime(r->rate, (i + 1) << 3); 149 | } 150 | 151 | 152 | static void do_ingress(double rate) { 153 | if (!do_send(prepare_tcmsg(RTM_DELQDISC, 0, TC_H_INGRESS, 0xffff0000, 0), true)) 154 | return; 155 | 156 | if (rate < 0) 157 | return; 158 | 159 | 160 | struct nl_msg *msg = prepare_tcmsg(RTM_NEWQDISC, NLM_F_CREATE | NLM_F_EXCL, TC_H_INGRESS, 0xffff0000, 0); 161 | nla_put_string(msg, TCA_KIND, "ingress"); 162 | 163 | if (!do_send(msg, false)) 164 | return; 165 | 166 | 167 | msg = prepare_tcmsg(RTM_NEWTFILTER, NLM_F_CREATE | NLM_F_EXCL, 0xffff0000, 0, TC_H_MAKE(0, htons(ETH_P_ALL))); 168 | 169 | const unsigned buffer = 10240; 170 | 171 | struct tc_police p; 172 | memset(&p, 0, sizeof(p)); 173 | 174 | /* Range check has been done in main() */ 175 | p.rate.rate = rate; 176 | p.burst = get_xmittime(p.rate.rate, buffer); 177 | p.action = TC_POLICE_SHOT; 178 | 179 | uint32_t rtab[256]; 180 | complete_rate(&p.rate, rtab); 181 | 182 | nla_put_string(msg, TCA_KIND, "basic"); 183 | 184 | struct nlattr *opts = nla_nest_start(msg, TCA_OPTIONS); 185 | struct nlattr *police = nla_nest_start(msg, TCA_BASIC_POLICE); 186 | 187 | nla_put(msg, TCA_POLICE_TBF, sizeof(p), &p); 188 | nla_put(msg, TCA_POLICE_RATE, sizeof(rtab), rtab); 189 | 190 | nla_nest_end(msg, police); 191 | nla_nest_end(msg, opts); 192 | 193 | do_send(msg, false); 194 | } 195 | 196 | static void do_egress(double rate) { 197 | if (!do_send(prepare_tcmsg(RTM_DELQDISC, 0, TC_H_ROOT, 0, 0), true)) 198 | return; 199 | 200 | if (rate < 0) 201 | return; 202 | 203 | 204 | struct nl_msg *msg = prepare_tcmsg(RTM_NEWQDISC, NLM_F_CREATE | NLM_F_EXCL, TC_H_ROOT, 0, 0); 205 | const unsigned buffer = 2048; 206 | 207 | struct tc_tbf_qopt opt; 208 | memset(&opt, 0, sizeof(opt)); 209 | 210 | /* Range check has been done in main() */ 211 | opt.rate.rate = rate; 212 | opt.limit = 0.05*rate + buffer; 213 | opt.buffer = get_xmittime(opt.rate.rate, buffer); 214 | 215 | uint32_t rtab[256]; 216 | complete_rate(&opt.rate, rtab); 217 | 218 | nla_put_string(msg, TCA_KIND, "tbf"); 219 | 220 | struct nlattr *opts = nla_nest_start(msg, TCA_OPTIONS); 221 | nla_put(msg, TCA_TBF_PARMS, sizeof(opt), &opt); 222 | nla_put(msg, TCA_TBF_BURST, sizeof(buffer), &buffer); 223 | nla_put(msg, TCA_TBF_RTAB, sizeof(rtab), rtab); 224 | nla_nest_end(msg, opts); 225 | 226 | do_send(msg, false); 227 | } 228 | 229 | 230 | static inline void usage(void) { 231 | fprintf(stderr, "Usage: simple-tc |- |-\n"); 232 | exit(1); 233 | } 234 | 235 | static inline void maxrate(void) { 236 | fprintf(stderr, "error: maximum allowed rate it about 2^25 Kbit/s"); 237 | exit(1); 238 | } 239 | 240 | 241 | int main(int argc, char *argv[]) { 242 | if (argc != 4) 243 | usage(); 244 | 245 | double ingress = -1, egress = -1; 246 | char *end; 247 | 248 | ifindex = if_nametoindex(argv[1]); 249 | if (!ifindex) { 250 | fprintf(stderr, "invalid interface: %s", argv[1]); 251 | exit(1); 252 | } 253 | 254 | if (strcmp(argv[2], "-") != 0) { 255 | ingress = strtod(argv[2], &end); 256 | if (*end || ingress < 0) 257 | usage(); 258 | 259 | ingress *= 125; 260 | 261 | if (ingress >= (1ull << 32)) 262 | maxrate(); 263 | } 264 | 265 | if (strcmp(argv[3], "-") != 0) { 266 | egress = strtod(argv[3], &end); 267 | if (*end || egress < 0) 268 | usage(); 269 | 270 | egress *= 125; 271 | 272 | if (egress >= (1ull << 32)) 273 | maxrate(); 274 | } 275 | 276 | read_psched(); 277 | 278 | cb = nl_cb_alloc(NL_CB_DEFAULT); 279 | nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL); 280 | 281 | sock = nl_socket_alloc_cb(cb); 282 | if (!sock) 283 | exit_errno("nl_socket_alloc"); 284 | 285 | if (nl_connect(sock, NETLINK_ROUTE)) 286 | exit_errno("nl_connect"); 287 | 288 | do_ingress(ingress); 289 | do_egress(egress); 290 | 291 | nl_socket_free(sock); 292 | nl_cb_put(cb); 293 | 294 | return 0; 295 | } 296 | -------------------------------------------------------------------------------- /package/sockread/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This software is licensed under the CC0-1.0 license. 3 | # 4 | include $(TOPDIR)/rules.mk 5 | 6 | PKG_NAME:=sockread 7 | PKG_VERSION:=1.0 8 | PKG_RELEASE:=1 9 | PKG_LICENSE:=CC0-1.0 10 | 11 | include $(INCLUDE_DIR)/package.mk 12 | 13 | define Package/sockread 14 | SECTION:=utils 15 | CATEGORY:=Utilities 16 | TITLE:=Read data from a Unix domain socket. 17 | endef 18 | 19 | define Package/sockread/description 20 | sockread reads data from a Unix domain socket 21 | represented as a special file on the file system. 22 | endef 23 | 24 | define Build/Prepare 25 | mkdir -p $(PKG_BUILD_DIR) 26 | $(CP) ./src/* $(PKG_BUILD_DIR)/ 27 | endef 28 | 29 | define Package/sockread/install 30 | $(INSTALL_DIR) $(1)/usr/bin 31 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/sockread $(1)/usr/bin/ 32 | endef 33 | 34 | $(eval $(call BuildPackage,sockread)) 35 | -------------------------------------------------------------------------------- /package/sockread/src/Makefile: -------------------------------------------------------------------------------- 1 | CC ?= gcc 2 | CFLAGS ?= -O2 -Wall -pedantic 3 | CFLAGS += -std=gnu99 4 | 5 | .PHONY: clean 6 | 7 | sockread: 8 | $(CC) $(CFLAGS) main.c -o sockread 9 | 10 | clean: 11 | rm -f sockread 12 | -------------------------------------------------------------------------------- /package/sockread/src/main.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | int main(int argc, char *argv[]) { 13 | if (argc != 2) { 14 | fprintf(stderr, "Usage: %s \n", argv[0]); 15 | return 1; 16 | } 17 | 18 | size_t addrlen = strlen(argv[1]); 19 | 20 | /* Allocate enough space for arbitrary-length paths */ 21 | char addrbuf[offsetof(struct sockaddr_un, sun_path) + addrlen + 1]; 22 | memset(addrbuf, 0, sizeof(addrbuf)); 23 | 24 | struct sockaddr_un *addr = (struct sockaddr_un *)addrbuf; 25 | addr->sun_family = AF_UNIX; 26 | memcpy(addr->sun_path, argv[1], addrlen+1); 27 | 28 | int fd = socket(AF_UNIX, SOCK_STREAM, 0); 29 | if (fd < 0) { 30 | fprintf(stderr, "Failed to create socket: %s\n", strerror(errno)); 31 | return 1; 32 | } 33 | 34 | if (connect(fd, (struct sockaddr*)addr, sizeof(addrbuf)) < 0) { 35 | fprintf(stderr, "Can't connect to `%s': %s\n", argv[1], strerror(errno)); 36 | return 1; 37 | } 38 | 39 | char buf[1024]; 40 | ssize_t r; 41 | while (1) { 42 | r = recv(fd, buf, sizeof(buf), 0); 43 | if (r < 0) { 44 | fprintf(stderr, "read: %s\n", strerror(errno)); 45 | return 1; 46 | } 47 | 48 | if (r == 0) 49 | return 0; 50 | 51 | fwrite(buf, r, 1, stdout); 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /patches/openwrt/0001-procd-add-support-for-alternative-rc.d-directories.patch: -------------------------------------------------------------------------------- 1 | From ab238e0240b007bc845097e24fdda3ffe2886c14 Mon Sep 17 00:00:00 2001 2 | From: Matthias Schiffer 3 | Date: Wed, 6 Aug 2014 19:12:00 +0200 4 | Subject: [PATCH 01/16] procd: add support for alternative rc.d directories 5 | 6 | --- 7 | ...ort-for-alternative-rc.d-directories.patch | 80 +++++++++++++++++++ 8 | 1 file changed, 80 insertions(+) 9 | create mode 100644 package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch 10 | 11 | diff --git a/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch 12 | new file mode 100644 13 | index 0000000000..16d3179f05 14 | --- /dev/null 15 | +++ b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch 16 | @@ -0,0 +1,80 @@ 17 | +From 03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d Mon Sep 17 00:00:00 2001 18 | +Message-Id: <03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d.1407329621.git.mschiffer@universe-factory.net> 19 | +From: Matthias Schiffer 20 | +Date: Wed, 6 Aug 2014 14:51:49 +0200 21 | +Subject: [PATCH] Add support for alternative rc.d directories 22 | + 23 | +--- 24 | + initd/preinit.c | 38 ++++++++++++++++++++++++++++++++++++++ 25 | + rcS.c | 2 +- 26 | + 2 files changed, 39 insertions(+), 1 deletion(-) 27 | + 28 | +--- a/initd/preinit.c 29 | ++++ b/initd/preinit.c 30 | +@@ -87,12 +87,42 @@ fail: 31 | + free(command); 32 | + } 33 | + 34 | ++static char* 35 | ++get_rc_d(void) 36 | ++{ 37 | ++ size_t n = 0; 38 | ++ ssize_t len; 39 | ++ char *ret = NULL; 40 | ++ 41 | ++ FILE *fp = fopen("/tmp/rc_d_path", "r"); 42 | ++ 43 | ++ if (!fp) 44 | ++ return NULL; 45 | ++ 46 | ++ len = getline(&ret, &n, fp); 47 | ++ 48 | ++ fclose(fp); 49 | ++ 50 | ++ unlink("/tmp/rc_d_path"); 51 | ++ 52 | ++ if (len <= 0) { 53 | ++ free(ret); 54 | ++ return NULL; 55 | ++ } 56 | ++ 57 | ++ if (ret[len-1] == '\n') 58 | ++ ret[len-1] = 0; 59 | ++ 60 | ++ return ret; 61 | ++} 62 | ++ 63 | + static void 64 | + spawn_procd(struct uloop_process *proc, int ret) 65 | + { 66 | + char *wdt_fd = watchdog_fd(); 67 | + char *argv[] = { "/sbin/procd", NULL}; 68 | + char dbg[2]; 69 | ++ char *rc_d_path; 70 | + 71 | + if (plugd_proc.pid > 0) 72 | + kill(plugd_proc.pid, SIGKILL); 73 | +@@ -112,6 +142,12 @@ spawn_procd(struct uloop_process *proc, 74 | + setenv("DBGLVL", dbg, 1); 75 | + } 76 | + 77 | ++ rc_d_path = get_rc_d(); 78 | ++ if (rc_d_path) { 79 | ++ setenv("RC_D_PATH", rc_d_path, 1); 80 | ++ free(rc_d_path); 81 | ++ } 82 | ++ 83 | + execvp(argv[0], argv); 84 | + } 85 | + 86 | +--- a/rcS.c 87 | ++++ b/rcS.c 88 | +@@ -184,7 +184,7 @@ int rcS(char *pattern, char *param, void 89 | + q.empty_cb = q_empty; 90 | + q.max_running_tasks = 1; 91 | + 92 | +- return _rc(&q, "/etc/rc.d", pattern, "*", param); 93 | ++ return _rc(&q, getenv("RC_D_PATH") ?: "/etc/rc.d", pattern, "*", param); 94 | + } 95 | + 96 | + int rc(const char *file, char *param) 97 | -- 98 | 2.30.0 99 | 100 | -------------------------------------------------------------------------------- /patches/openwrt/0002-base-files-disable-reset-button-handling.patch: -------------------------------------------------------------------------------- 1 | From 83e2d2a61a074534ffc8dc512c53a6152cef2efc Mon Sep 17 00:00:00 2001 2 | From: Matthias Schiffer 3 | Date: Sat, 21 Mar 2015 16:40:52 +0100 4 | Subject: [PATCH 02/16] base-files: disable reset button handling 5 | 6 | This conflicts with our reset button usage. 7 | --- 8 | package/base-files/files/etc/rc.button/reset | 31 -------------------- 9 | 1 file changed, 31 deletions(-) 10 | delete mode 100755 package/base-files/files/etc/rc.button/reset 11 | 12 | diff --git a/package/base-files/files/etc/rc.button/reset b/package/base-files/files/etc/rc.button/reset 13 | deleted file mode 100755 14 | index 2403122ad2..0000000000 15 | --- a/package/base-files/files/etc/rc.button/reset 16 | +++ /dev/null 17 | @@ -1,31 +0,0 @@ 18 | -#!/bin/sh 19 | - 20 | -. /lib/functions.sh 21 | - 22 | -OVERLAY="$( grep ' /overlay ' /proc/mounts )" 23 | - 24 | -case "$ACTION" in 25 | -pressed) 26 | - [ -z "$OVERLAY" ] && return 0 27 | - 28 | - return 5 29 | -;; 30 | -timeout) 31 | - . /etc/diag.sh 32 | - set_state failsafe 33 | -;; 34 | -released) 35 | - if [ "$SEEN" -lt 1 ] 36 | - then 37 | - echo "REBOOT" > /dev/console 38 | - sync 39 | - reboot 40 | - elif [ "$SEEN" -ge 5 -a -n "$OVERLAY" ] 41 | - then 42 | - echo "FACTORY RESET" > /dev/console 43 | - jffs2reset -y && reboot & 44 | - fi 45 | -;; 46 | -esac 47 | - 48 | -return 0 49 | -- 50 | 2.30.0 51 | 52 | -------------------------------------------------------------------------------- /patches/openwrt/0003-libjson-c-Add-support-for-custom-format-strings-for-.patch: -------------------------------------------------------------------------------- 1 | From 623f9220b5a63ff0ab50c7db17a54d5f98421fa1 Mon Sep 17 00:00:00 2001 2 | From: Jan-Philipp Litza 3 | Date: Fri, 6 May 2016 16:44:29 +0200 4 | Subject: [PATCH 03/16] libjson-c: Add support for custom format strings for 5 | doubles 6 | 7 | --- 8 | .../patches/002-custom-format-string.patch | 91 +++++++++++++++++++ 9 | 1 file changed, 91 insertions(+) 10 | create mode 100644 package/libs/libjson-c/patches/002-custom-format-string.patch 11 | 12 | diff --git a/package/libs/libjson-c/patches/002-custom-format-string.patch b/package/libs/libjson-c/patches/002-custom-format-string.patch 13 | new file mode 100644 14 | index 0000000000..b67433a7ba 15 | --- /dev/null 16 | +++ b/package/libs/libjson-c/patches/002-custom-format-string.patch 17 | @@ -0,0 +1,91 @@ 18 | +From 21dc5dc92bd56f5f4dc2c90b9ea6bf1e1407714e Mon Sep 17 00:00:00 2001 19 | +From: Jan-Philipp Litza 20 | +Date: Fri, 6 May 2016 16:12:44 +0200 21 | +Subject: [PATCH] Export json_object_double_to_json_string() and use custom 22 | + format string 23 | +BCC: janphilipp@litza.de 24 | + 25 | +--- 26 | + json_object.c | 12 ++++++------ 27 | + json_object.h | 28 ++++++++++++++++++++++++++++ 28 | + 2 files changed, 34 insertions(+), 6 deletions(-) 29 | + 30 | +--- a/json_object.c 31 | ++++ b/json_object.c 32 | +@@ -55,7 +55,6 @@ static struct json_object* json_object_n 33 | + static json_object_to_json_string_fn json_object_object_to_json_string; 34 | + static json_object_to_json_string_fn json_object_boolean_to_json_string; 35 | + static json_object_to_json_string_fn json_object_int_to_json_string; 36 | +-static json_object_to_json_string_fn json_object_double_to_json_string; 37 | + static json_object_to_json_string_fn json_object_string_to_json_string; 38 | + static json_object_to_json_string_fn json_object_array_to_json_string; 39 | + 40 | +@@ -560,10 +559,10 @@ int64_t json_object_get_int64(struct jso 41 | + 42 | + /* json_object_double */ 43 | + 44 | +-static int json_object_double_to_json_string(struct json_object* jso, 45 | +- struct printbuf *pb, 46 | +- int level, 47 | +- int flags) 48 | ++int json_object_double_to_json_string(struct json_object* jso, 49 | ++ struct printbuf *pb, 50 | ++ int level, 51 | ++ int flags) 52 | + { 53 | + char buf[128], *p, *q; 54 | + int size; 55 | +@@ -579,7 +578,8 @@ static int json_object_double_to_json_st 56 | + else 57 | + size = snprintf(buf, sizeof(buf), "-Infinity"); 58 | + else 59 | +- size = snprintf(buf, sizeof(buf), "%.17g", jso->o.c_double); 60 | ++ size = snprintf(buf, sizeof(buf), 61 | ++ jso->_userdata ? (const char*) jso->_userdata : "%.17g", jso->o.c_double); 62 | + 63 | + p = strchr(buf, ','); 64 | + if (p) { 65 | +--- a/json_object.h 66 | ++++ b/json_object.h 67 | +@@ -515,6 +515,9 @@ extern int64_t json_object_get_int64(str 68 | + /* double type methods */ 69 | + 70 | + /** Create a new empty json_object of type json_type_double 71 | ++ * 72 | ++ * @see json_object_double_to_json_string() for how to set a custom format string. 73 | ++ * 74 | + * @param d the double 75 | + * @returns a json_object of type json_type_double 76 | + */ 77 | +@@ -543,6 +546,31 @@ extern struct json_object* json_object_n 78 | + */ 79 | + extern struct json_object* json_object_new_double_s(double d, const char *ds); 80 | + 81 | ++ 82 | ++/** Serialize a json_object of type json_type_double to a string. 83 | ++ * 84 | ++ * This function isn't meant to be called directly. Instead, you can set a 85 | ++ * custom format string for the serialization of this double using the 86 | ++ * following call (where "%.17g" actually is the default): 87 | ++ * 88 | ++ * @code 89 | ++ * jso = json_object_new_double(d); 90 | ++ * json_object_set_serializer(jso, json_object_double_to_json_string, 91 | ++ * "%.17g", NULL); 92 | ++ * @endcode 93 | ++ * 94 | ++ * @see printf(3) man page for format strings 95 | ++ * 96 | ++ * @param jso The json_type_double object that is serialized. 97 | ++ * @param pb The destination buffer. 98 | ++ * @param level Ignored. 99 | ++ * @param flags Ignored. 100 | ++ */ 101 | ++extern int json_object_double_to_json_string(struct json_object* jso, 102 | ++ struct printbuf *pb, 103 | ++ int level, 104 | ++ int flags); 105 | ++ 106 | + /** Get the double floating point value of a json_object 107 | + * 108 | + * The type is coerced to a double if the passed object is not a double. 109 | -- 110 | 2.30.0 111 | 112 | -------------------------------------------------------------------------------- /patches/openwrt/0004-dropbear-add-a-failsafe-mode-that-will-always-allow-.patch: -------------------------------------------------------------------------------- 1 | From e7a48a663c4707c3e7a6d78f12f2c021c3e0a326 Mon Sep 17 00:00:00 2001 2 | From: Matthias Schiffer 3 | Date: Tue, 27 Sep 2016 03:55:55 +0200 4 | Subject: [PATCH 04/16] dropbear: add a failsafe mode that will always allow 5 | password-less root login 6 | 7 | Signed-off-by: Matthias Schiffer 8 | --- 9 | .../dropbear/patches/700-failsafe-mode.patch | 57 +++++++++++++++++++ 10 | 1 file changed, 57 insertions(+) 11 | create mode 100644 package/network/services/dropbear/patches/700-failsafe-mode.patch 12 | 13 | diff --git a/package/network/services/dropbear/patches/700-failsafe-mode.patch b/package/network/services/dropbear/patches/700-failsafe-mode.patch 14 | new file mode 100644 15 | index 0000000000..bd9cf1ce42 16 | --- /dev/null 17 | +++ b/package/network/services/dropbear/patches/700-failsafe-mode.patch 18 | @@ -0,0 +1,57 @@ 19 | +--- a/svr-auth.c 20 | ++++ b/svr-auth.c 21 | +@@ -125,10 +125,11 @@ void recv_msg_userauth_request() { 22 | + AUTH_METHOD_NONE_LEN) == 0) { 23 | + TRACE(("recv_msg_userauth_request: 'none' request")) 24 | + if (valid_user 25 | +- && (svr_opts.allowblankpass || !strcmp(ses.authstate.pw_name, "root")) 26 | +- && !svr_opts.noauthpass 27 | +- && !(svr_opts.norootpass && ses.authstate.pw_uid == 0) 28 | +- && ses.authstate.pw_passwd[0] == '\0') 29 | ++ && ((svr_opts.failsafe_mode && !strcmp(ses.authstate.pw_name, "root")) 30 | ++ || ((svr_opts.allowblankpass || !strcmp(ses.authstate.pw_name, "root")) 31 | ++ && !svr_opts.noauthpass 32 | ++ && !(svr_opts.norootpass && ses.authstate.pw_uid == 0) 33 | ++ && ses.authstate.pw_passwd[0] == '\0'))) 34 | + { 35 | + dropbear_log(LOG_NOTICE, 36 | + "Auth succeeded with blank password for '%s' from %s", 37 | +--- a/svr-runopts.c 38 | ++++ b/svr-runopts.c 39 | +@@ -77,6 +77,7 @@ static void printhelp(const char * progn 40 | + "-s Disable password logins\n" 41 | + "-g Disable password logins for root\n" 42 | + "-B Allow blank password logins\n" 43 | ++ "-f Failsafe mode: always allow password-less root login\n" 44 | + #endif 45 | + "-T Maximum authentication tries (default %d)\n" 46 | + #if DROPBEAR_SVR_LOCALTCPFWD 47 | +@@ -144,6 +145,7 @@ void svr_getopts(int argc, char ** argv) 48 | + svr_opts.noauthpass = 0; 49 | + svr_opts.norootpass = 0; 50 | + svr_opts.allowblankpass = 0; 51 | ++ svr_opts.failsafe_mode = 0; 52 | + svr_opts.maxauthtries = MAX_AUTH_TRIES; 53 | + svr_opts.inetdmode = 0; 54 | + svr_opts.portcount = 0; 55 | +@@ -266,6 +268,9 @@ void svr_getopts(int argc, char ** argv) 56 | + case 'B': 57 | + svr_opts.allowblankpass = 1; 58 | + break; 59 | ++ case 'f': 60 | ++ svr_opts.failsafe_mode = 1; 61 | ++ break; 62 | + #endif 63 | + case 'h': 64 | + printhelp(argv[0]); 65 | +--- a/runopts.h 66 | ++++ b/runopts.h 67 | +@@ -106,6 +106,8 @@ typedef struct svr_runopts { 68 | + int allowblankpass; 69 | + unsigned int maxauthtries; 70 | + 71 | ++ int failsafe_mode; 72 | ++ 73 | + #if DROPBEAR_SVR_REMOTETCPFWD 74 | + int noremotetcp; 75 | + #endif 76 | -- 77 | 2.30.0 78 | 79 | -------------------------------------------------------------------------------- /patches/openwrt/0005-kernel-ebtables-add-support-for-ICMP-IGMP-type-match.patch: -------------------------------------------------------------------------------- 1 | From bda509155111f896240e65a31a4a4dd6f8cf7d59 Mon Sep 17 00:00:00 2001 2 | From: Matthias Schiffer 3 | Date: Thu, 12 Apr 2018 07:50:02 +0200 4 | Subject: [PATCH 05/16] kernel: ebtables: add support for ICMP/IGMP type 5 | matches 6 | 7 | Signed-off-by: Matthias Schiffer 8 | --- 9 | ...port-for-matching-ICMP-type-and-code.patch | 134 ++++++++++++++++++ 10 | ...s-add-support-for-matching-IGMP-type.patch | 88 ++++++++++++ 11 | 2 files changed, 222 insertions(+) 12 | create mode 100644 target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch 13 | create mode 100644 target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch 14 | 15 | diff --git a/target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch b/target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch 16 | new file mode 100644 17 | index 0000000000..fe9c479338 18 | --- /dev/null 19 | +++ b/target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch 20 | @@ -0,0 +1,134 @@ 21 | +From: Matthias Schiffer 22 | +Date: Sat, 3 Mar 2018 11:55:21 +0100 23 | +Subject: [PATCH 1/2] ebtables: add support for matching ICMP type and code 24 | + 25 | +We already have ICMPv6 type/code matches. This adds support for IPv4 ICMP 26 | +matches in the same way. 27 | + 28 | +Signed-off-by: Matthias Schiffer 29 | +--- 30 | + include/uapi/linux/netfilter_bridge/ebt_ip.h | 13 +++++++-- 31 | + net/bridge/netfilter/ebt_ip.c | 43 +++++++++++++++++++++------- 32 | + 2 files changed, 43 insertions(+), 13 deletions(-) 33 | + 34 | +--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h 35 | ++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h 36 | +@@ -24,8 +24,9 @@ 37 | + #define EBT_IP_PROTO 0x08 38 | + #define EBT_IP_SPORT 0x10 39 | + #define EBT_IP_DPORT 0x20 40 | ++#define EBT_IP_ICMP 0x40 41 | + #define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\ 42 | +- EBT_IP_SPORT | EBT_IP_DPORT ) 43 | ++ EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP) 44 | + #define EBT_IP_MATCH "ip" 45 | + 46 | + /* the same values are used for the invflags */ 47 | +@@ -38,8 +39,14 @@ struct ebt_ip_info { 48 | + __u8 protocol; 49 | + __u8 bitmask; 50 | + __u8 invflags; 51 | +- __u16 sport[2]; 52 | +- __u16 dport[2]; 53 | ++ union { 54 | ++ __u16 sport[2]; 55 | ++ __u8 icmp_type[2]; 56 | ++ }; 57 | ++ union { 58 | ++ __u16 dport[2]; 59 | ++ __u8 icmp_code[2]; 60 | ++ }; 61 | + }; 62 | + 63 | + #endif 64 | +--- a/net/bridge/netfilter/ebt_ip.c 65 | ++++ b/net/bridge/netfilter/ebt_ip.c 66 | +@@ -19,9 +19,15 @@ 67 | + #include 68 | + #include 69 | + 70 | +-struct tcpudphdr { 71 | +- __be16 src; 72 | +- __be16 dst; 73 | ++union pkthdr { 74 | ++ struct { 75 | ++ __be16 src; 76 | ++ __be16 dst; 77 | ++ } tcpudphdr; 78 | ++ struct { 79 | ++ u8 type; 80 | ++ u8 code; 81 | ++ } icmphdr; 82 | + }; 83 | + 84 | + static bool 85 | +@@ -30,8 +36,8 @@ ebt_ip_mt(const struct sk_buff *skb, str 86 | + const struct ebt_ip_info *info = par->matchinfo; 87 | + const struct iphdr *ih; 88 | + struct iphdr _iph; 89 | +- const struct tcpudphdr *pptr; 90 | +- struct tcpudphdr _ports; 91 | ++ const union pkthdr *pptr; 92 | ++ union pkthdr _pkthdr; 93 | + 94 | + ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); 95 | + if (ih == NULL) 96 | +@@ -50,29 +56,38 @@ ebt_ip_mt(const struct sk_buff *skb, str 97 | + if (info->bitmask & EBT_IP_PROTO) { 98 | + if (NF_INVF(info, EBT_IP_PROTO, info->protocol != ih->protocol)) 99 | + return false; 100 | +- if (!(info->bitmask & EBT_IP_DPORT) && 101 | +- !(info->bitmask & EBT_IP_SPORT)) 102 | ++ if (!(info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT | 103 | ++ EBT_IP_ICMP))) 104 | + return true; 105 | + if (ntohs(ih->frag_off) & IP_OFFSET) 106 | + return false; 107 | ++ 108 | ++ /* min icmp headersize is 4, so sizeof(_pkthdr) is ok. */ 109 | + pptr = skb_header_pointer(skb, ih->ihl*4, 110 | +- sizeof(_ports), &_ports); 111 | ++ sizeof(_pkthdr), &_pkthdr); 112 | + if (pptr == NULL) 113 | + return false; 114 | + if (info->bitmask & EBT_IP_DPORT) { 115 | +- u32 dst = ntohs(pptr->dst); 116 | ++ u32 dst = ntohs(pptr->tcpudphdr.dst); 117 | + if (NF_INVF(info, EBT_IP_DPORT, 118 | + dst < info->dport[0] || 119 | + dst > info->dport[1])) 120 | + return false; 121 | + } 122 | + if (info->bitmask & EBT_IP_SPORT) { 123 | +- u32 src = ntohs(pptr->src); 124 | ++ u32 src = ntohs(pptr->tcpudphdr.src); 125 | + if (NF_INVF(info, EBT_IP_SPORT, 126 | + src < info->sport[0] || 127 | + src > info->sport[1])) 128 | + return false; 129 | + } 130 | ++ if ((info->bitmask & EBT_IP_ICMP) && 131 | ++ NF_INVF(info, EBT_IP_ICMP, 132 | ++ pptr->icmphdr.type < info->icmp_type[0] || 133 | ++ pptr->icmphdr.type > info->icmp_type[1] || 134 | ++ pptr->icmphdr.code < info->icmp_code[0] || 135 | ++ pptr->icmphdr.code > info->icmp_code[1])) 136 | ++ return false; 137 | + } 138 | + return true; 139 | + } 140 | +@@ -101,6 +116,14 @@ static int ebt_ip_mt_check(const struct 141 | + return -EINVAL; 142 | + if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) 143 | + return -EINVAL; 144 | ++ if (info->bitmask & EBT_IP_ICMP) { 145 | ++ if ((info->invflags & EBT_IP_PROTO) || 146 | ++ info->protocol != IPPROTO_ICMP) 147 | ++ return -EINVAL; 148 | ++ if (info->icmp_type[0] > info->icmp_type[1] || 149 | ++ info->icmp_code[0] > info->icmp_code[1]) 150 | ++ return -EINVAL; 151 | ++ } 152 | + return 0; 153 | + } 154 | + 155 | diff --git a/target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch b/target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch 156 | new file mode 100644 157 | index 0000000000..4c8144834d 158 | --- /dev/null 159 | +++ b/target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch 160 | @@ -0,0 +1,88 @@ 161 | +From: Matthias Schiffer 162 | +Date: Sat, 3 Mar 2018 12:02:21 +0100 163 | +Subject: [PATCH 2/2] ebtables: add support for matching IGMP type 164 | + 165 | +We already have ICMPv6 type/code matches (which can be used to distinguish 166 | +different types of MLD packets). Add support for IPv4 IGMP matches in the 167 | +same way. 168 | + 169 | +Signed-off-by: Matthias Schiffer 170 | +--- 171 | + include/uapi/linux/netfilter_bridge/ebt_ip.h | 4 +++- 172 | + net/bridge/netfilter/ebt_ip.c | 19 +++++++++++++++++-- 173 | + 2 files changed, 20 insertions(+), 3 deletions(-) 174 | + 175 | +--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h 176 | ++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h 177 | +@@ -25,8 +25,9 @@ 178 | + #define EBT_IP_SPORT 0x10 179 | + #define EBT_IP_DPORT 0x20 180 | + #define EBT_IP_ICMP 0x40 181 | ++#define EBT_IP_IGMP 0x80 182 | + #define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\ 183 | +- EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP) 184 | ++ EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP) 185 | + #define EBT_IP_MATCH "ip" 186 | + 187 | + /* the same values are used for the invflags */ 188 | +@@ -42,6 +43,7 @@ struct ebt_ip_info { 189 | + union { 190 | + __u16 sport[2]; 191 | + __u8 icmp_type[2]; 192 | ++ __u8 igmp_type[2]; 193 | + }; 194 | + union { 195 | + __u16 dport[2]; 196 | +--- a/net/bridge/netfilter/ebt_ip.c 197 | ++++ b/net/bridge/netfilter/ebt_ip.c 198 | +@@ -28,6 +28,9 @@ union pkthdr { 199 | + u8 type; 200 | + u8 code; 201 | + } icmphdr; 202 | ++ struct { 203 | ++ u8 type; 204 | ++ } igmphdr; 205 | + }; 206 | + 207 | + static bool 208 | +@@ -57,12 +60,12 @@ ebt_ip_mt(const struct sk_buff *skb, str 209 | + if (NF_INVF(info, EBT_IP_PROTO, info->protocol != ih->protocol)) 210 | + return false; 211 | + if (!(info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT | 212 | +- EBT_IP_ICMP))) 213 | ++ EBT_IP_ICMP | EBT_IP_IGMP))) 214 | + return true; 215 | + if (ntohs(ih->frag_off) & IP_OFFSET) 216 | + return false; 217 | + 218 | +- /* min icmp headersize is 4, so sizeof(_pkthdr) is ok. */ 219 | ++ /* min icmp/igmp headersize is 4, so sizeof(_pkthdr) is ok. */ 220 | + pptr = skb_header_pointer(skb, ih->ihl*4, 221 | + sizeof(_pkthdr), &_pkthdr); 222 | + if (pptr == NULL) 223 | +@@ -88,6 +91,11 @@ ebt_ip_mt(const struct sk_buff *skb, str 224 | + pptr->icmphdr.code < info->icmp_code[0] || 225 | + pptr->icmphdr.code > info->icmp_code[1])) 226 | + return false; 227 | ++ if ((info->bitmask & EBT_IP_IGMP) && 228 | ++ NF_INVF(info, EBT_IP_IGMP, 229 | ++ pptr->igmphdr.type < info->igmp_type[0] || 230 | ++ pptr->igmphdr.type > info->igmp_type[1])) 231 | ++ return false; 232 | + } 233 | + return true; 234 | + } 235 | +@@ -124,6 +132,13 @@ static int ebt_ip_mt_check(const struct 236 | + info->icmp_code[0] > info->icmp_code[1]) 237 | + return -EINVAL; 238 | + } 239 | ++ if (info->bitmask & EBT_IP_IGMP) { 240 | ++ if ((info->invflags & EBT_IP_PROTO) || 241 | ++ info->protocol != IPPROTO_IGMP) 242 | ++ return -EINVAL; 243 | ++ if (info->igmp_type[0] > info->igmp_type[1]) 244 | ++ return -EINVAL; 245 | ++ } 246 | + return 0; 247 | + } 248 | + 249 | -- 250 | 2.30.0 251 | 252 | -------------------------------------------------------------------------------- /patches/openwrt/0006-build-set-TARGET_ROOTFS_PARTSIZE-to-make-combined-im.patch: -------------------------------------------------------------------------------- 1 | From e3f7cf5df8f1d9bc15df874c9cc3cb170c8eec5d Mon Sep 17 00:00:00 2001 2 | From: Matthias Schiffer 3 | Date: Sat, 21 Sep 2019 13:21:36 +0200 4 | Subject: [PATCH 06/16] build: set TARGET_ROOTFS_PARTSIZE to make combined 5 | image fit in 128MB 6 | 7 | Change TARGET_ROOTFS_PARTSIZE from 128 to 104 MiB, so the whole image 8 | (bootloader + boot + root) will fit on a 128MB CF card by default. 9 | 10 | With these settings, the generated images (tested on x86-generic and 11 | x86-64) have 126,353,408 bytes; the smallest CF card marketed as "128MB" 12 | that I found a datasheet for (a Transcend TS128MCF80) has 126,959,616 13 | bytes. 14 | 15 | Signed-off-by: Matthias Schiffer 16 | --- 17 | config/Config-images.in | 2 +- 18 | 1 file changed, 1 insertion(+), 1 deletion(-) 19 | 20 | diff --git a/config/Config-images.in b/config/Config-images.in 21 | index 8548c7cd24..dc7a9cbd54 100644 22 | --- a/config/Config-images.in 23 | +++ b/config/Config-images.in 24 | @@ -274,7 +274,7 @@ menu "Target Images" 25 | config TARGET_ROOTFS_PARTSIZE 26 | int "Root filesystem partition size (in MB)" 27 | depends on GRUB_IMAGES || USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_omap || TARGET_rb532 || TARGET_sunxi || TARGET_uml 28 | - default 256 29 | + default 104 30 | help 31 | Select the root filesystem partition size. 32 | 33 | -- 34 | 2.30.0 35 | 36 | -------------------------------------------------------------------------------- /patches/openwrt/0007-ipq-wifi-add-BDF-for-Aruba-AP-303.patch: -------------------------------------------------------------------------------- 1 | From 29dcb05f21954a6935f120de59b3d7a675f2114a Mon Sep 17 00:00:00 2001 2 | From: David Bauer 3 | Date: Sun, 15 Dec 2019 23:02:54 +0100 4 | Subject: [PATCH 07/16] ipq-wifi: add BDF for Aruba AP-303 5 | 6 | The BDF originates from the vendor-firmware. 7 | 8 | Signed-off-by: David Bauer 9 | (cherry picked from commit 4113d8a2554adf5ecee55cc07956eafad378eaff) 10 | --- 11 | package/firmware/ipq-wifi/Makefile | 2 ++ 12 | .../ipq-wifi/board-aruba_ap-303.qca4019 | Bin 0 -> 24316 bytes 13 | 2 files changed, 2 insertions(+) 14 | create mode 100644 package/firmware/ipq-wifi/board-aruba_ap-303.qca4019 15 | 16 | diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile 17 | index eb7c2df1aa..cc0505b97c 100644 18 | --- a/package/firmware/ipq-wifi/Makefile 19 | +++ b/package/firmware/ipq-wifi/Makefile 20 | @@ -25,6 +25,7 @@ endef 21 | 22 | ALLWIFIBOARDS:= \ 23 | alfa-network_ap120c-ac \ 24 | + aruba_ap-303 \ 25 | asus_map-ac2200 \ 26 | avm_fritzbox-7530 \ 27 | avm_fritzrepeater-1200 \ 28 | @@ -97,6 +98,7 @@ endef 29 | # Add $(eval $(call generate-ipq-wifi-package,,)) 30 | 31 | $(eval $(call generate-ipq-wifi-package,alfa-network_ap120c-ac,ALFA Network AP120C-AC)) 32 | +$(eval $(call generate-ipq-wifi-package,aruba_ap-303,Aruba AP-303)) 33 | $(eval $(call generate-ipq-wifi-package,asus_map-ac2200,ASUS MAP-AC2200)) 34 | $(eval $(call generate-ipq-wifi-package,avm_fritzbox-7530,AVM FRITZ!Box 7530)) 35 | $(eval $(call generate-ipq-wifi-package,avm_fritzrepeater-1200,AVM FRITZRepeater 1200)) 36 | diff --git a/package/firmware/ipq-wifi/board-aruba_ap-303.qca4019 b/package/firmware/ipq-wifi/board-aruba_ap-303.qca4019 37 | new file mode 100644 38 | index 0000000000000000000000000000000000000000..4848115cfbe3a4a0ed6b17cac929731ecbd7968c 39 | GIT binary patch 40 | literal 24316 41 | zcmeHPdr(tX8b1l)p-UHTNDu)pAp}Se0tBi-!W$`%6c7~&un1I6BFeZwJ$y}AjvN}B`Pfz$mMbX<(NN~1F#FGd_`$kUSYm( 44 | zzFg|}UZJ$ePkJaU0I%hr$SXO7RRsaQWqBpiyyGXsqDmC`d45r;enA02aybRIXTiQ$ 45 | z{(Fv6D8Qnc9-NN#>(d1&AQynm*7jHxFaWR*!ZjM6>t{S38|w;yprD{vFJ4eY3@h-< 46 | z-!4WF$pUt;M0u#+u2DM@cmo9V_`vZ+ET^9yjw-&*$wzjskw6xF>07kKy8YxWZr<)vMT{juo&5WBJl$pvJ 48 | zSBe@2uw^qXb0;%4&|Y78I5R0hICi_exl*3FFCluYul;;oiF8lGjWOy2|{_1bA?;y|Gf7nVJwj){D78n-DgruPe_KCxqe+o_PC!v0LpI;0W&~ 50 | zgp7R#8_4hmJ+PC)%p@TfcGpx{l$j&E$%$G#3{F}KdUX|Jgd|puct0g5t8qXU6jp>E=A|Pc_n}{`jGyHYexpa) 53 | z8eg})+@@SU~bv!vW@t_*D0~j*k2Ra54<44 54 | zGAfly!Ey@=__b^`E!H<{G6I~Qyq_vSIUEo8>&bR^_h7rT+37SJ;+lkrg)CPdfsBl_ 55 | zWH#Fk4)pWSFMfRe8oL4#@;p7Xw*UV4*B^9knBz8EYbuTQKj>!%PuOhxmoH!ZTkE^h 56 | zQ5Oxs>k&9eQFX%rmay^oy5hs-a5%Vu>&0fVaLp_>UjzM_W;28hf+9#18ifR+fk=_! 57 | zRP~t;8=70^D?l_Y4@^?%D4kD#N=KYgXTG!89<@iD&}cN8AN@2MNkkL*iQ-5!5{X9z 58 | zsDLkcDnNFjyZF1r0cZdsL}!9fUpK7I#3T~UL`ACe&W|yWIG_$w4u}it!gmqJpfOW1 59 | zND`XFPZ9^AK~q6UC>qKS6>Cp|ZjKM7g?`0zZ0#0(s21q!}Wsktx^q!Hyz)q)K=GO 63 | zoF7djK!C#!ycz%kffr-~xxvJNR46t~SlLJq1Z=jeD_c)mpnblT&CYJ-0FjUaUY!7- 64 | z#TubR1_QvgL4XK|Xt`DhpfahOvtem(k8e884~Vp^8wB1A+A^rrLvRNI?k-blHXlQ| 65 | z28Ed52$bd6#2N6zwQKmBg-UNPPtI?dv^#g&y*lmgoH%t~Mt1I@LRDi+Ye!f2&4Iz; 66 | zkI`9mEA&tbcUZ 67 | z%raPCff}=CoSdFh&~W)`kLJ$!*9+*BuD^e+C^f1J|FyU;r!;;^^oI 71 | zutbQ7^|zo9O_y4-fz<*{BN<(cKQSIMS&pfWHI9R`Q7+)GZ~m87zSOtRt#@=xPIh$J 72 | z+RmlJ%=Iy)wjsB2$w?ctL{=e6#)NGiAEXw5z3>BC;Y0;D{!GEsIar?io&qX3RM0m- 73 | z1^qu!!LtzyFeRb^yHOg52(ttT)56l)JRy+1kO+_nY&ZmFIrD}%_y76l-@pIvyT3qG 74 | z!a_rK!Uv_0b8llsqdtHB4`|cp+)q8%a_-ajrKM^)`>$U7G-ZAsz9G)NzdxUkC2X$& 75 | zduqM~`z#Q)p7ZVawgPK2|7z4Vsn5hz4U5-aIh*Kyy`9 79 | z2K#+`d{Fa=s!Ar2h&1D>cG=1J-CQSpgrl-7ZAjx2Fr>-5ns)VRm0Y%a{Fdgrx(+r@ 80 | z*4$UM$;#s6xh~@)>W}b{+^~=yKH~BKoNA}$qFSNKg(0ccXH~^YiRPBNQznm(68cZx 81 | z*IZXs$_@yfwGDV)*c_VFr&I;XWO(qZszR13@rQx5DHW0=A#d`I=8CFBmJ-jw8hkOq 82 | zgDBk|Z&R15a+I-?Bk*9UGFz4i!@LHuj1;2qXotF778Ab}Z}1q-!4z4Am-=K##+*PB 83 | zB@(3t5LgdOV}YrW<_(KL>(KEV5iNeTE@js=e`t@r=v}q-_{qz0XL!ZV`L=NnyANLo 84 | zQ+gcPBDpqn@zBNZRxW7|) 85 | z$*qbmtL@F{5S&95^!$;V#g`*L;FZw#KkAbCs3#V=uB4NN#U`sakZFU2HEI?ks7Dsq&ROrak#AvEH|GYk~cN 88 | z-oYbXaZQ|4jDps_<5wfH44oN*XPh1H-<59xMxzd~07FF+FO3!KO 89 | zkzNs<^C)%5zR+;s{a_h8iyk@DSK5($fm`l$c*8Cna^fTc>i~h}zJUY22WwUg;4xU6 90 | zE40Voz~Sl1fxqzW8!QiZceZ;vST%3pn9qkNDEBsI+pnKL20^*sWVSI3z)zY;1PmfD 91 | zk8=M~&&^oEhq?Xq!q{llMLGBQ>t)~ra4xR!eZAQ1X^ph;*FG+*f4xJlJ!C>*eEV+r 92 | z#z~GXOppZ=2|4(iyLmNON}QN2ao#+YHqDy{lvv2w_X*(?ul{+G5$Yp=apGx^6Q9v~ 93 | z^YKb>;`PTfcYPtQJz@VX`S#e@Bso3?a_*Ok9NBKwB4Es(@j^U%UHht?;4%Xv 94 | NIrrxNmNc!u{{!hMI2Hf^ 95 | 96 | literal 0 97 | HcmV?d00001 98 | 99 | -- 100 | 2.30.0 101 | 102 | -------------------------------------------------------------------------------- /patches/openwrt/0009-ath79-enable-GL-AR750S-NOR-variant-from-master.patch: -------------------------------------------------------------------------------- 1 | From 32304a1dbca47210f5aaf3b4c358c4f859536fc1 Mon Sep 17 00:00:00 2001 2 | From: Jan Alexander 3 | Date: Tue, 31 Mar 2020 21:50:28 +0200 4 | Subject: [PATCH 09/16] ath79: enable GL-AR750S NOR variant from master 5 | 6 | --- 7 | target/linux/ath79/base-files/etc/board.d/02_network | 2 +- 8 | .../ath79/base-files/etc/hotplug.d/firmware/11-ath10k-caldata | 2 +- 9 | target/linux/ath79/dts/qca9563_glinet_gl-ar750s.dts | 4 ++-- 10 | target/linux/ath79/image/generic.mk | 4 ++-- 11 | 4 files changed, 6 insertions(+), 6 deletions(-) 12 | 13 | diff --git a/target/linux/ath79/base-files/etc/board.d/02_network b/target/linux/ath79/base-files/etc/board.d/02_network 14 | index 5dda551caa..b8fac8816c 100755 15 | --- a/target/linux/ath79/base-files/etc/board.d/02_network 16 | +++ b/target/linux/ath79/base-files/etc/board.d/02_network 17 | @@ -155,7 +155,7 @@ ath79_setup_interfaces() 18 | etactica,eg200) 19 | ucidef_set_interface_lan "eth0" "dhcp" 20 | ;; 21 | - glinet,gl-ar750s) 22 | + glinet,gl-ar750s-nor) 23 | ucidef_add_switch "switch0" \ 24 | "0@eth0" "2:lan:2" "3:lan:1" "1:wan" 25 | ;; 26 | diff --git a/target/linux/ath79/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ath79/base-files/etc/hotplug.d/firmware/11-ath10k-caldata 27 | index d93e6dcd71..c917f38211 100644 28 | --- a/target/linux/ath79/base-files/etc/hotplug.d/firmware/11-ath10k-caldata 29 | +++ b/target/linux/ath79/base-files/etc/hotplug.d/firmware/11-ath10k-caldata 30 | @@ -117,7 +117,7 @@ case "$FIRMWARE" in 31 | ath10kcal_extract "art" 20480 2116 32 | ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) +1) 33 | ;; 34 | - glinet,gl-ar750s) 35 | + glinet,gl-ar750s-nor) 36 | ath10kcal_extract "art" 20480 2116 37 | ath10kcal_patch_mac $(macaddr_add $(mtd_get_mac_binary art 0) +1) 38 | ;; 39 | diff --git a/target/linux/ath79/dts/qca9563_glinet_gl-ar750s.dts b/target/linux/ath79/dts/qca9563_glinet_gl-ar750s.dts 40 | index 03922bcd1f..ff64e16d1c 100644 41 | --- a/target/linux/ath79/dts/qca9563_glinet_gl-ar750s.dts 42 | +++ b/target/linux/ath79/dts/qca9563_glinet_gl-ar750s.dts 43 | @@ -7,8 +7,8 @@ 44 | #include "qca956x.dtsi" 45 | 46 | / { 47 | - compatible = "glinet,gl-ar750s", "qca,qca9563"; 48 | - model = "GL.iNet GL-AR750S"; 49 | + compatible = "glinet,gl-ar750s-nor", "qca,qca9563"; 50 | + model = "GL.iNet GL-AR750S (NOR)"; 51 | 52 | aliases { 53 | led-boot = &power; 54 | diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk 55 | index 55053be34f..892ef10f87 100644 56 | --- a/target/linux/ath79/image/generic.mk 57 | +++ b/target/linux/ath79/image/generic.mk 58 | @@ -403,9 +403,9 @@ define Device/glinet_gl-ar750s 59 | DEVICE_TITLE := GL.iNet GL-AR750S 60 | DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct ath10k-firmware-qca9887-ct block-mount 61 | IMAGE_SIZE := 16000k 62 | - SUPPORTED_DEVICES += gl-ar750s 63 | + SUPPORTED_DEVICES += gl-ar750s glinet,gl-ar750s-nor 64 | endef 65 | -#TARGET_DEVICES += glinet_gl-ar750s 66 | +TARGET_DEVICES += glinet_gl-ar750s 67 | 68 | define Device/glinet_gl-x750 69 | ATH_SOC := qca9531 70 | -- 71 | 2.30.0 72 | 73 | -------------------------------------------------------------------------------- /patches/openwrt/0010-tools-add-zstd.patch: -------------------------------------------------------------------------------- 1 | From 17282702f6fa9e2331767d6bddbbdcbd6eb96f82 Mon Sep 17 00:00:00 2001 2 | From: Matthias Schiffer 3 | Date: Wed, 13 May 2020 20:22:12 +0200 4 | Subject: [PATCH 10/16] tools: add zstd 5 | 6 | Signed-off-by: Matthias Schiffer 7 | (cherry picked from commit 258dc0d0fd3aae47add9b7dca40848a92d03a4ea) 8 | --- 9 | tools/Makefile | 2 +- 10 | tools/zstd/Makefile | 20 ++++++ 11 | ...re-portable-header-prefix-usage-1987.patch | 61 +++++++++++++++++++ 12 | 3 files changed, 82 insertions(+), 1 deletion(-) 13 | create mode 100644 tools/zstd/Makefile 14 | create mode 100644 tools/zstd/patches/0001-build-issue-More-portable-header-prefix-usage-1987.patch 15 | 16 | diff --git a/tools/Makefile b/tools/Makefile 17 | index b8d986b80c..33266ca72d 100644 18 | --- a/tools/Makefile 19 | +++ b/tools/Makefile 20 | @@ -33,7 +33,7 @@ tools-$(CONFIG_TARGET_mxs) += elftosb sdimage 21 | tools-$(CONFIG_TARGET_ar71xx) += lzma-old 22 | tools-$(CONFIG_TARGET_ar71xx)$(CONFIG_TARGET_ath79) += squashfs 23 | tools-$(CONFIG_USES_MINOR) += kernel2minor 24 | -tools-y += lzma squashfskit4 zip 25 | +tools-y += lzma squashfskit4 zip zstd 26 | tools-$(BUILD_B43_TOOLS) += b43-tools 27 | tools-$(BUILD_ISL) += isl 28 | tools-$(CONFIG_USE_SPARSE) += sparse 29 | diff --git a/tools/zstd/Makefile b/tools/zstd/Makefile 30 | new file mode 100644 31 | index 0000000000..7459725e8e 32 | --- /dev/null 33 | +++ b/tools/zstd/Makefile 34 | @@ -0,0 +1,20 @@ 35 | +include $(TOPDIR)/rules.mk 36 | + 37 | +PKG_NAME:=zstd 38 | +PKG_VERSION:=1.4.4 39 | + 40 | +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 41 | +PKG_SOURCE_URL:=@GITHUB/facebook/zstd/releases/download/v$(PKG_VERSION) 42 | +PKG_HASH:=a364f5162c7d1a455cc915e8e3cf5f4bd8b75d09bc0f53965b0c9ca1383c52c8 43 | + 44 | +PKG_LICENSE:=BSD-3-Clause 45 | +PKG_LICENSE_FILES:=LICENSE 46 | +PKG_CPE_ID:=cpe:/a:facebook:zstandard 47 | + 48 | +HOST_BUILD_PARALLEL:=1 49 | + 50 | +include $(INCLUDE_DIR)/host-build.mk 51 | + 52 | +HOST_MAKE_FLAGS = PREFIX=$(HOST_BUILD_PREFIX) HAVE_ZLIB=0 HAVE_LZMA=0 HAVE_LZ4=0 53 | + 54 | +$(eval $(call HostBuild)) 55 | diff --git a/tools/zstd/patches/0001-build-issue-More-portable-header-prefix-usage-1987.patch b/tools/zstd/patches/0001-build-issue-More-portable-header-prefix-usage-1987.patch 56 | new file mode 100644 57 | index 0000000000..6d743aa385 58 | --- /dev/null 59 | +++ b/tools/zstd/patches/0001-build-issue-More-portable-header-prefix-usage-1987.patch 60 | @@ -0,0 +1,61 @@ 61 | +From 06a57cf57e3c4e887cadcf688e3081154f3f6db4 Mon Sep 17 00:00:00 2001 62 | +Message-Id: <06a57cf57e3c4e887cadcf688e3081154f3f6db4.1589392463.git.mschiffer@universe-factory.net> 63 | +From: Bimba Shrestha 64 | +Date: Thu, 6 Feb 2020 14:10:51 -0800 65 | +Subject: [PATCH] [build-issue] More portable header prefix usage (#) (#1987) 66 | + 67 | +* make 4.3 build issue fix 68 | + 69 | +* Changing header name and adding comment 70 | +--- 71 | + programs/Makefile | 11 +++++++---- 72 | + 1 file changed, 7 insertions(+), 4 deletions(-) 73 | + 74 | +diff --git a/programs/Makefile b/programs/Makefile 75 | +index b75314a83f43..a9ee3cb5311b 100644 76 | +--- a/programs/Makefile 77 | ++++ b/programs/Makefile 78 | +@@ -94,9 +94,12 @@ endif 79 | + 80 | + VOID = /dev/null 81 | + 82 | ++# Make 4.3 doesn't support '\#' anymore (https://lwn.net/Articles/810071/) 83 | ++NUM_SYMBOL := \# 84 | ++ 85 | + # thread detection 86 | + NO_THREAD_MSG := ==> no threads, building without multithreading support 87 | +-HAVE_PTHREAD := $(shell printf '\#include \nint main(void) { return 0; }' > have_pthread.c && $(CC) $(FLAGS) -o have_pthread$(EXT) have_pthread.c -pthread 2> $(VOID) && rm have_pthread$(EXT) && echo 1 || echo 0; rm have_pthread.c) 88 | ++HAVE_PTHREAD := $(shell printf '$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_pthread.c && $(CC) $(FLAGS) -o have_pthread$(EXT) have_pthread.c -pthread 2> $(VOID) && rm have_pthread$(EXT) && echo 1 || echo 0; rm have_pthread.c) 89 | + HAVE_THREAD := $(shell [ "$(HAVE_PTHREAD)" -eq "1" -o -n "$(filter Windows%,$(OS))" ] && echo 1 || echo 0) 90 | + ifeq ($(HAVE_THREAD), 1) 91 | + THREAD_MSG := ==> building with threading support 92 | +@@ -108,7 +111,7 @@ endif 93 | + 94 | + # zlib detection 95 | + NO_ZLIB_MSG := ==> no zlib, building zstd without .gz support 96 | +-HAVE_ZLIB := $(shell printf '\#include \nint main(void) { return 0; }' > have_zlib.c && $(CC) $(FLAGS) -o have_zlib$(EXT) have_zlib.c -lz 2> $(VOID) && rm have_zlib$(EXT) && echo 1 || echo 0; rm have_zlib.c) 97 | ++HAVE_ZLIB := $(shell printf '$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_zlib.c && $(CC) $(FLAGS) -o have_zlib$(EXT) have_zlib.c -lz 2> $(VOID) && rm have_zlib$(EXT) && echo 1 || echo 0; rm have_zlib.c) 98 | + ifeq ($(HAVE_ZLIB), 1) 99 | + ZLIB_MSG := ==> building zstd with .gz compression support 100 | + ZLIBCPP = -DZSTD_GZCOMPRESS -DZSTD_GZDECOMPRESS 101 | +@@ -119,7 +122,7 @@ endif 102 | + 103 | + # lzma detection 104 | + NO_LZMA_MSG := ==> no liblzma, building zstd without .xz/.lzma support 105 | +-HAVE_LZMA := $(shell printf '\#include \nint main(void) { return 0; }' > have_lzma.c && $(CC) $(FLAGS) -o have_lzma$(EXT) have_lzma.c -llzma 2> $(VOID) && rm have_lzma$(EXT) && echo 1 || echo 0; rm have_lzma.c) 106 | ++HAVE_LZMA := $(shell printf '$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_lzma.c && $(CC) $(FLAGS) -o have_lzma$(EXT) have_lzma.c -llzma 2> $(VOID) && rm have_lzma$(EXT) && echo 1 || echo 0; rm have_lzma.c) 107 | + ifeq ($(HAVE_LZMA), 1) 108 | + LZMA_MSG := ==> building zstd with .xz/.lzma compression support 109 | + LZMACPP = -DZSTD_LZMACOMPRESS -DZSTD_LZMADECOMPRESS 110 | +@@ -130,7 +133,7 @@ endif 111 | + 112 | + # lz4 detection 113 | + NO_LZ4_MSG := ==> no liblz4, building zstd without .lz4 support 114 | +-HAVE_LZ4 := $(shell printf '\#include \n\#include \nint main(void) { return 0; }' > have_lz4.c && $(CC) $(FLAGS) -o have_lz4$(EXT) have_lz4.c -llz4 2> $(VOID) && rm have_lz4$(EXT) && echo 1 || echo 0; rm have_lz4.c) 115 | ++HAVE_LZ4 := $(shell printf '$(NUM_SYMBOL)include \n\#include \nint main(void) { return 0; }' > have_lz4.c && $(CC) $(FLAGS) -o have_lz4$(EXT) have_lz4.c -llz4 2> $(VOID) && rm have_lz4$(EXT) && echo 1 || echo 0; rm have_lz4.c) 116 | + ifeq ($(HAVE_LZ4), 1) 117 | + LZ4_MSG := ==> building zstd with .lz4 compression support 118 | + LZ4CPP = -DZSTD_LZ4COMPRESS -DZSTD_LZ4DECOMPRESS 119 | +-- 120 | +2.26.2 121 | + 122 | -- 123 | 2.30.0 124 | 125 | -------------------------------------------------------------------------------- /patches/openwrt/0011-build-compress-kernel-debuginfo-using-zstd.patch: -------------------------------------------------------------------------------- 1 | From 9cfb06bb8722af15e07fd675e8b0001c2012c6f5 Mon Sep 17 00:00:00 2001 2 | From: Matthias Schiffer 3 | Date: Wed, 13 May 2020 20:33:46 +0200 4 | Subject: [PATCH 11/16] build: compress kernel debuginfo using zstd 5 | 6 | zstd with its default settings (compression level -3) compresses better 7 | than bzip2 -9 (which is the default setting), and is an order of magnitude 8 | faster. 9 | 10 | I made the following measurements for the most common compression tools 11 | (all standard Debian Buster versions, default flags unless noted 12 | otherwise), using the debug information of a large x86-64 kernel with 13 | ALL_KMODS: 14 | 15 | * kernel-debug.tar: 376M 16 | * kernel-debug.tar.gz: 101M, compressed in ~12s 17 | * kernel-debug.tar.bz2: 91M, compressed in ~15s 18 | * kernel-debug.tar.xz: 57M, compressed in ~101s 19 | * kernel-debug.tar.zst: 86M, compressed in ~1s 20 | 21 | With zstd, there is still some room for improvement by increasing the 22 | compression, but the slight increase in compression ratio 23 | (22.83% -> 19.46%) does not justify the significant increase in 24 | compression time (about 5 times on my machine) in my opinion. 25 | 26 | Note that multithreaded compression (-T argument) does not affect 27 | reproducibility with zstd. 28 | 29 | Signed-off-by: Matthias Schiffer 30 | (cherry picked from commit 4bd7990488b0ca7b5cae16f0a9147a4146759053) 31 | --- 32 | include/kernel-build.mk | 2 +- 33 | 1 file changed, 1 insertion(+), 1 deletion(-) 34 | 35 | diff --git a/include/kernel-build.mk b/include/kernel-build.mk 36 | index 3fdf7efc52..af7c3a8f0b 100644 37 | --- a/include/kernel-build.mk 38 | +++ b/include/kernel-build.mk 39 | @@ -70,7 +70,7 @@ ifdef CONFIG_COLLECT_KERNEL_DEBUG 40 | $(FIND) $(KERNEL_BUILD_DIR)/debug -type f | $(XARGS) $(KERNEL_CROSS)strip --only-keep-debug 41 | $(TAR) c -C $(KERNEL_BUILD_DIR) debug \ 42 | $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \ 43 | - | bzip2 -c -9 > $(BIN_DIR)/kernel-debug.tar.bz2 44 | + | zstd -T0 -f -o $(BIN_DIR)/kernel-debug.tar.zst 45 | endef 46 | endif 47 | 48 | -- 49 | 2.30.0 50 | 51 | -------------------------------------------------------------------------------- /patches/openwrt/0012-mac80211-rt2800-enable-MFP-support-unconditionally.patch: -------------------------------------------------------------------------------- 1 | From 66e255586143903e824c015ab24046fa4b4261fb Mon Sep 17 00:00:00 2001 2 | From: Rui Salvaterra 3 | Date: Mon, 25 May 2020 14:49:07 +0100 4 | Subject: [PATCH 12/16] mac80211: rt2800: enable MFP support unconditionally 5 | 6 | This gives us WPA3 support out of the box without having to manually disable 7 | hardware crypto. The driver will fall back to software crypto if the connection 8 | requires management frame protection. 9 | 10 | Signed-off-by: Daniel Golle 11 | [apply to openwrt-1907] 12 | Signed-off-by: David Bauer 13 | --- 14 | ...0-enable-MFP-support-unconditionally.patch | 44 +++++++++++++++++++ 15 | 1 file changed, 44 insertions(+) 16 | create mode 100644 package/kernel/mac80211/patches/rt2x00/080-rt2800-enable-MFP-support-unconditionally.patch 17 | 18 | diff --git a/package/kernel/mac80211/patches/rt2x00/080-rt2800-enable-MFP-support-unconditionally.patch b/package/kernel/mac80211/patches/rt2x00/080-rt2800-enable-MFP-support-unconditionally.patch 19 | new file mode 100644 20 | index 0000000000..1d55b2756c 21 | --- /dev/null 22 | +++ b/package/kernel/mac80211/patches/rt2x00/080-rt2800-enable-MFP-support-unconditionally.patch 23 | @@ -0,0 +1,44 @@ 24 | +From b6b15e20421fefae9f78274f9fef80bc97bf5d5c Mon Sep 17 00:00:00 2001 25 | +From: Rui Salvaterra 26 | +Date: Mon, 25 May 2020 14:49:07 +0100 27 | +Subject: [PATCH] rt2800: enable MFP support unconditionally 28 | + 29 | +This gives us WPA3 support out of the box without having to manually disable 30 | +hardware crypto. The driver will fall back to software crypto if the connection 31 | +requires management frame protection. 32 | + 33 | +Suggested-by: Stanislaw Gruszka 34 | +Signed-off-by: Rui Salvaterra 35 | +Acked-by: Stanislaw Gruszka 36 | +Signed-off-by: Kalle Valo 37 | +Link: https://lore.kernel.org/r/20200525134906.1672-1-rsalvaterra@gmail.com 38 | +--- 39 | + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 4 +--- 40 | + drivers/net/wireless/ralink/rt2x00/rt2x00mac.c | 3 ++- 41 | + 2 files changed, 3 insertions(+), 4 deletions(-) 42 | + 43 | +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c 44 | ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c 45 | +@@ -9985,9 +9985,7 @@ static int rt2800_probe_hw_mode(struct r 46 | + if (!rt2x00_is_usb(rt2x00dev)) 47 | + ieee80211_hw_set(rt2x00dev->hw, HOST_BROADCAST_PS_BUFFERING); 48 | + 49 | +- /* Set MFP if HW crypto is disabled. */ 50 | +- if (rt2800_hwcrypt_disabled(rt2x00dev)) 51 | +- ieee80211_hw_set(rt2x00dev->hw, MFP_CAPABLE); 52 | ++ ieee80211_hw_set(rt2x00dev->hw, MFP_CAPABLE); 53 | + 54 | + SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); 55 | + SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, 56 | +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c 57 | ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c 58 | +@@ -459,7 +459,8 @@ int rt2x00mac_set_key(struct ieee80211_h 59 | + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) 60 | + return 0; 61 | + 62 | +- if (!rt2x00_has_cap_hw_crypto(rt2x00dev)) 63 | ++ /* The hardware can't do MFP */ 64 | ++ if (!rt2x00_has_cap_hw_crypto(rt2x00dev) || (sta && sta->mfp)) 65 | + return -EOPNOTSUPP; 66 | + 67 | + /* 68 | -- 69 | 2.30.0 70 | 71 | -------------------------------------------------------------------------------- /patches/openwrt/0013-mt76-mt76x0-disable-GTK-offloading.patch: -------------------------------------------------------------------------------- 1 | From 21f49bf874f2221751af16e2688d69c1dc06e7c9 Mon Sep 17 00:00:00 2001 2 | From: David Bauer 3 | Date: Sat, 13 Jun 2020 19:19:17 +0200 4 | Subject: [PATCH 13/16] mt76: mt76x0: disable GTK offloading 5 | 6 | When the GTK is offloaded, MT7610 won't transmit any multicast frames. 7 | This is most likely due to a bug in the offloading datapath. MT7612 is 8 | not affected. 9 | 10 | Disable GTK offloading for now. It can be re-enabled once the bug in the 11 | offloading path is fixed. 12 | 13 | Signed-off-by: David Bauer 14 | --- 15 | ...1-mt76-mt76x0-disable-gtk-offloading.patch | 30 +++++++++++++++++++ 16 | 1 file changed, 30 insertions(+) 17 | create mode 100644 package/kernel/mt76/patches/001-mt76-mt76x0-disable-gtk-offloading.patch 18 | 19 | diff --git a/package/kernel/mt76/patches/001-mt76-mt76x0-disable-gtk-offloading.patch b/package/kernel/mt76/patches/001-mt76-mt76x0-disable-gtk-offloading.patch 20 | new file mode 100644 21 | index 0000000000..e7e19ac957 22 | --- /dev/null 23 | +++ b/package/kernel/mt76/patches/001-mt76-mt76x0-disable-gtk-offloading.patch 24 | @@ -0,0 +1,30 @@ 25 | +From ae01717951013fbc8bb0315d902d5b9f5873631a Mon Sep 17 00:00:00 2001 26 | +From: David Bauer 27 | +Date: Fri, 12 Jun 2020 01:09:57 +0200 28 | +Subject: [PATCH] mt76: mt76x0: disable GTK offloading 29 | + 30 | +When the GTK is offloaded, MT7610 won't transmit any multicast frames. 31 | +This is most likely due to a bug in the offloading datapath. MT7612 is 32 | +not affected. 33 | + 34 | +Disable GTK offloading for now. It can be re-enabled once the bug in the 35 | +offloading path is fixed. 36 | + 37 | +Signed-off-by: David Bauer 38 | +--- 39 | + drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 ++++ 40 | + 1 file changed, 4 insertions(+) 41 | + 42 | +--- a/mt76x02_util.c 43 | ++++ b/mt76x02_util.c 44 | +@@ -432,6 +432,10 @@ int mt76x02_set_key(struct ieee80211_hw 45 | + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 46 | + return -EOPNOTSUPP; 47 | + 48 | ++ /* MT76x0 GTK offloading is currently broken */ 49 | ++ if (is_mt76x0(dev) && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 50 | ++ return -EOPNOTSUPP; 51 | ++ 52 | + /* 53 | + * In USB AP mode, broadcast/multicast frames are setup in beacon 54 | + * data registers and sent via HW beacons engine, they require to 55 | -- 56 | 2.30.0 57 | 58 | -------------------------------------------------------------------------------- /patches/openwrt/0014-mt76-mt7603-add-additional-EEPROM-chip-ID.patch: -------------------------------------------------------------------------------- 1 | From 26ee8ba70ee138a8532dea04a05a48e933760f03 Mon Sep 17 00:00:00 2001 2 | From: David Bauer 3 | Date: Thu, 15 Oct 2020 22:42:54 +0200 4 | Subject: [PATCH 14/16] mt76: mt7603: add additional EEPROM chip ID 5 | 6 | Some newer MT7628 based routers (notably the TP-Link Archer C50 v4) are 7 | shipped with a chip-id of 0x7600 in the on-flash EEPROM. Add this as a 8 | possible valid ID. 9 | 10 | Ref: https://bugs.openwrt.org/index.php?do=details&task_id=2781 11 | 12 | Suggested-by: Ron Asimi 13 | Signed-off-by: David Bauer 14 | --- 15 | ...mt7603-add-additional-EEPROM-chip-ID.patch | 27 +++++++++++++++++++ 16 | 1 file changed, 27 insertions(+) 17 | create mode 100644 package/kernel/mt76/patches/002-mt76-mt7603-add-additional-EEPROM-chip-ID.patch 18 | 19 | diff --git a/package/kernel/mt76/patches/002-mt76-mt7603-add-additional-EEPROM-chip-ID.patch b/package/kernel/mt76/patches/002-mt76-mt7603-add-additional-EEPROM-chip-ID.patch 20 | new file mode 100644 21 | index 0000000000..c749aa403f 22 | --- /dev/null 23 | +++ b/package/kernel/mt76/patches/002-mt76-mt7603-add-additional-EEPROM-chip-ID.patch 24 | @@ -0,0 +1,27 @@ 25 | +From 6b51340cdc32b1ba75163faaa8592feaeb4bddec Mon Sep 17 00:00:00 2001 26 | +From: David Bauer 27 | +Date: Sat, 10 Oct 2020 00:36:02 +0200 28 | +Subject: [PATCH] mt76: mt7603: add additional EEPROM chip ID 29 | + 30 | +Some newer MT7628 based routers (notably the TP-Link Archer C50 v4) are 31 | +shipped with a chip-id of 0x7600 in the on-flash EEPROM. Add this as a 32 | +possible valid ID. 33 | + 34 | +Ref: https://bugs.openwrt.org/index.php?do=details&task_id=2781 35 | + 36 | +Suggested-by: Ron Asimi 37 | +Signed-off-by: David Bauer 38 | +--- 39 | + mt7603/eeprom.c | 1 + 40 | + 1 file changed, 1 insertion(+) 41 | + 42 | +--- a/mt7603/eeprom.c 43 | ++++ b/mt7603/eeprom.c 44 | +@@ -136,6 +136,7 @@ static int mt7603_check_eeprom(struct mt 45 | + switch (val) { 46 | + case 0x7628: 47 | + case 0x7603: 48 | ++ case 0x7600: 49 | + return 0; 50 | + default: 51 | + return -EINVAL; 52 | -- 53 | 2.30.0 54 | 55 | -------------------------------------------------------------------------------- /patches/openwrt/0015-config-config-build-extend-small-flash-option.patch: -------------------------------------------------------------------------------- 1 | From e35ddf7b097e0901ccf1bff013893f65ad2e0868 Mon Sep 17 00:00:00 2001 2 | From: Moritz Warning 3 | Date: Tue, 20 Aug 2019 23:16:14 +0200 4 | Subject: [PATCH 15/16] config/config-build: extend small flash option 5 | 6 | --- 7 | config/Config-build.in | 2 ++ 8 | 1 file changed, 2 insertions(+) 9 | 10 | diff --git a/config/Config-build.in b/config/Config-build.in 11 | index e5d38578a2..1ec8a72e2e 100644 12 | --- a/config/Config-build.in 13 | +++ b/config/Config-build.in 14 | @@ -175,6 +175,7 @@ menu "Global build settings" 15 | 16 | config STRIP_KERNEL_EXPORTS 17 | bool "Strip unnecessary exports from the kernel image" 18 | + default y if SMALL_FLASH 19 | help 20 | Reduces kernel size by stripping unused kernel exports from the kernel 21 | image. Note that this might make the kernel incompatible with any kernel 22 | @@ -182,6 +183,7 @@ menu "Global build settings" 23 | 24 | config USE_MKLIBS 25 | bool "Strip unnecessary functions from libraries" 26 | + default y if SMALL_FLASH 27 | help 28 | Reduces libraries to only those functions that are necessary for using all 29 | selected packages (including those selected as ). Note that this will 30 | -- 31 | 2.30.0 32 | 33 | -------------------------------------------------------------------------------- /patches/openwrt/0016-include-target-remove-ppp-and-opkg-by-default.patch: -------------------------------------------------------------------------------- 1 | From 3ce76fe839e63392750b5b70febfff18b98a249c Mon Sep 17 00:00:00 2001 2 | From: Moritz Warning 3 | Date: Tue, 20 Aug 2019 23:17:52 +0200 4 | Subject: [PATCH 16/16] include/target: remove ppp and opkg by default 5 | 6 | --- 7 | include/target.mk | 4 ++-- 8 | 1 file changed, 2 insertions(+), 2 deletions(-) 9 | 10 | diff --git a/include/target.mk b/include/target.mk 11 | index 7b0e92fce8..879954805d 100644 12 | --- a/include/target.mk 13 | +++ b/include/target.mk 14 | @@ -13,11 +13,11 @@ __target_inc=1 15 | DEVICE_TYPE?=router 16 | 17 | # Default packages - the really basic set 18 | -DEFAULT_PACKAGES:=base-files libc libgcc busybox dropbear mtd uci opkg netifd fstools uclient-fetch logd urandom-seed urngd 19 | +DEFAULT_PACKAGES:=base-files libc libgcc busybox dropbear mtd uci netifd fstools uclient-fetch logd urandom-seed urngd 20 | # For nas targets 21 | DEFAULT_PACKAGES.nas:=block-mount fdisk lsblk mdadm 22 | # For router targets 23 | -DEFAULT_PACKAGES.router:=dnsmasq iptables ip6tables ppp ppp-mod-pppoe firewall odhcpd-ipv6only odhcp6c kmod-ipt-offload 24 | +DEFAULT_PACKAGES.router:=dnsmasq iptables ip6tables firewall odhcpd-ipv6only odhcp6c kmod-ipt-offload 25 | DEFAULT_PACKAGES.bootloader:= 26 | 27 | ifneq ($(DUMP),) 28 | -- 29 | 2.30.0 30 | 31 | -------------------------------------------------------------------------------- /patches/packages/0001-fastd-update-to-v19.patch: -------------------------------------------------------------------------------- 1 | From: Matthias Schiffer 2 | Date: Fri, 22 May 2020 21:09:21 +0200 3 | Subject: fastd: update to v19 4 | 5 | Signed-off-by: Matthias Schiffer 6 | 7 | diff --git a/net/fastd/Config.in b/net/fastd/Config.in 8 | index 3350eb3099a26c870d70373c0712a8b59881ee5c..e6440075e561093c86543943cb982d010a4ef0e0 100644 9 | --- a/net/fastd/Config.in 10 | +++ b/net/fastd/Config.in 11 | @@ -36,16 +36,6 @@ config FASTD_ENABLE_METHOD_NULL 12 | depends on PACKAGE_fastd 13 | default y 14 | 15 | -config FASTD_ENABLE_METHOD_XSALSA20_POLY1305 16 | - bool "Enable xsalsa20-poly1305 method" 17 | - depends on PACKAGE_fastd 18 | - default n 19 | - 20 | - 21 | -config FASTD_ENABLE_CIPHER_AES128_CTR 22 | - bool "Enable the AES128-CTR cipher" 23 | - depends on PACKAGE_fastd 24 | - default n 25 | 26 | config FASTD_ENABLE_CIPHER_NULL 27 | bool "Enable the null cipher" 28 | diff --git a/net/fastd/Makefile b/net/fastd/Makefile 29 | index f4890b56931a75849229d25fe78720e19d493383..7483e7b003041fb59991d72d0ccfcc8a28bb17a3 100644 30 | --- a/net/fastd/Makefile 31 | +++ b/net/fastd/Makefile 32 | @@ -8,13 +8,13 @@ 33 | include $(TOPDIR)/rules.mk 34 | 35 | PKG_NAME:=fastd 36 | -PKG_VERSION:=18 37 | -PKG_RELEASE:=5 38 | +PKG_VERSION:=19 39 | +PKG_RELEASE:=2 40 | 41 | PKG_MAINTAINER:=Matthias Schiffer 42 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz 43 | PKG_SOURCE_URL:=https://github.com/NeoRaider/fastd/releases/download/v$(PKG_VERSION) 44 | -PKG_HASH:=714ff09d7bd75f79783f744f6f8c5af2fe456c8cf876feaa704c205a73e043c9 45 | +PKG_HASH:=6054608e2103b634c9d19ecd1ae058d4ec694747047130719db180578729783a 46 | 47 | PKG_LICENSE:=BSD-2-Clause 48 | PKG_LICENSE_FILES:=COPYRIGHT 49 | @@ -27,8 +27,6 @@ PKG_CONFIG_DEPENDS:=\ 50 | CONFIG_FASTD_ENABLE_METHOD_GENERIC_POLY1305 \ 51 | CONFIG_FASTD_ENABLE_METHOD_GENERIC_UMAC \ 52 | CONFIG_FASTD_ENABLE_METHOD_NULL \ 53 | - CONFIG_FASTD_ENABLE_METHOD_XSALSA20_POLY1305 \ 54 | - CONFIG_FASTD_ENABLE_CIPHER_AES128_CTR \ 55 | CONFIG_FASTD_ENABLE_CIPHER_NULL \ 56 | CONFIG_FASTD_ENABLE_CIPHER_SALSA20 \ 57 | CONFIG_FASTD_ENABLE_CIPHER_SALSA2012 \ 58 | @@ -44,6 +42,7 @@ PKG_CONFIG_DEPENDS:=\ 59 | 60 | 61 | PKG_BUILD_DEPENDS:=nacl 62 | +PKG_BUILD_PARALLEL:=1 63 | 64 | include $(INCLUDE_DIR)/package.mk 65 | include $(INCLUDE_DIR)/cmake.mk 66 | @@ -73,7 +72,6 @@ CMAKE_OPTIONS += \ 67 | -DWITH_METHOD_GENERIC_POLY1305:BOOL=FALSE \ 68 | -DWITH_METHOD_GENERIC_UMAC:BOOL=FALSE \ 69 | -DWITH_METHOD_NULL:BOOL=FALSE \ 70 | - -DWITH_METHOD_XSALSA20_POLY1305:BOOL=FALSE \ 71 | -DWITH_CIPHER_AES128_CTR:BOOL=FALSE \ 72 | -DWITH_CIPHER_NULL:BOOL=FALSE \ 73 | -DWITH_CIPHER_SALSA20:BOOL=FALSE \ 74 | @@ -120,14 +118,6 @@ ifeq ($(CONFIG_FASTD_ENABLE_METHOD_NULL),y) 75 | CMAKE_OPTIONS += -DWITH_METHOD_NULL:BOOL=TRUE 76 | endif 77 | 78 | -ifeq ($(CONFIG_FASTD_ENABLE_METHOD_XSALSA20_POLY1305),y) 79 | -CMAKE_OPTIONS += -DWITH_METHOD_XSALSA20_POLY1305:BOOL=TRUE 80 | -endif 81 | - 82 | - 83 | -ifeq ($(CONFIG_FASTD_ENABLE_CIPHER_AES128_CTR),y) 84 | -CMAKE_OPTIONS += -DWITH_CIPHER_AES128_CTR:BOOL=TRUE 85 | -endif 86 | 87 | ifeq ($(CONFIG_FASTD_ENABLE_CIPHER_NULL),y) 88 | CMAKE_OPTIONS += -DWITH_CIPHER_NULL:BOOL=TRUE 89 | diff --git a/net/fastd/patches/0001-resolve-fix-segmentation-fault-with-musl-1.1.20.patch b/net/fastd/patches/0001-resolve-fix-segmentation-fault-with-musl-1.1.20.patch 90 | deleted file mode 100644 91 | index 52c19174083c29e5da02cabb2ddc02474cf11b37..0000000000000000000000000000000000000000 92 | --- a/net/fastd/patches/0001-resolve-fix-segmentation-fault-with-musl-1.1.20.patch 93 | +++ /dev/null 94 | @@ -1,35 +0,0 @@ 95 | -From 9710132c04cd378bd36f16a2a3d98d9c4c5fdbac Mon Sep 17 00:00:00 2001 96 | -From: David Bauer 97 | -Date: Thu, 25 Jul 2019 18:51:25 +0200 98 | -Subject: [PATCH] resolve: fix segmentation fault with musl >1.1.20 99 | - 100 | -When compiled with musl >1.1.20, fastd will crash in case it can't 101 | -resolve a peers hostname. This is due to a changed implementation of 102 | -freeaddrinfo in musl 1.1.21 onwards. 103 | - 104 | -This segfault is fixed by not calling freeaddrinfo in case the supplied 105 | -pointer is null. 106 | - 107 | -Signed-off-by: David Bauer 108 | ---- 109 | - src/resolve.c | 4 +++- 110 | - 1 file changed, 3 insertions(+), 1 deletion(-) 111 | - 112 | -diff --git a/src/resolve.c b/src/resolve.c 113 | -index 9bdfa1c..bfd2a59 100644 114 | ---- a/src/resolve.c 115 | -+++ b/src/resolve.c 116 | -@@ -104,7 +104,9 @@ static void * resolve_peer(void *varg) { 117 | - 118 | - fastd_async_enqueue(ASYNC_TYPE_RESOLVE_RETURN, ret, sizeof(fastd_async_resolve_return_t) + n_addr*sizeof(fastd_peer_address_t)); 119 | - 120 | -- freeaddrinfo(res); 121 | -+ if (res) 122 | -+ freeaddrinfo(res); 123 | -+ 124 | - free(arg->hostname); 125 | - free(arg); 126 | - 127 | --- 128 | -2.20.1 129 | - 130 | diff --git a/net/fastd/patches/0002-doc-examples-openwrt-fix-init-script-wasn-t-working-.patch b/net/fastd/patches/0002-doc-examples-openwrt-fix-init-script-wasn-t-working-.patch 131 | deleted file mode 100644 132 | index b576a987369e93f3cd14fbc83f3c4bffe5cc97d1..0000000000000000000000000000000000000000 133 | --- a/net/fastd/patches/0002-doc-examples-openwrt-fix-init-script-wasn-t-working-.patch 134 | +++ /dev/null 135 | @@ -1,29 +0,0 @@ 136 | -From c29b4b0e3cc5bf68129fd0f94f424950b7888deb Mon Sep 17 00:00:00 2001 137 | -Message-Id: 138 | -From: Wilfried Klaebe 139 | -Date: Sat, 31 Aug 2019 21:44:13 +0200 140 | -Subject: [PATCH] doc: examples/openwrt: fix init script, wasn't working with 141 | - two VPNs 142 | - 143 | -If two VPNs were configured via uci, the init script complained about 144 | -the peer group of its peers not matching its net. 145 | ---- 146 | - doc/examples/openwrt/fastd.init | 2 +- 147 | - 1 file changed, 1 insertion(+), 1 deletion(-) 148 | - 149 | -diff --git a/doc/examples/openwrt/fastd.init b/doc/examples/openwrt/fastd.init 150 | -index 15737b403ec2..4ba69ece9887 100644 151 | ---- a/doc/examples/openwrt/fastd.init 152 | -+++ b/doc/examples/openwrt/fastd.init 153 | -@@ -233,7 +233,7 @@ generate_peer_group_config() { 154 | - config_get group_parent "$group" parent 155 | - [ "$parent" = "$group_parent" ] || return 0 156 | - 157 | -- if [ "$net" != "$peer_net" ]; then 158 | -+ if [ "$net" != "$group_net" ]; then 159 | - [ -z "$parent" ] || error "warning: the parent of peer group '$group' doesn't match its net, the peer group will be ignored" 160 | - return 0 161 | - fi 162 | --- 163 | -2.23.0 164 | - 165 | -------------------------------------------------------------------------------- /patches/packages/0002-ecdsautils-verify-fix-signature-verification-CVE-2022-24884.patch: -------------------------------------------------------------------------------- 1 | From: Matthias Schiffer 2 | Date: Wed, 27 Apr 2022 19:01:39 +0200 3 | Subject: ecdsautils: verify: fix signature verification (CVE-2022-24884) 4 | 5 | Signed-off-by: Matthias Schiffer 6 | 7 | diff --git a/utils/ecdsautils/Makefile b/utils/ecdsautils/Makefile 8 | index 7f1c76f0301f56b0a88c1f6a1a0147397fde25c7..5ba893be69d40279cd6f5c9e544e941d0011f451 100644 9 | --- a/utils/ecdsautils/Makefile 10 | +++ b/utils/ecdsautils/Makefile 11 | @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk 12 | 13 | PKG_NAME:=ecdsautils 14 | PKG_VERSION:=0.3.2.20160630 15 | -PKG_RELEASE:=1 16 | +PKG_RELEASE:=2 17 | PKG_REV:=07538893fb6c2a9539678c45f9dbbf1e4f222b46 18 | PKG_MAINTAINER:=Matthias Schiffer 19 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz 20 | diff --git a/utils/ecdsautils/patches/0001-verify-fix-signature-verification-CVE-2022-24884.patch b/utils/ecdsautils/patches/0001-verify-fix-signature-verification-CVE-2022-24884.patch 21 | new file mode 100644 22 | index 0000000000000000000000000000000000000000..34d80cc201c0e87ca654c3def4fbbbddf622b0ba 23 | --- /dev/null 24 | +++ b/utils/ecdsautils/patches/0001-verify-fix-signature-verification-CVE-2022-24884.patch 25 | @@ -0,0 +1,48 @@ 26 | +From 1d4b091abdf15ad7b2312535b5b95ad70f6dbd08 Mon Sep 17 00:00:00 2001 27 | +Message-Id: <1d4b091abdf15ad7b2312535b5b95ad70f6dbd08.1651078760.git.mschiffer@universe-factory.net> 28 | +From: Matthias Schiffer 29 | +Date: Wed, 20 Apr 2022 22:04:07 +0200 30 | +Subject: [PATCH] verify: fix signature verification (CVE-2022-24884) 31 | + 32 | +Verify that r and s are non-zero. Without these checks, an all-zero 33 | +signature is always considered valid. 34 | + 35 | +While it would be nicer to error out in ecdsa_verify_prepare_legacy() 36 | +already, that would require users of libecdsautil to check a return value 37 | +of the prepare step. To be safe, implement the fix in an API/ABI-compatible 38 | +way that doesn't need changes to the users. 39 | +--- 40 | + src/lib/ecdsa.c | 10 ++++++++++ 41 | + 1 file changed, 10 insertions(+) 42 | + 43 | +diff --git a/src/lib/ecdsa.c b/src/lib/ecdsa.c 44 | +index 8cd7722be8cd..a661b56bd7c8 100644 45 | +--- a/src/lib/ecdsa.c 46 | ++++ b/src/lib/ecdsa.c 47 | +@@ -135,6 +135,12 @@ regenerate: 48 | + void ecdsa_verify_prepare_legacy(ecdsa_verify_context_t *ctx, const ecc_int256_t *hash, const ecdsa_signature_t *signature) { 49 | + ecc_int256_t w, u1, tmp; 50 | + 51 | ++ if (ecc_25519_gf_is_zero(&signature->s) || ecc_25519_gf_is_zero(&signature->r)) { 52 | ++ // Signature is invalid, mark by setting ctx->r to an invalid value 53 | ++ memset(&ctx->r, 0, sizeof(ctx->r)); 54 | ++ return; 55 | ++ } 56 | ++ 57 | + ctx->r = signature->r; 58 | + 59 | + ecc_25519_gf_recip(&w, &signature->s); 60 | +@@ -149,6 +155,10 @@ bool ecdsa_verify_legacy(const ecdsa_verify_context_t *ctx, const ecc_25519_work 61 | + ecc_25519_work_t s2, work; 62 | + ecc_int256_t w, tmp; 63 | + 64 | ++ // Signature was detected as invalid in prepare step 65 | ++ if (ecc_25519_gf_is_zero(&ctx->r)) 66 | ++ return false; 67 | ++ 68 | + ecc_25519_scalarmult(&s2, &ctx->u2, pubkey); 69 | + ecc_25519_add(&work, &ctx->s1, &s2); 70 | + ecc_25519_store_xy_legacy(&w, NULL, &work); 71 | +-- 72 | +2.36.0 73 | + 74 | -------------------------------------------------------------------------------- /patches/routing/0001-alfred-adjust-intervals.patch: -------------------------------------------------------------------------------- 1 | From f5a291cd75dbd0eefa8451118a8a7f97597730f8 Mon Sep 17 00:00:00 2001 2 | From: Matthias Schiffer 3 | Date: Wed, 7 Jan 2015 16:45:09 +0100 4 | Subject: [PATCH 1/1] alfred: adjust intervals 5 | 6 | --- 7 | alfred/patches/0001-alfred-adjust-intervals.patch | 15 +++++++++++++++ 8 | 1 file changed, 15 insertions(+) 9 | create mode 100644 alfred/patches/0001-alfred-adjust-intervals.patch 10 | 11 | diff --git a/alfred/patches/0001-alfred-adjust-intervals.patch b/alfred/patches/0001-alfred-adjust-intervals.patch 12 | new file mode 100644 13 | index 0000000..a6d1e40 14 | --- /dev/null 15 | +++ b/alfred/patches/0001-alfred-adjust-intervals.patch 16 | @@ -0,0 +1,15 @@ 17 | +--- a/alfred.h 18 | ++++ b/alfred.h 19 | +@@ -36,10 +36,10 @@ 20 | + #include "list.h" 21 | + #include "packet.h" 22 | + 23 | +-#define ALFRED_INTERVAL 10 24 | ++#define ALFRED_INTERVAL 60 25 | + #define ALFRED_IF_CHECK_INTERVAL 60 26 | + #define ALFRED_REQUEST_TIMEOUT 10 27 | +-#define ALFRED_SERVER_TIMEOUT 60 28 | ++#define ALFRED_SERVER_TIMEOUT 180 29 | + #define ALFRED_DATA_TIMEOUT 600 30 | + #define ALFRED_SOCK_PATH_DEFAULT "/var/run/alfred.sock" 31 | + #define NO_FILTER -1 32 | -- 33 | 2.26.2 34 | 35 | --------------------------------------------------------------------------------