ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/network/utils/adb-enablemodem/Makefile b/package/network/utils/adb-enablemodem/Makefile
new file mode 100644
index 0000000..05479e3
--- /dev/null
+++ b/package/network/utils/adb-enablemodem/Makefile
@@ -0,0 +1,26 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=adb-enablemodem
+PKG_VERSION:=2017.03.05
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/adb-enablemodem
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=WWAN
+ TITLE:=Enable modem via adb
+ DEPENDS:=+adb
+endef
+
+define Build/Compile
+ true
+endef
+
+define Package/adb-enablemodem/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/adb-enablemodem $(1)/etc/init.d/adb-enablemodem
+endef
+
+$(eval $(call BuildPackage,adb-enablemodem))
diff --git a/package/network/utils/adb-enablemodem/files/adb-enablemodem b/package/network/utils/adb-enablemodem/files/adb-enablemodem
new file mode 100644
index 0000000..ddfc681
--- /dev/null
+++ b/package/network/utils/adb-enablemodem/files/adb-enablemodem
@@ -0,0 +1,64 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+
+adb_exec() {
+ adb -s "$serial" shell "( $1 ) >/dev/null 2>&1"'; printf "\nEXIT_CODE: %i\n" $?' | head -c 64 | grep -qx 'EXIT_CODE: 0\r\?'
+}
+
+enablemodem_do() {
+ logger -t adb-enablemodem 'INFO: waiting for device'
+ adb wait-for-device
+ serial="$(adb get-serialno)"
+
+ vendor_id="$(adb -s "$serial" shell 'uci get product.usb.vid' | head -c 16 | tr -d '\r\n')"
+ product_id="$(adb -s "$serial" shell 'uci get product.usb.pid' | head -c 16 | tr -d '\r\n')"
+
+ case "$vendor_id:$product_id" in
+ "0x2357:0x000D") # TP-LINK LTE MODULE
+ case "$1" in
+ start)
+ if adb_exec '
+ chmod +x /WEBSERVER/www/cgi-bin/*
+ fds="$(ls /proc/$$/fd | grep -v "^[012]$")"
+ for fd in $fds; do
+ eval "exec $fd>&-"
+ done
+ start-stop-daemon -x httpd -S -- -h /WEBSERVER/www/
+ '; then
+ logger -t adb-enablemodem 'INFO: httpd on modem started'
+ else
+ logger -t adb-enablemodem 'ERROR: failed to start httpd on modem'
+ fi
+ option_newid='/sys/bus/usb-serial/drivers/option1/new_id'
+ if [ -e "$option_newid" ]; then
+ printf '%s %s' "$vendor_id" "$product_id" > "$option_newid"
+ fi
+ ;;
+ stop)
+ if adb_exec 'start-stop-daemon -x httpd -K'; then
+ logger -t adb-enablemodem 'INFO: httpd on modem stopped'
+ else
+ logger -t adb-enablemodem 'ERROR: failed to stop httpd on modem'
+ fi
+ ;;
+ esac
+ ;;
+ *)
+ logger -t adb-enablemodem "ERROR: unknown device $vendor_id:$product_id"
+ ;;
+ esac
+}
+
+start() {
+ ( enablemodem_do start ) &
+}
+
+stop() {
+ ( enablemodem_do stop ) &
+}
+
+restart() {
+ ( enablemodem_do stop; enablemodem_do start ) &
+}
+
diff --git a/package/network/utils/arptables/Makefile b/package/network/utils/arptables/Makefile
new file mode 100644
index 0000000..6a92e8a
--- /dev/null
+++ b/package/network/utils/arptables/Makefile
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2006-2016 OpenWrt.org
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=arptables
+PKG_VERSION:=0.0.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://ftp.netfilter.org/pub/arptables
+PKG_HASH:=4f9a0656ce5c90868f551cd4deeb2d04f33899667e1fb2818b64e432fe8f629c
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/arptables
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Firewall
+ TITLE:=ARP firewalling software
+ DEPENDS:=+kmod-arptables
+ URL:=https://git.netfilter.org/arptables/
+endef
+
+MAKE_FLAGS += \
+ COPT_FLAGS="$(TARGET_CFLAGS) -D__OPTIMIZE__=1" \
+ KERNEL_DIR="$(LINUX_DIR)"
+
+define Package/arptables/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,arptables))
diff --git a/package/network/utils/bpftool/Makefile b/package/network/utils/bpftool/Makefile
new file mode 100644
index 0000000..b2fdfc1
--- /dev/null
+++ b/package/network/utils/bpftool/Makefile
@@ -0,0 +1,120 @@
+#
+# Copyright (C) 2020-2024 Tony Ambardar <itugrok@yahoo.com>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bpftool
+PKG_VERSION:=7.5.0
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=https://github.com/libbpf/bpftool
+PKG_MIRROR_HASH:=1da7c08959e7819772145774322ffd876f3180065be1c3759336dca98ac9f666
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=v$(PKG_VERSION)
+
+PKG_MAINTAINER:=Tony Ambardar <itugrok@yahoo.com>
+
+PKG_BUILD_FLAGS:=no-mips16 gc-sections lto
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+HOST_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/bpftool/Default
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=bpftool - eBPF subsystem utility
+ LICENSE:=GPL-2.0-only OR BSD-2-Clause
+ URL:=http://www.kernel.org
+ DEPENDS:=+libelf
+endef
+
+define Package/bpftool-minimal
+ $(call Package/bpftool/Default)
+ TITLE+= (Minimal)
+ VARIANT:=minimal
+ DEFAULT_VARIANT:=1
+ PROVIDES:=bpftool
+ ALTERNATIVES:=200:/usr/sbin/bpftool:/usr/libexec/bpftool-minimal
+endef
+
+define Package/bpftool-full
+ $(call Package/bpftool/Default)
+ TITLE+= (Full)
+ VARIANT:=full
+ PROVIDES:=bpftool
+ ALTERNATIVES:=300:/usr/sbin/bpftool:/usr/libexec/bpftool-full
+ DEPENDS+= +libbfd +libopcodes
+endef
+
+define Package/bpftool-minimal/description
+ A tool for inspection and simple manipulation of eBPF programs and maps.
+endef
+
+define Package/bpftool-full/description
+ A tool for inspection and simple manipulation of eBPF programs and maps.
+ This full version uses libbfd and libopcodes to support disassembly of
+ eBPF programs and jited code.
+endef
+
+ifeq ($(BUILD_VARIANT),full)
+ full:=1
+else
+ full:=0
+endif
+
+MAKE_FLAGS += \
+ OUTPUT="$(PKG_BUILD_DIR)/" \
+ prefix="/usr" \
+ $(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='') \
+ check_feat=0 \
+ feature-clang-bpf-co-re=0 \
+ feature-libbfd=$(full) \
+ feature-llvm=0 \
+ feature-libcap=0 \
+ feature-disassembler-four-args=1 \
+ feature-disassembler-init-styled=1
+
+MAKE_PATH = src
+
+define Package/bpftool-$(BUILD_VARIANT)/install
+ $(INSTALL_DIR) $(1)/usr/libexec
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/bpftool \
+ $(1)/usr/libexec/bpftool-$(BUILD_VARIANT)
+endef
+
+HOST_MAKE_FLAGS += \
+ OUTPUT="$(HOST_BUILD_DIR)/" \
+ prefix="/usr" \
+ $(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='') \
+ check_feat=0 \
+ feature-clang-bpf-co-re=0 \
+ feature-libbfd=0 \
+ feature-llvm=0 \
+ feature-libcap=0 \
+ feature-disassembler-four-args=1 \
+ feature-disassembler-init-styled=1
+
+HOST_MAKE_PATH = src
+
+define Host/Install
+ $(INSTALL_DIR) $(STAGING_DIR_HOST)/usr/sbin
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/bpftool \
+ $(STAGING_DIR_HOST)/usr/sbin/bpftool
+endef
+
+define Host/Clean
+ rm -f $(STAGING_DIR_HOST)/usr/sbin/bpftool
+endef
+
+$(eval $(call BuildPackage,bpftool-full))
+$(eval $(call BuildPackage,bpftool-minimal))
+$(eval $(call HostBuild))
diff --git a/package/network/utils/bpftool/patches/002-includes.patch b/package/network/utils/bpftool/patches/002-includes.patch
new file mode 100644
index 0000000..e6ec3f2
--- /dev/null
+++ b/package/network/utils/bpftool/patches/002-includes.patch
@@ -0,0 +1,15 @@
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -73,10 +73,10 @@ CFLAGS += -W -Wall -Wextra -Wno-unused-p
+ CFLAGS += $(filter-out -Wswitch-enum -Wnested-externs,$(EXTRA_WARNINGS))
+ CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ \
+ -I$(or $(OUTPUT),.) \
+- -I$(LIBBPF_INCLUDE) \
+ -I$(srctree)/src/kernel/bpf/ \
+ -I$(srctree)/include \
+- -I$(srctree)/include/uapi
++ -I$(srctree)/include/uapi \
++ -I$(LIBBPF_INCLUDE)
+ ifneq ($(BPFTOOL_VERSION),)
+ CFLAGS += -DBPFTOOL_VERSION='"$(BPFTOOL_VERSION)"'
+ endif
diff --git a/package/network/utils/comgt/Makefile b/package/network/utils/comgt/Makefile
new file mode 100644
index 0000000..0e826e1
--- /dev/null
+++ b/package/network/utils/comgt/Makefile
@@ -0,0 +1,106 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=comgt
+PKG_VERSION:=0.32
+PKG_RELEASE:=36
+
+PKG_SOURCE:=$(PKG_NAME).$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=@SF/comgt
+PKG_HASH:=0cedb2a5aa608510da66a99aab74df3db363df495032e57e791a2ff55f1d7913
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+PKG_LICENSE:=GPL-2.0+
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME).$(PKG_VERSION)
+PKG_CHECK_FORMAT_SECURITY:=0
+
+PKG_FLAGS:=nonshared
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/comgt/Default
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=WWAN
+endef
+
+define Package/comgt
+$(call Package/comgt/Default)
+ TITLE:=Option/Vodafone 3G/GPRS control tool
+ DEPENDS:=+chat
+ URL:=http://manpages.ubuntu.com/manpages/trusty/man1/comgt.1.html
+endef
+
+define Package/comgt-directip
+$(call Package/comgt/Default)
+ TITLE:=Sierra Wireless Direct-IP support
+ DEPENDS:=+comgt +kmod-usb-serial +kmod-usb-serial-sierrawireless +kmod-usb-net +kmod-usb-net-sierrawireless
+endef
+
+define Package/comgt-ncm
+$(call Package/comgt/Default)
+ TITLE+=NCM 3G/4G Support
+ DEPENDS:=+comgt +wwan +kmod-usb-serial-option +kmod-usb-net-huawei-cdc-ncm
+endef
+
+define Package/comgt/description
+ comgt is a scripting language interpreter useful for establishing
+ communications on serial lines and through PCMCIA modems as well as GPRS
+ and 3G datacards.
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ LDFLAGS="" \
+ comgt
+endef
+
+define Package/comgt/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/comgt $(1)/usr/bin/
+ $(LN) comgt $(1)/usr/bin/gcom
+ $(INSTALL_DIR) $(1)/etc/chatscripts
+ $(INSTALL_DATA) ./files/3g.chat $(1)/etc/chatscripts/3g.chat
+ $(INSTALL_DATA) ./files/evdo.chat $(1)/etc/chatscripts/evdo.chat
+ $(INSTALL_DIR) $(1)/etc/gcom
+ $(INSTALL_DATA) ./files/setpin.gcom $(1)/etc/gcom/setpin.gcom
+ $(INSTALL_DATA) ./files/setmode.gcom $(1)/etc/gcom/setmode.gcom
+ $(INSTALL_DATA) ./files/getcardinfo.gcom $(1)/etc/gcom/getcardinfo.gcom
+ $(INSTALL_DATA) ./files/getstrength.gcom $(1)/etc/gcom/getstrength.gcom
+ $(INSTALL_DATA) ./files/getcarrier.gcom $(1)/etc/gcom/getcarrier.gcom
+ $(INSTALL_DATA) ./files/getcnum.gcom $(1)/etc/gcom/getcnum.gcom
+ $(INSTALL_DATA) ./files/getimsi.gcom $(1)/etc/gcom/getimsi.gcom
+ $(INSTALL_DATA) ./files/runcommand.gcom $(1)/etc/gcom/runcommand.gcom
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/tty
+ $(INSTALL_CONF) ./files/3g.usb $(1)/etc/hotplug.d/tty/30-3g
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/3g.sh $(1)/lib/netifd/proto/3g.sh
+endef
+
+define Package/comgt-directip/install
+ $(INSTALL_DIR) $(1)/etc/gcom
+ $(INSTALL_DATA) ./files/directip.gcom $(1)/etc/gcom/directip.gcom
+ $(INSTALL_DATA) ./files/directip-stop.gcom $(1)/etc/gcom/directip-stop.gcom
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/directip.sh $(1)/lib/netifd/proto/directip.sh
+endef
+
+define Package/comgt-ncm/install
+ $(INSTALL_DIR) $(1)/etc/gcom
+ $(INSTALL_DATA) ./files/ncm.json $(1)/etc/gcom/ncm.json
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/ncm.sh $(1)/lib/netifd/proto/ncm.sh
+endef
+
+$(eval $(call BuildPackage,comgt))
+$(eval $(call BuildPackage,comgt-directip))
+$(eval $(call BuildPackage,comgt-ncm))
diff --git a/package/network/utils/comgt/files/3g.chat b/package/network/utils/comgt/files/3g.chat
new file mode 100644
index 0000000..6656240
--- /dev/null
+++ b/package/network/utils/comgt/files/3g.chat
@@ -0,0 +1,12 @@
+ABORT BUSY
+ABORT 'NO CARRIER'
+ABORT ERROR
+REPORT CONNECT
+TIMEOUT 10
+"" "AT&F"
+OK "ATE1"
+OK 'AT+CGDCONT=1,"IP","$USE_APN"'
+SAY "Calling UMTS/GPRS"
+TIMEOUT 30
+OK "ATD$DIALNUMBER"
+CONNECT ' '
diff --git a/package/network/utils/comgt/files/3g.sh b/package/network/utils/comgt/files/3g.sh
new file mode 100644
index 0000000..42ba894
--- /dev/null
+++ b/package/network/utils/comgt/files/3g.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ NOT_INCLUDED=1
+ INCLUDE_ONLY=1
+
+ . ../netifd-proto.sh
+ . ./ppp.sh
+ init_proto "$@"
+}
+
+proto_3g_init_config() {
+ no_device=1
+ available=1
+ ppp_generic_init_config
+ proto_config_add_string "device:device"
+ proto_config_add_string "apn"
+ proto_config_add_string "service"
+ proto_config_add_string "pincode"
+ proto_config_add_string "delay"
+ proto_config_add_string "dialnumber"
+}
+
+proto_3g_setup() {
+ local interface="$1"
+ local chat
+
+ json_get_var device device
+ json_get_var apn apn
+ json_get_var service service
+ json_get_var pincode pincode
+ json_get_var dialnumber dialnumber
+ json_get_var delay delay
+
+ [ -n "$dat_device" ] && device=$dat_device
+
+ device="$(readlink -f $device)"
+ [ -e "$device" ] || {
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ [ -n "$delay" ] && sleep "$delay"
+
+ case "$service" in
+ cdma|evdo)
+ chat="/etc/chatscripts/evdo.chat"
+ ;;
+ *)
+ chat="/etc/chatscripts/3g.chat"
+ cardinfo=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom)
+ if echo "$cardinfo" | grep -q Novatel; then
+ case "$service" in
+ umts_only) CODE=2;;
+ gprs_only) CODE=1;;
+ *) CODE=0;;
+ esac
+ export MODE="AT\$NWRAT=${CODE},2"
+ elif echo "$cardinfo" | grep -q Option; then
+ case "$service" in
+ umts_only) CODE=1;;
+ gprs_only) CODE=0;;
+ *) CODE=3;;
+ esac
+ export MODE="AT_OPSYS=${CODE}"
+ elif echo "$cardinfo" | grep -q "Sierra Wireless"; then
+ SIERRA=1
+ elif echo "$cardinfo" | grep -qi huawei; then
+ case "$service" in
+ umts_only) CODE="14,2";;
+ gprs_only) CODE="13,1";;
+ *) CODE="2,2";;
+ esac
+ export MODE="AT^SYSCFG=${CODE},3FFFFFFF,2,4"
+ elif echo "$cardinfo" | grep -q "MikroTik"; then
+ COMMAND="AT+CFUN=1" gcom -d "$device" -s /etc/gcom/runcommand.gcom || return 1
+ fi
+
+ if [ -n "$pincode" ]; then
+ PINCODE="$pincode" gcom -d "$device" -s /etc/gcom/setpin.gcom || {
+ proto_notify_error "$interface" PIN_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+ fi
+ [ -n "$MODE" ] && gcom -d "$device" -s /etc/gcom/setmode.gcom
+
+ # wait for carrier to avoid firmware stability bugs
+ [ -n "$SIERRA" ] && {
+ gcom -d "$device" -s /etc/gcom/getcarrier.gcom || return 1
+ }
+
+ if [ -z "$dialnumber" ]; then
+ dialnumber="*99***1#"
+ fi
+
+ ;;
+ esac
+
+ connect="${apn:+USE_APN=$apn }DIALNUMBER=$dialnumber /usr/sbin/chat -t5 -v -E -f $chat"
+ ppp_generic_setup "$interface" \
+ noaccomp \
+ nopcomp \
+ novj \
+ nobsdcomp \
+ noauth \
+ set EXTENDPREFIX=1 \
+ lock \
+ crtscts \
+ 115200 "$device"
+ return 0
+}
+
+proto_3g_teardown() {
+ proto_kill_command "$interface"
+}
+
+[ -z "$NOT_INCLUDED" ] || add_protocol 3g
diff --git a/package/network/utils/comgt/files/3g.usb b/package/network/utils/comgt/files/3g.usb
new file mode 100644
index 0000000..9c7d07a
--- /dev/null
+++ b/package/network/utils/comgt/files/3g.usb
@@ -0,0 +1,35 @@
+#!/bin/sh
+. /lib/functions.sh
+. /lib/netifd/netifd-proto.sh
+
+find_3g_iface() {
+ local cfg="$1"
+ local tty="$2"
+
+ local proto
+ config_get proto "$cfg" proto
+ [ "$proto" = 3g ] || [ "$proto" = ncm ] || return 0
+
+ # bypass state vars here because 00-netstate could clobber .device
+ local dev=$(uci_get network "$cfg" device)
+
+ if [ "${dev##*/}" = "${tty##*/}" ]; then
+ if [ "$ACTION" = add ]; then
+ proto_set_available "$cfg" 1
+ fi
+ if [ "$ACTION" = remove ]; then
+ proto_set_available "$cfg" 0
+ fi
+ fi
+}
+
+[ "$ACTION" = add ] || [ "$ACTION" = remove ] || exit 0
+
+case "$DEVICENAME" in
+ tty*)
+ [ -e "/dev/$DEVICENAME" ] || [ "$ACTION" = remove ] || exit 0
+ config_load network
+ config_foreach find_3g_iface interface "/dev/$DEVICENAME"
+ ;;
+esac
+
diff --git a/package/network/utils/comgt/files/directip-stop.gcom b/package/network/utils/comgt/files/directip-stop.gcom
new file mode 100644
index 0000000..1c14863
--- /dev/null
+++ b/package/network/utils/comgt/files/directip-stop.gcom
@@ -0,0 +1,16 @@
+opengt
+set com 115200n81
+set comecho off
+set senddelay 0.05
+waitquiet 1 0.2
+
+:start
+ send "AT!SCACT=0,3^m"
+ waitfor 5 "OK"
+ if % = 0 goto hangupok
+ print "WWAN error. Hangup failed.\r\n"
+ exit 1
+
+:hangupok
+ print "WWAN connection established.\r\n"
+ exit 0
diff --git a/package/network/utils/comgt/files/directip.gcom b/package/network/utils/comgt/files/directip.gcom
new file mode 100644
index 0000000..9a772a9
--- /dev/null
+++ b/package/network/utils/comgt/files/directip.gcom
@@ -0,0 +1,55 @@
+opengt
+set com 115200n81
+set comecho off
+set senddelay 0.05
+waitquiet 1 0.2
+
+:start
+ if $env("USE_AUTH") = "0" goto connect
+ send "AT$QCPDPP=3,"
+ send $env("USE_AUTH")
+ send ",\""
+ if $env("USE_USER") <> "" send $env("USE_USER")
+ send "\",\""
+ if $env("USE_PASS") <> "" send $env("USE_PASS")
+ send "\"^m"
+ waitfor 5 "OK"
+ if % = 0 goto connect
+ print "WWAN error. Auth failed.\r\n"
+ exit 1
+
+:connect
+ send "AT+CFUN=1^m"
+ send "AT+CGDCONT=3,\"IP\",\""
+ send $env("USE_APN")
+ send "\"^m"
+ waitfor 5 "OK"
+ if % = 0 goto connok
+ print "WWAN error. Connection failed.\r\n"
+ exit 1
+
+:connok
+ let c=1
+:loop
+ sleep 2
+ send "AT+CGATT?^m"
+ waitfor 5 "+CGATT: 1"
+ if % = 0 goto carrierok
+ if c > 10 goto carriererr
+ inc c
+ goto loop
+
+:carriererr
+ print "WWAN error. No carrier.\r\n"
+ exit 1
+
+:carrierok
+ send "AT!SCACT=1,3^m"
+ waitfor 5 "OK"
+ if % = 0 goto dialok
+ print "WWAN error. Dialing failed.\r\n"
+ exit 1
+
+:dialok
+ print "WWAN connection established.\r\n"
+ exit 0
diff --git a/package/network/utils/comgt/files/directip.sh b/package/network/utils/comgt/files/directip.sh
new file mode 100644
index 0000000..6535de9
--- /dev/null
+++ b/package/network/utils/comgt/files/directip.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_directip_init_config() {
+ available=1
+ no_device=1
+ proto_config_add_string "device:device"
+ proto_config_add_string "apn"
+ proto_config_add_string "pincode"
+ proto_config_add_string "auth"
+ proto_config_add_string "username"
+ proto_config_add_string "password"
+ proto_config_add_boolean sourcefilter
+ proto_config_add_boolean delegate
+ proto_config_add_defaults
+}
+
+proto_directip_setup() {
+ local interface="$1"
+ local chat devpath devname
+
+ local device apn pincode ifname auth username password sourcefilter delegate $PROTO_DEFAULT_OPTIONS
+ json_get_vars device apn pincode auth username password sourcefilter delegate $PROTO_DEFAULT_OPTIONS
+
+ [ -n "$ctl_device" ] && device=$ctl_device
+
+ device="$(readlink -f $device)"
+ [ -e "$device" ] || {
+ proto_notify_error "$interface" NO_DEVICE
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ devname="$(basename "$device")"
+ devpath="$(readlink -f /sys/class/tty/$devname/device)"
+ ifname="$( ls "$devpath"/../../*/net )"
+
+ [ -n "$ifname" ] || {
+ proto_notify_error "$interface" NO_IFNAME
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | grep -q "Sierra Wireless" || {
+ proto_notify_error "$interface" BAD_DEVICE
+ proto_block_restart "$interface"
+ return 1
+ }
+
+ if [ -n "$pincode" ]; then
+ PINCODE="$pincode" gcom -d "$device" -s /etc/gcom/setpin.gcom || {
+ proto_notify_error "$interface" PIN_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+ fi
+ # wait for carrier to avoid firmware stability bugs
+ gcom -d "$device" -s /etc/gcom/getcarrier.gcom || return 1
+
+ local auth_type=0
+ case $auth in
+ pap) auth_type=1;;
+ chap) auth_type=2;;
+ esac
+
+ USE_APN="$apn" USE_USER="$username" USE_PASS="$password" USE_AUTH="$auth_type" \
+ gcom -d "$device" -s /etc/gcom/directip.gcom || {
+ proto_notify_error "$interface" CONNECT_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+
+ logger -p daemon.info -t "directip[$$]" "Connected, starting DHCP"
+ proto_init_update "$ifname" 1
+ proto_send_update "$interface"
+
+ json_init
+ json_add_string name "${interface}_4"
+ json_add_string ifname "@$interface"
+ json_add_string proto "dhcp"
+ proto_add_dynamic_defaults
+ ubus call network add_dynamic "$(json_dump)"
+
+ json_init
+ json_add_string name "${interface}_6"
+ json_add_string ifname "@$interface"
+ json_add_string proto "dhcpv6"
+ json_add_string extendprefix 1
+ [ "$delegate" = "0" ] && json_add_boolean delegate "0"
+ [ "$sourcefilter" = "0" ] && json_add_boolean sourcefilter "0"
+ proto_add_dynamic_defaults
+ ubus call network add_dynamic "$(json_dump)"
+
+ return 0
+}
+
+proto_directip_teardown() {
+ local interface="$1"
+
+ local device
+ json_get_vars device
+
+ [ -n "$ctl_device" ] && device=$ctl_device
+
+ gcom -d "$device" -s /etc/gcom/directip-stop.gcom || proto_notify_error "$interface" CONNECT_FAILED
+
+ proto_init_update "*" 0
+ proto_send_update "$interface"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol directip
+}
diff --git a/package/network/utils/comgt/files/evdo.chat b/package/network/utils/comgt/files/evdo.chat
new file mode 100644
index 0000000..de49e41
--- /dev/null
+++ b/package/network/utils/comgt/files/evdo.chat
@@ -0,0 +1,17 @@
+# This is a simple chat script based off of the one provided by Sierra Wireless
+# for CDMA connections. It should work for both Sprint and Verizon networks.
+
+ABORT BUSY
+ABORT 'NO CARRIER'
+ABORT ERROR
+ABORT 'NO DIAL TONE'
+ABORT 'NO ANSWER'
+ABORT DELAYED
+REPORT CONNECT
+TIMEOUT 10
+'' AT
+OK ATZ
+SAY 'Calling CDMA/EVDO'
+TIMEOUT 30
+OK ATDT#777
+CONNECT ''
diff --git a/package/network/utils/comgt/files/getcardinfo.gcom b/package/network/utils/comgt/files/getcardinfo.gcom
new file mode 100644
index 0000000..f91665f
--- /dev/null
+++ b/package/network/utils/comgt/files/getcardinfo.gcom
@@ -0,0 +1,14 @@
+opengt
+ set com 115200n81
+ set comecho off
+ set senddelay 0.02
+ waitquiet 0.2 0.2
+ flash 0.1
+
+:start
+ send "AT+CGMI^m"
+ get 1 "" $s
+ print $s
+
+:continue
+ exit 0
diff --git a/package/network/utils/comgt/files/getcarrier.gcom b/package/network/utils/comgt/files/getcarrier.gcom
new file mode 100644
index 0000000..1e0216d
--- /dev/null
+++ b/package/network/utils/comgt/files/getcarrier.gcom
@@ -0,0 +1,20 @@
+opengt
+ set senddelay 0.05
+ waitquiet 1 0.2
+ let c=1
+ :loop
+ inc c
+ send "AT+CGATT?^m"
+ waitfor 5 "+CGATT: 1","+CGATT: 0"
+ print "\n."
+ if % = -1 goto error
+ if c > 10 goto toolong
+ if % = 0 goto out
+ sleep 2
+ if % = 1 goto loop
+ :toolong
+ exit 1
+ :error
+ exit 0
+ :out
+ exit 0
diff --git a/package/network/utils/comgt/files/getcnum.gcom b/package/network/utils/comgt/files/getcnum.gcom
new file mode 100644
index 0000000..450cf8c
--- /dev/null
+++ b/package/network/utils/comgt/files/getcnum.gcom
@@ -0,0 +1,20 @@
+opengt
+ set com 115200n81
+ set comecho off
+ set senddelay 0.02
+ waitquiet 0.2 0.2
+ flash 0.1
+
+:start
+ send "AT+CNUM^m"
+ get 1 "^m" $n
+ get 1 ":" $n
+ get 1 "\"" $n
+ get 1 "\"" $n
+ get 1 "\"" $n
+ get 1 "\"" $n
+ let n = len($n)
+ if n<1 goto continue
+ print $n
+:continue
+ exit 0
diff --git a/package/network/utils/comgt/files/getimsi.gcom b/package/network/utils/comgt/files/getimsi.gcom
new file mode 100644
index 0000000..0485456
--- /dev/null
+++ b/package/network/utils/comgt/files/getimsi.gcom
@@ -0,0 +1,17 @@
+opengt
+ set com 115200n81
+ set comecho off
+ set senddelay 0.02
+ waitquiet 0.2 0.2
+ flash 0.1
+
+:start
+ send "AT+CIMI^m"
+ get 1 "^m" $s
+ get 1 "^m" $s
+ let x = len($s)
+ if x<2 goto continue
+ let $s = $right($s, x-1)
+ print $s
+:continue
+ exit 0
diff --git a/package/network/utils/comgt/files/getstrength.gcom b/package/network/utils/comgt/files/getstrength.gcom
new file mode 100644
index 0000000..2886285
--- /dev/null
+++ b/package/network/utils/comgt/files/getstrength.gcom
@@ -0,0 +1,14 @@
+opengt
+ set com 115200n81
+ set comecho off
+ set senddelay 0.02
+ waitquiet 0.2 0.2
+ flash 0.1
+
+:start
+ send "AT+CSQ^m"
+ get 1 "" $s
+ print $s
+
+:continue
+ exit 0
diff --git a/package/network/utils/comgt/files/ncm.json b/package/network/utils/comgt/files/ncm.json
new file mode 100644
index 0000000..5f68b13
--- /dev/null
+++ b/package/network/utils/comgt/files/ncm.json
@@ -0,0 +1,140 @@
+{
+ "huawei": {
+ "initialize": [
+ "AT",
+ "ATZ",
+ "ATQ0",
+ "ATV1",
+ "ATE1",
+ "ATS0=0",
+ "AT+CGDCONT=${profile},\\\"${pdptype}\\\"${apn:+,\\\"$apn\\\"}"
+ ],
+ "modes": {
+ "preferlte": "AT^SYSCFGEX=\\\"030201\\\",3fffffff,2,4,7fffffffffffffff,,",
+ "preferumts": "AT^SYSCFGEX=\\\"0201\\\",3fffffff,2,4,7fffffffffffffff,,",
+ "lte": "AT^SYSCFGEX=\\\"03\\\",3fffffff,2,4,7fffffffffffffff,,",
+ "umts": "AT^SYSCFGEX=\\\"02\\\",3fffffff,2,4,7fffffffffffffff,,",
+ "gsm": "AT^SYSCFGEX=\\\"01\\\",3fffffff,2,4,7fffffffffffffff,,",
+ "auto": "AT^SYSCFGEX=\\\"00\\\",3fffffff,2,4,7fffffffffffffff,,"
+ },
+ "connect": "AT^NDISDUP=${profile},1${apn:+,\\\"$apn\\\"}${username:+,\\\"$username\\\"}${password:+,\\\"$password\\\"}${auth:+,$auth}",
+ "disconnect": "AT^NDISDUP=${profile},0"
+ },
+ "samsung": {
+ "initialize": [
+ "AT",
+ "AT+CGREG=2",
+ "AT+CFUN=5",
+ "AT+MODESELECT=3",
+ "AT+CGDCONT=${profile},\\\"${pdptype}\\\"${apn:+,\\\"$apn\\\"}"
+ ],
+ "modes": {
+ "umts": "AT+CHANGEALLPATH=1"
+ },
+ "connect": "AT+CGATT=1",
+ "disconnect": "AT+CGATT=0"
+ },
+ "sierra": {
+ "initialize": [
+ "AT+CFUN=1",
+ "AT+CGDCONT=${profile},\\\"${pdptype}\\\"${apn:+,\\\"$apn\\\"}",
+ "AT$QCPDPP=${profile},${auth:-0}${password:+,\\\"$password\\\"}${username:+,\\\"$username\\\"}"
+ ],
+ "modes": {
+ "preferlte": "AT!SELRAT=07",
+ "preferumts": "AT!SELRAT=05",
+ "lte": "AT!SELRAT=06",
+ "umts": "AT!SELRAT=01",
+ "gsm": "AT!SELRAT=02",
+ "auto": "AT!SELRAT=00"
+ },
+ "connect": "AT!SCACT=1,${profile}",
+ "disconnect": "AT!SCACT=0,${profile}"
+ },
+ "sony": {
+ "initialize": [
+ "AT+CFUN=1",
+ "AT+CGDCONT=${profile},\\\"${pdptype}\\\"${apn:+,\\\"$apn\\\"}",
+ "AT*EIAAUW=${profile},1,\\\"${username}\\\",\\\"${password}\\\",${auth:-00111}"
+ ],
+ "modes": {
+ "umts": "AT+CFUN=6",
+ "gsm": "AT+CFUN=5"
+ },
+ "connect": "AT*ENAP=1,${profile}",
+ "disconnect": "AT*ENAP=0"
+ },
+ "mtk1": {
+ "initialize": [
+ "AT+CFUN=1"
+ ],
+ "configure": [
+ "AT+CGDCONT=${profile},\\\"${pdptype}\\\",\\\"${apn}\\\",0,0"
+ ],
+ "connect": "AT+CGACT=1,${profile}",
+ "finalize": "AT+CGDATA=\\\"M-MBIM\\\",${profile},1",
+ "disconnect": "AT+CGACT=0,${profile}"
+ },
+ "quectel": {
+ "initialize": [
+ "AT+CFUN=1"
+ ],
+ "configure": [
+ "at+qicsgp=${profile},${context_type},\\\"${apn}\\\",\\\"${username}\\\",\\\"${password}\\\",0"
+ ],
+ "modes": {
+ "lte": "AT+QCFG=\\\"nwscanmode\\\",3",
+ "umts": "AT+QCFG=\\\"nwscanmode\\\",2",
+ "gsm": "AT+QCFG=\\\"nwscanmode\\\",1",
+ "auto": "AT+QCFG=\\\"nwscanmode\\\",0"
+ },
+ "connect": "AT+qnetdevctl=1,${profile},1",
+ "disconnect": "AT+qnetdevctl=0,${profile},0"
+ },
+ "\"zte": {
+ "initialize": [
+ "AT+CFUN=1"
+ ],
+ "configure": [
+ "AT+ZGDCONT=${profile},\\\"${pdptype}\\\",\\\"${apn}\\\",\\\"\\\",0,0",
+ "AT+ZGPCOAUTH=${profile},\\\"${username}\\\",\\\"${password}\\\",0"
+ ],
+ "connect": "AT+ZGACT=1,${profile}",
+ "disconnect": "AT+ZGACT=0,${profile}"
+ },
+ "\"marvell\"": {
+ "initialize": [
+ "AT+CFUN=1"
+ ],
+ "configure": [
+ "AT+ZGDCONT=${profile},\\\"${pdptype}\\\",\\\"${apn}\\\",\\\"\\\",0,0",
+ "AT+ZGPCOAUTH=${profile},\\\"${username}\\\",\\\"${password}\\\",0"
+ ],
+ "connect": "AT+ZGACT=1,${profile}",
+ "disconnect": "AT+ZGACT=0,${profile}"
+ },
+ "\"mikrotik\"": {
+ "configure": [
+ "AT+CFUN=4",
+ "AT+ZGDCONT=${profile},\\\"${pdptype}\\\",\\\"${apn}\\\",0",
+ "AT+ZDHCPLEASE=10",
+ "AT+CFUN=1"
+ ],
+ "waitforconnect": "\\\"+ZCONSTAT: 1,${context_type}\\\",\\\"+ZGIPDNS: ${context_type}\\\"",
+ "connect": "AT+ZGACT=1,${context_type}",
+ "finalize": "AT+ZDHCPLEASE=0",
+ "disconnect": "AT+ZGACT=0,1"
+ },
+ "spreadtrum": {
+ "initialize": [
+ "AT+CFUN=1",
+ "AT+CCED=2,8",
+ "AT+SPTTYROUTER=1"
+ ],
+ "configure": [
+ "AT+CGDCONT=${profile},\\\"${pdptype}\\\"${apn:+,\\\"$apn\\\"}"
+ ],
+ "connect": "AT+SPTZCMD=\\\"Y29ubm1hbmN0bCBuZGlzZGlhbCBBVF5ORElTRFVOPSJ1c2IwIiwxLDE=\\\"",
+ "disconnect": "AT+SPTZCMD=\\\"Y29ubm1hbmN0bCBuZGlzZGlhbCBBVF5ORElTRFVOPSJ1c2IwIiwwLDE=\\\""
+ }
+}
diff --git a/package/network/utils/comgt/files/ncm.sh b/package/network/utils/comgt/files/ncm.sh
new file mode 100644
index 0000000..e9412b2
--- /dev/null
+++ b/package/network/utils/comgt/files/ncm.sh
@@ -0,0 +1,289 @@
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_ncm_init_config() {
+ no_device=1
+ available=1
+ proto_config_add_string "device:device"
+ proto_config_add_string ifname
+ proto_config_add_string apn
+ proto_config_add_string auth
+ proto_config_add_string username
+ proto_config_add_string password
+ proto_config_add_string pincode
+ proto_config_add_string delay
+ proto_config_add_string mode
+ proto_config_add_string pdptype
+ proto_config_add_boolean sourcefilter
+ proto_config_add_boolean delegate
+ proto_config_add_int profile
+ proto_config_add_defaults
+}
+
+proto_ncm_setup() {
+ local interface="$1"
+
+ local manufacturer initialize setmode connect finalize devname devpath ifpath
+
+ local device ifname apn auth username password pincode delay mode pdptype profile $PROTO_DEFAULT_OPTIONS
+ json_get_vars device ifname apn auth username password pincode delay mode pdptype sourcefilter delegate profile $PROTO_DEFAULT_OPTIONS
+
+ local context_type
+
+ [ "$metric" = "" ] && metric="0"
+
+ [ -n "$profile" ] || profile=1
+
+ pdptype=$(echo "$pdptype" | awk '{print toupper($0)}')
+ [ "$pdptype" = "IP" -o "$pdptype" = "IPV6" -o "$pdptype" = "IPV4V6" ] || pdptype="IP"
+
+ [ "$pdptype" = "IPV4V6" ] && context_type=3
+ [ -z "$context_type" -a "$pdptype" = "IPV6" ] && context_type=2
+ [ -n "$context_type" ] || context_type=1
+
+ [ -n "$ctl_device" ] && device=$ctl_device
+
+ [ -n "$device" ] || {
+ echo "No control device specified"
+ proto_notify_error "$interface" NO_DEVICE
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ device="$(readlink -f $device)"
+ [ -e "$device" ] || {
+ echo "Control device not valid"
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ [ -z "$ifname" ] && {
+ devname="$(basename "$device")"
+ case "$devname" in
+ 'ttyACM'*)
+ devpath="$(readlink -f /sys/class/tty/$devname/device)"
+ ifpath="$devpath/../*/net"
+ ;;
+ 'tty'*)
+ devpath="$(readlink -f /sys/class/tty/$devname/device)"
+ ifpath="$devpath/../../*/net"
+ ;;
+ *)
+ devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
+ ifpath="$devpath/net"
+ ;;
+ esac
+ ifname="$(ls $(ls -1 -d $ifpath | head -n 1))"
+ }
+
+ [ -n "$ifname" ] || {
+ echo "The interface could not be found."
+ proto_notify_error "$interface" NO_IFACE
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ start=$(date +%s)
+ while true; do
+ manufacturer=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk 'NF && $0 !~ /AT\+CGMI/ { sub(/\+CGMI: /,""); print tolower($1); exit; }')
+ [ "$manufacturer" = "error" ] && {
+ manufacturer=""
+ }
+ [ -n "$manufacturer" ] && {
+ break
+ }
+ [ -z "$delay" ] && {
+ break
+ }
+ sleep 1
+ elapsed=$(($(date +%s) - start))
+ [ "$elapsed" -gt "$delay" ] && {
+ break
+ }
+ done
+ [ -z "$manufacturer" ] && {
+ echo "Failed to get modem information"
+ proto_notify_error "$interface" GETINFO_FAILED
+ return 1
+ }
+
+ json_load "$(cat /etc/gcom/ncm.json)"
+ json_select "$manufacturer"
+ [ $? -ne 0 ] && {
+ echo "Unsupported modem"
+ proto_notify_error "$interface" UNSUPPORTED_MODEM
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ json_get_values initialize initialize
+ for i in $initialize; do
+ eval COMMAND="$i" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+ echo "Failed to initialize modem"
+ proto_notify_error "$interface" INITIALIZE_FAILED
+ return 1
+ }
+ done
+
+ [ -n "$pincode" ] && {
+ PINCODE="$pincode" gcom -d "$device" -s /etc/gcom/setpin.gcom || {
+ echo "Unable to verify PIN"
+ proto_notify_error "$interface" PIN_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+ }
+
+ json_get_values configure configure
+ echo "Configuring modem"
+ for i in $configure; do
+ eval COMMAND="$i" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+ echo "Failed to configure modem"
+ proto_notify_error "$interface" CONFIGURE_FAILED
+ return 1
+ }
+ done
+
+ [ -n "$mode" ] && {
+ json_select modes
+ json_get_var setmode "$mode"
+ [ -n "$setmode" ] && {
+ echo "Setting mode"
+ eval COMMAND="$setmode" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+ echo "Failed to set operating mode"
+ proto_notify_error "$interface" SETMODE_FAILED
+ return 1
+ }
+ }
+ json_select ..
+ }
+
+ echo "Starting network $interface"
+ json_get_vars connect
+ [ -n "$connect" ] && {
+ echo "Connecting modem"
+ eval COMMAND="$connect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+ echo "Failed to connect"
+ proto_notify_error "$interface" CONNECT_FAILED
+ return 1
+ }
+ }
+
+ json_get_vars finalize
+
+ echo "Setting up $ifname"
+ proto_init_update "$ifname" 1
+ proto_add_data
+ json_add_string "manufacturer" "$manufacturer"
+ proto_close_data
+ proto_send_update "$interface"
+
+ local zone="$(fw3 -q network "$interface" 2>/dev/null)"
+
+ [ "$pdptype" = "IP" -o "$pdptype" = "IPV4V6" ] && {
+ json_init
+ json_add_string name "${interface}_4"
+ json_add_string ifname "@$interface"
+ json_add_string proto "dhcp"
+ proto_add_dynamic_defaults
+ [ -n "$zone" ] && {
+ json_add_string zone "$zone"
+ }
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ }
+
+ [ "$pdptype" = "IPV6" -o "$pdptype" = "IPV4V6" ] && {
+ json_init
+ json_add_string name "${interface}_6"
+ json_add_string ifname "@$interface"
+ json_add_string proto "dhcpv6"
+ json_add_string extendprefix 1
+ [ "$delegate" = "0" ] && json_add_boolean delegate "0"
+ [ "$sourcefilter" = "0" ] && json_add_boolean sourcefilter "0"
+ proto_add_dynamic_defaults
+ [ -n "$zone" ] && {
+ json_add_string zone "$zone"
+ }
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ }
+
+ [ -n "$finalize" ] && {
+ eval COMMAND="$finalize" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+ echo "Failed to configure modem"
+ proto_notify_error "$interface" FINALIZE_FAILED
+ return 1
+ }
+ }
+}
+
+proto_ncm_teardown() {
+ local interface="$1"
+
+ local manufacturer disconnect
+
+ local device profile
+ json_get_vars device profile
+
+ [ -n "$ctl_device" ] && device=$ctl_device
+
+ [ -n "$device" ] || {
+ echo "No control device specified"
+ proto_notify_error "$interface" NO_DEVICE
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ device="$(readlink -f $device)"
+ [ -e "$device" ] || {
+ echo "Control device not valid"
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ [ -n "$profile" ] || profile=1
+
+ echo "Stopping network $interface"
+
+ json_load "$(ubus call network.interface.$interface status)"
+ json_select data
+ json_get_vars manufacturer
+ [ $? -ne 0 -o -z "$manufacturer" ] && {
+ # Fallback to direct detect, for proper handle device replug.
+ manufacturer=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk 'NF && $0 !~ /AT\+CGMI/ { sub(/\+CGMI: /,""); print tolower($1); exit; }')
+ [ $? -ne 0 -o -z "$manufacturer" ] && {
+ echo "Failed to get modem information"
+ proto_notify_error "$interface" GETINFO_FAILED
+ return 1
+ }
+ json_add_string "manufacturer" "$manufacturer"
+ }
+
+ json_load "$(cat /etc/gcom/ncm.json)"
+ json_select "$manufacturer" || {
+ echo "Unsupported modem"
+ proto_notify_error "$interface" UNSUPPORTED_MODEM
+ return 1
+ }
+
+ json_get_vars disconnect
+ [ -n "$disconnect" ] && {
+ eval COMMAND="$disconnect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+ echo "Failed to disconnect"
+ proto_notify_error "$interface" DISCONNECT_FAILED
+ return 1
+ }
+ }
+
+ proto_init_update "*" 0
+ proto_send_update "$interface"
+}
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol ncm
+}
diff --git a/package/network/utils/comgt/files/runcommand.gcom b/package/network/utils/comgt/files/runcommand.gcom
new file mode 100644
index 0000000..88a9d29
--- /dev/null
+++ b/package/network/utils/comgt/files/runcommand.gcom
@@ -0,0 +1,31 @@
+# run AT-command from environment
+opengt
+ set com 115200n81
+ set senddelay 0.02
+ waitquiet 1 0.2
+ flash 0.1
+
+:start
+ print "sending -> ",$env("COMMAND"),"\n"
+ send $env("COMMAND")
+ send "^m"
+
+ waitfor 25 "OK","ERR","ERROR","COMMAND NOT SUPPORT"
+ if % = 0 goto continue
+ if % = 1 goto error
+ if % = 2 goto error
+ if % = 3 goto notsupported
+
+ print "Timeout running AT-command\n"
+ exit 1
+
+:error
+ print "Error running AT-command\n"
+ exit 1
+
+:notsupported
+ print "AT-command not supported\n"
+ exit 1
+
+:continue
+ exit 0
diff --git a/package/network/utils/comgt/files/setmode.gcom b/package/network/utils/comgt/files/setmode.gcom
new file mode 100644
index 0000000..4ce0b5f
--- /dev/null
+++ b/package/network/utils/comgt/files/setmode.gcom
@@ -0,0 +1,26 @@
+# set wwan mode from environment
+opengt
+ set com 115200n81
+ set senddelay 0.02
+ waitquiet 1 0.2
+ flash 0.1
+
+:start
+ print "Trying to set mode\n"
+ send $env("MODE")
+ send "^m"
+
+ waitfor 15 "OK","ERR","ERROR"
+ if % = 0 goto continue
+ if % = 1 goto modeerror
+ if % = 2 goto modeerror
+
+ print "Timeout setting WWAN mode!\n"
+ exit 1
+
+:modeerror
+ print "Error setting WWAN mode!\n"
+ exit 1
+
+:continue
+ exit 0
diff --git a/package/network/utils/comgt/files/setpin.gcom b/package/network/utils/comgt/files/setpin.gcom
new file mode 100644
index 0000000..a3f3402
--- /dev/null
+++ b/package/network/utils/comgt/files/setpin.gcom
@@ -0,0 +1,56 @@
+# set pin code from evnironment "$PINCODE"
+opengt
+ set com 115200n81
+ set senddelay 0.05
+ waitquiet 3 0.5
+ flash 0.1
+
+ let c=0
+:start
+ send "AT+CFUN=1^m"
+ send "AT+CPIN?^m"
+ waitfor 15 "SIM PUK","SIM PIN","READY","ERROR","ERR"
+ if % = -1 goto timeout
+ if % = 0 goto ready
+ if % = 1 goto setpin
+ if % = 2 goto ready
+ if % = 3 goto checkrepeat
+ if % = 4 goto checkrepeat
+
+:checkrepeat
+ inc c
+ if c>3 goto pinerror
+ waitquiet 12 0.5
+ goto start
+
+:timeout
+ print "timeout checking for PIN."
+ exit 1
+
+:ready
+ print "SIM ready\n"
+ goto continue
+ exit 0
+
+:setpin
+ # check if output was "SIM PIN2", that's ok.
+ waitfor 1 "2"
+ if % = 0 goto ready
+
+ print "Trying to set PIN\n"
+ send "AT+CPIN=\""
+ send $env("PINCODE")
+ send "\"^m"
+
+ waitfor 20 "OK","ERR"
+ if % = -1 goto pinerror
+ if % = 0 goto continue
+ if % = 1 goto pinerror
+
+:pinerror
+ print "Error setting PIN, check card manually\n"
+ exit 1
+
+:continue
+ print "PIN set successfully\n"
+ exit 0
diff --git a/package/network/utils/comgt/files/ussd.gcom b/package/network/utils/comgt/files/ussd.gcom
new file mode 100644
index 0000000..c5be80b
--- /dev/null
+++ b/package/network/utils/comgt/files/ussd.gcom
@@ -0,0 +1,21 @@
+opengt
+ set com 115200n81
+ set comecho off
+ set senddelay 0.02
+ waitquiet 0.2 0.2
+ flash 0.1
+
+:start
+ send "AT+CUSD=1,"
+ send $env("ussd")
+ send ",15"
+ send "^m"
+ waitfor 120 "+CUSD:"
+ if % = -1 goto timeout
+ get 1 "^m" $s
+ print $s
+ exit 0
+
+:timeout
+ print "ERROR: no USSD response, timeout.\n"
+ exit 1
diff --git a/package/network/utils/comgt/patches/001-compile_fix.patch b/package/network/utils/comgt/patches/001-compile_fix.patch
new file mode 100644
index 0000000..15de850
--- /dev/null
+++ b/package/network/utils/comgt/patches/001-compile_fix.patch
@@ -0,0 +1,23 @@
+--- a/Makefile
++++ b/Makefile
+@@ -32,6 +32,7 @@ SCRIPTPATH = /etc/comgt/
+ SCRIPTSRC = ./scripts/
+ BIN = $(CPROG)
+ MANP = comgt.1 sigmon.1
++CC = cc
+
+ CFLAGS = -c
+ LDFLAGS =
+@@ -70,10 +71,5 @@ clean:
+ -rm *~
+ -rm $(SCRIPTSRC)*~
+
+-
+-comgt: comgt.o
+- cc comgt.o $(LDFLAGS) -o comgt
+-
+-comgt.o: comgt.c comgt.h
+- cc comgt.c $(CFLAGS)
+-
++comgt: comgt.c comgt.h
++ $(CC) $(CFLAGS) -o comgt $< $(LDFLAGS)
diff --git a/package/network/utils/comgt/patches/002-termios.patch b/package/network/utils/comgt/patches/002-termios.patch
new file mode 100644
index 0000000..08f22d1
--- /dev/null
+++ b/package/network/utils/comgt/patches/002-termios.patch
@@ -0,0 +1,105 @@
+--- a/comgt.c
++++ b/comgt.c
+@@ -30,7 +30,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <signal.h>
+-#include <termio.h>
++#include <termios.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <string.h>
+@@ -81,7 +81,7 @@ char token[MAXTOKEN]; /* For gettoken(
+ char scriptfile[MAXPATH]; /* Script file name */
+ char scriptfilepath[MAXPATH]; /* temp storage for full path */
+ BOOL verbose=0; /* Log actions */
+-struct termio cons, stbuf, svbuf; /* termios: svbuf=before, stbuf=while */
++struct termios cons, stbuf, svbuf; /* termios: svbuf=before, stbuf=while */
+ int comfd=0; /* Communication file descriptor. Defaults to stdin. */
+ char msg[STRINGL]; /* Massage messages here */
+ int preturn,returns[MAXGOSUBS];
+@@ -172,7 +172,7 @@ void dotestkey(void) {
+
+ /* Exit after resetting terminal settings */
+ void ext(long xtc) {
+- ioctl(1, TCSETA, &cons);
++ ioctl(1, TCSETS, &cons);
+ exit(xtc);
+ }
+
+@@ -920,24 +920,24 @@ BOOL getonoroff(void) {
+ void setcom(void) {
+ stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL | PARENB);
+ stbuf.c_cflag |= (speed | bits | CREAD | clocal | parity | stopbits );
+- if (ioctl(comfd, TCSETA, &stbuf) < 0) {
++ if (ioctl(comfd, TCSETS, &stbuf) < 0) {
+ serror("Can't ioctl set device",1);
+ }
+ }
+
+ void doset(void) {
+- struct termio console;
++ struct termios console;
+ int a,b;
+ gettoken();
+ if(strcmp(token,"echo")==0) {
+ a=0;
+ if(getonoroff()) a=ECHO|ECHOE;
+- if(ioctl(0, TCGETA, &console)<0) {
++ if(ioctl(0, TCGETS, &console)<0) {
+ serror("Can't ioctl FD zero!\n",2);
+ }
+ console.c_lflag &= ~(ECHO | ECHOE);
+ console.c_lflag |= a;
+- ioctl(0, TCSETA, &console);
++ ioctl(0, TCSETS, &console);
+ }
+ else if(strcmp(token,"senddelay")==0) {
+ senddelay=10000L*getdvalue();
+@@ -1224,7 +1224,7 @@ void doclose(void) {
+ if(strcmp(token,"hardcom")==0) {
+ if(comfd== -1) serror("Com device not open",1);
+ vmsg("Closing device");
+- if (ioctl(comfd, TCSETA, &svbuf) < 0) {
++ if (ioctl(comfd, TCSETS, &svbuf) < 0) {
+ sprintf(msg,"Can't ioctl set device %s.\n",device);
+ serror(msg,1);
+ }
+@@ -1266,12 +1266,12 @@ void opengt(void) {
+ ext(1);
+ }
+ }
+- if (ioctl (comfd, TCGETA, &svbuf) < 0) {
++ if (ioctl (comfd, TCGETS, &svbuf) < 0) {
+ sprintf(msg,"Can't control %s, please try again.\n",device);
+ serror(msg,1);
+ }
+ setenv("COMGTDEVICE",device,1);
+- ioctl(comfd, TCGETA, &stbuf);
++ ioctl(comfd, TCGETS, &stbuf);
+ speed=stbuf.c_cflag & CBAUD;
+ if (high_speed == 0) strcpy(cspeed,"115200");
+ else strcpy(cspeed,"57600");
+@@ -1303,11 +1303,11 @@ void opendevice(void) {
+ }
+ else comfd=0;
+
+- if (ioctl (comfd, TCGETA, &svbuf) < 0) {
++ if (ioctl (comfd, TCGETS, &svbuf) < 0) {
+ sprintf(msg,"Can't ioctl get device %s.\n",device);
+ serror(msg,1);
+ }
+- ioctl(comfd, TCGETA, &stbuf);
++ ioctl(comfd, TCGETS, &stbuf);
+ speed=stbuf.c_cflag & CBAUD;
+ switch(speed) {
+ case B0: strcpy(cspeed,"0");break;
+@@ -1553,7 +1553,7 @@ int main(int argc,char **argv) {
+ skip_default=0;
+ filep=NULL;
+ scriptspace=4096;
+- ioctl(1, TCGETA, &cons);
++ ioctl(1, TCGETS, &cons);
+ if((script=( char *)malloc(scriptspace))==NULL) {
+ serror("Could not malloc()",3);
+ }
diff --git a/package/network/utils/comgt/patches/003-no_XCASE.patch b/package/network/utils/comgt/patches/003-no_XCASE.patch
new file mode 100644
index 0000000..f2060a8
--- /dev/null
+++ b/package/network/utils/comgt/patches/003-no_XCASE.patch
@@ -0,0 +1,20 @@
+--- a/comgt.c
++++ b/comgt.c
+@@ -1281,7 +1281,7 @@ void opengt(void) {
+ parity=stbuf.c_cflag & (PARENB | PARODD);
+ stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY | IGNPAR );
+ stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET);
+- stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL);
++ stbuf.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL);
+ stbuf.c_lflag &= ~(ECHO | ECHOE);
+ stbuf.c_cc[VMIN] = 1;
+ stbuf.c_cc[VTIME] = 0;
+@@ -1336,7 +1336,7 @@ void opendevice(void) {
+ parity=stbuf.c_cflag & (PARENB | PARODD);
+ stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY | IGNPAR );
+ stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET);
+- stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL);
++ stbuf.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL);
+ stbuf.c_lflag &= ~(ECHO | ECHOE);
+ stbuf.c_cc[VMIN] = 1;
+ stbuf.c_cc[VTIME] = 0;
diff --git a/package/network/utils/comgt/patches/004-check_tty.patch b/package/network/utils/comgt/patches/004-check_tty.patch
new file mode 100644
index 0000000..fb1d9af
--- /dev/null
+++ b/package/network/utils/comgt/patches/004-check_tty.patch
@@ -0,0 +1,68 @@
+--- a/comgt.c
++++ b/comgt.c
+@@ -91,6 +91,7 @@ unsigned long hstart,hset;
+ char NullString[]={ "" };
+ BOOL lastcharnl=1; /* Indicate that last char printed from getonebyte
+ was a nl, so no new one is needed */
++BOOL tty=1;
+
+
+ //"open com \"/dev/modem\"\nset com 38400n81\nset senddelay 0.05\nsend \"ATi^m\"\nget 2 \" ^m\" $s\nprint \"Response : \",$s,\"\\n\"\nget 2 \" ^m\" $s\nprint \"Response :\",$s,\"\\n\"\nget 2 \" ^m\" $s\nprint \"Response : \",$s,\"\\n\"\n\n";
+@@ -920,7 +921,7 @@ BOOL getonoroff(void) {
+ void setcom(void) {
+ stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL | PARENB);
+ stbuf.c_cflag |= (speed | bits | CREAD | clocal | parity | stopbits );
+- if (ioctl(comfd, TCSETS, &stbuf) < 0) {
++ if (tty && ioctl(comfd, TCSETS, &stbuf) < 0) {
+ serror("Can't ioctl set device",1);
+ }
+ }
+@@ -1224,7 +1225,7 @@ void doclose(void) {
+ if(strcmp(token,"hardcom")==0) {
+ if(comfd== -1) serror("Com device not open",1);
+ vmsg("Closing device");
+- if (ioctl(comfd, TCSETS, &svbuf) < 0) {
++ if (tty && ioctl(comfd, TCSETS, &svbuf) < 0) {
+ sprintf(msg,"Can't ioctl set device %s.\n",device);
+ serror(msg,1);
+ }
+@@ -1266,12 +1267,17 @@ void opengt(void) {
+ ext(1);
+ }
+ }
+- if (ioctl (comfd, TCGETS, &svbuf) < 0) {
++ if (isatty (comfd))
++ tty=1;
++ else
++ tty=0;
++ if (tty && ioctl (comfd, TCGETS, &svbuf) < 0) {
+ sprintf(msg,"Can't control %s, please try again.\n",device);
+ serror(msg,1);
+ }
+ setenv("COMGTDEVICE",device,1);
+- ioctl(comfd, TCGETS, &stbuf);
++ if (tty)
++ ioctl(comfd, TCGETS, &stbuf);
+ speed=stbuf.c_cflag & CBAUD;
+ if (high_speed == 0) strcpy(cspeed,"115200");
+ else strcpy(cspeed,"57600");
+@@ -1302,12 +1308,16 @@ void opendevice(void) {
+ }
+ }
+ else comfd=0;
+-
+- if (ioctl (comfd, TCGETS, &svbuf) < 0) {
++ if (isatty (comfd))
++ tty=1;
++ else
++ tty=0;
++ if (tty && ioctl (comfd, TCGETS, &svbuf) < 0) {
+ sprintf(msg,"Can't ioctl get device %s.\n",device);
+ serror(msg,1);
+ }
+- ioctl(comfd, TCGETS, &stbuf);
++ if (tty)
++ ioctl(comfd, TCGETS, &stbuf);
+ speed=stbuf.c_cflag & CBAUD;
+ switch(speed) {
+ case B0: strcpy(cspeed,"0");break;
diff --git a/package/network/utils/ebtables/Makefile b/package/network/utils/ebtables/Makefile
new file mode 100644
index 0000000..49d8eff
--- /dev/null
+++ b/package/network/utils/ebtables/Makefile
@@ -0,0 +1,72 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ebtables
+PKG_SOURCE_DATE:=2018-06-27
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=https://git.netfilter.org/ebtables
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=48cff25dfea5b37e16ba5dc6601e98ab140f5f99
+PKG_MIRROR_HASH:=160f5087b403173d5d1e93880d28b89dab98e828ba3f545315bf1cb88afe5a46
+
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ebtables
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Firewall
+ DEPENDS:=+(!MODULE_BUILDIN):kmod-ebtables
+ TITLE:=Ethernet bridge firewall administration utility
+ URL:=http://ebtables.sourceforge.net/
+endef
+
+define Package/ebtables-utils
+ $(call Package/ebtables)
+ DEPENDS += ebtables
+ TITLE:=ebtables save/restore utilities
+endef
+
+define Package/ebtables/description
+ The ebtables program is a filtering tool for a bridging firewall. The
+ filtering is focussed on the Link Layer Ethernet frame fields. Apart
+ from filtering, it also gives the ability to alter the Ethernet MAC
+ addresses and implement a brouter.
+endef
+
+define Package/ebtables-utils/description
+ $(call Package/ebtables/description)
+endef
+
+MAKE_VARS += EXT_LIBSI="$(LIBGCC_S)"
+
+MAKE_FLAGS += \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ LIBDIR="/usr/lib/ebtables"
+
+define Package/ebtables/install
+ $(INSTALL_DIR) $(1)/etc
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/ethertypes $(1)/etc/
+ $(INSTALL_DIR) $(1)/usr/lib/ebtables
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib*.so $(1)/usr/lib/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/extensions/*.so $(1)/usr/lib/ebtables/
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ebtables $(1)/usr/sbin/
+endef
+
+define Package/ebtables-utils/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ebtables-save $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ebtables-restore $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,ebtables))
+$(eval $(call BuildPackage,ebtables-utils))
diff --git a/package/network/utils/ebtables/patches/200-fix-extension-init.patch b/package/network/utils/ebtables/patches/200-fix-extension-init.patch
new file mode 100644
index 0000000..60e2afd
--- /dev/null
+++ b/package/network/utils/ebtables/patches/200-fix-extension-init.patch
@@ -0,0 +1,260 @@
+--- a/extensions/Makefile
++++ b/extensions/Makefile
+@@ -11,13 +11,13 @@ EXT_LIBSI+=$(foreach T,$(EXT_FUNC), -leb
+ EXT_LIBSI+=$(foreach T,$(EXT_TABLES), -lebtable_$(T))
+
+ extensions/ebt_%.so: extensions/ebt_%.o
+- $(CC) $(LDFLAGS) -shared -o $@ -lc $< -nostartfiles
++ $(CC) $(LDFLAGS) -shared -o $@ -lc $<
+
+ extensions/libebt_%.so: extensions/ebt_%.so
+ mv $< $@
+
+ extensions/ebtable_%.so: extensions/ebtable_%.o
+- $(CC) $(LDFLAGS) -shared -o $@ -lc $< -nostartfiles
++ $(CC) $(LDFLAGS) -shared -o $@ -lc $<
+
+ extensions/libebtable_%.so: extensions/ebtable_%.so
+ mv $< $@
+--- a/extensions/ebt_802_3.c
++++ b/extensions/ebt_802_3.c
+@@ -141,7 +141,7 @@ static struct ebt_u_match _802_3_match =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&_802_3_match);
+ }
+--- a/extensions/ebt_among.c
++++ b/extensions/ebt_among.c
+@@ -491,7 +491,7 @@ static struct ebt_u_match among_match =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&among_match);
+ }
+--- a/extensions/ebt_arp.c
++++ b/extensions/ebt_arp.c
+@@ -362,7 +362,7 @@ static struct ebt_u_match arp_match =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&arp_match);
+ }
+--- a/extensions/ebt_arpreply.c
++++ b/extensions/ebt_arpreply.c
+@@ -133,7 +133,7 @@ static struct ebt_u_target arpreply_targ
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_target(&arpreply_target);
+ }
+--- a/extensions/ebt_ip.c
++++ b/extensions/ebt_ip.c
+@@ -472,7 +472,7 @@ static struct ebt_u_match ip_match =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&ip_match);
+ }
+--- a/extensions/ebt_ip6.c
++++ b/extensions/ebt_ip6.c
+@@ -413,7 +413,7 @@ static struct ebt_u_match ip6_match =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&ip6_match);
+ }
+--- a/extensions/ebt_limit.c
++++ b/extensions/ebt_limit.c
+@@ -212,7 +212,7 @@ static struct ebt_u_match limit_match =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&limit_match);
+ }
+--- a/extensions/ebt_log.c
++++ b/extensions/ebt_log.c
+@@ -217,7 +217,7 @@ static struct ebt_u_watcher log_watcher
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_watcher(&log_watcher);
+ }
+--- a/extensions/ebt_mark.c
++++ b/extensions/ebt_mark.c
+@@ -172,7 +172,7 @@ static struct ebt_u_target mark_target =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_target(&mark_target);
+ }
+--- a/extensions/ebt_mark_m.c
++++ b/extensions/ebt_mark_m.c
+@@ -121,7 +121,7 @@ static struct ebt_u_match mark_match =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&mark_match);
+ }
+--- a/extensions/ebt_nat.c
++++ b/extensions/ebt_nat.c
+@@ -231,7 +231,7 @@ static struct ebt_u_target dnat_target =
+ .extra_ops = opts_d,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_target(&snat_target);
+ ebt_register_target(&dnat_target);
+--- a/extensions/ebt_nflog.c
++++ b/extensions/ebt_nflog.c
+@@ -166,7 +166,7 @@ static struct ebt_u_watcher nflog_watche
+ .extra_ops = nflog_opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_watcher(&nflog_watcher);
+ }
+--- a/extensions/ebt_pkttype.c
++++ b/extensions/ebt_pkttype.c
+@@ -125,7 +125,7 @@ static struct ebt_u_match pkttype_match
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&pkttype_match);
+ }
+--- a/extensions/ebt_redirect.c
++++ b/extensions/ebt_redirect.c
+@@ -108,7 +108,7 @@ static struct ebt_u_target redirect_targ
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_target(&redirect_target);
+ }
+--- a/extensions/ebt_standard.c
++++ b/extensions/ebt_standard.c
+@@ -84,7 +84,7 @@ static struct ebt_u_target standard =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_target(&standard);
+ }
+--- a/extensions/ebt_stp.c
++++ b/extensions/ebt_stp.c
+@@ -337,7 +337,7 @@ static struct ebt_u_match stp_match =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&stp_match);
+ }
+--- a/extensions/ebt_ulog.c
++++ b/extensions/ebt_ulog.c
+@@ -180,7 +180,7 @@ static struct ebt_u_watcher ulog_watcher
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_watcher(&ulog_watcher);
+ }
+--- a/extensions/ebt_vlan.c
++++ b/extensions/ebt_vlan.c
+@@ -181,7 +181,7 @@ static struct ebt_u_match vlan_match = {
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&vlan_match);
+ }
+--- a/extensions/ebtable_broute.c
++++ b/extensions/ebtable_broute.c
+@@ -23,7 +23,7 @@ ebt_u_table table =
+ .help = print_help,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_table(&table);
+ }
+--- a/extensions/ebtable_filter.c
++++ b/extensions/ebtable_filter.c
+@@ -29,7 +29,7 @@ static struct ebt_u_table table =
+ .help = print_help,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_table(&table);
+ }
+--- a/extensions/ebtable_nat.c
++++ b/extensions/ebtable_nat.c
+@@ -30,7 +30,7 @@ ebt_u_table table =
+ .help = print_help,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_table(&table);
+ }
+--- a/extensions/ebt_string.c
++++ b/extensions/ebt_string.c
+@@ -312,7 +312,7 @@ static struct ebt_u_match string_match =
+ .extra_ops = opts,
+ };
+
+-void _init(void)
++__attribute__((constructor)) static void extension_init(void)
+ {
+ ebt_register_match(&string_match);
+ }
diff --git a/package/network/utils/ethtool/Makefile b/package/network/utils/ethtool/Makefile
new file mode 100644
index 0000000..5da6527
--- /dev/null
+++ b/package/network/utils/ethtool/Makefile
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ethtool
+PKG_VERSION:=6.11
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/software/network/ethtool
+PKG_HASH:=8d91f5c72ae3f25b7e88d4781279dcb320f71e30058914370b1c574c96b31202
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:kernel:ethtool
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ethtool
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Display or change ethernet card settings
+ URL:=http://www.kernel.org/pub/software/network/ethtool/
+ VARIANT:=tiny
+ CONFLICTS:=ethtool-full
+endef
+
+define Package/ethtool-full
+ $(Package/ethtool)
+ TITLE += (full)
+ VARIANT:=full
+ PROVIDES:=ethtool
+ DEPENDS:=+libmnl
+ CONFLICTS:=
+endef
+
+define Package/ethtool/description
+ ethtool is a small utility for examining and tuning your ethernet-based
+ network interface
+endef
+
+Package/ethtool-full/description:=$(Package/ethtool/description)
+
+ifeq ($(BUILD_VARIANT),full)
+CONFIGURE_ARGS += --enable-netlink --enable-pretty-dump
+else
+CONFIGURE_ARGS += --disable-netlink --disable-pretty-dump
+endif
+
+# enable support for input_xfrm with kernels newer than 6.6
+ifeq ($(CONFIG_LINUX_6_6),)
+CONFIGURE_ARGS += --enable-rss-input-xfrm
+endif
+
+define Package/ethtool/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ethtool $(1)/usr/sbin
+endef
+
+Package/ethtool-full/install=$(Package/ethtool/install)
+
+$(eval $(call BuildPackage,ethtool))
+$(eval $(call BuildPackage,ethtool-full))
diff --git a/package/network/utils/ethtool/patches/0001-ethtool-make-building-for-RSS-input-xfrm-optional.patch b/package/network/utils/ethtool/patches/0001-ethtool-make-building-for-RSS-input-xfrm-optional.patch
new file mode 100644
index 0000000..4c8403d
--- /dev/null
+++ b/package/network/utils/ethtool/patches/0001-ethtool-make-building-for-RSS-input-xfrm-optional.patch
@@ -0,0 +1,67 @@
+From c88eb6f4e9b2d8f71f3391db2bf0ec82ecccae81 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 12 Feb 2025 04:12:42 +0000
+Subject: [PATCH] ethtool: make building for RSS input xfrm optional
+
+Unfortunately there is no way to detect at runtime if the kernel the
+support for RSS input transformation, and the default value
+RXH_XFRM_NO_CHANGE (0xff) used by newer ethtool results in breakage
+with older kernels.
+As a stop-gap solution simply don't compile with support for input
+xfrm by default.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ configure.ac | 10 ++++++++++
+ ethtool.c | 10 ++++++++++
+ 2 files changed, 20 insertions(+)
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -45,6 +45,16 @@ if test x$enable_pretty_dump = xyes; the
+ fi
+ AM_CONDITIONAL([ETHTOOL_ENABLE_PRETTY_DUMP], [test x$enable_pretty_dump = xyes])
+
++AC_ARG_ENABLE(rss-input-xfrm,
++ [ --enable-rss-input-xfrm build with support for RSS input transformation (disabled by default)],
++ ,
++ enable_rss_input_xfrm=no)
++if test x$enable_rss_input_xfrm = xyes; then
++ AC_DEFINE(ETHTOOL_ENABLE_RSS_INPUT_XFRM, 1,
++ [Define this to enable building with support for RSS input transformation.])
++fi
++AM_CONDITIONAL([ETHTOOL_ENABLE_RSS_INPUT_XFRM], [test x$enable_rss_input_xfrm = xyes])
++
+ AC_ARG_WITH([bash-completion-dir],
+ AS_HELP_STRING([--with-bash-completion-dir[=PATH]],
+ [Install the bash-completion script in this directory. @<:@default=yes@:>@]),
+--- a/ethtool.c
++++ b/ethtool.c
+@@ -4109,9 +4109,11 @@ static int do_grxfh(struct cmd_context *
+ (const char *)hfuncs->data + i * ETH_GSTRING_LEN,
+ (rss->hfunc & (1 << i)) ? "on" : "off");
+
++#ifdef ETHTOOL_ENABLE_RSS_INPUT_XFRM
+ printf("RSS input transformation:\n");
+ printf(" symmetric-xor: %s\n",
+ (rss->input_xfrm & RXH_XFRM_SYM_XOR) ? "on" : "off");
++#endif
+
+ out:
+ free(hfuncs);
+@@ -4431,7 +4433,15 @@ static int do_srxfh(struct cmd_context *
+ rss->cmd = ETHTOOL_SRSSH;
+ rss->rss_context = rss_context;
+ rss->hfunc = req_hfunc;
++#ifdef ETHTOOL_ENABLE_RSS_INPUT_XFRM
+ rss->input_xfrm = req_input_xfrm;
++#else
++ if (req_input_xfrm != 0xff) {
++ perror("Compiled for kernel without support for input transformation");
++ err = 1;
++ goto free;
++ }
++#endif
+ if (delete) {
+ rss->indir_size = rss->key_size = 0;
+ } else {
diff --git a/package/network/utils/iproute2/Makefile b/package/network/utils/iproute2/Makefile
new file mode 100644
index 0000000..04a4df2
--- /dev/null
+++ b/package/network/utils/iproute2/Makefile
@@ -0,0 +1,268 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=iproute2
+PKG_VERSION:=6.11.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/linux/utils/net/iproute2
+PKG_HASH:=1f795398a04aeaacd06a8f6ace2cfd913c33fa5953ca99daae83bb5c534611c3
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_DEPENDS:=iptables
+PKG_LICENSE:=GPL-2.0
+PKG_CPE_ID:=cpe:/a:iproute2_project:iproute2
+
+PKG_BUILD_FLAGS:=gc-sections lto
+
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/iproute2/Default
+ SECTION:=net
+ CATEGORY:=Network
+ URL:=http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
+ SUBMENU:=Routing and Redirection
+ MAINTAINER:=Russell Senior <russell@personaltelco.net>
+endef
+
+define Package/ip-tiny
+$(call Package/iproute2/Default)
+ TITLE:=Routing control utility (minimal)
+ VARIANT:=iptiny
+ DEFAULT_VARIANT:=1
+ PROVIDES:=ip
+ ALTERNATIVES:=200:/sbin/ip:/usr/libexec/ip-tiny
+ DEPENDS:=+libnl-tiny +(PACKAGE_devlink||PACKAGE_rdma):libmnl
+endef
+
+define Package/ip-full
+$(call Package/iproute2/Default)
+ TITLE:=Routing control utility (full)
+ VARIANT:=ipfull
+ PROVIDES:=ip
+ ALTERNATIVES:=300:/sbin/ip:/usr/libexec/ip-full
+ DEPENDS:=+libnl-tiny +libbpf +(PACKAGE_devlink||PACKAGE_rdma):libmnl
+endef
+
+define Package/tc-tiny
+$(call Package/iproute2/Default)
+ TITLE:=Traffic control utility (minimal)
+ VARIANT:=tctiny
+ DEFAULT_VARIANT:=1
+ PROVIDES:=tc
+ ALTERNATIVES:=200:/sbin/tc:/usr/libexec/tc-tiny
+ DEPENDS:=+kmod-sched-core +(PACKAGE_devlink||PACKAGE_rdma):libmnl
+endef
+
+define Package/tc-bpf
+$(call Package/iproute2/Default)
+ TITLE:=Traffic control utility (bpf)
+ VARIANT:=tcbpf
+ PROVIDES:=tc
+ ALTERNATIVES:=300:/sbin/tc:/usr/libexec/tc-bpf
+ DEPENDS:=+kmod-sched-core +(PACKAGE_devlink||PACKAGE_rdma):libmnl +libbpf
+endef
+
+define Package/tc-full
+$(call Package/iproute2/Default)
+ TITLE:=Traffic control utility (full)
+ VARIANT:=tcfull
+ PROVIDES:=tc
+ ALTERNATIVES:=400:/sbin/tc:/usr/libexec/tc-full
+ DEPENDS:=+kmod-sched-core +(PACKAGE_devlink||PACKAGE_rdma):libmnl +libbpf +libxtables
+endef
+
+define Package/genl
+$(call Package/iproute2/Default)
+ TITLE:=General netlink utility frontend
+ DEPENDS:=+libnl-tiny +(PACKAGE_devlink||PACKAGE_rdma):libmnl
+endef
+
+define Package/ip-bridge
+$(call Package/iproute2/Default)
+ TITLE:=Bridge configuration utility from iproute2
+ DEPENDS:=+libnl-tiny +(PACKAGE_devlink||PACKAGE_rdma):libmnl
+endef
+
+define Package/ss
+$(call Package/iproute2/Default)
+ TITLE:=Socket statistics utility
+ DEPENDS:=+libnl-tiny +(PACKAGE_devlink||PACKAGE_rdma):libmnl +libbpf +kmod-netlink-diag
+endef
+
+define Package/nstat
+$(call Package/iproute2/Default)
+ TITLE:=Network statistics utility
+ DEPENDS:=+libnl-tiny +(PACKAGE_devlink||PACKAGE_rdma):libmnl
+endef
+
+define Package/devlink
+$(call Package/iproute2/Default)
+ TITLE:=Network devlink utility
+ DEPENDS:=+libmnl
+endef
+
+define Package/rdma
+$(call Package/iproute2/Default)
+ TITLE:=Network rdma utility
+ DEPENDS:=+libmnl
+endef
+
+ifeq ($(BUILD_VARIANT),iptiny)
+ IP_CONFIG_TINY:=y
+ LIBBPF_FORCE:=off
+endif
+
+ifeq ($(BUILD_VARIANT),ipfull)
+ HAVE_ELF:=y
+ LIBBPF_FORCE:=on
+endif
+
+ifeq ($(BUILD_VARIANT),tctiny)
+ LIBBPF_FORCE:=off
+endif
+
+ifeq ($(BUILD_VARIANT),tcbpf)
+ HAVE_ELF:=y
+ LIBBPF_FORCE:=on
+ SHARED_LIBS:=y
+endif
+
+ifeq ($(BUILD_VARIANT),tcfull)
+ #enable iptables/xtables requirement only if tciptables variant is selected
+ TC_CONFIG_XT:=y
+ TC_CONFIG_XT_OLD:=y
+ TC_CONFIG_XT_OLD_H:=y
+ TC_CONFIG_IPSET:=y
+ HAVE_ELF:=y
+ LIBBPF_FORCE:=on
+ SHARED_LIBS:=y
+else
+ #disable iptables requirement by default
+ TC_CONFIG_XT:=n
+ TC_CONFIG_XT_OLD:=n
+ TC_CONFIG_XT_OLD_H:=n
+ TC_CONFIG_IPSET:=n
+endif
+
+ifdef CONFIG_PACKAGE_devlink
+ HAVE_MNL:=y
+endif
+
+ifdef CONFIG_PACKAGE_rdma
+ HAVE_MNL:=y
+endif
+
+define Build/Configure
+ echo "static const char SNAPSHOT[] = \"$(PKG_VERSION)-$(PKG_RELEASE)-openwrt\";" \
+ > $(PKG_BUILD_DIR)/include/SNAPSHOT.h
+endef
+
+TARGET_LDFLAGS += -Wl,--as-needed
+TARGET_CPPFLAGS += -I$(STAGING_DIR)/usr/include/libnl-tiny
+
+MAKE_FLAGS += \
+ KERNEL_INCLUDE="$(LINUX_DIR)/include/uapi" \
+ SHARED_LIBS=$(SHARED_LIBS) \
+ IP_CONFIG_TINY=$(IP_CONFIG_TINY) \
+ BUILD_VARIANT=$(BUILD_VARIANT) \
+ LIBBPF_FORCE=$(LIBBPF_FORCE) \
+ HAVE_ELF=$(HAVE_ELF) \
+ HAVE_MNL=$(HAVE_MNL) \
+ HAVE_CAP=$(HAVE_CAP) \
+ HAVE_TIRPC=n \
+ IPT_LIB_DIR=/usr/lib/iptables \
+ XT_LIB_DIR=/usr/lib/iptables \
+ TC_CONFIG_XT=$(TC_CONFIG_XT) \
+ TC_CONFIG_XT_OLD=$(TC_CONFIG_XT_OLD) \
+ TC_CONFIG_XT_OLD_H=$(TC_CONFIG_XT_OLD_H) \
+ TC_CONFIG_IPSET=$(TC_CONFIG_IPSET) \
+ FPIC="$(FPIC)" \
+ $(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='')
+
+define Build/Compile
+ +$(MAKE_VARS) $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(MAKE_FLAGS)
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include/iproute2
+ $(CP) $(PKG_BUILD_DIR)/include/bpf_elf.h $(1)/usr/include/iproute2
+ $(CP) $(PKG_BUILD_DIR)/include/{libgenl,libnetlink}.h $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/lib/libnetlink.a $(1)/usr/lib/
+endef
+
+define Package/ip-tiny/install
+ $(INSTALL_DIR) $(1)/usr/libexec
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ip/ip $(1)/usr/libexec/ip-tiny
+endef
+
+define Package/ip-full/install
+ $(INSTALL_DIR) $(1)/usr/libexec
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ip/ip $(1)/usr/libexec/ip-full
+endef
+
+define Package/tc-tiny/install
+ $(INSTALL_DIR) $(1)/usr/libexec
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tc/tc $(1)/usr/libexec/tc-tiny
+endef
+
+define Package/tc-bpf/install
+ $(INSTALL_DIR) $(1)/usr/libexec
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tc/tc $(1)/usr/libexec/tc-bpf
+endef
+
+define Package/tc-full/install
+ $(INSTALL_DIR) $(1)/usr/libexec
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tc/tc $(1)/usr/libexec/tc-full
+endef
+
+define Package/genl/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/genl/genl $(1)/usr/sbin/
+endef
+
+define Package/ip-bridge/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/bridge/bridge $(1)/usr/sbin/
+endef
+
+define Package/ss/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/misc/ss $(1)/usr/sbin/
+endef
+
+define Package/nstat/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/misc/nstat $(1)/usr/sbin/
+endef
+
+define Package/devlink/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/devlink/devlink $(1)/usr/sbin/
+endef
+
+define Package/rdma/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/rdma/rdma $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,ip-tiny))
+$(eval $(call BuildPackage,ip-full))
+$(eval $(call BuildPackage,tc-tiny))
+$(eval $(call BuildPackage,tc-bpf))
+$(eval $(call BuildPackage,tc-full))
+$(eval $(call BuildPackage,genl))
+$(eval $(call BuildPackage,ip-bridge))
+$(eval $(call BuildPackage,ss))
+$(eval $(call BuildPackage,nstat))
+$(eval $(call BuildPackage,devlink))
+$(eval $(call BuildPackage,rdma))
diff --git a/package/network/utils/iproute2/patches/010-bridge-mst-fix-a-musl-build-issue.patch b/package/network/utils/iproute2/patches/010-bridge-mst-fix-a-musl-build-issue.patch
new file mode 100644
index 0000000..1630415
--- /dev/null
+++ b/package/network/utils/iproute2/patches/010-bridge-mst-fix-a-musl-build-issue.patch
@@ -0,0 +1,68 @@
+From 6a77abab92516e65f07f8657fc4e384c4541ce0e Mon Sep 17 00:00:00 2001
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Date: Sun, 22 Sep 2024 16:50:10 +0200
+Subject: bridge: mst: fix a musl build issue
+
+This patch fixes a compilation error raised by the bump to version 6.11.0
+in Buildroot using musl as the C library for the cross-compilation
+toolchain.
+
+After setting the CFLGAS
+
+ifeq ($(BR2_TOOLCHAIN_USES_MUSL),y)
+IPROUTE2_CFLAGS += -D__UAPI_DEF_IN6_ADDR=0 -D__UAPI_DEF_SOCKADDR_IN6=0 \
+ -D__UAPI_DEF_IPV6_MREQ=0
+endif
+
+to fix the following errors:
+
+In file included from ../../../host/mips64-buildroot-linux-musl/sysroot/usr/include/arpa/inet.h:9,
+ from ../include/libnetlink.h:14,
+ from mst.c:10:
+../../../host/mips64-buildroot-linux-musl/sysroot/usr/include/netinet/in.h:23:8: error: redefinition of 'struct in6_addr'
+ 23 | struct in6_addr {
+ | ^~~~~~~~
+In file included from ../include/uapi/linux/if_bridge.h:19,
+ from mst.c:7:
+../include/uapi/linux/in6.h:33:8: note: originally defined here
+ 33 | struct in6_addr {
+ | ^~~~~~~~
+../../../host/mips64-buildroot-linux-musl/sysroot/usr/include/netinet/in.h:34:8: error: redefinition of 'struct sockaddr_in6'
+ 34 | struct sockaddr_in6 {
+ | ^~~~~~~~~~~~
+../include/uapi/linux/in6.h:50:8: note: originally defined here
+ 50 | struct sockaddr_in6 {
+ | ^~~~~~~~~~~~
+../../../host/mips64-buildroot-linux-musl/sysroot/usr/include/netinet/in.h:42:8: error: redefinition of 'struct ipv6_mreq'
+ 42 | struct ipv6_mreq {
+ | ^~~~~~~~~
+../include/uapi/linux/in6.h:60:8: note: originally defined here
+ 60 | struct ipv6_mreq {
+
+I got this further errors
+
+../include/uapi/linux/in6.h:72:25: error: field 'flr_dst' has incomplete type
+ 72 | struct in6_addr flr_dst;
+ | ^~~~~~~
+../include/uapi/linux/if_bridge.h:711:41: error: field 'ip6' has incomplete type
+ 711 | struct in6_addr ip6;
+ | ^~~
+
+fixed by including the netinet/in.h header.
+
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ bridge/mst.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/bridge/mst.c
++++ b/bridge/mst.c
+@@ -4,6 +4,7 @@
+ */
+
+ #include <stdio.h>
++#include <netinet/in.h>
+ #include <linux/if_bridge.h>
+ #include <net/if.h>
+
diff --git a/package/network/utils/iproute2/patches/011-bridge-mst-fix-a-further-musl-build-issue.patch b/package/network/utils/iproute2/patches/011-bridge-mst-fix-a-further-musl-build-issue.patch
new file mode 100644
index 0000000..1bdab39
--- /dev/null
+++ b/package/network/utils/iproute2/patches/011-bridge-mst-fix-a-further-musl-build-issue.patch
@@ -0,0 +1,51 @@
+From 043ef90e2fa94397eb5c85330889ca4146a6d58a Mon Sep 17 00:00:00 2001
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Date: Sun, 22 Sep 2024 16:50:11 +0200
+Subject: bridge: mst: fix a further musl build issue
+
+This patch fixes the following build errors:
+
+In file included from mst.c:11:
+../include/json_print.h:80:30: warning: 'struct timeval' declared inside parameter list will not be visible outside of this definition or declaration
+ 80 | _PRINT_FUNC(tv, const struct timeval *)
+ | ^~~~~~~
+../include/json_print.h:50:37: note: in definition of macro '_PRINT_FUNC'
+ 50 | type value); \
+ | ^~~~
+../include/json_print.h:80:30: warning: 'struct timeval' declared inside parameter list will not be visible outside of this definition or declaration
+ 80 | _PRINT_FUNC(tv, const struct timeval *)
+ | ^~~~~~~
+../include/json_print.h:55:45: note: in definition of macro '_PRINT_FUNC'
+ 55 | type value) \
+ | ^~~~
+../include/json_print.h: In function 'print_tv':
+../include/json_print.h:58:48: error: passing argument 5 of 'print_color_tv' from incompatible pointer type [-Wincompatible-pointer-types]
+ 58 | value); \
+ | ^~~~~
+ | |
+ | const struct timeval *
+../include/json_print.h:80:1: note: in expansion of macro '_PRINT_FUNC'
+ 80 | _PRINT_FUNC(tv, const struct timeval *)
+ | ^~~~~~~~~~~
+../include/json_print.h:50:42: note: expected 'const struct timeval *' but argument is of type 'const struct timeval *'
+ 50 | type value); \
+ | ^
+../include/json_print.h:80:1: note: in expansion of macro '_PRINT_FUNC'
+ 80 | _PRINT_FUNC(tv, const struct timeval *)
+
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+---
+ bridge/mst.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/bridge/mst.c
++++ b/bridge/mst.c
+@@ -4,6 +4,7 @@
+ */
+
+ #include <stdio.h>
++#include <sys/time.h>
+ #include <netinet/in.h>
+ #include <linux/if_bridge.h>
+ #include <net/if.h>
diff --git a/package/network/utils/iproute2/patches/012-libnetlink-fix-build-with-musl-and-gcc-14.patch b/package/network/utils/iproute2/patches/012-libnetlink-fix-build-with-musl-and-gcc-14.patch
new file mode 100644
index 0000000..749176a
--- /dev/null
+++ b/package/network/utils/iproute2/patches/012-libnetlink-fix-build-with-musl-and-gcc-14.patch
@@ -0,0 +1,28 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Natanael Copa <ncopa@alpinelinux.org>
+Date: Thu, 8 Aug 2024 09:19:01 +0200
+Subject: libnetlink: fix build with musl and gcc 14
+
+Fixes compilation error with musl libc and gcc 14:
+
+../include/libnetlink.h: In function 'rta_getattr_be64':
+../include/libnetlink.h:280:16: error: implicit declaration of function 'htobe64' [-Wimplicit-function-declaration]
+ 280 | return htobe64(rta_getattr_u64(rta));
+ | ^~~~~~~
+
+Reference: https://man7.org/linux/man-pages/man3/endian.3.html
+Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
+---
+ include/libnetlink.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/libnetlink.h
++++ b/include/libnetlink.h
+@@ -2,6 +2,7 @@
+ #ifndef __LIBNETLINK_H__
+ #define __LIBNETLINK_H__ 1
+
++#include <endian.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <asm/types.h>
diff --git a/package/network/utils/iproute2/patches/110-darwin_fixes.patch b/package/network/utils/iproute2/patches/110-darwin_fixes.patch
new file mode 100644
index 0000000..06ae59f
--- /dev/null
+++ b/package/network/utils/iproute2/patches/110-darwin_fixes.patch
@@ -0,0 +1,59 @@
+--- a/netem/maketable.c
++++ b/netem/maketable.c
+@@ -11,7 +11,9 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <math.h>
++#if !defined(__APPLE__) && !defined(__FreeBSD__)
+ #include <malloc.h>
++#endif
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+--- a/netem/normal.c
++++ b/netem/normal.c
+@@ -9,8 +9,12 @@
+ #include <string.h>
+ #include <limits.h>
+
++#if !defined(__APPLE__) && !defined(__FreeBSD__)
+ #include <linux/types.h>
+ #include <linux/pkt_sched.h>
++#else
++#define NETEM_DIST_SCALE 8192
++#endif
+
+ #define TABLESIZE 16384
+ #define TABLEFACTOR NETEM_DIST_SCALE
+--- a/netem/pareto.c
++++ b/netem/pareto.c
+@@ -8,8 +8,12 @@
+ #include <math.h>
+ #include <limits.h>
+
++#if !defined(__APPLE__) && !defined(__FreeBSD__)
+ #include <linux/types.h>
+ #include <linux/pkt_sched.h>
++#else
++#define NETEM_DIST_SCALE 8192
++#endif
+
+ static const double a=3.0;
+ #define TABLESIZE 16384
+--- a/netem/paretonormal.c
++++ b/netem/paretonormal.c
+@@ -15,10 +15,13 @@
+ #include <string.h>
+ #include <math.h>
+ #include <limits.h>
++#if !defined(__APPLE__) && !defined(__FreeBSD__)
+ #include <malloc.h>
+-
+ #include <linux/types.h>
+ #include <linux/pkt_sched.h>
++#else
++#define NETEM_DIST_SCALE 8192
++#endif
+
+ #define TABLESIZE 16384
+ #define TABLEFACTOR NETEM_DIST_SCALE
diff --git a/package/network/utils/iproute2/patches/115-add-config-xtlibdir.patch b/package/network/utils/iproute2/patches/115-add-config-xtlibdir.patch
new file mode 100644
index 0000000..38448e6
--- /dev/null
+++ b/package/network/utils/iproute2/patches/115-add-config-xtlibdir.patch
@@ -0,0 +1,12 @@
+--- a/tc/Makefile
++++ b/tc/Makefile
+@@ -107,6 +107,9 @@ CFLAGS += -DCONFIG_GACT -DCONFIG_GACT_PR
+ ifneq ($(IPT_LIB_DIR),)
+ CFLAGS += -DIPT_LIB_DIR=\"$(IPT_LIB_DIR)\"
+ endif
++ifneq ($(XT_LIB_DIR),)
++ CFLAGS += -DXT_LIB_DIR=\"$(XT_LIB_DIR)\"
++endif
+
+ LEX := flex
+ CFLAGS += -DYY_NO_INPUT
diff --git a/package/network/utils/iproute2/patches/120-no_arpd_ifstat_rtacct_lnstat.patch b/package/network/utils/iproute2/patches/120-no_arpd_ifstat_rtacct_lnstat.patch
new file mode 100644
index 0000000..bb6a8d0
--- /dev/null
+++ b/package/network/utils/iproute2/patches/120-no_arpd_ifstat_rtacct_lnstat.patch
@@ -0,0 +1,20 @@
+--- a/misc/Makefile
++++ b/misc/Makefile
+@@ -2,13 +2,13 @@
+ SSOBJ=ss.o ssfilter_check.o ssfilter.tab.o
+ LNSTATOBJ=lnstat.o lnstat_util.o
+
+-TARGETS=ss nstat ifstat rtacct lnstat
++TARGETS=ss nstat
+
+ include ../config.mk
+
+-ifeq ($(HAVE_BERKELEY_DB),y)
+- TARGETS += arpd
+-endif
++#ifeq ($(HAVE_BERKELEY_DB),y)
++# TARGETS += arpd
++#endif
+
+ all: $(TARGETS)
+
diff --git a/package/network/utils/iproute2/patches/130-no_netem_tipc_dcb_man_vdpa.patch b/package/network/utils/iproute2/patches/130-no_netem_tipc_dcb_man_vdpa.patch
new file mode 100644
index 0000000..7f94607
--- /dev/null
+++ b/package/network/utils/iproute2/patches/130-no_netem_tipc_dcb_man_vdpa.patch
@@ -0,0 +1,14 @@
+--- a/Makefile
++++ b/Makefile
+@@ -69,9 +69,9 @@ WFLAGS += -Wmissing-declarations -Wold-s
+ CFLAGS := $(WFLAGS) $(CCOPTS) -I../include -I../include/uapi $(DEFINES) $(CFLAGS)
+ YACCFLAGS = -d -t -v
+
+-SUBDIRS=lib ip tc bridge misc netem genl man
++SUBDIRS=lib ip tc bridge misc genl
+ ifeq ($(HAVE_MNL),y)
+-SUBDIRS += tipc devlink rdma dcb vdpa
++SUBDIRS += devlink rdma
+ endif
+
+ LIBNETLINK=../lib/libutil.a ../lib/libnetlink.a
diff --git a/package/network/utils/iproute2/patches/140-allow_pfifo_fast.patch b/package/network/utils/iproute2/patches/140-allow_pfifo_fast.patch
new file mode 100644
index 0000000..8f5a7d3
--- /dev/null
+++ b/package/network/utils/iproute2/patches/140-allow_pfifo_fast.patch
@@ -0,0 +1,9 @@
+--- a/tc/q_fifo.c
++++ b/tc/q_fifo.c
+@@ -90,5 +90,6 @@ struct qdisc_util pfifo_head_drop_qdisc_
+
+ struct qdisc_util pfifo_fast_qdisc_util = {
+ .id = "pfifo_fast",
++ .parse_qopt = fifo_parse_opt,
+ .print_qopt = prio_print_opt,
+ };
diff --git a/package/network/utils/iproute2/patches/140-keep_libmnl_optional.patch b/package/network/utils/iproute2/patches/140-keep_libmnl_optional.patch
new file mode 100644
index 0000000..48a4ae7
--- /dev/null
+++ b/package/network/utils/iproute2/patches/140-keep_libmnl_optional.patch
@@ -0,0 +1,11 @@
+--- a/configure
++++ b/configure
+@@ -368,7 +368,7 @@ check_tirpc()
+
+ check_mnl()
+ {
+- if ${PKG_CONFIG} libmnl --exists; then
++ if [ "${HAVE_MNL}" = "y" ] && ${PKG_CONFIG} libmnl --exists; then
+ echo "HAVE_MNL:=y" >>$CONFIG
+ echo "yes"
+
diff --git a/package/network/utils/iproute2/patches/145-keep_libelf_optional.patch b/package/network/utils/iproute2/patches/145-keep_libelf_optional.patch
new file mode 100644
index 0000000..99b9d32
--- /dev/null
+++ b/package/network/utils/iproute2/patches/145-keep_libelf_optional.patch
@@ -0,0 +1,11 @@
+--- a/configure
++++ b/configure
+@@ -217,7 +217,7 @@ EOF
+
+ check_elf()
+ {
+- if ${PKG_CONFIG} libelf --exists; then
++ if [ "${HAVE_ELF}" = "y" ] && ${PKG_CONFIG} libelf --exists; then
+ echo "HAVE_ELF:=y" >>$CONFIG
+ echo "yes"
+
diff --git a/package/network/utils/iproute2/patches/150-keep_libcap_optional.patch b/package/network/utils/iproute2/patches/150-keep_libcap_optional.patch
new file mode 100644
index 0000000..49873f8
--- /dev/null
+++ b/package/network/utils/iproute2/patches/150-keep_libcap_optional.patch
@@ -0,0 +1,11 @@
+--- a/configure
++++ b/configure
+@@ -427,7 +427,7 @@ EOF
+
+ check_cap()
+ {
+- if ${PKG_CONFIG} libcap --exists; then
++ if [ "${HAVE_CAP}" = "y" ] && ${PKG_CONFIG} libcap --exists; then
+ echo "HAVE_CAP:=y" >>$CONFIG
+ echo "yes"
+
diff --git a/package/network/utils/iproute2/patches/155-keep_tirpc_optional.patch b/package/network/utils/iproute2/patches/155-keep_tirpc_optional.patch
new file mode 100644
index 0000000..9e5e433
--- /dev/null
+++ b/package/network/utils/iproute2/patches/155-keep_tirpc_optional.patch
@@ -0,0 +1,11 @@
+--- a/configure
++++ b/configure
+@@ -355,7 +355,7 @@ check_selinux()
+
+ check_tirpc()
+ {
+- if ${PKG_CONFIG} libtirpc --exists; then
++ if [ "${HAVE_TIRPC}" = "y" ] && ${PKG_CONFIG} libtirpc --exists; then
+ echo "HAVE_RPC:=y" >>$CONFIG
+ echo "yes"
+
diff --git a/package/network/utils/iproute2/patches/160-libnetlink-pic.patch b/package/network/utils/iproute2/patches/160-libnetlink-pic.patch
new file mode 100644
index 0000000..145ec7a
--- /dev/null
+++ b/package/network/utils/iproute2/patches/160-libnetlink-pic.patch
@@ -0,0 +1,11 @@
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ include ../config.mk
+
+-CFLAGS += -fPIC
++CFLAGS += $(FPIC)
+
+ UTILOBJ = utils.o utils_math.o rt_names.o ll_map.o ll_types.o ll_proto.o ll_addr.o \
+ inet_proto.o namespace.o json_writer.o json_print.o json_print_math.o \
diff --git a/package/network/utils/iproute2/patches/170-ip_tiny.patch b/package/network/utils/iproute2/patches/170-ip_tiny.patch
new file mode 100644
index 0000000..149bcd2
--- /dev/null
+++ b/package/network/utils/iproute2/patches/170-ip_tiny.patch
@@ -0,0 +1,108 @@
+--- a/ip/Makefile
++++ b/ip/Makefile
+@@ -19,6 +19,13 @@ RTMONOBJ=rtmon.o
+
+ include ../config.mk
+
++STATIC_SYM_FILTER:=
++ifeq ($(IP_CONFIG_TINY),y)
++ STATIC_SYM_FILTER:=iplink_can.c iplink_ipoib.c iplink_vxlan.c
++ CFLAGS += -DIPROUTE2_TINY
++endif
++STATIC_SYM_SOURCES:=$(filter-out $(STATIC_SYM_FILTER),$(wildcard *.c))
++
+ ALLOBJ=$(IPOBJ) $(RTMONOBJ)
+ SCRIPTS=routel
+ TARGETS=ip rtmon
+@@ -48,7 +55,7 @@ else
+
+ ip: static-syms.o
+ static-syms.o: static-syms.h
+-static-syms.h: $(wildcard *.c)
++static-syms.h: $(STATIC_SYM_SOURCES)
+ files="$^" ; \
+ for s in `grep -B 3 '\<dlsym' $$files | sed -n '/snprintf/{s:.*"\([^"]*\)".*:\1:;s:%s::;p}'` ; do \
+ sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
+--- a/ip/ip.c
++++ b/ip/ip.c
+@@ -61,11 +61,17 @@ static void usage(void)
+ fprintf(stderr,
+ "Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
+ " ip [ -force ] -batch filename\n"
++#ifndef IPROUTE2_TINY
+ "where OBJECT := { address | addrlabel | fou | help | ila | ioam | l2tp | link |\n"
+ " macsec | maddress | monitor | mptcp | mroute | mrule |\n"
+ " neighbor | neighbour | netconf | netns | nexthop | ntable |\n"
+ " ntbl | route | rule | sr | stats | tap | tcpmetrics |\n"
+ " token | tunnel | tuntap | vrf | xfrm }\n"
++#else
++ "where OBJECT := { address | help | link | maddress | monitor |\n"
++ " neighbor | neighbour | netns | route |\n"
++ " rule | stats | token | tunnel }\n"
++#endif
+ " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
+ " -h[uman-readable] | -iec | -j[son] | -p[retty] |\n"
+ " -f[amily] { inet | inet6 | mpls | bridge | link } |\n"
+@@ -88,37 +94,49 @@ static const struct cmd {
+ int (*func)(int argc, char **argv);
+ } cmds[] = {
+ { "address", do_ipaddr },
++#ifndef IPROUTE2_TINY
+ { "addrlabel", do_ipaddrlabel },
++#endif
+ { "maddress", do_multiaddr },
+ { "route", do_iproute },
+ { "rule", do_iprule },
+ { "neighbor", do_ipneigh },
+ { "neighbour", do_ipneigh },
++#ifndef IPROUTE2_TINY
+ { "ntable", do_ipntable },
+ { "ntbl", do_ipntable },
++#endif
+ { "link", do_iplink },
++#ifndef IPROUTE2_TINY
+ { "l2tp", do_ipl2tp },
+ { "fou", do_ipfou },
+ { "ila", do_ipila },
+ { "macsec", do_ipmacsec },
++#endif
+ { "tunnel", do_iptunnel },
+ { "tunl", do_iptunnel },
++#ifndef IPROUTE2_TINY
+ { "tuntap", do_iptuntap },
+ { "tap", do_iptuntap },
+ { "token", do_iptoken },
+ { "tcpmetrics", do_tcp_metrics },
+ { "tcp_metrics", do_tcp_metrics },
++#endif
+ { "monitor", do_ipmonitor },
++#ifndef IPROUTE2_TINY
+ { "xfrm", do_xfrm },
+ { "mroute", do_multiroute },
+ { "mrule", do_multirule },
++#endif
+ { "netns", do_netns },
++#ifndef IPROUTE2_TINY
+ { "netconf", do_ipnetconf },
+ { "vrf", do_ipvrf},
+ { "sr", do_seg6 },
+ { "nexthop", do_ipnh },
+ { "mptcp", do_mptcp },
+ { "ioam", do_ioam6 },
++#endif
+ { "help", do_help },
+ { "stats", do_ipstats },
+ { 0 }
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -3,6 +3,10 @@ include ../config.mk
+
+ CFLAGS += $(FPIC)
+
++ifeq ($(IP_CONFIG_TINY),y)
++ CFLAGS += -DIPROUTE2_TINY
++endif
++
+ UTILOBJ = utils.o utils_math.o rt_names.o ll_map.o ll_types.o ll_proto.o ll_addr.o \
+ inet_proto.o namespace.o json_writer.o json_print.o json_print_math.o \
+ names.o color.o bpf_legacy.o bpf_glue.o exec.o fs.o cg_map.o ppp_proto.o
diff --git a/package/network/utils/iproute2/patches/180-drop_FAILED_POLICY.patch b/package/network/utils/iproute2/patches/180-drop_FAILED_POLICY.patch
new file mode 100644
index 0000000..9ce7dd9
--- /dev/null
+++ b/package/network/utils/iproute2/patches/180-drop_FAILED_POLICY.patch
@@ -0,0 +1,41 @@
+From 4e7dbf76227e8c7be7897dc81def3011f637864d Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo@openwrt.org>
+Date: Thu, 30 May 2013 11:54:04 +0200
+Subject: [PATCH] add support for dropping with FAILED_POLICY
+
+---
+ include/linux/fib_rules.h | 4 ++++
+ include/linux/rtnetlink.h | 1 +
+ ip/rtm_map.c | 4 ++++
+ 3 files changed, 9 insertions(+)
+
+--- a/ip/rtm_map.c
++++ b/ip/rtm_map.c
+@@ -49,6 +49,8 @@ char *rtnl_rtntype_n2a(int id, char *buf
+ return "nat";
+ case RTN_XRESOLVE:
+ return "xresolve";
++ case RTN_FAILED_POLICY:
++ return "failed_policy";
+ default:
+ snprintf(buf, len, "%d", id);
+ return buf;
+@@ -84,6 +86,8 @@ int rtnl_rtntype_a2n(int *id, char *arg)
+ res = RTN_UNICAST;
+ else if (strcmp(arg, "throw") == 0)
+ res = RTN_THROW;
++ else if (strcmp(arg, "failed_policy") == 0)
++ res = RTN_FAILED_POLICY;
+ else {
+ res = strtoul(arg, &end, 0);
+ if (!end || end == arg || *end || res > 255)
+--- a/include/uapi/linux/rtnetlink.h
++++ b/include/uapi/linux/rtnetlink.h
+@@ -265,6 +265,7 @@ enum {
+ RTN_THROW, /* Not in this table */
+ RTN_NAT, /* Translate this address */
+ RTN_XRESOLVE, /* Use external resolver */
++ RTN_FAILED_POLICY, /* Source address failed policy */
+ __RTN_MAX
+ };
+
diff --git a/package/network/utils/iproute2/patches/190-fix-nls-rpath-link.patch b/package/network/utils/iproute2/patches/190-fix-nls-rpath-link.patch
new file mode 100644
index 0000000..545075f
--- /dev/null
+++ b/package/network/utils/iproute2/patches/190-fix-nls-rpath-link.patch
@@ -0,0 +1,20 @@
+--- a/configure
++++ b/configure
+@@ -241,7 +241,7 @@ int main(int argc, char **argv) {
+ }
+ EOF
+
+- $CC -o $TMPDIR/libbpf_test $TMPDIR/libbpf_test.c $LIBBPF_CFLAGS $LIBBPF_LDLIBS >/dev/null 2>&1
++ $CC -o $TMPDIR/libbpf_test $TMPDIR/libbpf_test.c $LIBBPF_CFLAGS $LIBBPF_LDLIBS $LDFLAGS >/dev/null 2>&1
+ local ret=$?
+
+ rm -f $TMPDIR/libbpf_test.c $TMPDIR/libbpf_test
+@@ -259,7 +259,7 @@ int main(int argc, char **argv) {
+ }
+ EOF
+
+- $CC -o $TMPDIR/libbpf_sec_test $TMPDIR/libbpf_sec_test.c $LIBBPF_CFLAGS $LIBBPF_LDLIBS >/dev/null 2>&1
++ $CC -o $TMPDIR/libbpf_sec_test $TMPDIR/libbpf_sec_test.c $LIBBPF_CFLAGS $LIBBPF_LDLIBS $LDFLAGS >/dev/null 2>&1
+ local ret=$?
+
+ rm -f $TMPDIR/libbpf_sec_test.c $TMPDIR/libbpf_sec_test
diff --git a/package/network/utils/iproute2/patches/195-build_variant_ip_tc.patch b/package/network/utils/iproute2/patches/195-build_variant_ip_tc.patch
new file mode 100644
index 0000000..6ecf556
--- /dev/null
+++ b/package/network/utils/iproute2/patches/195-build_variant_ip_tc.patch
@@ -0,0 +1,22 @@
+--- a/ip/Makefile
++++ b/ip/Makefile
+@@ -28,7 +28,7 @@ STATIC_SYM_SOURCES:=$(filter-out $(STATI
+
+ ALLOBJ=$(IPOBJ) $(RTMONOBJ)
+ SCRIPTS=routel
+-TARGETS=ip rtmon
++TARGETS=$(findstring ip,$(BUILD_VARIANT)) rtmon
+
+ all: $(TARGETS) $(SCRIPTS)
+
+--- a/tc/Makefile
++++ b/tc/Makefile
+@@ -120,7 +120,7 @@ MODDESTDIR := $(DESTDIR)$(LIBDIR)/tc
+ $(QUIET_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -shared -fpic $< -o $@
+
+
+-all: tc $(TCSO)
++all: $(findstring tc,$(BUILD_VARIANT)) $(TCSO)
+
+ tc: $(TCOBJ) $(LIBNETLINK) libtc.a
+ $(QUIET_LINK)$(CC) $^ $(LDFLAGS) $(LDLIBS) -o $@
diff --git a/package/network/utils/iproute2/patches/200-drop_libbsd_dependency.patch b/package/network/utils/iproute2/patches/200-drop_libbsd_dependency.patch
new file mode 100644
index 0000000..38193be
--- /dev/null
+++ b/package/network/utils/iproute2/patches/200-drop_libbsd_dependency.patch
@@ -0,0 +1,19 @@
+--- a/configure
++++ b/configure
+@@ -413,14 +413,8 @@ EOF
+ if $CC -I$INCLUDE -o $TMPDIR/strtest $TMPDIR/strtest.c >/dev/null 2>&1; then
+ echo "no"
+ else
+- if ${PKG_CONFIG} libbsd --exists; then
+- echo 'CFLAGS += -DHAVE_LIBBSD' "$(${PKG_CONFIG} libbsd --cflags)" >>$CONFIG
+- echo 'LDLIBS +=' "$(${PKG_CONFIG} libbsd --libs)" >> $CONFIG
+- echo "no"
+- else
+- echo 'CFLAGS += -DNEED_STRLCPY' >>$CONFIG
+- echo "yes"
+- fi
++ echo 'CFLAGS += -DNEED_STRLCPY' >>$CONFIG
++ echo "yes"
+ fi
+ rm -f $TMPDIR/strtest.c $TMPDIR/strtest
+ }
diff --git a/package/network/utils/iproute2/patches/300-selinux-configurable.patch b/package/network/utils/iproute2/patches/300-selinux-configurable.patch
new file mode 100644
index 0000000..9f07d31
--- /dev/null
+++ b/package/network/utils/iproute2/patches/300-selinux-configurable.patch
@@ -0,0 +1,11 @@
+--- a/configure
++++ b/configure
+@@ -342,7 +342,7 @@ check_libbpf()
+ check_selinux()
+ # SELinux is a compile time option in the ss utility
+ {
+- if ${PKG_CONFIG} libselinux --exists; then
++ if [ "${HAVE_SELINUX}" = "y" ] && ${PKG_CONFIG} libselinux --exists; then
+ echo "HAVE_SELINUX:=y" >>$CONFIG
+ echo "yes"
+
diff --git a/package/network/utils/iproute2/patches/400-rdma-include-libgen.h-for-basename.patch b/package/network/utils/iproute2/patches/400-rdma-include-libgen.h-for-basename.patch
new file mode 100644
index 0000000..530d2bc
--- /dev/null
+++ b/package/network/utils/iproute2/patches/400-rdma-include-libgen.h-for-basename.patch
@@ -0,0 +1,10 @@
+--- a/rdma/rdma.h
++++ b/rdma/rdma.h
+@@ -16,6 +16,7 @@
+ #include <rdma/rdma_user_cm.h>
+ #include <time.h>
+ #include <net/if_arp.h>
++#include <libgen.h>
+
+ #include "list.h"
+ #include "utils.h"
diff --git a/package/network/utils/ipset/Makefile b/package/network/utils/ipset/Makefile
new file mode 100644
index 0000000..c62bbd8
--- /dev/null
+++ b/package/network/utils/ipset/Makefile
@@ -0,0 +1,75 @@
+
+# Copyright (C) 2009-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ipset
+PKG_VERSION:=7.21
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://ipset.netfilter.org
+PKG_HASH:=e2c6ce4fcf3acb3893ca5d35c86935f80ad76fc5ccae601185842df760e0bc69
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
+PKG_LICENSE:=GPL-2.0
+PKG_CPE_ID:=cpe:/a:netfilter:ipset
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ipset/Default
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS+= +kmod-ipt-ipset +libmnl
+ TITLE:=IPset administration utility
+ URL:=http://ipset.netfilter.org/
+endef
+
+define Package/ipset
+$(call Package/ipset/Default)
+ DEPENDS+= +libipset
+endef
+
+define Package/libipset
+$(call Package/ipset/Default)
+ ABI_VERSION:=13
+endef
+
+CONFIGURE_ARGS += \
+ --disable-static \
+ --with-kbuild="$(LINUX_DIR)"
+
+TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
+
+MAKE_FLAGS += \
+ ARCH="$(LINUX_KARCH)" \
+ SHELL="$(BASH)"
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/libipset $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libipset.so* $(1)/usr/lib/
+ $(CP) $(PKG_BUILD_DIR)/lib/libipset.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/ipset/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/ipset $(1)/usr/sbin/
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/ipset-translate $(1)/usr/sbin/
+endef
+
+define Package/libipset/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libipset*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libipset))
+$(eval $(call BuildPackage,ipset))
diff --git a/package/network/utils/ipset/patches/0001-include-libgen.h-for-basename.patch b/package/network/utils/ipset/patches/0001-include-libgen.h-for-basename.patch
new file mode 100644
index 0000000..fb86bba
--- /dev/null
+++ b/package/network/utils/ipset/patches/0001-include-libgen.h-for-basename.patch
@@ -0,0 +1,12 @@
+--- a/src/ipset.c
++++ b/src/ipset.c
+@@ -6,8 +6,8 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+-#define _GNU_SOURCE
+ #include <assert.h> /* assert */
++#include <libgen.h> /* basename */
+ #include <stdio.h> /* fprintf */
+ #include <stdlib.h> /* exit */
+ #include <string.h> /* strcmp */
diff --git a/package/network/utils/ipt_trigger/inc/ipt_trigger.h b/package/network/utils/ipt_trigger/inc/ipt_trigger.h
new file mode 100644
index 0000000..886e201
--- /dev/null
+++ b/package/network/utils/ipt_trigger/inc/ipt_trigger.h
@@ -0,0 +1,24 @@
+#ifndef _IPT_TRIGGER_H_target
+#define _IPT_TRIGGER_H_target
+
+#define TRIGGER_TIMEOUT 600 /* 600 secs */
+
+enum ipt_trigger_type
+{
+ IPT_TRIGGER_DNAT = 1,
+ IPT_TRIGGER_IN = 2,
+ IPT_TRIGGER_OUT = 3
+};
+
+struct ipt_trigger_ports {
+ u_int16_t mport[2]; /* Related destination port range */
+ u_int16_t rport[2]; /* Port range to map related destination port range to */
+};
+
+struct ipt_trigger_info {
+ enum ipt_trigger_type type;
+ u_int16_t proto; /* Related protocol */
+ struct ipt_trigger_ports ports;
+};
+
+#endif /*_IPT_TRIGGER_H_target*/
diff --git a/package/network/utils/ipt_trigger/ipt_trigger_ko/Makefile b/package/network/utils/ipt_trigger/ipt_trigger_ko/Makefile
new file mode 100644
index 0000000..2443d84
--- /dev/null
+++ b/package/network/utils/ipt_trigger/ipt_trigger_ko/Makefile
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/netfilter.mk
+
+PKG_NAME:=ipt_trigger
+PKG_RELEASE:=1
+PKG_PATH=$(TOPDIR)/package/network/utils/ipt_trigger
+
+define KernelPackage/ipt_trigger
+ SUBMENU:=Netfilter Extensions
+ TITLE:=kernel module for port trigger
+ DEPENDS:=+kmod-ipt-core +kmod-ipt-conntrack +kmod-ipt-nat +kmod-x_tables
+ FILES:=$(PKG_BUILD_DIR)/ipt_trigger.ko
+ KCONFIG:=CONFIG_TRIGGER=y \
+ CONFIG_TRIGGER_MASTER=y
+ AUTOLOAD:=$(call AutoLoad,50,ipt_trigger)
+ DEFAULT:=N
+endef
+
+define KernelPackage/ipt_trigger/description
+ Kernel module for port trigger
+endef
+
+EXTRA_KCONFIG:= \
+ CONFIG_IPT_TRIGGER=m
+
+EXTRA_CFLAGS:= \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
+
+MAKE_OPTS:= \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ M="$(PKG_BUILD_DIR)" \
+ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
+ $(EXTRA_KCONFIG)
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) $(PKG_PATH)/ipt_trigger_ko/src/* $(PKG_BUILD_DIR)/
+ $(CP) $(PKG_PATH)/inc/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C "$(LINUX_DIR)" \
+ $(MAKE_OPTS) \
+ modules
+endef
+
+$(eval $(call KernelPackage,ipt_trigger))
diff --git a/package/network/utils/ipt_trigger/ipt_trigger_ko/src/Kconfig b/package/network/utils/ipt_trigger/ipt_trigger_ko/src/Kconfig
new file mode 100644
index 0000000..019411f
--- /dev/null
+++ b/package/network/utils/ipt_trigger/ipt_trigger_ko/src/Kconfig
@@ -0,0 +1,6 @@
+config ipt_trigger
+ tristate "ipt trigger port"
+ default y
+ help
+ haha
+
diff --git a/package/network/utils/ipt_trigger/ipt_trigger_ko/src/Makefile b/package/network/utils/ipt_trigger/ipt_trigger_ko/src/Makefile
new file mode 100644
index 0000000..82bc220
--- /dev/null
+++ b/package/network/utils/ipt_trigger/ipt_trigger_ko/src/Makefile
@@ -0,0 +1 @@
+obj-m += ipt_trigger.o
diff --git a/package/network/utils/ipt_trigger/ipt_trigger_ko/src/ipt_trigger.c b/package/network/utils/ipt_trigger/ipt_trigger_ko/src/ipt_trigger.c
new file mode 100644
index 0000000..cb1441a
--- /dev/null
+++ b/package/network/utils/ipt_trigger/ipt_trigger_ko/src/ipt_trigger.c
@@ -0,0 +1,380 @@
+/* Kernel module to match the port-ranges, trigger related port-ranges,
+ * and alters the destination to a local IP address.
+ *
+ * Description:
+ * This is kernel module for port-triggering.
+ *
+ * The module follows the Netfilter framework, called extended packet
+ * matching modules.
+ */
+
+#include <linux/types.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/timer.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/netdevice.h>
+#include <linux/if.h>
+#include <linux/inetdevice.h>
+#include <net/protocol.h>
+#include <net/checksum.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/types.h>
+
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/nf_nat.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_tuple.h>
+#include <net/netfilter/nf_nat.h>
+#include "ipt_trigger.h"
+
+MODULE_LICENSE("GPL");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+struct ipt_trigger {
+ struct list_head list; /* Trigger list */
+ struct timer_list timeout; /* Timer for list destroying */
+ u_int32_t srcip; /* Outgoing source address */
+ u_int32_t dstip; /* Outgoing destination address */
+ u_int16_t mproto; /* Trigger protocol */
+ u_int16_t rproto; /* Related protocol */
+ struct ipt_trigger_ports ports; /* Trigger and related ports */
+ u_int8_t reply; /* Confirm a reply connection */
+};
+
+
+LIST_HEAD(trigger_list);
+DEFINE_SPINLOCK(ip_trigger_lock);
+
+static void trigger_refresh(struct ipt_trigger *trig, unsigned long extra_jiffies)
+{
+ DEBUGP("%s: \n", __FUNCTION__);
+ NF_CT_ASSERT(trig);
+ spin_lock_bh(&ip_trigger_lock);
+
+ /* Need del_timer for race avoidance (may already be dying). */
+ if (del_timer(&trig->timeout)) {
+ trig->timeout.expires = jiffies + extra_jiffies;
+ add_timer(&trig->timeout);
+ }
+
+ spin_unlock_bh(&ip_trigger_lock);
+}
+
+static void __del_trigger(struct ipt_trigger *trig)
+{
+ DEBUGP("%s: \n", __FUNCTION__);
+ NF_CT_ASSERT(trig);
+
+ /* delete from 'trigger_list' */
+ list_del(&trig->list);
+ kfree(trig);
+}
+
+static void trigger_timeout(struct timer_list *t)
+{
+ struct ipt_trigger *trig = container_of(t, struct ipt_trigger, timeout);
+
+ DEBUGP("trigger list %p timed out\n", trig);
+ spin_lock_bh(&ip_trigger_lock);
+ __del_trigger(trig);
+ spin_unlock_bh(&ip_trigger_lock);
+}
+
+static unsigned int
+add_new_trigger(struct ipt_trigger *trig)
+{
+ struct ipt_trigger *trigger_new;
+
+ DEBUGP("!!!!!!!!!!!! %s !!!!!!!!!!!\n", __FUNCTION__);
+ spin_lock_bh(&ip_trigger_lock);
+ trigger_new = (struct ipt_trigger *)
+ kzalloc(sizeof(struct ipt_trigger), GFP_ATOMIC);
+
+ if (!trigger_new) {
+ spin_unlock_bh(&ip_trigger_lock);
+ DEBUGP("%s: OOM allocating trigger list\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ memcpy(trigger_new, trig, sizeof(*trig));
+ INIT_LIST_HEAD(&trigger_new->list);
+
+ /* add to global table of trigger */
+ list_add(&trigger_new->list, &trigger_list);
+ /* add and start timer if required */
+#if 0
+ init_timer(&trigger_new->timeout);
+ trigger_new->timeout.data = (unsigned long)trigger_new;
+ trigger_new->timeout.function = trigger_timeout;
+ trigger_new->timeout.expires = jiffies + (TRIGGER_TIMEOUT * HZ);
+ add_timer(&trigger_new->timeout);
+#else
+ timer_setup(&trigger_new->timeout, trigger_timeout, 0);
+#endif
+
+ spin_unlock_bh(&ip_trigger_lock);
+
+ return 0;
+}
+
+static inline int trigger_out_matched(const struct ipt_trigger *i,
+ const u_int16_t proto, const u_int16_t dport)
+{
+ /* DEBUGP("%s: i=%p, proto= %d, dport=%d.\n", __FUNCTION__, i, proto, dport);
+ DEBUGP("%s: Got one, mproto= %d, mport[0..1]=%d, %d.\n", __FUNCTION__,
+ i->mproto, i->ports.mport[0], i->ports.mport[1]); */
+
+ return ((i->mproto == proto) && (i->ports.mport[0] <= dport)
+ && (i->ports.mport[1] >= dport));
+}
+static inline int trigger_in_matched(const struct ipt_trigger *i,
+ const u_int16_t proto, const u_int16_t dport)
+{
+ /* DEBUGP("%s: i=%p, proto= %d, dport=%d.\n", __FUNCTION__, i, proto, dport);
+ DEBUGP("%s: Got one, rproto= %d, rport[0..1]=%d, %d.\n", __FUNCTION__,
+ i->rproto, i->ports.rport[0], i->ports.rport[1]); */
+ u_int16_t rproto = i->rproto;
+
+ if (!rproto)
+ rproto = proto;
+
+ return ((rproto == proto) && (i->ports.rport[0] <= dport)
+ && (i->ports.rport[1] >= dport));
+}
+/*in -- 0; out -- 1*/
+enum
+{
+ TRIGGER_IN_MATCH,
+ TRIGGER_OUT_MATCH,
+};
+struct ipt_trigger * trigger_find_match(struct list_head *list_head, const u_int16_t proto, const u_int16_t dport , int type)
+{
+ const struct list_head *_i, *_j = NULL;
+
+ list_for_each(_i, list_head)
+ {
+ if(type == TRIGGER_IN_MATCH)
+ {
+ if (trigger_in_matched((const struct ipt_trigger*)_i , proto, dport))
+ {
+ _j = _i;
+ break;
+ }
+ }
+ else if(type == TRIGGER_OUT_MATCH)
+ {
+ if (trigger_out_matched((const struct ipt_trigger*)_i , proto, dport))
+ {
+ _j = _i;
+ break;
+ }
+ }
+
+ }
+
+
+ if(_j)
+ {
+ return (struct ipt_trigger *)_j;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static unsigned int
+trigger_out(struct sk_buff *skb,
+ unsigned int hooknum,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *targinfo)
+{
+ const struct ipt_trigger_info *info = targinfo;
+ struct ipt_trigger trig, *found;
+ const struct iphdr *iph = ip_hdr(skb);
+ struct tcphdr *tcph = (void *)iph + iph->ihl*4; /* Might be TCP, UDP */
+
+ DEBUGP("############# %s ############\n", __FUNCTION__);
+
+ /* Check if the trigger range has already existed in 'trigger_list'. */
+ found = trigger_find_match(&trigger_list, iph->protocol, ntohs(tcph->dest), TRIGGER_OUT_MATCH);
+
+ if (found) {
+ /* Yeah, it exists. We need to update(delay) the destroying timer. */
+ trigger_refresh(found, TRIGGER_TIMEOUT * HZ);
+ /* In order to allow multiple hosts use the same port range, we update
+ the 'saddr' after previous trigger has a reply connection. */
+ if (found->reply)
+ found->srcip = iph->saddr;
+ }
+ else {
+ /* Create new trigger */
+ memset(&trig, 0, sizeof(trig));
+ trig.srcip = iph->saddr;
+ trig.mproto = iph->protocol;
+ trig.rproto = info->proto;
+ memcpy(&trig.ports, &info->ports, sizeof(struct ipt_trigger_ports));
+ add_new_trigger(&trig); /* Add the new 'trig' to list 'trigger_list'. */
+ }
+
+ return XT_CONTINUE; /* We don't block any packet. */
+}
+
+
+static unsigned int
+trigger_in(struct sk_buff *skb,
+ unsigned int hooknum,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *targinfo)
+{
+ struct ipt_trigger *found;
+ const struct iphdr *iph = ip_hdr(skb);
+ struct tcphdr *tcph = (void *)iph + iph->ihl*4; /* Might be TCP, UDP */
+ /* Check if the trigger-ed range has already existed in 'trigger_list'. */
+ found = trigger_find_match(&trigger_list, iph->protocol, ntohs(tcph->dest), TRIGGER_IN_MATCH);
+ if (found) {
+ DEBUGP("############# %s ############\n", __FUNCTION__);
+ /* Yeah, it exists. We need to update(delay) the destroying timer. */
+ trigger_refresh(found, TRIGGER_TIMEOUT * HZ);
+ return NF_ACCEPT; /* Accept it, or the imcoming packet could be
+ dropped in the FORWARD chain */
+ }
+
+ return XT_CONTINUE; /* Our job is the interception. */
+}
+
+static unsigned int
+trigger_dnat(struct sk_buff *skb,
+ unsigned int hooknum,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *targinfo)
+{
+ struct ipt_trigger *found;
+ const struct iphdr *iph = ip_hdr(skb);
+ struct tcphdr *tcph = (void *)iph + iph->ihl*4; /* Might be TCP, UDP */
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+ struct nf_nat_range2 newrange = { 0 };
+
+ NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING);
+ /* Check if the trigger-ed range has already existed in 'trigger_list'. */
+ found = trigger_find_match(&trigger_list, iph->protocol, ntohs(tcph->dest), TRIGGER_IN_MATCH);
+
+ if (!found || !found->srcip)
+ return XT_CONTINUE; /* We don't block any packet. */
+
+ DEBUGP("############# %s ############\n", __FUNCTION__);
+ found->reply = 1; /* Confirm there has been a reply connection. */
+ ct = nf_ct_get(skb, &ctinfo);
+ NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW));
+
+ DEBUGP("%s: got ", __FUNCTION__);
+ nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+
+ /* Alter the destination of imcoming packet. */
+ newrange.flags = NF_NAT_RANGE_MAP_IPS;
+ newrange.min_addr = newrange.max_addr = (union nf_inet_addr)found->srcip;
+ newrange.min_proto.all = newrange.max_proto.all = 0;
+
+ /* Hand modified range to generic setup. */
+ return nf_nat_setup_info(ct, &newrange, hooknum);
+}
+static unsigned int
+trigger_target (struct sk_buff *skb,
+ const struct xt_action_param *par)
+{
+ const struct ipt_trigger_info *info = par->targinfo;
+ const struct iphdr *iph = ip_hdr(skb);
+
+ /* DEBUGP("%s: type = %s\n", __FUNCTION__,
+ (info->type == IPT_TRIGGER_DNAT) ? "dnat" :
+ (info->type == IPT_TRIGGER_IN) ? "in" : "out"); */
+
+ /* The Port-trigger only supports TCP and UDP. */
+ if ((iph->protocol != IPPROTO_TCP) && (iph->protocol != IPPROTO_UDP))
+ return XT_CONTINUE;
+
+ if (info->type == IPT_TRIGGER_OUT)
+ return trigger_out(skb, par->state->hook, par->state->in, par->state->out, par->targinfo);
+ else if (info->type == IPT_TRIGGER_IN)
+ return trigger_in(skb, par->state->hook, par->state->in, par->state->out, par->targinfo);
+ else if (info->type == IPT_TRIGGER_DNAT)
+ return trigger_dnat(skb, par->state->hook, par->state->in, par->state->out, par->targinfo);
+
+ return XT_CONTINUE;
+}
+
+static int
+trigger_check(const struct xt_tgchk_param *par)
+{
+ const struct ipt_trigger_info *info = par->targinfo;
+ struct list_head *cur_item, *tmp_item;
+
+ if ((strcmp(par->table, "mangle") == 0)) {
+ DEBUGP("trigger_check: bad table `%s'.\n", par->table);
+ return -EINVAL;
+ }
+ if (par->hook_mask & ~((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_FORWARD))) {
+ DEBUGP("trigger_check: bad hooks %x.\n", par->hook_mask);
+ return -EINVAL;
+ }
+ if (info->proto) {
+ if (info->proto != IPPROTO_TCP && info->proto != IPPROTO_UDP) {
+ DEBUGP("trigger_check: bad proto %d.\n", info->proto);
+ return -EINVAL;
+ }
+ }
+ if (info->type == IPT_TRIGGER_OUT) {
+ if (!info->ports.mport[0] || !info->ports.rport[0]) {
+ DEBUGP("trigger_check: Try 'iptbles -j TRIGGER -h' for help.\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Empty the 'trigger_list' */
+ list_for_each_safe(cur_item, tmp_item, &trigger_list) {
+ struct ipt_trigger *trig = (void *)cur_item;
+
+ DEBUGP("%s: list_for_each_safe(): %p.\n", __FUNCTION__, trig);
+ del_timer(&trig->timeout);
+ __del_trigger(trig);
+ }
+
+ return 0;
+}
+
+static struct xt_target redirect_reg = {
+ .name = "TRIGGER",
+ .family = AF_INET,
+ .target = trigger_target,
+ .targetsize = sizeof(struct ipt_trigger_info),
+ .checkentry = trigger_check,
+ .me = THIS_MODULE,
+};
+
+static int __init init(void)
+{
+ return xt_register_target(&redirect_reg);
+}
+
+static void __exit fini(void)
+{
+ xt_unregister_target(&redirect_reg);
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/package/network/utils/ipt_trigger/libipt_trigger/Makefile b/package/network/utils/ipt_trigger/libipt_trigger/Makefile
new file mode 100644
index 0000000..7e9d0d2
--- /dev/null
+++ b/package/network/utils/ipt_trigger/libipt_trigger/Makefile
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/netfilter.mk
+
+PKG_NAME:=libipt_trigger
+PKG_VERSION:=2014
+PKG_RELEASE:=1
+
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+PKG_PATH:=$(TOPDIR)/package/network/utils/ipt_trigger
+SVC_SOURCE_DIR:=$(PKG_PATH)/libipt_trigger/src
+PKG_BUILD_PARALLEL:=0
+
+define Package/libipt_trigger
+ SECTION:=libipt_trigger
+ CATEGORY:=Network
+ TITLE:=ASR iptable addon to support port trigger
+ DEPENDS:=+iptables +kmod-ipt_trigger
+ DEFAULT:=N
+endef
+
+define Package/libipt_trigger/description
+ iptable addon to support port trigger
+endef
+
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+define Build/Compile
+ $(MAKE) $(PKG_JOBS) -C $(SVC_SOURCE_DIR) \
+ SUBTARGET="$(SUBTARGET)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ EXTRA_CFLAGS="$(TARGET_CFLAGS) -I$(PKG_PATH)/inc -I$(STAGING_DIR)/usr/include -I$(TOOLCHAIN_DIR)/include" \
+ LD_FLAGS="$(TARGET_LDFLAGS) -L$(TOOLCHAIN_DIR)/lib/"\
+ INSTALL_DIR="$(PKG_INSTALL_DIR)" \
+ OBJ_DIR="$(PKG_BUILD_DIR)/obj" \
+ compile
+endef
+
+define Build/Clean
+@if [ -d $(PKG_BUILD_DIR) ]; then \
+ $(MAKE) $(PKG_JOBS) -C $(SVC_SOURCE_DIR) \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ EXTRA_CFLAGS="$(TARGET_CFLAGS)" \
+ LD_FLAGS="$(TARGET_LDFLAGS)" \
+ INSTALL_DIR="$(PKG_INSTALL_DIR)" \
+ OBJ_DIR="$(PKG_BUILD_DIR)/obj" \
+ clean; \
+fi
+endef
+
+define Package/libipt_trigger/install
+ $(INSTALL_DIR) $(1)/usr/lib/iptables
+ $(CP) $(PKG_INSTALL_DIR)/lib/libipt_TRIGGER.so $(1)/usr/lib/iptables/
+endef
+$(eval $(call BuildPackage,libipt_trigger))
+
+
diff --git a/package/network/utils/ipt_trigger/libipt_trigger/src/Makefile b/package/network/utils/ipt_trigger/libipt_trigger/src/Makefile
new file mode 100644
index 0000000..878e7fa
--- /dev/null
+++ b/package/network/utils/ipt_trigger/libipt_trigger/src/Makefile
@@ -0,0 +1,76 @@
+#/******************************************************************************
+#*(C) Copyright 2008 Marvell International Ltd.
+#* All Rights Reserved
+#******************************************************************************/
+BUILDROOT := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
+
+#include $(TOPDIR)/rules.mk
+#include rules.make
+include $(BUILDROOT)/rules.make
+
+$(eval $(call define-local-build-dir, objs_libipt_TRIGGER))
+
+
+dtarget := $(LOCAL_BUILD_DIR)/libipt_TRIGGER.so
+
+compile: $(dtarget)
+
+LOCAL_SRC_FILES := \
+ libipt_TRIGGER.c \
+
+LINUX_KERNEL_INC := $(TOPDIR)/marvell/linux/include
+USER_LINUX_INC := $(TOPDIR)/marvell/linux/user_headers/include
+IPTABLES_INCLUDE = $(KERNEL_BUILD_DIR)/iptables.1.4.21/include
+
+LOCAL_CFLAGS += -DMARVELL_EXTENDED
+CFLAGS += $(LOCAL_C_INCLUDES)
+CFLAGS += $(LOCAL_CFLAGS)
+CFLAGS += $(LOCAL_CPPFLAGS)
+
+
+$(eval $(call add-many-objects-rule, ipt_trigger_src, $(LOCAL_SRC_FILES),,))
+
+#prepare:
+# @echo "begin make dir"
+# $(MRVL_HIDE)mkdir -p $(PXA_TARGET_OLIB)
+# $(MRVL_HIDE)mkdir -p $(LOCAL_BUILD_DIR)
+
+all: modules libipt_TRIGGER.so
+
+modules: $(dtarget)
+
+ @echo "KERNEL_SRC $(KERNEL_SRC)"
+
+#$(dtarget): libipt_TRIGGER.c
+ #$(MRVL_HIDE)$(CC) -DIPTABLES_VERSION=\"1.4.21\" -I$(IPTABLES_INCLUDE) -I$(USER_LINUX_INC) -I$(TOPDIR)/package/network/utils/ipt_trigger/inc -fPIC -c libipt_TRIGGER.c \
+ # -o $(LOCAL_BUILD_DIR)/libipt_TRIGGER.o
+ #$(MRVL_HIDE)$(CC) -shared -o $(dtarget) $(LOCAL_BUILD_DIR)/libipt_TRIGGER.o
+
+$(dtarget):
+ @echo "begin make dir"
+ $(MRVL_HIDE)mkdir -p $(PXA_TARGET_OLIB)
+ $(MRVL_HIDE)mkdir -p $(LOCAL_BUILD_DIR)
+ @echo "LOCAL_BUILD_DIR $(LOCAL_BUILD_DIR)"
+ @echo " LD $@"
+ $(MRVL_HIDE)$(CC) -DIPTABLES_VERSION=\"1.4.21\" -I$(IPTABLES_INCLUDE) -I$(USER_LINUX_INC) -I$(TOPDIR)/package/network/utils/ipt_trigger/inc -fPIC -c libipt_TRIGGER.c \
+ -o $(LOCAL_BUILD_DIR)/libipt_TRIGGER.o
+ $(MRVL_HIDE)$(CC) -shared -o $(dtarget) $(LOCAL_BUILD_DIR)/libipt_TRIGGER.o
+ $(call copy_elf,$(dtarget),lib)
+
+#$(dtarget): prepare $(libipt_TRIGGER_src_oo) alwayslink
+# @echo "LOCAL_BUILD_DIR $(LOCAL_BUILD_DIR)"
+# @echo " LD $@"
+# $(MRVL_HIDE)$(CC) $(CFLAGS) -DIPTABLES_VERSION=\"1.4.21\" -I$(IPTABLES_INCLUDE) -I$(USER_LINUX_INC) -I$(TOPDIR)/package/network/utils/ipt_trigger/inc -fPIC -c $(LOCAL_SRC_FILES) \
+# -o $@ $(libipt_TRIGGER_src_oo) $(LIBS)
+# $(call copy_elf,$(dtarget),lib)
+
+install:
+ @echo "install done"
+clean:
+ $(call clean_target, $(dtarget), bin)
+ $(MRVL_HIDE)rm -rf $(LOCAL_BUILD_DIR)
+
+ifeq "$(filter clean ,$(MAKECMDGOALS))" ""
+-include $(ipt_TRIGGER_src_dd)
+endif
+
diff --git a/package/network/utils/ipt_trigger/libipt_trigger/src/libipt_TRIGGER.c b/package/network/utils/ipt_trigger/libipt_trigger/src/libipt_TRIGGER.c
new file mode 100644
index 0000000..fdef8f1
--- /dev/null
+++ b/package/network/utils/ipt_trigger/libipt_trigger/src/libipt_TRIGGER.c
@@ -0,0 +1,206 @@
+/* Port-triggering target.
+ *
+ */
+
+/* Shared library add-on to iptables to add port-trigger support. */
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <xtables.h>
+#include <linux/netfilter/nf_nat.h>
+#include <ipt_trigger.h>
+
+/* Function which prints out usage message. */
+static void
+TRIGGER_help(void)
+{
+ printf(
+"TRIGGER v%s options:\n"
+" --trigger-type (dnat|in|out)\n"
+" Trigger type\n"
+" --trigger-proto proto\n"
+" Trigger protocol\n"
+" --trigger-match port[-port]\n"
+" Trigger destination port range\n"
+" --trigger-relate port[-port]\n"
+" Port range to map related destination port range to.\n\n",
+IPTABLES_VERSION);
+}
+
+enum{
+ TRIGGER_TYPE = 0,
+ TRIGGER_PROTO,
+ TRIGGER_MATCH,
+ TRIGGER_RELATE,
+ };
+static const struct xt_option_entry TRIGGER_opts[] = {
+ {.name = "trigger-type", .id = TRIGGER_TYPE, .type = XTTYPE_STRING},
+ {.name = "trigger-proto", .id = TRIGGER_PROTO, .type = XTTYPE_STRING},
+ {.name = "trigger-match", .id = TRIGGER_MATCH, .type = XTTYPE_STRING},
+ {.name = "trigger-relate", .id = TRIGGER_RELATE, .type = XTTYPE_STRING},
+ XTOPT_TABLEEND,
+};
+static void TRIGGER_init(struct xt_entry_target *t)
+{
+
+}
+
+/* Parses ports */
+static void
+TRIGGER_parse_ports(const char *arg, u_int16_t *ports)
+{
+ const char *dash;
+ int port;
+
+ port = atoi(arg);
+ if (port == 0 || port > 65535)
+ xtables_error(PARAMETER_PROBLEM, "Port range `%s' invalid\n", arg);
+
+ dash = strchr(arg, ':');
+ if (!dash)
+ ports[0] = ports[1] = port;
+ else {
+ int maxport;
+
+ maxport = atoi(dash + 1);
+ if (maxport == 0 || maxport > 65535)
+ xtables_error(PARAMETER_PROBLEM,
+ "Port range `%s' invalid\n", dash+1);
+ if (maxport < port)
+ xtables_error(PARAMETER_PROBLEM,
+ "Port range `%s' invalid\n", arg);
+ ports[0] = port;
+ ports[1] = maxport;
+ }
+}
+
+/* Function which parses command options; returns true if it
+ ate an option */
+static int
+TRIGGER_parse(struct xt_option_call *cb)
+{
+ struct ipt_trigger_info *info = (struct ipt_trigger_info *)(*cb->target)->data;
+
+ switch (cb->entry->id) {
+ case TRIGGER_TYPE:
+ if (!strcasecmp(cb->arg, "dnat"))
+ info->type = IPT_TRIGGER_DNAT;
+ else if (!strcasecmp(cb->arg, "in"))
+ info->type = IPT_TRIGGER_IN;
+ else if (!strcasecmp(cb->arg, "out"))
+ info->type = IPT_TRIGGER_OUT;
+ else
+ xtables_error(PARAMETER_PROBLEM,
+ "unknown type `%s' specified", cb->arg);
+ return 1;
+
+ case TRIGGER_PROTO:
+ if (!strcasecmp(cb->arg, "tcp"))
+ info->proto = IPPROTO_TCP;
+ else if (!strcasecmp(cb->arg, "udp"))
+ info->proto = IPPROTO_UDP;
+ else if (!strcasecmp(cb->arg, "all"))
+ info->proto = 0;
+ else
+ xtables_error(PARAMETER_PROBLEM,
+ "unknown protocol `%s' specified", cb->arg);
+ return 1;
+
+ case TRIGGER_MATCH:
+ if (cb->arg && (strcmp(cb->arg, "!") == 0))
+ {
+ cb->invert = 1;
+ xtables_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --trigger-match");
+ }
+ TRIGGER_parse_ports(cb->arg, info->ports.mport);
+ return 1;
+
+ case TRIGGER_RELATE:
+ if (cb->arg && (strcmp(cb->arg, "!") == 0))
+ {
+ cb->invert = 1;
+ xtables_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --trigger-match");
+ }
+ TRIGGER_parse_ports(cb->arg, info->ports.rport);
+ cb->xflags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* Final check; don't care. */
+static void TRIGGER_final_check(unsigned int flags)
+{
+}
+
+/* Prints out the targinfo. */
+static void
+TRIGGER_print(const struct ipt_ip *ip,
+ const struct xt_entry_target *target,
+ int numeric)
+{
+ struct ipt_trigger_info *info = (const void *)target->data;
+
+ printf("TRIGGER ");
+ if (info->type == IPT_TRIGGER_DNAT)
+ printf("type:dnat ");
+ else if (info->type == IPT_TRIGGER_IN)
+ printf("type:in ");
+ else if (info->type == IPT_TRIGGER_OUT)
+ printf("type:out ");
+
+ if (info->proto == IPPROTO_TCP)
+ printf("tcp ");
+ else if (info->proto == IPPROTO_UDP)
+ printf("udp ");
+
+ printf("match:%hu", info->ports.mport[0]);
+ if (info->ports.mport[1] > info->ports.mport[0])
+ printf(":%hu", info->ports.mport[1]);
+ printf(" ");
+
+ printf("relate:%hu", info->ports.rport[0]);
+ if (info->ports.rport[1] > info->ports.rport[0])
+ printf(":%hu", info->ports.rport[1]);
+ printf(" ");
+}
+
+/* Saves the union ipt_targinfo in parsable form to stdout. */
+static void
+TRIGGER_save(const struct ipt_ip *ip, const struct xt_entry_target *target)
+{
+ struct ipt_trigger_info *info = (const void *)target->data;
+
+ printf("--trigger-proto ");
+ if (info->proto == IPPROTO_TCP)
+ printf("tcp ");
+ else if (info->proto == IPPROTO_UDP)
+ printf("udp ");
+ printf("--trigger-match %hu:%hu ", info->ports.mport[0], info->ports.mport[1]);
+ printf("--trigger-relate %hu:%hu ", info->ports.rport[0], info->ports.rport[1]);
+}
+
+static struct xtables_target trigger_tg_reg = {
+ .name = "TRIGGER",
+ .version = XTABLES_VERSION,
+ .family = NFPROTO_IPV4,
+ .size = XT_ALIGN(sizeof(struct ipt_trigger_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct ipt_trigger_info)),
+ .help = TRIGGER_help,
+ .x6_parse = TRIGGER_parse,
+ .print = TRIGGER_print,
+ .save = TRIGGER_save,
+ .x6_options = TRIGGER_opts,
+};
+
+void _init(void)
+{
+ xtables_register_target(&trigger_tg_reg);
+}
diff --git a/package/network/utils/ipt_trigger/libipt_trigger/src/rules.make b/package/network/utils/ipt_trigger/libipt_trigger/src/rules.make
new file mode 100644
index 0000000..5ab965a
--- /dev/null
+++ b/package/network/utils/ipt_trigger/libipt_trigger/src/rules.make
@@ -0,0 +1,247 @@
+# main make rules for Marvell CM
+# this file is for generic linux. for Adnroid just see Android.mk makefiles
+
+#version -0.1
+#author - Chen Reichbach
+
+#for debug, remove this to see all compiler outputs.
+#MRVL_HIDE=@
+
+#general make rules
+#--------------------
+
+#compiler definisions
+ifneq "$(CROSS_COMPILE)" ""
+AS := $(CROSS_COMPILE)as
+CC := $(CROSS_COMPILE)gcc
+CPP := $(CROSS_COMPILE)c++
+AR := $(CROSS_COMPILE)ar rv
+LD := $(CROSS_COMPILE)ld
+STRIP := $(CROSS_COMPILE)strip
+RANLIB := $(CROSS_COMPILE)ranlib
+else
+#we do not have $(CROSS_COMPILE), assume compilers were passed by caller.
+echo "WARNING: did not get CROSS_COMPILE"
+endif
+
+#define base path for build objects
+ifeq "$(OBJ_DIR)" ""
+OBJ_DIR := $(BUILDROOT)/obj
+endif
+SYMBOLS_DIR := $(OBJ_DIR)/symbol
+#define base path for build outputs
+ifeq "$(INSTALL_DIR)" ""
+INSTALL_DIR := $(BUILDROOT)/out
+endif
+#usefull paths:
+PXA_SRC_DIR := $(BUILDROOT)
+PXA_APPS_DIR := $(BUILDROOT)
+PXA_SCRIPTS_DIR := $(BUILDROOT)/scripts
+PXA_CONFIG_DIR := $(BUILDROOT)/configuration
+PXA_PREPASS_DIR := $(PXA_APPS_DIR)/prepass
+PXA_TARGET_OLIB := $(OBJ_DIR)/olibs
+PXA_GENERATED_FILES_DIR := $(OBJ_DIR)/gendir
+
+#start off with flags from user and then add spesific flags
+COMMONCFLAGS := $(EXTRA_CFLAGS)
+
+#warnings flags
+WARNINGFLAG += -Waggregate-return -Wmissing-noreturn -W -Wall -Wextra \
+ -Winit-self -Wformat -Wformat-nonliteral -Wformat-security \
+ -Wmissing-declarations -Wpointer-arith
+#COMMONCFLAGS += $(WARNINGFLAG)
+
+#Other flags
+SHAREDOBJFLAGS := -shared -Wl,-shared,-Bsymbolic -Wl,--no-undefined
+
+# Always generate debug info. This is stripped from the executable files
+# in the final target image. The size of stripped image with and without -g
+# is the same, so code generation is not affected.
+#COMMONCFLAGS += -g
+
+# Enable optimization: default is very inefficient.
+#COMMONCFLAGS += -Os \
+# -fomit-frame-pointer \
+# -fno-strict-aliasing
+
+MRVL_COMMON_INCLUDE = -I$(PXA_APPS_DIR)/include
+
+PXA_LD_FLAGS = $(LD_FLAGS)
+PXA_LD_FLAGS += -L$(PXA_TARGET_OLIB) \
+ -L$(MRVLDIR)/services/android_wrapper/obj
+
+#start CFLAGS here
+CFLAGS:=
+CFLAGS += -DNOT_DROPPED_FLAGS_TEST
+
+not_droped_flags_test = \
+ echo '$(CFLAGS)' | grep -q NOT_DROPPED_FLAGS_TEST || \
+ (\
+ echo "@@================================================@@"&&\
+ echo NOT_DROPPED_FLAGS_TEST Failed &&\
+ echo It means that $@ file compiled with broken CFLAGS &&\
+ echo Please review related Makefile &&\
+ echo Note that original CFLAGS come from telephony main Makefile &&\
+ echo "@@================================================@@"&&\
+ exit 2 ;\
+ ) &&
+
+CFLAGS += $(COMMONCFLAGS)
+CFLAGS += $(MRVL_COMMON_INCLUDE)
+#temp flags to pass build without android
+CFLAGS += -DPROPERTY_VALUE_MAX=4 -DNAME_MAX=81
+
+# Bellow test_cmd_line Rule required for testing compiler lines to always happen
+# i.e. during every make run - we need to test per every object if his CMD line get changed
+.PHONY: test_cmd_line
+
+# Special rules for forceing linker to always run
+.PHONY: alwayslink
+
+# Rule for copy binary output and strip it from debug info.
+# $(1) - file to be copied
+# $(2) - relative path to output dir to copy to
+# Usage: $(call copy_elf,file,dir)
+#
+# copies file to <out>/symbols/dir
+# strips debug info from file and copies the product into <out>/dir
+# note the --strip-unneeded --discard-locals options are required otherwise
+# .ko produced have no symbols that are required for relocation and linkage with other .ko's
+copy_elf = $(call __copy_elf__,$(strip $(1)),$(strip $(2)))
+
+__copy_elf__ = \
+ $(MRVL_HIDE)echo '\033[1;35m'"Installing $(1)"'\033[0m' && \
+ mkdir -p $(SYMBOLS_DIR)/$(2) $(INSTALL_DIR)/$(2) && \
+ cp -f $(1) $(SYMBOLS_DIR)/$(2) && \
+ cp -f $(1) $(INSTALL_DIR)/$(2) && \
+ $(STRIP) --strip-unneeded --discard-locals $(INSTALL_DIR)/$(2)/$(notdir $(1)) ;
+
+#Rule for simple target clean
+# $(1) - binary to clean (dtarget)
+# $(2) - location in install dir
+clean_target = $(call __clean_target__, $(notdir $(1)), $(strip $(2)))
+
+__clean_target__ = \
+ $(MRVL_HIDE)echo '\033[1;35m'"cleaning $(1)"'\033[0m' && \
+ rm -rf $(SYMBOLS_DIR)/$(2)/$(1) && \
+ rm -rf $(INSTALL_DIR)/$(2)/$(1) && \
+ rm -rf $(LOCAL_BUILD_DIR);
+
+#
+## create generic rule for generation a local build directory.
+## $(1) - name of the local build directory.
+#
+define define-local-build-dir
+$(eval $(call __define-local-build-dir__,$(strip $(1))))
+endef
+
+define __define-local-build-dir__
+LOCAL_BUILD_DIR := $(OBJ_DIR)/$(1)
+$(OBJ_DIR)/$(1):
+ $(MRVL_HIDE)mkdir -p $(OBJ_DIR)/$(1)
+endef
+
+# Automatic Rules generator for any .c, .cpp, or .S files
+#
+# User required to define LOCAL_BUILD_DIR prior to calling this function
+# As well as defining rule for constructing LOCAL_BUILD_DIR
+# Input parameters:
+# $(1) - base name of "all results"
+# $(2) - Source file (.c|.cpp|.S)
+# $(3) - Extra CFLAGS for this file compilation
+#
+# Example with explanation:
+#### define directory where the compilation objects will be created
+# $(eval $(call define-local-build-dir, obj))
+#### Define final result - e.g. executable test_app
+# dtarget := test_app
+# all: $(dtarget)
+#### Call to virtual rule creator it will define per object
+#### rules and also fill
+#### test_app_oo with a list of $(LOCAL_BUILD_DIR)/<source_file_name>.o
+#### test_app_ii with a list of $(LOCAL_BUILD_DIR)/<source_file_name>.i (needed for Diag aware applications)
+#### test_app_dd with a list of $(LOCAL_BUILD_DIR)/<source_file_name>.d (for getting build dependencies)
+# $(eval $(call add-many-objects-rule, test_app , <source files separated by space (' ')>, -D<specific flags>,))
+# $(dtarget): $(test_app_ii) $(test_app_oo)
+# $(CC) -o $@ $(test_app_oo)
+### $(test_app_dd) is a dependency files which we include by Makefile
+# ifeq "$(filter clean install,$(MAKECMDGOALS))" ""
+# include $(test_app_dd)
+# endif
+#
+define add-many-objects-rule
+$(foreach i,$(strip $(2)),$(eval $(call __add-object-rule__,$(strip $(1)),$(i),$(strip $(3)),)))
+endef
+
+define __add-object-rule__
+ifeq "$(suffix $(2))" ".c"
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o.cmd) : $(2) test_cmd_line | $(LOCAL_BUILD_DIR)
+ @echo '$(CC) $(CFLAGS) $(3) -c -o $$(basename $$@).o $$<' | cmp -s - $$@ || \
+ echo '$(CC) $(CFLAGS) $(3) -c -o $$(basename $$@).o $$<' > $$@;
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o) : $(2) $(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o.cmd) | $(LOCAL_BUILD_DIR)
+ @echo " CC $$< "
+ $(MRVL_HIDE)$(not_droped_flags_test)$(CC) $(CFLAGS) $(3) -c -o $$@ $$<
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).i.cmd) : $(2) test_cmd_line | $(LOCAL_BUILD_DIR)
+ @echo '$(CC) $(CFLAGS) $(3) -C -E -o $$(basename $$@).i $$<' | cmp -s - $$@ || \
+ echo '$(CC) $(CFLAGS) $(3) -C -E -o $$(basename $$@).i $$<' > $$@
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).i) : $(2) $(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).i.cmd) | $(LOCAL_BUILD_DIR)
+ @echo " II $$@"
+ $(MRVL_HIDE)$(not_droped_flags_test)$(CC) $(CFLAGS) -DDIAG_API_H $(3) -C -E -o $$@ $$<
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).d) : $(2) | $(LOCAL_BUILD_DIR)
+ @echo " DD $$@"
+ $(MRVL_HIDE)set -e; rm -f $$@ 2>&- || true ;\
+ $(CC) -M $(CFLAGS) $(3) $$< > $$@.temp; \
+ awk '{gsub(/([^:]*:)/,"$$(@:.d=.o) $$(@:.d=.i) $$@ : ",$$$$0); print $$$$0}' > $$@ < $$@.temp ;\
+ rm $$@.temp 2>&- || true
+
+endif
+ifeq "$(suffix $(2))" ".cpp"
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o.cmd) : $(2) test_cmd_line | $(LOCAL_BUILD_DIR)
+ @echo '$(CPP) $(CFLAGS) $(3) -c -o $$(basename $$@).o $$<' | cmp -s - $$@ || \
+ echo '$(CPP) $(CFLAGS) $(3) -c -o $$(basename $$@).o $$<' > $$@
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o) : $(2) $(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o.cmd) | $(LOCAL_BUILD_DIR)
+ @echo " CPP $$<"
+ $(MRVL_HIDE)$(not_droped_flags_test)$(CPP) $(CFLAGS) $(3) -c -o $$@ $$<
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).i.cmd) : $(2) test_cmd_line | $(LOCAL_BUILD_DIR)
+ @echo '$(CPP) $(CFLAGS) $(3) -C -E -o $$(basename $$@).i $$<' | cmp -s - $$@ || \
+ echo '$(CPP) $(CFLAGS) $(3) -C -E -o $$(basename $$@).i $$<' > $$@
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).i) : $(2) $(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).i.cmd) | $(LOCAL_BUILD_DIR)
+ @echo " II $$@"
+ $(MRVL_HIDE)$(not_droped_flags_test)$(CPP) $(CFLAGS) -DDIAG_API_H $(3) -C -E -o $$@ $$<
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).d) : $(2) | $(LOCAL_BUILD_DIR)
+ @echo " DD $$@"
+ $(MRVL_HIDE)set -e; rm -f $$@ 2>&- || true ;\
+ $(CPP) -M $(CFLAGS) $(3) $$< > $$@.temp; \
+ awk '{gsub(/([^:]*:)/,"$$(@:.d=.o) $$(@:.d=.i) $$@ : ",$$$$0); print $$$$0}' > $$@ < $$@.temp ;\
+ rm $$@.temp 2>&- || true
+endif
+ifeq "$(suffix $(2))" ".S"
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o.cmd) : $(2) test_cmd_line | $(LOCAL_BUILD_DIR)
+ @echo '$(AS) $(AFLAGS) -o $$(basename $$@).i $$<' | cmp -s - $$@ || \
+ echo '$(AS) $(AFLAGS) -o $$(basename $$@).i $$<' > $$@
+
+$(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o) : $(2) $(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o.cmd) | $(LOCAL_BUILD_DIR)
+ @echo " AS $$<"
+ $(MRVL_HIDE)$(AS) $(AFLAGS) -o $$@ $$<
+endif
+
+$(1)_oo += $(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).o)
+##
+## No need to accumulate .i or .d files for assembler input
+##
+ifneq "$(suffix $(2))" ".S"
+$(1)_ii += $(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).i)
+$(1)_dd += $(LOCAL_BUILD_DIR)/$(notdir $(basename $(2)).d)
+endif
+
+endef
+#end Automatic Rules generator
diff --git a/package/network/utils/iptables/Makefile b/package/network/utils/iptables/Makefile
new file mode 100644
index 0000000..e8cbd5d
--- /dev/null
+++ b/package/network/utils/iptables/Makefile
@@ -0,0 +1,690 @@
+#
+# Copyright (C) 2006-2016 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=iptables
+PKG_VERSION:=1.8.7
+PKG_RELEASE:=2
+
+PKG_SOURCE_URL:=https://netfilter.org/projects/iptables/files
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_HASH:=c109c96bb04998cd44156622d36f8e04b140701ec60531a10668cfdff5e8d8f0
+
+PKG_FIXUP:=autoreconf
+PKG_FLAGS:=nonshared
+
+PKG_INSTALL:=1
+PKG_BUILD_FLAGS:=gc-sections no-lto
+PKG_BUILD_PARALLEL:=1
+PKG_LICENSE:=GPL-2.0
+PKG_CPE_ID:=cpe:/a:netfilter:iptables
+
+include $(INCLUDE_DIR)/package.mk
+ifeq ($(DUMP),)
+ -include $(LINUX_DIR)/.config
+ include $(INCLUDE_DIR)/netfilter.mk
+ STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell grep 'NETFILTER' $(LINUX_DIR)/.config | $(MKHASH) md5)
+endif
+
+
+define Package/iptables/Default
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Firewall
+ URL:=https://netfilter.org/
+endef
+
+define Package/iptables/Module
+$(call Package/iptables/Default)
+ DEPENDS:=iptables $(1)
+endef
+
+define Package/iptables
+$(call Package/iptables/Default)
+ TITLE:=IP firewall administration tool
+ MENU:=1
+ DEPENDS+= +(!MODULE_BUILDIN):kmod-ipt-core +libip4tc +IPV6:libip6tc +libxtables
+endef
+
+define Package/iptables/config
+ config IPTABLES_CONNLABEL
+ bool "Enable Connlabel support"
+ default n
+ help
+ This enable connlabel support in iptables.
+
+ config IPTABLES_NFTABLES
+ bool "Enable Nftables support"
+ default n
+ help
+ This enable nftables support in iptables.
+endef
+
+define Package/iptables/description
+IP firewall administration tool.
+
+ Matches:
+ - icmp
+ - tcp
+ - udp
+ - comment
+ - conntrack
+ - limit
+ - mac
+ - mark
+ - multiport
+ - set
+ - state
+ - time
+
+ Targets:
+ - ACCEPT
+ - CT
+ - DNAT
+ - DROP
+ - REJECT
+ - FLOWOFFLOAD
+ - LOG
+ - MARK
+ - MASQUERADE
+ - REDIRECT
+ - SET
+ - SNAT
+ - TCPMSS
+
+ Tables:
+ - filter
+ - mangle
+ - nat
+ - raw
+
+endef
+
+define Package/iptables-nft
+$(call Package/iptables/Default)
+ TITLE:=IP firewall administration tool nft
+ DEPENDS:=iptables @IPTABLES_NFTABLES +libxtables-nft
+endef
+
+define Package/iptables-nft/description
+Extra iptables nftables nft binaries.
+ iptables-nft
+ iptables-nft-restore
+ iptables-nft-save
+ iptables-translate
+ iptables-restore-translate
+endef
+
+define Package/iptables-mod-conntrack-extra
+$(call Package/iptables/Module, +kmod-ipt-conntrack-extra +kmod-ipt-raw)
+ TITLE:=Extra connection tracking extensions
+endef
+
+define Package/iptables-mod-conntrack-extra/description
+Extra iptables extensions for connection tracking.
+
+ Matches:
+ - connbytes
+ - connlimit
+ - connmark
+ - recent
+ - helper
+
+ Targets:
+ - CONNMARK
+
+endef
+
+define Package/iptables-mod-conntrack-label
+$(call Package/iptables/Module, +kmod-ipt-conntrack-label @IPTABLES_CONNLABEL)
+ TITLE:=Connection tracking labeling extension
+ DEFAULT:=y if IPTABLES_CONNLABEL
+endef
+
+define Package/iptables-mod-conntrack-label/description
+Match and set label(s) on connection tracking entries
+
+ Matches:
+ - connlabel
+
+endef
+
+define Package/iptables-mod-filter
+$(call Package/iptables/Module, +kmod-ipt-filter)
+ TITLE:=Content inspection extensions
+endef
+
+define Package/iptables-mod-filter/description
+iptables extensions for packet content inspection.
+Includes support for:
+
+ Matches:
+ - string
+ - bpf
+
+endef
+
+define Package/iptables-mod-ipopt
+$(call Package/iptables/Module, +(!MODULE_BUILDIN):kmod-ipt-ipopt)
+ TITLE:=IP/Packet option extensions
+endef
+
+define Package/iptables-mod-ipopt/description
+iptables extensions for matching/changing IP packet options.
+
+ Matches:
+ - dscp
+ - ecn
+ - length
+ - statistic
+ - tcpmss
+ - unclean
+ - hl
+
+ Targets:
+ - DSCP
+ - CLASSIFY
+ - ECN
+ - HL
+
+endef
+
+define Package/iptables-mod-ipsec
+$(call Package/iptables/Module, +kmod-ipt-ipsec)
+ TITLE:=IPsec extensions
+endef
+
+define Package/iptables-mod-ipsec/description
+iptables extensions for matching ipsec traffic.
+
+ Matches:
+ - ah
+ - esp
+ - policy
+
+endef
+
+define Package/iptables-mod-nat-extra
+$(call Package/iptables/Module, +kmod-ipt-nat-extra)
+ TITLE:=Extra NAT extensions
+endef
+
+define Package/iptables-mod-nat-extra/description
+iptables extensions for extra NAT targets.
+
+ Targets:
+ - MIRROR
+ - NETMAP
+endef
+
+define Package/iptables-mod-nflog
+$(call Package/iptables/Module, +kmod-nfnetlink-log +kmod-ipt-nflog)
+ TITLE:=Netfilter NFLOG target
+endef
+
+define Package/iptables-mod-nflog/description
+ iptables extension for user-space logging via NFNETLINK.
+
+ Includes:
+ - libxt_NFLOG
+
+endef
+
+define Package/iptables-mod-trace
+$(call Package/iptables/Module, +kmod-ipt-debug)
+ TITLE:=Netfilter TRACE target
+endef
+
+define Package/iptables-mod-trace/description
+ iptables extension for TRACE target
+
+ Includes:
+ - libxt_TRACE
+
+endef
+
+
+define Package/iptables-mod-nfqueue
+$(call Package/iptables/Module, +kmod-nfnetlink-queue +kmod-ipt-nfqueue)
+ TITLE:=Netfilter NFQUEUE target
+endef
+
+define Package/iptables-mod-nfqueue/description
+ iptables extension for user-space queuing via NFNETLINK.
+
+ Includes:
+ - libxt_NFQUEUE
+
+endef
+
+define Package/iptables-mod-hashlimit
+$(call Package/iptables/Module, +kmod-ipt-hashlimit)
+ TITLE:=hashlimit matching
+endef
+
+define Package/iptables-mod-hashlimit/description
+iptables extensions for hashlimit matching
+
+ Matches:
+ - hashlimit
+
+endef
+
+define Package/iptables-mod-rpfilter
+$(call Package/iptables/Module, +kmod-ipt-rpfilter)
+ TITLE:=rpfilter iptables extension
+endef
+
+define Package/iptables-mod-rpfilter/description
+iptables extensions for reverse path filter test on a packet
+
+ Matches:
+ - rpfilter
+
+endef
+
+define Package/iptables-mod-iprange
+$(call Package/iptables/Module, +kmod-ipt-iprange)
+ TITLE:=IP range extension
+endef
+
+define Package/iptables-mod-iprange/description
+iptables extensions for matching ip ranges.
+
+ Matches:
+ - iprange
+
+endef
+
+define Package/iptables-mod-cluster
+$(call Package/iptables/Module, +kmod-ipt-cluster)
+ TITLE:=Match cluster extension
+endef
+
+define Package/iptables-mod-cluster/description
+iptables extensions for matching cluster.
+
+ Netfilter (IPv4/IPv6) module for matching cluster
+ This option allows you to build work-load-sharing clusters of
+ network servers/stateful firewalls without having a dedicated
+ load-balancing router/server/switch. Basically, this match returns
+ true when the packet must be handled by this cluster node. Thus,
+ all nodes see all packets and this match decides which node handles
+ what packets. The work-load sharing algorithm is based on source
+ address hashing.
+
+ This module is usable for ipv4 and ipv6.
+
+ If you select it, it enables kmod-ipt-cluster.
+
+ see `iptables -m cluster --help` for more information.
+endef
+
+define Package/iptables-mod-clusterip
+$(call Package/iptables/Module, +kmod-ipt-clusterip)
+ TITLE:=Clusterip extension
+endef
+
+define Package/iptables-mod-clusterip/description
+iptables extensions for CLUSTERIP.
+ The CLUSTERIP target allows you to build load-balancing clusters of
+ network servers without having a dedicated load-balancing
+ router/server/switch.
+
+ If you select it, it enables kmod-ipt-clusterip.
+
+ see `iptables -j CLUSTERIP --help` for more information.
+endef
+
+define Package/iptables-mod-extra
+$(call Package/iptables/Module, +kmod-ipt-extra)
+ TITLE:=Other extra iptables extensions
+endef
+
+define Package/iptables-mod-extra/description
+Other extra iptables extensions.
+
+ Matches:
+ - addrtype
+ - condition
+ - owner
+ - pkttype
+ - quota
+
+endef
+
+define Package/iptables-mod-physdev
+$(call Package/iptables/Module, +kmod-ipt-physdev)
+ TITLE:=physdev iptables extension
+endef
+
+define Package/iptables-mod-physdev/description
+The iptables physdev match.
+endef
+
+define Package/iptables-mod-led
+$(call Package/iptables/Module, +kmod-ipt-led)
+ TITLE:=LED trigger iptables extension
+endef
+
+define Package/iptables-mod-led/description
+iptables extension for triggering a LED.
+
+ Targets:
+ - LED
+
+endef
+
+define Package/iptables-mod-socket
+$(call Package/iptables/Module, +kmod-ipt-socket)
+ TITLE:=Socket match iptables extensions
+endef
+
+define Package/iptables-mod-socket/description
+Socket match iptables extensions.
+
+ Matches:
+ - socket
+
+endef
+
+define Package/iptables-mod-tproxy
+$(call Package/iptables/Module, +kmod-ipt-tproxy)
+ TITLE:=Transparent proxy iptables extensions
+endef
+
+define Package/iptables-mod-tproxy/description
+Transparent proxy iptables extensions.
+
+ Targets:
+ - TPROXY
+
+endef
+
+define Package/iptables-mod-tee
+$(call Package/iptables/Module, +kmod-ipt-tee)
+ TITLE:=TEE iptables extensions
+endef
+
+define Package/iptables-mod-tee/description
+TEE iptables extensions.
+
+ Targets:
+ - TEE
+
+endef
+
+define Package/iptables-mod-u32
+$(call Package/iptables/Module, +kmod-ipt-u32)
+ TITLE:=U32 iptables extensions
+endef
+
+define Package/iptables-mod-u32/description
+U32 iptables extensions.
+
+ Matches:
+ - u32
+
+endef
+
+define Package/iptables-mod-checksum
+$(call Package/iptables/Module, +kmod-ipt-checksum)
+ TITLE:=IP CHECKSUM target extension
+endef
+
+define Package/iptables-mod-checksum/description
+iptables extension for the CHECKSUM calculation target
+endef
+
+define Package/ip6tables
+$(call Package/iptables/Default)
+ DEPENDS:=@IPV6 +(!MODULE_BUILDIN):kmod-ip6tables +iptables
+ CATEGORY:=Network
+ TITLE:=IPv6 firewall administration tool
+ MENU:=1
+endef
+
+define Package/ip6tables-nft
+$(call Package/iptables/Default)
+ DEPENDS:=ip6tables @IPTABLES_NFTABLES +libxtables-nft
+ TITLE:=IP firewall administration tool nft
+endef
+
+define Package/ip6tables-nft/description
+Extra ip6tables nftables nft binaries.
+ iptables-nft
+ iptables-nft-restore
+ iptables-nft-save
+ iptables-translate
+ iptables-restore-translate
+endef
+
+define Package/ip6tables-extra
+$(call Package/iptables/Default)
+ DEPENDS:=ip6tables +kmod-ip6tables-extra
+ TITLE:=IPv6 header matching modules
+endef
+
+define Package/ip6tables-mod-extra/description
+iptables header matching modules for IPv6
+endef
+
+define Package/ip6tables-mod-nat
+$(call Package/iptables/Default)
+ DEPENDS:=ip6tables +kmod-ipt-nat6
+ TITLE:=IPv6 NAT extensions
+endef
+
+define Package/ip6tables-mod-nat/description
+iptables extensions for IPv6-NAT targets.
+endef
+
+define Package/libip4tc
+$(call Package/iptables/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=IPv4 firewall - shared libiptc library
+ ABI_VERSION:=2
+ DEPENDS:=+libxtables
+endef
+
+define Package/libip6tc
+$(call Package/iptables/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=IPv6 firewall - shared libiptc library
+ ABI_VERSION:=2
+ DEPENDS:=+libxtables
+endef
+
+define Package/libxtables
+ $(call Package/iptables/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=IPv4/IPv6 firewall - shared xtables library
+ ABI_VERSION:=12
+ DEPENDS:= \
+ +IPTABLES_CONNLABEL:libnetfilter-conntrack \
+ +IPTABLES_NFTABLES:libnftnl
+endef
+
+define Package/libxtables-nft
+ $(call Package/iptables/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=IPv4/IPv6 firewall - shared xtables nft library
+ ABI_VERSION:=12
+ DEPENDS:=libxtables
+endef
+
+TARGET_CPPFLAGS := \
+ -I$(PKG_BUILD_DIR)/include \
+ -I$(LINUX_DIR)/user_headers/include \
+ $(TARGET_CPPFLAGS)
+
+TARGET_CFLAGS += \
+ -I$(PKG_BUILD_DIR)/include \
+ -I$(LINUX_DIR)/user_headers/include \
+ -ffunction-sections -fdata-sections \
+ -DNO_LEGACY
+
+TARGET_LDFLAGS += \
+ -Wl,--gc-sections
+
+CONFIGURE_ARGS += \
+ --enable-shared \
+ --enable-static \
+ --enable-devel \
+ --with-kernel="$(LINUX_DIR)/user_headers" \
+ --with-xtlibdir=/usr/lib/iptables \
+ --with-xt-lock-name=/var/run/xtables.lock \
+ $(if $(CONFIG_IPTABLES_CONNLABEL),,--disable-connlabel) \
+ $(if $(CONFIG_IPTABLES_NFTABLES),,--disable-nftables) \
+ $(if $(CONFIG_IPV6),,--disable-ipv6)
+
+MAKE_FLAGS := \
+ $(TARGET_CONFIGURE_OPTS) \
+ COPT_FLAGS="$(TARGET_CFLAGS)" \
+ KERNEL_DIR="$(LINUX_DIR)/user_headers/" PREFIX=/usr \
+ KBUILD_OUTPUT="$(LINUX_DIR)" \
+ BUILTIN_MODULES="$(patsubst ip6t_%,%,$(patsubst ipt_%,%,$(patsubst xt_%,%,$(IPT_BUILTIN) $(IPT_CONNTRACK-m) $(IPT_NAT-m))))"
+
+ifneq ($(wildcard $(PKG_BUILD_DIR)/.config_*),$(subst .configured_,.config_,$(STAMP_CONFIGURED)))
+ define Build/Configure/rebuild
+ $(FIND) $(PKG_BUILD_DIR) -name \*.o -or -name \*.\?o -or -name \*.a | $(XARGS) rm -f
+ rm -f $(PKG_BUILD_DIR)/.config_*
+ rm -f $(PKG_BUILD_DIR)/.configured_*
+ touch $(subst .configured_,.config_,$(STAMP_CONFIGURED))
+ endef
+endif
+
+define Build/Configure
+$(Build/Configure/rebuild)
+$(Build/Configure/Default)
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(INSTALL_DIR) $(1)/usr/include/iptables
+ $(INSTALL_DIR) $(1)/usr/include/net/netfilter
+
+ # XXX: iptables header fixup, some headers are not installed by iptables anymore
+ $(CP) $(PKG_BUILD_DIR)/include/iptables/*.h $(1)/usr/include/iptables/
+ $(CP) $(PKG_BUILD_DIR)/include/iptables.h $(1)/usr/include/
+ $(CP) $(PKG_BUILD_DIR)/include/ip6tables.h $(1)/usr/include/
+ $(CP) $(PKG_BUILD_DIR)/include/libipulog $(1)/usr/include/
+ $(CP) $(PKG_BUILD_DIR)/include/libiptc $(1)/usr/include/
+
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libxtables.so* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libip*tc.so* $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/xtables.pc $(1)/usr/lib/pkgconfig/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libip*tc.pc $(1)/usr/lib/pkgconfig/
+
+ # XXX: needed by firewall3
+ $(CP) $(PKG_BUILD_DIR)/extensions/libiptext*.so $(1)/usr/lib/
+endef
+
+define Package/iptables/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/xtables-legacy-multi $(1)/usr/sbin/
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/iptables{,-restore,-save} $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/usr/lib/iptables
+endef
+
+define Package/iptables-nft/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/xtables-nft-multi $(1)/usr/sbin/
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/iptables-nft{,-restore,-save} $(1)/usr/sbin/
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/iptables{,-restore}-translate $(1)/usr/sbin/
+endef
+
+define Package/ip6tables/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/ip6tables{,-restore,-save} $(1)/usr/sbin/
+endef
+
+define Package/ip6tables-nft/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/ip6tables-nft{,-restore,-save} $(1)/usr/sbin/
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/ip6tables{,-restore}-translate $(1)/usr/sbin/
+endef
+
+define Package/libip4tc/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libip4tc.so.* $(1)/usr/lib/
+ $(CP) $(PKG_BUILD_DIR)/extensions/libiptext4.so $(1)/usr/lib/
+endef
+
+define Package/libip6tc/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libip6tc.so.* $(1)/usr/lib/
+ $(CP) $(PKG_BUILD_DIR)/extensions/libiptext6.so $(1)/usr/lib/
+endef
+
+define Package/libxtables/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libxtables.so.* $(1)/usr/lib/
+ $(CP) $(PKG_BUILD_DIR)/extensions/libiptext.so $(1)/usr/lib/
+endef
+
+define Package/libxtables-nft/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/extensions/libiptext_*.so $(1)/usr/lib/
+endef
+
+define BuildPlugin
+ define Package/$(1)/install
+ $(INSTALL_DIR) $$(1)/usr/lib/iptables
+ for m in $(patsubst xt_%,ipt_%,$(2)) $(patsubst ipt_%,xt_%,$(2)) $(patsubst xt_%,ip6t_%,$(2)) $(patsubst ip6t_%,xt_%,$(2)); do \
+ if [ -f $(PKG_INSTALL_DIR)/usr/lib/iptables/lib$$$$$$$${m}.so ]; then \
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/iptables/lib$$$$$$$${m}.so $$(1)/usr/lib/iptables/ ; \
+ fi; \
+ done
+ $(3)
+ endef
+
+ $$(eval $$(call BuildPackage,$(1)))
+endef
+
+$(eval $(call BuildPackage,libxtables))
+$(eval $(call BuildPackage,libxtables-nft))
+$(eval $(call BuildPackage,libip4tc))
+$(eval $(call BuildPackage,libip6tc))
+$(eval $(call BuildPackage,iptables))
+$(eval $(call BuildPackage,iptables-nft))
+$(eval $(call BuildPlugin,iptables-mod-conntrack-extra,$(IPT_CONNTRACK_EXTRA-m)))
+$(eval $(call BuildPlugin,iptables-mod-conntrack-label,$(IPT_CONNTRACK_LABEL-m)))
+$(eval $(call BuildPlugin,iptables-mod-extra,$(IPT_EXTRA-m)))
+$(eval $(call BuildPlugin,iptables-mod-physdev,$(IPT_PHYSDEV-m)))
+$(eval $(call BuildPlugin,iptables-mod-filter,$(IPT_FILTER-m)))
+$(eval $(call BuildPlugin,iptables-mod-ipopt,$(IPT_IPOPT-m)))
+$(eval $(call BuildPlugin,iptables-mod-ipsec,$(IPT_IPSEC-m)))
+$(eval $(call BuildPlugin,iptables-mod-nat-extra,$(IPT_NAT_EXTRA-m)))
+$(eval $(call BuildPlugin,iptables-mod-iprange,$(IPT_IPRANGE-m)))
+$(eval $(call BuildPlugin,iptables-mod-cluster,$(IPT_CLUSTER-m)))
+$(eval $(call BuildPlugin,iptables-mod-clusterip,$(IPT_CLUSTERIP-m)))
+$(eval $(call BuildPlugin,iptables-mod-hashlimit,$(IPT_HASHLIMIT-m)))
+$(eval $(call BuildPlugin,iptables-mod-rpfilter,$(IPT_RPFILTER-m)))
+$(eval $(call BuildPlugin,iptables-mod-led,$(IPT_LED-m)))
+$(eval $(call BuildPlugin,iptables-mod-socket,$(IPT_SOCKET-m)))
+$(eval $(call BuildPlugin,iptables-mod-tproxy,$(IPT_TPROXY-m)))
+$(eval $(call BuildPlugin,iptables-mod-tee,$(IPT_TEE-m)))
+$(eval $(call BuildPlugin,iptables-mod-u32,$(IPT_U32-m)))
+$(eval $(call BuildPlugin,iptables-mod-nflog,$(IPT_NFLOG-m)))
+$(eval $(call BuildPlugin,iptables-mod-trace,$(IPT_DEBUG-m)))
+$(eval $(call BuildPlugin,iptables-mod-nfqueue,$(IPT_NFQUEUE-m)))
+$(eval $(call BuildPlugin,iptables-mod-checksum,$(IPT_CHECKSUM-m)))
+$(eval $(call BuildPackage,ip6tables))
+$(eval $(call BuildPackage,ip6tables-nft))
+$(eval $(call BuildPlugin,ip6tables-extra,$(IPT_IPV6_EXTRA-m)))
+$(eval $(call BuildPlugin,ip6tables-mod-nat,$(IPT_NAT6-m)))
+
diff --git a/package/network/utils/iptables/patches/010-add-set-dscpmark-support.patch b/package/network/utils/iptables/patches/010-add-set-dscpmark-support.patch
new file mode 100644
index 0000000..9a5de63
--- /dev/null
+++ b/package/network/utils/iptables/patches/010-add-set-dscpmark-support.patch
@@ -0,0 +1,452 @@
+From 74267bacce0c43e5038b0377cb7c08f1ad9d50a3 Mon Sep 17 00:00:00 2001
+From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+Date: Sat, 23 Mar 2019 10:21:03 +0000
+Subject: [PATCH] iptables: connmark - add set-dscpmark option for openwrt
+
+Naive user space front end to xt_connmark 'setdscp' option.
+
+iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000
+
+This version has a hack to support a backport to 4.14
+
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+---
+ extensions/libxt_CONNMARK.c | 315 +++++++++++++++++++++++++-
+ include/linux/netfilter/xt_connmark.h | 10 +
+ 2 files changed, 324 insertions(+), 1 deletion(-)
+
+--- a/extensions/libxt_CONNMARK.c
++++ b/extensions/libxt_CONNMARK.c
+@@ -22,6 +22,7 @@
+ #include <stdbool.h>
+ #include <stdint.h>
+ #include <stdio.h>
++#include <strings.h>
+ #include <xtables.h>
+ #include <linux/netfilter/xt_CONNMARK.h>
+
+@@ -49,6 +50,7 @@ enum {
+ O_CTMASK,
+ O_NFMASK,
+ O_MASK,
++ O_DSCP_MARK,
+ F_SET_MARK = 1 << O_SET_MARK,
+ F_SAVE_MARK = 1 << O_SAVE_MARK,
+ F_RESTORE_MARK = 1 << O_RESTORE_MARK,
+@@ -61,8 +63,10 @@ enum {
+ F_CTMASK = 1 << O_CTMASK,
+ F_NFMASK = 1 << O_NFMASK,
+ F_MASK = 1 << O_MASK,
++ F_DSCP_MARK = 1 << O_DSCP_MARK,
+ F_OP_ANY = F_SET_MARK | F_SAVE_MARK | F_RESTORE_MARK |
+- F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK,
++ F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK |
++ F_DSCP_MARK,
+ };
+
+ static const char *const xt_connmark_shift_ops[] = {
+@@ -114,6 +118,8 @@ static const struct xt_option_entry conn
+ .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, nfmask)},
+ {.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32,
+ .excl = F_CTMASK | F_NFMASK},
++ {.name = "set-dscpmark", .id = O_DSCP_MARK, .type = XTTYPE_MARKMASK32,
++ .excl = F_OP_ANY},
+ XTOPT_TABLEEND,
+ };
+ #undef s
+@@ -148,6 +154,38 @@ static const struct xt_option_entry conn
+ };
+ #undef s
+
++#define s struct xt_connmark_tginfo3
++static const struct xt_option_entry connmark_tg_opts_v3[] = {
++ {.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
++ .excl = F_OP_ANY},
++ {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
++ .excl = F_OP_ANY},
++ {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
++ .excl = F_OP_ANY},
++ {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
++ .excl = F_OP_ANY},
++ {.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
++ .excl = F_OP_ANY},
++ {.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE,
++ .excl = F_OP_ANY},
++ {.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
++ .excl = F_OP_ANY},
++ {.name = "left-shift-mark", .id = O_LEFT_SHIFT_MARK, .type = XTTYPE_UINT8,
++ .min = 0, .max = 32},
++ {.name = "right-shift-mark", .id = O_RIGHT_SHIFT_MARK, .type = XTTYPE_UINT8,
++ .min = 0, .max = 32},
++ {.name = "ctmask", .id = O_CTMASK, .type = XTTYPE_UINT32,
++ .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, ctmask)},
++ {.name = "nfmask", .id = O_NFMASK, .type = XTTYPE_UINT32,
++ .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, nfmask)},
++ {.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32,
++ .excl = F_CTMASK | F_NFMASK},
++ {.name = "set-dscpmark", .id = O_DSCP_MARK, .type = XTTYPE_MARKMASK32,
++ .excl = F_OP_ANY},
++ XTOPT_TABLEEND,
++};
++#undef s
++
+ static void connmark_tg_help(void)
+ {
+ printf(
+@@ -175,6 +213,15 @@ static void connmark_tg_help_v2(void)
+ );
+ }
+
++static void connmark_tg_help_v3(void)
++{
++ connmark_tg_help_v2();
++ printf(
++" --set-dscpmark value/mask Save DSCP to conntrack mark value\n"
++);
++}
++
++
+ static void connmark_tg_init(struct xt_entry_target *target)
+ {
+ struct xt_connmark_tginfo1 *info = (void *)target->data;
+@@ -199,6 +246,16 @@ static void connmark_tg_init_v2(struct x
+ info->shift_bits = 0;
+ }
+
++static void connmark_tg_init_v3(struct xt_entry_target *target)
++{
++ struct xt_connmark_tginfo3 *info;
++
++ connmark_tg_init_v2(target);
++ info = (void *)target->data;
++
++ info->func = 0;
++}
++
+ static void CONNMARK_parse(struct xt_option_call *cb)
+ {
+ struct xt_connmark_target_info *markinfo = cb->data;
+@@ -253,6 +310,23 @@ static void connmark_tg_parse(struct xt_
+ info->ctmark = cb->val.u32;
+ info->ctmask = 0;
+ break;
++ case O_DSCP_MARK:
++/* we sneaky sneaky this. nfmask isn't used by the set mark functionality
++ * and by default is set to uint32max. We can use the top bit as a flag
++ * that we're in DSCP_MARK submode of SET_MARK, if set then it's normal
++ * if unset then we're in DSCP_MARK
++ */
++ info->mode = XT_CONNMARK_SET;
++ info->ctmark = cb->val.mark;
++ info->ctmask = cb->val.mask;
++ info->nfmask = info->ctmark ? ffs(info->ctmark) - 1 : 0;
++ /* need 6 contiguous bits */
++ if ((~0 & (info->ctmark >> info->nfmask)) != 0x3f)
++ xtables_error(PARAMETER_PROBLEM,
++ "CONNMARK set-dscpmark: need 6 contiguous dscpmask bits");
++ if (info->ctmark & info->ctmask)
++ xtables_error(PARAMETER_PROBLEM,
++ "CONNMARK set-dscpmark: dscpmask/statemask bits overlap");
+ case O_SAVE_MARK:
+ info->mode = XT_CONNMARK_SAVE;
+ break;
+@@ -320,6 +394,78 @@ static void connmark_tg_parse_v2(struct
+ }
+ }
+
++static void connmark_tg_parse_v3(struct xt_option_call *cb)
++{
++ struct xt_connmark_tginfo3 *info = cb->data;
++
++ xtables_option_parse(cb);
++ switch (cb->entry->id) {
++ case O_SET_XMARK:
++ info->mode = XT_CONNMARK_SET;
++ info->func = XT_CONNMARK_VALUE;
++ info->ctmark = cb->val.mark;
++ info->ctmask = cb->val.mask;
++ break;
++ case O_SET_MARK:
++ info->mode = XT_CONNMARK_SET;
++ info->func = XT_CONNMARK_VALUE;
++ info->ctmark = cb->val.mark;
++ info->ctmask = cb->val.mark | cb->val.mask;
++ break;
++ case O_AND_MARK:
++ info->mode = XT_CONNMARK_SET;
++ info->func = XT_CONNMARK_VALUE;
++ info->ctmark = 0;
++ info->ctmask = ~cb->val.u32;
++ break;
++ case O_OR_MARK:
++ info->mode = XT_CONNMARK_SET;
++ info->func = XT_CONNMARK_VALUE;
++ info->ctmark = cb->val.u32;
++ info->ctmask = cb->val.u32;
++ break;
++ case O_XOR_MARK:
++ info->mode = XT_CONNMARK_SET;
++ info->func = XT_CONNMARK_VALUE;
++ info->ctmark = cb->val.u32;
++ info->ctmask = 0;
++ break;
++ case O_DSCP_MARK:
++ info->mode = XT_CONNMARK_SET;
++ info->func = XT_CONNMARK_DSCP;
++ info->ctmark = cb->val.mark;
++ info->ctmask = cb->val.mask;
++ info->shift_bits = info->ctmark ? ffs(info->ctmark) - 1 : 0;
++ /* need 6 contiguous bits */
++ if ((~0 & (info->ctmark >> info->shift_bits)) != 0x3f)
++ xtables_error(PARAMETER_PROBLEM,
++ "CONNMARK set-dscpmark: need 6 contiguous dscpmask bits");
++ if (info->ctmark & info->ctmask)
++ xtables_error(PARAMETER_PROBLEM,
++ "CONNMARK set-dscpmark: dscpmask/statemask bits overlap");
++ break;
++ case O_SAVE_MARK:
++ info->mode = XT_CONNMARK_SAVE;
++ break;
++ case O_RESTORE_MARK:
++ info->mode = XT_CONNMARK_RESTORE;
++ break;
++ case O_MASK:
++ info->nfmask = info->ctmask = cb->val.u32;
++ break;
++ case O_LEFT_SHIFT_MARK:
++ info->shift_dir = D_SHIFT_LEFT;
++ info->shift_bits = cb->val.u8;
++ break;
++ case O_RIGHT_SHIFT_MARK:
++ info->shift_dir = D_SHIFT_RIGHT;
++ info->shift_bits = cb->val.u8;
++ break;
++ default:
++ break;
++ }
++}
++
+ static void connmark_tg_check(struct xt_fcheck_call *cb)
+ {
+ if (!(cb->xflags & F_OP_ANY))
+@@ -463,6 +609,65 @@ connmark_tg_print_v2(const void *ip, con
+ }
+ }
+
++static void
++connmark_tg_print_v3(const void *ip, const struct xt_entry_target *target,
++ int numeric)
++{
++ const struct xt_connmark_tginfo3 *info = (const void *)target->data;
++ const char *shift_op = xt_connmark_shift_ops[info->shift_dir];
++
++ switch (info->mode) {
++ case XT_CONNMARK_SET:
++ if (info->func & XT_CONNMARK_DSCP) {
++ printf(" CONNMARK DSCP 0x%x/0x%x",
++ info->ctmark, info->ctmask);
++ }
++ if (info->func & XT_CONNMARK_VALUE) {
++ if (info->ctmark == 0)
++ printf(" CONNMARK and 0x%x",
++ (unsigned int)(uint32_t)~info->ctmask);
++ else if (info->ctmark == info->ctmask)
++ printf(" CONNMARK or 0x%x", info->ctmark);
++ else if (info->ctmask == 0)
++ printf(" CONNMARK xor 0x%x", info->ctmark);
++ else if (info->ctmask == 0xFFFFFFFFU)
++ printf(" CONNMARK set 0x%x", info->ctmark);
++ else
++ printf(" CONNMARK xset 0x%x/0x%x",
++ info->ctmark, info->ctmask);
++ }
++ break;
++ case XT_CONNMARK_SAVE:
++ if (info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX)
++ printf(" CONNMARK save");
++ else if (info->nfmask == info->ctmask)
++ printf(" CONNMARK save mask 0x%x", info->nfmask);
++ else
++ printf(" CONNMARK save nfmask 0x%x ctmask ~0x%x",
++ info->nfmask, info->ctmask);
++ break;
++ case XT_CONNMARK_RESTORE:
++ if (info->ctmask == UINT32_MAX && info->nfmask == UINT32_MAX)
++ printf(" CONNMARK restore");
++ else if (info->ctmask == info->nfmask)
++ printf(" CONNMARK restore mask 0x%x", info->ctmask);
++ else
++ printf(" CONNMARK restore ctmask 0x%x nfmask ~0x%x",
++ info->ctmask, info->nfmask);
++ break;
++
++ default:
++ printf(" ERROR: UNKNOWN CONNMARK MODE");
++ break;
++ }
++
++ if (info->mode <= XT_CONNMARK_RESTORE &&
++ !(info->mode == XT_CONNMARK_SET && info->func == XT_CONNMARK_DSCP) &&
++ info->shift_bits != 0) {
++ printf(" %s %u", shift_op, info->shift_bits);
++ }
++}
++
+ static void CONNMARK_save(const void *ip, const struct xt_entry_target *target)
+ {
+ const struct xt_connmark_target_info *markinfo =
+@@ -548,6 +753,38 @@ connmark_tg_save_v2(const void *ip, cons
+ }
+ }
+
++static void
++connmark_tg_save_v3(const void *ip, const struct xt_entry_target *target)
++{
++ const struct xt_connmark_tginfo3 *info = (const void *)target->data;
++ const char *shift_op = xt_connmark_shift_ops[info->shift_dir];
++
++ switch (info->mode) {
++ case XT_CONNMARK_SET:
++ if (info->func & XT_CONNMARK_VALUE)
++ printf(" --set-xmark 0x%x/0x%x", info->ctmark, info->ctmask);
++ if (info->func & XT_CONNMARK_DSCP)
++ printf(" --set-dscpmark 0x%x/0x%x", info->ctmark, info->ctmask);
++ break;
++ case XT_CONNMARK_SAVE:
++ printf(" --save-mark --nfmask 0x%x --ctmask 0x%x",
++ info->nfmask, info->ctmask);
++ break;
++ case XT_CONNMARK_RESTORE:
++ printf(" --restore-mark --nfmask 0x%x --ctmask 0x%x",
++ info->nfmask, info->ctmask);
++ break;
++ default:
++ printf(" ERROR: UNKNOWN CONNMARK MODE");
++ break;
++ }
++ if (info->mode <= XT_CONNMARK_RESTORE &&
++ !(info->mode == XT_CONNMARK_SET && info->func == XT_CONNMARK_DSCP) &&
++ info->shift_bits != 0) {
++ printf(" --%s %u", shift_op, info->shift_bits);
++ }
++}
++
+ static int connmark_tg_xlate(struct xt_xlate *xl,
+ const struct xt_xlate_tg_params *params)
+ {
+@@ -639,6 +876,66 @@ static int connmark_tg_xlate_v2(struct x
+
+ return 1;
+ }
++
++static int connmark_tg_xlate_v3(struct xt_xlate *xl,
++ const struct xt_xlate_tg_params *params)
++{
++ const struct xt_connmark_tginfo3 *info =
++ (const void *)params->target->data;
++ const char *shift_op = xt_connmark_shift_ops[info->shift_dir];
++
++ switch (info->mode) {
++ case XT_CONNMARK_SET:
++ xt_xlate_add(xl, "ct mark set ");
++ if (info->func & XT_CONNMARK_VALUE) {
++ if (info->ctmask == 0xFFFFFFFFU)
++ xt_xlate_add(xl, "0x%x ", info->ctmark);
++ else if (info->ctmark == 0)
++ xt_xlate_add(xl, "ct mark and 0x%x", ~info->ctmask);
++ else if (info->ctmark == info->ctmask)
++ xt_xlate_add(xl, "ct mark or 0x%x",
++ info->ctmark);
++ else if (info->ctmask == 0)
++ xt_xlate_add(xl, "ct mark xor 0x%x",
++ info->ctmark);
++ else
++ xt_xlate_add(xl, "ct mark xor 0x%x and 0x%x",
++ info->ctmark, ~info->ctmask);
++ }
++ if (info->func & XT_CONNMARK_DSCP) {
++/* FIXME the nftables syntax would go here if only we knew what it was */
++ xt_xlate_add(xl, "ct mark set typeof(ct mark) ip dscp "
++ "<< %u or 0x%x", info->shift_bits,
++ info->ctmask);
++ }
++ break;
++ case XT_CONNMARK_SAVE:
++ xt_xlate_add(xl, "ct mark set mark");
++ if (!(info->nfmask == UINT32_MAX &&
++ info->ctmask == UINT32_MAX)) {
++ if (info->nfmask == info->ctmask)
++ xt_xlate_add(xl, " and 0x%x", info->nfmask);
++ }
++ break;
++ case XT_CONNMARK_RESTORE:
++ xt_xlate_add(xl, "meta mark set ct mark");
++ if (!(info->nfmask == UINT32_MAX &&
++ info->ctmask == UINT32_MAX)) {
++ if (info->nfmask == info->ctmask)
++ xt_xlate_add(xl, " and 0x%x", info->nfmask);
++ }
++ break;
++ }
++
++ if (info->mode <= XT_CONNMARK_RESTORE &&
++ !(info->mode == XT_CONNMARK_SET && info->func == XT_CONNMARK_DSCP) &&
++ info->shift_bits != 0) {
++ xt_xlate_add(xl, " %s %u", shift_op, info->shift_bits);
++ }
++
++ return 1;
++}
++
+ static struct xtables_target connmark_tg_reg[] = {
+ {
+ .family = NFPROTO_UNSPEC,
+@@ -687,6 +984,22 @@ static struct xtables_target connmark_tg
+ .x6_options = connmark_tg_opts_v2,
+ .xlate = connmark_tg_xlate_v2,
+ },
++ {
++ .version = XTABLES_VERSION,
++ .name = "CONNMARK",
++ .revision = 3,
++ .family = NFPROTO_UNSPEC,
++ .size = XT_ALIGN(sizeof(struct xt_connmark_tginfo3)),
++ .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo3)),
++ .help = connmark_tg_help_v3,
++ .init = connmark_tg_init_v3,
++ .print = connmark_tg_print_v3,
++ .save = connmark_tg_save_v3,
++ .x6_parse = connmark_tg_parse_v3,
++ .x6_fcheck = connmark_tg_check,
++ .x6_options = connmark_tg_opts_v3,
++ .xlate = connmark_tg_xlate_v3,
++ },
+ };
+
+ void _init(void)
+--- a/include/linux/netfilter/xt_connmark.h
++++ b/include/linux/netfilter/xt_connmark.h
+@@ -18,6 +18,11 @@ enum {
+ XT_CONNMARK_RESTORE
+ };
+
++enum {
++ XT_CONNMARK_VALUE = (1 << 0),
++ XT_CONNMARK_DSCP = (1 << 1)
++};
++
+ struct xt_connmark_tginfo1 {
+ __u32 ctmark, ctmask, nfmask;
+ __u8 mode;
+@@ -28,6 +33,11 @@ struct xt_connmark_tginfo2 {
+ __u8 shift_dir, shift_bits, mode;
+ };
+
++struct xt_connmark_tginfo3 {
++ __u32 ctmark, ctmask, nfmask;
++ __u8 shift_dir, shift_bits, mode, func;
++};
++
+ struct xt_connmark_mtinfo1 {
+ __u32 mark, mask;
+ __u8 invert;
diff --git a/package/network/utils/iptables/patches/101-remove-check-already.patch b/package/network/utils/iptables/patches/101-remove-check-already.patch
new file mode 100644
index 0000000..16afafe
--- /dev/null
+++ b/package/network/utils/iptables/patches/101-remove-check-already.patch
@@ -0,0 +1,28 @@
+--- a/libxtables/xtables.c
++++ b/libxtables/xtables.c
+@@ -968,12 +968,6 @@ void xtables_register_match(struct xtabl
+ struct xtables_match **pos;
+ bool seen_myself = false;
+
+- if (me->next) {
+- fprintf(stderr, "%s: match \"%s\" already registered\n",
+- xt_params->program_name, me->name);
+- exit(1);
+- }
+-
+ if (me->version == NULL) {
+ fprintf(stderr, "%s: match %s<%u> is missing a version\n",
+ xt_params->program_name, me->name, me->revision);
+@@ -1152,12 +1146,6 @@ void xtables_register_target(struct xtab
+ struct xtables_target **pos;
+ bool seen_myself = false;
+
+- if (me->next) {
+- fprintf(stderr, "%s: target \"%s\" already registered\n",
+- xt_params->program_name, me->name);
+- exit(1);
+- }
+-
+ if (me->version == NULL) {
+ fprintf(stderr, "%s: target %s<%u> is missing a version\n",
+ xt_params->program_name, me->name, me->revision);
diff --git a/package/network/utils/iptables/patches/102-iptables-disable-modprobe.patch b/package/network/utils/iptables/patches/102-iptables-disable-modprobe.patch
new file mode 100644
index 0000000..b8e19c7
--- /dev/null
+++ b/package/network/utils/iptables/patches/102-iptables-disable-modprobe.patch
@@ -0,0 +1,18 @@
+--- a/libxtables/xtables.c
++++ b/libxtables/xtables.c
+@@ -403,6 +403,7 @@ static char *get_modprobe(void)
+
+ int xtables_insmod(const char *modname, const char *modprobe, bool quiet)
+ {
++#if 0
+ char *buf = NULL;
+ char *argv[4];
+ int status;
+@@ -437,6 +438,7 @@ int xtables_insmod(const char *modname,
+ free(buf);
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
+ return 0;
++#endif
+ return -1;
+ }
+
diff --git a/package/network/utils/iptables/patches/103-optional-xml.patch b/package/network/utils/iptables/patches/103-optional-xml.patch
new file mode 100644
index 0000000..342808a
--- /dev/null
+++ b/package/network/utils/iptables/patches/103-optional-xml.patch
@@ -0,0 +1,13 @@
+--- a/iptables/xtables-legacy-multi.c
++++ b/iptables/xtables-legacy-multi.c
+@@ -32,8 +32,10 @@ static const struct subcommand multi_sub
+
+
+ #endif
++#ifdef ENABLE_XML
+ {"iptables-xml", iptables_xml_main},
+ {"xml", iptables_xml_main},
++#endif
+ #ifdef ENABLE_IPV6
+ {"ip6tables", ip6tables_main},
+ {"main6", ip6tables_main},
diff --git a/package/network/utils/iptables/patches/200-configurable_builtin.patch b/package/network/utils/iptables/patches/200-configurable_builtin.patch
new file mode 100644
index 0000000..6d7b5b5
--- /dev/null
+++ b/package/network/utils/iptables/patches/200-configurable_builtin.patch
@@ -0,0 +1,79 @@
+--- a/extensions/GNUmakefile.in
++++ b/extensions/GNUmakefile.in
+@@ -50,11 +50,31 @@ pfb_build_mod := $(filter-out @blacklist
+ pfa_build_mod := $(filter-out @blacklist_modules@ @blacklist_a_modules@,${pfa_build_mod})
+ pf4_build_mod := $(filter-out @blacklist_modules@ @blacklist_4_modules@,${pf4_build_mod})
+ pf6_build_mod := $(filter-out @blacklist_modules@ @blacklist_6_modules@,${pf6_build_mod})
+-pfx_objs := $(patsubst %,libxt_%.o,${pfx_build_mod})
+-pfb_objs := $(patsubst %,libebt_%.o,${pfb_build_mod})
+-pfa_objs := $(patsubst %,libarpt_%.o,${pfa_build_mod})
+-pf4_objs := $(patsubst %,libipt_%.o,${pf4_build_mod})
+-pf6_objs := $(patsubst %,libip6t_%.o,${pf6_build_mod})
++ifdef BUILTIN_MODULES
++pfx_build_static := $(filter $(BUILTIN_MODULES),${pfx_build_mod})
++pfb_build_static := $(filter $(BUILTIN_MODULES),${pfb_build_mod})
++pfa_build_static := $(filter $(BUILTIN_MODULES),${pfa_build_mod})
++pf4_build_static := $(filter $(BUILTIN_MODULES),${pf4_build_mod})
++pf6_build_static := $(filter $(BUILTIN_MODULES),${pf6_build_mod})
++else
++@ENABLE_STATIC_TRUE@ pfx_build_static := $(pfx_build_mod)
++@ENABLE_STATIC_TRUE@ pfb_build_static := $(pfb_build_mod)
++@ENABLE_STATIC_TRUE@ pfa_build_static := $(pfa_build_mod)
++@ENABLE_STATIC_TRUE@ pf4_build_static := $(pf4_build_mod)
++@ENABLE_STATIC_TRUE@ pf6_build_static := $(pf6_build_mod)
++endif
++
++pfx_build_mod := $(filter-out $(pfx_build_static),$(pfx_build_mod))
++pfb_build_mod := $(filter-out $(pfb_build_static),$(pfb_build_mod))
++pfa_build_mod := $(filter-out $(pfa_build_static),$(pfa_build_mod))
++pf4_build_mod := $(filter-out $(pf4_build_static),$(pf4_build_mod))
++pf6_build_mod := $(filter-out $(pf6_build_static),$(pf6_build_mod))
++
++pfx_objs := $(patsubst %,libxt_%.o,${pfx_build_static})
++pfb_objs := $(patsubst %,libebt_%.o,${pfb_build_static})
++pfa_objs := $(patsubst %,libarpt_%.o,${pfa_build_static})
++pf4_objs := $(patsubst %,libipt_%.o,${pf4_build_static})
++pf6_objs := $(patsubst %,libip6t_%.o,${pf6_build_static})
+ pfx_solibs := $(patsubst %,libxt_%.so,${pfx_build_mod})
+ pfb_solibs := $(patsubst %,libebt_%.so,${pfb_build_mod})
+ pfa_solibs := $(patsubst %,libarpt_%.so,${pfa_build_mod})
+@@ -68,14 +88,14 @@ pfx_symlink_files := $(patsubst %,libxt_
+ #
+ targets := libext.a libext4.a libext6.a libext_ebt.a libext_arpt.a matches.man targets.man
+ targets_install :=
+-@ENABLE_STATIC_TRUE@ libext_objs := ${pfx_objs}
+-@ENABLE_STATIC_TRUE@ libext_ebt_objs := ${pfb_objs}
+-@ENABLE_STATIC_TRUE@ libext_arpt_objs := ${pfa_objs}
+-@ENABLE_STATIC_TRUE@ libext4_objs := ${pf4_objs}
+-@ENABLE_STATIC_TRUE@ libext6_objs := ${pf6_objs}
+-@ENABLE_STATIC_FALSE@ targets += ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs} ${pfx_symlink_files}
+-@ENABLE_STATIC_FALSE@ targets_install += ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs}
+-@ENABLE_STATIC_FALSE@ symlinks_install := ${pfx_symlink_files}
++libext_objs := ${pfx_objs}
++libext_ebt_objs := ${pfb_objs}
++libext_arpt_objs := ${pfa_objs}
++libext4_objs := ${pf4_objs}
++libext6_objs := ${pf6_objs}
++targets += ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs} ${pfx_symlink_files}
++targets_install := $(strip ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs})
++symlinks_install := ${pfx_symlink_files}
+
+ .SECONDARY:
+
+@@ -161,11 +181,11 @@ libext4.a: initext4.o ${libext4_objs}
+ libext6.a: initext6.o ${libext6_objs}
+ ${AM_VERBOSE_AR} ${AR} crs $@ $^;
+
+-initext_func := $(addprefix xt_,${pfx_build_mod})
+-initextb_func := $(addprefix ebt_,${pfb_build_mod})
+-initexta_func := $(addprefix arpt_,${pfa_build_mod})
+-initext4_func := $(addprefix ipt_,${pf4_build_mod})
+-initext6_func := $(addprefix ip6t_,${pf6_build_mod})
++initext_func := $(addprefix xt_,${pfx_build_static})
++initextb_func := $(addprefix ebt_,${pfb_build_static})
++initexta_func := $(addprefix arpt_,${pfa_build_static})
++initext4_func := $(addprefix ipt_,${pf4_build_static})
++initext6_func := $(addprefix ip6t_,${pf6_build_static})
+
+ .initext.dd: FORCE
+ @echo "${initext_func}" >$@.tmp; \
diff --git a/package/network/utils/iptables/patches/600-shared-libext.patch b/package/network/utils/iptables/patches/600-shared-libext.patch
new file mode 100644
index 0000000..819f628
--- /dev/null
+++ b/package/network/utils/iptables/patches/600-shared-libext.patch
@@ -0,0 +1,102 @@
+--- a/extensions/GNUmakefile.in
++++ b/extensions/GNUmakefile.in
+@@ -86,7 +86,7 @@ pfx_symlink_files := $(patsubst %,libxt_
+ #
+ # Building blocks
+ #
+-targets := libext.a libext4.a libext6.a libext_ebt.a libext_arpt.a matches.man targets.man
++targets := libiptext.so libiptext4.so libiptext6.so libiptext_ebt.so libiptext_arpt.so matches.man targets.man
+ targets_install :=
+ libext_objs := ${pfx_objs}
+ libext_ebt_objs := ${pfb_objs}
+@@ -132,7 +132,7 @@ clean:
+ distclean: clean
+
+ init%.o: init%.c
+- ${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=$*_init ${CFLAGS} -o $@ -c $<;
++ ${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
+
+ -include .*.d
+
+@@ -164,22 +164,22 @@ xt_connlabel_LIBADD = @libnetfilter_conn
+ # handling code in the Makefiles.
+ #
+ lib%.o: ${srcdir}/lib%.c
+- ${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -DNO_SHARED_LIBS=1 -D_INIT=lib$*_init ${CFLAGS} -o $@ -c $<;
++ ${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -DNO_SHARED_LIBS=1 -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
+
+-libext.a: initext.o ${libext_objs}
+- ${AM_VERBOSE_AR} ${AR} crs $@ $^;
++libiptext.so: initext.o ${libext_objs}
++ ${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $^ -L../libxtables/.libs -lxtables $(foreach obj,$^,${$(patsubst lib%.o,%,$(obj))_LIBADD});
+
+-libext_ebt.a: initextb.o ${libext_ebt_objs}
+- ${AM_VERBOSE_AR} ${AR} crs $@ $^;
++libiptext_ebt.so: initextb.o ${libext_ebt_objs}
++ ${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $^ -L../libxtables/.libs -lxtables $(foreach obj,$^,${$(patsubst lib%.o,%,$(obj))_LIBADD});
+
+-libext_arpt.a: initexta.o ${libext_arpt_objs}
+- ${AM_VERBOSE_AR} ${AR} crs $@ $^;
++libiptext_arpt.so: initexta.o ${libext_arpt_objs}
++ ${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $^ -L../libxtables/.libs -lxtables $(foreach obj,$^,${$(patsubst lib%.o,%,$(obj))_LIBADD});
+
+-libext4.a: initext4.o ${libext4_objs}
+- ${AM_VERBOSE_AR} ${AR} crs $@ $^;
++libiptext4.so: initext4.o ${libext4_objs}
++ ${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $^ -L../libxtables/.libs -lxtables $(foreach obj,$^,${$(patsubst lib%.o,%,$(obj))_LIBADD});
+
+-libext6.a: initext6.o ${libext6_objs}
+- ${AM_VERBOSE_AR} ${AR} crs $@ $^;
++libiptext6.so: initext6.o ${libext6_objs}
++ ${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $^ -L../libxtables/.libs -lxtables $(foreach obj,$^,${$(patsubst lib%.o,%,$(obj))_LIBADD});
+
+ initext_func := $(addprefix xt_,${pfx_build_static})
+ initextb_func := $(addprefix ebt_,${pfb_build_static})
+--- a/iptables/Makefile.am
++++ b/iptables/Makefile.am
+@@ -7,19 +7,22 @@ BUILT_SOURCES =
+
+ xtables_legacy_multi_SOURCES = xtables-legacy-multi.c iptables-xml.c
+ xtables_legacy_multi_CFLAGS = ${AM_CFLAGS}
+-xtables_legacy_multi_LDADD = ../extensions/libext.a
++xtables_legacy_multi_LDADD =
++xtables_legacy_multi_LDFLAGS = -L../extensions/ -liptext
+ if ENABLE_STATIC
+ xtables_legacy_multi_CFLAGS += -DALL_INCLUSIVE
+ endif
+ if ENABLE_IPV4
+ xtables_legacy_multi_SOURCES += iptables-standalone.c iptables.c
+ xtables_legacy_multi_CFLAGS += -DENABLE_IPV4
+-xtables_legacy_multi_LDADD += ../libiptc/libip4tc.la ../extensions/libext4.a
++xtables_legacy_multi_LDADD += ../libiptc/libip4tc.la
++xtables_legacy_multi_LDFLAGS += -liptext4
+ endif
+ if ENABLE_IPV6
+ xtables_legacy_multi_SOURCES += ip6tables-standalone.c ip6tables.c
+ xtables_legacy_multi_CFLAGS += -DENABLE_IPV6
+-xtables_legacy_multi_LDADD += ../libiptc/libip6tc.la ../extensions/libext6.a
++xtables_legacy_multi_LDADD += ../libiptc/libip6tc.la
++xtables_legacy_multi_LDFLAGS += -liptext6
+ endif
+ xtables_legacy_multi_SOURCES += xshared.c iptables-restore.c iptables-save.c
+ xtables_legacy_multi_LDADD += ../libxtables/libxtables.la -lm
+@@ -28,7 +31,8 @@ xtables_legacy_multi_LDADD += ../libxt
+ if ENABLE_NFTABLES
+ xtables_nft_multi_SOURCES = xtables-nft-multi.c iptables-xml.c
+ xtables_nft_multi_CFLAGS = ${AM_CFLAGS}
+-xtables_nft_multi_LDADD = ../extensions/libext.a ../extensions/libext_ebt.a
++xtables_nft_multi_LDADD =
++xtables_nft_multi_LDFLAGS = -L../extensions/ -liptext -liptext_ebt
+ if ENABLE_STATIC
+ xtables_nft_multi_CFLAGS += -DALL_INCLUSIVE
+ endif
+@@ -42,7 +46,8 @@ xtables_nft_multi_SOURCES += xtables-sav
+ xtables-eb-standalone.c xtables-eb.c \
+ xtables-eb-translate.c \
+ xtables-translate.c
+-xtables_nft_multi_LDADD += ${libmnl_LIBS} ${libnftnl_LIBS} ${libnetfilter_conntrack_LIBS} ../extensions/libext4.a ../extensions/libext6.a ../extensions/libext_ebt.a ../extensions/libext_arpt.a
++xtables_nft_multi_LDADD += ${libmnl_LIBS} ${libnftnl_LIBS} ${libnetfilter_conntrack_LIBS}
++xtables_nft_multi_LDFLAGS += -liptext4 -liptext6 -liptext_arpt
+ xtables_nft_multi_SOURCES += xshared.c
+ xtables_nft_multi_LDADD += ../libxtables/libxtables.la -lm
+ endif
diff --git a/package/network/utils/iptables/patches/700-disable-legacy-revisions.patch b/package/network/utils/iptables/patches/700-disable-legacy-revisions.patch
new file mode 100644
index 0000000..cc451ef
--- /dev/null
+++ b/package/network/utils/iptables/patches/700-disable-legacy-revisions.patch
@@ -0,0 +1,95 @@
+--- a/extensions/libxt_conntrack.c
++++ b/extensions/libxt_conntrack.c
+@@ -1395,6 +1395,7 @@ static int conntrack3_mt6_xlate(struct x
+ }
+
+ static struct xtables_match conntrack_mt_reg[] = {
++#ifndef NO_LEGACY
+ {
+ .version = XTABLES_VERSION,
+ .name = "conntrack",
+@@ -1470,6 +1471,7 @@ static struct xtables_match conntrack_mt
+ .alias = conntrack_print_name_alias,
+ .x6_options = conntrack2_mt_opts,
+ },
++#endif
+ {
+ .version = XTABLES_VERSION,
+ .name = "conntrack",
+@@ -1502,6 +1504,7 @@ static struct xtables_match conntrack_mt
+ .x6_options = conntrack3_mt_opts,
+ .xlate = conntrack3_mt6_xlate,
+ },
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "state",
+@@ -1532,6 +1535,8 @@ static struct xtables_match conntrack_mt
+ .x6_parse = state_ct23_parse,
+ .x6_options = state_opts,
+ },
++#endif
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "state",
+@@ -1561,6 +1566,7 @@ static struct xtables_match conntrack_mt
+ .x6_parse = state_parse,
+ .x6_options = state_opts,
+ },
++#endif
+ };
+
+ void _init(void)
+--- a/extensions/libxt_CT.c
++++ b/extensions/libxt_CT.c
+@@ -363,6 +363,7 @@ static int xlate_ct1_tg(struct xt_xlate
+ }
+
+ static struct xtables_target ct_target_reg[] = {
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "CT",
+@@ -388,6 +389,7 @@ static struct xtables_target ct_target_r
+ .x6_parse = ct_parse_v1,
+ .x6_options = ct_opts_v1,
+ },
++#endif
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "CT",
+@@ -403,6 +405,7 @@ static struct xtables_target ct_target_r
+ .x6_options = ct_opts_v1,
+ .xlate = xlate_ct1_tg,
+ },
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "NOTRACK",
+@@ -441,6 +444,7 @@ static struct xtables_target ct_target_r
+ .revision = 0,
+ .version = XTABLES_VERSION,
+ },
++#endif
+ };
+
+ void _init(void)
+--- a/extensions/libxt_multiport.c
++++ b/extensions/libxt_multiport.c
+@@ -571,6 +571,7 @@ static int multiport_xlate6_v1(struct xt
+ }
+
+ static struct xtables_match multiport_mt_reg[] = {
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_IPV4,
+ .name = "multiport",
+@@ -601,6 +602,7 @@ static struct xtables_match multiport_mt
+ .x6_options = multiport_opts,
+ .xlate = multiport_xlate6,
+ },
++#endif
+ {
+ .family = NFPROTO_IPV4,
+ .name = "multiport",
diff --git a/package/network/utils/iptables/patches/800-flowoffload_target.patch b/package/network/utils/iptables/patches/800-flowoffload_target.patch
new file mode 100644
index 0000000..2f79ee8
--- /dev/null
+++ b/package/network/utils/iptables/patches/800-flowoffload_target.patch
@@ -0,0 +1,95 @@
+--- /dev/null
++++ b/extensions/libxt_FLOWOFFLOAD.c
+@@ -0,0 +1,72 @@
++#include <stdio.h>
++#include <xtables.h>
++#include <linux/netfilter/xt_FLOWOFFLOAD.h>
++
++enum {
++ O_HW,
++};
++
++static void offload_help(void)
++{
++ printf(
++"FLOWOFFLOAD target options:\n"
++" --hw Enable hardware offload\n"
++ );
++}
++
++static const struct xt_option_entry offload_opts[] = {
++ {.name = "hw", .id = O_HW, .type = XTTYPE_NONE},
++ XTOPT_TABLEEND,
++};
++
++static void offload_parse(struct xt_option_call *cb)
++{
++ struct xt_flowoffload_target_info *info = cb->data;
++
++ xtables_option_parse(cb);
++ switch (cb->entry->id) {
++ case O_HW:
++ info->flags |= XT_FLOWOFFLOAD_HW;
++ break;
++ }
++}
++
++static void offload_print(const void *ip, const struct xt_entry_target *target, int numeric)
++{
++ const struct xt_flowoffload_target_info *info =
++ (const struct xt_flowoffload_target_info *)target->data;
++
++ printf(" FLOWOFFLOAD");
++ if (info->flags & XT_FLOWOFFLOAD_HW)
++ printf(" hw");
++}
++
++static void offload_save(const void *ip, const struct xt_entry_target *target)
++{
++ const struct xt_flowoffload_target_info *info =
++ (const struct xt_flowoffload_target_info *)target->data;
++
++ if (info->flags & XT_FLOWOFFLOAD_HW)
++ printf(" --hw");
++}
++
++static struct xtables_target offload_tg_reg[] = {
++ {
++ .family = NFPROTO_UNSPEC,
++ .name = "FLOWOFFLOAD",
++ .revision = 0,
++ .version = XTABLES_VERSION,
++ .size = XT_ALIGN(sizeof(struct xt_flowoffload_target_info)),
++ .userspacesize = sizeof(struct xt_flowoffload_target_info),
++ .help = offload_help,
++ .print = offload_print,
++ .save = offload_save,
++ .x6_parse = offload_parse,
++ .x6_options = offload_opts,
++ },
++};
++
++void _init(void)
++{
++ xtables_register_targets(offload_tg_reg, ARRAY_SIZE(offload_tg_reg));
++}
+--- /dev/null
++++ b/include/linux/netfilter/xt_FLOWOFFLOAD.h
+@@ -0,0 +1,17 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++#ifndef _XT_FLOWOFFLOAD_H
++#define _XT_FLOWOFFLOAD_H
++
++#include <linux/types.h>
++
++enum {
++ XT_FLOWOFFLOAD_HW = 1 << 0,
++
++ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW
++};
++
++struct xt_flowoffload_target_info {
++ __u32 flags;
++};
++
++#endif /* _XT_FLOWOFFLOAD_H */
diff --git a/package/network/utils/iptables/patches/900-iptables-notify-fastpath.patch b/package/network/utils/iptables/patches/900-iptables-notify-fastpath.patch
new file mode 100644
index 0000000..d83102c
--- /dev/null
+++ b/package/network/utils/iptables/patches/900-iptables-notify-fastpath.patch
@@ -0,0 +1,239 @@
+--- a/libiptc/libiptc.c
++++ b/libiptc/libiptc.c
+@@ -2505,6 +2505,224 @@ static void counters_map_set(STRUCT_COUN
+ DEBUGP_C("SET\n");
+ }
+
++#define FASTPATH
++
++#ifdef FASTPATH
++#include <stdio.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <unistd.h>
++#include <poll.h>
++#include <string.h>
++#include <fcntl.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/statfs.h>
++#include <sys/socket.h>
++#include <sys/types.h>
++#include <signal.h>
++#include <linux/magic.h>
++#include <linux/genetlink.h>
++
++/*
++ * Generic macros for dealing with netlink sockets. Might be duplicated
++ * elsewhere. It is recommended that commercial grade applications use
++ * libnl or libnetlink and use the interfaces provided by the library
++ */
++#define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
++#define GENLMSG_PAYLOAD(glh) (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
++#define NLA_DATA(na) ((void *)((char*)(na) + NLA_HDRLEN))
++
++static bool proc_file_exists(const char *filename)
++{
++ struct stat s;
++ struct statfs f;
++
++ if (lstat(filename, &s))
++ return false;
++ if (!S_ISREG(s.st_mode))
++ return false;
++ if (statfs(filename, &f))
++ return false;
++ if (f.f_type != PROC_SUPER_MAGIC)
++ return false;
++ return true;
++}
++
++static int create_nl_socket(int protocol, int groups)
++{
++ socklen_t addr_len;
++ int fd;
++ struct sockaddr_nl local;
++
++ fd = socket(AF_NETLINK, SOCK_RAW, protocol);
++ if (fd < 0) {
++ perror("socket");
++ return -1;
++ }
++
++ memset(&local, 0, sizeof(local));
++ local.nl_family = AF_NETLINK;
++ local.nl_groups = groups;
++ if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0)
++ goto error;
++
++ return fd;
++error:
++ close(fd);
++ return -1;
++}
++
++/*
++ * Send netlink message to kernel
++ */
++int sendto_fd(int s, const char *buf, int bufLen)
++{
++ struct sockaddr_nl nladdr;
++ int r;
++
++ memset(&nladdr, 0, sizeof(nladdr));
++ nladdr.nl_family = AF_NETLINK;
++
++ while ((r = sendto(s, buf, bufLen, 0, (struct sockaddr *) &nladdr,
++ sizeof(nladdr))) < bufLen) {
++ if (r > 0) {
++ buf += r;
++ bufLen -= r;
++ } else if (errno != EAGAIN) {
++ return -1;
++ }
++ }
++
++ return 0;
++}
++
++/*
++ * Probe the controller in genetlink to find the family id
++ * for the CONTROL_EXMPL family
++ */
++int get_family_id(int sd)
++{
++ struct {
++ struct nlmsghdr n;
++ struct genlmsghdr g;
++ char buf[256];
++ } family_req;
++
++ struct {
++ struct nlmsghdr n;
++ struct genlmsghdr g;
++ char buf[256];
++ } ans;
++
++ int id;
++ struct nlattr *na;
++ int rep_len;
++
++ /* Get family name */
++ family_req.n.nlmsg_type = GENL_ID_CTRL;
++ family_req.n.nlmsg_flags = NLM_F_REQUEST;
++ family_req.n.nlmsg_seq = 0;
++ family_req.n.nlmsg_pid = getpid();
++ family_req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
++ family_req.g.cmd = CTRL_CMD_GETFAMILY;
++ family_req.g.version = 0x1;
++
++ na = (struct nlattr *) GENLMSG_DATA(&family_req);
++ na->nla_type = CTRL_ATTR_FAMILY_NAME;
++
++ /*------change here--------*/
++ na->nla_len = strlen("FASTPATH") + 1 + NLA_HDRLEN;
++ strcpy(NLA_DATA(na), "FASTPATH");
++
++ family_req.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
++
++ if (sendto_fd(sd, (char *) &family_req, family_req.n.nlmsg_len) < 0)
++ return -1;
++
++ rep_len = recv(sd, &ans, sizeof(ans), 0);
++ if (rep_len < 0){
++ perror("recv");
++ return -1;
++ }
++
++ /* Validate response message */
++ if (!NLMSG_OK((&ans.n), rep_len)){
++ fprintf(stderr, "invalid reply message\n");
++ return -1;
++ }
++
++ if (ans.n.nlmsg_type == NLMSG_ERROR) { /* error */
++ fprintf(stderr, "received error\n");
++ return -1;
++ }
++
++ na = (struct nlattr *)GENLMSG_DATA(&ans);
++ na = (struct nlattr *)((char *) na + NLA_ALIGN(na->nla_len));
++ if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
++ id = *(__u16 *)NLA_DATA(na);
++ }
++
++ return id;
++}
++
++static int tc_commit_notify_fastpath(void)
++{
++ struct {
++ struct nlmsghdr n;
++ struct genlmsghdr g;
++ char buf[256];
++ } ans;
++
++ struct {
++ struct nlmsghdr n;
++ struct genlmsghdr g;
++ char buf[256];
++ } req;
++
++ struct nlattr *na;
++ int nl_sd, id, mlength;
++ struct sockaddr_nl nladdr;
++ char *message = "TC_COMMIT!";
++
++ nl_sd = create_nl_socket(NETLINK_GENERIC,0);
++ if (nl_sd < 0) {
++ printf("create failure\n");
++ return -1;
++ }
++
++ id = get_family_id(nl_sd);
++ if (id < 0) {
++ printf("bad id\n");
++ return -1;
++ }
++
++ /* Send command needed */
++ req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
++ req.n.nlmsg_type = id;
++ req.n.nlmsg_flags = NLM_F_REQUEST;
++ req.n.nlmsg_seq = 60;
++ req.n.nlmsg_pid = getpid();
++ req.g.cmd = 1; //FASTPATH_NL_C_IPT_NOTIFY
++
++ /*compose message*/
++ na = (struct nlattr *)GENLMSG_DATA(&req);
++ na->nla_type = 1; //FASTPATH_NL_C_IPT_NOTIFY
++ mlength = strlen(message);
++ na->nla_len = mlength+NLA_HDRLEN; //message length
++ memcpy(NLA_DATA(na), message, mlength);
++ req.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
++
++ /*send message*/
++ memset(&nladdr, 0, sizeof(nladdr));
++ nladdr.nl_family = AF_NETLINK;
++
++ sendto(nl_sd, (char *)&req, req.n.nlmsg_len, 0,
++ (struct sockaddr *)&nladdr, sizeof(nladdr));
++ close(nl_sd);
++ return 0;
++}
++#endif
+
+ int
+ TC_COMMIT(struct xtc_handle *handle)
+@@ -2672,6 +2890,11 @@ TC_COMMIT(struct xtc_handle *handle)
+ free(repl);
+ free(newcounters);
+
++#ifdef FASTPATH
++ if (proc_file_exists("/proc/net/fastpath"))
++ tc_commit_notify_fastpath();
++#endif
++
+ finished:
+ return 1;
+
diff --git a/package/network/utils/iw/Makefile b/package/network/utils/iw/Makefile
new file mode 100644
index 0000000..1237c10
--- /dev/null
+++ b/package/network/utils/iw/Makefile
@@ -0,0 +1,75 @@
+#
+# Copyright (C) 2007-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=iw
+PKG_VERSION:=6.9
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/software/network/iw
+PKG_HASH:=3f2db22ad41c675242b98ae3942dbf3112548c60a42ff739210f2de4e98e4894
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+PKG_LICENSE:=GPL-2.0
+PKG_CPE_ID:=cpe:/a:kernel:iw
+
+PKG_BUILD_FLAGS:=gc-sections lto
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/iw
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=cfg80211 interface configuration utility
+ URL:=http://wireless.kernel.org/en/users/Documentation/iw
+ DEPENDS:= +libnl-tiny
+ VARIANT:=tiny
+endef
+
+define Package/iw-full
+ $(Package/iw)
+ TITLE += (full version)
+ VARIANT:=full
+ PROVIDES:=iw
+endef
+
+define Build/Configure
+ echo "const char iw_version[] = \"$(PKG_VERSION)\";" > $(PKG_BUILD_DIR)/version.c
+ echo "#!/bin/sh" > $(PKG_BUILD_DIR)/version.sh
+ chmod +x $(PKG_BUILD_DIR)/version.sh
+endef
+
+TARGET_CPPFLAGS:= \
+ -I$(STAGING_DIR)/usr/include/libnl-tiny \
+ $(TARGET_CPPFLAGS) \
+ -DCONFIG_LIBNL20 \
+ -D_GNU_SOURCE
+
+ifeq ($(BUILD_VARIANT),full)
+ TARGET_CPPFLAGS += -DIW_FULL
+ MAKE_FLAGS += IW_FULL=1
+endif
+
+MAKE_FLAGS += \
+ CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
+ LDFLAGS="$(TARGET_LDFLAGS)" \
+ NL1FOUND="" NL2FOUND=Y \
+ NLLIBNAME="libnl-tiny" \
+ LIBS="-lm -lnl-tiny" \
+ V=1
+
+define Package/iw/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/iw $(1)/usr/sbin/
+endef
+
+Package/iw-full/install=$(Package/iw/install)
+
+$(eval $(call BuildPackage,iw))
+$(eval $(call BuildPackage,iw-full))
diff --git a/package/network/utils/iw/patches/001-nl80211_h_sync.patch b/package/network/utils/iw/patches/001-nl80211_h_sync.patch
new file mode 100644
index 0000000..f48c083
--- /dev/null
+++ b/package/network/utils/iw/patches/001-nl80211_h_sync.patch
@@ -0,0 +1,98 @@
+--- a/nl80211.h
++++ b/nl80211.h
+@@ -2061,6 +2061,10 @@ enum nl80211_commands {
+ * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported
+ * interface combinations. In each nested item, it contains attributes
+ * defined in &enum nl80211_if_combination_attrs.
++ * If the wiphy uses multiple radios (@NL80211_ATTR_WIPHY_RADIOS is set),
++ * this attribute contains the interface combinations of the first radio.
++ * See @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS for the global wiphy
++ * combinations for the sum of all radios.
+ * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like
+ * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that
+ * are managed in software: interfaces of these types aren't subject to
+@@ -2856,6 +2860,17 @@ enum nl80211_commands {
+ * %NL80211_CMD_ASSOCIATE indicating the SPP A-MSDUs
+ * are used on this connection
+ *
++ * @NL80211_ATTR_WIPHY_RADIOS: Nested attribute describing physical radios
++ * belonging to this wiphy. See &enum nl80211_wiphy_radio_attrs.
++ *
++ * @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS: Nested attribute listing the
++ * supported interface combinations for all radios combined. In each
++ * nested item, it contains attributes defined in
++ * &enum nl80211_if_combination_attrs.
++ *
++ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32).
++ * A value of 0 means all radios.
++ *
+ * @NUM_NL80211_ATTR: total number of nl80211_attrs available
+ * @NL80211_ATTR_MAX: highest attribute number currently defined
+ * @__NL80211_ATTR_AFTER_LAST: internal use
+@@ -3401,6 +3416,11 @@ enum nl80211_attrs {
+
+ NL80211_ATTR_ASSOC_SPP_AMSDU,
+
++ NL80211_ATTR_WIPHY_RADIOS,
++ NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
++
++ NL80211_ATTR_VIF_RADIO_MASK,
++
+ /* add attributes here, update the policy in nl80211.c */
+
+ __NL80211_ATTR_AFTER_LAST,
+@@ -7987,4 +8007,54 @@ enum nl80211_ap_settings_flags {
+ NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1,
+ };
+
++/**
++ * enum nl80211_wiphy_radio_attrs - wiphy radio attributes
++ *
++ * @__NL80211_WIPHY_RADIO_ATTR_INVALID: Invalid
++ *
++ * @NL80211_WIPHY_RADIO_ATTR_INDEX: Index of this radio (u32)
++ * @NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE: Frequency range supported by this
++ * radio. Attribute may be present multiple times.
++ * @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface
++ * combination for this radio. Attribute may be present multiple times
++ * and contains attributes defined in &enum nl80211_if_combination_attrs.
++ *
++ * @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal
++ * @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute
++ */
++enum nl80211_wiphy_radio_attrs {
++ __NL80211_WIPHY_RADIO_ATTR_INVALID,
++
++ NL80211_WIPHY_RADIO_ATTR_INDEX,
++ NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE,
++ NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
++
++ /* keep last */
++ __NL80211_WIPHY_RADIO_ATTR_LAST,
++ NL80211_WIPHY_RADIO_ATTR_MAX = __NL80211_WIPHY_RADIO_ATTR_LAST - 1,
++};
++
++/**
++ * enum nl80211_wiphy_radio_freq_range - wiphy radio frequency range
++ *
++ * @__NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID: Invalid
++ *
++ * @NL80211_WIPHY_RADIO_FREQ_ATTR_START: Frequency range start (u32).
++ * The unit is kHz.
++ * @NL80211_WIPHY_RADIO_FREQ_ATTR_END: Frequency range end (u32).
++ * The unit is kHz.
++ *
++ * @__NL80211_WIPHY_RADIO_FREQ_ATTR_LAST: Internal
++ * @NL80211_WIPHY_RADIO_FREQ_ATTR_MAX: Highest attribute
++ */
++enum nl80211_wiphy_radio_freq_range {
++ __NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID,
++
++ NL80211_WIPHY_RADIO_FREQ_ATTR_START,
++ NL80211_WIPHY_RADIO_FREQ_ATTR_END,
++
++ __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST,
++ NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST - 1,
++};
++
+ #endif /* __LINUX_NL80211_H */
diff --git a/package/network/utils/iw/patches/010-Revert-iw-allow-specifying-CFLAGS-LIBS-externally.patch b/package/network/utils/iw/patches/010-Revert-iw-allow-specifying-CFLAGS-LIBS-externally.patch
new file mode 100644
index 0000000..1c93f00
--- /dev/null
+++ b/package/network/utils/iw/patches/010-Revert-iw-allow-specifying-CFLAGS-LIBS-externally.patch
@@ -0,0 +1,68 @@
+From 1f3706d10812d70adefe32fe0d7d3a3ec25374f0 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Sun, 21 Nov 2021 00:02:57 +0100
+Subject: Revert "iw: allow specifying CFLAGS/LIBS externally"
+
+This reverts commit 1325244b77d56fd7a16d1e35fdae0efc151920b1.
+
+The OpenWrt build system provides the CFLAGS and LIBS names from the
+package Makefile to overwrite them for libnl-tiny. This is not possible
+after this upstream change which we revert here any more
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ Makefile | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -46,30 +46,30 @@ NLLIBNAME = libnl-1
+ endif
+
+ ifeq ($(NL2FOUND),Y)
+-override CFLAGS += -DCONFIG_LIBNL20
+-override LIBS += -lnl-genl
++CFLAGS += -DCONFIG_LIBNL20
++LIBS += -lnl-genl
+ NLLIBNAME = libnl-2.0
+ endif
+
+ ifeq ($(NL3xFOUND),Y)
+ # libnl 3.2 might be found as 3.2 and 3.0
+ NL3FOUND = N
+-override CFLAGS += -DCONFIG_LIBNL30
+-override LIBS += -lnl-genl-3
++CFLAGS += -DCONFIG_LIBNL30
++LIBS += -lnl-genl-3
+ NLLIBNAME = libnl-3.0
+ endif
+
+ ifeq ($(NL3FOUND),Y)
+-override CFLAGS += -DCONFIG_LIBNL30
+-override LIBS += -lnl-genl
++CFLAGS += -DCONFIG_LIBNL30
++LIBS += -lnl-genl
+ NLLIBNAME = libnl-3.0
+ endif
+
+ # nl-3.1 has a broken libnl-gnl-3.1.pc file
+ # as show by pkg-config --debug --libs --cflags --exact-version=3.1 libnl-genl-3.1;echo $?
+ ifeq ($(NL31FOUND),Y)
+-override CFLAGS += -DCONFIG_LIBNL30
+-override LIBS += -lnl-genl
++CFLAGS += -DCONFIG_LIBNL30
++LIBS += -lnl-genl
+ NLLIBNAME = libnl-3.1
+ endif
+
+@@ -77,8 +77,8 @@ ifeq ($(NLLIBNAME),)
+ $(error Cannot find development files for any supported version of libnl)
+ endif
+
+-override LIBS += $(shell $(PKG_CONFIG) --libs $(NLLIBNAME))
+-override CFLAGS += $(shell $(PKG_CONFIG) --cflags $(NLLIBNAME))
++LIBS += $(shell $(PKG_CONFIG) --libs $(NLLIBNAME))
++CFLAGS += $(shell $(PKG_CONFIG) --cflags $(NLLIBNAME))
+ endif # NO_PKG_CONFIG
+
+ ifeq ($(V),1)
diff --git a/package/network/utils/iw/patches/130-survey-bss-rx-time.patch b/package/network/utils/iw/patches/130-survey-bss-rx-time.patch
new file mode 100644
index 0000000..d488c14
--- /dev/null
+++ b/package/network/utils/iw/patches/130-survey-bss-rx-time.patch
@@ -0,0 +1,12 @@
+--- a/survey.c
++++ b/survey.c
+@@ -60,6 +60,9 @@ static int print_survey_handler(struct n
+ if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX])
+ printf("\tchannel receive time:\t\t%llu ms\n",
+ (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]));
++ if (sinfo[NL80211_SURVEY_INFO_TIME_BSS_RX])
++ printf("\tchannel BSS receive time:\t%llu ms\n",
++ (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BSS_RX]));
+ if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX])
+ printf("\tchannel transmit time:\t\t%llu ms\n",
+ (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]));
diff --git a/package/network/utils/iw/patches/200-reduce_size.patch b/package/network/utils/iw/patches/200-reduce_size.patch
new file mode 100644
index 0000000..9924ffa
--- /dev/null
+++ b/package/network/utils/iw/patches/200-reduce_size.patch
@@ -0,0 +1,371 @@
+--- a/event.c
++++ b/event.c
+@@ -973,6 +973,7 @@ static int print_event(struct nl_msg *ms
+ }
+
+ switch (gnlh->cmd) {
++#ifdef IW_FULL
+ case NL80211_CMD_NEW_WIPHY:
+ printf("renamed to %s\n", nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]));
+ break;
+@@ -1008,6 +1009,7 @@ static int print_event(struct nl_msg *ms
+ case NL80211_CMD_SCHED_SCAN_RESULTS:
+ printf("got scheduled scan results\n");
+ break;
++#endif
+ case NL80211_CMD_WIPHY_REG_CHANGE:
+ case NL80211_CMD_REG_CHANGE:
+ if (gnlh->cmd == NL80211_CMD_WIPHY_REG_CHANGE)
+@@ -1090,6 +1092,7 @@ static int print_event(struct nl_msg *ms
+ mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC]));
+ printf("del station %s\n", macbuf);
+ break;
++#ifdef IW_FULL
+ case NL80211_CMD_JOIN_IBSS:
+ mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC]));
+ printf("IBSS %s joined\n", macbuf);
+@@ -1297,9 +1300,9 @@ static int print_event(struct nl_msg *ms
+ case NL80211_CMD_ASSOC_COMEBACK: /* 147 */
+ parse_assoc_comeback(tb, gnlh->cmd);
+ break;
++#endif
+ default:
+- printf("unknown event %d (%s)\n",
+- gnlh->cmd, command_name(gnlh->cmd));
++ printf("unknown event %d\n", gnlh->cmd);
+ break;
+ }
+
+--- a/info.c
++++ b/info.c
+@@ -446,6 +446,7 @@ next:
+ }
+ }
+
++#ifdef IW_FULL
+ if (tb_band[NL80211_BAND_ATTR_RATES]) {
+ printf("\t\tBitrates (non-HT):\n");
+ nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
+@@ -462,6 +463,7 @@ next:
+ printf("\n");
+ }
+ }
++#endif
+ }
+ }
+
+@@ -527,6 +529,7 @@ next:
+ printf("\tCoverage class: %d (up to %dm)\n", coverage, 450 * coverage);
+ }
+
++#ifdef IW_FULL
+ if (tb_msg[NL80211_ATTR_CIPHER_SUITES]) {
+ int num = nla_len(tb_msg[NL80211_ATTR_CIPHER_SUITES]) / sizeof(__u32);
+ int i;
+@@ -538,6 +541,7 @@ next:
+ cipher_name(ciphers[i]));
+ }
+ }
++#endif
+
+ if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX] &&
+ tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX])
+@@ -555,9 +559,11 @@ next:
+ print_iftype_list("\tSupported interface modes", "\t\t",
+ tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES]);
+
++#ifdef IW_FULL
+ if (tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES])
+ print_iftype_list("\tsoftware interface modes (can always be added)",
+ "\t\t", tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES]);
++#endif
+
+ if (tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS]) {
+ struct nlattr *nl_combi;
+@@ -647,6 +653,7 @@ broken_combination:
+ printf("\tinterface combinations are not supported\n");
+ }
+
++#ifdef IW_FULL
+ if (tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS]) {
+ printf("\tSupported commands:\n");
+ nla_for_each_nested(nl_cmd, tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS], rem_cmd)
+@@ -744,6 +751,7 @@ broken_combination:
+ printf("\t\t * wake up on TCP connection\n");
+ }
+ }
++#endif
+
+ if (tb_msg[NL80211_ATTR_ROAM_SUPPORT])
+ printf("\tDevice supports roaming.\n");
+@@ -782,6 +790,7 @@ broken_combination:
+ }
+ }
+
++#ifdef IW_FULL
+ if (tb_msg[NL80211_ATTR_FEATURE_FLAGS]) {
+ unsigned int features = nla_get_u32(tb_msg[NL80211_ATTR_FEATURE_FLAGS]);
+
+@@ -846,6 +855,7 @@ broken_combination:
+ if (features & NL80211_FEATURE_ND_RANDOM_MAC_ADDR)
+ printf("\tDevice supports randomizing MAC-addr in net-detect scans.\n");
+ }
++#endif
+
+ if (tb_msg[NL80211_ATTR_TDLS_SUPPORT])
+ printf("\tDevice supports T-DLS.\n");
+@@ -914,6 +924,7 @@ TOPLEVEL(list, NULL, NL80211_CMD_GET_WIP
+ "List all wireless devices and their capabilities.");
+ TOPLEVEL(phy, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info, NULL);
+
++#ifdef IW_FULL
+ static int handle_commands(struct nl80211_state *state, struct nl_msg *msg,
+ int argc, char **argv, enum id_input id)
+ {
+@@ -925,6 +936,7 @@ static int handle_commands(struct nl8021
+ }
+ TOPLEVEL(commands, NULL, NL80211_CMD_GET_WIPHY, 0, CIB_NONE, handle_commands,
+ "list all known commands and their decimal & hex value");
++#endif
+
+ static int print_feature_handler(struct nl_msg *msg, void *arg)
+ {
+--- a/scan.c
++++ b/scan.c
+@@ -1308,6 +1308,9 @@ static void print_ht_op(const uint8_t ty
+ printf("\t\t * secondary channel offset: %s\n",
+ ht_secondary_offset[data[1] & 0x3]);
+ printf("\t\t * STA channel width: %s\n", sta_chan_width[(data[1] & 0x4)>>2]);
++#ifndef IW_FULL
++ return;
++#endif
+ printf("\t\t * RIFS: %d\n", (data[1] & 0x8)>>3);
+ printf("\t\t * HT protection: %s\n", protection[data[2] & 0x3]);
+ printf("\t\t * non-GF present: %d\n", (data[2] & 0x4) >> 2);
+@@ -1818,30 +1821,31 @@ static void print_ie(const struct ie_pri
+ static const struct ie_print ieprinters[] = {
+ [0] = { "SSID", print_ssid, 0, 32,
+ BIT(PRINT_SCAN) | BIT(PRINT_LINK) | BIT(PRINT_LINK_MLO_MLD), },
++ [11] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), },
++ [45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
++ [48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
++ [61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
++ [62] = { "Secondary Channel Offset", print_secchan_offs, 1, 1, BIT(PRINT_SCAN), },
++ [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
++ [191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
++ [192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
++#ifdef IW_FULL
+ [1] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
+ [3] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), },
+ [5] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), },
+ [6] = { "IBSS ATIM window", print_ibssatim, 2, 2, BIT(PRINT_SCAN), },
+ [7] = { "Country", print_country, 3, 255, BIT(PRINT_SCAN), },
+- [11] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), },
+ [32] = { "Power constraint", print_powerconstraint, 1, 1, BIT(PRINT_SCAN), },
+ [35] = { "TPC report", print_tpcreport, 2, 2, BIT(PRINT_SCAN), },
+ [42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), },
+- [45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
+ [47] = { "ERP D4.0", print_erp, 1, 255, BIT(PRINT_SCAN), },
+ [51] = { "AP Channel Report", print_ap_channel_report, 1, 255, BIT(PRINT_SCAN), },
+ [59] = { "Supported operating classes", print_supp_op_classes, 1, 255, BIT(PRINT_SCAN), },
+ [66] = { "Measurement Pilot Transmission", print_measurement_pilot_tx, 1, 255, BIT(PRINT_SCAN), },
+ [74] = { "Overlapping BSS scan params", print_obss_scan_params, 14, 255, BIT(PRINT_SCAN), },
+- [61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
+- [62] = { "Secondary Channel Offset", print_secchan_offs, 1, 1, BIT(PRINT_SCAN), },
+- [191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
+- [192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
+- [48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
+ [50] = { "Extended supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
+ [70] = { "RM enabled capabilities", print_rm_enabled_capabilities, 5, 5, BIT(PRINT_SCAN), },
+ [113] = { "MESH Configuration", print_mesh_conf, 7, 7, BIT(PRINT_SCAN), },
+- [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
+ [127] = { "Extended capabilities", print_capabilities, 0, 255, BIT(PRINT_SCAN), },
+ [107] = { "802.11u Interworking", print_interworking, 0, 255, BIT(PRINT_SCAN), },
+ [108] = { "802.11u Advertisement", print_11u_advert, 0, 255, BIT(PRINT_SCAN), },
+@@ -1850,6 +1854,7 @@ static const struct ie_print ieprinters[
+ [214] = { "Short beacon interval", print_short_beacon_int, 2, 2, BIT(PRINT_SCAN), },
+ [217] = { "S1G capabilities", print_s1g_capa, 15, 15, BIT(PRINT_SCAN), },
+ [232] = { "S1G operation", print_s1g_oper, 6, 6, BIT(PRINT_SCAN), },
++#endif
+ };
+
+ static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data,
+@@ -2185,8 +2190,10 @@ static void print_wifi_wps(const uint8_t
+
+ static const struct ie_print wifiprinters[] = {
+ [1] = { "WPA", print_wifi_wpa, 2, 255, BIT(PRINT_SCAN), },
++#ifdef IW_FULL
+ [2] = { "WMM", print_wifi_wmm, 1, 255, BIT(PRINT_SCAN), },
+ [4] = { "WPS", print_wifi_wps, 0, 255, BIT(PRINT_SCAN), },
++#endif
+ };
+
+ static inline void print_p2p(const uint8_t type, uint8_t len,
+@@ -2349,6 +2356,10 @@ static void print_vendor(unsigned char l
+ return;
+ }
+
++#ifdef IW_FULL
++ return;
++#endif
++
+ if (len >= 4 && memcmp(data, wfa_oui, 3) == 0) {
+ if (data[3] < ARRAY_SIZE(wfa_printers) &&
+ wfa_printers[data[3]].name &&
+@@ -2483,6 +2494,7 @@ static void print_capa_non_dmg(__u16 cap
+ printf(" ESS");
+ if (capa & WLAN_CAPABILITY_IBSS)
+ printf(" IBSS");
++#ifdef IW_FULL
+ if (capa & WLAN_CAPABILITY_CF_POLLABLE)
+ printf(" CfPollable");
+ if (capa & WLAN_CAPABILITY_CF_POLL_REQUEST)
+@@ -2511,6 +2523,7 @@ static void print_capa_non_dmg(__u16 cap
+ printf(" DelayedBACK");
+ if (capa & WLAN_CAPABILITY_IMM_BACK)
+ printf(" ImmediateBACK");
++#endif
+ }
+
+ static int print_bss_handler(struct nl_msg *msg, void *arg)
+@@ -2601,8 +2614,10 @@ static int print_bss_handler(struct nl_m
+ else
+ printf("\tfreq: %d\n", freq);
+
++#ifdef IW_FULL
+ if (freq > 45000)
+ is_dmg = true;
++#endif
+ }
+ if (bss[NL80211_BSS_BEACON_INTERVAL])
+ printf("\tbeacon interval: %d TUs\n",
+@@ -2796,6 +2811,7 @@ static int handle_stop_sched_scan(struct
+ return 0;
+ }
+
++#ifdef IW_FULL
+ COMMAND(scan, sched_start,
+ SCHED_SCAN_OPTIONS,
+ NL80211_CMD_START_SCHED_SCAN, 0, CIB_NETDEV, handle_start_sched_scan,
+@@ -2806,3 +2822,4 @@ COMMAND(scan, sched_start,
+ COMMAND(scan, sched_stop, "",
+ NL80211_CMD_STOP_SCHED_SCAN, 0, CIB_NETDEV, handle_stop_sched_scan,
+ "Stop an ongoing scheduled scan.");
++#endif
+--- a/util.c
++++ b/util.c
+@@ -153,6 +153,7 @@ static const char *commands[NL80211_CMD_
+
+ static char cmdbuf[100];
+
++#ifdef IW_FULL
+ const char *command_name(enum nl80211_commands cmd)
+ {
+ if (cmd <= NL80211_CMD_MAX && commands[cmd])
+@@ -160,6 +161,7 @@ const char *command_name(enum nl80211_co
+ sprintf(cmdbuf, "Unknown command (%d)", cmd);
+ return cmdbuf;
+ }
++#endif
+
+ int ieee80211_channel_to_frequency(int chan, enum nl80211_band band)
+ {
+@@ -313,6 +315,9 @@ int parse_keys(struct nl_msg *msg, char
+ char keybuf[13];
+ int pos = 0;
+
++#ifndef IW_FULL
++ return 1;
++#endif
+ if (!*argc)
+ return 1;
+
+--- a/Makefile
++++ b/Makefile
+@@ -24,6 +24,12 @@ _OBJS := $(sort $(patsubst %.c,%.o,$(wil
+ VERSION_OBJS := $(filter-out version.o, $(_OBJS))
+ OBJS := $(VERSION_OBJS) version.o
+
++OBJS_FULL = ocb offch cqm wowlan coalesce roc p2p vendor mgmt ap sha256 nan bloom measurements ftm
++ifdef IW_FULL
++ CFLAGS += -DIW_FULL
++else
++ OBJS:=$(filter-out $(patsubst %,%.o,$(OBJS_FULL)),$(OBJS))
++endif
+ ALL = iw
+
+ ifeq ($(NO_PKG_CONFIG),)
+--- a/station.c
++++ b/station.c
+@@ -801,10 +801,12 @@ static int handle_station_set_plink(stru
+ nla_put_failure:
+ return -ENOBUFS;
+ }
++#ifdef IW_FULL
+ COMMAND_ALIAS(station, set, "<MAC address> plink_action <open|block>",
+ NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set_plink,
+ "Set mesh peer link action for this station (peer).",
+ select_station_cmd, station_set_plink);
++#endif
+
+ static int handle_station_set_vlan(struct nl80211_state *state,
+ struct nl_msg *msg,
+@@ -899,11 +901,13 @@ static int handle_station_set_mesh_power
+ nla_put_failure:
+ return -ENOBUFS;
+ }
++#ifdef IW_FULL
+ COMMAND_ALIAS(station, set, "<MAC address> mesh_power_mode "
+ "<active|light|deep>", NL80211_CMD_SET_STATION, 0, CIB_NETDEV,
+ handle_station_set_mesh_power_mode,
+ "Set link-specific mesh power mode for this station",
+ select_station_cmd, station_set_mesh_power_mode);
++#endif
+
+ static int handle_station_set_airtime_weight(struct nl80211_state *state,
+ struct nl_msg *msg,
+--- a/interface.c
++++ b/interface.c
+@@ -668,9 +668,11 @@ static int handle_interface_wds_peer(str
+ nla_put_failure:
+ return -ENOBUFS;
+ }
++#ifdef IW_FULL
+ COMMAND(set, peer, "<MAC address>",
+ NL80211_CMD_SET_WDS_PEER, 0, CIB_NETDEV, handle_interface_wds_peer,
+ "Set interface WDS peer.");
++#endif
+
+ static int set_mcast_rate(struct nl80211_state *state,
+ struct nl_msg *msg,
+@@ -760,6 +762,7 @@ static int handle_chan(struct nl80211_st
+ return handle_chanfreq(state, msg, true, argc, argv, id);
+ }
+
++#ifdef IW_FULL
+ SECTION(switch);
+ COMMAND(switch, freq,
+ "<freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz] [beacons <count>] [block-tx]\n"
+@@ -1031,3 +1034,4 @@ COMMAND(set, tidconf, "[peer <MAC addres
+ " $ iw dev wlan0 set tidconf peer xx:xx:xx:xx:xx:xx tids 0x2 bitrates auto\n"
+ " $ iw dev wlan0 set tidconf peer xx:xx:xx:xx:xx:xx tids 0x2 bitrates limit vht-mcs-5 4:9\n"
+ );
++#endif
+--- a/phy.c
++++ b/phy.c
+@@ -403,6 +403,7 @@ err_out:
+ free(cac_trigger_argv);
+ return err;
+ }
++#ifdef IW_FULL
+ TOPLEVEL(cac, "channel <channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
+ "freq <freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
+ "freq <control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]",
+@@ -422,6 +423,7 @@ COMMAND(cac, background,
+ NL80211_CMD_RADAR_DETECT, 0, CIB_NETDEV, handle_cac_background,
+ "Start background channel availability check (CAC) looking to look for\n"
+ "radars on the given channel.");
++#endif
+
+ static int handle_fragmentation(struct nl80211_state *state,
+ struct nl_msg *msg,
diff --git a/package/network/utils/iw/patches/300-wiphy_radios.patch b/package/network/utils/iw/patches/300-wiphy_radios.patch
new file mode 100644
index 0000000..534addf
--- /dev/null
+++ b/package/network/utils/iw/patches/300-wiphy_radios.patch
@@ -0,0 +1,252 @@
+--- a/info.c
++++ b/info.c
+@@ -295,6 +295,151 @@ static void print_pmsr_capabilities(stru
+ }
+ }
+
++static void print_interface_combinations(struct nlattr *ifcomb, bool radio)
++{
++ const char *indent = radio ? "\t" : "";
++ struct nlattr *nl_combi;
++ bool have_combinations = false;
++ int rem;
++
++ nla_for_each_nested(nl_combi, ifcomb, rem) {
++ static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
++ [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
++ [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
++ [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
++ [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
++ [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
++ };
++ struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
++ static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
++ [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
++ [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
++ };
++ struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
++ struct nlattr *nl_limit;
++ int err, rem_limit;
++ bool comma = false;
++
++ if (radio && nla_type(nl_combi) !=
++ NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION)
++ continue;
++
++ if (!have_combinations) {
++ printf("\t%svalid interface combinations:\n", indent);
++ have_combinations = true;
++ }
++
++ printf("\t\t%s * ", indent);
++
++ err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
++ nl_combi, iface_combination_policy);
++ if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
++ !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
++ !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
++ printf(" <failed to parse>\n");
++ goto broken_combination;
++ }
++
++ nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS], rem_limit) {
++ err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
++ nl_limit, iface_limit_policy);
++ if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES]) {
++ printf("<failed to parse>\n");
++ goto broken_combination;
++ }
++
++ if (comma)
++ printf(", ");
++ comma = true;
++ printf("#{ ");
++ print_iftype_line(tb_limit[NL80211_IFACE_LIMIT_TYPES]);
++ printf(" } <= %u", nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX]));
++ }
++ printf(",\n\t\t%s ", indent);
++
++ printf("total <= %d, #channels <= %d%s",
++ nla_get_u32(tb_comb[NL80211_IFACE_COMB_MAXNUM]),
++ nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]),
++ tb_comb[NL80211_IFACE_COMB_STA_AP_BI_MATCH] ?
++ ", STA/AP BI must match" : "");
++ if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]) {
++ unsigned long widths = nla_get_u32(tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]);
++
++ if (widths) {
++ int width;
++ bool first = true;
++
++ printf(", radar detect widths: {");
++ for (width = 0; width < 32; width++)
++ if (widths & (1 << width)) {
++ printf("%s %s",
++ first ? "":",",
++ channel_width_name(width));
++ first = false;
++ }
++ printf(" }\n");
++ }
++ }
++ printf("\n");
++broken_combination:
++ ;
++ }
++
++ if (!have_combinations)
++ printf("\t%sinterface combinations are not supported\n", indent);
++}
++
++static void print_radio_freq(struct nlattr *freqs)
++{
++ struct nlattr *freq;
++ int rem;
++
++ nla_for_each_nested(freq, freqs, rem) {
++ static struct nla_policy freq_policy[NL80211_WIPHY_RADIO_FREQ_ATTR_MAX + 1] = {
++ [NL80211_WIPHY_RADIO_FREQ_ATTR_START] = { .type = NLA_U32 },
++ [NL80211_WIPHY_RADIO_FREQ_ATTR_END] = { .type = NLA_U32 },
++ };
++ struct nlattr *tb[NL80211_WIPHY_RADIO_FREQ_ATTR_MAX + 1];
++ uint32_t start, end;
++
++ if (nla_type(freq) != NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE)
++ continue;
++
++ if (nla_parse_nested(tb, NL80211_WIPHY_RADIO_ATTR_MAX + 1,
++ freq, freq_policy) ||
++ !tb[NL80211_WIPHY_RADIO_FREQ_ATTR_START] ||
++ !tb[NL80211_WIPHY_RADIO_FREQ_ATTR_END])
++ continue;
++
++ start = nla_get_u32(tb[NL80211_WIPHY_RADIO_FREQ_ATTR_START]);
++ end = nla_get_u32(tb[NL80211_WIPHY_RADIO_FREQ_ATTR_END]);
++
++ printf("\t\tfreq range: %.1f MHz - %.1f MHz\n", (float)start / 1000, (float)end / 1000);
++ }
++}
++
++static void print_radios(struct nlattr *radios)
++{
++ struct nlattr *radio;
++ int rem, idx = 0;
++
++ nla_for_each_nested(radio, radios, rem) {
++ static struct nla_policy radio_policy[NL80211_WIPHY_RADIO_ATTR_MAX + 1] = {
++ [NL80211_WIPHY_RADIO_ATTR_INDEX] = { .type = NLA_U32 },
++ };
++ struct nlattr *tb[NL80211_WIPHY_RADIO_ATTR_MAX + 1];
++
++ if (nla_parse_nested(tb, NL80211_WIPHY_RADIO_ATTR_MAX + 1,
++ radio, radio_policy) ||
++ !tb[NL80211_WIPHY_RADIO_ATTR_INDEX])
++ continue;
++
++ printf("\twiphy radio %d:\n", nla_get_u32(tb[NL80211_WIPHY_RADIO_ATTR_INDEX]));
++ print_radio_freq(radio);
++ print_interface_combinations(radio, true);
++ }
++}
++
+ static int print_phy_handler(struct nl_msg *msg, void *arg)
+ {
+ struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
+@@ -565,93 +710,11 @@ next:
+ "\t\t", tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES]);
+ #endif
+
+- if (tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS]) {
+- struct nlattr *nl_combi;
+- int rem_combi;
+- bool have_combinations = false;
+-
+- nla_for_each_nested(nl_combi, tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS], rem_combi) {
+- static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
+- [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
+- [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
+- [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
+- [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
+- [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
+- };
+- struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
+- static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
+- [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
+- [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
+- };
+- struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
+- struct nlattr *nl_limit;
+- int err, rem_limit;
+- bool comma = false;
+-
+- if (!have_combinations) {
+- printf("\tvalid interface combinations:\n");
+- have_combinations = true;
+- }
+-
+- printf("\t\t * ");
++ if (tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS])
++ print_interface_combinations(tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS], false);
+
+- err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
+- nl_combi, iface_combination_policy);
+- if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
+- !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
+- !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
+- printf(" <failed to parse>\n");
+- goto broken_combination;
+- }
+-
+- nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS], rem_limit) {
+- err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
+- nl_limit, iface_limit_policy);
+- if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES]) {
+- printf("<failed to parse>\n");
+- goto broken_combination;
+- }
+-
+- if (comma)
+- printf(", ");
+- comma = true;
+- printf("#{ ");
+- print_iftype_line(tb_limit[NL80211_IFACE_LIMIT_TYPES]);
+- printf(" } <= %u", nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX]));
+- }
+- printf(",\n\t\t ");
+-
+- printf("total <= %d, #channels <= %d%s",
+- nla_get_u32(tb_comb[NL80211_IFACE_COMB_MAXNUM]),
+- nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]),
+- tb_comb[NL80211_IFACE_COMB_STA_AP_BI_MATCH] ?
+- ", STA/AP BI must match" : "");
+- if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]) {
+- unsigned long widths = nla_get_u32(tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]);
+-
+- if (widths) {
+- int width;
+- bool first = true;
+-
+- printf(", radar detect widths: {");
+- for (width = 0; width < 32; width++)
+- if (widths & (1 << width)) {
+- printf("%s %s",
+- first ? "":",",
+- channel_width_name(width));
+- first = false;
+- }
+- printf(" }\n");
+- }
+- }
+- printf("\n");
+-broken_combination:
+- ;
+- }
+-
+- if (!have_combinations)
+- printf("\tinterface combinations are not supported\n");
+- }
++ if (tb_msg[NL80211_ATTR_WIPHY_RADIOS])
++ print_radios(tb_msg[NL80211_ATTR_WIPHY_RADIOS]);
+
+ #ifdef IW_FULL
+ if (tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS]) {
diff --git a/package/network/utils/iw/patches/310-vif_radio_mask.patch b/package/network/utils/iw/patches/310-vif_radio_mask.patch
new file mode 100644
index 0000000..724f71c
--- /dev/null
+++ b/package/network/utils/iw/patches/310-vif_radio_mask.patch
@@ -0,0 +1,99 @@
+--- a/interface.c
++++ b/interface.c
+@@ -226,6 +226,43 @@ nla_put_failure:
+ return 1;
+ }
+
++static int parse_radio_list(char *str, struct nl_msg *msg)
++{
++ unsigned int mask = 0;
++ unsigned long id;
++ char *end;
++
++ if (!str)
++ return 1;
++
++ if (!strcmp(str, "all"))
++ goto out;
++
++ while (1) {
++ if (!*str)
++ return 1;
++
++ id = strtoul(str, &end, 0);
++ if (id > 31)
++ return 1;
++
++ mask |= 1 << id;
++ if (!*end)
++ break;
++
++ if (end == str || *end != ',')
++ return 1;
++
++ str = end + 1;
++ }
++
++out:
++ NLA_PUT_U32(msg, NL80211_ATTR_VIF_RADIO_MASK, mask);
++ return 0;
++nla_put_failure:
++ return 1;
++}
++
+ static int handle_interface_add(struct nl80211_state *state,
+ struct nl_msg *msg,
+ int argc, char **argv,
+@@ -287,6 +324,15 @@ try_another:
+ fprintf(stderr, "flags error\n");
+ return 2;
+ }
++ } else if (strcmp(argv[0], "radios") == 0) {
++ argc--;
++ argv++;
++ if (parse_radio_list(argv[0], msg)) {
++ fprintf(stderr, "Invalid radio list\n");
++ return 2;
++ }
++ argc--;
++ argv++;
+ } else {
+ return 1;
+ }
+@@ -306,14 +352,14 @@ try_another:
+ nla_put_failure:
+ return -ENOBUFS;
+ }
+-COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>]",
++COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>] [radios all|<id>[,<id>...]]",
+ NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add,
+ "Add a new virtual interface with the given configuration.\n"
+ IFACE_TYPES "\n\n"
+ "The flags are only used for monitor interfaces, valid flags are:\n"
+ VALID_FLAGS "\n\n"
+ "The mesh_id is used only for mesh mode.");
+-COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>]",
++COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>] [radios all|<id>[,<id>...]]",
+ NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add, NULL);
+
+ static int handle_interface_del(struct nl80211_state *state,
+@@ -493,6 +539,19 @@ static int print_iface_handler(struct nl
+ printf("\n");
+ }
+ }
++
++ if (tb_msg[NL80211_ATTR_VIF_RADIO_MASK]) {
++ uint32_t mask = nla_get_u32(tb_msg[NL80211_ATTR_VIF_RADIO_MASK]);
++ int i;
++
++ if (mask) {
++ printf("%s\tRadios:", indent);
++ for (i = 0; mask; i++, mask >>= 1)
++ if (mask & 1)
++ printf(" %d", i);
++ printf("\n");
++ }
++ }
+
+ return NL_SKIP;
+ }
diff --git a/package/network/utils/iwcap/Makefile b/package/network/utils/iwcap/Makefile
new file mode 100644
index 0000000..7b43d62
--- /dev/null
+++ b/package/network/utils/iwcap/Makefile
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2012 Jo-Philipp Wich <jo@mein.io>
+#
+# This is free software, licensed under the Apache 2 license.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=iwcap
+PKG_RELEASE:=1
+PKG_LICENSE:=Apache-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define Package/iwcap
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Simple radiotap capture utility
+ MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
+endef
+
+define Package/iwcap/description
+ The iwcap utility receives radiotap packet data from wifi monitor interfaces
+ and outputs it to pcap format. It gathers recived packets in a fixed ring
+ buffer to dump them on demand which is useful for background monitoring.
+ Alternatively the utility can stream the data to stdout to act as remote
+ capture drone for Wireshark or similar programs.
+endef
+
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(TARGET_CC) $(TARGET_CFLAGS) \
+ -o $(PKG_BUILD_DIR)/iwcap $(PKG_BUILD_DIR)/iwcap.c
+endef
+
+
+define Package/iwcap/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwcap $(1)/usr/sbin/iwcap
+endef
+
+$(eval $(call BuildPackage,iwcap))
diff --git a/package/network/utils/iwcap/src/iwcap.c b/package/network/utils/iwcap/src/iwcap.c
new file mode 100644
index 0000000..bc69550
--- /dev/null
+++ b/package/network/utils/iwcap/src/iwcap.c
@@ -0,0 +1,583 @@
+/*
+ * iwcap.c - A simply radiotap capture utility outputting pcap dumps
+ *
+ * Copyright 2012 Jo-Philipp Wich <jo@mein.io>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <syslog.h>
+#include <errno.h>
+#include <byteswap.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <linux/if_packet.h>
+
+#define ARPHRD_IEEE80211_RADIOTAP 803
+
+#define DLT_IEEE802_11_RADIO 127
+#define LEN_IEEE802_11_HDR 32
+
+#define FRAMETYPE_MASK 0xFC
+#define FRAMETYPE_BEACON 0x80
+#define FRAMETYPE_DATA 0x08
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define le16(x) __bswap_16(x)
+#else
+#define le16(x) (x)
+#endif
+
+uint8_t run_dump = 0;
+uint8_t run_stop = 0;
+uint8_t run_daemon = 0;
+
+uint32_t frames_captured = 0;
+uint32_t frames_filtered = 0;
+
+int capture_sock = -1;
+const char *ifname = NULL;
+
+
+struct ringbuf {
+ uint32_t len; /* number of slots */
+ uint32_t fill; /* last used slot */
+ uint32_t slen; /* slot size */
+ void *buf; /* ring memory */
+};
+
+struct ringbuf_entry {
+ uint32_t len; /* used slot memory */
+ uint32_t olen; /* original data size */
+ uint32_t sec; /* epoch of slot creation */
+ uint32_t usec; /* epoch microseconds */
+};
+
+typedef struct pcap_hdr_s {
+ uint32_t magic_number; /* magic number */
+ uint16_t version_major; /* major version number */
+ uint16_t version_minor; /* minor version number */
+ int32_t thiszone; /* GMT to local correction */
+ uint32_t sigfigs; /* accuracy of timestamps */
+ uint32_t snaplen; /* max length of captured packets, in octets */
+ uint32_t network; /* data link type */
+} pcap_hdr_t;
+
+typedef struct pcaprec_hdr_s {
+ uint32_t ts_sec; /* timestamp seconds */
+ uint32_t ts_usec; /* timestamp microseconds */
+ uint32_t incl_len; /* number of octets of packet saved in file */
+ uint32_t orig_len; /* actual length of packet */
+} pcaprec_hdr_t;
+
+typedef struct ieee80211_radiotap_header {
+ u_int8_t it_version; /* set to 0 */
+ u_int8_t it_pad;
+ u_int16_t it_len; /* entire length */
+ u_int32_t it_present; /* fields present */
+} __attribute__((__packed__)) radiotap_hdr_t;
+
+
+int check_type(void)
+{
+ struct ifreq ifr;
+
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+ if (ioctl(capture_sock, SIOCGIFHWADDR, &ifr) < 0)
+ return -1;
+
+ return (ifr.ifr_hwaddr.sa_family == ARPHRD_IEEE80211_RADIOTAP);
+}
+
+int set_promisc(int on)
+{
+ struct ifreq ifr;
+
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+ if (ioctl(capture_sock, SIOCGIFFLAGS, &ifr) < 0)
+ return -1;
+
+ if (on && !(ifr.ifr_flags & IFF_PROMISC))
+ {
+ ifr.ifr_flags |= IFF_PROMISC;
+
+ if (ioctl(capture_sock, SIOCSIFFLAGS, &ifr))
+ return -1;
+
+ return 1;
+ }
+ else if (!on && (ifr.ifr_flags & IFF_PROMISC))
+ {
+ ifr.ifr_flags &= ~IFF_PROMISC;
+
+ if (ioctl(capture_sock, SIOCSIFFLAGS, &ifr))
+ return -1;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+void sig_dump(int sig)
+{
+ run_dump = 1;
+}
+
+void sig_teardown(int sig)
+{
+ run_stop = 1;
+}
+
+
+void write_pcap_header(FILE *o)
+{
+ pcap_hdr_t ghdr = {
+ .magic_number = 0xa1b2c3d4,
+ .version_major = 2,
+ .version_minor = 4,
+ .thiszone = 0,
+ .sigfigs = 0,
+ .snaplen = 0xFFFF,
+ .network = DLT_IEEE802_11_RADIO
+ };
+
+ fwrite(&ghdr, 1, sizeof(ghdr), o);
+}
+
+void write_pcap_frame(FILE *o, uint32_t *sec, uint32_t *usec,
+ uint16_t len, uint16_t olen)
+{
+ struct timeval tv;
+ pcaprec_hdr_t fhdr;
+
+ if (!sec || !usec)
+ {
+ gettimeofday(&tv, NULL);
+ }
+ else
+ {
+ tv.tv_sec = *sec;
+ tv.tv_usec = *usec;
+ }
+
+ fhdr.ts_sec = tv.tv_sec;
+ fhdr.ts_usec = tv.tv_usec;
+ fhdr.incl_len = len;
+ fhdr.orig_len = olen;
+
+ fwrite(&fhdr, 1, sizeof(fhdr), o);
+}
+
+
+struct ringbuf * ringbuf_init(uint32_t num_item, uint16_t len_item)
+{
+ static struct ringbuf r;
+
+ if (len_item <= 0)
+ return NULL;
+
+ r.buf = malloc(num_item * (len_item + sizeof(struct ringbuf_entry)));
+
+ if (r.buf)
+ {
+ r.len = num_item;
+ r.fill = 0;
+ r.slen = (len_item + sizeof(struct ringbuf_entry));
+
+ memset(r.buf, 0, num_item * len_item);
+
+ return &r;
+ }
+
+ return NULL;
+}
+
+struct ringbuf_entry * ringbuf_add(struct ringbuf *r)
+{
+ struct timeval t;
+ struct ringbuf_entry *e;
+
+ gettimeofday(&t, NULL);
+
+ e = r->buf + (r->fill++ * r->slen);
+ r->fill %= r->len;
+
+ memset(e, 0, r->slen);
+
+ e->sec = t.tv_sec;
+ e->usec = t.tv_usec;
+
+ return e;
+}
+
+struct ringbuf_entry * ringbuf_get(struct ringbuf *r, int i)
+{
+ struct ringbuf_entry *e = r->buf + (((r->fill + i) % r->len) * r->slen);
+
+ if (e->len > 0)
+ return e;
+
+ return NULL;
+}
+
+void ringbuf_free(struct ringbuf *r)
+{
+ free(r->buf);
+ memset(r, 0, sizeof(*r));
+}
+
+
+void msg(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+ if (run_daemon)
+ vsyslog(LOG_INFO | LOG_USER, fmt, ap);
+ else
+ vfprintf(stderr, fmt, ap);
+
+ va_end(ap);
+}
+
+
+int main(int argc, char **argv)
+{
+ int i, n;
+ struct ringbuf *ring;
+ struct ringbuf_entry *e;
+ struct sockaddr_ll local = {
+ .sll_family = AF_PACKET,
+ .sll_protocol = htons(ETH_P_ALL)
+ };
+
+ radiotap_hdr_t *rhdr;
+
+ uint8_t frametype;
+ uint8_t pktbuf[0xFFFF];
+ ssize_t pktlen;
+
+ FILE *o;
+
+ int opt;
+
+ uint8_t promisc = 0;
+ uint8_t streaming = 0;
+ uint8_t foreground = 0;
+ uint8_t filter_data = 0;
+ uint8_t filter_beacon = 0;
+ uint8_t header_written = 0;
+
+ uint32_t ringsz = 1024 * 1024; /* 1 Mbyte ring buffer */
+ uint16_t pktcap = 256; /* truncate frames after 265KB */
+
+ const char *output = NULL;
+
+
+ while ((opt = getopt(argc, argv, "i:r:c:o:sfhBD")) != -1)
+ {
+ switch (opt)
+ {
+ case 'i':
+ ifname = optarg;
+ if (!(local.sll_ifindex = if_nametoindex(ifname)))
+ {
+ msg("Unknown interface '%s'\n", ifname);
+ return 2;
+ }
+ break;
+
+ case 'r':
+ ringsz = atoi(optarg);
+ if (ringsz < (3 * pktcap))
+ {
+ msg("Ring size of %d bytes is too short, "
+ "must be at least %d bytes\n", ringsz, 3 * pktcap);
+ return 3;
+ }
+ break;
+
+ case 'c':
+ pktcap = atoi(optarg);
+ if (pktcap <= (sizeof(radiotap_hdr_t) + LEN_IEEE802_11_HDR))
+ {
+ msg("Packet truncate after %d bytes is too short, "
+ "must be at least %d bytes\n",
+ pktcap, sizeof(radiotap_hdr_t) + LEN_IEEE802_11_HDR);
+ return 4;
+ }
+ break;
+
+ case 's':
+ streaming = 1;
+ break;
+
+ case 'o':
+ output = optarg;
+ break;
+
+ case 'B':
+ filter_beacon = 1;
+ break;
+
+ case 'D':
+ filter_data = 1;
+ break;
+
+ case 'f':
+ foreground = 1;
+ break;
+
+ case 'h':
+ msg(
+ "Usage:\n"
+ " %s -i {iface} -s [-b] [-d]\n"
+ " %s -i {iface} -o {file} [-r len] [-c len] [-B] [-D] [-f]\n"
+ "\n"
+ " -i iface\n"
+ " Specify interface to use, must be in monitor mode and\n"
+ " produce IEEE 802.11 Radiotap headers.\n\n"
+ " -s\n"
+ " Stream to stdout instead of Dumping to file on USR1.\n\n"
+ " -o file\n"
+ " Write current ringbuffer contents to given output file\n"
+ " on receipt of SIGUSR1.\n\n"
+ " -r len\n"
+ " Specify the amount of bytes to use for the ringbuffer.\n"
+ " The default length is %d bytes.\n\n"
+ " -c len\n"
+ " Truncate captured packets after given amount of bytes.\n"
+ " The default size limit is %d bytes.\n\n"
+ " -B\n"
+ " Don't store beacon frames in ring, default is keep.\n\n"
+ " -D\n"
+ " Don't store data frames in ring, default is keep.\n\n"
+ " -f\n"
+ " Do not daemonize but keep running in foreground.\n\n"
+ " -h\n"
+ " Display this help.\n\n",
+ argv[0], argv[0], ringsz, pktcap);
+
+ return 1;
+ }
+ }
+
+ if (!streaming && !output)
+ {
+ msg("No output file specified\n");
+ return 1;
+ }
+
+ if (streaming && output)
+ {
+ msg("The -s and -o options are exclusive\n");
+ return 1;
+ }
+
+ if (streaming && isatty(1))
+ {
+ msg("Refusing to stream into a terminal\n");
+ return 1;
+ }
+
+ if (!local.sll_ifindex)
+ {
+ msg("No interface specified\n");
+ return 2;
+ }
+
+ if (!check_type())
+ {
+ msg("Bad interface: not ARPHRD_IEEE80211_RADIOTAP\n");
+ return 2;
+ }
+
+ if ((capture_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0)
+ {
+ msg("Unable to create raw socket: %s\n",
+ strerror(errno));
+ return 6;
+ }
+
+ if (bind(capture_sock, (struct sockaddr *)&local, sizeof(local)) == -1)
+ {
+ msg("Unable to bind to interface: %s\n",
+ strerror(errno));
+ return 7;
+ }
+
+ if (!streaming)
+ {
+ if (!foreground)
+ {
+ switch (fork())
+ {
+ case -1:
+ msg("Unable to fork: %s\n", strerror(errno));
+ return 8;
+
+ case 0:
+ umask(0077);
+ chdir("/");
+ freopen("/dev/null", "r", stdin);
+ freopen("/dev/null", "w", stdout);
+ freopen("/dev/null", "w", stderr);
+ run_daemon = 1;
+ break;
+
+ default:
+ msg("Daemon launched ...\n");
+ return 0;
+ }
+ }
+
+ msg("Monitoring interface %s ...\n", ifname);
+
+ if (!(ring = ringbuf_init(ringsz / pktcap, pktcap)))
+ {
+ msg("Unable to allocate ring buffer: %s\n",
+ strerror(errno));
+ return 5;
+ }
+
+ msg(" * Using %d bytes ringbuffer with %d slots\n", ringsz, ring->len);
+ msg(" * Truncating frames at %d bytes\n", pktcap);
+ msg(" * Dumping data to file %s\n", output);
+
+ signal(SIGUSR1, sig_dump);
+ }
+ else
+ {
+ msg("Monitoring interface %s ...\n", ifname);
+ msg(" * Streaming data to stdout\n");
+ }
+
+ msg(" * Beacon frames are %sfiltered\n", filter_beacon ? "" : "not ");
+ msg(" * Data frames are %sfiltered\n", filter_data ? "" : "not ");
+
+ signal(SIGINT, sig_teardown);
+ signal(SIGTERM, sig_teardown);
+
+ promisc = set_promisc(1);
+
+ /* capture loop */
+ while (1)
+ {
+ if (run_dump)
+ {
+ msg("Dumping ring to %s ...\n", output);
+
+ if (!(o = fopen(output, "w")))
+ {
+ msg("Unable to open %s: %s\n",
+ output, strerror(errno));
+ }
+ else
+ {
+ write_pcap_header(o);
+
+ /* sig_dump packet buffer */
+ for (i = 0, n = 0; i < ring->len; i++)
+ {
+ if (!(e = ringbuf_get(ring, i)))
+ continue;
+
+ write_pcap_frame(o, &(e->sec), &(e->usec), e->len, e->olen);
+ fwrite((void *)e + sizeof(*e), 1, e->len, o);
+ n++;
+ }
+
+ fclose(o);
+
+ msg(" * %d frames captured\n", frames_captured);
+ msg(" * %d frames filtered\n", frames_filtered);
+ msg(" * %d frames dumped\n", n);
+ }
+
+ run_dump = 0;
+ }
+ if (run_stop)
+ {
+ msg("Shutting down ...\n");
+
+ if (promisc)
+ set_promisc(0);
+
+ if (ring)
+ ringbuf_free(ring);
+
+ return 0;
+ }
+
+ pktlen = recvfrom(capture_sock, pktbuf, sizeof(pktbuf), 0, NULL, 0);
+ frames_captured++;
+
+ /* check received frametype, if we should filter it, rewind the ring */
+ rhdr = (radiotap_hdr_t *)pktbuf;
+
+ if (pktlen <= sizeof(radiotap_hdr_t) || le16(rhdr->it_len) >= pktlen)
+ {
+ frames_filtered++;
+ continue;
+ }
+
+ frametype = *(uint8_t *)(pktbuf + le16(rhdr->it_len));
+
+ if ((filter_data && (frametype & FRAMETYPE_MASK) == FRAMETYPE_DATA) ||
+ (filter_beacon && (frametype & FRAMETYPE_MASK) == FRAMETYPE_BEACON))
+ {
+ frames_filtered++;
+ continue;
+ }
+
+ if (streaming)
+ {
+ if (!header_written)
+ {
+ write_pcap_header(stdout);
+ header_written = 1;
+ }
+
+ write_pcap_frame(stdout, NULL, NULL, pktlen, pktlen);
+ fwrite(pktbuf, 1, pktlen, stdout);
+ fflush(stdout);
+ }
+ else
+ {
+ e = ringbuf_add(ring);
+ e->olen = pktlen;
+ e->len = (pktlen > pktcap) ? pktcap : pktlen;
+
+ memcpy((void *)e + sizeof(*e), pktbuf, e->len);
+ }
+ }
+
+ return 0;
+}
diff --git a/package/network/utils/iwinfo/Makefile b/package/network/utils/iwinfo/Makefile
new file mode 100644
index 0000000..9055fa2
--- /dev/null
+++ b/package/network/utils/iwinfo/Makefile
@@ -0,0 +1,121 @@
+#
+# Copyright (C) 2010-2016 Jo-Philipp Wich <jo@mein.io>
+#
+# This is free software, licensed under the GPL 2 license.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libiwinfo
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=$(PROJECT_GIT)/project/iwinfo.git
+PKG_SOURCE_DATE:=2024-10-20
+PKG_SOURCE_VERSION:=b94f066e3f5839b8509483cdd8f4f582a45fa233
+PKG_MIRROR_HASH:=a29bd61d17e4f2d21a3c89fdd6a9776dbefad1396ede7cd0a8813506e35f73b8
+PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
+PKG_LICENSE:=GPL-2.0
+
+PKG_BUILD_FLAGS:=no-lto
+
+IWINFO_ABI_VERSION:=20230701
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define Package/libiwinfo
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=Generalized Wireless Information Library (iwinfo)
+ DEPENDS:=+libnl-tiny +libuci +libubus +libiwinfo-data
+ ABI_VERSION:=$(IWINFO_ABI_VERSION)
+endef
+
+define Package/libiwinfo/description
+ Wireless information library with simplified API for nl80211
+ and wext driver interfaces.
+endef
+
+
+define Package/libiwinfo-lua
+ SUBMENU:=Lua
+ SECTION:=lang
+ CATEGORY:=Languages
+ TITLE:=libiwinfo Lua binding
+ DEPENDS:=+libiwinfo +liblua
+endef
+
+define Package/libiwinfo-lua/description
+ This is the Lua binding for the iwinfo library. It provides access to all enabled
+ backends.
+endef
+
+
+define Package/libiwinfo-data
+ TITLE:=libiwinfo Lua binding
+ HIDDEN:=1
+endef
+
+
+define Package/iwinfo
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Generalized Wireless Information utility
+ DEPENDS:=+libiwinfo
+endef
+
+define Package/iwinfo/description
+ Command line frontend for the wireless information library.
+endef
+
+
+define Build/Configure
+endef
+
+TARGET_CFLAGS += \
+ -I$(STAGING_DIR)/usr/include/libnl-tiny \
+ -I$(STAGING_DIR)/usr/include \
+ -D_GNU_SOURCE
+
+MAKE_FLAGS += \
+ FPIC="$(FPIC)" \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ LDFLAGS="$(TARGET_LDFLAGS)" \
+ BACKENDS="nl80211" \
+ SOVERSION="$(IWINFO_ABI_VERSION)"
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include/iwinfo
+ $(CP) $(PKG_BUILD_DIR)/include/iwinfo.h $(1)/usr/include/
+ $(CP) $(PKG_BUILD_DIR)/include/iwinfo/* $(1)/usr/include/iwinfo/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/libiwinfo.so* $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/lib/lua
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo.so $(1)/usr/lib/lua/iwinfo.so
+endef
+
+define Package/libiwinfo/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/libiwinfo.so.$(IWINFO_ABI_VERSION) $(1)/usr/lib/libiwinfo.so.$(IWINFO_ABI_VERSION)
+endef
+
+define Package/libiwinfo-lua/install
+ $(INSTALL_DIR) $(1)/usr/lib/lua
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo.so $(1)/usr/lib/lua/iwinfo.so
+endef
+
+define Package/libiwinfo-data/install
+ $(INSTALL_DIR) $(1)/usr/share/libiwinfo
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/devices.txt $(1)/usr/share/libiwinfo/devices.txt
+endef
+
+define Package/iwinfo/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo $(1)/usr/bin/iwinfo
+endef
+
+$(eval $(call BuildPackage,libiwinfo))
+$(eval $(call BuildPackage,libiwinfo-lua))
+$(eval $(call BuildPackage,libiwinfo-data))
+$(eval $(call BuildPackage,iwinfo))
diff --git a/package/network/utils/iwinfo/patches/100-multi_radio.patch b/package/network/utils/iwinfo/patches/100-multi_radio.patch
new file mode 100644
index 0000000..3ad3b4f
--- /dev/null
+++ b/package/network/utils/iwinfo/patches/100-multi_radio.patch
@@ -0,0 +1,1498 @@
+--- a/api/nl80211.h
++++ b/api/nl80211.h
+@@ -11,7 +11,7 @@
+ * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
+ * Copyright 2008 Colin McCabe <colin@cozybit.com>
+ * Copyright 2015-2017 Intel Deutschland GmbH
+- * Copyright (C) 2018-2023 Intel Corporation
++ * Copyright (C) 2018-2024 Intel Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+@@ -72,7 +72,7 @@
+ * For drivers supporting TDLS with external setup (WIPHY_FLAG_SUPPORTS_TDLS
+ * and WIPHY_FLAG_TDLS_EXTERNAL_SETUP), the station lifetime is as follows:
+ * - a setup station entry is added, not yet authorized, without any rate
+- * or capability information, this just exists to avoid race conditions
++ * or capability information; this just exists to avoid race conditions
+ * - when the TDLS setup is done, a single NL80211_CMD_SET_STATION is valid
+ * to add rate and capability information to the station and at the same
+ * time mark it authorized.
+@@ -87,7 +87,7 @@
+ * DOC: Frame transmission/registration support
+ *
+ * Frame transmission and registration support exists to allow userspace
+- * management entities such as wpa_supplicant react to management frames
++ * management entities such as wpa_supplicant to react to management frames
+ * that are not being handled by the kernel. This includes, for example,
+ * certain classes of action frames that cannot be handled in the kernel
+ * for various reasons.
+@@ -113,7 +113,7 @@
+ *
+ * Frame transmission allows userspace to send for example the required
+ * responses to action frames. It is subject to some sanity checking,
+- * but many frames can be transmitted. When a frame was transmitted, its
++ * but many frames can be transmitted. When a frame is transmitted, its
+ * status is indicated to the sending socket.
+ *
+ * For more technical details, see the corresponding command descriptions
+@@ -123,7 +123,7 @@
+ /**
+ * DOC: Virtual interface / concurrency capabilities
+ *
+- * Some devices are able to operate with virtual MACs, they can have
++ * Some devices are able to operate with virtual MACs; they can have
+ * more than one virtual interface. The capability handling for this
+ * is a bit complex though, as there may be a number of restrictions
+ * on the types of concurrency that are supported.
+@@ -135,7 +135,7 @@
+ * Once concurrency is desired, more attributes must be observed:
+ * To start with, since some interface types are purely managed in
+ * software, like the AP-VLAN type in mac80211 for example, there's
+- * an additional list of these, they can be added at any time and
++ * an additional list of these; they can be added at any time and
+ * are only restricted by some semantic restrictions (e.g. AP-VLAN
+ * cannot be added without a corresponding AP interface). This list
+ * is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute.
+@@ -164,17 +164,17 @@
+ * Packet coalesce feature helps to reduce number of received interrupts
+ * to host by buffering these packets in firmware/hardware for some
+ * predefined time. Received interrupt will be generated when one of the
+- * following events occur.
++ * following events occurs.
+ * a) Expiration of hardware timer whose expiration time is set to maximum
+ * coalescing delay of matching coalesce rule.
+- * b) Coalescing buffer in hardware reaches it's limit.
++ * b) Coalescing buffer in hardware reaches its limit.
+ * c) Packet doesn't match any of the configured coalesce rules.
+ *
+ * User needs to configure following parameters for creating a coalesce
+ * rule.
+ * a) Maximum coalescing delay
+ * b) List of packet patterns which needs to be matched
+- * c) Condition for coalescence. pattern 'match' or 'no match'
++ * c) Condition for coalescence: pattern 'match' or 'no match'
+ * Multiple such rules can be created.
+ */
+
+@@ -213,7 +213,7 @@
+ /**
+ * DOC: FILS shared key authentication offload
+ *
+- * FILS shared key authentication offload can be advertized by drivers by
++ * FILS shared key authentication offload can be advertised by drivers by
+ * setting @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD flag. The drivers that support
+ * FILS shared key authentication offload should be able to construct the
+ * authentication and association frames for FILS shared key authentication and
+@@ -239,7 +239,7 @@
+ * The PMKSA can be maintained in userspace persistently so that it can be used
+ * later after reboots or wifi turn off/on also.
+ *
+- * %NL80211_ATTR_FILS_CACHE_ID is the cache identifier advertized by a FILS
++ * %NL80211_ATTR_FILS_CACHE_ID is the cache identifier advertised by a FILS
+ * capable AP supporting PMK caching. It specifies the scope within which the
+ * PMKSAs are cached in an ESS. %NL80211_CMD_SET_PMKSA and
+ * %NL80211_CMD_DEL_PMKSA are enhanced to allow support for PMKSA caching based
+@@ -290,12 +290,12 @@
+ * If the configuration needs to be applied for specific peer then the MAC
+ * address of the peer needs to be passed in %NL80211_ATTR_MAC, otherwise the
+ * configuration will be applied for all the connected peers in the vif except
+- * any peers that have peer specific configuration for the TID by default; if
+- * the %NL80211_TID_CONFIG_ATTR_OVERRIDE flag is set, peer specific values
++ * any peers that have peer-specific configuration for the TID by default; if
++ * the %NL80211_TID_CONFIG_ATTR_OVERRIDE flag is set, peer-specific values
+ * will be overwritten.
+ *
+- * All this configuration is valid only for STA's current connection
+- * i.e. the configuration will be reset to default when the STA connects back
++ * All this configuration is valid only for STA's current connection,
++ * i.e., the configuration will be reset to default when the STA connects back
+ * after disconnection/roaming, and this configuration will be cleared when
+ * the interface goes down.
+ */
+@@ -326,7 +326,7 @@
+ /**
+ * DOC: Multi-Link Operation
+ *
+- * In Multi-Link Operation, a connection between to MLDs utilizes multiple
++ * In Multi-Link Operation, a connection between two MLDs utilizes multiple
+ * links. To use this in nl80211, various commands and responses now need
+ * to or will include the new %NL80211_ATTR_MLO_LINKS attribute.
+ * Additionally, various commands that need to operate on a specific link
+@@ -335,6 +335,15 @@
+ */
+
+ /**
++ * DOC: OWE DH IE handling offload
++ *
++ * By setting @NL80211_EXT_FEATURE_OWE_OFFLOAD flag, drivers can indicate
++ * kernel/application space to avoid DH IE handling. When this flag is
++ * advertised, the driver/device will take care of DH IE inclusion and
++ * processing of peer DH IE to generate PMK.
++ */
++
++/**
+ * enum nl80211_commands - supported nl80211 commands
+ *
+ * @NL80211_CMD_UNSPEC: unspecified command to catch errors
+@@ -404,8 +413,8 @@
+ * are like for %NL80211_CMD_SET_BEACON, and additionally parameters that
+ * do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL,
+ * %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID,
+- * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
+- * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
++ * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
++ * %NL80211_ATTR_CIPHER_SUITE_GROUP, %NL80211_ATTR_WPA_VERSIONS,
+ * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
+ * %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT,
+ * %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS.
+@@ -429,23 +438,19 @@
+ * %NL80211_ATTR_REASON_CODE can optionally be used to specify which type
+ * of disconnection indication should be sent to the station
+ * (Deauthentication or Disassociation frame and reason code for that
+- * frame).
++ * frame). %NL80211_ATTR_MLO_LINK_ID can be used optionally to remove
++ * stations connected and using at least that link as one of its links.
+ *
+ * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to
+- * destination %NL80211_ATTR_MAC on the interface identified by
+- * %NL80211_ATTR_IFINDEX.
++ * destination %NL80211_ATTR_MAC on the interface identified by
++ * %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_MPATH: Set mesh path attributes for mesh path to
+- * destination %NL80211_ATTR_MAC on the interface identified by
+- * %NL80211_ATTR_IFINDEX.
++ * destination %NL80211_ATTR_MAC on the interface identified by
++ * %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_MPATH: Create a new mesh path for the destination given by
+ * %NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP.
+ * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by
+ * %NL80211_ATTR_MAC.
+- * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the
+- * interface identified by %NL80211_ATTR_IFINDEX.
+- * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC
+- * or, if no MAC address given, all mesh paths, on the interface identified
+- * by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by
+ * %NL80211_ATTR_IFINDEX.
+ *
+@@ -466,15 +471,15 @@
+ * after being queried by the kernel. CRDA replies by sending a regulatory
+ * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
+ * current alpha2 if it found a match. It also provides
+- * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each
+- * regulatory rule is a nested set of attributes given by
+- * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and
+- * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by
+- * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and
+- * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP.
++ * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each
++ * regulatory rule is a nested set of attributes given by
++ * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and
++ * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by
++ * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and
++ * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP.
+ * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain
+- * to the specified ISO/IEC 3166-1 alpha2 country code. The core will
+- * store this as a valid request and then query userspace for it.
++ * to the specified ISO/IEC 3166-1 alpha2 country code. The core will
++ * store this as a valid request and then query userspace for it.
+ *
+ * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the
+ * interface identified by %NL80211_ATTR_IFINDEX
+@@ -512,7 +517,7 @@
+ * %NL80211_ATTR_SCHED_SCAN_PLANS. If %NL80211_ATTR_SCHED_SCAN_PLANS is
+ * not specified and only %NL80211_ATTR_SCHED_SCAN_INTERVAL is specified,
+ * scheduled scan will run in an infinite loop with the specified interval.
+- * These attributes are mutually exculsive,
++ * These attributes are mutually exclusive,
+ * i.e. NL80211_ATTR_SCHED_SCAN_INTERVAL must not be passed if
+ * NL80211_ATTR_SCHED_SCAN_PLANS is defined.
+ * If for some reason scheduled scan is aborted by the driver, all scan
+@@ -543,7 +548,7 @@
+ * %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface
+ * is brought down while a scheduled scan was running.
+ *
+- * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
++ * @NL80211_CMD_GET_SURVEY: get survey results, e.g. channel occupation
+ * or noise level
+ * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
+ * NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
+@@ -554,40 +559,41 @@
+ * using %NL80211_ATTR_SSID, %NL80211_ATTR_FILS_CACHE_ID,
+ * %NL80211_ATTR_PMKID, and %NL80211_ATTR_PMK in case of FILS
+ * authentication where %NL80211_ATTR_FILS_CACHE_ID is the identifier
+- * advertized by a FILS capable AP identifying the scope of PMKSA in an
++ * advertised by a FILS capable AP identifying the scope of PMKSA in an
+ * ESS.
+ * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC
+ * (for the BSSID) and %NL80211_ATTR_PMKID or using %NL80211_ATTR_SSID,
+ * %NL80211_ATTR_FILS_CACHE_ID, and %NL80211_ATTR_PMKID in case of FILS
+- * authentication.
++ * authentication. Additionally in case of SAE offload and OWE offloads
++ * PMKSA entry can be deleted using %NL80211_ATTR_SSID.
+ * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries.
+ *
+ * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
+- * has been changed and provides details of the request information
+- * that caused the change such as who initiated the regulatory request
+- * (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx
+- * (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if
+- * the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or
+- * %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain
+- * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
+- * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
+- * to (%NL80211_ATTR_REG_ALPHA2).
++ * has been changed and provides details of the request information
++ * that caused the change such as who initiated the regulatory request
++ * (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx
++ * (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if
++ * the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or
++ * %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain
++ * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
++ * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
++ * to (%NL80211_ATTR_REG_ALPHA2).
+ * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon
+- * has been found while world roaming thus enabling active scan or
+- * any mode of operation that initiates TX (beacons) on a channel
+- * where we would not have been able to do either before. As an example
+- * if you are world roaming (regulatory domain set to world or if your
+- * driver is using a custom world roaming regulatory domain) and while
+- * doing a passive scan on the 5 GHz band you find an AP there (if not
+- * on a DFS channel) you will now be able to actively scan for that AP
+- * or use AP mode on your card on that same channel. Note that this will
+- * never be used for channels 1-11 on the 2 GHz band as they are always
+- * enabled world wide. This beacon hint is only sent if your device had
+- * either disabled active scanning or beaconing on a channel. We send to
+- * userspace the wiphy on which we removed a restriction from
+- * (%NL80211_ATTR_WIPHY) and the channel on which this occurred
+- * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER)
+- * the beacon hint was processed.
++ * has been found while world roaming thus enabling active scan or
++ * any mode of operation that initiates TX (beacons) on a channel
++ * where we would not have been able to do either before. As an example
++ * if you are world roaming (regulatory domain set to world or if your
++ * driver is using a custom world roaming regulatory domain) and while
++ * doing a passive scan on the 5 GHz band you find an AP there (if not
++ * on a DFS channel) you will now be able to actively scan for that AP
++ * or use AP mode on your card on that same channel. Note that this will
++ * never be used for channels 1-11 on the 2 GHz band as they are always
++ * enabled world wide. This beacon hint is only sent if your device had
++ * either disabled active scanning or beaconing on a channel. We send to
++ * userspace the wiphy on which we removed a restriction from
++ * (%NL80211_ATTR_WIPHY) and the channel on which this occurred
++ * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER)
++ * the beacon hint was processed.
+ *
+ * @NL80211_CMD_AUTHENTICATE: authentication request and notification.
+ * This command is used both as a command (request to authenticate) and
+@@ -598,7 +604,7 @@
+ * BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify
+ * the SSID (mainly for association, but is included in authentication
+ * request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ +
+- * %NL80211_ATTR_WIPHY_FREQ_OFFSET is used to specify the frequence of the
++ * %NL80211_ATTR_WIPHY_FREQ_OFFSET is used to specify the frequency of the
+ * channel in MHz. %NL80211_ATTR_AUTH_TYPE is used to specify the
+ * authentication type. %NL80211_ATTR_IE is used to define IEs
+ * (VendorSpecificInfo, but also including RSN IE and FT IEs) to be added
+@@ -807,7 +813,7 @@
+ * reached.
+ * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
+ * and the attributes determining channel width) the given interface
+- * (identifed by %NL80211_ATTR_IFINDEX) shall operate on.
++ * (identified by %NL80211_ATTR_IFINDEX) shall operate on.
+ * In case multiple channels are supported by the device, the mechanism
+ * with which it switches channels is implementation-defined.
+ * When a monitor interface is given, it can only switch channel while
+@@ -879,7 +885,7 @@
+ * inform userspace of the new replay counter.
+ *
+ * @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace
+- * of PMKSA caching dandidates.
++ * of PMKSA caching candidates.
+ *
+ * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
+ * In addition, this can be used as an event to request userspace to take
+@@ -915,7 +921,7 @@
+ *
+ * @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface
+ * by sending a null data frame to it and reporting when the frame is
+- * acknowleged. This is used to allow timing out inactive clients. Uses
++ * acknowledged. This is used to allow timing out inactive clients. Uses
+ * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a
+ * direct reply with an %NL80211_ATTR_COOKIE that is later used to match
+ * up the event with the request. The event includes the same data and
+@@ -1109,7 +1115,7 @@
+ * current configuration is not changed. If it is present but
+ * set to zero, the configuration is changed to don't-care
+ * (i.e. the device can decide what to do).
+- * @NL80211_CMD_NAN_FUNC_MATCH: Notification sent when a match is reported.
++ * @NL80211_CMD_NAN_MATCH: Notification sent when a match is reported.
+ * This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
+ * %NL80211_ATTR_COOKIE.
+ *
+@@ -1126,11 +1132,15 @@
+ * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously
+ * configured PMK for the authenticator address identified by
+ * %NL80211_ATTR_MAC.
+- * @NL80211_CMD_PORT_AUTHORIZED: An event that indicates an 802.1X FT roam was
+- * completed successfully. Drivers that support 4 way handshake offload
+- * should send this event after indicating 802.1X FT assocation with
+- * %NL80211_CMD_ROAM. If the 4 way handshake failed %NL80211_CMD_DISCONNECT
+- * should be indicated instead.
++ * @NL80211_CMD_PORT_AUTHORIZED: An event that indicates port is authorized and
++ * open for regular data traffic. For STA/P2P-client, this event is sent
++ * with AP MAC address and for AP/P2P-GO, the event carries the STA/P2P-
++ * client MAC address.
++ * Drivers that support 4 way handshake offload should send this event for
++ * STA/P2P-client after successful 4-way HS or after 802.1X FT following
++ * NL80211_CMD_CONNECT or NL80211_CMD_ROAM. Drivers using AP/P2P-GO 4-way
++ * handshake offload should send this event on successful completion of
++ * 4-way handshake with the peer (STA/P2P-client).
+ * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
+ * and RX notification. This command is used both as a request to transmit
+ * a control port frame and as a notification that a control port frame
+@@ -1314,6 +1324,11 @@
+ * Multi-Link reconfiguration. %NL80211_ATTR_MLO_LINKS is used to provide
+ * information about the removed STA MLD setup links.
+ *
++ * @NL80211_CMD_SET_TID_TO_LINK_MAPPING: Set the TID to Link Mapping for a
++ * non-AP MLD station. The %NL80211_ATTR_MLO_TTLM_DLINK and
++ * %NL80211_ATTR_MLO_TTLM_ULINK attributes are used to specify the
++ * TID to Link mapping for downlink/uplink traffic.
++ *
+ * @NL80211_CMD_MAX: highest used command number
+ * @__NL80211_CMD_AFTER_LAST: internal use
+ */
+@@ -1569,6 +1584,8 @@ enum nl80211_commands {
+
+ NL80211_CMD_LINKS_REMOVED,
+
++ NL80211_CMD_SET_TID_TO_LINK_MAPPING,
++
+ /* add new commands above here */
+
+ /* used to define NL80211_CMD_MAX below */
+@@ -1693,21 +1710,21 @@ enum nl80211_commands {
+ * (see &enum nl80211_plink_action).
+ * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path.
+ * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path
+- * info given for %NL80211_CMD_GET_MPATH, nested attribute described at
++ * info given for %NL80211_CMD_GET_MPATH, nested attribute described at
+ * &enum nl80211_mpath_info.
+ *
+ * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of
+ * &enum nl80211_mntr_flags.
+ *
+ * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the
+- * current regulatory domain should be set to or is already set to.
+- * For example, 'CR', for Costa Rica. This attribute is used by the kernel
+- * to query the CRDA to retrieve one regulatory domain. This attribute can
+- * also be used by userspace to query the kernel for the currently set
+- * regulatory domain. We chose an alpha2 as that is also used by the
+- * IEEE-802.11 country information element to identify a country.
+- * Users can also simply ask the wireless core to set regulatory domain
+- * to a specific alpha2.
++ * current regulatory domain should be set to or is already set to.
++ * For example, 'CR', for Costa Rica. This attribute is used by the kernel
++ * to query the CRDA to retrieve one regulatory domain. This attribute can
++ * also be used by userspace to query the kernel for the currently set
++ * regulatory domain. We chose an alpha2 as that is also used by the
++ * IEEE-802.11 country information element to identify a country.
++ * Users can also simply ask the wireless core to set regulatory domain
++ * to a specific alpha2.
+ * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory
+ * rules.
+ *
+@@ -1750,9 +1767,9 @@ enum nl80211_commands {
+ * @NL80211_ATTR_BSS: scan result BSS
+ *
+ * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain
+- * currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_*
++ * currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_*
+ * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently
+- * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*)
++ * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*)
+ *
+ * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies
+ * an array of command numbers (i.e. a mapping index to command number)
+@@ -1771,15 +1788,15 @@ enum nl80211_commands {
+ * a u32
+ *
+ * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change
+- * due to considerations from a beacon hint. This attribute reflects
+- * the state of the channel _before_ the beacon hint processing. This
+- * attributes consists of a nested attribute containing
+- * NL80211_FREQUENCY_ATTR_*
++ * due to considerations from a beacon hint. This attribute reflects
++ * the state of the channel _before_ the beacon hint processing. This
++ * attributes consists of a nested attribute containing
++ * NL80211_FREQUENCY_ATTR_*
+ * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change
+- * due to considerations from a beacon hint. This attribute reflects
+- * the state of the channel _after_ the beacon hint processing. This
+- * attributes consists of a nested attribute containing
+- * NL80211_FREQUENCY_ATTR_*
++ * due to considerations from a beacon hint. This attribute reflects
++ * the state of the channel _after_ the beacon hint processing. This
++ * attributes consists of a nested attribute containing
++ * NL80211_FREQUENCY_ATTR_*
+ *
+ * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported
+ * cipher suites
+@@ -1826,7 +1843,7 @@ enum nl80211_commands {
+ * using %CMD_CONTROL_PORT_FRAME. If control port routing over NL80211 is
+ * to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER
+ * flag. When used with %NL80211_ATTR_CONTROL_PORT_NO_PREAUTH, pre-auth
+- * frames are not forwared over the control port.
++ * frames are not forwarded over the control port.
+ *
+ * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
+ * We recommend using nested, driver-specific attributes within this.
+@@ -1840,12 +1857,6 @@ enum nl80211_commands {
+ * that protected APs should be used. This is also used with NEW_BEACON to
+ * indicate that the BSS is to use protection.
+ *
+- * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT, ASSOCIATE, and NEW_BEACON
+- * to indicate which unicast key ciphers will be used with the connection
+- * (an array of u32).
+- * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
+- * indicate which group key cipher will be used with the connection (a
+- * u32).
+ * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
+ * indicate which WPA version(s) the AP we want to associate with is using
+ * (a u32 with flags from &enum nl80211_wpa_versions).
+@@ -1876,6 +1887,7 @@ enum nl80211_commands {
+ * with %NL80211_KEY_* sub-attributes
+ *
+ * @NL80211_ATTR_PID: Process ID of a network namespace.
++ * @NL80211_ATTR_NETNS_FD: File descriptor of a network namespace.
+ *
+ * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for
+ * dumps. This number increases whenever the object list being
+@@ -1930,6 +1942,7 @@ enum nl80211_commands {
+ *
+ * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was
+ * acknowledged by the recipient.
++ * @NL80211_ATTR_ACK_SIGNAL: Station's ack signal strength (s32)
+ *
+ * @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values.
+ *
+@@ -1963,10 +1976,10 @@ enum nl80211_commands {
+ * bit. Depending on which antennas are selected in the bitmap, 802.11n
+ * drivers can derive which chainmasks to use (if all antennas belonging to
+ * a particular chain are disabled this chain should be disabled) and if
+- * a chain has diversity antennas wether diversity should be used or not.
++ * a chain has diversity antennas whether diversity should be used or not.
+ * HT capabilities (STBC, TX Beamforming, Antenna selection) can be
+ * derived from the available chains after applying the antenna mask.
+- * Non-802.11n drivers can derive wether to use diversity or not.
++ * Non-802.11n drivers can derive whether to use diversity or not.
+ * Drivers may reject configurations or RX/TX mask combinations they cannot
+ * support by returning -EINVAL.
+ *
+@@ -2039,6 +2052,10 @@ enum nl80211_commands {
+ * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported
+ * interface combinations. In each nested item, it contains attributes
+ * defined in &enum nl80211_if_combination_attrs.
++ * If the wiphy uses multiple radios (@NL80211_ATTR_WIPHY_RADIOS is set),
++ * this attribute contains the interface combinations of the first radio.
++ * See @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS for the global wiphy
++ * combinations for the sum of all radios.
+ * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like
+ * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that
+ * are managed in software: interfaces of these types aren't subject to
+@@ -2127,6 +2144,9 @@ enum nl80211_commands {
+ * @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable
+ * this feature during association. This is a flag attribute.
+ * Currently only supported in mac80211 drivers.
++ * @NL80211_ATTR_DISABLE_EHT: Force EHT capable interfaces to disable
++ * this feature during association. This is a flag attribute.
++ * Currently only supported in mac80211 drivers.
+ * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
+ * ATTR_HT_CAPABILITY to which attention should be paid.
+ * Currently, only mac80211 NICs support this feature.
+@@ -2136,6 +2156,12 @@ enum nl80211_commands {
+ * All values are treated as suggestions and may be ignored
+ * by the driver as required. The actual values may be seen in
+ * the station debugfs ht_caps file.
++ * @NL80211_ATTR_VHT_CAPABILITY_MASK: Specify which bits of the
++ * ATTR_VHT_CAPABILITY to which attention should be paid.
++ * Currently, only mac80211 NICs support this feature.
++ * All values are treated as suggestions and may be ignored
++ * by the driver as required. The actual values may be seen in
++ * the station debugfs vht_caps file.
+ *
+ * @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country
+ * abides to when initiating radiation on DFS channels. A country maps
+@@ -2394,7 +2420,7 @@ enum nl80211_commands {
+ * scheduled scan is started. Or the delay before a WoWLAN
+ * net-detect scan is started, counting from the moment the
+ * system is suspended. This value is a u32, in seconds.
+-
++ *
+ * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
+ * is operating in an indoor environment.
+ *
+@@ -2536,7 +2562,7 @@ enum nl80211_commands {
+ * from successful FILS authentication and is used with
+ * %NL80211_CMD_CONNECT.
+ *
+- * @NL80211_ATTR_FILS_CACHE_ID: A 2-octet identifier advertized by a FILS AP
++ * @NL80211_ATTR_FILS_CACHE_ID: A 2-octet identifier advertised by a FILS AP
+ * identifying the scope of PMKSAs. This is used with
+ * @NL80211_CMD_SET_PMKSA and @NL80211_CMD_DEL_PMKSA.
+ *
+@@ -2690,11 +2716,13 @@ enum nl80211_commands {
+ *
+ * @NL80211_ATTR_FILS_DISCOVERY: Optional parameter to configure FILS
+ * discovery. It is a nested attribute, see
+- * &enum nl80211_fils_discovery_attributes.
++ * &enum nl80211_fils_discovery_attributes. Userspace should pass an empty
++ * nested attribute to disable this feature and delete the templates.
+ *
+ * @NL80211_ATTR_UNSOL_BCAST_PROBE_RESP: Optional parameter to configure
+ * unsolicited broadcast probe response. It is a nested attribute, see
+- * &enum nl80211_unsol_bcast_probe_resp_attributes.
++ * &enum nl80211_unsol_bcast_probe_resp_attributes. Userspace should pass an empty
++ * nested attribute to disable this feature and delete the templates.
+ *
+ * @NL80211_ATTR_S1G_CAPABILITY: S1G Capability information element (from
+ * association request when used with NL80211_CMD_NEW_STATION)
+@@ -2815,6 +2843,34 @@ enum nl80211_commands {
+ * @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is
+ * disabled.
+ *
++ * @NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA: Include BSS usage data, i.e.
++ * include BSSes that can only be used in restricted scenarios and/or
++ * cannot be used at all.
++ *
++ * @NL80211_ATTR_MLO_TTLM_DLINK: Binary attribute specifying the downlink TID to
++ * link mapping. The length is 8 * sizeof(u16). For each TID the link
++ * mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
++ * in Draft P802.11be_D4.0.
++ * @NL80211_ATTR_MLO_TTLM_ULINK: Binary attribute specifying the uplink TID to
++ * link mapping. The length is 8 * sizeof(u16). For each TID the link
++ * mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
++ * in Draft P802.11be_D4.0.
++ *
++ * @NL80211_ATTR_ASSOC_SPP_AMSDU: flag attribute used with
++ * %NL80211_CMD_ASSOCIATE indicating the SPP A-MSDUs
++ * are used on this connection
++ *
++ * @NL80211_ATTR_WIPHY_RADIOS: Nested attribute describing physical radios
++ * belonging to this wiphy. See &enum nl80211_wiphy_radio_attrs.
++ *
++ * @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS: Nested attribute listing the
++ * supported interface combinations for all radios combined. In each
++ * nested item, it contains attributes defined in
++ * &enum nl80211_if_combination_attrs.
++ *
++ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32).
++ * A value of 0 means all radios.
++ *
+ * @NUM_NL80211_ATTR: total number of nl80211_attrs available
+ * @NL80211_ATTR_MAX: highest attribute number currently defined
+ * @__NL80211_ATTR_AFTER_LAST: internal use
+@@ -3353,6 +3409,18 @@ enum nl80211_attrs {
+
+ NL80211_ATTR_MLO_LINK_DISABLED,
+
++ NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA,
++
++ NL80211_ATTR_MLO_TTLM_DLINK,
++ NL80211_ATTR_MLO_TTLM_ULINK,
++
++ NL80211_ATTR_ASSOC_SPP_AMSDU,
++
++ NL80211_ATTR_WIPHY_RADIOS,
++ NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
++
++ NL80211_ATTR_VIF_RADIO_MASK,
++
+ /* add attributes here, update the policy in nl80211.c */
+
+ __NL80211_ATTR_AFTER_LAST,
+@@ -3493,6 +3561,7 @@ enum nl80211_iftype {
+ * @NL80211_STA_FLAG_ASSOCIATED: station is associated; used with drivers
+ * that support %NL80211_FEATURE_FULL_AP_CLIENT_STATE to transition a
+ * previously added station into associated state
++ * @NL80211_STA_FLAG_SPP_AMSDU: station supports SPP A-MSDUs
+ * @NL80211_STA_FLAG_MAX: highest station flag number currently defined
+ * @__NL80211_STA_FLAG_AFTER_LAST: internal use
+ */
+@@ -3505,6 +3574,7 @@ enum nl80211_sta_flags {
+ NL80211_STA_FLAG_AUTHENTICATED,
+ NL80211_STA_FLAG_TDLS_PEER,
+ NL80211_STA_FLAG_ASSOCIATED,
++ NL80211_STA_FLAG_SPP_AMSDU,
+
+ /* keep last */
+ __NL80211_STA_FLAG_AFTER_LAST,
+@@ -3515,7 +3585,7 @@ enum nl80211_sta_flags {
+ * enum nl80211_sta_p2p_ps_status - station support of P2P PS
+ *
+ * @NL80211_P2P_PS_UNSUPPORTED: station doesn't support P2P PS mechanism
+- * @@NL80211_P2P_PS_SUPPORTED: station supports P2P PS mechanism
++ * @NL80211_P2P_PS_SUPPORTED: station supports P2P PS mechanism
+ * @NUM_NL80211_P2P_PS_STATUS: number of values
+ */
+ enum nl80211_sta_p2p_ps_status {
+@@ -3553,9 +3623,9 @@ enum nl80211_he_gi {
+
+ /**
+ * enum nl80211_he_ltf - HE long training field
+- * @NL80211_RATE_INFO_HE_1xLTF: 3.2 usec
+- * @NL80211_RATE_INFO_HE_2xLTF: 6.4 usec
+- * @NL80211_RATE_INFO_HE_4xLTF: 12.8 usec
++ * @NL80211_RATE_INFO_HE_1XLTF: 3.2 usec
++ * @NL80211_RATE_INFO_HE_2XLTF: 6.4 usec
++ * @NL80211_RATE_INFO_HE_4XLTF: 12.8 usec
+ */
+ enum nl80211_he_ltf {
+ NL80211_RATE_INFO_HE_1XLTF,
+@@ -3670,7 +3740,7 @@ enum nl80211_eht_ru_alloc {
+ * @NL80211_RATE_INFO_HE_GI: HE guard interval identifier
+ * (u8, see &enum nl80211_he_gi)
+ * @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1)
+- * @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then
++ * @NL80211_RATE_INFO_HE_RU_ALLOC: HE RU allocation, if not present then
+ * non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc)
+ * @NL80211_RATE_INFO_320_MHZ_WIDTH: 320 MHz bitrate
+ * @NL80211_RATE_INFO_EHT_MCS: EHT MCS index (u8, 0-15)
+@@ -3773,7 +3843,7 @@ enum nl80211_sta_bss_param {
+ * (u64, to this station)
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
+- * containing info as possible, see &enum nl80211_rate_info
++ * containing info as possible, see &enum nl80211_rate_info
+ * @NL80211_STA_INFO_RX_PACKETS: total received packet (MSDUs and MMPDUs)
+ * (u32, from this station)
+ * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (MSDUs and MMPDUs)
+@@ -3802,8 +3872,8 @@ enum nl80211_sta_bss_param {
+ * Contains a nested array of signal strength attributes (u8, dBm)
+ * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
+ * Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
+- * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the
+- * 802.11 header (u32, kbps)
++ * @NL80211_STA_INFO_EXPECTED_THROUGHPUT: expected throughput considering also
++ * the 802.11 header (u32, kbps)
+ * @NL80211_STA_INFO_RX_DROP_MISC: RX packets dropped for unspecified reasons
+ * (u64)
+ * @NL80211_STA_INFO_BEACON_RX: number of beacons received from this peer (u64)
+@@ -3989,7 +4059,7 @@ enum nl80211_mpath_flags {
+ * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path
+ * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now
+ * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in
+- * &enum nl80211_mpath_flags;
++ * &enum nl80211_mpath_flags;
+ * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec
+ * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries
+ * @NL80211_MPATH_INFO_HOP_COUNT: hop count to destination
+@@ -4129,7 +4199,7 @@ enum nl80211_band_attr {
+ * @NL80211_WMMR_CW_MAX: Maximum contention window slot.
+ * @NL80211_WMMR_AIFSN: Arbitration Inter Frame Space.
+ * @NL80211_WMMR_TXOP: Maximum allowed tx operation time.
+- * @nl80211_WMMR_MAX: highest possible wmm rule.
++ * @NL80211_WMMR_MAX: highest possible wmm rule.
+ * @__NL80211_WMMR_LAST: Internal use.
+ */
+ enum nl80211_wmm_rule {
+@@ -4151,15 +4221,16 @@ enum nl80211_wmm_rule {
+ * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
+ * regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation
+- * are permitted on this channel, this includes sending probe
+- * requests, or modes of operation that require beaconing.
++ * are permitted on this channel, this includes sending probe
++ * requests, or modes of operation that require beaconing.
++ * @__NL80211_FREQUENCY_ATTR_NO_IBSS: obsolete, same as _NO_IR
+ * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
+ * on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
+ * (100 * dBm).
+ * @NL80211_FREQUENCY_ATTR_DFS_STATE: current state for DFS
+ * (enum nl80211_dfs_state)
+- * @NL80211_FREQUENCY_ATTR_DFS_TIME: time in miliseconds for how long
++ * @NL80211_FREQUENCY_ATTR_DFS_TIME: time in milliseconds for how long
+ * this channel is in this DFS state.
+ * @NL80211_FREQUENCY_ATTR_NO_HT40_MINUS: HT40- isn't possible with this
+ * channel as the control channel
+@@ -4213,6 +4284,21 @@ enum nl80211_wmm_rule {
+ * as the primary or any of the secondary channels isn't possible
+ * @NL80211_FREQUENCY_ATTR_NO_EHT: EHT operation is not allowed on this channel
+ * in current regulatory domain.
++ * @NL80211_FREQUENCY_ATTR_PSD: Power spectral density (in dBm) that
++ * is allowed on this channel in current regulatory domain.
++ * @NL80211_FREQUENCY_ATTR_DFS_CONCURRENT: Operation on this channel is
++ * allowed for peer-to-peer or adhoc communication under the control
++ * of a DFS master which operates on the same channel (FCC-594280 D01
++ * Section B.3). Should be used together with %NL80211_RRF_DFS only.
++ * @NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT: Client connection to VLP AP
++ * not allowed using this channel
++ * @NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT: Client connection to AFC AP
++ * not allowed using this channel
++ * @NL80211_FREQUENCY_ATTR_CAN_MONITOR: This channel can be used in monitor
++ * mode despite other (regulatory) restrictions, even if the channel is
++ * otherwise completely disabled.
++ * @NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP: This channel can be used for a
++ * very low power (VLP) AP, despite being NO_IR.
+ * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
+ * currently defined
+ * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
+@@ -4251,6 +4337,12 @@ enum nl80211_frequency_attr {
+ NL80211_FREQUENCY_ATTR_16MHZ,
+ NL80211_FREQUENCY_ATTR_NO_320MHZ,
+ NL80211_FREQUENCY_ATTR_NO_EHT,
++ NL80211_FREQUENCY_ATTR_PSD,
++ NL80211_FREQUENCY_ATTR_DFS_CONCURRENT,
++ NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT,
++ NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT,
++ NL80211_FREQUENCY_ATTR_CAN_MONITOR,
++ NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP,
+
+ /* keep last */
+ __NL80211_FREQUENCY_ATTR_AFTER_LAST,
+@@ -4263,6 +4355,10 @@ enum nl80211_frequency_attr {
+ #define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR
+ #define NL80211_FREQUENCY_ATTR_GO_CONCURRENT \
+ NL80211_FREQUENCY_ATTR_IR_CONCURRENT
++#define NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT \
++ NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT
++#define NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT \
++ NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT
+
+ /**
+ * enum nl80211_bitrate_attr - bitrate attributes
+@@ -4285,16 +4381,16 @@ enum nl80211_bitrate_attr {
+ };
+
+ /**
+- * enum nl80211_initiator - Indicates the initiator of a reg domain request
++ * enum nl80211_reg_initiator - Indicates the initiator of a reg domain request
+ * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world
+- * regulatory domain.
++ * regulatory domain.
+ * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the
+- * regulatory domain.
++ * regulatory domain.
+ * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the
+- * wireless core it thinks its knows the regulatory domain we should be in.
++ * wireless core it thinks its knows the regulatory domain we should be in.
+ * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an
+- * 802.11 country information element with regulatory information it
+- * thinks we should consider. cfg80211 only processes the country
++ * 802.11 country information element with regulatory information it
++ * thinks we should consider. cfg80211 only processes the country
+ * code from the IE, and relies on the regulatory domain information
+ * structure passed by userspace (CRDA) from our wireless-regdb.
+ * If a channel is enabled but the country code indicates it should
+@@ -4313,11 +4409,11 @@ enum nl80211_reg_initiator {
+ * to a specific country. When this is set you can count on the
+ * ISO / IEC 3166 alpha2 country code being valid.
+ * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory
+- * domain.
++ * domain.
+ * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom
+- * driver specific world regulatory domain. These do not apply system-wide
+- * and are only applicable to the individual devices which have requested
+- * them to be applied.
++ * driver specific world regulatory domain. These do not apply system-wide
++ * and are only applicable to the individual devices which have requested
++ * them to be applied.
+ * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product
+ * of an intersection between two regulatory domains -- the previously
+ * set regulatory domain on the system and the last accepted regulatory
+@@ -4334,23 +4430,25 @@ enum nl80211_reg_type {
+ * enum nl80211_reg_rule_attr - regulatory rule attributes
+ * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional
+- * considerations for a given frequency range. These are the
+- * &enum nl80211_reg_rule_flags.
++ * considerations for a given frequency range. These are the
++ * &enum nl80211_reg_rule_flags.
+ * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory
+- * rule in KHz. This is not a center of frequency but an actual regulatory
+- * band edge.
++ * rule in KHz. This is not a center of frequency but an actual regulatory
++ * band edge.
+ * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule
+- * in KHz. This is not a center a frequency but an actual regulatory
+- * band edge.
++ * in KHz. This is not a center a frequency but an actual regulatory
++ * band edge.
+ * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this
+ * frequency range, in KHz.
+ * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain
+- * for a given frequency range. The value is in mBi (100 * dBi).
+- * If you don't have one then don't send this.
++ * for a given frequency range. The value is in mBi (100 * dBi).
++ * If you don't have one then don't send this.
+ * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for
+- * a given frequency range. The value is in mBm (100 * dBm).
++ * a given frequency range. The value is in mBm (100 * dBm).
+ * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
+ * If not present or 0 default CAC time will be used.
++ * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm).
++ * This could be negative.
+ * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
+ * currently defined
+ * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
+@@ -4368,6 +4466,8 @@ enum nl80211_reg_rule_attr {
+
+ NL80211_ATTR_DFS_CAC_TIME,
+
++ NL80211_ATTR_POWER_RULE_PSD,
++
+ /* keep last */
+ __NL80211_REG_RULE_ATTR_AFTER_LAST,
+ NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
+@@ -4396,14 +4496,7 @@ enum nl80211_reg_rule_attr {
+ * value as specified by &struct nl80211_bss_select_rssi_adjust.
+ * @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching
+ * (this cannot be used together with SSID).
+- * @NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI: Nested attribute that carries the
+- * band specific minimum rssi thresholds for the bands defined in
+- * enum nl80211_band. The minimum rssi threshold value(s32) specific to a
+- * band shall be encapsulated in attribute with type value equals to one
+- * of the NL80211_BAND_* defined in enum nl80211_band. For example, the
+- * minimum rssi threshold value for 2.4GHZ band shall be encapsulated
+- * within an attribute of type NL80211_BAND_2GHZ. And one or more of such
+- * attributes will be nested within this attribute.
++ * @NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI: Obsolete
+ * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
+ * attribute number currently defined
+ * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
+@@ -4416,7 +4509,7 @@ enum nl80211_sched_scan_match_attr {
+ NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI,
+ NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST,
+ NL80211_SCHED_SCAN_MATCH_ATTR_BSSID,
+- NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI,
++ NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI, /* obsolete */
+
+ /* keep last */
+ __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
+@@ -4438,8 +4531,9 @@ enum nl80211_sched_scan_match_attr {
+ * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links
+ * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links
+ * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
+- * this includes probe requests or modes of operation that require
+- * beaconing.
++ * this includes probe requests or modes of operation that require
++ * beaconing.
++ * @__NL80211_RRF_NO_IBSS: obsolete, same as NO_IR
+ * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated
+ * base on contiguous rules and wider channels will be allowed to cross
+ * multiple contiguous/overlapping frequency ranges.
+@@ -4451,6 +4545,15 @@ enum nl80211_sched_scan_match_attr {
+ * @NL80211_RRF_NO_HE: HE operation not allowed
+ * @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed
+ * @NL80211_RRF_NO_EHT: EHT operation not allowed
++ * @NL80211_RRF_PSD: Ruleset has power spectral density value
++ * @NL80211_RRF_DFS_CONCURRENT: Operation on this channel is allowed for
++ * peer-to-peer or adhoc communication under the control of a DFS master
++ * which operates on the same channel (FCC-594280 D01 Section B.3).
++ * Should be used together with %NL80211_RRF_DFS only.
++ * @NL80211_RRF_NO_6GHZ_VLP_CLIENT: Client connection to VLP AP not allowed
++ * @NL80211_RRF_NO_6GHZ_AFC_CLIENT: Client connection to AFC AP not allowed
++ * @NL80211_RRF_ALLOW_6GHZ_VLP_AP: Very low power (VLP) AP can be permitted
++ * despite NO_IR configuration.
+ */
+ enum nl80211_reg_rule_flags {
+ NL80211_RRF_NO_OFDM = 1<<0,
+@@ -4471,6 +4574,11 @@ enum nl80211_reg_rule_flags {
+ NL80211_RRF_NO_HE = 1<<17,
+ NL80211_RRF_NO_320MHZ = 1<<18,
+ NL80211_RRF_NO_EHT = 1<<19,
++ NL80211_RRF_PSD = 1<<20,
++ NL80211_RRF_DFS_CONCURRENT = 1<<21,
++ NL80211_RRF_NO_6GHZ_VLP_CLIENT = 1<<22,
++ NL80211_RRF_NO_6GHZ_AFC_CLIENT = 1<<23,
++ NL80211_RRF_ALLOW_6GHZ_VLP_AP = 1<<24,
+ };
+
+ #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
+@@ -4479,6 +4587,8 @@ enum nl80211_reg_rule_flags {
+ #define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS |\
+ NL80211_RRF_NO_HT40PLUS)
+ #define NL80211_RRF_GO_CONCURRENT NL80211_RRF_IR_CONCURRENT
++#define NL80211_RRF_NO_UHB_VLP_CLIENT NL80211_RRF_NO_6GHZ_VLP_CLIENT
++#define NL80211_RRF_NO_UHB_AFC_CLIENT NL80211_RRF_NO_6GHZ_AFC_CLIENT
+
+ /* For backport compatibility with older userspace */
+ #define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
+@@ -4593,6 +4703,7 @@ enum nl80211_survey_info {
+ * overrides all other flags.
+ * @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address
+ * and ACK incoming unicast packets.
++ * @NL80211_MNTR_FLAG_SKIP_TX: do not pass local tx packets
+ *
+ * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
+ * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
+@@ -4605,6 +4716,7 @@ enum nl80211_mntr_flags {
+ NL80211_MNTR_FLAG_OTHER_BSS,
+ NL80211_MNTR_FLAG_COOK_FRAMES,
+ NL80211_MNTR_FLAG_ACTIVE,
++ NL80211_MNTR_FLAG_SKIP_TX,
+
+ /* keep last */
+ __NL80211_MNTR_FLAG_AFTER_LAST,
+@@ -4625,8 +4737,8 @@ enum nl80211_mntr_flags {
+ * alternate between Active and Doze states, but may not wake up
+ * for neighbor's beacons.
+ *
+- * @__NL80211_MESH_POWER_AFTER_LAST - internal use
+- * @NL80211_MESH_POWER_MAX - highest possible power save level
++ * @__NL80211_MESH_POWER_AFTER_LAST: internal use
++ * @NL80211_MESH_POWER_MAX: highest possible power save level
+ */
+
+ enum nl80211_mesh_power_mode {
+@@ -5008,6 +5120,36 @@ enum nl80211_bss_scan_width {
+ };
+
+ /**
++ * enum nl80211_bss_use_for - bitmap indicating possible BSS use
++ * @NL80211_BSS_USE_FOR_NORMAL: Use this BSS for normal "connection",
++ * including IBSS/MBSS depending on the type.
++ * @NL80211_BSS_USE_FOR_MLD_LINK: This BSS can be used as a link in an
++ * MLO connection. Note that for an MLO connection, all links including
++ * the assoc link must have this flag set, and the assoc link must
++ * additionally have %NL80211_BSS_USE_FOR_NORMAL set.
++ */
++enum nl80211_bss_use_for {
++ NL80211_BSS_USE_FOR_NORMAL = 1 << 0,
++ NL80211_BSS_USE_FOR_MLD_LINK = 1 << 1,
++};
++
++/**
++ * enum nl80211_bss_cannot_use_reasons - reason(s) connection to a
++ * BSS isn't possible
++ * @NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY: NSTR nonprimary links aren't
++ * supported by the device, and this BSS entry represents one.
++ * @NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH: STA is not supporting
++ * the AP power type (SP, VLP, AP) that the AP uses.
++ */
++enum nl80211_bss_cannot_use_reasons {
++ NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 1 << 0,
++ NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH = 1 << 1,
++};
++
++#define NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH \
++ NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH
++
++/**
+ * enum nl80211_bss - netlink attributes for a BSS
+ *
+ * @__NL80211_BSS_INVALID: invalid
+@@ -5038,7 +5180,7 @@ enum nl80211_bss_scan_width {
+ * elements from a Beacon frame (bin); not present if no Beacon frame has
+ * yet been received
+ * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel
+- * (u32, enum nl80211_bss_scan_width)
++ * (u32, enum nl80211_bss_scan_width) - No longer used!
+ * @NL80211_BSS_BEACON_TSF: TSF of the last received beacon (u64)
+ * (not present if no beacon frame has been received yet)
+ * @NL80211_BSS_PRESP_DATA: the data in @NL80211_BSS_INFORMATION_ELEMENTS and
+@@ -5059,6 +5201,14 @@ enum nl80211_bss_scan_width {
+ * @NL80211_BSS_FREQUENCY_OFFSET: frequency offset in KHz
+ * @NL80211_BSS_MLO_LINK_ID: MLO link ID of the BSS (u8).
+ * @NL80211_BSS_MLD_ADDR: MLD address of this BSS if connected to it.
++ * @NL80211_BSS_USE_FOR: u32 bitmap attribute indicating what the BSS can be
++ * used for, see &enum nl80211_bss_use_for.
++ * @NL80211_BSS_CANNOT_USE_REASONS: Indicates the reason that this BSS cannot
++ * be used for all or some of the possible uses by the device reporting it,
++ * even though its presence was detected.
++ * This is a u64 attribute containing a bitmap of values from
++ * &enum nl80211_cannot_use_reasons, note that the attribute may be missing
++ * if no reasons are specified.
+ * @__NL80211_BSS_AFTER_LAST: internal
+ * @NL80211_BSS_MAX: highest BSS attribute
+ */
+@@ -5086,6 +5236,8 @@ enum nl80211_bss {
+ NL80211_BSS_FREQUENCY_OFFSET,
+ NL80211_BSS_MLO_LINK_ID,
+ NL80211_BSS_MLD_ADDR,
++ NL80211_BSS_USE_FOR,
++ NL80211_BSS_CANNOT_USE_REASONS,
+
+ /* keep last */
+ __NL80211_BSS_AFTER_LAST,
+@@ -5434,7 +5586,7 @@ enum nl80211_tx_rate_setting {
+ * (%NL80211_TID_CONFIG_ATTR_TIDS, %NL80211_TID_CONFIG_ATTR_OVERRIDE).
+ * @NL80211_TID_CONFIG_ATTR_PEER_SUPP: same as the previous per-vif one, but
+ * per peer instead.
+- * @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribue, if set indicates
++ * @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribute, if set indicates
+ * that the new configuration overrides all previous peer
+ * configurations, otherwise previous peer specific configurations
+ * should be left untouched.
+@@ -5606,7 +5758,7 @@ struct nl80211_pattern_support {
+ * "TCP connection wakeup" for more details. This is a nested attribute
+ * containing the exact information for establishing and keeping alive
+ * the TCP connection.
+- * @NL80211_WOWLAN_TRIG_TCP_WAKEUP_MATCH: For wakeup reporting only, the
++ * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH: For wakeup reporting only, the
+ * wakeup packet was received on the TCP connection
+ * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST: For wakeup reporting only, the
+ * TCP connection was lost or failed to be established
+@@ -5635,6 +5787,8 @@ struct nl80211_pattern_support {
+ * %NL80211_ATTR_SCAN_FREQUENCIES contains more than one
+ * frequency, it means that the match occurred in more than one
+ * channel.
++ * @NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC: For wakeup reporting only.
++ * Wake up happened due to unprotected deauth or disassoc frame in MFP.
+ * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers
+ * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number
+ *
+@@ -5662,6 +5816,7 @@ enum nl80211_wowlan_triggers {
+ NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS,
+ NL80211_WOWLAN_TRIG_NET_DETECT,
+ NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS,
++ NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC,
+
+ /* keep last */
+ NUM_NL80211_WOWLAN_TRIG,
+@@ -5817,7 +5972,7 @@ enum nl80211_attr_coalesce_rule {
+
+ /**
+ * enum nl80211_coalesce_condition - coalesce rule conditions
+- * @NL80211_COALESCE_CONDITION_MATCH: coalaesce Rx packets when patterns
++ * @NL80211_COALESCE_CONDITION_MATCH: coalesce Rx packets when patterns
+ * in a rule are matched.
+ * @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns
+ * in a rule are not matched.
+@@ -5916,7 +6071,7 @@ enum nl80211_if_combination_attrs {
+ * enum nl80211_plink_state - state of a mesh peer link finite state machine
+ *
+ * @NL80211_PLINK_LISTEN: initial state, considered the implicit
+- * state of non existent mesh peer links
++ * state of non-existent mesh peer links
+ * @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to
+ * this mesh peer
+ * @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received
+@@ -5952,7 +6107,7 @@ enum nl80211_plink_state {
+ * @NL80211_PLINK_ACTION_BLOCK: block traffic from this mesh peer
+ * @NUM_NL80211_PLINK_ACTIONS: number of possible actions
+ */
+-enum plink_actions {
++enum nl80211_plink_action {
+ NL80211_PLINK_ACTION_NO_ACTION,
+ NL80211_PLINK_ACTION_OPEN,
+ NL80211_PLINK_ACTION_BLOCK,
+@@ -6209,7 +6364,7 @@ enum nl80211_feature_flags {
+ * request to use RRM (see %NL80211_ATTR_USE_RRM) with
+ * %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests, which will set
+ * the ASSOC_REQ_USE_RRM flag in the association request even if
+- * NL80211_FEATURE_QUIET is not advertized.
++ * NL80211_FEATURE_QUIET is not advertised.
+ * @NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER: This device supports MU-MIMO air
+ * sniffer which means that it can be configured to hear packets from
+ * certain groups which can be configured by the
+@@ -6221,13 +6376,15 @@ enum nl80211_feature_flags {
+ * the BSS that the interface that requested the scan is connected to
+ * (if available).
+ * @NL80211_EXT_FEATURE_BSS_PARENT_TSF: Per BSS, this driver reports the
+- * time the last beacon/probe was received. The time is the TSF of the
+- * BSS that the interface that requested the scan is connected to
+- * (if available).
++ * time the last beacon/probe was received. For a non-MLO connection, the
++ * time is the TSF of the BSS that the interface that requested the scan is
++ * connected to (if available). For an MLO connection, the time is the TSF
++ * of the BSS corresponding with link ID specified in the scan request (if
++ * specified).
+ * @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of
+ * channel dwell time.
+ * @NL80211_EXT_FEATURE_BEACON_RATE_LEGACY: Driver supports beacon rate
+- * configuration (AP/mesh), supporting a legacy (non HT/VHT) rate.
++ * configuration (AP/mesh), supporting a legacy (non-HT/VHT) rate.
+ * @NL80211_EXT_FEATURE_BEACON_RATE_HT: Driver supports beacon rate
+ * configuration (AP/mesh) with HT rates.
+ * @NL80211_EXT_FEATURE_BEACON_RATE_VHT: Driver supports beacon rate
+@@ -6277,6 +6434,7 @@ enum nl80211_feature_flags {
+ * receiving control port frames over nl80211 instead of the netdevice.
+ * @NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT: This driver/device supports
+ * (average) ACK signal strength reporting.
++ * @NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT: Backward-compatible ID
+ * @NL80211_EXT_FEATURE_TXQS: Driver supports FQ-CoDel-enabled intermediate
+ * TXQs.
+ * @NL80211_EXT_FEATURE_SCAN_RANDOM_SN: Driver/device supports randomizing the
+@@ -6301,8 +6459,7 @@ enum nl80211_feature_flags {
+ * @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching
+ * (set/del PMKSA operations) in AP mode.
+ *
+- * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports
+- * filtering of sched scan results using band specific RSSI thresholds.
++ * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Obsolete
+ *
+ * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power
+ * to a station.
+@@ -6400,6 +6557,22 @@ enum nl80211_feature_flags {
+ * in authentication and deauthentication frames sent to unassociated peer
+ * using @NL80211_CMD_FRAME.
+ *
++ * @NL80211_EXT_FEATURE_OWE_OFFLOAD: Driver/Device wants to do OWE DH IE
++ * handling in station mode.
++ *
++ * @NL80211_EXT_FEATURE_OWE_OFFLOAD_AP: Driver/Device wants to do OWE DH IE
++ * handling in AP mode.
++ *
++ * @NL80211_EXT_FEATURE_DFS_CONCURRENT: The device supports peer-to-peer or
++ * ad hoc operation on DFS channels under the control of a concurrent
++ * DFS master on the same channel as described in FCC-594280 D01
++ * (Section B.3). This, for example, allows P2P GO and P2P clients to
++ * operate on DFS channels as long as there's a concurrent BSS connection.
++ *
++ * @NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT: The driver has support for SPP
++ * (signaling and payload protected) A-MSDUs and this shall be advertised
++ * in the RSNXE.
++ *
+ * @NUM_NL80211_EXT_FEATURES: number of extended features.
+ * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
+ */
+@@ -6441,7 +6614,7 @@ enum nl80211_ext_feature_index {
+ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
+ NL80211_EXT_FEATURE_AP_PMKSA_CACHING,
+- NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
++ NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD, /* obsolete */
+ NL80211_EXT_FEATURE_EXT_KEY_ID,
+ NL80211_EXT_FEATURE_STA_TX_PWR,
+ NL80211_EXT_FEATURE_SAE_OFFLOAD,
+@@ -6471,6 +6644,10 @@ enum nl80211_ext_feature_index {
+ NL80211_EXT_FEATURE_PUNCT,
+ NL80211_EXT_FEATURE_SECURE_NAN,
+ NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA,
++ NL80211_EXT_FEATURE_OWE_OFFLOAD,
++ NL80211_EXT_FEATURE_OWE_OFFLOAD_AP,
++ NL80211_EXT_FEATURE_DFS_CONCURRENT,
++ NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT,
+
+ /* add new features before the definition below */
+ NUM_NL80211_EXT_FEATURES,
+@@ -6555,7 +6732,7 @@ enum nl80211_timeout_reason {
+ * request parameters IE in the probe request
+ * @NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP: accept broadcast probe responses
+ * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE: send probe request frames at
+- * rate of at least 5.5M. In case non OCE AP is discovered in the channel,
++ * rate of at least 5.5M. In case non-OCE AP is discovered in the channel,
+ * only the first probe req in the channel will be sent in high rate.
+ * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: allow probe request
+ * tx deferral (dot11FILSProbeDelay shall be set to 15ms)
+@@ -6591,7 +6768,7 @@ enum nl80211_timeout_reason {
+ * received on the 2.4/5 GHz channels to actively scan only the 6GHz
+ * channels on which APs are expected to be found. Note that when not set,
+ * the scan logic would scan all 6GHz channels, but since transmission of
+- * probe requests on non PSC channels is limited, it is highly likely that
++ * probe requests on non-PSC channels is limited, it is highly likely that
+ * these channels would passively be scanned. Also note that when the flag
+ * is set, in addition to the colocated APs, PSC channels would also be
+ * scanned if the user space has asked for it.
+@@ -6641,6 +6818,8 @@ enum nl80211_acl_policy {
+ * @NL80211_SMPS_STATIC: static SMPS (use a single antenna)
+ * @NL80211_SMPS_DYNAMIC: dynamic smps (start with a single antenna and
+ * turn on other antennas after CTS/RTS).
++ * @__NL80211_SMPS_AFTER_LAST: internal
++ * @NL80211_SMPS_MAX: highest used enumeration
+ */
+ enum nl80211_smps_mode {
+ NL80211_SMPS_OFF,
+@@ -6671,14 +6850,6 @@ enum nl80211_smps_mode {
+ * applicable for ETSI dfs domain where pre-CAC is valid for ever.
+ * @NL80211_RADAR_CAC_STARTED: Channel Availability Check has been started,
+ * should be generated by HW if NL80211_EXT_FEATURE_DFS_OFFLOAD is enabled.
+- * @NL80211_RADAR_BACKGROUND_CHAN_UPDATE: background channel is updated by the
+- * driver.
+- * @NL80211_RADAR_BACKGROUND_CHAN_EXPAND: background channel is updated by the
+- * driver and required to expand main operating channel.
+- * @NL80211_RADAR_STA_CAC_SKIPPED: STA set the DFS state to available
+- * when receiving CSA/assoc resp
+- * @NL80211_RADAR_STA_CAC_EXPIRED: STA set the DFS state to usable
+- * when STA is disconnected or leaving the channel
+ */
+ enum nl80211_radar_event {
+ NL80211_RADAR_DETECTED,
+@@ -6687,10 +6858,6 @@ enum nl80211_radar_event {
+ NL80211_RADAR_NOP_FINISHED,
+ NL80211_RADAR_PRE_CAC_EXPIRED,
+ NL80211_RADAR_CAC_STARTED,
+- NL80211_RADAR_BACKGROUND_CHAN_UPDATE,
+- NL80211_RADAR_BACKGROUND_CHAN_EXPAND,
+- NL80211_RADAR_STA_CAC_SKIPPED,
+- NL80211_RADAR_STA_CAC_EXPIRED,
+ };
+
+ /**
+@@ -6874,6 +7041,8 @@ enum nl80211_bss_select_attr {
+ * @NL80211_NAN_FUNC_PUBLISH: function is publish
+ * @NL80211_NAN_FUNC_SUBSCRIBE: function is subscribe
+ * @NL80211_NAN_FUNC_FOLLOW_UP: function is follow-up
++ * @__NL80211_NAN_FUNC_TYPE_AFTER_LAST: internal use
++ * @NL80211_NAN_FUNC_MAX_TYPE: internal use
+ */
+ enum nl80211_nan_function_type {
+ NL80211_NAN_FUNC_PUBLISH,
+@@ -6935,7 +7104,7 @@ enum nl80211_nan_func_term_reason {
+ * The instance ID for the follow up Service Discovery Frame. This is u8.
+ * @NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID: relevant if the function's type
+ * is follow up. This is a u8.
+- * The requestor instance ID for the follow up Service Discovery Frame.
++ * The requester instance ID for the follow up Service Discovery Frame.
+ * @NL80211_NAN_FUNC_FOLLOW_UP_DEST: the MAC address of the recipient of the
+ * follow up Service Discovery Frame. This is a binary attribute.
+ * @NL80211_NAN_FUNC_CLOSE_RANGE: is this function limited for devices in a
+@@ -7034,7 +7203,7 @@ enum nl80211_nan_match_attributes {
+ };
+
+ /**
+- * nl80211_external_auth_action - Action to perform with external
++ * enum nl80211_external_auth_action - Action to perform with external
+ * authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION.
+ * @NL80211_EXTERNAL_AUTH_START: Start the authentication.
+ * @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication.
+@@ -7052,7 +7221,7 @@ enum nl80211_external_auth_action {
+ * @NL80211_FTM_RESP_ATTR_LCI: The content of Measurement Report Element
+ * (9.4.2.22 in 802.11-2016) with type 8 - LCI (9.4.2.22.10),
+ * i.e. starting with the measurement token
+- * @NL80211_FTM_RESP_ATTR_CIVIC: The content of Measurement Report Element
++ * @NL80211_FTM_RESP_ATTR_CIVICLOC: The content of Measurement Report Element
+ * (9.4.2.22 in 802.11-2016) with type 11 - Civic (Section 9.4.2.22.13),
+ * i.e. starting with the measurement token
+ * @__NL80211_FTM_RESP_ATTR_LAST: Internal
+@@ -7325,7 +7494,7 @@ enum nl80211_peer_measurement_attrs {
+ * @NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED: flag attribute indicating if
+ * trigger based ranging measurement is supported
+ * @NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED: flag attribute indicating
+- * if non trigger based ranging measurement is supported
++ * if non-trigger-based ranging measurement is supported
+ *
+ * @NUM_NL80211_PMSR_FTM_CAPA_ATTR: internal
+ * @NL80211_PMSR_FTM_CAPA_ATTR_MAX: highest attribute number
+@@ -7379,7 +7548,7 @@ enum nl80211_peer_measurement_ftm_capa {
+ * if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
+ * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
+ * ranging will be used.
+- * @NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED: request non trigger based
++ * @NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED: request non-trigger-based
+ * ranging measurement (flag)
+ * This attribute and %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED are
+ * mutually exclusive.
+@@ -7457,7 +7626,7 @@ enum nl80211_peer_measurement_ftm_failur
+ * @NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_ATTEMPTS: number of FTM Request frames
+ * transmitted (u32, optional)
+ * @NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_SUCCESSES: number of FTM Request frames
+- * that were acknowleged (u32, optional)
++ * that were acknowledged (u32, optional)
+ * @NL80211_PMSR_FTM_RESP_ATTR_BUSY_RETRY_TIME: retry time received from the
+ * busy peer (u32, seconds)
+ * @NL80211_PMSR_FTM_RESP_ATTR_NUM_BURSTS_EXP: actual number of bursts exponent
+@@ -7618,7 +7787,7 @@ enum nl80211_iftype_akm_attributes {
+ * @NL80211_FILS_DISCOVERY_ATTR_INT_MIN: Minimum packet interval (u32, TU).
+ * Allowed range: 0..10000 (TU = Time Unit)
+ * @NL80211_FILS_DISCOVERY_ATTR_INT_MAX: Maximum packet interval (u32, TU).
+- * Allowed range: 0..10000 (TU = Time Unit)
++ * Allowed range: 0..10000 (TU = Time Unit). If set to 0, the feature is disabled.
+ * @NL80211_FILS_DISCOVERY_ATTR_TMPL: Template data for FILS discovery action
+ * frame including the headers.
+ *
+@@ -7631,7 +7800,6 @@ enum nl80211_fils_discovery_attributes {
+ NL80211_FILS_DISCOVERY_ATTR_INT_MIN,
+ NL80211_FILS_DISCOVERY_ATTR_INT_MAX,
+ NL80211_FILS_DISCOVERY_ATTR_TMPL,
+- NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INTE,
+
+ /* keep last */
+ __NL80211_FILS_DISCOVERY_ATTR_LAST,
+@@ -7652,7 +7820,8 @@ enum nl80211_fils_discovery_attributes {
+ *
+ * @NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT: Maximum packet interval (u32, TU).
+ * Allowed range: 0..20 (TU = Time Unit). IEEE P802.11ax/D6.0
+- * 26.17.2.3.2 (AP behavior for fast passive scanning).
++ * 26.17.2.3.2 (AP behavior for fast passive scanning). If set to 0, the feature is
++ * disabled.
+ * @NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL: Unsolicited broadcast probe response
+ * frame template (binary).
+ *
+@@ -7695,6 +7864,7 @@ enum nl80211_sae_pwe_mechanism {
+ *
+ * @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit
+ *
++ * @NUM_NL80211_SAR_TYPE: internal
+ */
+ enum nl80211_sar_type {
+ NL80211_SAR_TYPE_POWER,
+@@ -7708,6 +7878,8 @@ enum nl80211_sar_type {
+ /**
+ * enum nl80211_sar_attrs - Attributes for SAR spec
+ *
++ * @__NL80211_SAR_ATTR_INVALID: Invalid
++ *
+ * @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type.
+ *
+ * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power
+@@ -7739,6 +7911,8 @@ enum nl80211_sar_attrs {
+ /**
+ * enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs
+ *
++ * @__NL80211_SAR_ATTR_SPECS_INVALID: Invalid
++ *
+ * @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual
+ * power limit value in units of 0.25 dBm if type is
+ * NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm).
+@@ -7853,4 +8027,54 @@ enum nl80211_ap_settings_flags {
+ NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1,
+ };
+
++/**
++ * enum nl80211_wiphy_radio_attrs - wiphy radio attributes
++ *
++ * @__NL80211_WIPHY_RADIO_ATTR_INVALID: Invalid
++ *
++ * @NL80211_WIPHY_RADIO_ATTR_INDEX: Index of this radio (u32)
++ * @NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE: Frequency range supported by this
++ * radio. Attribute may be present multiple times.
++ * @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface
++ * combination for this radio. Attribute may be present multiple times
++ * and contains attributes defined in &enum nl80211_if_combination_attrs.
++ *
++ * @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal
++ * @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute
++ */
++enum nl80211_wiphy_radio_attrs {
++ __NL80211_WIPHY_RADIO_ATTR_INVALID,
++
++ NL80211_WIPHY_RADIO_ATTR_INDEX,
++ NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE,
++ NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
++
++ /* keep last */
++ __NL80211_WIPHY_RADIO_ATTR_LAST,
++ NL80211_WIPHY_RADIO_ATTR_MAX = __NL80211_WIPHY_RADIO_ATTR_LAST - 1,
++};
++
++/**
++ * enum nl80211_wiphy_radio_freq_range - wiphy radio frequency range
++ *
++ * @__NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID: Invalid
++ *
++ * @NL80211_WIPHY_RADIO_FREQ_ATTR_START: Frequency range start (u32).
++ * The unit is kHz.
++ * @NL80211_WIPHY_RADIO_FREQ_ATTR_END: Frequency range end (u32).
++ * The unit is kHz.
++ *
++ * @__NL80211_WIPHY_RADIO_FREQ_ATTR_LAST: Internal
++ * @NL80211_WIPHY_RADIO_FREQ_ATTR_MAX: Highest attribute
++ */
++enum nl80211_wiphy_radio_freq_range {
++ __NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID,
++
++ NL80211_WIPHY_RADIO_FREQ_ATTR_START,
++ NL80211_WIPHY_RADIO_FREQ_ATTR_END,
++
++ __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST,
++ NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST - 1,
++};
++
+ #endif /* __LINUX_NL80211_H */
+--- a/iwinfo_nl80211.c
++++ b/iwinfo_nl80211.c
+@@ -37,6 +37,11 @@
+
+ static struct nl80211_state *nls = NULL;
+
++struct nl80211_if_data {
++ int mode;
++ int radio_idx;
++};
++
+ static void nl80211_close(void)
+ {
+ if (nls)
+@@ -862,7 +867,7 @@ static char * nl80211_phy2ifname(const c
+
+ static int nl80211_get_mode_cb(struct nl_msg *msg, void *arg)
+ {
+- int *mode = arg;
++ struct nl80211_if_data *data = arg;
+ struct nlattr **tb = nl80211_parse(msg);
+ const int ifmodes[NL80211_IFTYPE_MAX + 1] = {
+ IWINFO_OPMODE_UNKNOWN, /* unspecified */
+@@ -878,37 +883,57 @@ static int nl80211_get_mode_cb(struct nl
+ };
+
+ if (tb[NL80211_ATTR_IFTYPE])
+- *mode = ifmodes[nla_get_u32(tb[NL80211_ATTR_IFTYPE])];
++ data->mode = ifmodes[nla_get_u32(tb[NL80211_ATTR_IFTYPE])];
++
++ if (tb[NL80211_ATTR_VIF_RADIO_MASK]) {
++ uint32_t mask = nla_get_u32(tb[NL80211_ATTR_VIF_RADIO_MASK]);
++
++ for (int i = 0; mask && i < 32; i++, mask >>= 1)
++ if (mask & 1)
++ data->radio_idx = i;
++ }
+
+ return NL_SKIP;
+ }
+
+
+-static int nl80211_get_mode(const char *ifname, int *buf)
++static int nl80211_get_if_data(const char *ifname, struct nl80211_if_data *data)
+ {
+ char *res;
+
+- *buf = IWINFO_OPMODE_UNKNOWN;
+-
+ res = nl80211_phy2ifname(ifname);
+
++ data->mode = IWINFO_OPMODE_UNKNOWN;
++ data->radio_idx = -1;
+ nl80211_request(res ? res : ifname, NL80211_CMD_GET_INTERFACE, 0,
+- nl80211_get_mode_cb, buf);
++ nl80211_get_mode_cb, data);
+
+- return (*buf == IWINFO_OPMODE_UNKNOWN) ? -1 : 0;
++ return (data->mode == IWINFO_OPMODE_UNKNOWN) ? -1 : 0;
++}
++
++static int nl80211_get_mode(const char *ifname, int *buf)
++{
++ struct nl80211_if_data data = {};
++ int ret;
++
++ ret = nl80211_get_if_data(ifname, &data);
++ *buf = data.mode;
++
++ return ret;
+ }
+
+ static int __nl80211_hostapd_query(const char *ifname, ...)
+ {
++ struct nl80211_if_data data = {};
+ va_list ap, ap_cur;
+ char *phy, *search, *dest, *key, *val, buf[128];
+- int len, mode, found = 0, match = 1;
++ int len, found = 0, match = 1;
+ FILE *fp;
+
+- if (nl80211_get_mode(ifname, &mode))
++ if (nl80211_get_if_data(ifname, &data))
+ return 0;
+
+- if (mode != IWINFO_OPMODE_MASTER && mode != IWINFO_OPMODE_AP_VLAN)
++ if (data.mode != IWINFO_OPMODE_MASTER && data.mode != IWINFO_OPMODE_AP_VLAN)
+ return 0;
+
+ phy = nl80211_ifname2phy(ifname);
+@@ -916,7 +941,10 @@ static int __nl80211_hostapd_query(const
+ if (!phy)
+ return 0;
+
+- snprintf(buf, sizeof(buf), "/var/run/hostapd-%s.conf", phy);
++ if (data.radio_idx >= 0)
++ snprintf(buf, sizeof(buf), "/var/run/hostapd-%s.%d.conf", phy, data.radio_idx);
++ else
++ snprintf(buf, sizeof(buf), "/var/run/hostapd-%s.conf", phy);
+ fp = fopen(buf, "r");
+
+ if (!fp)
diff --git a/package/network/utils/layerscape/restool/Makefile b/package/network/utils/layerscape/restool/Makefile
new file mode 100644
index 0000000..bca78fb
--- /dev/null
+++ b/package/network/utils/layerscape/restool/Makefile
@@ -0,0 +1,39 @@
+#
+# Copyright 2017 NXP
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=restool
+PKG_VERSION:=21.08
+PKG_RELEASE:=4
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/nxp-qoriq/restool
+PKG_SOURCE_VERSION:=LSDK-21.08
+PKG_MIRROR_HASH:=3c289e6c9adc2c61445473ecd8b1b1a7b6dfd19a66d3c65f3b83b669e4c3e25b
+
+PKG_FLAGS:=nonshared
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/restool
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Layerscape DPAA2 dynamical management tool
+ DEPENDS:=@TARGET_layerscape_armv8_64b
+endef
+
+MAKE_FLAGS += \
+ DESTDIR="$(PKG_BUILD_DIR)"/output/ \
+ install
+
+define Package/restool/install
+ $(INSTALL_DIR) $(1)/usr/bin/
+ $(CP) $(PKG_BUILD_DIR)/output/usr/local/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,restool))
diff --git a/package/network/utils/layerscape/restool/patches/remove-manpage.patch b/package/network/utils/layerscape/restool/patches/remove-manpage.patch
new file mode 100644
index 0000000..5cb9e0a
--- /dev/null
+++ b/package/network/utils/layerscape/restool/patches/remove-manpage.patch
@@ -0,0 +1,18 @@
+--- a/Makefile
++++ b/Makefile
+@@ -53,14 +53,13 @@ restool: $(OBJ)
+ %.1: %.md
+ pandoc --standalone --to man $^ -o $@
+
+-install: restool scripts/ls-main scripts/ls-append-dpl scripts/ls-debug scripts/restool_completion.sh $(MANPAGE)
++install: restool scripts/ls-main scripts/ls-append-dpl scripts/ls-debug scripts/restool_completion.sh
+ install -D -m 755 restool $(DESTDIR)$(bindir)/restool
+ install -D -m 755 scripts/ls-main $(DESTDIR)$(bindir)/ls-main
+ install -D -m 755 scripts/ls-append-dpl $(DESTDIR)$(bindir)/ls-append-dpl
+ install -D -m 755 scripts/ls-debug $(DESTDIR)$(bindir)/ls-debug
+ $(foreach symlink, $(RESTOOL_SCRIPT_SYMLINKS), sh -c "cd $(DESTDIR)$(bindir) && ln -sf ls-main $(symlink)" ;)
+ install -D -m 755 scripts/restool_completion.sh $(DESTDIR)$(bindir_completion)/restool
+- install -m 0644 -D $(MANPAGE) $(call get_manpage_destination,$(MANPAGE))
+
+ clean:
+ rm -f $(OBJ) $(MANPAGE) \
diff --git a/package/network/utils/linux-atm/Makefile b/package/network/utils/linux-atm/Makefile
new file mode 100644
index 0000000..c48309d
--- /dev/null
+++ b/package/network/utils/linux-atm/Makefile
@@ -0,0 +1,200 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=linux-atm
+PKG_VERSION:=2.5.2
+PKG_RELEASE:=8
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_HASH:=9645481a2b16476b59220aa2d6bc5bc41043f291326c9b37581018fbd16dd53a
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_LICENSE:=GPL-2.0+
+PKG_CPE_ID:=cpe:/a:linux-atm:linux-atm
+PKG_FIXUP:=autoreconf
+PKG_FLAGS:=nonshared
+
+include $(INCLUDE_DIR)/package.mk
+
+ATM_DEBUG_BINS:=aread awrite atmdiag atmdump atmswitch saaldump \
+ sonetdiag svc_recv svc_send ttcp_atm
+ATM_DEBUG_SBINS:=atmaddr atmloop atmtcp esi atmsigd bus \
+ ilmid ilmidiag lecs les mpcd zeppelin
+ATM_DEBUG_TOOLS:=$(ATM_DEBUG_BINS) $(ATM_DEBUG_SBINS)
+
+define Package/linux-atm
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=Linux ATM library
+ URL:=http://linux-atm.sourceforge.net/
+endef
+
+define Package/linux-atm/description
+ This package contains a library for accessing the Linux ATM subsystem.
+endef
+
+define Package/linux-atm/Default
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=+linux-atm
+ URL:=http://linux-atm.sourceforge.net/
+ SUBMENU:=Linux ATM tools
+endef
+
+define Package/atm-tools
+ $(call Package/linux-atm/Default)
+ TITLE:=Linux ATM tools
+endef
+
+define Package/atm-tools/description
+ This package contains the Linux ATM tools.
+endef
+
+define Package/atm-diagnostics
+ $(call Package/linux-atm/Default)
+ TITLE:=Linux ATM Diagnostics
+endef
+
+define Package/atm-diagnostics/description
+ This package contains the Linux ATM diagnostics.
+endef
+
+define Package/atm-debug-tools
+ $(call Package/linux-atm/Default)
+ TITLE:=Linux ATM debugging tools
+endef
+
+define Package/atm-debug-tools/description
+ This package contains the Linux ATM debugging tools.
+endef
+
+define Package/br2684ctl
+ $(call Package/linux-atm/Default)
+ TITLE:=ATM Ethernet bridging configuration utility
+endef
+
+define Package/br2684ctl/description
+ Support for AAL5 encapsulation (RFC-1483/RFC-2684) over ATM.
+endef
+
+define GenAtmPlugin
+ define Package/$(1)
+ $(call Package/linux-atm/Default)
+ TITLE:=Linux ATM tool $(2)
+ endef
+
+ define Package/$(1)/description
+ Linux ATM tool $(2).
+ endef
+endef
+
+$(foreach t,$(ATM_DEBUG_TOOLS),$(eval $(call GenAtmPlugin,atm-$(t),$(t))))
+
+TARGET_CFLAGS += -I$(LINUX_DIR)/user_headers/include
+
+define Build/Configure
+ $(call Build/Configure/Default)
+ # prevent autoheader invocation
+ touch $(PKG_BUILD_DIR)/stamp-h.in
+endef
+
+unexport PREFIX
+
+define Build/Compile
+ # src/qgen is built with HOSTCC, which does not really like our LDFLAGS
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/src/qgen \
+ LDFLAGS="" \
+ all
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) OBJCOPY=$(TARGET_CROSS)objcopy all
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/include \
+ $(PKG_INSTALL_DIR)/usr/lib \
+ $(1)/usr/
+endef
+
+define Package/linux-atm/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libatm.so* $(1)/usr/lib/
+endef
+
+define Package/atm-tools/install
+ $(INSTALL_DIR) $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/atmarp{,d} $(1)/usr/sbin/
+endef
+
+
+define BuildAtmPlugin
+ define Package/$(1)/install
+ $(INSTALL_DIR) $$(1)/usr/$(3)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/$(3)/$(2) $$(1)/usr/$(3)
+ endef
+
+ $$(eval $$(call BuildPackage,$(1)))
+endef
+
+define Package/atm-debug-tools/install
+ $(INSTALL_DIR) $(1)/usr/bin/
+ $(INSTALL_DIR) $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/atmaddr $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/atmloop $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/atmtcp $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/esi $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/aread $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/awrite $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/atmdiag $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/atmdump $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/atmsigd $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/bus $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ilmid $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ilmidiag $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/lecs $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/les $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/mpcd $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/zeppelin $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/atmswitch $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/saaldump $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sonetdiag $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/svc_recv $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/svc_send $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ttcp_atm $(1)/usr/bin/
+endef
+
+define Package/atm-diagnostics/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/aread $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/awrite $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/atmdiag $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/atmdump $(1)/usr/bin/
+endef
+
+define Package/br2684ctl/install
+ $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/hotplug.d/atm $(1)/usr/sbin $(1)/lib/netifd
+ $(INSTALL_BIN) ./files/br2684-up $(1)/lib/netifd/br2684-up
+ $(INSTALL_BIN) ./files/br2684ctl $(1)/etc/init.d/
+ $(INSTALL_CONF) ./files/atm.hotplug $(1)/etc/hotplug.d/atm/00-trigger
+ $(INSTALL_BIN) \
+ ./files/br2684ctl_wrap \
+ $(PKG_INSTALL_DIR)/usr/sbin/br2684ctl \
+ $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,linux-atm))
+$(eval $(call BuildPackage,atm-tools))
+$(eval $(call BuildPackage,atm-debug-tools))
+$(eval $(call BuildPackage,atm-diagnostics))
+$(eval $(call BuildPackage,br2684ctl))
+$(foreach t,$(ATM_DEBUG_BINS),$(eval $(call BuildAtmPlugin,atm-$(t),$(t),bin)))
+$(foreach t,$(ATM_DEBUG_SBINS),$(eval $(call BuildAtmPlugin,atm-$(t),$(t),sbin)))
diff --git a/package/network/utils/linux-atm/files/atm.hotplug b/package/network/utils/linux-atm/files/atm.hotplug
new file mode 100644
index 0000000..68fb96d
--- /dev/null
+++ b/package/network/utils/linux-atm/files/atm.hotplug
@@ -0,0 +1 @@
+ubus call service event '{ "type": "hotplug.atm", "data": { "name": "'"$DEVICENAME"'" } }'
diff --git a/package/network/utils/linux-atm/files/br2684-up b/package/network/utils/linux-atm/files/br2684-up
new file mode 100644
index 0000000..ba1d670
--- /dev/null
+++ b/package/network/utils/linux-atm/files/br2684-up
@@ -0,0 +1,3 @@
+#!/bin/sh
+. /lib/functions/network.sh
+network_ready_device "$1"
diff --git a/package/network/utils/linux-atm/files/br2684ctl b/package/network/utils/linux-atm/files/br2684ctl
new file mode 100755
index 0000000..6513dd3
--- /dev/null
+++ b/package/network/utils/linux-atm/files/br2684ctl
@@ -0,0 +1,84 @@
+#!/bin/sh /etc/rc.common
+
+START=50
+USE_PROCD=1
+
+start_daemon() {
+ local cfg="$1"
+
+ local atmdev disabled
+
+ config_get_bool disabled "$cfg" disabled 0
+ [ "$disabled" -eq 1 ] && return
+
+ config_get atmdev "$cfg" atmdev 0
+
+ local nameprefix
+ config_get nameprefix "$cfg" nameprefix "nas"
+
+ local unit
+ config_get unit "$cfg" unit 0
+
+ local vpi
+ config_get vpi "$cfg" vpi 8
+
+ local vci
+ config_get vci "$cfg" vci 35
+
+ local encaps
+ config_get encaps "$cfg" encaps
+
+ case "$encaps" in
+ 1|vc) encaps=1;;
+ *) encaps=0;;
+ esac
+
+ local payload
+ config_get payload "$cfg" payload
+
+ case "$payload" in
+ 0|routed) payload=0;;
+ *) payload=1;;
+ esac
+
+ local qos
+ config_get qos "$cfg" qos
+
+ local sendsize
+ config_get sendsize "$cfg" sendsize
+
+ found=
+ for device in /sys/class/atm/*; do
+ [ -d "$device" ] || break
+ [ "$(cat $device/atmindex)" = "$atmdev" ] || continue
+ found=1
+ break
+ done
+
+ [ -n "$found" ] || return
+
+ local circuit="$atmdev.$vpi.$vci"
+
+ procd_open_instance
+ procd_set_param command \
+ /usr/sbin/br2684ctl_wrap "${nameprefix}${unit}" \
+ -n "$nameprefix" -c "$unit" -e "$encaps" -p "$payload" \
+ -a "$circuit" ${qos:+-q "$qos"} ${sendsize:+-s "$sendsize"} \
+ -S /lib/netifd/br2684-up
+ procd_close_instance
+}
+
+service_triggers() {
+ local script=$(readlink "$initscript")
+ local name=$(basename ${script:-$initscript})
+
+ procd_open_trigger
+ procd_add_raw_trigger hotplug.atm 2000 /etc/init.d/$name reload
+ procd_add_config_trigger "config.change" "network" /etc/init.d/$name reload
+ procd_close_trigger
+}
+
+start_service() {
+ config_load network
+ config_foreach start_daemon atm-bridge
+}
diff --git a/package/network/utils/linux-atm/files/br2684ctl_wrap b/package/network/utils/linux-atm/files/br2684ctl_wrap
new file mode 100644
index 0000000..d1bc98e
--- /dev/null
+++ b/package/network/utils/linux-atm/files/br2684ctl_wrap
@@ -0,0 +1,5 @@
+#!/bin/sh
+. /lib/functions/network.sh
+device="$1"; shift
+network_defer_device "$device"
+exec /usr/sbin/br2684ctl "$@"
diff --git a/package/network/utils/linux-atm/patches/000-debian_2.5.1-5.1.patch b/package/network/utils/linux-atm/patches/000-debian_2.5.1-5.1.patch
new file mode 100644
index 0000000..27bf6b1
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/000-debian_2.5.1-5.1.patch
@@ -0,0 +1,319 @@
+--- a/src/mpoad/mpcd.8
++++ b/src/mpoad/mpcd.8
+@@ -28,7 +28,7 @@ mpcd \- ATM MPOA (Multi\-Protocol Over A
+ .B ]]
+ .SH DESCRIPTION
+ MPOA client
+-.SM(MPC) is responsible for creating and receiving
++.SM (MPC) is responsible for creating and receiving
+ internetwork layer shortcuts. Using these shortcuts MPCs forward
+ unicast internetwork layer packets effectively over ATM without need
+ for routing protocols.
+@@ -43,7 +43,7 @@ accepts shortcuts and packets arriving o
+ shortcuts is done with the help of
+ .SM MPOA
+ server
+-.SM(MPS).
++.SM (MPS).
+ .PP
+ Just as the Linux
+ .SM LAN
+--- a/src/led/zeppelin.8
++++ b/src/led/zeppelin.8
+@@ -99,7 +99,7 @@ Ring and ATM parts of the ELAN, so using
+ recommended. Token Ring support has received less testing than its
+ Ethernet counterpart.
+ .SH FILES
+-.IP \fI/var/run/lec[interface number].pid\fP
++.IP \fI/var/run/lec[interface\ number].pid\fP
+ The file containing the process id of zeppelin.
+ .SH BUGS
+ John Bonham died 1980 and Led Zeppelin broke.
+--- a/src/sigd/atmsigd.conf.4
++++ b/src/sigd/atmsigd.conf.4
+@@ -125,7 +125,7 @@ a comment. The `#' character cannot be e
+ .P
+ If an option is specified in \fBatmsigd.conf\fP and on the command
+ line, the command line has priority.
+-.COMPATIBILITY
++.SH COMPATIBILITY
+ Certain options used by past versions of \fBatmsigd\fP but no longer documented
+ on the man page are still recognized and supported, but they also yield a
+ warning message. Future versions of \fBatmsigd\fP will not recognize those
+--- a/src/arpd/io.c
++++ b/src/arpd/io.c
+@@ -277,7 +277,8 @@ static void accept_new(void)
+ struct atm_qos qos;
+ ENTRY *entry;
+ VCC *vcc;
+- int fd,len,size,error;
++ int fd,error;
++ socklen_t len,size;
+
+ len = sizeof(addr);
+ if ((fd = accept(incoming,(struct sockaddr *) &addr,&len)) < 0) {
+@@ -614,7 +615,8 @@ int ip_itf_info(int number,uint32_t *ip,
+
+ int get_local(int fd,struct sockaddr_atmsvc *addr)
+ {
+- int length,result;
++ int result;
++ size_t length;
+
+ length = sizeof(struct sockaddr_atmsvc);
+ result = getsockname(fd,(struct sockaddr *) addr,&length);
+--- a/src/arpd/table.c
++++ b/src/arpd/table.c
+@@ -101,7 +101,8 @@ static void dump_vcc(VCC *vcc)
+ char addr_buf[MAX_ATM_ADDR_LEN+1];
+ char qos_buf[MAX_ATM_QOS_LEN+1];
+ struct atm_qos qos;
+- int size,sndbuf;
++ int sndbuf;
++ socklen_t size;
+
+ size = sizeof(addr);
+ if (getpeername(vcc->fd,(struct sockaddr *) &addr,&size) < 0) {
+--- a/src/ilmid/asn1/asn_int.c
++++ b/src/ilmid/asn1/asn_int.c
+@@ -185,7 +185,7 @@ FILE* f _AND_
+ AsnInt* v _AND_
+ unsigned short int indent)
+ {
+- fprintf(f,"%d", *v);
++ fprintf(f,"%ld", *v);
+ }
+
+
+@@ -370,5 +370,5 @@ FILE* f _AND_
+ UAsnInt* v _AND_
+ unsigned short int indent)
+ {
+- fprintf(f,"%u", *v);
++ fprintf(f,"%lu", *v);
+ }
+--- a/src/ilmid/asn1/asn_oid.c
++++ b/src/ilmid/asn1/asn_oid.c
+@@ -127,7 +127,7 @@ unsigned short int indent)
+ if (firstArcNum > 2)
+ firstArcNum = 2;
+
+- fprintf(f,"%u %u", firstArcNum, arcNum - (firstArcNum * 40));
++ fprintf(f,"%d %lu", firstArcNum, arcNum - (firstArcNum * 40));
+
+ for (; i < v->octetLen ; )
+ {
+@@ -136,7 +136,7 @@ unsigned short int indent)
+
+ arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
+ i++;
+- fprintf(f," %u", arcNum);
++ fprintf(f," %lu", arcNum);
+ }
+ fprintf(f,"}");
+
+--- a/src/lane/connect.c
++++ b/src/lane/connect.c
+@@ -258,7 +258,8 @@ static int
+ data_handler(const Event_t *event, void *funcdata)
+ {
+ Conn_t *tmp, *newconn;
+- int fd, nbytes;
++ int fd;
++ socklen_t nbytes;
+ static char buffer[BUFSIZE];
+ LaneControl_t *ctmp;
+ struct sockaddr_atmsvc addr;
+--- a/src/lane/connect_bus.c
++++ b/src/lane/connect_bus.c
+@@ -170,7 +170,8 @@ static int
+ data_handler(const Event_t *event, void *funcdata)
+ {
+ Conn_t *tmp, *newconn;
+- int fd, nbytes;
++ int fd;
++ socklen_t nbytes;
+ static char buffer[BUFSIZE];
+ struct sockaddr_atmsvc addr;
+
+--- a/src/lane/lane_atm.c
++++ b/src/lane/lane_atm.c
+@@ -138,7 +138,7 @@ atm_connect_back(const AtmAddr_t *our_ad
+ struct atm_blli blli;
+ struct atm_qos qos;
+ int fd, ret;
+- int len = sizeof(address);
++ socklen_t len = sizeof(address);
+
+ fd = socket(PF_ATMSVC, SOCK_DGRAM, 0);
+ if (fd <0) {
+--- a/src/lane/lecs.c
++++ b/src/lane/lecs.c
+@@ -119,7 +119,7 @@ int main(int argc, char **argv)
+ int just_dump=0;
+ fd_set fds;
+ struct sockaddr_atmsvc client;
+- int len;
++ socklen_t len;
+ unsigned char buffer[P_SIZE];
+
+ while(i!=-1) {
+--- a/src/lib/ans.c
++++ b/src/lib/ans.c
+@@ -41,7 +41,7 @@
+ static int ans(const char *text,int wanted,void *result,int res_len)
+ {
+ unsigned char answer[MAX_ANSWER];
+- unsigned char name[MAX_NAME];
++ char name[MAX_NAME];
+ unsigned char *pos,*data,*found;
+ int answer_len,name_len,data_len,found_len;
+ int questions,answers;
+--- a/src/lib/sdu2cell.c
++++ b/src/lib/sdu2cell.c
+@@ -15,7 +15,8 @@ int sdu2cell(int s,int sizes,const int *
+ {
+ struct atm_qos qos;
+ int trailer,total,cells;
+- int size,i;
++ int i;
++ socklen_t size;
+
+ size = sizeof(qos);
+ if (getsockopt(s,SOL_AAL,SO_ATMQOS,&qos,&size) < 0) return -1;
+--- a/src/lib/unix.c
++++ b/src/lib/unix.c
+@@ -63,8 +63,8 @@ int un_attach(const char *path)
+ int un_recv_connect(int s,void *buf,int size)
+ {
+ struct sockaddr_un addr;
+- int addr_size;
+ int len;
++ socklen_t addr_size;
+
+ addr_size = sizeof(addr);
+ len = recvfrom(s,buf,size,0,(struct sockaddr *) &addr,&addr_size);
+--- a/src/maint/atmtcp.c
++++ b/src/maint/atmtcp.c
+@@ -817,7 +817,8 @@ int main(int argc,char **argv)
+ }
+ else if (!strcmp(ARG,"listen") ||
+ (do_background = !strcmp(ARG,"listen-bg"))) {
+- int fd,port,addr_len;
++ int fd,port;
++ socklen_t addr_len;
+ int *fd2 = alloc_t(int);
+
+ if ((fd = socket(PF_INET,SOCK_STREAM,0)) < 0) {
+--- a/src/maint/hediag.c
++++ b/src/maint/hediag.c
+@@ -1,6 +1,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
++#include <string.h>
+ #include <sys/ioctl.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+--- a/src/mpoad/io.c
++++ b/src/mpoad/io.c
+@@ -521,7 +521,8 @@ static int msg_from_mps(int slot)
+ static int accept_conn(int slot)
+ {
+ struct sockaddr_atmsvc sa;
+- int i, new_fd, sa_len;
++ int i, new_fd;
++ socklen_t sa_len;
+
+ sa_len = sizeof(sa);
+ new_fd = accept(fds[slot].fd, (struct sockaddr *)&sa, &sa_len);
+--- a/src/sigd/io.c
++++ b/src/sigd/io.c
+@@ -355,7 +355,7 @@ int get_pvc(int itf,int *vci)
+ error = 0;
+ if (bind(s,(struct sockaddr *) &addr,sizeof(addr)) < 0) error = errno;
+ else {
+- int size;
++ socklen_t size;
+
+ size = sizeof(addr);
+ if (getsockname(s,(struct sockaddr *) &addr,&size) < 0)
+--- a/src/test/ttcp.c
++++ b/src/test/ttcp.c
+@@ -92,7 +92,8 @@ struct sockaddr_in frominet;
+ struct sockaddr_atmsvc satm;
+ struct atm_qos qos;
+
+-int domain, fromlen;
++int domain;
++socklen_t fromlen;
+ int fd; /* fd of network socket */
+
+ int buflen = 8 * 1024; /* length of buffer */
+@@ -466,7 +467,7 @@ int no_check = 0;
+
+ {
+ struct sockaddr_atmsvc peer;
+- int peerlen = sizeof(peer);
++ socklen_t peerlen = sizeof(peer);
+ if (getpeername(fd, (struct sockaddr *) &peer,
+ &peerlen) < 0) {
+ err("getpeername");
+@@ -498,7 +499,7 @@ int no_check = 0;
+ /* set socket buffer size */
+ #if defined(SO_SNDBUF) || defined(SO_RCVBUF)
+ if (sockbufsize) {
+- int len;
++ socklen_t len;
+
+ if (trans) {
+ /* set send socket buffer if we are transmitting */
+@@ -663,7 +664,7 @@ int no_check = 0;
+ exit(0);
+
+ usage:
+- fprintf(stderr, Usage);
++ fprintf(stderr, "%s", Usage);
+ exit(1);
+ }
+
+--- a/src/arpd/arp.c
++++ b/src/arpd/arp.c
+@@ -17,6 +17,7 @@
+ #include <netinet/in.h> /* for ntohs, etc. */
+ #define _LINUX_NETDEVICE_H /* very crude hack for glibc2 */
+ #include <linux/types.h>
++#include <linux/if.h>
+ #include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <atm.h>
+--- a/src/arpd/itf.c
++++ b/src/arpd/itf.c
+@@ -14,6 +14,7 @@
+ #include <sys/socket.h>
+ #define _LINUX_NETDEVICE_H /* glibc2 */
+ #include <linux/types.h>
++#include <linux/if.h>
+ #include <linux/if_arp.h>
+
+ #include "atmd.h"
+--- a/src/maint/atmdump.c
++++ b/src/maint/atmdump.c
+@@ -14,6 +14,7 @@
+ #include <sys/types.h>
+ #include <sys/time.h>
+ #include <sys/socket.h>
++#include <linux/sockios.h>
+ #include <netinet/in.h> /* for htonl and ntohl */
+ #include <atm.h>
+
+--- a/src/maint/saaldump.c
++++ b/src/maint/saaldump.c
+@@ -15,6 +15,7 @@
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
++#include <linux/sockios.h>
+ #include <atm.h>
+
+ #include "pdu.h"
diff --git a/package/network/utils/linux-atm/patches/200-no_libfl.patch b/package/network/utils/linux-atm/patches/200-no_libfl.patch
new file mode 100644
index 0000000..6db8779
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/200-no_libfl.patch
@@ -0,0 +1,179 @@
+--- a/src/qgen/Makefile.am
++++ b/src/qgen/Makefile.am
+@@ -2,7 +2,7 @@ noinst_PROGRAMS = qgen
+
+ qgen_SOURCES = common.c common.h file.c file.h first.c ql_y.y ql_l.l qgen.c \
+ qgen.h second.c third.c
+-qgen_LDADD = -lfl
++qgen_LDADD =
+
+ COMPILE = @CC_FOR_BUILD@ @CFLAGS_FOR_BUILD@
+ LINK = @CC_FOR_BUILD@ @CFLAGS_FOR_BUILD@ -o $@
+--- a/src/qgen/Makefile.in
++++ b/src/qgen/Makefile.in
+@@ -204,7 +204,7 @@ top_srcdir = @top_srcdir@
+ qgen_SOURCES = common.c common.h file.c file.h first.c ql_y.y ql_l.l qgen.c \
+ qgen.h second.c third.c
+
+-qgen_LDADD = -lfl
++qgen_LDADD =
+ COMPILE = @CC_FOR_BUILD@ @CFLAGS_FOR_BUILD@
+ LINK = @CC_FOR_BUILD@ @CFLAGS_FOR_BUILD@ -o $@
+
+--- a/src/sigd/Makefile.am
++++ b/src/sigd/Makefile.am
+@@ -8,7 +8,7 @@ atmsigd_XTRAS = mess.o $(top_builddir)/s
+ $(top_builddir)/src/q2931/qd.dump.o \
+ $(top_builddir)/src/lib/libatm.la \
+ $(top_builddir)/src/saal/libsaal.a
+-atmsigd_LDADD = $(atmsigd_XTRAS) -lfl
++atmsigd_LDADD = $(atmsigd_XTRAS)
+ atmsigd_DEPENDENCIES = mess.c $(atmsigd_XTRAS)
+
+ CLEANFILES = mess.c
+--- a/src/sigd/Makefile.in
++++ b/src/sigd/Makefile.in
+@@ -245,7 +245,7 @@ atmsigd_XTRAS = mess.o $(top_builddir)/s
+ $(top_builddir)/src/lib/libatm.la \
+ $(top_builddir)/src/saal/libsaal.a
+
+-atmsigd_LDADD = $(atmsigd_XTRAS) -lfl
++atmsigd_LDADD = $(atmsigd_XTRAS)
+ atmsigd_DEPENDENCIES = mess.c $(atmsigd_XTRAS)
+ CLEANFILES = mess.c
+ sysconf_DATA = atmsigd.conf
+--- a/src/switch/debug/debug.c
++++ b/src/switch/debug/debug.c
+@@ -20,6 +20,11 @@
+
+ #define PRV(call) ((FAB *) (call)->fab)
+
++int yywrap(void)
++{
++ return 1;
++}
++
+
+ typedef struct _fab {
+ CALL *next; /* relay.c may not keep track of calls, but WE are */
+--- a/src/switch/debug/Makefile.am
++++ b/src/switch/debug/Makefile.am
+@@ -5,7 +5,7 @@ INCLUDES = -I$(srcdir)/../../q2931
+ sw_debug_SOURCES = debug.c
+ sw_debug_XTRAS = $(top_builddir)/src/switch/libsw.a \
+ $(top_builddir)/src/lib/libatm.la
+-sw_debug_LDADD = $(sw_debug_XTRAS) -lfl
++sw_debug_LDADD = $(sw_debug_XTRAS)
+
+ sw_debug_DEPENDENCIES = $(sw_debug_XTRAS)
+
+--- a/src/switch/debug/Makefile.in
++++ b/src/switch/debug/Makefile.in
+@@ -200,7 +200,8 @@ sw_debug_SOURCES = debug.c
+ sw_debug_XTRAS = $(top_builddir)/src/switch/libsw.a \
+ $(top_builddir)/src/lib/libatm.la
+
+-sw_debug_LDADD = $(sw_debug_XTRAS) -lfl
++sw_debug_LDADD = $(sw_debug_XTRAS)
++
+ sw_debug_DEPENDENCIES = $(sw_debug_XTRAS)
+ EXTRA_DIST = demo README
+ all: all-am
+--- a/src/switch/tcp/Makefile.am
++++ b/src/switch/tcp/Makefile.am
+@@ -5,7 +5,7 @@ INCLUDES = -I$(srcdir)/../../q2931
+ sw_tcp_SOURCES = tcpsw.c
+ sw_tcp_XTRAS = $(top_builddir)/src/switch/libsw.a \
+ $(top_builddir)/src/lib/libatm.la
+-sw_tcp_LDADD = $(sw_tcp_XTRAS) -lfl
++sw_tcp_LDADD = $(sw_tcp_XTRAS)
+ sw_tcp_DEPENDENCIES = $(sw_tcp_XTRAS)
+
+ EXTRA_DIST = mkfiles README
+--- a/src/switch/tcp/Makefile.in
++++ b/src/switch/tcp/Makefile.in
+@@ -200,7 +200,7 @@ sw_tcp_SOURCES = tcpsw.c
+ sw_tcp_XTRAS = $(top_builddir)/src/switch/libsw.a \
+ $(top_builddir)/src/lib/libatm.la
+
+-sw_tcp_LDADD = $(sw_tcp_XTRAS) -lfl
++sw_tcp_LDADD = $(sw_tcp_XTRAS)
+ sw_tcp_DEPENDENCIES = $(sw_tcp_XTRAS)
+ EXTRA_DIST = mkfiles README
+ all: all-am
+--- a/src/switch/tcp/tcpsw.c
++++ b/src/switch/tcp/tcpsw.c
+@@ -35,6 +35,10 @@
+ #define MAX_PACKET (ATM_MAX_AAL5_PDU+sizeof(struct atmtcp_hdr))
+ #define BUFFER_SIZE (MAX_PACKET*2)
+
++int yywrap(void)
++{
++ return 1;
++}
+
+ typedef struct _table {
+ struct _link *out; /* output port */
+--- a/src/test/Makefile.am
++++ b/src/test/Makefile.am
+@@ -20,7 +20,7 @@ br_SOURCES = br.c
+ bw_SOURCES = bw.c
+ isp_SOURCES = isp.c isp.h ispl_y.y ispl_l.l
+ isp_XTRAS = $(LDADD)
+-isp_LDADD = $(isp_XTRAS) -lfl
++isp_LDADD = $(isp_XTRAS)
+ isp_DEPENDENCIES = $(isp_XTRAS)
+ window_SOURCES = window.c
+
+--- a/src/test/Makefile.in
++++ b/src/test/Makefile.in
+@@ -283,7 +283,7 @@ br_SOURCES = br.c
+ bw_SOURCES = bw.c
+ isp_SOURCES = isp.c isp.h ispl_y.y ispl_l.l
+ isp_XTRAS = $(LDADD)
+-isp_LDADD = $(isp_XTRAS) -lfl
++isp_LDADD = $(isp_XTRAS)
+ isp_DEPENDENCIES = $(isp_XTRAS)
+ window_SOURCES = window.c
+ CLEANFILES = errnos.inc
+--- a/src/test/ispl_l.l
++++ b/src/test/ispl_l.l
+@@ -18,6 +18,11 @@
+ #include "ispl_y.h"
+
+
++int yywrap(void)
++{
++ return 1;
++}
++
+ static int lineno = 1;
+
+ %}
+--- a/src/qgen/ql_l.l
++++ b/src/qgen/ql_l.l
+@@ -11,6 +11,11 @@
+ #include "ql_y.h"
+
+
++int yywrap(void)
++{
++ return 1;
++}
++
+ typedef struct _tree {
+ struct _tree *left,*right;
+ const char str[0];
+--- a/src/sigd/cfg_l.l
++++ b/src/sigd/cfg_l.l
+@@ -16,6 +16,10 @@
+
+ #include "cfg_y.h"
+
++int yywrap(void)
++{
++ return 1;
++}
+
+ static int lineno = 1;
+ static int token; /* f@#%ing flex doesn't grok return after BEGIN */
diff --git a/package/network/utils/linux-atm/patches/300-objcopy_path.patch b/package/network/utils/linux-atm/patches/300-objcopy_path.patch
new file mode 100644
index 0000000..4f11516
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/300-objcopy_path.patch
@@ -0,0 +1,40 @@
+--- a/src/extra/Makefile.am
++++ b/src/extra/Makefile.am
+@@ -7,6 +7,8 @@ EXTRA_DIST = linux-atm.spec.in \
+ BUILT_SOURCES = pca200e.bin pca200e_ecd.bin2 sba200e_ecd.bin2
+ CLEANFILES = pca200e.bin pca200e_ecd.bin2 sba200e_ecd.bin2
+
++OBJCOPY = objcopy
++
+ install-exec-hook:
+ $(MKDIR_P) $(DESTDIR)/lib/firmware
+ $(INSTALL_DATA) $(srcdir)/pca200e.bin $(DESTDIR)/lib/firmware
+@@ -14,7 +16,7 @@ install-exec-hook:
+ $(INSTALL_DATA) $(srcdir)/sba200e_ecd.bin2 $(DESTDIR)/lib/firmware
+
+ %.bin %.bin2: %.data
+- objcopy -Iihex $< -Obinary $@.gz
++ $(OBJCOPY) -Iihex $< -Obinary $@.gz
+ gzip -n -df $@.gz
+
+
+--- a/src/extra/Makefile.in
++++ b/src/extra/Makefile.in
+@@ -187,6 +187,8 @@ CLEANFILES = pca200e.bin pca200e_ecd.bin
+ all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
++OBJCOPY = objcopy
++
+ .SUFFIXES:
+ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+@@ -385,7 +387,7 @@ install-exec-hook:
+ $(INSTALL_DATA) $(srcdir)/sba200e_ecd.bin2 $(DESTDIR)/lib/firmware
+
+ %.bin %.bin2: %.data
+- objcopy -Iihex $< -Obinary $@.gz
++ $(OBJCOPY) -Iihex $< -Obinary $@.gz
+ gzip -n -df $@.gz
+
+ # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/package/network/utils/linux-atm/patches/400-portability_fixes.patch b/package/network/utils/linux-atm/patches/400-portability_fixes.patch
new file mode 100644
index 0000000..41425ee
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/400-portability_fixes.patch
@@ -0,0 +1,70 @@
+--- a/src/ilmid/io.c
++++ b/src/ilmid/io.c
+@@ -48,6 +48,14 @@
+ be manually configured (after ilmid has
+ registered the "official" address) - HACK */
+
++#ifndef SUN_LEN
++# include <string.h> /* For prototype of `strlen'. */
++
++/* Evaluate to actual length of the `sockaddr_un' structure. */
++# define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
++ + strlen ((ptr)->sun_path))
++#endif
++
+ extern SysGroup *remsys;
+ extern State ilmi_state;
+ static short atm_itf = -1; /* bad value */
+--- a/src/mpoad/io.c
++++ b/src/mpoad/io.c
+@@ -10,14 +10,7 @@
+ #include <errno.h>
+ #include <sys/ioctl.h>
+ #include <sys/param.h> /* for OPEN_MAX */
+-#if __GLIBC__ >= 2
+ #include <sys/poll.h>
+-#else /* ugly hack to make it compile on RH 4.2 - WA */
+-#include <syscall.h>
+-#include <linux/poll.h>
+-#define SYS_poll 168
+-_syscall3(int,poll,struct pollfd *,ufds,unsigned int,nfds,int,timeout);
+-#endif
+ #include <atm.h>
+ #include <linux/types.h>
+ #include <linux/atmioc.h>
+--- a/src/sigd/atmsigd.c
++++ b/src/sigd/atmsigd.c
+@@ -283,12 +283,11 @@ static void setup_signals(void)
+ /* ------------------------------- main ... ------------------------------- */
+
+
+-static void trace_on_exit(int status,void *dummy)
++static void trace_on_exit(void)
+ {
+ char path[PATH_MAX+1];
+ FILE *file;
+
+- if (!status) return;
+ if (!dump_dir) file = stderr;
+ else {
+ sprintf(path,"atmsigd.%d.trace.exit",getpid());
+@@ -517,7 +516,7 @@ int main(int argc,char **argv)
+ exit(0);
+ }
+ }
+- (void) on_exit(trace_on_exit,NULL);
++ (void) atexit(trace_on_exit);
+ poll_loop();
+ close_all();
+ for (sig = entities; sig; sig = sig->next) stop_saal(&sig->saal);
+--- a/src/test/align.c
++++ b/src/test/align.c
+@@ -24,7 +24,7 @@
+ #include <signal.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+-#include <sys/errno.h>
++#include <errno.h>
+ #include <atm.h>
+
+
diff --git a/package/network/utils/linux-atm/patches/500-br2684ctl_script.patch b/package/network/utils/linux-atm/patches/500-br2684ctl_script.patch
new file mode 100644
index 0000000..78aabf8
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/500-br2684ctl_script.patch
@@ -0,0 +1,63 @@
+--- a/src/br2684/br2684ctl.c
++++ b/src/br2684/br2684ctl.c
+@@ -1,3 +1,4 @@
++#define _GNU_SOURCE
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+@@ -43,6 +44,7 @@ struct br2684_params {
+
+
+ int lastsock, lastitf;
++static char *up_script;
+
+
+ void fatal(const char *str, int err)
+@@ -185,6 +187,8 @@ int assign_vcc(char *astr, int encap, in
+
+ void start_interface(struct br2684_params* params)
+ {
++ char *cmd;
++
+ if (params->astr==NULL) {
+ syslog(LOG_ERR, "Required ATM parameters not specified.");
+ exit(1);
+@@ -193,13 +197,18 @@ void start_interface(struct br2684_param
+ create_br(params->itfnum, params->payload);
+ assign_vcc(params->astr, params->encap, params->payload, params->sndbuf,
+ params->reqqos);
++ if (up_script) {
++ asprintf(&cmd, "%s nas%d", up_script, lastitf);
++ system(cmd);
++ free(cmd);
++ }
+ }
+
+
+ void usage(char *s)
+ {
+ printf("usage: %s [-b] [[-c number] [-e 0|1] [-s sndbuf] [-q qos] [-p 0|1] "
+- "[-a [itf.]vpi.vci]*]*\n", s);
++ "[-a [itf.]vpi.vci]*]* [-S script]\n", s);
+ printf(" encapsulations: 0=llc, 1=vcmux\n payloads: 0=routed, 1=bridged\n");
+ exit(1);
+ }
+@@ -225,7 +234,7 @@ int main (int argc, char **argv)
+
+ openlog (LOG_NAME,LOG_OPTION,LOG_FACILITY);
+ if (argc>1)
+- while ((c = getopt(argc, argv,"q:a:bc:e:s:p:?h")) !=EOF)
++ while ((c = getopt(argc, argv,"q:a:bc:e:s:S:p:?h")) !=EOF)
+ switch (c) {
+ case 'q':
+ printf ("optarg : %s",optarg);
+@@ -258,6 +267,9 @@ int main (int argc, char **argv)
+ params.sndbuf=8192;
+ }
+ break;
++ case 'S':
++ up_script = optarg;
++ break;
+ case 'p': /* payload type: routed (0) or bridged (1) */
+ #ifdef BR2684_FLAG_ROUTED
+ params.payload = atoi(optarg);
diff --git a/package/network/utils/linux-atm/patches/501-br2684ctl_itfname.patch b/package/network/utils/linux-atm/patches/501-br2684ctl_itfname.patch
new file mode 100644
index 0000000..839b395
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/501-br2684ctl_itfname.patch
@@ -0,0 +1,74 @@
+--- a/src/br2684/br2684ctl.c
++++ b/src/br2684/br2684ctl.c
+@@ -45,6 +45,7 @@ struct br2684_params {
+
+ int lastsock, lastitf;
+ static char *up_script;
++const char *itfname = "nas";
+
+
+ void fatal(const char *str, int err)
+@@ -73,7 +74,7 @@ int create_pidfile(int num)
+
+ if (num < 0) return -1;
+
+- snprintf(name, 32, "/var/run/br2684ctl-nas%d.pid", num);
++ snprintf(name, 32, "/var/run/br2684ctl-%s%d.pid", itfname, num);
+ pidfile = fopen(name, "w");
+ if (pidfile == NULL) return -1;
+ fprintf(pidfile, "%d", getpid());
+@@ -102,7 +103,7 @@ int create_br(int itfnum, int payload)
+ ni.media |= BR2684_FLAG_ROUTED;
+ #endif
+ ni.mtu = 1500;
+- sprintf(ni.ifname, "nas%d", itfnum);
++ sprintf(ni.ifname, "%s%d", itfname, itfnum);
+ err=ioctl (lastsock, ATM_NEWBACKENDIF, &ni);
+
+ if (err == 0)
+@@ -167,7 +168,7 @@ int assign_vcc(char *astr, int encap, in
+
+ be.backend_num = ATM_BACKEND_BR2684;
+ be.ifspec.method = BR2684_FIND_BYIFNAME;
+- sprintf(be.ifspec.spec.ifname, "nas%d", lastitf);
++ sprintf(be.ifspec.spec.ifname, "%s%d", itfname, lastitf);
+ be.fcs_in = BR2684_FCSIN_NO;
+ be.fcs_out = BR2684_FCSOUT_NO;
+ be.fcs_auto = 0;
+@@ -198,7 +199,7 @@ void start_interface(struct br2684_param
+ assign_vcc(params->astr, params->encap, params->payload, params->sndbuf,
+ params->reqqos);
+ if (up_script) {
+- asprintf(&cmd, "%s nas%d", up_script, lastitf);
++ asprintf(&cmd, "%s %s%d", up_script, itfname, lastitf);
+ system(cmd);
+ free(cmd);
+ }
+@@ -207,7 +208,7 @@ void start_interface(struct br2684_param
+
+ void usage(char *s)
+ {
+- printf("usage: %s [-b] [[-c number] [-e 0|1] [-s sndbuf] [-q qos] [-p 0|1] "
++ printf("usage: %s [-b] [-n name] [[-c number] [-e 0|1] [-s sndbuf] [-q qos] [-p 0|1] "
+ "[-a [itf.]vpi.vci]*]* [-S script]\n", s);
+ printf(" encapsulations: 0=llc, 1=vcmux\n payloads: 0=routed, 1=bridged\n");
+ exit(1);
+@@ -234,7 +235,7 @@ int main (int argc, char **argv)
+
+ openlog (LOG_NAME,LOG_OPTION,LOG_FACILITY);
+ if (argc>1)
+- while ((c = getopt(argc, argv,"q:a:bc:e:s:S:p:?h")) !=EOF)
++ while ((c = getopt(argc, argv,"q:a:bn:c:e:s:S:p:?h")) !=EOF)
+ switch (c) {
+ case 'q':
+ printf ("optarg : %s",optarg);
+@@ -247,6 +248,9 @@ int main (int argc, char **argv)
+ case 'b':
+ background=1;
+ break;
++ case 'n':
++ itfname = optarg;
++ break;
+ case 'c':
+ /* temporary, to make it work with multiple interfaces: */
+ if (params.itfnum>=0) start_interface(¶ms);
diff --git a/package/network/utils/linux-atm/patches/510-remove-LINUX_NETDEVICE-hack.patch b/package/network/utils/linux-atm/patches/510-remove-LINUX_NETDEVICE-hack.patch
new file mode 100644
index 0000000..c16df18
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/510-remove-LINUX_NETDEVICE-hack.patch
@@ -0,0 +1,52 @@
+This fixes the following compile problem with kernel 4.20:
+
+In file included from arp.c:20:0:
+include/linux/if_arp.h:121:16: error: 'IFNAMSIZ' undeclared here (not in a function)
+ char arp_dev[IFNAMSIZ];
+ ^~~~~~~~
+make[7]: *** [Makefile:459: arp.o] Error 1
+
+This is caused by commit 6a12709da354 ("net: if_arp: use define instead
+of hard-coded value") in the upstream Linux kernel which is integrated
+in Linux 4.20.
+
+--- a/src/oamd/io.c
++++ b/src/oamd/io.c
+@@ -20,7 +20,6 @@
+ #include <net/if.h>
+ #include <netinet/in.h>
+ #include <atm.h>
+-#define _LINUX_NETDEVICE_H /* glibc2 */
+ #include <linux/types.h>
+ #include <linux/if_arp.h>
+
+--- a/src/arpd/itf.c
++++ b/src/arpd/itf.c
+@@ -12,7 +12,6 @@
+ #include <sys/types.h>
+ #include <linux/atmclip.h>
+ #include <sys/socket.h>
+-#define _LINUX_NETDEVICE_H /* glibc2 */
+ #include <linux/types.h>
+ #include <linux/if.h>
+ #include <linux/if_arp.h>
+--- a/src/arpd/io.c
++++ b/src/arpd/io.c
+@@ -21,7 +21,6 @@
+ #include <atm.h>
+ #include <linux/atmclip.h> /* for CLIP_DEFAULT_IDLETIMER */
+ #include <linux/atmarp.h>
+-#define _LINUX_NETDEVICE_H /* glibc2 */
+ #include <linux/types.h>
+ #include <linux/if_arp.h>
+
+--- a/src/arpd/arp.c
++++ b/src/arpd/arp.c
+@@ -15,7 +15,6 @@
+ #include <sys/types.h>
+ #include <sys/socket.h> /* for linux/if_arp.h */
+ #include <netinet/in.h> /* for ntohs, etc. */
+-#define _LINUX_NETDEVICE_H /* very crude hack for glibc2 */
+ #include <linux/types.h>
+ #include <linux/if.h>
+ #include <linux/if_arp.h>
diff --git a/package/network/utils/linux-atm/patches/600-musl-include.patch b/package/network/utils/linux-atm/patches/600-musl-include.patch
new file mode 100644
index 0000000..2b2268d
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/600-musl-include.patch
@@ -0,0 +1,30 @@
+--- a/src/include/atmd.h
++++ b/src/include/atmd.h
+@@ -10,6 +10,7 @@
+
+ #include <stdint.h>
+ #include <stdio.h>
++#include <string.h>
+ #include <sys/types.h>
+ #include <sys/time.h>
+
+--- a/src/lib/unix.c
++++ b/src/lib/unix.c
+@@ -8,6 +8,7 @@
+
+ #include <stdlib.h>
+ #include <stdio.h>
++#include <string.h>
+ #include <unistd.h>
+ #include <errno.h>
+ #include <sys/types.h>
+--- a/src/sigd/kernel.c
++++ b/src/sigd/kernel.c
+@@ -8,6 +8,7 @@
+
+ #include <stdlib.h>
+ #include <stdio.h>
++#include <string.h>
+ #include <errno.h>
+ #include <assert.h>
+
diff --git a/package/network/utils/linux-atm/patches/700-fix-gcc14-build.patch b/package/network/utils/linux-atm/patches/700-fix-gcc14-build.patch
new file mode 100644
index 0000000..a19dc6c
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/700-fix-gcc14-build.patch
@@ -0,0 +1,82 @@
+--- a/src/arpd/io.c
++++ b/src/arpd/io.c
+@@ -615,7 +615,7 @@ int ip_itf_info(int number,uint32_t *ip,
+ int get_local(int fd,struct sockaddr_atmsvc *addr)
+ {
+ int result;
+- size_t length;
++ socklen_t length;
+
+ length = sizeof(struct sockaddr_atmsvc);
+ result = getsockname(fd,(struct sockaddr *) addr,&length);
+--- a/src/led/conn.c
++++ b/src/led/conn.c
+@@ -405,7 +405,7 @@ Conn_t *accept_conn(Conn_t *conn)
+ {
+ Conn_t *new;
+ struct sockaddr_atmsvc addr;
+- size_t len;
++ socklen_t len;
+ int fd;
+ char buff[MAX_ATM_ADDR_LEN+1];
+
+@@ -538,7 +538,7 @@ static int handle_accept(Conn_t *conn)
+ */
+ static int handle_data(Conn_t *conn)
+ {
+- char buff[MAX_CTRL_FRAME];
++ unsigned char buff[MAX_CTRL_FRAME];
+ int retval;
+
+ retval = recv_frame(conn, buff, sizeof(buff));
+--- a/src/led/frames.c
++++ b/src/led/frames.c
+@@ -312,7 +312,7 @@ static void handle_ready_ind(Conn_t *con
+ * dependant handler functions.
+ * Returns < 0 for serious error
+ */
+-int handle_frame(Conn_t *conn, char *buff, int size)
++int handle_frame(Conn_t *conn, unsigned char *buff, int size)
+ {
+ struct ctrl_frame *frame;
+
+--- a/src/led/frames.h
++++ b/src/led/frames.h
+@@ -13,7 +13,7 @@ int validate_frame(unsigned char *buff,
+ void send_ready_ind(Conn_t *conn);
+ void send_register_req(void);
+
+-int handle_frame(Conn_t *conn, char *buff, int size);
++int handle_frame(Conn_t *conn, unsigned char *buff, int size);
+ uint32_t send_flush_req(Conn_t *conn);
+
+ void parse_tlvs(uint16_t opcode, unsigned char *tlvp, int numtlvs, int sizeoftlvs);
+--- a/src/led/join.c
++++ b/src/led/join.c
+@@ -43,7 +43,7 @@ static int read_join_rsp(char *buff, int
+ static int parse_join_rsp(unsigned char *buff, int size);
+
+ static int get_bus_addr(struct sockaddr_atmsvc *addr);
+-static int read_bus_arp(Conn_t *conn, struct sockaddr_atmsvc *addr, char *buff, int buffsize);
++static int read_bus_arp(Conn_t *conn, struct sockaddr_atmsvc *addr, unsigned char *buff, int buffsize);
+
+ /*
+ * 5.1, Initial state
+@@ -693,7 +693,7 @@ static int get_bus_addr(struct sockaddr_
+ fd_set rfds;
+ struct timeval tv;
+ int n = 0, retval, timeout;
+- char buff[MAX_CTRL_FRAME];
++ unsigned char buff[MAX_CTRL_FRAME];
+
+ timeout = 4; /* wait response for 4 seconds */
+ lec_params.c7c_current_timeout = 1;
+@@ -740,7 +740,7 @@ static int get_bus_addr(struct sockaddr_
+ * Tries to read BUS ATM address in *addr
+ * returns < 0 for error, 0 for not found > 0 for success
+ */
+-static int read_bus_arp(Conn_t *conn, struct sockaddr_atmsvc *addr, char *buff, int buffsize)
++static int read_bus_arp(Conn_t *conn, struct sockaddr_atmsvc *addr, unsigned char *buff, int buffsize)
+ {
+ int frame_size;
+ struct ctrl_frame *frame;
diff --git a/package/network/utils/ltq-dsl-base/Makefile b/package/network/utils/ltq-dsl-base/Makefile
new file mode 100644
index 0000000..b51851f
--- /dev/null
+++ b/package/network/utils/ltq-dsl-base/Makefile
@@ -0,0 +1,34 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ltq-dsl-base
+PKG_RELEASE:=3
+
+PKG_FLAGS:=nonshared
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ltq-dsl-base
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=DSL related files for Intel/Lantiq DSL Chipsets
+ URL:=http://openwrt.org/
+ DEPENDS:=@(TARGET_lantiq||TARGET_ipq40xx) +jshn
+endef
+
+define Package/ltq-dsl-base/description
+ This package contains DSL related files for Intel/Lantiq DSL Chipsets.
+endef
+
+define Build/Compile
+endef
+
+define Package/ltq-dsl-base/install
+ $(CP) ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,ltq-dsl-base))
diff --git a/package/network/utils/ltq-dsl-base/files/etc/hotplug.d/dsl/led_dsl.sh b/package/network/utils/ltq-dsl-base/files/etc/hotplug.d/dsl/led_dsl.sh
new file mode 100755
index 0000000..dd8e84a
--- /dev/null
+++ b/package/network/utils/ltq-dsl-base/files/etc/hotplug.d/dsl/led_dsl.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+[ "$DSL_NOTIFICATION_TYPE" = "DSL_INTERFACE_STATUS" ] || exit 0
+
+. /lib/functions.sh
+. /lib/functions/leds.sh
+
+led_dsl_up() {
+ case "$(config_get led_dsl trigger)" in
+ "netdev")
+ led_set_attr $1 "trigger" "netdev"
+ led_set_attr $1 "device_name" "$(config_get led_dsl dev)"
+ for m in $(config_get led_dsl mode); do
+ led_set_attr $1 "$m" "1"
+ done
+ ;;
+ *)
+ led_on $1
+ ;;
+ esac
+}
+
+config_load system
+config_get led led_dsl sysfs
+if [ -n "$led" ]; then
+ case "$DSL_INTERFACE_STATUS" in
+ "HANDSHAKE") led_timer $led 500 500;;
+ "TRAINING") led_timer $led 200 200;;
+ "UP") led_dsl_up $led;;
+ *) led_off $led
+ esac
+fi
diff --git a/package/network/utils/ltq-dsl-base/files/etc/hotplug.d/dsl/pppoa.sh b/package/network/utils/ltq-dsl-base/files/etc/hotplug.d/dsl/pppoa.sh
new file mode 100755
index 0000000..4506737
--- /dev/null
+++ b/package/network/utils/ltq-dsl-base/files/etc/hotplug.d/dsl/pppoa.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+[ "$DSL_NOTIFICATION_TYPE" = "DSL_INTERFACE_STATUS" ] || exit 0
+
+. /usr/share/libubox/jshn.sh
+. /lib/functions.sh
+
+include /lib/network
+scan_interfaces
+
+interfaces=$(ubus list network.interface.\* | cut -d"." -f3)
+for ifc in $interfaces; do
+
+ json_load "$(ifstatus $ifc)"
+
+ json_get_var proto proto
+ if [ "$proto" != "pppoa" ]; then
+ continue
+ fi
+
+ json_get_var up up
+ config_get_bool auto "$ifc" auto 1
+ if [ "$DSL_INTERFACE_STATUS" = "UP" ]; then
+ if [ "$up" != 1 ] && [ "$auto" = 1 ]; then
+ ( sleep 1; ifup "$ifc" ) &
+ fi
+ else
+ if [ "$up" = 1 ] && [ "$auto" = 1 ]; then
+ ( sleep 1; ifdown "$ifc" ) &
+ else
+ json_get_var autostart autostart
+ if [ "$up" != 1 ] && [ "$autostart" = 1 ]; then
+ ( sleep 1; ifdown "$ifc" ) &
+ fi
+ fi
+ fi
+done
diff --git a/package/network/utils/ltq-dsl-base/files/sbin/dsl_notify.sh b/package/network/utils/ltq-dsl-base/files/sbin/dsl_notify.sh
new file mode 100755
index 0000000..d615db5
--- /dev/null
+++ b/package/network/utils/ltq-dsl-base/files/sbin/dsl_notify.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+#
+# This script is called by dsl_cpe_control whenever there is a DSL event
+# and calls any available hotplug script(s) in /etc/hotplug.d/dsl.
+
+exec /sbin/hotplug-call dsl
diff --git a/package/network/utils/net-snmp/Makefile b/package/network/utils/net-snmp/Makefile
new file mode 100644
index 0000000..75a80cc
--- /dev/null
+++ b/package/network/utils/net-snmp/Makefile
@@ -0,0 +1,292 @@
+#
+# Copyright (C) 2006-2017 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=net-snmp
+PKG_VERSION:=5.8
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/net-snmp
+PKG_HASH:=b2fc3500840ebe532734c4786b0da4ef0a5f67e51ef4c86b3345d697e4976adf
+PKG_MAINTAINER:=Stijn Tintel <stijn@linux-ipv6.be>
+PKG_LICENSE:=MIT BSD-3-Clause-Clear
+PKG_CPE_ID:=cpe:/a:net-snmp:net-snmp
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/net-snmp/Default
+ SECTION:=net
+ CATEGORY:=Network
+ URL:=http://www.net-snmp.org/
+endef
+
+define Package/net-snmp/Default/description
+ Simple Network Management Protocol (SNMP) is a widely used protocol for
+ monitoring the health and welfare of network equipment (eg. routers),
+ computer equipment and even devices like UPSs. Net-SNMP is a suite of
+ applications used to implement SNMP v1, SNMP v2c and SNMP v3 using both
+ IPv4 and IPv6.
+endef
+
+
+define Package/libnetsnmp
+$(call Package/net-snmp/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=+libnl-tiny +libpci
+ TITLE:=Open source SNMP implementation (libraries)
+endef
+
+define Package/libnetsnmp/description
+$(call Package/net-snmp/Default/description)
+ .
+ This package contains shared libraries, needed by other programs.
+endef
+
+
+define Package/snmp-mibs
+$(call Package/net-snmp/Default)
+ TITLE:=Open source SNMP implementation (MIB-files)
+endef
+
+define Package/snmp-mibs/description
+$(call Package/net-snmp/Default/description)
+ .
+ This package contains SNMP MIB-Files.
+endef
+
+
+define Package/snmp-utils
+$(call Package/net-snmp/Default)
+ DEPENDS:=+libnetsnmp
+ TITLE:=Open source SNMP implementation (utilities)
+endef
+
+define Package/snmp-utils/description
+$(call Package/net-snmp/Default/description)
+ .
+ This package contains SNMP client utilities:
+ - snmpget
+ - snmpset
+ - snmpstatus
+ - snmptest
+ - snmptrap
+ - snmpwalk
+endef
+
+
+define Package/snmpd
+$(call Package/net-snmp/Default)
+ DEPENDS:=+libnetsnmp
+ TITLE:=Open source SNMP implementation (daemon)
+endef
+
+define Package/snmpd/description
+$(call Package/net-snmp/Default/description)
+ .
+ This package contains the SNMP agent, dynamically linked.
+endef
+
+
+define Package/snmpd-static
+$(call Package/net-snmp/Default)
+ DEPENDS:=+snmpd
+ TITLE:=Open source SNMP implementation (daemon)
+ BUILDONLY:=1
+endef
+
+
+define Package/snmptrapd
+$(call Package/net-snmp/Default)
+ DEPENDS:=+libnetsnmp
+ TITLE:=Open source SNMP implementation (notification receiver)
+endef
+
+define Package/snmptrapd/description
+$(call Package/net-snmp/Default/description)
+ .
+ This package contains the SNMP notification receiver.
+endef
+
+
+SNMP_MIB_MODULES_INCLUDED = \
+ agent/extend \
+ agentx \
+ host/hr_device \
+ host/hr_disk \
+ host/hr_filesys \
+ host/hr_network \
+ host/hr_partition \
+ host/hr_proc \
+ host/hr_storage \
+ host/hr_system \
+ ieee802dot11 \
+ if-mib/ifXTable \
+ ip-mib/inetNetToMediaTable \
+ mibII/at \
+ mibII/icmp \
+ mibII/ifTable \
+ mibII/ip \
+ mibII/snmp_mib \
+ mibII/sysORTable \
+ mibII/system_mib \
+ mibII/tcp \
+ mibII/udp \
+ mibII/vacm_context \
+ mibII/vacm_vars \
+ snmpv3/snmpEngine \
+ snmpv3/snmpMPDStats \
+ snmpv3/usmConf \
+ snmpv3/usmStats \
+ snmpv3/usmUser \
+ tunnel \
+ ucd-snmp/disk \
+ ucd-snmp/dlmod \
+ ucd-snmp/extensible \
+ ucd-snmp/loadave \
+ ucd-snmp/memory \
+ ucd-snmp/pass \
+ ucd-snmp/pass_persist \
+ ucd-snmp/proc \
+ ucd-snmp/vmstat \
+ util_funcs \
+ utilities/execute \
+
+SNMP_MIB_MODULES_EXCLUDED = \
+ agent_mibs \
+ disman/event \
+ disman/schedule \
+ hardware \
+ host \
+ if-mib \
+ ip-mib \
+ mibII \
+ notification \
+ notification-log-mib \
+ snmpv3mibs \
+ target \
+ tcp-mib \
+ ucd_snmp \
+ udp-mib \
+ utilities \
+
+SNMP_TRANSPORTS_INCLUDED = Callback UDP Unix
+
+SNMP_TRANSPORTS_EXCLUDED = TCP TCPIPv6
+
+TARGET_CFLAGS += $(FPIC)
+TARGET_CPPFLAGS += -I$(STAGING_DIR)/usr/include/libnl-tiny
+
+CONFIGURE_ARGS += \
+ --enable-mfd-rewrites \
+ --enable-shared \
+ --enable-static \
+ --with-endianness=$(if $(CONFIG_BIG_ENDIAN),big,little) \
+ --with-logfile=/var/log/snmpd.log \
+ --with-persistent-directory=/usr/lib/snmp/ \
+ --with-default-snmp-version=1 \
+ --with-sys-contact=root@localhost \
+ --with-sys-location=Unknown \
+ --enable-applications \
+ --disable-debugging \
+ --disable-manuals \
+ --disable-scripts \
+ --with-out-mib-modules="$(SNMP_MIB_MODULES_EXCLUDED)" \
+ --with-mib-modules="$(SNMP_MIB_MODULES_INCLUDED)" \
+ --with-out-transports="$(SNMP_TRANSPORTS_EXCLUDED)" \
+ --with-transports="$(SNMP_TRANSPORTS_INCLUDED)" \
+ --without-openssl \
+ --without-libwrap \
+ --without-mysql \
+ --without-rpm \
+ --without-zlib \
+ --with-nl \
+ $(call autoconf_bool,CONFIG_IPV6,ipv6) \
+ --disable-perl-cc-checks \
+ --disable-embedded-perl \
+ --without-perl-modules
+
+CONFIGURE_VARS += \
+ ac_cv_header_netlink_netlink_h=yes \
+ ac_cv_header_pcre_h=no \
+ netsnmp_cv_func_nl_connect_LIBS=-lnl-tiny \
+
+ifeq ($(CONFIG_IPV6),y)
+SNMP_TRANSPORTS_INCLUDED+= UDPIPv6
+endif
+
+TARGET_LDFLAGS += -L$(TOOLCHAIN_DIR)/usr/lib
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \
+ LDFLAGS="$(TARGET_LDFLAGS) -lm -lc" \
+ all install
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(2)/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/net-snmp-config $(2)/bin/
+ $(SED) 's,=/usr,=$(STAGING_DIR)/usr,g' $(2)/bin/net-snmp-config
+ $(INSTALL_DIR) $(STAGING_DIR)/usr/bin
+ $(LN) $(STAGING_DIR)/host/bin/net-snmp-config $(STAGING_DIR)/usr/bin/
+
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/net-snmp $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnetsnmp{,agent,helpers,mibs}.{a,so*} $(1)/usr/lib/
+endef
+
+define Package/libnetsnmp/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnetsnmp{,agent,helpers,mibs}.so.* $(1)/usr/lib/
+endef
+
+define Package/snmp-mibs/install
+ $(INSTALL_DIR) $(1)/usr/share/snmp/mibs
+ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/snmp/mibs/* $(1)/usr/share/snmp/mibs/
+endef
+
+define Package/snmp-utils/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/snmp{get,set,status,test,trap,walk} $(1)/usr/bin/
+endef
+
+define Package/snmpd/conffiles
+/etc/config/snmpd
+endef
+
+define Package/snmpd/install
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_DATA) ./files/snmpd.conf $(1)/etc/config/snmpd
+ $(INSTALL_DIR) $(1)/etc/snmp
+ $(LN) /var/run/snmpd.conf $(1)/etc/snmp/
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/snmpd.init $(1)/etc/init.d/snmpd
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/snmpd $(1)/usr/sbin/snmpd
+endef
+
+define Package/snmptrapd/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/snmptrapd.init $(1)/etc/init.d/snmptrapd
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnetsnmptrapd.so.* $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/snmptrapd $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,libnetsnmp))
+$(eval $(call BuildPackage,snmp-mibs))
+$(eval $(call BuildPackage,snmp-utils))
+$(eval $(call BuildPackage,snmpd))
+$(eval $(call BuildPackage,snmpd-static))
+$(eval $(call BuildPackage,snmptrapd))
diff --git a/package/network/utils/net-snmp/files/snmpd.conf b/package/network/utils/net-snmp/files/snmpd.conf
new file mode 100644
index 0000000..e18864d
--- /dev/null
+++ b/package/network/utils/net-snmp/files/snmpd.conf
@@ -0,0 +1,130 @@
+config agent
+ option agentaddress UDP:161,UDP6:161
+
+config agentx
+ option agentxsocket /var/run/agentx.sock
+
+config com2sec public
+ option secname ro
+ option source default
+ option community public
+
+config com2sec private
+ option secname rw
+ option source localhost
+ option community private
+
+config com2sec6 public6
+ option secname ro
+ option source default
+ option community public
+
+config com2sec6 private6
+ option secname rw
+ option source localhost
+ option community private
+
+config group public_v1
+ option group public
+ option version v1
+ option secname ro
+
+config group public_v2c
+ option group public
+ option version v2c
+ option secname ro
+
+config group public_usm
+ option group public
+ option version usm
+ option secname ro
+
+config group private_v1
+ option group private
+ option version v1
+ option secname rw
+
+config group private_v2c
+ option group private
+ option version v2c
+ option secname rw
+
+config group private_usm
+ option group private
+ option version usm
+ option secname rw
+
+config view all
+ option viewname all
+ option type included
+ option oid .1
+
+config access public_access
+ option group public
+ option context none
+ option version any
+ option level noauth
+ option prefix exact
+ option read all
+ option write none
+ option notify none
+
+config access private_access
+ option group private
+ option context none
+ option version any
+ option level noauth
+ option prefix exact
+ option read all
+ option write all
+ option notify all
+
+config system
+ option sysLocation 'office'
+ option sysContact 'bofh@example.com'
+ option sysName 'HeartOfGold'
+# option sysServices 72
+# option sysDescr 'adult playground'
+# option sysObjectID '1.2.3.4'
+
+config exec
+ option name filedescriptors
+ option prog /bin/cat
+ option args /proc/sys/fs/file-nr
+# option miboid 1.2.3.4
+
+config engineid
+# option engineid 'LEDE'
+ option engineidtype '3'
+ option engineidnic 'eth0'
+
+#config trapcommunity 'trapcommunity'
+# option community 'public'
+
+#config trapsink
+# option host 'nms.system.com'
+# option community 'public'
+# option port '162'
+
+#config trap2sink
+# option host 'nms.system.com'
+# option community 'secret'
+# option port '162'
+
+#config informsink
+# option host 'nms.sytem.com'
+# option community 'public'
+# option port '162'
+
+#config authtrapenable 'authtrapenable'
+# option enable '1'
+
+#config v1trapaddress 'v1trapaddress'
+# option host '1.2.3.4'
+
+#config trapsess 'trapsess'
+# option trapsess '-v 3 -e 0x80001f88808c18d3f7b0000 -u trapuser -a MD5 -A administrator -l authPriv -x DES -X rootpasswd udp:127.0.0.1:162'
+
+config snmpd general
+ option enabled '1'
+# list network 'wan'
diff --git a/package/network/utils/net-snmp/files/snmpd.init b/package/network/utils/net-snmp/files/snmpd.init
new file mode 100644
index 0000000..fbae9c2
--- /dev/null
+++ b/package/network/utils/net-snmp/files/snmpd.init
@@ -0,0 +1,359 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2008 OpenWrt.org
+START=50
+
+USE_PROCD=1
+PROG="/usr/sbin/snmpd"
+
+CONFIGFILE="/var/run/snmpd.conf"
+
+snmpd_agent_add() {
+ local cfg="$1"
+
+ config_get agentaddress "$cfg" agentaddress
+ [ -n "$agentaddress" ] || return 0
+ echo "agentaddress $agentaddress" >> $CONFIGFILE
+}
+
+snmpd_agentx_add() {
+ local cfg="$1"
+ echo "master agentx" >> $CONFIGFILE
+ config_get agentxsocket "$cfg" agentxsocket
+ [ -n "$agentxsocket" ] && echo "agentXSocket $agentxsocket" >> $CONFIGFILE
+}
+
+snmpd_system_add() {
+ local cfg="$1"
+ config_get syslocation "$cfg" sysLocation
+ [ -n "$syslocation" ] && echo "sysLocation $syslocation" >> $CONFIGFILE
+ config_get syscontact "$cfg" sysContact
+ [ -n "$syscontact" ] && echo "sysContact $syscontact" >> $CONFIGFILE
+ config_get sysname "$cfg" sysName
+ [ -n "$sysname" ] && echo "sysName $sysname" >> $CONFIGFILE
+ config_get sysservice "$cfg" sysService
+ [ -n "$sysservice" ] && echo "sysService $sysservice" >> $CONFIGFILE
+ config_get sysdescr "$cfg" sysDescr
+ [ -n "$sysdescr" ] && echo "sysDescr $sysdescr" >> $CONFIGFILE
+ config_get sysobjectid "$cfg" sysObjectID
+ [ -n "$sysobjectid" ] && echo "sysObjectID $sysobjectid" >> $CONFIGFILE
+}
+
+snmpd_com2sec_add() {
+ local cfg="$1"
+ config_get secname "$cfg" secname
+ [ -n "$secname" ] || return 0
+ config_get source "$cfg" source
+ [ -n "$source" ] || return 0
+ config_get community "$cfg" community
+ [ -n "$community" ] || return 0
+ echo "com2sec $secname $source $community" >> $CONFIGFILE
+}
+
+snmpd_com2sec6_add() {
+ local cfg="$1"
+ config_get secname "$cfg" secname
+ [ -n "$secname" ] || return 0
+ config_get source "$cfg" source
+ [ -n "$source" ] || return 0
+ config_get community "$cfg" community
+ [ -n "$community" ] || return 0
+ echo "com2sec6 $secname $source $community" >> $CONFIGFILE
+}
+
+snmpd_group_add() {
+ local cfg="$1"
+ config_get group "$cfg" group
+ [ -n "$group" ] || return 0
+ config_get version "$cfg" version
+ [ -n "$version" ] || return 0
+ config_get secname "$cfg" secname
+ [ -n "$secname" ] || return 0
+ echo "group $group $version $secname" >> $CONFIGFILE
+}
+
+snmpd_view_add() {
+ local cfg="$1"
+ config_get viewname "$cfg" viewname
+ [ -n "$viewname" ] || return 0
+ config_get type "$cfg" type
+ [ -n "$type" ] || return 0
+ config_get oid "$cfg" oid
+ [ -n "$oid" ] || return 0
+ # optional mask
+ config_get mask "$cfg" mask
+ echo "view $viewname $type $oid $mask" >> $CONFIGFILE
+}
+
+snmpd_access_add() {
+ local cfg="$1"
+ config_get group "$cfg" group
+ [ -n "$group" ] || return 0
+ config_get context "$cfg" context
+ [ -n $context ] || return 0
+ [ "$context" == "none" ] && context='""'
+ config_get version "$cfg" version
+ [ -n "$version" ] || return 0
+ config_get level "$cfg" level
+ [ -n "$level" ] || return 0
+ config_get prefix "$cfg" prefix
+ [ -n "$prefix" ] || return 0
+ config_get read "$cfg" read
+ [ -n "$read" ] || return 0
+ config_get write "$cfg" write
+ [ -n "$write" ] || return 0
+ config_get notify "$cfg" notify
+ [ -n "$notify" ] || return 0
+ echo "access $group $context $version $level $prefix $read $write $notify" >> $CONFIGFILE
+}
+
+snmpd_trap_hostname_add() {
+ local cfg="$1"
+ config_get hostname "$cfg" HostName
+ config_get port "$cfg" Port
+ config_get community "$cfg" Community
+ config_get type "$cfg" Type
+ echo "$type $hostname $community $port" >> $CONFIGFILE
+}
+
+snmpd_trap_ip_add() {
+ local cfg="$1"
+ config_get host_ip "$cfg" HostIP
+ config_get port "$cfg" Port
+ config_get community "$cfg" Community
+ config_get type "$cfg" Type
+ echo "$type $host_ip $community $port" >> $CONFIGFILE
+}
+
+snmpd_access_default_add() {
+ local cfg="$1"
+ config_get mode "$cfg" Mode
+ config_get community "$cfg" CommunityName
+ config_get oidrestrict "$cfg" RestrictOID
+ config_get oid "$cfg" RestrictedOID
+ echo -n "$mode $community default" >> $CONFIGFILE
+ [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE
+ [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE
+}
+
+snmpd_access_HostName_add() {
+ local cfg="$1"
+ config_get hostname "$cfg" HostName
+ config_get mode "$cfg" Mode
+ config_get community "$cfg" CommunityName
+ config_get oidrestrict "$cfg" RestrictOID
+ config_get oid "$cfg" RestrictedOID
+ echo -n "$mode $community $hostname" >> $CONFIGFILE
+ [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE
+ [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE
+}
+
+snmpd_access_HostIP_add() {
+ local cfg="$1"
+ config_get host_ip "$cfg" HostIP
+ config_get ip_mask "$cfg" IPMask
+ config_get mode "$cfg" Mode
+ config_get community "$cfg" CommunityName
+ config_get oidrestrict "$cfg" RestrictOID
+ config_get oid "$cfg" RestrictedOID
+ echo -n "$mode $community $host_ip/$ip_mask" >> $CONFIGFILE
+ [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE
+ [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE
+}
+
+snmpd_pass_add() {
+ local cfg="$1"
+ local pass='pass'
+
+ config_get miboid "$cfg" miboid
+ [ -n "$miboid" ] || return 0
+ config_get prog "$cfg" prog
+ [ -n "$prog" ] || return 0
+ config_get_bool persist "$cfg" persist 0
+ [ $persist -ne 0 ] && pass='pass_persist'
+ config_get priority "$cfg" priority
+ priority=${priority:+-p $priority}
+ echo "$pass $priority $miboid $prog" >> $CONFIGFILE
+}
+
+snmpd_exec_add() {
+ local cfg="$1"
+
+ config_get name "$cfg" name
+ [ -n "$name" ] || return 0
+ config_get prog "$cfg" prog
+ [ -n "$prog" ] || return 0
+ config_get args "$cfg" args
+ config_get miboid "$cfg" miboid
+ echo "exec $miboid $name $prog $args" >> $CONFIGFILE
+}
+
+snmpd_extend_add() {
+ local cfg="$1"
+
+ config_get name "$cfg" name
+ [ -n "$name" ] || return 0
+ config_get prog "$cfg" prog
+ [ -n "$prog" ] || return 0
+ config_get args "$cfg" args
+ config_get miboid "$cfg" miboid
+ echo "extend $miboid $name $prog $args" >> $CONFIGFILE
+}
+
+snmpd_disk_add() {
+ local cfg="$1"
+ local disk='disk'
+
+ config_get partition "$cfg" partition
+ [ -n "$partition" ] || return 0
+ config_get size "$cfg" size
+ [ -n "$size" ] || return 0
+ echo "$disk $partition $size" >> $CONFIGFILE
+}
+
+snmpd_engineid_add() {
+ local cfg="$1"
+
+ config_get engineid "$cfg" engineid
+ [ -n "$engineid" ] && echo "engineID $engineid" >> $CONFIGFILE
+ config_get engineidtype "$cfg" engineidtype
+ [ "$engineidtype" -ge 1 -a "$engineidtype" -le 3 ] && \
+ echo "engineIDType $engineidtype" >> $CONFIGFILE
+ config_get engineidnic "$cfg" engineidnic
+ [ -n "$engineidnic" ] && echo "engineIDNic $engineidnic" >> $CONFIGFILE
+}
+
+snmpd_sink_add() {
+ local cfg="$1"
+ local section="$2"
+ local community
+ local port
+ local host
+
+ config_get host "$cfg" host
+ [ -n "section" -a -n "$host" ] || return 0
+ # optional community
+ config_get community "$cfg" community
+ # optional port
+ config_get port "$cfg" port
+ port=${port:+:$port}
+ echo "$section $host$port $community" >> $CONFIGFILE
+}
+
+append_parm() {
+ local section="$1"
+ local option="$2"
+ local switch="$3"
+ local _loctmp
+ config_get _loctmp "$section" "$option"
+ [ -z "$_loctmp" ] && return 0
+ echo "$switch $_loctmp" >> $CONFIGFILE
+}
+
+append_authtrapenable() {
+ local section="$1"
+ local option="$2"
+ local switch="$3"
+ local _loctmp
+ config_get_bool _loctmp "$section" "$option"
+ [ -z "$_loctmp" ] && return 0
+ [ "$_loctmp" -gt 0 ] && echo "$switch $_loctmp" >> $CONFIGFILE
+}
+
+snmpd_setup_fw_rules() {
+ local net="$1"
+ local zone
+
+ zone=$(fw3 -q network "$net" 2>/dev/null)
+
+ local handled_zone
+ for handled_zone in $HANDLED_SNMP_ZONES; do
+ [ "$handled_zone" = "$zone" ] && return
+ done
+
+ json_add_object ""
+ json_add_string type rule
+ json_add_string src "$zone"
+ json_add_string proto udp
+ json_add_string dest_port 161
+ json_add_string target ACCEPT
+ json_close_object
+
+ HANDLED_SNMP_ZONES="$HANDLED_SNMP_ZONES $zone"
+}
+
+start_service() {
+ [ -f "$CONFIGFILE" ] && rm -f "$CONFIGFILE"
+
+ config_load snmpd
+
+ config_get_bool snmp_enabled general enabled 1
+ [ "$snmp_enabled" -eq 0 ] && return
+
+ procd_open_instance
+
+ config_foreach snmpd_agent_add agent
+ config_foreach snmpd_agentx_add agentx
+ config_foreach snmpd_system_add system
+ config_foreach snmpd_com2sec_add com2sec
+ config_foreach snmpd_com2sec6_add com2sec6
+ config_foreach snmpd_group_add group
+ config_foreach snmpd_view_add view
+ config_foreach snmpd_access_add access
+ config_foreach snmpd_trap_hostname_add trap_HostName
+ config_foreach snmpd_trap_ip_add trap_HostIP
+ config_foreach snmpd_access_default_add access_default
+ config_foreach snmpd_access_HostName_add access_HostName
+ config_foreach snmpd_access_HostIP_add access_HostIP
+ config_foreach snmpd_pass_add pass
+ config_foreach snmpd_exec_add exec
+ config_foreach snmpd_extend_add extend
+ config_foreach snmpd_disk_add disk
+ config_foreach snmpd_engineid_add engineid
+ append_parm trapcommunity community trapcommunity
+ config_foreach snmpd_sink_add trapsink trapsink
+ config_foreach snmpd_sink_add trap2sink trap2sink
+ config_foreach snmpd_sink_add informsink informsink
+ append_authtrapenable authtrapenable enable authtrapenable
+ append_parm v1trapaddress host v1trapaddress
+ append_parm trapsess trapsess trapsess
+
+ procd_set_param command $PROG -Lf /dev/null -f -r
+ procd_set_param file $CONFIGFILE
+ procd_set_param respawn
+
+ for iface in $(ls /sys/class/net 2>/dev/null); do
+ procd_append_param netdev "$iface"
+ done
+
+ procd_open_data
+
+ json_add_array firewall
+ config_list_foreach general network snmpd_setup_fw_rules
+ json_close_array
+
+ procd_close_data
+
+ procd_close_instance
+}
+
+stop_service() {
+ [ -f "$CONFIGFILE" ] || return
+ rm -f "$CONFIGFILE"
+ procd_set_config_changed firewall
+}
+
+service_triggers(){
+ local script=$(readlink "$initscript")
+ local name=$(basename ${script:-$initscript})
+
+ procd_open_trigger
+ procd_add_raw_trigger "interface.*" 2000 /etc/init.d/$name reload
+ procd_close_trigger
+
+ procd_add_reload_trigger 'snmpd'
+}
+
+service_started() {
+ [ "$snmp_enabled" -eq 0 ] && return
+ procd_set_config_changed firewall
+}
diff --git a/package/network/utils/net-snmp/files/snmptrapd.init b/package/network/utils/net-snmp/files/snmptrapd.init
new file mode 100644
index 0000000..43278a2
--- /dev/null
+++ b/package/network/utils/net-snmp/files/snmptrapd.init
@@ -0,0 +1,15 @@
+#!/bin/sh /etc/rc.common
+
+START=50
+
+USE_PROCD=1
+PROG="/usr/sbin/snmptrapd"
+
+start_service() {
+ procd_open_instance
+
+ procd_set_param command $PROG -Lf /dev/null -f
+ procd_set_param respawn
+
+ procd_close_instance
+}
diff --git a/package/network/utils/net-snmp/patches/000-cross-compile.patch b/package/network/utils/net-snmp/patches/000-cross-compile.patch
new file mode 100644
index 0000000..730bdbc
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/000-cross-compile.patch
@@ -0,0 +1,47 @@
+From: Jo-Philipp Wich <jo@mein.io>
+Date: Fri, 6 Jan 2017 13:41:00 +0100
+Subject: [PATCH] configure: allow overriding hardcoded /usr/include/libnl3
+
+In a cross-compile setting we do not want to probe the host systems
+/usr/include path, therfore allow to disable this include path by passing
+ac_cv_header_netlink_netlink_h=yes to configure.
+
+Also disable the testing for libraries providing nl_connect when
+netsnmp_cv_func_nl_connect_LIBS is predefined since the proprietary
+NETSNMP_SEARCH_LIBS() macro will clobber the internal link flags upon
+encountering predefined cache variables, causing all subsequent configure
+link tests to fail due to a stray "no" word getting passed to the linker.
+
+Signed-off-by: Jo-Philipp Wich <jo@mein.io>
+--- a/configure.d/config_os_libs2
++++ b/configure.d/config_os_libs2
+@@ -254,14 +254,22 @@ if test "x$with_nl" != "xno"; then
+ )
+
+ netsnmp_save_CPPFLAGS="$CPPFLAGS"
+- CPPFLAGS="${LIBNL3_CFLAGS} $CPPFLAGS"
+- NETSNMP_SEARCH_LIBS(nl_connect, nl-3,
+- [AC_CHECK_HEADERS(netlink/netlink.h)
+- EXTERNAL_MIBGROUP_INCLUDES="$EXTERNAL_MIBGROUP_INCLUDES ${LIBNL3_CFLAGS}"],
+- [CPPFLAGS="$netsnmp_save_CPPFLAGS"], [], [], [LMIBLIBS])
++ netsnmp_netlink_include_flags=""
+ if test "x$ac_cv_header_netlink_netlink_h" != xyes; then
+- NETSNMP_SEARCH_LIBS(nl_connect, nl, [
+- AC_CHECK_HEADERS(netlink/netlink.h)], [], [], LMIBLIBS)
++ netsnmp_netlink_include_flags="-I/usr/include/libnl3"
++ fi
++ CPPFLAGS="$netsnmp_netlink_include_flags $CPPFLAGS"
++ if test "x$netsnmp_cv_func_nl_connect_LIBS" = x; then
++ NETSNMP_SEARCH_LIBS(nl_connect, nl-3,
++ [AC_CHECK_HEADERS(netlink/netlink.h)
++ EXTERNAL_MIBGROUP_INCLUDES="$EXTERNAL_MIBGROUP_INCLUDES $netsnmp_netlink_include_flags"],
++ [CPPFLAGS="$netsnmp_save_CPPFLAGS"], [], [], [LMIBLIBS])
++ if test "x$ac_cv_header_netlink_netlink_h" != xyes; then
++ NETSNMP_SEARCH_LIBS(nl_connect, nl, [
++ AC_CHECK_HEADERS(netlink/netlink.h)], [], [], LMIBLIBS)
++ fi
++ else
++ LMIBLIBS="$LMIBLIBS $netsnmp_cv_func_nl_connect_LIBS"
+ fi
+ if test "x$ac_cv_header_netlink_netlink_h" = xyes; then
+ AC_EGREP_HEADER([nl_socket_free], [netlink/socket.h],
diff --git a/package/network/utils/net-snmp/patches/100-debian-statistics.patch b/package/network/utils/net-snmp/patches/100-debian-statistics.patch
new file mode 100644
index 0000000..2b24d94
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/100-debian-statistics.patch
@@ -0,0 +1,22 @@
+--- a/agent/mibgroup/mibII/interfaces.c
++++ b/agent/mibgroup/mibII/interfaces.c
+@@ -1588,6 +1588,10 @@ Interface_Scan_Init(void)
+ struct ifnet *nnew;
+ char *stats, *ifstart = line;
+
++ /* Ignore interfaces with no statistics. */
++ if (strstr(line, "No statistics available."))
++ continue;
++
+ if (line[strlen(line) - 1] == '\n')
+ line[strlen(line) - 1] = '\0';
+
+@@ -1620,7 +1624,7 @@ Interface_Scan_Init(void)
+ &coll) != 5)) {
+ if ((scan_line_to_use == scan_line_2_2)
+ && !strstr(line, "No statistics available"))
+- snmp_log(LOG_ERR,
++ snmp_log(LOG_DEBUG,
+ "/proc/net/dev data format error, line ==|%s|",
+ line);
+ continue;
diff --git a/package/network/utils/net-snmp/patches/110-debian-makefiles.patch b/package/network/utils/net-snmp/patches/110-debian-makefiles.patch
new file mode 100644
index 0000000..2cb2715
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/110-debian-makefiles.patch
@@ -0,0 +1,40 @@
+--- a/local/Makefile.in
++++ b/local/Makefile.in
+@@ -101,7 +101,7 @@ tkmib.made: $(srcdir)/tkmib
+
+ mib2c.made: $(srcdir)/mib2c
+ if test "x$(PERL)" != "x" ; then \
+- $(PERL) -p -e 's%^#!.*/perl.*%#!$(PERL)%;s#/usr/local/share/snmp#$(snmplibdir)#;' ${srcdir}/mib2c > mib2c.made; \
++ $(PERL) -p -e 's%^#!.*/perl.*%#!$(PERL)%;s#/usr/local/share/snmp#$(snmplibdir)#;s#/usr/local/etc/snmp#$(SNMPCONFPATH)#;' ${srcdir}/mib2c > mib2c.made; \
+ else \
+ touch mib2c.made; \
+ fi
+--- a/Makefile.top
++++ b/Makefile.top
+@@ -28,6 +28,7 @@ man8dir = $(mandir)/man8
+ snmplibdir = $(datadir)/snmp
+ mibdir = $(snmplibdir)/mibs
+ persistentdir = @PERSISTENT_DIRECTORY@
++sysconfdir = @sysconfdir@
+ DESTDIR = @INSTALL_PREFIX@
+ INSTALL_PREFIX = $(DESTDIR)
+
+--- a/mibs/Makefile.in
++++ b/mibs/Makefile.in
+@@ -47,11 +47,15 @@ NETSNMPMIBS = NET-SNMP-TC.txt NET-SNMP-M
+ UCDMIBS = UCD-SNMP-MIB.txt UCD-DEMO-MIB.txt UCD-IPFWACC-MIB.txt \
+ UCD-DLMOD-MIB.txt UCD-DISKIO-MIB.txt
+
++EXTRAMIBS = BGP4-MIB.txt BRIDGE-MIB.txt GNOME-SMI.txt OSPF-MIB.txt \
++ OSPF-TRAP-MIB.txt RIPv2-MIB.txt SOURCE-ROUTING-MIB.txt \
++ LM-SENSORS-MIB.txt
++
+ DEFAULTMIBS = @default_mibs_install@
+
+ MIBS = $(V1MIBS) $(V2MIBS) $(V3MIBS) $(RFCMIBS) \
+ $(AGENTMIBS) $(IANAMIBS) \
+- $(NETSNMPMIBS) $(UCDMIBS) $(DEFAULTMIBS)
++ $(NETSNMPMIBS) $(UCDMIBS) $(DEFAULTMIBS) $(EXTRAMIBS)
+
+ all: standardall
+
diff --git a/package/network/utils/net-snmp/patches/120-debian-searchdirs.patch b/package/network/utils/net-snmp/patches/120-debian-searchdirs.patch
new file mode 100644
index 0000000..b5e377f
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/120-debian-searchdirs.patch
@@ -0,0 +1,14 @@
+--- a/local/mib2c
++++ b/local/mib2c
+@@ -61,8 +61,9 @@ $currentlevel = -1;
+ if($ENV{MIB2C_DIR}) {
+ push @def_search_dirs, split(/:/, $ENV{MIB2C_DIR});
+ }
+-push @def_search_dirs, "/usr/local/share/snmp/";
+-push @def_search_dirs, "/usr/local/share/snmp/mib2c-data";
++push @def_search_dirs, "/etc/snmp/";
++push @def_search_dirs, "/usr/share/snmp/";
++push @def_search_dirs, "/usr/share/snmp/mib2c-data";
+ push @def_search_dirs, "./mib2c-conf.d";
+
+ sub usage {
diff --git a/package/network/utils/net-snmp/patches/130-debian-extramibs.patch b/package/network/utils/net-snmp/patches/130-debian-extramibs.patch
new file mode 100644
index 0000000..48fb907
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/130-debian-extramibs.patch
@@ -0,0 +1,5183 @@
+--- /dev/null
++++ b/mibs/BGP4-MIB.txt
+@@ -0,0 +1,929 @@
++ BGP4-MIB DEFINITIONS ::= BEGIN
++
++ IMPORTS
++ MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
++ IpAddress, Integer32, Counter32, Gauge32, mib-2
++ FROM SNMPv2-SMI
++ MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
++ FROM SNMPv2-CONF;
++
++ bgp MODULE-IDENTITY
++ LAST-UPDATED "9902100000Z"
++ ORGANIZATION "IETF IDR Working Group"
++ CONTACT-INFO "E-mail: idr@merit.net
++
++ Susan Hares (Editor)
++ Merit Network
++ 4251 Plymouth Road
++ Suite C
++ Ann Arbor, MI 48105-2785
++ Tel: +1 734 936 2095
++ Fax: +1 734 647 3185
++ E-mail: skh@merit.edu
++
++ Jeff Johnson (Editor)
++ RedBack Networks, Inc.
++ 1389 Moffett Park Drive
++ Sunnyvale, CA 94089-1134
++ Tel: +1 408 548 3516
++ Fax: +1 408 548 3599
++ E-mail: jeff@redback.com"
++ DESCRIPTION
++ "The MIB module for BGP-4."
++ REVISION "9902100000Z"
++ DESCRIPTION
++ "Corrected duplicate OBJECT IDENTIFIER
++ assignment in the conformance information."
++ REVISION "9601080000Z"
++ DESCRIPTION
++ "1) Fixed the definitions of the traps to
++ make them equivalent to their initial
++ definition in RFC 1269.
++ 2) Added compliance and conformance info."
++ ::= { mib-2 15 }
++
++ bgpVersion OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE (1..255))
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "Vector of supported BGP protocol version
++ numbers. Each peer negotiates the version
++ from this vector. Versions are identified
++ via the string of bits contained within this
++ object. The first octet contains bits 0 to
++ 7, the second octet contains bits 8 to 15,
++ and so on, with the most significant bit
++ referring to the lowest bit number in the
++ octet (e.g., the MSB of the first octet
++ refers to bit 0). If a bit, i, is present
++ and set, then the version (i+1) of the BGP
++ is supported."
++ ::= { bgp 1 }
++
++ bgpLocalAs OBJECT-TYPE
++ SYNTAX INTEGER (0..65535)
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The local autonomous system number."
++ ::= { bgp 2 }
++
++
++
++ -- BGP Peer table. This table contains, one entry per BGP
++ -- peer, information about the BGP peer.
++
++ bgpPeerTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF BgpPeerEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "BGP peer table. This table contains,
++ one entry per BGP peer, information about the
++ connections with BGP peers."
++ ::= { bgp 3 }
++
++ bgpPeerEntry OBJECT-TYPE
++ SYNTAX BgpPeerEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "Entry containing information about the
++ connection with a BGP peer."
++ INDEX { bgpPeerRemoteAddr }
++ ::= { bgpPeerTable 1 }
++
++ BgpPeerEntry ::= SEQUENCE {
++ bgpPeerIdentifier
++ IpAddress,
++ bgpPeerState
++ INTEGER,
++ bgpPeerAdminStatus
++ INTEGER,
++ bgpPeerNegotiatedVersion
++ Integer32,
++ bgpPeerLocalAddr
++ IpAddress,
++ bgpPeerLocalPort
++ INTEGER,
++ bgpPeerRemoteAddr
++ IpAddress,
++ bgpPeerRemotePort
++ INTEGER,
++ bgpPeerRemoteAs
++ INTEGER,
++ bgpPeerInUpdates
++ Counter32,
++ bgpPeerOutUpdates
++ Counter32,
++ bgpPeerInTotalMessages
++ Counter32,
++ bgpPeerOutTotalMessages
++ Counter32,
++ bgpPeerLastError
++ OCTET STRING,
++ bgpPeerFsmEstablishedTransitions
++ Counter32,
++ bgpPeerFsmEstablishedTime
++ Gauge32,
++ bgpPeerConnectRetryInterval
++ INTEGER,
++ bgpPeerHoldTime
++ INTEGER,
++ bgpPeerKeepAlive
++ INTEGER,
++ bgpPeerHoldTimeConfigured
++ INTEGER,
++ bgpPeerKeepAliveConfigured
++ INTEGER,
++ bgpPeerMinASOriginationInterval
++ INTEGER,
++ bgpPeerMinRouteAdvertisementInterval
++ INTEGER,
++ bgpPeerInUpdateElapsedTime
++ Gauge32
++ }
++
++ bgpPeerIdentifier OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The BGP Identifier of this entry's BGP peer."
++ ::= { bgpPeerEntry 1 }
++
++ bgpPeerState OBJECT-TYPE
++ SYNTAX INTEGER {
++ idle(1),
++ connect(2),
++ active(3),
++ opensent(4),
++ openconfirm(5),
++ established(6)
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The BGP peer connection state."
++ ::= { bgpPeerEntry 2 }
++
++ bgpPeerAdminStatus OBJECT-TYPE
++ SYNTAX INTEGER {
++ stop(1),
++ start(2)
++ }
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "The desired state of the BGP connection. A
++ transition from 'stop' to 'start' will cause
++ the BGP Start Event to be generated. A
++ transition from 'start' to 'stop' will cause
++ the BGP Stop Event to be generated. This
++ parameter can be used to restart BGP peer
++ connections. Care should be used in providing
++ write access to this object without adequate
++ authentication."
++ ::= { bgpPeerEntry 3 }
++
++ bgpPeerNegotiatedVersion OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The negotiated version of BGP running between
++ the two peers."
++ ::= { bgpPeerEntry 4 }
++
++ bgpPeerLocalAddr OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The local IP address of this entry's BGP
++ connection."
++ ::= { bgpPeerEntry 5 }
++
++ bgpPeerLocalPort OBJECT-TYPE
++ SYNTAX INTEGER (0..65535)
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The local port for the TCP connection between
++ the BGP peers."
++ ::= { bgpPeerEntry 6 }
++
++ bgpPeerRemoteAddr OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The remote IP address of this entry's BGP
++ peer."
++ ::= { bgpPeerEntry 7 }
++
++ bgpPeerRemotePort OBJECT-TYPE
++ SYNTAX INTEGER (0..65535)
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The remote port for the TCP connection between
++ the BGP peers. Note that the objects
++ bgpPeerLocalAddr, bgpPeerLocalPort,
++ bgpPeerRemoteAddr and bgpPeerRemotePort
++ provide the appropriate reference to the
++ standard MIB TCP connection table."
++ ::= { bgpPeerEntry 8 }
++
++ bgpPeerRemoteAs OBJECT-TYPE
++ SYNTAX INTEGER (0..65535)
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The remote autonomous system number."
++ ::= { bgpPeerEntry 9 }
++
++ bgpPeerInUpdates OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of BGP UPDATE messages received on
++ this connection. This object should be
++ initialized to zero (0) when the connection is
++ established."
++ ::= { bgpPeerEntry 10 }
++
++ bgpPeerOutUpdates OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of BGP UPDATE messages transmitted
++ on this connection. This object should be
++ initialized to zero (0) when the connection is
++ established."
++ ::= { bgpPeerEntry 11 }
++
++ bgpPeerInTotalMessages OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The total number of messages received from the
++ remote peer on this connection. This object
++ should be initialized to zero when the
++ connection is established."
++ ::= { bgpPeerEntry 12 }
++
++ bgpPeerOutTotalMessages OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The total number of messages transmitted to
++ the remote peer on this connection. This object
++ should be initialized to zero when the
++ connection is established."
++ ::= { bgpPeerEntry 13 }
++
++ bgpPeerLastError OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE (2))
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The last error code and subcode seen by this
++ peer on this connection. If no error has
++ occurred, this field is zero. Otherwise, the
++ first byte of this two byte OCTET STRING
++ contains the error code, and the second byte
++ contains the subcode."
++ ::= { bgpPeerEntry 14 }
++
++ bgpPeerFsmEstablishedTransitions OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The total number of times the BGP FSM
++ transitioned into the established state."
++ ::= { bgpPeerEntry 15 }
++
++ bgpPeerFsmEstablishedTime OBJECT-TYPE
++ SYNTAX Gauge32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "This timer indicates how long (in seconds) this
++ peer has been in the Established state or how long
++ since this peer was last in the Established state.
++ It is set to zero when a new peer is configured or
++ the router is booted."
++ ::= { bgpPeerEntry 16 }
++
++ bgpPeerConnectRetryInterval OBJECT-TYPE
++ SYNTAX INTEGER (1..65535)
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "Time interval in seconds for the ConnectRetry
++ timer. The suggested value for this timer is
++ 120 seconds."
++ ::= { bgpPeerEntry 17 }
++
++ bgpPeerHoldTime OBJECT-TYPE
++ SYNTAX INTEGER ( 0 | 3..65535 )
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "Time interval in seconds for the Hold Timer
++ established with the peer. The value of this
++ object is calculated by this BGP speaker by
++ using the smaller of the value in
++ bgpPeerHoldTimeConfigured and the Hold Time
++ received in the OPEN message. This value
++ must be at lease three seconds if it is not
++ zero (0) in which case the Hold Timer has
++ not been established with the peer, or, the
++ value of bgpPeerHoldTimeConfigured is zero (0)."
++ ::= { bgpPeerEntry 18 }
++
++ bgpPeerKeepAlive OBJECT-TYPE
++ SYNTAX INTEGER ( 0 | 1..21845 )
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "Time interval in seconds for the KeepAlive
++ timer established with the peer. The value of
++ this object is calculated by this BGP speaker
++ such that, when compared with bgpPeerHoldTime,
++ it has the same proportion as what
++ bgpPeerKeepAliveConfigured has when compared
++ with bgpPeerHoldTimeConfigured. If the value
++ of this object is zero (0), it indicates that
++ the KeepAlive timer has not been established
++ with the peer, or, the value of
++ bgpPeerKeepAliveConfigured is zero (0)."
++ ::= { bgpPeerEntry 19 }
++
++ bgpPeerHoldTimeConfigured OBJECT-TYPE
++ SYNTAX INTEGER ( 0 | 3..65535 )
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "Time interval in seconds for the Hold Time
++ configured for this BGP speaker with this peer.
++ This value is placed in an OPEN message sent to
++ this peer by this BGP speaker, and is compared
++ with the Hold Time field in an OPEN message
++ received from the peer when determining the Hold
++ Time (bgpPeerHoldTime) with the peer. This value
++ must not be less than three seconds if it is not
++ zero (0) in which case the Hold Time is NOT to be
++ established with the peer. The suggested value for
++ this timer is 90 seconds."
++ ::= { bgpPeerEntry 20 }
++
++ bgpPeerKeepAliveConfigured OBJECT-TYPE
++ SYNTAX INTEGER ( 0 | 1..21845 )
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "Time interval in seconds for the KeepAlive timer
++ configured for this BGP speaker with this peer.
++ The value of this object will only determine the
++ KEEPALIVE messages' frequency relative to the value
++ specified in bgpPeerHoldTimeConfigured; the actual
++ time interval for the KEEPALIVE messages is
++ indicated by bgpPeerKeepAlive. A reasonable
++ maximum value for this timer would be configured to
++ be one third of that of bgpPeerHoldTimeConfigured.
++ If the value of this object is zero (0), no
++ periodical KEEPALIVE messages are sent to the peer
++ after the BGP connection has been established. The
++ suggested value for this timer is 30 seconds."
++ ::= { bgpPeerEntry 21 }
++
++ bgpPeerMinASOriginationInterval OBJECT-TYPE
++ SYNTAX INTEGER (1..65535)
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "Time interval in seconds for the
++ MinASOriginationInterval timer.
++ The suggested value for this timer is 15 seconds."
++ ::= { bgpPeerEntry 22 }
++
++ bgpPeerMinRouteAdvertisementInterval OBJECT-TYPE
++ SYNTAX INTEGER (1..65535)
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "Time interval in seconds for the
++ MinRouteAdvertisementInterval timer.
++ The suggested value for this timer is 30 seconds."
++ ::= { bgpPeerEntry 23 }
++
++ bgpPeerInUpdateElapsedTime OBJECT-TYPE
++ SYNTAX Gauge32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "Elapsed time in seconds since the last BGP
++ UPDATE message was received from the peer.
++ Each time bgpPeerInUpdates is incremented,
++ the value of this object is set to zero (0)."
++ ::= { bgpPeerEntry 24 }
++
++
++
++ bgpIdentifier OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The BGP Identifier of local system."
++ ::= { bgp 4 }
++
++
++
++ -- Received Path Attribute Table. This table contains,
++ -- one entry per path to a network, path attributes
++ -- received from all peers running BGP version 3 or less.
++ -- This table is obsolete, having been replaced in
++ -- functionality with the bgp4PathAttrTable.
++
++ bgpRcvdPathAttrTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF BgpPathAttrEntry
++ MAX-ACCESS not-accessible
++ STATUS obsolete
++ DESCRIPTION
++ "The BGP Received Path Attribute Table contains
++ information about paths to destination networks
++ received from all peers running BGP version 3 or
++ less."
++ ::= { bgp 5 }
++
++ bgpPathAttrEntry OBJECT-TYPE
++ SYNTAX BgpPathAttrEntry
++ MAX-ACCESS not-accessible
++ STATUS obsolete
++ DESCRIPTION
++ "Information about a path to a network."
++ INDEX { bgpPathAttrDestNetwork,
++ bgpPathAttrPeer }
++ ::= { bgpRcvdPathAttrTable 1 }
++
++ BgpPathAttrEntry ::= SEQUENCE {
++ bgpPathAttrPeer
++ IpAddress,
++ bgpPathAttrDestNetwork
++ IpAddress,
++ bgpPathAttrOrigin
++ INTEGER,
++ bgpPathAttrASPath
++ OCTET STRING,
++ bgpPathAttrNextHop
++ IpAddress,
++ bgpPathAttrInterASMetric
++ Integer32
++ }
++
++ bgpPathAttrPeer OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS obsolete
++ DESCRIPTION
++ "The IP address of the peer where the path
++ information was learned."
++ ::= { bgpPathAttrEntry 1 }
++
++ bgpPathAttrDestNetwork OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS obsolete
++ DESCRIPTION
++ "The address of the destination network."
++ ::= { bgpPathAttrEntry 2 }
++
++ bgpPathAttrOrigin OBJECT-TYPE
++ SYNTAX INTEGER {
++ igp(1),-- networks are interior
++ egp(2),-- networks learned via EGP
++ incomplete(3) -- undetermined
++ }
++ MAX-ACCESS read-only
++ STATUS obsolete
++ DESCRIPTION
++ "The ultimate origin of the path information."
++ ::= { bgpPathAttrEntry 3 }
++
++ bgpPathAttrASPath OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE (2..255))
++ MAX-ACCESS read-only
++ STATUS obsolete
++ DESCRIPTION
++ "The set of ASs that must be traversed to reach
++ the network. This object is probably best
++ represented as SEQUENCE OF INTEGER. For SMI
++ compatibility, though, it is represented as
++ OCTET STRING. Each AS is represented as a pair
++ of octets according to the following algorithm:
++
++ first-byte-of-pair = ASNumber / 256;
++ second-byte-of-pair = ASNumber & 255;"
++ ::= { bgpPathAttrEntry 4 }
++
++ bgpPathAttrNextHop OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS obsolete
++ DESCRIPTION
++ "The address of the border router that should
++ be used for the destination network."
++ ::= { bgpPathAttrEntry 5 }
++
++ bgpPathAttrInterASMetric OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS obsolete
++ DESCRIPTION
++ "The optional inter-AS metric. If this
++ attribute has not been provided for this route,
++ the value for this object is 0."
++ ::= { bgpPathAttrEntry 6 }
++
++
++
++ -- BGP-4 Received Path Attribute Table. This table contains,
++ -- one entry per path to a network, path attributes
++ -- received from all peers running BGP-4.
++
++ bgp4PathAttrTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF Bgp4PathAttrEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The BGP-4 Received Path Attribute Table contains
++ information about paths to destination networks
++ received from all BGP4 peers."
++ ::= { bgp 6 }
++
++ bgp4PathAttrEntry OBJECT-TYPE
++ SYNTAX Bgp4PathAttrEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "Information about a path to a network."
++ INDEX { bgp4PathAttrIpAddrPrefix,
++ bgp4PathAttrIpAddrPrefixLen,
++ bgp4PathAttrPeer }
++ ::= { bgp4PathAttrTable 1 }
++
++ Bgp4PathAttrEntry ::= SEQUENCE {
++ bgp4PathAttrPeer
++ IpAddress,
++ bgp4PathAttrIpAddrPrefixLen
++ INTEGER,
++ bgp4PathAttrIpAddrPrefix
++ IpAddress,
++ bgp4PathAttrOrigin
++ INTEGER,
++ bgp4PathAttrASPathSegment
++ OCTET STRING,
++ bgp4PathAttrNextHop
++ IpAddress,
++ bgp4PathAttrMultiExitDisc
++ INTEGER,
++ bgp4PathAttrLocalPref
++ INTEGER,
++ bgp4PathAttrAtomicAggregate
++ INTEGER,
++ bgp4PathAttrAggregatorAS
++ INTEGER,
++ bgp4PathAttrAggregatorAddr
++ IpAddress,
++ bgp4PathAttrCalcLocalPref
++ INTEGER,
++ bgp4PathAttrBest
++ INTEGER,
++ bgp4PathAttrUnknown
++ OCTET STRING
++ }
++
++ bgp4PathAttrPeer OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP address of the peer where the path
++ information was learned."
++ ::= { bgp4PathAttrEntry 1 }
++ bgp4PathAttrIpAddrPrefixLen OBJECT-TYPE
++ SYNTAX INTEGER (0..32)
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "Length in bits of the IP address prefix in the
++ Network Layer Reachability Information field."
++ ::= { bgp4PathAttrEntry 2 }
++
++ bgp4PathAttrIpAddrPrefix OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "An IP address prefix in the Network Layer
++ Reachability Information field. This object
++ is an IP address containing the prefix with
++ length specified by bgp4PathAttrIpAddrPrefixLen.
++ Any bits beyond the length specified by
++ bgp4PathAttrIpAddrPrefixLen are zeroed."
++ ::= { bgp4PathAttrEntry 3 }
++
++ bgp4PathAttrOrigin OBJECT-TYPE
++ SYNTAX INTEGER {
++ igp(1),-- networks are interior
++ egp(2),-- networks learned via EGP
++ incomplete(3) -- undetermined
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The ultimate origin of the path information."
++ ::= { bgp4PathAttrEntry 4 }
++
++ bgp4PathAttrASPathSegment OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE (2..255))
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The sequence of AS path segments. Each AS
++ path segment is represented by a triple
++ <type, length, value>.
++
++ The type is a 1-octet field which has two
++ possible values:
++ 1 AS_SET: unordered set of ASs a
++ route in the UPDATE message
++ has traversed
++ 2 AS_SEQUENCE: ordered set of ASs
++ a route in the UPDATE message
++ has traversed.
++
++ The length is a 1-octet field containing the
++ number of ASs in the value field.
++
++ The value field contains one or more AS
++ numbers, each AS is represented in the octet
++ string as a pair of octets according to the
++ following algorithm:
++
++ first-byte-of-pair = ASNumber / 256;
++ second-byte-of-pair = ASNumber & 255;"
++ ::= { bgp4PathAttrEntry 5 }
++
++ bgp4PathAttrNextHop OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The address of the border router that should
++ be used for the destination network."
++ ::= { bgp4PathAttrEntry 6 }
++
++ bgp4PathAttrMultiExitDisc OBJECT-TYPE
++ SYNTAX INTEGER (-1..2147483647)
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "This metric is used to discriminate between
++ multiple exit points to an adjacent autonomous
++ system. A value of -1 indicates the absence of
++ this attribute."
++ ::= { bgp4PathAttrEntry 7 }
++
++ bgp4PathAttrLocalPref OBJECT-TYPE
++ SYNTAX INTEGER (-1..2147483647)
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The originating BGP4 speaker's degree of
++ preference for an advertised route. A value of
++ -1 indicates the absence of this attribute."
++ ::= { bgp4PathAttrEntry 8 }
++
++ bgp4PathAttrAtomicAggregate OBJECT-TYPE
++ SYNTAX INTEGER {
++ lessSpecificRrouteNotSelected(1),
++ lessSpecificRouteSelected(2)
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "Whether or not a system has selected
++ a less specific route without selecting a
++ more specific route."
++ ::= { bgp4PathAttrEntry 9 }
++
++ bgp4PathAttrAggregatorAS OBJECT-TYPE
++ SYNTAX INTEGER (0..65535)
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The AS number of the last BGP4 speaker that
++ performed route aggregation. A value of zero (0)
++ indicates the absence of this attribute."
++ ::= { bgp4PathAttrEntry 10 }
++
++ bgp4PathAttrAggregatorAddr OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP address of the last BGP4 speaker that
++ performed route aggregation. A value of
++ 0.0.0.0 indicates the absence of this attribute."
++ ::= { bgp4PathAttrEntry 11 }
++
++ bgp4PathAttrCalcLocalPref OBJECT-TYPE
++ SYNTAX INTEGER (-1..2147483647)
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The degree of preference calculated by the
++ receiving BGP4 speaker for an advertised route.
++ A value of -1 indicates the absence of this
++ attribute."
++ ::= { bgp4PathAttrEntry 12 }
++
++ bgp4PathAttrBest OBJECT-TYPE
++ SYNTAX INTEGER {
++ false(1),-- not chosen as best route
++ true(2) -- chosen as best route
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "An indication of whether or not this route
++ was chosen as the best BGP4 route."
++ ::= { bgp4PathAttrEntry 13 }
++
++ bgp4PathAttrUnknown OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE(0..255))
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "One or more path attributes not understood
++ by this BGP4 speaker. Size zero (0) indicates
++ the absence of such attribute(s). Octets
++ beyond the maximum size, if any, are not
++ recorded by this object."
++ ::= { bgp4PathAttrEntry 14 }
++
++
++ -- Traps.
++
++ -- note that in RFC 1657, bgpTraps was incorrectly
++ -- assigned a value of { bgp 7 }, and each of the
++ -- traps had the bgpPeerRemoteAddr object inappropriately
++ -- removed from their OBJECTS clause. The following
++ -- definitions restore the semantics of the traps as
++ -- they were initially defined in RFC 1269.
++
++ -- { bgp 7 } is unused
++
++ bgpTraps OBJECT IDENTIFIER ::= { bgp 0 }
++
++ bgpEstablished NOTIFICATION-TYPE
++ OBJECTS { bgpPeerRemoteAddr,
++ bgpPeerLastError,
++ bgpPeerState }
++ STATUS current
++ DESCRIPTION
++ "The BGP Established event is generated when
++ the BGP FSM enters the ESTABLISHED state."
++ ::= { bgpTraps 1 }
++
++ bgpBackwardTransition NOTIFICATION-TYPE
++ OBJECTS { bgpPeerRemoteAddr,
++ bgpPeerLastError,
++ bgpPeerState }
++ STATUS current
++ DESCRIPTION
++ "The BGPBackwardTransition Event is generated
++ when the BGP FSM moves from a higher numbered
++ state to a lower numbered state."
++ ::= { bgpTraps 2 }
++
++ -- conformance information
++
++ bgpMIBConformance OBJECT IDENTIFIER ::= { bgp 8 }
++ bgpMIBCompliances OBJECT IDENTIFIER ::= { bgpMIBConformance 1 }
++ bgpMIBGroups OBJECT IDENTIFIER ::= { bgpMIBConformance 2 }
++
++ -- compliance statements
++
++ bgpMIBCompliance MODULE-COMPLIANCE
++ STATUS current
++ DESCRIPTION
++ "The compliance statement for entities which
++ implement the BGP4 mib."
++ MODULE -- this module
++ MANDATORY-GROUPS { bgp4MIBGlobalsGroup,
++ bgp4MIBPeerGroup,
++ bgp4MIBPathAttrGroup,
++ bgp4MIBNotificationGroup }
++ ::= { bgpMIBCompliances 1 }
++
++ -- units of conformance
++
++ bgp4MIBGlobalsGroup OBJECT-GROUP
++ OBJECTS { bgpVersion,
++ bgpLocalAs,
++ bgpIdentifier }
++ STATUS current
++ DESCRIPTION
++ "A collection of objects providing information
++ on global BGP state."
++ ::= { bgpMIBGroups 1 }
++
++ bgp4MIBPeerGroup OBJECT-GROUP
++ OBJECTS { bgpPeerIdentifier,
++ bgpPeerState,
++ bgpPeerAdminStatus,
++ bgpPeerNegotiatedVersion,
++ bgpPeerLocalAddr,
++ bgpPeerLocalPort,
++ bgpPeerRemoteAddr,
++ bgpPeerRemotePort,
++ bgpPeerRemoteAs,
++ bgpPeerInUpdates,
++ bgpPeerOutUpdates,
++ bgpPeerInTotalMessages,
++ bgpPeerOutTotalMessages,
++ bgpPeerLastError,
++ bgpPeerFsmEstablishedTransitions,
++ bgpPeerFsmEstablishedTime,
++ bgpPeerConnectRetryInterval,
++ bgpPeerHoldTime,
++ bgpPeerKeepAlive,
++ bgpPeerHoldTimeConfigured,
++ bgpPeerKeepAliveConfigured,
++ bgpPeerMinASOriginationInterval,
++ bgpPeerMinRouteAdvertisementInterval,
++ bgpPeerInUpdateElapsedTime }
++ STATUS current
++ DESCRIPTION
++ "A collection of objects for managing
++ BGP peers."
++ ::= { bgpMIBGroups 2 }
++
++ bgp4MIBRcvdPathAttrGroup OBJECT-GROUP
++ OBJECTS { bgpPathAttrPeer,
++ bgpPathAttrDestNetwork,
++ bgpPathAttrOrigin,
++ bgpPathAttrASPath,
++ bgpPathAttrNextHop,
++ bgpPathAttrInterASMetric }
++ STATUS obsolete
++ DESCRIPTION
++ "A collection of objects for managing BGP
++ path entries.
++
++ This conformance group is obsolete,
++ replaced by bgp4MIBPathAttrGroup."
++ ::= { bgpMIBGroups 3 }
++
++ bgp4MIBPathAttrGroup OBJECT-GROUP
++ OBJECTS { bgp4PathAttrPeer,
++ bgp4PathAttrIpAddrPrefixLen,
++ bgp4PathAttrIpAddrPrefix,
++ bgp4PathAttrOrigin,
++ bgp4PathAttrASPathSegment,
++ bgp4PathAttrNextHop,
++ bgp4PathAttrMultiExitDisc,
++ bgp4PathAttrLocalPref,
++ bgp4PathAttrAtomicAggregate,
++ bgp4PathAttrAggregatorAS,
++ bgp4PathAttrAggregatorAddr,
++ bgp4PathAttrCalcLocalPref,
++ bgp4PathAttrBest,
++ bgp4PathAttrUnknown }
++ STATUS current
++ DESCRIPTION
++ "A collection of objects for managing
++ BGP path entries."
++ ::= { bgpMIBGroups 4 }
++
++ bgp4MIBNotificationGroup NOTIFICATION-GROUP
++ NOTIFICATIONS { bgpEstablished,
++ bgpBackwardTransition }
++ STATUS current
++ DESCRIPTION
++ "A collection of notifications for signaling
++ changes in BGP peer relationships."
++ ::= { bgpMIBGroups 5 }
++
++ END
+--- /dev/null
++++ b/mibs/GNOME-SMI.txt
+@@ -0,0 +1,88 @@
++GNOME-SMI DEFINITIONS ::= BEGIN
++
++IMPORTS
++ MODULE-IDENTITY,
++ OBJECT-IDENTITY,
++ enterprises
++ FROM SNMPv2-SMI;
++
++gnome MODULE-IDENTITY
++ LAST-UPDATED "200709070000Z"
++ ORGANIZATION "GNOME project"
++ CONTACT-INFO
++ "GNU Network Object Model Environment project
++
++ see http://www.gnome.org for contact persons of a particular
++ area or subproject of GNOME.
++
++ Administrative contact for MIB module:
++
++ Jochen Friedrich
++ Ramsaystr. 9
++ 63450 Hanau
++ Germany
++
++ email: jochen@scram.de"
++ DESCRIPTION
++ "The Structure of GNOME."
++
++ -- revision history
++
++ REVISION "200709070000Z" -- Sep 07, 2007
++ DESCRIPTION
++ "Fixed wrong enterprise number (how comes this
++ typo was unnoticed for so long?)."
++
++ REVISION "200505070000Z" -- May 07, 2005
++ DESCRIPTION
++ "Added gnomeLDAP subtree for LDAP definitions."
++
++ REVISION "200312070000Z" -- December 07, 2003
++ DESCRIPTION
++ "Added gnomeSysadmin subtree for GNOME project system administration.
++ Updated contact info."
++
++ REVISION "9809010000Z" -- September 01, 1998
++ DESCRIPTION
++ "Initial version."
++
++ ::= { enterprises 3319 } -- assigned by IANA
++
++gnomeProducts OBJECT-IDENTITY
++ STATUS current
++ DESCRIPTION
++ "gnomeProducts is the root OBJECT IDENTIFIER from
++ which sysObjectID values are assigned."
++ ::= { gnome 1 }
++
++gnomeMgmt OBJECT-IDENTITY
++ STATUS current
++ DESCRIPTION
++ "gnomeMgmt defines the subtree for production GNOME related
++ MIB registrations."
++ ::= { gnome 2 }
++
++gnomeTest OBJECT-IDENTITY
++ STATUS current
++ DESCRIPTION
++ "gnomeTest defines the subtree for testing GNOME related
++ MIB registrations."
++ ::= { gnome 3 }
++
++gnomeSysadmin OBJECT-IDENTITY
++ STATUS current
++ DESCRIPTION
++ "gnomeSysadmin defines the subtree for GNOME related Sysadmin
++ MIB registrations."
++ ::= { gnome 4 }
++
++gnomeLDAP OBJECT-IDENTITY
++ STATUS current
++ DESCRIPTION
++ "gnomeLDAP defines the subtree for GNOME related LDAP
++ registrations."
++ ::= { gnome 5 }
++
++-- more to come if necessary.
++
++END
+--- /dev/null
++++ b/mibs/OSPF-MIB.txt
+@@ -0,0 +1,2723 @@
++OSPF-MIB DEFINITIONS ::= BEGIN
++
++ IMPORTS
++ MODULE-IDENTITY, OBJECT-TYPE, Counter32, Gauge32,
++ Integer32, IpAddress
++ FROM SNMPv2-SMI
++ TEXTUAL-CONVENTION, TruthValue, RowStatus
++ FROM SNMPv2-TC
++ MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF
++ mib-2 FROM RFC1213-MIB;
++
++-- This MIB module uses the extended OBJECT-TYPE macro as
++-- defined in [9].
++
++ospf MODULE-IDENTITY
++ LAST-UPDATED "9501201225Z" -- Fri Jan 20 12:25:50 PST 1995
++ ORGANIZATION "IETF OSPF Working Group"
++ CONTACT-INFO
++ " Fred Baker
++ Postal: Cisco Systems
++ 519 Lado Drive
++ Santa Barbara, California 93111
++ Tel: +1 805 681 0115
++ E-Mail: fred@cisco.com
++
++ Rob Coltun
++ Postal: RainbowBridge Communications
++ Tel: (301) 340-9416
++ E-Mail: rcoltun@rainbow-bridge.com"
++ DESCRIPTION
++ "The MIB module to describe the OSPF Version 2
++ Protocol"
++ ::= { mib-2 14 }
++
++-- The Area ID, in OSPF, has the same format as an IP Address,
++-- but has the function of defining a summarization point for
++-- Link State Advertisements
++
++AreaID ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "An OSPF Area Identifier."
++ SYNTAX IpAddress
++
++
++-- The Router ID, in OSPF, has the same format as an IP Address,
++-- but identifies the router independent of its IP Address.
++
++RouterID ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "A OSPF Router Identifier."
++ SYNTAX IpAddress
++
++
++-- The OSPF Metric is defined as an unsigned value in the range
++
++Metric ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "The OSPF Internal Metric."
++ SYNTAX Integer32 (0..'FFFF'h)
++
++BigMetric ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "The OSPF External Metric."
++ SYNTAX Integer32 (0..'FFFFFF'h)
++
++-- Status Values
++
++Status ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "The status of an interface: 'enabled' indicates that
++ it is willing to communicate with other OSPF Routers,
++ while 'disabled' indicates that it is not."
++ SYNTAX INTEGER { enabled (1), disabled (2) }
++
++-- Time Durations measured in seconds
++
++PositiveInteger ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "A positive integer. Values in excess are precluded as
++ unnecessary and prone to interoperability issues."
++ SYNTAX Integer32 (0..'7FFFFFFF'h)
++
++HelloRange ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "The range of intervals on which hello messages are
++ exchanged."
++ SYNTAX Integer32 (1..'FFFF'h)
++
++UpToMaxAge ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "The values that one might find or configure for
++ variables bounded by the maximum age of an LSA."
++ SYNTAX Integer32 (0..3600)
++
++
++-- The range of ifIndex
++
++InterfaceIndex ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "The range of ifIndex."
++ SYNTAX Integer32
++
++
++-- Potential Priorities for the Designated Router Election
++
++DesignatedRouterPriority ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "The values defined for the priority of a system for
++ becoming the designated router."
++ SYNTAX Integer32 (0..'FF'h)
++
++TOSType ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "Type of Service is defined as a mapping to the IP Type of
++ Service Flags as defined in the IP Forwarding Table MIB
++
++ +-----+-----+-----+-----+-----+-----+-----+-----+
++ | | | |
++ | PRECEDENCE | TYPE OF SERVICE | 0 |
++ | | | |
++ +-----+-----+-----+-----+-----+-----+-----+-----+
++
++ IP TOS IP TOS
++ Field Policy Field Policy
++
++ Contents Code Contents Code
++ 0 0 0 0 ==> 0 0 0 0 1 ==> 2
++ 0 0 1 0 ==> 4 0 0 1 1 ==> 6
++ 0 1 0 0 ==> 8 0 1 0 1 ==> 10
++ 0 1 1 0 ==> 12 0 1 1 1 ==> 14
++ 1 0 0 0 ==> 16 1 0 0 1 ==> 18
++ 1 0 1 0 ==> 20 1 0 1 1 ==> 22
++ 1 1 0 0 ==> 24 1 1 0 1 ==> 26
++ 1 1 1 0 ==> 28 1 1 1 1 ==> 30
++
++ The remaining values are left for future definition."
++ SYNTAX Integer32 (0..30)
++
++
++-- OSPF General Variables
++
++-- These parameters apply globally to the Router's
++-- OSPF Process.
++
++ospfGeneralGroup OBJECT IDENTIFIER ::= { ospf 1 }
++
++
++ ospfRouterId OBJECT-TYPE
++ SYNTAX RouterID
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "A 32-bit integer uniquely identifying the
++ router in the Autonomous System.
++
++ By convention, to ensure uniqueness, this
++ should default to the value of one of the
++ router's IP interface addresses."
++ REFERENCE
++ "OSPF Version 2, C.1 Global parameters"
++ ::= { ospfGeneralGroup 1 }
++
++
++ ospfAdminStat OBJECT-TYPE
++ SYNTAX Status
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "The administrative status of OSPF in the
++ router. The value 'enabled' denotes that the
++ OSPF Process is active on at least one inter-
++ face; 'disabled' disables it on all inter-
++ faces."
++ ::= { ospfGeneralGroup 2 }
++
++ ospfVersionNumber OBJECT-TYPE
++ SYNTAX INTEGER { version2 (2) }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The current version number of the OSPF proto-
++ col is 2."
++ REFERENCE
++ "OSPF Version 2, Title"
++ ::= { ospfGeneralGroup 3 }
++
++
++ ospfAreaBdrRtrStatus OBJECT-TYPE
++ SYNTAX TruthValue
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "A flag to note whether this router is an area
++ border router."
++ REFERENCE
++ "OSPF Version 2, Section 3 Splitting the AS into
++ Areas"
++ ::= { ospfGeneralGroup 4 }
++
++
++ ospfASBdrRtrStatus OBJECT-TYPE
++ SYNTAX TruthValue
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "A flag to note whether this router is config-
++ ured as an Autonomous System border router."
++ REFERENCE
++ "OSPF Version 2, Section 3.3 Classification of
++ routers"
++ ::= { ospfGeneralGroup 5 }
++
++ ospfExternLsaCount OBJECT-TYPE
++ SYNTAX Gauge32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of external (LS type 5) link-state
++ advertisements in the link-state database."
++ REFERENCE
++ "OSPF Version 2, Appendix A.4.5 AS external link
++ advertisements"
++ ::= { ospfGeneralGroup 6 }
++
++
++ ospfExternLsaCksumSum OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The 32-bit unsigned sum of the LS checksums of
++ the external link-state advertisements con-
++ tained in the link-state database. This sum
++ can be used to determine if there has been a
++ change in a router's link state database, and
++ to compare the link-state database of two
++ routers."
++ ::= { ospfGeneralGroup 7 }
++
++
++ ospfTOSSupport OBJECT-TYPE
++ SYNTAX TruthValue
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "The router's support for type-of-service rout-
++ ing."
++ REFERENCE
++ "OSPF Version 2, Appendix F.1.2 Optional TOS
++ support"
++ ::= { ospfGeneralGroup 8 }
++
++ ospfOriginateNewLsas OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of new link-state advertisements
++ that have been originated. This number is in-
++ cremented each time the router originates a new
++ LSA."
++ ::= { ospfGeneralGroup 9 }
++
++
++ ospfRxNewLsas OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of link-state advertisements re-
++ ceived determined to be new instantiations.
++ This number does not include newer instantia-
++ tions of self-originated link-state advertise-
++ ments."
++ ::= { ospfGeneralGroup 10 }
++
++ ospfExtLsdbLimit OBJECT-TYPE
++ SYNTAX Integer32 (-1..'7FFFFFFF'h)
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "The maximum number of non-default AS-
++ external-LSAs entries that can be stored in the
++ link-state database. If the value is -1, then
++ there is no limit.
++
++ When the number of non-default AS-external-LSAs
++ in a router's link-state database reaches
++ ospfExtLsdbLimit, the router enters Overflow-
++ State. The router never holds more than
++ ospfExtLsdbLimit non-default AS-external-LSAs
++ in its database. OspfExtLsdbLimit MUST be set
++ identically in all routers attached to the OSPF
++ backbone and/or any regular OSPF area. (i.e.,
++ OSPF stub areas and NSSAs are excluded)."
++ DEFVAL { -1 }
++ ::= { ospfGeneralGroup 11 }
++
++ ospfMulticastExtensions OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "A Bit Mask indicating whether the router is
++ forwarding IP multicast (Class D) datagrams
++ based on the algorithms defined in the Multi-
++ cast Extensions to OSPF.
++
++ Bit 0, if set, indicates that the router can
++ forward IP multicast datagrams in the router's
++ directly attached areas (called intra-area mul-
++ ticast routing).
++
++ Bit 1, if set, indicates that the router can
++ forward IP multicast datagrams between OSPF
++ areas (called inter-area multicast routing).
++
++ Bit 2, if set, indicates that the router can
++ forward IP multicast datagrams between Auto-
++ nomous Systems (called inter-AS multicast rout-
++ ing).
++
++ Only certain combinations of bit settings are
++ allowed, namely: 0 (no multicast forwarding is
++ enabled), 1 (intra-area multicasting only), 3
++ (intra-area and inter-area multicasting), 5
++ (intra-area and inter-AS multicasting) and 7
++ (multicasting everywhere). By default, no mul-
++ ticast forwarding is enabled."
++ DEFVAL { 0 }
++ ::= { ospfGeneralGroup 12 }
++
++ ospfExitOverflowInterval OBJECT-TYPE
++ SYNTAX PositiveInteger
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "The number of seconds that, after entering
++ OverflowState, a router will attempt to leave
++ OverflowState. This allows the router to again
++ originate non-default AS-external-LSAs. When
++ set to 0, the router will not leave Overflow-
++ State until restarted."
++ DEFVAL { 0 }
++ ::= { ospfGeneralGroup 13 }
++
++
++ ospfDemandExtensions OBJECT-TYPE
++ SYNTAX TruthValue
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "The router's support for demand routing."
++ REFERENCE
++ "OSPF Version 2, Appendix on Demand Routing"
++ ::= { ospfGeneralGroup 14 }
++
++
++-- The OSPF Area Data Structure contains information
++-- regarding the various areas. The interfaces and
++-- virtual links are configured as part of these areas.
++-- Area 0.0.0.0, by definition, is the Backbone Area
++
++
++ ospfAreaTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfAreaEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "Information describing the configured parame-
++ ters and cumulative statistics of the router's
++ attached areas."
++ REFERENCE
++ "OSPF Version 2, Section 6 The Area Data Struc-
++ ture"
++ ::= { ospf 2 }
++
++
++ ospfAreaEntry OBJECT-TYPE
++ SYNTAX OspfAreaEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "Information describing the configured parame-
++ ters and cumulative statistics of one of the
++ router's attached areas."
++ INDEX { ospfAreaId }
++ ::= { ospfAreaTable 1 }
++
++OspfAreaEntry ::=
++ SEQUENCE {
++ ospfAreaId
++ AreaID,
++ ospfAuthType
++ Integer32,
++ ospfImportAsExtern
++ INTEGER,
++ ospfSpfRuns
++ Counter32,
++ ospfAreaBdrRtrCount
++ Gauge32,
++ ospfAsBdrRtrCount
++ Gauge32,
++ ospfAreaLsaCount
++ Gauge32,
++ ospfAreaLsaCksumSum
++ Integer32,
++ ospfAreaSummary
++ INTEGER,
++ ospfAreaStatus
++ RowStatus
++ }
++
++ ospfAreaId OBJECT-TYPE
++ SYNTAX AreaID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "A 32-bit integer uniquely identifying an area.
++ Area ID 0.0.0.0 is used for the OSPF backbone."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospfAreaEntry 1 }
++
++
++ ospfAuthType OBJECT-TYPE
++ SYNTAX Integer32
++ -- none (0),
++ -- simplePassword (1)
++ -- md5 (2)
++ -- reserved for specification by IANA (> 2)
++ MAX-ACCESS read-create
++ STATUS obsolete
++ DESCRIPTION
++ "The authentication type specified for an area.
++ Additional authentication types may be assigned
++ locally on a per Area basis."
++ REFERENCE
++ "OSPF Version 2, Appendix E Authentication"
++ DEFVAL { 0 } -- no authentication, by default
++ ::= { ospfAreaEntry 2 }
++
++ ospfImportAsExtern OBJECT-TYPE
++ SYNTAX INTEGER {
++ importExternal (1),
++ importNoExternal (2),
++ importNssa (3)
++ }
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The area's support for importing AS external
++ link- state advertisements."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ DEFVAL { importExternal }
++ ::= { ospfAreaEntry 3 }
++
++
++ ospfSpfRuns OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of times that the intra-area route
++ table has been calculated using this area's
++ link-state database. This is typically done
++ using Dijkstra's algorithm."
++ ::= { ospfAreaEntry 4 }
++
++
++ ospfAreaBdrRtrCount OBJECT-TYPE
++ SYNTAX Gauge32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The total number of area border routers reach-
++ able within this area. This is initially zero,
++ and is calculated in each SPF Pass."
++ ::= { ospfAreaEntry 5 }
++
++ ospfAsBdrRtrCount OBJECT-TYPE
++ SYNTAX Gauge32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The total number of Autonomous System border
++ routers reachable within this area. This is
++ initially zero, and is calculated in each SPF
++ Pass."
++ ::= { ospfAreaEntry 6 }
++
++
++ ospfAreaLsaCount OBJECT-TYPE
++ SYNTAX Gauge32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The total number of link-state advertisements
++ in this area's link-state database, excluding
++ AS External LSA's."
++ ::= { ospfAreaEntry 7 }
++
++
++ ospfAreaLsaCksumSum OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The 32-bit unsigned sum of the link-state ad-
++ vertisements' LS checksums contained in this
++ area's link-state database. This sum excludes
++ external (LS type 5) link-state advertisements.
++ The sum can be used to determine if there has
++ been a change in a router's link state data-
++ base, and to compare the link-state database of
++ two routers."
++ DEFVAL { 0 }
++ ::= { ospfAreaEntry 8 }
++
++ ospfAreaSummary OBJECT-TYPE
++ SYNTAX INTEGER {
++ noAreaSummary (1),
++ sendAreaSummary (2)
++ }
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The variable ospfAreaSummary controls the im-
++ port of summary LSAs into stub areas. It has
++ no effect on other areas.
++
++ If it is noAreaSummary, the router will neither
++ originate nor propagate summary LSAs into the
++ stub area. It will rely entirely on its de-
++ fault route.
++
++ If it is sendAreaSummary, the router will both
++ summarize and propagate summary LSAs."
++ DEFVAL { noAreaSummary }
++ ::= { ospfAreaEntry 9 }
++
++
++ ospfAreaStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. Setting it to 'invalid' has the effect of
++ rendering it inoperative. The internal effect
++ (row removal) is implementation dependent."
++ ::= { ospfAreaEntry 10 }
++
++
++-- OSPF Area Default Metric Table
++
++-- The OSPF Area Default Metric Table describes the metrics
++-- that a default Area Border Router will advertise into a
++-- Stub area.
++
++
++ ospfStubAreaTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfStubAreaEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The set of metrics that will be advertised by
++ a default Area Border Router into a stub area."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2, Area Parameters"
++ ::= { ospf 3 }
++
++
++ ospfStubAreaEntry OBJECT-TYPE
++ SYNTAX OspfStubAreaEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The metric for a given Type of Service that
++ will be advertised by a default Area Border
++ Router into a stub area."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2, Area Parameters"
++ INDEX { ospfStubAreaId, ospfStubTOS }
++ ::= { ospfStubAreaTable 1 }
++
++OspfStubAreaEntry ::=
++ SEQUENCE {
++ ospfStubAreaId
++ AreaID,
++ ospfStubTOS
++ TOSType,
++ ospfStubMetric
++ BigMetric,
++ ospfStubStatus
++ RowStatus,
++ ospfStubMetricType
++ INTEGER
++ }
++
++ ospfStubAreaId OBJECT-TYPE
++ SYNTAX AreaID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The 32 bit identifier for the Stub Area. On
++ creation, this can be derived from the in-
++ stance."
++ ::= { ospfStubAreaEntry 1 }
++
++
++ ospfStubTOS OBJECT-TYPE
++ SYNTAX TOSType
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Type of Service associated with the
++ metric. On creation, this can be derived from
++ the instance."
++ ::= { ospfStubAreaEntry 2 }
++
++
++ ospfStubMetric OBJECT-TYPE
++ SYNTAX BigMetric
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The metric value applied at the indicated type
++ of service. By default, this equals the least
++ metric at the type of service among the inter-
++ faces to other areas."
++ ::= { ospfStubAreaEntry 3 }
++
++
++ ospfStubStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. Setting it to 'invalid' has the effect of
++ rendering it inoperative. The internal effect
++ (row removal) is implementation dependent."
++ ::= { ospfStubAreaEntry 4 }
++
++ ospfStubMetricType OBJECT-TYPE
++ SYNTAX INTEGER {
++ ospfMetric (1), -- OSPF Metric
++ comparableCost (2), -- external type 1
++ nonComparable (3) -- external type 2
++ }
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable displays the type of metric ad-
++ vertised as a default route."
++ DEFVAL { ospfMetric }
++ ::= { ospfStubAreaEntry 5 }
++
++-- OSPF Link State Database
++
++-- The Link State Database contains the Link State
++-- Advertisements from throughout the areas that the
++-- device is attached to.
++
++
++ ospfLsdbTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfLsdbEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The OSPF Process's Link State Database."
++ REFERENCE
++ "OSPF Version 2, Section 12 Link State Adver-
++ tisements"
++ ::= { ospf 4 }
++
++
++ ospfLsdbEntry OBJECT-TYPE
++ SYNTAX OspfLsdbEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A single Link State Advertisement."
++ INDEX { ospfLsdbAreaId, ospfLsdbType,
++ ospfLsdbLsid, ospfLsdbRouterId }
++ ::= { ospfLsdbTable 1 }
++
++OspfLsdbEntry ::=
++ SEQUENCE {
++ ospfLsdbAreaId
++ AreaID,
++ ospfLsdbType
++ INTEGER,
++ ospfLsdbLsid
++ IpAddress,
++ ospfLsdbRouterId
++ RouterID,
++ ospfLsdbSequence
++ Integer32,
++ ospfLsdbAge
++ Integer32,
++ ospfLsdbChecksum
++ Integer32,
++ ospfLsdbAdvertisement
++ OCTET STRING
++ }
++ ospfLsdbAreaId OBJECT-TYPE
++ SYNTAX AreaID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The 32 bit identifier of the Area from which
++ the LSA was received."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospfLsdbEntry 1 }
++
++-- External Link State Advertisements are permitted
++-- for backward compatibility, but should be displayed in
++-- the ospfExtLsdbTable rather than here.
++
++ ospfLsdbType OBJECT-TYPE
++ SYNTAX INTEGER {
++ routerLink (1),
++ networkLink (2),
++ summaryLink (3),
++ asSummaryLink (4),
++ asExternalLink (5), -- but see ospfExtLsdbTable
++ multicastLink (6),
++ nssaExternalLink (7)
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The type of the link state advertisement.
++ Each link state type has a separate advertise-
++ ment format."
++ REFERENCE
++ "OSPF Version 2, Appendix A.4.1 The Link State
++ Advertisement header"
++ ::= { ospfLsdbEntry 2 }
++
++ ospfLsdbLsid OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Link State ID is an LS Type Specific field
++ containing either a Router ID or an IP Address;
++ it identifies the piece of the routing domain
++ that is being described by the advertisement."
++ REFERENCE
++ "OSPF Version 2, Section 12.1.4 Link State ID"
++ ::= { ospfLsdbEntry 3 }
++ ospfLsdbRouterId OBJECT-TYPE
++ SYNTAX RouterID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The 32 bit number that uniquely identifies the
++ originating router in the Autonomous System."
++ REFERENCE
++ "OSPF Version 2, Appendix C.1 Global parameters"
++ ::= { ospfLsdbEntry 4 }
++
++-- Note that the OSPF Sequence Number is a 32 bit signed
++-- integer. It starts with the value '80000001'h,
++-- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h
++-- Thus, a typical sequence number will be very negative.
++
++ ospfLsdbSequence OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The sequence number field is a signed 32-bit
++ integer. It is used to detect old and dupli-
++ cate link state advertisements. The space of
++ sequence numbers is linearly ordered. The
++ larger the sequence number the more recent the
++ advertisement."
++ REFERENCE
++ "OSPF Version 2, Section 12.1.6 LS sequence
++ number"
++ ::= { ospfLsdbEntry 5 }
++
++
++ ospfLsdbAge OBJECT-TYPE
++ SYNTAX Integer32 -- Should be 0..MaxAge
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "This field is the age of the link state adver-
++ tisement in seconds."
++ REFERENCE
++ "OSPF Version 2, Section 12.1.1 LS age"
++ ::= { ospfLsdbEntry 6 }
++
++ ospfLsdbChecksum OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "This field is the checksum of the complete
++ contents of the advertisement, excepting the
++ age field. The age field is excepted so that
++ an advertisement's age can be incremented
++ without updating the checksum. The checksum
++ used is the same that is used for ISO connec-
++ tionless datagrams; it is commonly referred to
++ as the Fletcher checksum."
++ REFERENCE
++ "OSPF Version 2, Section 12.1.7 LS checksum"
++ ::= { ospfLsdbEntry 7 }
++
++
++ ospfLsdbAdvertisement OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE (1..65535))
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The entire Link State Advertisement, including
++ its header."
++ REFERENCE
++ "OSPF Version 2, Section 12 Link State Adver-
++ tisements"
++ ::= { ospfLsdbEntry 8 }
++
++
++-- Address Range Table
++
++-- The Address Range Table acts as an adjunct to the Area
++-- Table; It describes those Address Range Summaries that
++-- are configured to be propagated from an Area to reduce
++-- the amount of information about it which is known beyond
++-- its borders.
++
++ ospfAreaRangeTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfAreaRangeEntry
++ MAX-ACCESS not-accessible
++ STATUS obsolete
++ DESCRIPTION
++ "A range if IP addresses specified by an IP
++ address/IP network mask pair. For example,
++ class B address range of X.X.X.X with a network
++ mask of 255.255.0.0 includes all IP addresses
++ from X.X.0.0 to X.X.255.255"
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospf 5 }
++ ospfAreaRangeEntry OBJECT-TYPE
++ SYNTAX OspfAreaRangeEntry
++ MAX-ACCESS not-accessible
++ STATUS obsolete
++ DESCRIPTION
++ "A range if IP addresses specified by an IP
++ address/IP network mask pair. For example,
++ class B address range of X.X.X.X with a network
++ mask of 255.255.0.0 includes all IP addresses
++ from X.X.0.0 to X.X.255.255"
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ INDEX { ospfAreaRangeAreaId, ospfAreaRangeNet }
++ ::= { ospfAreaRangeTable 1 }
++
++OspfAreaRangeEntry ::=
++ SEQUENCE {
++ ospfAreaRangeAreaId
++ AreaID,
++ ospfAreaRangeNet
++ IpAddress,
++ ospfAreaRangeMask
++ IpAddress,
++ ospfAreaRangeStatus
++ RowStatus,
++ ospfAreaRangeEffect
++ INTEGER
++ }
++
++ ospfAreaRangeAreaId OBJECT-TYPE
++ SYNTAX AreaID
++ MAX-ACCESS read-only
++ STATUS obsolete
++ DESCRIPTION
++ "The Area the Address Range is to be found
++ within."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospfAreaRangeEntry 1 }
++
++
++ ospfAreaRangeNet OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS obsolete
++ DESCRIPTION
++ "The IP Address of the Net or Subnet indicated
++ by the range."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospfAreaRangeEntry 2 }
++
++
++ ospfAreaRangeMask OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-create
++ STATUS obsolete
++ DESCRIPTION
++ "The Subnet Mask that pertains to the Net or
++ Subnet."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospfAreaRangeEntry 3 }
++
++ ospfAreaRangeStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS obsolete
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. Setting it to 'invalid' has the effect of
++ rendering it inoperative. The internal effect
++ (row removal) is implementation dependent."
++ ::= { ospfAreaRangeEntry 4 }
++
++
++ ospfAreaRangeEffect OBJECT-TYPE
++ SYNTAX INTEGER {
++ advertiseMatching (1),
++ doNotAdvertiseMatching (2)
++ }
++ MAX-ACCESS read-create
++ STATUS obsolete
++ DESCRIPTION
++ "Subnets subsumed by ranges either trigger the
++ advertisement of the indicated summary (adver-
++ tiseMatching), or result in the subnet's not
++ being advertised at all outside the area."
++ DEFVAL { advertiseMatching }
++ ::= { ospfAreaRangeEntry 5 }
++
++
++
++-- OSPF Host Table
++
++-- The Host/Metric Table indicates what hosts are directly
++-- attached to the Router, and what metrics and types of
++-- service should be advertised for them.
++
++ ospfHostTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfHostEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The list of Hosts, and their metrics, that the
++ router will advertise as host routes."
++ REFERENCE
++ "OSPF Version 2, Appendix C.6 Host route param-
++ eters"
++ ::= { ospf 6 }
++
++
++ ospfHostEntry OBJECT-TYPE
++ SYNTAX OspfHostEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A metric to be advertised, for a given type of
++ service, when a given host is reachable."
++ INDEX { ospfHostIpAddress, ospfHostTOS }
++ ::= { ospfHostTable 1 }
++
++OspfHostEntry ::=
++ SEQUENCE {
++ ospfHostIpAddress
++ IpAddress,
++ ospfHostTOS
++ TOSType,
++ ospfHostMetric
++ Metric,
++ ospfHostStatus
++ RowStatus,
++ ospfHostAreaID
++ AreaID
++ }
++
++ ospfHostIpAddress OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP Address of the Host."
++ REFERENCE
++ "OSPF Version 2, Appendix C.6 Host route parame-
++ ters"
++ ::= { ospfHostEntry 1 }
++
++
++ ospfHostTOS OBJECT-TYPE
++ SYNTAX TOSType
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Type of Service of the route being config-
++ ured."
++ REFERENCE
++ "OSPF Version 2, Appendix C.6 Host route parame-
++ ters"
++ ::= { ospfHostEntry 2 }
++
++
++ ospfHostMetric OBJECT-TYPE
++ SYNTAX Metric
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The Metric to be advertised."
++ REFERENCE
++ "OSPF Version 2, Appendix C.6 Host route parame-
++ ters"
++ ::= { ospfHostEntry 3 }
++
++ ospfHostStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. Setting it to 'invalid' has the effect of
++ rendering it inoperative. The internal effect
++ (row removal) is implementation dependent."
++ ::= { ospfHostEntry 4 }
++
++
++ ospfHostAreaID OBJECT-TYPE
++ SYNTAX AreaID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Area the Host Entry is to be found within.
++ By default, the area that a subsuming OSPF in-
++ terface is in, or 0.0.0.0"
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospfHostEntry 5 }
++
++
++-- OSPF Interface Table
++
++-- The OSPF Interface Table augments the ipAddrTable
++-- with OSPF specific information.
++
++ ospfIfTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfIfEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The OSPF Interface Table describes the inter-
++ faces from the viewpoint of OSPF."
++ REFERENCE
++ "OSPF Version 2, Appendix C.3 Router interface
++ parameters"
++ ::= { ospf 7 }
++
++
++ ospfIfEntry OBJECT-TYPE
++ SYNTAX OspfIfEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The OSPF Interface Entry describes one inter-
++ face from the viewpoint of OSPF."
++ INDEX { ospfIfIpAddress, ospfAddressLessIf }
++ ::= { ospfIfTable 1 }
++
++OspfIfEntry ::=
++ SEQUENCE {
++ ospfIfIpAddress
++ IpAddress,
++ ospfAddressLessIf
++ Integer32,
++ ospfIfAreaId
++ AreaID,
++ ospfIfType
++ INTEGER,
++ ospfIfAdminStat
++ Status,
++ ospfIfRtrPriority
++ DesignatedRouterPriority,
++ ospfIfTransitDelay
++ UpToMaxAge,
++ ospfIfRetransInterval
++ UpToMaxAge,
++ ospfIfHelloInterval
++ HelloRange,
++ ospfIfRtrDeadInterval
++ PositiveInteger,
++ ospfIfPollInterval
++ PositiveInteger,
++ ospfIfState
++ INTEGER,
++ ospfIfDesignatedRouter
++ IpAddress,
++ ospfIfBackupDesignatedRouter
++ IpAddress,
++ ospfIfEvents
++ Counter32,
++ ospfIfAuthType
++ INTEGER,
++ ospfIfAuthKey
++ OCTET STRING,
++ ospfIfStatus
++ RowStatus,
++ ospfIfMulticastForwarding
++ INTEGER,
++ ospfIfDemand
++ TruthValue
++ }
++
++ ospfIfIpAddress OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP address of this OSPF interface."
++ ::= { ospfIfEntry 1 }
++
++ ospfAddressLessIf OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "For the purpose of easing the instancing of
++ addressed and addressless interfaces; This
++ variable takes the value 0 on interfaces with
++ IP Addresses, and the corresponding value of
++ ifIndex for interfaces having no IP Address."
++ ::= { ospfIfEntry 2 }
++ ospfIfAreaId OBJECT-TYPE
++ SYNTAX AreaID
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "A 32-bit integer uniquely identifying the area
++ to which the interface connects. Area ID
++ 0.0.0.0 is used for the OSPF backbone."
++ DEFVAL { '00000000'H } -- 0.0.0.0
++ ::= { ospfIfEntry 3 }
++
++ ospfIfType OBJECT-TYPE
++ SYNTAX INTEGER {
++ broadcast (1),
++ nbma (2),
++ pointToPoint (3),
++ pointToMultipoint (5)
++ }
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The OSPF interface type.
++
++ By way of a default, this field may be intuited
++ from the corresponding value of ifType. Broad-
++ cast LANs, such as Ethernet and IEEE 802.5,
++ take the value 'broadcast', X.25 and similar
++ technologies take the value 'nbma', and links
++ that are definitively point to point take the
++ value 'pointToPoint'."
++ ::= { ospfIfEntry 4 }
++
++
++ ospfIfAdminStat OBJECT-TYPE
++ SYNTAX Status
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The OSPF interface's administrative status.
++ The value formed on the interface, and the in-
++ terface will be advertised as an internal route
++ to some area. The value 'disabled' denotes
++ that the interface is external to OSPF."
++ DEFVAL { enabled }
++ ::= { ospfIfEntry 5 }
++
++ ospfIfRtrPriority OBJECT-TYPE
++ SYNTAX DesignatedRouterPriority
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The priority of this interface. Used in
++ multi-access networks, this field is used in
++ the designated router election algorithm. The
++ value 0 signifies that the router is not eligi-
++ ble to become the designated router on this
++ particular network. In the event of a tie in
++ this value, routers will use their Router ID as
++ a tie breaker."
++ DEFVAL { 1 }
++ ::= { ospfIfEntry 6 }
++
++
++ ospfIfTransitDelay OBJECT-TYPE
++ SYNTAX UpToMaxAge
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The estimated number of seconds it takes to
++ transmit a link state update packet over this
++ interface."
++ DEFVAL { 1 }
++ ::= { ospfIfEntry 7 }
++
++
++ ospfIfRetransInterval OBJECT-TYPE
++ SYNTAX UpToMaxAge
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The number of seconds between link-state ad-
++ vertisement retransmissions, for adjacencies
++ belonging to this interface. This value is
++ also used when retransmitting database descrip-
++ tion and link-state request packets."
++ DEFVAL { 5 }
++ ::= { ospfIfEntry 8 }
++
++
++ ospfIfHelloInterval OBJECT-TYPE
++ SYNTAX HelloRange
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The length of time, in seconds, between the
++ Hello packets that the router sends on the in-
++ terface. This value must be the same for all
++ routers attached to a common network."
++ DEFVAL { 10 }
++ ::= { ospfIfEntry 9 }
++
++
++ ospfIfRtrDeadInterval OBJECT-TYPE
++ SYNTAX PositiveInteger
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The number of seconds that a router's Hello
++ packets have not been seen before it's neigh-
++ bors declare the router down. This should be
++ some multiple of the Hello interval. This
++ value must be the same for all routers attached
++ to a common network."
++ DEFVAL { 40 }
++ ::= { ospfIfEntry 10 }
++
++
++ ospfIfPollInterval OBJECT-TYPE
++ SYNTAX PositiveInteger
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The larger time interval, in seconds, between
++ the Hello packets sent to an inactive non-
++ broadcast multi- access neighbor."
++ DEFVAL { 120 }
++ ::= { ospfIfEntry 11 }
++
++
++ ospfIfState OBJECT-TYPE
++ SYNTAX INTEGER {
++ down (1),
++ loopback (2),
++ waiting (3),
++ pointToPoint (4),
++ designatedRouter (5),
++ backupDesignatedRouter (6),
++ otherDesignatedRouter (7)
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The OSPF Interface State."
++ DEFVAL { down }
++ ::= { ospfIfEntry 12 }
++
++
++ ospfIfDesignatedRouter OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP Address of the Designated Router."
++ DEFVAL { '00000000'H } -- 0.0.0.0
++ ::= { ospfIfEntry 13 }
++
++
++ ospfIfBackupDesignatedRouter OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP Address of the Backup Designated
++ Router."
++ DEFVAL { '00000000'H } -- 0.0.0.0
++ ::= { ospfIfEntry 14 }
++
++ ospfIfEvents OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of times this OSPF interface has
++ changed its state, or an error has occurred."
++ ::= { ospfIfEntry 15 }
++
++
++ ospfIfAuthKey OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE (0..256))
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The Authentication Key. If the Area's Author-
++ ization Type is simplePassword, and the key
++ length is shorter than 8 octets, the agent will
++ left adjust and zero fill to 8 octets.
++
++ Note that unauthenticated interfaces need no
++ authentication key, and simple password authen-
++ tication cannot use a key of more than 8 oc-
++ tets. Larger keys are useful only with authen-
++ tication mechanisms not specified in this docu-
++ ment.
++
++ When read, ospfIfAuthKey always returns an Oc-
++ tet String of length zero."
++ REFERENCE
++ "OSPF Version 2, Section 9 The Interface Data
++ Structure"
++ DEFVAL { '0000000000000000'H } -- 0.0.0.0.0.0.0.0
++ ::= { ospfIfEntry 16 }
++
++ ospfIfStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. Setting it to 'invalid' has the effect of
++ rendering it inoperative. The internal effect
++ (row removal) is implementation dependent."
++ ::= { ospfIfEntry 17 }
++
++
++ ospfIfMulticastForwarding OBJECT-TYPE
++ SYNTAX INTEGER {
++ blocked (1), -- no multicast forwarding
++ multicast (2), -- using multicast address
++ unicast (3) -- to each OSPF neighbor
++ }
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The way multicasts should forwarded on this
++ interface; not forwarded, forwarded as data
++ link multicasts, or forwarded as data link uni-
++ casts. Data link multicasting is not meaning-
++ ful on point to point and NBMA interfaces, and
++ setting ospfMulticastForwarding to 0 effective-
++ ly disables all multicast forwarding."
++ DEFVAL { blocked }
++ ::= { ospfIfEntry 18 }
++
++
++ ospfIfDemand OBJECT-TYPE
++ SYNTAX TruthValue
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "Indicates whether Demand OSPF procedures (hel-
++ lo supression to FULL neighbors and setting the
++ DoNotAge flag on proogated LSAs) should be per-
++ formed on this interface."
++ DEFVAL { false }
++ ::= { ospfIfEntry 19 }
++
++
++ ospfIfAuthType OBJECT-TYPE
++ SYNTAX INTEGER (0..255)
++ -- none (0),
++ -- simplePassword (1)
++ -- md5 (2)
++ -- reserved for specification by IANA (> 2)
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The authentication type specified for an in-
++ terface. Additional authentication types may
++ be assigned locally."
++ REFERENCE
++ "OSPF Version 2, Appendix E Authentication"
++ DEFVAL { 0 } -- no authentication, by default
++ ::= { ospfIfEntry 20 }
++
++
++-- OSPF Interface Metric Table
++
++-- The Metric Table describes the metrics to be advertised
++-- for a specified interface at the various types of service.
++-- As such, this table is an adjunct of the OSPF Interface
++-- Table.
++
++-- Types of service, as defined by RFC 791, have the ability
++-- to request low delay, high bandwidth, or reliable linkage.
++
++-- For the purposes of this specification, the measure of
++-- bandwidth
++
++-- Metric = 10^8 / ifSpeed
++
++-- is the default value. For multiple link interfaces, note
++-- that ifSpeed is the sum of the individual link speeds.
++-- This yields a number having the following typical values:
++
++-- Network Type/bit rate Metric
++
++-- >= 100 MBPS 1
++-- Ethernet/802.3 10
++-- E1 48
++-- T1 (ESF) 65
++-- 64 KBPS 1562
++-- 56 KBPS 1785
++-- 19.2 KBPS 5208
++-- 9.6 KBPS 10416
++
++-- Routes that are not specified use the default (TOS 0) metric
++
++ ospfIfMetricTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfIfMetricEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The TOS metrics for a non-virtual interface
++ identified by the interface index."
++ REFERENCE
++ "OSPF Version 2, Appendix C.3 Router interface
++ parameters"
++ ::= { ospf 8 }
++
++ ospfIfMetricEntry OBJECT-TYPE
++ SYNTAX OspfIfMetricEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A particular TOS metric for a non-virtual in-
++ terface identified by the interface index."
++ REFERENCE
++ "OSPF Version 2, Appendix C.3 Router interface
++ parameters"
++ INDEX { ospfIfMetricIpAddress,
++ ospfIfMetricAddressLessIf,
++ ospfIfMetricTOS }
++ ::= { ospfIfMetricTable 1 }
++
++OspfIfMetricEntry ::=
++ SEQUENCE {
++ ospfIfMetricIpAddress
++ IpAddress,
++ ospfIfMetricAddressLessIf
++ Integer32,
++ ospfIfMetricTOS
++ TOSType,
++ ospfIfMetricValue
++ Metric,
++ ospfIfMetricStatus
++ RowStatus
++ }
++
++ ospfIfMetricIpAddress OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP address of this OSPF interface. On row
++ creation, this can be derived from the in-
++ stance."
++ ::= { ospfIfMetricEntry 1 }
++
++ ospfIfMetricAddressLessIf OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "For the purpose of easing the instancing of
++ addressed and addressless interfaces; This
++ variable takes the value 0 on interfaces with
++ IP Addresses, and the value of ifIndex for in-
++ terfaces having no IP Address. On row crea-
++ tion, this can be derived from the instance."
++ ::= { ospfIfMetricEntry 2 }
++
++
++ ospfIfMetricTOS OBJECT-TYPE
++ SYNTAX TOSType
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The type of service metric being referenced.
++ On row creation, this can be derived from the
++ instance."
++ ::= { ospfIfMetricEntry 3 }
++
++
++ ospfIfMetricValue OBJECT-TYPE
++ SYNTAX Metric
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The metric of using this type of service on
++ this interface. The default value of the TOS 0
++ Metric is 10^8 / ifSpeed."
++ ::= { ospfIfMetricEntry 4 }
++
++ ospfIfMetricStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. Setting it to 'invalid' has the effect of
++ rendering it inoperative. The internal effect
++ (row removal) is implementation dependent."
++ ::= { ospfIfMetricEntry 5 }
++
++
++-- OSPF Virtual Interface Table
++
++-- The Virtual Interface Table describes the virtual
++-- links that the OSPF Process is configured to
++-- carry on.
++
++ ospfVirtIfTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfVirtIfEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "Information about this router's virtual inter-
++ faces."
++ REFERENCE
++ "OSPF Version 2, Appendix C.4 Virtual link
++ parameters"
++ ::= { ospf 9 }
++
++
++ ospfVirtIfEntry OBJECT-TYPE
++ SYNTAX OspfVirtIfEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "Information about a single Virtual Interface."
++ INDEX { ospfVirtIfAreaId, ospfVirtIfNeighbor }
++ ::= { ospfVirtIfTable 1 }
++
++OspfVirtIfEntry ::=
++ SEQUENCE {
++ ospfVirtIfAreaId
++ AreaID,
++ ospfVirtIfNeighbor
++ RouterID,
++ ospfVirtIfTransitDelay
++ UpToMaxAge,
++ ospfVirtIfRetransInterval
++ UpToMaxAge,
++ ospfVirtIfHelloInterval
++ HelloRange,
++ ospfVirtIfRtrDeadInterval
++ PositiveInteger,
++ ospfVirtIfState
++ INTEGER,
++ ospfVirtIfEvents
++ Counter32,
++ ospfVirtIfAuthType
++ INTEGER,
++ ospfVirtIfAuthKey
++ OCTET STRING,
++ ospfVirtIfStatus
++ RowStatus
++ }
++
++ ospfVirtIfAreaId OBJECT-TYPE
++ SYNTAX AreaID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Transit Area that the Virtual Link
++ traverses. By definition, this is not 0.0.0.0"
++ ::= { ospfVirtIfEntry 1 }
++
++
++ ospfVirtIfNeighbor OBJECT-TYPE
++ SYNTAX RouterID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Router ID of the Virtual Neighbor."
++ ::= { ospfVirtIfEntry 2 }
++
++
++ ospfVirtIfTransitDelay OBJECT-TYPE
++ SYNTAX UpToMaxAge
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The estimated number of seconds it takes to
++ transmit a link- state update packet over this
++ interface."
++ DEFVAL { 1 }
++ ::= { ospfVirtIfEntry 3 }
++
++
++ ospfVirtIfRetransInterval OBJECT-TYPE
++ SYNTAX UpToMaxAge
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The number of seconds between link-state ad-
++ vertisement retransmissions, for adjacencies
++ belonging to this interface. This value is
++ also used when retransmitting database descrip-
++ tion and link-state request packets. This
++ value should be well over the expected round-
++ trip time."
++ DEFVAL { 5 }
++ ::= { ospfVirtIfEntry 4 }
++
++
++ ospfVirtIfHelloInterval OBJECT-TYPE
++ SYNTAX HelloRange
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The length of time, in seconds, between the
++ Hello packets that the router sends on the in-
++ terface. This value must be the same for the
++ virtual neighbor."
++ DEFVAL { 10 }
++ ::= { ospfVirtIfEntry 5 }
++
++
++ ospfVirtIfRtrDeadInterval OBJECT-TYPE
++ SYNTAX PositiveInteger
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The number of seconds that a router's Hello
++ packets have not been seen before it's neigh-
++ bors declare the router down. This should be
++ some multiple of the Hello interval. This
++ value must be the same for the virtual neigh-
++ bor."
++ DEFVAL { 60 }
++ ::= { ospfVirtIfEntry 6 }
++
++
++ ospfVirtIfState OBJECT-TYPE
++ SYNTAX INTEGER {
++ down (1), -- these use the same encoding
++ pointToPoint (4) -- as the ospfIfTable
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "OSPF virtual interface states."
++ DEFVAL { down }
++ ::= { ospfVirtIfEntry 7 }
++
++
++ ospfVirtIfEvents OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of state changes or error events on
++ this Virtual Link"
++ ::= { ospfVirtIfEntry 8 }
++
++
++ ospfVirtIfAuthKey OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE(0..256))
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "If Authentication Type is simplePassword, the
++ device will left adjust and zero fill to 8 oc-
++ tets.
++
++ Note that unauthenticated interfaces need no
++ authentication key, and simple password authen-
++ tication cannot use a key of more than 8 oc-
++ tets. Larger keys are useful only with authen-
++ tication mechanisms not specified in this docu-
++ ment.
++
++ When read, ospfVifAuthKey always returns a
++ string of length zero."
++ REFERENCE
++ "OSPF Version 2, Section 9 The Interface Data
++ Structure"
++ DEFVAL { '0000000000000000'H } -- 0.0.0.0.0.0.0.0
++ ::= { ospfVirtIfEntry 9 }
++
++
++ ospfVirtIfStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. Setting it to 'invalid' has the effect of
++ rendering it inoperative. The internal effect
++ (row removal) is implementation dependent."
++ ::= { ospfVirtIfEntry 10 }
++
++
++ ospfVirtIfAuthType OBJECT-TYPE
++ SYNTAX INTEGER (0..255)
++ -- none (0),
++ -- simplePassword (1)
++ -- md5 (2)
++ -- reserved for specification by IANA (> 2)
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The authentication type specified for a virtu-
++ al interface. Additional authentication types
++ may be assigned locally."
++ REFERENCE
++ "OSPF Version 2, Appendix E Authentication"
++ DEFVAL { 0 } -- no authentication, by default
++ ::= { ospfVirtIfEntry 11 }
++
++
++-- OSPF Neighbor Table
++
++-- The OSPF Neighbor Table describes all neighbors in
++-- the locality of the subject router.
++
++ ospfNbrTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfNbrEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A table of non-virtual neighbor information."
++ REFERENCE
++ "OSPF Version 2, Section 10 The Neighbor Data
++ Structure"
++ ::= { ospf 10 }
++
++
++ ospfNbrEntry OBJECT-TYPE
++ SYNTAX OspfNbrEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The information regarding a single neighbor."
++ REFERENCE
++ "OSPF Version 2, Section 10 The Neighbor Data
++ Structure"
++ INDEX { ospfNbrIpAddr, ospfNbrAddressLessIndex }
++ ::= { ospfNbrTable 1 }
++
++OspfNbrEntry ::=
++ SEQUENCE {
++ ospfNbrIpAddr
++ IpAddress,
++ ospfNbrAddressLessIndex
++ InterfaceIndex,
++ ospfNbrRtrId
++ RouterID,
++ ospfNbrOptions
++ Integer32,
++ ospfNbrPriority
++ DesignatedRouterPriority,
++ ospfNbrState
++ INTEGER,
++ ospfNbrEvents
++ Counter32,
++ ospfNbrLsRetransQLen
++ Gauge32,
++ ospfNbmaNbrStatus
++ RowStatus,
++ ospfNbmaNbrPermanence
++ INTEGER,
++ ospfNbrHelloSuppressed
++ TruthValue
++ }
++
++ ospfNbrIpAddr OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP address this neighbor is using in its
++ IP Source Address. Note that, on addressless
++ links, this will not be 0.0.0.0, but the ad-
++ dress of another of the neighbor's interfaces."
++ ::= { ospfNbrEntry 1 }
++
++
++ ospfNbrAddressLessIndex OBJECT-TYPE
++ SYNTAX InterfaceIndex
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "On an interface having an IP Address, zero.
++ On addressless interfaces, the corresponding
++ value of ifIndex in the Internet Standard MIB.
++ On row creation, this can be derived from the
++ instance."
++ ::= { ospfNbrEntry 2 }
++
++
++ ospfNbrRtrId OBJECT-TYPE
++ SYNTAX RouterID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "A 32-bit integer (represented as a type IpAd-
++ dress) uniquely identifying the neighboring
++ router in the Autonomous System."
++ DEFVAL { '00000000'H } -- 0.0.0.0
++ ::= { ospfNbrEntry 3 }
++
++
++ ospfNbrOptions OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "A Bit Mask corresponding to the neighbor's op-
++ tions field.
++
++ Bit 0, if set, indicates that the system will
++ operate on Type of Service metrics other than
++ TOS 0. If zero, the neighbor will ignore all
++ metrics except the TOS 0 metric.
++
++ Bit 1, if set, indicates that the associated
++ area accepts and operates on external informa-
++ tion; if zero, it is a stub area.
++
++ Bit 2, if set, indicates that the system is ca-
++ pable of routing IP Multicast datagrams; i.e.,
++ that it implements the Multicast Extensions to
++ OSPF.
++
++ Bit 3, if set, indicates that the associated
++ area is an NSSA. These areas are capable of
++ carrying type 7 external advertisements, which
++ are translated into type 5 external advertise-
++ ments at NSSA borders."
++ REFERENCE
++ "OSPF Version 2, Section 12.1.2 Options"
++ DEFVAL { 0 }
++ ::= { ospfNbrEntry 4 }
++
++
++ ospfNbrPriority OBJECT-TYPE
++ SYNTAX DesignatedRouterPriority
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The priority of this neighbor in the designat-
++ ed router election algorithm. The value 0 sig-
++ nifies that the neighbor is not eligible to be-
++ come the designated router on this particular
++ network."
++ DEFVAL { 1 }
++ ::= { ospfNbrEntry 5 }
++
++
++ ospfNbrState OBJECT-TYPE
++ SYNTAX INTEGER {
++ down (1),
++ attempt (2),
++ init (3),
++ twoWay (4),
++ exchangeStart (5),
++ exchange (6),
++ loading (7),
++ full (8)
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The State of the relationship with this Neigh-
++ bor."
++ REFERENCE
++ "OSPF Version 2, Section 10.1 Neighbor States"
++ DEFVAL { down }
++ ::= { ospfNbrEntry 6 }
++
++
++ ospfNbrEvents OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of times this neighbor relationship
++ has changed state, or an error has occurred."
++ ::= { ospfNbrEntry 7 }
++
++
++ ospfNbrLsRetransQLen OBJECT-TYPE
++ SYNTAX Gauge32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The current length of the retransmission
++ queue."
++ ::= { ospfNbrEntry 8 }
++
++
++ ospfNbmaNbrStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. Setting it to 'invalid' has the effect of
++ rendering it inoperative. The internal effect
++ (row removal) is implementation dependent."
++ ::= { ospfNbrEntry 9 }
++
++
++ ospfNbmaNbrPermanence OBJECT-TYPE
++ SYNTAX INTEGER {
++ dynamic (1), -- learned through protocol
++ permanent (2) -- configured address
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. 'dynamic' and 'permanent' refer to how
++ the neighbor became known."
++ DEFVAL { permanent }
++ ::= { ospfNbrEntry 10 }
++
++
++ ospfNbrHelloSuppressed OBJECT-TYPE
++ SYNTAX TruthValue
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "Indicates whether Hellos are being suppressed
++ to the neighbor"
++ ::= { ospfNbrEntry 11 }
++
++
++-- OSPF Virtual Neighbor Table
++
++-- This table describes all virtual neighbors.
++-- Since Virtual Links are configured in the
++-- virtual interface table, this table is read-only.
++
++ ospfVirtNbrTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfVirtNbrEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A table of virtual neighbor information."
++ REFERENCE
++ "OSPF Version 2, Section 15 Virtual Links"
++ ::= { ospf 11 }
++
++
++ ospfVirtNbrEntry OBJECT-TYPE
++ SYNTAX OspfVirtNbrEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "Virtual neighbor information."
++ INDEX { ospfVirtNbrArea, ospfVirtNbrRtrId }
++ ::= { ospfVirtNbrTable 1 }
++
++OspfVirtNbrEntry ::=
++ SEQUENCE {
++ ospfVirtNbrArea
++ AreaID,
++ ospfVirtNbrRtrId
++ RouterID,
++ ospfVirtNbrIpAddr
++ IpAddress,
++ ospfVirtNbrOptions
++ Integer32,
++ ospfVirtNbrState
++ INTEGER,
++ ospfVirtNbrEvents
++ Counter32,
++ ospfVirtNbrLsRetransQLen
++ Gauge32,
++ ospfVirtNbrHelloSuppressed
++ TruthValue
++ }
++
++ ospfVirtNbrArea OBJECT-TYPE
++ SYNTAX AreaID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Transit Area Identifier."
++ ::= { ospfVirtNbrEntry 1 }
++
++
++ ospfVirtNbrRtrId OBJECT-TYPE
++ SYNTAX RouterID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "A 32-bit integer uniquely identifying the
++ neighboring router in the Autonomous System."
++ ::= { ospfVirtNbrEntry 2 }
++
++
++ ospfVirtNbrIpAddr OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP address this Virtual Neighbor is us-
++ ing."
++ ::= { ospfVirtNbrEntry 3 }
++
++
++ ospfVirtNbrOptions OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "A Bit Mask corresponding to the neighbor's op-
++ tions field.
++
++ Bit 1, if set, indicates that the system will
++ operate on Type of Service metrics other than
++ TOS 0. If zero, the neighbor will ignore all
++ metrics except the TOS 0 metric.
++
++ Bit 2, if set, indicates that the system is
++ Network Multicast capable; ie, that it imple-
++ ments OSPF Multicast Routing."
++ ::= { ospfVirtNbrEntry 4 }
++ ospfVirtNbrState OBJECT-TYPE
++ SYNTAX INTEGER {
++ down (1),
++ attempt (2),
++ init (3),
++ twoWay (4),
++ exchangeStart (5),
++ exchange (6),
++ loading (7),
++ full (8)
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The state of the Virtual Neighbor Relation-
++ ship."
++ ::= { ospfVirtNbrEntry 5 }
++
++
++ ospfVirtNbrEvents OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of times this virtual link has
++ changed its state, or an error has occurred."
++ ::= { ospfVirtNbrEntry 6 }
++
++
++ ospfVirtNbrLsRetransQLen OBJECT-TYPE
++ SYNTAX Gauge32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The current length of the retransmission
++ queue."
++ ::= { ospfVirtNbrEntry 7 }
++
++
++ ospfVirtNbrHelloSuppressed OBJECT-TYPE
++ SYNTAX TruthValue
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "Indicates whether Hellos are being suppressed
++ to the neighbor"
++ ::= { ospfVirtNbrEntry 8 }
++
++-- OSPF Link State Database, External
++
++-- The Link State Database contains the Link State
++-- Advertisements from throughout the areas that the
++-- device is attached to.
++
++-- This table is identical to the OSPF LSDB Table in
++-- format, but contains only External Link State
++-- Advertisements. The purpose is to allow external
++-- LSAs to be displayed once for the router rather
++-- than once in each non-stub area.
++
++ ospfExtLsdbTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfExtLsdbEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "The OSPF Process's Links State Database."
++ REFERENCE
++ "OSPF Version 2, Section 12 Link State Adver-
++ tisements"
++ ::= { ospf 12 }
++
++
++ ospfExtLsdbEntry OBJECT-TYPE
++ SYNTAX OspfExtLsdbEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A single Link State Advertisement."
++ INDEX { ospfExtLsdbType, ospfExtLsdbLsid, ospfExtLsdbRouterId }
++ ::= { ospfExtLsdbTable 1 }
++
++OspfExtLsdbEntry ::=
++ SEQUENCE {
++ ospfExtLsdbType
++ INTEGER,
++ ospfExtLsdbLsid
++ IpAddress,
++ ospfExtLsdbRouterId
++ RouterID,
++ ospfExtLsdbSequence
++ Integer32,
++ ospfExtLsdbAge
++ Integer32,
++ ospfExtLsdbChecksum
++ Integer32,
++ ospfExtLsdbAdvertisement
++ OCTET STRING
++ }
++
++ ospfExtLsdbType OBJECT-TYPE
++ SYNTAX INTEGER {
++ asExternalLink (5)
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The type of the link state advertisement.
++ Each link state type has a separate advertise-
++ ment format."
++ REFERENCE
++ "OSPF Version 2, Appendix A.4.1 The Link State
++ Advertisement header"
++ ::= { ospfExtLsdbEntry 1 }
++
++
++ ospfExtLsdbLsid OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Link State ID is an LS Type Specific field
++ containing either a Router ID or an IP Address;
++ it identifies the piece of the routing domain
++ that is being described by the advertisement."
++ REFERENCE
++ "OSPF Version 2, Section 12.1.4 Link State ID"
++ ::= { ospfExtLsdbEntry 2 }
++
++
++ ospfExtLsdbRouterId OBJECT-TYPE
++ SYNTAX RouterID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The 32 bit number that uniquely identifies the
++ originating router in the Autonomous System."
++ REFERENCE
++ "OSPF Version 2, Appendix C.1 Global parameters"
++ ::= { ospfExtLsdbEntry 3 }
++
++-- Note that the OSPF Sequence Number is a 32 bit signed
++-- integer. It starts with the value '80000001'h,
++-- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h
++-- Thus, a typical sequence number will be very negative.
++ ospfExtLsdbSequence OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The sequence number field is a signed 32-bit
++ integer. It is used to detect old and dupli-
++ cate link state advertisements. The space of
++ sequence numbers is linearly ordered. The
++ larger the sequence number the more recent the
++ advertisement."
++ REFERENCE
++ "OSPF Version 2, Section 12.1.6 LS sequence
++ number"
++ ::= { ospfExtLsdbEntry 4 }
++
++
++ ospfExtLsdbAge OBJECT-TYPE
++ SYNTAX Integer32 -- Should be 0..MaxAge
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "This field is the age of the link state adver-
++ tisement in seconds."
++ REFERENCE
++ "OSPF Version 2, Section 12.1.1 LS age"
++ ::= { ospfExtLsdbEntry 5 }
++
++
++ ospfExtLsdbChecksum OBJECT-TYPE
++ SYNTAX Integer32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "This field is the checksum of the complete
++ contents of the advertisement, excepting the
++ age field. The age field is excepted so that
++ an advertisement's age can be incremented
++ without updating the checksum. The checksum
++ used is the same that is used for ISO connec-
++ tionless datagrams; it is commonly referred to
++ as the Fletcher checksum."
++ REFERENCE
++ "OSPF Version 2, Section 12.1.7 LS checksum"
++ ::= { ospfExtLsdbEntry 6 }
++
++
++ ospfExtLsdbAdvertisement OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE(36))
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The entire Link State Advertisement, including
++ its header."
++ REFERENCE
++ "OSPF Version 2, Section 12 Link State Adver-
++ tisements"
++ ::= { ospfExtLsdbEntry 7 }
++
++
++-- OSPF Use of the CIDR Route Table
++
++ospfRouteGroup OBJECT IDENTIFIER ::= { ospf 13 }
++
++-- The IP Forwarding Table defines a number of objects for use by
++-- the routing protocol to externalize its information. Most of
++-- the variables (ipForwardDest, ipForwardMask, ipForwardPolicy,
++-- ipForwardNextHop, ipForwardIfIndex, ipForwardType,
++-- ipForwardProto, ipForwardAge, and ipForwardNextHopAS) are
++-- defined there.
++
++-- Those that leave some discretion are defined here.
++
++-- ipCidrRouteProto is, of course, ospf (13).
++
++-- ipCidrRouteAge is the time since the route was first calculated,
++-- as opposed to the time since the last SPF run.
++
++-- ipCidrRouteInfo is an OBJECT IDENTIFIER for use by the routing
++-- protocol. The following values shall be found there depending
++-- on the way the route was calculated.
++
++ospfIntraArea OBJECT IDENTIFIER ::= { ospfRouteGroup 1 }
++ospfInterArea OBJECT IDENTIFIER ::= { ospfRouteGroup 2 }
++ospfExternalType1 OBJECT IDENTIFIER ::= { ospfRouteGroup 3 }
++ospfExternalType2 OBJECT IDENTIFIER ::= { ospfRouteGroup 4 }
++
++-- ipCidrRouteMetric1 is, by definition, the primary routing
++-- metric. Therefore, it should be the metric that route
++-- selection is based on. For intra-area and inter-area routes,
++-- it is an OSPF metric. For External Type 1 (comparable value)
++-- routes, it is an OSPF metric plus the External Metric. For
++-- external Type 2 (non-comparable value) routes, it is the
++-- external metric.
++
++-- ipCidrRouteMetric2 is, by definition, a secondary routing
++-- metric. Therefore, it should be the metric that breaks a tie
++-- among routes having equal metric1 values and the same
++-- calculation rule. For intra-area, inter-area routes, and
++-- External Type 1 (comparable value) routes, it is unused. For
++-- external Type 2 (non-comparable value) routes, it is the metric
++-- to the AS border router.
++
++-- ipCidrRouteMetric3, ipCidrRouteMetric4, and ipCidrRouteMetric5 are
++-- unused.
++
++--
++-- The OSPF Area Aggregate Table
++--
++-- This table replaces the OSPF Area Summary Table, being an
++-- extension of that for CIDR routers.
++
++ ospfAreaAggregateTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF OspfAreaAggregateEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A range of IP addresses specified by an IP
++ address/IP network mask pair. For example,
++ class B address range of X.X.X.X with a network
++ mask of 255.255.0.0 includes all IP addresses
++ from X.X.0.0 to X.X.255.255. Note that if
++ ranges are configured such that one range sub-
++ sumes another range (e.g., 10.0.0.0 mask
++ 255.0.0.0 and 10.1.0.0 mask 255.255.0.0), the
++ most specific match is the preferred one."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospf 14 }
++
++
++ ospfAreaAggregateEntry OBJECT-TYPE
++ SYNTAX OspfAreaAggregateEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A range of IP addresses specified by an IP
++ address/IP network mask pair. For example,
++ class B address range of X.X.X.X with a network
++ mask of 255.255.0.0 includes all IP addresses
++ from X.X.0.0 to X.X.255.255. Note that if
++ ranges are range configured such that one range
++ subsumes another range (e.g., 10.0.0.0 mask
++ 255.0.0.0 and 10.1.0.0 mask 255.255.0.0), the
++ most specific match is the preferred one."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ INDEX { ospfAreaAggregateAreaID, ospfAreaAggregateLsdbType,
++ ospfAreaAggregateNet, ospfAreaAggregateMask }
++ ::= { ospfAreaAggregateTable 1 }
++
++
++OspfAreaAggregateEntry ::=
++ SEQUENCE {
++ ospfAreaAggregateAreaID
++ AreaID,
++ ospfAreaAggregateLsdbType
++ INTEGER,
++ ospfAreaAggregateNet
++ IpAddress,
++ ospfAreaAggregateMask
++ IpAddress,
++ ospfAreaAggregateStatus
++ RowStatus,
++ ospfAreaAggregateEffect
++ INTEGER
++ }
++
++ ospfAreaAggregateAreaID OBJECT-TYPE
++ SYNTAX AreaID
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Area the Address Aggregate is to be found
++ within."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospfAreaAggregateEntry 1 }
++
++
++ ospfAreaAggregateLsdbType OBJECT-TYPE
++ SYNTAX INTEGER {
++ summaryLink (3),
++ nssaExternalLink (7)
++ }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The type of the Address Aggregate. This field
++ specifies the Lsdb type that this Address Ag-
++ gregate applies to."
++ REFERENCE
++ "OSPF Version 2, Appendix A.4.1 The Link State
++ Advertisement header"
++ ::= { ospfAreaAggregateEntry 2 }
++
++
++ ospfAreaAggregateNet OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP Address of the Net or Subnet indicated
++ by the range."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospfAreaAggregateEntry 3 }
++
++
++ ospfAreaAggregateMask OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The Subnet Mask that pertains to the Net or
++ Subnet."
++ REFERENCE
++ "OSPF Version 2, Appendix C.2 Area parameters"
++ ::= { ospfAreaAggregateEntry 4 }
++
++
++ ospfAreaAggregateStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable displays the status of the en-
++ try. Setting it to 'invalid' has the effect of
++ rendering it inoperative. The internal effect
++ (row removal) is implementation dependent."
++ ::= { ospfAreaAggregateEntry 5 }
++
++
++ ospfAreaAggregateEffect OBJECT-TYPE
++ SYNTAX INTEGER {
++ advertiseMatching (1),
++ doNotAdvertiseMatching (2)
++ }
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "Subnets subsumed by ranges either trigger the
++ advertisement of the indicated aggregate (ad-
++ vertiseMatching), or result in the subnet's not
++ being advertised at all outside the area."
++ DEFVAL { advertiseMatching }
++ ::= { ospfAreaAggregateEntry 6 }
++
++
++-- conformance information
++
++ospfConformance OBJECT IDENTIFIER ::= { ospf 15 }
++
++ospfGroups OBJECT IDENTIFIER ::= { ospfConformance 1 }
++ospfCompliances OBJECT IDENTIFIER ::= { ospfConformance 2 }
++
++-- compliance statements
++
++ ospfCompliance MODULE-COMPLIANCE
++ STATUS current
++ DESCRIPTION
++ "The compliance statement "
++ MODULE -- this module
++ MANDATORY-GROUPS {
++ ospfBasicGroup,
++ ospfAreaGroup,
++ ospfStubAreaGroup,
++ ospfIfGroup,
++ ospfIfMetricGroup,
++ ospfVirtIfGroup,
++ ospfNbrGroup,
++ ospfVirtNbrGroup,
++ ospfAreaAggregateGroup
++ }
++ ::= { ospfCompliances 1 }
++
++
++-- units of conformance
++
++ ospfBasicGroup OBJECT-GROUP
++ OBJECTS {
++ ospfRouterId,
++ ospfAdminStat,
++ ospfVersionNumber,
++ ospfAreaBdrRtrStatus,
++ ospfASBdrRtrStatus,
++ ospfExternLsaCount,
++ ospfExternLsaCksumSum,
++ ospfTOSSupport,
++ ospfOriginateNewLsas,
++ ospfRxNewLsas,
++ ospfExtLsdbLimit,
++ ospfMulticastExtensions,
++ ospfExitOverflowInterval,
++ ospfDemandExtensions
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems."
++ ::= { ospfGroups 1 }
++
++
++ ospfAreaGroup OBJECT-GROUP
++ OBJECTS {
++ ospfAreaId,
++ ospfImportAsExtern,
++ ospfSpfRuns,
++ ospfAreaBdrRtrCount,
++ ospfAsBdrRtrCount,
++ ospfAreaLsaCount,
++ ospfAreaLsaCksumSum,
++ ospfAreaSummary,
++ ospfAreaStatus
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems
++ supporting areas."
++ ::= { ospfGroups 2 }
++
++
++ ospfStubAreaGroup OBJECT-GROUP
++ OBJECTS {
++ ospfStubAreaId,
++ ospfStubTOS,
++ ospfStubMetric,
++ ospfStubStatus,
++ ospfStubMetricType
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems
++ supporting stub areas."
++ ::= { ospfGroups 3 }
++
++
++ ospfLsdbGroup OBJECT-GROUP
++ OBJECTS {
++ ospfLsdbAreaId,
++ ospfLsdbType,
++ ospfLsdbLsid,
++ ospfLsdbRouterId,
++ ospfLsdbSequence,
++ ospfLsdbAge,
++ ospfLsdbChecksum,
++ ospfLsdbAdvertisement
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems
++ that display their link state database."
++ ::= { ospfGroups 4 }
++
++
++ ospfAreaRangeGroup OBJECT-GROUP
++ OBJECTS {
++ ospfAreaRangeAreaId,
++ ospfAreaRangeNet,
++ ospfAreaRangeMask,
++ ospfAreaRangeStatus,
++ ospfAreaRangeEffect
++ }
++ STATUS obsolete
++ DESCRIPTION
++ "These objects are required for non-CIDR OSPF
++ systems that support multiple areas."
++ ::= { ospfGroups 5 }
++
++
++ ospfHostGroup OBJECT-GROUP
++ OBJECTS {
++ ospfHostIpAddress,
++ ospfHostTOS,
++ ospfHostMetric,
++ ospfHostStatus,
++ ospfHostAreaID
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems
++ that support attached hosts."
++ ::= { ospfGroups 6 }
++
++
++ ospfIfGroup OBJECT-GROUP
++ OBJECTS {
++ ospfIfIpAddress,
++ ospfAddressLessIf,
++ ospfIfAreaId,
++ ospfIfType,
++ ospfIfAdminStat,
++ ospfIfRtrPriority,
++ ospfIfTransitDelay,
++ ospfIfRetransInterval,
++ ospfIfHelloInterval,
++ ospfIfRtrDeadInterval,
++ ospfIfPollInterval,
++ ospfIfState,
++ ospfIfDesignatedRouter,
++ ospfIfBackupDesignatedRouter,
++ ospfIfEvents,
++ ospfIfAuthType,
++ ospfIfAuthKey,
++ ospfIfStatus,
++ ospfIfMulticastForwarding,
++ ospfIfDemand
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems."
++ ::= { ospfGroups 7 }
++
++
++ ospfIfMetricGroup OBJECT-GROUP
++ OBJECTS {
++ ospfIfMetricIpAddress,
++ ospfIfMetricAddressLessIf,
++ ospfIfMetricTOS,
++ ospfIfMetricValue,
++ ospfIfMetricStatus
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems."
++ ::= { ospfGroups 8 }
++
++
++ ospfVirtIfGroup OBJECT-GROUP
++ OBJECTS {
++ ospfVirtIfAreaId,
++ ospfVirtIfNeighbor,
++ ospfVirtIfTransitDelay,
++ ospfVirtIfRetransInterval,
++ ospfVirtIfHelloInterval,
++ ospfVirtIfRtrDeadInterval,
++ ospfVirtIfState,
++ ospfVirtIfEvents,
++ ospfVirtIfAuthType,
++ ospfVirtIfAuthKey,
++ ospfVirtIfStatus
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems."
++ ::= { ospfGroups 9 }
++
++
++ ospfNbrGroup OBJECT-GROUP
++ OBJECTS {
++ ospfNbrIpAddr,
++ ospfNbrAddressLessIndex,
++ ospfNbrRtrId,
++ ospfNbrOptions,
++ ospfNbrPriority,
++ ospfNbrState,
++ ospfNbrEvents,
++ ospfNbrLsRetransQLen,
++ ospfNbmaNbrStatus,
++ ospfNbmaNbrPermanence,
++ ospfNbrHelloSuppressed
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems."
++ ::= { ospfGroups 10 }
++
++
++ ospfVirtNbrGroup OBJECT-GROUP
++ OBJECTS {
++ ospfVirtNbrArea,
++ ospfVirtNbrRtrId,
++ ospfVirtNbrIpAddr,
++ ospfVirtNbrOptions,
++ ospfVirtNbrState,
++ ospfVirtNbrEvents,
++ ospfVirtNbrLsRetransQLen,
++ ospfVirtNbrHelloSuppressed
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems."
++ ::= { ospfGroups 11 }
++
++
++ ospfExtLsdbGroup OBJECT-GROUP
++ OBJECTS {
++ ospfExtLsdbType,
++ ospfExtLsdbLsid,
++ ospfExtLsdbRouterId,
++ ospfExtLsdbSequence,
++ ospfExtLsdbAge,
++ ospfExtLsdbChecksum,
++ ospfExtLsdbAdvertisement
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems
++ that display their link state database."
++ ::= { ospfGroups 12 }
++
++
++ ospfAreaAggregateGroup OBJECT-GROUP
++ OBJECTS {
++ ospfAreaAggregateAreaID,
++ ospfAreaAggregateLsdbType,
++ ospfAreaAggregateNet,
++ ospfAreaAggregateMask,
++ ospfAreaAggregateStatus,
++ ospfAreaAggregateEffect
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required for OSPF systems."
++ ::= { ospfGroups 13 }
++
++END
+--- /dev/null
++++ b/mibs/OSPF-TRAP-MIB.txt
+@@ -0,0 +1,443 @@
++OSPF-TRAP-MIB DEFINITIONS ::= BEGIN
++
++ IMPORTS
++ MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, IpAddress
++ FROM SNMPv2-SMI
++ MODULE-COMPLIANCE, OBJECT-GROUP
++ FROM SNMPv2-CONF
++ ospfRouterId, ospfIfIpAddress, ospfAddressLessIf, ospfIfState,
++ ospfVirtIfAreaId, ospfVirtIfNeighbor, ospfVirtIfState,
++ ospfNbrIpAddr, ospfNbrAddressLessIndex, ospfNbrRtrId,
++ ospfNbrState, ospfVirtNbrArea, ospfVirtNbrRtrId, ospfVirtNbrState,
++ ospfLsdbType, ospfLsdbLsid, ospfLsdbRouterId, ospfLsdbAreaId,
++ ospfExtLsdbLimit, ospf
++ FROM OSPF-MIB;
++
++ ospfTrap MODULE-IDENTITY
++ LAST-UPDATED "9501201225Z" -- Fri Jan 20 12:25:50 PST 1995
++ ORGANIZATION "IETF OSPF Working Group"
++ CONTACT-INFO
++ " Fred Baker
++ Postal: Cisco Systems
++ 519 Lado Drive
++ Santa Barbara, California 93111
++ Tel: +1 805 681 0115
++ E-Mail: fred@cisco.com
++
++ Rob Coltun
++ Postal: RainbowBridge Communications
++ Tel: (301) 340-9416
++ E-Mail: rcoltun@rainbow-bridge.com"
++ DESCRIPTION
++ "The MIB module to describe traps for the OSPF
++ Version 2 Protocol."
++ ::= { ospf 16 }
++
++-- Trap Support Objects
++
++-- The following are support objects for the OSPF traps.
++
++ospfTrapControl OBJECT IDENTIFIER ::= { ospfTrap 1 }
++ospfTraps OBJECT IDENTIFIER ::= { ospfTrap 2 }
++
++ ospfSetTrap OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE(4))
++ MAX-ACCESS read-write
++ STATUS current
++ DESCRIPTION
++ "A four-octet string serving as a bit map for
++ the trap events defined by the OSPF traps. This
++ object is used to enable and disable specific
++ OSPF traps where a 1 in the bit field
++ represents enabled. The right-most bit (least
++ significant) represents trap 0."
++ ::= { ospfTrapControl 1 }
++
++
++ ospfConfigErrorType OBJECT-TYPE
++ SYNTAX INTEGER {
++ badVersion (1),
++ areaMismatch (2),
++ unknownNbmaNbr (3), -- Router is Dr eligible
++ unknownVirtualNbr (4),
++ authTypeMismatch(5),
++ authFailure (6),
++ netMaskMismatch (7),
++ helloIntervalMismatch (8),
++ deadIntervalMismatch (9),
++ optionMismatch (10) }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "Potential types of configuration conflicts.
++ Used by the ospfConfigError and ospfConfigVir-
++ tError traps."
++ ::= { ospfTrapControl 2 }
++
++
++ ospfPacketType OBJECT-TYPE
++ SYNTAX INTEGER {
++ hello (1),
++ dbDescript (2),
++ lsReq (3),
++ lsUpdate (4),
++ lsAck (5) }
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "OSPF packet types."
++ ::= { ospfTrapControl 3 }
++
++
++ ospfPacketSrc OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP address of an inbound packet that can-
++ not be identified by a neighbor instance."
++ ::= { ospfTrapControl 4 }
++
++
++-- Traps
++
++
++ ospfIfStateChange NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfIfIpAddress,
++ ospfAddressLessIf,
++ ospfIfState -- The new state
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfIfStateChange trap signifies that there
++ has been a change in the state of a non-virtual
++ OSPF interface. This trap should be generated
++ when the interface state regresses (e.g., goes
++ from Dr to Down) or progresses to a terminal
++ state (i.e., Point-to-Point, DR Other, Dr, or
++ Backup)."
++ ::= { ospfTraps 16 }
++
++
++ ospfVirtIfStateChange NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfVirtIfAreaId,
++ ospfVirtIfNeighbor,
++ ospfVirtIfState -- The new state
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfIfStateChange trap signifies that there
++ has been a change in the state of an OSPF vir-
++ tual interface.
++ This trap should be generated when the inter-
++ face state regresses (e.g., goes from Point-
++ to-Point to Down) or progresses to a terminal
++ state (i.e., Point-to-Point)."
++ ::= { ospfTraps 1 }
++
++
++ ospfNbrStateChange NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfNbrIpAddr,
++ ospfNbrAddressLessIndex,
++ ospfNbrRtrId,
++ ospfNbrState -- The new state
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfNbrStateChange trap signifies that
++ there has been a change in the state of a non-
++ virtual OSPF neighbor. This trap should be
++ generated when the neighbor state regresses
++ (e.g., goes from Attempt or Full to 1-Way or
++ Down) or progresses to a terminal state (e.g.,
++ 2-Way or Full). When an neighbor transitions
++ from or to Full on non-broadcast multi-access
++ and broadcast networks, the trap should be gen-
++ erated by the designated router. A designated
++ router transitioning to Down will be noted by
++ ospfIfStateChange."
++ ::= { ospfTraps 2 }
++
++
++ ospfVirtNbrStateChange NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfVirtNbrArea,
++ ospfVirtNbrRtrId,
++ ospfVirtNbrState -- The new state
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfIfStateChange trap signifies that there
++ has been a change in the state of an OSPF vir-
++ tual neighbor. This trap should be generated
++ when the neighbor state regresses (e.g., goes
++ from Attempt or Full to 1-Way or Down) or
++ progresses to a terminal state (e.g., Full)."
++ ::= { ospfTraps 3 }
++ ospfIfConfigError NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfIfIpAddress,
++ ospfAddressLessIf,
++ ospfPacketSrc, -- The source IP address
++ ospfConfigErrorType, -- Type of error
++ ospfPacketType
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfIfConfigError trap signifies that a
++ packet has been received on a non-virtual in-
++ terface from a router whose configuration
++ parameters conflict with this router's confi-
++ guration parameters. Note that the event op-
++ tionMismatch should cause a trap only if it
++ prevents an adjacency from forming."
++ ::= { ospfTraps 4 }
++
++
++ ospfVirtIfConfigError NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfVirtIfAreaId,
++ ospfVirtIfNeighbor,
++ ospfConfigErrorType, -- Type of error
++ ospfPacketType
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfConfigError trap signifies that a pack-
++ et has been received on a virtual interface
++ from a router whose configuration parameters
++ conflict with this router's configuration
++ parameters. Note that the event optionMismatch
++ should cause a trap only if it prevents an ad-
++ jacency from forming."
++ ::= { ospfTraps 5 }
++
++
++ ospfIfAuthFailure NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfIfIpAddress,
++ ospfAddressLessIf,
++ ospfPacketSrc, -- The source IP address
++ ospfConfigErrorType, -- authTypeMismatch or
++ -- authFailure
++ ospfPacketType
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfIfAuthFailure trap signifies that a
++ packet has been received on a non-virtual in-
++ terface from a router whose authentication key
++ or authentication type conflicts with this
++ router's authentication key or authentication
++ type."
++ ::= { ospfTraps 6 }
++
++
++ ospfVirtIfAuthFailure NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfVirtIfAreaId,
++ ospfVirtIfNeighbor,
++ ospfConfigErrorType, -- authTypeMismatch or
++ -- authFailure
++ ospfPacketType
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfVirtIfAuthFailure trap signifies that a
++ packet has been received on a virtual interface
++ from a router whose authentication key or au-
++ thentication type conflicts with this router's
++ authentication key or authentication type."
++ ::= { ospfTraps 7 }
++
++
++ ospfIfRxBadPacket NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfIfIpAddress,
++ ospfAddressLessIf,
++ ospfPacketSrc, -- The source IP address
++ ospfPacketType
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfIfRxBadPacket trap signifies that an
++ OSPF packet has been received on a non-virtual
++ interface that cannot be parsed."
++ ::= { ospfTraps 8 }
++
++ ospfVirtIfRxBadPacket NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfVirtIfAreaId,
++ ospfVirtIfNeighbor,
++ ospfPacketType
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfRxBadPacket trap signifies that an OSPF
++ packet has been received on a virtual interface
++ that cannot be parsed."
++ ::= { ospfTraps 9 }
++
++
++ ospfTxRetransmit NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfIfIpAddress,
++ ospfAddressLessIf,
++ ospfNbrRtrId, -- Destination
++ ospfPacketType,
++ ospfLsdbType,
++ ospfLsdbLsid,
++ ospfLsdbRouterId
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfTxRetransmit trap signifies than an
++ OSPF packet has been retransmitted on a non-
++ virtual interface. All packets that may be re-
++ transmitted are associated with an LSDB entry.
++ The LS type, LS ID, and Router ID are used to
++ identify the LSDB entry."
++ ::= { ospfTraps 10 }
++
++
++ ospfVirtIfTxRetransmit NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfVirtIfAreaId,
++ ospfVirtIfNeighbor,
++ ospfPacketType,
++ ospfLsdbType,
++ ospfLsdbLsid,
++ ospfLsdbRouterId
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfTxRetransmit trap signifies than an
++ OSPF packet has been retransmitted on a virtual
++ interface. All packets that may be retransmit-
++ ted are associated with an LSDB entry. The LS
++ type, LS ID, and Router ID are used to identify
++ the LSDB entry."
++ ::= { ospfTraps 11 }
++
++
++ ospfOriginateLsa NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfLsdbAreaId, -- 0.0.0.0 for AS Externals
++ ospfLsdbType,
++ ospfLsdbLsid,
++ ospfLsdbRouterId
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfOriginateLsa trap signifies that a new
++ LSA has been originated by this router. This
++ trap should not be invoked for simple refreshes
++ of LSAs (which happesn every 30 minutes), but
++ instead will only be invoked when an LSA is
++ (re)originated due to a topology change. Addi-
++ tionally, this trap does not include LSAs that
++ are being flushed because they have reached
++ MaxAge."
++ ::= { ospfTraps 12 }
++
++
++ ospfMaxAgeLsa NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfLsdbAreaId, -- 0.0.0.0 for AS Externals
++ ospfLsdbType,
++ ospfLsdbLsid,
++ ospfLsdbRouterId
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfMaxAgeLsa trap signifies that one of
++ the LSA in the router's link-state database has
++ aged to MaxAge."
++ ::= { ospfTraps 13 }
++
++
++ ospfLsdbOverflow NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfExtLsdbLimit
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfLsdbOverflow trap signifies that the
++ number of LSAs in the router's link-state data-
++ base has exceeded ospfExtLsdbLimit."
++ ::= { ospfTraps 14 }
++
++
++ ospfLsdbApproachingOverflow NOTIFICATION-TYPE
++ OBJECTS {
++ ospfRouterId, -- The originator of the trap
++ ospfExtLsdbLimit
++ }
++ STATUS current
++ DESCRIPTION
++ "An ospfLsdbApproachingOverflow trap signifies
++ that the number of LSAs in the router's link-
++ state database has exceeded ninety percent of
++ ospfExtLsdbLimit."
++ ::= { ospfTraps 15 }
++
++
++-- conformance information
++
++ospfTrapConformance OBJECT IDENTIFIER ::= { ospfTrap 3 }
++
++ospfTrapGroups OBJECT IDENTIFIER ::= { ospfTrapConformance 1 }
++ospfTrapCompliances OBJECT IDENTIFIER ::= { ospfTrapConformance 2 }
++
++-- compliance statements
++
++ ospfTrapCompliance MODULE-COMPLIANCE
++ STATUS current
++ DESCRIPTION
++ "The compliance statement "
++ MODULE -- this module
++ MANDATORY-GROUPS { ospfTrapControlGroup }
++
++
++ GROUP ospfTrapControlGroup
++ DESCRIPTION
++ "This group is optional but recommended for all
++ OSPF systems"
++ ::= { ospfTrapCompliances 1 }
++
++
++-- units of conformance
++
++ ospfTrapControlGroup OBJECT-GROUP
++ OBJECTS {
++ ospfSetTrap,
++ ospfConfigErrorType,
++ ospfPacketType,
++ ospfPacketSrc
++ }
++ STATUS current
++ DESCRIPTION
++ "These objects are required to control traps
++ from OSPF systems."
++ ::= { ospfTrapGroups 1 }
++
++
++END
+--- /dev/null
++++ b/mibs/RIPv2-MIB.txt
+@@ -0,0 +1,530 @@
++ RIPv2-MIB DEFINITIONS ::= BEGIN
++
++ IMPORTS
++ MODULE-IDENTITY, OBJECT-TYPE, Counter32,
++ TimeTicks, IpAddress FROM SNMPv2-SMI
++ TEXTUAL-CONVENTION, RowStatus FROM SNMPv2-TC
++ MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF
++ mib-2 FROM RFC1213-MIB;
++
++ -- This MIB module uses the extended OBJECT-TYPE macro as
++ -- defined in [9].
++
++ rip2 MODULE-IDENTITY
++ LAST-UPDATED "9407272253Z" -- Wed Jul 27 22:53:04 PDT 1994
++ ORGANIZATION "IETF RIP-II Working Group"
++ CONTACT-INFO
++ " Fred Baker
++ Postal: Cisco Systems
++ 519 Lado Drive
++ Santa Barbara, California 93111
++ Tel: +1 805 681 0115
++ E-Mail: fbaker@cisco.com
++
++ Postal: Gary Malkin
++ Xylogics, Inc.
++ 53 Third Avenue
++ Burlington, MA 01803
++
++ Phone: (617) 272-8140
++ EMail: gmalkin@Xylogics.COM"
++ DESCRIPTION
++ "The MIB module to describe the RIP2 Version 2 Protocol"
++ ::= { mib-2 23 }
++
++ -- RIP-2 Management Information Base
++
++ -- the RouteTag type represents the contents of the
++ -- Route Domain field in the packet header or route entry.
++ -- The use of the Route Domain is deprecated.
++
++ RouteTag ::= TEXTUAL-CONVENTION
++ STATUS current
++ DESCRIPTION
++ "the RouteTag type represents the contents of the Route Domain
++ field in the packet header or route entry"
++ SYNTAX OCTET STRING (SIZE (2))
++
++--4.1 Global Counters
++
++-- The RIP-2 Globals Group.
++-- Implementation of this group is mandatory for systems
++-- which implement RIP-2.
++
++-- These counters are intended to facilitate debugging quickly
++-- changing routes or failing neighbors
++
++rip2Globals OBJECT IDENTIFIER ::= { rip2 1 }
++
++ rip2GlobalRouteChanges OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of route changes made to the IP Route
++ Database by RIP. This does not include the refresh
++ of a route's age."
++ ::= { rip2Globals 1 }
++
++ rip2GlobalQueries OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of responses sent to RIP queries
++ from other systems."
++ ::= { rip2Globals 2 }
++
++--4.2 RIP Interface Tables
++
++-- RIP Interfaces Groups
++-- Implementation of these Groups is mandatory for systems
++-- which implement RIP-2.
++
++-- The RIP Interface Status Table.
++
++ rip2IfStatTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF Rip2IfStatEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A list of subnets which require separate
++ status monitoring in RIP."
++ ::= { rip2 2 }
++
++ rip2IfStatEntry OBJECT-TYPE
++ SYNTAX Rip2IfStatEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A Single Routing Domain in a single Subnet."
++ INDEX { rip2IfStatAddress }
++ ::= { rip2IfStatTable 1 }
++
++ Rip2IfStatEntry ::=
++ SEQUENCE {
++ rip2IfStatAddress
++ IpAddress,
++ rip2IfStatRcvBadPackets
++ Counter32,
++ rip2IfStatRcvBadRoutes
++ Counter32,
++ rip2IfStatSentUpdates
++ Counter32,
++ rip2IfStatStatus
++ RowStatus
++ }
++
++ rip2IfStatAddress OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP Address of this system on the indicated
++ subnet. For unnumbered interfaces, the value 0.0.0.N,
++ where the least significant 24 bits (N) is the ifIndex
++ for the IP Interface in network byte order."
++ ::= { rip2IfStatEntry 1 }
++
++ rip2IfStatRcvBadPackets OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of RIP response packets received by
++ the RIP process which were subsequently discarded
++ for any reason (e.g. a version 0 packet, or an
++ unknown command type)."
++ ::= { rip2IfStatEntry 2 }
++
++ rip2IfStatRcvBadRoutes OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of routes, in valid RIP packets,
++ which were ignored for any reason (e.g. unknown
++ address family, or invalid metric)."
++ ::= { rip2IfStatEntry 3 }
++
++ rip2IfStatSentUpdates OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of triggered RIP updates actually
++ sent on this interface. This explicitly does
++ NOT include full updates sent containing new
++ information."
++ ::= { rip2IfStatEntry 4 }
++
++ rip2IfStatStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "Writing invalid has the effect of deleting
++ this interface."
++ ::= { rip2IfStatEntry 5 }
++
++-- The RIP Interface Configuration Table.
++
++ rip2IfConfTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF Rip2IfConfEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A list of subnets which require separate
++ configuration in RIP."
++ ::= { rip2 3 }
++
++ rip2IfConfEntry OBJECT-TYPE
++ SYNTAX Rip2IfConfEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A Single Routing Domain in a single Subnet."
++ INDEX { rip2IfConfAddress }
++ ::= { rip2IfConfTable 1 }
++
++ Rip2IfConfEntry ::=
++ SEQUENCE {
++ rip2IfConfAddress
++ IpAddress,
++ rip2IfConfDomain
++ RouteTag,
++ rip2IfConfAuthType
++ INTEGER,
++ rip2IfConfAuthKey
++ OCTET STRING (SIZE(0..16)),
++ rip2IfConfSend
++ INTEGER,
++ rip2IfConfReceive
++ INTEGER,
++ rip2IfConfDefaultMetric
++ INTEGER,
++ rip2IfConfStatus
++ RowStatus,
++ rip2IfConfSrcAddress
++ IpAddress
++ }
++
++ rip2IfConfAddress OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP Address of this system on the indicated
++ subnet. For unnumbered interfaces, the value 0.0.0.N,
++ where the least significant 24 bits (N) is the ifIndex
++ for the IP Interface in network byte order."
++ ::= { rip2IfConfEntry 1 }
++
++ rip2IfConfDomain OBJECT-TYPE
++ SYNTAX RouteTag
++ MAX-ACCESS read-create
++ STATUS obsolete
++ DESCRIPTION
++ "Value inserted into the Routing Domain field
++ of all RIP packets sent on this interface."
++ DEFVAL { '0000'h }
++ ::= { rip2IfConfEntry 2 }
++
++ rip2IfConfAuthType OBJECT-TYPE
++ SYNTAX INTEGER {
++ noAuthentication (1),
++ simplePassword (2),
++ md5 (3)
++ }
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The type of Authentication used on this
++ interface."
++ DEFVAL { noAuthentication }
++ ::= { rip2IfConfEntry 3 }
++
++ rip2IfConfAuthKey OBJECT-TYPE
++ SYNTAX OCTET STRING (SIZE(0..16))
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The value to be used as the Authentication Key
++ whenever the corresponding instance of
++ rip2IfConfAuthType has a value other than
++ noAuthentication. A modification of the corresponding
++ instance of rip2IfConfAuthType does not modify
++ the rip2IfConfAuthKey value. If a string shorter
++ than 16 octets is supplied, it will be left-
++ justified and padded to 16 octets, on the right,
++ with nulls (0x00).
++
++ Reading this object always results in an OCTET
++ STRING of length zero; authentication may not
++ be bypassed by reading the MIB object."
++ DEFVAL { ''h }
++ ::= { rip2IfConfEntry 4 }
++
++ rip2IfConfSend OBJECT-TYPE
++ SYNTAX INTEGER {
++ doNotSend (1),
++ ripVersion1 (2),
++ rip1Compatible (3),
++ ripVersion2 (4),
++ ripV1Demand (5),
++ ripV2Demand (6)
++ }
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "What the router sends on this interface.
++ ripVersion1 implies sending RIP updates compliant
++ with RFC 1058. rip1Compatible implies
++ broadcasting RIP-2 updates using RFC 1058 route
++ subsumption rules. ripVersion2 implies
++ multicasting RIP-2 updates. ripV1Demand indicates
++ the use of Demand RIP on a WAN interface under RIP
++ Version 1 rules. ripV2Demand indicates the use of
++ Demand RIP on a WAN interface under Version 2 rules."
++ DEFVAL { rip1Compatible }
++ ::= { rip2IfConfEntry 5 }
++
++ rip2IfConfReceive OBJECT-TYPE
++ SYNTAX INTEGER {
++ rip1 (1),
++ rip2 (2),
++ rip1OrRip2 (3),
++ doNotRecieve (4)
++ }
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This indicates which version of RIP updates
++ are to be accepted. Note that rip2 and
++ rip1OrRip2 implies reception of multicast
++ packets."
++ DEFVAL { rip1OrRip2 }
++ ::= { rip2IfConfEntry 6 }
++
++ rip2IfConfDefaultMetric OBJECT-TYPE
++ SYNTAX INTEGER ( 0..15 )
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "This variable indicates the metric that is to
++ be used for the default route entry in RIP updates
++ originated on this interface. A value of zero
++ indicates that no default route should be
++ originated; in this case, a default route via
++ another router may be propagated."
++ ::= { rip2IfConfEntry 7 }
++
++ rip2IfConfStatus OBJECT-TYPE
++ SYNTAX RowStatus
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "Writing invalid has the effect of deleting
++ this interface."
++ ::= { rip2IfConfEntry 8 }
++
++ rip2IfConfSrcAddress OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-create
++ STATUS current
++ DESCRIPTION
++ "The IP Address this system will use as a source
++ address on this interface. If it is a numbered
++ interface, this MUST be the same value as
++ rip2IfConfAddress. On unnumbered interfaces,
++ it must be the value of rip2IfConfAddress for
++ some interface on the system."
++ ::= { rip2IfConfEntry 9 }
++
++--4.3 Peer Table
++
++-- Peer Table
++
++-- The RIP Peer Group
++-- Implementation of this Group is Optional
++
++-- This group provides information about active peer
++-- relationships intended to assist in debugging. An
++-- active peer is a router from which a valid RIP
++-- updated has been heard in the last 180 seconds.
++
++ rip2PeerTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF Rip2PeerEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "A list of RIP Peers."
++ ::= { rip2 4 }
++
++ rip2PeerEntry OBJECT-TYPE
++ SYNTAX Rip2PeerEntry
++ MAX-ACCESS not-accessible
++ STATUS current
++ DESCRIPTION
++ "Information regarding a single routing peer."
++ INDEX { rip2PeerAddress, rip2PeerDomain }
++ ::= { rip2PeerTable 1 }
++
++ Rip2PeerEntry ::=
++ SEQUENCE {
++ rip2PeerAddress
++ IpAddress,
++ rip2PeerDomain
++ RouteTag,
++ rip2PeerLastUpdate
++ TimeTicks,
++ rip2PeerVersion
++ INTEGER,
++ rip2PeerRcvBadPackets
++ Counter32,
++ rip2PeerRcvBadRoutes
++ Counter32
++ }
++
++ rip2PeerAddress OBJECT-TYPE
++ SYNTAX IpAddress
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The IP Address that the peer is using as its source
++ address. Note that on an unnumbered link, this may
++ not be a member of any subnet on the system."
++ ::= { rip2PeerEntry 1 }
++
++ rip2PeerDomain OBJECT-TYPE
++ SYNTAX RouteTag
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The value in the Routing Domain field in RIP
++ packets received from the peer. As domain suuport
++ is deprecated, this must be zero."
++ ::= { rip2PeerEntry 2 }
++
++ rip2PeerLastUpdate OBJECT-TYPE
++ SYNTAX TimeTicks
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The value of sysUpTime when the most recent
++ RIP update was received from this system."
++ ::= { rip2PeerEntry 3 }
++
++ rip2PeerVersion OBJECT-TYPE
++ SYNTAX INTEGER ( 0..255 )
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The RIP version number in the header of the
++ last RIP packet received."
++ ::= { rip2PeerEntry 4 }
++
++ rip2PeerRcvBadPackets OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of RIP response packets from this
++ peer discarded as invalid."
++ ::= { rip2PeerEntry 5 }
++
++
++ rip2PeerRcvBadRoutes OBJECT-TYPE
++ SYNTAX Counter32
++ MAX-ACCESS read-only
++ STATUS current
++ DESCRIPTION
++ "The number of routes from this peer that were
++ ignored because the entry format was invalid."
++ ::= { rip2PeerEntry 6 }
++
++-- conformance information
++
++rip2Conformance OBJECT IDENTIFIER ::= { rip2 5 }
++
++rip2Groups OBJECT IDENTIFIER ::= { rip2Conformance 1 }
++rip2Compliances OBJECT IDENTIFIER ::= { rip2Conformance 2 }
++
++-- compliance statements
++rip2Compliance MODULE-COMPLIANCE
++ STATUS current
++ DESCRIPTION
++ "The compliance statement "
++ MODULE -- this module
++ MANDATORY-GROUPS {
++ rip2GlobalGroup,
++ rip2IfStatGroup,
++ rip2IfConfGroup,
++ rip2PeerGroup
++ }
++ GROUP rip2GlobalGroup
++ DESCRIPTION
++ "This group defines global controls for RIP-II systems."
++ GROUP rip2IfStatGroup
++ DESCRIPTION
++ "This group defines interface statistics for RIP-II systems."
++ GROUP rip2IfConfGroup
++ DESCRIPTION
++ "This group defines interface configuration for RIP-II systems."
++ GROUP rip2PeerGroup
++ DESCRIPTION
++ "This group defines peer information for RIP-II systems."
++ ::= { rip2Compliances 1 }
++
++-- units of conformance
++
++rip2GlobalGroup OBJECT-GROUP
++ OBJECTS {
++ rip2GlobalRouteChanges,
++ rip2GlobalQueries
++ }
++ STATUS current
++ DESCRIPTION
++ "This group defines global controls for RIP-II systems."
++ ::= { rip2Groups 1 }
++rip2IfStatGroup OBJECT-GROUP
++ OBJECTS {
++ rip2IfStatAddress,
++ rip2IfStatRcvBadPackets,
++ rip2IfStatRcvBadRoutes,
++ rip2IfStatSentUpdates,
++ rip2IfStatStatus
++ }
++ STATUS current
++ DESCRIPTION
++ "This group defines interface statistics for RIP-II systems."
++ ::= { rip2Groups 2 }
++rip2IfConfGroup OBJECT-GROUP
++ OBJECTS {
++ rip2IfConfAddress,
++ rip2IfConfAuthType,
++ rip2IfConfAuthKey,
++ rip2IfConfSend,
++ rip2IfConfReceive,
++ rip2IfConfDefaultMetric,
++ rip2IfConfStatus,
++ rip2IfConfSrcAddress
++ }
++ STATUS current
++ DESCRIPTION
++ "This group defines interface configuration for RIP-II systems."
++ ::= { rip2Groups 3 }
++rip2PeerGroup OBJECT-GROUP
++ OBJECTS {
++ rip2PeerAddress,
++ rip2PeerDomain,
++ rip2PeerLastUpdate,
++ rip2PeerVersion,
++ rip2PeerRcvBadPackets,
++ rip2PeerRcvBadRoutes
++ }
++ STATUS current
++ DESCRIPTION
++ "This group defines peer information for RIP-II systems."
++ ::= { rip2Groups 4 }
++END
+--- /dev/null
++++ b/mibs/SOURCE-ROUTING-MIB.txt
+@@ -0,0 +1,452 @@
++SOURCE-ROUTING-MIB DEFINITIONS ::= BEGIN
++
++IMPORTS
++ Counter, Gauge
++ FROM RFC1155-SMI
++ dot1dBridge, dot1dSr
++ FROM BRIDGE-MIB
++ OBJECT-TYPE
++ FROM RFC-1212;
++
++-- groups in the SR MIB
++
++-- dot1dSr is imported from the Bridge MIB
++
++dot1dPortPair OBJECT IDENTIFIER ::= { dot1dBridge 10 }
++
++-- the dot1dSr group
++
++-- this group is implemented by those bridges that
++-- support the source route bridging mode, including Source
++-- Routing and SRT bridges.
++
++dot1dSrPortTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF Dot1dSrPortEntry
++ ACCESS not-accessible
++ STATUS mandatory
++ DESCRIPTION
++ "A table that contains information about every
++ port that is associated with this source route
++ bridge."
++ ::= { dot1dSr 1 }
++
++dot1dSrPortEntry OBJECT-TYPE
++ SYNTAX Dot1dSrPortEntry
++ ACCESS not-accessible
++ STATUS mandatory
++ DESCRIPTION
++ "A list of information for each port of a source
++ route bridge."
++ INDEX { dot1dSrPort }
++
++ ::= { dot1dSrPortTable 1 }
++
++Dot1dSrPortEntry ::=
++ SEQUENCE {
++ dot1dSrPort
++ INTEGER,
++ dot1dSrPortHopCount
++ INTEGER,
++ dot1dSrPortLocalSegment
++ INTEGER,
++ dot1dSrPortBridgeNum
++ INTEGER,
++ dot1dSrPortTargetSegment
++ INTEGER,
++ dot1dSrPortLargestFrame
++ INTEGER,
++ dot1dSrPortSTESpanMode
++ INTEGER,
++ dot1dSrPortSpecInFrames
++ Counter,
++ dot1dSrPortSpecOutFrames
++ Counter,
++ dot1dSrPortApeInFrames
++ Counter,
++ dot1dSrPortApeOutFrames
++ Counter,
++ dot1dSrPortSteInFrames
++ Counter,
++ dot1dSrPortSteOutFrames
++ Counter,
++ dot1dSrPortSegmentMismatchDiscards
++ Counter,
++ dot1dSrPortDuplicateSegmentDiscards
++ Counter,
++ dot1dSrPortHopCountExceededDiscards
++ Counter,
++ dot1dSrPortDupLanIdOrTreeErrors
++ Counter,
++ dot1dSrPortLanIdMismatches
++ Counter
++ }
++
++dot1dSrPort OBJECT-TYPE
++ SYNTAX INTEGER (1..65535)
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The port number of the port for which this entry
++
++ contains Source Route management information."
++ ::= { dot1dSrPortEntry 1 }
++
++dot1dSrPortHopCount OBJECT-TYPE
++ SYNTAX INTEGER
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "The maximum number of routing descriptors allowed
++ in an All Paths or Spanning Tree Explorer frames."
++ ::= { dot1dSrPortEntry 2 }
++
++dot1dSrPortLocalSegment OBJECT-TYPE
++ SYNTAX INTEGER
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "The segment number that uniquely identifies the
++ segment to which this port is connected. Current
++ source routing protocols limit this value to the
++ range: 0 through 4095. (The value 0 is used by
++ some management applications for special test
++ cases.) A value of 65535 signifies that no segment
++ number is assigned to this port."
++ ::= { dot1dSrPortEntry 3 }
++
++dot1dSrPortBridgeNum OBJECT-TYPE
++ SYNTAX INTEGER
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "A bridge number uniquely identifies a bridge when
++ more than one bridge is used to span the same two
++ segments. Current source routing protocols limit
++ this value to the range: 0 through 15. A value of
++ 65535 signifies that no bridge number is assigned
++ to this bridge."
++ ::= { dot1dSrPortEntry 4 }
++
++dot1dSrPortTargetSegment OBJECT-TYPE
++ SYNTAX INTEGER
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "The segment number that corresponds to the target
++ segment this port is considered to be connected to
++ by the bridge. Current source routing protocols
++ limit this value to the range: 0 through 4095.
++
++ (The value 0 is used by some management
++ applications for special test cases.) A value of
++ 65535 signifies that no target segment is assigned
++ to this port."
++ ::= { dot1dSrPortEntry 5 }
++
++-- It would be nice if we could use ifMtu as the size of the
++-- largest frame, but we can't because ifMtu is defined to be
++-- the size that the (inter-)network layer can use which can
++-- differ from the MAC layer (especially if several layers of
++-- encapsulation are used).
++
++dot1dSrPortLargestFrame OBJECT-TYPE
++ SYNTAX INTEGER
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "The maximum size of the INFO field (LLC and
++ above) that this port can send/receive. It does
++ not include any MAC level (framing) octets. The
++ value of this object is used by this bridge to
++ determine whether a modification of the
++ LargestFrame (LF, see [14]) field of the Routing
++ Control field of the Routing Information Field is
++ necessary.
++
++ 64 valid values are defined by the IEEE 802.5M SRT
++ Addendum: 516, 635, 754, 873, 993, 1112, 1231,
++ 1350, 1470, 1542, 1615, 1688, 1761, 1833, 1906,
++ 1979, 2052, 2345, 2638, 2932, 3225, 3518, 3812,
++ 4105, 4399, 4865, 5331, 5798, 6264, 6730, 7197,
++ 7663, 8130, 8539, 8949, 9358, 9768, 10178, 10587,
++ 10997, 11407, 12199, 12992, 13785, 14578, 15370,
++ 16163, 16956, 17749, 20730, 23711, 26693, 29674,
++ 32655, 35637, 38618, 41600, 44591, 47583, 50575,
++ 53567, 56559, 59551, and 65535.
++
++ An illegal value will not be accepted by the
++ bridge."
++ ::= { dot1dSrPortEntry 6 }
++
++dot1dSrPortSTESpanMode OBJECT-TYPE
++ SYNTAX INTEGER {
++ auto-span(1),
++ disabled(2),
++ forced(3)
++ }
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "Determines how this port behaves when presented
++ with a Spanning Tree Explorer frame. The value
++ 'disabled(2)' indicates that the port will not
++ accept or send Spanning Tree Explorer packets; any
++ STE packets received will be silently discarded.
++ The value 'forced(3)' indicates the port will
++ always accept and propagate Spanning Tree Explorer
++ frames. This allows a manually configured
++ Spanning Tree for this class of packet to be
++ configured. Note that unlike transparent
++ bridging, this is not catastrophic to the network
++ if there are loops. The value 'auto-span(1)' can
++ only be returned by a bridge that both implements
++ the Spanning Tree Protocol and has use of the
++ protocol enabled on this port. The behavior of the
++ port for Spanning Tree Explorer frames is
++ determined by the state of dot1dStpPortState. If
++ the port is in the 'forwarding' state, the frame
++ will be accepted or propagated. Otherwise, it
++ will be silently discarded."
++ ::= { dot1dSrPortEntry 7 }
++
++dot1dSrPortSpecInFrames OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of Specifically Routed frames, also
++ referred to as Source Routed Frames, that have
++ been received from this port's segment."
++ ::= { dot1dSrPortEntry 8 }
++
++dot1dSrPortSpecOutFrames OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of Specifically Routed frames, also
++ referred to as Source Routed Frames, that this
++ port has transmitted on its segment."
++ ::= { dot1dSrPortEntry 9 }
++
++dot1dSrPortApeInFrames OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of All Paths Explorer frames, also
++ referred to as All Routes Explorer frames, that
++ have been received by this port from its segment."
++ ::= { dot1dSrPortEntry 10 }
++
++dot1dSrPortApeOutFrames OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of all Paths Explorer Frames, also
++ referred to as All Routes Explorer frames, that
++ have been transmitted by this port on its
++ segment."
++ ::= { dot1dSrPortEntry 11 }
++
++dot1dSrPortSteInFrames OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of spanning tree explorer frames that
++ have been received by this port from its segment."
++ ::= { dot1dSrPortEntry 12 }
++
++dot1dSrPortSteOutFrames OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of spanning tree explorer frames that
++ have been transmitted by this port on its
++ segment."
++ ::= { dot1dSrPortEntry 13 }
++
++dot1dSrPortSegmentMismatchDiscards OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of explorer frames that have been
++ discarded by this port because the routing
++ descriptor field contained an invalid adjacent
++ segment value."
++ ::= { dot1dSrPortEntry 14 }
++
++dot1dSrPortDuplicateSegmentDiscards OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of frames that have been discarded by
++ this port because the routing descriptor field
++ contained a duplicate segment identifier."
++ ::= { dot1dSrPortEntry 15 }
++
++dot1dSrPortHopCountExceededDiscards OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of explorer frames that have been
++ discarded by this port because the Routing
++ Information Field has exceeded the maximum route
++ descriptor length."
++ ::= { dot1dSrPortEntry 16 }
++
++dot1dSrPortDupLanIdOrTreeErrors OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of duplicate LAN IDs or Tree errors.
++ This helps in detection of problems in networks
++ containing older IBM Source Routing Bridges."
++ ::= { dot1dSrPortEntry 17 }
++
++dot1dSrPortLanIdMismatches OBJECT-TYPE
++ SYNTAX Counter
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The number of ARE and STE frames that were
++ discarded because the last LAN ID in the routing
++ information field did not equal the LAN-in ID.
++ This error can occur in implementations which do
++ only a LAN-in ID and Bridge Number check instead
++ of a LAN-in ID, Bridge Number, and LAN-out ID
++ check before they forward broadcast frames."
++ ::= { dot1dSrPortEntry 18 }
++
++-- scalar object in dot1dSr
++
++dot1dSrBridgeLfMode OBJECT-TYPE
++ SYNTAX INTEGER {
++ mode3(1),
++ mode6(2)
++ }
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "Indicates whether the bridge operates using older
++ 3 bit length negotiation fields or the newer 6 bit
++ length field in its RIF."
++ ::= { dot1dSr 2 }
++
++-- The Port-Pair Database
++
++-- Implementation of this group is optional.
++
++-- This group is implemented by those bridges that support
++-- the direct multiport model of the source route bridging
++-- mode as defined in the IEEE 802.5 SRT Addendum to
++-- 802.1d.
++
++-- Bridges implementing this group may report 65535 for
++-- dot1dSrPortBridgeNumber and dot1dSrPortTargetSegment,
++-- indicating that those objects are not applicable.
++
++dot1dPortPairTableSize OBJECT-TYPE
++ SYNTAX Gauge
++ ACCESS read-only
++ STATUS mandatory
++ DESCRIPTION
++ "The total number of entries in the Bridge Port
++ Pair Database."
++ ::= { dot1dPortPair 1 }
++
++-- the Bridge Port-Pair table
++
++-- this table represents port pairs within a bridge forming
++-- a unique bridge path, as defined in the IEEE 802.5M SRT
++-- Addendum.
++
++dot1dPortPairTable OBJECT-TYPE
++ SYNTAX SEQUENCE OF Dot1dPortPairEntry
++ ACCESS not-accessible
++ STATUS mandatory
++ DESCRIPTION
++ "A table that contains information about every
++
++ port pair database entity associated with this
++ source routing bridge."
++ ::= { dot1dPortPair 2 }
++
++dot1dPortPairEntry OBJECT-TYPE
++ SYNTAX Dot1dPortPairEntry
++ ACCESS not-accessible
++ STATUS mandatory
++ DESCRIPTION
++ "A list of information for each port pair entity
++ of a bridge."
++ INDEX { dot1dPortPairLowPort, dot1dPortPairHighPort }
++ ::= { dot1dPortPairTable 1 }
++
++Dot1dPortPairEntry ::=
++ SEQUENCE {
++ dot1dPortPairLowPort
++ INTEGER,
++ dot1dPortPairHighPort
++ INTEGER,
++ dot1dPortPairBridgeNum
++ INTEGER,
++ dot1dPortPairBridgeState
++ INTEGER
++ }
++
++dot1dPortPairLowPort OBJECT-TYPE
++ SYNTAX INTEGER (1..65535)
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "The port number of the lower numbered port for
++ which this entry contains port pair database
++ information."
++ ::= { dot1dPortPairEntry 1 }
++
++dot1dPortPairHighPort OBJECT-TYPE
++ SYNTAX INTEGER (1..65535)
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "The port number of the higher numbered port for
++ which this entry contains port pair database
++ information."
++ ::= { dot1dPortPairEntry 2 }
++
++dot1dPortPairBridgeNum OBJECT-TYPE
++ SYNTAX INTEGER
++
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "A bridge number that uniquely identifies the path
++ provided by this source routing bridge between the
++ segments connected to dot1dPortPairLowPort and
++ dot1dPortPairHighPort. The purpose of bridge
++ number is to disambiguate between multiple paths
++ connecting the same two LANs."
++ ::= { dot1dPortPairEntry 3 }
++
++dot1dPortPairBridgeState OBJECT-TYPE
++ SYNTAX INTEGER {
++ enabled(1),
++ disabled(2),
++ invalid(3)
++ }
++ ACCESS read-write
++ STATUS mandatory
++ DESCRIPTION
++ "The state of dot1dPortPairBridgeNum. Writing
++ 'invalid(3)' to this object removes the
++ corresponding entry."
++ ::= { dot1dPortPairEntry 4 }
++
++END
diff --git a/package/network/utils/net-snmp/patches/160-no_ldconfig.patch b/package/network/utils/net-snmp/patches/160-no_ldconfig.patch
new file mode 100644
index 0000000..d9de73e
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/160-no_ldconfig.patch
@@ -0,0 +1,11 @@
+--- a/configure
++++ b/configure
+@@ -15097,7 +15097,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
++ finish_cmds=''
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
diff --git a/package/network/utils/net-snmp/patches/170-ldflags.patch b/package/network/utils/net-snmp/patches/170-ldflags.patch
new file mode 100644
index 0000000..dd1b9fe
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/170-ldflags.patch
@@ -0,0 +1,11 @@
+--- a/Makefile.top
++++ b/Makefile.top
+@@ -87,7 +87,7 @@ LIBCURRENT = 35
+ LIBAGE = 0
+ LIBREVISION = 0
+
+-LIB_LD_CMD = $(LIBTOOL) --mode=link $(LINKCC) $(CFLAGS) -rpath $(libdir) -version-info $(LIBCURRENT):$(LIBREVISION):$(LIBAGE) -o
++LIB_LD_CMD = $(LIBTOOL) --mode=link $(LINKCC) $(CFLAGS) -rpath $(libdir) $(LDFLAGS) -version-info $(LIBCURRENT):$(LIBREVISION):$(LIBAGE) -o
+ LIB_EXTENSION = la
+ LIB_VERSION =
+ LIB_LDCONFIG_CMD = $(LIBTOOL) --mode=finish $(INSTALL_PREFIX)$(libdir)
diff --git a/package/network/utils/net-snmp/patches/750-ieee802dot11.patch b/package/network/utils/net-snmp/patches/750-ieee802dot11.patch
new file mode 100644
index 0000000..a3c5c0a
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/750-ieee802dot11.patch
@@ -0,0 +1,6156 @@
+--- /dev/null
++++ b/agent/mibgroup/ieee802dot11.c
+@@ -0,0 +1,4915 @@
++/****************************************************************************
++* *
++* File Name: ieee802dot11.c *
++* Used By: *
++* *
++* Operating System: *
++* Purpose: *
++* *
++* Comments: *
++* *
++* Author: Larry Simmons *
++* lsimmons@avantcom.com *
++* www.avantcom.com *
++* *
++* Creation Date: 09/02/03 *
++* *
++* Ver Date Inits Modification *
++* ----- -------- ----- ------------ *
++* 0.0.1 09/02/03 LRS created *
++* 0.0.2 09/24/03 LRS wouldn't build after fresh ./configure *
++****************************************************************************/
++/****************************************************************************
++* Includes *
++****************************************************************************/
++#include <net-snmp/net-snmp-config.h>
++#include <net-snmp/net-snmp-includes.h>
++#include <net-snmp/agent/net-snmp-agent-includes.h>
++#include "ieee802dot11.h"
++#include "iwlib.h"
++
++/****************************************************************************
++* Defines *
++****************************************************************************/
++#define DISPLAYWIEXT // display wireless ext info
++#define TABLE_SIZE 1
++//#define MINLOADFREQ 15 // min reload frequency in seconds
++#define MINLOADFREQ 5 // min reload frequency in seconds // for testing
++#define PROC_NET_DEV "/proc/net/dev"
++#define PROC_NET_WIRELESS "/proc/net/wireless"
++
++#ifndef UCHAR
++ typedef unsigned char UCHAR;
++#endif
++
++/****************************************************************************
++* Private Functions *
++****************************************************************************/
++static void loadTables();
++static void loadWiExt ( int, char *, struct wireless_info * );
++static void load80211Structs ( int, char *, struct wireless_info * );
++static void initStructs();
++
++// Wireless Extensions Specific Functions
++static void loadWiExtTo80211Structs ( int, char *, struct wireless_info * );
++static void displayWiExt ( struct wireless_info );
++
++// Linked List Functions
++static void addList ( char *, char *, int );
++static void initLists(); // initialize all the linked lists
++static void flushLists(); // flush all the linked lists
++static void flushList ( char * ); // flush a single linked list
++
++// Utility Functions
++static int openSocket ( void );
++static int mWatt2dbm ( int );
++static char *htob ( char * );
++static int hasChanged ( char *, int );
++
++/****************************************************************************
++* Private Variables *
++****************************************************************************/
++static unsigned long lastLoad = 0; // ET in secs at last table load
++
++static struct avNode *lastNode, *newNode, *np;
++
++/****************************************************************************
++* External Functions *
++****************************************************************************/
++
++/****************************************************************************
++* ieee802dot11_variables_oid: *
++* this is the top level oid that we want to register under. This *
++* is essentially a prefix, with the suffix appearing in the *
++* variable below. *
++****************************************************************************/
++oid ieee802dot11_variables_oid[] = { 1,2,840,10036 };
++
++/****************************************************************************
++* variable7 ieee802dot11_variables: *
++* this variable defines function callbacks and type return information *
++* for the ieee802dot11 mib section *
++****************************************************************************/
++struct variable7 ieee802dot11_variables[] = {
++/* magic number , variable type , ro/rw , callback fn , L, oidsuffix */
++#define DOT11STATIONID 3
++ { DOT11STATIONID , ASN_OCTET_STR , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,1 } },
++#define DOT11MEDIUMOCCUPANCYLIMIT 4
++ { DOT11MEDIUMOCCUPANCYLIMIT, ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,2 } },
++#define DOT11CFPOLLABLE 5
++ { DOT11CFPOLLABLE , ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,3 } },
++#define DOT11CFPPERIOD 6
++ { DOT11CFPPERIOD , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,4 } },
++#define DOT11CFPMAXDURATION 7
++ { DOT11CFPMAXDURATION , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,5 } },
++#define DOT11AUTHENTICATIONRESPONSETIMEOUT 8
++ { DOT11AUTHENTICATIONRESPONSETIMEOUT, ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,6 } },
++#define DOT11PRIVACYOPTIONIMPLEMENTED 9
++ { DOT11PRIVACYOPTIONIMPLEMENTED, ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,7 } },
++#define DOT11POWERMANAGEMENTMODE 10
++ { DOT11POWERMANAGEMENTMODE, ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,8 } },
++#define DOT11DESIREDSSID 11
++ { DOT11DESIREDSSID , ASN_OCTET_STR , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,9 } },
++#define DOT11DESIREDBSSTYPE 12
++ { DOT11DESIREDBSSTYPE , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,10 } },
++#define DOT11OPERATIONALRATESET 13
++ { DOT11OPERATIONALRATESET, ASN_OCTET_STR , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,11 } },
++#define DOT11BEACONPERIOD 14
++ { DOT11BEACONPERIOD , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,12 } },
++#define DOT11DTIMPERIOD 15
++ { DOT11DTIMPERIOD , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,13 } },
++#define DOT11ASSOCIATIONRESPONSETIMEOUT 16
++ { DOT11ASSOCIATIONRESPONSETIMEOUT, ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,14 } },
++#define DOT11DISASSOCIATEREASON 17
++ { DOT11DISASSOCIATEREASON, ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,15 } },
++#define DOT11DISASSOCIATESTATION 18
++ { DOT11DISASSOCIATESTATION, ASN_OCTET_STR , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,16 } },
++#define DOT11DEAUTHENTICATEREASON 19
++ { DOT11DEAUTHENTICATEREASON, ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,17 } },
++#define DOT11DEAUTHENTICATESTATION 20
++ { DOT11DEAUTHENTICATESTATION, ASN_OCTET_STR , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,18 } },
++#define DOT11AUTHENTICATEFAILSTATUS 21
++ { DOT11AUTHENTICATEFAILSTATUS, ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,19 } },
++#define DOT11AUTHENTICATEFAILSTATION 22
++ { DOT11AUTHENTICATEFAILSTATION, ASN_OCTET_STR , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,20 } },
++
++#define DOT11AUTHENTICATIONALGORITHM 26
++ { DOT11AUTHENTICATIONALGORITHM, ASN_INTEGER , RONLY , var_dot11AuthenticationAlgorithmsTable, 4, { 1,2,1,2 } },
++#define DOT11AUTHENTICATIONALGORITHMSENABLE 27
++ { DOT11AUTHENTICATIONALGORITHMSENABLE, ASN_INTEGER , RWRITE, var_dot11AuthenticationAlgorithmsTable, 4, { 1,2,1,3 } },
++
++#define DOT11WEPDEFAULTKEYVALUE 31
++ { DOT11WEPDEFAULTKEYVALUE, ASN_OCTET_STR , RWRITE, var_dot11WEPDefaultKeysTable, 4, { 1,3,1,2 } },
++
++#define DOT11WEPKEYMAPPINGADDRESS 35
++ { DOT11WEPKEYMAPPINGADDRESS, ASN_OCTET_STR , RWRITE, var_dot11WEPKeyMappingsTable, 4, { 1,4,1,2 } },
++#define DOT11WEPKEYMAPPINGWEPON 36
++ { DOT11WEPKEYMAPPINGWEPON, ASN_INTEGER , RWRITE, var_dot11WEPKeyMappingsTable, 4, { 1,4,1,3 } },
++#define DOT11WEPKEYMAPPINGVALUE 37
++ { DOT11WEPKEYMAPPINGVALUE, ASN_OCTET_STR , RWRITE, var_dot11WEPKeyMappingsTable, 4, { 1,4,1,4 } },
++#define DOT11WEPKEYMAPPINGSTATUS 38
++ { DOT11WEPKEYMAPPINGSTATUS, ASN_INTEGER , RWRITE, var_dot11WEPKeyMappingsTable, 4, { 1,4,1,5 } },
++
++#define DOT11PRIVACYINVOKED 41
++ { DOT11PRIVACYINVOKED , ASN_INTEGER , RWRITE, var_dot11PrivacyTable, 4, { 1,5,1,1 } },
++#define DOT11WEPDEFAULTKEYID 42
++ { DOT11WEPDEFAULTKEYID, ASN_INTEGER , RWRITE, var_dot11PrivacyTable, 4, { 1,5,1,2 } },
++#define DOT11WEPKEYMAPPINGLENGTH 43
++ { DOT11WEPKEYMAPPINGLENGTH, ASN_INTEGER , RWRITE, var_dot11PrivacyTable, 4, { 1,5,1,3 } },
++#define DOT11EXCLUDEUNENCRYPTED 44
++ { DOT11EXCLUDEUNENCRYPTED, ASN_INTEGER , RWRITE, var_dot11PrivacyTable, 4, { 1,5,1,4 } },
++#define DOT11WEPICVERRORCOUNT 45
++ { DOT11WEPICVERRORCOUNT, ASN_COUNTER , RONLY , var_dot11PrivacyTable, 4, { 1,5,1,5 } },
++#define DOT11WEPEXCLUDEDCOUNT 46
++ { DOT11WEPEXCLUDEDCOUNT, ASN_COUNTER , RONLY , var_dot11PrivacyTable, 4, { 1,5,1,6 } },
++
++#define DOT11MACADDRESS 49
++ { DOT11MACADDRESS , ASN_OCTET_STR , RONLY , var_dot11OperationTable, 4, { 2,1,1,1 } },
++#define DOT11RTSTHRESHOLD 50
++ { DOT11RTSTHRESHOLD , ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,2 } },
++#define DOT11SHORTRETRYLIMIT 51
++ { DOT11SHORTRETRYLIMIT, ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,3 } },
++#define DOT11LONGRETRYLIMIT 52
++ { DOT11LONGRETRYLIMIT , ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,4 } },
++#define DOT11FRAGMENTATIONTHRESHOLD 53
++ { DOT11FRAGMENTATIONTHRESHOLD, ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,5 } },
++#define DOT11MAXTRANSMITMSDULIFETIME 54
++ { DOT11MAXTRANSMITMSDULIFETIME, ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,6 } },
++#define DOT11MAXRECEIVELIFETIME 55
++ { DOT11MAXRECEIVELIFETIME, ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,7 } },
++#define DOT11MANUFACTURERID 56
++ { DOT11MANUFACTURERID , ASN_OCTET_STR , RONLY , var_dot11OperationTable, 4, { 2,1,1,8 } },
++#define DOT11PRODUCTID 57
++ { DOT11PRODUCTID , ASN_OCTET_STR , RONLY , var_dot11OperationTable, 4, { 2,1,1,9 } },
++
++#define DOT11TRANSMITTEDFRAGMENTCOUNT 60
++ { DOT11TRANSMITTEDFRAGMENTCOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,1 } },
++#define DOT11MULTICASTTRANSMITTEDFRAMECOUNT 61
++ { DOT11MULTICASTTRANSMITTEDFRAMECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,2 } },
++#define DOT11FAILEDCOUNT 62
++ { DOT11FAILEDCOUNT , ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,3 } },
++#define DOT11RETRYCOUNT 63
++ { DOT11RETRYCOUNT , ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,4 } },
++#define DOT11MULTIPLERETRYCOUNT 64
++ { DOT11MULTIPLERETRYCOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,5 } },
++#define DOT11FRAMEDUPLICATECOUNT 65
++ { DOT11FRAMEDUPLICATECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,6 } },
++#define DOT11RTSSUCCESSCOUNT 66
++ { DOT11RTSSUCCESSCOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,7 } },
++#define DOT11RTSFAILURECOUNT 67
++ { DOT11RTSFAILURECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,8 } },
++#define DOT11ACKFAILURECOUNT 68
++ { DOT11ACKFAILURECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,9 } },
++#define DOT11RECEIVEDFRAGMENTCOUNT 69
++ { DOT11RECEIVEDFRAGMENTCOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,10 } },
++#define DOT11MULTICASTRECEIVEDFRAMECOUNT 70
++ { DOT11MULTICASTRECEIVEDFRAMECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,11 } },
++#define DOT11FCSERRORCOUNT 71
++ { DOT11FCSERRORCOUNT , ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,12 } },
++#define DOT11TRANSMITTEDFRAMECOUNT 72
++ { DOT11TRANSMITTEDFRAMECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,13 } },
++#define DOT11WEPUNDECRYPTABLECOUNT 73
++ { DOT11WEPUNDECRYPTABLECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,14 } },
++
++#define DOT11ADDRESS 77
++ { DOT11ADDRESS , ASN_OCTET_STR , RWRITE, var_dot11GroupAddressesTable, 4, { 2,3,1,2 } },
++#define DOT11GROUPADDRESSESSTATUS 78
++ { DOT11GROUPADDRESSESSTATUS, ASN_INTEGER , RWRITE, var_dot11GroupAddressesTable, 4, { 2,3,1,3 } },
++
++#define DOT11RESOURCETYPEIDNAME 79
++ { DOT11RESOURCETYPEIDNAME, ASN_OCTET_STR , RONLY , var_ieee802dot11, 3, { 3,1,1 } },
++#define DOT11MANUFACTUREROUI 82
++ { DOT11MANUFACTUREROUI, ASN_OCTET_STR , RONLY , var_dot11ResourceInfoTable, 5, { 3,1,2,1,1 } },
++#define DOT11MANUFACTURERNAME 83
++ { DOT11MANUFACTURERNAME, ASN_OCTET_STR , RONLY , var_dot11ResourceInfoTable, 5, { 3,1,2,1,2 } },
++#define DOT11MANUFACTURERPRODUCTNAME 84
++ { DOT11MANUFACTURERPRODUCTNAME, ASN_OCTET_STR , RONLY , var_dot11ResourceInfoTable, 5, { 3,1,2,1,3 } },
++#define DOT11MANUFACTURERPRODUCTVERSION 85
++ { DOT11MANUFACTURERPRODUCTVERSION, ASN_OCTET_STR , RONLY , var_dot11ResourceInfoTable, 5, { 3,1,2,1,4 } },
++
++#define DOT11PHYTYPE 88
++ { DOT11PHYTYPE , ASN_INTEGER , RONLY , var_dot11PhyOperationTable, 4, { 4,1,1,1 } },
++#define DOT11CURRENTREGDOMAIN 89
++ { DOT11CURRENTREGDOMAIN, ASN_INTEGER , RWRITE, var_dot11PhyOperationTable, 4, { 4,1,1,2 } },
++#define DOT11TEMPTYPE 90
++ { DOT11TEMPTYPE , ASN_INTEGER , RONLY , var_dot11PhyOperationTable, 4, { 4,1,1,3 } },
++#define DOT11CURRENTTXANTENNA 93
++ { DOT11CURRENTTXANTENNA, ASN_INTEGER , RWRITE, var_dot11PhyAntennaTable, 4, { 4,2,1,1 } },
++#define DOT11DIVERSITYSUPPORT 94
++ { DOT11DIVERSITYSUPPORT, ASN_INTEGER , RONLY , var_dot11PhyAntennaTable, 4, { 4,2,1,2 } },
++#define DOT11CURRENTRXANTENNA 95
++ { DOT11CURRENTRXANTENNA, ASN_INTEGER , RWRITE, var_dot11PhyAntennaTable, 4, { 4,2,1,3 } },
++#define DOT11NUMBERSUPPORTEDPOWERLEVELS 98
++ { DOT11NUMBERSUPPORTEDPOWERLEVELS, ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,1 } },
++#define DOT11TXPOWERLEVEL1 99
++ { DOT11TXPOWERLEVEL1 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,2 } },
++#define DOT11TXPOWERLEVEL2 100
++ { DOT11TXPOWERLEVEL2 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,3 } },
++#define DOT11TXPOWERLEVEL3 101
++ { DOT11TXPOWERLEVEL3 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,4 } },
++#define DOT11TXPOWERLEVEL4 102
++ { DOT11TXPOWERLEVEL4 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,5 } },
++#define DOT11TXPOWERLEVEL5 103
++ { DOT11TXPOWERLEVEL5 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,6 } },
++#define DOT11TXPOWERLEVEL6 104
++ { DOT11TXPOWERLEVEL6 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,7 } },
++#define DOT11TXPOWERLEVEL7 105
++ { DOT11TXPOWERLEVEL7 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,8 } },
++#define DOT11TXPOWERLEVEL8 106
++ { DOT11TXPOWERLEVEL8 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,9 } },
++#define DOT11CURRENTTXPOWERLEVEL 107
++ { DOT11CURRENTTXPOWERLEVEL, ASN_INTEGER , RWRITE, var_dot11PhyTxPowerTable, 4, { 4,3,1,10 } },
++
++#define DOT11HOPTIME 110
++ { DOT11HOPTIME , ASN_INTEGER , RONLY , var_dot11PhyFHSSTable, 4, { 4,4,1,1 } },
++#define DOT11CURRENTCHANNELNUMBER 111
++ { DOT11CURRENTCHANNELNUMBER, ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,2 } },
++#define DOT11MAXDWELLTIME 112
++ { DOT11MAXDWELLTIME , ASN_INTEGER , RONLY , var_dot11PhyFHSSTable, 4, { 4,4,1,3 } },
++#define DOT11CURRENTDWELLTIME 113
++ { DOT11CURRENTDWELLTIME, ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,4 } },
++#define DOT11CURRENTSET 114
++ { DOT11CURRENTSET , ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,5 } },
++#define DOT11CURRENTPATTERN 115
++ { DOT11CURRENTPATTERN , ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,6 } },
++#define DOT11CURRENTINDEX 116
++ { DOT11CURRENTINDEX , ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,7 } },
++
++#define DOT11CURRENTCHANNEL 119
++ { DOT11CURRENTCHANNEL , ASN_INTEGER , RWRITE, var_dot11PhyDSSSTable, 4, { 4,5,1,1 } },
++#define DOT11CCAMODESUPPORTED 120
++ { DOT11CCAMODESUPPORTED, ASN_INTEGER , RONLY , var_dot11PhyDSSSTable, 4, { 4,5,1,2 } },
++#define DOT11CURRENTCCAMODE 121
++ { DOT11CURRENTCCAMODE , ASN_INTEGER , RWRITE, var_dot11PhyDSSSTable, 4, { 4,5,1,3 } },
++#define DOT11EDTHRESHOLD 122
++ { DOT11EDTHRESHOLD , ASN_INTEGER , RWRITE, var_dot11PhyDSSSTable, 4, { 4,5,1,4 } },
++
++#define DOT11CCAWATCHDOGTIMERMAX 125
++ { DOT11CCAWATCHDOGTIMERMAX, ASN_INTEGER , RWRITE, var_dot11PhyIRTable, 4, { 4,6,1,1 } },
++#define DOT11CCAWATCHDOGCOUNTMAX 126
++ { DOT11CCAWATCHDOGCOUNTMAX, ASN_INTEGER , RWRITE, var_dot11PhyIRTable, 4, { 4,6,1,2 } },
++#define DOT11CCAWATCHDOGTIMERMIN 127
++ { DOT11CCAWATCHDOGTIMERMIN, ASN_INTEGER , RWRITE, var_dot11PhyIRTable, 4, { 4,6,1,3 } },
++#define DOT11CCAWATCHDOGCOUNTMIN 128
++ { DOT11CCAWATCHDOGCOUNTMIN, ASN_INTEGER , RWRITE, var_dot11PhyIRTable, 4, { 4,6,1,4 } },
++
++#define DOT11REGDOMAINSSUPPORTVALUE 132
++ { DOT11REGDOMAINSSUPPORTVALUE, ASN_INTEGER , RONLY , var_dot11RegDomainsSupportedTable, 4, { 4,7,1,2 } },
++
++#define DOT11SUPPORTEDTXANTENNA 136
++ { DOT11SUPPORTEDTXANTENNA, ASN_INTEGER , RWRITE, var_dot11AntennasListTable, 4, { 4,8,1,2 } },
++#define DOT11SUPPORTEDRXANTENNA 137
++ { DOT11SUPPORTEDRXANTENNA, ASN_INTEGER , RWRITE, var_dot11AntennasListTable, 4, { 4,8,1,3 } },
++#define DOT11DIVERSITYSELECTIONRX 138
++ { DOT11DIVERSITYSELECTIONRX, ASN_INTEGER , RWRITE, var_dot11AntennasListTable, 4, { 4,8,1,4 } },
++
++#define DOT11SUPPORTEDDATARATESTXVALUE 142
++ { DOT11SUPPORTEDDATARATESTXVALUE, ASN_INTEGER , RONLY , var_dot11SupportedDataRatesTxTable, 4, { 4,9,1,2 } },
++
++#define DOT11SUPPORTEDDATARATESRXVALUE 146
++ { DOT11SUPPORTEDDATARATESRXVALUE, ASN_INTEGER , RONLY , var_dot11SupportedDataRatesRxTable, 4, { 4,10,1,2 } },
++};
++// ( L = length of the oidsuffix )
++
++/****************************************************************************
++* *
++* init_ieee802dot11() - perform any required initialization *
++* *
++****************************************************************************/
++void init_ieee802dot11 ( void ) {
++
++ /* register ourselves with the agent to handle our mib tree */
++ REGISTER_MIB("ieee802dot11", ieee802dot11_variables, variable7,
++ ieee802dot11_variables_oid);
++
++ initLists();
++}
++
++/****************************************************************************
++* *
++* shutdown_ieee802dot11() - perform any required cleanup @ shutdown *
++* *
++****************************************************************************/
++void shutdown_ieee802dot11 ( void )
++{
++ flushLists();
++}
++
++/****************************************************************************
++* *
++* var_ieee802dot11() - *
++* *
++****************************************************************************/
++unsigned char *
++var_ieee802dot11 ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method)
++{
++ loadTables();
++
++ if ( header_generic ( vp, name, length, exact,var_len,write_method )
++ == MATCH_FAILED )
++ return NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11RESOURCETYPEIDNAME:
++ if ( !haveResourceTypeIDName )
++ return NULL;
++ *var_len = strlen ( resourceTypeIDName );
++ return ( UCHAR * ) resourceTypeIDName;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11StationConfigTable() - return a variable value from the table *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11StationConfigTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++ static char MACWork[17];
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &scList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ sc = ( struct scTbl_data * ) np->data;
++ rName[vp->namelen] = sc->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++
++ switch ( vp->magic ) { // found requested OID, now check for requested variable
++ case DOT11STATIONID:
++ if ( sc->haveStationID ) found = TRUE; break;
++ case DOT11MEDIUMOCCUPANCYLIMIT:
++ if ( sc->haveMediumOccupancyLimit ) found = TRUE; break;
++ case DOT11CFPOLLABLE:
++ if ( sc->haveCFPPollable ) found = TRUE; break;
++ case DOT11CFPPERIOD:
++ if ( sc->haveCFPPeriod ) found = TRUE; break;
++ case DOT11CFPMAXDURATION:
++ if ( sc->haveMaxDuration ) found = TRUE; break;
++ case DOT11AUTHENTICATIONRESPONSETIMEOUT:
++ if ( sc->haveAuthenticationResponseTimeOut ) found = TRUE; break;
++ case DOT11PRIVACYOPTIONIMPLEMENTED:
++ if ( sc->havePrivacyOptionImplemented ) found = TRUE; break;
++ case DOT11POWERMANAGEMENTMODE:
++ if ( sc->havePowerManagementMode ) found = TRUE; break;
++ case DOT11DESIREDSSID:
++ if ( sc->haveDesiredSSID ) found = TRUE; break;
++ case DOT11DESIREDBSSTYPE:
++ if ( sc->haveDesiredBSSType ) found = TRUE; break;
++ case DOT11OPERATIONALRATESET:
++ if ( sc->haveOperationalRateSet ) found = TRUE; break;
++ case DOT11BEACONPERIOD:
++ if ( sc->haveBeaconPeriod ) found = TRUE; break;
++ case DOT11DTIMPERIOD:
++ if ( sc->haveDTIMPeriod ) found = TRUE; break;
++ case DOT11ASSOCIATIONRESPONSETIMEOUT:
++ if ( sc->haveAssociationResponseTimeOut ) found = TRUE; break;
++ case DOT11DISASSOCIATEREASON:
++ if ( sc->disAssociationReason ) found = TRUE; break;
++ case DOT11DISASSOCIATESTATION:
++ if ( sc->haveDisAssociationStation ) found = TRUE; break;
++ case DOT11DEAUTHENTICATEREASON:
++ if ( sc->deAuthenticationReason ) found = TRUE; break;
++ case DOT11DEAUTHENTICATESTATION:
++ if ( sc->haveDeAuthenticationStation ) found = TRUE; break;
++ case DOT11AUTHENTICATEFAILSTATUS:
++ if ( sc->authenticateFailStatus ) found = TRUE; break;
++ case DOT11AUTHENTICATEFAILSTATION:
++ if ( sc->haveAuthenticateFailStation ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11STATIONID:
++// *write_method = write_dot11StationID;
++ MACWork[ 0] = sc->stationID [ 0];
++ MACWork[ 1] = sc->stationID [ 1];
++ MACWork[ 2] = sc->stationID [ 3];
++ MACWork[ 3] = sc->stationID [ 4];
++ MACWork[ 4] = sc->stationID [ 6];
++ MACWork[ 5] = sc->stationID [ 7];
++ MACWork[ 6] = sc->stationID [ 9];
++ MACWork[ 7] = sc->stationID [10];
++ MACWork[ 8] = sc->stationID [12];
++ MACWork[ 9] = sc->stationID [13];
++ MACWork[10] = sc->stationID [15];
++ MACWork[11] = sc->stationID [16];
++ MACWork[12] = '\0';
++ *var_len = 6;
++ return ( UCHAR * ) htob ( MACWork );
++
++ case DOT11MEDIUMOCCUPANCYLIMIT:
++// *write_method = write_dot11MediumOccupancyLimit;
++ sc->mediumOccupancyLimit = 5;
++ return ( UCHAR * ) &sc->mediumOccupancyLimit;
++
++ case DOT11CFPOLLABLE:
++ return ( UCHAR * ) &sc->CFPPollable;
++
++ case DOT11CFPPERIOD:
++// *write_method = write_dot11CFPPeriod;
++ return ( UCHAR * ) &sc->CFPPeriod;
++
++ case DOT11CFPMAXDURATION:
++// *write_method = write_dot11CFPMaxDuration;
++ return ( UCHAR * ) &sc->maxDuration;
++
++ case DOT11AUTHENTICATIONRESPONSETIMEOUT:
++// *write_method = write_dot11AuthenticationResponseTimeOut;
++ return ( UCHAR * ) &sc->authenticationResponseTimeOut;
++
++ case DOT11PRIVACYOPTIONIMPLEMENTED:
++ return ( UCHAR * ) &sc->privacyOptionImplemented;
++
++ case DOT11POWERMANAGEMENTMODE:
++// *write_method = write_dot11PowerManagementMode;
++ return ( UCHAR * ) &sc->powerManagementMode;
++
++ case DOT11DESIREDSSID:
++// *write_method = write_dot11DesiredSSID;
++ *var_len = strlen ( sc->desiredSSID );
++ return ( UCHAR * ) sc->desiredSSID;
++
++ case DOT11DESIREDBSSTYPE:
++// *write_method = write_dot11DesiredBSSType;
++ return ( UCHAR * ) &sc->desiredBSSType;
++
++ case DOT11OPERATIONALRATESET:
++// *write_method = write_dot11OperationalRateSet;
++ *var_len = strlen ( sc->operationalRateSet );
++ return ( UCHAR * ) sc->operationalRateSet;
++
++ case DOT11BEACONPERIOD:
++// *write_method = write_dot11BeaconPeriod;
++ return ( UCHAR * ) &sc->beaconPeriod;
++
++ case DOT11DTIMPERIOD:
++// *write_method = write_dot11DTIMPeriod;
++ return ( UCHAR * ) &sc->DTIMPeriod;
++
++ case DOT11ASSOCIATIONRESPONSETIMEOUT:
++// *write_method = write_dot11AssociationResponseTimeOut;
++ return ( UCHAR * ) &sc->associationResponseTimeOut;
++
++ case DOT11DISASSOCIATEREASON:
++ return ( UCHAR * ) &sc->disAssociationReason;
++
++ case DOT11DISASSOCIATESTATION:
++ MACWork[ 0] = sc->disAssociationStation[ 0];
++ MACWork[ 1] = sc->disAssociationStation[ 1];
++ MACWork[ 2] = sc->disAssociationStation[ 3];
++ MACWork[ 3] = sc->disAssociationStation[ 4];
++ MACWork[ 4] = sc->disAssociationStation[ 6];
++ MACWork[ 5] = sc->disAssociationStation[ 7];
++ MACWork[ 6] = sc->disAssociationStation[ 9];
++ MACWork[ 7] = sc->disAssociationStation[10];
++ MACWork[ 8] = sc->disAssociationStation[12];
++ MACWork[ 9] = sc->disAssociationStation[13];
++ MACWork[10] = sc->disAssociationStation[15];
++ MACWork[11] = sc->disAssociationStation[16];
++ MACWork[12] = '\0';
++ *var_len = 6;
++ return ( UCHAR * ) htob ( MACWork );
++
++ case DOT11DEAUTHENTICATEREASON:
++ return ( UCHAR * ) &sc->deAuthenticationReason;
++
++ case DOT11DEAUTHENTICATESTATION:
++ MACWork[ 0] = sc->deAuthenticationStation[ 0];
++ MACWork[ 1] = sc->deAuthenticationStation[ 1];
++ MACWork[ 2] = sc->deAuthenticationStation[ 3];
++ MACWork[ 3] = sc->deAuthenticationStation[ 4];
++ MACWork[ 4] = sc->deAuthenticationStation[ 6];
++ MACWork[ 5] = sc->deAuthenticationStation[ 7];
++ MACWork[ 6] = sc->deAuthenticationStation[ 9];
++ MACWork[ 7] = sc->deAuthenticationStation[10];
++ MACWork[ 8] = sc->deAuthenticationStation[12];
++ MACWork[ 9] = sc->deAuthenticationStation[13];
++ MACWork[10] = sc->deAuthenticationStation[15];
++ MACWork[11] = sc->deAuthenticationStation[16];
++ MACWork[12] = '\0';
++ *var_len = 6;
++ return ( UCHAR * ) htob ( MACWork );
++
++ case DOT11AUTHENTICATEFAILSTATUS:
++ return ( UCHAR * ) &sc->authenticateFailStatus;
++
++ case DOT11AUTHENTICATEFAILSTATION:
++ MACWork[ 0] = sc->authenticateFailStation[ 0];
++ MACWork[ 1] = sc->authenticateFailStation[ 1];
++ MACWork[ 2] = sc->authenticateFailStation[ 3];
++ MACWork[ 3] = sc->authenticateFailStation[ 4];
++ MACWork[ 4] = sc->authenticateFailStation[ 6];
++ MACWork[ 5] = sc->authenticateFailStation[ 7];
++ MACWork[ 6] = sc->authenticateFailStation[ 9];
++ MACWork[ 7] = sc->authenticateFailStation[10];
++ MACWork[ 8] = sc->authenticateFailStation[12];
++ MACWork[ 9] = sc->authenticateFailStation[13];
++ MACWork[10] = sc->authenticateFailStation[15];
++ MACWork[11] = sc->authenticateFailStation[16];
++ MACWork[12] = '\0';
++ *var_len = 6;
++ return ( UCHAR * ) htob ( MACWork );
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11AuthenticationAlgorithmsTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11AuthenticationAlgorithmsTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &aaList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ aa = ( struct aaTbl_data * ) np->data;
++ rName[vp->namelen + 0] = aa->ifIndex;
++ rName[vp->namelen + 1] = aa->authenticationAlgorithmsIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11AUTHENTICATIONALGORITHM:
++ if ( aa->haveAuthenticationAlgorithm ) found = TRUE; break;
++ case DOT11AUTHENTICATIONALGORITHMSENABLE:
++ if ( aa->authenticationAlgorithmsEnable ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid ));
++ *length = vp->namelen + 2;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11AUTHENTICATIONALGORITHM:
++ return ( UCHAR * ) &aa->authenticationAlgorithm;
++
++ case DOT11AUTHENTICATIONALGORITHMSENABLE:
++// *write_method = write_dot11AuthenticationAlgorithmsEnable;
++ return ( UCHAR * ) &aa->authenticationAlgorithmsEnable;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11WEPDefaultKeysTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11WEPDefaultKeysTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &dfList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ df = ( struct dfTbl_data * ) np->data;
++ rName[vp->namelen + 0] = df->ifIndex;
++ rName[vp->namelen + 1] = df->WEPDefaultKeyIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11WEPDEFAULTKEYVALUE:
++ if ( df->haveWEPDefaultKeyValue ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid ));
++ *length = vp->namelen + 2;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11WEPDEFAULTKEYVALUE:
++// *write_method = write_dot11WEPDefaultKeyValue;
++ *var_len = strlen ( df->WEPDefaultKeyValue );
++ return ( UCHAR * ) df->WEPDefaultKeyValue;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11WEPKeyMappingsTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11WEPKeyMappingsTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method)
++{
++ static char MACWork[17];
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &kmList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ km = ( struct kmTbl_data * ) np->data;
++ rName[vp->namelen + 0] = km->ifIndex;
++ rName[vp->namelen + 1] = km->WEPKeyMappingIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11WEPKEYMAPPINGADDRESS:
++ if ( km->haveWEPKeyMappingAddress ) found = TRUE; break;
++ case DOT11WEPKEYMAPPINGWEPON:
++ if ( km->haveWEPKeyMappingWEPOn ) found = TRUE; break;
++ case DOT11WEPKEYMAPPINGVALUE:
++ if ( km->haveWEPKeyMappingValue ) found = TRUE; break;
++ case DOT11WEPKEYMAPPINGSTATUS:
++ if ( km->haveWEPKeyMappingStatus ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid ));
++ *length = vp->namelen + 2;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11WEPKEYMAPPINGADDRESS:
++// *write_method = write_dot11WEPKeyMappingAddress;
++ MACWork[ 0] = km->WEPKeyMappingAddress[ 0];
++ MACWork[ 1] = km->WEPKeyMappingAddress[ 1];
++ MACWork[ 2] = km->WEPKeyMappingAddress[ 3];
++ MACWork[ 3] = km->WEPKeyMappingAddress[ 4];
++ MACWork[ 4] = km->WEPKeyMappingAddress[ 6];
++ MACWork[ 5] = km->WEPKeyMappingAddress[ 7];
++ MACWork[ 6] = km->WEPKeyMappingAddress[ 9];
++ MACWork[ 7] = km->WEPKeyMappingAddress[10];
++ MACWork[ 8] = km->WEPKeyMappingAddress[12];
++ MACWork[ 9] = km->WEPKeyMappingAddress[13];
++ MACWork[10] = km->WEPKeyMappingAddress[15];
++ MACWork[11] = km->WEPKeyMappingAddress[16];
++ MACWork[12] = '\0';
++ *var_len = 6;
++ return ( UCHAR * ) htob ( MACWork );
++
++ case DOT11WEPKEYMAPPINGWEPON:
++// *write_method = write_dot11WEPKeyMappingWEPOn;
++ return ( UCHAR * ) &km->WEPKeyMappingWEPOn;
++
++ case DOT11WEPKEYMAPPINGVALUE:
++// *write_method = write_dot11WEPKeyMappingValue;
++ *var_len = strlen ( km->WEPKeyMappingValue );
++ return ( UCHAR * ) km->WEPKeyMappingValue;
++
++ case DOT11WEPKEYMAPPINGSTATUS:
++// *write_method = write_dot11WEPKeyMappingStatus;
++ return ( UCHAR * ) &km->WEPKeyMappingStatus;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11PrivacyTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11PrivacyTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &prList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ pr = ( struct prTbl_data * ) np->data;
++ rName[vp->namelen] = pr->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11PRIVACYINVOKED:
++ if ( pr->havePrivacyInvoked ) found = TRUE; break;
++ case DOT11WEPDEFAULTKEYID:
++ if ( pr->haveWEPDefaultKeyID ) found = TRUE; break;
++ case DOT11WEPKEYMAPPINGLENGTH:
++ if ( pr->haveWEPKeyMappingLength ) found = TRUE; break;
++ case DOT11EXCLUDEUNENCRYPTED:
++ if ( pr->haveExcludeUnencrypted ) found = TRUE; break;
++ case DOT11WEPICVERRORCOUNT:
++ if ( pr->haveWEPICVErrorCount ) found = TRUE; break;
++ case DOT11WEPEXCLUDEDCOUNT:
++ if ( pr->haveWEPExcludedCount ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11PRIVACYINVOKED:
++// *write_method = write_dot11PrivacyInvoked;
++ return ( UCHAR * ) &pr->privacyInvoked;
++
++ case DOT11WEPDEFAULTKEYID:
++// *write_method = write_dot11WEPDefaultKeyID;
++ return ( UCHAR * ) &pr->WEPDefaultKeyID;
++
++ case DOT11WEPKEYMAPPINGLENGTH:
++// *write_method = write_dot11WEPKeyMappingLength;
++ return ( UCHAR * ) &pr->WEPKeyMappingLength;
++
++ case DOT11EXCLUDEUNENCRYPTED:
++// *write_method = write_dot11ExcludeUnencrypted;
++ return ( UCHAR * ) &pr->excludeUnencrypted;
++
++ case DOT11WEPICVERRORCOUNT:
++ return ( UCHAR * ) &pr->WEPICVErrorCount;
++
++ case DOT11WEPEXCLUDEDCOUNT:
++ return ( UCHAR * ) &pr->WEPExcludedCount;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11OperationTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11OperationTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++ static char MACWork[17];
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &opList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ op = ( struct opTbl_data * ) np->data;
++ rName[vp->namelen] = op->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++
++ switch ( vp->magic ) { // found requested OID, now check for requested variable
++ case DOT11MACADDRESS:
++ if ( op->haveMACAddress ) found = TRUE; break;
++ case DOT11RTSTHRESHOLD:
++ if ( op->haveRTSThreshold ) found = TRUE; break;
++ case DOT11SHORTRETRYLIMIT:
++ if ( op->haveShortRetryLimit ) found = TRUE; break;
++ case DOT11LONGRETRYLIMIT:
++ if ( op->haveLongRetryLimit ) found = TRUE; break;
++ case DOT11FRAGMENTATIONTHRESHOLD:
++ if ( op->haveFragmentationThreshold ) found = TRUE; break;
++ case DOT11MAXTRANSMITMSDULIFETIME:
++ if ( op->haveMaxTransmitMSDULifetime ) found = TRUE; break;
++ case DOT11MAXRECEIVELIFETIME:
++ if ( op->haveMaxReceiveLifetime ) found = TRUE; break;
++ case DOT11MANUFACTURERID:
++ if ( op->haveManufacturerID ) found = TRUE; break;
++ case DOT11PRODUCTID:
++ if ( op->haveProductID ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11MACADDRESS:
++ MACWork[ 0] = op->MACAddress[ 0];
++ MACWork[ 1] = op->MACAddress[ 1];
++ MACWork[ 2] = op->MACAddress[ 3];
++ MACWork[ 3] = op->MACAddress[ 4];
++ MACWork[ 4] = op->MACAddress[ 6];
++ MACWork[ 5] = op->MACAddress[ 7];
++ MACWork[ 6] = op->MACAddress[ 9];
++ MACWork[ 7] = op->MACAddress[10];
++ MACWork[ 8] = op->MACAddress[12];
++ MACWork[ 9] = op->MACAddress[13];
++ MACWork[10] = op->MACAddress[15];
++ MACWork[11] = op->MACAddress[16];
++ MACWork[12] = '\0';
++ *var_len = 6;
++ return ( UCHAR * ) htob ( MACWork );
++
++ case DOT11RTSTHRESHOLD:
++// *write_method = write_dot11RTSThreshold;
++ return ( UCHAR * ) &op->RTSThreshold;
++
++ case DOT11SHORTRETRYLIMIT:
++// *write_method = write_dot11ShortRetryLimit;
++ return ( UCHAR * ) &op->shortRetryLimit;
++
++ case DOT11LONGRETRYLIMIT:
++// *write_method = write_dot11LongRetryLimit;
++ return ( UCHAR * ) &op->longRetryLimit;
++
++ case DOT11FRAGMENTATIONTHRESHOLD:
++// *write_method = write_dot11FragmentationThreshold;
++ return ( UCHAR * ) &op->fragmentationThreshold;
++
++ case DOT11MAXTRANSMITMSDULIFETIME:
++// *write_method = write_dot11MaxTransmitMSDULifetime;
++ return ( UCHAR * ) &op->maxTransmitMSDULifetime;
++
++ case DOT11MAXRECEIVELIFETIME:
++// *write_method = write_dot11MaxReceiveLifetime;
++ return ( UCHAR * ) &op->maxReceiveLifetime;
++
++ case DOT11MANUFACTURERID:
++ *var_len = strlen ( op->manufacturerID );
++ return ( UCHAR * ) op->manufacturerID;
++
++ case DOT11PRODUCTID:
++ *var_len = strlen ( op->productID );
++ return ( UCHAR * ) op->productID;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11CountersTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11CountersTable(struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method)
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &coList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ co = ( struct coTbl_data * ) np->data;
++ rName[vp->namelen] = co->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11TRANSMITTEDFRAGMENTCOUNT:
++ if ( co->haveTransmittedFragmentCount ) found = TRUE; break;
++ case DOT11MULTICASTTRANSMITTEDFRAMECOUNT:
++ if ( co->haveTransmittedFrameCount ) found = TRUE; break;
++ case DOT11FAILEDCOUNT:
++ if ( co->haveFailedCount ) found = TRUE; break;
++ case DOT11RETRYCOUNT:
++ if ( co->haveRetryCount ) found = TRUE; break;
++ case DOT11MULTIPLERETRYCOUNT:
++ if ( co->haveMultipleRetryCount ) found = TRUE; break;
++ case DOT11FRAMEDUPLICATECOUNT:
++ if ( co->haveFrameDuplicateCount ) found = TRUE; break;
++ case DOT11RTSSUCCESSCOUNT:
++ if ( co->haveRTSSuccessCount ) found = TRUE; break;
++ case DOT11RTSFAILURECOUNT:
++ if ( co->haveRTSFailureCount ) found = TRUE; break;
++ case DOT11ACKFAILURECOUNT:
++ if ( co->haveACKFailureCount ) found = TRUE; break;
++ case DOT11RECEIVEDFRAGMENTCOUNT:
++ if ( co->haveReceivedFragmentCount ) found = TRUE; break;
++ case DOT11MULTICASTRECEIVEDFRAMECOUNT:
++ if ( co->haveMulticastReceivedFrameCount ) found = TRUE; break;
++ case DOT11FCSERRORCOUNT:
++ if ( co->haveFCSErrorCount ) found = TRUE; break;
++ case DOT11TRANSMITTEDFRAMECOUNT:
++ if ( co->haveTransmittedFrameCount ) found = TRUE; break;
++ case DOT11WEPUNDECRYPTABLECOUNT:
++ if ( co->haveWEPUndecryptableCount ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11TRANSMITTEDFRAGMENTCOUNT: return ( UCHAR * ) &co->transmittedFragmentCount;
++ case DOT11MULTICASTTRANSMITTEDFRAMECOUNT: return ( UCHAR * ) &co->transmittedFrameCount;
++ case DOT11FAILEDCOUNT: return ( UCHAR * ) &co->failedCount;
++ case DOT11RETRYCOUNT: return ( UCHAR * ) &co->retryCount;
++ case DOT11MULTIPLERETRYCOUNT: return ( UCHAR * ) &co->multipleRetryCount;
++ case DOT11FRAMEDUPLICATECOUNT: return ( UCHAR * ) &co->frameDuplicateCount;
++ case DOT11RTSSUCCESSCOUNT: return ( UCHAR * ) &co->RTSSuccessCount;
++ case DOT11RTSFAILURECOUNT: return ( UCHAR * ) &co->RTSFailureCount;
++ case DOT11ACKFAILURECOUNT: return ( UCHAR * ) &co->ACKFailureCount;
++ case DOT11RECEIVEDFRAGMENTCOUNT: return ( UCHAR * ) &co->receivedFragmentCount;
++ case DOT11MULTICASTRECEIVEDFRAMECOUNT: return ( UCHAR * ) &co->multicastReceivedFrameCount;
++ case DOT11FCSERRORCOUNT: return ( UCHAR * ) &co->FCSErrorCount;
++ case DOT11TRANSMITTEDFRAMECOUNT: return ( UCHAR * ) &co->transmittedFrameCount;
++ case DOT11WEPUNDECRYPTABLECOUNT: return ( UCHAR * ) &co->WEPUndecryptableCount;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11GroupAddressesTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11GroupAddressesTable(struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method)
++{
++ static char MACWork[17];
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &gaList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ ga = ( struct gaTbl_data * ) np->data;
++ rName[vp->namelen + 0] = ga->ifIndex;
++ rName[vp->namelen + 1] = ga->groupAddressesIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11ADDRESS:
++ if ( ga->haveAddress ) found = TRUE; break;
++ case DOT11GROUPADDRESSESSTATUS:
++ if ( ga->haveGroupAddressesStatus ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid ));
++ *length = vp->namelen + 2;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11ADDRESS:
++// *write_method = write_dot11Address;
++ MACWork[ 0] = ga->address[ 0];
++ MACWork[ 1] = ga->address[ 1];
++ MACWork[ 2] = ga->address[ 3];
++ MACWork[ 3] = ga->address[ 4];
++ MACWork[ 4] = ga->address[ 6];
++ MACWork[ 5] = ga->address[ 7];
++ MACWork[ 6] = ga->address[ 9];
++ MACWork[ 7] = ga->address[10];
++ MACWork[ 8] = ga->address[12];
++ MACWork[ 9] = ga->address[13];
++ MACWork[10] = ga->address[15];
++ MACWork[11] = ga->address[16];
++ MACWork[12] = '\0';
++ *var_len = 6;
++ return ( UCHAR * ) htob ( MACWork );
++
++ case DOT11GROUPADDRESSESSTATUS:
++// *write_method = write_dot11GroupAddressesStatus;
++ return ( UCHAR * ) &ga->groupAddressesStatus;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11ResourceInfoTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11ResourceInfoTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &riList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ ri = ( struct riTbl_data * ) np->data;
++ rName[vp->namelen] = ri->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11MANUFACTUREROUI:
++ if ( ri->haveManufacturerOUI ) found = TRUE; break;
++ case DOT11MANUFACTURERNAME:
++ if ( ri->haveManufacturerName ) found = TRUE; break;
++ case DOT11MANUFACTURERPRODUCTNAME:
++ if ( ri->haveManufacturerProductName ) found = TRUE; break;
++ case DOT11MANUFACTURERPRODUCTVERSION:
++ if ( ri->haveManufacturerProductVersion ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11MANUFACTUREROUI:
++ *var_len = strlen ( ri->manufacturerOUI );
++ return ( UCHAR * ) ri->manufacturerOUI;
++
++ case DOT11MANUFACTURERNAME:
++ *var_len = strlen ( ri->manufacturerName );
++ return ( UCHAR * ) ri->manufacturerName;
++
++ case DOT11MANUFACTURERPRODUCTNAME:
++ *var_len = strlen ( ri->manufacturerProductName );
++ return ( UCHAR * ) ri->manufacturerProductName;
++
++ case DOT11MANUFACTURERPRODUCTVERSION:
++ *var_len = strlen ( ri->manufacturerProductVersion );
++ return ( UCHAR * ) ri->manufacturerProductVersion;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11PhyOperationTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11PhyOperationTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &poList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ po = ( struct poTbl_data * ) np->data;
++ rName[vp->namelen] = po->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11PHYTYPE:
++ if ( po->havePHYType ) found = TRUE; break;
++ case DOT11CURRENTREGDOMAIN:
++ if ( po->haveCurrentRegDomain ) found = TRUE; break;
++ case DOT11TEMPTYPE:
++ if ( po->haveTempType ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11PHYTYPE:
++ return ( UCHAR * ) &po->PHYType;
++
++ case DOT11CURRENTREGDOMAIN:
++// *write_method = write_dot11CurrentRegDomain;
++ return ( UCHAR * ) &po->currentRegDomain;
++
++ case DOT11TEMPTYPE:
++ return ( UCHAR * ) &po->tempType;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11PhyAntennaTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11PhyAntennaTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &paList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ pa = ( struct paTbl_data * ) np->data;
++ rName[vp->namelen] = pa->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11CURRENTTXANTENNA:
++ if ( pa->haveCurrentTxAntenna ) found = TRUE; break;
++ case DOT11DIVERSITYSUPPORT:
++ if ( pa->haveDiversitySupport ) found = TRUE; break;
++ case DOT11CURRENTRXANTENNA:
++ if ( pa->haveCurrentRxAntenna ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11CURRENTTXANTENNA:
++// *write_method = write_dot11CurrentTxAntenna;
++ return ( UCHAR * ) &pa->currentTxAntenna;
++
++ case DOT11DIVERSITYSUPPORT:
++ return ( UCHAR * ) &pa->diversitySupport;
++
++ case DOT11CURRENTRXANTENNA:
++// *write_method = write_dot11CurrentRxAntenna;
++ return ( UCHAR * ) &pa->currentRxAntenna;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11PhyTxPowerTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11PhyTxPowerTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &ptList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ pt = ( struct ptTbl_data * ) np->data;
++ rName[vp->namelen] = pt->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11NUMBERSUPPORTEDPOWERLEVELS:
++ if ( pt->haveNumberSupportedPowerLevels ) found = TRUE; break;
++ case DOT11TXPOWERLEVEL1:
++ if ( pt->haveTxPowerLevel1 ) found = TRUE; break;
++ case DOT11TXPOWERLEVEL2:
++ if ( pt->haveTxPowerLevel2 ) found = TRUE; break;
++ case DOT11TXPOWERLEVEL3:
++ if ( pt->haveTxPowerLevel3 ) found = TRUE; break;
++ case DOT11TXPOWERLEVEL4:
++ if ( pt->haveTxPowerLevel4 ) found = TRUE; break;
++ case DOT11TXPOWERLEVEL5:
++ if ( pt->haveTxPowerLevel5 ) found = TRUE; break;
++ case DOT11TXPOWERLEVEL6:
++ if ( pt->haveTxPowerLevel6 ) found = TRUE; break;
++ case DOT11TXPOWERLEVEL7:
++ if ( pt->haveTxPowerLevel7 ) found = TRUE; break;
++ case DOT11TXPOWERLEVEL8:
++ if ( pt->haveTxPowerLevel8 ) found = TRUE; break;
++ case DOT11CURRENTTXPOWERLEVEL:
++ if ( pt->currentTxPowerLevel ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11NUMBERSUPPORTEDPOWERLEVELS:
++ return ( UCHAR * ) &pt->numberSupportedPowerLevels;
++
++ case DOT11TXPOWERLEVEL1: return ( UCHAR * ) &pt->TxPowerLevel1;
++ case DOT11TXPOWERLEVEL2: return ( UCHAR * ) &pt->TxPowerLevel2;
++ case DOT11TXPOWERLEVEL3: return ( UCHAR * ) &pt->TxPowerLevel3;
++ case DOT11TXPOWERLEVEL4: return ( UCHAR * ) &pt->TxPowerLevel4;
++ case DOT11TXPOWERLEVEL5: return ( UCHAR * ) &pt->TxPowerLevel5;
++ case DOT11TXPOWERLEVEL6: return ( UCHAR * ) &pt->TxPowerLevel6;
++ case DOT11TXPOWERLEVEL7: return ( UCHAR * ) &pt->TxPowerLevel7;
++ case DOT11TXPOWERLEVEL8: return ( UCHAR * ) &pt->TxPowerLevel8;
++
++ case DOT11CURRENTTXPOWERLEVEL:
++// *write_method = write_dot11CurrentTxPowerLevel;
++ return ( UCHAR * ) &pt->currentTxPowerLevel;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11PhyFHSSTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11PhyFHSSTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &pfList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ pf = ( struct pfTbl_data * ) np->data;
++ rName[vp->namelen] = pf->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11HOPTIME:
++ if ( pf->haveHopTime ) found = TRUE; break;
++ case DOT11CURRENTCHANNELNUMBER:
++ if ( pf->haveCurrentChannelNumber ) found = TRUE; break;
++ case DOT11MAXDWELLTIME:
++ if ( pf->haveMaxDwellTime ) found = TRUE; break;
++ case DOT11CURRENTDWELLTIME:
++ if ( pf->haveCurrentDwellTime ) found = TRUE; break;
++ case DOT11CURRENTSET:
++ if ( pf->haveCurrentSet ) found = TRUE; break;
++ case DOT11CURRENTPATTERN:
++ if ( pf->haveCurrentPattern ) found = TRUE; break;
++ case DOT11CURRENTINDEX:
++ if ( pf->haveCurrentIndex ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11HOPTIME:
++ return ( UCHAR * ) &pf->hopTime;
++
++ case DOT11CURRENTCHANNELNUMBER:
++// *write_method = write_dot11CurrentChannelNumber;
++ return ( UCHAR * ) &pf->currentChannelNumber;
++
++ case DOT11MAXDWELLTIME:
++ return ( UCHAR * ) &pf->maxDwellTime;
++
++ case DOT11CURRENTDWELLTIME:
++// *write_method = write_dot11CurrentDwellTime;
++ return ( UCHAR * ) &pf->currentDwellTime;
++
++ case DOT11CURRENTSET:
++// *write_method = write_dot11CurrentSet;
++ return ( UCHAR * ) &pf->currentSet;
++
++ case DOT11CURRENTPATTERN:
++// *write_method = write_dot11CurrentPattern;
++ return ( UCHAR * ) &pf->currentPattern;
++
++ case DOT11CURRENTINDEX:
++// *write_method = write_dot11CurrentIndex;
++ return ( UCHAR * ) &pf->currentIndex;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11PhyDSSSTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11PhyDSSSTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &pdList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ pd = ( struct pdTbl_data * ) np->data;
++ rName[vp->namelen] = pd->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11CURRENTCHANNEL:
++ if ( pd->haveCurrentChannel ) found = TRUE; break;
++ case DOT11CCAMODESUPPORTED:
++ if ( pd->haveCCAModeSupported ) found = TRUE; break;
++ case DOT11CURRENTCCAMODE:
++ if ( pd->haveCurrentCCAMode ) found = TRUE; break;
++ case DOT11EDTHRESHOLD:
++ if ( pd->haveEDThreshold ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11CURRENTCHANNEL:
++// *write_method = write_dot11CurrentChannel;
++ return ( UCHAR * ) &pd->currentChannel;
++
++ case DOT11CCAMODESUPPORTED:
++ return ( UCHAR * ) &pd->CCAModeSupported;
++
++ case DOT11CURRENTCCAMODE:
++// *write_method = write_dot11CurrentCCAMode;
++ return ( UCHAR * ) &pd->currentCCAMode;
++
++ case DOT11EDTHRESHOLD:
++// *write_method = write_dot11EDThreshold;
++ return ( UCHAR * ) &pd->EDThreshold;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11PhyIRTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11PhyIRTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method)
++{
++
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &piList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ pi = ( struct piTbl_data * ) np->data;
++ rName[vp->namelen] = pi->ifIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11CCAWATCHDOGTIMERMAX:
++ if ( pi->CCAWatchdogTimerMax ) found = TRUE; break;
++ case DOT11CCAWATCHDOGCOUNTMAX:
++ if ( pi->CCAWatchdogCountMax ) found = TRUE; break;
++ case DOT11CCAWATCHDOGTIMERMIN:
++ if ( pi->CCAWatchdogTimerMin ) found = TRUE; break;
++ case DOT11CCAWATCHDOGCOUNTMIN:
++ if ( pi->CCAWatchdogCountMin ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid ));
++ *length = vp->namelen + 1;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11CCAWATCHDOGTIMERMAX:
++// *write_method = write_dot11CCAWatchdogTimerMax;
++ return ( UCHAR * ) &pi->CCAWatchdogTimerMax;
++
++ case DOT11CCAWATCHDOGCOUNTMAX:
++// *write_method = write_dot11CCAWatchdogCountMax;
++ return ( UCHAR * ) &pi->CCAWatchdogCountMax;
++
++ case DOT11CCAWATCHDOGTIMERMIN:
++// *write_method = write_dot11CCAWatchdogTimerMin;
++ return ( UCHAR * ) &pi->CCAWatchdogTimerMin;
++
++ case DOT11CCAWATCHDOGCOUNTMIN:
++// *write_method = write_dot11CCAWatchdogCountMin;
++ return ( UCHAR * ) &pi->CCAWatchdogCountMin;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11RegDomainsSupportedTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11RegDomainsSupportedTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method)
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &rdList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ rd = ( struct rdTbl_data * ) np->data;
++ rName[vp->namelen + 0] = rd->ifIndex;
++ rName[vp->namelen + 1] = rd->regDomainsSupportIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11REGDOMAINSSUPPORTVALUE:
++ if ( rd->haveRegDomainsSupportValue ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid ));
++ *length = vp->namelen + 2;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11REGDOMAINSSUPPORTVALUE:
++ return ( UCHAR * ) &rd->regDomainsSupportValue;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11AntennasListTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11AntennasListTable(struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method)
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &alList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ al = ( struct alTbl_data * ) np->data;
++ rName[vp->namelen + 0] = al->ifIndex;
++ rName[vp->namelen + 1] = al->antennaListIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11SUPPORTEDTXANTENNA:
++ if ( al->haveSupportedTxAntenna ) found = TRUE; break;
++ case DOT11SUPPORTEDRXANTENNA:
++ if ( al->haveSupportedRxAntenna ) found = TRUE; break;
++ case DOT11DIVERSITYSELECTIONRX:
++ if ( al->haveDiversitySelectionRx ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid ));
++ *length = vp->namelen + 2;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11SUPPORTEDTXANTENNA:
++// *write_method = write_dot11SupportedTxAntenna;
++ return ( UCHAR * ) &al->supportedTxAntenna;
++
++ case DOT11SUPPORTEDRXANTENNA:
++// *write_method = write_dot11SupportedRxAntenna;
++ return ( UCHAR * ) &al->supportedRxAntenna;
++
++ case DOT11DIVERSITYSELECTIONRX:
++// *write_method = write_dot11DiversitySelectionRx;
++ return ( UCHAR * ) &al->diversitySelectionRx;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11SupportedDataRatesTxTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11SupportedDataRatesTxTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &rtList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ rt = ( struct rtTbl_data * ) np->data;
++ rName[vp->namelen + 0] = rt->ifIndex;
++ rName[vp->namelen + 1] = rt->supportedDataRatesTxIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11SUPPORTEDDATARATESTXVALUE:
++ if ( rt->haveSupportedDataRatesTxValue ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid ));
++ *length = vp->namelen + 2;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11SUPPORTEDDATARATESTXVALUE:
++ return ( UCHAR * ) &rt->supportedDataRatesTxValue;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++* var_dot11SupportedDataRatesRxTable() - *
++* *
++****************************************************************************/
++unsigned char *
++var_dot11SupportedDataRatesRxTable ( struct variable *vp,
++ oid *name,
++ size_t *length,
++ int exact,
++ size_t *var_len,
++ WriteMethod **write_method )
++{
++ int found = FALSE;
++ oid rName [ MAX_OID_LEN ]; // OID to be returned
++
++ loadTables();
++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid ));
++ for ( np = LIST_FIRST ( &rrList ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ rr = ( struct rrTbl_data * ) np->data;
++ rName[vp->namelen + 0] = rr->ifIndex;
++ rName[vp->namelen + 1] = rr->supportedDataRatesRxIndex;
++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) ||
++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) {
++ switch ( vp->magic ) {
++ case DOT11SUPPORTEDDATARATESRXVALUE:
++ if ( rr->haveSupportedDataRatesRxValue ) found = TRUE; break;
++ }
++ }
++ if ( found )
++ break;
++ }
++
++ if ( !found )
++ return NULL;
++
++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid ));
++ *length = vp->namelen + 2;
++ *var_len = sizeof ( long );
++ *write_method = NULL;
++
++ switch ( vp->magic ) {
++
++ case DOT11SUPPORTEDDATARATESRXVALUE:
++ return ( UCHAR * ) &rr->supportedDataRatesRxValue;
++
++ default:
++ ERROR_MSG ( "" );
++ }
++
++ return NULL;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11StationID(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static unsigned char string[SPRINT_MAX_LEN];
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_OCTET_STR ) {
++ fprintf ( stderr, "write to dot11StationID not ASN_OCTET_STR\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( string )) {
++ fprintf ( stderr,"write to dot11StationID: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11MediumOccupancyLimit(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11MediumOccupancyLimit not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11MediumOccupancyLimit: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CFPPeriod(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CFPPeriod not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CFPPeriod: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CFPMaxDuration(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CFPMaxDuration not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CFPMaxDuration: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11AuthenticationResponseTimeOut(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11AuthenticationResponseTimeOut not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11AuthenticationResponseTimeOut: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11PowerManagementMode(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11PowerManagementMode not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )) {
++ fprintf ( stderr, "write to dot11PowerManagementMode: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11DesiredSSID(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static unsigned char string[SPRINT_MAX_LEN];
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_OCTET_STR ) {
++ fprintf ( stderr, "write to dot11DesiredSSID not ASN_OCTET_STR\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( string )){
++ fprintf ( stderr, "write to dot11DesiredSSID: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11DesiredBSSType(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11DesiredBSSType not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11DesiredBSSType: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11OperationalRateSet(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static unsigned char string[SPRINT_MAX_LEN];
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_OCTET_STR ) {
++ fprintf ( stderr, "write to dot11OperationalRateSet not ASN_OCTET_STR\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( string )){
++ fprintf ( stderr, "write to dot11OperationalRateSet: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11BeaconPeriod(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11BeaconPeriod not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11BeaconPeriod: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11DTIMPeriod(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11DTIMPeriod not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11DTIMPeriod: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11AssociationResponseTimeOut(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11AssociationResponseTimeOut not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )) {
++ fprintf ( stderr,"write to dot11AssociationResponseTimeOut: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11AuthenticationAlgorithmsEnable(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11AuthenticationAlgorithmsEnable not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11AuthenticationAlgorithmsEnable: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11WEPDefaultKeyValue(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static unsigned char string[SPRINT_MAX_LEN];
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_OCTET_STR ) {
++ fprintf ( stderr, "write to dot11WEPDefaultKeyValue not ASN_OCTET_STR\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( string )){
++ fprintf ( stderr,"write to dot11WEPDefaultKeyValue: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11WEPKeyMappingAddress(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static unsigned char string[SPRINT_MAX_LEN];
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_OCTET_STR ) {
++ fprintf ( stderr, "write to dot11WEPKeyMappingAddress not ASN_OCTET_STR\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( string )) {
++ fprintf ( stderr,"write to dot11WEPKeyMappingAddress: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11WEPKeyMappingWEPOn(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11WEPKeyMappingWEPOn not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11WEPKeyMappingWEPOn: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11WEPKeyMappingValue(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static unsigned char string[SPRINT_MAX_LEN];
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_OCTET_STR ) {
++ fprintf ( stderr, "write to dot11WEPKeyMappingValue not ASN_OCTET_STR\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( string )) {
++ fprintf ( stderr, "write to dot11WEPKeyMappingValue: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11WEPKeyMappingStatus(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11WEPKeyMappingStatus not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11WEPKeyMappingStatus: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11PrivacyInvoked(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11PrivacyInvoked not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11PrivacyInvoked: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11WEPDefaultKeyID(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11WEPDefaultKeyID not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11WEPDefaultKeyID: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11WEPKeyMappingLength(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11WEPKeyMappingLength not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11WEPKeyMappingLength: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11ExcludeUnencrypted(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11ExcludeUnencrypted not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11ExcludeUnencrypted: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11RTSThreshold(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ){
++ fprintf ( stderr, "write to dot11RTSThreshold not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11RTSThreshold: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11ShortRetryLimit(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11ShortRetryLimit not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11ShortRetryLimit: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11LongRetryLimit(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11LongRetryLimit not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11LongRetryLimit: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11FragmentationThreshold(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11FragmentationThreshold not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11FragmentationThreshold: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11MaxTransmitMSDULifetime(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11MaxTransmitMSDULifetime not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11MaxTransmitMSDULifetime: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11MaxReceiveLifetime(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11MaxReceiveLifetime not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11MaxReceiveLifetime: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11Address(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static unsigned char string[SPRINT_MAX_LEN];
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_OCTET_STR ) {
++ fprintf ( stderr, "write to dot11Address not ASN_OCTET_STR\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( string )){
++ fprintf ( stderr, "write to dot11Address: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11GroupAddressesStatus(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11GroupAddressesStatus not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11GroupAddressesStatus: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentRegDomain(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentRegDomain not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CurrentRegDomain: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentTxAntenna(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentTxAntenna not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CurrentTxAntenna: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentRxAntenna(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentRxAntenna not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11CurrentRxAntenna: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentTxPowerLevel(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentTxPowerLevel not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CurrentTxPowerLevel: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentChannelNumber(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentChannelNumber not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11CurrentChannelNumber: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentDwellTime(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentDwellTime not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CurrentDwellTime: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentSet(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentSet not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CurrentSet: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentPattern(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentPattern not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CurrentPattern: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentIndex(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentIndex not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CurrentIndex: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentChannel(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentChannel not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CurrentChannel: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CurrentCCAMode(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CurrentCCAMode not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11CurrentCCAMode: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11EDThreshold(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11EDThreshold not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11EDThreshold: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CCAWatchdogTimerMax(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CCAWatchdogTimerMax not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CCAWatchdogTimerMax: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CCAWatchdogCountMax(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CCAWatchdogCountMax not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CCAWatchdogCountMax: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CCAWatchdogTimerMin(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CCAWatchdogTimerMin not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CCAWatchdogTimerMin: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11CCAWatchdogCountMin(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11CCAWatchdogCountMin not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11CCAWatchdogCountMin: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11SupportedTxAntenna(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11SupportedTxAntenna not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11SupportedTxAntenna: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11SupportedRxAntenna(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11SupportedRxAntenna not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr,"write to dot11SupportedRxAntenna: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++****************************************************************************/
++int
++write_dot11DiversitySelectionRx(int action,
++ u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len,
++ u_char *statP,
++ oid *name,
++ size_t name_len)
++{
++ static long *long_ret;
++ int size;
++
++ switch ( action ) {
++
++ case RESERVE1:
++ if ( var_val_type != ASN_INTEGER ) {
++ fprintf ( stderr, "write to dot11DiversitySelectionRx not ASN_INTEGER\n" );
++ return SNMP_ERR_WRONGTYPE;
++ }
++ if ( var_val_len > sizeof ( long_ret )){
++ fprintf ( stderr, "write to dot11DiversitySelectionRx: bad length\n" );
++ return SNMP_ERR_WRONGLENGTH;
++ }
++ break;
++
++ case RESERVE2:
++ case FREE:
++ case ACTION:
++ case UNDO:
++ break;
++
++ case COMMIT:
++ break;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++/****************************************************************************
++* *
++* loadTables() - Load the Tables *
++* *
++****************************************************************************/
++static void loadTables()
++{
++ int skfd; // generic raw socket desc
++ struct iwreq wrq; // ioctl request structure
++ struct ifreq ifr;
++ struct timeval et; // elapsed time
++ struct wireless_info info; // workarea for wireless ioctl information
++ FILE *fp;
++ char bfr[1024], ifName[1024];
++ char *s, *t;
++
++ gettimeofday ( &et, ( struct timezone * ) 0 ); // get time-of-day
++ if ( et.tv_sec < lastLoad + MINLOADFREQ ) // only reload so often
++ return;
++ lastLoad = et.tv_sec;
++
++ skfd = openSocket(); // open socket
++ if ( skfd < 0 ) {
++ syslog ( LOG_ERR, "SNMP ieee802dot11.loadTables() - %s\n", "socket open failure" );
++ return;
++ }
++
++ flushLists();
++
++ // find interfaces in /proc/net/dev and find the wireless interfaces
++ fp = fopen ( PROC_NET_DEV, "r" );
++ if ( fp ) {
++ while ( fgets ( bfr, sizeof ( bfr ), fp )) {
++ if ( strstr ( bfr, ":" )) {
++ s = bfr; t = ifName;
++ while ( isspace ( *s )) // discard white space
++ *s++;
++ while ( *s != ':' ) // get interface name
++ *t++ = *s++;
++ *t = '\0';
++
++ // verify as a wireless device
++ memset (( char * ) &info, 0, sizeof ( struct wireless_info ));
++ strncpy ( wrq.ifr_name, ifName, IFNAMSIZ );
++ if ( ioctl ( skfd, SIOCGIWNAME, &wrq ) >= 0 ) {
++ printf ( "%s ifName: %s\n", "loadTables() -", ifName );
++ initStructs();
++ loadWiExt( skfd, ifName, &info );
++ displayWiExt ( info );
++ load80211Structs ( skfd, ifName, &info );
++ }
++ }
++ }
++ fclose ( fp );
++ }
++
++ close ( skfd );
++}
++
++/****************************************************************************
++* *
++* load80211Structs() - load the 802.11 structures *
++* *
++****************************************************************************/
++static void
++load80211Structs ( int skfd, char *ifName, struct wireless_info *wi )
++{
++ int rc, ifIndex = 0;
++ struct ifreq ifr;
++ char MACAddress [ MACADDR_LEN + 1 ];
++
++ strcpy ( ifr.ifr_name, ifName );
++ rc = ioctl ( skfd, SIOCGIFHWADDR, &ifr );
++ if ( rc >= 0 ) {
++
++ sprintf ( MACAddress, "%02X:%02X:%02X:%02X:%02X:%02X\0",
++ ( UCHAR ) ifr.ifr_hwaddr.sa_data[0], ( UCHAR ) ifr.ifr_hwaddr.sa_data[1],
++ ( UCHAR ) ifr.ifr_hwaddr.sa_data[2], ( UCHAR ) ifr.ifr_hwaddr.sa_data[3],
++ ( UCHAR ) ifr.ifr_hwaddr.sa_data[4], ( UCHAR ) ifr.ifr_hwaddr.sa_data[5] );
++
++ nSc.haveStationID = TRUE;
++ strcpy ( nSc.stationID, MACAddress );
++ nOp.haveMACAddress = TRUE;
++ strcpy ( nOp.MACAddress, MACAddress );
++ nRi.haveManufacturerOUI = TRUE;
++ strncpy ( nRi.manufacturerOUI, MACAddress, MAN_OUI_LEN );
++
++ ifIndex = if_nametoindex ( ifName );
++ if ( !ifIndex ) {
++ syslog ( LOG_ERR, "SNMP %s - %s %s\n",
++ "ieee802dot11.load80211Structs()", ifName, "has no ifIndex" );
++ return;
++ }
++
++ loadWiExtTo80211Structs ( ifIndex, ifName, wi );
++
++ if ( hasChanged (( char * ) &nSc, sizeof ( nSc ))) {
++ nSc.ifIndex = ifIndex;
++ sprintf ( nSc.UID, "%04d\0", nSc.ifIndex );
++ strcpy ( nSc.ifName, ifName );
++ addList (( char * ) &scList, ( char * ) &nSc, sizeof ( nSc ));
++ }
++
++ if ( hasChanged (( char * ) &nPr, sizeof ( nPr ))) {
++ nPr.ifIndex = ifIndex;
++ sprintf ( nPr.UID, "%04d\0", nPr.ifIndex );
++ strcpy ( nPr.ifName, ifName );
++ addList (( char * ) &prList, ( char * ) &nPr, sizeof ( nPr ));
++ }
++
++ if ( hasChanged (( char * ) &nOp, sizeof ( nOp ))) {
++ nOp.ifIndex = ifIndex;
++ sprintf ( nOp.UID, "%04d\0", nOp.ifIndex );
++ strcpy ( nOp.ifName, ifName );
++ addList (( char * ) &opList, ( char * ) &nOp, sizeof ( nOp ));
++ }
++
++ if ( hasChanged (( char * ) &nCo, sizeof ( nCo ))) {
++ nCo.ifIndex = ifIndex;
++ sprintf ( nCo.UID, "%04d\0", nCo.ifIndex );
++ strcpy ( nCo.ifName, ifName );
++ addList (( char * ) &coList, ( char * ) &nCo, sizeof ( nCo ));
++ }
++
++ if ( hasChanged (( char * ) &nRi, sizeof ( nRi ))) {
++ nRi.ifIndex = ifIndex;
++ sprintf ( nRi.UID, "%04d\0", nRi.ifIndex );
++ strcpy ( nRi.ifName, ifName );
++ addList (( char * ) &riList, ( char * ) &nRi, sizeof ( nRi ));
++ }
++
++ if ( hasChanged (( char * ) &nPo, sizeof ( nPo ))) {
++ nPo.ifIndex = ifIndex;
++ sprintf ( nPo.UID, "%04d\0", nPo.ifIndex );
++ strcpy ( nPo.ifName, ifName );
++ addList (( char * ) &poList, ( char * ) &nPo, sizeof ( nPo ));
++ }
++
++ if ( hasChanged (( char * ) &nPa, sizeof ( nPa ))) {
++ nPa.ifIndex = ifIndex;
++ sprintf ( nPa.UID, "%04d\0", nPa.ifIndex );
++ strcpy ( nPa.ifName, ifName );
++ addList (( char * ) &paList, ( char * ) &nPa, sizeof ( nPa ));
++ }
++
++ if ( hasChanged (( char * ) &nPt, sizeof ( nPt ))) {
++ nPt.ifIndex = ifIndex;
++ sprintf ( nPt.UID, "%04d\0", nPt.ifIndex );
++ strcpy ( nPt.ifName, ifName );
++ addList (( char * ) &ptList, ( char * ) &nPt, sizeof ( nPt ));
++ }
++
++ if ( hasChanged (( char * ) &nPf, sizeof ( nPf ))) {
++ nPf.ifIndex = ifIndex;
++ sprintf ( nPf.UID, "%04d\0", nPf.ifIndex );
++ strcpy ( nPf.ifName, ifName );
++ addList (( char * ) &pfList, ( char * ) &nPf, sizeof ( nPf ));
++ }
++
++ if ( hasChanged (( char * ) &nPd, sizeof ( nPd ))) {
++ nPd.ifIndex = ifIndex;
++ sprintf ( nPd.UID, "%04d\0", nPd.ifIndex );
++ strcpy ( nPd.ifName, ifName );
++ addList (( char * ) &pdList, ( char * ) &nPd, sizeof ( nPd ));
++ }
++
++ if ( hasChanged (( char * ) &nPi, sizeof ( nPi ))) {
++ nPi.ifIndex = ifIndex;
++ sprintf ( nPi.UID, "%04d\0", nPi.ifIndex );
++ strcpy ( nPi.ifName, ifName );
++ addList (( char * ) &piList, ( char * ) &nPi, sizeof ( nPi ));
++ }
++ }
++
++//printf ( "%s - ifIndex: %d ifName: %s UID: %s\n",
++// "load80211Structs() - HASCHANGED", ifIndex, ifName, nSc.UID );
++}
++
++/****************************************************************************
++* *
++* initStructs() - initialize structures *
++* *
++****************************************************************************/
++static void initStructs()
++{
++ int i;
++
++ // 802.11 MIB Stuctures
++ memset (( char * ) &nSc, 0, sizeof ( nSc )); memset (( char * ) &nAa, 0, sizeof ( nAa ));
++ memset (( char * ) &nDf, 0, sizeof ( nDf )); memset (( char * ) &nKm, 0, sizeof ( nKm ));
++ memset (( char * ) &nPr, 0, sizeof ( nPr )); memset (( char * ) &nOp, 0, sizeof ( nOp ));
++ memset (( char * ) &nCo, 0, sizeof ( nCo )); memset (( char * ) &nGa, 0, sizeof ( nGa ));
++ memset (( char * ) &nRi, 0, sizeof ( nRi )); memset (( char * ) &nPo, 0, sizeof ( nPo ));
++ memset (( char * ) &nPa, 0, sizeof ( nPa )); memset (( char * ) &nPt, 0, sizeof ( nPt ));
++ memset (( char * ) &nPf, 0, sizeof ( nPf )); memset (( char * ) &nPd, 0, sizeof ( nPd ));
++ memset (( char * ) &nPi, 0, sizeof ( nPi )); memset (( char * ) &nRd, 0, sizeof ( nRd ));
++ memset (( char * ) &nAl, 0, sizeof ( nAl )); memset (( char * ) &nRt, 0, sizeof ( nRt ));
++ memset (( char * ) &nRr, 0, sizeof ( nRr ));
++
++ // Wireless Extensions
++ wepCurrentKey = 0;
++ haveWepCurrentKey = FALSE;
++ for ( i = 0; i < MAX_WEP_KEYS; i++ ) {
++ wep[i].len = 0;
++ wep[i].key[0] = '\0';
++ wep[i].haveKey = FALSE;
++ }
++}
++
++/****************************************************************************
++* *
++* Wireless Extensions Specific Functions *
++* *
++****************************************************************************/
++/****************************************************************************
++* *
++* loadWiExtTo80211Structs() - load wireless extensions to 802.11 structures *
++* *
++****************************************************************************/
++static void
++loadWiExtTo80211Structs ( int ifIndex, char *ifName, struct wireless_info *wi )
++{
++ int i, j = 0;
++
++ // dot11Smt Group
++ // dot11StationConfigTable
++ nSc.havePrivacyOptionImplemented = TRUE;
++ nSc.privacyOptionImplemented = 1; // assume we support WEP
++
++ if ( wi->has_power ) {
++ nSc.havePowerManagementMode = TRUE;
++ nSc.powerManagementMode = 1; // assume power is active
++ if ( !wi->power.disabled &&
++ wi->power.flags & IW_POWER_MIN )
++ nSc.powerManagementMode = 2; // power save mode
++ }
++
++ if ( wi->has_essid && strlen ( wi->essid )) {
++ nSc.haveDesiredSSID = TRUE;
++ strcpy ( nSc.desiredSSID, wi->essid );
++ }
++
++ if ( wi->has_mode ) {
++ nSc.haveDesiredBSSType = TRUE;
++ if ( wi->mode == IW_MODE_ADHOC )
++ nSc.desiredBSSType = 2; // independent
++ else if ( wi->has_ap_addr )
++ nSc.desiredBSSType = 1; // infrastructure
++ else
++ nSc.desiredBSSType = 3; // any
++ }
++
++ if ( wi->has_range ) {
++ for ( i = 0; i < wi->range.num_bitrates && j < 126; i++ ) {
++ nSc.haveOperationalRateSet = TRUE;
++ nSc.operationalRateSet[j++] = ( char ) ( wi->range.bitrate[i] / 500000L );
++ }
++ }
++
++ // dot11AuthenticationAlgorithmsTable
++ nAa.haveAuthenticationAlgorithm = TRUE; // it's a rule to always have
++ nAa.haveAuthenticationAlgorithmsEnable = TRUE; // 'open' supported
++ nAa.ifIndex = ifIndex;
++ nAa.authenticationAlgorithmsIndex = 1; // index number one
++ nAa.authenticationAlgorithm = 1; // 1 => open key
++ sprintf ( nAa.UID, "%04d%04d\0", nAa.ifIndex, nAa.authenticationAlgorithmsIndex );
++ nAa.authenticationAlgorithmsEnable = 1; // enabled by default
++ if ( ( wi->has_key ) &&
++ ( wi->key_size != 0 ) &&
++ !( wi->key_flags & IW_ENCODE_DISABLED ))
++ nAa.authenticationAlgorithmsEnable = 2;
++ addList (( char * ) &aaList, ( char * ) &nAa, sizeof ( nAa ));
++
++ nAa.haveAuthenticationAlgorithm = TRUE; // I'm gonna assume we always support WEP
++ nAa.haveAuthenticationAlgorithmsEnable = TRUE;
++ nAa.ifIndex = ifIndex;
++ nAa.authenticationAlgorithmsIndex = 2; // index number 2
++ nAa.authenticationAlgorithm = 2; // 2 => shared key
++ sprintf ( nAa.UID, "%04d%04d\0", nAa.ifIndex, nAa.authenticationAlgorithmsIndex );
++ nAa.authenticationAlgorithmsEnable = 2;
++ if ( ( wi->has_key ) &&
++ ( wi->key_size != 0 ) &&
++ !( wi->key_flags & IW_ENCODE_DISABLED ))
++ nAa.authenticationAlgorithmsEnable = 1; // disabled by default
++ addList (( char * ) &aaList, ( char * ) &nAa, sizeof ( nAa ));
++
++ //dot11WEPDefaultKeysTable
++ if ( wi->has_range ) {
++ for ( i = 0; i < MAX_WEP_KEYS; i++ ) {
++ nDf.haveWEPDefaultKeyValue = TRUE;
++ nDf.ifIndex = ifIndex;
++ nDf.WEPDefaultKeyIndex = i + 1; // index number
++ sprintf ( nDf.UID, "%04d%04d\0", nDf.ifIndex, nDf.WEPDefaultKeyIndex );
++ if ( wep[i].haveKey )
++ strcpy ( nDf.WEPDefaultKeyValue, "*****" );
++ else
++ nDf.WEPDefaultKeyValue[0] = '\0';
++ addList (( char * ) &dfList, ( char * ) &nDf, sizeof ( nDf ));
++ }
++ }
++
++ // dot11PrivacyTable
++ nPr.havePrivacyInvoked = TRUE;
++ nPr.privacyInvoked = 2; // 2 => FALSE
++ nPr.haveWEPDefaultKeyID = TRUE;
++ nPr.WEPDefaultKeyID = 0;
++ nPr.haveExcludeUnencrypted = TRUE;
++ nPr.excludeUnencrypted = 2; // 2 => FALSE
++ if ( wi->has_range ) {
++ if ( ( wi->key_size != 0 ) &&
++ !( wi->key_flags & IW_ENCODE_DISABLED )) {
++ nPr.privacyInvoked = 1;
++ if ( wi->key_flags & IW_ENCODE_RESTRICTED )
++ nPr.excludeUnencrypted = 1;
++ nPr.WEPDefaultKeyID = wepCurrentKey;
++ }
++ }
++
++ // dot11Mac Group
++ // dot11OperationTable
++ if ( wi->has_range ) {
++ nOp.haveRTSThreshold = TRUE;
++ nOp.RTSThreshold = wi->range.max_rts;
++ }
++
++ if ( wi->has_frag && wi->frag.value ) {
++ nOp.haveFragmentationThreshold = TRUE;
++ nOp.fragmentationThreshold = wi->frag.value;
++ }
++
++ // dot11Phy Group
++ // dot11PhyOperationTable
++ if ( strstr ( wi->name, "IEEE 802.11-FS" )) nPo.PHYType = 1; // So what if I
++ if ( strstr ( wi->name, "IEEE 802.11-DS" )) nPo.PHYType = 2; // made up a couple?
++ if ( strstr ( wi->name, "IEEE 802.11-IR" )) nPo.PHYType = 3;
++ if ( strstr ( wi->name, "IEEE 802.11-OFDM" )) nPo.PHYType = 4; // 802.11a
++ if ( strstr ( wi->name, "IEEE 802.11-OFDM/DS" )) nPo.PHYType = 5; // 802.11g
++ if ( strstr ( wi->name, "IEEE 802.11-TURBO" )) nPo.PHYType = 6; // Atheros TURBO mode
++ if ( nPo.PHYType ) nPo.havePHYType = TRUE;
++
++ // dot11PhyDSSSTable
++ if ( wi->has_range ) { // && wi->freq <= ( double ) 2483000000 ) { // DSSS frequencies only
++ for ( i = 0; i < wi->range.num_frequency; i++ ) {
++ if ((( double ) ( wi->range.freq[i].e * 10 ) * ( double ) wi->range.freq[i].m ) == wi->freq ) {
++ nPd.haveCurrentChannel = TRUE;
++ nPd.currentChannel = wi->range.freq[i].i;
++ }
++ }
++ }
++
++ // dot11SupportedDataRatesTxTable
++ if ( wi->has_range ) {
++ for ( i = 0; i < wi->range.num_bitrates; i++ ) {
++ nRt.ifIndex = ifIndex;
++ nRt.supportedDataRatesTxIndex = i + 1;
++ nRt.supportedDataRatesTxValue = wi->range.bitrate[i] / 500000L;
++ nRt.haveSupportedDataRatesTxValue = TRUE;
++ sprintf ( nRt.UID, "%04d%04d\0", nRt.ifIndex, nRt.supportedDataRatesTxIndex );
++ strcpy ( nRt.ifName, ifName );
++ addList (( char * ) &rtList, ( char * ) &nRt, sizeof ( nRt ));
++ }
++ }
++
++ // dot11SupportedDataRatesRxTable
++ if ( wi->has_range ) {
++ for ( i = 0; i < wi->range.num_bitrates; i++ ) {
++ nRr.ifIndex = ifIndex;
++ nRr.supportedDataRatesRxIndex = i + 1;
++ nRr.supportedDataRatesRxValue = wi->range.bitrate[i] / 500000L;
++ nRr.haveSupportedDataRatesRxValue = TRUE;
++ sprintf ( nRr.UID, "%04d%04d\0", nRr.ifIndex, nRr.supportedDataRatesRxIndex );
++ strcpy ( nRr.ifName, ifName );
++ addList (( char * ) &rrList, ( char * ) &nRr, sizeof ( nRr ));
++ }
++ }
++
++//printf ( "%s max_encoding_tokens: %d\n",
++// "loadWiExtTo80211Structs() - ", wi->range.max_encoding_tokens );
++}
++
++/****************************************************************************
++* *
++* loadWiExt() - load wireless extensions structures; *
++* use ioctl calls and read /proc/net/wireless *
++* *
++****************************************************************************/
++static void loadWiExt ( int skfd, char *ifname, struct wireless_info *wi )
++{
++ struct iwreq wrq; // ioctl request structure
++ FILE *fp;
++ char bfr[1024];
++ char buffer[sizeof ( iwrange ) * 2]; /* Large enough */
++ char *s, *t;
++ int i, j;
++
++ strncpy ( wrq.ifr_name, ifname, IFNAMSIZ );
++
++ /* Get wireless name */
++ if ( ioctl ( skfd, SIOCGIWNAME, &wrq ) >= 0 ) {
++ strncpy ( wi->name, wrq.u.name, IFNAMSIZ );
++ wi->name[IFNAMSIZ] = '\0';
++ }
++
++ /* Get ranges */ // NOTE: some version checking in iwlib.c
++ memset ( buffer, 0, sizeof ( buffer ));
++ wrq.u.data.pointer = ( caddr_t ) &buffer;
++ wrq.u.data.length = sizeof ( buffer );
++ wrq.u.data.flags = 0;
++ if ( ioctl ( skfd, SIOCGIWRANGE, &wrq ) >= 0 ) {
++ memcpy (( char * ) &wi->range, buffer, sizeof ( iwrange ));
++ wi->has_range = 1;
++ }
++
++ /* Get network ID */
++ if ( ioctl ( skfd, SIOCGIWNWID, &wrq ) >= 0 ) {
++ memcpy ( &wi->nwid, &wrq.u.nwid, sizeof ( iwparam ));
++ wi->has_nwid = 1;
++ }
++
++ /* Get frequency / channel */ // THIS NUMBER LOOKS FUNNY
++ if ( ioctl ( skfd, SIOCGIWFREQ, &wrq ) >= 0 ) {
++ wi->has_freq = 1;
++ wi->freq = (( double ) wrq.u.freq.m ) * pow ( 10, wrq.u.freq.e );
++ }
++
++ /* Get sensitivity */
++ if ( ioctl ( skfd, SIOCGIWSENS, &wrq ) >= 0 ) {
++ wi->has_sens = 1;
++ memcpy ( &wi->sens, &wrq.u.sens, sizeof ( iwparam ));
++ }
++
++ /* Get encryption information */
++ wrq.u.data.pointer = ( caddr_t ) &wi->key;
++ wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
++ wrq.u.data.flags = 0;
++ if ( ioctl ( skfd, SIOCGIWENCODE, &wrq ) >= 0 ) {
++ wi->has_key = 1;
++ wi->key_size = wrq.u.data.length;
++ wi->key_flags = wrq.u.data.flags;
++ wepCurrentKey = wrq.u.data.flags & IW_ENCODE_INDEX;
++ }
++
++ for ( i = 0; i < wi->range.max_encoding_tokens; i++ ) {
++ wrq.u.data.pointer = ( caddr_t ) &wi->key;
++ wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
++ wrq.u.data.flags = i;
++ if ( ioctl ( skfd, SIOCGIWENCODE, &wrq ) >= 0 ) {
++ if ( ( wrq.u.data.length != 0 ) &&
++ !( wrq.u.data.flags & IW_ENCODE_DISABLED )) {
++ wep[i].len = wrq.u.data.length;
++ wep[i].haveKey = TRUE;
++ t = wep[i].key;
++ for ( j = 0; j < wrq.u.data.length; j++ ) {
++ if (( j & 0x1 ) == 0 && j != 0 )
++ strcpy ( t++, "-");
++ sprintf ( t, "%.2X", wi->key[j] );
++ t += 2;
++ }
++ t = '\0';
++ }
++ }
++ }
++
++ /* Get ESSID */
++ wrq.u.essid.pointer = ( caddr_t ) &wi->essid;
++ wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
++ wrq.u.essid.flags = 0;
++ if ( ioctl ( skfd, SIOCGIWESSID, &wrq ) >= 0 ) {
++ wi->has_essid = 1;
++ wi->essid_on = wrq.u.data.flags;
++ }
++
++ /* Get AP address */
++ if ( ioctl ( skfd, SIOCGIWAP, &wrq ) >= 0 ) {
++ wi->has_ap_addr = 1;
++ memcpy ( &wi->ap_addr, &wrq.u.ap_addr, sizeof ( sockaddr ));
++ }
++
++ /* Get NickName */
++ wrq.u.essid.pointer = ( caddr_t ) &wi->nickname;
++ wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
++ wrq.u.essid.flags = 0;
++ if ( ioctl ( skfd, SIOCGIWNICKN, &wrq ) >= 0 ) {
++ if ( wrq.u.data.length > 1 )
++ wi->has_nickname = 1;
++ }
++
++ /* Get bit rate */
++ if ( ioctl ( skfd, SIOCGIWRATE, &wrq ) >= 0 ) {
++ wi->has_bitrate = 1;
++ memcpy ( &wi->bitrate, &wrq.u.bitrate, sizeof ( iwparam ));
++ }
++
++ /* Get RTS threshold */
++ if ( ioctl ( skfd, SIOCGIWRTS, &wrq ) >= 0 ) {
++ wi->has_rts = 1;
++ memcpy ( &wi->rts, &wrq.u.rts, sizeof ( iwparam ));
++ }
++
++ /* Get fragmentation threshold */
++ if ( ioctl ( skfd, SIOCGIWFRAG, &wrq ) >= 0 ) {
++ wi->has_frag = 1;
++ memcpy ( &wi->frag, &wrq.u.frag, sizeof ( iwparam ));
++ }
++
++ /* Get operation mode */
++ if ( ioctl ( skfd, SIOCGIWMODE, &wrq ) >= 0 ) {
++ wi->mode = wrq.u.mode;
++ if ( wi->mode < IW_NUM_OPER_MODE && wi->mode >= 0 )
++ wi->has_mode = 1;
++ }
++
++ /* Get Power Management settings */ // #if WIRELESS_EXT > 9
++ wrq.u.power.flags = 0;
++ if ( ioctl ( skfd, SIOCGIWPOWER, &wrq ) >= 0 ) {
++ wi->has_power = 1;
++ memcpy ( &wi->power, &wrq.u.power, sizeof ( iwparam ));
++ }
++
++ /* Get retry limit/lifetime */ // #if WIRELESS_EXT > 10
++ if ( ioctl ( skfd, SIOCGIWRETRY, &wrq ) >= 0 ) {
++ wi->has_retry = 1;
++ memcpy ( &wi->retry, &wrq.u.retry, sizeof ( iwparam ));
++ }
++
++ /* Get stats */ // #if WIRELESS_EXT > 11
++ wrq.u.data.pointer = ( caddr_t ) &wi->stats;
++ wrq.u.data.length = 0;
++ wrq.u.data.flags = 1; /* Clear updated flag */
++ if ( ioctl ( skfd, SIOCGIWSTATS, &wrq ) < 0 )
++ wi->has_stats = 1;
++
++ if ( !wi->has_stats ) { // no ioctl support, go to file
++ fp = fopen ( PROC_NET_WIRELESS, "r" );
++ if ( fp ) {
++ while ( fgets ( bfr, sizeof ( bfr ), fp )) {
++ bfr [ sizeof ( bfr ) - 1 ] = '\0'; // no buffer overruns here!
++ strtok (( char * ) &bfr, "\n" ); // '\n' => '\0'
++ if ( strstr ( bfr, ifname ) && strstr ( bfr, ":" )) {
++ wi->has_stats = 1;
++ s = bfr;
++ s = strchr ( s, ':' ); s++; /* Skip ethX: */
++ s = strtok ( s, " " ); /* ' ' => '\0' */
++ sscanf ( s, "%X", &wi->stats.status ); // status
++
++ s = strtok ( NULL, " " ); // link quality
++ if ( strchr ( s, '.' ) != NULL )
++ wi->stats.qual.updated |= 1;
++ sscanf ( s, "%d", &wi->stats.qual.qual );
++
++ s = strtok ( NULL, " " ); // signal level
++ if ( strchr ( s,'.' ) != NULL )
++ wi->stats.qual.updated |= 2;
++ sscanf ( s, "%d", &wi->stats.qual.level );
++
++ s = strtok ( NULL, " " ); // noise level
++ if ( strchr ( s, '.' ) != NULL )
++ wi->stats.qual.updated += 4;
++ sscanf ( s, "%d", &wi->stats.qual.noise );
++
++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.nwid );
++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.code );
++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.fragment );
++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.retries );
++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.misc );
++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.miss.beacon );
++ }
++ }
++ fclose ( fp );
++ }
++ }
++
++// printf ( "%s bfr: %s\n", "loadTables()", bfr );
++}
++
++/****************************************************************************
++* *
++* displayWiExt() - show what I got from Wireless Extensions *
++* *
++****************************************************************************/
++static void displayWiExt ( struct wireless_info info )
++{
++#ifdef DISPLAYWIEXT
++ int i;
++ char title[] = "displayWiExt() -";
++
++ printf ( "========================================\n" );
++ printf ( "===> Wireless Extension IOCTL calls <===\n" );
++ printf ( "========================================\n" );
++
++ if ( strlen ( info.name ))
++ printf ( "%s name: %s\n", "SIOCGIWNAME", info.name );
++ else
++ printf ( "%s\n", "no info.name support" );
++
++ if ( info.has_nickname = 1 )
++ printf ( "%s nickname: %s\n", "SIOCGIWNICKN", info.nickname );
++ else
++ printf ( "%s %s\n", "SIOCGIWNICKN", " ===> no info.nickname support" );
++
++ if ( info.has_essid )
++ printf ( "%s essid_on: %d essid: %s\n", "SIOCGIWESSID", info.essid_on, info.essid );
++ else
++ printf ( "%s %s\n", "SIOCGIWESSID", " ===> no info.essid support" );
++
++ if ( info.has_range ) {
++ printf ( "%s throughput: %d\n", "SIOCGIWRANGE", info.range.throughput );
++ printf ( "%s min_nwid: %d\n", "SIOCGIWRANGE", info.range.min_nwid );
++ printf ( "%s max_nwid: %d\n", "SIOCGIWRANGE", info.range.max_nwid );
++ printf ( "%s sensitivity: %d\n", "SIOCGIWRANGE", info.range.sensitivity );
++ printf ( "%s num_bitrates: %d\n", "SIOCGIWRANGE", info.range.num_bitrates );
++ for ( i = 0; i < info.range.num_bitrates; i++ )
++ printf ( "%s bitrate[%d]: %d\n", "SIOCGIWRANGE", i, info.range.bitrate[i] );
++ printf ( "%s min_rts: %d\n", "SIOCGIWRANGE", info.range.min_rts );
++ printf ( "%s max_rts: %d\n", "SIOCGIWRANGE", info.range.max_rts );
++ printf ( "%s min_frag: %d\n", "SIOCGIWRANGE", info.range.min_frag );
++ printf ( "%s max_frag: %d\n", "SIOCGIWRANGE", info.range.max_frag );
++ printf ( "%s min_pmp: %d\n", "SIOCGIWRANGE", info.range.min_pmp );
++ printf ( "%s max_pmp: %d\n", "SIOCGIWRANGE", info.range.max_pmp );
++ printf ( "%s min_pmt: %d\n", "SIOCGIWRANGE", info.range.min_pmt );
++ printf ( "%s max_pmt: %d\n", "SIOCGIWRANGE", info.range.max_pmt );
++ printf ( "%s pmp_flags: %d\n", "SIOCGIWRANGE", info.range.pmp_flags );
++ printf ( "%s pmt_flags: %d\n", "SIOCGIWRANGE", info.range.pmt_flags );
++ printf ( "%s pm_capa: %d\n", "SIOCGIWRANGE", info.range.pm_capa );
++ printf ( "%s num_encoding_sizes: %d\n", "SIOCGIWRANGE", info.range.num_encoding_sizes );
++ for ( i = 0; i < info.range.num_encoding_sizes; i++ )
++ printf ( "%s encoding_size[%d]: %d\n", "SIOCGIWRANGE", i, info.range.encoding_size[i] );
++ printf ( "%s max_encoding_tokens: %d\n", "SIOCGIWRANGE", info.range.max_encoding_tokens );
++// printf ( "%s encoding_login_index: %d\n", "SIOCGIWRANGE", info.range.encoding_login_index );
++ printf ( "%s txpower_capa: %d\n", "SIOCGIWRANGE", info.range.txpower_capa );
++ printf ( "%s num_txpower: %d dBm\n", "SIOCGIWRANGE", info.range.num_txpower );
++ for ( i = 0; i < info.range.num_txpower; i++ )
++ printf ( "%s txpower[%d]: %d\n", "SIOCGIWRANGE", i, info.range.txpower[i] );
++ printf ( "%s we_version_compiled: %d\n", "SIOCGIWRANGE", info.range.we_version_compiled );
++ printf ( "%s we_version_source: %d\n", "SIOCGIWRANGE", info.range.we_version_source );
++ printf ( "%s retry_capa: %d\n", "SIOCGIWRANGE", info.range.retry_capa );
++ printf ( "%s retry_flags: %d\n", "SIOCGIWRANGE", info.range.retry_flags );
++ printf ( "%s r_time_flags: %d\n", "SIOCGIWRANGE", info.range.r_time_flags );
++ printf ( "%s min_retry: %d\n", "SIOCGIWRANGE", info.range.min_retry );
++ printf ( "%s max_retry: %d\n", "SIOCGIWRANGE", info.range.max_retry );
++ printf ( "%s min_r_time: %d\n", "SIOCGIWRANGE", info.range.min_r_time );
++ printf ( "%s max_r_time: %d\n", "SIOCGIWRANGE", info.range.max_r_time );
++ printf ( "%s num_channels: %d\n", "SIOCGIWRANGE", info.range.num_channels );
++ printf ( "%s num_frequency: %d\n", "SIOCGIWRANGE", info.range.num_frequency );
++ for ( i = 0; i < info.range.num_frequency; i++ )
++ printf ( "%s freq[%d].i: %d freq[%d].e: %d freq[%d].m: %d\n", "SIOCGIWRANGE",
++ i, info.range.freq[i].i, i, info.range.freq[i].e, i, info.range.freq[i].m );
++ }
++ else
++ printf ( "%s %s\n", "SIOCGIWRANGE", " ===> no info.range support" );
++
++ if ( info.has_nwid )
++ printf ( "%s nwid - disabled: %d value: %X\n", "SIOCGIWNWID", info.nwid.disabled, info.nwid.value );
++ else
++ printf ( "%s %s\n", "SIOCGIWNWID", " ===> no info.nwid support" );
++
++ if ( info.has_freq ) {
++// printf ( "%s freq: %g\n", "SIOCGIWFREQ", info.freq / GIGA );
++ printf ( "%s freq: %g\n", "SIOCGIWFREQ", info.freq );
++ }
++ else
++ printf ( "%s %s\n", "SIOCGIWFREQ", " ===> no info.freq support" );
++
++ if ( info.has_sens )
++ printf ( "%s sens: %d\n", "SIOCGIWSENS", info.sens );
++ else
++ printf ( "%s %s\n", "SIOCGIWSENS", " ===> no info.sens support" );
++
++ if ( info.has_key ) {
++ printf ( "%s key_size: %d key_flags: %d wepCurrentKey: %d\n",
++ "SIOCGIWENCODE", info.key_size, info.key_flags, wepCurrentKey );
++ printf ( "%s MODE: %d DISABLED: %d INDEX: %d OPEN: %d RESTRICTED: %d NOKEY: %d TEMP: %d\n",
++ "SIOCGIWENCODE", info.key_flags & IW_ENCODE_MODE,
++ info.key_flags & IW_ENCODE_DISABLED ? 1:0, info.key_flags & IW_ENCODE_INDEX,
++ info.key_flags & IW_ENCODE_OPEN ? 1:0, info.key_flags & IW_ENCODE_RESTRICTED ? 1:0,
++ info.key_flags & IW_ENCODE_NOKEY ? 1:0, info.key_flags & IW_ENCODE_TEMP ? 1:0 );
++ }
++ else
++ printf ( "%s %s\n", "SIOCGIWENCODE", " ===> no info.key support" );
++
++ for ( i = 0; i < MAX_WEP_KEYS; i++ ) {
++ if ( wep[i].haveKey )
++ printf ( "%s wep[%d].len: %d wep[%d].key: %s\n",
++ "SIOCGIWENCODE", i, wep[i].len, i, wep[i].key );
++ }
++
++ if ( info.has_ap_addr )
++ printf ( "%s ap_addr.sa_data: %02X:%02X:%02X:%02X:%02X:%02X ap_addr.sa_family: %d\n",
++ "SIOCGIWAP", ( UCHAR ) info.ap_addr.sa_data[0], ( UCHAR ) info.ap_addr.sa_data[1],
++ ( UCHAR ) info.ap_addr.sa_data[2], ( UCHAR ) info.ap_addr.sa_data[3],
++ ( UCHAR ) info.ap_addr.sa_data[4], ( UCHAR ) info.ap_addr.sa_data[5],
++ info.ap_addr.sa_family );
++ else
++ printf ( "%s %s\n", "SIOCGIWAP", " ===> no ap_addr information" );
++
++ if ( info.has_bitrate )
++ printf ( "%s bitrate: %d value: %d fixed: %d disabled: %d flags: %d\n",
++ "SIOCGIWRATE", info.bitrate, info.bitrate.value, info.bitrate.fixed,
++ info.bitrate.disabled, info.bitrate.flags );
++ else
++ printf ( "%s %s\n", "SIOCGIWRATE", " ===> no info.bitrate support" );
++
++ if ( info.has_rts )
++ printf ( "%s rts: %d\n", "SIOCGIWRTS", info.rts );
++ else
++ printf ( "%s %s\n", "SIOCGIWRTS", " ===> no info.rts support" );
++
++ if ( info.has_frag )
++ printf ( "%s frag: %d\n", "SIOCGIWFRAG", info.frag );
++ else
++ printf ( "%s %s\n", "SIOCGIWFRAG", " ===> no info.frag support" );
++
++ if ( info.has_mode )
++ printf ( "%s mode: %d\n", "SIOCGIWMODE", info.mode );
++ else
++ printf ( "%s %s\n", "SIOCGIWMODE", " ===> no info.mode support" );
++
++ if ( info.has_power ) {
++ printf ( "%s power: %d\n", "SIOCGIWPOWER", info.power );
++ printf ( "%s disabled: %d MIN: %d MAX: %d TIMEOUT: %d RELATIVE: %d\n",
++ "SIOCGIWPOWER",
++ info.power.disabled ? 1:0,
++ info.power.flags & IW_POWER_MIN ? 1:0,
++ info.power.flags & IW_POWER_MAX ? 1:0,
++ info.power.flags & IW_POWER_TIMEOUT ? 1:0,
++ info.power.flags & IW_POWER_RELATIVE ? 1:0 );
++ printf ( "%s UNICAST: %d MULTICAST: %d ALL: %d FORCE: %d REPEATER: %d\n",
++ "SIOCGIWPOWER",
++ info.power.flags & IW_POWER_UNICAST_R ? 1:0,
++ info.power.flags & IW_POWER_MULTICAST_R ? 1:0,
++ info.power.flags & IW_POWER_ALL_R ? 1:0,
++ info.power.flags & IW_POWER_FORCE_S ? 1:0,
++ info.power.flags & IW_POWER_REPEATER ? 1:0 );
++ }
++ else
++ printf ( "%s %s\n", "SIOCGIWPOWER", " ===> no info.power support" );
++
++ if ( info.has_retry )
++ printf ( "%s retry: %d\n", "SIOCGIWRETRY", info.retry );
++ else
++ printf ( "%s %s\n", "SIOCGIWRETRY", " ===> no info.retry support" );
++
++ if ( info.has_stats ) {
++ printf ( "%s status: %d\n", "SIOCGIWSTATS", info.stats.status );
++ printf ( "%s qual.level: %d\n", "SIOCGIWSTATS", info.stats.qual.level );
++ printf ( "%s qual.noise: %d\n", "SIOCGIWSTATS", info.stats.qual.noise );
++ printf ( "%s qual.qual: %d\n", "SIOCGIWSTATS", info.stats.qual.qual );
++ printf ( "%s qual.updated: %d\n", "SIOCGIWSTATS", info.stats.qual.updated );
++ printf ( "%s discard.code: %d\n", "SIOCGIWSTATS", info.stats.discard.code );
++ printf ( "%s discard.fragment: %d\n", "SIOCGIWSTATS", info.stats.discard.fragment );
++ printf ( "%s discard.misc: %d\n", "SIOCGIWSTATS", info.stats.discard.misc );
++ printf ( "%s discard.nwid: %d\n", "SIOCGIWSTATS", info.stats.discard.nwid );
++ printf ( "%s discard.retries: %d\n", "SIOCGIWSTATS", info.stats.discard.retries );
++ printf ( "%s miss.beacon: %d\n", "SIOCGIWSTATS", info.stats.miss.beacon );
++ }
++ else
++ printf ( "%s %s\n", "SIOCGIWSTATS", " ===> no info.stats support" );
++
++ if ( info.txpower.flags & IW_TXPOW_MWATT )
++ printf ( "%s txpower1: %d dBm disabled: %d fixed: %d flags: %d\n", "SIOCGIWRANGE",
++ mWatt2dbm ( info.txpower.value ), info.txpower.disabled, info.txpower.fixed, info.txpower.flags);
++ else
++ printf ( "%s txpower2: %d dBm disabled: %d fixed: %d flags: %d\n", "SIOCGIWRANGE", info.txpower.value, info.txpower.disabled, info.txpower.fixed, info.txpower.flags );
++
++ if ( info.has_range )
++ if ( info.sens.value < 0 )
++ printf ( "%s sens: %d dBm\n", "SIOCGIWRANGE", info.sens.value );
++ else
++ printf ( "%s sens: %d/%d\n", "SIOCGIWRANGE", info.sens.value, info.range.sensitivity );
++
++ if ( info.has_range && ( info.stats.qual.level != 0 ))
++ if ( info.stats.qual.level > info.range.max_qual.level )
++ /* Statistics are in dBm (absolute power measurement) */
++ printf ( "%s Quality: %d/%d Signal level: %d dBm Noise level: %d dBm\n",
++ "SIOCGIWRANGE",
++ info.stats.qual.qual, info.range.max_qual.qual,
++ info.stats.qual.level - 0x100,
++ info.stats.qual.noise - 0x100 );
++ else
++ printf ( "%s Quality: %d/%d Signal level: %d/%d Noise level: %d/%d",
++ "SIOCGIWRANGE",
++ info.stats.qual.qual, info.range.max_qual.qual,
++ info.stats.qual.level, info.range.max_qual.level,
++ info.stats.qual.noise, info.range.max_qual.noise );
++
++#endif // #ifdef DISPLAYWIEXT
++}
++
++/****************************************************************************
++* *
++* Linked List Functions *
++* *
++****************************************************************************/
++/****************************************************************************
++* *
++* addList() - add an entry to a linked list *
++* *
++****************************************************************************/
++static void
++addList ( char *l, char *data, int len )
++{
++ char uid[256];
++ LIST_HEAD ( , avNode ) *list;
++
++ // NOTE: this assumes the UID is at the beginning of the
++ // data structure and that UIDs are strings
++
++ list = ( LIST_HEAD ( , avNode ) * ) l; // NOTE: don't know how to get
++ strcpy ( uid, data ); // rid of compiler warning on
++ // LISTHEAD typecast
++ // create a new node and the data that goes in it
++ newNode = malloc ( sizeof ( struct avNode ));
++ newNode->data = malloc ( len );
++ memcpy ( newNode->data, data, len );
++
++ // this deals with an empty list
++ if ( LIST_EMPTY ( list )) {
++ LIST_INSERT_HEAD ( list, newNode, nodes );
++ return;
++ }
++
++ // this deals with UIDs that match
++ for ( np = LIST_FIRST ( list ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ if ( strncmp ( uid, np->data, strlen ( uid )) == 0 ) { // found matching UID
++ LIST_INSERT_AFTER ( np, newNode, nodes );
++ if ( np->data )
++ free ( np->data );
++ LIST_REMOVE ( np, nodes );
++ free ( np );
++ return;
++ }
++ }
++
++ // this deals with inserting a new UID in the list
++ for ( np = LIST_FIRST ( list ); np != NULL; np = LIST_NEXT ( np, nodes )) {
++ lastNode = np;
++ if ( strncmp ( np->data, uid, strlen ( uid )) > 0 ) { // old ID > new ID AND
++ LIST_INSERT_BEFORE ( np, newNode, nodes );
++ return;
++ }
++ }
++
++ // this deals with a UID that needs to go on the end of the list
++ LIST_INSERT_AFTER ( lastNode, newNode, nodes );
++
++ return;
++}
++
++/****************************************************************************
++* *
++* initLists() - initialize all the linked lists *
++* *
++****************************************************************************/
++static void initLists()
++{
++ LIST_INIT ( &scList ); LIST_INIT ( &aaList ); LIST_INIT ( &dfList );
++ LIST_INIT ( &kmList ); LIST_INIT ( &prList );
++ LIST_INIT ( &opList ); LIST_INIT ( &coList );
++ LIST_INIT ( &gaList ); LIST_INIT ( &riList ); LIST_INIT ( &poList );
++ LIST_INIT ( &paList ); LIST_INIT ( &ptList ); LIST_INIT ( &pfList );
++ LIST_INIT ( &pdList ); LIST_INIT ( &piList ); LIST_INIT ( &rdList );
++ LIST_INIT ( &alList ); LIST_INIT ( &rtList ); LIST_INIT ( &rrList );
++}
++/****************************************************************************
++* *
++* flushLists() - flush all linked lists *
++* *
++****************************************************************************/
++static void flushLists()
++{
++ flushList (( char * ) &scList ); flushList (( char * ) &aaList );
++ flushList (( char * ) &dfList ); flushList (( char * ) &kmList );
++ flushList (( char * ) &prList );
++ flushList (( char * ) &opList ); flushList (( char * ) &coList );
++ flushList (( char * ) &gaList ); flushList (( char * ) &riList );
++ flushList (( char * ) &poList ); flushList (( char * ) &paList );
++ flushList (( char * ) &ptList ); flushList (( char * ) &pfList );
++ flushList (( char * ) &pdList ); flushList (( char * ) &piList );
++ flushList (( char * ) &rdList ); flushList (( char * ) &alList );
++ flushList (( char * ) &rtList ); flushList (( char * ) &rrList );
++}
++
++/****************************************************************************
++* *
++* flushList() - flush a linked list *
++* *
++****************************************************************************/
++static void flushList ( char *l )
++{
++ LIST_HEAD ( , avNode ) *list;
++
++ list = ( LIST_HEAD ( , avNode ) * ) l; // NOTE: don't know how to get
++ while ( !LIST_EMPTY ( list )) { // rid of compiler warning on
++ np = LIST_FIRST ( list ); // LISTHEAD typecast
++ if ( np->data )
++ free ( np->data );
++ LIST_REMOVE ( np, nodes );
++ free ( np );
++ }
++}
++
++/****************************************************************************
++* *
++* Utility Functions *
++* *
++****************************************************************************/
++/****************************************************************************
++* *
++* The following two routines were taken directly from iwlib.c *
++* *
++****************************************************************************/
++ /*
++ * Open a socket.
++ * Depending on the protocol present, open the right socket. The socket
++ * will allow us to talk to the driver.
++ */
++static int openSocket ( void )
++{
++ static const int families[] = {
++ AF_INET, AF_IPX, AF_AX25, AF_APPLETALK
++ };
++ unsigned int i;
++ int sock;
++
++ /*
++ * Now pick any (exisiting) useful socket family for generic queries
++ * Note : don't open all the socket, only returns when one matches,
++ * all protocols might not be valid.
++ * Workaround by Jim Kaba <jkaba@sarnoff.com>
++ * Note : in 99% of the case, we will just open the inet_sock.
++ * The remaining 1% case are not fully correct...
++ */
++
++ /* Try all families we support */
++ for(i = 0; i < sizeof(families)/sizeof(int); ++i) {
++ /* Try to open the socket, if success returns it */
++ sock = socket(families[i], SOCK_DGRAM, 0);
++ if(sock >= 0)
++ return sock;
++ }
++
++ return -1;
++}
++
++/*------------------------------------------------------------------*/
++/*
++ * Convert a value in milliWatt to a value in dBm.
++ */
++static int mWatt2dbm ( int in )
++{
++#ifdef WE_NOLIBM
++ /* Version without libm : slower */
++ double fin = (double) in;
++ int res = 0;
++
++ /* Split integral and floating part to avoid accumulating rounding errors */
++ while(fin > 10.0)
++ {
++ res += 10;
++ fin /= 10.0;
++ }
++ while(fin > 1.000001) /* Eliminate rounding errors, take ceil */
++ {
++ res += 1;
++ fin /= LOG10_MAGIC;
++ }
++ return(res);
++#else /* WE_NOLIBM */
++ /* Version with libm : faster */
++ return((int) (ceil(10.0 * log10((double) in))));
++#endif /* WE_NOLIBM */
++}
++
++/****************************************************************************
++* *
++* htob - converts hex string to binary *
++* *
++****************************************************************************/
++static char *htob ( char *s )
++{
++ char nibl, *byt;
++ static char bin[20];
++
++ byt = bin;
++
++ while ((nibl = *s++) && nibl != ' ') { /* While not end of string. */
++ nibl -= ( nibl > '9') ? ('A' - 10): '0';
++ *byt = nibl << 4; /* place high nibble */
++ if((nibl = *s++) && nibl != ' ') {
++ nibl -= ( nibl > '9') ? ('A' - 10): '0';
++ *byt |= nibl; /* place low nibble */
++ }
++ else break;
++ ++byt;
++ }
++ *++byt = '\0';
++ return ( bin );
++}
++
++/****************************************************************************
++* *
++* hasChanged() - see if area has been changed from NULLs *
++* *
++****************************************************************************/
++static int hasChanged ( char *loc, int len )
++{
++ char *wrk;
++ int changed = TRUE;
++
++ wrk = malloc ( len );
++ memset ( wrk, 0, len );
++ if ( memcmp ( loc, wrk, len ) == 0 )
++ changed = FALSE;
++ free ( wrk );
++
++ return ( changed );
++}
++
+--- /dev/null
++++ b/agent/mibgroup/ieee802dot11.h
+@@ -0,0 +1,730 @@
++/****************************************************************************
++* *
++* File Name: ieee802dot11.h *
++* Used By: *
++* *
++* Operating System: *
++* Purpose: *
++* *
++* Comments: *
++* *
++* Author: Larry Simmons *
++* lsimmons@avantcom.com *
++* www.avantcom.com *
++* *
++* Creation Date: 09/02/03 *
++* *
++* Ver Date Inits Modification *
++* ----- -------- ----- ------------ *
++* 0.0.1 09/02/03 LRS created *
++* 0.0.2 09/24/03 LRS wouldn't build after fresh ./configure *
++****************************************************************************/
++/* This file was generated by mib2c and is intended for use as a mib module
++ for the ucd-snmp snmpd agent. */
++#ifndef _MIBGROUP_IEEE802DOT11_H
++#define _MIBGROUP_IEEE802DOT11_H
++/* we may use header_generic and header_simple_table from the util_funcs module */
++
++/****************************************************************************
++* Includes *
++****************************************************************************/
++#include <sys/queue.h>
++
++/****************************************************************************
++* Linked List Defines *
++****************************************************************************/
++// here are some Linked List MACROS I wanted to use,
++// but curiously were not in /usr/includes/sys/queue.h
++
++#ifndef LIST_EMPTY
++ #define LIST_EMPTY(head) ((head)->lh_first == NULL)
++#endif
++
++#ifndef LIST_NEXT
++ #define LIST_NEXT(elm, field) ((elm)->field.le_next)
++#endif
++
++#ifndef LIST_INSERT_BEFORE
++ #define LIST_INSERT_BEFORE(listelm, elm, field) do { \
++ (elm)->field.le_prev = (listelm)->field.le_prev; \
++ LIST_NEXT((elm), field) = (listelm); \
++ *(listelm)->field.le_prev = (elm); \
++ (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
++ } while (0)
++#endif
++
++#ifndef LIST_FIRST
++ #define LIST_FIRST(head) ((head)->lh_first)
++#endif
++
++/****************************************************************************
++* 802.11 MIB Defines *
++****************************************************************************/
++#define SYS_STRING_LEN 256
++#define MACADDR_LEN ( 6 * 2 ) + 5
++#define OPER_RATE_SET_LEN 126
++#define MAN_OUI_LEN ( 3 * 2 ) + 2
++#define WEP_STR_LEN 64
++#define SNMP_STR_LEN 128
++#define TEXT_LEN 80
++#define IFINDEX_LEN 4
++#define IFNAME_LEN 16
++#define MAX_WEP_KEYS 4
++
++#define AUTHENICATION_ALGORITHMS_INDEX_LEN 4
++#define WEP_DEFAULT_KEY_INDEX_LEN 4
++#define WEP_KEY_MAPPING_INDEX_LEN 4
++#define GROUP_ADDRESS_INDEX_LEN 4
++#define REG_DOMAIN_SUPPORT_INDEX_LEN 4
++#define ANTENNA_LIST_INDEX_LEN 4
++#define SUPPORTED_DATA_RATES_TX_INDEX_LEN 4
++#define SUPPORTED_DATA_RATES_RX_INDEX_LEN 4
++
++#define SC_UID_LEN IFINDEX_LEN
++#define AA_UID_LEN IFINDEX_LEN + AUTHENICATION_ALGORITHMS_INDEX_LEN
++#define DF_UID_LEN IFINDEX_LEN + WEP_DEFAULT_KEY_INDEX_LEN
++#define KM_UID_LEN IFINDEX_LEN + WEP_KEY_MAPPING_INDEX_LEN
++#define PR_UID_LEN IFINDEX_LEN
++#define OP_UID_LEN IFINDEX_LEN
++#define CO_UID_LEN IFINDEX_LEN
++#define GA_UID_LEN IFINDEX_LEN + GROUP_ADDRESS_INDEX_LEN
++#define RI_UID_LEN IFINDEX_LEN
++#define PO_UID_LEN IFINDEX_LEN
++#define PA_UID_LEN IFINDEX_LEN
++#define PT_UID_LEN IFINDEX_LEN
++#define PF_UID_LEN IFINDEX_LEN
++#define PD_UID_LEN IFINDEX_LEN
++#define PI_UID_LEN IFINDEX_LEN
++#define RD_UID_LEN IFINDEX_LEN + REG_DOMAIN_SUPPORT_INDEX_LEN
++#define AL_UID_LEN IFINDEX_LEN + ANTENNA_LIST_INDEX_LEN
++#define RT_UID_LEN IFINDEX_LEN + SUPPORTED_DATA_RATES_TX_INDEX_LEN
++#define RR_UID_LEN IFINDEX_LEN + SUPPORTED_DATA_RATES_RX_INDEX_LEN
++
++/****************************************************************************
++* Linked List Structure *
++****************************************************************************/
++static struct avNode {
++ LIST_ENTRY ( avNode ) nodes;
++ char *data; // pointer to data
++};
++
++typedef LIST_HEAD ( , avNode ) avList_t;
++
++/****************************************************************************
++* 802.11 MIB structures *
++****************************************************************************/
++/****************************************************************************
++* dot11Smt Group *
++****************************************************************************/
++/****************************************************************************
++* dot11StationConfigTable *
++****************************************************************************/
++static struct scTbl_data {
++
++ char UID [ SC_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ char stationID [ MACADDR_LEN + 1 ]; // Default actual MacAddr
++ long mediumOccupancyLimit;
++ long CFPPollable;
++ long CFPPeriod;
++ long maxDuration;
++ long authenticationResponseTimeOut;
++ long privacyOptionImplemented;
++ long powerManagementMode;
++ char desiredSSID [ SNMP_STR_LEN + 1 ];
++ long desiredBSSType;
++ char operationalRateSet [ OPER_RATE_SET_LEN + 1];
++ long beaconPeriod;
++ long DTIMPeriod;
++ long associationResponseTimeOut;
++ long disAssociationReason;
++ char disAssociationStation [ MACADDR_LEN + 1 ];
++ long deAuthenticationReason;
++ char deAuthenticationStation [ MACADDR_LEN + 1 ];
++ long authenticateFailStatus;
++ char authenticateFailStation [ MACADDR_LEN + 1 ];
++
++ long haveStationID;
++ long haveMediumOccupancyLimit;
++ long haveCFPPollable;
++ long haveCFPPeriod;
++ long haveMaxDuration;
++ long haveAuthenticationResponseTimeOut;
++ long havePrivacyOptionImplemented;
++ long havePowerManagementMode;
++ long haveDesiredSSID;
++ long haveDesiredBSSType;
++ long haveOperationalRateSet;
++ long haveBeaconPeriod;
++ long haveDTIMPeriod;
++ long haveAssociationResponseTimeOut;
++ long haveDisAssociationReason;
++ long haveDisAssociationStation;
++ long haveDeAuthenticationReason;
++ long haveDeAuthenticationStation;
++ long haveAuthenticateFailStatus;
++ long haveAuthenticateFailStation;
++
++} nSc, *sc = &nSc;
++
++static avList_t scList;
++
++/****************************************************************************
++* dot11AuthenticationAlgorithmsTable *
++****************************************************************************/
++static struct aaTbl_data {
++
++ char UID [ AA_UID_LEN + 1 ];
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++ long authenticationAlgorithmsIndex;
++
++ long authenticationAlgorithm;
++ long authenticationAlgorithmsEnable;
++
++ long haveAuthenticationAlgorithm;
++ long haveAuthenticationAlgorithmsEnable;
++
++} nAa, *aa = &nAa;
++
++static avList_t aaList;
++
++/****************************************************************************
++* dot11WEPDefaultKeysTable *
++****************************************************************************/
++static struct dfTbl_data {
++
++ char UID [ DF_UID_LEN + 1 ];
++ char ifName [ IFNAME_LEN + 1 ];
++
++ long ifIndex; // ifindex of card
++ long WEPDefaultKeyIndex;
++
++ char WEPDefaultKeyValue [ WEP_STR_LEN + 1 ];
++ long haveWEPDefaultKeyValue;
++
++} nDf, *df = &nDf;
++
++static avList_t dfList;
++
++/****************************************************************************
++* dot11WEPKeyMappingsTable *
++****************************************************************************/
++static struct kmTbl_data {
++
++ char UID [ KM_UID_LEN + 1 ];
++ char ifName [ IFNAME_LEN + 1 ];
++
++ long ifIndex;
++ long WEPKeyMappingIndex;
++
++ char WEPKeyMappingAddress [ MACADDR_LEN + 1 ];
++ long WEPKeyMappingWEPOn;
++ char WEPKeyMappingValue [ WEP_STR_LEN + 1 ];
++ long WEPKeyMappingStatus;
++
++ long haveWEPKeyMappingIndex;
++ long haveWEPKeyMappingAddress;
++ long haveWEPKeyMappingWEPOn;
++ long haveWEPKeyMappingValue;
++ long haveWEPKeyMappingStatus;
++
++} nKm, *km = &nKm;
++
++static avList_t kmList;
++
++/****************************************************************************
++* dot11PrivacyTable *
++****************************************************************************/
++static struct prTbl_data {
++
++ char UID [ PR_UID_LEN + 1 ];
++ char ifName [ IFNAME_LEN + 1 ];
++
++ long ifIndex;
++
++ long privacyInvoked;
++ long WEPDefaultKeyID;
++ long WEPKeyMappingLength;
++ long excludeUnencrypted;
++ unsigned long WEPICVErrorCount;
++ unsigned long WEPExcludedCount;
++
++ long havePrivacyInvoked;
++ long haveWEPDefaultKeyID;
++ long haveWEPKeyMappingLength;
++ long haveExcludeUnencrypted;
++ long haveWEPICVErrorCount;
++ long haveWEPExcludedCount;
++
++} nPr, *pr = &nPr;
++
++static avList_t prList;
++
++/****************************************************************************
++* dot11Mac Group *
++****************************************************************************/
++/****************************************************************************
++* dot11OperationTable *
++****************************************************************************/
++static struct opTbl_data {
++
++ char UID [ OP_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ char MACAddress [ MACADDR_LEN + 1 ];
++ long RTSThreshold;
++ long shortRetryLimit;
++ long longRetryLimit;
++ long fragmentationThreshold;
++ long maxTransmitMSDULifetime;
++ long maxReceiveLifetime;
++ char manufacturerID [ SNMP_STR_LEN + 1 ];
++ char productID [ SNMP_STR_LEN + 1 ];
++
++ long haveMACAddress;
++ long haveRTSThreshold;
++ long haveShortRetryLimit;
++ long haveLongRetryLimit;
++ long haveFragmentationThreshold;
++ long haveMaxTransmitMSDULifetime;
++ long haveMaxReceiveLifetime;
++ long haveManufacturerID;
++ long haveProductID;
++
++} nOp, *op = &nOp;
++
++static avList_t opList;
++
++/****************************************************************************
++* dot11CountersTable *
++****************************************************************************/
++static struct coTbl_data {
++
++ char UID [ CO_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ unsigned long transmittedFragmentCount;
++ unsigned long multicastTransmittedFrameCount;
++ unsigned long failedCount;
++ unsigned long retryCount;
++ unsigned long multipleRetryCount;
++ unsigned long frameDuplicateCount;
++ unsigned long RTSSuccessCount;
++ unsigned long RTSFailureCount;
++ unsigned long ACKFailureCount;
++ unsigned long receivedFragmentCount;
++ unsigned long multicastReceivedFrameCount;
++ unsigned long FCSErrorCount;
++ unsigned long transmittedFrameCount;
++ unsigned long WEPUndecryptableCount;
++
++ long haveTransmittedFragmentCount;
++ long haveMulticastTransmittedFrameCount;
++ long haveFailedCount;
++ long haveRetryCount;
++ long haveMultipleRetryCount;
++ long haveFrameDuplicateCount;
++ long haveRTSSuccessCount;
++ long haveRTSFailureCount;
++ long haveACKFailureCount;
++ long haveReceivedFragmentCount;
++ long haveMulticastReceivedFrameCount;
++ long haveFCSErrorCount;
++ long haveTransmittedFrameCount;
++ long haveWEPUndecryptableCount;
++
++} nCo, *co = &nCo;
++
++static avList_t coList;
++
++/****************************************************************************
++* dot11GroupAddressesTable *
++****************************************************************************/
++static struct gaTbl_data {
++
++ char UID [ GA_UID_LEN + 1 ];
++ char ifName [ IFNAME_LEN + 1 ];
++
++ long ifIndex; // ifindex of card
++ long groupAddressesIndex;
++
++ char address [ MACADDR_LEN + 1 ];
++ long groupAddressesStatus;
++
++ long haveAddress;
++ long haveGroupAddressesStatus;
++
++} nGa, *ga = &nGa;
++
++static avList_t gaList;
++
++/****************************************************************************
++* dot11Res Group *
++****************************************************************************/
++static char resourceTypeIDName[] = "RTID";
++static long haveResourceTypeIDName = 1;
++
++/****************************************************************************
++* dot11ResourceInfoTable *
++****************************************************************************/
++static struct riTbl_data {
++
++ char UID [ RI_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ char manufacturerOUI [ MAN_OUI_LEN + 1 ];
++ char manufacturerName [ SYS_STRING_LEN + 1 ];
++ char manufacturerProductName [ SYS_STRING_LEN + 1 ];
++ char manufacturerProductVersion [ SYS_STRING_LEN + 1 ];
++
++ char haveManufacturerOUI;
++ char haveManufacturerName;
++ char haveManufacturerProductName;
++ char haveManufacturerProductVersion;
++
++} nRi, *ri = &nRi;
++
++static avList_t riList;
++
++/****************************************************************************
++* dot11Phy Group *
++****************************************************************************/
++/****************************************************************************
++* dot11PhyOperationTable *
++****************************************************************************/
++static struct poTbl_data {
++
++ char UID [ PO_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ long PHYType;
++ long currentRegDomain;
++ long tempType;
++
++ long havePHYType;
++ long haveCurrentRegDomain;
++ long haveTempType;
++
++} nPo, *po = &nPo;
++
++static avList_t poList;
++
++/****************************************************************************
++* dot11PhyAntennaEntry *
++****************************************************************************/
++static struct paTbl_data {
++
++ char UID [ PA_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ long currentTxAntenna;
++ long diversitySupport;
++ long currentRxAntenna;
++
++ long haveCurrentTxAntenna;
++ long haveDiversitySupport;
++ long haveCurrentRxAntenna;
++
++} nPa, *pa = &nPa;
++
++static avList_t paList;
++
++/****************************************************************************
++* dot11PhyTxPowerTable *
++****************************************************************************/
++static struct ptTbl_data {
++
++ char UID [ PT_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ long numberSupportedPowerLevels;
++ long TxPowerLevel1;
++ long TxPowerLevel2;
++ long TxPowerLevel3;
++ long TxPowerLevel4;
++ long TxPowerLevel5;
++ long TxPowerLevel6;
++ long TxPowerLevel7;
++ long TxPowerLevel8;
++ long currentTxPowerLevel;
++
++ long haveNumberSupportedPowerLevels;
++ long haveTxPowerLevel1;
++ long haveTxPowerLevel2;
++ long haveTxPowerLevel3;
++ long haveTxPowerLevel4;
++ long haveTxPowerLevel5;
++ long haveTxPowerLevel6;
++ long haveTxPowerLevel7;
++ long haveTxPowerLevel8;
++ long haveCurrentTxPowerLevel ;
++
++} nPt, *pt = &nPt;
++
++static avList_t ptList;
++
++/****************************************************************************
++* dot11PhyFHSSTable *
++****************************************************************************/
++static struct pfTbl_data {
++
++ char UID [ PF_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ long hopTime;
++ long currentChannelNumber;
++ long maxDwellTime;
++ long currentDwellTime;
++ long currentSet;
++ long currentPattern;
++ long currentIndex;
++
++ long haveHopTime;
++ long haveCurrentChannelNumber;
++ long haveMaxDwellTime;
++ long haveCurrentDwellTime;
++ long haveCurrentSet;
++ long haveCurrentPattern;
++ long haveCurrentIndex;
++
++} nPf, *pf = &nPf;
++
++static avList_t pfList;
++
++/****************************************************************************
++* dot11PhyDSSSTable *
++****************************************************************************/
++static struct pdTbl_data {
++
++ char UID [ PD_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ long currentChannel;
++ long CCAModeSupported;
++ long currentCCAMode;
++ long EDThreshold;
++
++ long haveCurrentChannel;
++ long haveCCAModeSupported ;
++ long haveCurrentCCAMode;
++ long haveEDThreshold;
++
++} nPd, *pd = &nPd;
++
++static avList_t pdList;
++
++/****************************************************************************
++* dot11PhyIRTable *
++****************************************************************************/
++static struct piTbl_data {
++
++ char UID [ PI_UID_LEN + 1 ]; // unique ID
++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card
++
++ long ifIndex; // ifindex of card
++
++ long CCAWatchdogTimerMax;
++ long CCAWatchdogCountMax;
++ long CCAWatchdogTimerMin;
++ long CCAWatchdogCountMin;
++
++ long haveCCAWatchdogTimerMax;
++ long haveCCAWatchdogCountMax;
++ long haveCCAWatchdogTimerMin;
++ long haveCCAWatchdogCountMin;
++
++} nPi, *pi = &nPi;
++
++static avList_t piList;
++
++/****************************************************************************
++* dot11RegDomainsSupportedTable *
++****************************************************************************/
++static struct rdTbl_data {
++
++ char UID [ RD_UID_LEN + 1 ];
++ char ifName [ IFNAME_LEN + 1 ];
++
++ long ifIndex; // ifindex of card
++ long regDomainsSupportIndex;
++
++ long regDomainsSupportValue;
++ long haveRegDomainsSupportValue;
++
++} nRd, *rd = &nRd;
++
++static avList_t rdList;
++
++/****************************************************************************
++* dot11AntennasListTable *
++****************************************************************************/
++static struct alTbl_data {
++
++ char UID [ AL_UID_LEN + 1 ];
++ char ifName [ IFNAME_LEN + 1 ];
++
++ long ifIndex; // ifindex of card
++ long antennaListIndex;
++
++ long supportedTxAntenna;
++ long supportedRxAntenna;
++ long diversitySelectionRx ;
++
++ long haveSupportedTxAntenna;
++ long haveSupportedRxAntenna;
++ long haveDiversitySelectionRx ;
++
++} nAl, *al = &nAl;
++
++static avList_t alList;
++
++/****************************************************************************
++* dot11SupportedDataRatesTxTable *
++****************************************************************************/
++static struct rtTbl_data {
++
++ char UID [ RT_UID_LEN + 1 ];
++ char ifName [ IFNAME_LEN + 1 ];
++
++ long ifIndex; // ifindex of card
++ long supportedDataRatesTxIndex;
++
++ long supportedDataRatesTxValue;
++ long haveSupportedDataRatesTxValue;
++
++} nRt, *rt = &nRt;
++
++static avList_t rtList;
++
++/****************************************************************************
++* dot11SupportedDataRatesRxTable *
++****************************************************************************/
++static struct rrTbl_data {
++
++ char UID [ RR_UID_LEN + 1 ];
++ char ifName [ IFNAME_LEN + 1 ];
++
++ long ifIndex; // ifindex of card
++ long supportedDataRatesRxIndex;
++
++ long supportedDataRatesRxValue;
++ long haveSupportedDataRatesRxValue;
++
++} nRr, *rr = &nRr;
++
++static avList_t rrList;
++
++/****************************************************************************
++* Wireless Extensions Structures *
++****************************************************************************/
++static long wepCurrentKey;
++static long haveWepCurrentKey;
++static struct wepTbl_data {
++
++ long len;
++ char key [ WEP_STR_LEN + 1 ];
++ long haveKey;
++
++} wep[4];
++
++/****************************************************************************
++* *
++****************************************************************************/
++config_require(util_funcs)
++
++/* function prototypes */
++
++void init_ieee802dot11 ( void );
++FindVarMethod var_ieee802dot11;
++FindVarMethod var_dot11StationConfigTable;
++FindVarMethod var_dot11AuthenticationAlgorithmsTable;
++FindVarMethod var_dot11WEPDefaultKeysTable;
++FindVarMethod var_dot11WEPKeyMappingsTable;
++FindVarMethod var_dot11PrivacyTable;
++FindVarMethod var_dot11OperationTable;
++FindVarMethod var_dot11CountersTable;
++FindVarMethod var_dot11GroupAddressesTable;
++FindVarMethod var_dot11ResourceInfoTable;
++FindVarMethod var_dot11PhyOperationTable;
++FindVarMethod var_dot11PhyAntennaTable;
++FindVarMethod var_dot11PhyTxPowerTable;
++FindVarMethod var_dot11PhyFHSSTable;
++FindVarMethod var_dot11PhyDSSSTable;
++FindVarMethod var_dot11PhyIRTable;
++FindVarMethod var_dot11RegDomainsSupportedTable;
++FindVarMethod var_dot11AntennasListTable;
++FindVarMethod var_dot11SupportedDataRatesTxTable;
++FindVarMethod var_dot11SupportedDataRatesRxTable;
++
++WriteMethod write_dot11StationID;
++WriteMethod write_dot11MediumOccupancyLimit;
++WriteMethod write_dot11CFPPeriod;
++WriteMethod write_dot11CFPMaxDuration;
++WriteMethod write_dot11AuthenticationResponseTimeOut;
++WriteMethod write_dot11PowerManagementMode;
++WriteMethod write_dot11DesiredSSID;
++WriteMethod write_dot11DesiredBSSType;
++WriteMethod write_dot11OperationalRateSet;
++WriteMethod write_dot11BeaconPeriod;
++WriteMethod write_dot11DTIMPeriod;
++WriteMethod write_dot11AssociationResponseTimeOut;
++WriteMethod write_dot11AuthenticationAlgorithmsEnable;
++WriteMethod write_dot11WEPDefaultKeyValue;
++WriteMethod write_dot11WEPKeyMappingAddress;
++WriteMethod write_dot11WEPKeyMappingWEPOn;
++WriteMethod write_dot11WEPKeyMappingValue;
++WriteMethod write_dot11WEPKeyMappingStatus;
++WriteMethod write_dot11PrivacyInvoked;
++WriteMethod write_dot11WEPDefaultKeyID;
++WriteMethod write_dot11WEPKeyMappingLength;
++WriteMethod write_dot11ExcludeUnencrypted;
++WriteMethod write_dot11RTSThreshold;
++WriteMethod write_dot11ShortRetryLimit;
++WriteMethod write_dot11LongRetryLimit;
++WriteMethod write_dot11FragmentationThreshold;
++WriteMethod write_dot11MaxTransmitMSDULifetime;
++WriteMethod write_dot11MaxReceiveLifetime;
++WriteMethod write_dot11Address;
++WriteMethod write_dot11GroupAddressesStatus;
++WriteMethod write_dot11CurrentRegDomain;
++WriteMethod write_dot11CurrentTxAntenna;
++WriteMethod write_dot11CurrentRxAntenna;
++WriteMethod write_dot11CurrentTxPowerLevel;
++WriteMethod write_dot11CurrentChannelNumber;
++WriteMethod write_dot11CurrentDwellTime;
++WriteMethod write_dot11CurrentSet;
++WriteMethod write_dot11CurrentPattern;
++WriteMethod write_dot11CurrentIndex;
++WriteMethod write_dot11CurrentChannel;
++WriteMethod write_dot11CurrentCCAMode;
++WriteMethod write_dot11EDThreshold;
++WriteMethod write_dot11CCAWatchdogTimerMax;
++WriteMethod write_dot11CCAWatchdogCountMax;
++WriteMethod write_dot11CCAWatchdogTimerMin;
++WriteMethod write_dot11CCAWatchdogCountMin;
++WriteMethod write_dot11SupportedTxAntenna;
++WriteMethod write_dot11SupportedRxAntenna;
++WriteMethod write_dot11DiversitySelectionRx;
++
++#endif /* _MIBGROUP_IEEE802DOT11_H */
+--- /dev/null
++++ b/agent/mibgroup/iwlib.h
+@@ -0,0 +1,502 @@
++/*
++ * Wireless Tools
++ *
++ * Jean II - HPLB 97->99 - HPL 99->02
++ *
++ * Common header for the Wireless Extension library...
++ *
++ * This file is released under the GPL license.
++ * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
++ */
++
++#ifndef IWLIB_H
++#define IWLIB_H
++
++/*#include "CHANGELOG.h"*/
++
++/***************************** INCLUDES *****************************/
++
++/* Standard headers */
++#include <sys/types.h>
++#include <sys/ioctl.h>
++#include <stdio.h>
++#include <math.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <ctype.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <netdb.h> /* gethostbyname, getnetbyname */
++#include <net/ethernet.h> /* struct ether_addr */
++#include <sys/time.h> /* struct timeval */
++#include <unistd.h>
++
++/* This is our header selection. Try to hide the mess and the misery :-(
++ * Don't look, you would go blind ;-) */
++
++#ifndef LINUX_VERSION_CODE
++#include <linux/version.h>
++#endif
++
++/* Kernel headers 2.4.X + Glibc 2.2 - Mandrake 8.0, Debian 2.3, RH 7.1
++ * Kernel headers 2.2.X + Glibc 2.2 - Slackware 8.0 */
++#if defined(__GLIBC__) \
++ && __GLIBC__ == 2 \
++ && __GLIBC_MINOR__ >= 2 \
++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
++//#define GLIBC22_HEADERS
++#define GENERIC_HEADERS
++
++/* Kernel headers 2.4.X + Glibc 2.1 - Debian 2.2 upgraded, RH 7.0
++ * Kernel headers 2.2.X + Glibc 2.1 - Debian 2.2, RH 6.1 */
++#elif defined(__GLIBC__) \
++ && __GLIBC__ == 2 \
++ && __GLIBC_MINOR__ == 1 \
++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
++//#define GLIBC_HEADERS
++#define GENERIC_HEADERS
++
++/* Kernel headers 2.2.X + Glibc 2.0 - Debian 2.1 */
++#elif defined(__GLIBC__) \
++ && __GLIBC__ == 2 \
++ && __GLIBC_MINOR__ == 0 \
++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0) \
++ && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
++#define GLIBC_HEADERS
++#define KLUDGE_HEADERS
++
++/* Note : is it really worth supporting kernel 2.0.X, knowing that
++ * we require WE v9, which is only available in 2.2.X and higher ?
++ * I guess one could use 2.0.x with an upgraded wireless.h... */
++
++/* Kernel headers 2.0.X + Glibc 2.0 - Debian 2.0, RH 5 */
++#elif defined(__GLIBC__) \
++ && __GLIBC__ == 2 \
++ && __GLIBC_MINOR__ == 0 \
++ && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) \
++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0)
++#define GLIBC_HEADERS
++
++/* Kernel headers 2.0.X + libc5 - old systems */
++#elif defined(_LINUX_C_LIB_VERSION_MAJOR) \
++ && _LINUX_C_LIB_VERSION_MAJOR == 5 \
++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0) \
++ && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
++#define LIBC5_HEADERS
++
++/* Unsupported combination */
++#else
++#error "Your kernel/libc combination is not supported"
++#endif
++
++#ifdef GENERIC_HEADERS
++/* Proposed by Dr. Michael Rietz <rietz@mail.amps.de>, 27.3.2 */
++/* If this works for all, it might be more stable on the long term - Jean II */
++#include <net/if_arp.h> /* For ARPHRD_ETHER */
++#include <sys/socket.h> /* For AF_INET & struct sockaddr */
++#include <netinet/in.h> /* For struct sockaddr_in */
++#include <netinet/if_ether.h>
++#endif /* GENERIC_HEADERS */
++
++#ifdef GLIBC22_HEADERS
++/* Added by Ross G. Miller <Ross_Miller@baylor.edu>, 3/28/01 */
++#include <linux/if_arp.h> /* For ARPHRD_ETHER */
++#include <linux/socket.h> /* For AF_INET & struct sockaddr */
++#include <sys/socket.h>
++#endif /* GLIBC22_HEADERS */
++
++#ifdef KLUDGE_HEADERS
++#include <socketbits.h>
++#endif /* KLUDGE_HEADERS */
++
++#ifdef GLIBC_HEADERS
++#include <linux/if_arp.h> /* For ARPHRD_ETHER */
++#include <linux/socket.h> /* For AF_INET & struct sockaddr */
++#include <linux/in.h> /* For struct sockaddr_in */
++#endif /* KLUDGE_HEADERS || GLIBC_HEADERS */
++
++#ifdef LIBC5_HEADERS
++#include <sys/socket.h> /* For AF_INET & struct sockaddr & socket() */
++#include <linux/if_arp.h> /* For ARPHRD_ETHER */
++#include <linux/in.h> /* For struct sockaddr_in */
++#endif /* LIBC5_HEADERS */
++
++/* Those 3 headers were previously included in wireless.h */
++#include <linux/types.h> /* for "caddr_t" et al */
++#include <linux/socket.h> /* for "struct sockaddr" et al */
++#include <linux/if.h> /* for IFNAMSIZ and co... */
++
++#ifdef WEXT_HEADER
++/* Private copy of Wireless extensions */
++#include WEXT_HEADER
++#else /* !WEXT_HEADER */
++/* System wide Wireless extensions */
++#include <linux/wireless.h>
++#endif /* !WEXT_HEADER */
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/****************************** DEBUG ******************************/
++
++
++/************************ CONSTANTS & MACROS ************************/
++
++/* Paths */
++#define PROC_NET_WIRELESS "/proc/net/wireless"
++#define PROC_NET_DEV "/proc/net/dev"
++
++/* Some useful constants */
++#define KILO 1e3
++#define MEGA 1e6
++#define GIGA 1e9
++/* For doing log10/exp10 without libm */
++#define LOG10_MAGIC 1.25892541179
++
++/* Backward compatibility for Wireless Extension 9 */
++#ifndef IW_POWER_MODIFIER
++#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */
++#define IW_POWER_MIN 0x0001 /* Value is a minimum */
++#define IW_POWER_MAX 0x0002 /* Value is a maximum */
++#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
++#endif /* IW_POWER_MODIFIER */
++
++#ifndef IW_ENCODE_NOKEY
++#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not here */
++#define IW_ENCODE_MODE 0xF000 /* Modes defined below */
++#endif /* IW_ENCODE_NOKEY */
++#ifndef IW_ENCODE_TEMP
++#define IW_ENCODE_TEMP 0x0400 /* Temporary key */
++#endif /* IW_ENCODE_TEMP */
++
++/* More backward compatibility */
++#ifndef SIOCSIWCOMMIT
++#define SIOCSIWCOMMIT SIOCSIWNAME
++#endif /* SIOCSIWCOMMIT */
++
++/****************************** TYPES ******************************/
++
++/* Shortcuts */
++typedef struct iw_statistics iwstats;
++typedef struct iw_range iwrange;
++typedef struct iw_param iwparam;
++typedef struct iw_freq iwfreq;
++typedef struct iw_quality iwqual;
++typedef struct iw_priv_args iwprivargs;
++typedef struct sockaddr sockaddr;
++
++/* Structure for storing all wireless information for each device
++ * This is pretty exhaustive... */
++typedef struct wireless_info
++{
++ char name[IFNAMSIZ + 1]; /* Wireless/protocol name */
++ int has_nwid;
++ iwparam nwid; /* Network ID */
++ int has_freq;
++ double freq; /* Frequency/channel */
++ int has_sens;
++ iwparam sens; /* sensitivity */
++ int has_key;
++ unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */
++ int key_size; /* Number of bytes */
++ int key_flags; /* Various flags */
++ int has_essid;
++ int essid_on;
++ char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */
++ int has_nickname;
++ char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */
++ int has_ap_addr;
++ sockaddr ap_addr; /* Access point address */
++ int has_bitrate;
++ iwparam bitrate; /* Bit rate in bps */
++ int has_rts;
++ iwparam rts; /* RTS threshold in bytes */
++ int has_frag;
++ iwparam frag; /* Fragmentation threshold in bytes */
++ int has_mode;
++ int mode; /* Operation mode */
++ int has_power;
++ iwparam power; /* Power management parameters */
++ int has_txpower;
++ iwparam txpower; /* Transmit Power in dBm */
++ int has_retry;
++ iwparam retry; /* Retry limit or lifetime */
++
++ /* Stats */
++ iwstats stats;
++ int has_stats;
++ iwrange range;
++ int has_range;
++} wireless_info;
++
++/* Structure for storing all wireless information for each device
++ * This is a cut down version of the one above, containing only
++ * the things *truly* needed to configure a card.
++ * Don't add other junk, I'll remove it... */
++typedef struct wireless_config
++{
++ char name[IFNAMSIZ + 1]; /* Wireless/protocol name */
++ int has_nwid;
++ iwparam nwid; /* Network ID */
++ int has_freq;
++ double freq; /* Frequency/channel */
++ int has_key;
++ unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */
++ int key_size; /* Number of bytes */
++ int key_flags; /* Various flags */
++ int has_essid;
++ int essid_on;
++ char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */
++ int has_mode;
++ int mode; /* Operation mode */
++} wireless_config;
++
++typedef struct stream_descr
++{
++ char * end; /* End of the stream */
++ char * current; /* Current event in stream of events */
++ char * value; /* Current value in event */
++} stream_descr;
++
++/* Prototype for handling display of each single interface on the
++ * system - see iw_enum_devices() */
++typedef int (*iw_enum_handler)(int skfd,
++ char * ifname,
++ char * args[],
++ int count);
++
++/**************************** PROTOTYPES ****************************/
++/*
++ * All the functions in iwcommon.c
++ */
++
++/* ---------------------- SOCKET SUBROUTINES -----------------------*/
++int
++ iw_sockets_open(void);
++void
++ iw_enum_devices(int skfd,
++ iw_enum_handler fn,
++ char * args[],
++ int count);
++/* --------------------- WIRELESS SUBROUTINES ----------------------*/
++int
++ iw_get_range_info(int skfd,
++ char * ifname,
++ iwrange * range);
++int
++ iw_print_version_info(char * toolname);
++int
++ iw_get_priv_info(int skfd,
++ char * ifname,
++ iwprivargs * priv,
++ int maxpriv);
++int
++ iw_get_basic_config(int skfd,
++ char * ifname,
++ wireless_config * info);
++int
++ iw_set_basic_config(int skfd,
++ char * ifname,
++ wireless_config * info);
++/* --------------------- PROTOCOL SUBROUTINES --------------------- */
++int
++ iw_protocol_compare(char * protocol1,
++ char * protocol2);
++/* -------------------- FREQUENCY SUBROUTINES --------------------- */
++void
++ iw_float2freq(double in,
++ iwfreq * out);
++double
++ iw_freq2float(iwfreq * in);
++void
++ iw_print_freq(char * buffer,
++ double freq);
++int
++ iw_freq_to_channel(double freq,
++ struct iw_range * range);
++void
++ iw_print_bitrate(char * buffer,
++ int bitrate);
++/* ---------------------- POWER SUBROUTINES ----------------------- */
++int
++ iw_dbm2mwatt(int in);
++int
++ iw_mwatt2dbm(int in);
++/* -------------------- STATISTICS SUBROUTINES -------------------- */
++int
++ iw_get_stats(int skfd,
++ char * ifname,
++ iwstats * stats);
++void
++ iw_print_stats(char * buffer,
++ iwqual * qual,
++ iwrange * range,
++ int has_range);
++/* --------------------- ENCODING SUBROUTINES --------------------- */
++void
++ iw_print_key(char * buffer,
++ unsigned char * key,
++ int key_size,
++ int key_flags);
++int
++ iw_in_key(char * input,
++ unsigned char * key);
++int
++ iw_in_key_full(int skfd,
++ char * ifname,
++ char * input,
++ unsigned char * key,
++ __u16 * flags);
++/* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */
++void
++ iw_print_pm_value(char * buffer,
++ int value,
++ int flags);
++void
++ iw_print_pm_mode(char * buffer,
++ int flags);
++/* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */
++#if WIRELESS_EXT > 10
++void
++ iw_print_retry_value(char * buffer,
++ int value,
++ int flags);
++#endif
++/* ----------------------- TIME SUBROUTINES ----------------------- */
++void
++ iw_print_timeval(char * buffer,
++ const struct timeval * time);
++/* --------------------- ADDRESS SUBROUTINES ---------------------- */
++int
++ iw_check_mac_addr_type(int skfd,
++ char * ifname);
++int
++ iw_check_if_addr_type(int skfd,
++ char * ifname);
++#if 0
++int
++ iw_check_addr_type(int skfd,
++ char * ifname);
++#endif
++void
++ iw_ether_ntop(const struct ether_addr* eth, char* buf);
++char*
++ iw_ether_ntoa(const struct ether_addr* eth);
++int
++ iw_ether_aton(const char* bufp, struct ether_addr* eth);
++int
++ iw_in_inet(char *bufp, struct sockaddr *sap);
++int
++ iw_in_addr(int skfd,
++ char * ifname,
++ char * bufp,
++ struct sockaddr * sap);
++/* ----------------------- MISC SUBROUTINES ------------------------ */
++int
++ iw_get_priv_size(int args);
++
++#if WIRELESS_EXT > 13
++/* ---------------------- EVENT SUBROUTINES ---------------------- */
++void
++ iw_init_event_stream(struct stream_descr * stream,
++ char * data,
++ int len);
++int
++ iw_extract_event_stream(struct stream_descr * stream,
++ struct iw_event * iwe);
++#endif /* WIRELESS_EXT > 13 */
++
++/**************************** VARIABLES ****************************/
++
++extern const char * const iw_operation_mode[];
++#define IW_NUM_OPER_MODE 7
++
++/************************* INLINE FUNTIONS *************************/
++/*
++ * Functions that are so simple that it's more efficient inlining them
++ */
++
++/*
++ * Note : I've defined wrapper for the ioctl request so that
++ * it will be easier to migrate to other kernel API if needed
++ */
++
++/*------------------------------------------------------------------*/
++/*
++ * Wrapper to push some Wireless Parameter in the driver
++ */
++static inline int
++iw_set_ext(int skfd, /* Socket to the kernel */
++ char * ifname, /* Device name */
++ int request, /* WE ID */
++ struct iwreq * pwrq) /* Fixed part of the request */
++{
++ /* Set device name */
++ strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
++ /* Do the request */
++ return(ioctl(skfd, request, pwrq));
++}
++
++/*------------------------------------------------------------------*/
++/*
++ * Wrapper to extract some Wireless Parameter out of the driver
++ */
++static inline int
++iw_get_ext(int skfd, /* Socket to the kernel */
++ char * ifname, /* Device name */
++ int request, /* WE ID */
++ struct iwreq * pwrq) /* Fixed part of the request */
++{
++ /* Set device name */
++ strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
++ /* Do the request */
++ return(ioctl(skfd, request, pwrq));
++}
++
++/*------------------------------------------------------------------*/
++/* Backwards compatibility
++ * Actually, those form are much easier to use when dealing with
++ * struct sockaddr... */
++static inline char*
++iw_pr_ether(char* bufp, const unsigned char* addr)
++{
++ iw_ether_ntop((const struct ether_addr *) addr, bufp);
++ return bufp;
++}
++/* Backwards compatibility */
++static inline int
++iw_in_ether(const char *bufp, struct sockaddr *sap)
++{
++ sap->sa_family = ARPHRD_ETHER;
++ return iw_ether_aton(bufp, (struct ether_addr *) sap->sa_data) ? 0 : -1;
++}
++
++/*------------------------------------------------------------------*/
++/*
++ * Create an Ethernet broadcast address
++ */
++static inline void
++iw_broad_ether(struct sockaddr *sap)
++{
++ sap->sa_family = ARPHRD_ETHER;
++ memset((char *) sap->sa_data, 0xFF, ETH_ALEN);
++}
++
++/*------------------------------------------------------------------*/
++/*
++ * Create an Ethernet NULL address
++ */
++static inline void
++iw_null_ether(struct sockaddr *sap)
++{
++ sap->sa_family = ARPHRD_ETHER;
++ memset((char *) sap->sa_data, 0x00, ETH_ALEN);
++}
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* IWLIB_H */
diff --git a/package/network/utils/net-snmp/patches/900-musl-compat.patch b/package/network/utils/net-snmp/patches/900-musl-compat.patch
new file mode 100644
index 0000000..fa9a01e
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/900-musl-compat.patch
@@ -0,0 +1,14 @@
+--- a/agent/mibgroup/iwlib.h
++++ b/agent/mibgroup/iwlib.h
+@@ -85,6 +85,11 @@
+ && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+ #define LIBC5_HEADERS
+
++/* Musl */
++#elif !defined(__GLIBC__) && !defined(__UCLIBC__) \
++ && LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
++#define GENERIC_HEADERS
++
+ /* Unsupported combination */
+ #else
+ #error "Your kernel/libc combination is not supported"
diff --git a/package/network/utils/net-snmp/patches/910-signal.patch b/package/network/utils/net-snmp/patches/910-signal.patch
new file mode 100644
index 0000000..45cd1fa
--- /dev/null
+++ b/package/network/utils/net-snmp/patches/910-signal.patch
@@ -0,0 +1,143 @@
+From 1ee70571e0cae37f155f59d4382bc7109138cf09 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bvanassche@acm.org>
+Date: Sat, 15 Aug 2020 17:29:25 -0700
+Subject: [PATCH] apps/snmpnetstat: Stop using obsolete signal functions
+
+This was reported by Rosen Penev. See also
+https://github.com/net-snmp/net-snmp/pull/162.
+---
+ apps/snmpnetstat/if.c | 111 +++++++++++-------------------------------
+ 1 file changed, 28 insertions(+), 83 deletions(-)
+ mode change 100644 => 100755 apps/snmpnetstat/if.c
+
+--- a/apps/snmpnetstat/if.c
++++ b/apps/snmpnetstat/if.c
+@@ -64,8 +64,6 @@ static char *rcsid = "$OpenBSD: if.c,v 1
+ #define NO 0
+
+ static void sidewaysintpr(u_int);
+-static void timerSet(int interval_seconds);
+-static void timerPause(void);
+
+ struct _if_info {
+ char name[128];
+@@ -92,6 +90,34 @@ static void timerPause(void);
+ };
+
+
++static struct timeval deadline;
++
++static void
++timerSet(int interval_seconds)
++{
++ const struct timeval interval = { interval_seconds, 0 };
++
++ netsnmp_get_monotonic_clock(&deadline);
++ NETSNMP_TIMERADD(&deadline, &interval, &deadline);
++}
++
++static void
++timerPause(void)
++{
++ struct timeval now, delta;
++
++ netsnmp_get_monotonic_clock(&now);
++ NETSNMP_TIMERSUB(&deadline, &now, &delta);
++ if (delta.tv_sec < 0)
++ return;
++#ifdef WIN32
++ Sleep(delta.tv_sec * 1000 + delta.tv_usec / 1000);
++#else
++ if (select(0, NULL, NULL, NULL, &delta) < 0)
++ snmp_perror("select");
++#endif
++}
++
+ /*
+ * Retrieve the interface addressing information
+ * XXX - This could also be extended to handle non-IP interfaces
+@@ -845,84 +871,3 @@ loop:
+ goto loop;
+ /*NOTREACHED*/
+ }
+-
+-
+-/*
+- * timerSet sets or resets the timer to fire in "interval" seconds.
+- * timerPause waits only if the timer has not fired.
+- * timing precision is not considered important.
+- */
+-
+-#if (defined(WIN32) || defined(cygwin))
+-static int sav_int;
+-static time_t timezup;
+-static void
+-timerSet(int interval_seconds)
+-{
+- sav_int = interval_seconds;
+- timezup = time(0) + interval_seconds;
+-}
+-
+-/*
+- * you can do better than this !
+- */
+-static void
+-timerPause(void)
+-{
+- time_t now;
+- while (time(&now) < timezup)
+-#ifdef WIN32
+- Sleep(400);
+-#else
+- {
+- struct timeval tx;
+- tx.tv_sec = 0;
+- tx.tv_usec = 400 * 1000; /* 400 milliseconds */
+- select(0, 0, 0, 0, &tx);
+- }
+-#endif
+-}
+-
+-#else
+-
+-/*
+- * Called if an interval expires before sidewaysintpr has completed a loop.
+- * Sets a flag to not wait for the alarm.
+- */
+-RETSIGTYPE
+-catchalarm(int sig)
+-{
+- signalled = YES;
+-}
+-
+-static void
+-timerSet(int interval_seconds)
+-{
+-#ifdef HAVE_SIGSET
+- (void) sigset(SIGALRM, catchalarm);
+-#else
+- (void) signal(SIGALRM, catchalarm);
+-#endif
+- signalled = NO;
+- (void) alarm(interval_seconds);
+-}
+-
+-static void
+-timerPause(void)
+-{
+-#ifdef HAVE_SIGHOLD
+- sighold(SIGALRM);
+- if (!signalled) {
+- sigpause(SIGALRM);
+- }
+-#else
+- int oldmask;
+- oldmask = sigblock(sigmask(SIGALRM));
+- if (!signalled) {
+- sigpause(0);
+- }
+- sigsetmask(oldmask);
+-#endif
+-}
+-
+-#endif /* !WIN32 && !cygwin */
diff --git a/package/network/utils/nftables/Makefile b/package/network/utils/nftables/Makefile
new file mode 100644
index 0000000..06b3fcf
--- /dev/null
+++ b/package/network/utils/nftables/Makefile
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nftables
+PKG_VERSION:=1.1.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://netfilter.org/projects/$(PKG_NAME)/files
+PKG_HASH:=6358830f3a64f31e39b0ad421d7dadcd240b72343ded48d8ef13b8faf204865a
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+
+DISABLE_NLS:=
+
+CONFIGURE_ARGS += \
+ --disable-debug \
+ --disable-man-doc \
+ --with-mini-gmp \
+ --without-cli \
+ --disable-python
+
+define Package/nftables/Default
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Firewall
+ TITLE:=nftables userspace utility
+ DEPENDS:=+kmod-nft-core +libnftnl
+ URL:=http://netfilter.org/projects/nftables/
+ PROVIDES:=nftables
+endef
+
+define Package/nftables-nojson
+ $(Package/nftables/Default)
+ TITLE+= no JSON support
+ VARIANT:=nojson
+ DEFAULT_VARIANT:=1
+ CONFLICTS:=nftables-json
+endef
+
+define Package/nftables-json
+ $(Package/nftables/Default)
+ TITLE+= with JSON support
+ VARIANT:=json
+ DEPENDS+=+jansson
+endef
+
+ifeq ($(BUILD_VARIANT),json)
+ CONFIGURE_ARGS += --with-json
+endif
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/lib $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/nftables $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnftables.pc \
+ $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/nftables/install/Default
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/nft $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+Package/nftables-nojson/install = $(Package/nftables/install/Default)
+Package/nftables-json/install = $(Package/nftables/install/Default)
+
+$(eval $(call BuildPackage,nftables-nojson))
+$(eval $(call BuildPackage,nftables-json))
diff --git a/package/network/utils/resolveip/Makefile b/package/network/utils/resolveip/Makefile
new file mode 100644
index 0000000..ab5d4ea
--- /dev/null
+++ b/package/network/utils/resolveip/Makefile
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2011-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=resolveip
+PKG_RELEASE:=2
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/resolveip
+ SECTION:=utils
+ CATEGORY:=Base system
+ TITLE:=Simple DNS resolver with configurable timeout
+ MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
+endef
+
+define Package/resolveip/description
+ This package contains the small resolveip utility which
+ can be used by scripts to turn host names into numeric
+ IP addresses. It supports IPv4 and IPv6 resolving and
+ has a configurable timeout to guarantee a certain maximum
+ runtime in case of slow or defunct DNS servers.
+endef
+
+define Build/Compile
+ $(TARGET_CC) $(TARGET_CFLAGS) -Wall \
+ -o $(PKG_BUILD_DIR)/resolveip $(PKG_BUILD_DIR)/resolveip.c
+endef
+
+define Package/resolveip/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/resolveip $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,resolveip))
diff --git a/package/network/utils/resolveip/src/resolveip.c b/package/network/utils/resolveip/src/resolveip.c
new file mode 100644
index 0000000..f7a918d
--- /dev/null
+++ b/package/network/utils/resolveip/src/resolveip.c
@@ -0,0 +1,98 @@
+/*
+ * Based on code found at https://dev.openwrt.org/ticket/4876 .
+ * Extended by Jo-Philipp Wich <jo@mein.io> for use in OpenWrt.
+ *
+ * You may use this program under the terms of the GPLv2 license.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+
+static void abort_query(int sig)
+{
+ exit(1);
+}
+
+static void show_usage(void)
+{
+ printf("Usage:\n");
+ printf(" resolveip -h\n");
+ printf(" resolveip [-t timeout] hostname\n");
+ printf(" resolveip -4 [-t timeout] hostname\n");
+ printf(" resolveip -6 [-t timeout] hostname\n");
+ exit(255);
+}
+
+int main(int argc, char **argv)
+{
+ int timeout = 3;
+ int opt;
+ char ipaddr[INET6_ADDRSTRLEN];
+ void *addr;
+ struct addrinfo *res, *rp;
+ struct sigaction sa = { .sa_handler = &abort_query };
+ struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM,
+ .ai_protocol = IPPROTO_TCP,
+ .ai_flags = 0
+ };
+
+ while ((opt = getopt(argc, argv, "46t:h")) > -1)
+ {
+ switch ((char)opt)
+ {
+ case '4':
+ hints.ai_family = AF_INET;
+ break;
+
+ case '6':
+ hints.ai_family = AF_INET6;
+ break;
+
+ case 't':
+ timeout = atoi(optarg);
+ if (timeout <= 0)
+ show_usage();
+ break;
+
+ case 'h':
+ show_usage();
+ break;
+ }
+ }
+
+ if (!argv[optind])
+ show_usage();
+
+ sigaction(SIGALRM, &sa, NULL);
+ alarm(timeout);
+
+ if (getaddrinfo(argv[optind], NULL, &hints, &res))
+ exit(2);
+
+ for (rp = res; rp != NULL; rp = rp->ai_next)
+ {
+ addr = (rp->ai_family == AF_INET)
+ ? (void *)&((struct sockaddr_in *)rp->ai_addr)->sin_addr
+ : (void *)&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr
+ ;
+
+ if (!inet_ntop(rp->ai_family, addr, ipaddr, INET6_ADDRSTRLEN - 1))
+ exit(3);
+
+ printf("%s\n", ipaddr);
+ }
+
+ freeaddrinfo(res);
+ exit(0);
+}
diff --git a/package/network/utils/rssileds/Makefile b/package/network/utils/rssileds/Makefile
new file mode 100644
index 0000000..5adc25e
--- /dev/null
+++ b/package/network/utils/rssileds/Makefile
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2011-2012 Daniel Golle <dgolle@allnet.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=rssileds
+PKG_RELEASE:=4
+PKG_LICNESE:=GPL-2.0+
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/rssileds
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=RSSI real-time LED indicator
+ DEPENDS:=+libiwinfo +libnl-tiny +libubox +libuci
+ MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+endef
+
+define Package/rssileds/description
+ A small process written in C to update the signal-strength indicator LEDs
+endef
+
+define Build/Configure
+endef
+
+TARGET_LDFLAGS += -liwinfo -luci -lubox -lnl-tiny
+
+define Build/Compile
+ $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_CPPFLAGS) -Wall \
+ -o $(PKG_BUILD_DIR)/rssileds $(PKG_BUILD_DIR)/rssileds.c $(TARGET_LDFLAGS)
+endef
+
+define Package/rssileds/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/rssileds.init $(1)/etc/init.d/rssileds
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/rssileds $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/usr/libexec/led-trigger
+ $(INSTALL_BIN) ./files/rssi $(1)/usr/libexec/led-trigger/
+endef
+
+$(eval $(call BuildPackage,rssileds))
diff --git a/package/network/utils/rssileds/files/rssi b/package/network/utils/rssileds/files/rssi
new file mode 100644
index 0000000..0c06733
--- /dev/null
+++ b/package/network/utils/rssileds/files/rssi
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+logger -t led-trigger "LED trigger rssi is handled by /etc/init.d/rssileds"
diff --git a/package/network/utils/rssileds/files/rssileds.init b/package/network/utils/rssileds/files/rssileds.init
new file mode 100644
index 0000000..4c9b549
--- /dev/null
+++ b/package/network/utils/rssileds/files/rssileds.init
@@ -0,0 +1,75 @@
+#!/bin/sh /etc/rc.common
+# (C) 2012 Daniel Golle, Allnet GmbH <dgolle@allnet.de>
+
+START=96
+STOP=89
+RSSILEDS_BIN="/usr/sbin/rssileds"
+
+SERVICE_DAEMONIZE=1
+SERVICE_WRITE_PID=1
+
+start_rssid() {
+ local name
+ local dev
+ local threshold
+ local refresh
+ local leds
+ config_get name $1 name
+ config_get dev $1 dev
+ config_get threshold $1 threshold
+ config_get refresh $1 refresh
+ leds="$( cur_iface=$1 ; config_foreach get_led led )"
+ SERVICE_PID_FILE=/var/run/rssileds-$dev.pid
+ service_start $RSSILEDS_BIN $dev $refresh $threshold $leds
+}
+
+stop_rssid() {
+ local dev
+ config_get dev $1 dev
+ SERVICE_PID_FILE=/var/run/rssileds-$dev.pid
+ service_stop $RSSILEDS_BIN
+}
+
+get_led() {
+ local name
+ local sysfs
+ local trigger
+ local iface
+ config_get sysfs $1 sysfs
+ config_get name $1 name "$sysfs"
+ config_get trigger $1 trigger "none"
+ config_get iface $1 iface
+ config_get minq $1 minq
+ config_get maxq $1 maxq
+ config_get offset $1 offset
+ config_get factor $1 factor
+ [ "$trigger" = "rssi" ] || return
+ [ "$iface" = "$cur_iface" ] || return
+ [ ! "$minq" ] || [ ! "$maxq" ] || [ ! "$offset" ] || [ ! "$factor" ] && return
+ echo "none" > /sys/class/leds/$sysfs/trigger
+ echo "$sysfs $minq $maxq $offset $factor"
+}
+
+off_led() {
+ local name
+ local sysfs
+ local trigger
+ config_get sysfs $1 sysfs
+ config_get name $1 name "$sysfs"
+ config_get trigger $1 trigger "none"
+ [ "$trigger" = "rssi" ] || return
+ echo "0" > /sys/class/leds/$sysfs/brightness
+}
+
+start() {
+ [ -e /sys/class/leds/ ] && [ -x "$RSSILEDS_BIN" ] && {
+ config_load system
+ config_foreach start_rssid rssid
+ }
+}
+
+stop() {
+ config_load system
+ config_foreach stop_rssid rssid
+ config_foreach off_led led
+}
diff --git a/package/network/utils/rssileds/src/rssileds.c b/package/network/utils/rssileds/src/rssileds.c
new file mode 100644
index 0000000..60d30f1
--- /dev/null
+++ b/package/network/utils/rssileds/src/rssileds.c
@@ -0,0 +1,290 @@
+/*
+ * configurable RSSI LED control daemon for OpenWrt
+ * (c) 2012 Allnet GmbH, Daniel Golle <dgolle@allnet.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * The author may be reached as dgolle@allnet.de, or
+ * ALLNET GmbH
+ * Maistr. 2
+ * D-82110 Germering
+ * Germany
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include <syslog.h>
+
+#include "iwinfo.h"
+
+#define RUN_DIR "/var/run"
+#define LEDS_BASEPATH "/sys/class/leds/"
+#define BACKEND_RETRY_DELAY 500000
+
+char *ifname;
+int qual_max;
+
+struct led {
+ char *sysfspath;
+ FILE *controlfd;
+ unsigned char state;
+};
+
+typedef struct rule rule_t;
+struct rule {
+ struct led *led;
+ int minq;
+ int maxq;
+ int boffset;
+ int bfactor;
+ rule_t *next;
+};
+
+void log_rules(rule_t *rules)
+{
+ rule_t *rule = rules;
+ while (rule)
+ {
+ syslog(LOG_INFO, " %s r: %d..%d, o: %d, f: %d\n",
+ rule->led->sysfspath,
+ rule->minq, rule->maxq,
+ rule->boffset, rule->bfactor);
+ rule = rule->next;
+ }
+}
+
+int set_led(struct led *led, unsigned char value)
+{
+ char buf[8];
+
+ if ( ! led )
+ return -1;
+
+ if ( ! led->controlfd )
+ return -1;
+
+ if ( led->state == value )
+ return 0;
+
+ snprintf(buf, 8, "%d", value);
+
+ rewind(led->controlfd);
+
+ if ( ! fwrite(buf, sizeof(char), strlen(buf), led->controlfd) )
+ return -2;
+
+ fflush(led->controlfd);
+ led->state=value;
+
+ return 0;
+}
+
+int init_led(struct led **led, char *ledname)
+{
+ struct led *newled;
+ struct stat statbuffer;
+ int status;
+ char *bp;
+ FILE *bfp;
+
+ bp = calloc(sizeof(char), strlen(ledname) + strlen(LEDS_BASEPATH) + 12);
+ if ( ! bp )
+ goto return_error;
+
+ sprintf(bp, "%s%s/brightness", LEDS_BASEPATH, ledname);
+
+ status = stat(bp, &statbuffer);
+ if ( status )
+ goto cleanup_fname;
+
+ bfp = fopen( bp, "w" );
+ if ( !bfp )
+ goto cleanup_fname;
+
+ if ( ferror(bfp) )
+ goto cleanup_fp;
+
+ /* sysfs path exists and, allocate LED struct */
+ newled = calloc(sizeof(struct led),1);
+ if ( !newled )
+ goto cleanup_fp;
+
+ newled->sysfspath = bp;
+ newled->controlfd = bfp;
+
+ *led = newled;
+
+ if ( set_led(newled, 255) )
+ goto cleanup_fp;
+
+ if ( set_led(newled, 0) )
+ goto cleanup_fp;
+
+ return 0;
+
+cleanup_fp:
+ fclose(bfp);
+cleanup_fname:
+ free(bp);
+return_error:
+ syslog(LOG_CRIT, "can't open LED %s\n", ledname);
+ *led = NULL;
+ return -1;
+}
+
+void close_led(struct led **led)
+{
+ fclose((*led)->controlfd);
+ free((*led)->sysfspath);
+ free((*led));
+ (*led)=NULL;
+}
+
+
+int quality(const struct iwinfo_ops *iw, const char *ifname)
+{
+ int qual;
+
+ if ( ! iw ) return -1;
+
+ if (qual_max < 1)
+ if (iw->quality_max(ifname, &qual_max))
+ return -1;
+
+ if (iw->quality(ifname, &qual))
+ return -1;
+
+ return ( qual * 100 ) / qual_max ;
+}
+
+int open_backend(const struct iwinfo_ops **iw, const char *ifname)
+{
+ *iw = iwinfo_backend(ifname);
+
+ if (!(*iw))
+ return 1;
+
+ return 0;
+}
+
+void update_leds(rule_t *rules, int q)
+{
+ rule_t *rule = rules;
+ while (rule)
+ {
+ int b;
+ /* offset and factore correction according to rule */
+ b = ( q + rule->boffset ) * rule->bfactor;
+ if ( b < 0 )
+ b=0;
+ if ( b > 255 )
+ b=255;
+
+ if ( q >= rule->minq && q <= rule->maxq )
+ set_led(rule->led, (unsigned char)b);
+ else
+ set_led(rule->led, 0);
+
+ rule = rule->next;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int i,q,q0,r,s;
+ const struct iwinfo_ops *iw = NULL;
+ rule_t *headrule = NULL, *currentrule = NULL;
+
+ if (argc < 9 || ( (argc-4) % 5 != 0 ) )
+ {
+ printf("syntax: %s (ifname) (refresh) (threshold) (rule) [rule] ...\n", argv[0]);
+ printf(" rule: (sysfs-name) (minq) (maxq) (offset) (factore)\n");
+ return 1;
+ }
+
+ ifname = argv[1];
+
+ /* refresh interval */
+ if ( sscanf(argv[2], "%d", &r) != 1 )
+ return 1;
+
+ /* sustain threshold */
+ if ( sscanf(argv[3], "%d", &s) != 1 )
+ return 1;
+
+ openlog("rssileds", LOG_PID, LOG_DAEMON);
+ syslog(LOG_INFO, "monitoring %s, refresh rate %d, threshold %d\n", ifname, r, s);
+
+ currentrule = headrule;
+ for (i=4; i<argc; i=i+5) {
+ if (! currentrule)
+ {
+ /* first element in the list */
+ currentrule = calloc(sizeof(rule_t),1);
+ headrule = currentrule;
+ }
+ else
+ {
+ /* follow-up element */
+ currentrule->next = calloc(sizeof(rule_t),1);
+ currentrule = currentrule->next;
+ }
+
+ if ( init_led(&(currentrule->led), argv[i]) )
+ return 1;
+
+ if ( sscanf(argv[i+1], "%d", &(currentrule->minq)) != 1 )
+ return 1;
+
+ if ( sscanf(argv[i+2], "%d", &(currentrule->maxq)) != 1 )
+ return 1;
+
+ if ( sscanf(argv[i+3], "%d", &(currentrule->boffset)) != 1 )
+ return 1;
+
+ if ( sscanf(argv[i+4], "%d", &(currentrule->bfactor)) != 1 )
+ return 1;
+ }
+ log_rules(headrule);
+
+ q0 = -1;
+ do {
+ q = quality(iw, ifname);
+ if ( q < q0 - s || q > q0 + s ) {
+ update_leds(headrule, q);
+ q0=q;
+ };
+ // re-open backend...
+ if ( q == -1 && q0 == -1 ) {
+ if (iw) {
+ iwinfo_finish();
+ iw=NULL;
+ usleep(BACKEND_RETRY_DELAY);
+ }
+ while (open_backend(&iw, ifname))
+ usleep(BACKEND_RETRY_DELAY);
+ }
+ usleep(r);
+ } while(1);
+
+ iwinfo_finish();
+
+ return 0;
+}
diff --git a/package/network/utils/tcpdump/Makefile b/package/network/utils/tcpdump/Makefile
new file mode 100644
index 0000000..bb42888
--- /dev/null
+++ b/package/network/utils/tcpdump/Makefile
@@ -0,0 +1,66 @@
+#
+# Copyright (C) 2007-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=tcpdump
+PKG_VERSION:=4.99.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.tcpdump.org/release/
+PKG_HASH:=8c75856e00addeeadf70dad67c9ff3dd368536b2b8563abf6854d7c764cd3adb
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+PKG_LICENSE:=BSD-3-Clause
+PKG_CPE_ID:=cpe:/a:tcpdump:tcpdump
+
+PKG_INSTALL:=1
+PKG_BUILD_FLAGS:=gc-sections
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/tcpdump/default
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=+libpcap
+ TITLE:=Network monitoring and data acquisition tool
+ URL:=http://www.tcpdump.org/
+endef
+
+define Package/tcpdump
+ $(Package/tcpdump/default)
+ VARIANT:=full
+endef
+
+define Package/tcpdump-mini
+ $(Package/tcpdump/default)
+ TITLE+= (minimal version)
+ VARIANT:=mini
+endef
+
+CONFIGURE_ARGS += \
+ --without-cap-ng \
+ --without-crypto \
+ $(call autoconf_bool,CONFIG_IPV6,ipv6)
+
+ifeq ($(BUILD_VARIANT),mini)
+ TARGET_CFLAGS += -DTCPDUMP_MINI
+ CONFIGURE_ARGS += --disable-smb
+ MAKE_FLAGS += TCPDUMP_MINI=1
+endif
+
+define Package/tcpdump/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/tcpdump $(1)/usr/bin/
+endef
+
+Package/tcpdump-mini/install = $(Package/tcpdump/install)
+
+$(eval $(call BuildPackage,tcpdump))
+$(eval $(call BuildPackage,tcpdump-mini))
diff --git a/package/network/utils/tcpdump/patches/001-remove_pcap_debug.patch b/package/network/utils/tcpdump/patches/001-remove_pcap_debug.patch
new file mode 100644
index 0000000..948e3b5
--- /dev/null
+++ b/package/network/utils/tcpdump/patches/001-remove_pcap_debug.patch
@@ -0,0 +1,100 @@
+--- a/configure
++++ b/configure
+@@ -7346,97 +7346,6 @@ esac
+ fi
+
+
+-#
+-# Check for special debugging functions
+-#
+-ac_fn_c_check_func "$LINENO" "pcap_set_parser_debug" "ac_cv_func_pcap_set_parser_debug"
+-if test "x$ac_cv_func_pcap_set_parser_debug" = xyes
+-then :
+- printf "%s\n" "#define HAVE_PCAP_SET_PARSER_DEBUG 1" >>confdefs.h
+-
+-fi
+-
+-if test "$ac_cv_func_pcap_set_parser_debug" = "no" ; then
+- #
+- # OK, we don't have pcap_set_parser_debug() to set the libpcap
+- # filter expression parser debug flag; can we directly set the
+- # flag?
+- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pcap_debug is defined by libpcap" >&5
+-printf %s "checking whether pcap_debug is defined by libpcap... " >&6; }
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-int
+-main (void)
+-{
+-
+- extern int pcap_debug;
+-
+- return pcap_debug;
+-
+- ;
+- return 0;
+-}
+-
+-_ACEOF
+-if ac_fn_c_try_link "$LINENO"
+-then :
+- ac_lbl_cv_pcap_debug_defined=yes
+-else $as_nop
+- ac_lbl_cv_pcap_debug_defined=no
+-fi
+-rm -f core conftest.err conftest.$ac_objext conftest.beam \
+- conftest$ac_exeext conftest.$ac_ext
+- if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then
+- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-printf "%s\n" "yes" >&6; }
+-
+-printf "%s\n" "#define HAVE_PCAP_DEBUG 1" >>confdefs.h
+-
+- else
+- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-printf "%s\n" "no" >&6; }
+- #
+- # OK, what about "yydebug"?
+- #
+- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether yydebug is defined by libpcap" >&5
+-printf %s "checking whether yydebug is defined by libpcap... " >&6; }
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-int
+-main (void)
+-{
+-
+- extern int yydebug;
+-
+- return yydebug;
+-
+- ;
+- return 0;
+-}
+-
+-_ACEOF
+-if ac_fn_c_try_link "$LINENO"
+-then :
+- ac_lbl_cv_yydebug_defined=yes
+-else $as_nop
+- ac_lbl_cv_yydebug_defined=no
+-fi
+-rm -f core conftest.err conftest.$ac_objext conftest.beam \
+- conftest$ac_exeext conftest.$ac_ext
+- if test "$ac_lbl_cv_yydebug_defined" = yes ; then
+- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-printf "%s\n" "yes" >&6; }
+-
+-printf "%s\n" "#define HAVE_YYDEBUG 1" >>confdefs.h
+-
+- else
+- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-printf "%s\n" "no" >&6; }
+- fi
+- fi
+-fi
+ ac_fn_c_check_func "$LINENO" "pcap_set_optimizer_debug" "ac_cv_func_pcap_set_optimizer_debug"
+ if test "x$ac_cv_func_pcap_set_optimizer_debug" = xyes
+ then :
diff --git a/package/network/utils/tcpdump/patches/100-tcpdump_mini.patch b/package/network/utils/tcpdump/patches/100-tcpdump_mini.patch
new file mode 100644
index 0000000..eeaa17c
--- /dev/null
+++ b/package/network/utils/tcpdump/patches/100-tcpdump_mini.patch
@@ -0,0 +1,861 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -73,6 +73,86 @@ DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
+
+ CSRC = fptype.c tcpdump.c
+
++ifdef TCPDUMP_MINI
++
++LIBNETDISSECT_SRC=\
++ netdissect.c \
++ netdissect-alloc.c \
++ addrtoname.c \
++ addrtostr.c \
++ af.c \
++ ascii_strcasecmp.c \
++ checksum.c \
++ cpack.c \
++ gmpls.c \
++ in_cksum.c \
++ ipproto.c \
++ l2vpn.c \
++ machdep.c \
++ ntp.c \
++ nlpid.c \
++ oui.c \
++ parsenfsfh.c \
++ print.c \
++ print-802_11.c \
++ print-aodv.c \
++ print-arista.c \
++ print-arp.c \
++ print-ascii.c \
++ print-bootp.c \
++ print-dhcp6.c \
++ print-domain.c \
++ print-eap.c \
++ print-ether.c \
++ print-ftp.c \
++ print-gre.c \
++ print-http.c \
++ print-icmp.c \
++ print-icmp6.c \
++ print-igmp.c \
++ print-ip-demux.c \
++ print-ip.c \
++ print-ip6.c \
++ print-ip6opts.c \
++ print-ipnet.c \
++ print-l2tp.c \
++ print-llc.c \
++ print-lldp.c \
++ print-loopback.c \
++ print-macsec.c \
++ print-nfs.c \
++ print-ntp.c \
++ print-null.c \
++ print-olsr.c \
++ print-ospf.c \
++ print-ospf6.c \
++ print-ppp.c \
++ print-pppoe.c \
++ print-pptp.c \
++ print-radius.c \
++ print-raw.c \
++ print-rsvp.c \
++ print-rt6.c \
++ print-rtsp.c \
++ print-sip.c \
++ print-sll.c \
++ print-smtp.c \
++ print-snmp.c \
++ print-stp.c \
++ print-sunrpc.c \
++ print-syslog.c \
++ print-tcp.c \
++ print-telnet.c \
++ print-tftp.c \
++ print-udp.c \
++ print-unsupported.c \
++ print-whois.c \
++ signature.c \
++ strtoaddr.c \
++ util-print.c
++
++else
++
+ LIBNETDISSECT_SRC=\
+ addrtoname.c \
+ addrtostr.c \
+@@ -254,6 +334,8 @@ LIBNETDISSECT_SRC=\
+ strtoaddr.c \
+ util-print.c
+
++endif
++
+ LOCALSRC = @LOCALSRC@
+ LIBOBJS = @LIBOBJS@
+
+--- a/addrtoname.c
++++ b/addrtoname.c
+@@ -677,8 +677,10 @@ linkaddr_string(netdissect_options *ndo,
+ if (type == LINKADDR_ETHER && len == MAC_ADDR_LEN)
+ return (etheraddr_string(ndo, ep));
+
++#ifndef TCPDUMP_MINI
+ if (type == LINKADDR_FRELAY)
+ return (q922_string(ndo, ep, len));
++#endif
+
+ tp = lookup_bytestring(ndo, ep, len);
+ if (tp->bs_name)
+@@ -1257,6 +1259,7 @@ init_addrtoname(netdissect_options *ndo,
+ init_ipxsaparray(ndo);
+ }
+
++#ifndef TCPDUMP_MINI
+ const char *
+ dnaddr_string(netdissect_options *ndo, u_short dnaddr)
+ {
+@@ -1273,6 +1276,7 @@ dnaddr_string(netdissect_options *ndo, u
+
+ return(tp->name);
+ }
++#endif
+
+ /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
+ struct hnamemem *
+--- a/print-ether.c
++++ b/print-ether.c
+@@ -543,6 +543,7 @@ ethertype_print(netdissect_options *ndo,
+ arp_print(ndo, p, length, caplen);
+ return (1);
+
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_DN:
+ decnet_print(ndo, p, length, caplen);
+ return (1);
+@@ -573,6 +574,7 @@ ethertype_print(netdissect_options *ndo,
+ ND_TCHECK_LEN(p, 1);
+ isoclns_print(ndo, p + 1, length - 1);
+ return(1);
++#endif
+
+ case ETHERTYPE_PPPOED:
+ case ETHERTYPE_PPPOES:
+@@ -585,9 +587,11 @@ ethertype_print(netdissect_options *ndo,
+ eapol_print(ndo, p);
+ return (1);
+
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_REALTEK:
+ rtl_print(ndo, p, length, src, dst);
+ return (1);
++#endif
+
+ case ETHERTYPE_PPP:
+ if (length) {
+@@ -596,6 +600,7 @@ ethertype_print(netdissect_options *ndo,
+ }
+ return (1);
+
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_MPCP:
+ mpcp_print(ndo, p, length);
+ return (1);
+@@ -608,19 +613,23 @@ ethertype_print(netdissect_options *ndo,
+ case ETHERTYPE_CFM_OLD:
+ cfm_print(ndo, p, length);
+ return (1);
++#endif
+
+ case ETHERTYPE_LLDP:
+ lldp_print(ndo, p, length);
+ return (1);
+
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_NSH:
+ nsh_print(ndo, p, length);
+ return (1);
++#endif
+
+ case ETHERTYPE_LOOPBACK:
+ loopback_print(ndo, p, length);
+ return (1);
+
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_MPLS:
+ case ETHERTYPE_MPLS_MULTI:
+ mpls_print(ndo, p, length);
+@@ -650,6 +659,7 @@ ethertype_print(netdissect_options *ndo,
+ case ETHERTYPE_PTP:
+ ptp_print(ndo, p, length);
+ return (1);
++#endif
+
+ case ETHERTYPE_LAT:
+ case ETHERTYPE_SCA:
+--- a/print-gre.c
++++ b/print-gre.c
+@@ -205,6 +205,7 @@ gre_print_0(netdissect_options *ndo, con
+ case ETHERTYPE_IPV6:
+ ip6_print(ndo, bp, len);
+ break;
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_MPLS:
+ mpls_print(ndo, bp, len);
+ break;
+@@ -217,6 +218,7 @@ gre_print_0(netdissect_options *ndo, con
+ case ETHERTYPE_GRE_ISO:
+ isoclns_print(ndo, bp, len);
+ break;
++#endif
+ case ETHERTYPE_TEB:
+ ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
+ break;
+--- a/print-icmp6.c
++++ b/print-icmp6.c
+@@ -1369,7 +1369,7 @@ get_upperlayer(netdissect_options *ndo,
+ nh = GET_U_1(fragh->ip6f_nxt);
+ hlen = sizeof(struct ip6_frag);
+ break;
+-
++#ifndef TCPDUMP_MINI
+ case IPPROTO_AH:
+ ah = (const struct ah *)bp;
+ if (!ND_TTEST_1(ah->ah_len))
+@@ -1377,7 +1377,7 @@ get_upperlayer(netdissect_options *ndo,
+ nh = GET_U_1(ah->ah_nxt);
+ hlen = (GET_U_1(ah->ah_len) + 2) << 2;
+ break;
+-
++#endif
+ default: /* unknown or undecodable header */
+ *prot = nh; /* meaningless, but set here anyway */
+ return(NULL);
+--- a/print-igmp.c
++++ b/print-igmp.c
+@@ -267,6 +267,7 @@ igmp_print(netdissect_options *ndo,
+ case 0x17:
+ ND_PRINT("igmp leave %s", GET_IPADDR_STRING(bp + 4));
+ break;
++#ifndef TCPDUMP_MINI
+ case 0x13:
+ ND_PRINT("igmp dvmrp");
+ if (len < 8)
+@@ -278,6 +279,7 @@ igmp_print(netdissect_options *ndo,
+ ND_PRINT("igmp pimv1");
+ pimv1_print(ndo, bp, len);
+ break;
++#endif
+ case 0x1e:
+ print_mtrace(ndo, "mresp", bp, len);
+ break;
+--- a/print-ip-demux.c
++++ b/print-ip-demux.c
+@@ -46,6 +46,7 @@ ip_demux_print(netdissect_options *ndo,
+ again:
+ switch (nh) {
+
++#ifndef TCPDUMP_MINI
+ case IPPROTO_AH:
+ if (!ND_TTEST_1(bp)) {
+ ndo->ndo_protocol = "ah";
+@@ -83,7 +84,9 @@ again:
+ */
+ break;
+ }
++#endif
+
++#ifndef TCPDUMP_MINI
+ case IPPROTO_SCTP:
+ sctp_print(ndo, bp, iph, length);
+ break;
+@@ -91,7 +94,7 @@ again:
+ case IPPROTO_DCCP:
+ dccp_print(ndo, bp, iph, length);
+ break;
+-
++#endif
+ case IPPROTO_TCP:
+ tcp_print(ndo, bp, length, iph, fragmented);
+ break;
+@@ -120,6 +123,7 @@ again:
+ }
+ break;
+
++#ifndef TCPDUMP_MINI
+ case IPPROTO_PIGP:
+ /*
+ * XXX - the current IANA protocol number assignments
+@@ -140,14 +144,17 @@ again:
+ case IPPROTO_EIGRP:
+ eigrp_print(ndo, bp, length);
+ break;
++#endif
+
+ case IPPROTO_ND:
+ ND_PRINT(" nd %u", length);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case IPPROTO_EGP:
+ egp_print(ndo, bp, length);
+ break;
++#endif
+
+ case IPPROTO_OSPF:
+ if (ver == 6)
+@@ -184,6 +191,7 @@ again:
+ gre_print(ndo, bp, length);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case IPPROTO_MOBILE:
+ mobile_print(ndo, bp, length);
+ break;
+@@ -203,6 +211,7 @@ again:
+ case IPPROTO_PGM:
+ pgm_print(ndo, bp, length, iph);
+ break;
++#endif
+
+ case IPPROTO_ETHERNET:
+ if (ver == 6)
+--- a/print-ip6.c
++++ b/print-ip6.c
+@@ -133,10 +133,11 @@ ip6_finddst(netdissect_options *ndo, nd_
+ * Only one routing header to a customer.
+ */
+ goto done;
+-
++#ifndef TCPDUMP_MINI
+ case IPPROTO_AH:
+ case IPPROTO_ESP:
+ case IPPROTO_IPCOMP:
++#endif
+ default:
+ /*
+ * AH and ESP are, in the RFCs that describe them,
+@@ -371,6 +372,7 @@ ip6_print(netdissect_options *ndo, const
+ nh = GET_U_1(cp);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case IPPROTO_FRAGMENT:
+ advance = frag6_print(ndo, cp, (const u_char *)ip6);
+ if (advance < 0 || ndo->ndo_snapend <= cp + advance) {
+@@ -401,7 +403,7 @@ ip6_print(netdissect_options *ndo, const
+ nh = GET_U_1(cp);
+ nd_pop_packet_info(ndo);
+ return;
+-
++#endif
+ case IPPROTO_ROUTING:
+ ND_TCHECK_1(cp);
+ advance = rt6_print(ndo, cp, (const u_char *)ip6);
+--- a/print-llc.c
++++ b/print-llc.c
+@@ -205,6 +205,7 @@ llc_print(netdissect_options *ndo, const
+ hdrlen = 4; /* DSAP, SSAP, 2-byte control field */
+ }
+
++#ifndef TCPDUMP_MINI
+ if (ssap_field == LLCSAP_GLOBAL && dsap_field == LLCSAP_GLOBAL) {
+ /*
+ * This is an Ethernet_802.3 IPX frame; it has an
+@@ -227,6 +228,7 @@ llc_print(netdissect_options *ndo, const
+ ipx_print(ndo, p, length);
+ return (0); /* no LLC header */
+ }
++#endif
+
+ dsap = dsap_field & ~LLC_IG;
+ ssap = ssap_field & ~LLC_GSAP;
+@@ -290,6 +292,7 @@ llc_print(netdissect_options *ndo, const
+ return (hdrlen);
+ }
+
++#ifndef TCPDUMP_MINI
+ if (ssap == LLCSAP_IPX && dsap == LLCSAP_IPX &&
+ control == LLC_UI) {
+ /*
+@@ -303,6 +306,7 @@ llc_print(netdissect_options *ndo, const
+ ipx_print(ndo, p, length);
+ return (hdrlen);
+ }
++#endif
+
+ #ifdef ENABLE_SMB
+ if (ssap == LLCSAP_NETBEUI && dsap == LLCSAP_NETBEUI
+@@ -321,12 +325,13 @@ llc_print(netdissect_options *ndo, const
+ return (hdrlen);
+ }
+ #endif
++#ifndef TCPDUMP_MINI
+ if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
+ && control == LLC_UI) {
+ isoclns_print(ndo, p, length);
+ return (hdrlen);
+ }
+-
++#endif
+ if (!ndo->ndo_eflag) {
+ if (ssap == dsap) {
+ if (src == NULL || dst == NULL)
+@@ -482,6 +487,7 @@ snap_print(netdissect_options *ndo, cons
+
+ case OUI_CISCO:
+ switch (et) {
++#ifndef TCPDUMP_MINI
+ case PID_CISCO_CDP:
+ cdp_print(ndo, p, length);
+ return (1);
+@@ -494,6 +500,7 @@ snap_print(netdissect_options *ndo, cons
+ case PID_CISCO_VTP:
+ vtp_print(ndo, p, length);
+ return (1);
++#endif
+ case PID_CISCO_PVST:
+ case PID_CISCO_VLANBRIDGE:
+ stp_print(ndo, p, length);
+@@ -506,6 +513,7 @@ snap_print(netdissect_options *ndo, cons
+ case OUI_RFC2684:
+ switch (et) {
+
++#ifndef TCPDUMP_MINI
+ case PID_RFC2684_ETH_FCS:
+ case PID_RFC2684_ETH_NOFCS:
+ /*
+@@ -567,6 +575,7 @@ snap_print(netdissect_options *ndo, cons
+ */
+ fddi_print(ndo, p, length, caplen);
+ return (1);
++#endif
+
+ case PID_RFC2684_BPDU:
+ stp_print(ndo, p, length);
+--- a/print-null.c
++++ b/print-null.c
+@@ -114,6 +114,7 @@ null_if_print(netdissect_options *ndo, c
+ ip6_print(ndo, p, length);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case BSD_AFNUM_ISO:
+ isoclns_print(ndo, p, length);
+ break;
+@@ -125,6 +126,7 @@ null_if_print(netdissect_options *ndo, c
+ case BSD_AFNUM_IPX:
+ ipx_print(ndo, p, length);
+ break;
++#endif
+
+ default:
+ /* unknown AF_ value */
+--- a/print-ppp.c
++++ b/print-ppp.c
+@@ -1354,6 +1354,7 @@ trunc:
+ * The length argument is the on-the-wire length, not the captured
+ * length; we can only un-escape the captured part.
+ */
++#ifndef TCPDUMP_MINI
+ static void
+ ppp_hdlc(netdissect_options *ndo,
+ const u_char *p, u_int length)
+@@ -1451,17 +1452,19 @@ trunc:
+ nd_pop_packet_info(ndo);
+ nd_print_trunc(ndo);
+ }
+-
++#endif
+
+ /* PPP */
+ static void
+ handle_ppp(netdissect_options *ndo,
+ u_int proto, const u_char *p, u_int length)
+ {
++#ifndef TCPDUMP_MINI
+ if ((proto & 0xff00) == 0x7e00) { /* is this an escape code ? */
+ ppp_hdlc(ndo, p - 1, length);
+ return;
+ }
++#endif
+
+ switch (proto) {
+ case PPP_LCP: /* fall through */
+@@ -1494,6 +1497,7 @@ handle_ppp(netdissect_options *ndo,
+ case PPP_IPV6:
+ ip6_print(ndo, p, length);
+ break;
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_IPX: /*XXX*/
+ case PPP_IPX:
+ ipx_print(ndo, p, length);
+@@ -1505,6 +1509,7 @@ handle_ppp(netdissect_options *ndo,
+ case PPP_MPLS_MCAST:
+ mpls_print(ndo, p, length);
+ break;
++#endif
+ case PPP_COMP:
+ ND_PRINT("compressed PPP data");
+ break;
+@@ -1652,6 +1657,7 @@ ppp_if_print(netdissect_options *ndo,
+ ppp_print(ndo, p, length);
+ }
+
++#ifndef TCPDUMP_MINI
+ /*
+ * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like
+ * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547,
+@@ -1895,3 +1901,4 @@ printx:
+ #endif /* __bsdi__ */
+ ndo->ndo_ll_hdr_len += hdrlength;
+ }
++#endif
+--- a/print-sll.c
++++ b/print-sll.c
+@@ -463,12 +463,14 @@ recurse:
+ */
+ switch (ether_type) {
+
++#ifndef TCPDUMP_MINI
+ case LINUX_SLL_P_802_3:
+ /*
+ * Ethernet_802.3 IPX frame.
+ */
+ ipx_print(ndo, p, length);
+ break;
++#endif
+
+ case LINUX_SLL_P_802_2:
+ /*
+--- a/print-tcp.c
++++ b/print-tcp.c
+@@ -612,6 +612,7 @@ tcp_print(netdissect_options *ndo,
+ ND_PRINT(" %u", utoval);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case TCPOPT_MPTCP:
+ {
+ const u_char *snapend_save;
+@@ -635,7 +636,7 @@ tcp_print(netdissect_options *ndo,
+ goto bad;
+ break;
+ }
+-
++#endif
+ case TCPOPT_FASTOPEN:
+ datalen = len - 2;
+ LENCHECK(datalen);
+@@ -720,6 +721,7 @@ tcp_print(netdissect_options *ndo,
+ return;
+ }
+
++#ifndef TCPDUMP_MINI
+ if (ndo->ndo_packettype) {
+ switch (ndo->ndo_packettype) {
+ case PT_ZMTP1:
+@@ -735,12 +737,15 @@ tcp_print(netdissect_options *ndo,
+ }
+ return;
+ }
++#endif
+
+ if (IS_SRC_OR_DST_PORT(FTP_PORT)) {
+ ND_PRINT(": ");
+ ftp_print(ndo, bp, length);
++#ifndef TCPDUMP_MINI
+ } else if (IS_SRC_OR_DST_PORT(SSH_PORT)) {
+ ssh_print(ndo, bp, length);
++#endif
+ } else if (IS_SRC_OR_DST_PORT(TELNET_PORT)) {
+ telnet_print(ndo, bp, length);
+ } else if (IS_SRC_OR_DST_PORT(SMTP_PORT)) {
+@@ -759,10 +764,12 @@ tcp_print(netdissect_options *ndo,
+ } else if (IS_SRC_OR_DST_PORT(NETBIOS_SSN_PORT)) {
+ nbt_tcp_print(ndo, bp, length);
+ #endif
++#ifndef TCPDUMP_MINI
+ } else if (IS_SRC_OR_DST_PORT(BGP_PORT)) {
+- bgp_print(ndo, bp, length);
++ bgp_print(ndo, bp, length);
+ } else if (IS_SRC_OR_DST_PORT(RPKI_RTR_PORT)) {
+ rpki_rtr_print(ndo, bp, length);
++#endif
+ #ifdef ENABLE_SMB
+ } else if (IS_SRC_OR_DST_PORT(SMB_PORT)) {
+ smb_tcp_print(ndo, bp, length);
+@@ -770,18 +777,22 @@ tcp_print(netdissect_options *ndo,
+ } else if (IS_SRC_OR_DST_PORT(RTSP_PORT)) {
+ ND_PRINT(": ");
+ rtsp_print(ndo, bp, length);
++#ifndef TCPDUMP_MINI
+ } else if (IS_SRC_OR_DST_PORT(MSDP_PORT)) {
+ msdp_print(ndo, bp, length);
+ } else if (IS_SRC_OR_DST_PORT(LDP_PORT)) {
+ ldp_print(ndo, bp, length);
+- } else if (IS_SRC_OR_DST_PORT(PPTP_PORT))
++#endif
++ } else if (IS_SRC_OR_DST_PORT(PPTP_PORT)) {
+ pptp_print(ndo, bp);
+- else if (IS_SRC_OR_DST_PORT(REDIS_PORT))
++#ifndef TCPDUMP_MINI
++ } else if (IS_SRC_OR_DST_PORT(REDIS_PORT))
+ resp_print(ndo, bp, length);
+ else if (IS_SRC_OR_DST_PORT(BEEP_PORT))
+ beep_print(ndo, bp, length);
+ else if (IS_SRC_OR_DST_PORT(OPENFLOW_PORT_OLD) || IS_SRC_OR_DST_PORT(OPENFLOW_PORT_IANA)) {
+ openflow_print(ndo, bp, length);
++#endif
+ } else if (IS_SRC_OR_DST_PORT(HTTP_PORT_ALT)) {
+ ND_PRINT(": ");
+ http_print(ndo, bp, length);
+--- a/print-udp.c
++++ b/print-udp.c
+@@ -433,10 +433,12 @@ udp_print(netdissect_options *ndo, const
+ vat_print(ndo, cp, length);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case PT_WB:
+ udpipaddr_print(ndo, ip, sport, dport);
+ wb_print(ndo, cp, length);
+ break;
++#endif
+
+ case PT_RPC:
+ rp = (const struct sunrpc_msg *)cp;
+@@ -465,10 +467,12 @@ udp_print(netdissect_options *ndo, const
+ snmp_print(ndo, cp, length);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case PT_CNFP:
+ udpipaddr_print(ndo, ip, sport, dport);
+ cnfp_print(ndo, cp);
+ break;
++#endif
+
+ case PT_TFTP:
+ udpipaddr_print(ndo, ip, sport, dport);
+@@ -485,6 +489,7 @@ udp_print(netdissect_options *ndo, const
+ radius_print(ndo, cp, length);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case PT_VXLAN:
+ udpipaddr_print(ndo, ip, sport, dport);
+ vxlan_print(ndo, cp, length);
+@@ -507,6 +512,7 @@ udp_print(netdissect_options *ndo, const
+ udpipaddr_print(ndo, ip, sport, dport);
+ someip_print(ndo, cp, length);
+ break;
++#endif
+ case PT_DOMAIN:
+ udpipaddr_print(ndo, ip, sport, dport);
+ /* over_tcp: FALSE, is_mdns: FALSE */
+@@ -594,8 +600,12 @@ udp_print(netdissect_options *ndo, const
+ bootp_print(ndo, cp, length);
+ else if (IS_SRC_OR_DST_PORT(TFTP_PORT))
+ tftp_print(ndo, cp, length);
++#ifndef TCPDUMP_MINI
++#ifdef ENABLE_SMB
+ else if (IS_SRC_OR_DST_PORT(KERBEROS_PORT))
+ krb_print(ndo, (const u_char *)cp);
++#endif
++#endif
+ else if (IS_SRC_OR_DST_PORT(NTP_PORT))
+ ntp_print(ndo, cp, length);
+ #ifdef ENABLE_SMB
+@@ -607,6 +617,7 @@ udp_print(netdissect_options *ndo, const
+ else if (IS_SRC_OR_DST_PORT(SNMP_PORT) ||
+ IS_SRC_OR_DST_PORT(SNMPTRAP_PORT))
+ snmp_print(ndo, cp, length);
++#ifndef TCPDUMP_MINI
+ else if (IS_SRC_OR_DST_PORT(PTP_EVENT_PORT) ||
+ IS_SRC_OR_DST_PORT(PTP_GENERAL_PORT))
+ ptp_print(ndo, cp, length);
+@@ -614,38 +625,50 @@ udp_print(netdissect_options *ndo, const
+ cisco_autorp_print(ndo, cp, length);
+ else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT))
+ isakmp_print(ndo, cp, length, bp2);
++#endif
+ else if (IS_SRC_OR_DST_PORT(SYSLOG_PORT))
+ syslog_print(ndo, cp, length);
++#ifndef TCPDUMP_MINI
+ else if (IS_SRC_OR_DST_PORT(RIP_PORT))
+ rip_print(ndo, cp, length);
+ else if (IS_SRC_OR_DST_PORT(RIPNG_PORT))
+ ripng_print(ndo, cp, length);
+ else if (IS_SRC_OR_DST_PORT(TIMED_PORT))
+ timed_print(ndo, (const u_char *)cp);
++#endif
+ else if (IS_SRC_OR_DST_PORT(DHCP6_SERV_PORT) ||
+ IS_SRC_OR_DST_PORT(DHCP6_CLI_PORT))
+ dhcp6_print(ndo, cp, length);
++#ifndef TCPDUMP_MINI
+ else if (IS_SRC_OR_DST_PORT(LDP_PORT))
+ ldp_print(ndo, cp, length);
+ else if (IS_SRC_OR_DST_PORT(AODV_PORT))
+ aodv_print(ndo, cp, length, IP_V(ip) == 6);
++#endif
+ else if (IS_SRC_OR_DST_PORT(OLSR_PORT))
+ olsr_print(ndo, cp, length, IP_V(ip) == 6);
++#ifndef TCPDUMP_MINI
+ else if (IS_SRC_OR_DST_PORT(LMP_PORT))
+ lmp_print(ndo, cp, length);
++#ifdef ENABLE_SMB
+ else if (IS_SRC_OR_DST_PORT(KERBEROS_SEC_PORT))
+ krb_print(ndo, (const u_char *)cp);
++#endif
+ else if (IS_SRC_OR_DST_PORT(LWRES_PORT))
+ lwres_print(ndo, cp, length);
+ else if (IS_SRC_OR_DST_PORT(MULTICASTDNS_PORT))
+ /* over_tcp: FALSE, is_mdns: TRUE */
+ domain_print(ndo, cp, length, FALSE, TRUE);
++#ifdef ENABLE_SMB
+ else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT_NATT))
+ isakmp_rfc3948_print(ndo, cp, length, bp2, IP_V(ip), fragmented, ttl_hl);
+ else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT_USER1) || IS_SRC_OR_DST_PORT(ISAKMP_PORT_USER2))
+ isakmp_print(ndo, cp, length, bp2);
++#endif
++#endif
+ else if (IS_SRC_OR_DST_PORT(L2TP_PORT))
+ l2tp_print(ndo, cp, length);
++#ifndef TCPDUMP_MINI
+ else if (dport == VAT_PORT)
+ vat_print(ndo, cp, length);
+ else if (IS_SRC_OR_DST_PORT(ZEPHYR_SRV_PORT) || IS_SRC_OR_DST_PORT(ZEPHYR_CLT_PORT))
+@@ -669,6 +692,7 @@ udp_print(netdissect_options *ndo, const
+ */
+ else if (dport == WB_PORT)
+ wb_print(ndo, cp, length);
++#endif
+ else if (IS_SRC_OR_DST_PORT(RADIUS_PORT) ||
+ IS_SRC_OR_DST_PORT(RADIUS_NEW_PORT) ||
+ IS_SRC_OR_DST_PORT(RADIUS_ACCOUNTING_PORT) ||
+@@ -676,6 +700,7 @@ udp_print(netdissect_options *ndo, const
+ IS_SRC_OR_DST_PORT(RADIUS_CISCO_COA_PORT) ||
+ IS_SRC_OR_DST_PORT(RADIUS_COA_PORT) )
+ radius_print(ndo, cp, length);
++#ifndef TCPDUMP_MINI
+ else if (dport == HSRP_PORT)
+ hsrp_print(ndo, cp, length);
+ else if (IS_SRC_OR_DST_PORT(MPLS_LSP_PING_PORT))
+@@ -695,8 +720,10 @@ udp_print(netdissect_options *ndo, const
+ lwapp_control_print(ndo, cp, length, 0);
+ else if (IS_SRC_OR_DST_PORT(LWAPP_DATA_PORT))
+ lwapp_data_print(ndo, cp, length);
++#endif
+ else if (IS_SRC_OR_DST_PORT(SIP_PORT))
+ sip_print(ndo, cp, length);
++#ifndef TCPDUMP_MINI
+ else if (IS_SRC_OR_DST_PORT(OTV_PORT))
+ otv_print(ndo, cp, length);
+ else if (IS_SRC_OR_DST_PORT(VXLAN_PORT))
+@@ -721,6 +748,7 @@ udp_print(netdissect_options *ndo, const
+ someip_print(ndo, cp, length);
+ else if (sport == BCM_LI_PORT)
+ bcm_li_print(ndo, cp, length);
++#endif
+ else {
+ if (ulen > length && !fragmented)
+ ND_PRINT("UDP, bad length %u > %u",
+--- a/print.c
++++ b/print.c
+@@ -46,6 +46,7 @@ struct printer {
+ };
+
+ static const struct printer printers[] = {
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_APPLE_IP_OVER_IEEE1394
+ { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 },
+ #endif
+@@ -84,7 +85,9 @@ static const struct printer printers[] =
+ #ifdef DLT_ENC
+ { enc_if_print, DLT_ENC },
+ #endif
++#endif
+ { ether_if_print, DLT_EN10MB },
++#ifndef TCPDUMP_MINI
+ { fddi_if_print, DLT_FDDI },
+ #ifdef DLT_FR
+ { fr_if_print, DLT_FR },
+@@ -92,6 +95,7 @@ static const struct printer printers[] =
+ #ifdef DLT_FRELAY
+ { fr_if_print, DLT_FRELAY },
+ #endif
++#endif
+ #ifdef DLT_IEEE802_11
+ { ieee802_11_if_print, DLT_IEEE802_11},
+ #endif
+@@ -101,6 +105,7 @@ static const struct printer printers[] =
+ #ifdef DLT_IEEE802_11_RADIO
+ { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO },
+ #endif
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_IEEE802_15_4
+ { ieee802_15_4_if_print, DLT_IEEE802_15_4 },
+ #endif
+@@ -113,9 +118,11 @@ static const struct printer printers[] =
+ #ifdef DLT_IP_OVER_FC
+ { ipfc_if_print, DLT_IP_OVER_FC },
+ #endif
++#endif
+ #ifdef DLT_IPNET
+ { ipnet_if_print, DLT_IPNET },
+ #endif
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_IPOIB
+ { ipoib_if_print, DLT_IPOIB },
+ #endif
+@@ -170,19 +177,23 @@ static const struct printer printers[] =
+ #ifdef DLT_MFR
+ { mfr_if_print, DLT_MFR },
+ #endif
++#endif
+ #ifdef DLT_NETANALYZER
+ { netanalyzer_if_print, DLT_NETANALYZER },
+ #endif
+ #ifdef DLT_NETANALYZER_TRANSPARENT
+ { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
+ #endif
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_NFLOG
+ { nflog_if_print, DLT_NFLOG},
+ #endif
++#endif
+ { null_if_print, DLT_NULL },
+ #ifdef DLT_LOOP
+ { null_if_print, DLT_LOOP },
+ #endif
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_PFLOG
+ { pflog_if_print, DLT_PFLOG },
+ #endif
+@@ -198,6 +209,7 @@ static const struct printer printers[] =
+ #ifdef DLT_PPP_SERIAL
+ { ppp_hdlc_if_print, DLT_PPP_SERIAL },
+ #endif
++#endif
+ { ppp_if_print, DLT_PPP },
+ #ifdef DLT_PPP_PPPD
+ { ppp_if_print, DLT_PPP_PPPD },
+@@ -209,6 +221,7 @@ static const struct printer printers[] =
+ { prism_if_print, DLT_PRISM_HEADER },
+ #endif
+ { raw_if_print, DLT_RAW },
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_IPV4
+ { raw_if_print, DLT_IPV4 },
+ #endif
+@@ -241,6 +254,7 @@ static const struct printer printers[] =
+ #ifdef DLT_VSOCK
+ { vsock_if_print, DLT_VSOCK },
+ #endif
++#endif
+ { NULL, 0 },
+ };
+
diff --git a/package/network/utils/umbim/Makefile b/package/network/utils/umbim/Makefile
new file mode 100644
index 0000000..39c30d7
--- /dev/null
+++ b/package/network/utils/umbim/Makefile
@@ -0,0 +1,44 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=umbim
+PKG_RELEASE:=25
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=$(PROJECT_GIT)/project/umbim.git
+PKG_SOURCE_DATE:=2022-08-13
+PKG_SOURCE_VERSION:=146bc77c98ace3d1cc672986669650d2e1da71f3
+PKG_MIRROR_HASH:=9eae9f191e9c4a8132dba32e356047b8dfd62556f06800f05a283630cfed472a
+PKG_MAINTAINER:=John Crispin <john@phrozen.org>
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=
+
+PKG_FLAGS:=nonshared
+PKG_BUILD_FLAGS:=gc-sections
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/umbim
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=WWAN
+ DEPENDS:=+libubox +kmod-usb-net +kmod-usb-net-cdc-mbim +wwan
+ TITLE:=Control utility for mobile broadband modems
+endef
+
+define Package/umbim/description
+ umbim is a command line tool for controlling mobile broadband modems using
+ the MBIM-protocol.
+endef
+
+TARGET_CFLAGS += \
+ -I$(STAGING_DIR)/usr/include
+
+define Package/umbim/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/umbim $(1)/sbin/
+ $(CP) ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,umbim))
diff --git a/package/network/utils/umbim/files/lib/netifd/proto/mbim.sh b/package/network/utils/umbim/files/lib/netifd/proto/mbim.sh
new file mode 100755
index 0000000..75b914e
--- /dev/null
+++ b/package/network/utils/umbim/files/lib/netifd/proto/mbim.sh
@@ -0,0 +1,336 @@
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+#DBG=-v
+
+proto_mbim_init_config() {
+ available=1
+ no_device=1
+ proto_config_add_string "device:device"
+ proto_config_add_string apn
+ proto_config_add_string pincode
+ proto_config_add_string delay
+ proto_config_add_boolean allow_roaming
+ proto_config_add_boolean allow_partner
+ proto_config_add_string auth
+ proto_config_add_string username
+ proto_config_add_string password
+ [ -e /proc/sys/net/ipv6 ] && proto_config_add_string ipv6
+ proto_config_add_string dhcp
+ proto_config_add_string dhcpv6
+ proto_config_add_boolean sourcefilter
+ proto_config_add_boolean delegate
+ proto_config_add_string pdptype
+ proto_config_add_int mtu
+ proto_config_add_defaults
+}
+
+_proto_mbim_get_field() {
+ local field="$1"
+ shift
+ local mbimconfig="$@"
+ echo "$mbimconfig" | while read -r line; do
+ variable=${line%%:*}
+ [ "$variable" = "$field" ] || continue;
+ value=${line##* }
+ echo -n "$value "
+ done
+}
+
+_proto_mbim_setup() {
+ local interface="$1"
+ local tid=2
+ local ret
+
+ local device apn pincode delay auth username password allow_roaming allow_partner
+ local dhcp dhcpv6 pdptype ip4table ip6table mtu $PROTO_DEFAULT_OPTIONS
+ json_get_vars device apn pincode delay auth username password allow_roaming allow_partner
+ json_get_vars dhcp dhcpv6 sourcefilter delegate pdptype ip4table ip6table mtu $PROTO_DEFAULT_OPTIONS
+
+ [ ! -e /proc/sys/net/ipv6 ] && ipv6=0 || json_get_var ipv6 ipv6
+
+ [ -n "$ctl_device" ] && device=$ctl_device
+
+ [ -n "$device" ] || {
+ echo "mbim[$$]" "No control device specified"
+ proto_notify_error "$interface" NO_DEVICE
+ proto_set_available "$interface" 0
+ return 1
+ }
+ [ -c "$device" ] || {
+ echo "mbim[$$]" "The specified control device does not exist"
+ proto_notify_error "$interface" NO_DEVICE
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ devname="$(basename "$device")"
+ devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
+ ifname="$( ls "$devpath"/net )"
+
+ [ -n "$ifname" ] || {
+ echo "mbim[$$]" "Failed to find matching interface"
+ proto_notify_error "$interface" NO_IFNAME
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ [ -n "$apn" ] || {
+ echo "mbim[$$]" "No APN specified"
+ proto_notify_error "$interface" NO_APN
+ return 1
+ }
+
+ [ -n "$delay" ] && sleep "$delay"
+
+ echo "mbim[$$]" "Reading capabilities"
+ umbim $DBG -n -d $device caps || {
+ echo "mbim[$$]" "Failed to read modem caps"
+ tid=$((tid + 1))
+ umbim $DBG -t $tid -d "$device" disconnect
+ proto_notify_error "$interface" PIN_FAILED
+ return 1
+ }
+ tid=$((tid + 1))
+
+ [ "$pincode" ] && {
+ echo "mbim[$$]" "Sending pin"
+ umbim $DBG -n -t $tid -d $device unlock "$pincode" || {
+ echo "mbim[$$]" "Unable to verify PIN"
+ tid=$((tid + 1))
+ umbim $DBG -t $tid -d "$device" disconnect
+ proto_notify_error "$interface" PIN_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+ }
+ tid=$((tid + 1))
+
+ echo "mbim[$$]" "Checking pin"
+ umbim $DBG -n -t $tid -d $device pinstate
+ [ $? -eq 2 ] && {
+ echo "mbim[$$]" "PIN required"
+ tid=$((tid + 1))
+ umbim $DBG -t $tid -d "$device" disconnect
+ proto_notify_error "$interface" PIN_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+ tid=$((tid + 1))
+
+ echo "mbim[$$]" "Checking subscriber"
+ umbim $DBG -n -t $tid -d $device subscriber || {
+ echo "mbim[$$]" "Subscriber init failed"
+ tid=$((tid + 1))
+ umbim $DBG -t $tid -d "$device" disconnect
+ proto_notify_error "$interface" NO_SUBSCRIBER
+ return 1
+ }
+ tid=$((tid + 1))
+
+ echo "mbim[$$]" "Register with network"
+ connected=0
+ umbim $DBG -n -t $tid -d $device registration
+ reg_status=$?
+ case $reg_status in
+ 0) echo "mbim[$$]" "Registered in home mode"
+ tid=$((tid + 1))
+ connected=1;;
+ 4) if [ "$allow_roaming" = "1" ]; then
+ echo "mbim[$$]" "Registered in roaming mode"
+ tid=$((tid + 1))
+ connected=1
+ fi;;
+ 5) if [ "$allow_partner" = "1" ]; then
+ echo "mbim[$$]" "Registered in partner mode"
+ tid=$((tid + 1))
+ connected=1
+ fi;;
+ esac
+ if [ $connected -ne 1 ]; then
+ echo "mbim[$$]" "Subscriber registration failed (code $reg_status)"
+ tid=$((tid + 1))
+ umbim $DBG -t $tid -d "$device" disconnect
+ proto_notify_error "$interface" NO_REGISTRATION
+ return 1
+ fi
+
+ echo "mbim[$$]" "Attach to network"
+ umbim $DBG -n -t $tid -d $device attach || {
+ echo "mbim[$$]" "Failed to attach to network"
+ tid=$((tid + 1))
+ umbim $DBG -t $tid -d "$device" disconnect
+ proto_notify_error "$interface" ATTACH_FAILED
+ return 1
+ }
+ tid=$((tid + 1))
+
+ pdptype=$(echo "$pdptype" | awk '{print tolower($0)}')
+ [ "$ipv6" = 0 ] && pdptype="ipv4"
+
+ local req_pdptype="" # Pass "default" PDP type to umbim if unconfigured
+ [ "$pdptype" = "ipv4" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && req_pdptype="$pdptype:"
+
+ local connect_state
+ echo "mbim[$$]" "Connect to network"
+ connect_state=$(umbim $DBG -n -t $tid -d $device connect "$req_pdptype$apn" "$auth" "$username" "$password") || {
+ echo "mbim[$$]" "Failed to connect bearer"
+ tid=$((tid + 1))
+ umbim $DBG -t $tid -d "$device" disconnect
+ proto_notify_error "$interface" CONNECT_FAILED
+ return 1
+ }
+ tid=$((tid + 1))
+
+ echo "$connect_state"
+ local iptype="$(echo "$connect_state" | grep iptype: | awk '{print $4}')"
+
+ echo "mbim[$$]" "Connected"
+
+ local zone="$(fw3 -q network "$interface" 2>/dev/null)"
+
+ echo "mbim[$$]" "Setting up $ifname"
+ local mbimconfig="$(umbim $DBG -n -t $tid -d $device config)"
+ echo "$mbimconfig"
+ tid=$((tid + 1))
+
+ proto_init_update "$ifname" 1
+ proto_send_update "$interface"
+
+ [ -z "$dhcp" ] && dhcp="auto"
+ [ -z "$dhcpv6" ] && dhcpv6="auto"
+
+ [ "$iptype" != "ipv6" ] && {
+ json_init
+ json_add_string name "${interface}_4"
+ json_add_string ifname "@$interface"
+ ipv4address=$(_proto_mbim_get_field ipv4address "$mbimconfig")
+ if [ -n "$ipv4address" -a "$dhcp" != 1 ]; then
+ json_add_string proto "static"
+
+ json_add_array ipaddr
+ for address in $ipv4address; do
+ json_add_string "" "$address"
+ done
+ json_close_array
+
+ json_add_string gateway $(_proto_mbim_get_field ipv4gateway "$mbimconfig")
+ elif [ "$dhcp" != 0 ]; then
+ echo "mbim[$$]" "Starting DHCP on $ifname"
+ json_add_string proto "dhcp"
+ fi
+
+ [ "$peerdns" = 0 -a "$dhcp" != 1 ] || {
+ json_add_array dns
+ for server in $(_proto_mbim_get_field ipv4dnsserver "$mbimconfig"); do
+ json_add_string "" "$server"
+ done
+ json_close_array
+ }
+
+ proto_add_dynamic_defaults
+ [ -n "$zone" ] && json_add_string zone "$zone"
+ [ -n "$ip4table" ] && json_add_string ip4table "$ip4table"
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ }
+
+ [ "$iptype" != "ipv4" ] && {
+ json_init
+ json_add_string name "${interface}_6"
+ json_add_string ifname "@$interface"
+ ipv6address=$(_proto_mbim_get_field ipv6address "$mbimconfig")
+ if [ -n "$ipv6address" -a "$dhcpv6" != 1 ]; then
+ json_add_string proto "static"
+
+ json_add_array ip6addr
+ for address in $ipv6address; do
+ json_add_string "" "$address"
+ done
+ json_close_array
+
+ json_add_array ip6prefix
+ for address in $ipv6address; do
+ json_add_string "" "$address"
+ done
+ json_close_array
+
+ json_add_string ip6gw $(_proto_mbim_get_field ipv6gateway "$mbimconfig")
+
+ elif [ "$dhcpv6" != 0 ]; then
+ echo "mbim[$$]" "Starting DHCPv6 on $ifname"
+ json_add_string proto "dhcpv6"
+ json_add_string extendprefix 1
+ [ "$delegate" = "0" ] && json_add_boolean delegate "0"
+ [ "$sourcefilter" = "0" ] && json_add_boolean sourcefilter "0"
+ fi
+
+ [ "$peerdns" = 0 -a "$dhcpv6" != 1 ] || {
+ json_add_array dns
+ for server in $(_proto_mbim_get_field ipv6dnsserver "$mbimconfig"); do
+ json_add_string "" "$server"
+ done
+ json_close_array
+ }
+
+ proto_add_dynamic_defaults
+ [ -n "$zone" ] && json_add_string zone "$zone"
+ [ -n "$ip6table" ] && json_add_string ip6table "$ip6table"
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ }
+
+ [ -z "$mtu" ] && {
+ local ipv4mtu=$(_proto_mbim_get_field ipv4mtu "$mbimconfig")
+ ipv4mtu="${ipv4mtu:-0}"
+ local ipv6mtu=$(_proto_mbim_get_field ipv6mtu "$mbimconfig")
+ ipv6mtu="${ipv6mtu:-0}"
+
+ mtu=$((ipv6mtu > ipv4mtu ? ipv6mtu : ipv4mtu))
+ }
+ [ -n "$mtu" -a "$mtu" != 0 ] && {
+ echo Setting MTU of $ifname to $mtu
+ /sbin/ip link set dev $ifname mtu $mtu
+ }
+
+ uci_set_state network $interface tid "$tid"
+}
+
+proto_mbim_setup() {
+ local ret
+
+ _proto_mbim_setup $@
+ ret=$?
+
+ [ "$ret" = 0 ] || {
+ logger "mbim bringup failed, retry in 15s"
+ sleep 15
+ }
+
+ return $ret
+}
+
+proto_mbim_teardown() {
+ local interface="$1"
+
+ local device
+ json_get_vars device
+ local tid=$(uci_get_state network $interface tid)
+
+ [ -n "$ctl_device" ] && device=$ctl_device
+
+ echo "mbim[$$]" "Stopping network"
+ [ -n "$tid" ] && {
+ umbim $DBG -t $tid -d "$device" disconnect
+ uci_revert_state network $interface tid
+ }
+
+ proto_init_update "*" 0
+ proto_send_update "$interface"
+}
+
+[ -n "$INCLUDE_ONLY" ] || add_protocol mbim
diff --git a/package/network/utils/uqmi/Makefile b/package/network/utils/uqmi/Makefile
new file mode 100644
index 0000000..54e1b4f
--- /dev/null
+++ b/package/network/utils/uqmi/Makefile
@@ -0,0 +1,48 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=uqmi
+PKG_RELEASE:=2
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=$(PROJECT_GIT)/project/uqmi.git
+PKG_SOURCE_DATE:=2024-08-25
+PKG_SOURCE_VERSION:=28b48a10dbcd1177095b73c6d8086d10114f49b8
+PKG_MIRROR_HASH:=ca4c07775185b873da572d973b9bbce86198d41d921a8d32b990da34e5ffd65d
+PKG_MAINTAINER:=Matti Laakso <malaakso@elisanet.fi>
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=
+
+PKG_FLAGS:=nonshared
+PKG_BUILD_FLAGS:=gc-sections
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/uqmi
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=WWAN
+ DEPENDS:=+libubox +libblobmsg-json +kmod-usb-net +kmod-usb-net-qmi-wwan +wwan
+ TITLE:=Control utility for mobile broadband modems
+endef
+
+define Package/uqmi/description
+ uqmi is a command line tool for controlling mobile broadband modems using
+ the QMI-protocol.
+endef
+
+TARGET_CFLAGS += \
+ -I$(STAGING_DIR)/usr/include \
+ -Wno-error=maybe-uninitialized
+
+CMAKE_OPTIONS += \
+ -DDEBUG=1
+
+define Package/uqmi/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/uqmi/uqmi $(1)/sbin/
+ $(CP) ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,uqmi))
diff --git a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
new file mode 100755
index 0000000..8ec577a
--- /dev/null
+++ b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
@@ -0,0 +1,535 @@
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_qmi_init_config() {
+ available=1
+ no_device=1
+ proto_config_add_string "device:device"
+ proto_config_add_string apn
+ proto_config_add_string v6apn
+ proto_config_add_string auth
+ proto_config_add_string username
+ proto_config_add_string password
+ proto_config_add_string pincode
+ proto_config_add_int delay
+ proto_config_add_string modes
+ proto_config_add_string pdptype
+ proto_config_add_int profile
+ proto_config_add_int v6profile
+ proto_config_add_boolean dhcp
+ proto_config_add_boolean dhcpv6
+ proto_config_add_boolean sourcefilter
+ proto_config_add_boolean delegate
+ proto_config_add_boolean autoconnect
+ proto_config_add_int plmn
+ proto_config_add_int timeout
+ proto_config_add_int mtu
+ proto_config_add_defaults
+}
+
+proto_qmi_setup() {
+ local interface="$1"
+ local dataformat connstat plmn_mode mcc mnc
+ local device apn v6apn auth username password pincode delay modes pdptype
+ local profile v6profile dhcp dhcpv6 autoconnect plmn timeout mtu $PROTO_DEFAULT_OPTIONS
+ local ip4table ip6table
+ local cid_4 pdh_4 cid_6 pdh_6
+ local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6
+ local profile_pdptype
+
+ json_get_vars device apn v6apn auth username password pincode delay modes
+ json_get_vars pdptype profile v6profile dhcp dhcpv6 sourcefilter delegate autoconnect plmn ip4table
+ json_get_vars ip6table timeout mtu $PROTO_DEFAULT_OPTIONS
+
+ [ "$timeout" = "" ] && timeout="10"
+
+ [ "$metric" = "" ] && metric="0"
+
+ [ -n "$ctl_device" ] && device=$ctl_device
+
+ [ -n "$device" ] || {
+ echo "No control device specified"
+ proto_notify_error "$interface" NO_DEVICE
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ [ -n "$delay" ] && sleep "$delay"
+
+ device="$(readlink -f $device)"
+ [ -c "$device" ] || {
+ echo "The specified control device does not exist"
+ proto_notify_error "$interface" NO_DEVICE
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ devname="$(basename "$device")"
+ devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
+ ifname="$( ls "$devpath"/net )"
+ [ -n "$ifname" ] || {
+ echo "The interface could not be found."
+ proto_notify_error "$interface" NO_IFACE
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ [ -n "$mtu" ] && {
+ echo "Setting MTU to $mtu"
+ /sbin/ip link set dev $ifname mtu $mtu
+ }
+
+ echo "Waiting for SIM initialization"
+ local uninitialized_timeout=0
+ # timeout 3s for first call to avoid hanging uqmi
+ uqmi -d "$device" -t 3000 --get-pin-status > /dev/null 2>&1
+ while uqmi -s -d "$device" -t 1000 --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do
+ [ -e "$device" ] || return 1
+ if [ "$uninitialized_timeout" -lt "$timeout" -o "$timeout" = "0" ]; then
+ let uninitialized_timeout++
+ sleep 1;
+ else
+ echo "SIM not initialized"
+ proto_notify_error "$interface" SIM_NOT_INITIALIZED
+ proto_block_restart "$interface"
+ return 1
+ fi
+ done
+
+ # Check if UIM application is stuck in illegal state
+ local uim_state_timeout=0
+ while true; do
+ json_load "$(uqmi -s -d "$device" -t 1000 --uim-get-sim-state)"
+ json_get_var card_application_state card_application_state
+
+ # SIM card is either completely absent or state is labeled as illegal
+ # Try to power-cycle the SIM card to recover from this state
+ if [ -z "$card_application_state" -o "$card_application_state" = "illegal" ]; then
+ echo "SIM in illegal state - Power-cycling SIM"
+
+ # Try to reset SIM application
+ uqmi -d "$device" -t 1000 --uim-power-off --uim-slot 1
+ sleep 3
+ uqmi -d "$device" -t 1000 --uim-power-on --uim-slot 1
+
+ if [ "$uim_state_timeout" -lt "$timeout" ] || [ "$timeout" = "0" ]; then
+ let uim_state_timeout++
+ sleep 1
+ continue
+ fi
+
+ # Recovery failed
+ proto_notify_error "$interface" SIM_ILLEGAL_STATE
+ proto_block_restart "$interface"
+ return 1
+ else
+ break
+ fi
+ done
+
+ if uqmi -s -d "$device" -t 1000 --uim-get-sim-state | grep -q '"Not supported"\|"Invalid QMI command"' &&
+ uqmi -s -d "$device" -t 1000 --get-pin-status | grep -q '"Not supported"\|"Invalid QMI command"' ; then
+ [ -n "$pincode" ] && {
+ uqmi -s -d "$device" -t 1000 --verify-pin1 "$pincode" > /dev/null || uqmi -s -d "$device" -t 1000 --uim-verify-pin1 "$pincode" > /dev/null || {
+ echo "Unable to verify PIN"
+ proto_notify_error "$interface" PIN_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+ }
+ else
+ json_load "$(uqmi -s -d "$device" -t 1000 --get-pin-status)"
+ json_get_var pin1_status pin1_status
+ if [ -z "$pin1_status" ]; then
+ json_load "$(uqmi -s -d "$device" -t 1000 --uim-get-sim-state)"
+ json_get_var pin1_status pin1_status
+ fi
+ json_get_var pin1_verify_tries pin1_verify_tries
+
+ case "$pin1_status" in
+ disabled)
+ echo "PIN verification is disabled"
+ ;;
+ blocked)
+ echo "SIM locked PUK required"
+ proto_notify_error "$interface" PUK_NEEDED
+ proto_block_restart "$interface"
+ return 1
+ ;;
+ not_verified)
+ [ "$pin1_verify_tries" -lt "3" ] && {
+ echo "PIN verify count value is $pin1_verify_tries this is below the limit of 3"
+ proto_notify_error "$interface" PIN_TRIES_BELOW_LIMIT
+ proto_block_restart "$interface"
+ return 1
+ }
+ if [ -n "$pincode" ]; then
+ uqmi -s -d "$device" -t 1000 --verify-pin1 "$pincode" > /dev/null 2>&1 || uqmi -s -d "$device" -t 1000 --uim-verify-pin1 "$pincode" > /dev/null 2>&1 || {
+ echo "Unable to verify PIN"
+ proto_notify_error "$interface" PIN_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+ else
+ echo "PIN not specified but required"
+ proto_notify_error "$interface" PIN_NOT_SPECIFIED
+ proto_block_restart "$interface"
+ return 1
+ fi
+ ;;
+ verified)
+ echo "PIN already verified"
+ ;;
+ *)
+ echo "PIN status failed (${pin1_status:-sim_not_present})"
+ proto_notify_error "$interface" PIN_STATUS_FAILED
+ proto_block_restart "$interface"
+ return 1
+ ;;
+ esac
+ json_cleanup
+ fi
+
+ if [ -n "$plmn" ]; then
+ json_load "$(uqmi -s -d "$device" -t 1000 --get-plmn)"
+ json_get_var plmn_mode mode
+ json_get_vars mcc mnc || {
+ mcc=0
+ mnc=0
+ }
+
+ if [ "$plmn" = "0" ]; then
+ if [ "$plmn_mode" != "automatic" ]; then
+ mcc=0
+ mnc=0
+ echo "Setting PLMN to auto"
+ fi
+ elif [ "$mcc" -ne "${plmn:0:3}" -o "$mnc" -ne "${plmn:3}" ]; then
+ mcc=${plmn:0:3}
+ mnc=${plmn:3}
+ echo "Setting PLMN to $plmn"
+ else
+ mcc=""
+ mnc=""
+ fi
+ fi
+
+ # Cleanup current state if any
+ uqmi -s -d "$device" -t 1000 --stop-network 0xffffffff --autoconnect > /dev/null 2>&1
+ uqmi -s -d "$device" -t 1000 --set-ip-family ipv6 --stop-network 0xffffffff --autoconnect > /dev/null 2>&1
+
+ # Go online
+ uqmi -s -d "$device" -t 1000 --set-device-operating-mode online > /dev/null 2>&1
+
+ # Set IP format
+ uqmi -s -d "$device" -t 1000 --set-data-format 802.3 > /dev/null 2>&1
+ uqmi -s -d "$device" -t 1000 --wda-set-data-format 802.3 > /dev/null 2>&1
+ dataformat="$(uqmi -s -d "$device" -t 1000 --wda-get-data-format)"
+
+ if [ "$dataformat" = '"raw-ip"' ]; then
+
+ [ -f /sys/class/net/$ifname/qmi/raw_ip ] || {
+ echo "Device only supports raw-ip mode but is missing this required driver attribute: /sys/class/net/$ifname/qmi/raw_ip"
+ return 1
+ }
+
+ echo "Device does not support 802.3 mode. Informing driver of raw-ip only for $ifname .."
+ echo "Y" > /sys/class/net/$ifname/qmi/raw_ip
+ fi
+
+ uqmi -s -d "$device" -t 1000 --sync > /dev/null 2>&1
+
+ uqmi -s -d "$device" -t 20000 --network-register > /dev/null 2>&1
+
+ # PLMN selection must happen after the call to network-register
+ if [ -n "$mcc" -a -n "$mnc" ]; then
+ uqmi -s -d "$device" -t 1000 --set-plmn --mcc "$mcc" --mnc "$mnc" > /dev/null 2>&1 || {
+ echo "Unable to set PLMN"
+ proto_notify_error "$interface" PLMN_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+ fi
+
+ [ -n "$modes" ] && {
+ uqmi -s -d "$device" -t 1000 --set-network-modes "$modes" > /dev/null 2>&1
+ sleep 3
+ # Scan network to not rely on registration-timeout after RAT change
+ uqmi -s -d "$device" -t 30000 --network-scan > /dev/null 2>&1
+ }
+
+ echo "Waiting for network registration"
+ sleep 5
+ local registration_timeout=0
+ local registration_state=""
+ while true; do
+ registration_state=$(uqmi -s -d "$device" -t 1000 --get-serving-system 2>/dev/null | jsonfilter -e "@.registration" 2>/dev/null)
+
+ [ "$registration_state" = "registered" ] && break
+
+ if [ "$registration_state" = "searching" ] || [ "$registration_state" = "not_registered" ]; then
+ if [ "$registration_timeout" -lt "$timeout" ] || [ "$timeout" = "0" ]; then
+ [ "$registration_state" = "searching" ] || {
+ echo "Device stopped network registration. Restart network registration"
+ uqmi -s -d "$device" -t 20000 --network-register > /dev/null 2>&1
+ }
+ let registration_timeout++
+ sleep 1
+ continue
+ fi
+ echo "Network registration failed, registration timeout reached"
+ else
+ # registration_state is 'registration_denied' or 'unknown' or ''
+ echo "Network registration failed (reason: '$registration_state')"
+ fi
+
+ proto_notify_error "$interface" NETWORK_REGISTRATION_FAILED
+ return 1
+ done
+
+
+ echo "Starting network $interface"
+
+ pdptype="$(echo "$pdptype" | awk '{print tolower($0)}')"
+
+ [ "$pdptype" = "ip" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] || pdptype="ip"
+
+ # Configure PDP type and APN for profile 1.
+ # In case GGSN rejects IPv4v6 PDP, modem might not be able to
+ # establish a non-LTE data session.
+ profile_pdptype="$pdptype"
+ [ "$profile_pdptype" = "ip" ] && profile_pdptype="ipv4"
+ uqmi -s -d "$device" -t 1000 --modify-profile "3gpp,1" --apn "$apn" --pdp-type "$profile_pdptype" > /dev/null 2>&1
+
+ if [ "$pdptype" = "ip" ]; then
+ [ -z "$autoconnect" ] && autoconnect=1
+ [ "$autoconnect" = 0 ] && autoconnect=""
+ else
+ [ "$autoconnect" = 1 ] || autoconnect=""
+ fi
+
+ [ "$pdptype" = "ip" -o "$pdptype" = "ipv4v6" ] && {
+ cid_4=$(uqmi -s -d "$device" -t 1000 --get-client-id wds)
+ if ! [ "$cid_4" -eq "$cid_4" ] 2> /dev/null; then
+ echo "Unable to obtain client ID"
+ proto_notify_error "$interface" NO_CID
+ return 1
+ fi
+
+ uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --set-ip-family ipv4 > /dev/null 2>&1
+
+ pdh_4=$(uqmi -s -d "$device" -t 5000 --set-client-id wds,"$cid_4" \
+ --start-network \
+ ${apn:+--apn $apn} \
+ ${profile:+--profile $profile} \
+ ${auth:+--auth-type $auth} \
+ ${username:+--username $username} \
+ ${password:+--password $password} \
+ ${autoconnect:+--autoconnect})
+
+ # pdh_4 is a numeric value on success
+ if ! [ "$pdh_4" -eq "$pdh_4" ] 2> /dev/null; then
+ echo "Unable to connect IPv4"
+ uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
+ proto_notify_error "$interface" CALL_FAILED
+ return 1
+ fi
+
+ # Check data connection state
+ connstat=$(uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --get-data-status)
+ [ "$connstat" == '"connected"' ] || {
+ echo "No data link!"
+ uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
+ proto_notify_error "$interface" CALL_FAILED
+ return 1
+ }
+ }
+
+ [ "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && {
+ cid_6=$(uqmi -s -d "$device" -t 1000 --get-client-id wds)
+ if ! [ "$cid_6" -eq "$cid_6" ] 2> /dev/null; then
+ echo "Unable to obtain client ID"
+ proto_notify_error "$interface" NO_CID
+ return 1
+ fi
+
+ uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --set-ip-family ipv6 > /dev/null 2>&1
+
+ : "${v6apn:=${apn}}"
+ : "${v6profile:=${profile}}"
+
+ pdh_6=$(uqmi -s -d "$device" -t 5000 --set-client-id wds,"$cid_6" \
+ --start-network \
+ ${v6apn:+--apn $v6apn} \
+ ${v6profile:+--profile $v6profile} \
+ ${auth:+--auth-type $auth} \
+ ${username:+--username $username} \
+ ${password:+--password $password} \
+ ${autoconnect:+--autoconnect})
+
+ # pdh_6 is a numeric value on success
+ if ! [ "$pdh_6" -eq "$pdh_6" ] 2> /dev/null; then
+ echo "Unable to connect IPv6"
+ uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
+ proto_notify_error "$interface" CALL_FAILED
+ return 1
+ fi
+
+ # Check data connection state
+ connstat=$(uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --set-ip-family ipv6 --get-data-status)
+ [ "$connstat" == '"connected"' ] || {
+ echo "No data link!"
+ uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
+ proto_notify_error "$interface" CALL_FAILED
+ return 1
+ }
+ }
+
+ echo "Setting up $ifname"
+ proto_init_update "$ifname" 1
+ proto_set_keep 1
+ proto_add_data
+ [ -n "$pdh_4" ] && {
+ json_add_string "cid_4" "$cid_4"
+ json_add_string "pdh_4" "$pdh_4"
+ }
+ [ -n "$pdh_6" ] && {
+ json_add_string "cid_6" "$cid_6"
+ json_add_string "pdh_6" "$pdh_6"
+ }
+ proto_close_data
+ proto_send_update "$interface"
+
+ local zone="$(fw3 -q network "$interface" 2>/dev/null)"
+
+ [ -n "$pdh_6" ] && {
+ if [ -z "$dhcpv6" -o "$dhcpv6" = 0 ]; then
+ json_load "$(uqmi -s -d $device -t 1000 --set-client-id wds,$cid_6 --get-current-settings)"
+ json_select ipv6
+ json_get_var ip_6 ip
+ json_get_var gateway_6 gateway
+ json_get_var dns1_6 dns1
+ json_get_var dns2_6 dns2
+ json_get_var ip_prefix_length ip-prefix-length
+
+ proto_init_update "$ifname" 1
+ proto_set_keep 1
+ proto_add_ipv6_address "$ip_6" "128"
+ proto_add_ipv6_prefix "${ip_6}/${ip_prefix_length}"
+ proto_add_ipv6_route "$gateway_6" "128"
+ [ "$defaultroute" = 0 ] || proto_add_ipv6_route "::0" 0 "$gateway_6" "" "" "${ip_6}/${ip_prefix_length}"
+ [ "$peerdns" = 0 ] || {
+ proto_add_dns_server "$dns1_6"
+ proto_add_dns_server "$dns2_6"
+ }
+ [ -n "$zone" ] && {
+ proto_add_data
+ json_add_string zone "$zone"
+ proto_close_data
+ }
+ proto_send_update "$interface"
+ else
+ json_init
+ json_add_string name "${interface}_6"
+ json_add_string ifname "@$interface"
+ [ "$pdptype" = "ipv4v6" ] && json_add_string iface_464xlat "0"
+ json_add_string proto "dhcpv6"
+ [ -n "$ip6table" ] && json_add_string ip6table "$ip6table"
+ proto_add_dynamic_defaults
+ # RFC 7278: Extend an IPv6 /64 Prefix to LAN
+ json_add_string extendprefix 1
+ [ "$delegate" = "0" ] && json_add_boolean delegate "0"
+ [ "$sourcefilter" = "0" ] && json_add_boolean sourcefilter "0"
+ [ -n "$zone" ] && json_add_string zone "$zone"
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ fi
+ }
+
+ [ -n "$pdh_4" ] && {
+ if [ "$dhcp" = 0 ]; then
+ json_load "$(uqmi -s -d $device -t 1000 --set-client-id wds,$cid_4 --get-current-settings)"
+ json_select ipv4
+ json_get_var ip_4 ip
+ json_get_var gateway_4 gateway
+ json_get_var dns1_4 dns1
+ json_get_var dns2_4 dns2
+ json_get_var subnet_4 subnet
+
+ proto_init_update "$ifname" 1
+ proto_set_keep 1
+ proto_add_ipv4_address "$ip_4" "$subnet_4"
+ proto_add_ipv4_route "$gateway_4" "128"
+ [ "$defaultroute" = 0 ] || proto_add_ipv4_route "0.0.0.0" 0 "$gateway_4"
+ [ "$peerdns" = 0 ] || {
+ proto_add_dns_server "$dns1_4"
+ proto_add_dns_server "$dns2_4"
+ }
+ [ -n "$zone" ] && {
+ proto_add_data
+ json_add_string zone "$zone"
+ proto_close_data
+ }
+ proto_send_update "$interface"
+ else
+ json_init
+ json_add_string name "${interface}_4"
+ json_add_string ifname "@$interface"
+ json_add_string proto "dhcp"
+ [ -n "$ip4table" ] && json_add_string ip4table "$ip4table"
+ proto_add_dynamic_defaults
+ [ -n "$zone" ] && json_add_string zone "$zone"
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ fi
+ }
+}
+
+qmi_wds_stop() {
+ local cid="$1"
+ local pdh="$2"
+
+ [ -n "$cid" ] || return
+
+ uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid" \
+ --stop-network 0xffffffff \
+ --autoconnect > /dev/null 2>&1
+
+ [ -n "$pdh" ] && {
+ uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid" \
+ --stop-network "$pdh" > /dev/null 2>&1
+ }
+
+ uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid" \
+ --release-client-id wds > /dev/null 2>&1
+}
+
+proto_qmi_teardown() {
+ local interface="$1"
+
+ local device cid_4 pdh_4 cid_6 pdh_6
+ json_get_vars device
+
+ [ -n "$ctl_device" ] && device=$ctl_device
+
+ echo "Stopping network $interface"
+
+ json_load "$(ubus call network.interface.$interface status)"
+ json_select data
+ json_get_vars cid_4 pdh_4 cid_6 pdh_6
+
+ qmi_wds_stop "$cid_4" "$pdh_4"
+ qmi_wds_stop "$cid_6" "$pdh_6"
+
+ proto_init_update "*" 0
+ proto_send_update "$interface"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol qmi
+}
diff --git a/package/network/utils/wireguard-tools/Makefile b/package/network/utils/wireguard-tools/Makefile
new file mode 100644
index 0000000..d704577
--- /dev/null
+++ b/package/network/utils/wireguard-tools/Makefile
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2016-2019 Jason A. Donenfeld <Jason@zx2c4.com>
+# Copyright (C) 2016 Baptiste Jonglez <openwrt@bitsofnetworks.org>
+# Copyright (C) 2016-2017 Dan Luedtke <mail@danrl.com>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=wireguard-tools
+
+PKG_VERSION:=1.0.20210914
+PKG_RELEASE:=4
+
+PKG_SOURCE:=wireguard-tools-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://git.zx2c4.com/wireguard-tools/snapshot/
+PKG_HASH:=97ff31489217bb265b7ae850d3d0f335ab07d2652ba1feec88b734bc96bd05ac
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+MAKE_PATH:=src
+MAKE_VARS += PLATFORM=linux
+
+define Package/wireguard-tools
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=VPN
+ URL:=https://www.wireguard.com
+ MAINTAINER:=Jason A. Donenfeld <Jason@zx2c4.com>
+ TITLE:=WireGuard userspace control program (wg)
+ DEPENDS:= \
+ +!BUSYBOX_CONFIG_IP:ip \
+ +!BUSYBOX_CONFIG_FEATURE_IP_LINK:ip \
+ +kmod-wireguard
+endef
+
+define Package/wireguard-tools/description
+ WireGuard is a novel VPN that runs inside the Linux Kernel and utilizes
+ state-of-the-art cryptography. It aims to be faster, simpler, leaner, and
+ more useful than IPSec, while avoiding the massive headache. It intends to
+ be considerably more performant than OpenVPN. WireGuard is designed as a
+ general purpose VPN for running on embedded interfaces and super computers
+ alike, fit for many different circumstances. It uses UDP.
+
+ This package provides the userspace control program for WireGuard,
+ `wg(8)`, a netifd protocol helper, and a re-resolve watchdog script.
+endef
+
+define Package/wireguard-tools/install
+ $(INSTALL_DIR) $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/wg $(1)/usr/bin/
+ $(INSTALL_BIN) ./files/wireguard_watchdog $(1)/usr/bin/
+ $(INSTALL_DIR) $(1)/lib/netifd/proto/
+ $(INSTALL_BIN) ./files/wireguard.sh $(1)/lib/netifd/proto/
+endef
+
+$(eval $(call BuildPackage,wireguard-tools))
diff --git a/package/network/utils/wireguard-tools/files/wireguard.sh b/package/network/utils/wireguard-tools/files/wireguard.sh
new file mode 100644
index 0000000..f6ad967
--- /dev/null
+++ b/package/network/utils/wireguard-tools/files/wireguard.sh
@@ -0,0 +1,217 @@
+#!/bin/sh
+# Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
+# Licensed to the public under the Apache License 2.0.
+
+WG=/usr/bin/wg
+if [ ! -x $WG ]; then
+ logger -t "wireguard" "error: missing wireguard-tools (${WG})"
+ exit 0
+fi
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_wireguard_init_config() {
+ proto_config_add_string "private_key"
+ proto_config_add_int "listen_port"
+ proto_config_add_int "mtu"
+ proto_config_add_string "fwmark"
+ available=1
+ no_proto_task=1
+}
+
+proto_wireguard_setup_peer() {
+ local peer_config="$1"
+
+ local disabled
+ local public_key
+ local preshared_key
+ local allowed_ips
+ local route_allowed_ips
+ local endpoint_host
+ local endpoint_port
+ local persistent_keepalive
+
+ config_get_bool disabled "${peer_config}" "disabled" 0
+ config_get public_key "${peer_config}" "public_key"
+ config_get preshared_key "${peer_config}" "preshared_key"
+ config_get allowed_ips "${peer_config}" "allowed_ips"
+ config_get_bool route_allowed_ips "${peer_config}" "route_allowed_ips" 0
+ config_get endpoint_host "${peer_config}" "endpoint_host"
+ config_get endpoint_port "${peer_config}" "endpoint_port"
+ config_get persistent_keepalive "${peer_config}" "persistent_keepalive"
+
+ if [ "${disabled}" -eq 1 ]; then
+ # skip disabled peers
+ return 0
+ fi
+
+ if [ -z "$public_key" ]; then
+ echo "Skipping peer config $peer_config because public key is not defined."
+ return 0
+ fi
+
+ echo "[Peer]" >> "${wg_cfg}"
+ echo "PublicKey=${public_key}" >> "${wg_cfg}"
+ if [ "${preshared_key}" ]; then
+ echo "PresharedKey=${preshared_key}" >> "${wg_cfg}"
+ fi
+ for allowed_ip in $allowed_ips; do
+ echo "AllowedIPs=${allowed_ip}" >> "${wg_cfg}"
+ done
+ if [ "${endpoint_host}" ]; then
+ case "${endpoint_host}" in
+ *:*)
+ endpoint="[${endpoint_host}]"
+ ;;
+ *)
+ endpoint="${endpoint_host}"
+ ;;
+ esac
+ if [ "${endpoint_port}" ]; then
+ endpoint="${endpoint}:${endpoint_port}"
+ else
+ endpoint="${endpoint}:51820"
+ fi
+ echo "Endpoint=${endpoint}" >> "${wg_cfg}"
+ fi
+ if [ "${persistent_keepalive}" ]; then
+ echo "PersistentKeepalive=${persistent_keepalive}" >> "${wg_cfg}"
+ fi
+
+ if [ ${route_allowed_ips} -ne 0 ]; then
+ for allowed_ip in ${allowed_ips}; do
+ case "${allowed_ip}" in
+ *:*/*)
+ proto_add_ipv6_route "${allowed_ip%%/*}" "${allowed_ip##*/}"
+ ;;
+ *.*/*)
+ proto_add_ipv4_route "${allowed_ip%%/*}" "${allowed_ip##*/}"
+ ;;
+ *:*)
+ proto_add_ipv6_route "${allowed_ip%%/*}" "128"
+ ;;
+ *.*)
+ proto_add_ipv4_route "${allowed_ip%%/*}" "32"
+ ;;
+ esac
+ done
+ fi
+}
+
+ensure_key_is_generated() {
+ local private_key
+ private_key="$(uci get network."$1".private_key)"
+
+ if [ "$private_key" == "generate" ]; then
+ local ucitmp
+ oldmask="$(umask)"
+ umask 077
+ ucitmp="$(mktemp -d)"
+ private_key="$("${WG}" genkey)"
+ uci -q -t "$ucitmp" set network."$1".private_key="$private_key" && \
+ uci -q -t "$ucitmp" commit network
+ rm -rf "$ucitmp"
+ umask "$oldmask"
+ fi
+}
+
+proto_wireguard_setup() {
+ local config="$1"
+ local wg_dir="/tmp/wireguard"
+ local wg_cfg="${wg_dir}/${config}"
+
+ local private_key
+ local listen_port
+ local mtu
+
+ ensure_key_is_generated "${config}"
+
+ config_load network
+ config_get private_key "${config}" "private_key"
+ config_get listen_port "${config}" "listen_port"
+ config_get addresses "${config}" "addresses"
+ config_get mtu "${config}" "mtu"
+ config_get fwmark "${config}" "fwmark"
+ config_get ip6prefix "${config}" "ip6prefix"
+ config_get nohostroute "${config}" "nohostroute"
+ config_get tunlink "${config}" "tunlink"
+
+ ip link del dev "${config}" 2>/dev/null
+ ip link add dev "${config}" type wireguard
+
+ if [ "${mtu}" ]; then
+ ip link set mtu "${mtu}" dev "${config}"
+ fi
+
+ proto_init_update "${config}" 1
+
+ umask 077
+ mkdir -p "${wg_dir}"
+ echo "[Interface]" > "${wg_cfg}"
+ echo "PrivateKey=${private_key}" >> "${wg_cfg}"
+ if [ "${listen_port}" ]; then
+ echo "ListenPort=${listen_port}" >> "${wg_cfg}"
+ fi
+ if [ "${fwmark}" ]; then
+ echo "FwMark=${fwmark}" >> "${wg_cfg}"
+ fi
+ config_foreach proto_wireguard_setup_peer "wireguard_${config}"
+
+ # apply configuration file
+ ${WG} setconf ${config} "${wg_cfg}"
+ WG_RETURN=$?
+
+ rm -f "${wg_cfg}"
+
+ if [ ${WG_RETURN} -ne 0 ]; then
+ sleep 5
+ proto_setup_failed "${config}"
+ exit 1
+ fi
+
+ for address in ${addresses}; do
+ case "${address}" in
+ *:*/*)
+ proto_add_ipv6_address "${address%%/*}" "${address##*/}"
+ ;;
+ *.*/*)
+ proto_add_ipv4_address "${address%%/*}" "${address##*/}"
+ ;;
+ *:*)
+ proto_add_ipv6_address "${address%%/*}" "128"
+ ;;
+ *.*)
+ proto_add_ipv4_address "${address%%/*}" "32"
+ ;;
+ esac
+ done
+
+ for prefix in ${ip6prefix}; do
+ proto_add_ipv6_prefix "$prefix"
+ done
+
+ # endpoint dependency
+ if [ "${nohostroute}" != "1" ]; then
+ wg show "${config}" endpoints | \
+ sed -E 's/\[?([0-9.:a-f]+)\]?:([0-9]+)/\1 \2/' | \
+ while IFS=$'\t ' read -r key address port; do
+ [ -n "${port}" ] || continue
+ proto_add_host_dependency "${config}" "${address}" "${tunlink}"
+ done
+ fi
+
+ proto_send_update "${config}"
+}
+
+proto_wireguard_teardown() {
+ local config="$1"
+ ip link del dev "${config}" >/dev/null 2>&1
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol wireguard
+}
diff --git a/package/network/utils/wireguard-tools/files/wireguard_watchdog b/package/network/utils/wireguard-tools/files/wireguard_watchdog
new file mode 100644
index 0000000..fc90f4a
--- /dev/null
+++ b/package/network/utils/wireguard-tools/files/wireguard_watchdog
@@ -0,0 +1,68 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2018 Aleksandr V. Piskunov <aleksandr.v.piskunov@gmail.com>.
+# Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+#
+# This watchdog script tries to re-resolve hostnames for inactive WireGuard peers.
+# Use it for peers with a frequently changing dynamic IP.
+# persistent_keepalive must be set, recommended value is 25 seconds.
+#
+# Run this script from cron every minute:
+# echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root
+
+
+. /lib/functions.sh
+
+check_peer_activity() {
+ local cfg=$1
+ local iface=$2
+ local disabled
+ local public_key
+ local endpoint_host
+ local endpoint_port
+ local persistent_keepalive
+ local last_handshake
+ local idle_seconds
+
+ config_get_bool disabled "${cfg}" "disabled" 0
+ config_get public_key "${cfg}" "public_key"
+ config_get endpoint_host "${cfg}" "endpoint_host"
+ config_get endpoint_port "${cfg}" "endpoint_port"
+
+ if [ "${disabled}" -eq 1 ]; then
+ # skip disabled peers
+ return 0
+ fi
+
+ persistent_keepalive=$(wg show ${iface} persistent-keepalive | grep ${public_key} | awk '{print $2}')
+
+ # only process peers with endpoints and keepalive set
+ [ -z ${endpoint_host} ] && return 0;
+ [ -z ${persistent_keepalive} -o ${persistent_keepalive} = "off" ] && return 0;
+
+ # skip IP addresses
+ # check taken from packages/net/ddns-scripts/files/dynamic_dns_functions.sh
+ local IPV4_REGEX="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
+ local IPV6_REGEX="\(\([0-9A-Fa-f]\{1,4\}:\)\{1,\}\)\(\([0-9A-Fa-f]\{1,4\}\)\{0,1\}\)\(\(:[0-9A-Fa-f]\{1,4\}\)\{1,\}\)"
+ local IPV4=$(echo ${endpoint_host} | grep -m 1 -o "$IPV4_REGEX$") # do not detect ip in 0.0.0.0.example.com
+ local IPV6=$(echo ${endpoint_host} | grep -m 1 -o "$IPV6_REGEX")
+ [ -n "${IPV4}" -o -n "${IPV6}" ] && return 0;
+
+ # re-resolve endpoint hostname if not responding for too long
+ last_handshake=$(wg show ${iface} latest-handshakes | grep ${public_key} | awk '{print $2}')
+ [ -z ${last_handshake} ] && return 0;
+ idle_seconds=$(($(date +%s)-${last_handshake}))
+ [ ${idle_seconds} -lt 150 ] && return 0;
+ logger -t "wireguard_monitor" "${iface} endpoint ${endpoint_host}:${endpoint_port} is not responding for ${idle_seconds} seconds, trying to re-resolve hostname"
+ wg set ${iface} peer ${public_key} endpoint "${endpoint_host}:${endpoint_port}"
+}
+
+# query ubus for all active wireguard interfaces
+eval $(ubus -S call network.interface dump | jsonfilter -e 'wg_ifaces=@.interface[@.up=true && @.proto="wireguard"].interface')
+
+# check every peer in every active wireguard interface
+config_load network
+for iface in $wg_ifaces; do
+ config_foreach check_peer_activity "wireguard_${iface}" "${iface}"
+done
diff --git a/package/network/utils/wireless-tools/Makefile b/package/network/utils/wireless-tools/Makefile
new file mode 100644
index 0000000..6ac66a0
--- /dev/null
+++ b/package/network/utils/wireless-tools/Makefile
@@ -0,0 +1,94 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=wireless-tools
+PKG_CPE_ID:=cpe:/a:wireless_tools_project:wireless_tools
+PKG_VERSION:=29
+PKG_MINOR:=
+PKG_RELEASE:=6
+
+PKG_SOURCE:=wireless_tools.$(PKG_VERSION)$(PKG_MINOR).tar.gz
+PKG_SOURCE_URL:=https://hewlettpackard.github.io/wireless-tools
+PKG_HASH:=6fb80935fe208538131ce2c4178221bab1078a1656306bce8909c19887e2e5a1
+TAR_OPTIONS += || true
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+PKG_LICENSE:=GPL-2.0
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/wireless_tools.$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/wireless-tools/Default
+ URL:=http://hplabs.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
+endef
+
+define Package/wireless-tools
+$(call Package/wireless-tools/Default)
+ SECTION:=net
+ CATEGORY:=Base system
+ TITLE:=Tools for manipulating Linux Wireless Extensions
+endef
+
+define Package/wireless-tools/description
+ This package contains a collection of tools for configuring wireless
+ adapters implementing the "Linux Wireless Extensions".
+endef
+
+define Package/libiw
+$(call Package/wireless-tools/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=Library for manipulating Linux Wireless Extensions
+ ABI_VERSION:=29
+endef
+
+define Package/libiw/description
+ This package contains a library for manipulating
+ "Linux Wireless Extensions".
+endef
+
+define Build/Compile
+ rm -rf $(PKG_INSTALL_DIR)
+ mkdir -p $(PKG_INSTALL_DIR)
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="$(TARGET_CFLAGS) -I." \
+ BUILD_WE_ESSENTIAL=y \
+ LIBS="-lm -Wl,--gc-sections" \
+ libiw.so.$(PKG_VERSION) iwmulticall
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ PREFIX="$(PKG_INSTALL_DIR)" \
+ INSTALL_DIR="$(PKG_INSTALL_DIR)/usr/sbin" \
+ INSTALL_LIB="$(PKG_INSTALL_DIR)/usr/lib" \
+ install-iwmulticall
+endef
+
+define Build/InstallDev
+ mkdir -p $(1)/usr/include
+ $(CP) $(PKG_BUILD_DIR)/{iwlib,wireless}.h $(1)/usr/include/
+ mkdir -p $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/libiw.so* $(1)/usr/lib/
+ $(LN) libiw.so.$(PKG_VERSION) $(1)/usr/lib/libiw.so
+endef
+
+define Package/wireless-tools/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/iwconfig $(1)/usr/sbin/
+ $(LN) iwconfig $(1)/usr/sbin/iwlist
+ $(LN) iwconfig $(1)/usr/sbin/iwpriv
+endef
+
+define Package/libiw/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/libiw.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libiw))
+$(eval $(call BuildPackage,wireless-tools))
diff --git a/package/network/utils/wireless-tools/patches/001-debian.patch b/package/network/utils/wireless-tools/patches/001-debian.patch
new file mode 100644
index 0000000..e00bad2
--- /dev/null
+++ b/package/network/utils/wireless-tools/patches/001-debian.patch
@@ -0,0 +1,35 @@
+--- a/iwlib.c
++++ b/iwlib.c
+@@ -667,6 +667,7 @@ iw_get_basic_config(int skfd,
+ {
+ struct iwreq wrq;
+
++ memset((char *) &wrq, 0, sizeof(struct iwreq));
+ memset((char *) info, 0, sizeof(struct wireless_config));
+
+ /* Get wireless name */
+--- a/Makefile
++++ b/Makefile
+@@ -73,8 +73,8 @@ DYNAMIC_LINK= libiw.so
+ # Install directories
+ INSTALL_DIR= $(PREFIX)/sbin/
+ INSTALL_LIB= $(PREFIX)/lib/
+-INSTALL_INC= $(PREFIX)/include/
+-INSTALL_MAN= $(PREFIX)/man/
++INSTALL_INC= $(PREFIX)/usr/include/
++INSTALL_MAN= $(PREFIX)/usr/share/man/
+
+ # Various commands
+ RM = rm -f
+@@ -102,9 +102,9 @@ ifdef BUILD_WE_ESSENTIAL
+ endif
+
+ # Other flags
+-CFLAGS=-Os -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow \
++#CFLAGS=-Os -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow \
+ -Wpointer-arith -Wcast-qual -Winline -I.
+-#CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
++CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
+ DEPFLAGS=-MMD
+ XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) $(WELIB_FLAG) $(WEDEF_FLAG)
+ PICFLAG=-fPIC
diff --git a/package/network/utils/wireless-tools/patches/002-fix-iwconfig-power-argument-parsing.patch b/package/network/utils/wireless-tools/patches/002-fix-iwconfig-power-argument-parsing.patch
new file mode 100644
index 0000000..2b61ef2
--- /dev/null
+++ b/package/network/utils/wireless-tools/patches/002-fix-iwconfig-power-argument-parsing.patch
@@ -0,0 +1,13 @@
+--- a/iwconfig.c
++++ b/iwconfig.c
+@@ -1034,8 +1034,8 @@ set_power_info(int skfd,
+ wrq.u.power.disabled = 0;
+
+ /* Is there any value to grab ? */
+- value = strtod(args[0], &unit);
+- if(unit != args[0])
++ value = strtod(args[i], &unit);
++ if(unit != args[i])
+ {
+ struct iw_range range;
+ int flags;
diff --git a/package/network/utils/wireless-tools/patches/003-we_essential_def.patch b/package/network/utils/wireless-tools/patches/003-we_essential_def.patch
new file mode 100644
index 0000000..8666f3e
--- /dev/null
+++ b/package/network/utils/wireless-tools/patches/003-we_essential_def.patch
@@ -0,0 +1,359 @@
+--- a/iwlist.c
++++ b/iwlist.c
+@@ -58,7 +58,6 @@ typedef struct iw_auth_descr
+ * Maybe this should go in iwlib.c ?
+ */
+
+-#ifndef WE_ESSENTIAL
+ #define IW_ARRAY_LEN(x) (sizeof(x)/sizeof((x)[0]))
+
+ //static const struct iwmask_name iw_enc_mode_name[] = {
+@@ -161,11 +160,8 @@ static const char * iw_ie_key_mgmt_name[
+ };
+ #define IW_IE_KEY_MGMT_NUM IW_ARRAY_LEN(iw_ie_key_mgmt_name)
+
+-#endif /* WE_ESSENTIAL */
+-
+ /************************* WPA SUBROUTINES *************************/
+
+-#ifndef WE_ESSENTIAL
+ /*------------------------------------------------------------------*/
+ /*
+ * Print all names corresponding to a mask.
+@@ -431,7 +427,6 @@ iw_print_gen_ie(unsigned char * buffer,
+ offset += buffer[offset+1] + 2;
+ }
+ }
+-#endif /* WE_ESSENTIAL */
+
+ /***************************** SCANNING *****************************/
+ /*
+@@ -585,12 +580,10 @@ print_scanning_token(struct stream_descr
+ &event->u.qual, iw_range, has_range);
+ printf(" %s\n", buffer);
+ break;
+-#ifndef WE_ESSENTIAL
+ case IWEVGENIE:
+ /* Informations Elements are complex, let's do only some of them */
+ iw_print_gen_ie(event->u.data.pointer, event->u.data.length);
+ break;
+-#endif /* WE_ESSENTIAL */
+ case IWEVCUSTOM:
+ {
+ char custom[IW_CUSTOM_MAX+1];
+@@ -1302,7 +1295,6 @@ print_pm_info(int skfd,
+ return(0);
+ }
+
+-#ifndef WE_ESSENTIAL
+ /************************** TRANSMIT POWER **************************/
+
+ /*------------------------------------------------------------------*/
+@@ -1405,6 +1397,7 @@ print_txpower_info(int skfd,
+ return(0);
+ }
+
++#ifndef WE_ESSENTIAL
+ /*********************** RETRY LIMIT/LIFETIME ***********************/
+
+ /*------------------------------------------------------------------*/
+@@ -2060,8 +2053,8 @@ static const struct iwlist_entry iwlist_
+ { "encryption", print_keys_info, 0, NULL },
+ { "keys", print_keys_info, 0, NULL },
+ { "power", print_pm_info, 0, NULL },
+-#ifndef WE_ESSENTIAL
+ { "txpower", print_txpower_info, 0, NULL },
++#ifndef WE_ESSENTIAL
+ { "retry", print_retry_info, 0, NULL },
+ { "ap", print_ap_info, 0, NULL },
+ { "accesspoints", print_ap_info, 0, NULL },
+--- a/iwconfig.c
++++ b/iwconfig.c
+@@ -106,16 +106,6 @@ get_info(int skfd,
+ if(wrq.u.data.length > 1)
+ info->has_nickname = 1;
+
+- if((info->has_range) && (info->range.we_version_compiled > 9))
+- {
+- /* Get Transmit Power */
+- if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
+- {
+- info->has_txpower = 1;
+- memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
+- }
+- }
+-
+ /* Get sensitivity */
+ if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
+ {
+@@ -132,6 +122,17 @@ get_info(int skfd,
+ memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
+ }
+ }
++#endif /* WE_ESSENTIAL */
++
++ if((info->has_range) && (info->range.we_version_compiled > 9))
++ {
++ /* Get Transmit Power */
++ if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
++ {
++ info->has_txpower = 1;
++ memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
++ }
++ }
+
+ /* Get RTS threshold */
+ if(iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
+@@ -146,7 +147,6 @@ get_info(int skfd,
+ info->has_frag = 1;
+ memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
+ }
+-#endif /* WE_ESSENTIAL */
+
+ return(0);
+ }
+@@ -269,7 +269,6 @@ display_info(struct wireless_info * info
+ printf("Bit Rate%c%s ", (info->bitrate.fixed ? '=' : ':'), buffer);
+ }
+
+-#ifndef WE_ESSENTIAL
+ /* Display the Transmit Power */
+ if(info->has_txpower)
+ {
+@@ -286,6 +285,7 @@ display_info(struct wireless_info * info
+ printf("Tx-Power%c%s ", (info->txpower.fixed ? '=' : ':'), buffer);
+ }
+
++#ifndef WE_ESSENTIAL
+ /* Display sensitivity */
+ if(info->has_sens)
+ {
+@@ -340,6 +340,7 @@ display_info(struct wireless_info * info
+ printf(" ");
+ tokens += 5; /* Between 3 and 5, depend on flags */
+ }
++#endif /* WE_ESSENTIAL */
+
+ /* Display the RTS threshold */
+ if(info->has_rts)
+@@ -383,7 +384,6 @@ display_info(struct wireless_info * info
+ /* Formating */
+ if(tokens > 0)
+ printf("\n ");
+-#endif /* WE_ESSENTIAL */
+
+ /* Display encryption information */
+ /* Note : we display only the "current" key, use iwlist to list all keys */
+@@ -1196,6 +1196,7 @@ set_nwid_info(int skfd,
+ /* 1 arg */
+ return(1);
+ }
++#endif /* WE_ESSENTIAL */
+
+ /*------------------------------------------------------------------*/
+ /*
+@@ -1362,6 +1363,7 @@ set_txpower_info(int skfd,
+ return(i);
+ }
+
++#ifndef WE_ESSENTIAL
+ /*------------------------------------------------------------------*/
+ /*
+ * Set Sensitivity
+@@ -1459,6 +1461,7 @@ set_retry_info(int skfd,
+ /* Var args */
+ return(i);
+ }
++#endif /* WE_ESSENTIAL */
+
+ /*------------------------------------------------------------------*/
+ /*
+@@ -1565,6 +1568,7 @@ set_frag_info(int skfd,
+ return(1);
+ }
+
++#ifndef WE_ESSENTIAL
+ /*------------------------------------------------------------------*/
+ /*
+ * Set Modulation
+@@ -1719,21 +1723,21 @@ static const struct iwconfig_entry iwcon
+ "Set Nickname", "NNN" },
+ { "nwid", set_nwid_info, 1, SIOCSIWNWID,
+ "Set NWID", "{NN|on|off}" },
+- { "ap", set_apaddr_info, 1, SIOCSIWAP,
+- "Set AP Address", "{N|off|auto}" },
+- { "txpower", set_txpower_info, 1, SIOCSIWTXPOW,
+- "Set Tx Power", "{NmW|NdBm|off|auto}" },
+ { "sens", set_sens_info, 1, SIOCSIWSENS,
+ "Set Sensitivity", "N" },
++ { "modulation", set_modulation_info, 1, SIOCGIWMODUL,
++ "Set Modulation", "{11g|11a|CCK|OFDMg|...}" },
+ { "retry", set_retry_info, 1, SIOCSIWRETRY,
+ "Set Retry Limit", "{limit N|lifetime N}" },
++#endif /* WE_ESSENTIAL */
++ { "ap", set_apaddr_info, 1, SIOCSIWAP,
++ "Set AP Address", "{N|off|auto}" },
++ { "txpower", set_txpower_info, 1, SIOCSIWTXPOW,
++ "Set Tx Power", "{NmW|NdBm|off|auto}" },
+ { "rts", set_rts_info, 1, SIOCSIWRTS,
+ "Set RTS Threshold", "{N|auto|fixed|off}" },
+ { "frag", set_frag_info, 1, SIOCSIWFRAG,
+ "Set Fragmentation Threshold", "{N|auto|fixed|off}" },
+- { "modulation", set_modulation_info, 1, SIOCGIWMODUL,
+- "Set Modulation", "{11g|11a|CCK|OFDMg|...}" },
+-#endif /* WE_ESSENTIAL */
+ { "commit", set_commit_info, 0, SIOCSIWCOMMIT,
+ "Commit changes", "" },
+ { NULL, NULL, 0, 0, NULL, NULL },
+--- a/iwmulticall.c
++++ b/iwmulticall.c
+@@ -81,7 +81,7 @@ extern int
+ #define main(args...) main_iwspy(args)
+ #include "iwspy.c"
+ #undef main
+-#endif /* WE_ESSENTIAL */
++#endif
+
+ /* Get iwpriv in there. Mandatory for HostAP and some other drivers. */
+ #define main(args...) main_iwpriv(args)
+@@ -90,12 +90,14 @@ extern int
+ #undef iw_usage
+ #undef main
+
++#ifndef WE_ESSENTIAL
+ /* Do we really need iwgetid ? Well, it's not like it's a big one */
+ #define main(args...) main_iwgetid(args)
+ #define iw_usage(args...) iwgetid_usage(args)
+ #include "iwgetid.c"
+ #undef iw_usage
+ #undef main
++#endif
+
+ /* iwevent is useless for most people, don't grab it ? */
+
+@@ -131,11 +133,13 @@ main(int argc,
+ #ifndef WE_ESSENTIAL
+ if(!strcmp(call_name, "iwspy"))
+ return(main_iwspy(argc, argv));
+-#endif /* WE_ESSENTIAL */
++#endif
+ if(!strcmp(call_name, "iwpriv"))
+ return(main_iwpriv(argc, argv));
++#ifndef WE_ESSENTIAL
+ if(!strcmp(call_name, "iwgetid"))
+ return(main_iwgetid(argc, argv));
++#endif
+
+ /* Uh oh... Not supposed to come here. */
+ printf("iwmulticall : you are not supposed to call me this way...\n");
+--- a/iwlib.c
++++ b/iwlib.c
+@@ -113,6 +113,7 @@ const struct iw_modul_descr iw_modul_lis
+ { IW_MODUL_11A, "11a", "IEEE 802.11a (5 GHz, up to 54 Mb/s)" },
+ { IW_MODUL_11B, "11b", "IEEE 802.11b (2.4 GHz, up to 11 Mb/s)" },
+
++#ifndef WE_ESSENTIAL
+ /* Proprietary aggregates */
+ { IW_MODUL_TURBO | IW_MODUL_11A, "turboa",
+ "Atheros turbo mode at 5 GHz (up to 108 Mb/s)" },
+@@ -120,6 +121,7 @@ const struct iw_modul_descr iw_modul_lis
+ "Atheros turbo mode at 2.4 GHz (up to 108 Mb/s)" },
+ { IW_MODUL_PBCC | IW_MODUL_11B, "11+",
+ "TI 802.11+ (2.4 GHz, up to 22 Mb/s)" },
++#endif
+
+ /* Individual modulations */
+ { IW_MODUL_OFDM_G, "OFDMg",
+@@ -129,6 +131,7 @@ const struct iw_modul_descr iw_modul_lis
+ { IW_MODUL_DS, "DS", "802.11 Direct Sequence (2.4 GHz, up to 2 Mb/s)" },
+ { IW_MODUL_FH, "FH", "802.11 Frequency Hopping (2,4 GHz, up to 2 Mb/s)" },
+
++#ifndef WE_ESSENTIAL
+ /* Proprietary modulations */
+ { IW_MODUL_TURBO, "turbo",
+ "Atheros turbo mode, channel bonding (up to 108 Mb/s)" },
+@@ -136,6 +139,7 @@ const struct iw_modul_descr iw_modul_lis
+ "TI 802.11+ higher rates (2.4 GHz, up to 22 Mb/s)" },
+ { IW_MODUL_CUSTOM, "custom",
+ "Driver specific modulation (check driver documentation)" },
++#endif
+ };
+
+ /* Disable runtime version warning in iw_get_range_info() */
+@@ -440,6 +444,7 @@ iw_print_version_info(const char * tooln
+ return -1;
+ }
+
++#ifndef WE_ESSENTIAL
+ /* Information about the tools themselves */
+ if(toolname != NULL)
+ printf("%-8.16s Wireless-Tools version %d\n", toolname, WT_VERSION);
+@@ -452,6 +457,7 @@ iw_print_version_info(const char * tooln
+ if(we_kernel_version > 15)
+ printf("Kernel Currently compiled with Wireless Extension v%d.\n\n",
+ we_kernel_version);
++#endif
+
+ /* Version for each device */
+ iw_enum_devices(skfd, &print_iface_version_info, NULL, 0);
+@@ -501,6 +507,7 @@ iw_get_range_info(int skfd,
+ /* Copy stuff at the right place, ignore extra */
+ memcpy((char *) range, buffer, sizeof(iwrange));
+ }
++#ifndef WE_ESSENTIAL
+ else
+ {
+ /* Zero unknown fields */
+@@ -574,6 +581,7 @@ iw_get_range_info(int skfd,
+ * If the driver source has not been updated to the latest, it doesn't
+ * matter because the new fields are set to zero */
+ }
++#endif
+
+ /* Don't complain twice.
+ * In theory, the test apply to each individual driver, but usually
+@@ -1542,6 +1550,7 @@ iw_print_key(char * buffer,
+ }
+ }
+
++#ifndef WE_ESSENTIAL
+ /*------------------------------------------------------------------*/
+ /*
+ * Convert a passphrase into a key
+@@ -1556,6 +1565,7 @@ iw_pass_key(const char * input,
+ fprintf(stderr, "Error: Passphrase not implemented\n");
+ return(-1);
+ }
++#endif
+
+ /*------------------------------------------------------------------*/
+ /*
+@@ -1578,12 +1588,14 @@ iw_in_key(const char * input,
+ keylen = IW_ENCODING_TOKEN_MAX;
+ memcpy(key, input + 2, keylen);
+ }
++#ifndef WE_ESSENTIAL
+ else
+ if(!strncmp(input, "p:", 2))
+ {
+ /* Second case : as a passphrase (PrismII cards) */
+ return(iw_pass_key(input + 2, key)); /* skip "p:" */
+ }
++#endif
+ else
+ {
+ const char * p;
+--- a/Makefile
++++ b/Makefile
+@@ -195,9 +195,9 @@ install-iwmulticall:: iwmulticall
+ install -m 755 $< $(INSTALL_DIR)/iwconfig
+ ( cd $(INSTALL_DIR) ; \
+ ln -f -s iwconfig iwlist ; \
+- ln -f -s iwconfig iwspy ; \
++ $(if $(BUILD_WE_ESSENTIAL),,ln -f -s iwconfig iwspy ;) \
+ ln -f -s iwconfig iwpriv ; \
+- ln -f -s iwconfig iwgetid )
++ $(if $(BUILD_WE_ESSENTIAL),,ln -f -s iwconfig iwgetid ) )
+
+ clean::
+ $(RM_CMD)
diff --git a/package/network/utils/wireless-tools/patches/004-increase_iwlist_buffer.patch b/package/network/utils/wireless-tools/patches/004-increase_iwlist_buffer.patch
new file mode 100644
index 0000000..f2fdb12
--- /dev/null
+++ b/package/network/utils/wireless-tools/patches/004-increase_iwlist_buffer.patch
@@ -0,0 +1,46 @@
+--- a/iwlist.c
++++ b/iwlist.c
+@@ -792,7 +792,8 @@ print_scanning_info(int skfd,
+ if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0)
+ {
+ /* Check if buffer was too small (WE-17 only) */
+- if((errno == E2BIG) && (range.we_version_compiled > 16))
++ if((errno == E2BIG) && (range.we_version_compiled > 16)
++ && (buflen < 0xFFFF))
+ {
+ /* Some driver may return very large scan results, either
+ * because there are many cells, or because they have many
+@@ -808,6 +809,10 @@ print_scanning_info(int skfd,
+ else
+ buflen *= 2;
+
++ /* wrq.u.data.length is 16 bits so max size is 65535 */
++ if(buflen > 0xFFFF)
++ buflen = 0xFFFF;
++
+ /* Try again */
+ goto realloc;
+ }
+@@ -2152,6 +2157,7 @@ main(int argc,
+ char **args; /* Command arguments */
+ int count; /* Number of arguments */
+ const iwlist_cmd *iwcmd;
++ int goterr = 0;
+
+ if(argc < 2)
+ iw_usage(1);
+@@ -2199,12 +2205,12 @@ main(int argc,
+
+ /* do the actual work */
+ if (dev)
+- (*iwcmd->fn)(skfd, dev, args, count);
++ goterr = (*iwcmd->fn)(skfd, dev, args, count);
+ else
+ iw_enum_devices(skfd, iwcmd->fn, args, count);
+
+ /* Close the socket. */
+ iw_sockets_close(skfd);
+
+- return 0;
++ return goterr;
+ }
diff --git a/package/network/utils/wpan-tools/Makefile b/package/network/utils/wpan-tools/Makefile
new file mode 100644
index 0000000..7b2cfe7
--- /dev/null
+++ b/package/network/utils/wpan-tools/Makefile
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=wpan-tools
+PKG_VERSION:=0.9
+PKG_RELEASE=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/linux-wpan/wpan-tools/releases/download/$(PKG_NAME)-$(PKG_VERSION)/$(PKG_NAME)-$(PKG_VERSION).tar.gz?
+PKG_HASH:=fa76d9c1874220e4b1f91c226f42baf1e372ea8ccf4b892effaf0d164448f608
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/wpan-tools
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=cfg802154 interface configuration utility
+ URL:=https://linux-wpan.org/wpan-tools.html
+ DEPENDS:= +libnl
+endef
+
+define Package/wpan-tools/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/iwpan $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/wpan-ping/wpan-ping $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,wpan-tools))
diff --git a/package/network/utils/wwan/Makefile b/package/network/utils/wwan/Makefile
new file mode 100644
index 0000000..b02f9e1
--- /dev/null
+++ b/package/network/utils/wwan/Makefile
@@ -0,0 +1,45 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=wwan
+PKG_VERSION:=2019.04.29
+PKG_RELEASE=6
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=
+
+PKG_MAINTAINER:=John Crispin <john@phrozen.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/wwan
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Generic OpenWrt 3G/4G proto handler
+endef
+
+define Build/Compile
+ true
+endef
+
+define Package/wwan/install
+ $(INSTALL_DIR) $(1)/lib/netifd/proto/
+ $(CP) ./files/wwan.sh $(1)/lib/netifd/proto/
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/usb
+ $(INSTALL_BIN) ./files/wwan.usb $(1)/etc/hotplug.d/usb/00_wwan.sh
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/usbmisc
+ $(INSTALL_BIN) ./files/wwan.usbmisc $(1)/etc/hotplug.d/usbmisc/00_wwan.sh
+ $(INSTALL_DIR) $(1)/lib/network/wwan/
+ $(INSTALL_DATA) ./files/data/* $(1)/lib/network/wwan/
+ #in order to keep the Lede GIT repo free of filenames with colons,
+ #we name the files xxxx-yyyy
+ # and rename here after copying to the build directory
+ shopt -s nullglob ; \
+ for filevar in $(1)/lib/network/wwan/*-* ; \
+ do \
+ FILENAME=$$$$(basename $$$$filevar) ; \
+ NEWNAME=$$$${FILENAME//-/:} ; \
+ mv "$(1)/lib/network/wwan/$$$$FILENAME" "$(1)/lib/network/wwan/$$$$NEWNAME" ; \
+ done
+endef
+
+$(eval $(call BuildPackage,wwan))
diff --git a/package/network/utils/wwan/files/data/0421-03a7 b/package/network/utils/wwan/files/data/0421-03a7
new file mode 100644
index 0000000..c2ce008
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-03a7
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia C5-00 Mobile phone",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-060d b/package/network/utils/wwan/files/data/0421-060d
new file mode 100644
index 0000000..3ef6df4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-060d
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia CS-10",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-060e b/package/network/utils/wwan/files/data/0421-060e
new file mode 100644
index 0000000..3ef6df4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-060e
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia CS-10",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-0612 b/package/network/utils/wwan/files/data/0421-0612
new file mode 100644
index 0000000..d219e7a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-0612
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia CS-15/CS-18",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-0619 b/package/network/utils/wwan/files/data/0421-0619
new file mode 100644
index 0000000..e61bb09
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-0619
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia CS-12",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-061e b/package/network/utils/wwan/files/data/0421-061e
new file mode 100644
index 0000000..41c8afa
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-061e
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia CS-11",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-0623 b/package/network/utils/wwan/files/data/0421-0623
new file mode 100644
index 0000000..14c2530
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-0623
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia CS-17",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-0629 b/package/network/utils/wwan/files/data/0421-0629
new file mode 100644
index 0000000..0feb718
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-0629
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia CS-18",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-062d b/package/network/utils/wwan/files/data/0421-062d
new file mode 100644
index 0000000..e901589
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-062d
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia CS-19",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-062f b/package/network/utils/wwan/files/data/0421-062f
new file mode 100644
index 0000000..e901589
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-062f
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia CS-19",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0421-0638 b/package/network/utils/wwan/files/data/0421-0638
new file mode 100644
index 0000000..42ec6fe
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0421-0638
@@ -0,0 +1,6 @@
+{
+ "desc": "Nokia 21M-02",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/05c6-0016 b/package/network/utils/wwan/files/data/05c6-0016
new file mode 100644
index 0000000..b623ebf
--- /dev/null
+++ b/package/network/utils/wwan/files/data/05c6-0016
@@ -0,0 +1,6 @@
+{
+ "desc": "iBall 3.5G Connect",
+ "control": 2,
+ "data": 2,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/05c6-0023 b/package/network/utils/wwan/files/data/05c6-0023
new file mode 100644
index 0000000..a01dea8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/05c6-0023
@@ -0,0 +1,5 @@
+{
+ "desc": "Leoxsys LN-72V",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/05c6-00a0 b/package/network/utils/wwan/files/data/05c6-00a0
new file mode 100644
index 0000000..3397252
--- /dev/null
+++ b/package/network/utils/wwan/files/data/05c6-00a0
@@ -0,0 +1,6 @@
+{
+ "desc": "Axesstel MV241",
+ "control": 2,
+ "data": 0,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/05c6-6000 b/package/network/utils/wwan/files/data/05c6-6000
new file mode 100644
index 0000000..217038f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/05c6-6000
@@ -0,0 +1,5 @@
+{
+ "desc": "Siemens SG75",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/05c6-9000 b/package/network/utils/wwan/files/data/05c6-9000
new file mode 100644
index 0000000..17cc41d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/05c6-9000
@@ -0,0 +1,5 @@
+{
+ "desc": "Generic Qualcomm",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/07d1-3e01 b/package/network/utils/wwan/files/data/07d1-3e01
new file mode 100644
index 0000000..8944705
--- /dev/null
+++ b/package/network/utils/wwan/files/data/07d1-3e01
@@ -0,0 +1,5 @@
+{
+ "desc": "D-Link DWM-152",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/07d1-3e02 b/package/network/utils/wwan/files/data/07d1-3e02
new file mode 100644
index 0000000..be0a893
--- /dev/null
+++ b/package/network/utils/wwan/files/data/07d1-3e02
@@ -0,0 +1,5 @@
+{
+ "desc": "D-Link DWM-156",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/07d1-7e11 b/package/network/utils/wwan/files/data/07d1-7e11
new file mode 100644
index 0000000..3da9895
--- /dev/null
+++ b/package/network/utils/wwan/files/data/07d1-7e11
@@ -0,0 +1,6 @@
+{
+ "desc": "D-Link DWM-156",
+ "control": 1,
+ "data": 2,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/0af0-4005 b/package/network/utils/wwan/files/data/0af0-4005
new file mode 100644
index 0000000..5ab6c12
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0af0-4005
@@ -0,0 +1,4 @@
+{
+ "desc": "Option GIO711",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0af0-6901 b/package/network/utils/wwan/files/data/0af0-6901
new file mode 100644
index 0000000..a88c36d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0af0-6901
@@ -0,0 +1,5 @@
+{
+ "desc": "Option GI0201",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/0af0-7201 b/package/network/utils/wwan/files/data/0af0-7201
new file mode 100644
index 0000000..fc84354
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0af0-7201
@@ -0,0 +1,5 @@
+{
+ "desc": "Option GTM380",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/0af0-8120 b/package/network/utils/wwan/files/data/0af0-8120
new file mode 100644
index 0000000..c378e7f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0af0-8120
@@ -0,0 +1,4 @@
+{
+ "desc": "Option GTM681W",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0af0-9200 b/package/network/utils/wwan/files/data/0af0-9200
new file mode 100644
index 0000000..8230dd0
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0af0-9200
@@ -0,0 +1,5 @@
+{
+ "desc": "Option GTM671WFS",
+ "control": 2,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/0b3c-c000 b/package/network/utils/wwan/files/data/0b3c-c000
new file mode 100644
index 0000000..b45bbf4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0b3c-c000
@@ -0,0 +1,4 @@
+{
+ "desc": "Olivetti Olicard 100",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0b3c-c001 b/package/network/utils/wwan/files/data/0b3c-c001
new file mode 100644
index 0000000..74a0334
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0b3c-c001
@@ -0,0 +1,4 @@
+{
+ "desc": "Olivetti Olicard 120",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0b3c-c002 b/package/network/utils/wwan/files/data/0b3c-c002
new file mode 100644
index 0000000..ed4f2fd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0b3c-c002
@@ -0,0 +1,4 @@
+{
+ "desc": "Olivetti Olicard 140",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0b3c-c003 b/package/network/utils/wwan/files/data/0b3c-c003
new file mode 100644
index 0000000..77528b5
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0b3c-c003
@@ -0,0 +1,5 @@
+{
+ "desc": "Olivetti Olicard 145",
+ "control": 0,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/0b3c-c004 b/package/network/utils/wwan/files/data/0b3c-c004
new file mode 100644
index 0000000..d819379
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0b3c-c004
@@ -0,0 +1,4 @@
+{
+ "desc": "Olivetti Olicard 155",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0b3c-c005 b/package/network/utils/wwan/files/data/0b3c-c005
new file mode 100644
index 0000000..f3768c6
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0b3c-c005
@@ -0,0 +1,4 @@
+{
+ "desc": "Olivetti Olicard 200",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0b3c-c00a b/package/network/utils/wwan/files/data/0b3c-c00a
new file mode 100644
index 0000000..a2ba14a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0b3c-c00a
@@ -0,0 +1,4 @@
+{
+ "desc": "Olivetti Olicard 160",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0b3c-c00b b/package/network/utils/wwan/files/data/0b3c-c00b
new file mode 100644
index 0000000..1c6edb1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0b3c-c00b
@@ -0,0 +1,4 @@
+{
+ "desc": "Olivetti Olicard 500",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0bdb-1900 b/package/network/utils/wwan/files/data/0bdb-1900
new file mode 100644
index 0000000..e7d72f1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0bdb-1900
@@ -0,0 +1,6 @@
+{
+ "desc": "Ericsson F3507g",
+ "control": 4,
+ "data": 1,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0bdb-1902 b/package/network/utils/wwan/files/data/0bdb-1902
new file mode 100644
index 0000000..e7d72f1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0bdb-1902
@@ -0,0 +1,6 @@
+{
+ "desc": "Ericsson F3507g",
+ "control": 4,
+ "data": 1,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0bdb-190a b/package/network/utils/wwan/files/data/0bdb-190a
new file mode 100644
index 0000000..e5b16e3
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0bdb-190a
@@ -0,0 +1,6 @@
+{
+ "desc": "Ericsson F3307",
+ "control": 4,
+ "data": 1,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0bdb-190d b/package/network/utils/wwan/files/data/0bdb-190d
new file mode 100644
index 0000000..126c09f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0bdb-190d
@@ -0,0 +1,6 @@
+{
+ "desc": "Ericsson F5521gw",
+ "control": 4,
+ "data": 1,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0bdb-1910 b/package/network/utils/wwan/files/data/0bdb-1910
new file mode 100644
index 0000000..126c09f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0bdb-1910
@@ -0,0 +1,6 @@
+{
+ "desc": "Ericsson F5521gw",
+ "control": 4,
+ "data": 1,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/0c88-17da b/package/network/utils/wwan/files/data/0c88-17da
new file mode 100644
index 0000000..fcdf611
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0c88-17da
@@ -0,0 +1,5 @@
+{
+ "desc": "Kyocera KPC650",
+ "control": 0,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/0c88-180a b/package/network/utils/wwan/files/data/0c88-180a
new file mode 100644
index 0000000..e042642
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0c88-180a
@@ -0,0 +1,5 @@
+{
+ "desc": "Kyocera KPC680",
+ "control": 0,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/0e8d-00a5 b/package/network/utils/wwan/files/data/0e8d-00a5
new file mode 100644
index 0000000..23a7ce3
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0e8d-00a5
@@ -0,0 +1,5 @@
+{
+ "desc": "Medion S4222",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/0f3d-68a2 b/package/network/utils/wwan/files/data/0f3d-68a2
new file mode 100644
index 0000000..f85a049
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0f3d-68a2
@@ -0,0 +1,4 @@
+{
+ "desc": "Sierra MC7700",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/0f3d-68aa b/package/network/utils/wwan/files/data/0f3d-68aa
new file mode 100644
index 0000000..dab35fa
--- /dev/null
+++ b/package/network/utils/wwan/files/data/0f3d-68aa
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra Wireless AC313U/320U/330U Direct IP",
+ "control": 3,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/1004-6124 b/package/network/utils/wwan/files/data/1004-6124
new file mode 100644
index 0000000..b6da8c4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1004-6124
@@ -0,0 +1,6 @@
+{
+ "desc": "LG L-05A",
+ "control": 0,
+ "data": 2,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/1004-6141 b/package/network/utils/wwan/files/data/1004-6141
new file mode 100644
index 0000000..142d70f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1004-6141
@@ -0,0 +1,6 @@
+{
+ "desc": "LG LUU-2100TI",
+ "control": 0,
+ "data": 2,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/1004-6157 b/package/network/utils/wwan/files/data/1004-6157
new file mode 100644
index 0000000..842c0b4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1004-6157
@@ -0,0 +1,6 @@
+{
+ "desc": "LG LUU-2110TI",
+ "control": 0,
+ "data": 2,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/1004-618f b/package/network/utils/wwan/files/data/1004-618f
new file mode 100644
index 0000000..bb4b534
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1004-618f
@@ -0,0 +1,5 @@
+{
+ "desc": "LG L-02C",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/106c-3711 b/package/network/utils/wwan/files/data/106c-3711
new file mode 100644
index 0000000..0198c33
--- /dev/null
+++ b/package/network/utils/wwan/files/data/106c-3711
@@ -0,0 +1,6 @@
+{
+ "desc": "PANTECH UM-150",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/106c-3714 b/package/network/utils/wwan/files/data/106c-3714
new file mode 100644
index 0000000..a735680
--- /dev/null
+++ b/package/network/utils/wwan/files/data/106c-3714
@@ -0,0 +1,6 @@
+{
+ "desc": "PANTECH UM-175",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/106c-3715 b/package/network/utils/wwan/files/data/106c-3715
new file mode 100644
index 0000000..5a5194d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/106c-3715
@@ -0,0 +1,6 @@
+{
+ "desc": "PANTECH UM-175AL",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/106c-3716 b/package/network/utils/wwan/files/data/106c-3716
new file mode 100644
index 0000000..aa50f5d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/106c-3716
@@ -0,0 +1,6 @@
+{
+ "desc": "PANTECH UM-190",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/106c-3717 b/package/network/utils/wwan/files/data/106c-3717
new file mode 100644
index 0000000..fd80949
--- /dev/null
+++ b/package/network/utils/wwan/files/data/106c-3717
@@ -0,0 +1,6 @@
+{
+ "desc": "PANTECH UM-185C/UM185E",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/106c-3718 b/package/network/utils/wwan/files/data/106c-3718
new file mode 100644
index 0000000..362f482
--- /dev/null
+++ b/package/network/utils/wwan/files/data/106c-3718
@@ -0,0 +1,4 @@
+{
+ "desc": "PANTECH UML-290 4G Modem",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/106c-3721 b/package/network/utils/wwan/files/data/106c-3721
new file mode 100644
index 0000000..ac61a08
--- /dev/null
+++ b/package/network/utils/wwan/files/data/106c-3721
@@ -0,0 +1,4 @@
+{
+ "desc": "PANTECH P4200 4G Modem",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/1199-0017 b/package/network/utils/wwan/files/data/1199-0017
new file mode 100644
index 0000000..532aadd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0017
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra EM5625",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0018 b/package/network/utils/wwan/files/data/1199-0018
new file mode 100644
index 0000000..71447d1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0018
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC5720",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0019 b/package/network/utils/wwan/files/data/1199-0019
new file mode 100644
index 0000000..43ccfd0
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0019
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC595U",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0020 b/package/network/utils/wwan/files/data/1199-0020
new file mode 100644
index 0000000..d92732c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0020
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC5725",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0021 b/package/network/utils/wwan/files/data/1199-0021
new file mode 100644
index 0000000..d879a34
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0021
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC597E",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0022 b/package/network/utils/wwan/files/data/1199-0022
new file mode 100644
index 0000000..b4780db
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0022
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra EM5725",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0023 b/package/network/utils/wwan/files/data/1199-0023
new file mode 100644
index 0000000..447f681
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0023
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC597",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0024 b/package/network/utils/wwan/files/data/1199-0024
new file mode 100644
index 0000000..9617b69
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0024
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC5727 CDMA",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0025 b/package/network/utils/wwan/files/data/1199-0025
new file mode 100644
index 0000000..f0792c8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0025
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC598",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0026 b/package/network/utils/wwan/files/data/1199-0026
new file mode 100644
index 0000000..ba1ea2a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0026
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra T11",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0027 b/package/network/utils/wwan/files/data/1199-0027
new file mode 100644
index 0000000..b959eca
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0027
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC402",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0028 b/package/network/utils/wwan/files/data/1199-0028
new file mode 100644
index 0000000..02967db
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0028
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC5728",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0112 b/package/network/utils/wwan/files/data/1199-0112
new file mode 100644
index 0000000..900923c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0112
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra CDMA 1xEVDO PC Card, AC580",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0120 b/package/network/utils/wwan/files/data/1199-0120
new file mode 100644
index 0000000..43ccfd0
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0120
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC595U",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0218 b/package/network/utils/wwan/files/data/1199-0218
new file mode 100644
index 0000000..71447d1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0218
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC5720",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0220 b/package/network/utils/wwan/files/data/1199-0220
new file mode 100644
index 0000000..d92732c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0220
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC5725",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0224 b/package/network/utils/wwan/files/data/1199-0224
new file mode 100644
index 0000000..b5b13cc
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0224
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC5727",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-0301 b/package/network/utils/wwan/files/data/1199-0301
new file mode 100644
index 0000000..2f3a6d0
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-0301
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC250U",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-6802 b/package/network/utils/wwan/files/data/1199-6802
new file mode 100644
index 0000000..497aff2
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6802
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8755",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6803 b/package/network/utils/wwan/files/data/1199-6803
new file mode 100644
index 0000000..0e3ebbb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6803
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8765",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6804 b/package/network/utils/wwan/files/data/1199-6804
new file mode 100644
index 0000000..497aff2
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6804
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8755",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6805 b/package/network/utils/wwan/files/data/1199-6805
new file mode 100644
index 0000000..0e3ebbb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6805
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8765",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6808 b/package/network/utils/wwan/files/data/1199-6808
new file mode 100644
index 0000000..497aff2
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6808
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8755",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6809 b/package/network/utils/wwan/files/data/1199-6809
new file mode 100644
index 0000000..497aff2
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6809
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8755",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6813 b/package/network/utils/wwan/files/data/1199-6813
new file mode 100644
index 0000000..4e667e7
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6813
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8775",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6815 b/package/network/utils/wwan/files/data/1199-6815
new file mode 100644
index 0000000..4e667e7
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6815
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8775",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6816 b/package/network/utils/wwan/files/data/1199-6816
new file mode 100644
index 0000000..4e667e7
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6816
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8775",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6820 b/package/network/utils/wwan/files/data/1199-6820
new file mode 100644
index 0000000..be1a659
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6820
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC875",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1199-6821 b/package/network/utils/wwan/files/data/1199-6821
new file mode 100644
index 0000000..a912288
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6821
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC875U",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1199-6822 b/package/network/utils/wwan/files/data/1199-6822
new file mode 100644
index 0000000..90fe42b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6822
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC875E",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-6833 b/package/network/utils/wwan/files/data/1199-6833
new file mode 100644
index 0000000..11859ac
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6833
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8781",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-6834 b/package/network/utils/wwan/files/data/1199-6834
new file mode 100644
index 0000000..e23f53e
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6834
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8780",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-6835 b/package/network/utils/wwan/files/data/1199-6835
new file mode 100644
index 0000000..11859ac
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6835
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8781",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-6838 b/package/network/utils/wwan/files/data/1199-6838
new file mode 100644
index 0000000..e23f53e
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6838
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8780",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-6839 b/package/network/utils/wwan/files/data/1199-6839
new file mode 100644
index 0000000..11859ac
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6839
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8781",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-683a b/package/network/utils/wwan/files/data/1199-683a
new file mode 100644
index 0000000..aca144d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-683a
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8785",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-683b b/package/network/utils/wwan/files/data/1199-683b
new file mode 100644
index 0000000..8df7e72
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-683b
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra MC8785 Composite",
+ "control": 3,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1199-6850 b/package/network/utils/wwan/files/data/1199-6850
new file mode 100644
index 0000000..c878825
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6850
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC880",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1199-6851 b/package/network/utils/wwan/files/data/1199-6851
new file mode 100644
index 0000000..339f39a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6851
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC 881",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1199-6852 b/package/network/utils/wwan/files/data/1199-6852
new file mode 100644
index 0000000..6dcb045
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6852
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC880E",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1199-6853 b/package/network/utils/wwan/files/data/1199-6853
new file mode 100644
index 0000000..09b482c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6853
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC881E",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1199-6855 b/package/network/utils/wwan/files/data/1199-6855
new file mode 100644
index 0000000..ad5f049
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6855
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC880U",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1199-6856 b/package/network/utils/wwan/files/data/1199-6856
new file mode 100644
index 0000000..9bc6872
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6856
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra ATT USB Connect 881",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1199-6859 b/package/network/utils/wwan/files/data/1199-6859
new file mode 100644
index 0000000..9383e6c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6859
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC885E",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1199-685a b/package/network/utils/wwan/files/data/1199-685a
new file mode 100644
index 0000000..9383e6c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-685a
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC885E",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1199-6880 b/package/network/utils/wwan/files/data/1199-6880
new file mode 100644
index 0000000..bae654f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6880
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra C885",
+ "control": 3,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/1199-6890 b/package/network/utils/wwan/files/data/1199-6890
new file mode 100644
index 0000000..7154b0c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6890
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra C888",
+ "control": 3,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/1199-6891 b/package/network/utils/wwan/files/data/1199-6891
new file mode 100644
index 0000000..1e1c89c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6891
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra C22 and C33",
+ "control": 3,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/1199-6892 b/package/network/utils/wwan/files/data/1199-6892
new file mode 100644
index 0000000..923302a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6892
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra Compass HSPA",
+ "control": 3,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/1199-6893 b/package/network/utils/wwan/files/data/1199-6893
new file mode 100644
index 0000000..9cd3ad0
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-6893
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra C889",
+ "control": 3,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/1199-68a2 b/package/network/utils/wwan/files/data/1199-68a2
new file mode 100644
index 0000000..ac1b184
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-68a2
@@ -0,0 +1,4 @@
+{
+ "desc": "Sierra MC7710",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/1199-68aa b/package/network/utils/wwan/files/data/1199-68aa
new file mode 100644
index 0000000..062c200
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-68aa
@@ -0,0 +1,5 @@
+{
+ "desc": "Sierra AC320U/AC330U Direct IP",
+ "control": 3,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/1199-68c0 b/package/network/utils/wwan/files/data/1199-68c0
new file mode 100644
index 0000000..fedd6d7
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1199-68c0
@@ -0,0 +1,4 @@
+{
+ "desc": "Sierra MC7304",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1035 b/package/network/utils/wwan/files/data/12d1-1035
new file mode 100644
index 0000000..1b595cd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1035
@@ -0,0 +1,5 @@
+{
+ "desc": "HUAWEI U8110",
+ "control": 0,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1404 b/package/network/utils/wwan/files/data/12d1-1404
new file mode 100644
index 0000000..b186ad5
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1404
@@ -0,0 +1,4 @@
+{
+ "desc": "HUAWEI UMG1831",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1406 b/package/network/utils/wwan/files/data/12d1-1406
new file mode 100644
index 0000000..7961908
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1406
@@ -0,0 +1,5 @@
+{
+ "desc": "HUAWEI/Option newer modems",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-140b b/package/network/utils/wwan/files/data/12d1-140b
new file mode 100644
index 0000000..cd8cbdd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-140b
@@ -0,0 +1,5 @@
+{
+ "desc": "HUAWEI/Option EC1260 Wireless Data Modem HSD USB Card",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-140c b/package/network/utils/wwan/files/data/12d1-140c
new file mode 100644
index 0000000..148d1d1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-140c
@@ -0,0 +1,4 @@
+{
+ "desc": "HUAWEI/Option newer modems",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1412 b/package/network/utils/wwan/files/data/12d1-1412
new file mode 100644
index 0000000..342672a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1412
@@ -0,0 +1,5 @@
+{
+ "desc": "HUAWEI/Option EC168",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-141b b/package/network/utils/wwan/files/data/12d1-141b
new file mode 100644
index 0000000..7961908
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-141b
@@ -0,0 +1,5 @@
+{
+ "desc": "HUAWEI/Option newer modems",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1433 b/package/network/utils/wwan/files/data/12d1-1433
new file mode 100644
index 0000000..3159714
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1433
@@ -0,0 +1,5 @@
+{
+ "desc": "HUAWEI/Option E1756C",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1436 b/package/network/utils/wwan/files/data/12d1-1436
new file mode 100644
index 0000000..a73fdc4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1436
@@ -0,0 +1,5 @@
+{
+ "desc": "HUAWEI/Option E1800",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1444 b/package/network/utils/wwan/files/data/12d1-1444
new file mode 100644
index 0000000..cbbf9d2
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1444
@@ -0,0 +1,5 @@
+{
+ "desc": "HUAWEI/Option E352-R1",
+ "control": 0,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-144e b/package/network/utils/wwan/files/data/12d1-144e
new file mode 100644
index 0000000..c80d2e9
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-144e
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei K3806",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1464 b/package/network/utils/wwan/files/data/12d1-1464
new file mode 100644
index 0000000..ffa690d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1464
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei K4505",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1465 b/package/network/utils/wwan/files/data/12d1-1465
new file mode 100644
index 0000000..55696ff
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1465
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei K3765",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1491 b/package/network/utils/wwan/files/data/12d1-1491
new file mode 100644
index 0000000..2228a90
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1491
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei R201",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14a5 b/package/network/utils/wwan/files/data/12d1-14a5
new file mode 100644
index 0000000..6eac38b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14a5
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E173",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14a8 b/package/network/utils/wwan/files/data/12d1-14a8
new file mode 100644
index 0000000..6eac38b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14a8
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E173",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14ac b/package/network/utils/wwan/files/data/12d1-14ac
new file mode 100644
index 0000000..148d1d1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14ac
@@ -0,0 +1,4 @@
+{
+ "desc": "HUAWEI/Option newer modems",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14ae b/package/network/utils/wwan/files/data/12d1-14ae
new file mode 100644
index 0000000..92f9b6a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14ae
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei K3806",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14c6 b/package/network/utils/wwan/files/data/12d1-14c6
new file mode 100644
index 0000000..0cb4d8c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14c6
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei K4605",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14c8 b/package/network/utils/wwan/files/data/12d1-14c8
new file mode 100644
index 0000000..958b118
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14c8
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei K5005",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14c9 b/package/network/utils/wwan/files/data/12d1-14c9
new file mode 100644
index 0000000..bc75791
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14c9
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei K3770",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14ca b/package/network/utils/wwan/files/data/12d1-14ca
new file mode 100644
index 0000000..8155b4b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14ca
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei K3771",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14cb b/package/network/utils/wwan/files/data/12d1-14cb
new file mode 100644
index 0000000..8419b69
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14cb
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei K4510",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14cc b/package/network/utils/wwan/files/data/12d1-14cc
new file mode 100644
index 0000000..98488bd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14cc
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei K4511",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14cf b/package/network/utils/wwan/files/data/12d1-14cf
new file mode 100644
index 0000000..88a0f92
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14cf
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei K3772",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-14d2 b/package/network/utils/wwan/files/data/12d1-14d2
new file mode 100644
index 0000000..414b846
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-14d2
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei E173/E177",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1506 b/package/network/utils/wwan/files/data/12d1-1506
new file mode 100644
index 0000000..9e575af
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1506
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E367/E398",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-150a b/package/network/utils/wwan/files/data/12d1-150a
new file mode 100644
index 0000000..45f191a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-150a
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei E398",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-150c b/package/network/utils/wwan/files/data/12d1-150c
new file mode 100644
index 0000000..7ab4c49
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-150c
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei E367",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-150f b/package/network/utils/wwan/files/data/12d1-150f
new file mode 100644
index 0000000..7ab4c49
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-150f
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei E367",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-151b b/package/network/utils/wwan/files/data/12d1-151b
new file mode 100644
index 0000000..28e561c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-151b
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei E392u-12",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-151d b/package/network/utils/wwan/files/data/12d1-151d
new file mode 100644
index 0000000..b5a3f10
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-151d
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E3131",
+ "control": 3,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-156c b/package/network/utils/wwan/files/data/12d1-156c
new file mode 100644
index 0000000..9a0a292
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-156c
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E3276",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1576 b/package/network/utils/wwan/files/data/12d1-1576
new file mode 100644
index 0000000..1aeb021
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1576
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei K4201 composite",
+ "type": "mbim"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1577 b/package/network/utils/wwan/files/data/12d1-1577
new file mode 100644
index 0000000..46a12da
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1577
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei K4202 composite",
+ "type": "mbim"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1578 b/package/network/utils/wwan/files/data/12d1-1578
new file mode 100644
index 0000000..6710d15
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1578
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei K4606 composite",
+ "type": "mbim"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1589 b/package/network/utils/wwan/files/data/12d1-1589
new file mode 100644
index 0000000..e2d3527
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1589
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei E8278",
+ "type": "ncm"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1c05 b/package/network/utils/wwan/files/data/12d1-1c05
new file mode 100644
index 0000000..6345f53
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1c05
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E173s",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1c07 b/package/network/utils/wwan/files/data/12d1-1c07
new file mode 100644
index 0000000..e8681e6
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1c07
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E188",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1c08 b/package/network/utils/wwan/files/data/12d1-1c08
new file mode 100644
index 0000000..52df7e2
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1c08
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E173s",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1c10 b/package/network/utils/wwan/files/data/12d1-1c10
new file mode 100644
index 0000000..6eac38b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1c10
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E173",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1c12 b/package/network/utils/wwan/files/data/12d1-1c12
new file mode 100644
index 0000000..6eac38b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1c12
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E173",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1c1e b/package/network/utils/wwan/files/data/12d1-1c1e
new file mode 100644
index 0000000..4622965
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1c1e
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei E586",
+ "type": "ncm"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1c1f b/package/network/utils/wwan/files/data/12d1-1c1f
new file mode 100644
index 0000000..13cb40f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1c1f
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei E587",
+ "type": "ncm"
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1c23 b/package/network/utils/wwan/files/data/12d1-1c23
new file mode 100644
index 0000000..41aef76
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1c23
@@ -0,0 +1,5 @@
+{
+ "desc": "Huawei E173",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/12d1-1f16 b/package/network/utils/wwan/files/data/12d1-1f16
new file mode 100644
index 0000000..10d27cf
--- /dev/null
+++ b/package/network/utils/wwan/files/data/12d1-1f16
@@ -0,0 +1,4 @@
+{
+ "desc": "Huawei K5150 composite",
+ "mode": "mbim"
+}
diff --git a/package/network/utils/wwan/files/data/1410-1400 b/package/network/utils/wwan/files/data/1410-1400
new file mode 100644
index 0000000..a36e1aa
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-1400
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel U730",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-1410 b/package/network/utils/wwan/files/data/1410-1410
new file mode 100644
index 0000000..0702468
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-1410
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel U740",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-1420 b/package/network/utils/wwan/files/data/1410-1420
new file mode 100644
index 0000000..f29b08f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-1420
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel U870",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-1430 b/package/network/utils/wwan/files/data/1410-1430
new file mode 100644
index 0000000..275d3a7
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-1430
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel XU870",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-1450 b/package/network/utils/wwan/files/data/1410-1450
new file mode 100644
index 0000000..a28901f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-1450
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel X950D",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-2100 b/package/network/utils/wwan/files/data/1410-2100
new file mode 100644
index 0000000..4c8f576
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-2100
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel EV620",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-2110 b/package/network/utils/wwan/files/data/1410-2110
new file mode 100644
index 0000000..14012df
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-2110
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel ES720",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-2120 b/package/network/utils/wwan/files/data/1410-2120
new file mode 100644
index 0000000..d1c7615
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-2120
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel E725",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-2130 b/package/network/utils/wwan/files/data/1410-2130
new file mode 100644
index 0000000..fc8404f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-2130
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel ES620",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-2400 b/package/network/utils/wwan/files/data/1410-2400
new file mode 100644
index 0000000..1f18712
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-2400
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel EU730",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-2410 b/package/network/utils/wwan/files/data/1410-2410
new file mode 100644
index 0000000..fe656f5
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-2410
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel EU740",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-2420 b/package/network/utils/wwan/files/data/1410-2420
new file mode 100644
index 0000000..db1c68f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-2420
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel EU870D",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-4100 b/package/network/utils/wwan/files/data/1410-4100
new file mode 100644
index 0000000..6ec5735
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-4100
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel MC727/U727",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-4400 b/package/network/utils/wwan/files/data/1410-4400
new file mode 100644
index 0000000..0ecddcf
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-4400
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel Ovation MC930D/MC950D",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-6000 b/package/network/utils/wwan/files/data/1410-6000
new file mode 100644
index 0000000..861c992
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-6000
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel USB760",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-6001 b/package/network/utils/wwan/files/data/1410-6001
new file mode 100644
index 0000000..861c992
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-6001
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel USB760",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-6002 b/package/network/utils/wwan/files/data/1410-6002
new file mode 100644
index 0000000..1c97f16
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-6002
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel USB760 3G",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-6010 b/package/network/utils/wwan/files/data/1410-6010
new file mode 100644
index 0000000..0b9b226
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-6010
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel MC780",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-7001 b/package/network/utils/wwan/files/data/1410-7001
new file mode 100644
index 0000000..ac03ddc
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-7001
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel MiFi 2372",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-7003 b/package/network/utils/wwan/files/data/1410-7003
new file mode 100644
index 0000000..ac03ddc
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-7003
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel MiFi 2372",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-7030 b/package/network/utils/wwan/files/data/1410-7030
new file mode 100644
index 0000000..1ea46ea
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-7030
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel USB998",
+ "control": 0,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-7031 b/package/network/utils/wwan/files/data/1410-7031
new file mode 100644
index 0000000..86d03ce
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-7031
@@ -0,0 +1,6 @@
+{
+ "desc": "Novatel USB679",
+ "control": 0,
+ "data": 0,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/1410-7041 b/package/network/utils/wwan/files/data/1410-7041
new file mode 100644
index 0000000..203597d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-7041
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel MF3470",
+ "control": 0,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-7042 b/package/network/utils/wwan/files/data/1410-7042
new file mode 100644
index 0000000..ea6d71f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-7042
@@ -0,0 +1,5 @@
+{
+ "desc": "Novatel Ovation MC545/MC547",
+ "control": 0,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1410-9011 b/package/network/utils/wwan/files/data/1410-9011
new file mode 100644
index 0000000..8247a97
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-9011
@@ -0,0 +1,4 @@
+{
+ "desc": "Novatel E371",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/1410-b001 b/package/network/utils/wwan/files/data/1410-b001
new file mode 100644
index 0000000..3c13539
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1410-b001
@@ -0,0 +1,4 @@
+{
+ "desc": "Novatel MC551/USB551L",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/1529-3100 b/package/network/utils/wwan/files/data/1529-3100
new file mode 100644
index 0000000..afeb681
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1529-3100
@@ -0,0 +1,6 @@
+{
+ "desc": "UBIQUAM U-100/105/200/300/520",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d5-6202 b/package/network/utils/wwan/files/data/16d5-6202
new file mode 100644
index 0000000..6225785
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d5-6202
@@ -0,0 +1,5 @@
+{
+ "desc": "AnyData ADU-620UW",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/16d5-6501 b/package/network/utils/wwan/files/data/16d5-6501
new file mode 100644
index 0000000..96574f3
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d5-6501
@@ -0,0 +1,5 @@
+{
+ "desc": "AnyData ADU-300A",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/16d5-6502 b/package/network/utils/wwan/files/data/16d5-6502
new file mode 100644
index 0000000..8607d41
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d5-6502
@@ -0,0 +1,5 @@
+{
+ "desc": "AnyData ADU-500A",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/16d5-6603 b/package/network/utils/wwan/files/data/16d5-6603
new file mode 100644
index 0000000..8f0ff3b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d5-6603
@@ -0,0 +1,6 @@
+{
+ "desc": "AnyData ADU-890WH",
+ "control": 0,
+ "data": 0,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d5-900d b/package/network/utils/wwan/files/data/16d5-900d
new file mode 100644
index 0000000..4ac52bb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d5-900d
@@ -0,0 +1,6 @@
+{
+ "desc": "AnyData ADU-890WH",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-5141 b/package/network/utils/wwan/files/data/16d8-5141
new file mode 100644
index 0000000..eeb3ea4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-5141
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CNU-510",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-5533 b/package/network/utils/wwan/files/data/16d8-5533
new file mode 100644
index 0000000..9fd23cd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-5533
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CNU-550",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-5543 b/package/network/utils/wwan/files/data/16d8-5543
new file mode 100644
index 0000000..9fd23cd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-5543
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CNU-550",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-5553 b/package/network/utils/wwan/files/data/16d8-5553
new file mode 100644
index 0000000..323ec28
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-5553
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CDU-550",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-6002 b/package/network/utils/wwan/files/data/16d8-6002
new file mode 100644
index 0000000..d779cdf
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-6002
@@ -0,0 +1,5 @@
+{
+ "desc": "Franklin U300",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/16d8-6006 b/package/network/utils/wwan/files/data/16d8-6006
new file mode 100644
index 0000000..92c5f0d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-6006
@@ -0,0 +1,5 @@
+{
+ "desc": "Cmotech CGU-628",
+ "control": 0,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/16d8-6007 b/package/network/utils/wwan/files/data/16d8-6007
new file mode 100644
index 0000000..a0ed8bc
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-6007
@@ -0,0 +1,4 @@
+{
+ "desc": "Cmotech CHE-628S",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/16d8-6008 b/package/network/utils/wwan/files/data/16d8-6008
new file mode 100644
index 0000000..1afeb99
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-6008
@@ -0,0 +1,4 @@
+{
+ "desc": "Franklin U301",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/16d8-6522 b/package/network/utils/wwan/files/data/16d8-6522
new file mode 100644
index 0000000..8301da1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-6522
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CDU-650",
+ "control": 2,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-6523 b/package/network/utils/wwan/files/data/16d8-6523
new file mode 100644
index 0000000..40ee5cb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-6523
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CCU-650U",
+ "control": 2,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-6532 b/package/network/utils/wwan/files/data/16d8-6532
new file mode 100644
index 0000000..e0cbfe2
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-6532
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CCU-650",
+ "control": 2,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-6533 b/package/network/utils/wwan/files/data/16d8-6533
new file mode 100644
index 0000000..f3866bb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-6533
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CNM-650",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-6543 b/package/network/utils/wwan/files/data/16d8-6543
new file mode 100644
index 0000000..99fcedd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-6543
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CNU-650",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/16d8-680a b/package/network/utils/wwan/files/data/16d8-680a
new file mode 100644
index 0000000..8360921
--- /dev/null
+++ b/package/network/utils/wwan/files/data/16d8-680a
@@ -0,0 +1,6 @@
+{
+ "desc": "Cmotech CDU-680",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0001 b/package/network/utils/wwan/files/data/19d2-0001
new file mode 100644
index 0000000..5b0d962
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0001
@@ -0,0 +1,5 @@
+{
+ "desc": "ONDA MT505UP/ZTE",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0002 b/package/network/utils/wwan/files/data/19d2-0002
new file mode 100644
index 0000000..ee80af5
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0002
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE ET502HS/MT505UP/MF632",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0015 b/package/network/utils/wwan/files/data/19d2-0015
new file mode 100644
index 0000000..5b0d962
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0015
@@ -0,0 +1,5 @@
+{
+ "desc": "ONDA MT505UP/ZTE",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0016 b/package/network/utils/wwan/files/data/19d2-0016
new file mode 100644
index 0000000..31c7421
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0016
@@ -0,0 +1,5 @@
+{
+ "desc": "ONDA MF110/ZTE",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0017 b/package/network/utils/wwan/files/data/19d2-0017
new file mode 100644
index 0000000..87178fb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0017
@@ -0,0 +1,4 @@
+{
+ "desc": "ONDA MT505UP/ZTE",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0018 b/package/network/utils/wwan/files/data/19d2-0018
new file mode 100644
index 0000000..35dc57e
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0018
@@ -0,0 +1,5 @@
+{
+ "desc": "ONDA MSA110UP/ZTE",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0019 b/package/network/utils/wwan/files/data/19d2-0019
new file mode 100644
index 0000000..8d31ed7
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0019
@@ -0,0 +1,4 @@
+{
+ "desc": "ONDA MT689DC/ZTE",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0022 b/package/network/utils/wwan/files/data/19d2-0022
new file mode 100644
index 0000000..0d7b826
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0022
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE K2525",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0024 b/package/network/utils/wwan/files/data/19d2-0024
new file mode 100644
index 0000000..128bd72
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0024
@@ -0,0 +1,5 @@
+{
+ "desc": "ONDA MT503HSA",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0025 b/package/network/utils/wwan/files/data/19d2-0025
new file mode 100644
index 0000000..68baeb7
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0025
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF628",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0031 b/package/network/utils/wwan/files/data/19d2-0031
new file mode 100644
index 0000000..7aa8aa4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0031
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF110/MF112/MF626",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0033 b/package/network/utils/wwan/files/data/19d2-0033
new file mode 100644
index 0000000..bcca7ff
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0033
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF636",
+ "control": 1,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0037 b/package/network/utils/wwan/files/data/19d2-0037
new file mode 100644
index 0000000..0bc992e
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0037
@@ -0,0 +1,5 @@
+{
+ "desc": "ONDA MT505UP/ZTE",
+ "control": 2,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0039 b/package/network/utils/wwan/files/data/19d2-0039
new file mode 100644
index 0000000..3a6e72e
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0039
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF100",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0042 b/package/network/utils/wwan/files/data/19d2-0042
new file mode 100644
index 0000000..c08014c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0042
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF190",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0052 b/package/network/utils/wwan/files/data/19d2-0052
new file mode 100644
index 0000000..87178fb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0052
@@ -0,0 +1,4 @@
+{
+ "desc": "ONDA MT505UP/ZTE",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0055 b/package/network/utils/wwan/files/data/19d2-0055
new file mode 100644
index 0000000..87178fb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0055
@@ -0,0 +1,4 @@
+{
+ "desc": "ONDA MT505UP/ZTE",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0057 b/package/network/utils/wwan/files/data/19d2-0057
new file mode 100644
index 0000000..1d0f0a1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0057
@@ -0,0 +1,5 @@
+{
+ "desc": "AIKO 83D",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0063 b/package/network/utils/wwan/files/data/19d2-0063
new file mode 100644
index 0000000..f45825d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0063
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE K3565-Z",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0064 b/package/network/utils/wwan/files/data/19d2-0064
new file mode 100644
index 0000000..2b47841
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0064
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF627",
+ "control": 0,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0066 b/package/network/utils/wwan/files/data/19d2-0066
new file mode 100644
index 0000000..f8bbdae
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0066
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF626",
+ "control": 1,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0073 b/package/network/utils/wwan/files/data/19d2-0073
new file mode 100644
index 0000000..acd581c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0073
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE A580",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0079 b/package/network/utils/wwan/files/data/19d2-0079
new file mode 100644
index 0000000..c2d52de
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0079
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE A353",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0082 b/package/network/utils/wwan/files/data/19d2-0082
new file mode 100644
index 0000000..2dbd3b5
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0082
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF668/MF190",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0086 b/package/network/utils/wwan/files/data/19d2-0086
new file mode 100644
index 0000000..0527f6f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0086
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF645",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0091 b/package/network/utils/wwan/files/data/19d2-0091
new file mode 100644
index 0000000..be9cb55
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0091
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF636",
+ "control": 1,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0094 b/package/network/utils/wwan/files/data/19d2-0094
new file mode 100644
index 0000000..ed2fd26
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0094
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE AC581",
+ "control": 3,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0104 b/package/network/utils/wwan/files/data/19d2-0104
new file mode 100644
index 0000000..0646b8d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0104
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE K4505-Z",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0108 b/package/network/utils/wwan/files/data/19d2-0108
new file mode 100644
index 0000000..aac3158
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0108
@@ -0,0 +1,5 @@
+{
+ "desc": "ONDA MT505UP/ZTE",
+ "control": 1,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0116 b/package/network/utils/wwan/files/data/19d2-0116
new file mode 100644
index 0000000..974edf4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0116
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF651",
+ "control": 1,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0117 b/package/network/utils/wwan/files/data/19d2-0117
new file mode 100644
index 0000000..0cb57d9
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0117
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF112",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0121 b/package/network/utils/wwan/files/data/19d2-0121
new file mode 100644
index 0000000..da5b96c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0121
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF637",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0124 b/package/network/utils/wwan/files/data/19d2-0124
new file mode 100644
index 0000000..74b4f6f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0124
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF110",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0128 b/package/network/utils/wwan/files/data/19d2-0128
new file mode 100644
index 0000000..078932e
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0128
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF651",
+ "control": 1,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0142 b/package/network/utils/wwan/files/data/19d2-0142
new file mode 100644
index 0000000..db86581
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0142
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF665C",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0143 b/package/network/utils/wwan/files/data/19d2-0143
new file mode 100644
index 0000000..4208016
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0143
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF190B",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0152 b/package/network/utils/wwan/files/data/19d2-0152
new file mode 100644
index 0000000..f5b84eb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0152
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE AC583",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0157 b/package/network/utils/wwan/files/data/19d2-0157
new file mode 100644
index 0000000..d7be7c4
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0157
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF683",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0167 b/package/network/utils/wwan/files/data/19d2-0167
new file mode 100644
index 0000000..0eefdc1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0167
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF820D",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0170 b/package/network/utils/wwan/files/data/19d2-0170
new file mode 100644
index 0000000..e7eb5aa
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0170
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE A371",
+ "control": 0,
+ "data": 1,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0199 b/package/network/utils/wwan/files/data/19d2-0199
new file mode 100644
index 0000000..565afcf
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0199
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF820S",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0257 b/package/network/utils/wwan/files/data/19d2-0257
new file mode 100644
index 0000000..6e94316
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0257
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF821",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0265 b/package/network/utils/wwan/files/data/19d2-0265
new file mode 100644
index 0000000..284c6ed
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0265
@@ -0,0 +1,4 @@
+{
+ "desc": "Onda MT8205/ZTE",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0284 b/package/network/utils/wwan/files/data/19d2-0284
new file mode 100644
index 0000000..4fc3bbb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0284
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF880",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-0326 b/package/network/utils/wwan/files/data/19d2-0326
new file mode 100644
index 0000000..c854f2a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-0326
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF821D",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1003 b/package/network/utils/wwan/files/data/19d2-1003
new file mode 100644
index 0000000..d91f388
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1003
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE K3805-Z",
+ "control": 1,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1008 b/package/network/utils/wwan/files/data/19d2-1008
new file mode 100644
index 0000000..d0b329c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1008
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE K3570-Z",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1010 b/package/network/utils/wwan/files/data/19d2-1010
new file mode 100644
index 0000000..fe294f0
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1010
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE K3571-Z",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1015 b/package/network/utils/wwan/files/data/19d2-1015
new file mode 100644
index 0000000..5d3e5a6
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1015
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE K3806-Z",
+ "control": 1,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1018 b/package/network/utils/wwan/files/data/19d2-1018
new file mode 100644
index 0000000..48add8f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1018
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE K5006-Z",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1172 b/package/network/utils/wwan/files/data/19d2-1172
new file mode 100644
index 0000000..7f6805b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1172
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE K4510-Z",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1173 b/package/network/utils/wwan/files/data/19d2-1173
new file mode 100644
index 0000000..7f6805b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1173
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE K4510-Z",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1176 b/package/network/utils/wwan/files/data/19d2-1176
new file mode 100644
index 0000000..4bbd5b7
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1176
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE K3770-Z",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1177 b/package/network/utils/wwan/files/data/19d2-1177
new file mode 100644
index 0000000..b5113e9
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1177
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE K3770-Z",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1181 b/package/network/utils/wwan/files/data/19d2-1181
new file mode 100644
index 0000000..bad2bd8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1181
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE K3772-Z",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1203 b/package/network/utils/wwan/files/data/19d2-1203
new file mode 100644
index 0000000..7155ac7
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1203
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF691",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1208 b/package/network/utils/wwan/files/data/19d2-1208
new file mode 100644
index 0000000..9884b7d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1208
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF192",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1211 b/package/network/utils/wwan/files/data/19d2-1211
new file mode 100644
index 0000000..807068f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1211
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF195",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1212 b/package/network/utils/wwan/files/data/19d2-1212
new file mode 100644
index 0000000..807068f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1212
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF195",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1217 b/package/network/utils/wwan/files/data/19d2-1217
new file mode 100644
index 0000000..9884b7d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1217
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF192",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1218 b/package/network/utils/wwan/files/data/19d2-1218
new file mode 100644
index 0000000..9884b7d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1218
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF192",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1220 b/package/network/utils/wwan/files/data/19d2-1220
new file mode 100644
index 0000000..9884b7d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1220
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF192",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1222 b/package/network/utils/wwan/files/data/19d2-1222
new file mode 100644
index 0000000..9884b7d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1222
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF192",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1245 b/package/network/utils/wwan/files/data/19d2-1245
new file mode 100644
index 0000000..c08014c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1245
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF190",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1252 b/package/network/utils/wwan/files/data/19d2-1252
new file mode 100644
index 0000000..768a433
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1252
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF669",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1254 b/package/network/utils/wwan/files/data/19d2-1254
new file mode 100644
index 0000000..c08014c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1254
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF190",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1256 b/package/network/utils/wwan/files/data/19d2-1256
new file mode 100644
index 0000000..c08014c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1256
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF190",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1270 b/package/network/utils/wwan/files/data/19d2-1270
new file mode 100644
index 0000000..7ad57f0
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1270
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF667",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1401 b/package/network/utils/wwan/files/data/19d2-1401
new file mode 100644
index 0000000..730b634
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1401
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF60",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1402 b/package/network/utils/wwan/files/data/19d2-1402
new file mode 100644
index 0000000..730b634
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1402
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF60",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1426 b/package/network/utils/wwan/files/data/19d2-1426
new file mode 100644
index 0000000..cb9337b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1426
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE MF91D",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1512 b/package/network/utils/wwan/files/data/19d2-1512
new file mode 100644
index 0000000..fa2c87d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1512
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MFxxx",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1515 b/package/network/utils/wwan/files/data/19d2-1515
new file mode 100644
index 0000000..9884b7d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1515
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF192",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1518 b/package/network/utils/wwan/files/data/19d2-1518
new file mode 100644
index 0000000..9884b7d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1518
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF192",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1519 b/package/network/utils/wwan/files/data/19d2-1519
new file mode 100644
index 0000000..9884b7d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1519
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF192",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1522 b/package/network/utils/wwan/files/data/19d2-1522
new file mode 100644
index 0000000..1e19b2c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1522
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF652",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1525 b/package/network/utils/wwan/files/data/19d2-1525
new file mode 100644
index 0000000..58e392c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1525
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF591",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1527 b/package/network/utils/wwan/files/data/19d2-1527
new file mode 100644
index 0000000..c622100
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1527
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF196",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1537 b/package/network/utils/wwan/files/data/19d2-1537
new file mode 100644
index 0000000..b58df70
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1537
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF190J",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1538 b/package/network/utils/wwan/files/data/19d2-1538
new file mode 100644
index 0000000..b58df70
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1538
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF190J",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-1544 b/package/network/utils/wwan/files/data/19d2-1544
new file mode 100644
index 0000000..b58df70
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-1544
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE MF190J",
+ "control": 0,
+ "data": 0,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-2002 b/package/network/utils/wwan/files/data/19d2-2002
new file mode 100644
index 0000000..a049f19
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-2002
@@ -0,0 +1,4 @@
+{
+ "desc": "ZTE K3765-Z",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/19d2-2003 b/package/network/utils/wwan/files/data/19d2-2003
new file mode 100644
index 0000000..ae1da49
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-2003
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MF180",
+ "control": 1,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/19d2-ffdd b/package/network/utils/wwan/files/data/19d2-ffdd
new file mode 100644
index 0000000..e122028
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-ffdd
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE AC682",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-ffe4 b/package/network/utils/wwan/files/data/19d2-ffe4
new file mode 100644
index 0000000..d561593
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-ffe4
@@ -0,0 +1,6 @@
+{
+ "desc": "ZTE AC3781",
+ "control": 1,
+ "data": 0,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/19d2-ffe9 b/package/network/utils/wwan/files/data/19d2-ffe9
new file mode 100644
index 0000000..3fe5f4b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-ffe9
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE AC2738",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-fff1 b/package/network/utils/wwan/files/data/19d2-fff1
new file mode 100644
index 0000000..adf579c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-fff1
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE generic",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-fffb b/package/network/utils/wwan/files/data/19d2-fffb
new file mode 100644
index 0000000..fb3d597
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-fffb
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MG880",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-fffc b/package/network/utils/wwan/files/data/19d2-fffc
new file mode 100644
index 0000000..fb3d597
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-fffc
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MG880",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-fffd b/package/network/utils/wwan/files/data/19d2-fffd
new file mode 100644
index 0000000..fb3d597
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-fffd
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE MG880",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-fffe b/package/network/utils/wwan/files/data/19d2-fffe
new file mode 100644
index 0000000..faf9832
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-fffe
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE AC8700",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/19d2-ffff b/package/network/utils/wwan/files/data/19d2-ffff
new file mode 100644
index 0000000..517dbb8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/19d2-ffff
@@ -0,0 +1,5 @@
+{
+ "desc": "ZTE AC8710",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1a8d-1002 b/package/network/utils/wwan/files/data/1a8d-1002
new file mode 100644
index 0000000..bf67e65
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1a8d-1002
@@ -0,0 +1,5 @@
+{
+ "desc": "Bandrich C-100/C-120",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1a8d-1003 b/package/network/utils/wwan/files/data/1a8d-1003
new file mode 100644
index 0000000..bf67e65
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1a8d-1003
@@ -0,0 +1,5 @@
+{
+ "desc": "Bandrich C-100/C-120",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1a8d-1007 b/package/network/utils/wwan/files/data/1a8d-1007
new file mode 100644
index 0000000..9e482b1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1a8d-1007
@@ -0,0 +1,5 @@
+{
+ "desc": "Bandrich C-270",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1a8d-1009 b/package/network/utils/wwan/files/data/1a8d-1009
new file mode 100644
index 0000000..b183834
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1a8d-1009
@@ -0,0 +1,5 @@
+{
+ "desc": "Bandrich C-170/C-180",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1a8d-100c b/package/network/utils/wwan/files/data/1a8d-100c
new file mode 100644
index 0000000..6f19f1f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1a8d-100c
@@ -0,0 +1,5 @@
+{
+ "desc": "Bandrich C-320",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1a8d-100d b/package/network/utils/wwan/files/data/1a8d-100d
new file mode 100644
index 0000000..e96c51a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1a8d-100d
@@ -0,0 +1,5 @@
+{
+ "desc": "Bandrich C-508",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1a8d-2006 b/package/network/utils/wwan/files/data/1a8d-2006
new file mode 100644
index 0000000..8164eed
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1a8d-2006
@@ -0,0 +1,6 @@
+{
+ "desc": "Bandrich C-33x",
+ "control": 0,
+ "data": 1,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/1bbb-0000 b/package/network/utils/wwan/files/data/1bbb-0000
new file mode 100644
index 0000000..5b445a3
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1bbb-0000
@@ -0,0 +1,5 @@
+{
+ "desc": "Alcatel X060S/X070S/X080S/X200",
+ "control": 2,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1bbb-0012 b/package/network/utils/wwan/files/data/1bbb-0012
new file mode 100644
index 0000000..9ba190f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1bbb-0012
@@ -0,0 +1,6 @@
+{
+ "desc": "Alcatel X085C",
+ "control": 2,
+ "data": 2,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/1bbb-0017 b/package/network/utils/wwan/files/data/1bbb-0017
new file mode 100644
index 0000000..ad488dd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1bbb-0017
@@ -0,0 +1,5 @@
+{
+ "desc": "Alcatel X220L",
+ "control": 4,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1bbb-0052 b/package/network/utils/wwan/files/data/1bbb-0052
new file mode 100644
index 0000000..ad488dd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1bbb-0052
@@ -0,0 +1,5 @@
+{
+ "desc": "Alcatel X220L",
+ "control": 4,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1bbb-00b7 b/package/network/utils/wwan/files/data/1bbb-00b7
new file mode 100644
index 0000000..0fbf6de
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1bbb-00b7
@@ -0,0 +1,5 @@
+{
+ "desc": "Alcatel X600",
+ "control": 0,
+ "data": 4
+}
diff --git a/package/network/utils/wwan/files/data/1bbb-00ca b/package/network/utils/wwan/files/data/1bbb-00ca
new file mode 100644
index 0000000..e40cc86
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1bbb-00ca
@@ -0,0 +1,6 @@
+{
+ "desc": "Alcatel X080C",
+ "control": 0,
+ "data": 0,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/1bbb-011e b/package/network/utils/wwan/files/data/1bbb-011e
new file mode 100644
index 0000000..160221d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1bbb-011e
@@ -0,0 +1,4 @@
+{
+ "desc": "Alcatel L100V,",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/1bbb-0203 b/package/network/utils/wwan/files/data/1bbb-0203
new file mode 100644
index 0000000..2632a63
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1bbb-0203
@@ -0,0 +1,4 @@
+{
+ "desc": "Alcatel L800Z,",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/1c9e-6060 b/package/network/utils/wwan/files/data/1c9e-6060
new file mode 100644
index 0000000..8786375
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1c9e-6060
@@ -0,0 +1,6 @@
+{
+ "desc": "Alcatel X020 & X030",
+ "control": 2,
+ "data": 0,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/1c9e-6061 b/package/network/utils/wwan/files/data/1c9e-6061
new file mode 100644
index 0000000..8786375
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1c9e-6061
@@ -0,0 +1,6 @@
+{
+ "desc": "Alcatel X020 & X030",
+ "control": 2,
+ "data": 0,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/1c9e-9000 b/package/network/utils/wwan/files/data/1c9e-9000
new file mode 100644
index 0000000..28566b3
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1c9e-9000
@@ -0,0 +1,6 @@
+{
+ "desc": "4G Systems XS Stick W14",
+ "control": 0,
+ "data": 0,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/1c9e-9603 b/package/network/utils/wwan/files/data/1c9e-9603
new file mode 100644
index 0000000..44f62eb
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1c9e-9603
@@ -0,0 +1,5 @@
+{
+ "desc": "4G Systems XS Stick W14",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1c9e-9605 b/package/network/utils/wwan/files/data/1c9e-9605
new file mode 100644
index 0000000..fafcefd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1c9e-9605
@@ -0,0 +1,5 @@
+{
+ "desc": "4G Systems XS Stick W14",
+ "control": 1,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/1c9e-9607 b/package/network/utils/wwan/files/data/1c9e-9607
new file mode 100644
index 0000000..fafcefd
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1c9e-9607
@@ -0,0 +1,5 @@
+{
+ "desc": "4G Systems XS Stick W14",
+ "control": 1,
+ "data": 3
+}
diff --git a/package/network/utils/wwan/files/data/1c9e-9801 b/package/network/utils/wwan/files/data/1c9e-9801
new file mode 100644
index 0000000..dced60d
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1c9e-9801
@@ -0,0 +1,6 @@
+{
+ "desc": "4G Systems XS Stick W21",
+ "control": 2,
+ "data": 1,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/1c9e-9900 b/package/network/utils/wwan/files/data/1c9e-9900
new file mode 100644
index 0000000..efbb056
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1c9e-9900
@@ -0,0 +1,6 @@
+{
+ "desc": "Softbank C02LC",
+ "control": 1,
+ "data": 2,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/1e0e-9000 b/package/network/utils/wwan/files/data/1e0e-9000
new file mode 100644
index 0000000..5b83213
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1e0e-9000
@@ -0,0 +1,5 @@
+{
+ "desc": "PROLink PHS100, Hyundai MB-810, A-Link 3GU",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1e0e-9100 b/package/network/utils/wwan/files/data/1e0e-9100
new file mode 100644
index 0000000..b89257f
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1e0e-9100
@@ -0,0 +1,5 @@
+{
+ "desc": "PROLink PHS300, A-Link 3GU",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1e0e-9200 b/package/network/utils/wwan/files/data/1e0e-9200
new file mode 100644
index 0000000..5b83213
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1e0e-9200
@@ -0,0 +1,5 @@
+{
+ "desc": "PROLink PHS100, Hyundai MB-810, A-Link 3GU",
+ "control": 1,
+ "data": 2
+}
diff --git a/package/network/utils/wwan/files/data/1e0e-ce16 b/package/network/utils/wwan/files/data/1e0e-ce16
new file mode 100644
index 0000000..d9088e9
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1e0e-ce16
@@ -0,0 +1,5 @@
+{
+ "desc": "D-Link DWM-162-U5, Micromax MMX 300c",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/1e0e-cefe b/package/network/utils/wwan/files/data/1e0e-cefe
new file mode 100644
index 0000000..78d6148
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1e0e-cefe
@@ -0,0 +1,6 @@
+{
+ "desc": "D-Link DWM-162-U5, Micromax MMX 300c",
+ "control": 1,
+ "data": 2,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/1e2d-0053 b/package/network/utils/wwan/files/data/1e2d-0053
new file mode 100644
index 0000000..e83f04c
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1e2d-0053
@@ -0,0 +1,6 @@
+{
+ "desc": "Cinterion PH8",
+ "control": 2,
+ "data": 3
+}
+
diff --git a/package/network/utils/wwan/files/data/1e2d-005b b/package/network/utils/wwan/files/data/1e2d-005b
new file mode 100644
index 0000000..6678ff0
--- /dev/null
+++ b/package/network/utils/wwan/files/data/1e2d-005b
@@ -0,0 +1,5 @@
+{
+ "desc": "Cinterion ELS61",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/2001-7d00 b/package/network/utils/wwan/files/data/2001-7d00
new file mode 100644
index 0000000..3b5a3a2
--- /dev/null
+++ b/package/network/utils/wwan/files/data/2001-7d00
@@ -0,0 +1,6 @@
+{
+ "desc": "D-Link DWM-156 A6",
+ "control": 1,
+ "data": 0,
+ "generic": 1
+}
diff --git a/package/network/utils/wwan/files/data/2001-7d01 b/package/network/utils/wwan/files/data/2001-7d01
new file mode 100644
index 0000000..9f039b1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/2001-7d01
@@ -0,0 +1,5 @@
+{
+ "desc": "D-Link DWM-156 A7",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/2001-7d02 b/package/network/utils/wwan/files/data/2001-7d02
new file mode 100644
index 0000000..9f039b1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/2001-7d02
@@ -0,0 +1,5 @@
+{
+ "desc": "D-Link DWM-156 A7",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/2001-7d03 b/package/network/utils/wwan/files/data/2001-7d03
new file mode 100644
index 0000000..9f039b1
--- /dev/null
+++ b/package/network/utils/wwan/files/data/2001-7d03
@@ -0,0 +1,5 @@
+{
+ "desc": "D-Link DWM-156 A7",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/211f-6801 b/package/network/utils/wwan/files/data/211f-6801
new file mode 100644
index 0000000..07f1148
--- /dev/null
+++ b/package/network/utils/wwan/files/data/211f-6801
@@ -0,0 +1,5 @@
+{
+ "desc": "Celot K-3000/CT-650/CT-680",
+ "control": 2,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/2357-0201 b/package/network/utils/wwan/files/data/2357-0201
new file mode 100644
index 0000000..7ad8690
--- /dev/null
+++ b/package/network/utils/wwan/files/data/2357-0201
@@ -0,0 +1,4 @@
+{
+ "desc": "TP-Link MA180",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/2357-0202 b/package/network/utils/wwan/files/data/2357-0202
new file mode 100644
index 0000000..7ad8690
--- /dev/null
+++ b/package/network/utils/wwan/files/data/2357-0202
@@ -0,0 +1,4 @@
+{
+ "desc": "TP-Link MA180",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/2357-0203 b/package/network/utils/wwan/files/data/2357-0203
new file mode 100644
index 0000000..7ad8690
--- /dev/null
+++ b/package/network/utils/wwan/files/data/2357-0203
@@ -0,0 +1,4 @@
+{
+ "desc": "TP-Link MA180",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/2357-9000 b/package/network/utils/wwan/files/data/2357-9000
new file mode 100644
index 0000000..0ddb804
--- /dev/null
+++ b/package/network/utils/wwan/files/data/2357-9000
@@ -0,0 +1,4 @@
+{
+ "desc": "TP-Link MA260",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/2c7c-0125 b/package/network/utils/wwan/files/data/2c7c-0125
new file mode 100644
index 0000000..f58afa2
--- /dev/null
+++ b/package/network/utils/wwan/files/data/2c7c-0125
@@ -0,0 +1,4 @@
+{
+ "desc": "Quectel EC25",
+ "type": "qmi",
+}
diff --git a/package/network/utils/wwan/files/data/413c-8114 b/package/network/utils/wwan/files/data/413c-8114
new file mode 100644
index 0000000..c0b7678
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8114
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5700",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8115 b/package/network/utils/wwan/files/data/413c-8115
new file mode 100644
index 0000000..3f99a0b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8115
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5500",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8116 b/package/network/utils/wwan/files/data/413c-8116
new file mode 100644
index 0000000..ff18d6a
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8116
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5505",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8117 b/package/network/utils/wwan/files/data/413c-8117
new file mode 100644
index 0000000..c0b7678
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8117
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5700",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8118 b/package/network/utils/wwan/files/data/413c-8118
new file mode 100644
index 0000000..0404557
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8118
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5510",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8128 b/package/network/utils/wwan/files/data/413c-8128
new file mode 100644
index 0000000..c0b7678
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8128
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5700",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8129 b/package/network/utils/wwan/files/data/413c-8129
new file mode 100644
index 0000000..c0b7678
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8129
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5700",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8133 b/package/network/utils/wwan/files/data/413c-8133
new file mode 100644
index 0000000..7940b33
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8133
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5720",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8134 b/package/network/utils/wwan/files/data/413c-8134
new file mode 100644
index 0000000..7940b33
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8134
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5720",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8135 b/package/network/utils/wwan/files/data/413c-8135
new file mode 100644
index 0000000..7940b33
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8135
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5720",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8136 b/package/network/utils/wwan/files/data/413c-8136
new file mode 100644
index 0000000..fffa1e8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8136
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5520",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8137 b/package/network/utils/wwan/files/data/413c-8137
new file mode 100644
index 0000000..fffa1e8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8137
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5520",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8138 b/package/network/utils/wwan/files/data/413c-8138
new file mode 100644
index 0000000..fffa1e8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8138
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5520",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8147 b/package/network/utils/wwan/files/data/413c-8147
new file mode 100644
index 0000000..e9aff09
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8147
@@ -0,0 +1,6 @@
+{
+ "desc": "Dell 5530",
+ "control": 0,
+ "data": 1,
+ "acm": 1
+}
diff --git a/package/network/utils/wwan/files/data/413c-8180 b/package/network/utils/wwan/files/data/413c-8180
new file mode 100644
index 0000000..d3ac0d8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8180
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5730",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8181 b/package/network/utils/wwan/files/data/413c-8181
new file mode 100644
index 0000000..d3ac0d8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8181
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5730",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8182 b/package/network/utils/wwan/files/data/413c-8182
new file mode 100644
index 0000000..d3ac0d8
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8182
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5730",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/data/413c-8186 b/package/network/utils/wwan/files/data/413c-8186
new file mode 100644
index 0000000..fa24099
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8186
@@ -0,0 +1,4 @@
+{
+ "desc": "Dell 5620",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/413c-8194 b/package/network/utils/wwan/files/data/413c-8194
new file mode 100644
index 0000000..b361f54
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8194
@@ -0,0 +1,4 @@
+{
+ "desc": "Dell 5630",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/413c-8195 b/package/network/utils/wwan/files/data/413c-8195
new file mode 100644
index 0000000..45b7876
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8195
@@ -0,0 +1,4 @@
+{
+ "desc": "Dell 5800",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/413c-8196 b/package/network/utils/wwan/files/data/413c-8196
new file mode 100644
index 0000000..cd24730
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-8196
@@ -0,0 +1,4 @@
+{
+ "desc": "Dell 5800v2",
+ "type": "qmi"
+}
diff --git a/package/network/utils/wwan/files/data/413c-819b b/package/network/utils/wwan/files/data/413c-819b
new file mode 100644
index 0000000..575410b
--- /dev/null
+++ b/package/network/utils/wwan/files/data/413c-819b
@@ -0,0 +1,5 @@
+{
+ "desc": "Dell 5804",
+ "control": 1,
+ "data": 0
+}
diff --git a/package/network/utils/wwan/files/wwan.sh b/package/network/utils/wwan/files/wwan.sh
new file mode 100755
index 0000000..9907195
--- /dev/null
+++ b/package/network/utils/wwan/files/wwan.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. ../netifd-proto.sh
+init_proto "$@"
+
+INCLUDE_ONLY=1
+
+ctl_device=""
+dat_device=""
+
+proto_mbim_setup() { echo "wwan[$$] mbim proto is missing"; }
+proto_qmi_setup() { echo "wwan[$$] qmi proto is missing"; }
+proto_ncm_setup() { echo "wwan[$$] ncm proto is missing"; }
+proto_3g_setup() { echo "wwan[$$] 3g proto is missing"; }
+proto_directip_setup() { echo "wwan[$$] directip proto is missing"; }
+
+[ -f ./mbim.sh ] && . ./mbim.sh
+[ -f ./ncm.sh ] && . ./ncm.sh
+[ -f ./qmi.sh ] && . ./qmi.sh
+[ -f ./3g.sh ] && { . ./ppp.sh; . ./3g.sh; }
+[ -f ./directip.sh ] && . ./directip.sh
+
+proto_wwan_init_config() {
+ available=1
+ no_device=1
+
+ proto_config_add_string apn
+ proto_config_add_string auth
+ proto_config_add_string username
+ proto_config_add_string password
+ proto_config_add_string pincode
+ proto_config_add_string delay
+ proto_config_add_string modes
+ proto_config_add_string bus
+}
+
+proto_wwan_setup() {
+ local driver usb devicename desc bus
+
+ json_get_vars bus
+
+ if [ -L "/sys/bus/usb/devices/${bus}" ]; then
+ if [ -f "/sys/bus/usb/devices/${bus}/idVendor" ] \
+ && [ -f "/sys/bus/usb/devices/${bus}/idProduct" ]; then
+ local vendor product
+ vendor=$(cat /sys/bus/usb/devices/${bus}/idVendor)
+ product=$(cat /sys/bus/usb/devices/${bus}/idProduct)
+ [ -f /lib/network/wwan/$vendor:$product ] && {
+ usb=/lib/network/wwan/$vendor:$product
+ devicename=$bus
+ }
+ else
+ echo "wwan[$$]" "Specified usb bus ${bus} was not found"
+ proto_notify_error "$interface" NO_USB
+ proto_block_restart "$interface"
+ return 1
+ fi
+ else
+ echo "wwan[$$]" "Searching for a valid wwan usb device..."
+ for a in $(ls /sys/bus/usb/devices); do
+ local vendor product
+ [ -z "$usb" -a -f /sys/bus/usb/devices/$a/idVendor -a -f /sys/bus/usb/devices/$a/idProduct ] || continue
+ vendor=$(cat /sys/bus/usb/devices/$a/idVendor)
+ product=$(cat /sys/bus/usb/devices/$a/idProduct)
+ [ -f /lib/network/wwan/$vendor:$product ] && {
+ usb=/lib/network/wwan/$vendor:$product
+ devicename=$a
+ }
+ done
+ fi
+
+ echo "wwan[$$]" "Using wwan usb device on bus $devicename"
+
+ [ -n "$usb" ] && {
+ local old_cb control data
+
+ json_set_namespace wwan old_cb
+ json_init
+ json_load "$(cat "$usb")"
+ json_select
+ json_get_vars desc control data
+ json_set_namespace "$old_cb"
+
+ [ -n "$control" -a -n "$data" ] && {
+ ttys=$(ls -d /sys/bus/usb/devices/$devicename/${devicename}*/tty?* /sys/bus/usb/devices/$devicename/${devicename}*/tty/tty?* | sed "s/.*\///g" | tr "\n" " ")
+ ctl_device=/dev/$(echo $ttys | cut -d" " -f $((control + 1)))
+ dat_device=/dev/$(echo $ttys | cut -d" " -f $((data + 1)))
+ driver=comgt
+ }
+ }
+
+ [ -z "$ctl_device" ] && for net in $(ls /sys/class/net/ | grep -e wwan -e usb); do
+ [ -z "$ctl_device" ] || continue
+ [ -n "$bus" ] && {
+ [ $(readlink /sys/class/net/$net | grep $bus) ] || continue
+ }
+ driver=$(grep DRIVER /sys/class/net/$net/device/uevent | cut -d= -f2)
+ case "$driver" in
+ qmi_wwan|cdc_mbim)
+ ctl_device=/dev/$(ls /sys/class/net/$net/device/usbmisc)
+ ;;
+ sierra_net|cdc_ether|*cdc_ncm)
+ ctl_device=/dev/$(cd /sys/class/net/$net/; find ../../../ -name ttyUSB* |xargs -n1 basename | head -n1)
+ ;;
+ *) continue;;
+ esac
+ echo "wwan[$$]" "Using proto:$proto device:$ctl_device iface:$net desc:$desc"
+ done
+
+ [ -n "$ctl_device" ] || {
+ echo "wwan[$$]" "No valid device was found"
+ proto_notify_error "$interface" NO_DEVICE
+ proto_block_restart "$interface"
+ return 1
+ }
+
+ uci_set_state network "$interface" driver "$driver"
+ uci_set_state network "$interface" ctl_device "$ctl_device"
+ uci_set_state network "$interface" dat_device "$dat_device"
+
+ case $driver in
+ qmi_wwan) proto_qmi_setup $@ ;;
+ cdc_mbim) proto_mbim_setup $@ ;;
+ sierra_net) proto_directip_setup $@ ;;
+ comgt) proto_3g_setup $@ ;;
+ cdc_ether|*cdc_ncm) proto_ncm_setup $@ ;;
+ esac
+}
+
+proto_wwan_teardown() {
+ local interface=$1
+ local driver=$(uci_get_state network "$interface" driver)
+ ctl_device=$(uci_get_state network "$interface" ctl_device)
+ dat_device=$(uci_get_state network "$interface" dat_device)
+
+ case $driver in
+ qmi_wwan) proto_qmi_teardown $@ ;;
+ cdc_mbim) proto_mbim_teardown $@ ;;
+ sierra_net) proto_directip_teardown $@ ;;
+ comgt) proto_3g_teardown $@ ;;
+ cdc_ether|*cdc_ncm) proto_ncm_teardown $@ ;;
+ esac
+}
+
+add_protocol wwan
diff --git a/package/network/utils/wwan/files/wwan.usb b/package/network/utils/wwan/files/wwan.usb
new file mode 100644
index 0000000..b757c1c
--- /dev/null
+++ b/package/network/utils/wwan/files/wwan.usb
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+[ "$ACTION" = add -a "$DEVTYPE" = usb_device ] || exit 0
+
+. /lib/functions.sh
+. /lib/netifd/netifd-proto.sh
+
+vid=$(cat /sys$DEVPATH/idVendor)
+pid=$(cat /sys$DEVPATH/idProduct)
+[ -f "/lib/network/wwan/$vid:$pid" ] || exit 0
+
+find_wwan_iface() {
+ local cfg="$1"
+ local proto
+ config_get proto "$cfg" proto
+ [ "$proto" = wwan ] || return 0
+ proto_set_available "$cfg" 1
+ ifup $cfg
+ exit 0
+}
+
+config_load network
+config_foreach find_wwan_iface interface
diff --git a/package/network/utils/wwan/files/wwan.usbmisc b/package/network/utils/wwan/files/wwan.usbmisc
new file mode 100644
index 0000000..a86ff5d
--- /dev/null
+++ b/package/network/utils/wwan/files/wwan.usbmisc
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+[ "$ACTION" = add ] || [ "$ACTION" = remove ] || exit 0
+[ "${DEVNAME/[0-9]/}" = cdc-wdm ] || exit 0
+
+. /lib/functions.sh
+. /lib/netifd/netifd-proto.sh
+
+find_wwan_iface() {
+ local cfg="$1"
+
+ local proto device
+ config_get proto "$cfg" proto
+ config_get device "$cfg" device
+
+ [ "$proto" = wwan ] || [ "$proto" = mbim ] || [ "$proto" = qmi ] || [ "$proto" = ncm ] || return 0
+ [ -z "$device" -a "$proto" = wwan ] || [ "$device" = "/dev/$DEVNAME" ] || return 0
+ if [ "$ACTION" = add ]; then
+ proto_set_available "$cfg" 1
+ fi
+ if [ "$ACTION" = remove ]; then
+ proto_set_available "$cfg" 0
+ fi
+ exit 0
+}
+
+config_load network
+config_foreach find_wwan_iface interface