aboutsummaryrefslogtreecommitdiffstats
path: root/package/network
diff options
context:
space:
mode:
Diffstat (limited to 'package/network')
-rw-r--r--package/network/config/firewall/Makefile59
-rw-r--r--package/network/config/firewall/files/firewall.config194
-rw-r--r--package/network/config/firewall/files/firewall.hotplug11
-rwxr-xr-xpackage/network/config/firewall/files/firewall.init61
-rw-r--r--package/network/config/firewall/files/firewall.user7
-rw-r--r--package/network/config/gre/Makefile65
-rwxr-xr-xpackage/network/config/gre/files/gre.sh237
-rw-r--r--package/network/config/ipip/Makefile40
-rwxr-xr-xpackage/network/config/ipip/files/ipip.sh80
-rw-r--r--package/network/config/ltq-adsl-app/Makefile84
-rw-r--r--package/network/config/ltq-adsl-app/files/dsl_control59
-rw-r--r--package/network/config/ltq-adsl-app/patches/010-eglibc_compile_fix.patch23
-rw-r--r--package/network/config/ltq-vdsl-app/Makefile78
-rw-r--r--package/network/config/ltq-vdsl-app/files/dsl_control91
-rw-r--r--package/network/config/ltq-vdsl-app/patches/100-compat.patch22
-rw-r--r--package/network/config/ltq-vdsl-app/patches/101-musl.patch10
-rw-r--r--package/network/config/netifd/Makefile46
-rw-r--r--package/network/config/netifd/files/etc/hotplug.d/iface/00-netstate7
-rwxr-xr-xpackage/network/config/netifd/files/etc/init.d/network151
-rwxr-xr-xpackage/network/config/netifd/files/lib/netifd/dhcp.script102
-rwxr-xr-xpackage/network/config/netifd/files/lib/netifd/proto/dhcp.sh74
-rwxr-xr-xpackage/network/config/netifd/files/lib/network/config.sh79
-rwxr-xr-xpackage/network/config/netifd/files/sbin/devstatus12
l---------package/network/config/netifd/files/sbin/ifdown1
-rwxr-xr-xpackage/network/config/netifd/files/sbin/ifstatus13
-rwxr-xr-xpackage/network/config/netifd/files/sbin/ifup79
-rwxr-xr-xpackage/network/config/netifd/files/usr/share/udhcpc/default.script57
-rw-r--r--package/network/config/qos-scripts/Makefile52
-rw-r--r--package/network/config/qos-scripts/files/etc/config/qos68
-rwxr-xr-xpackage/network/config/qos-scripts/files/etc/hotplug.d/iface/10-qos2
-rwxr-xr-xpackage/network/config/qos-scripts/files/etc/init.d/qos28
-rwxr-xr-xpackage/network/config/qos-scripts/files/usr/bin/qos-start4
-rwxr-xr-xpackage/network/config/qos-scripts/files/usr/bin/qos-stat67
-rwxr-xr-xpackage/network/config/qos-scripts/files/usr/bin/qos-stop6
-rwxr-xr-xpackage/network/config/qos-scripts/files/usr/lib/qos/generate.sh499
-rw-r--r--package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk106
-rw-r--r--package/network/config/soloscli/Makefile45
-rw-r--r--package/network/config/soloscli/files/etc/hotplug.d/atm/15-solos-init26
-rw-r--r--package/network/config/soloscli/files/etc/uci-default/solos15
-rw-r--r--package/network/config/soloscli/files/solos-log-stats19
-rw-r--r--package/network/config/soloscli/patches/001-no-driver.patch11
-rw-r--r--package/network/config/soloscli/patches/002-cflags.patch12
-rw-r--r--package/network/config/swconfig/Makefile60
-rw-r--r--package/network/config/swconfig/files/switch.sh15
-rw-r--r--package/network/config/swconfig/src/Makefile15
-rw-r--r--package/network/config/swconfig/src/cli.c354
-rw-r--r--package/network/config/swconfig/src/swlib.c801
-rw-r--r--package/network/config/swconfig/src/swlib.h252
-rw-r--r--package/network/config/swconfig/src/uci.c246
-rw-r--r--package/network/ipv6/6in4/Makefile43
-rwxr-xr-xpackage/network/ipv6/6in4/files/6in4.sh156
-rw-r--r--package/network/ipv6/6rd/Makefile54
-rw-r--r--package/network/ipv6/6rd/files/6rd.sh102
-rw-r--r--package/network/ipv6/6rd/src/6rdcalc.c126
-rw-r--r--package/network/ipv6/6rd/src/Makefile7
-rw-r--r--package/network/ipv6/6to4/Makefile43
-rwxr-xr-xpackage/network/ipv6/6to4/files/6to4.sh98
-rw-r--r--package/network/ipv6/ds-lite/Makefile43
-rwxr-xr-xpackage/network/ipv6/ds-lite/files/dslite.sh102
-rw-r--r--package/network/ipv6/map/Makefile45
-rwxr-xr-xpackage/network/ipv6/map/files/map.sh221
-rw-r--r--package/network/ipv6/map/src/CMakeLists.txt26
-rw-r--r--package/network/ipv6/map/src/mapcalc.c412
-rw-r--r--package/network/ipv6/odhcp6c/Makefile51
-rwxr-xr-xpackage/network/ipv6/odhcp6c/files/dhcpv6.script219
-rwxr-xr-xpackage/network/ipv6/odhcp6c/files/dhcpv6.sh103
-rw-r--r--package/network/ipv6/thc-ipv6/Makefile61
-rw-r--r--package/network/ipv6/thc-ipv6/patches/100-no-ssl.patch9
-rw-r--r--package/network/services/authsae/Makefile47
-rw-r--r--package/network/services/authsae/files/lib/wifi/authsae.sh57
-rw-r--r--package/network/services/authsae/patches/100-musl_fix.patch20
-rw-r--r--package/network/services/dnsmasq/Makefile152
-rw-r--r--package/network/services/dnsmasq/files/dhcp.conf32
-rw-r--r--package/network/services/dnsmasq/files/dnsmasq.conf37
-rw-r--r--package/network/services/dnsmasq/files/dnsmasq.hotplug5
-rw-r--r--package/network/services/dnsmasq/files/dnsmasq.init641
-rw-r--r--package/network/services/dnsmasq/patches/100-fix-dhcp-no-address-warning.patch47
-rw-r--r--package/network/services/dnsmasq/patches/110-ipset-remove-old-kernel-support.patch110
-rw-r--r--package/network/services/dnsmasq/patches/210-dnssec-improve-timestamp-heuristic.patch47
-rw-r--r--package/network/services/dropbear/Config.in27
-rw-r--r--package/network/services/dropbear/Makefile128
-rw-r--r--package/network/services/dropbear/files/dropbear.config5
-rwxr-xr-xpackage/network/services/dropbear/files/dropbear.init178
-rw-r--r--package/network/services/dropbear/patches/100-pubkey_path.patch91
-rw-r--r--package/network/services/dropbear/patches/110-change_user.patch18
-rw-r--r--package/network/services/dropbear/patches/120-openwrt_options.patch81
-rw-r--r--package/network/services/dropbear/patches/130-ssh_ignore_o_and_x_args.patch21
-rw-r--r--package/network/services/dropbear/patches/140-disable_assert.patch15
-rw-r--r--package/network/services/dropbear/patches/150-dbconvert_standalone.patch14
-rw-r--r--package/network/services/dropbear/patches/500-set-default-path.patch11
-rw-r--r--package/network/services/dropbear/patches/600-allow-blank-root-password.patch11
-rw-r--r--package/network/services/dropbear/patches/610-skip-default-keys-in-custom-runs.patch18
-rw-r--r--package/network/services/ead/Makefile57
-rw-r--r--package/network/services/ead/src/Makefile33
-rw-r--r--package/network/services/ead/src/aes.c1061
-rw-r--r--package/network/services/ead/src/ead-client.c433
-rw-r--r--package/network/services/ead/src/ead-crypt.c179
-rw-r--r--package/network/services/ead/src/ead-crypt.h21
-rw-r--r--package/network/services/ead/src/ead-pcap.h71
-rw-r--r--package/network/services/ead/src/ead.c976
-rw-r--r--package/network/services/ead/src/ead.h139
-rw-r--r--package/network/services/ead/src/filter.c25
-rw-r--r--package/network/services/ead/src/libbridge.h60
-rw-r--r--package/network/services/ead/src/libbridge_init.c127
-rw-r--r--package/network/services/ead/src/libbridge_private.h35
-rw-r--r--package/network/services/ead/src/list.h602
-rw-r--r--package/network/services/ead/src/passwd3
-rw-r--r--package/network/services/ead/src/pfc.c54
-rw-r--r--package/network/services/ead/src/pw_encrypt_md5.c646
-rw-r--r--package/network/services/ead/src/sha1.c104
-rw-r--r--package/network/services/ead/src/tinysrp/Makefile.am28
-rw-r--r--package/network/services/ead/src/tinysrp/Makefile.in477
-rw-r--r--package/network/services/ead/src/tinysrp/Notes110
-rw-r--r--package/network/services/ead/src/tinysrp/acconfig.h9
-rw-r--r--package/network/services/ead/src/tinysrp/acinclude.m427
-rw-r--r--package/network/services/ead/src/tinysrp/aclocal.m4157
-rw-r--r--package/network/services/ead/src/tinysrp/bn.h471
-rw-r--r--package/network/services/ead/src/tinysrp/bn_add.c305
-rw-r--r--package/network/services/ead/src/tinysrp/bn_asm.c382
-rw-r--r--package/network/services/ead/src/tinysrp/bn_ctx.c142
-rw-r--r--package/network/services/ead/src/tinysrp/bn_div.c378
-rw-r--r--package/network/services/ead/src/tinysrp/bn_exp.c395
-rw-r--r--package/network/services/ead/src/tinysrp/bn_lcl.h419
-rw-r--r--package/network/services/ead/src/tinysrp/bn_lib.c576
-rw-r--r--package/network/services/ead/src/tinysrp/bn_mul.c172
-rw-r--r--package/network/services/ead/src/tinysrp/bn_prime.h325
-rw-r--r--package/network/services/ead/src/tinysrp/bn_shift.c139
-rw-r--r--package/network/services/ead/src/tinysrp/bn_sqr.c160
-rw-r--r--package/network/services/ead/src/tinysrp/bn_word.c130
-rw-r--r--package/network/services/ead/src/tinysrp/clitest.c110
-rw-r--r--package/network/services/ead/src/tinysrp/config.h.in79
-rwxr-xr-xpackage/network/services/ead/src/tinysrp/configure2421
-rw-r--r--package/network/services/ead/src/tinysrp/configure.in52
-rwxr-xr-xpackage/network/services/ead/src/tinysrp/install-sh250
-rwxr-xr-xpackage/network/services/ead/src/tinysrp/missing134
-rwxr-xr-xpackage/network/services/ead/src/tinysrp/mkinstalldirs39
-rw-r--r--package/network/services/ead/src/tinysrp/srvtest.c111
-rw-r--r--package/network/services/ead/src/tinysrp/stamp-h.in1
-rw-r--r--package/network/services/ead/src/tinysrp/t_client.c285
-rw-r--r--package/network/services/ead/src/tinysrp/t_client.h148
-rw-r--r--package/network/services/ead/src/tinysrp/t_conf.c1080
-rw-r--r--package/network/services/ead/src/tinysrp/t_conv.c226
-rw-r--r--package/network/services/ead/src/tinysrp/t_defines.h169
-rw-r--r--package/network/services/ead/src/tinysrp/t_getconf.c118
-rw-r--r--package/network/services/ead/src/tinysrp/t_getpass.c191
-rw-r--r--package/network/services/ead/src/tinysrp/t_math.c177
-rw-r--r--package/network/services/ead/src/tinysrp/t_misc.c338
-rw-r--r--package/network/services/ead/src/tinysrp/t_pw.c262
-rw-r--r--package/network/services/ead/src/tinysrp/t_pwd.h310
-rw-r--r--package/network/services/ead/src/tinysrp/t_read.c81
-rw-r--r--package/network/services/ead/src/tinysrp/t_read.h55
-rw-r--r--package/network/services/ead/src/tinysrp/t_server.c259
-rw-r--r--package/network/services/ead/src/tinysrp/t_server.h138
-rw-r--r--package/network/services/ead/src/tinysrp/t_sha.c166
-rw-r--r--package/network/services/ead/src/tinysrp/t_sha.h26
-rw-r--r--package/network/services/ead/src/tinysrp/t_truerand.c151
-rw-r--r--package/network/services/ead/src/tinysrp/tconf.c157
-rw-r--r--package/network/services/ead/src/tinysrp/tinysrp.c235
-rw-r--r--package/network/services/ead/src/tinysrp/tinysrp.h18
-rw-r--r--package/network/services/ead/src/tinysrp/tpasswd2
-rw-r--r--package/network/services/ead/src/tinysrp/tphrase.c354
-rw-r--r--package/network/services/hostapd/Config.in52
-rw-r--r--package/network/services/hostapd/Makefile446
-rw-r--r--package/network/services/hostapd/files/hostapd-full.config166
-rw-r--r--package/network/services/hostapd/files/hostapd-mini.config159
-rw-r--r--package/network/services/hostapd/files/hostapd.sh394
-rw-r--r--package/network/services/hostapd/files/multicall.c28
-rw-r--r--package/network/services/hostapd/files/netifd.sh715
-rw-r--r--package/network/services/hostapd/files/wpa_supplicant-full.config403
-rw-r--r--package/network/services/hostapd/files/wpa_supplicant-mesh.config407
-rw-r--r--package/network/services/hostapd/files/wpa_supplicant-mini.config401
-rw-r--r--package/network/services/hostapd/files/wpa_supplicant-p2p.config406
-rw-r--r--package/network/services/hostapd/files/wpa_supplicant.sh194
-rw-r--r--package/network/services/hostapd/files/wps-hotplug.sh11
-rw-r--r--package/network/services/hostapd/patches/001-P2P-Validate-SSID-element-length-before-copying-it-C.patch37
-rw-r--r--package/network/services/hostapd/patches/002-AP-WMM-Fix-integer-underflow-in-WMM-Action-frame-par.patch36
-rw-r--r--package/network/services/hostapd/patches/110-bool_fix.patch14
-rw-r--r--package/network/services/hostapd/patches/120-daemonize_fix.patch97
-rw-r--r--package/network/services/hostapd/patches/130-no_eapol_fix.patch14
-rw-r--r--package/network/services/hostapd/patches/140-disable_bridge_packet_workaround.patch12
-rw-r--r--package/network/services/hostapd/patches/200-multicall.patch276
-rw-r--r--package/network/services/hostapd/patches/300-noscan.patch57
-rw-r--r--package/network/services/hostapd/patches/310-rescan_immediately.patch11
-rw-r--r--package/network/services/hostapd/patches/320-optional_rfkill.patch61
-rw-r--r--package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch11
-rw-r--r--package/network/services/hostapd/patches/340-reload_freq_change.patch44
-rw-r--r--package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch72
-rw-r--r--package/network/services/hostapd/patches/360-ctrl_iface_reload.patch104
-rw-r--r--package/network/services/hostapd/patches/370-ap_sta_support.patch237
-rw-r--r--package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch178
-rw-r--r--package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch56
-rw-r--r--package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch25
-rw-r--r--package/network/services/hostapd/patches/410-limit_debug_messages.patch214
-rw-r--r--package/network/services/hostapd/patches/420-indicate-features.patch82
-rw-r--r--package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch50
-rw-r--r--package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch13
-rw-r--r--package/network/services/hostapd/patches/440-max_num_sta_probe.patch13
-rw-r--r--package/network/services/hostapd/patches/450-scan_wait.patch66
-rw-r--r--package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch188
-rw-r--r--package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch59
-rw-r--r--package/network/services/hostapd/patches/462-wpa_s-support-htmode-param.patch156
-rw-r--r--package/network/services/hostapd/patches/470-wait-for-nullfunc-longer.patch11
-rw-r--r--package/network/services/hostapd/patches/600-ubus_support.patch858
-rw-r--r--package/network/services/igmpproxy/Makefile59
-rw-r--r--package/network/services/igmpproxy/files/igmpproxy.config11
-rw-r--r--package/network/services/igmpproxy/files/igmpproxy.init146
-rw-r--r--package/network/services/igmpproxy/patches/001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch79
-rw-r--r--package/network/services/igmpproxy/patches/002-Change-default-interface-state-to-disabled-wrt-29458.patch43
-rw-r--r--package/network/services/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch164
-rw-r--r--package/network/services/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch62
-rw-r--r--package/network/services/igmpproxy/patches/010-missing_include.patch10
-rw-r--r--package/network/services/igmpproxy/patches/020-Silence-downstream-interface-igmp-messages.patch19
-rw-r--r--package/network/services/igmpproxy/patches/100-use-monotic-clock-instead-of-time-of-day.patch120
-rw-r--r--package/network/services/igmpproxy/patches/200-allow_wildcard_addr.patch24
-rw-r--r--package/network/services/igmpproxy/patches/250-fix_multiple_downlink_interfaces.patch154
-rw-r--r--package/network/services/ipset-dns/Makefile60
-rw-r--r--package/network/services/ipset-dns/files/ipset-dns.config16
-rwxr-xr-xpackage/network/services/ipset-dns/files/ipset-dns.init57
-rw-r--r--package/network/services/ipset-dns/patches/100-simultaneous-ipv4-ipv6.patch57
-rw-r--r--package/network/services/lldpd/Config.in54
-rw-r--r--package/network/services/lldpd/Makefile108
-rw-r--r--package/network/services/lldpd/files/lldpd.config15
-rw-r--r--package/network/services/lldpd/files/lldpd.init93
-rw-r--r--package/network/services/lldpd/patches/100-os-release.patch39
-rw-r--r--package/network/services/mdns/Makefile48
-rw-r--r--package/network/services/mdns/files/mdns.config3
-rw-r--r--package/network/services/mdns/files/mdns.init54
-rw-r--r--package/network/services/mdns/files/mdns.json32
-rw-r--r--package/network/services/odhcpd/Makefile67
-rwxr-xr-xpackage/network/services/odhcpd/files/odhcpd-update5
-rw-r--r--package/network/services/odhcpd/files/odhcpd.defaults13
-rw-r--r--package/network/services/odhcpd/files/odhcpd.init18
-rw-r--r--package/network/services/omcproxy/Makefile43
-rw-r--r--package/network/services/omcproxy/files/omcproxy.config9
-rw-r--r--package/network/services/omcproxy/files/omcproxy.init143
-rw-r--r--package/network/services/openvpn-easy-rsa/Makefile59
-rw-r--r--package/network/services/openvpn-easy-rsa/files/easy-rsa.index0
-rw-r--r--package/network/services/openvpn-easy-rsa/files/easy-rsa.serial1
-rw-r--r--package/network/services/openvpn-easy-rsa/patches/100-run-ootb.patch152
-rw-r--r--package/network/services/openvpn/Config-nossl.in54
-rw-r--r--package/network/services/openvpn/Config-openssl.in66
-rw-r--r--package/network/services/openvpn/Config-polarssl.in66
-rw-r--r--package/network/services/openvpn/Makefile125
-rw-r--r--package/network/services/openvpn/files/openvpn.config400
-rw-r--r--package/network/services/openvpn/files/openvpn.init154
-rw-r--r--package/network/services/openvpn/files/openvpn.upgrade1
-rw-r--r--package/network/services/openvpn/patches/001-reproducible-remove_DATE.patch10
-rw-r--r--package/network/services/openvpn/patches/100-polarssl_compat.h257
-rw-r--r--package/network/services/openvpn/patches/120-polarssl-disable-record-splitting.patch14
-rw-r--r--package/network/services/openvpn/patches/130-polarssl-disable-runtime-version-check.patch11
-rw-r--r--package/network/services/ppp/Makefile265
-rw-r--r--package/network/services/ppp/files/etc/ppp/chap-secrets1
-rw-r--r--package/network/services/ppp/files/etc/ppp/filter23
-rw-r--r--package/network/services/ppp/files/etc/ppp/options10
-rw-r--r--package/network/services/ppp/files/etc/ppp/options.pptp7
-rw-r--r--package/network/services/ppp/files/etc/ppp/radius.conf8
-rw-r--r--package/network/services/ppp/files/etc/ppp/radius/dictionary253
-rw-r--r--package/network/services/ppp/files/etc/ppp/radius/dictionary.asnet3
-rw-r--r--package/network/services/ppp/files/etc/ppp/radius/dictionary.microsoft80
-rw-r--r--package/network/services/ppp/files/etc/ppp/radius/servers2
-rwxr-xr-xpackage/network/services/ppp/files/lib/netifd/ppp-down13
-rwxr-xr-xpackage/network/services/ppp/files/lib/netifd/ppp-up31
-rwxr-xr-xpackage/network/services/ppp/files/ppp.sh314
-rw-r--r--package/network/services/ppp/patches/001-honor-ldflags.patch39
-rw-r--r--package/network/services/ppp/patches/010-use_target_for_configure.patch24
-rw-r--r--package/network/services/ppp/patches/100-debian_ip-ip_option.patch96
-rw-r--r--package/network/services/ppp/patches/101-debian_close_dev_ppp.patch28
-rw-r--r--package/network/services/ppp/patches/103-debian_fix_link_pidfile.patch23
-rw-r--r--package/network/services/ppp/patches/105-debian_demand.patch172
-rw-r--r--package/network/services/ppp/patches/106-debian_stripMSdomain.patch47
-rw-r--r--package/network/services/ppp/patches/107-debian_pppoatm_wildcard.patch25
-rw-r--r--package/network/services/ppp/patches/110-debian_defaultroute.patch313
-rw-r--r--package/network/services/ppp/patches/120-debian_ipv6_updown_option.patch95
-rw-r--r--package/network/services/ppp/patches/121-debian_adaptive_lcp_echo.patch56
-rw-r--r--package/network/services/ppp/patches/130-no_cdefs_h.patch11
-rw-r--r--package/network/services/ppp/patches/131-missing_prototype_macro.patch23
-rw-r--r--package/network/services/ppp/patches/132-fix_linux_includes.patch40
-rw-r--r--package/network/services/ppp/patches/133-fix_sha1_include.patch11
-rw-r--r--package/network/services/ppp/patches/140-pppoe_compile_fix.patch101
-rw-r--r--package/network/services/ppp/patches/200-makefile.patch49
-rw-r--r--package/network/services/ppp/patches/201-mppe_mppc_1.1.patch1495
-rw-r--r--package/network/services/ppp/patches/202-no_strip.patch88
-rw-r--r--package/network/services/ppp/patches/203-opt_flags.patch32
-rw-r--r--package/network/services/ppp/patches/204-radius_config.patch72
-rw-r--r--package/network/services/ppp/patches/205-no_exponential_timeout.patch29
-rw-r--r--package/network/services/ppp/patches/206-compensate_time_change.patch94
-rw-r--r--package/network/services/ppp/patches/207-lcp_mtu_max.patch25
-rw-r--r--package/network/services/ppp/patches/208-fix_status_code.patch24
-rw-r--r--package/network/services/ppp/patches/300-filter-pcap-includes-lib.patch20
-rw-r--r--package/network/services/ppp/patches/310-precompile_filter.patch196
-rw-r--r--package/network/services/ppp/patches/320-custom_iface_names.patch135
-rw-r--r--package/network/services/ppp/patches/321-multilink_support_custom_iface_names.patch146
-rw-r--r--package/network/services/ppp/patches/330-retain_foreign_default_routes.patch22
-rw-r--r--package/network/services/ppp/patches/340-populate_default_gateway.patch34
-rw-r--r--package/network/services/ppp/patches/400-simplify_kernel_checks.patch154
-rw-r--r--package/network/services/ppp/patches/401-no_record_file.patch39
-rw-r--r--package/network/services/ppp/patches/403-no_wtmp.patch25
-rw-r--r--package/network/services/ppp/patches/404-remove_obsolete_protocol_names.patch151
-rw-r--r--package/network/services/ppp/patches/405-no_multilink_option.patch28
-rw-r--r--package/network/services/ppp/patches/500-add-pptp-plugin.patch3065
-rw-r--r--package/network/services/ppp/patches/510-pptp_compile_fix.patch11
-rw-r--r--package/network/services/ppp/patches/520-uniq.patch269
-rw-r--r--package/network/services/ppp/patches/530-pppoe_send_padt.patch11
-rw-r--r--package/network/services/ppp/patches/531-pppoe_no_disconnect_warning.patch14
-rw-r--r--package/network/services/ppp/patches/540-save-pppol2tp_fd_str.patch13
-rw-r--r--package/network/services/ppp/patches/550-fix-printer-args.patch11
-rw-r--r--package/network/services/ppp/utils/pfc.c51
-rw-r--r--package/network/services/relayd/Makefile45
-rw-r--r--package/network/services/relayd/files/relay.hotplug2
-rw-r--r--package/network/services/relayd/files/relay.init115
-rw-r--r--package/network/services/samba36/Makefile160
-rw-r--r--package/network/services/samba36/files/samba.config6
-rwxr-xr-xpackage/network/services/samba36/files/samba.init118
-rw-r--r--package/network/services/samba36/files/smb.conf.template34
-rw-r--r--package/network/services/samba36/patches/100-configure_fixes.patch14
-rw-r--r--package/network/services/samba36/patches/110-multicall.patch119
-rw-r--r--package/network/services/samba36/patches/111-owrt_smbpasswd.patch281
-rw-r--r--package/network/services/samba36/patches/120-add_missing_ifdef.patch26
-rw-r--r--package/network/services/samba36/patches/200-remove_printer_support.patch346
-rw-r--r--package/network/services/samba36/patches/210-remove_ad_support.patch88
-rw-r--r--package/network/services/samba36/patches/220-remove_services.patch98
-rw-r--r--package/network/services/samba36/patches/230-remove_winreg_support.patch146
-rw-r--r--package/network/services/samba36/patches/240-remove_dfs_api.patch71
-rw-r--r--package/network/services/samba36/patches/250-remove_domain_logon.patch185
-rw-r--r--package/network/services/samba36/patches/260-remove_samr.patch144
-rw-r--r--package/network/services/samba36/patches/270-remove_registry_backend.patch43
-rw-r--r--package/network/services/samba36/patches/280-strip_srvsvc.patch143
-rw-r--r--package/network/services/samba36/patches/290-remove_lsa.patch73
-rw-r--r--package/network/services/samba36/patches/300-assert_debug_level.patch11
-rw-r--r--package/network/services/samba36/patches/310-remove_error_strings.patch253
-rw-r--r--package/network/services/samba36/patches/320-debug_level_checks.patch22
-rw-r--r--package/network/services/samba36/patches/330-librpc_default_print.patch8854
-rw-r--r--package/network/services/uhttpd/Makefile146
-rw-r--r--package/network/services/uhttpd/files/ubus.default8
-rw-r--r--package/network/services/uhttpd/files/uhttpd.config122
-rwxr-xr-xpackage/network/services/uhttpd/files/uhttpd.init149
-rw-r--r--package/network/utils/arptables/Makefile43
-rw-r--r--package/network/utils/arptables/patches/100-always_optimize.patch19
-rw-r--r--package/network/utils/arptables/patches/200-musl_fixes.patch31
-rw-r--r--package/network/utils/comgt/Makefile103
-rw-r--r--package/network/utils/comgt/files/3g.chat12
-rw-r--r--package/network/utils/comgt/files/3g.sh110
-rw-r--r--package/network/utils/comgt/files/3g.usb33
-rw-r--r--package/network/utils/comgt/files/directip-stop.gcom16
-rw-r--r--package/network/utils/comgt/files/directip.gcom55
-rw-r--r--package/network/utils/comgt/files/directip.sh111
-rw-r--r--package/network/utils/comgt/files/evdo.chat17
-rw-r--r--package/network/utils/comgt/files/getcardinfo.gcom14
-rw-r--r--package/network/utils/comgt/files/getcarrier.gcom20
-rw-r--r--package/network/utils/comgt/files/getcnum.gcom20
-rw-r--r--package/network/utils/comgt/files/getimsi.gcom17
-rw-r--r--package/network/utils/comgt/files/getstrength.gcom14
-rw-r--r--package/network/utils/comgt/files/ncm.json67
-rw-r--r--package/network/utils/comgt/files/ncm.sh192
-rw-r--r--package/network/utils/comgt/files/runcommand.gcom31
-rw-r--r--package/network/utils/comgt/files/setmode.gcom26
-rw-r--r--package/network/utils/comgt/files/setpin.gcom55
-rw-r--r--package/network/utils/comgt/patches/001-compile_fix.patch23
-rw-r--r--package/network/utils/comgt/patches/002-termios.patch105
-rw-r--r--package/network/utils/comgt/patches/003-no_XCASE.patch20
-rw-r--r--package/network/utils/comgt/patches/004-check_tty.patch68
-rw-r--r--package/network/utils/conntrack-tools/Makefile70
-rw-r--r--package/network/utils/conntrack-tools/files/conntrackd.init17
-rw-r--r--package/network/utils/conntrack-tools/patches/100-missing_include.patch40
-rw-r--r--package/network/utils/curl/Config.in154
-rw-r--r--package/network/utils/curl/Makefile178
-rw-r--r--package/network/utils/curl/patches/200-no_docs_tests.patch22
-rw-r--r--package/network/utils/curl/patches/300-fix-disable-crypto-auth.patch25
-rw-r--r--package/network/utils/curl/patches/310-polarssl-disable-runtime-version-check.patch11
-rw-r--r--package/network/utils/dante/Makefile117
-rw-r--r--package/network/utils/dante/patches/001-automake-compat.patch482
-rw-r--r--package/network/utils/dante/patches/100-do-not-use-defdname.patch42
-rw-r--r--package/network/utils/dante/patches/200-fix-RTLD_NEXT.patch36
-rw-r--r--package/network/utils/ebtables/Makefile72
-rw-r--r--package/network/utils/ebtables/patches/100-musl_fix.patch180
-rw-r--r--package/network/utils/iftop/Makefile43
-rw-r--r--package/network/utils/iftop/patches/0001-force-ncurses.patch12
-rw-r--r--package/network/utils/iperf/Makefile88
-rw-r--r--package/network/utils/iperf/patches/001-set-report-next-time-in-single-thread-mode.patch14
-rw-r--r--package/network/utils/iperf3/Makefile49
-rw-r--r--package/network/utils/iproute2/Makefile140
-rw-r--r--package/network/utils/iproute2/files/15-teql23
-rw-r--r--package/network/utils/iproute2/patches/001-config.patch7
-rw-r--r--package/network/utils/iproute2/patches/004-darwin_fixes.patch59
-rw-r--r--package/network/utils/iproute2/patches/006-no_sctp.patch18
-rw-r--r--package/network/utils/iproute2/patches/007-no_arpd.patch11
-rw-r--r--package/network/utils/iproute2/patches/008-no_netem.patch11
-rw-r--r--package/network/utils/iproute2/patches/010-type_fixes.patch396
-rw-r--r--package/network/utils/iproute2/patches/100-allow_pfifo_fast.patch9
-rw-r--r--package/network/utils/iproute2/patches/110-extra-ccopts.patch11
-rw-r--r--package/network/utils/iproute2/patches/120-libnetlink-pic.patch11
-rw-r--r--package/network/utils/iproute2/patches/130-missing_include.patch10
-rw-r--r--package/network/utils/iproute2/patches/200-add-tc_esfq.patch249
-rw-r--r--package/network/utils/iproute2/patches/210-add-act_connmark.patch87
-rw-r--r--package/network/utils/iproute2/patches/300-ip_tiny.patch101
-rw-r--r--package/network/utils/iproute2/patches/900-drop_FAILED_POLICY.patch54
-rw-r--r--package/network/utils/iproute2/patches/910-sanitize_headers_for_musl.patch10
-rw-r--r--package/network/utils/ipset/Makefile53
-rw-r--r--package/network/utils/iptables/Makefile548
-rw-r--r--package/network/utils/iptables/patches/020-iptables-disable-modprobe.patch18
-rw-r--r--package/network/utils/iptables/patches/030-no-libnfnetlink.patch94
-rw-r--r--package/network/utils/iptables/patches/050-optional-xml.patch13
-rw-r--r--package/network/utils/iptables/patches/100-bash-location.patch8
-rw-r--r--package/network/utils/iptables/patches/200-configurable_builtin.patch60
-rw-r--r--package/network/utils/iptables/patches/300-musl_fixes.patch127
-rw-r--r--package/network/utils/iptables/patches/500-add-xt_id-match.patch59
-rw-r--r--package/network/utils/iptables/patches/600-shared-libext.patch78
-rw-r--r--package/network/utils/iptables/patches/700-disable-legacy-revisions.patch108
-rw-r--r--package/network/utils/iputils/Makefile181
-rw-r--r--package/network/utils/iputils/patches/001-iputils.patch14
-rw-r--r--package/network/utils/iputils/patches/002-fix-ipv6.patch14
-rw-r--r--package/network/utils/iputils/patches/003-fix-makefile.patch18
-rw-r--r--package/network/utils/iputils/patches/010-ping6_uclibc_resolv.patch200
-rw-r--r--package/network/utils/iputils/patches/011-ping6_use_gnu_source.patch11
-rw-r--r--package/network/utils/iputils/patches/020-include_fixes.patch71
-rw-r--r--package/network/utils/iw/Makefile57
-rw-r--r--package/network/utils/iw/patches/001-nl80211_h_sync.patch100
-rw-r--r--package/network/utils/iw/patches/120-antenna_gain.patch34
-rw-r--r--package/network/utils/iw/patches/200-reduce_size.patch255
-rw-r--r--package/network/utils/iwcap/Makefile51
-rw-r--r--package/network/utils/iwcap/src/iwcap.c583
-rw-r--r--package/network/utils/iwinfo/Makefile121
-rw-r--r--package/network/utils/linux-atm/Makefile193
-rwxr-xr-xpackage/network/utils/linux-atm/files/br2684ctl89
-rw-r--r--package/network/utils/linux-atm/patches/000-debian_16.patch270
-rw-r--r--package/network/utils/linux-atm/patches/200-no_libfl.patch179
-rw-r--r--package/network/utils/linux-atm/patches/300-objcopy_path.patch40
-rw-r--r--package/network/utils/linux-atm/patches/400-portability_fixes.patch60
-rw-r--r--package/network/utils/maccalc/Makefile48
-rw-r--r--package/network/utils/maccalc/src/Makefile14
-rw-r--r--package/network/utils/maccalc/src/main.c256
-rw-r--r--package/network/utils/nftables/Makefile43
-rw-r--r--package/network/utils/nftables/patches/100-disable-doc-generation.patch8
-rw-r--r--package/network/utils/owipcalc/Makefile50
-rw-r--r--package/network/utils/owipcalc/src/owipcalc.c951
-rw-r--r--package/network/utils/resolveip/Makefile46
-rw-r--r--package/network/utils/resolveip/src/resolveip.c98
-rw-r--r--package/network/utils/rssileds/Makefile49
-rw-r--r--package/network/utils/rssileds/files/rssileds.init75
-rw-r--r--package/network/utils/rssileds/src/rssileds.c290
-rw-r--r--package/network/utils/tcpdump/Makefile90
-rw-r--r--package/network/utils/tcpdump/patches/001-remove_pcap_debug.patch23
-rw-r--r--package/network/utils/tcpdump/patches/002-remove_static_libpcap_check.patch73
-rw-r--r--package/network/utils/tcpdump/patches/100-tcpdump_mini.patch844
-rw-r--r--package/network/utils/umbim/Makefile45
-rwxr-xr-xpackage/network/utils/umbim/files/lib/netifd/proto/mbim.sh177
-rw-r--r--package/network/utils/uqmi/Makefile50
-rwxr-xr-xpackage/network/utils/uqmi/files/lib/netifd/proto/qmi.sh257
-rw-r--r--package/network/utils/wireless-tools/Makefile92
-rw-r--r--package/network/utils/wireless-tools/patches/001-debian.patch35
-rw-r--r--package/network/utils/wireless-tools/patches/002-fix-iwconfig-power-argument-parsing.patch13
-rw-r--r--package/network/utils/wireless-tools/patches/003-we_essential_def.patch359
-rw-r--r--package/network/utils/wireless-tools/patches/004-increase_iwlist_buffer.patch46
-rw-r--r--package/network/utils/wpan-tools/Makefile36
-rw-r--r--package/network/utils/wwan/Makefile35
-rw-r--r--package/network/utils/wwan/files/data/0421:03a76
-rw-r--r--package/network/utils/wwan/files/data/0421:060d6
-rw-r--r--package/network/utils/wwan/files/data/0421:060e6
-rw-r--r--package/network/utils/wwan/files/data/0421:06126
-rw-r--r--package/network/utils/wwan/files/data/0421:06196
-rw-r--r--package/network/utils/wwan/files/data/0421:061e6
-rw-r--r--package/network/utils/wwan/files/data/0421:06236
-rw-r--r--package/network/utils/wwan/files/data/0421:06296
-rw-r--r--package/network/utils/wwan/files/data/0421:062d6
-rw-r--r--package/network/utils/wwan/files/data/0421:062f6
-rw-r--r--package/network/utils/wwan/files/data/0421:06386
-rw-r--r--package/network/utils/wwan/files/data/05c6:00166
-rw-r--r--package/network/utils/wwan/files/data/05c6:00235
-rw-r--r--package/network/utils/wwan/files/data/05c6:00a06
-rw-r--r--package/network/utils/wwan/files/data/05c6:60005
-rw-r--r--package/network/utils/wwan/files/data/05c6:90005
-rw-r--r--package/network/utils/wwan/files/data/07d1:3e015
-rw-r--r--package/network/utils/wwan/files/data/07d1:3e025
-rw-r--r--package/network/utils/wwan/files/data/07d1:7e116
-rw-r--r--package/network/utils/wwan/files/data/0af0:40054
-rw-r--r--package/network/utils/wwan/files/data/0af0:69015
-rw-r--r--package/network/utils/wwan/files/data/0af0:72015
-rw-r--r--package/network/utils/wwan/files/data/0af0:81204
-rw-r--r--package/network/utils/wwan/files/data/0af0:92005
-rw-r--r--package/network/utils/wwan/files/data/0b3c:c0004
-rw-r--r--package/network/utils/wwan/files/data/0b3c:c0014
-rw-r--r--package/network/utils/wwan/files/data/0b3c:c0024
-rw-r--r--package/network/utils/wwan/files/data/0b3c:c0035
-rw-r--r--package/network/utils/wwan/files/data/0b3c:c0044
-rw-r--r--package/network/utils/wwan/files/data/0b3c:c0054
-rw-r--r--package/network/utils/wwan/files/data/0b3c:c00a4
-rw-r--r--package/network/utils/wwan/files/data/0b3c:c00b4
-rw-r--r--package/network/utils/wwan/files/data/0bdb:19006
-rw-r--r--package/network/utils/wwan/files/data/0bdb:19026
-rw-r--r--package/network/utils/wwan/files/data/0bdb:190a6
-rw-r--r--package/network/utils/wwan/files/data/0bdb:190d6
-rw-r--r--package/network/utils/wwan/files/data/0bdb:19106
-rw-r--r--package/network/utils/wwan/files/data/0c88:17da5
-rw-r--r--package/network/utils/wwan/files/data/0c88:180a5
-rw-r--r--package/network/utils/wwan/files/data/0f3d:68a24
-rw-r--r--package/network/utils/wwan/files/data/0f3d:68aa5
-rw-r--r--package/network/utils/wwan/files/data/1004:61246
-rw-r--r--package/network/utils/wwan/files/data/1004:61416
-rw-r--r--package/network/utils/wwan/files/data/1004:61576
-rw-r--r--package/network/utils/wwan/files/data/1004:618f5
-rw-r--r--package/network/utils/wwan/files/data/106c:37116
-rw-r--r--package/network/utils/wwan/files/data/106c:37146
-rw-r--r--package/network/utils/wwan/files/data/106c:37156
-rw-r--r--package/network/utils/wwan/files/data/106c:37166
-rw-r--r--package/network/utils/wwan/files/data/106c:37176
-rw-r--r--package/network/utils/wwan/files/data/106c:37184
-rw-r--r--package/network/utils/wwan/files/data/106c:37214
-rw-r--r--package/network/utils/wwan/files/data/1199:00175
-rw-r--r--package/network/utils/wwan/files/data/1199:00185
-rw-r--r--package/network/utils/wwan/files/data/1199:00195
-rw-r--r--package/network/utils/wwan/files/data/1199:00205
-rw-r--r--package/network/utils/wwan/files/data/1199:00215
-rw-r--r--package/network/utils/wwan/files/data/1199:00225
-rw-r--r--package/network/utils/wwan/files/data/1199:00235
-rw-r--r--package/network/utils/wwan/files/data/1199:00245
-rw-r--r--package/network/utils/wwan/files/data/1199:00255
-rw-r--r--package/network/utils/wwan/files/data/1199:00265
-rw-r--r--package/network/utils/wwan/files/data/1199:00275
-rw-r--r--package/network/utils/wwan/files/data/1199:00285
-rw-r--r--package/network/utils/wwan/files/data/1199:01125
-rw-r--r--package/network/utils/wwan/files/data/1199:01205
-rw-r--r--package/network/utils/wwan/files/data/1199:02185
-rw-r--r--package/network/utils/wwan/files/data/1199:02205
-rw-r--r--package/network/utils/wwan/files/data/1199:02245
-rw-r--r--package/network/utils/wwan/files/data/1199:03015
-rw-r--r--package/network/utils/wwan/files/data/1199:68025
-rw-r--r--package/network/utils/wwan/files/data/1199:68035
-rw-r--r--package/network/utils/wwan/files/data/1199:68045
-rw-r--r--package/network/utils/wwan/files/data/1199:68055
-rw-r--r--package/network/utils/wwan/files/data/1199:68085
-rw-r--r--package/network/utils/wwan/files/data/1199:68095
-rw-r--r--package/network/utils/wwan/files/data/1199:68135
-rw-r--r--package/network/utils/wwan/files/data/1199:68155
-rw-r--r--package/network/utils/wwan/files/data/1199:68165
-rw-r--r--package/network/utils/wwan/files/data/1199:68205
-rw-r--r--package/network/utils/wwan/files/data/1199:68215
-rw-r--r--package/network/utils/wwan/files/data/1199:68225
-rw-r--r--package/network/utils/wwan/files/data/1199:68335
-rw-r--r--package/network/utils/wwan/files/data/1199:68345
-rw-r--r--package/network/utils/wwan/files/data/1199:68355
-rw-r--r--package/network/utils/wwan/files/data/1199:68385
-rw-r--r--package/network/utils/wwan/files/data/1199:68395
-rw-r--r--package/network/utils/wwan/files/data/1199:683a5
-rw-r--r--package/network/utils/wwan/files/data/1199:683b5
-rw-r--r--package/network/utils/wwan/files/data/1199:68505
-rw-r--r--package/network/utils/wwan/files/data/1199:68515
-rw-r--r--package/network/utils/wwan/files/data/1199:68525
-rw-r--r--package/network/utils/wwan/files/data/1199:68535
-rw-r--r--package/network/utils/wwan/files/data/1199:68555
-rw-r--r--package/network/utils/wwan/files/data/1199:68565
-rw-r--r--package/network/utils/wwan/files/data/1199:68595
-rw-r--r--package/network/utils/wwan/files/data/1199:685a5
-rw-r--r--package/network/utils/wwan/files/data/1199:68805
-rw-r--r--package/network/utils/wwan/files/data/1199:68905
-rw-r--r--package/network/utils/wwan/files/data/1199:68915
-rw-r--r--package/network/utils/wwan/files/data/1199:68925
-rw-r--r--package/network/utils/wwan/files/data/1199:68935
-rw-r--r--package/network/utils/wwan/files/data/1199:68a24
-rw-r--r--package/network/utils/wwan/files/data/1199:68aa5
-rw-r--r--package/network/utils/wwan/files/data/12d1:10355
-rw-r--r--package/network/utils/wwan/files/data/12d1:14044
-rw-r--r--package/network/utils/wwan/files/data/12d1:14065
-rw-r--r--package/network/utils/wwan/files/data/12d1:140b5
-rw-r--r--package/network/utils/wwan/files/data/12d1:140c4
-rw-r--r--package/network/utils/wwan/files/data/12d1:14125
-rw-r--r--package/network/utils/wwan/files/data/12d1:141b5
-rw-r--r--package/network/utils/wwan/files/data/12d1:14335
-rw-r--r--package/network/utils/wwan/files/data/12d1:14365
-rw-r--r--package/network/utils/wwan/files/data/12d1:14445
-rw-r--r--package/network/utils/wwan/files/data/12d1:144e5
-rw-r--r--package/network/utils/wwan/files/data/12d1:14645
-rw-r--r--package/network/utils/wwan/files/data/12d1:14655
-rw-r--r--package/network/utils/wwan/files/data/12d1:14915
-rw-r--r--package/network/utils/wwan/files/data/12d1:14a55
-rw-r--r--package/network/utils/wwan/files/data/12d1:14a85
-rw-r--r--package/network/utils/wwan/files/data/12d1:14ac4
-rw-r--r--package/network/utils/wwan/files/data/12d1:14ae5
-rw-r--r--package/network/utils/wwan/files/data/12d1:14c64
-rw-r--r--package/network/utils/wwan/files/data/12d1:14c84
-rw-r--r--package/network/utils/wwan/files/data/12d1:14c94
-rw-r--r--package/network/utils/wwan/files/data/12d1:14ca4
-rw-r--r--package/network/utils/wwan/files/data/12d1:14cb5
-rw-r--r--package/network/utils/wwan/files/data/12d1:14cc4
-rw-r--r--package/network/utils/wwan/files/data/12d1:14cf5
-rw-r--r--package/network/utils/wwan/files/data/12d1:14d24
-rw-r--r--package/network/utils/wwan/files/data/12d1:15065
-rw-r--r--package/network/utils/wwan/files/data/12d1:150a4
-rw-r--r--package/network/utils/wwan/files/data/12d1:150c4
-rw-r--r--package/network/utils/wwan/files/data/12d1:150f4
-rw-r--r--package/network/utils/wwan/files/data/12d1:151b4
-rw-r--r--package/network/utils/wwan/files/data/12d1:151d5
-rw-r--r--package/network/utils/wwan/files/data/12d1:156c5
-rw-r--r--package/network/utils/wwan/files/data/12d1:15764
-rw-r--r--package/network/utils/wwan/files/data/12d1:15774
-rw-r--r--package/network/utils/wwan/files/data/12d1:15784
-rw-r--r--package/network/utils/wwan/files/data/12d1:15894
-rw-r--r--package/network/utils/wwan/files/data/12d1:1c055
-rw-r--r--package/network/utils/wwan/files/data/12d1:1c075
-rw-r--r--package/network/utils/wwan/files/data/12d1:1c085
-rw-r--r--package/network/utils/wwan/files/data/12d1:1c105
-rw-r--r--package/network/utils/wwan/files/data/12d1:1c125
-rw-r--r--package/network/utils/wwan/files/data/12d1:1c1e4
-rw-r--r--package/network/utils/wwan/files/data/12d1:1c1f4
-rw-r--r--package/network/utils/wwan/files/data/12d1:1c235
-rw-r--r--package/network/utils/wwan/files/data/12d1:1f164
-rw-r--r--package/network/utils/wwan/files/data/1410:14005
-rw-r--r--package/network/utils/wwan/files/data/1410:14105
-rw-r--r--package/network/utils/wwan/files/data/1410:14205
-rw-r--r--package/network/utils/wwan/files/data/1410:14305
-rw-r--r--package/network/utils/wwan/files/data/1410:14505
-rw-r--r--package/network/utils/wwan/files/data/1410:21005
-rw-r--r--package/network/utils/wwan/files/data/1410:21105
-rw-r--r--package/network/utils/wwan/files/data/1410:21205
-rw-r--r--package/network/utils/wwan/files/data/1410:21305
-rw-r--r--package/network/utils/wwan/files/data/1410:24005
-rw-r--r--package/network/utils/wwan/files/data/1410:24105
-rw-r--r--package/network/utils/wwan/files/data/1410:24205
-rw-r--r--package/network/utils/wwan/files/data/1410:41005
-rw-r--r--package/network/utils/wwan/files/data/1410:44005
-rw-r--r--package/network/utils/wwan/files/data/1410:60005
-rw-r--r--package/network/utils/wwan/files/data/1410:60015
-rw-r--r--package/network/utils/wwan/files/data/1410:60025
-rw-r--r--package/network/utils/wwan/files/data/1410:60105
-rw-r--r--package/network/utils/wwan/files/data/1410:70015
-rw-r--r--package/network/utils/wwan/files/data/1410:70035
-rw-r--r--package/network/utils/wwan/files/data/1410:70305
-rw-r--r--package/network/utils/wwan/files/data/1410:70316
-rw-r--r--package/network/utils/wwan/files/data/1410:70415
-rw-r--r--package/network/utils/wwan/files/data/1410:70425
-rw-r--r--package/network/utils/wwan/files/data/1410:90114
-rw-r--r--package/network/utils/wwan/files/data/1410:b0014
-rw-r--r--package/network/utils/wwan/files/data/1529:31006
-rw-r--r--package/network/utils/wwan/files/data/16d5:62025
-rw-r--r--package/network/utils/wwan/files/data/16d5:65015
-rw-r--r--package/network/utils/wwan/files/data/16d5:65025
-rw-r--r--package/network/utils/wwan/files/data/16d5:66036
-rw-r--r--package/network/utils/wwan/files/data/16d5:900d6
-rw-r--r--package/network/utils/wwan/files/data/16d8:51416
-rw-r--r--package/network/utils/wwan/files/data/16d8:55336
-rw-r--r--package/network/utils/wwan/files/data/16d8:55436
-rw-r--r--package/network/utils/wwan/files/data/16d8:55536
-rw-r--r--package/network/utils/wwan/files/data/16d8:60025
-rw-r--r--package/network/utils/wwan/files/data/16d8:60065
-rw-r--r--package/network/utils/wwan/files/data/16d8:60074
-rw-r--r--package/network/utils/wwan/files/data/16d8:60084
-rw-r--r--package/network/utils/wwan/files/data/16d8:65226
-rw-r--r--package/network/utils/wwan/files/data/16d8:65236
-rw-r--r--package/network/utils/wwan/files/data/16d8:65326
-rw-r--r--package/network/utils/wwan/files/data/16d8:65336
-rw-r--r--package/network/utils/wwan/files/data/16d8:65436
-rw-r--r--package/network/utils/wwan/files/data/16d8:680a6
-rw-r--r--package/network/utils/wwan/files/data/19d2:00015
-rw-r--r--package/network/utils/wwan/files/data/19d2:00024
-rw-r--r--package/network/utils/wwan/files/data/19d2:00155
-rw-r--r--package/network/utils/wwan/files/data/19d2:00165
-rw-r--r--package/network/utils/wwan/files/data/19d2:00174
-rw-r--r--package/network/utils/wwan/files/data/19d2:00185
-rw-r--r--package/network/utils/wwan/files/data/19d2:00194
-rw-r--r--package/network/utils/wwan/files/data/19d2:00225
-rw-r--r--package/network/utils/wwan/files/data/19d2:00245
-rw-r--r--package/network/utils/wwan/files/data/19d2:00254
-rw-r--r--package/network/utils/wwan/files/data/19d2:00314
-rw-r--r--package/network/utils/wwan/files/data/19d2:00335
-rw-r--r--package/network/utils/wwan/files/data/19d2:00375
-rw-r--r--package/network/utils/wwan/files/data/19d2:00395
-rw-r--r--package/network/utils/wwan/files/data/19d2:00424
-rw-r--r--package/network/utils/wwan/files/data/19d2:00524
-rw-r--r--package/network/utils/wwan/files/data/19d2:00554
-rw-r--r--package/network/utils/wwan/files/data/19d2:00575
-rw-r--r--package/network/utils/wwan/files/data/19d2:00634
-rw-r--r--package/network/utils/wwan/files/data/19d2:00645
-rw-r--r--package/network/utils/wwan/files/data/19d2:00665
-rw-r--r--package/network/utils/wwan/files/data/19d2:00735
-rw-r--r--package/network/utils/wwan/files/data/19d2:00795
-rw-r--r--package/network/utils/wwan/files/data/19d2:00825
-rw-r--r--package/network/utils/wwan/files/data/19d2:00865
-rw-r--r--package/network/utils/wwan/files/data/19d2:00915
-rw-r--r--package/network/utils/wwan/files/data/19d2:00945
-rw-r--r--package/network/utils/wwan/files/data/19d2:01044
-rw-r--r--package/network/utils/wwan/files/data/19d2:01085
-rw-r--r--package/network/utils/wwan/files/data/19d2:01166
-rw-r--r--package/network/utils/wwan/files/data/19d2:01175
-rw-r--r--package/network/utils/wwan/files/data/19d2:01214
-rw-r--r--package/network/utils/wwan/files/data/19d2:01244
-rw-r--r--package/network/utils/wwan/files/data/19d2:01285
-rw-r--r--package/network/utils/wwan/files/data/19d2:01426
-rw-r--r--package/network/utils/wwan/files/data/19d2:01436
-rw-r--r--package/network/utils/wwan/files/data/19d2:01525
-rw-r--r--package/network/utils/wwan/files/data/19d2:01574
-rw-r--r--package/network/utils/wwan/files/data/19d2:01674
-rw-r--r--package/network/utils/wwan/files/data/19d2:01706
-rw-r--r--package/network/utils/wwan/files/data/19d2:01994
-rw-r--r--package/network/utils/wwan/files/data/19d2:02574
-rw-r--r--package/network/utils/wwan/files/data/19d2:02654
-rw-r--r--package/network/utils/wwan/files/data/19d2:02844
-rw-r--r--package/network/utils/wwan/files/data/19d2:03264
-rw-r--r--package/network/utils/wwan/files/data/19d2:10036
-rw-r--r--package/network/utils/wwan/files/data/19d2:10084
-rw-r--r--package/network/utils/wwan/files/data/19d2:10104
-rw-r--r--package/network/utils/wwan/files/data/19d2:10156
-rw-r--r--package/network/utils/wwan/files/data/19d2:10184
-rw-r--r--package/network/utils/wwan/files/data/19d2:11726
-rw-r--r--package/network/utils/wwan/files/data/19d2:11736
-rw-r--r--package/network/utils/wwan/files/data/19d2:11764
-rw-r--r--package/network/utils/wwan/files/data/19d2:11776
-rw-r--r--package/network/utils/wwan/files/data/19d2:11816
-rw-r--r--package/network/utils/wwan/files/data/19d2:12036
-rw-r--r--package/network/utils/wwan/files/data/19d2:12086
-rw-r--r--package/network/utils/wwan/files/data/19d2:12116
-rw-r--r--package/network/utils/wwan/files/data/19d2:12126
-rw-r--r--package/network/utils/wwan/files/data/19d2:12176
-rw-r--r--package/network/utils/wwan/files/data/19d2:12186
-rw-r--r--package/network/utils/wwan/files/data/19d2:12206
-rw-r--r--package/network/utils/wwan/files/data/19d2:12226
-rw-r--r--package/network/utils/wwan/files/data/19d2:12454
-rw-r--r--package/network/utils/wwan/files/data/19d2:12524
-rw-r--r--package/network/utils/wwan/files/data/19d2:12544
-rw-r--r--package/network/utils/wwan/files/data/19d2:12564
-rw-r--r--package/network/utils/wwan/files/data/19d2:12704
-rw-r--r--package/network/utils/wwan/files/data/19d2:14014
-rw-r--r--package/network/utils/wwan/files/data/19d2:14024
-rw-r--r--package/network/utils/wwan/files/data/19d2:14264
-rw-r--r--package/network/utils/wwan/files/data/19d2:15126
-rw-r--r--package/network/utils/wwan/files/data/19d2:15156
-rw-r--r--package/network/utils/wwan/files/data/19d2:15186
-rw-r--r--package/network/utils/wwan/files/data/19d2:15196
-rw-r--r--package/network/utils/wwan/files/data/19d2:15226
-rw-r--r--package/network/utils/wwan/files/data/19d2:15256
-rw-r--r--package/network/utils/wwan/files/data/19d2:15276
-rw-r--r--package/network/utils/wwan/files/data/19d2:15376
-rw-r--r--package/network/utils/wwan/files/data/19d2:15386
-rw-r--r--package/network/utils/wwan/files/data/19d2:15446
-rw-r--r--package/network/utils/wwan/files/data/19d2:20024
-rw-r--r--package/network/utils/wwan/files/data/19d2:20035
-rw-r--r--package/network/utils/wwan/files/data/19d2:ffdd5
-rw-r--r--package/network/utils/wwan/files/data/19d2:ffe46
-rw-r--r--package/network/utils/wwan/files/data/19d2:ffe95
-rw-r--r--package/network/utils/wwan/files/data/19d2:fff15
-rw-r--r--package/network/utils/wwan/files/data/19d2:fffb5
-rw-r--r--package/network/utils/wwan/files/data/19d2:fffc5
-rw-r--r--package/network/utils/wwan/files/data/19d2:fffd5
-rw-r--r--package/network/utils/wwan/files/data/19d2:fffe5
-rw-r--r--package/network/utils/wwan/files/data/19d2:ffff5
-rw-r--r--package/network/utils/wwan/files/data/1a8d:10025
-rw-r--r--package/network/utils/wwan/files/data/1a8d:10035
-rw-r--r--package/network/utils/wwan/files/data/1a8d:10075
-rw-r--r--package/network/utils/wwan/files/data/1a8d:10095
-rw-r--r--package/network/utils/wwan/files/data/1a8d:100c5
-rw-r--r--package/network/utils/wwan/files/data/1a8d:100d5
-rw-r--r--package/network/utils/wwan/files/data/1a8d:20066
-rw-r--r--package/network/utils/wwan/files/data/1bbb:00005
-rw-r--r--package/network/utils/wwan/files/data/1bbb:00126
-rw-r--r--package/network/utils/wwan/files/data/1bbb:00175
-rw-r--r--package/network/utils/wwan/files/data/1bbb:00525
-rw-r--r--package/network/utils/wwan/files/data/1bbb:00b75
-rw-r--r--package/network/utils/wwan/files/data/1bbb:00ca6
-rw-r--r--package/network/utils/wwan/files/data/1bbb:011e4
-rw-r--r--package/network/utils/wwan/files/data/1bbb:02034
-rw-r--r--package/network/utils/wwan/files/data/1c9e:60606
-rw-r--r--package/network/utils/wwan/files/data/1c9e:60616
-rw-r--r--package/network/utils/wwan/files/data/1c9e:90006
-rw-r--r--package/network/utils/wwan/files/data/1c9e:96035
-rw-r--r--package/network/utils/wwan/files/data/1c9e:96055
-rw-r--r--package/network/utils/wwan/files/data/1c9e:96075
-rw-r--r--package/network/utils/wwan/files/data/1c9e:98016
-rw-r--r--package/network/utils/wwan/files/data/1c9e:99006
-rw-r--r--package/network/utils/wwan/files/data/1e0e:90005
-rw-r--r--package/network/utils/wwan/files/data/1e0e:91005
-rw-r--r--package/network/utils/wwan/files/data/1e0e:92005
-rw-r--r--package/network/utils/wwan/files/data/1e0e:ce165
-rw-r--r--package/network/utils/wwan/files/data/1e0e:cefe6
-rw-r--r--package/network/utils/wwan/files/data/2001:7d006
-rw-r--r--package/network/utils/wwan/files/data/2001:7d015
-rw-r--r--package/network/utils/wwan/files/data/2001:7d025
-rw-r--r--package/network/utils/wwan/files/data/2001:7d035
-rw-r--r--package/network/utils/wwan/files/data/211f:68015
-rw-r--r--package/network/utils/wwan/files/data/2357:02014
-rw-r--r--package/network/utils/wwan/files/data/2357:02024
-rw-r--r--package/network/utils/wwan/files/data/2357:02034
-rw-r--r--package/network/utils/wwan/files/data/2357:90004
-rw-r--r--package/network/utils/wwan/files/data/413c:81145
-rw-r--r--package/network/utils/wwan/files/data/413c:81155
-rw-r--r--package/network/utils/wwan/files/data/413c:81165
-rw-r--r--package/network/utils/wwan/files/data/413c:81175
-rw-r--r--package/network/utils/wwan/files/data/413c:81185
-rw-r--r--package/network/utils/wwan/files/data/413c:81285
-rw-r--r--package/network/utils/wwan/files/data/413c:81295
-rw-r--r--package/network/utils/wwan/files/data/413c:81335
-rw-r--r--package/network/utils/wwan/files/data/413c:81345
-rw-r--r--package/network/utils/wwan/files/data/413c:81355
-rw-r--r--package/network/utils/wwan/files/data/413c:81365
-rw-r--r--package/network/utils/wwan/files/data/413c:81375
-rw-r--r--package/network/utils/wwan/files/data/413c:81385
-rw-r--r--package/network/utils/wwan/files/data/413c:81476
-rw-r--r--package/network/utils/wwan/files/data/413c:81805
-rw-r--r--package/network/utils/wwan/files/data/413c:81815
-rw-r--r--package/network/utils/wwan/files/data/413c:81825
-rw-r--r--package/network/utils/wwan/files/data/413c:81864
-rw-r--r--package/network/utils/wwan/files/data/413c:81944
-rw-r--r--package/network/utils/wwan/files/data/413c:81954
-rw-r--r--package/network/utils/wwan/files/data/413c:81964
-rw-r--r--package/network/utils/wwan/files/data/413c:819b5
-rwxr-xr-xpackage/network/utils/wwan/files/wwan.sh119
-rw-r--r--package/network/utils/wwan/files/wwan.usb18
-rw-r--r--package/network/utils/wwan/files/wwan.usbmisc27
-rw-r--r--package/network/utils/xtables-addons/Makefile152
-rw-r--r--package/network/utils/xtables-addons/patches/002-fix-kernel-version-detection.patch11
-rw-r--r--package/network/utils/xtables-addons/patches/100-add-rtsp-conntrack.patch1526
-rw-r--r--package/network/utils/xtables-addons/patches/200-add-lua-packetscript.patch18158
-rw-r--r--package/network/utils/xtables-addons/patches/201-fix-lua-packetscript.patch89
-rw-r--r--package/network/utils/xtables-addons/patches/300-geoip-endian-detection.patch18
811 files changed, 89764 insertions, 0 deletions
diff --git a/package/network/config/firewall/Makefile b/package/network/config/firewall/Makefile
new file mode 100644
index 0000000..15cfa31
--- /dev/null
+++ b/package/network/config/firewall/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2013-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:=firewall
+PKG_VERSION:=2015-07-27
+PKG_RELEASE:=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://nbd.name/firewall3.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=980b7859bbd1db1e5e46422fccccbce38f9809ab
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=ISC
+
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/firewall
+ SECTION:=net
+ CATEGORY:=Base system
+ TITLE:=OpenWrt C Firewall
+ DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libxtables +kmod-ipt-core +kmod-ipt-conntrack +kmod-ipt-nat
+endef
+
+define Package/firewall/description
+ This package provides a config-compatible C implementation of the UCI firewall.
+endef
+
+define Package/firewall/conffiles
+/etc/config/firewall
+/etc/firewall.user
+endef
+
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+TARGET_LDFLAGS += -Wl,--gc-sections
+CMAKE_OPTIONS += $(if $(CONFIG_IPV6),,-DDISABLE_IPV6=1)
+
+define Package/firewall/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/firewall3 $(1)/sbin/fw3
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/firewall.init $(1)/etc/init.d/firewall
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+ $(INSTALL_DATA) ./files/firewall.hotplug $(1)/etc/hotplug.d/iface/20-firewall
+ $(INSTALL_DIR) $(1)/etc/config/
+ $(INSTALL_DATA) ./files/firewall.config $(1)/etc/config/firewall
+ $(INSTALL_DIR) $(1)/etc/
+ $(INSTALL_DATA) ./files/firewall.user $(1)/etc/firewall.user
+endef
+
+$(eval $(call BuildPackage,firewall))
diff --git a/package/network/config/firewall/files/firewall.config b/package/network/config/firewall/files/firewall.config
new file mode 100644
index 0000000..749dbec
--- /dev/null
+++ b/package/network/config/firewall/files/firewall.config
@@ -0,0 +1,194 @@
+config defaults
+ option syn_flood 1
+ option input ACCEPT
+ option output ACCEPT
+ option forward REJECT
+# Uncomment this line to disable ipv6 rules
+# option disable_ipv6 1
+
+config zone
+ option name lan
+ list network 'lan'
+ option input ACCEPT
+ option output ACCEPT
+ option forward ACCEPT
+
+config zone
+ option name wan
+ list network 'wan'
+ list network 'wan6'
+ option input REJECT
+ option output ACCEPT
+ option forward REJECT
+ option masq 1
+ option mtu_fix 1
+
+config forwarding
+ option src lan
+ option dest wan
+
+# We need to accept udp packets on port 68,
+# see https://dev.openwrt.org/ticket/4108
+config rule
+ option name Allow-DHCP-Renew
+ option src wan
+ option proto udp
+ option dest_port 68
+ option target ACCEPT
+ option family ipv4
+
+# Allow IPv4 ping
+config rule
+ option name Allow-Ping
+ option src wan
+ option proto icmp
+ option icmp_type echo-request
+ option family ipv4
+ option target ACCEPT
+
+config rule
+ option name Allow-IGMP
+ option src wan
+ option proto igmp
+ option family ipv4
+ option target ACCEPT
+
+# Allow DHCPv6 replies
+# see https://dev.openwrt.org/ticket/10381
+config rule
+ option name Allow-DHCPv6
+ option src wan
+ option proto udp
+ option src_ip fc00::/6
+ option dest_ip fc00::/6
+ option dest_port 546
+ option family ipv6
+ option target ACCEPT
+
+config rule
+ option name Allow-MLD
+ option src wan
+ option proto icmp
+ option src_ip fe80::/10
+ list icmp_type '130/0'
+ list icmp_type '131/0'
+ list icmp_type '132/0'
+ list icmp_type '143/0'
+ option family ipv6
+ option target ACCEPT
+
+# Allow essential incoming IPv6 ICMP traffic
+config rule
+ option name Allow-ICMPv6-Input
+ option src wan
+ option proto icmp
+ list icmp_type echo-request
+ list icmp_type echo-reply
+ list icmp_type destination-unreachable
+ list icmp_type packet-too-big
+ list icmp_type time-exceeded
+ list icmp_type bad-header
+ list icmp_type unknown-header-type
+ list icmp_type router-solicitation
+ list icmp_type neighbour-solicitation
+ list icmp_type router-advertisement
+ list icmp_type neighbour-advertisement
+ option limit 1000/sec
+ option family ipv6
+ option target ACCEPT
+
+# Allow essential forwarded IPv6 ICMP traffic
+config rule
+ option name Allow-ICMPv6-Forward
+ option src wan
+ option dest *
+ option proto icmp
+ list icmp_type echo-request
+ list icmp_type echo-reply
+ list icmp_type destination-unreachable
+ list icmp_type packet-too-big
+ list icmp_type time-exceeded
+ list icmp_type bad-header
+ list icmp_type unknown-header-type
+ option limit 1000/sec
+ option family ipv6
+ option target ACCEPT
+
+# include a file with users custom iptables rules
+config include
+ option path /etc/firewall.user
+
+
+### EXAMPLE CONFIG SECTIONS
+# do not allow a specific ip to access wan
+#config rule
+# option src lan
+# option src_ip 192.168.45.2
+# option dest wan
+# option proto tcp
+# option target REJECT
+
+# block a specific mac on wan
+#config rule
+# option dest wan
+# option src_mac 00:11:22:33:44:66
+# option target REJECT
+
+# block incoming ICMP traffic on a zone
+#config rule
+# option src lan
+# option proto ICMP
+# option target DROP
+
+# port redirect port coming in on wan to lan
+#config redirect
+# option src wan
+# option src_dport 80
+# option dest lan
+# option dest_ip 192.168.16.235
+# option dest_port 80
+# option proto tcp
+
+# port redirect of remapped ssh port (22001) on wan
+#config redirect
+# option src wan
+# option src_dport 22001
+# option dest lan
+# option dest_port 22
+# option proto tcp
+
+# allow IPsec/ESP and ISAKMP passthrough
+config rule
+ option src wan
+ option dest lan
+ option proto esp
+ option target ACCEPT
+
+config rule
+ option src wan
+ option dest lan
+ option dest_port 500
+ option proto udp
+ option target ACCEPT
+
+### FULL CONFIG SECTIONS
+#config rule
+# option src lan
+# option src_ip 192.168.45.2
+# option src_mac 00:11:22:33:44:55
+# option src_port 80
+# option dest wan
+# option dest_ip 194.25.2.129
+# option dest_port 120
+# option proto tcp
+# option target REJECT
+
+#config redirect
+# option src lan
+# option src_ip 192.168.45.2
+# option src_mac 00:11:22:33:44:55
+# option src_port 1024
+# option src_dport 80
+# option dest_ip 194.25.2.129
+# option dest_port 120
+# option proto tcp
diff --git a/package/network/config/firewall/files/firewall.hotplug b/package/network/config/firewall/files/firewall.hotplug
new file mode 100644
index 0000000..f1eab00
--- /dev/null
+++ b/package/network/config/firewall/files/firewall.hotplug
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+[ "$ACTION" = ifup -o "$ACTION" = ifupdate ] || exit 0
+[ "$ACTION" = ifupdate -a -z "$IFUPDATE_ADDRESSES" -a -z "$IFUPDATE_DATA" ] && exit 0
+
+/etc/init.d/firewall enabled || exit 0
+
+fw3 -q network "$INTERFACE" >/dev/null || exit 0
+
+logger -t firewall "Reloading firewall due to $ACTION of $INTERFACE ($DEVICE)"
+fw3 -q reload
diff --git a/package/network/config/firewall/files/firewall.init b/package/network/config/firewall/files/firewall.init
new file mode 100755
index 0000000..ee3ed1a
--- /dev/null
+++ b/package/network/config/firewall/files/firewall.init
@@ -0,0 +1,61 @@
+#!/bin/sh /etc/rc.common
+
+START=19
+USE_PROCD=1
+QUIET=""
+
+validate_firewall_redirect()
+{
+ uci_validate_section firewall redirect "${1}" \
+ 'proto:or(uinteger, string)' \
+ 'src:string' \
+ 'src_ip:cidr' \
+ 'src_dport:or(port, portrange)' \
+ 'dest:string' \
+ 'dest_ip:cidr' \
+ 'dest_port:or(port, portrange)' \
+ 'target:or("SNAT", "DNAT")'
+}
+
+validate_firewall_rule()
+{
+ uci_validate_section firewall rule "${1}" \
+ 'proto:or(uinteger, string)' \
+ 'src:string' \
+ 'dest:string' \
+ 'src_port:or(port, portrange)' \
+ 'dest_port:or(port, portrange)' \
+ 'target:string'
+}
+
+service_triggers() {
+ procd_add_reload_trigger firewall
+
+ procd_open_validate
+ validate_firewall_redirect
+ validate_firewall_rule
+ procd_close_validate
+}
+
+restart() {
+ fw3 restart
+}
+
+start_service() {
+ fw3 ${QUIET} start
+}
+
+stop_service() {
+ fw3 flush
+}
+
+reload_service() {
+ fw3 reload
+}
+
+boot() {
+ # Be silent on boot, firewall might be started by hotplug already,
+ # so don't complain in syslog.
+ QUIET=-q
+ start
+}
diff --git a/package/network/config/firewall/files/firewall.user b/package/network/config/firewall/files/firewall.user
new file mode 100644
index 0000000..6f79906
--- /dev/null
+++ b/package/network/config/firewall/files/firewall.user
@@ -0,0 +1,7 @@
+# This file is interpreted as shell script.
+# Put your custom iptables rules here, they will
+# be executed with each firewall (re-)start.
+
+# Internal uci firewall chains are flushed and recreated on reload, so
+# put custom rules into the root chains e.g. INPUT or FORWARD or into the
+# special user chains, e.g. input_wan_rule or postrouting_lan_rule.
diff --git a/package/network/config/gre/Makefile b/package/network/config/gre/Makefile
new file mode 100644
index 0000000..49e7d19
--- /dev/null
+++ b/package/network/config/gre/Makefile
@@ -0,0 +1,65 @@
+#
+# Copyright (C) 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:=gre
+PKG_VERSION:=1
+PKG_RELEASE:=3
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/gre/Default
+ SECTION:=net
+ CATEGORY:=Network
+ MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
+endef
+
+define Package/gre
+$(call Package/gre/Default)
+ TITLE:=Generic Routing Encapsulation config support
+endef
+
+define Package/gre/description
+ Generic Routing Encapsulation config support (IPv4 and IPv6) in /etc/config/network.
+endef
+
+define Package/grev4
+$(call Package/gre/Default)
+ TITLE:=Generic Routing Encapsulation (IPv4) config support
+ DEPENDS:=@(PACKAGE_gre) +kmod-gre
+endef
+
+define Package/grev4/description
+ Generic Routing Encapsulation config support (IPv4) in /etc/config/network.
+endef
+
+define Package/grev6
+$(call Package/gre/Default)
+ TITLE:=Generic Routing Encapsulation (IPv6) config support
+ DEPENDS:=@(PACKAGE_gre) @IPV6 +kmod-ip6-gre
+endef
+
+define Package/grev6/description
+ Generic Routing Encapsulation config support (IPv6) in /etc/config/network.
+endef
+
+define Build/Compile
+endef
+
+define Build/Configure
+endef
+
+define Package/gre/install
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/gre.sh $(1)/lib/netifd/proto/gre.sh
+endef
+
+$(eval $(call BuildPackage,gre))
+$(eval $(call BuildPackage,grev4))
+$(eval $(call BuildPackage,grev6))
diff --git a/package/network/config/gre/files/gre.sh b/package/network/config/gre/files/gre.sh
new file mode 100755
index 0000000..4483a08
--- /dev/null
+++ b/package/network/config/gre/files/gre.sh
@@ -0,0 +1,237 @@
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+gre_generic_setup() {
+ local cfg="$1"
+ local mode="$2"
+ local local="$3"
+ local remote="$4"
+ local link="$5"
+ local mtu ttl tos zone ikey okey icsum ocsum iseqno oseqno
+ json_get_vars mtu ttl tos zone ikey okey icsum ocsum iseqno oseqno
+
+ [ -z "$zone" ] && zone="wan"
+
+ proto_init_update "$link" 1
+
+ proto_add_tunnel
+ json_add_string mode "$mode"
+ json_add_int mtu "${mtu:-1280}"
+ [ -n "$df" ] && json_add_boolean df "$df"
+ json_add_int ttl "${ttl:-64}"
+ [ -n "$tos" ] && json_add_string tos "$tos"
+ json_add_string local "$local"
+ json_add_string remote "$remote"
+ [ -n "$tunlink" ] && json_add_string link "$tunlink"
+ json_add_string info "${ikey:-0},${okey:-0},${icsum:-0},${ocsum:-0},${iseqno:-0},${oseqno:-0}"
+ proto_close_tunnel
+
+ proto_add_data
+ [ -n "$zone" ] && json_add_string zone "$zone"
+ proto_close_data
+
+ proto_send_update "$cfg"
+}
+
+gre_setup() {
+ local cfg="$1"
+ local mode="$2"
+
+ local ipaddr peeraddr
+ json_get_vars df ipaddr peeraddr tunlink
+
+ [ -z "$peeraddr" ] && {
+ proto_notify_error "$cfg" "MISSING_ADDRESS"
+ proto_block_restart "$cfg"
+ exit
+ }
+
+ ( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" )
+
+ [ -z "$ipaddr" ] && {
+ local wanif="$tunlink"
+ if [ -z $wanif ] && ! network_find_wan wanif; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ exit
+ fi
+
+ if ! network_get_ipaddr ipaddr "$wanif"; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ exit
+ fi
+ }
+
+ [ -z "$df" ] && df="1"
+
+ gre_generic_setup $cfg $mode $ipaddr $peeraddr "gre-$cfg"
+}
+
+proto_gre_setup() {
+ local cfg="$1"
+
+ gre_setup $cfg "greip"
+}
+
+proto_gretap_setup() {
+ local cfg="$1"
+
+ local network
+ json_get_vars network
+
+ gre_setup $cfg "gretapip"
+
+ json_init
+ json_add_string name "gre-$cfg"
+ json_add_boolean link-ext 0
+ json_close_object
+
+ for i in $network; do
+ ubus call network.interface."$i" add_device "$(json_dump)"
+ done
+}
+
+grev6_setup() {
+ local cfg="$1"
+ local mode="$2"
+
+ local ip6addr peer6addr weakif
+ json_get_vars ip6addr peer6addr tunlink weakif
+
+ [ -z "$peer6addr" ] && {
+ proto_notify_error "$cfg" "MISSING_ADDRESS"
+ proto_block_restart "$cfg"
+ exit
+ }
+
+ ( proto_add_host_dependency "$cfg" "$peer6addr" "$tunlink" )
+
+ [ -z "$ip6addr" ] && {
+ local wanif="$tunlink"
+ if [ -z $wanif ] && ! network_find_wan6 wanif; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ exit
+ fi
+
+ if ! network_get_ipaddr6 ip6addr "$wanif"; then
+ [ -z "$weakif" ] && weakif="lan"
+ if ! network_get_ipaddr6 ip6addr "$weakif"; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ exit
+ fi
+ fi
+ }
+
+ gre_generic_setup $cfg $mode $ip6addr $peer6addr "grev6-$cfg"
+}
+
+proto_grev6_setup() {
+ local cfg="$1"
+
+ grev6_setup $cfg "greip6"
+}
+
+proto_grev6tap_setup() {
+ local cfg="$1"
+
+ local network
+ json_get_vars network
+
+ grev6_setup $cfg "gretapip6"
+
+ json_init
+ json_add_string name "grev6-$cfg"
+ json_add_boolean link-ext 0
+ json_close_object
+
+ for i in $network; do
+ ubus call network.interface."$i" add_device "$(json_dump)"
+ done
+}
+
+gretap_generic_teardown() {
+ local network
+ json_get_vars network
+
+ json_init
+ json_add_string name "$1"
+ json_add_boolean link-ext 0
+ json_close_object
+
+ for i in $network; do
+ ubus call network.interface."$i" remove_device "$(json_dump)"
+ done
+}
+
+proto_gre_teardown() {
+ local cfg="$1"
+}
+
+proto_gretap_teardown() {
+ local cfg="$1"
+
+ gretap_generic_teardown "gre-$cfg"
+}
+
+proto_grev6_teardown() {
+ local cfg="$1"
+}
+
+proto_grev6tap_teardown() {
+ local cfg="$1"
+
+ gretap_generic_teardown "grev6-$cfg"
+}
+
+gre_generic_init_config() {
+ no_device=1
+ available=1
+
+ proto_config_add_int "mtu"
+ proto_config_add_int "ttl"
+ proto_config_add_string "tos"
+ proto_config_add_string "tunlink"
+ proto_config_add_string "zone"
+ proto_config_add_int "ikey"
+ proto_config_add_int "okey"
+ proto_config_add_boolean "icsum"
+ proto_config_add_boolean "ocsum"
+ proto_config_add_boolean "iseqno"
+ proto_config_add_boolean "oseqno"
+}
+
+proto_gre_init_config() {
+ gre_generic_init_config
+ proto_config_add_string "ipaddr"
+ proto_config_add_string "peeraddr"
+ proto_config_add_boolean "df"
+}
+
+proto_gretap_init_config() {
+ proto_gre_init_config
+ proto_config_add_string "network"
+}
+
+proto_grev6_init_config() {
+ gre_generic_init_config
+ proto_config_add_string "ip6addr"
+ proto_config_add_string "peer6addr"
+ proto_config_add_string "weakif"
+}
+
+proto_grev6tap_init_config() {
+ proto_grev6_init_config
+ proto_config_add_string "network"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ [ -f /lib/modules/$(uname -r)/gre.ko ] && add_protocol gre
+ [ -f /lib/modules/$(uname -r)/gre.ko ] && add_protocol gretap
+ [ -f /lib/modules/$(uname -r)/ip6_gre.ko ] && add_protocol grev6
+ [ -f /lib/modules/$(uname -r)/ip6_gre.ko ] && add_protocol grev6tap
+}
diff --git a/package/network/config/ipip/Makefile b/package/network/config/ipip/Makefile
new file mode 100644
index 0000000..5aa722d
--- /dev/null
+++ b/package/network/config/ipip/Makefile
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 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:=ipip
+PKG_VERSION:=1
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ipip
+ SECTION:=net
+ CATEGORY:=Network
+ MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
+ TITLE:=IP in IP Tunnel config support
+ DEPENDS:= +kmod-ipip
+endef
+
+define Package/ipip/description
+ IP in IP Tunnel config support in /etc/config/network.
+endef
+
+define Build/Compile
+endef
+
+define Build/Configure
+endef
+
+define Package/ipip/install
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/ipip.sh $(1)/lib/netifd/proto/ipip.sh
+endef
+
+$(eval $(call BuildPackage,ipip))
diff --git a/package/network/config/ipip/files/ipip.sh b/package/network/config/ipip/files/ipip.sh
new file mode 100755
index 0000000..51c503f
--- /dev/null
+++ b/package/network/config/ipip/files/ipip.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_ipip_setup() {
+ local cfg="$1"
+
+ local df ipaddr peeraddr tunlink ttl tos zone mtu
+ json_get_vars df ipaddr peeraddr tunlink ttl tos zone mtu
+
+ [ -z "$peeraddr" ] && {
+ proto_notify_error "$cfg" "MISSING_ADDRESS"
+ proto_block_restart "$cfg"
+ return
+ }
+
+ ( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" )
+
+ [ -z "$ipaddr" ] && {
+ local wanif="$tunlink"
+ if [ -z $wanif ] && ! network_find_wan wanif; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ return
+ fi
+
+ if ! network_get_ipaddr ipaddr "$wanif"; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ return
+ fi
+ }
+
+ [ -z "$zone" ] && zone="wan"
+
+ proto_init_update "ipip-$cfg" 1
+
+ proto_add_tunnel
+ json_add_string mode "ipip"
+ json_add_int mtu "${mtu:-1280}"
+ json_add_int ttl "${ttl:-64}"
+ [ -n "$tos" ] && json_add_string tos "$tos"
+ json_add_string local "$ipaddr"
+ json_add_string remote "$peeraddr"
+ [ -n "$tunlink" ] && json_add_string link "$tunlink"
+ json_add_boolean df "${df:-1}"
+
+ proto_close_tunnel
+
+ proto_add_data
+ [ -n "$zone" ] && json_add_string zone "$zone"
+ proto_close_data
+
+ proto_send_update "$cfg"
+}
+
+proto_ipip_teardown() {
+ local cfg="$1"
+}
+
+proto_ipip_init_config() {
+ no_device=1
+ available=1
+
+ proto_config_add_int "mtu"
+ proto_config_add_int "ttl"
+ proto_config_add_string "tos"
+ proto_config_add_string "tunlink"
+ proto_config_add_string "zone"
+ proto_config_add_string "ipaddr"
+ proto_config_add_string "peeraddr"
+ proto_config_add_boolean "df"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol ipip
+}
diff --git a/package/network/config/ltq-adsl-app/Makefile b/package/network/config/ltq-adsl-app/Makefile
new file mode 100644
index 0000000..9670119
--- /dev/null
+++ b/package/network/config/ltq-adsl-app/Makefile
@@ -0,0 +1,84 @@
+#
+# 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
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=dsl_cpe_control_danube
+PKG_VERSION:=3.24.4.4
+PKG_RELEASE:=2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_BUILD_DIR:=$(BUILD_DIR)/dsl_cpe_control-$(PKG_VERSION)
+PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
+PKG_MD5SUM:=ee315306626b68794d3d3636dabfe161
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=BSD-3-Clause
+
+PKG_FIXUP:=autoreconf
+
+PKG_CONFIG_DEPENDS:=\
+ CONFIG_LTQ_DSL_ENABLE_SOAP \
+ CONFIG_LTQ_DSL_ENABLE_DSL_EVENT_POLLING
+
+PKG_BUILD_DEPENDS:=TARGET_lantiq_xway:kmod-ltq-adsl-danube TARGET_lantiq_ase:kmod-ltq-adsl-ase
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ltq-adsl-app
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Lantiq DSL userland tool
+ URL:=http://www.lantiq.com/
+ DEPENDS:=@(TARGET_lantiq_xway||TARGET_lantiq_ase) +libpthread
+ MENU:=1
+endef
+
+define Package/ltq-adsl-app/description
+ Infineon DSL CPE API for Amazon SE, Danube and Vinax.
+endef
+
+LTQ_DSL_MAX_DEVICE=1
+LTQ_DSL_LINES_PER_DEVICE=1
+LTQ_DSL_CHANNELS_PER_LINE=1
+
+CONFIGURE_ARGS += \
+ --with-max-device="$(LTQ_DSL_MAX_DEVICE)" \
+ --with-lines-per-device="$(LTQ_DSL_LINES_PER_DEVICE)" \
+ --with-channels-per-line="$(LTQ_DSL_CHANNELS_PER_LINE)" \
+ --enable-danube \
+ --enable-driver-include="-I$(STAGING_DIR)/usr/include/adsl/" \
+ --enable-debug-prints \
+ --enable-add-appl-cflags="-DMAX_CLI_PIPES=2" \
+ --enable-cli-support \
+ --enable-cmv-scripts \
+ --enable-debug-tool-interface \
+ --enable-adsl-led \
+ --enable-dsl-ceoc \
+ --enable-script-notification \
+ --enable-dsl-pm \
+ --enable-dsl-pm-total \
+ --enable-dsl-pm-history \
+ --enable-dsl-pm-showtime \
+ --enable-dsl-pm-channel-counters \
+ --enable-dsl-pm-datapath-counters \
+ --enable-dsl-pm-line-counters \
+ --enable-dsl-pm-channel-thresholds \
+ --enable-dsl-pm-datapath-thresholds \
+ --enable-dsl-pm-line-thresholds \
+ --enable-dsl-pm-optional-parameters
+
+TARGET_CFLAGS += -I$(LINUX_DIR)/include
+
+define Package/ltq-adsl-app/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/dsl_control $(1)/etc/init.d/
+
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dsl_cpe_control $(1)/sbin
+endef
+
+$(eval $(call BuildPackage,ltq-adsl-app))
diff --git a/package/network/config/ltq-adsl-app/files/dsl_control b/package/network/config/ltq-adsl-app/files/dsl_control
new file mode 100644
index 0000000..cece347
--- /dev/null
+++ b/package/network/config/ltq-adsl-app/files/dsl_control
@@ -0,0 +1,59 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2012 OpenWrt.org
+
+START=99
+
+EXTRA_COMMANDS="status lucistat"
+EXTRA_HELP=" status Get DSL status information
+ lucistat Get status information if lua friendly format"
+
+SERVICE_DAEMONIZE=1
+SERVICE_WRITE_PID=1
+
+[ -f /lib/functions/lantiq_dsl.sh ] && . /lib/functions/lantiq_dsl.sh
+
+annex_b=10_00_10_00_00_04_00_00
+annex_bdmt=10_00_00_00_00_00_00_00
+annex_b2=00_00_10_00_00_00_00_00
+annex_b2p=00_00_00_00_00_04_00_00
+annex_a=04_01_04_00_00_01_00_00
+annex_at1=01_00_00_00_00_00_00_00
+annex_alite=00_01_00_00_00_00_00_00
+annex_admt=04_00_00_00_00_00_00_00
+annex_a2=00_00_04_00_00_00_00_00
+annex_a2p=00_00_00_00_00_01_00_00
+annex_l=00_00_00_00_04_00_00_00
+annex_m=00_00_00_00_40_00_04_00
+annex_m2=00_00_00_00_40_00_00_00
+annex_m2p=00_00_00_00_00_00_04_00
+
+start() {
+ local annex
+ local firmware
+ local xtu
+ config_load network
+ config_get annex dsl annex
+ config_get firmware dsl firmware
+
+ eval "xtu=\"\${annex_$annex}\""
+
+ [ -z "${firmware}" ] &&
+ firmware=/lib/firmware/adsl.bin
+ [ -f "${firmware}" ] || {
+ echo failed to find $firmware
+ return 1
+ }
+
+ service_start /sbin/dsl_cpe_control -i${xtu} \
+ -n /sbin/dsl_notify.sh \
+ -f ${firmware}
+}
+
+stop() {
+ DSL_NOTIFICATION_TYPE="DSL_INTERFACE_STATUS" \
+ DSL_INTERFACE_STATUS="DOWN" \
+ /sbin/dsl_notify.sh
+
+ service_stop /sbin/dsl_cpe_control
+}
+
diff --git a/package/network/config/ltq-adsl-app/patches/010-eglibc_compile_fix.patch b/package/network/config/ltq-adsl-app/patches/010-eglibc_compile_fix.patch
new file mode 100644
index 0000000..268f868
--- /dev/null
+++ b/package/network/config/ltq-adsl-app/patches/010-eglibc_compile_fix.patch
@@ -0,0 +1,23 @@
+--- a/configure.in
++++ b/configure.in
+@@ -29,6 +29,8 @@ AC_C_VOLATILE
+ #AC_FUNC_STRTOD
+ #AC_CHECK_FUNCS([ftime gethostbyname gettimeofday localtime_r memset select socket strchr strerror strstr strtoull])
+
++AC_SEARCH_LIBS([clock_gettime],[rt])
++
+ #
+ # save the configure arguments
+ #
+--- a/src/dsl_cpe_linux.h
++++ b/src/dsl_cpe_linux.h
+@@ -45,7 +45,8 @@
+ #include <arpa/inet.h>
+ #include <sys/socket.h> /* socket */
+ #include <sys/sem.h> /* semget */
+-#include <semaphore.h> /* sem_t */
++#include <semaphore.h> /* sem_t */
++#include <limits.h>
+
+ #ifdef DSL_DEBUG_TOOL_INTERFACE
+ #include <sys/socket.h>
diff --git a/package/network/config/ltq-vdsl-app/Makefile b/package/network/config/ltq-vdsl-app/Makefile
new file mode 100644
index 0000000..061a966
--- /dev/null
+++ b/package/network/config/ltq-vdsl-app/Makefile
@@ -0,0 +1,78 @@
+# Copyright (C) 2010 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:=ltq-vdsl-app
+PKG_VERSION:=4.16.2.4
+PKG_RELEASE:=1
+PKG_BASE_NAME:=dsl_cpe_control_vrx
+PKG_SOURCE:=$(PKG_BASE_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/xdarklight/$(PKG_BASE_NAME)/archive/v$(PKG_VERSION)
+PKG_MD5SUM:=487925ef5327ea38c544035b388de8bb
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_BASE_NAME)-$(PKG_VERSION)
+PKG_LICENSE:=BSD-2-Clause
+
+PKG_BUILD_DEPENDS:=kmod-ltq-vdsl-vr9
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ltq-vdsl-app
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Lantiq VDSL userland tool
+ URL:=http://www.lantiq.com/
+ DEPENDS:=@TARGET_lantiq_xrx200 +libpthread +librt
+endef
+
+define Package/ltq-vdsl-app/description
+ Userland tool needed to control Lantiq VDSL CPE
+endef
+
+CONFIGURE_ARGS += \
+ --with-max-device="1" \
+ --with-lines-per-device="1" \
+ --with-channels-per-line="1" \
+ --enable-vrx \
+ --enable-driver-include="-I$(STAGING_DIR)/usr/include/drv_vdsl_cpe_api" \
+ --enable-device-driver-include="-I$(STAGING_DIR)/usr/include/vdsl/" \
+ --enable-add-appl-cflags="-DMAX_CLI_PIPES=2" \
+ --enable-ifxos \
+ --enable-ifxos-include="-I$(STAGING_DIR)/usr/include/ifxos" \
+ --enable-ifxos-library="-I$(STAGING_DIR)/usr/lib" \
+ --disable-dsl-ceoc \
+ --enable-dsl-pm-total \
+ --enable-dsl-pm-showtime \
+ --enable-dsl-pm-line-counters \
+ --enable-dsl-pm-line-failure-counters \
+ --enable-dsl-pm-datapath-counters \
+ --enable-dsl-pm-datapath-failure-counters \
+ --enable-deprecated \
+ --disable-soap-support \
+ --enable-dsl-bonding=no \
+ --enable-debug-prints=err \
+ --disable-dti
+
+ifeq ($(CONFIG_IFX_CLI),y)
+CONFIGURE_ARGS += \
+ --enable-cli-support
+endif
+
+CONFIGURE_ARGS += --enable-model=full
+#CONFIGURE_ARGS += --enable-model=lite
+#CONFIGURE_ARGS += --enable-model=footprint
+#CONFIGURE_ARGS += --enable-model=typical
+#CONFIGURE_ARGS += --enable-model=debug
+
+define Package/ltq-vdsl-app/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/dsl_control $(1)/etc/init.d/
+
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dsl_cpe_control $(1)/sbin/vdsl_cpe_control
+endef
+
+$(eval $(call BuildPackage,ltq-vdsl-app))
diff --git a/package/network/config/ltq-vdsl-app/files/dsl_control b/package/network/config/ltq-vdsl-app/files/dsl_control
new file mode 100644
index 0000000..394e1c0
--- /dev/null
+++ b/package/network/config/ltq-vdsl-app/files/dsl_control
@@ -0,0 +1,91 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2012 OpenWrt.org
+
+# needs to start before the atm layer which starts at 50
+START=48
+
+EXTRA_COMMANDS="status lucistat"
+EXTRA_HELP=" status Get DSL status information
+ lucistat Get status information if lua friendly format"
+
+SERVICE_DAEMONIZE=1
+SERVICE_WRITE_PID=1
+
+[ -f /lib/functions/lantiq_dsl.sh ] && . /lib/functions/lantiq_dsl.sh
+
+# G.992.1 Annex A
+# G.992.2 Annex A
+# G.992.3 Annex A
+# G.992.4 Annex A
+# G.992.5 Annex A
+# G.993.2 Annex A/B/C
+xtse_adsl_a="04 01 04 01 00 01 00 00"
+
+# G.992.1 Annex B
+# G.992.3 Annex B
+# G.992.5 Annex B
+# G.993.2 Annex A/B/C
+xtse_adsl_b="10 00 10 00 00 04 00 00"
+
+# G.992.1 Annex B
+# G.992.3 Annex B
+# G.992.3 Annex J
+# G.992.5 Annex B
+# G.992.5 Annex J
+# G.993.2 Annex A/B/C
+xtse_adsl_j="10 00 10 40 00 04 01 00"
+
+xtse_vdsl="00 00 00 00 00 00 00 07"
+
+start() {
+ local annex
+ local firmware
+ local xtse
+ local xtse_adsl
+ local mode
+
+ config_load network
+ config_get annex dsl annex
+ config_get firmware dsl firmware
+ config_get xfer_mode dsl xfer_mode
+
+ [ -z "${xfer_mode}" ] && xfer_mode=ptm
+
+ case "${xfer_mode}" in
+ atm)
+ insmod ltq_atm_vr9
+ mode=1
+ ;;
+ *)
+ insmod ltq_ptm_vr9
+ mode=2
+ ;;
+ esac
+
+ eval "xtse_adsl=\"\${xtse_adsl_$annex}\""
+ if [ "${xtse_adsl}" ]; then
+ xtse=$xtse_adsl
+ else
+ xtse=$xtse_vdsl
+ fi
+
+ [ -z "${firmware}" ] && firmware=/lib/firmware/vdsl.bin
+ [ -f "${firmware}" ] || {
+ echo failed to find $firmware
+ return 1
+ }
+
+ service_start /sbin/vdsl_cpe_control \
+ -i `echo $xtse | sed "s/ /_/g"` \
+ -n /sbin/dsl_notify.sh \
+ -f ${firmware} \
+ -M ${mode}
+}
+
+stop() {
+ DSL_NOTIFICATION_TYPE="DSL_INTERFACE_STATUS" \
+ DSL_INTERFACE_STATUS="DOWN" \
+ /sbin/dsl_notify.sh
+
+ service_stop /sbin/vdsl_cpe_control
+}
diff --git a/package/network/config/ltq-vdsl-app/patches/100-compat.patch b/package/network/config/ltq-vdsl-app/patches/100-compat.patch
new file mode 100644
index 0000000..eeedc54
--- /dev/null
+++ b/package/network/config/ltq-vdsl-app/patches/100-compat.patch
@@ -0,0 +1,22 @@
+--- a/src/dsl_cpe_init_cfg.c
++++ b/src/dsl_cpe_init_cfg.c
+@@ -38,7 +38,7 @@ DSL_InitData_t gInitCfgData =
+ DSL_DEV_HS_TONE_GROUP_CLEANED, \
+ DSL_DEV_HS_TONE_GROUP_CLEANED, \
+ DSL_DEV_HS_TONE_GROUP_CLEANED, \
+- 0x1E116000, 0x37, -1),
++ 0x1E116000, 0x3f, -1),
+ DSL_CPE_SIC_SET(DSL_TC_ATM, DSL_EMF_TC_CLEANED, DSL_EMF_TC_CLEANED, DSL_SYSTEMIF_MII, \
+ DSL_TC_EFM, DSL_EMF_TC_CLEANED, DSL_EMF_TC_CLEANED, DSL_SYSTEMIF_MII),
+ }
+--- a/src/dsl_cpe_control.c
++++ b/src/dsl_cpe_control.c
+@@ -6856,7 +6856,7 @@ DSL_int_t dsl_cpe_daemon (
+ for (nDevice = 0; nDevice < DSL_CPE_MAX_DSL_ENTITIES; nDevice++)
+ {
+ #if defined(INCLUDE_DSL_CPE_API_VRX)
+- sprintf (device, "%s/%d", DSL_CPE_DEVICE_NAME, nDevice);
++ sprintf (device, "%s%d", DSL_CPE_DEVICE_NAME, nDevice);
+ #else
+ sprintf (device, "%s", DSL_CPE_DEVICE_NAME);
+ #endif /* defined(INCLUDE_DSL_CPE_API_VRX)*/
diff --git a/package/network/config/ltq-vdsl-app/patches/101-musl.patch b/package/network/config/ltq-vdsl-app/patches/101-musl.patch
new file mode 100644
index 0000000..9982426
--- /dev/null
+++ b/package/network/config/ltq-vdsl-app/patches/101-musl.patch
@@ -0,0 +1,10 @@
+--- a/src/dsl_cpe_control.c
++++ b/src/dsl_cpe_control.c
+@@ -12,6 +12,7 @@
+ /*
+ Includes
+ */
++#include <limits.h>
+ #include "dsl_cpe_control.h"
+ #include "dsl_cpe_cli.h"
+ #include "dsl_cpe_cli_console.h"
diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile
new file mode 100644
index 0000000..beacd50
--- /dev/null
+++ b/package/network/config/netifd/Makefile
@@ -0,0 +1,46 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=netifd
+PKG_VERSION:=2015-09-27
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=http://git.openwrt.org/project/netifd.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=509ffb22475ebdd5291d510a098f996473951344
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+# PKG_MIRROR_MD5SUM:=
+# CMAKE_INSTALL:=1
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/netifd
+ SECTION:=base
+ CATEGORY:=Base system
+ DEPENDS:=+libuci +libnl-tiny +libubus +ubus +ubusd +jshn +libubox
+ TITLE:=OpenWrt Network Interface Configuration Daemon
+endef
+
+TARGET_CFLAGS += \
+ -I$(STAGING_DIR)/usr/include/libnl-tiny \
+ -I$(STAGING_DIR)/usr/include
+
+CMAKE_OPTIONS += \
+ -DLIBNL_LIBS=-lnl-tiny \
+ -DDEBUG=1
+
+define Package/netifd/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/netifd $(1)/sbin/
+ $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/scripts/* $(1)/lib/netifd/
+endef
+
+$(eval $(call BuildPackage,netifd))
diff --git a/package/network/config/netifd/files/etc/hotplug.d/iface/00-netstate b/package/network/config/netifd/files/etc/hotplug.d/iface/00-netstate
new file mode 100644
index 0000000..023025c
--- /dev/null
+++ b/package/network/config/netifd/files/etc/hotplug.d/iface/00-netstate
@@ -0,0 +1,7 @@
+[ ifup = "$ACTION" ] && {
+ uci_toggle_state network "$INTERFACE" up 1
+ [ -n "$DEVICE" ] && {
+ uci_toggle_state network "$INTERFACE" device "$(uci -q get network.$INTERFACE.ifname)"
+ uci_toggle_state network "$INTERFACE" ifname "$DEVICE"
+ }
+}
diff --git a/package/network/config/netifd/files/etc/init.d/network b/package/network/config/netifd/files/etc/init.d/network
new file mode 100755
index 0000000..bdadbbc
--- /dev/null
+++ b/package/network/config/netifd/files/etc/init.d/network
@@ -0,0 +1,151 @@
+#!/bin/sh /etc/rc.common
+
+START=20
+STOP=90
+
+USE_PROCD=1
+
+init_switch() {
+ setup_switch() { return 0; }
+
+ include /lib/network
+ setup_switch
+}
+
+start_service() {
+ init_switch
+
+ procd_open_instance
+ procd_set_param command /sbin/netifd
+ procd_set_param respawn
+ procd_set_param watch network.interface
+ [ -e /proc/sys/kernel/core_pattern ] && {
+ procd_set_param limits core="unlimited"
+ }
+ procd_close_instance
+}
+
+reload_service() {
+ init_switch
+ ubus call network reload
+ /sbin/wifi reload_legacy
+}
+
+stop() {
+ /sbin/wifi down
+ procd_kill network ''
+}
+
+service_running() {
+ ubus -t 30 wait_for network.interface
+ /sbin/wifi reload_legacy
+}
+
+validate_atm_bridge_section()
+{
+ uci_validate_section network "atm-bridge" "${1}" \
+ 'unit:uinteger:0' \
+ 'vci:range(32, 65535):35' \
+ 'vpi:range(0, 255):8' \
+ 'atmdev:uinteger:0' \
+ 'encaps:or("llc", "vc"):llc' \
+ 'payload:or("bridged", "routed"):bridged'
+}
+
+validate_route_section()
+{
+ uci_validate_section network route "${1}" \
+ 'interface:string' \
+ 'target:cidr4' \
+ 'netmask:netmask4' \
+ 'gateway:ip4addr' \
+ 'metric:uinteger' \
+ 'mtu:uinteger' \
+ 'table:or(range(0,65535),string)'
+}
+
+validate_route6_section()
+{
+ uci_validate_section network route6 "${1}" \
+ 'interface:string' \
+ 'target:cidr6' \
+ 'gateway:ip6addr' \
+ 'metric:uinteger' \
+ 'mtu:uinteger' \
+ 'table:or(range(0,65535),string)'
+}
+
+validate_rule_section()
+{
+ uci_validate_section network rule "${1}" \
+ 'in:string' \
+ 'out:string' \
+ 'src:cidr4' \
+ 'dest:cidr4' \
+ 'tos:range(0,31)' \
+ 'mark:string' \
+ 'invert:bool' \
+ 'lookup:or(range(0,65535),string)' \
+ 'goto:range(0,65535)' \
+ 'action:or("prohibit", "unreachable", "blackhole", "throw")'
+}
+
+validate_rule6_section()
+{
+ uci_validate_section network rule6 "${1}" \
+ 'in:string' \
+ 'out:string' \
+ 'src:cidr6' \
+ 'dest:cidr6' \
+ 'tos:range(0,31)' \
+ 'mark:string' \
+ 'invert:bool' \
+ 'lookup:or(range(0,65535),string)' \
+ 'goto:range(0,65535)' \
+ 'action:or("prohibit", "unreachable", "blackhole", "throw")'
+}
+
+validate_switch_section()
+{
+ uci_validate_section network switch "${1}" \
+ 'name:string' \
+ 'enable:bool' \
+ 'enable_vlan:bool' \
+ 'reset:bool'
+}
+
+validate_switch_vlan()
+{
+ uci_validate_section network switch_vlan "${1}" \
+ 'device:string' \
+ 'vlan:uinteger' \
+ 'ports:list(ports)'
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger network wireless
+
+ procd_open_validate
+ validate_atm_bridge_section
+ validate_route_section
+ validate_route6_section
+ validate_rule_section
+ validate_rule6_section
+ validate_switch_section
+ validate_switch_vlan
+ procd_close_validate
+}
+
+restart() {
+ ifdown -a
+ sleep 1
+ trap '' TERM
+ stop "$@"
+ start "$@"
+}
+
+shutdown() {
+ ifdown -a
+ sleep 1
+}
diff --git a/package/network/config/netifd/files/lib/netifd/dhcp.script b/package/network/config/netifd/files/lib/netifd/dhcp.script
new file mode 100755
index 0000000..b3a61e2
--- /dev/null
+++ b/package/network/config/netifd/files/lib/netifd/dhcp.script
@@ -0,0 +1,102 @@
+#!/bin/sh
+[ -z "$1" ] && echo "Error: should be run by udhcpc" && exit 1
+
+. /lib/functions.sh
+. /lib/netifd/netifd-proto.sh
+
+set_classless_routes() {
+ local max=128
+ while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do
+ proto_add_ipv4_route "${1%%/*}" "${1##*/}" "$2" "$ip"
+ max=$(($max-1))
+ shift 2
+ done
+}
+
+setup_interface () {
+ proto_init_update "*" 1
+ proto_add_ipv4_address "$ip" "${subnet:-255.255.255.0}"
+ # TODO: apply $broadcast
+
+ for i in $router; do
+ proto_add_ipv4_route "$i" 32 "" "$ip"
+ proto_add_ipv4_route 0.0.0.0 0 "$i" "$ip"
+
+ for r in $CUSTOMROUTES; do
+ proto_add_ipv4_route "${r%%/*}" "${r##*/}" "$i" "$ip"
+ done
+ done
+
+ # CIDR STATIC ROUTES (rfc3442)
+ [ -n "$staticroutes" ] && set_classless_routes $staticroutes
+ [ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes
+
+ for dns in $dns; do
+ proto_add_dns_server "$dns"
+ done
+ for domain in $domain; do
+ proto_add_dns_search "$domain"
+ done
+
+ proto_add_data
+ [ -n "$ZONE" ] && json_add_string zone "$ZONE"
+ [ -n "$ntpsrv" ] && json_add_string ntpserver "$ntpsrv"
+ [ -n "$timesvr" ] && json_add_string timeserver "$timesvr"
+ [ -n "$hostname" ] && json_add_string hostname "$hostname"
+ [ -n "$message" ] && json_add_string message "$message"
+ [ -n "$timezone" ] && json_add_int timezone "$timezone"
+ [ -n "$lease" ] && json_add_int leasetime "$lease"
+ proto_close_data
+
+ proto_send_update "$INTERFACE"
+
+
+ if [ "$IFACE6RD" != 0 -a -n "$ip6rd" ]; then
+ local v4mask="${ip6rd%% *}"
+ ip6rd="${ip6rd#* }"
+ local ip6rdprefixlen="${ip6rd%% *}"
+ ip6rd="${ip6rd#* }"
+ local ip6rdprefix="${ip6rd%% *}"
+ ip6rd="${ip6rd#* }"
+ local ip6rdbr="${ip6rd%% *}"
+
+ [ -n "$ZONE" ] || ZONE=$(fw3 -q network $INTERFACE)
+ [ -z "$IFACE6RD" -o "$IFACE6RD" = 1 ] && IFACE6RD=${INTERFACE}_6
+
+ json_init
+ json_add_string name "$IFACE6RD"
+ json_add_string ifname "@$INTERFACE"
+ json_add_string proto "6rd"
+ json_add_string peeraddr "$ip6rdbr"
+ json_add_int ip4prefixlen "$v4mask"
+ json_add_string ip6prefix "$ip6rdprefix"
+ json_add_int ip6prefixlen "$ip6rdprefixlen"
+ json_add_string tunlink "$INTERFACE"
+ [ -n "$IFACE6RD_DELEGATE" ] && json_add_boolean delegate "$IFACE6RD_DELEGATE"
+ [ -n "$ZONE6RD" ] || ZONE6RD=$ZONE
+ [ -n "$ZONE6RD" ] && json_add_string zone "$ZONE6RD"
+ [ -n "$MTU6RD" ] && json_add_string mtu "$MTU6RD"
+ json_close_object
+
+ ubus call network add_dynamic "$(json_dump)"
+ fi
+}
+
+deconfig_interface() {
+ proto_init_update "*" 0
+ proto_send_update "$INTERFACE"
+}
+
+case "$1" in
+ deconfig)
+ deconfig_interface
+ ;;
+ renew|bound)
+ setup_interface
+ ;;
+esac
+
+# user rules
+[ -f /etc/udhcpc.user ] && . /etc/udhcpc.user "$@"
+
+exit 0
diff --git a/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh b/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh
new file mode 100755
index 0000000..0e88af9
--- /dev/null
+++ b/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. ../netifd-proto.sh
+init_proto "$@"
+
+proto_dhcp_init_config() {
+ renew_handler=1
+
+ proto_config_add_string 'ipaddr:ipaddr'
+ proto_config_add_string 'hostname:hostname'
+ proto_config_add_string clientid
+ proto_config_add_string vendorid
+ proto_config_add_boolean 'broadcast:bool'
+ proto_config_add_string 'reqopts:list(string)'
+ proto_config_add_string iface6rd
+ proto_config_add_string sendopts
+ proto_config_add_boolean delegate
+ proto_config_add_string zone6rd
+ proto_config_add_string zone
+ proto_config_add_string mtu6rd
+ proto_config_add_string customroutes
+}
+
+proto_dhcp_setup() {
+ local config="$1"
+ local iface="$2"
+
+ local ipaddr hostname clientid vendorid broadcast reqopts iface6rd sendopts delegate zone6rd zone mtu6rd customroutes
+ json_get_vars ipaddr hostname clientid vendorid broadcast reqopts iface6rd sendopts delegate zone6rd zone mtu6rd customroutes
+
+ local opt dhcpopts
+ for opt in $reqopts; do
+ append dhcpopts "-O $opt"
+ done
+
+ for opt in $sendopts; do
+ append dhcpopts "-x $opt"
+ done
+
+ [ "$broadcast" = 1 ] && broadcast="-B" || broadcast=
+ [ -n "$clientid" ] && clientid="-x 0x3d:${clientid//:/}" || clientid="-C"
+ [ -n "$iface6rd" ] && proto_export "IFACE6RD=$iface6rd"
+ [ "$iface6rd" != 0 -a -f /lib/netifd/proto/6rd.sh ] && append dhcpopts "-O 212"
+ [ -n "$zone6rd" ] && proto_export "ZONE6RD=$zone6rd"
+ [ -n "$zone" ] && proto_export "ZONE=$zone"
+ [ -n "$mtu6rd" ] && proto_export "MTU6RD=$mtu6rd"
+ [ -n "$customroutes" ] && proto_export "CUSTOMROUTES=$customroutes"
+ [ "$delegate" = "0" ] && proto_export "IFACE6RD_DELEGATE=0"
+
+ proto_export "INTERFACE=$config"
+ proto_run_command "$config" udhcpc \
+ -p /var/run/udhcpc-$iface.pid \
+ -s /lib/netifd/dhcp.script \
+ -f -t 0 -i "$iface" \
+ ${ipaddr:+-r $ipaddr} \
+ ${hostname:+-H $hostname} \
+ ${vendorid:+-V $vendorid} \
+ $clientid $broadcast $dhcpopts
+}
+
+proto_dhcp_renew() {
+ local interface="$1"
+ # SIGUSR1 forces udhcpc to renew its lease
+ local sigusr1="$(kill -l SIGUSR1)"
+ [ -n "$sigusr1" ] && proto_kill_command "$interface" $sigusr1
+}
+
+proto_dhcp_teardown() {
+ local interface="$1"
+ proto_kill_command "$interface"
+}
+
+add_protocol dhcp
diff --git a/package/network/config/netifd/files/lib/network/config.sh b/package/network/config/netifd/files/lib/network/config.sh
new file mode 100755
index 0000000..9128971
--- /dev/null
+++ b/package/network/config/netifd/files/lib/network/config.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+# Copyright (C) 2011 OpenWrt.org
+
+. /usr/share/libubox/jshn.sh
+
+find_config() {
+ local device="$1"
+ local ifdev ifl3dev ifobj
+ for ifobj in `ubus list network.interface.\*`; do
+ interface="${ifobj##network.interface.}"
+ (
+ json_load "$(ifstatus $interface)"
+ json_get_var ifdev device
+ json_get_var ifl3dev l3_device
+ if [[ "$device" = "$ifdev" ]] || [[ "$device" = "$ifl3dev" ]]; then
+ echo "$interface"
+ exit 0
+ else
+ exit 1
+ fi
+ ) && return
+ done
+}
+
+unbridge() {
+ return
+}
+
+ubus_call() {
+ json_init
+ local _data="$(ubus -S call "$1" "$2")"
+ [ -z "$_data" ] && return 1
+ json_load "$_data"
+ return 0
+}
+
+
+fixup_interface() {
+ local config="$1"
+ local ifname type device l3dev
+
+ config_get type "$config" type
+ config_get ifname "$config" ifname
+ config_get device "$config" device "$ifname"
+ [ "bridge" = "$type" ] && ifname="br-$config"
+ config_set "$config" device "$ifname"
+ ubus_call "network.interface.$config" status || return 0
+ json_get_var l3dev l3_device
+ [ -n "$l3dev" ] && ifname="$l3dev"
+ json_init
+ config_set "$config" ifname "$ifname"
+ config_set "$config" device "$device"
+}
+
+scan_interfaces() {
+ config_load network
+ config_foreach fixup_interface interface
+}
+
+prepare_interface_bridge() {
+ local config="$1"
+
+ [ -n "$config" ] || return 0
+ ubus call network.interface."$config" prepare
+}
+
+setup_interface() {
+ local iface="$1"
+ local config="$2"
+
+ [ -n "$config" ] || return 0
+ ubus call network.interface."$config" add_device "{ \"name\": \"$iface\" }"
+}
+
+do_sysctl() {
+ [ -n "$2" ] && \
+ sysctl -n -e -w "$1=$2" >/dev/null || \
+ sysctl -n -e "$1"
+}
diff --git a/package/network/config/netifd/files/sbin/devstatus b/package/network/config/netifd/files/sbin/devstatus
new file mode 100755
index 0000000..3c35b26
--- /dev/null
+++ b/package/network/config/netifd/files/sbin/devstatus
@@ -0,0 +1,12 @@
+#!/bin/sh
+. /usr/share/libubox/jshn.sh
+DEVICE="$1"
+
+[ -n "$DEVICE" ] || {
+ echo "Usage: $0 <device>"
+ exit 1
+}
+
+json_init
+json_add_string name "$DEVICE"
+ubus call network.device status "$(json_dump)"
diff --git a/package/network/config/netifd/files/sbin/ifdown b/package/network/config/netifd/files/sbin/ifdown
new file mode 120000
index 0000000..a0e5c17
--- /dev/null
+++ b/package/network/config/netifd/files/sbin/ifdown
@@ -0,0 +1 @@
+ifup \ No newline at end of file
diff --git a/package/network/config/netifd/files/sbin/ifstatus b/package/network/config/netifd/files/sbin/ifstatus
new file mode 100755
index 0000000..8a951e6
--- /dev/null
+++ b/package/network/config/netifd/files/sbin/ifstatus
@@ -0,0 +1,13 @@
+#!/bin/sh
+INTERFACE="$1"
+
+[ -n "$INTERFACE" ] || {
+ echo "Usage: $0 <interface>"
+ exit 1
+}
+
+ubus -S list "network.interface.$INTERFACE" >/dev/null || {
+ echo "Interface $INTERFACE not found"
+ exit 1
+}
+ubus call network.interface status "{ \"interface\" : \"$INTERFACE\" }"
diff --git a/package/network/config/netifd/files/sbin/ifup b/package/network/config/netifd/files/sbin/ifup
new file mode 100755
index 0000000..af3aaa8
--- /dev/null
+++ b/package/network/config/netifd/files/sbin/ifup
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+ifup_all=
+setup_wifi=
+
+if_call() {
+ local interface="$1"
+ for mode in $modes; do
+ ubus call network.interface $mode "{ \"interface\" : \"$interface\" }"
+ done
+}
+
+case "$0" in
+ *ifdown) modes=down;;
+ *ifup)
+ modes="down up"
+ setup_wifi=1
+ ;;
+ *) echo "Invalid command: $0";;
+esac
+
+while :; do
+ case "$1" in
+ -a)
+ ifup_all=1
+ shift
+ ;;
+ -w)
+ setup_wifi=
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+[ "$modes" = "down up" ] && ubus call network reload
+if [ -n "$ifup_all" ]; then
+ for interface in `ubus -S list 'network.interface.*'`; do
+ if_call "${interface##network.interface.}"
+ done
+ [ -n "$setup_wifi" ] && /sbin/wifi up
+ exit
+else
+ ubus -S list "network.interface.$1" > /dev/null || {
+ echo "Interface $1 not found"
+ exit
+ }
+ if_call "$1"
+fi
+
+if [ -n "$setup_wifi" ] && grep -sq config /etc/config/wireless; then
+ . /lib/functions.sh
+
+ find_related_radios() {
+ local wdev wnet
+ config_get wdev "$1" device
+ config_get wnet "$1" network
+
+ if [ -n "$wdev" ]; then
+ for wnet in $wnet; do
+ if [ "$wnet" = "$network" ]; then
+ append radio_devs "$wdev" "$N"
+ fi
+ done
+ fi
+ }
+
+ local radio_devs
+ local network="$1"
+ config_load wireless
+ config_foreach find_related_radios wifi-iface
+
+ local dev
+ for dev in $(echo "$radio_devs" | sort -u); do
+ /sbin/wifi up "$dev"
+ done
+fi
diff --git a/package/network/config/netifd/files/usr/share/udhcpc/default.script b/package/network/config/netifd/files/usr/share/udhcpc/default.script
new file mode 100755
index 0000000..ac765a6
--- /dev/null
+++ b/package/network/config/netifd/files/usr/share/udhcpc/default.script
@@ -0,0 +1,57 @@
+#!/bin/sh
+[ -z "$1" ] && echo "Error: should be run by udhcpc" && exit 1
+
+set_classless_routes() {
+ local max=128
+ local type
+ while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do
+ [ ${1##*/} -eq 32 ] && type=host || type=net
+ echo "udhcpc: adding route for $type $1 via $2"
+ route add -$type "$1" gw "$2" dev "$interface"
+ max=$(($max-1))
+ shift 2
+ done
+}
+
+setup_interface() {
+ echo "udhcpc: ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}"
+ ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}
+
+ [ -n "$router" ] && [ "$router" != "0.0.0.0" ] && [ "$router" != "255.255.255.255" ] && {
+ echo "udhcpc: setting default routers: $router"
+
+ local valid_gw=""
+ for i in $router ; do
+ route add default gw $i dev $interface
+ valid_gw="${valid_gw:+$valid_gw|}$i"
+ done
+
+ eval $(route -n | awk '
+ /^0.0.0.0\W{9}('$valid_gw')\W/ {next}
+ /^0.0.0.0/ {print "route del -net "$1" gw "$2";"}
+ ')
+ }
+
+ # CIDR STATIC ROUTES (rfc3442)
+ [ -n "$staticroutes" ] && set_classless_routes $staticroutes
+ [ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes
+}
+
+
+applied=
+case "$1" in
+ deconfig)
+ ifconfig "$interface" 0.0.0.0
+ ;;
+ renew)
+ setup_interface update
+ ;;
+ bound)
+ setup_interface ifup
+ ;;
+esac
+
+# user rules
+[ -f /etc/udhcpc.user ] && . /etc/udhcpc.user
+
+exit 0
diff --git a/package/network/config/qos-scripts/Makefile b/package/network/config/qos-scripts/Makefile
new file mode 100644
index 0000000..9118c00
--- /dev/null
+++ b/package/network/config/qos-scripts/Makefile
@@ -0,0 +1,52 @@
+#
+# 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:=qos-scripts
+PKG_VERSION:=1.2.1
+PKG_RELEASE:=7
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/qos-scripts
+ SECTION:=utils
+ CATEGORY:=Base system
+ DEPENDS:=+tc +kmod-sched-core +kmod-sched-connmark +kmod-ifb +iptables +iptables-mod-ipopt +iptables-mod-conntrack-extra
+ TITLE:=QoS scripts
+ PKGARCH:=all
+endef
+
+define Package/qos-scripts/description
+ A set of scripts that abstract QoS configuration into a simple
+ configuration file supporting stanzas that specify any number of QoS
+ entries.
+endef
+
+define Package/qos-scripts/conffiles
+/etc/config/qos
+endef
+
+define Build/Prepare
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/qos-scripts/install
+ $(INSTALL_DIR) $(1)
+ $(CP) ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,qos-scripts))
diff --git a/package/network/config/qos-scripts/files/etc/config/qos b/package/network/config/qos-scripts/files/etc/config/qos
new file mode 100644
index 0000000..44e988a
--- /dev/null
+++ b/package/network/config/qos-scripts/files/etc/config/qos
@@ -0,0 +1,68 @@
+# QoS configuration for OpenWrt
+
+# INTERFACES:
+config interface wan
+ option classgroup "Default"
+ option enabled 0
+ option upload 128
+ option download 1024
+
+# RULES:
+config classify
+ option target "Priority"
+ option ports "22,53"
+ option comment "ssh, dns"
+config classify
+ option target "Normal"
+ option proto "tcp"
+ option ports "20,21,25,80,110,443,993,995"
+ option comment "ftp, smtp, http(s), imap"
+config classify
+ option target "Express"
+ option ports "5190"
+ option comment "AOL, iChat, ICQ"
+config default
+ option target "Express"
+ option proto "udp"
+ option pktsize "-500"
+config reclassify
+ option target "Priority"
+ option proto "icmp"
+config default
+ option target "Bulk"
+ option portrange "1024-65535"
+
+
+# Don't change the stuff below unless you
+# really know what it means :)
+
+config classgroup "Default"
+ option classes "Priority Express Normal Bulk"
+ option default "Normal"
+
+
+config class "Priority"
+ option packetsize 400
+ option avgrate 10
+ option priority 20
+config class "Priority_down"
+ option packetsize 1000
+ option avgrate 10
+
+
+config class "Express"
+ option packetsize 1000
+ option avgrate 50
+ option priority 10
+
+config class "Normal"
+ option packetsize 1500
+ option packetdelay 100
+ option avgrate 10
+ option priority 5
+config class "Normal_down"
+ option avgrate 20
+
+config class "Bulk"
+ option avgrate 1
+ option packetdelay 200
diff --git a/package/network/config/qos-scripts/files/etc/hotplug.d/iface/10-qos b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/10-qos
new file mode 100755
index 0000000..0ced29a
--- /dev/null
+++ b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/10-qos
@@ -0,0 +1,2 @@
+#!/bin/sh
+[ "$ACTION" = ifup ] && /etc/init.d/qos enabled && /usr/lib/qos/generate.sh interface "$INTERFACE" | sh
diff --git a/package/network/config/qos-scripts/files/etc/init.d/qos b/package/network/config/qos-scripts/files/etc/init.d/qos
new file mode 100755
index 0000000..712d906
--- /dev/null
+++ b/package/network/config/qos-scripts/files/etc/init.d/qos
@@ -0,0 +1,28 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006 OpenWrt.org
+
+START=50
+USE_PROCD=1
+
+validate_qos_section()
+{
+ uci_validate_section qos interface "${1}" \
+ 'enabled:bool' \
+ 'upload:uinteger' \
+ 'download:uinteger'
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger "qos"
+ procd_add_validation validate_qos_section
+ qos-start
+}
+
+start_service() {
+ qos-start
+}
+
+reload_service() {
+ qos-start
+}
diff --git a/package/network/config/qos-scripts/files/usr/bin/qos-start b/package/network/config/qos-scripts/files/usr/bin/qos-start
new file mode 100755
index 0000000..261ffb4
--- /dev/null
+++ b/package/network/config/qos-scripts/files/usr/bin/qos-start
@@ -0,0 +1,4 @@
+#!/bin/sh
+qos-stop
+/usr/lib/qos/generate.sh all | sh
+
diff --git a/package/network/config/qos-scripts/files/usr/bin/qos-stat b/package/network/config/qos-scripts/files/usr/bin/qos-stat
new file mode 100755
index 0000000..cbbf8e8
--- /dev/null
+++ b/package/network/config/qos-scripts/files/usr/bin/qos-stat
@@ -0,0 +1,67 @@
+#!/bin/sh
+# Copyright (C) 2011 OpenWrt.org
+
+. /lib/functions.sh
+
+include /lib/network
+
+get_ifname() {
+ local interface="$1"
+ local cfgt
+
+ scan_interfaces
+ config_get cfgt "$interface" TYPE
+ [ "$cfgt" = "interface" ] && config_get "$interface" ifname
+}
+
+config_cb() {
+ config_get TYPE "$CONFIG_SECTION" TYPE
+ [ "interface" = "$TYPE" ] && {
+ config_get device "$CONFIG_SECTION" ifname
+ [ -z "$device" ] && device="$(get_ifname ${CONFIG_SECTION})"
+ config_set "$CONFIG_SECTION" device "$device"
+ }
+}
+
+config_load qos
+
+print_comments() {
+ echo ''
+ echo '# Interface: '"$1"
+ echo '# Direction: '"$2"
+ echo '# Stats: '"$3"
+ echo ''
+}
+
+get_device() {
+ ( config_load network; scan_interfaces; config_get "$1" ifname )
+}
+
+interface_stats() {
+ local interface="$1"
+ local device
+
+ device="$(get_device "$interface")"
+ [ -z "$device" ] && config_get device "$interface" device
+ config_get_bool enabled "$interface" enabled 1
+ [ -z "$device" -o 1 -ne "$enabled" ] && {
+ return 1
+ }
+ config_get_bool halfduplex "$interface" halfduplex 0
+
+ if [ 1 -ne "$halfduplex" ]; then
+ unset halfduplex
+ print_comments "$interface" "Egress" "Start"
+ tc -s class show dev "$device"
+ print_comments "$interface" "Egress" "End"
+ id="root"
+ else
+ id=""
+ fi
+
+ print_comments "$interface" "Ingress${halfduplex:+/Egress}" "Start"
+ tc -s class show dev "$(tc filter show dev $device $id | grep mirred | sed -e 's,.*\(ifb.*\)).*,\1,')"
+ print_comments "$interface" "Ingress${halfduplex:+/Egress}" "End"
+}
+
+[ -z "$1" ] && config_foreach interface_stats interface || interface_stats "$1"
diff --git a/package/network/config/qos-scripts/files/usr/bin/qos-stop b/package/network/config/qos-scripts/files/usr/bin/qos-stop
new file mode 100755
index 0000000..7f654d8
--- /dev/null
+++ b/package/network/config/qos-scripts/files/usr/bin/qos-stop
@@ -0,0 +1,6 @@
+#!/bin/sh
+for iface in $(tc qdisc show | grep -E '(hfsc|ingress)' | awk '{print $5}'); do
+ tc qdisc del dev "$iface" ingress 2>&- >&-
+ tc qdisc del dev "$iface" root 2>&- >&-
+done
+/usr/lib/qos/generate.sh firewall stop | sh
diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh b/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh
new file mode 100755
index 0000000..01f9b6b
--- /dev/null
+++ b/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh
@@ -0,0 +1,499 @@
+#!/bin/sh
+[ -e /lib/functions.sh ] && . /lib/functions.sh || . ./functions.sh
+[ -x /sbin/modprobe ] && {
+ insmod="modprobe"
+ rmmod="$insmod -r"
+} || {
+ insmod="insmod"
+ rmmod="rmmod"
+}
+
+add_insmod() {
+ eval "export isset=\${insmod_$1}"
+ case "$isset" in
+ 1) ;;
+ *) {
+ [ "$2" ] && append INSMOD "$rmmod $1 >&- 2>&-" "$N"
+ append INSMOD "$insmod $* >&- 2>&-" "$N"; export insmod_$1=1
+ };;
+ esac
+}
+
+[ -e /etc/config/network ] && {
+ # only try to parse network config on openwrt
+
+ find_ifname() {(
+ reset_cb
+ include /lib/network
+ scan_interfaces
+ config_get "$1" ifname
+ )}
+} || {
+ find_ifname() {
+ echo "Interface not found."
+ exit 1
+ }
+}
+
+parse_matching_rule() {
+ local var="$1"
+ local section="$2"
+ local options="$3"
+ local prefix="$4"
+ local suffix="$5"
+ local proto="$6"
+ local mport=""
+ local ports=""
+
+ append "$var" "$prefix" "$N"
+ for option in $options; do
+ case "$option" in
+ proto) config_get value "$section" proto; proto="${proto:-$value}";;
+ esac
+ done
+ config_get type "$section" TYPE
+ case "$type" in
+ classify) unset pkt; append "$var" "-m mark --mark 0/0x0f";;
+ default) pkt=1; append "$var" "-m mark --mark 0/0xf0";;
+ reclassify) pkt=1;;
+ esac
+ append "$var" "${proto:+-p $proto}"
+ for option in $options; do
+ config_get value "$section" "$option"
+
+ case "$pkt:$option" in
+ *:srchost)
+ append "$var" "-s $value"
+ ;;
+ *:dsthost)
+ append "$var" "-d $value"
+ ;;
+ *:ports|*:srcports|*:dstports)
+ value="$(echo "$value" | sed -e 's,-,:,g')"
+ lproto=${lproto:-tcp}
+ case "$proto" in
+ ""|tcp|udp) append "$var" "-m ${proto:-tcp -p tcp} -m multiport";;
+ *) unset "$var"; return 0;;
+ esac
+ case "$option" in
+ ports)
+ config_set "$section" srcports ""
+ config_set "$section" dstports ""
+ config_set "$section" portrange ""
+ append "$var" "--ports $value"
+ ;;
+ srcports)
+ config_set "$section" ports ""
+ config_set "$section" dstports ""
+ config_set "$section" portrange ""
+ append "$var" "--sports $value"
+ ;;
+ dstports)
+ config_set "$section" ports ""
+ config_set "$section" srcports ""
+ config_set "$section" portrange ""
+ append "$var" "--dports $value"
+ ;;
+ esac
+ ports=1
+ ;;
+ *:portrange)
+ config_set "$section" ports ""
+ config_set "$section" srcports ""
+ config_set "$section" dstports ""
+ value="$(echo "$value" | sed -e 's,-,:,g')"
+ case "$proto" in
+ ""|tcp|udp) append "$var" "-m ${proto:-tcp -p tcp} --sport $value --dport $value";;
+ *) unset "$var"; return 0;;
+ esac
+ ports=1
+ ;;
+ *:connbytes)
+ value="$(echo "$value" | sed -e 's,-,:,g')"
+ add_insmod xt_connbytes
+ append "$var" "-m connbytes --connbytes $value --connbytes-dir both --connbytes-mode bytes"
+ ;;
+ *:comment)
+ add_insmod xt_comment
+ append "$var" "-m comment --comment '$value'"
+ ;;
+ *:tos)
+ add_insmod xt_dscp
+ case "$value" in
+ !*) append "$var" "-m tos ! --tos $value";;
+ *) append "$var" "-m tos --tos $value"
+ esac
+ ;;
+ *:dscp)
+ add_insmod xt_dscp
+ dscp_option="--dscp"
+ [ -z "${value%%[EBCA]*}" ] && dscp_option="--dscp-class"
+ case "$value" in
+ !*) append "$var" "-m dscp ! $dscp_option $value";;
+ *) append "$var" "-m dscp $dscp_option $value"
+ esac
+ ;;
+ *:direction)
+ value="$(echo "$value" | sed -e 's,-,:,g')"
+ if [ "$value" = "out" ]; then
+ append "$var" "-o $device"
+ elif [ "$value" = "in" ]; then
+ append "$var" "-i $device"
+ fi
+ ;;
+ 1:pktsize)
+ value="$(echo "$value" | sed -e 's,-,:,g')"
+ add_insmod xt_length
+ append "$var" "-m length --length $value"
+ ;;
+ 1:limit)
+ add_insmod xt_limit
+ append "$var" "-m limit --limit $value"
+ ;;
+ 1:tcpflags)
+ case "$proto" in
+ tcp) append "$var" "-m tcp --tcp-flags ALL $value";;
+ *) unset $var; return 0;;
+ esac
+ ;;
+ 1:mark)
+ config_get class "${value##!}" classnr
+ [ -z "$class" ] && continue;
+ case "$value" in
+ !*) append "$var" "-m mark ! --mark $class/0x0f";;
+ *) append "$var" "-m mark --mark $class/0x0f";;
+ esac
+ ;;
+ 1:TOS)
+ add_insmod xt_DSCP
+ config_get TOS "$rule" 'TOS'
+ suffix="-j TOS --set-tos "${TOS:-"Normal-Service"}
+ ;;
+ 1:DSCP)
+ add_insmod xt_DSCP
+ config_get DSCP "$rule" 'DSCP'
+ [ -z "${DSCP%%[EBCA]*}" ] && set_value="--set-dscp-class $DSCP" \
+ || set_value="--set-dscp $DSCP"
+ suffix="-j DSCP $set_value"
+ ;;
+ esac
+ done
+ append "$var" "$suffix"
+ case "$ports:$proto" in
+ 1:) parse_matching_rule "$var" "$section" "$options" "$prefix" "$suffix" "udp";;
+ esac
+}
+
+config_cb() {
+ option_cb() {
+ return 0
+ }
+
+ # Section start
+ case "$1" in
+ interface)
+ config_set "$2" "classgroup" "Default"
+ config_set "$2" "upload" "128"
+ ;;
+ classify|default|reclassify)
+ option_cb() {
+ append options "$1"
+ }
+ ;;
+ esac
+
+ # Section end
+ config_get TYPE "$CONFIG_SECTION" TYPE
+ case "$TYPE" in
+ interface)
+ config_get_bool enabled "$CONFIG_SECTION" enabled 1
+ [ 1 -eq "$enabled" ] || return 0
+ config_get classgroup "$CONFIG_SECTION" classgroup
+ config_set "$CONFIG_SECTION" ifbdev "$C"
+ C=$(($C+1))
+ append INTERFACES "$CONFIG_SECTION"
+ config_set "$classgroup" enabled 1
+ config_get device "$CONFIG_SECTION" device
+ [ -z "$device" ] && {
+ device="$(find_ifname ${CONFIG_SECTION})"
+ config_set "$CONFIG_SECTION" device "${device:-eth0}"
+ }
+ ;;
+ classgroup) append CG "$CONFIG_SECTION";;
+ classify|default|reclassify)
+ case "$TYPE" in
+ classify) var="ctrules";;
+ *) var="rules";;
+ esac
+ config_get target "$CONFIG_SECTION" target
+ config_set "$CONFIG_SECTION" options "$options"
+ append "$var" "$CONFIG_SECTION"
+ unset options
+ ;;
+ esac
+}
+
+
+enum_classes() {
+ local c="0"
+ config_get classes "$1" classes
+ config_get default "$1" default
+ for class in $classes; do
+ c="$(($c + 1))"
+ config_set "${class}" classnr $c
+ case "$class" in
+ $default) class_default=$c;;
+ esac
+ done
+ class_default="${class_default:-$c}"
+}
+
+cls_var() {
+ local varname="$1"
+ local class="$2"
+ local name="$3"
+ local type="$4"
+ local default="$5"
+ local tmp tmp1 tmp2
+ config_get tmp1 "$class" "$name"
+ config_get tmp2 "${class}_${type}" "$name"
+ tmp="${tmp2:-$tmp1}"
+ tmp="${tmp:-$tmp2}"
+ export ${varname}="${tmp:-$default}"
+}
+
+tcrules() {
+ _dir=/usr/lib/qos
+ [ -e $_dir/tcrules.awk ] || _dir=.
+ echo "$cstr" | awk \
+ -v device="$dev" \
+ -v linespeed="$rate" \
+ -v direction="$dir" \
+ -f $_dir/tcrules.awk
+}
+
+start_interface() {
+ local iface="$1"
+ local num_ifb="$2"
+ config_get device "$iface" device
+ config_get_bool enabled "$iface" enabled 1
+ [ -z "$device" -o 1 -ne "$enabled" ] && {
+ return 1
+ }
+ config_get upload "$iface" upload
+ config_get_bool halfduplex "$iface" halfduplex
+ config_get download "$iface" download
+ config_get classgroup "$iface" classgroup
+ config_get_bool overhead "$iface" overhead 0
+
+ download="${download:-${halfduplex:+$upload}}"
+ enum_classes "$classgroup"
+ for dir in ${halfduplex:-up} ${download:+down}; do
+ case "$dir" in
+ up)
+ [ "$overhead" = 1 ] && upload=$(($upload * 98 / 100 - (15 * 128 / $upload)))
+ dev="$device"
+ rate="$upload"
+ dl_mode=""
+ prefix="cls"
+ ;;
+ down)
+ [ "$(ls -d /proc/sys/net/ipv4/conf/ifb* 2>&- | wc -l)" -ne "$num_ifb" ] && add_insmod ifb numifbs="$num_ifb"
+ config_get ifbdev "$iface" ifbdev
+ [ "$overhead" = 1 ] && download=$(($download * 98 / 100 - (80 * 1024 / $download)))
+ dev="ifb$ifbdev"
+ rate="$download"
+ dl_mode=1
+ prefix="d_cls"
+ ;;
+ *) continue;;
+ esac
+ cstr=
+ for class in $classes; do
+ cls_var pktsize "$class" packetsize $dir 1500
+ cls_var pktdelay "$class" packetdelay $dir 0
+ cls_var maxrate "$class" limitrate $dir 100
+ cls_var prio "$class" priority $dir 1
+ cls_var avgrate "$class" avgrate $dir 0
+ cls_var qdisc "$class" qdisc $dir ""
+ cls_var filter "$class" filter $dir ""
+ config_get classnr "$class" classnr
+ append cstr "$classnr:$prio:$avgrate:$pktsize:$pktdelay:$maxrate:$qdisc:$filter" "$N"
+ done
+ append ${prefix}q "$(tcrules)" "$N"
+ export dev_${dir}="ifconfig $dev up txqueuelen 5 >&- 2>&-
+tc qdisc del dev $dev root >&- 2>&-
+tc qdisc add dev $dev root handle 1: hfsc default ${class_default}0
+tc class add dev $dev parent 1: classid 1:1 hfsc sc rate ${rate}kbit ul rate ${rate}kbit"
+ done
+ [ -n "$download" ] && {
+ add_insmod cls_u32
+ add_insmod em_u32
+ add_insmod act_connmark
+ add_insmod act_mirred
+ add_insmod sch_ingress
+ }
+ if [ -n "$halfduplex" ]; then
+ export dev_up="tc qdisc del dev $device root >&- 2>&-
+tc qdisc add dev $device root handle 1: hfsc
+tc filter add dev $device parent 1: protocol ip prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb$ifbdev"
+ elif [ -n "$download" ]; then
+ append dev_${dir} "tc qdisc del dev $device ingress >&- 2>&-
+tc qdisc add dev $device ingress
+tc filter add dev $device parent ffff: protocol ip prio 1 u32 match u32 0 0 flowid 1:1 action connmark action mirred egress redirect dev ifb$ifbdev" "$N"
+ fi
+ add_insmod cls_fw
+ add_insmod sch_hfsc
+ add_insmod sch_fq_codel
+
+ cat <<EOF
+${INSMOD:+$INSMOD$N}${dev_up:+$dev_up
+$clsq
+}${ifbdev:+$dev_down
+$d_clsq
+$d_clsl
+$d_clsf
+}
+EOF
+ unset INSMOD clsq clsf clsl d_clsq d_clsl d_clsf dev_up dev_down
+}
+
+start_interfaces() {
+ local C="$1"
+ for iface in $INTERFACES; do
+ start_interface "$iface" "$C"
+ done
+}
+
+add_rules() {
+ local var="$1"
+ local rules="$2"
+ local prefix="$3"
+
+ for rule in $rules; do
+ unset iptrule
+ config_get target "$rule" target
+ config_get target "$target" classnr
+ config_get options "$rule" options
+
+ ## If we want to override the TOS field, let's clear the DSCP field first.
+ [ ! -z "$(echo $options | grep 'TOS')" ] && {
+ s_options=${options%%TOS}
+ add_insmod xt_DSCP
+ parse_matching_rule iptrule "$rule" "$s_options" "$prefix" "-j DSCP --set-dscp 0"
+ append "$var" "$iptrule" "$N"
+ unset iptrule
+ }
+
+ target=$(($target | ($target << 4)))
+ parse_matching_rule iptrule "$rule" "$options" "$prefix" "-j MARK --set-mark $target/0xff"
+ append "$var" "$iptrule" "$N"
+ done
+}
+
+start_cg() {
+ local cg="$1"
+ local iptrules
+ local pktrules
+ local sizerules
+ enum_classes "$cg"
+ add_rules iptrules "$ctrules" "iptables -t mangle -A qos_${cg}_ct"
+ config_get classes "$cg" classes
+ for class in $classes; do
+ config_get mark "$class" classnr
+ config_get maxsize "$class" maxsize
+ [ -z "$maxsize" -o -z "$mark" ] || {
+ add_insmod xt_length
+ append pktrules "iptables -t mangle -A qos_${cg} -m mark --mark $mark/0x0f -m length --length $maxsize: -j MARK --set-mark 0/0xff" "$N"
+ }
+ done
+ add_rules pktrules "$rules" "iptables -t mangle -A qos_${cg}"
+ for iface in $INTERFACES; do
+ config_get classgroup "$iface" classgroup
+ config_get device "$iface" device
+ config_get ifbdev "$iface" ifbdev
+ config_get upload "$iface" upload
+ config_get download "$iface" download
+ config_get halfduplex "$iface" halfduplex
+ download="${download:-${halfduplex:+$upload}}"
+ append up "iptables -t mangle -A OUTPUT -o $device -j qos_${cg}" "$N"
+ append up "iptables -t mangle -A FORWARD -o $device -j qos_${cg}" "$N"
+ done
+ cat <<EOF
+$INSMOD
+iptables -t mangle -N qos_${cg} >&- 2>&-
+iptables -t mangle -N qos_${cg}_ct >&- 2>&-
+${iptrules:+${iptrules}${N}iptables -t mangle -A qos_${cg}_ct -j CONNMARK --save-mark --mask 0xff}
+iptables -t mangle -A qos_${cg} -j CONNMARK --restore-mark --mask 0x0f
+iptables -t mangle -A qos_${cg} -m mark --mark 0/0x0f -j qos_${cg}_ct
+$pktrules
+${iptrules:+${iptrules}${N}iptables -t mangle -A qos_${cg} -j CONNMARK --save-mark --mask 0xf0}
+$up$N${down:+${down}$N}
+EOF
+ unset INSMOD
+}
+
+start_firewall() {
+ add_insmod xt_multiport
+ add_insmod xt_CONNMARK
+ stop_firewall
+ for group in $CG; do
+ start_cg $group
+ done
+}
+
+stop_firewall() {
+ # Builds up a list of iptables commands to flush the qos_* chains,
+ # remove rules referring to them, then delete them
+
+ # Print rules in the mangle table, like iptables-save
+ iptables -t mangle -S |
+ # Find rules for the qos_* chains
+ grep '^-N qos_\|-j qos_' |
+ # Exclude rules in qos_* chains (inter-qos_* refs)
+ grep -v '^-A qos_' |
+ # Replace -N with -X and hold, with -F and print
+ # Replace -A with -D
+ # Print held lines at the end (note leading newline)
+ sed -e '/^-N/{s/^-N/-X/;H;s/^-X/-F/}' \
+ -e 's/^-A/-D/' \
+ -e '${p;g}' |
+ # Make into proper iptables calls
+ # Note: awkward in previous call due to hold space usage
+ sed -n -e 's/^./iptables -t mangle &/p'
+}
+
+C="0"
+INTERFACES=""
+[ -e ./qos.conf ] && {
+ . ./qos.conf
+ config_cb
+} || config_load qos
+
+C="0"
+for iface in $INTERFACES; do
+ export C="$(($C + 1))"
+done
+
+case "$1" in
+ all)
+ start_interfaces "$C"
+ start_firewall
+ ;;
+ interface)
+ start_interface "$2" "$C"
+ ;;
+ interfaces)
+ start_interfaces
+ ;;
+ firewall)
+ case "$2" in
+ stop)
+ stop_firewall
+ ;;
+ start|"")
+ start_firewall
+ ;;
+ esac
+ ;;
+esac
diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk b/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk
new file mode 100644
index 0000000..12f94a6
--- /dev/null
+++ b/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk
@@ -0,0 +1,106 @@
+BEGIN {
+ dmax=100
+ if (!(linespeed > 0)) linespeed = 128
+ FS=":"
+ n = 0
+}
+
+($1 != "") {
+ n++
+ class[n] = $1
+ prio[n] = $2
+ avgrate[n] = ($3 * linespeed / 100)
+ pktsize[n] = $4
+ delay[n] = $5
+ maxrate[n] = ($6 * linespeed / 100)
+ qdisc[n] = $7
+ filter[n] = $8
+}
+
+END {
+ allocated = 0
+ maxdelay = 0
+
+ for (i = 1; i <= n; i++) {
+ # set defaults
+ if (!(pktsize[i] > 0)) pktsize[i] = 1500
+ if (!(prio[i] > 0)) prio[i] = 1
+
+ allocated += avgrate[i]
+ sum_prio += prio[i]
+ if ((avgrate[i] > 0) && !(delay[i] > 0)) {
+ sum_rtprio += prio[i]
+ }
+ }
+
+ # allocation of m1 in rt classes:
+ # sum(d * m1) must not exceed dmax * (linespeed - allocated)
+ dmax = 0
+ for (i = 1; i <= n; i++) {
+ if (avgrate[i] > 0) {
+ rtm2[i] = avgrate[i]
+ if (delay[i] > 0) {
+ d[i] = delay[i]
+ } else {
+ d[i] = 2 * pktsize[i] * 1000 / (linespeed * 1024)
+ if (d[i] > dmax) dmax = d[i]
+ }
+ }
+ }
+
+ ds_avail = dmax * (linespeed - allocated)
+ for (i = 1; i <= n; i++) {
+ lsm1[i] = 0
+ rtm1[i] = 0
+ lsm2[i] = linespeed * prio[i] / sum_prio
+ if ((avgrate[i] > 0) && (d[i] > 0)) {
+ if (!(delay[i] > 0)) {
+ ds = ds_avail * prio[i] / sum_rtprio
+ ds_avail -= ds
+ rtm1[i] = rtm2[i] + ds/d[i]
+ }
+ lsm1[i] = rtm1[i]
+ }
+ else {
+ d[i] = 0
+ }
+ }
+
+ # main qdisc
+ for (i = 1; i <= n; i++) {
+ printf "tc class add dev "device" parent 1:1 classid 1:"class[i]"0 hfsc"
+ if (rtm1[i] > 0) {
+ printf " rt m1 " int(rtm1[i]) "kbit d " int(d[i] * 1000) "us m2 " int(rtm2[i])"kbit"
+ }
+ printf " ls m1 " int(lsm1[i]) "kbit d " int(d[i] * 1000) "us m2 " int(lsm2[i]) "kbit"
+ print " ul rate " int(maxrate[i]) "kbit"
+ }
+
+ # leaf qdisc
+ avpkt = 1200
+ for (i = 1; i <= n; i++) {
+ print "tc qdisc add dev "device" parent 1:"class[i]"0 handle "class[i]"00: fq_codel limit 800 quantum 300 noecn"
+ }
+
+ # filter rule
+ for (i = 1; i <= n; i++) {
+ filter_cmd = "tc filter add dev "device" parent 1: prio %d protocol ip handle %s fw flowid 1:%d0\n";
+ if (direction == "up") {
+ filter_1 = sprintf("0x%x0/0xf0", class[i])
+ filter_2 = sprintf("0x0%x/0x0f", class[i])
+ } else {
+ filter_1 = sprintf("0x0%x/0x0f", class[i])
+ filter_2 = sprintf("0x%x0/0xf0", class[i])
+ }
+
+ printf filter_cmd, class[i] * 2, filter_1, class[i]
+ printf filter_cmd, class[i] * 2 + 1, filter_2, class[i]
+
+ filterc=1
+ if (filter[i] != "") {
+ print " tc filter add dev "device" parent "class[i]"00: handle "filterc"0 "filter[i]
+ filterc=filterc+1
+ }
+ }
+}
+
diff --git a/package/network/config/soloscli/Makefile b/package/network/config/soloscli/Makefile
new file mode 100644
index 0000000..12bc15e
--- /dev/null
+++ b/package/network/config/soloscli/Makefile
@@ -0,0 +1,45 @@
+#
+# 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:=soloscli
+PKG_VERSION:=1.04
+PKG_RELEASE:=1
+
+PKG_SOURCE:=solos-pci-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/openadsl
+PKG_MD5SUM:=c398866de3c059b14eb953c89d698124
+PKG_LICENSE:=GPL-2.0
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/solos-pci-$(PKG_VERSION)
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/soloscli
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Configuration utility for Solos ADSL2+ modems
+ DEPENDS:=+kmod-solos-pci
+ URL:=http://sourceforge.net/projects/openadsl
+endef
+
+define Package/soloscli/description
+ This package contains the soloscli utility
+ for interrogating Traverse Technologies' Solos ADSL2+ modems.
+endef
+
+define Package/soloscli/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/soloscli/soloscli $(1)/usr/bin/
+ $(INSTALL_BIN) ./files/solos-log-stats $(1)/usr/bin/
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/atm
+ $(INSTALL_DATA) ./files/etc/hotplug.d/atm/15-solos-init $(1)/etc/hotplug.d/atm/
+endef
+
+$(eval $(call BuildPackage,soloscli))
diff --git a/package/network/config/soloscli/files/etc/hotplug.d/atm/15-solos-init b/package/network/config/soloscli/files/etc/hotplug.d/atm/15-solos-init
new file mode 100644
index 0000000..36d13ea
--- /dev/null
+++ b/package/network/config/soloscli/files/etc/hotplug.d/atm/15-solos-init
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+dialog() {
+ local tag="$(echo "$1" | cut -d= -f1)"
+ local value="$(echo "$1" | cut -d= -f2-)"
+ local response
+
+ response="$(soloscli -s "$port" "$tag" "$value")"
+ [ $? -ne 0 ] && {
+ logger "soloscli($port): $tag '$value' returns $response"
+ }
+}
+
+if [ "$ACTION" = "add" ]; then
+ include /lib/network
+ scan_interfaces
+
+ case $DEVICENAME in
+ solos-pci[0-3])
+ port="${DEVICENAME#solos-pci}"
+ device="solos${port}"
+
+ config_list_foreach wan "$device" dialog
+ ;;
+ esac
+fi
diff --git a/package/network/config/soloscli/files/etc/uci-default/solos b/package/network/config/soloscli/files/etc/uci-default/solos
new file mode 100644
index 0000000..7f69da6
--- /dev/null
+++ b/package/network/config/soloscli/files/etc/uci-default/solos
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+uci batch <<__EOF__
+
+delete network.wan.solos0
+
+add_list network.wan.solos0="ActivateLine=Abort"
+add_list network.wan.solos0="Retrain=EnableAll"
+add_list network.wan.solos0="DetectNoise=Enable"
+add_list network.wan.solos0="BisMCapability=Disable"
+add_list network.wan.solos0="BisACapability=Disable"
+add_list network.wan.solos0="ActivateLine=Start"
+
+commit network
+__EOF__
diff --git a/package/network/config/soloscli/files/solos-log-stats b/package/network/config/soloscli/files/solos-log-stats
new file mode 100644
index 0000000..2b75ee3
--- /dev/null
+++ b/package/network/config/soloscli/files/solos-log-stats
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+cd /sys/class/atm/ || exit 1
+
+for PORT in solos-pci* ; do
+
+ RXRATE=`cat $PORT/parameters/RxBitRate`
+ TXRATE=`cat $PORT/parameters/TxBitRate`
+ RXSNR=`cat $PORT/parameters/LocalSNRMargin | sed "s/ dB//"`
+ TXSNR=`cat $PORT/parameters/RemoteSNRMargin | sed "s/ dB//"`
+ RXERR=`cat $PORT/parameters/RSUnCorrectedErrorsDn`
+ TXERR=`cat $PORT/parameters/RSUnCorrectedErrorsUp`
+ RXFEC=`cat $PORT/parameters/RSCorrectedErrorsDn`
+ TXFEC=`cat $PORT/parameters/RSCorrectedErrorsUp`
+
+ echo "$RXRATE $RXSNR $RXERR $RXFEC / $TXRATE $TXSNR $TXERR $TXFEC" |
+ logger -t $PORT
+done
+
diff --git a/package/network/config/soloscli/patches/001-no-driver.patch b/package/network/config/soloscli/patches/001-no-driver.patch
new file mode 100644
index 0000000..95588aa
--- /dev/null
+++ b/package/network/config/soloscli/patches/001-no-driver.patch
@@ -0,0 +1,11 @@
+--- a/Makefile
++++ b/Makefile
+@@ -11,7 +11,7 @@ else
+ KDIR ?= /lib/modules/$(shell uname -r)/build
+ PWD := $(shell pwd)
+
+-all: soloscli driver
++all: soloscli
+
+ soloscli: soloscli/soloscli
+
diff --git a/package/network/config/soloscli/patches/002-cflags.patch b/package/network/config/soloscli/patches/002-cflags.patch
new file mode 100644
index 0000000..a7d6a86
--- /dev/null
+++ b/package/network/config/soloscli/patches/002-cflags.patch
@@ -0,0 +1,12 @@
+--- a/soloscli/Makefile
++++ b/soloscli/Makefile
+@@ -4,9 +4,6 @@
+ # Last Mod: 2009-06-16
+ #
+
+-CC=gcc
+-CFLAGS=-Wall
+-
+ soloscli: soloscli.c soloscli.h
+
+ clean:
diff --git a/package/network/config/swconfig/Makefile b/package/network/config/swconfig/Makefile
new file mode 100644
index 0000000..b62b059
--- /dev/null
+++ b/package/network/config/swconfig/Makefile
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2008-2010 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:=swconfig
+PKG_RELEASE:=10
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+define Package/swconfig
+ SECTION:=base
+ CATEGORY:=Base system
+ DEPENDS:=+libuci +libnl-tiny
+ TITLE:=Switch configuration utility
+endef
+
+TARGET_CPPFLAGS := \
+ -D_GNU_SOURCE \
+ -I$(STAGING_DIR)/usr/include/libnl-tiny \
+ -I$(PKG_BUILD_DIR) \
+ $(TARGET_CPPFLAGS) \
+ -I$(LINUX_DIR)/user_headers/include
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(TARGET_CONFIGURE_OPTS) \
+ LIBS="$(TARGET_LDFLAGS) -lnl-tiny -lm -luci"
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_BUILD_DIR)/swlib.h $(1)/usr/include/
+
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/libsw.so $(1)/usr/lib/
+endef
+
+define Package/swconfig/install
+ $(INSTALL_DIR) $(1)/sbin $(1)/lib/network
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/swconfig $(1)/sbin/swconfig
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/libsw.so $(1)/lib
+ $(INSTALL_DATA) ./files/switch.sh $(1)/lib/network/
+endef
+
+$(eval $(call BuildPackage,swconfig))
diff --git a/package/network/config/swconfig/files/switch.sh b/package/network/config/swconfig/files/switch.sh
new file mode 100644
index 0000000..74d2590
--- /dev/null
+++ b/package/network/config/swconfig/files/switch.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# Copyright (C) 2009 OpenWrt.org
+
+setup_switch_dev() {
+ local name
+ config_get name "$1" name
+ name="${name:-$1}"
+ [ -d "/sys/class/net/$name" ] && ip link set dev "$name" up
+ swconfig dev "$name" load network
+}
+
+setup_switch() {
+ config_load network
+ config_foreach setup_switch_dev switch
+}
diff --git a/package/network/config/swconfig/src/Makefile b/package/network/config/swconfig/src/Makefile
new file mode 100644
index 0000000..1176bf0
--- /dev/null
+++ b/package/network/config/swconfig/src/Makefile
@@ -0,0 +1,15 @@
+ifndef CFLAGS
+CFLAGS = -O2 -g -I ../src
+endif
+LIBS=-lnl -lnl-genl
+
+all: swconfig
+
+%.o: %.c
+ $(CC) $(CFLAGS) -fPIC -c -o $@ $^
+
+libsw.so: swlib.o
+ $(CC) $(CFLAGS) -fPIC -shared -o $@ swlib.o
+
+swconfig: libsw.so cli.o uci.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) -L./ -lsw
diff --git a/package/network/config/swconfig/src/cli.c b/package/network/config/swconfig/src/cli.c
new file mode 100644
index 0000000..d472086
--- /dev/null
+++ b/package/network/config/swconfig/src/cli.c
@@ -0,0 +1,354 @@
+/*
+ * swconfig.c: Switch configuration utility
+ *
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2010 Martin Mares <mj@ucw.cz>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundatio.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <uci.h>
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+#include <linux/genetlink.h>
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/switch.h>
+#include "swlib.h"
+
+enum {
+ CMD_NONE,
+ CMD_GET,
+ CMD_SET,
+ CMD_LOAD,
+ CMD_HELP,
+ CMD_SHOW,
+ CMD_PORTMAP,
+};
+
+static void
+print_attrs(const struct switch_attr *attr)
+{
+ int i = 0;
+ while (attr) {
+ const char *type;
+ switch(attr->type) {
+ case SWITCH_TYPE_INT:
+ type = "int";
+ break;
+ case SWITCH_TYPE_STRING:
+ type = "string";
+ break;
+ case SWITCH_TYPE_PORTS:
+ type = "ports";
+ break;
+ case SWITCH_TYPE_NOVAL:
+ type = "none";
+ break;
+ default:
+ type = "unknown";
+ break;
+ }
+ printf("\tAttribute %d (%s): %s (%s)\n", ++i, type, attr->name, attr->description);
+ attr = attr->next;
+ }
+}
+
+static void
+list_attributes(struct switch_dev *dev)
+{
+ printf("%s: %s(%s), ports: %d (cpu @ %d), vlans: %d\n", dev->dev_name, dev->alias, dev->name, dev->ports, dev->cpu_port, dev->vlans);
+ printf(" --switch\n");
+ print_attrs(dev->ops);
+ printf(" --vlan\n");
+ print_attrs(dev->vlan_ops);
+ printf(" --port\n");
+ print_attrs(dev->port_ops);
+}
+
+static void
+print_attr_val(const struct switch_attr *attr, const struct switch_val *val)
+{
+ int i;
+
+ switch (attr->type) {
+ case SWITCH_TYPE_INT:
+ printf("%d", val->value.i);
+ break;
+ case SWITCH_TYPE_STRING:
+ printf("%s", val->value.s);
+ break;
+ case SWITCH_TYPE_PORTS:
+ for(i = 0; i < val->len; i++) {
+ printf("%d%s ",
+ val->value.ports[i].id,
+ (val->value.ports[i].flags &
+ SWLIB_PORT_FLAG_TAGGED) ? "t" : "");
+ }
+ break;
+ default:
+ printf("?unknown-type?");
+ }
+}
+
+static void
+show_attrs(struct switch_dev *dev, struct switch_attr *attr, struct switch_val *val)
+{
+ while (attr) {
+ if (attr->type != SWITCH_TYPE_NOVAL) {
+ printf("\t%s: ", attr->name);
+ if (swlib_get_attr(dev, attr, val) < 0)
+ printf("???");
+ else
+ print_attr_val(attr, val);
+ putchar('\n');
+ }
+ attr = attr->next;
+ }
+}
+
+static void
+show_global(struct switch_dev *dev)
+{
+ struct switch_val val;
+
+ printf("Global attributes:\n");
+ show_attrs(dev, dev->ops, &val);
+}
+
+static void
+show_port(struct switch_dev *dev, int port)
+{
+ struct switch_val val;
+
+ printf("Port %d:\n", port);
+ val.port_vlan = port;
+ show_attrs(dev, dev->port_ops, &val);
+}
+
+static void
+show_vlan(struct switch_dev *dev, int vlan, bool all)
+{
+ struct switch_val val;
+ struct switch_attr *attr;
+
+ val.port_vlan = vlan;
+
+ if (all) {
+ attr = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_VLAN, "ports");
+ if (swlib_get_attr(dev, attr, &val) < 0)
+ return;
+
+ if (!val.len)
+ return;
+ }
+
+ printf("VLAN %d:\n", vlan);
+ show_attrs(dev, dev->vlan_ops, &val);
+}
+
+static void
+print_usage(void)
+{
+ printf("swconfig list\n");
+ printf("swconfig dev <dev> [port <port>|vlan <vlan>] (help|set <key> <value>|get <key>|load <config>|show)\n");
+ exit(1);
+}
+
+static void
+swconfig_load_uci(struct switch_dev *dev, const char *name)
+{
+ struct uci_context *ctx;
+ struct uci_package *p = NULL;
+ int ret = -1;
+
+ ctx = uci_alloc_context();
+ if (!ctx)
+ return;
+
+ uci_load(ctx, name, &p);
+ if (!p) {
+ uci_perror(ctx, "Failed to load config file: ");
+ goto out;
+ }
+
+ ret = swlib_apply_from_uci(dev, p);
+ if (ret < 0)
+ fprintf(stderr, "Failed to apply configuration for switch '%s'\n", dev->dev_name);
+
+out:
+ uci_free_context(ctx);
+ exit(ret);
+}
+
+int main(int argc, char **argv)
+{
+ int retval = 0;
+ struct switch_dev *dev;
+ struct switch_attr *a;
+ struct switch_val val;
+ int i;
+
+ int cmd = CMD_NONE;
+ char *cdev = NULL;
+ int cport = -1;
+ int cvlan = -1;
+ char *ckey = NULL;
+ char *cvalue = NULL;
+ char *csegment = NULL;
+
+ if((argc == 2) && !strcmp(argv[1], "list")) {
+ swlib_list();
+ return 0;
+ }
+
+ if(argc < 4)
+ print_usage();
+
+ if(strcmp(argv[1], "dev"))
+ print_usage();
+
+ cdev = argv[2];
+
+ for(i = 3; i < argc; i++)
+ {
+ char *arg = argv[i];
+ if (cmd != CMD_NONE) {
+ print_usage();
+ } else if (!strcmp(arg, "port") && i+1 < argc) {
+ cport = atoi(argv[++i]);
+ } else if (!strcmp(arg, "vlan") && i+1 < argc) {
+ cvlan = atoi(argv[++i]);
+ } else if (!strcmp(arg, "help")) {
+ cmd = CMD_HELP;
+ } else if (!strcmp(arg, "set") && i+1 < argc) {
+ cmd = CMD_SET;
+ ckey = argv[++i];
+ if (i+1 < argc)
+ cvalue = argv[++i];
+ } else if (!strcmp(arg, "get") && i+1 < argc) {
+ cmd = CMD_GET;
+ ckey = argv[++i];
+ } else if (!strcmp(arg, "load") && i+1 < argc) {
+ if ((cport >= 0) || (cvlan >= 0))
+ print_usage();
+ cmd = CMD_LOAD;
+ ckey = argv[++i];
+ } else if (!strcmp(arg, "portmap")) {
+ if (i + 1 < argc)
+ csegment = argv[++i];
+ cmd = CMD_PORTMAP;
+ } else if (!strcmp(arg, "show")) {
+ cmd = CMD_SHOW;
+ } else {
+ print_usage();
+ }
+ }
+
+ if (cmd == CMD_NONE)
+ print_usage();
+ if (cport > -1 && cvlan > -1)
+ print_usage();
+
+ dev = swlib_connect(cdev);
+ if (!dev) {
+ fprintf(stderr, "Failed to connect to the switch. Use the \"list\" command to see which switches are available.\n");
+ return 1;
+ }
+
+ swlib_scan(dev);
+
+ if (cmd == CMD_GET || cmd == CMD_SET) {
+ if(cport > -1)
+ a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_PORT, ckey);
+ else if(cvlan > -1)
+ a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_VLAN, ckey);
+ else
+ a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_GLOBAL, ckey);
+
+ if(!a)
+ {
+ fprintf(stderr, "Unknown attribute \"%s\"\n", ckey);
+ retval = -1;
+ goto out;
+ }
+ }
+
+ switch(cmd)
+ {
+ case CMD_SET:
+ if ((a->type != SWITCH_TYPE_NOVAL) &&
+ (cvalue == NULL))
+ print_usage();
+
+ if(cvlan > -1)
+ cport = cvlan;
+
+ if(swlib_set_attr_string(dev, a, cport, cvalue) < 0)
+ {
+ fprintf(stderr, "failed\n");
+ retval = -1;
+ goto out;
+ }
+ break;
+ case CMD_GET:
+ if(cvlan > -1)
+ val.port_vlan = cvlan;
+ if(cport > -1)
+ val.port_vlan = cport;
+ if(swlib_get_attr(dev, a, &val) < 0)
+ {
+ fprintf(stderr, "failed\n");
+ retval = -1;
+ goto out;
+ }
+ print_attr_val(a, &val);
+ putchar('\n');
+ break;
+ case CMD_LOAD:
+ swconfig_load_uci(dev, ckey);
+ break;
+ case CMD_HELP:
+ list_attributes(dev);
+ break;
+ case CMD_PORTMAP:
+ swlib_print_portmap(dev, csegment);
+ break;
+ case CMD_SHOW:
+ if (cport >= 0 || cvlan >= 0) {
+ if (cport >= 0)
+ show_port(dev, cport);
+ else
+ show_vlan(dev, cvlan, false);
+ } else {
+ show_global(dev);
+ for (i=0; i < dev->ports; i++)
+ show_port(dev, i);
+ for (i=0; i < dev->vlans; i++)
+ show_vlan(dev, i, true);
+ }
+ break;
+ }
+
+out:
+ swlib_free_all(dev);
+ return retval;
+}
diff --git a/package/network/config/swconfig/src/swlib.c b/package/network/config/swconfig/src/swlib.c
new file mode 100644
index 0000000..0dbace5
--- /dev/null
+++ b/package/network/config/swconfig/src/swlib.c
@@ -0,0 +1,801 @@
+/*
+ * swlib.c: Switch configuration API (user space part)
+ *
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/switch.h>
+#include "swlib.h"
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+
+//#define DEBUG 1
+#ifdef DEBUG
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s(%d): " fmt, __func__, __LINE__, ##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+static struct nl_sock *handle;
+static struct nl_cache *cache;
+static struct genl_family *family;
+static struct nlattr *tb[SWITCH_ATTR_MAX + 1];
+static int refcount = 0;
+
+static struct nla_policy port_policy[SWITCH_ATTR_MAX] = {
+ [SWITCH_PORT_ID] = { .type = NLA_U32 },
+ [SWITCH_PORT_FLAG_TAGGED] = { .type = NLA_FLAG },
+};
+
+static struct nla_policy portmap_policy[SWITCH_PORTMAP_MAX] = {
+ [SWITCH_PORTMAP_SEGMENT] = { .type = NLA_STRING },
+ [SWITCH_PORTMAP_VIRT] = { .type = NLA_U32 },
+};
+
+static inline void *
+swlib_alloc(size_t size)
+{
+ void *ptr;
+
+ ptr = malloc(size);
+ if (!ptr)
+ goto done;
+ memset(ptr, 0, size);
+
+done:
+ return ptr;
+}
+
+static int
+wait_handler(struct nl_msg *msg, void *arg)
+{
+ int *finished = arg;
+
+ *finished = 1;
+ return NL_STOP;
+}
+
+/* helper function for performing netlink requests */
+static int
+swlib_call(int cmd, int (*call)(struct nl_msg *, void *),
+ int (*data)(struct nl_msg *, void *), void *arg)
+{
+ struct nl_msg *msg;
+ struct nl_cb *cb = NULL;
+ int finished;
+ int flags = 0;
+ int err;
+
+ msg = nlmsg_alloc();
+ if (!msg) {
+ fprintf(stderr, "Out of memory!\n");
+ exit(1);
+ }
+
+ if (!data)
+ flags |= NLM_F_DUMP;
+
+ genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, genl_family_get_id(family), 0, flags, cmd, 0);
+ if (data) {
+ if (data(msg, arg) < 0)
+ goto nla_put_failure;
+ }
+
+ cb = nl_cb_alloc(NL_CB_CUSTOM);
+ if (!cb) {
+ fprintf(stderr, "nl_cb_alloc failed.\n");
+ exit(1);
+ }
+
+ err = nl_send_auto_complete(handle, msg);
+ if (err < 0) {
+ fprintf(stderr, "nl_send_auto_complete failed: %d\n", err);
+ goto out;
+ }
+
+ finished = 0;
+
+ if (call)
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, call, arg);
+
+ if (data)
+ nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
+ else
+ nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, wait_handler, &finished);
+
+ err = nl_recvmsgs(handle, cb);
+ if (err < 0) {
+ goto out;
+ }
+
+ if (!finished)
+ err = nl_wait_for_ack(handle);
+
+out:
+ if (cb)
+ nl_cb_put(cb);
+nla_put_failure:
+ nlmsg_free(msg);
+ return err;
+}
+
+static int
+send_attr(struct nl_msg *msg, void *arg)
+{
+ struct switch_val *val = arg;
+ struct switch_attr *attr = val->attr;
+
+ NLA_PUT_U32(msg, SWITCH_ATTR_ID, attr->dev->id);
+ NLA_PUT_U32(msg, SWITCH_ATTR_OP_ID, attr->id);
+ switch(attr->atype) {
+ case SWLIB_ATTR_GROUP_PORT:
+ NLA_PUT_U32(msg, SWITCH_ATTR_OP_PORT, val->port_vlan);
+ break;
+ case SWLIB_ATTR_GROUP_VLAN:
+ NLA_PUT_U32(msg, SWITCH_ATTR_OP_VLAN, val->port_vlan);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+
+nla_put_failure:
+ return -1;
+}
+
+static int
+store_port_val(struct nl_msg *msg, struct nlattr *nla, struct switch_val *val)
+{
+ struct nlattr *p;
+ int ports = val->attr->dev->ports;
+ int err = 0;
+ int remaining;
+
+ if (!val->value.ports)
+ val->value.ports = malloc(sizeof(struct switch_port) * ports);
+
+ nla_for_each_nested(p, nla, remaining) {
+ struct nlattr *tb[SWITCH_PORT_ATTR_MAX+1];
+ struct switch_port *port;
+
+ if (val->len >= ports)
+ break;
+
+ err = nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, p, port_policy);
+ if (err < 0)
+ goto out;
+
+ if (!tb[SWITCH_PORT_ID])
+ continue;
+
+ port = &val->value.ports[val->len];
+ port->id = nla_get_u32(tb[SWITCH_PORT_ID]);
+ port->flags = 0;
+ if (tb[SWITCH_PORT_FLAG_TAGGED])
+ port->flags |= SWLIB_PORT_FLAG_TAGGED;
+
+ val->len++;
+ }
+
+out:
+ return err;
+}
+
+static int
+store_val(struct nl_msg *msg, void *arg)
+{
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ struct switch_val *val = arg;
+
+ if (!val)
+ goto error;
+
+ if (nla_parse(tb, SWITCH_ATTR_MAX - 1, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL) < 0) {
+ goto error;
+ }
+
+ if (tb[SWITCH_ATTR_OP_VALUE_INT])
+ val->value.i = nla_get_u32(tb[SWITCH_ATTR_OP_VALUE_INT]);
+ else if (tb[SWITCH_ATTR_OP_VALUE_STR])
+ val->value.s = strdup(nla_get_string(tb[SWITCH_ATTR_OP_VALUE_STR]));
+ else if (tb[SWITCH_ATTR_OP_VALUE_PORTS])
+ val->err = store_port_val(msg, tb[SWITCH_ATTR_OP_VALUE_PORTS], val);
+
+ val->err = 0;
+ return 0;
+
+error:
+ return NL_SKIP;
+}
+
+int
+swlib_get_attr(struct switch_dev *dev, struct switch_attr *attr, struct switch_val *val)
+{
+ int cmd;
+ int err;
+
+ switch(attr->atype) {
+ case SWLIB_ATTR_GROUP_GLOBAL:
+ cmd = SWITCH_CMD_GET_GLOBAL;
+ break;
+ case SWLIB_ATTR_GROUP_PORT:
+ cmd = SWITCH_CMD_GET_PORT;
+ break;
+ case SWLIB_ATTR_GROUP_VLAN:
+ cmd = SWITCH_CMD_GET_VLAN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ memset(&val->value, 0, sizeof(val->value));
+ val->len = 0;
+ val->attr = attr;
+ val->err = -EINVAL;
+ err = swlib_call(cmd, store_val, send_attr, val);
+ if (!err)
+ err = val->err;
+
+ return err;
+}
+
+static int
+send_attr_ports(struct nl_msg *msg, struct switch_val *val)
+{
+ struct nlattr *n;
+ int i;
+
+ /* TODO implement multipart? */
+ if (val->len == 0)
+ goto done;
+ n = nla_nest_start(msg, SWITCH_ATTR_OP_VALUE_PORTS);
+ if (!n)
+ goto nla_put_failure;
+ for (i = 0; i < val->len; i++) {
+ struct switch_port *port = &val->value.ports[i];
+ struct nlattr *np;
+
+ np = nla_nest_start(msg, SWITCH_ATTR_PORT);
+ if (!np)
+ goto nla_put_failure;
+
+ NLA_PUT_U32(msg, SWITCH_PORT_ID, port->id);
+ if (port->flags & SWLIB_PORT_FLAG_TAGGED)
+ NLA_PUT_FLAG(msg, SWITCH_PORT_FLAG_TAGGED);
+
+ nla_nest_end(msg, np);
+ }
+ nla_nest_end(msg, n);
+done:
+ return 0;
+
+nla_put_failure:
+ return -1;
+}
+
+static int
+send_attr_val(struct nl_msg *msg, void *arg)
+{
+ struct switch_val *val = arg;
+ struct switch_attr *attr = val->attr;
+
+ if (send_attr(msg, arg))
+ goto nla_put_failure;
+
+ switch(attr->type) {
+ case SWITCH_TYPE_NOVAL:
+ break;
+ case SWITCH_TYPE_INT:
+ NLA_PUT_U32(msg, SWITCH_ATTR_OP_VALUE_INT, val->value.i);
+ break;
+ case SWITCH_TYPE_STRING:
+ if (!val->value.s)
+ goto nla_put_failure;
+ NLA_PUT_STRING(msg, SWITCH_ATTR_OP_VALUE_STR, val->value.s);
+ break;
+ case SWITCH_TYPE_PORTS:
+ if (send_attr_ports(msg, val) < 0)
+ goto nla_put_failure;
+ break;
+ default:
+ goto nla_put_failure;
+ }
+ return 0;
+
+nla_put_failure:
+ return -1;
+}
+
+int
+swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr, struct switch_val *val)
+{
+ int cmd;
+
+ switch(attr->atype) {
+ case SWLIB_ATTR_GROUP_GLOBAL:
+ cmd = SWITCH_CMD_SET_GLOBAL;
+ break;
+ case SWLIB_ATTR_GROUP_PORT:
+ cmd = SWITCH_CMD_SET_PORT;
+ break;
+ case SWLIB_ATTR_GROUP_VLAN:
+ cmd = SWITCH_CMD_SET_VLAN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val->attr = attr;
+ return swlib_call(cmd, NULL, send_attr_val, val);
+}
+
+int swlib_set_attr_string(struct switch_dev *dev, struct switch_attr *a, int port_vlan, const char *str)
+{
+ struct switch_port *ports;
+ struct switch_val val;
+ char *ptr;
+
+ memset(&val, 0, sizeof(val));
+ val.port_vlan = port_vlan;
+ switch(a->type) {
+ case SWITCH_TYPE_INT:
+ val.value.i = atoi(str);
+ break;
+ case SWITCH_TYPE_STRING:
+ val.value.s = (char *)str;
+ break;
+ case SWITCH_TYPE_PORTS:
+ ports = alloca(sizeof(struct switch_port) * dev->ports);
+ memset(ports, 0, sizeof(struct switch_port) * dev->ports);
+ val.len = 0;
+ ptr = (char *)str;
+ while(ptr && *ptr)
+ {
+ while(*ptr && isspace(*ptr))
+ ptr++;
+
+ if (!*ptr)
+ break;
+
+ if (!isdigit(*ptr))
+ return -1;
+
+ if (val.len >= dev->ports)
+ return -1;
+
+ ports[val.len].flags = 0;
+ ports[val.len].id = strtoul(ptr, &ptr, 10);
+ while(*ptr && !isspace(*ptr)) {
+ if (*ptr == 't')
+ ports[val.len].flags |= SWLIB_PORT_FLAG_TAGGED;
+ else
+ return -1;
+
+ ptr++;
+ }
+ if (*ptr)
+ ptr++;
+ val.len++;
+ }
+ val.value.ports = ports;
+ break;
+ case SWITCH_TYPE_NOVAL:
+ if (str && !strcmp(str, "0"))
+ return 0;
+
+ break;
+ default:
+ return -1;
+ }
+ return swlib_set_attr(dev, a, &val);
+}
+
+
+struct attrlist_arg {
+ int id;
+ int atype;
+ struct switch_dev *dev;
+ struct switch_attr *prev;
+ struct switch_attr **head;
+};
+
+static int
+add_id(struct nl_msg *msg, void *arg)
+{
+ struct attrlist_arg *l = arg;
+
+ NLA_PUT_U32(msg, SWITCH_ATTR_ID, l->id);
+
+ return 0;
+nla_put_failure:
+ return -1;
+}
+
+static int
+add_attr(struct nl_msg *msg, void *ptr)
+{
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ struct attrlist_arg *arg = ptr;
+ struct switch_attr *new;
+
+ if (nla_parse(tb, SWITCH_ATTR_MAX - 1, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL) < 0)
+ goto done;
+
+ new = swlib_alloc(sizeof(struct switch_attr));
+ if (!new)
+ goto done;
+
+ new->dev = arg->dev;
+ new->atype = arg->atype;
+ if (arg->prev) {
+ arg->prev->next = new;
+ } else {
+ arg->prev = *arg->head;
+ }
+ *arg->head = new;
+ arg->head = &new->next;
+
+ if (tb[SWITCH_ATTR_OP_ID])
+ new->id = nla_get_u32(tb[SWITCH_ATTR_OP_ID]);
+ if (tb[SWITCH_ATTR_OP_TYPE])
+ new->type = nla_get_u32(tb[SWITCH_ATTR_OP_TYPE]);
+ if (tb[SWITCH_ATTR_OP_NAME])
+ new->name = strdup(nla_get_string(tb[SWITCH_ATTR_OP_NAME]));
+ if (tb[SWITCH_ATTR_OP_DESCRIPTION])
+ new->description = strdup(nla_get_string(tb[SWITCH_ATTR_OP_DESCRIPTION]));
+
+done:
+ return NL_SKIP;
+}
+
+int
+swlib_scan(struct switch_dev *dev)
+{
+ struct attrlist_arg arg;
+
+ if (dev->ops || dev->port_ops || dev->vlan_ops)
+ return 0;
+
+ arg.atype = SWLIB_ATTR_GROUP_GLOBAL;
+ arg.dev = dev;
+ arg.id = dev->id;
+ arg.prev = NULL;
+ arg.head = &dev->ops;
+ swlib_call(SWITCH_CMD_LIST_GLOBAL, add_attr, add_id, &arg);
+
+ arg.atype = SWLIB_ATTR_GROUP_PORT;
+ arg.prev = NULL;
+ arg.head = &dev->port_ops;
+ swlib_call(SWITCH_CMD_LIST_PORT, add_attr, add_id, &arg);
+
+ arg.atype = SWLIB_ATTR_GROUP_VLAN;
+ arg.prev = NULL;
+ arg.head = &dev->vlan_ops;
+ swlib_call(SWITCH_CMD_LIST_VLAN, add_attr, add_id, &arg);
+
+ return 0;
+}
+
+struct switch_attr *swlib_lookup_attr(struct switch_dev *dev,
+ enum swlib_attr_group atype, const char *name)
+{
+ struct switch_attr *head;
+
+ if (!name || !dev)
+ return NULL;
+
+ switch(atype) {
+ case SWLIB_ATTR_GROUP_GLOBAL:
+ head = dev->ops;
+ break;
+ case SWLIB_ATTR_GROUP_PORT:
+ head = dev->port_ops;
+ break;
+ case SWLIB_ATTR_GROUP_VLAN:
+ head = dev->vlan_ops;
+ break;
+ }
+ while(head) {
+ if (!strcmp(name, head->name))
+ return head;
+ head = head->next;
+ }
+
+ return NULL;
+}
+
+static void
+swlib_priv_free(void)
+{
+ if (family)
+ nl_object_put((struct nl_object*)family);
+ if (cache)
+ nl_cache_free(cache);
+ if (handle)
+ nl_socket_free(handle);
+ family = NULL;
+ handle = NULL;
+ cache = NULL;
+}
+
+static int
+swlib_priv_init(void)
+{
+ int ret;
+
+ handle = nl_socket_alloc();
+ if (!handle) {
+ DPRINTF("Failed to create handle\n");
+ goto err;
+ }
+
+ if (genl_connect(handle)) {
+ DPRINTF("Failed to connect to generic netlink\n");
+ goto err;
+ }
+
+ ret = genl_ctrl_alloc_cache(handle, &cache);
+ if (ret < 0) {
+ DPRINTF("Failed to allocate netlink cache\n");
+ goto err;
+ }
+
+ family = genl_ctrl_search_by_name(cache, "switch");
+ if (!family) {
+ DPRINTF("Switch API not present\n");
+ goto err;
+ }
+ return 0;
+
+err:
+ swlib_priv_free();
+ return -EINVAL;
+}
+
+struct swlib_scan_arg {
+ const char *name;
+ struct switch_dev *head;
+ struct switch_dev *ptr;
+};
+
+static int
+add_port_map(struct switch_dev *dev, struct nlattr *nla)
+{
+ struct nlattr *p;
+ int err = 0, idx = 0;
+ int remaining;
+
+ dev->maps = malloc(sizeof(struct switch_portmap) * dev->ports);
+ if (!dev->maps)
+ return -1;
+ memset(dev->maps, 0, sizeof(struct switch_portmap) * dev->ports);
+
+ nla_for_each_nested(p, nla, remaining) {
+ struct nlattr *tb[SWITCH_PORTMAP_MAX+1];
+
+ if (idx >= dev->ports)
+ continue;
+
+ err = nla_parse_nested(tb, SWITCH_PORTMAP_MAX, p, portmap_policy);
+ if (err < 0)
+ continue;
+
+
+ if (tb[SWITCH_PORTMAP_SEGMENT] && tb[SWITCH_PORTMAP_VIRT]) {
+ dev->maps[idx].segment = strdup(nla_get_string(tb[SWITCH_PORTMAP_SEGMENT]));
+ dev->maps[idx].virt = nla_get_u32(tb[SWITCH_PORTMAP_VIRT]);
+ }
+ idx++;
+ }
+
+out:
+ return err;
+}
+
+
+static int
+add_switch(struct nl_msg *msg, void *arg)
+{
+ struct swlib_scan_arg *sa = arg;
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ struct switch_dev *dev;
+ const char *name;
+ const char *alias;
+
+ if (nla_parse(tb, SWITCH_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0)
+ goto done;
+
+ if (!tb[SWITCH_ATTR_DEV_NAME])
+ goto done;
+
+ name = nla_get_string(tb[SWITCH_ATTR_DEV_NAME]);
+ alias = nla_get_string(tb[SWITCH_ATTR_ALIAS]);
+
+ if (sa->name && (strcmp(name, sa->name) != 0) && (strcmp(alias, sa->name) != 0))
+ goto done;
+
+ dev = swlib_alloc(sizeof(struct switch_dev));
+ if (!dev)
+ goto done;
+
+ strncpy(dev->dev_name, name, IFNAMSIZ - 1);
+ dev->alias = strdup(alias);
+ if (tb[SWITCH_ATTR_ID])
+ dev->id = nla_get_u32(tb[SWITCH_ATTR_ID]);
+ if (tb[SWITCH_ATTR_NAME])
+ dev->name = strdup(nla_get_string(tb[SWITCH_ATTR_NAME]));
+ if (tb[SWITCH_ATTR_PORTS])
+ dev->ports = nla_get_u32(tb[SWITCH_ATTR_PORTS]);
+ if (tb[SWITCH_ATTR_VLANS])
+ dev->vlans = nla_get_u32(tb[SWITCH_ATTR_VLANS]);
+ if (tb[SWITCH_ATTR_CPU_PORT])
+ dev->cpu_port = nla_get_u32(tb[SWITCH_ATTR_CPU_PORT]);
+ if (tb[SWITCH_ATTR_PORTMAP])
+ add_port_map(dev, tb[SWITCH_ATTR_PORTMAP]);
+
+ if (!sa->head) {
+ sa->head = dev;
+ sa->ptr = dev;
+ } else {
+ sa->ptr->next = dev;
+ sa->ptr = dev;
+ }
+
+ refcount++;
+done:
+ return NL_SKIP;
+}
+
+static int
+list_switch(struct nl_msg *msg, void *arg)
+{
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+
+ if (nla_parse(tb, SWITCH_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0)
+ goto done;
+
+ if (!tb[SWITCH_ATTR_DEV_NAME] || !tb[SWITCH_ATTR_NAME])
+ goto done;
+
+ printf("Found: %s - %s\n", nla_get_string(tb[SWITCH_ATTR_DEV_NAME]),
+ nla_get_string(tb[SWITCH_ATTR_ALIAS]));
+
+done:
+ return NL_SKIP;
+}
+
+void
+swlib_list(void)
+{
+ if (swlib_priv_init() < 0)
+ return;
+ swlib_call(SWITCH_CMD_GET_SWITCH, list_switch, NULL, NULL);
+ swlib_priv_free();
+}
+
+void
+swlib_print_portmap(struct switch_dev *dev, char *segment)
+{
+ int i;
+
+ if (segment) {
+ if (!strcmp(segment, "cpu")) {
+ printf("%d ", dev->cpu_port);
+ } else if (!strcmp(segment, "disabled")) {
+ for (i = 0; i < dev->ports; i++)
+ if (!dev->maps[i].segment)
+ printf("%d ", i);
+ } else for (i = 0; i < dev->ports; i++) {
+ if (dev->maps[i].segment && !strcmp(dev->maps[i].segment, segment))
+ printf("%d ", i);
+ }
+ } else {
+ printf("%s - %s\n", dev->dev_name, dev->name);
+ for (i = 0; i < dev->ports; i++)
+ if (i == dev->cpu_port)
+ printf("port%d:\tcpu\n", i);
+ else if (dev->maps[i].segment)
+ printf("port%d:\t%s.%d\n", i, dev->maps[i].segment, dev->maps[i].virt);
+ else
+ printf("port%d:\tdisabled\n", i);
+ }
+}
+
+struct switch_dev *
+swlib_connect(const char *name)
+{
+ struct swlib_scan_arg arg;
+
+ if (!refcount) {
+ if (swlib_priv_init() < 0)
+ return NULL;
+ };
+
+ arg.head = NULL;
+ arg.ptr = NULL;
+ arg.name = name;
+ swlib_call(SWITCH_CMD_GET_SWITCH, add_switch, NULL, &arg);
+
+ if (!refcount)
+ swlib_priv_free();
+
+ return arg.head;
+}
+
+static void
+swlib_free_attributes(struct switch_attr **head)
+{
+ struct switch_attr *a = *head;
+ struct switch_attr *next;
+
+ while (a) {
+ next = a->next;
+ free(a->name);
+ free(a->description);
+ free(a);
+ a = next;
+ }
+ *head = NULL;
+}
+
+static void
+swlib_free_port_map(struct switch_dev *dev)
+{
+ int i;
+
+ if (!dev || !dev->maps)
+ return;
+
+ for (i = 0; i < dev->ports; i++)
+ free(dev->maps[i].segment);
+ free(dev->maps);
+}
+
+void
+swlib_free(struct switch_dev *dev)
+{
+ swlib_free_attributes(&dev->ops);
+ swlib_free_attributes(&dev->port_ops);
+ swlib_free_attributes(&dev->vlan_ops);
+ swlib_free_port_map(dev);
+ free(dev->name);
+ free(dev->alias);
+ free(dev);
+
+ if (--refcount == 0)
+ swlib_priv_free();
+}
+
+void
+swlib_free_all(struct switch_dev *dev)
+{
+ struct switch_dev *p;
+
+ while (dev) {
+ p = dev->next;
+ swlib_free(dev);
+ dev = p;
+ }
+}
diff --git a/package/network/config/swconfig/src/swlib.h b/package/network/config/swconfig/src/swlib.h
new file mode 100644
index 0000000..7edece3
--- /dev/null
+++ b/package/network/config/swconfig/src/swlib.h
@@ -0,0 +1,252 @@
+/*
+ * swlib.h: Switch configuration API (user space part)
+ *
+ * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+
+Usage of the library functions:
+
+ The main datastructure for a switch is the struct switch_device
+ To get started, you first need to use switch_connect() to probe
+ for switches and allocate an instance of this struct.
+
+ There are two possible usage modes:
+ dev = switch_connect("eth0");
+ - this call will look for a switch registered for the linux device
+ "eth0" and only allocate a switch_device for this particular switch.
+
+ dev = switch_connect(NULL)
+ - this will return one switch_device struct for each available
+ switch. The switch_device structs are chained with by ->next pointer
+
+ Then to query a switch for all available attributes, use:
+ swlib_scan(dev);
+
+ All allocated datastructures for the switch_device struct can be freed with
+ swlib_free(dev);
+ or
+ swlib_free_all(dev);
+
+ The latter traverses a whole chain of switch_device structs and frees them all
+
+ Switch attributes (struct switch_attr) are divided into three groups:
+ dev->ops:
+ - global settings
+ dev->port_ops:
+ - per-port settings
+ dev->vlan_ops:
+ - per-vlan settings
+
+ switch_lookup_attr() is a small helper function to locate attributes
+ by name.
+
+ switch_set_attr() and switch_get_attr() can alter or request the values
+ of attributes.
+
+Usage of the switch_attr struct:
+
+ ->atype: attribute group, one of:
+ - SWLIB_ATTR_GROUP_GLOBAL
+ - SWLIB_ATTR_GROUP_VLAN
+ - SWLIB_ATTR_GROUP_PORT
+
+ ->id: identifier for the attribute
+
+ ->type: data type, one of:
+ - SWITCH_TYPE_INT
+ - SWITCH_TYPE_STRING
+ - SWITCH_TYPE_PORT
+
+ ->name: short name of the attribute
+ ->description: longer description
+ ->next: pointer to the next attribute of the current group
+
+
+Usage of the switch_val struct:
+
+ When setting attributes, following members of the struct switch_val need
+ to be set up:
+
+ ->len (for attr->type == SWITCH_TYPE_PORT)
+ ->port_vlan:
+ - port number (for attr->atype == SWLIB_ATTR_GROUP_PORT), or:
+ - vlan number (for attr->atype == SWLIB_ATTR_GROUP_VLAN)
+ ->value.i (for attr->type == SWITCH_TYPE_INT)
+ ->value.s (for attr->type == SWITCH_TYPE_STRING)
+ - owned by the caller, not stored in the library internally
+ ->value.ports (for attr->type == SWITCH_TYPE_PORT)
+ - must point to an array of at lest val->len * sizeof(struct switch_port)
+
+ When getting string attributes, val->value.s must be freed by the caller
+ When getting port list attributes, an internal static buffer is used,
+ which changes from call to call.
+
+ */
+
+#ifndef __SWLIB_H
+#define __SWLIB_H
+
+enum swlib_attr_group {
+ SWLIB_ATTR_GROUP_GLOBAL,
+ SWLIB_ATTR_GROUP_VLAN,
+ SWLIB_ATTR_GROUP_PORT,
+};
+
+enum swlib_port_flags {
+ SWLIB_PORT_FLAG_TAGGED = (1 << 0),
+};
+
+
+struct switch_dev;
+struct switch_attr;
+struct switch_port;
+struct switch_port_map;
+struct switch_val;
+struct uci_package;
+
+struct switch_dev {
+ int id;
+ char dev_name[IFNAMSIZ];
+ char *name;
+ char *alias;
+ int ports;
+ int vlans;
+ int cpu_port;
+ struct switch_attr *ops;
+ struct switch_attr *port_ops;
+ struct switch_attr *vlan_ops;
+ struct switch_portmap *maps;
+ struct switch_dev *next;
+ void *priv;
+};
+
+struct switch_val {
+ struct switch_attr *attr;
+ int len;
+ int err;
+ int port_vlan;
+ union {
+ char *s;
+ int i;
+ struct switch_port *ports;
+ } value;
+};
+
+struct switch_attr {
+ struct switch_dev *dev;
+ int atype;
+ int id;
+ int type;
+ char *name;
+ char *description;
+ struct switch_attr *next;
+};
+
+struct switch_port {
+ unsigned int id;
+ unsigned int flags;
+};
+
+struct switch_portmap {
+ unsigned int virt;
+ char *segment;
+};
+
+/**
+ * swlib_list: list all switches
+ */
+void swlib_list(void);
+
+/**
+ * swlib_print_portmap: get portmap
+ * @dev: switch device struct
+ */
+void swlib_print_portmap(struct switch_dev *dev, char *segment);
+
+/**
+ * swlib_connect: connect to the switch through netlink
+ * @name: name of the ethernet interface,
+ *
+ * if name is NULL, it connect and builds a chain of all switches
+ */
+struct switch_dev *swlib_connect(const char *name);
+
+/**
+ * swlib_free: free all dynamically allocated data for the switch connection
+ * @dev: switch device struct
+ *
+ * all members of a switch device chain (generated by swlib_connect(NULL))
+ * must be freed individually
+ */
+void swlib_free(struct switch_dev *dev);
+
+/**
+ * swlib_free_all: run swlib_free on all devices in the chain
+ * @dev: switch device struct
+ */
+void swlib_free_all(struct switch_dev *dev);
+
+/**
+ * swlib_scan: probe the switch driver for available commands/attributes
+ * @dev: switch device struct
+ */
+int swlib_scan(struct switch_dev *dev);
+
+/**
+ * swlib_lookup_attr: look up a switch attribute
+ * @dev: switch device struct
+ * @type: global, port or vlan
+ * @name: name of the attribute
+ */
+struct switch_attr *swlib_lookup_attr(struct switch_dev *dev,
+ enum swlib_attr_group atype, const char *name);
+
+/**
+ * swlib_set_attr: set the value for an attribute
+ * @dev: switch device struct
+ * @attr: switch attribute struct
+ * @val: attribute value pointer
+ * returns 0 on success
+ */
+int swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr,
+ struct switch_val *val);
+
+/**
+ * swlib_set_attr_string: set the value for an attribute with type conversion
+ * @dev: switch device struct
+ * @attr: switch attribute struct
+ * @port_vlan: port or vlan (if applicable)
+ * @str: string value
+ * returns 0 on success
+ */
+int swlib_set_attr_string(struct switch_dev *dev, struct switch_attr *attr,
+ int port_vlan, const char *str);
+
+/**
+ * swlib_get_attr: get the value for an attribute
+ * @dev: switch device struct
+ * @attr: switch attribute struct
+ * @val: attribute value pointer
+ * returns 0 on success
+ * for string attributes, the result string must be freed by the caller
+ */
+int swlib_get_attr(struct switch_dev *dev, struct switch_attr *attr,
+ struct switch_val *val);
+
+/**
+ * swlib_apply_from_uci: set up the switch from a uci configuration
+ * @dev: switch device struct
+ * @p: uci package which contains the desired global config
+ */
+int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p);
+
+#endif
diff --git a/package/network/config/swconfig/src/uci.c b/package/network/config/swconfig/src/uci.c
new file mode 100644
index 0000000..bbeeb03
--- /dev/null
+++ b/package/network/config/swconfig/src/uci.c
@@ -0,0 +1,246 @@
+/*
+ * uci.c: UCI binding for the switch configuration utility
+ *
+ * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundatio.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <uci.h>
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+#include <linux/genetlink.h>
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/switch.h>
+#include "swlib.h"
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+struct swlib_setting {
+ struct switch_attr *attr;
+ const char *name;
+ int port_vlan;
+ const char *val;
+ struct swlib_setting *next;
+};
+
+struct swlib_setting early_settings[] = {
+ { .name = "reset", .val = "1" },
+ { .name = "enable_vlan", .val = "1" },
+};
+
+static struct swlib_setting *settings;
+static struct swlib_setting **head;
+
+static bool swlib_match_name(struct switch_dev *dev, const char *name)
+{
+ return (strcmp(name, dev->dev_name) == 0 ||
+ strcmp(name, dev->alias) == 0);
+}
+
+static int
+swlib_map_settings(struct switch_dev *dev, int type, int port_vlan, struct uci_section *s)
+{
+ struct swlib_setting *setting;
+ struct switch_attr *attr;
+ struct uci_element *e;
+ struct uci_option *o;
+
+ uci_foreach_element(&s->options, e) {
+ o = uci_to_option(e);
+
+ if (o->type != UCI_TYPE_STRING)
+ continue;
+
+ if (!strcmp(e->name, "device"))
+ continue;
+
+ /* map early settings */
+ if (type == SWLIB_ATTR_GROUP_GLOBAL) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
+ if (strcmp(e->name, early_settings[i].name) != 0)
+ continue;
+
+ early_settings[i].val = o->v.string;
+ goto skip;
+ }
+ }
+
+ attr = swlib_lookup_attr(dev, type, e->name);
+ if (!attr)
+ continue;
+
+ setting = malloc(sizeof(struct swlib_setting));
+ memset(setting, 0, sizeof(struct swlib_setting));
+ setting->attr = attr;
+ setting->port_vlan = port_vlan;
+ setting->val = o->v.string;
+ *head = setting;
+ head = &setting->next;
+skip:
+ continue;
+ }
+}
+
+int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p)
+{
+ struct switch_attr *attr;
+ struct uci_element *e;
+ struct uci_section *s;
+ struct uci_option *o;
+ struct uci_ptr ptr;
+ struct switch_val val;
+ int i;
+
+ settings = NULL;
+ head = &settings;
+
+ uci_foreach_element(&p->sections, e) {
+ struct uci_element *n;
+
+ s = uci_to_section(e);
+
+ if (strcmp(s->type, "switch") != 0)
+ continue;
+
+ uci_foreach_element(&s->options, n) {
+ struct uci_option *o = uci_to_option(n);
+
+ if (strcmp(n->name, "name") != 0)
+ continue;
+
+ if (o->type != UCI_TYPE_STRING)
+ continue;
+
+ if (swlib_match_name(dev, o->v.string))
+ goto found;
+
+ break;
+ }
+
+ if (!swlib_match_name(dev, e->name))
+ continue;
+
+ goto found;
+ }
+
+ /* not found */
+ return -1;
+
+found:
+ /* look up available early options, which need to be taken care
+ * of in the correct order */
+ for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
+ early_settings[i].attr = swlib_lookup_attr(dev,
+ SWLIB_ATTR_GROUP_GLOBAL, early_settings[i].name);
+ }
+ swlib_map_settings(dev, SWLIB_ATTR_GROUP_GLOBAL, 0, s);
+
+ /* look for port or vlan sections */
+ uci_foreach_element(&p->sections, e) {
+ struct uci_element *os;
+ s = uci_to_section(e);
+
+ if (!strcmp(s->type, "switch_port")) {
+ char *devn, *port, *port_err = NULL;
+ int port_n;
+
+ uci_foreach_element(&s->options, os) {
+ o = uci_to_option(os);
+ if (o->type != UCI_TYPE_STRING)
+ continue;
+
+ if (!strcmp(os->name, "device")) {
+ devn = o->v.string;
+ if (!swlib_match_name(dev, devn))
+ devn = NULL;
+ } else if (!strcmp(os->name, "port")) {
+ port = o->v.string;
+ }
+ }
+ if (!devn || !port || !port[0])
+ continue;
+
+ port_n = strtoul(port, &port_err, 0);
+ if (port_err && port_err[0])
+ continue;
+
+ swlib_map_settings(dev, SWLIB_ATTR_GROUP_PORT, port_n, s);
+ } else if (!strcmp(s->type, "switch_vlan")) {
+ char *devn, *vlan, *vlan_err = NULL;
+ int vlan_n;
+
+ uci_foreach_element(&s->options, os) {
+ o = uci_to_option(os);
+ if (o->type != UCI_TYPE_STRING)
+ continue;
+
+ if (!strcmp(os->name, "device")) {
+ devn = o->v.string;
+ if (!swlib_match_name(dev, devn))
+ devn = NULL;
+ } else if (!strcmp(os->name, "vlan")) {
+ vlan = o->v.string;
+ }
+ }
+ if (!devn || !vlan || !vlan[0])
+ continue;
+
+ vlan_n = strtoul(vlan, &vlan_err, 0);
+ if (vlan_err && vlan_err[0])
+ continue;
+
+ swlib_map_settings(dev, SWLIB_ATTR_GROUP_VLAN, vlan_n, s);
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
+ struct swlib_setting *st = &early_settings[i];
+ if (!st->attr || !st->val)
+ continue;
+ swlib_set_attr_string(dev, st->attr, st->port_vlan, st->val);
+
+ }
+
+ while (settings) {
+ struct swlib_setting *st = settings;
+
+ swlib_set_attr_string(dev, st->attr, st->port_vlan, st->val);
+ st = st->next;
+ free(settings);
+ settings = st;
+ }
+
+ /* Apply the config */
+ attr = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_GLOBAL, "apply");
+ if (!attr)
+ return 0;
+
+ memset(&val, 0, sizeof(val));
+ swlib_set_attr(dev, attr, &val);
+
+ return 0;
+}
diff --git a/package/network/ipv6/6in4/Makefile b/package/network/ipv6/6in4/Makefile
new file mode 100644
index 0000000..9eca57a
--- /dev/null
+++ b/package/network/ipv6/6in4/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2010-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:=6in4
+PKG_VERSION:=22
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/6in4
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=@IPV6 +kmod-sit
+ TITLE:=IPv6-in-IPv4 configuration support
+ MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
+ PKGARCH:=all
+endef
+
+define Package/6in4/description
+Provides support for 6in4 tunnels in /etc/config/network.
+Refer to http://wiki.openwrt.org/doc/uci/network for
+configuration details.
+endef
+
+define Build/Compile
+endef
+
+define Build/Configure
+endef
+
+define Package/6in4/install
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/6in4.sh $(1)/lib/netifd/proto/6in4.sh
+endef
+
+$(eval $(call BuildPackage,6in4))
diff --git a/package/network/ipv6/6in4/files/6in4.sh b/package/network/ipv6/6in4/files/6in4.sh
new file mode 100755
index 0000000..59747a3
--- /dev/null
+++ b/package/network/ipv6/6in4/files/6in4.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+# 6in4.sh - IPv6-in-IPv4 tunnel backend
+# Copyright (c) 2010-2015 OpenWrt.org
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_6in4_update() {
+ sh -c '
+ local timeout=5
+
+ (while [ $((timeout--)) -gt 0 ]; do
+ sleep 1
+ kill -0 $$ || exit 0
+ done; kill -9 $$) 2>/dev/null &
+
+ exec "$@"
+ ' "$1" "$@"
+}
+
+proto_6in4_setup() {
+ local cfg="$1"
+ local iface="$2"
+ local link="6in4-$cfg"
+
+ local mtu ttl tos ipaddr peeraddr ip6addr ip6prefix tunlink tunnelid username password updatekey
+ json_get_vars mtu ttl tos ipaddr peeraddr ip6addr ip6prefix tunlink tunnelid username password updatekey
+
+ [ -z "$peeraddr" ] && {
+ proto_notify_error "$cfg" "MISSING_ADDRESS"
+ proto_block_restart "$cfg"
+ return
+ }
+
+ ( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" )
+
+ [ -z "$ipaddr" ] && {
+ local wanif="$tunlink"
+ if [ -z "$wanif" ] && ! network_find_wan wanif; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ return
+ fi
+
+ if ! network_get_ipaddr ipaddr "$wanif"; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ return
+ fi
+ }
+
+ proto_init_update "$link" 1
+
+ [ -n "$ip6addr" ] && {
+ local local6="${ip6addr%%/*}"
+ local mask6="${ip6addr##*/}"
+ [[ "$local6" = "$mask6" ]] && mask6=
+ proto_add_ipv6_address "$local6" "$mask6"
+ proto_add_ipv6_route "::" 0 "" "" "" "$local6/$mask6"
+ }
+
+ [ -n "$ip6prefix" ] && {
+ proto_add_ipv6_prefix "$ip6prefix"
+ proto_add_ipv6_route "::" 0 "" "" "" "$ip6prefix"
+ }
+
+ proto_add_tunnel
+ json_add_string mode sit
+ json_add_int mtu "${mtu:-1280}"
+ json_add_int ttl "${ttl:-64}"
+ [ -n "$tos" ] && json_add_string tos "$tos"
+ json_add_string local "$ipaddr"
+ json_add_string remote "$peeraddr"
+ [ -n "$tunlink" ] && json_add_string link "$tunlink"
+ proto_close_tunnel
+
+ proto_send_update "$cfg"
+
+ [ -n "$tunnelid" -a -n "$username" -a \( -n "$password" -o -n "$updatekey" \) ] && {
+ [ -n "$updatekey" ] && password="$updatekey"
+
+ local http="http"
+ local urlget="wget"
+ local urlget_opts="-qO-"
+ local ca_path="${SSL_CERT_DIR-/etc/ssl/certs}"
+
+ if [ -n "$(which curl)" ]; then
+ urlget="curl"
+ urlget_opts="-s -S"
+ if curl -V | grep "Protocols:" | grep -qF "https"; then
+ http="https"
+ urlget_opts="$urlget_opts --capath $ca_path"
+ fi
+ fi
+ if [ "$http" = "http" ] &&
+ wget --version 2>&1 | grep -qF "+https"; then
+ urlget="wget"
+ urlget_opts="-qO- --ca-directory=$ca_path"
+ http="https"
+ fi
+ [ "$http" = "https" -a -z "$(find $ca_path -name "*.0" 2>/dev/null)" ] && {
+ if [ "$urlget" = "curl" ]; then
+ urlget_opts="$urlget_opts -k"
+ else
+ urlget_opts="$urlget_opts --no-check-certificate"
+ fi
+ }
+
+ local url="$http://ipv4.tunnelbroker.net/nic/update?username=$username&password=$password&hostname=$tunnelid"
+ local try=0
+ local max=3
+
+ (
+ set -o pipefail
+ while [ $((++try)) -le $max ]; do
+ if proto_6in4_update $urlget $urlget_opts "$url" 2>&1 | \
+ sed -e 's,^Killed$,timeout,' -e "s,^,update $try/$max: ," | \
+ logger -t "$link";
+ then
+ logger -t "$link" "updated"
+ return 0
+ fi
+ sleep 5
+ done
+ logger -t "$link" "update failed"
+ )
+ }
+}
+
+proto_6in4_teardown() {
+ local cfg="$1"
+}
+
+proto_6in4_init_config() {
+ no_device=1
+ available=1
+
+ proto_config_add_string "ipaddr"
+ proto_config_add_string "ip6addr"
+ proto_config_add_string "ip6prefix"
+ proto_config_add_string "peeraddr"
+ proto_config_add_string "tunlink"
+ proto_config_add_string "tunnelid"
+ proto_config_add_string "username"
+ proto_config_add_string "password"
+ proto_config_add_string "updatekey"
+ proto_config_add_int "mtu"
+ proto_config_add_int "ttl"
+ proto_config_add_string "tos"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol 6in4
+}
diff --git a/package/network/ipv6/6rd/Makefile b/package/network/ipv6/6rd/Makefile
new file mode 100644
index 0000000..04d607e
--- /dev/null
+++ b/package/network/ipv6/6rd/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2010-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:=6rd
+PKG_VERSION:=9
+PKG_RELEASE:=2
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/6rd
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=@IPV6 +kmod-sit
+ TITLE:=6rd configuration support
+ MAINTAINER:=Steven Barth <cyrus@openwrt.org>
+ PKGARCH:=all
+endef
+
+define Package/6rd/description
+Provides support for 6rd tunnels in /etc/config/network.
+Refer to http://wiki.openwrt.org/doc/uci/network for
+configuration details.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -Wall" \
+ LDFLAGS="$(TARGET_LDFLAGS)"
+endef
+
+define Package/6rd/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/6rdcalc $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/6rd.sh $(1)/lib/netifd/proto/6rd.sh
+endef
+
+$(eval $(call BuildPackage,6rd))
diff --git a/package/network/ipv6/6rd/files/6rd.sh b/package/network/ipv6/6rd/files/6rd.sh
new file mode 100644
index 0000000..62d35b6
--- /dev/null
+++ b/package/network/ipv6/6rd/files/6rd.sh
@@ -0,0 +1,102 @@
+#!/bin/sh
+# 6rd.sh - IPv6-in-IPv4 tunnel backend
+# Copyright (c) 2010-2012 OpenWrt.org
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_6rd_setup() {
+ local cfg="$1"
+ local iface="$2"
+ local link="6rd-$cfg"
+
+ local mtu df ttl tos ipaddr peeraddr ip6prefix ip6prefixlen ip4prefixlen tunlink zone
+ json_get_vars mtu df ttl tos ipaddr peeraddr ip6prefix ip6prefixlen ip4prefixlen tunlink zone
+
+ [ -z "$ip6prefix" -o -z "$peeraddr" ] && {
+ proto_notify_error "$cfg" "MISSING_ADDRESS"
+ proto_block_restart "$cfg"
+ return
+ }
+
+ ( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" )
+
+ [ -z "$ipaddr" ] && {
+ local wanif="$tunlink"
+ if [ -z $wanif ] && ! network_find_wan wanif; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ return
+ fi
+
+ if ! network_get_ipaddr ipaddr "$wanif"; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ return
+ fi
+ }
+
+ # Determine the relay prefix.
+ local ip4prefixlen="${ip4prefixlen:-0}"
+ local ip4prefix=$(ipcalc.sh "$ipaddr/$ip4prefixlen" | grep NETWORK)
+ ip4prefix="${ip4prefix#NETWORK=}"
+
+ # Determine our IPv6 address.
+ local ip6subnet=$(6rdcalc "$ip6prefix/$ip6prefixlen" "$ipaddr/$ip4prefixlen")
+ local ip6addr="${ip6subnet%%::*}::1"
+
+ # Determine the IPv6 prefix
+ local ip6lanprefix="$ip6subnet/$(($ip6prefixlen + 32 - $ip4prefixlen))"
+
+ proto_init_update "$link" 1
+ proto_add_ipv6_address "$ip6addr" "$ip6prefixlen"
+ proto_add_ipv6_prefix "$ip6lanprefix"
+
+ proto_add_ipv6_route "::" 0 "::$peeraddr" 4096 "" "$ip6addr/$ip6prefixlen"
+ proto_add_ipv6_route "::" 0 "::$peeraddr" 4096 "" "$ip6lanprefix"
+
+ proto_add_tunnel
+ json_add_string mode sit
+ json_add_int mtu "${mtu:-1280}"
+ json_add_boolean df "${df:-1}"
+ json_add_int ttl "${ttl:-64}"
+ [ -n "$tos" ] && json_add_string tos "$tos"
+ json_add_string local "$ipaddr"
+ json_add_string 6rd-prefix "$ip6prefix/$ip6prefixlen"
+ json_add_string 6rd-relay-prefix "$ip4prefix/$ip4prefixlen"
+ [ -n "$tunlink" ] && json_add_string link "$tunlink"
+ proto_close_tunnel
+
+ proto_add_data
+ [ -n "$zone" ] && json_add_string zone "$zone"
+ proto_close_data
+
+ proto_send_update "$cfg"
+}
+
+proto_6rd_teardown() {
+ local cfg="$1"
+}
+
+proto_6rd_init_config() {
+ no_device=1
+ available=1
+
+ proto_config_add_int "mtu"
+ proto_config_add_boolean "df"
+ proto_config_add_int "ttl"
+ proto_config_add_string "tos"
+ proto_config_add_string "ipaddr"
+ proto_config_add_string "peeraddr"
+ proto_config_add_string "ip6prefix"
+ proto_config_add_string "ip6prefixlen"
+ proto_config_add_string "ip4prefixlen"
+ proto_config_add_string "tunlink"
+ proto_config_add_string "zone"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol 6rd
+}
diff --git a/package/network/ipv6/6rd/src/6rdcalc.c b/package/network/ipv6/6rd/src/6rdcalc.c
new file mode 100644
index 0000000..87bc397
--- /dev/null
+++ b/package/network/ipv6/6rd/src/6rdcalc.c
@@ -0,0 +1,126 @@
+/*
+ * Utility used to calculate the 6rd subnet.
+ *
+ * Copyright 2012, Stéphan Kochen <stephan@kochen.nl>
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define INET_PREFIXSTRLEN (INET_ADDRSTRLEN+3)
+#define INET6_PREFIXSTRLEN (INET6_ADDRSTRLEN+4)
+
+static void print_usage()
+{
+ fprintf(stderr, "Usage: 6rdcalc <v6 prefix>/<mask> <v4 address>/<mask>\n");
+ exit(1);
+}
+
+static void print_error()
+{
+ fprintf(stderr, "%s", strerror(errno));
+ exit(1);
+}
+
+static void parse_str(int af, char *str, void *addr, unsigned long *mask)
+{
+ int ret;
+ char *slash;
+
+ /* Split the address at the slash. */
+ if ((slash = strchr(str, '/')) == NULL)
+ print_usage();
+ *slash = '\0';
+
+ /* Parse the address. */
+ if ((ret = inet_pton(af, str, addr)) != 1) {
+ if (ret == 0)
+ print_usage();
+ else
+ print_error();
+ }
+
+ /* Parse the mask. */
+ *mask = strtoul(slash+1, NULL, 10);
+ if ((af == AF_INET && *mask > 32) ||
+ (af == AF_INET6 && *mask > 128))
+ print_usage();
+}
+
+int main(int argc, const char **argv)
+{
+ char v6str[INET6_PREFIXSTRLEN], v4str[INET_PREFIXSTRLEN];
+ struct in6_addr v6;
+ struct in_addr v4;
+ unsigned long v6it, v4it, mask;
+ unsigned char *byte4, *byte6;
+ unsigned char bit4, bit6;
+
+ /* Check parameters. */
+ if (argc != 3)
+ print_usage();
+
+ /* Parse the v6 address. */
+ strncpy(v6str, argv[1], INET6_PREFIXSTRLEN);
+ v6str[INET6_PREFIXSTRLEN-1] = '\0';
+ parse_str(AF_INET6, v6str, &v6, &v6it);
+
+ /* Parse the v4 address */
+ strncpy(v4str, argv[2], INET_PREFIXSTRLEN);
+ v6str[INET_PREFIXSTRLEN-1] = '\0';
+ parse_str(AF_INET, v4str, &v4, &v4it);
+
+ /* Check if the combined mask is within bounds. */
+ mask = (32 - v4it) + v6it;
+ if (mask > 128)
+ print_usage();
+
+ /* Combine the addresses. */
+ while (v4it < 32) {
+ byte6 = (unsigned char *)(&v6.s6_addr) + (v6it >> 3);
+ byte4 = (unsigned char *)(&v4.s_addr) + (v4it >> 3);
+ bit6 = 128 >> (v6it & 0x07);
+ bit4 = 128 >> (v4it & 0x07);
+
+ if (*byte4 & bit4)
+ *byte6 |= bit6;
+ else
+ *byte6 &= ~bit6;
+
+ v4it++; v6it++;
+ }
+
+ /* Clear remaining bits. */
+ while (v6it < 128) {
+ byte6 = (unsigned char *)(&v6.s6_addr) + (v6it >> 3);
+ bit6 = 128 >> (v6it & 0x07);
+
+ *byte6 &= ~bit6;
+
+ v6it++;
+ }
+
+ /* Print the subnet prefix. */
+ if (inet_ntop(AF_INET6, &v6, v6str, sizeof(v6str)) == NULL)
+ print_error();
+ printf("%s/%lu\n", v6str, mask);
+ return 0;
+}
diff --git a/package/network/ipv6/6rd/src/Makefile b/package/network/ipv6/6rd/src/Makefile
new file mode 100644
index 0000000..2881d43
--- /dev/null
+++ b/package/network/ipv6/6rd/src/Makefile
@@ -0,0 +1,7 @@
+all: 6rdcalc
+
+6rdcalc: 6rdcalc.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+
+clean:
+ rm -f 6rdcalc
diff --git a/package/network/ipv6/6to4/Makefile b/package/network/ipv6/6to4/Makefile
new file mode 100644
index 0000000..20605f6
--- /dev/null
+++ b/package/network/ipv6/6to4/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2010-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:=6to4
+PKG_VERSION:=12
+PKG_RELEASE:=2
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/6to4
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=@IPV6 +kmod-sit
+ TITLE:=IPv6-to-IPv4 configuration support
+ MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
+ PKGARCH:=all
+endef
+
+define Package/6to4/description
+Provides support for 6to4 tunnels in /etc/config/network.
+Refer to http://wiki.openwrt.org/doc/uci/network for
+configuration details.
+endef
+
+define Build/Compile
+endef
+
+define Build/Configure
+endef
+
+define Package/6to4/install
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/6to4.sh $(1)/lib/netifd/proto/6to4.sh
+endef
+
+$(eval $(call BuildPackage,6to4))
diff --git a/package/network/ipv6/6to4/files/6to4.sh b/package/network/ipv6/6to4/files/6to4.sh
new file mode 100755
index 0000000..a5d0567
--- /dev/null
+++ b/package/network/ipv6/6to4/files/6to4.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+# 6to4.sh - IPv6-in-IPv4 tunnel backend
+# Copyright (c) 2010-2012 OpenWrt.org
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+find_6to4_prefix() {
+ local ip4="$1"
+ local oIFS="$IFS"; IFS="."; set -- $ip4; IFS="$oIFS"
+
+ printf "2002:%02x%02x:%02x%02x\n" $1 $2 $3 $4
+}
+
+test_6to4_rfc1918()
+{
+ local oIFS="$IFS"; IFS="."; set -- $1; IFS="$oIFS"
+ [ $1 -eq 10 ] && return 0
+ [ $1 -eq 192 ] && [ $2 -eq 168 ] && return 0
+ [ $1 -eq 172 ] && [ $2 -ge 16 ] && [ $2 -le 31 ] && return 0
+
+ # RFC 6598
+ [ $1 -eq 100 ] && [ $2 -ge 64 ] && [ $2 -le 127 ] && return 0
+
+ return 1
+}
+
+proto_6to4_setup() {
+ local cfg="$1"
+ local iface="$2"
+ local link="6to4-$cfg"
+
+ local mtu ttl tos ipaddr
+ json_get_vars mtu ttl tos ipaddr
+
+ ( proto_add_host_dependency "$cfg" 0.0.0.0 )
+
+ local wanif
+ if ! network_find_wan wanif; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ return
+ fi
+
+ [ -z "$ipaddr" ] && {
+ if ! network_get_ipaddr ipaddr "$wanif"; then
+ proto_notify_error "$cfg" "NO_WAN_ADDRESS"
+ return
+ fi
+ }
+
+ test_6to4_rfc1918 "$ipaddr" && {
+ proto_notify_error "$cfg" "INVALID_LOCAL_ADDRESS"
+ return
+ }
+
+ # find our local prefix
+ local prefix6=$(find_6to4_prefix "$ipaddr")
+ local local6="$prefix6::1"
+
+ proto_init_update "$link" 1
+ proto_add_ipv6_address "$local6" 16
+ proto_add_ipv6_prefix "$prefix6::/48"
+
+ proto_add_ipv6_route "::" 0 "::192.88.99.1" "" "" "$local6/16"
+ proto_add_ipv6_route "::" 0 "::192.88.99.1" "" "" "$prefix6::/48"
+
+ proto_add_tunnel
+ json_add_string mode sit
+ json_add_int mtu "${mtu:-1280}"
+ json_add_int ttl "${ttl:-64}"
+ [ -n "$tos" ] && json_add_string tos "$tos"
+ json_add_string local "$ipaddr"
+ proto_close_tunnel
+
+ proto_send_update "$cfg"
+}
+
+proto_6to4_teardown() {
+ local cfg="$1"
+}
+
+proto_6to4_init_config() {
+ no_device=1
+ available=1
+
+ proto_config_add_string "ipaddr"
+ proto_config_add_int "mtu"
+ proto_config_add_int "ttl"
+ proto_config_add_string "tos"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol 6to4
+}
diff --git a/package/network/ipv6/ds-lite/Makefile b/package/network/ipv6/ds-lite/Makefile
new file mode 100644
index 0000000..919ac7e
--- /dev/null
+++ b/package/network/ipv6/ds-lite/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2013 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:=ds-lite
+PKG_VERSION:=7
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ds-lite
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=@IPV6 +kmod-ip6-tunnel +resolveip
+ TITLE:=Dual-Stack Lite (DS-Lite) configuration support
+ MAINTAINER:=Steven Barth <steven@midlink.org>
+ PKGARCH:=all
+endef
+
+define Package/ds-lite/description
+Provides support for Dual-Stack Lite in /etc/config/network.
+Refer to http://wiki.openwrt.org/doc/uci/network for
+configuration details.
+endef
+
+define Build/Compile
+endef
+
+define Build/Configure
+endef
+
+define Package/ds-lite/install
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/dslite.sh $(1)/lib/netifd/proto/dslite.sh
+endef
+
+$(eval $(call BuildPackage,ds-lite))
diff --git a/package/network/ipv6/ds-lite/files/dslite.sh b/package/network/ipv6/ds-lite/files/dslite.sh
new file mode 100755
index 0000000..a7e0a10
--- /dev/null
+++ b/package/network/ipv6/ds-lite/files/dslite.sh
@@ -0,0 +1,102 @@
+#!/bin/sh
+# dslite.sh - IPv4-in-IPv6 tunnel backend
+# Copyright (c) 2013 OpenWrt.org
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_dslite_setup() {
+ local cfg="$1"
+ local iface="$2"
+ local link="ds-$cfg"
+ local remoteip6
+
+ local mtu ttl peeraddr ip6addr tunlink zone weakif
+ json_get_vars mtu ttl peeraddr ip6addr tunlink zone weakif
+
+ [ -z "$peeraddr" ] && {
+ proto_notify_error "$cfg" "MISSING_ADDRESS"
+ proto_block_restart "$cfg"
+ return
+ }
+
+ ( proto_add_host_dependency "$cfg" "::" "$tunlink" )
+
+ remoteip6=$(resolveip -6 $peeraddr)
+ if [ -z "$remoteip6" ]; then
+ sleep 3
+ remoteip6=$(resolveip -6 $peeraddr)
+ if [ -z "$remoteip6" ]; then
+ proto_notify_error "$cfg" "AFTR_DNS_FAIL"
+ return
+ fi
+ fi
+ peeraddr="${remoteip6%% *}"
+
+ [ -z "$ip6addr" ] && {
+ local wanif="$tunlink"
+ if [ -z "$wanif" ] && ! network_find_wan6 wanif; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ return
+ fi
+
+ if ! network_get_ipaddr6 ip6addr "$wanif"; then
+ [ -z "$weakif" ] && weakif="lan"
+ if ! network_get_ipaddr6 ip6addr "$weakif"; then
+ proto_notify_error "$cfg" "NO_WAN_LINK"
+ return
+ fi
+ fi
+ }
+
+ proto_init_update "$link" 1
+ proto_add_ipv4_route "0.0.0.0" 0
+ proto_add_ipv4_address "192.0.0.2" "" "" "192.0.0.1"
+
+ proto_add_tunnel
+ json_add_string mode ipip6
+ json_add_int mtu "${mtu:-1280}"
+ json_add_int ttl "${ttl:-64}"
+ json_add_string local "$ip6addr"
+ json_add_string remote "$peeraddr"
+ [ -n "$tunlink" ] && json_add_string link "$tunlink"
+ proto_close_tunnel
+
+ proto_add_data
+ [ -n "$zone" ] && json_add_string zone "$zone"
+
+ json_add_array firewall
+ json_add_object ""
+ json_add_string type nat
+ json_add_string target ACCEPT
+ json_close_object
+ json_close_array
+ proto_close_data
+
+ proto_send_update "$cfg"
+}
+
+proto_dslite_teardown() {
+ local cfg="$1"
+}
+
+proto_dslite_init_config() {
+ no_device=1
+ available=1
+
+ proto_config_add_string "ip6addr"
+ proto_config_add_string "peeraddr"
+ proto_config_add_string "tunlink"
+ proto_config_add_int "mtu"
+ proto_config_add_int "ttl"
+ proto_config_add_string "zone"
+ proto_config_add_string "weakif"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol dslite
+}
diff --git a/package/network/ipv6/map/Makefile b/package/network/ipv6/map/Makefile
new file mode 100644
index 0000000..af6f758
--- /dev/null
+++ b/package/network/ipv6/map/Makefile
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2014-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:=map
+PKG_VERSION:=4
+PKG_RELEASE:=5
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/map
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=@IPV6 +kmod-ip6-tunnel +libubox +libubus +iptables-mod-conntrack-extra
+ TITLE:=MAP-E and Lightweight 4over6 configuration support
+ MAINTAINER:=Steven Barth <steven@midlink.org>
+endef
+
+define Package/map/description
+ Provides support for MAP-E (draft-ietf-softwire-map) and
+ Lightweight 4over6 (draft-ietf-softwire-lw4over6) in /etc/config/network.
+ Refer to http://wiki.openwrt.org/doc/uci/network for
+ configuration details.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Package/map/install
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/map.sh $(1)/lib/netifd/proto/map.sh
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/mapcalc $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,map))
diff --git a/package/network/ipv6/map/files/map.sh b/package/network/ipv6/map/files/map.sh
new file mode 100755
index 0000000..98a493d
--- /dev/null
+++ b/package/network/ipv6/map/files/map.sh
@@ -0,0 +1,221 @@
+#!/bin/sh
+# map.sh - IPv4-in-IPv6 tunnel backend
+#
+# Author: Steven Barth <cyrus@openwrt.org>
+# Copyright (c) 2014 cisco Systems, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation
+#
+# 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.
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_map_setup() {
+ local cfg="$1"
+ local iface="$2"
+ local link="map-$cfg"
+
+ # uncomment for legacy MAP0 mode
+ #export LEGACY=1
+
+ local type mtu ttl tunlink zone
+ local rule ipaddr ip4prefixlen ip6prefix ip6prefixlen peeraddr ealen psidlen psid offset
+ json_get_vars type mtu ttl tunlink zone
+ json_get_vars rule ipaddr ip4prefixlen ip6prefix ip6prefixlen peeraddr ealen psidlen psid offset
+
+ [ -z "$zone" ] && zone="wan"
+ [ -z "$type" ] && type="map-e"
+ [ -z "$ip4prefixlen" ] && ip4prefixlen=32
+
+ ( proto_add_host_dependency "$cfg" "::" "$tunlink" )
+
+ # fixme: handle RA/DHCPv6 address race for LW
+ [ "$type" = lw4o6 ] && sleep 5
+
+ if [ -z "$rule" ]; then
+ rule="type=$type,ipv6prefix=$ip6prefix,prefix6len=$ip6prefixlen,ipv4prefix=$ipaddr,prefix4len=$ip4prefixlen"
+ [ -n "$psid" ] && rule="$rule,psid=$psid"
+ [ -n "$psidlen" ] && rule="$rule,psidlen=$psidlen"
+ [ -n "$offset" ] && rule="$rule,offset=$offset"
+ [ -n "$ealen" ] && rule="$rule,ealen=$ealen"
+ if [ "$type" = "map-t" ]; then
+ rule="$rule,dmr=$peeraddr"
+ else
+ rule="$rule,br=$peeraddr"
+ fi
+ fi
+
+ echo "rule=$rule" > /tmp/map-$cfg.rules
+ RULE_DATA=$(mapcalc ${tunlink:-\*} $rule)
+ if [ "$?" != 0 ]; then
+ proto_notify_error "$cfg" "INVALID_MAP_RULE"
+ proto_block_restart "$cfg"
+ return
+ fi
+
+ echo "$RULE_DATA" >> /tmp/map-$cfg.rules
+ eval $RULE_DATA
+
+ if [ -z "$RULE_BMR" ]; then
+ proto_notify_error "$cfg" "NO_MATCHING_PD"
+ proto_block_restart "$cfg"
+ return
+ fi
+
+ k=$RULE_BMR
+ if [ "$type" = "lw4o6" -o "$type" = "map-e" ]; then
+ proto_init_update "$link" 1
+ proto_add_ipv4_address $(eval "echo \$RULE_${k}_IPV4ADDR") "" "" ""
+
+ proto_add_tunnel
+ json_add_string mode ipip6
+ json_add_int mtu "${mtu:-1280}"
+ json_add_int ttl "${ttl:-64}"
+ json_add_string local $(eval "echo \$RULE_${k}_IPV6ADDR")
+ json_add_string remote $(eval "echo \$RULE_${k}_BR")
+ json_add_string link $(eval "echo \$RULE_${k}_PD6IFACE")
+
+ if [ "$type" = "map-e" ]; then
+ json_add_array "fmrs"
+ for i in $(seq $RULE_COUNT); do
+ [ "$(eval "echo \$RULE_${i}_FMR")" != 1 ] && continue
+ fmr="$(eval "echo \$RULE_${i}_IPV6PREFIX")/$(eval "echo \$RULE_${i}_PREFIX6LEN")"
+ fmr="$fmr,$(eval "echo \$RULE_${i}_IPV4PREFIX")/$(eval "echo \$RULE_${i}_PREFIX4LEN")"
+ fmr="$fmr,$(eval "echo \$RULE_${i}_EALEN"),$(eval "echo \$RULE_${i}_OFFSET")"
+ json_add_string "" "$fmr"
+ done
+ json_close_array
+ fi
+
+ proto_close_tunnel
+ elif [ "$type" = "map-t" -a -f "/proc/net/nat46/control" ]; then
+ proto_init_update "$link" 1
+ local style="MAP"
+ [ "$LEGACY" = 1 ] && style="MAP0"
+
+ echo add $link > /proc/net/nat46/control
+ local cfgstr="local.style $style local.v4 $(eval "echo \$RULE_${k}_IPV4PREFIX")/$(eval "echo \$RULE_${k}_PREFIX4LEN")"
+ cfgstr="$cfgstr local.v6 $(eval "echo \$RULE_${k}_IPV6PREFIX")/$(eval "echo \$RULE_${k}_PREFIX6LEN")"
+ cfgstr="$cfgstr local.ea-len $(eval "echo \$RULE_${k}_EALEN") local.psid-offset $(eval "echo \$RULE_${k}_OFFSET")"
+ cfgstr="$cfgstr remote.v4 0.0.0.0/0 remote.v6 $(eval "echo \$RULE_${k}_DMR") remote.style RFC6052 remote.ea-len 0 remote.psid-offset 0"
+ echo config $link $cfgstr > /proc/net/nat46/control
+
+ for i in $(seq $RULE_COUNT); do
+ [ "$(eval "echo \$RULE_${i}_FMR")" != 1 ] && continue
+ local cfgstr="remote.style $style remote.v4 $(eval "echo \$RULE_${i}_IPV4PREFIX")/$(eval "echo \$RULE_${i}_PREFIX4LEN")"
+ cfgstr="$cfgstr remote.v6 $(eval "echo \$RULE_${i}_IPV6PREFIX")/$(eval "echo \$RULE_${i}_PREFIX6LEN")"
+ cfgstr="$cfgstr remote.ea-len $(eval "echo \$RULE_${i}_EALEN") remote.psid-offset $(eval "echo \$RULE_${i}_OFFSET")"
+ echo insert $link $cfgstr > /proc/net/nat46/control
+ done
+ else
+ proto_notify_error "$cfg" "UNSUPPORTED_TYPE"
+ proto_block_restart "$cfg"
+ fi
+
+ proto_add_ipv4_route "0.0.0.0" 0
+ proto_add_data
+ [ "$zone" != "-" ] && json_add_string zone "$zone"
+
+ json_add_array firewall
+ if [ -z "$(eval "echo \$RULE_${k}_PORTSETS")" ]; then
+ json_add_object ""
+ json_add_string type nat
+ json_add_string target SNAT
+ json_add_string family inet
+ json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
+ json_close_object
+ else
+ for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
+ for proto in icmp tcp udp; do
+ json_add_object ""
+ json_add_string type nat
+ json_add_string target SNAT
+ json_add_string family inet
+ json_add_string proto "$proto"
+ json_add_boolean connlimit_ports 1
+ json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
+ json_add_string snat_port "$portset"
+ json_close_object
+ done
+ done
+ fi
+ if [ "$type" = "map-t" ]; then
+ json_add_object ""
+ json_add_string type rule
+ json_add_string family inet6
+ json_add_string proto all
+ json_add_string direction in
+ json_add_string dest "$zone"
+ json_add_string src "$zone"
+ json_add_string src_ip $(eval "echo \$RULE_${k}_IPV6ADDR")
+ json_add_string target ACCEPT
+ json_close_object
+ json_add_object ""
+ json_add_string type rule
+ json_add_string family inet6
+ json_add_string proto all
+ json_add_string direction out
+ json_add_string dest "$zone"
+ json_add_string src "$zone"
+ json_add_string dest_ip $(eval "echo \$RULE_${k}_IPV6ADDR")
+ json_add_string target ACCEPT
+ json_close_object
+ proto_add_ipv6_route $(eval "echo \$RULE_${k}_IPV6ADDR") 128
+ fi
+ json_close_array
+ proto_close_data
+
+ proto_send_update "$cfg"
+
+ if [ "$type" = "lw4o6" -o "$type" = "map-e" ]; then
+ json_init
+ json_add_string name "${cfg}_"
+ json_add_string ifname "@$(eval "echo \$RULE_${k}_PD6IFACE")"
+ json_add_string proto "static"
+ json_add_array ip6addr
+ json_add_string "" "$(eval "echo \$RULE_${k}_IPV6ADDR")"
+ json_close_array
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ fi
+}
+
+proto_map_teardown() {
+ local cfg="$1"
+ ifdown "${cfg}_"
+ rm -f /tmp/map-$cfg.rules
+}
+
+proto_map_init_config() {
+ no_device=1
+ available=1
+
+ proto_config_add_string "rule"
+ proto_config_add_string "ipaddr"
+ proto_config_add_int "ip4prefixlen"
+ proto_config_add_string "ip6prefix"
+ proto_config_add_int "ip6prefixlen"
+ proto_config_add_string "peeraddr"
+ proto_config_add_int "psidlen"
+ proto_config_add_int "psid"
+ proto_config_add_int "offset"
+
+ proto_config_add_string "tunlink"
+ proto_config_add_int "mtu"
+ proto_config_add_int "ttl"
+ proto_config_add_string "zone"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol map
+}
diff --git a/package/network/ipv6/map/src/CMakeLists.txt b/package/network/ipv6/map/src/CMakeLists.txt
new file mode 100644
index 0000000..2cbeb2c
--- /dev/null
+++ b/package/network/ipv6/map/src/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 2.8.1)
+
+project(mapcalc C)
+
+set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -std=c99")
+
+add_definitions(-D_GNU_SOURCE -Wall -Wno-gnu -Wextra)
+
+add_executable(mapcalc mapcalc.c)
+target_link_libraries(mapcalc ubus ubox)
+
+install(TARGETS mapcalc DESTINATION sbin/)
+
+
+# Packaging rules
+set(CPACK_PACKAGE_VERSION "1")
+set(CPACK_PACKAGE_CONTACT "Steven Barth <steven@midlink.org>")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "hnetd")
+set(CPACK_GENERATOR "DEB;RPM;STGZ")
+set(CPACK_STRIP_FILES true)
+
+SET(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
+set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}")
+
+include(CPack)
diff --git a/package/network/ipv6/map/src/mapcalc.c b/package/network/ipv6/map/src/mapcalc.c
new file mode 100644
index 0000000..648840d
--- /dev/null
+++ b/package/network/ipv6/map/src/mapcalc.c
@@ -0,0 +1,412 @@
+/*
+ * mapcalc - MAP parameter calculation
+ *
+ * Author: Steven Barth <cyrus@openwrt.org>
+ * Copyright (c) 2014-2015 cisco Systems, Inc.
+ * Copyright (c) 2015 Steven Barth <cyrus@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <libubus.h>
+#include <libubox/utils.h>
+
+
+struct blob_attr *dump = NULL;
+
+enum {
+ DUMP_ATTR_INTERFACE,
+ DUMP_ATTR_MAX
+};
+
+static const struct blobmsg_policy dump_attrs[DUMP_ATTR_MAX] = {
+ [DUMP_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_ARRAY },
+};
+
+
+enum {
+ IFACE_ATTR_INTERFACE,
+ IFACE_ATTR_PREFIX,
+ IFACE_ATTR_ADDRESS,
+ IFACE_ATTR_MAX,
+};
+
+static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = {
+ [IFACE_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING },
+ [IFACE_ATTR_PREFIX] = { .name = "ipv6-prefix", .type = BLOBMSG_TYPE_ARRAY },
+ [IFACE_ATTR_ADDRESS] = { .name = "ipv6-address", .type = BLOBMSG_TYPE_ARRAY },
+};
+
+
+enum {
+ PREFIX_ATTR_ADDRESS,
+ PREFIX_ATTR_MASK,
+ PREFIX_ATTR_MAX,
+};
+
+static const struct blobmsg_policy prefix_attrs[PREFIX_ATTR_MAX] = {
+ [PREFIX_ATTR_ADDRESS] = { .name = "address", .type = BLOBMSG_TYPE_STRING },
+ [PREFIX_ATTR_MASK] = { .name = "mask", .type = BLOBMSG_TYPE_INT32 },
+};
+
+static int bmemcmp(const void *av, const void *bv, size_t bits)
+{
+ const uint8_t *a = av, *b = bv;
+ size_t bytes = bits / 8;
+ bits %= 8;
+
+ int res = memcmp(a, b, bytes);
+ if (res == 0 && bits > 0)
+ res = (a[bytes] >> (8 - bits)) - (b[bytes] >> (8 - bits));
+
+ return res;
+}
+
+static void bmemcpy(void *av, const void *bv, size_t bits)
+{
+ uint8_t *a = av;
+ const uint8_t *b = bv;
+
+ size_t bytes = bits / 8;
+ bits %= 8;
+ memcpy(a, b, bytes);
+
+ if (bits > 0) {
+ uint8_t mask = (1 << (8 - bits)) - 1;
+ a[bytes] = (a[bytes] & mask) | ((~mask) & b[bytes]);
+ }
+}
+
+static void bmemcpys64(void *av, const void *bv, size_t frombits, size_t nbits)
+{
+ uint64_t buf = 0;
+ const uint8_t *b = bv;
+ size_t frombyte = frombits / 8, tobyte = (frombits + nbits) / 8;
+
+ memcpy(&buf, &b[frombyte], tobyte - frombyte + 1);
+ buf = cpu_to_be64(be64_to_cpu(buf) << (frombits % 8));
+
+ bmemcpy(av, &buf, nbits);
+}
+
+static void handle_dump(struct ubus_request *req __attribute__((unused)),
+ int type __attribute__((unused)), struct blob_attr *msg)
+{
+ struct blob_attr *tb[DUMP_ATTR_INTERFACE];
+ blobmsg_parse(dump_attrs, DUMP_ATTR_MAX, tb, blob_data(msg), blob_len(msg));
+
+ if (!tb[DUMP_ATTR_INTERFACE])
+ return;
+
+ dump = blob_memdup(tb[DUMP_ATTR_INTERFACE]);
+}
+
+static void match_prefix(int *pdlen, struct in6_addr *pd, struct blob_attr *cur,
+ const struct in6_addr *ipv6prefix, int prefix6len, bool lw4o6)
+{
+ struct blob_attr *d;
+ unsigned drem;
+
+ if (!cur || blobmsg_type(cur) != BLOBMSG_TYPE_ARRAY || !blobmsg_check_attr(cur, NULL))
+ return;
+
+ blobmsg_for_each_attr(d, cur, drem) {
+ struct blob_attr *ptb[PREFIX_ATTR_MAX];
+ blobmsg_parse(prefix_attrs, PREFIX_ATTR_MAX, ptb,
+ blobmsg_data(d), blobmsg_data_len(d));
+
+ if (!ptb[PREFIX_ATTR_ADDRESS] || !ptb[PREFIX_ATTR_MASK])
+ continue;
+
+ struct in6_addr prefix = IN6ADDR_ANY_INIT;
+ int mask = blobmsg_get_u32(ptb[PREFIX_ATTR_MASK]);
+ inet_pton(AF_INET6, blobmsg_get_string(ptb[PREFIX_ATTR_ADDRESS]), &prefix);
+
+ // lw4over6 /128-address-as-PD matching madness workaround
+ if (lw4o6 && mask == 128)
+ mask = 64;
+
+ if (*pdlen < mask && mask >= prefix6len &&
+ !bmemcmp(&prefix, ipv6prefix, prefix6len)) {
+ bmemcpy(pd, &prefix, mask);
+ *pdlen = mask;
+ } else if (lw4o6 && *pdlen < prefix6len && mask < prefix6len &&
+ !bmemcmp(&prefix, ipv6prefix, mask)) {
+ bmemcpy(pd, ipv6prefix, prefix6len);
+ *pdlen = prefix6len;
+ }
+ }
+}
+
+enum {
+ OPT_TYPE,
+ OPT_FMR,
+ OPT_EALEN,
+ OPT_PREFIX4LEN,
+ OPT_PREFIX6LEN,
+ OPT_IPV6PREFIX,
+ OPT_IPV4PREFIX,
+ OPT_OFFSET,
+ OPT_PSIDLEN,
+ OPT_PSID,
+ OPT_BR,
+ OPT_DMR,
+ OPT_PD,
+ OPT_PDLEN,
+ OPT_MAX
+};
+
+static char *const token[] = {
+ [OPT_TYPE] = "type",
+ [OPT_FMR] = "fmr",
+ [OPT_EALEN] = "ealen",
+ [OPT_PREFIX4LEN] = "prefix4len",
+ [OPT_PREFIX6LEN] = "prefix6len",
+ [OPT_IPV6PREFIX] = "ipv6prefix",
+ [OPT_IPV4PREFIX] = "ipv4prefix",
+ [OPT_OFFSET] = "offset",
+ [OPT_PSIDLEN] = "psidlen",
+ [OPT_PSID] = "psid",
+ [OPT_BR] = "br",
+ [OPT_DMR] = "dmr",
+ [OPT_PD] = "pd",
+ [OPT_PDLEN] = "pdlen",
+ [OPT_MAX] = NULL
+};
+
+
+int main(int argc, char *argv[])
+{
+ int status = 0;
+ const char *iface = argv[1];
+
+ const char *legacy_env = getenv("LEGACY");
+ bool legacy = legacy_env && atoi(legacy_env);
+
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s <interface|*> <rule1> [rule2] [...]\n", argv[0]);
+ return 1;
+ }
+
+ uint32_t network_interface;
+ struct ubus_context *ubus = ubus_connect(NULL);
+ if (ubus) {
+ ubus_lookup_id(ubus, "network.interface", &network_interface);
+ ubus_invoke(ubus, network_interface, "dump", NULL, handle_dump, NULL, 5000);
+ }
+
+ int rulecnt = 0;
+ for (int i = 2; i < argc; ++i) {
+ bool lw4o6 = false;
+ bool fmr = false;
+ int ealen = -1;
+ int addr4len = 32;
+ int prefix4len = 32;
+ int prefix6len = -1;
+ int pdlen = -1;
+ struct in_addr ipv4prefix = {INADDR_ANY};
+ struct in_addr ipv4addr = {INADDR_ANY};
+ struct in6_addr ipv6addr = IN6ADDR_ANY_INIT;
+ struct in6_addr ipv6prefix = IN6ADDR_ANY_INIT;
+ struct in6_addr pd = IN6ADDR_ANY_INIT;
+ int offset = -1;
+ int psidlen = -1;
+ int psid = -1;
+ uint16_t psid16 = 0;
+ const char *dmr = NULL;
+ const char *br = NULL;
+
+ for (char *rule = strdup(argv[i]); *rule; ) {
+ char *value;
+ int intval;
+ int idx = getsubopt(&rule, token, &value);
+ errno = 0;
+
+ if (idx == OPT_TYPE) {
+ lw4o6 = (value && !strcmp(value, "lw4o6"));
+ } else if (idx == OPT_FMR) {
+ fmr = true;
+ } else if (idx == OPT_EALEN && (intval = strtoul(value, NULL, 0)) <= 48 && !errno) {
+ ealen = intval;
+ } else if (idx == OPT_PREFIX4LEN && (intval = strtoul(value, NULL, 0)) <= 32 && !errno) {
+ prefix4len = intval;
+ } else if (idx == OPT_PREFIX6LEN && (intval = strtoul(value, NULL, 0)) <= 128 && !errno) {
+ prefix6len = intval;
+ } else if (idx == OPT_IPV4PREFIX && inet_pton(AF_INET, value, &ipv4prefix) == 1) {
+ // dummy
+ } else if (idx == OPT_IPV6PREFIX && inet_pton(AF_INET6, value, &ipv6prefix) == 1) {
+ // dummy
+ } else if (idx == OPT_PD && inet_pton(AF_INET6, value, &pd) == 1) {
+ // dummy
+ } else if (idx == OPT_OFFSET && (intval = strtoul(value, NULL, 0)) <= 16 && !errno) {
+ offset = intval;
+ } else if (idx == OPT_PSIDLEN && (intval = strtoul(value, NULL, 0)) <= 16 && !errno) {
+ psidlen = intval;
+ } else if (idx == OPT_PDLEN && (intval = strtoul(value, NULL, 0)) <= 128 && !errno) {
+ pdlen = intval;
+ } else if (idx == OPT_PSID && (intval = strtoul(value, NULL, 0)) <= 65535 && !errno) {
+ psid = intval;
+ } else if (idx == OPT_DMR) {
+ dmr = value;
+ } else if (idx == OPT_BR) {
+ br = value;
+ } else {
+ if (idx == -1 || idx >= OPT_MAX)
+ fprintf(stderr, "Skipped invalid option: %s\n", value);
+ else
+ fprintf(stderr, "Skipped invalid value %s for option %s\n",
+ value, token[idx]);
+ }
+ }
+
+ if (offset < 0)
+ offset = (lw4o6) ? 0 : (legacy) ? 4 : 6;
+
+ // LW4over6 doesn't have an EALEN and has no psid-autodetect
+ if (lw4o6) {
+ if (psidlen < 0)
+ psidlen = 0;
+
+ ealen = psidlen;
+ }
+
+ // Find PD
+ if (pdlen < 0) {
+ struct blob_attr *c;
+ unsigned rem;
+ blobmsg_for_each_attr(c, dump, rem) {
+ struct blob_attr *tb[IFACE_ATTR_MAX];
+ blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, blobmsg_data(c), blobmsg_data_len(c));
+
+ if (!tb[IFACE_ATTR_INTERFACE] || (strcmp(argv[1], "*") && strcmp(argv[1],
+ blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]))))
+ continue;
+
+ match_prefix(&pdlen, &pd, tb[IFACE_ATTR_PREFIX], &ipv6prefix, prefix6len, lw4o6);
+
+ if (lw4o6)
+ match_prefix(&pdlen, &pd, tb[IFACE_ATTR_ADDRESS], &ipv6prefix, prefix6len, lw4o6);
+
+ if (pdlen >= 0) {
+ iface = blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]);
+ break;
+ }
+ }
+ }
+
+ if (ealen < 0 && pdlen >= 0)
+ ealen = pdlen - prefix6len;
+
+ if (psidlen <= 0) {
+ psidlen = ealen - (32 - prefix4len);
+ psid = -1;
+ }
+
+ if (psid < 0 && psidlen <= 16 && psidlen >= 0 && pdlen >= 0 && ealen >= psidlen) {
+ bmemcpys64(&psid16, &pd, prefix6len + ealen - psidlen, psidlen);
+ psid = be16_to_cpu(psid16);
+ }
+
+ psid = psid >> (16 - psidlen);
+ psid16 = cpu_to_be16(psid);
+ psid = psid << (16 - psidlen);
+
+ if (prefix4len < 0 || prefix6len < 0 || ealen < 0 || ealen < psidlen) {
+ fprintf(stderr, "Skipping invalid or incomplete rule: %s\n", argv[i]);
+ status = 1;
+ continue;
+ }
+
+ if ((pdlen >= 0 || ealen == psidlen) && ealen >= psidlen) {
+ bmemcpys64(&ipv4addr, &pd, prefix6len, ealen - psidlen);
+ ipv4addr.s_addr = htonl(ntohl(ipv4addr.s_addr) >> prefix4len);
+ bmemcpy(&ipv4addr, &ipv4prefix, prefix4len);
+
+ if (prefix4len + ealen < 32)
+ addr4len = prefix4len + ealen;
+ }
+
+ if (pdlen < 0 && !fmr) {
+ fprintf(stderr, "Skipping non-FMR without matching PD: %s\n", argv[i]);
+ status = 1;
+ continue;
+ } else if (pdlen >= 0) {
+ size_t v4offset = (legacy) ? 9 : 10;
+ memcpy(&ipv6addr.s6_addr[v4offset], &ipv4addr, 4);
+ memcpy(&ipv6addr.s6_addr[v4offset + 4], &psid16, 2);
+ bmemcpy(&ipv6addr, &pd, pdlen);
+ }
+
+ ++rulecnt;
+ char ipv4addrbuf[INET_ADDRSTRLEN];
+ char ipv4prefixbuf[INET_ADDRSTRLEN];
+ char ipv6prefixbuf[INET6_ADDRSTRLEN];
+ char ipv6addrbuf[INET6_ADDRSTRLEN];
+ char pdbuf[INET6_ADDRSTRLEN];
+
+ inet_ntop(AF_INET, &ipv4addr, ipv4addrbuf, sizeof(ipv4addrbuf));
+ inet_ntop(AF_INET, &ipv4prefix, ipv4prefixbuf, sizeof(ipv4prefixbuf));
+ inet_ntop(AF_INET6, &ipv6prefix, ipv6prefixbuf, sizeof(ipv6prefixbuf));
+ inet_ntop(AF_INET6, &ipv6addr, ipv6addrbuf, sizeof(ipv6addrbuf));
+ inet_ntop(AF_INET6, &pd, pdbuf, sizeof(pdbuf));
+
+ printf("RULE_%d_FMR=%d\n", rulecnt, fmr);
+ printf("RULE_%d_EALEN=%d\n", rulecnt, ealen);
+ printf("RULE_%d_PSIDLEN=%d\n", rulecnt, psidlen);
+ printf("RULE_%d_OFFSET=%d\n", rulecnt, offset);
+ printf("RULE_%d_PREFIX4LEN=%d\n", rulecnt, prefix4len);
+ printf("RULE_%d_PREFIX6LEN=%d\n", rulecnt, prefix6len);
+ printf("RULE_%d_IPV4PREFIX=%s\n", rulecnt, ipv4prefixbuf);
+ printf("RULE_%d_IPV6PREFIX=%s\n", rulecnt, ipv6prefixbuf);
+
+ if (pdlen >= 0) {
+ printf("RULE_%d_IPV6PD=%s\n", rulecnt, pdbuf);
+ printf("RULE_%d_PD6LEN=%d\n", rulecnt, pdlen);
+ printf("RULE_%d_PD6IFACE=%s\n", rulecnt, iface);
+ printf("RULE_%d_IPV6ADDR=%s\n", rulecnt, ipv6addrbuf);
+ printf("RULE_BMR=%d\n", rulecnt);
+ }
+
+ if (ipv4addr.s_addr) {
+ printf("RULE_%d_IPV4ADDR=%s\n", rulecnt, ipv4addrbuf);
+ printf("RULE_%d_ADDR4LEN=%d\n", rulecnt, addr4len);
+ }
+
+
+ if (psidlen > 0 && psid >= 0) {
+ printf("RULE_%d_PORTSETS='", rulecnt);
+ for (int k = (offset) ? 1 : 0; k < (1 << offset); ++k) {
+ int start = (k << (16 - offset)) | (psid >> offset);
+ int end = start + (1 << (16 - offset - psidlen)) - 1;
+
+ if (start == 0)
+ start = 1;
+
+ if (start <= end)
+ printf("%d-%d ", start, end);
+ }
+ printf("'\n");
+ }
+
+ if (dmr)
+ printf("RULE_%d_DMR=%s\n", rulecnt, dmr);
+
+ if (br)
+ printf("RULE_%d_BR=%s\n", rulecnt, br);
+ }
+
+ printf("RULE_COUNT=%d\n", rulecnt);
+ return status;
+}
diff --git a/package/network/ipv6/odhcp6c/Makefile b/package/network/ipv6/odhcp6c/Makefile
new file mode 100644
index 0000000..0b38be9
--- /dev/null
+++ b/package/network/ipv6/odhcp6c/Makefile
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2012-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:=odhcp6c
+PKG_VERSION:=2015-09-04
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=https://github.com/sbyx/odhcp6c.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=dc186d6d2b0dd4ad23ca5fc69c00e81f796ff6d9
+PKG_MAINTAINER:=Steven Barth <steven@midlink.org>
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+ifneq ($(CONFIG_PACKAGE_odhcp6c_ext_cer_id),0)
+ CMAKE_OPTIONS += -DEXT_CER_ID=$(CONFIG_PACKAGE_odhcp6c_ext_cer_id)
+endif
+
+define Package/odhcp6c
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Embedded DHCPv6-client for OpenWrt
+ DEPENDS:=@IPV6
+endef
+
+define Package/odhcp6c/config
+ config PACKAGE_odhcp6c_ext_cer_id
+ int "CER-ID Extension ID (0 = disabled)"
+ depends on PACKAGE_odhcp6c
+ default 0
+endef
+
+define Package/odhcp6c/install
+ $(INSTALL_DIR) $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/odhcp6c $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/dhcpv6.sh $(1)/lib/netifd/proto/dhcpv6.sh
+ $(INSTALL_BIN) ./files/dhcpv6.script $(1)/lib/netifd/
+endef
+
+$(eval $(call BuildPackage,odhcp6c))
diff --git a/package/network/ipv6/odhcp6c/files/dhcpv6.script b/package/network/ipv6/odhcp6c/files/dhcpv6.script
new file mode 100755
index 0000000..c307d09
--- /dev/null
+++ b/package/network/ipv6/odhcp6c/files/dhcpv6.script
@@ -0,0 +1,219 @@
+#!/bin/sh
+[ -z "$2" ] && echo "Error: should be run by odhcpc6c" && exit 1
+. /lib/functions.sh
+. /lib/netifd/netifd-proto.sh
+
+setup_interface () {
+ local device="$1"
+ local prefsig=""
+ local addrsig=""
+ proto_init_update "*" 1
+
+ # Merge RA-DNS
+ for radns in $RA_DNS; do
+ local duplicate=0
+ for dns in $RDNSS; do
+ [ "$radns" = "$dns" ] && duplicate=1
+ done
+ [ "$duplicate" = 0 ] && RDNSS="$RDNSS $radns"
+ done
+
+ for dns in $RDNSS; do
+ proto_add_dns_server "$dns"
+ done
+
+ for radomain in $RA_DOMAINS; do
+ local duplicate=0
+ for domain in $DOMAINS; do
+ [ "$radomain" = "$domain" ] && duplicate=1
+ done
+ [ "$duplicate" = 0 ] && DOMAINS="$DOMAINS $radomain"
+ done
+
+ for domain in $DOMAINS; do
+ proto_add_dns_search "$domain"
+ done
+
+ for prefix in $PREFIXES; do
+ proto_add_ipv6_prefix "$prefix"
+ prefsig="$prefsig ${prefix%%,*}"
+ local entry="${prefix#*/}"
+ entry="${entry#*,}"
+ entry="${entry#*,}"
+ local valid="${entry%%,*}"
+
+ if [ -z "$RA_ADDRESSES" -a -z "$RA_ROUTES" -a \
+ -z "$RA_DNS" -a "$FAKE_ROUTES" = 1 ]; then
+ RA_ROUTES="::/0,$SERVER,$valid,4096"
+ fi
+ done
+
+ [ -n "$USERPREFIX" ] && proto_add_ipv6_prefix "$USERPREFIX"
+
+ # Merge addresses
+ for entry in $RA_ADDRESSES; do
+ local duplicate=0
+ local addr="${entry%%/*}"
+ for dentry in $ADDRESSES; do
+ local daddr="${dentry%%/*}"
+ [ "$addr" = "$daddr" ] && duplicate=1
+ done
+ [ "$duplicate" = "0" ] && ADDRESSES="$ADDRESSES $entry"
+ done
+
+ for entry in $ADDRESSES; do
+ local addr="${entry%%/*}"
+ entry="${entry#*/}"
+ local mask="${entry%%,*}"
+ entry="${entry#*,}"
+ local preferred="${entry%%,*}"
+ entry="${entry#*,}"
+ local valid="${entry%%,*}"
+
+ proto_add_ipv6_address "$addr" "$mask" "$preferred" "$valid" 1
+ addrsig="$addrsig $addr/$mask"
+
+ if [ -z "$RA_ADDRESSES" -a -z "$RA_ROUTES" -a \
+ -z "$RA_DNS" -a "$FAKE_ROUTES" = 1 ]; then
+ RA_ROUTES="::/0,$SERVER,$valid,4096"
+ fi
+
+ # RFC 7278
+ if [ "$mask" -eq 64 -a -z "$PREFIXES" -a -n "$EXTENDPREFIX" ]; then
+ proto_add_ipv6_prefix "$addr/$mask,$preferred,$valid"
+ fi
+ done
+
+ for entry in $RA_ROUTES; do
+ local duplicate=$NOSOURCEFILTER
+ local addr="${entry%%/*}"
+ entry="${entry#*/}"
+ local mask="${entry%%,*}"
+ entry="${entry#*,}"
+ local gw="${entry%%,*}"
+ entry="${entry#*,}"
+ local valid="${entry%%,*}"
+ entry="${entry#*,}"
+ local metric="${entry%%,*}"
+
+ for xentry in $RA_ROUTES; do
+ local xprefix="${xentry%%,*}"
+ xentry="${xentry#*,}"
+ local xgw="${xentry%%,*}"
+
+ [ -n "$gw" -a -z "$xgw" -a "$addr/$mask" = "$xprefix" ] && duplicate=1
+ done
+
+ if [ -z "$gw" -o "$duplicate" = 1 ]; then
+ proto_add_ipv6_route "$addr" "$mask" "$gw" "$metric" "$valid"
+ else
+ for prefix in $PREFIXES $ADDRESSES; do
+ local paddr="${prefix%%,*}"
+ proto_add_ipv6_route "$addr" "$mask" "$gw" "$metric" "$valid" "$paddr"
+ done
+ fi
+ done
+
+ proto_add_data
+ [ -n "$CER" ] && json_add_string cer "$CER"
+ [ -n "$PASSTHRU" ] && json_add_string passthru "$PASSTHRU"
+ [ -n "$ZONE" ] && json_add_string zone "$ZONE"
+ proto_close_data
+
+ proto_send_update "$INTERFACE"
+
+ MAPTYPE=""
+ MAPRULE=""
+
+ if [ -n "$MAPE" -a -f /lib/netifd/proto/map.sh ]; then
+ MAPTYPE="map-e"
+ MAPRULE="$MAPE"
+ elif [ -n "$MAPT" -a -f /lib/netifd/proto/map.sh -a -f /proc/net/nat46/control ]; then
+ MAPTYPE="map-t"
+ MAPRULE="$MAPT"
+ elif [ -n "$LW4O6" -a -f /lib/netifd/proto/map.sh ]; then
+ MAPTYPE="lw4o6"
+ MAPRULE="$LW4O6"
+ fi
+
+ [ -n "$ZONE" ] || ZONE=$(fw3 -q network $INTERFACE 2>/dev/null)
+
+ if [ "$IFACE_MAP" != 0 -a -n "$MAPTYPE" -a -n "$MAPRULE" ]; then
+ [ -z "$IFACE_MAP" -o "$IFACE_MAP" = 1 ] && IFACE_MAP=${INTERFACE}_4
+ json_init
+ json_add_string name "$IFACE_MAP"
+ json_add_string ifname "@$INTERFACE"
+ json_add_string proto map
+ json_add_string type "$MAPTYPE"
+ json_add_string _prefsig "$prefsig"
+ [ "$MAPTYPE" = lw4o6 ] && json_add_string _addrsig "$addrsig"
+ json_add_string rule "$MAPRULE"
+ json_add_string tunlink "$INTERFACE"
+ [ -n "$ZONE_MAP" ] || ZONE_MAP=$ZONE
+ [ -n "$ZONE_MAP" ] && json_add_string zone "$ZONE_MAP"
+ [ -n "$IFACE_MAP_DELEGATE" ] && json_add_boolean delegate "$IFACE_MAP_DELEGATE"
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ elif [ -n "$AFTR" -a "$IFACE_DSLITE" != 0 -a -f /lib/netifd/proto/dslite.sh ]; then
+ [ -z "$IFACE_DSLITE" -o "$IFACE_DSLITE" = 1 ] && IFACE_DSLITE=${INTERFACE}_4
+ json_init
+ json_add_string name "$IFACE_DSLITE"
+ json_add_string ifname "@$INTERFACE"
+ json_add_string proto "dslite"
+ json_add_string peeraddr "$AFTR"
+ json_add_string tunlink "$INTERFACE"
+ [ -n "$ZONE_DSLITE" ] || ZONE_DSLITE=$ZONE
+ [ -n "$ZONE_DSLITE" ] && json_add_string zone "$ZONE_DSLITE"
+ [ -n "$IFACE_DSLITE_DELEGATE" ] && json_add_boolean delegate "$IFACE_DSLITE_DELEGATE"
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ elif [ "$IFACE_464XLAT" != 0 -a -f /lib/netifd/proto/464xlat.sh ]; then
+ [ -z "$IFACE_464XLAT" -o "$IFACE_464XLAT" = 1 ] && IFACE_464XLAT=${INTERFACE}_4
+ json_init
+ json_add_string name "$IFACE_464XLAT"
+ json_add_string ifname "@$INTERFACE"
+ json_add_string proto "464xlat"
+ json_add_string tunlink "$INTERFACE"
+ json_add_string _addrsig "$addrsig"
+ [ -n "$ZONE_464XLAT" ] || ZONE_464XLAT=$ZONE
+ [ -n "$ZONE_464XLAT" ] && json_add_string zone "$ZONE_464XLAT"
+ [ -n "$IFACE_464XLAT_DELEGATE" ] && json_add_boolean delegate "$IFACE_464XLAT_DELEGATE"
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ fi
+
+ # Apply IPv6 / ND configuration
+ HOPLIMIT=$(cat /proc/sys/net/ipv6/conf/$device/hop_limit)
+ [ -n "$RA_HOPLIMIT" -a -n "$HOPLIMIT" ] && [ "$RA_HOPLIMIT" -gt "$HOPLIMIT" ] && echo "$RA_HOPLIMIT" > /proc/sys/net/ipv6/conf/$device/hop_limit
+ [ -n "$RA_MTU" ] && [ "$RA_MTU" -gt 0 ] && echo "$RA_MTU" > /proc/sys/net/ipv6/conf/$device/mtu
+ [ -n "$RA_REACHABLE" ] && [ "$RA_REACHABLE" -gt 0 ] && echo "$RA_REACHABLE" > /proc/sys/net/ipv6/neigh/$device/base_reachable_time_ms
+ [ -n "$RA_RETRANSMIT" ] && [ "$RA_RETRANSMIT" -gt 0 ] && echo "$RA_RETRANSMIT" > /proc/sys/net/ipv6/neigh/$device/retrans_time_ms
+
+ # TODO: $SNTP_IP $SIP_IP $SNTP_FQDN $SIP_DOMAIN
+}
+
+teardown_interface() {
+ proto_init_update "*" 0
+ proto_send_update "$INTERFACE"
+}
+
+case "$2" in
+ bound)
+ teardown_interface "$1"
+ setup_interface "$1"
+ ;;
+ informed|updated|rebound)
+ setup_interface "$1"
+ ;;
+ ra-updated)
+ [ -n "$ADDRESSES$RA_ADDRESSES$PREFIXES$USERPREFIX" ] && setup_interface "$1"
+ ;;
+ started|stopped|unbound)
+ teardown_interface "$1"
+ ;;
+esac
+
+# user rules
+[ -f /etc/odhcp6c.user ] && . /etc/odhcp6c.user
+
+exit 0
diff --git a/package/network/ipv6/odhcp6c/files/dhcpv6.sh b/package/network/ipv6/odhcp6c/files/dhcpv6.sh
new file mode 100755
index 0000000..6c47399
--- /dev/null
+++ b/package/network/ipv6/odhcp6c/files/dhcpv6.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. ../netifd-proto.sh
+init_proto "$@"
+
+proto_dhcpv6_init_config() {
+ renew_handler=1
+
+ proto_config_add_string 'reqaddress:or("try","force","none")'
+ proto_config_add_string 'reqprefix:or("auto","no",range(0, 64))'
+ proto_config_add_string clientid
+ proto_config_add_string 'reqopts:list(uinteger)'
+ proto_config_add_string 'noslaaconly:bool'
+ proto_config_add_string 'forceprefix:bool'
+ proto_config_add_string 'extendprefix:bool'
+ proto_config_add_string 'norelease:bool'
+ proto_config_add_string 'ip6prefix:ip6addr'
+ proto_config_add_string iface_dslite
+ proto_config_add_string zone_dslite
+ proto_config_add_string iface_map
+ proto_config_add_string zone_map
+ proto_config_add_string iface_464xlat
+ proto_config_add_string zone_464xlat
+ proto_config_add_string zone
+ proto_config_add_string 'ifaceid:ip6addr'
+ proto_config_add_string "userclass"
+ proto_config_add_string "vendorclass"
+ proto_config_add_boolean delegate
+ proto_config_add_int "soltimeout"
+ proto_config_add_boolean fakeroutes
+ proto_config_add_boolean sourcefilter
+}
+
+proto_dhcpv6_setup() {
+ local config="$1"
+ local iface="$2"
+
+ local reqaddress reqprefix clientid reqopts noslaaconly forceprefix extendprefix norelease ip6prefix iface_dslite iface_map iface_464xlat ifaceid userclass vendorclass delegate zone_dslite zone_map zone_464xlat zone soltimeout fakeroutes sourcefilter
+ json_get_vars reqaddress reqprefix clientid reqopts noslaaconly forceprefix extendprefix norelease ip6prefix iface_dslite iface_map iface_464xlat ifaceid userclass vendorclass delegate zone_dslite zone_map zone_464xlat zone soltimeout fakeroutes sourcefilter
+
+
+ # Configure
+ local opts=""
+ [ -n "$reqaddress" ] && append opts "-N$reqaddress"
+
+ [ -z "$reqprefix" -o "$reqprefix" = "auto" ] && reqprefix=0
+ [ "$reqprefix" != "no" ] && append opts "-P$reqprefix"
+
+ [ -n "$clientid" ] && append opts "-c$clientid"
+
+ [ "$noslaaconly" = "1" ] && append opts "-S"
+
+ [ "$forceprefix" = "1" ] && append opts "-F"
+
+ [ "$norelease" = "1" ] && append opts "-k"
+
+ [ -n "$ifaceid" ] && append opts "-i$ifaceid"
+
+ [ -n "$vendorclass" ] && append opts "-V$vendorclass"
+
+ [ -n "$userclass" ] && append opts "-u$userclass"
+
+ for opt in $reqopts; do
+ append opts "-r$opt"
+ done
+
+ append opts "-t${soltimeout:-120}"
+
+ [ -n "$ip6prefix" ] && proto_export "USERPREFIX=$ip6prefix"
+ [ -n "$iface_dslite" ] && proto_export "IFACE_DSLITE=$iface_dslite"
+ [ -n "$iface_map" ] && proto_export "IFACE_MAP=$iface_map"
+ [ -n "$iface_464xlat" ] && proto_export "IFACE_464XLAT=$iface_464xlat"
+ [ "$delegate" = "0" ] && proto_export "IFACE_DSLITE_DELEGATE=0"
+ [ "$delegate" = "0" ] && proto_export "IFACE_MAP_DELEGATE=0"
+ [ -n "$zone_dslite" ] && proto_export "ZONE_DSLITE=$zone_dslite"
+ [ -n "$zone_map" ] && proto_export "ZONE_MAP=$zone_map"
+ [ -n "$zone_464xlat" ] && proto_export "ZONE_464XLAT=$zone_464xlat"
+ [ -n "$zone" ] && proto_export "ZONE=$zone"
+ [ "$fakeroutes" != "0" ] && proto_export "FAKE_ROUTES=1"
+ [ "$sourcefilter" = "0" ] && proto_export "NOSOURCEFILTER=1"
+ [ "$extendprefix" = "1" ] && proto_export "EXTENDPREFIX=1"
+
+ proto_export "INTERFACE=$config"
+ proto_run_command "$config" odhcp6c \
+ -s /lib/netifd/dhcpv6.script \
+ $opts $iface
+}
+
+proto_dhcpv6_renew() {
+ local interface="$1"
+ # SIGUSR1 forces odhcp6c to renew its lease
+ local sigusr1="$(kill -l SIGUSR1)"
+ [ -n "$sigusr1" ] && proto_kill_command "$interface" $sigusr1
+}
+
+proto_dhcpv6_teardown() {
+ local interface="$1"
+ proto_kill_command "$interface"
+}
+
+add_protocol dhcpv6
+
diff --git a/package/network/ipv6/thc-ipv6/Makefile b/package/network/ipv6/thc-ipv6/Makefile
new file mode 100644
index 0000000..fdfc1f2
--- /dev/null
+++ b/package/network/ipv6/thc-ipv6/Makefile
@@ -0,0 +1,61 @@
+#
+# Copyright (C) 2009-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:=thc-ipv6
+PKG_VERSION:=2.7
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-3.0
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://freeworld.thc.org/releases/
+PKG_MD5SUM:=2975dd54be35b68c140eb2a6b8ef5e59
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+THC_APPLETS := \
+ address6 alive6 covert_send6 covert_send6d denial6 detect-new-ip6 \
+ detect_sniffer6 dnsdict6 dnsrevenum6 dos-new-ip6 \
+ dump_router6 exploit6 fake_advertise6 fake_dhcps6 fake_dns6d \
+ fake_dnsupdate6 fake_mipv6 fake_mld26 fake_mld6 fake_mldrouter6 \
+ fake_router26 fake_router6 fake_solicitate6 flood_advertise6 \
+ flood_dhcpc6 flood_mld26 flood_mld6 flood_mldrouter6 flood_router26 \
+ flood_router6 flood_solicitate6 fragmentation6 fuzz_ip6 fuzz_dhcpc6 \
+ fuzz_dhcps6 implementation6 implementation6d inverse_lookup6 \
+ kill_router6 ndpexhaust6 node_query6 parasite6 passive_discovery6 \
+ randicmp6 redir6 rsmurf6 sendpees6 sendpeesmp6 smurf6 thcping6 \
+ toobig6 trace6
+
+THC_DEPENDS_dnsdict6 := +libpthread
+THC_DEPENDS_thcping6 := +librt
+
+define BuildTool
+ define Package/thc-ipv6-$(subst _,-,$(1))
+ TITLE:=THC-IPv6 $(1) utility
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=+libpcap $(THC_DEPENDS_$(1))
+ URL:=http://freeworld.thc.org/
+ SUBMENU:=THC-IPv6 attack and analyzing toolkit
+ endef
+
+ define Package/thc-ipv6-$(subst _,-,$(1))/description
+ This package contains the $(1) utility of the THC-IPv6 toolkit.
+ endef
+
+ define Package/thc-ipv6-$(subst _,-,$(1))/install
+ $(INSTALL_DIR) $$(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(1) $$(1)/usr/sbin/$(1)
+ endef
+
+ $$(eval $$(call BuildPackage,thc-ipv6-$(subst _,-,$(1))))
+endef
+
+$(foreach a,$(THC_APPLETS),$(eval $(call BuildTool,$(a))))
diff --git a/package/network/ipv6/thc-ipv6/patches/100-no-ssl.patch b/package/network/ipv6/thc-ipv6/patches/100-no-ssl.patch
new file mode 100644
index 0000000..1ef1f66
--- /dev/null
+++ b/package/network/ipv6/thc-ipv6/patches/100-no-ssl.patch
@@ -0,0 +1,9 @@
+--- a/Makefile
++++ b/Makefile
+@@ -1,5 +1,5 @@
+ # Comment out if openssl-dev is not present
+-HAVE_SSL=yes
++#HAVE_SSL=yes
+
+ CC=gcc
+ #CFLAGS=-g
diff --git a/package/network/services/authsae/Makefile b/package/network/services/authsae/Makefile
new file mode 100644
index 0000000..2955021
--- /dev/null
+++ b/package/network/services/authsae/Makefile
@@ -0,0 +1,47 @@
+
+# Copyright (C) 2007-2013 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:=authsae
+PKG_VERSION:=2014-06-09
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://github.com/cozybit/authsae.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=8531ab158910a525d4bcbb3ad02c08342f6987f2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+
+PKG_BUILD_PARALLEL:=1
+CMAKE_INSTALL:=1
+
+CMAKE_OPTIONS += -DSYSCONF_INSTALL_DIR=/etc
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=BSD-4-Clause
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/authsae
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=80211s mesh security
+ DEPENDS:=+libopenssl +libconfig +libnl-tiny +@OPENSSL_WITH_EC
+endef
+
+TARGET_CFLAGS += -D_GNU_SOURCE
+
+define Package/authsae/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin
+ $(INSTALL_DIR) $(1)/lib/wifi
+ $(INSTALL_DATA) ./files/lib/wifi/authsae.sh $(1)/lib/wifi/
+endef
+
+$(eval $(call BuildPackage,authsae))
diff --git a/package/network/services/authsae/files/lib/wifi/authsae.sh b/package/network/services/authsae/files/lib/wifi/authsae.sh
new file mode 100644
index 0000000..d8c5598
--- /dev/null
+++ b/package/network/services/authsae/files/lib/wifi/authsae.sh
@@ -0,0 +1,57 @@
+authsae_start_interface() {
+ local mcast_rate
+ local mesh_htmode
+ local mesh_band
+ local authsae_conf_file="/var/run/authsae-$ifname.cfg"
+ local ret=1
+
+ json_get_vars mcast_rate
+ set_default mcast_rate "12"
+
+ case "$htmode" in
+ HT20|HT40+|HT40-) mesh_htmode="$htmode";;
+ *) mesh_htmode="none";;
+ esac
+
+ case "$hwmode" in
+ *g*) mesh_band=11g;;
+ *a*) mesh_band=11a;;
+ esac
+
+ cat > "$authsae_conf_file" <<EOF
+authsae:
+{
+ sae:
+ {
+ debug = 0;
+ password = "$key";
+ group = [19, 26, 21, 25, 20];
+ blacklist = 5;
+ thresh = 5;
+ lifetime = 3600;
+ };
+ meshd:
+ {
+ meshid = "$mesh_id";
+ interface = "$ifname";
+ passive = 0;
+ debug = 0;
+ mediaopt = 1;
+ band = "$mesh_band";
+ channel = $channel;
+ htmode = "$mesh_htmode";
+ mcast-rate = $mcast_rate;
+ };
+};
+EOF
+
+ /usr/bin/meshd-nl80211 -i "$ifname" -s "$mesh_id" -c "$authsae_conf_file" </dev/null >/dev/null 2>/dev/null &
+ authsae_pid="$!"
+ ret="$?"
+
+ echo $authsae_pid > /var/run/authsae-$ifname.pid
+ wireless_add_process "$authsae_pid" "/usr/bin/meshd-nl80211" 1
+
+ [ "$ret" != 0 ] && wireless_setup_vif_failed AUTHSAE_FAILED
+ return $ret
+}
diff --git a/package/network/services/authsae/patches/100-musl_fix.patch b/package/network/services/authsae/patches/100-musl_fix.patch
new file mode 100644
index 0000000..19d2d9b
--- /dev/null
+++ b/package/network/services/authsae/patches/100-musl_fix.patch
@@ -0,0 +1,20 @@
+--- a/linux/mon.c
++++ b/linux/mon.c
+@@ -44,7 +44,6 @@
+ #include <signal.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+-#include <sys/sysctl.h>
+ #include <sys/queue.h>
+ #include <netinet/in.h>
+ #include <net/if.h>
+--- a/linux/meshd.c
++++ b/linux/meshd.c
+@@ -44,7 +44,6 @@
+ #include <signal.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+-#include <sys/sysctl.h>
+ #include <sys/queue.h>
+ #include <netinet/in.h>
+ #include <net/if.h>
diff --git a/package/network/services/dnsmasq/Makefile b/package/network/services/dnsmasq/Makefile
new file mode 100644
index 0000000..cddde5c
--- /dev/null
+++ b/package/network/services/dnsmasq/Makefile
@@ -0,0 +1,152 @@
+#
+# 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:=dnsmasq
+PKG_VERSION:=2.75
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
+PKG_MD5SUM:=887236f1ddde6eb57cdb9d01916c9f72
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_CONFIG_DEPENDS:=CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6 \
+ CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec \
+ CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth \
+ CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/dnsmasq/Default
+ SECTION:=net
+ CATEGORY:=Base system
+ TITLE:=DNS and DHCP server
+ URL:=http://www.thekelleys.org.uk/dnsmasq/
+endef
+
+define Package/dnsmasq
+$(call Package/dnsmasq/Default)
+ VARIANT:=nodhcpv6
+endef
+
+define Package/dnsmasq-dhcpv6
+$(call Package/dnsmasq/Default)
+ TITLE += (with DHCPv6 support)
+ DEPENDS:=@IPV6
+ VARIANT:=dhcpv6
+endef
+
+define Package/dnsmasq-full
+$(call Package/dnsmasq/Default)
+ TITLE += (with DNSSEC, DHCPv6, Auth DNS, IPset enabled by default)
+ DEPENDS:=+PACKAGE_dnsmasq_full_dnssec:libnettle \
+ +PACKAGE_dnsmasq_full_ipset:kmod-ipt-ipset
+ VARIANT:=full
+endef
+
+define Package/dnsmasq/description
+ It is intended to provide coupled DNS and DHCP service to a LAN.
+endef
+
+define Package/dnsmasq-dhcpv6/description
+$(call Package/dnsmasq/description)
+
+This is a variant with DHCPv6 support
+endef
+
+define Package/dnsmasq-full/description
+$(call Package/dnsmasq/description)
+
+This is a fully configurable variant with DHCPv6, DNSSEC, Authroitative DNS and
+IPset support enabled by default.
+endef
+
+define Package/dnsmasq/conffiles
+/etc/config/dhcp
+/etc/dnsmasq.conf
+endef
+
+define Package/dnsmasq-full/config
+ if PACKAGE_dnsmasq-full
+ config PACKAGE_dnsmasq_full_dhcpv6
+ bool "Build with DHCPv6 support."
+ depends on IPV6
+ default y
+ config PACKAGE_dnsmasq_full_dnssec
+ bool "Build with DNSSEC support."
+ default y
+ config PACKAGE_dnsmasq_full_auth
+ bool "Build with the facility to act as an authoritative DNS server."
+ default y
+ config PACKAGE_dnsmasq_full_ipset
+ bool "Build with IPset support."
+ default y
+ endif
+endef
+
+Package/dnsmasq-dhcpv6/conffiles = $(Package/dnsmasq/conffiles)
+Package/dnsmasq-full/conffiles = $(Package/dnsmasq/conffiles)
+
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+COPTS = $(if $(CONFIG_IPV6),,-DNO_IPV6)
+
+ifeq ($(BUILD_VARIANT),nodhcpv6)
+ COPTS += -DNO_DHCP6
+endif
+
+ifeq ($(BUILD_VARIANT),full)
+ COPTS += $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6),,-DNO_DHCP6) \
+ $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec),-DHAVE_DNSSEC) \
+ $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth),,-DNO_AUTH) \
+ $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset),,-DNO_IPSET)
+ COPTS += $(if $(CONFIG_LIBNETTLE_MINI),-DNO_GMP,)
+else
+ COPTS += -DNO_AUTH -DNO_IPSET
+endif
+
+MAKE_FLAGS := \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ LDFLAGS="$(TARGET_LDFLAGS)" \
+ COPTS="$(COPTS)" \
+ PREFIX="/usr"
+
+define Package/dnsmasq/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/dnsmasq $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_DATA) ./files/dhcp.conf $(1)/etc/config/dhcp
+ $(INSTALL_DATA) ./files/dnsmasq.conf $(1)/etc/dnsmasq.conf
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/dnsmasq.init $(1)/etc/init.d/dnsmasq
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+ $(INSTALL_DATA) ./files/dnsmasq.hotplug $(1)/etc/hotplug.d/iface/25-dnsmasq
+endef
+
+Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install)
+
+define Package/dnsmasq-full/install
+$(call Package/dnsmasq/install,$(1))
+ifneq ($(CONFIG_PACKAGE_dnsmasq_full_dnssec),)
+ $(INSTALL_DIR) $(1)/usr/share/dnsmasq
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/trust-anchors.conf $(1)/usr/share/dnsmasq
+endif
+endef
+
+$(eval $(call BuildPackage,dnsmasq))
+$(eval $(call BuildPackage,dnsmasq-dhcpv6))
+$(eval $(call BuildPackage,dnsmasq-full))
diff --git a/package/network/services/dnsmasq/files/dhcp.conf b/package/network/services/dnsmasq/files/dhcp.conf
new file mode 100644
index 0000000..362b90a
--- /dev/null
+++ b/package/network/services/dnsmasq/files/dhcp.conf
@@ -0,0 +1,32 @@
+config dnsmasq
+ option domainneeded 1
+ option boguspriv 1
+ option filterwin2k 0 # enable for dial on demand
+ option localise_queries 1
+ option rebind_protection 1 # disable if upstream must serve RFC1918 addresses
+ option rebind_localhost 1 # enable for RBL checking and similar services
+ #list rebind_domain example.lan # whitelist RFC1918 responses for domains
+ option local '/lan/'
+ option domain 'lan'
+ option expandhosts 1
+ option nonegcache 0
+ option authoritative 1
+ option readethers 1
+ option leasefile '/tmp/dhcp.leases'
+ option resolvfile '/tmp/resolv.conf.auto'
+ #list server '/mycompany.local/1.2.3.4'
+ #option nonwildcard 1
+ #list interface br-lan
+ #list notinterface lo
+ #list bogusnxdomain '64.94.110.11'
+ option localservice 1 # disable to allow DNS requests from non-local subnets
+
+config dhcp lan
+ option interface lan
+ option start 100
+ option limit 150
+ option leasetime 12h
+
+config dhcp wan
+ option interface wan
+ option ignore 1
diff --git a/package/network/services/dnsmasq/files/dnsmasq.conf b/package/network/services/dnsmasq/files/dnsmasq.conf
new file mode 100644
index 0000000..bf5816b
--- /dev/null
+++ b/package/network/services/dnsmasq/files/dnsmasq.conf
@@ -0,0 +1,37 @@
+# Change the following lines if you want dnsmasq to serve SRV
+# records.
+# You may add multiple srv-host lines.
+# The fields are <name>,<target>,<port>,<priority>,<weight>
+
+# A SRV record sending LDAP for the example.com domain to
+# ldapserver.example.com port 289
+#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389
+
+# Two SRV records for LDAP, each with different priorities
+#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1
+#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2
+
+# A SRV record indicating that there is no LDAP server for the domain
+# example.com
+#srv-host=_ldap._tcp.example.com
+
+# The following line shows how to make dnsmasq serve an arbitrary PTR
+# record. This is useful for DNS-SD.
+# The fields are <name>,<target>
+#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services"
+
+# Change the following lines to enable dnsmasq to serve TXT records.
+# These are used for things like SPF and zeroconf.
+# The fields are <name>,<text>,<text>...
+
+#Example SPF.
+#txt-record=example.com,"v=spf1 a -all"
+
+#Example zeroconf
+#txt-record=_http._tcp.example.com,name=value,paper=A4
+
+# Provide an alias for a "local" DNS name. Note that this _only_ works
+# for targets which are names from DHCP or /etc/hosts. Give host
+# "bert" another name, bertrand
+# The fields are <cname>,<target>
+#cname=bertand,bert
diff --git a/package/network/services/dnsmasq/files/dnsmasq.hotplug b/package/network/services/dnsmasq/files/dnsmasq.hotplug
new file mode 100644
index 0000000..ca5d10c
--- /dev/null
+++ b/package/network/services/dnsmasq/files/dnsmasq.hotplug
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$ACTION" = ifup ] || exit 0
+
+/etc/init.d/dnsmasq enabled && /etc/init.d/dnsmasq start
diff --git a/package/network/services/dnsmasq/files/dnsmasq.init b/package/network/services/dnsmasq/files/dnsmasq.init
new file mode 100644
index 0000000..1b42cff
--- /dev/null
+++ b/package/network/services/dnsmasq/files/dnsmasq.init
@@ -0,0 +1,641 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2007-2012 OpenWrt.org
+
+START=60
+
+USE_PROCD=1
+PROG=/usr/sbin/dnsmasq
+
+DNS_SERVERS=""
+DOMAIN=""
+
+ADD_LOCAL_DOMAIN=1
+ADD_LOCAL_HOSTNAME=1
+
+CONFIGFILE="/var/etc/dnsmasq.conf"
+HOSTFILE="/tmp/hosts/dhcp"
+TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf"
+TIMESTAMPFILE="/etc/dnsmasq.time"
+
+xappend() {
+ local value="$1"
+
+ echo "${value#--}" >> $CONFIGFILE
+}
+
+dhcp_calc() {
+ local ip="$1"
+ local res=0
+
+ while [ -n "$ip" ]; do
+ part="${ip%%.*}"
+ res="$(($res * 256))"
+ res="$(($res + $part))"
+ [ "${ip%.*}" != "$ip" ] && ip="${ip#*.}" || ip=
+ done
+ echo "$res"
+}
+
+dhcp_check() {
+ local ifname="$1"
+ local stamp="/var/run/dnsmasq.$ifname.dhcp"
+ local rv=0
+
+ [ -s "$stamp" ] && return $(cat "$stamp")
+
+ udhcpc -n -q -s /bin/true -t 1 -i "$ifname" >&- && rv=1 || rv=0
+
+ [ $rv -eq 1 ] && \
+ logger -t dnsmasq \
+ "found already running DHCP-server on interface '$ifname'" \
+ "refusing to start, use 'option force 1' to override"
+
+ echo $rv > "$stamp"
+ return $rv
+}
+
+log_once() {
+ pidof dnsmasq >/dev/null || \
+ logger -t dnsmasq "$@"
+}
+
+append_bool() {
+ local section="$1"
+ local option="$2"
+ local value="$3"
+ local _loctmp
+ config_get_bool _loctmp "$section" "$option" 0
+ [ $_loctmp -gt 0 ] && xappend "$value"
+}
+
+append_parm() {
+ local section="$1"
+ local option="$2"
+ local switch="$3"
+ local _loctmp
+ config_get _loctmp "$section" "$option"
+ [ -z "$_loctmp" ] && return 0
+ xappend "$switch=$_loctmp"
+}
+
+append_server() {
+ xappend "--server=$1"
+}
+
+append_address() {
+ xappend "--address=$1"
+}
+
+append_ipset() {
+ xappend "--ipset=$1"
+}
+
+append_interface() {
+ local ifname=$(uci_get_state network "$1" ifname "$1")
+ xappend "--interface=$ifname"
+}
+
+append_notinterface() {
+ local ifname=$(uci_get_state network "$1" ifname "$1")
+ xappend "--except-interface=$ifname"
+}
+
+append_addnhosts() {
+ xappend "--addn-hosts=$1"
+}
+
+append_bogusnxdomain() {
+ xappend "--bogus-nxdomain=$1"
+}
+
+append_pxe_service() {
+ xappend "--pxe-service=$1"
+}
+
+dnsmasq() {
+ local cfg="$1"
+ append_bool "$cfg" authoritative "--dhcp-authoritative"
+ append_bool "$cfg" nodaemon "--no-daemon"
+ append_bool "$cfg" domainneeded "--domain-needed"
+ append_bool "$cfg" filterwin2k "--filterwin2k"
+ append_bool "$cfg" nohosts "--no-hosts"
+ append_bool "$cfg" nonegcache "--no-negcache"
+ append_bool "$cfg" strictorder "--strict-order"
+ append_bool "$cfg" logqueries "--log-queries=extra"
+ append_bool "$cfg" noresolv "--no-resolv"
+ append_bool "$cfg" localise_queries "--localise-queries"
+ append_bool "$cfg" readethers "--read-ethers"
+ append_bool "$cfg" dbus "--enable-dbus"
+ append_bool "$cfg" boguspriv "--bogus-priv"
+ append_bool "$cfg" expandhosts "--expand-hosts"
+ append_bool "$cfg" enable_tftp "--enable-tftp"
+ append_bool "$cfg" tftp_no_fail "--tftp-no-fail"
+ append_bool "$cfg" nonwildcard "--bind-interfaces"
+ append_bool "$cfg" fqdn "--dhcp-fqdn"
+ append_bool "$cfg" proxydnssec "--proxy-dnssec"
+ append_bool "$cfg" localservice "--local-service"
+ append_bool "$cfg" quietdhcp "--quiet-dhcp"
+ append_bool "$cfg" sequential_ip "--dhcp-sequential-ip"
+
+ append_parm "$cfg" dhcpscript "--dhcp-script"
+ append_parm "$cfg" cachesize "--cache-size"
+ append_parm "$cfg" dnsforwardmax "--dns-forward-max"
+ append_parm "$cfg" port "--port"
+ append_parm "$cfg" ednspacket_max "--edns-packet-max"
+ append_parm "$cfg" dhcpleasemax "--dhcp-lease-max"
+ append_parm "$cfg" "queryport" "--query-port"
+ append_parm "$cfg" "domain" "--domain"
+ append_parm "$cfg" "local" "--server"
+ config_list_foreach "$cfg" "server" append_server
+ config_list_foreach "$cfg" "address" append_address
+ config_list_foreach "$cfg" "ipset" append_ipset
+ config_list_foreach "$cfg" "interface" append_interface
+ config_list_foreach "$cfg" "notinterface" append_notinterface
+ config_list_foreach "$cfg" "addnhosts" append_addnhosts
+ config_list_foreach "$cfg" "bogusnxdomain" append_bogusnxdomain
+ append_parm "$cfg" "leasefile" "--dhcp-leasefile"
+ append_parm "$cfg" "resolvfile" "--resolv-file"
+ append_parm "$cfg" "serversfile" "--servers-file"
+ append_parm "$cfg" "tftp_root" "--tftp-root"
+ append_parm "$cfg" "dhcp_boot" "--dhcp-boot"
+ append_parm "$cfg" "local_ttl" "--local-ttl"
+ append_parm "$cfg" "pxe_prompt" "--pxe-prompt"
+ config_list_foreach "$cfg" "pxe_service" append_pxe_service
+ config_get DOMAIN "$cfg" domain
+
+ config_get_bool ADD_LOCAL_DOMAIN "$cfg" add_local_domain 1
+ config_get_bool ADD_LOCAL_HOSTNAME "$cfg" add_local_hostname 1
+
+ config_get_bool readethers "$cfg" readethers
+ [ "$readethers" = "1" -a \! -e "/etc/ethers" ] && touch /etc/ethers
+
+ config_get leasefile $cfg leasefile
+ [ -n "$leasefile" -a \! -e "$leasefile" ] && touch "$leasefile"
+ config_get_bool cachelocal "$cfg" cachelocal 1
+
+ config_get hostsfile "$cfg" dhcphostsfile
+ [ -e "$hostsfile" ] && xappend "--dhcp-hostsfile=$hostsfile"
+
+ local rebind
+ config_get_bool rebind "$cfg" rebind_protection 1
+ [ $rebind -gt 0 ] && {
+ log_once \
+ "DNS rebinding protection is active," \
+ "will discard upstream RFC1918 responses!"
+ xappend "--stop-dns-rebind"
+
+ local rebind_localhost
+ config_get_bool rebind_localhost "$cfg" rebind_localhost 0
+ [ $rebind_localhost -gt 0 ] && {
+ log_once "Allowing 127.0.0.0/8 responses"
+ xappend "--rebind-localhost-ok"
+ }
+
+ append_rebind_domain() {
+ log_once "Allowing RFC1918 responses for domain $1"
+ xappend "--rebind-domain-ok=$1"
+ }
+
+ config_list_foreach "$cfg" rebind_domain append_rebind_domain
+ }
+
+ config_get_bool dnssec "$cfg" dnssec 0
+ [ "$dnssec" -gt 0 ] && {
+ xappend "--conf-file=$TRUSTANCHORSFILE"
+ xappend "--dnssec"
+ xappend "--dnssec-timestamp=$TIMESTAMPFILE"
+ append_bool "$cfg" dnsseccheckunsigned "--dnssec-check-unsigned"
+ }
+
+ dhcp_option_add "$cfg" "" 0
+
+ xappend "--dhcp-broadcast=tag:needs-broadcast"
+
+ mkdir -p /tmp/hosts /tmp/dnsmasq.d
+ xappend "--addn-hosts=/tmp/hosts"
+ xappend "--conf-dir=/tmp/dnsmasq.d"
+
+ echo >> $CONFIGFILE
+}
+
+dhcp_subscrid_add() {
+ local cfg="$1"
+
+ config_get networkid "$cfg" networkid
+ [ -n "$networkid" ] || return 0
+
+ config_get subscriberid "$cfg" subscriberid
+ [ -n "$subscriberid" ] || return 0
+
+ xappend "--dhcp-subscrid=$networkid,$subscriberid"
+
+ config_get_bool force "$cfg" force 0
+
+ dhcp_option_add "$cfg" "$networkid" "$force"
+}
+
+dhcp_remoteid_add() {
+ local cfg="$1"
+
+ config_get networkid "$cfg" networkid
+ [ -n "$networkid" ] || return 0
+
+ config_get remoteid "$cfg" remoteid
+ [ -n "$remoteid" ] || return 0
+
+ xappend "--dhcp-remoteid=$networkid,$remoteid"
+
+ config_get_bool force "$cfg" force 0
+
+ dhcp_option_add "$cfg" "$networkid" "$force"
+}
+
+dhcp_circuitid_add() {
+ local cfg="$1"
+
+ config_get networkid "$cfg" networkid
+ [ -n "$networkid" ] || return 0
+
+ config_get circuitid "$cfg" circuitid
+ [ -n "$circuitid" ] || return 0
+
+ xappend "--dhcp-circuitid=$networkid,$circuitid"
+
+ config_get_bool force "$cfg" force 0
+
+ dhcp_option_add "$cfg" "$networkid" "$force"
+}
+
+dhcp_userclass_add() {
+ local cfg="$1"
+
+ config_get networkid "$cfg" networkid
+ [ -n "$networkid" ] || return 0
+
+ config_get userclass "$cfg" userclass
+ [ -n "$userclass" ] || return 0
+
+ xappend "--dhcp-userclass=$networkid,$userclass"
+
+ config_get_bool force "$cfg" force 0
+
+ dhcp_option_add "$cfg" "$networkid" "$force"
+}
+
+dhcp_vendorclass_add() {
+ local cfg="$1"
+
+ config_get networkid "$cfg" networkid
+ [ -n "$networkid" ] || return 0
+
+ config_get vendorclass "$cfg" vendorclass
+ [ -n "$vendorclass" ] || return 0
+
+ xappend "--dhcp-vendorclass=$networkid,$vendorclass"
+
+ config_get_bool force "$cfg" force 0
+
+ dhcp_option_add "$cfg" "$networkid" "$force"
+}
+
+dhcp_host_add() {
+ local cfg="$1"
+
+ config_get_bool force "$cfg" force 0
+
+ config_get networkid "$cfg" networkid
+ [ -n "$networkid" ] && dhcp_option_add "$cfg" "$networkid" "$force"
+
+ config_get name "$cfg" name
+ config_get ip "$cfg" ip
+ [ -n "$ip" -o -n "$name" ] || return 0
+
+ config_get_bool dns "$cfg" dns 0
+ [ "$dns" = "1" -a -n "$ip" -a -n "$name" ] && {
+ echo "$ip $name${DOMAIN:+.$DOMAIN}" >> $HOSTFILE
+ }
+
+ config_get mac "$cfg" mac
+ if [ -n "$mac" ]; then
+ # --dhcp-host=00:20:e0:3b:13:af,192.168.0.199,lap
+ macs=""
+ for m in $mac; do append macs "$m" ","; done
+ else
+ # --dhcp-host=lap,192.168.0.199
+ [ -n "$name" ] || return 0
+ macs="$name"
+ name=""
+ fi
+
+ config_get tag "$cfg" tag
+
+ config_get_bool broadcast "$cfg" broadcast 0
+ [ "$broadcast" = "0" ] && broadcast=
+
+ xappend "--dhcp-host=$macs${networkid:+,net:$networkid}${broadcast:+,set:needs-broadcast}${tag:+,set:$tag}${ip:+,$ip}${name:+,$name}"
+}
+
+dhcp_tag_add() {
+ local cfg="$1"
+
+ tag="$cfg"
+
+ [ -n "$tag" ] || return 0
+
+ config_get_bool force "$cfg" force 0
+ [ "$force" = "0" ] && force=
+
+ config_get option "$cfg" dhcp_option
+ for o in $option; do
+ xappend "--dhcp-option${force:+-force}=tag:$tag,$o"
+ done
+}
+
+dhcp_mac_add() {
+ local cfg="$1"
+
+ config_get networkid "$cfg" networkid
+ [ -n "$networkid" ] || return 0
+
+ config_get mac "$cfg" mac
+ [ -n "$mac" ] || return 0
+
+ xappend "--dhcp-mac=$networkid,$mac"
+
+ dhcp_option_add "$cfg" "$networkid"
+}
+
+dhcp_boot_add() {
+ local cfg="$1"
+
+ config_get networkid "$cfg" networkid
+
+ config_get filename "$cfg" filename
+ [ -n "$filename" ] || return 0
+
+ config_get servername "$cfg" servername
+ config_get serveraddress "$cfg" serveraddress
+
+ [ -n "$serveraddress" -a ! -n "$servername" ] && return 0
+
+ xappend "--dhcp-boot=${networkid:+net:$networkid,}${filename}${servername:+,$servername}${serveraddress:+,$serveraddress}"
+
+ config_get_bool force "$cfg" force 0
+
+ dhcp_option_add "$cfg" "$networkid" "$force"
+}
+
+
+dhcp_add() {
+ local cfg="$1"
+ config_get net "$cfg" interface
+ [ -n "$net" ] || return 0
+
+ config_get dhcpv4 "$cfg" dhcpv4
+ [ "$dhcpv4" != "disabled" ] || return 0
+
+ config_get networkid "$cfg" networkid
+ [ -n "$networkid" ] || networkid="$net"
+
+ network_get_subnet subnet "$net" || return 0
+ network_get_device ifname "$net" || return 0
+ network_get_protocol proto "$net" || return 0
+
+ [ "$cachelocal" = "0" ] && network_get_dnsserver dnsserver "$net" && {
+ DNS_SERVERS="$DNS_SERVERS $dnsserver"
+ }
+
+ append_bool "$cfg" ignore "--no-dhcp-interface=$ifname" && return 0
+
+ # Do not support non-static interfaces for now
+ [ static = "$proto" ] || return 0
+
+ # Override interface netmask with dhcp config if applicable
+ config_get netmask "$cfg" netmask "${subnet##*/}"
+
+ #check for an already active dhcp server on the interface, unless 'force' is set
+ config_get_bool force "$cfg" force 0
+ [ $force -gt 0 ] || dhcp_check "$ifname" || return 0
+
+ config_get start "$cfg" start
+ config_get limit "$cfg" limit
+ config_get leasetime "$cfg" leasetime
+ config_get options "$cfg" options
+ config_get_bool dynamicdhcp "$cfg" dynamicdhcp 1
+
+ leasetime="${leasetime:-12h}"
+ start="$(dhcp_calc "${start:-100}")"
+ limit="${limit:-150}"
+ [ "$limit" -gt 0 ] && limit=$((limit-1))
+ eval "$(ipcalc.sh "${subnet%%/*}" $netmask $start $limit)"
+ if [ "$dynamicdhcp" = "0" ]; then END="static"; fi
+ xappend "--dhcp-range=$networkid,$START,$END,$NETMASK,$leasetime${options:+ $options}"
+
+ dhcp_option_add "$cfg" "$networkid"
+}
+
+dhcp_option_add() {
+ local cfg="$1"
+ local networkid="$2"
+ local force="$3"
+
+ [ "$force" = "0" ] && force=
+
+ config_get dhcp_option "$cfg" dhcp_option
+ for o in $dhcp_option; do
+ xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$o"
+ done
+
+}
+
+dhcp_domain_add() {
+ local cfg="$1"
+ local ip name names record
+
+ config_get names "$cfg" name "$2"
+ [ -n "$names" ] || return 0
+
+ config_get ip "$cfg" ip "$3"
+ [ -n "$ip" ] || return 0
+
+ for name in $names; do
+ record="${record:+$record }$name"
+ done
+
+ echo "$ip $record" >> $HOSTFILE
+}
+
+dhcp_srv_add() {
+ local cfg="$1"
+
+ config_get srv "$cfg" srv
+ [ -n "$srv" ] || return 0
+
+ config_get target "$cfg" target
+ [ -n "$target" ] || return 0
+
+ config_get port "$cfg" port
+ [ -n "$port" ] || return 0
+
+ config_get class "$cfg" class
+ config_get weight "$cfg" weight
+
+ local service="$srv,$target,$port${class:+,$class${weight:+,$weight}}"
+
+ xappend "--srv-host=$service"
+}
+
+dhcp_mx_add() {
+ local cfg="$1"
+ local domain relay pref
+
+ config_get domain "$cfg" domain
+ [ -n "$domain" ] || return 0
+
+ config_get relay "$cfg" relay
+ [ -n "$relay" ] || return 0
+
+ config_get pref "$cfg" pref 0
+
+ local service="$domain,$relay,$pref"
+
+ xappend "--mx-host=$service"
+}
+
+dhcp_cname_add() {
+ local cfg="$1"
+ local cname target
+
+ config_get cname "$cfg" cname
+ [ -n "$cname" ] || return 0
+
+ config_get target "$cfg" target
+ [ -n "$target" ] || return 0
+
+ xappend "--cname=${cname},${target}"
+}
+
+dhcp_hostrecord_add() {
+ local cfg="$1"
+ local names addresses record val
+
+ config_get names "$cfg" name "$2"
+ if [ -z "$names" ]; then
+ return 0
+ fi
+
+ config_get addresses "$cfg" ip "$3"
+ if [ -z "$addresses" ]; then
+ return 0
+ fi
+
+ for val in $names $addresses; do
+ record="${record:+$record,}$val"
+ done
+
+ xappend "--host-record=$record"
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger "dhcp"
+}
+
+boot() {
+ # Will be launched through hotplug
+ return 0
+}
+
+start_service() {
+ include /lib/functions
+
+ config_load dhcp
+
+ procd_open_instance
+ procd_set_param command $PROG -C $CONFIGFILE -k -x /var/run/dnsmasq/dnsmasq.pid
+ procd_set_param file $CONFIGFILE
+ procd_set_param respawn
+
+ procd_add_jail dnsmasq ubus log
+ procd_add_jail_mount $CONFIGFILE $TRUSTANCHORSFILE $HOSTFILE /etc/passwd /etc/group /etc/TZ /dev/null /dev/urandom /etc/dnsmasq.conf /tmp/dnsmasq.d /tmp/resolv.conf.auto /etc/hosts /etc/ethers
+ procd_add_jail_mount_rw /var/run/dnsmasq/ /tmp/dhcp.leases $TIMESTAMPFILE
+
+ procd_close_instance
+
+ # before we can call xappend
+ mkdir -p /var/run/dnsmasq/
+ mkdir -p $(dirname $CONFIGFILE)
+ mkdir -p /var/lib/misc
+ touch /tmp/dhcp.leases
+
+ if [ ! -f "$TIMESTAMPFILE" ]; then
+ touch "$TIMESTAMPFILE"
+ chown nobody.nogroup "$TIMESTAMPFILE"
+ fi
+
+ echo "# auto-generated config file from /etc/config/dhcp" > $CONFIGFILE
+ echo "# auto-generated config file from /etc/config/dhcp" > $HOSTFILE
+
+ # if we did this last, we could override auto-generated config
+ [ -f /etc/dnsmasq.conf ] && {
+ xappend "--conf-file=/etc/dnsmasq.conf"
+ }
+
+ args=""
+ config_foreach dnsmasq dnsmasq
+ config_foreach dhcp_host_add host
+ echo >> $CONFIGFILE
+ config_foreach dhcp_boot_add boot
+ config_foreach dhcp_mac_add mac
+ config_foreach dhcp_tag_add tag
+ config_foreach dhcp_vendorclass_add vendorclass
+ config_foreach dhcp_userclass_add userclass
+ config_foreach dhcp_circuitid_add circuitid
+ config_foreach dhcp_remoteid_add remoteid
+ config_foreach dhcp_subscrid_add subscrid
+ config_foreach dhcp_domain_add domain
+ config_foreach dhcp_hostrecord_add hostrecord
+
+ # add own hostname
+ local lanaddr
+ [ $ADD_LOCAL_HOSTNAME -eq 1 ] && network_get_ipaddr lanaddr "lan" && {
+ local hostname="$(uci_get system @system[0] hostname OpenWrt)"
+ dhcp_domain_add "" "$hostname" "$lanaddr"
+ }
+
+ echo >> $CONFIGFILE
+ config_foreach dhcp_srv_add srvhost
+ config_foreach dhcp_mx_add mxhost
+ echo >> $CONFIGFILE
+
+ config_get odhcpd_is_active odhcpd maindhcp
+ if [ "$odhcpd_is_active" != "1" ]; then
+ config_foreach dhcp_add dhcp
+ fi
+
+ echo >> $CONFIGFILE
+ config_foreach dhcp_cname_add cname
+ echo >> $CONFIGFILE
+
+ rm -f /tmp/resolv.conf
+ [ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -n "$DOMAIN" ] && {
+ echo "search $DOMAIN" >> /tmp/resolv.conf
+ }
+ DNS_SERVERS="$DNS_SERVERS 127.0.0.1"
+ for DNS_SERVER in $DNS_SERVERS ; do
+ echo "nameserver $DNS_SERVER" >> /tmp/resolv.conf
+ done
+}
+
+reload_service() {
+ rc_procd start_service "$@"
+ return 0
+}
+
+stop_service() {
+ [ -f /tmp/resolv.conf ] && {
+ rm -f /tmp/resolv.conf
+ ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
+ }
+ rm -f /var/run/dnsmasq.*.dhcp
+}
diff --git a/package/network/services/dnsmasq/patches/100-fix-dhcp-no-address-warning.patch b/package/network/services/dnsmasq/patches/100-fix-dhcp-no-address-warning.patch
new file mode 100644
index 0000000..f5b5ca0
--- /dev/null
+++ b/package/network/services/dnsmasq/patches/100-fix-dhcp-no-address-warning.patch
@@ -0,0 +1,47 @@
+--- a/src/dhcp.c
++++ b/src/dhcp.c
+@@ -146,7 +146,7 @@ void dhcp_packet(time_t now, int pxe_fd)
+ struct iovec iov;
+ ssize_t sz;
+ int iface_index = 0, unicast_dest = 0, is_inform = 0;
+- struct in_addr iface_addr;
++ struct in_addr iface_addr, *addrp = NULL;
+ struct iface_param parm;
+ #ifdef HAVE_LINUX_NETWORK
+ struct arpreq arp_req;
+@@ -275,11 +275,9 @@ void dhcp_packet(time_t now, int pxe_fd)
+ {
+ ifr.ifr_addr.sa_family = AF_INET;
+ if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 )
+- iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
+- else
+ {
+- my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
+- return;
++ addrp = &iface_addr;
++ iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
+ }
+
+ for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
+@@ -298,7 +296,7 @@ void dhcp_packet(time_t now, int pxe_fd)
+ parm.relay_local.s_addr = 0;
+ parm.ind = iface_index;
+
+- if (!iface_check(AF_INET, (struct all_addr *)&iface_addr, ifr.ifr_name, NULL))
++ if (!iface_check(AF_INET, (struct all_addr *)addrp, ifr.ifr_name, NULL))
+ {
+ /* If we failed to match the primary address of the interface, see if we've got a --listen-address
+ for a secondary */
+@@ -318,6 +316,12 @@ void dhcp_packet(time_t now, int pxe_fd)
+ complete_context(match.addr, iface_index, NULL, match.netmask, match.broadcast, &parm);
+ }
+
++ if (!addrp)
++ {
++ my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
++ return;
++ }
++
+ if (!iface_enumerate(AF_INET, &parm, complete_context))
+ return;
+
diff --git a/package/network/services/dnsmasq/patches/110-ipset-remove-old-kernel-support.patch b/package/network/services/dnsmasq/patches/110-ipset-remove-old-kernel-support.patch
new file mode 100644
index 0000000..61b09d5
--- /dev/null
+++ b/package/network/services/dnsmasq/patches/110-ipset-remove-old-kernel-support.patch
@@ -0,0 +1,110 @@
+--- a/src/ipset.c
++++ b/src/ipset.c
+@@ -22,7 +22,6 @@
+ #include <errno.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+-#include <sys/utsname.h>
+ #include <arpa/inet.h>
+ #include <linux/version.h>
+ #include <linux/netlink.h>
+@@ -72,7 +71,7 @@ struct my_nfgenmsg {
+
+ #define NL_ALIGN(len) (((len)+3) & ~(3))
+ static const struct sockaddr_nl snl = { .nl_family = AF_NETLINK };
+-static int ipset_sock, old_kernel;
++static int ipset_sock;
+ static char *buffer;
+
+ static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
+@@ -87,25 +86,7 @@ static inline void add_attr(struct nlmsg
+
+ void ipset_init(void)
+ {
+- struct utsname utsname;
+- int version;
+- char *split;
+-
+- if (uname(&utsname) < 0)
+- die(_("failed to find kernel version: %s"), NULL, EC_MISC);
+-
+- split = strtok(utsname.release, ".");
+- version = (split ? atoi(split) : 0);
+- split = strtok(NULL, ".");
+- version = version * 256 + (split ? atoi(split) : 0);
+- split = strtok(NULL, ".");
+- version = version * 256 + (split ? atoi(split) : 0);
+- old_kernel = (version < KERNEL_VERSION(2,6,32));
+-
+- if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1)
+- return;
+-
+- if (!old_kernel &&
++ if (
+ (buffer = safe_malloc(BUFF_SZ)) &&
+ (ipset_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER)) != -1 &&
+ (bind(ipset_sock, (struct sockaddr *)&snl, sizeof(snl)) != -1))
+@@ -168,62 +149,16 @@ static int new_add_to_ipset(const char *
+ }
+
+
+-static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove)
+-{
+- socklen_t size;
+- struct ip_set_req_adt_get {
+- unsigned op;
+- unsigned version;
+- union {
+- char name[IPSET_MAXNAMELEN];
+- uint16_t index;
+- } set;
+- char typename[IPSET_MAXNAMELEN];
+- } req_adt_get;
+- struct ip_set_req_adt {
+- unsigned op;
+- uint16_t index;
+- uint32_t ip;
+- } req_adt;
+-
+- if (strlen(setname) >= sizeof(req_adt_get.set.name))
+- {
+- errno = ENAMETOOLONG;
+- return -1;
+- }
+-
+- req_adt_get.op = 0x10;
+- req_adt_get.version = 3;
+- strcpy(req_adt_get.set.name, setname);
+- size = sizeof(req_adt_get);
+- if (getsockopt(ipset_sock, SOL_IP, 83, &req_adt_get, &size) < 0)
+- return -1;
+- req_adt.op = remove ? 0x102 : 0x101;
+- req_adt.index = req_adt_get.set.index;
+- req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr);
+- if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0)
+- return -1;
+-
+- return 0;
+-}
+-
+-
+-
+ int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove)
+ {
+ int af = AF_INET;
+
+ #ifdef HAVE_IPV6
+ if (flags & F_IPV6)
+- {
+ af = AF_INET6;
+- /* old method only supports IPv4 */
+- if (old_kernel)
+- return -1;
+- }
+ #endif
+
+- return old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
++ return new_add_to_ipset(setname, ipaddr, af, remove);
+ }
+
+ #endif
diff --git a/package/network/services/dnsmasq/patches/210-dnssec-improve-timestamp-heuristic.patch b/package/network/services/dnsmasq/patches/210-dnssec-improve-timestamp-heuristic.patch
new file mode 100644
index 0000000..81fbf18
--- /dev/null
+++ b/package/network/services/dnsmasq/patches/210-dnssec-improve-timestamp-heuristic.patch
@@ -0,0 +1,47 @@
+From 79e60e145f8a595bca5a784c00b437216d51de68 Mon Sep 17 00:00:00 2001
+From: Steven Barth <steven@midlink.org>
+Date: Mon, 13 Apr 2015 09:45:20 +0200
+Subject: [PATCH] dnssec: improve timestamp heuristic
+
+Signed-off-by: Steven Barth <steven@midlink.org>
+---
+ src/dnssec.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/src/dnssec.c
++++ b/src/dnssec.c
+@@ -429,17 +429,24 @@ static time_t timestamp_time;
+ int setup_timestamp(void)
+ {
+ struct stat statbuf;
++ time_t now;
++ time_t base = 1420070400; /* 1-1-2015 */
+
+ daemon->back_to_the_future = 0;
+
+ if (!daemon->timestamp_file)
+ return 0;
++
++ now = time(NULL);
++
++ if (!stat("/proc/self/exe", &statbuf) && difftime(statbuf.st_mtime, base) > 0)
++ base = statbuf.st_mtime;
+
+ if (stat(daemon->timestamp_file, &statbuf) != -1)
+ {
+ timestamp_time = statbuf.st_mtime;
+ check_and_exit:
+- if (difftime(timestamp_time, time(0)) <= 0)
++ if (difftime(now, base) >= 0 && difftime(timestamp_time, now) <= 0)
+ {
+ /* time already OK, update timestamp, and do key checking from the start. */
+ if (utime(daemon->timestamp_file, NULL) == -1)
+@@ -460,7 +467,7 @@ int setup_timestamp(void)
+
+ close(fd);
+
+- timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
++ timestamp_time = timbuf.actime = timbuf.modtime = base;
+ if (utime(daemon->timestamp_file, &timbuf) == 0)
+ goto check_and_exit;
+ }
diff --git a/package/network/services/dropbear/Config.in b/package/network/services/dropbear/Config.in
new file mode 100644
index 0000000..e2a7610
--- /dev/null
+++ b/package/network/services/dropbear/Config.in
@@ -0,0 +1,27 @@
+menu "Configuration"
+ depends on PACKAGE_dropbear
+
+config DROPBEAR_ECC
+ bool "Elliptic curve cryptography (ECC)"
+ default n
+ help
+ Enables elliptic curve cryptography (ECC) support in key exchange and public key
+ authentication.
+
+ Key exchange algorithms:
+ ecdh-sha2-nistp256
+ ecdh-sha2-nistp384
+ ecdh-sha2-nistp521
+ curve25519-sha256@libssh.org
+
+ Public key algorithms:
+ ecdsa-sha2-nistp256
+ ecdsa-sha2-nistp384
+ ecdsa-sha2-nistp521
+
+ Does not generate ECC host keys by default (ECC key exchange will not be used,
+ only ECC public key auth).
+
+ Increases binary size by about 36 kB (MIPS).
+
+endmenu
diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile
new file mode 100644
index 0000000..4515165
--- /dev/null
+++ b/package/network/services/dropbear/Makefile
@@ -0,0 +1,128 @@
+#
+# 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:=dropbear
+PKG_VERSION:=2015.68
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:= \
+ http://matt.ucc.asn.au/dropbear/releases/ \
+ https://dropbear.nl/mirror/releases/
+PKG_MD5SUM:=7664ac10f7cc2301c530eb80c756fc5d
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE libtomcrypt/LICENSE libtommath/LICENSE
+
+PKG_BUILD_PARALLEL:=1
+PKG_USE_MIPS16:=0
+
+PKG_CONFIG_DEPENDS:=CONFIG_DROPBEAR_ECC
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/dropbear/Default
+ URL:=http://matt.ucc.asn.au/dropbear/
+endef
+
+define Package/dropbear/config
+ source "$(SOURCE)/Config.in"
+endef
+
+define Package/dropbear
+ $(call Package/dropbear/Default)
+ SECTION:=net
+ CATEGORY:=Base system
+ TITLE:=Small SSH2 client/server
+endef
+
+define Package/dropbear/description
+ A small SSH2 server/client designed for small memory environments.
+endef
+
+define Package/dropbear/conffiles
+/etc/dropbear/dropbear_rsa_host_key
+/etc/config/dropbear
+endef
+
+define Package/dropbearconvert
+ $(call Package/dropbear/Default)
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Utility for converting SSH keys
+endef
+
+CONFIGURE_ARGS += \
+ --disable-pam \
+ --enable-openpty \
+ --enable-syslog \
+ $(if $(CONFIG_SHADOW_PASSWORDS),,--disable-shadow) \
+ --disable-lastlog \
+ --disable-utmp \
+ --disable-utmpx \
+ --disable-wtmp \
+ --disable-wtmpx \
+ --disable-loginfunc \
+ --disable-pututline \
+ --disable-pututxline \
+ --disable-zlib \
+ --enable-bundled-libtom
+
+TARGET_CFLAGS += -DARGTYPE=3 -ffunction-sections -fdata-sections
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+define Build/Configure
+ $(Build/Configure/Default)
+
+ # Enforce that all replacements are made, otherwise options.h has changed
+ # format and this logic is broken.
+ for OPTION in DROPBEAR_ECDSA DROPBEAR_ECDH DROPBEAR_CURVE25519; do \
+ awk 'BEGIN { rc = 1 } \
+ /'$$$$OPTION'/ { $$$$0 = "$(if $(CONFIG_DROPBEAR_ECC),,// )#define '$$$$OPTION'"; rc = 0 } \
+ { print } \
+ END { exit(rc) }' $(PKG_BUILD_DIR)/options.h \
+ >$(PKG_BUILD_DIR)/options.h.new && \
+ mv $(PKG_BUILD_DIR)/options.h.new $(PKG_BUILD_DIR)/options.h || exit 1; \
+ done
+endef
+
+define Build/Compile
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+ $(TARGET_CONFIGURE_OPTS) \
+ PROGRAMS="dropbear dbclient dropbearkey scp" \
+ MULTI=1 SCPPROGRESS=1
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+ $(TARGET_CONFIGURE_OPTS) \
+ PROGRAMS="dropbearconvert"
+endef
+
+define Package/dropbear/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/dropbearmulti $(1)/usr/sbin/dropbear
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(LN) ../sbin/dropbear $(1)/usr/bin/scp
+ $(LN) ../sbin/dropbear $(1)/usr/bin/ssh
+ $(LN) ../sbin/dropbear $(1)/usr/bin/dbclient
+ $(LN) ../sbin/dropbear $(1)/usr/bin/dropbearkey
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_DATA) ./files/dropbear.config $(1)/etc/config/dropbear
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/dropbear.init $(1)/etc/init.d/dropbear
+ $(INSTALL_DIR) $(1)/usr/lib/opkg/info
+ $(INSTALL_DIR) $(1)/etc/dropbear
+ touch $(1)/etc/dropbear/dropbear_rsa_host_key
+endef
+
+define Package/dropbearconvert/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/dropbearconvert $(1)/usr/bin/dropbearconvert
+endef
+
+$(eval $(call BuildPackage,dropbear))
+$(eval $(call BuildPackage,dropbearconvert))
diff --git a/package/network/services/dropbear/files/dropbear.config b/package/network/services/dropbear/files/dropbear.config
new file mode 100644
index 0000000..2139ba0
--- /dev/null
+++ b/package/network/services/dropbear/files/dropbear.config
@@ -0,0 +1,5 @@
+config dropbear
+ option PasswordAuth 'on'
+ option RootPasswordAuth 'on'
+ option Port '22'
+# option BannerFile '/etc/banner'
diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init
new file mode 100755
index 0000000..03745c9
--- /dev/null
+++ b/package/network/services/dropbear/files/dropbear.init
@@ -0,0 +1,178 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006-2010 OpenWrt.org
+# Copyright (C) 2006 Carlos Sobrinho
+
+START=50
+STOP=50
+
+USE_PROCD=1
+PROG=/usr/sbin/dropbear
+NAME=dropbear
+PIDCOUNT=0
+EXTRA_COMMANDS="killclients"
+EXTRA_HELP=" killclients Kill ${NAME} processes except servers and yourself"
+
+append_ports()
+{
+ local ipaddrs="$1"
+ local port="$2"
+
+ [ -z "$ipaddrs" ] && {
+ procd_append_param command -p "$port"
+ return
+ }
+
+ for addr in $ipaddrs; do
+ procd_append_param command -p "$addr:$port"
+ done
+}
+
+validate_section_dropbear()
+{
+ uci_validate_section dropbear dropbear "${1}" \
+ 'PasswordAuth:bool:1' \
+ 'enable:bool:1' \
+ 'Interface:string' \
+ 'GatewayPorts:bool:0' \
+ 'RootPasswordAuth:bool:1' \
+ 'RootLogin:bool:1' \
+ 'rsakeyfile:file' \
+ 'BannerFile:file' \
+ 'Port:list(port):22' \
+ 'SSHKeepAlive:uinteger:300' \
+ 'IdleTimeout:uinteger:0' \
+ 'mdns:uinteger:1'
+}
+
+dropbear_instance()
+{
+ local PasswordAuth enable Interface GatewayPorts \
+ RootPasswordAuth RootLogin rsakeyfile \
+ BannerFile Port SSHKeepAlive IdleTimeout \
+ mdns ipaddrs
+
+ validate_section_dropbear "${1}" || {
+ echo "validation failed"
+ return 1
+ }
+
+ [ -n "${Interface}" ] && {
+ network_get_ipaddrs_all ipaddrs "${Interface}" || {
+ echo "interface ${Interface} has no physdev or physdev has no suitable ip"
+ return 1
+ }
+ }
+
+ [ "${enable}" = "0" ] && return 1
+ PIDCOUNT="$(( ${PIDCOUNT} + 1))"
+ local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid"
+
+ procd_open_instance
+ procd_set_param command "$PROG" -F -P "$pid_file"
+ [ "${PasswordAuth}" -eq 0 ] && procd_append_param command -s
+ [ "${GatewayPorts}" -eq 1 ] && procd_append_param command -a
+ [ "${RootPasswordAuth}" -eq 0 ] && procd_append_param command -g
+ [ "${RootLogin}" -eq 0 ] && procd_append_param command -w
+ [ -n "${rsakeyfile}" ] && procd_append_param command -r "${rsakeyfile}"
+ [ -n "${BannerFile}" ] && procd_append_param command -b "${BannerFile}"
+ append_ports "${ipaddrs}" "${Port}"
+ [ "${IdleTimeout}" -ne 0 ] && procd_append_param command -I "${IdleTimeout}"
+ [ "${SSHKeepAlive}" -ne 0 ] && procd_append_param command -K "${SSHKeepAlive}"
+ [ "${mdns}" -ne 0 ] && procd_add_mdns "ssh" "tcp" "$Port" "daemon=dropbear"
+ procd_set_param respawn
+ procd_close_instance
+}
+
+keygen()
+{
+ for keytype in rsa; do
+ # check for keys
+ key=dropbear/dropbear_${keytype}_host_key
+ [ -f /tmp/$key -o -s /etc/$key ] || {
+ # generate missing keys
+ mkdir -p /tmp/dropbear
+ [ -x /usr/bin/dropbearkey ] && {
+ /usr/bin/dropbearkey -t $keytype -f /tmp/$key 2>&- >&- && exec /etc/rc.common "$initscript" start
+ } &
+ exit 0
+ }
+ done
+
+ lock /tmp/.switch2jffs
+ mkdir -p /etc/dropbear
+ mv /tmp/dropbear/dropbear_* /etc/dropbear/
+ lock -u /tmp/.switch2jffs
+ chown root /etc/dropbear
+ chmod 0700 /etc/dropbear
+}
+
+start_service()
+{
+ [ -s /etc/dropbear/dropbear_rsa_host_key ] || keygen
+
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+
+ config_load "${NAME}"
+ config_foreach dropbear_instance dropbear
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger "dropbear"
+ procd_add_validation validate_section_dropbear
+}
+
+killclients()
+{
+ local ignore=''
+ local server
+ local pid
+
+ # if this script is run from inside a client session, then ignore that session
+ pid="$$"
+ while [ "${pid}" -ne 0 ]
+ do
+ # get parent process id
+ pid=`cut -d ' ' -f 4 "/proc/${pid}/stat"`
+ [ "${pid}" -eq 0 ] && break
+
+ # check if client connection
+ grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" && {
+ append ignore "${pid}"
+ break
+ }
+ done
+
+ # get all server pids that should be ignored
+ for server in `cat /var/run/${NAME}.*.pid`
+ do
+ append ignore "${server}"
+ done
+
+ # get all running pids and kill client connections
+ local skip
+ for pid in `pidof "${NAME}"`
+ do
+ # check if correct program, otherwise process next pid
+ grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" || {
+ continue
+ }
+
+ # check if pid should be ignored (servers, ourself)
+ skip=0
+ for server in ${ignore}
+ do
+ if [ "${pid}" = "${server}" ]
+ then
+ skip=1
+ break
+ fi
+ done
+ [ "${skip}" -ne 0 ] && continue
+
+ # kill process
+ echo "${initscript}: Killing ${pid}..."
+ kill -KILL ${pid}
+ done
+}
diff --git a/package/network/services/dropbear/patches/100-pubkey_path.patch b/package/network/services/dropbear/patches/100-pubkey_path.patch
new file mode 100644
index 0000000..41fdc1a
--- /dev/null
+++ b/package/network/services/dropbear/patches/100-pubkey_path.patch
@@ -0,0 +1,91 @@
+--- a/svr-authpubkey.c
++++ b/svr-authpubkey.c
+@@ -218,17 +218,21 @@ static int checkpubkey(char* algo, unsig
+ goto out;
+ }
+
+- /* we don't need to check pw and pw_dir for validity, since
+- * its been done in checkpubkeyperms. */
+- len = strlen(ses.authstate.pw_dir);
+- /* allocate max required pathname storage,
+- * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */
+- filename = m_malloc(len + 22);
+- snprintf(filename, len + 22, "%s/.ssh/authorized_keys",
+- ses.authstate.pw_dir);
+-
+- /* open the file */
+- authfile = fopen(filename, "r");
++ if (ses.authstate.pw_uid != 0) {
++ /* we don't need to check pw and pw_dir for validity, since
++ * its been done in checkpubkeyperms. */
++ len = strlen(ses.authstate.pw_dir);
++ /* allocate max required pathname storage,
++ * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */
++ filename = m_malloc(len + 22);
++ snprintf(filename, len + 22, "%s/.ssh/authorized_keys",
++ ses.authstate.pw_dir);
++
++ /* open the file */
++ authfile = fopen(filename, "r");
++ } else {
++ authfile = fopen("/etc/dropbear/authorized_keys","r");
++ }
+ if (authfile == NULL) {
+ goto out;
+ }
+@@ -381,26 +385,35 @@ static int checkpubkeyperms() {
+ goto out;
+ }
+
+- /* allocate max required pathname storage,
+- * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */
+- filename = m_malloc(len + 22);
+- strncpy(filename, ses.authstate.pw_dir, len+1);
+-
+- /* check ~ */
+- if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
+- goto out;
+- }
+-
+- /* check ~/.ssh */
+- strncat(filename, "/.ssh", 5); /* strlen("/.ssh") == 5 */
+- if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
+- goto out;
+- }
+-
+- /* now check ~/.ssh/authorized_keys */
+- strncat(filename, "/authorized_keys", 16);
+- if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
+- goto out;
++ if (ses.authstate.pw_uid == 0) {
++ if (checkfileperm("/etc/dropbear") != DROPBEAR_SUCCESS) {
++ goto out;
++ }
++ if (checkfileperm("/etc/dropbear/authorized_keys") != DROPBEAR_SUCCESS) {
++ goto out;
++ }
++ } else {
++ /* allocate max required pathname storage,
++ * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */
++ filename = m_malloc(len + 22);
++ strncpy(filename, ses.authstate.pw_dir, len+1);
++
++ /* check ~ */
++ if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
++ goto out;
++ }
++
++ /* check ~/.ssh */
++ strncat(filename, "/.ssh", 5); /* strlen("/.ssh") == 5 */
++ if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
++ goto out;
++ }
++
++ /* now check ~/.ssh/authorized_keys */
++ strncat(filename, "/authorized_keys", 16);
++ if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
++ goto out;
++ }
+ }
+
+ /* file looks ok, return success */
diff --git a/package/network/services/dropbear/patches/110-change_user.patch b/package/network/services/dropbear/patches/110-change_user.patch
new file mode 100644
index 0000000..4b5c1cb
--- /dev/null
+++ b/package/network/services/dropbear/patches/110-change_user.patch
@@ -0,0 +1,18 @@
+--- a/svr-chansession.c
++++ b/svr-chansession.c
+@@ -922,12 +922,12 @@ static void execchild(void *user_data) {
+ /* We can only change uid/gid as root ... */
+ if (getuid() == 0) {
+
+- if ((setgid(ses.authstate.pw_gid) < 0) ||
++ if ((ses.authstate.pw_gid != 0) && ((setgid(ses.authstate.pw_gid) < 0) ||
+ (initgroups(ses.authstate.pw_name,
+- ses.authstate.pw_gid) < 0)) {
++ ses.authstate.pw_gid) < 0))) {
+ dropbear_exit("Error changing user group");
+ }
+- if (setuid(ses.authstate.pw_uid) < 0) {
++ if ((ses.authstate.pw_uid != 0) && (setuid(ses.authstate.pw_uid) < 0)) {
+ dropbear_exit("Error changing user");
+ }
+ } else {
diff --git a/package/network/services/dropbear/patches/120-openwrt_options.patch b/package/network/services/dropbear/patches/120-openwrt_options.patch
new file mode 100644
index 0000000..87118ef
--- /dev/null
+++ b/package/network/services/dropbear/patches/120-openwrt_options.patch
@@ -0,0 +1,81 @@
+--- a/options.h
++++ b/options.h
+@@ -41,7 +41,7 @@
+ * Both of these flags can be defined at once, don't compile without at least
+ * one of them. */
+ #define NON_INETD_MODE
+-#define INETD_MODE
++/*#define INETD_MODE*/
+
+ /* Setting this disables the fast exptmod bignum code. It saves ~5kB, but is
+ * perhaps 20% slower for pubkey operations (it is probably worth experimenting
+@@ -81,7 +81,7 @@ much traffic. */
+
+ /* Enable "Netcat mode" option. This will forward standard input/output
+ * to a remote TCP-forwarded connection */
+-#define ENABLE_CLI_NETCAT
++/*#define ENABLE_CLI_NETCAT*/
+
+ /* Whether to support "-c" and "-m" flags to choose ciphers/MACs at runtime */
+ #define ENABLE_USER_ALGO_LIST
+@@ -91,16 +91,16 @@ much traffic. */
+ * Including multiple keysize variants the same cipher
+ * (eg AES256 as well as AES128) will result in a minimal size increase.*/
+ #define DROPBEAR_AES128
+-#define DROPBEAR_3DES
++/*#define DROPBEAR_3DES*/
+ #define DROPBEAR_AES256
+ /* Compiling in Blowfish will add ~6kB to runtime heap memory usage */
+ /*#define DROPBEAR_BLOWFISH*/
+-#define DROPBEAR_TWOFISH256
+-#define DROPBEAR_TWOFISH128
++/*#define DROPBEAR_TWOFISH256*/
++/*#define DROPBEAR_TWOFISH128*/
+
+ /* Enable CBC mode for ciphers. This has security issues though
+ * is the most compatible with older SSH implementations */
+-#define DROPBEAR_ENABLE_CBC_MODE
++/*#define DROPBEAR_ENABLE_CBC_MODE*/
+
+ /* Enable "Counter Mode" for ciphers. This is more secure than normal
+ * CBC mode against certain attacks. It is recommended for security
+@@ -131,9 +131,9 @@ If you test it please contact the Dropbe
+ * If you disable MD5, Dropbear will fall back to SHA1 fingerprints,
+ * which are not the standard form. */
+ #define DROPBEAR_SHA1_HMAC
+-#define DROPBEAR_SHA1_96_HMAC
+-#define DROPBEAR_SHA2_256_HMAC
+-#define DROPBEAR_SHA2_512_HMAC
++/*#define DROPBEAR_SHA1_96_HMAC*/
++/*#define DROPBEAR_SHA2_256_HMAC*/
++/*#define DROPBEAR_SHA2_512_HMAC*/
+ #define DROPBEAR_MD5_HMAC
+
+ /* You can also disable integrity. Don't bother disabling this if you're
+@@ -146,7 +146,7 @@ If you test it please contact the Dropbe
+ * Removing either of these won't save very much space.
+ * SSH2 RFC Draft requires dss, recommends rsa */
+ #define DROPBEAR_RSA
+-#define DROPBEAR_DSS
++/*#define DROPBEAR_DSS*/
+ /* ECDSA is significantly faster than RSA or DSS. Compiling in ECC
+ * code (either ECDSA or ECDH) increases binary size - around 30kB
+ * on x86-64 */
+@@ -189,7 +189,7 @@ If you test it please contact the Dropbe
+
+ /* Whether to print the message of the day (MOTD). This doesn't add much code
+ * size */
+-#define DO_MOTD
++/*#define DO_MOTD*/
+
+ /* The MOTD file path */
+ #ifndef MOTD_FILENAME
+@@ -231,7 +231,7 @@ Homedir is prepended unless path begins
+ * note that it will be provided for all "hidden" client-interactive
+ * style prompts - if you want something more sophisticated, use
+ * SSH_ASKPASS instead. Comment out this var to remove this functionality.*/
+-#define DROPBEAR_PASSWORD_ENV "DROPBEAR_PASSWORD"
++/*#define DROPBEAR_PASSWORD_ENV "DROPBEAR_PASSWORD"*/
+
+ /* Define this (as well as ENABLE_CLI_PASSWORD_AUTH) to allow the use of
+ * a helper program for the ssh client. The helper program should be
diff --git a/package/network/services/dropbear/patches/130-ssh_ignore_o_and_x_args.patch b/package/network/services/dropbear/patches/130-ssh_ignore_o_and_x_args.patch
new file mode 100644
index 0000000..edb2909
--- /dev/null
+++ b/package/network/services/dropbear/patches/130-ssh_ignore_o_and_x_args.patch
@@ -0,0 +1,21 @@
+--- a/cli-runopts.c
++++ b/cli-runopts.c
+@@ -315,6 +315,10 @@ void cli_getopts(int argc, char ** argv)
+ debug_trace = 1;
+ break;
+ #endif
++ case 'o':
++ next = &dummy;
++ case 'x':
++ break;
+ case 'F':
+ case 'e':
+ #ifndef ENABLE_USER_ALGO_LIST
+@@ -332,7 +336,6 @@ void cli_getopts(int argc, char ** argv)
+ print_version();
+ exit(EXIT_SUCCESS);
+ break;
+- case 'o':
+ case 'b':
+ next = &dummy;
+ default:
diff --git a/package/network/services/dropbear/patches/140-disable_assert.patch b/package/network/services/dropbear/patches/140-disable_assert.patch
new file mode 100644
index 0000000..667d69c
--- /dev/null
+++ b/package/network/services/dropbear/patches/140-disable_assert.patch
@@ -0,0 +1,15 @@
+--- a/dbutil.h
++++ b/dbutil.h
+@@ -88,7 +88,11 @@ int m_str_to_uint(const char* str, unsig
+ #define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL}
+
+ /* Dropbear assertion */
+-#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
++#ifndef DROPBEAR_ASSERT_ENABLED
++#define DROPBEAR_ASSERT_ENABLED 0
++#endif
++
++#define dropbear_assert(X) do { if (DROPBEAR_ASSERT_ENABLED && !(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
+
+ /* Returns 0 if a and b have the same contents */
+ int constant_time_memcmp(const void* a, const void *b, size_t n);
diff --git a/package/network/services/dropbear/patches/150-dbconvert_standalone.patch b/package/network/services/dropbear/patches/150-dbconvert_standalone.patch
new file mode 100644
index 0000000..ccc2cb7
--- /dev/null
+++ b/package/network/services/dropbear/patches/150-dbconvert_standalone.patch
@@ -0,0 +1,14 @@
+--- a/options.h
++++ b/options.h
+@@ -5,6 +5,11 @@
+ #ifndef DROPBEAR_OPTIONS_H_
+ #define DROPBEAR_OPTIONS_H_
+
++#if !defined(DROPBEAR_CLIENT) && !defined(DROPBEAR_SERVER)
++#define DROPBEAR_SERVER
++#define DROPBEAR_CLIENT
++#endif
++
+ /* Define compile-time options below - the "#ifndef DROPBEAR_XXX .... #endif"
+ * parts are to allow for commandline -DDROPBEAR_XXX options etc. */
+
diff --git a/package/network/services/dropbear/patches/500-set-default-path.patch b/package/network/services/dropbear/patches/500-set-default-path.patch
new file mode 100644
index 0000000..f6880ef
--- /dev/null
+++ b/package/network/services/dropbear/patches/500-set-default-path.patch
@@ -0,0 +1,11 @@
+--- a/options.h
++++ b/options.h
+@@ -341,7 +341,7 @@ be overridden at runtime with -I. 0 disa
+ #define DEFAULT_IDLE_TIMEOUT 0
+
+ /* The default path. This will often get replaced by the shell */
+-#define DEFAULT_PATH "/usr/bin:/bin"
++#define DEFAULT_PATH "/bin:/sbin:/usr/bin:/usr/sbin"
+
+ /* Some other defines (that mostly should be left alone) are defined
+ * in sysoptions.h */
diff --git a/package/network/services/dropbear/patches/600-allow-blank-root-password.patch b/package/network/services/dropbear/patches/600-allow-blank-root-password.patch
new file mode 100644
index 0000000..7c67b08
--- /dev/null
+++ b/package/network/services/dropbear/patches/600-allow-blank-root-password.patch
@@ -0,0 +1,11 @@
+--- a/svr-auth.c
++++ b/svr-auth.c
+@@ -149,7 +149,7 @@ void recv_msg_userauth_request() {
+ AUTH_METHOD_NONE_LEN) == 0) {
+ TRACE(("recv_msg_userauth_request: 'none' request"))
+ if (valid_user
+- && svr_opts.allowblankpass
++ && (svr_opts.allowblankpass || !strcmp(ses.authstate.pw_name, "root"))
+ && !svr_opts.noauthpass
+ && !(svr_opts.norootpass && ses.authstate.pw_uid == 0)
+ && ses.authstate.pw_passwd[0] == '\0')
diff --git a/package/network/services/dropbear/patches/610-skip-default-keys-in-custom-runs.patch b/package/network/services/dropbear/patches/610-skip-default-keys-in-custom-runs.patch
new file mode 100644
index 0000000..ee6d273
--- /dev/null
+++ b/package/network/services/dropbear/patches/610-skip-default-keys-in-custom-runs.patch
@@ -0,0 +1,18 @@
+--- a/svr-runopts.c
++++ b/svr-runopts.c
+@@ -475,6 +475,7 @@ void load_all_hostkeys() {
+ m_free(hostkey_file);
+ }
+
++ if (svr_opts.num_hostkey_files <= 0) {
+ #ifdef DROPBEAR_RSA
+ loadhostkey(RSA_PRIV_FILENAME, 0);
+ #endif
+@@ -486,6 +487,7 @@ void load_all_hostkeys() {
+ #ifdef DROPBEAR_ECDSA
+ loadhostkey(ECDSA_PRIV_FILENAME, 0);
+ #endif
++ }
+
+ #ifdef DROPBEAR_DELAY_HOSTKEY
+ if (svr_opts.delay_hostkey) {
diff --git a/package/network/services/ead/Makefile b/package/network/services/ead/Makefile
new file mode 100644
index 0000000..bd33010
--- /dev/null
+++ b/package/network/services/ead/Makefile
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2006-2008 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:=ead
+PKG_RELEASE:=1
+
+PKG_BUILD_DEPENDS:=libpcap
+PKG_BUILD_DIR:=$(BUILD_DIR)/ead
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+define Package/ead
+ SECTION:=net
+ CATEGORY:=Base system
+ TITLE:=Emergency Access Daemon
+ URL:=http://bridge.sourceforge.net/
+endef
+
+define Package/ead/description
+ Provides remote access to your device even if IP and firewall
+ configuration settings are defunct
+endef
+
+CONFIGURE_PATH = tinysrp
+
+TARGET_CFLAGS += \
+ -I$(PKG_BUILD_DIR) \
+ -I$(PKG_BUILD_DIR)/tinysrp \
+ $(TARGET_CPPFLAGS)
+
+MAKE_FLAGS += \
+ CONFIGURE_ARGS="$(CONFIGURE_ARGS)" \
+ LIBS_EADCLIENT="$(PKG_BUILD_DIR)/tinysrp/libtinysrp.a" \
+ LIBS_EAD="$(PKG_BUILD_DIR)/tinysrp/libtinysrp.a $(STAGING_DIR)/usr/lib/libpcap.a" \
+ CFLAGS="$(TARGET_CFLAGS)"
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Package/ead/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ead $(1)/sbin/
+endef
+
+$(eval $(call BuildPackage,ead))
diff --git a/package/network/services/ead/src/Makefile b/package/network/services/ead/src/Makefile
new file mode 100644
index 0000000..eb75516
--- /dev/null
+++ b/package/network/services/ead/src/Makefile
@@ -0,0 +1,33 @@
+CC = gcc
+CPPFLAGS = -I. -Itinysrp
+CFLAGS = -Os -Wall
+LDFLAGS =
+LIBS_EADCLIENT = tinysrp/libtinysrp.a
+LIBS_EAD = tinysrp/libtinysrp.a -lpcap
+CONFIGURE_ARGS =
+
+all: ead ead-client
+
+obj = ead-crypt.o libbridge_init.o
+
+tinysrp/Makefile:
+ cd tinysrp; ./configure $(CONFIGURE_ARGS)
+
+tinysrp/libtinysrp.a: tinysrp/Makefile
+ -$(MAKE) -C tinysrp CFLAGS="$(CFLAGS)"
+
+%.o: %.c $(wildcard *.h) tinysrp/libtinysrp.a
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
+
+ead.o: filter.c
+ead-crypt.o: aes.c sha1.c
+
+ead: ead.o $(obj) tinysrp/libtinysrp.a
+ $(CC) -o $@ $< $(obj) $(LDFLAGS) $(LIBS_EAD)
+
+ead-client: ead-client.o $(obj)
+ $(CC) -o $@ $< $(obj) $(LDFLAGS) $(LIBS_EADCLIENT)
+
+clean:
+ rm -f *.o ead ead-client
+ if [ -f tinysrp/Makefile ]; then $(MAKE) -C tinysrp distclean; fi
diff --git a/package/network/services/ead/src/aes.c b/package/network/services/ead/src/aes.c
new file mode 100644
index 0000000..6f9db34
--- /dev/null
+++ b/package/network/services/ead/src/aes.c
@@ -0,0 +1,1061 @@
+/*
+ * AES (Rijndael) cipher
+ *
+ * Modifications to public domain implementation:
+ * - support only 128-bit keys
+ * - cleanup
+ * - use C pre-processor to make it easier to change S table access
+ * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
+ * cost of reduced throughput (quite small difference on Pentium 4,
+ * 10-25% when using -O1 or -O2 optimization)
+ *
+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+/*
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* #define FULL_UNROLL */
+#define AES_SMALL_TABLES
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+*/
+
+static const u32 Te0[256] = {
+ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+#ifndef AES_SMALL_TABLES
+static const u32 Te1[256] = {
+ 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+ 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+ 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+ 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+ 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+ 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+ 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+ 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+ 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+ 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+ 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+ 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+ 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+ 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+ 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+ 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+ 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+ 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+ 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+ 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+ 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+ 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+ 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+ 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+ 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+ 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+ 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+ 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+ 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+ 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+ 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+ 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+ 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+ 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+ 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+ 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+ 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+ 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+ 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+ 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+ 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+ 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+ 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+ 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+ 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+ 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+ 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+ 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+ 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+ 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+ 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+ 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+ 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+ 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+ 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+ 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+ 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+ 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+ 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+ 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+ 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+ 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+ 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+ 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+ 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+ 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+ 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+ 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+ 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+ 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+ 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+ 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+ 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+ 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+ 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+ 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+ 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+ 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+ 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+ 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+ 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+ 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+ 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+ 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+ 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+ 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+ 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+ 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+ 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+ 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+ 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+ 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+ 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+ 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+ 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+ 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+ 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+ 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+ 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+ 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+ 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+ 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+ 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+ 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+ 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+ 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+ 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+ 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+ 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+ 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+ 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+ 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+ 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+ 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+ 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+ 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+ 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+ 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+ 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+ 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+ 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+ 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+ 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+ 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+ 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+ 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+ 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+
+ 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+ 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+ 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+ 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+ 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+ 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+ 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+ 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+ 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+ 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+ 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+ 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+ 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+ 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+ 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+ 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+ 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+ 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+ 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+ 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+ 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+ 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+ 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+ 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+ 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+ 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+ 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+ 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+ 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+ 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+ 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+ 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+ 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+ 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+ 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+ 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+ 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+ 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+ 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+ 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+ 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+ 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+ 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+ 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+ 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+ 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+ 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+ 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+ 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+ 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+ 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+ 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+ 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+ 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+ 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+ 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+ 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+ 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+ 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+ 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+ 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+ 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+ 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+ 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+static const u32 Te4[256] = {
+ 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+ 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+ 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+ 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+ 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+ 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+ 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+ 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+ 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+ 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+ 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+ 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+ 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+ 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+ 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+ 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+ 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+ 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+ 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+ 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+ 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+ 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+ 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+ 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+ 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+ 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+ 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+ 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+ 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+ 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+ 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+ 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+ 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+ 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+ 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+ 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+ 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+ 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+ 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+ 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+ 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+ 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+ 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+ 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+ 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+ 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+ 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+ 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+ 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+ 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+ 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+ 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+ 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+ 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+ 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+ 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+ 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+ 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+ 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+ 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+ 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+ 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+ 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+ 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+#endif /* AES_SMALL_TABLES */
+static const u32 Td0[256] = {
+ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+#ifndef AES_SMALL_TABLES
+static const u32 Td1[256] = {
+ 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+ 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+ 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+ 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+ 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+ 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+ 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+ 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+ 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+ 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+ 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+ 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+ 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+ 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+ 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+ 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+ 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+ 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+ 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+ 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+ 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+ 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+ 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+ 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+ 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+ 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+ 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+ 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+ 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+ 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+ 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+ 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+ 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+ 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+ 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+ 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+ 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+ 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+ 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+ 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+ 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+ 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+ 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+ 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+ 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+ 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+ 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+ 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+ 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+ 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+ 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+ 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+ 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+ 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+ 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+ 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+ 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+ 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+ 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+ 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+ 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+ 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+ 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+ 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+ 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+ 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+ 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+ 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+ 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+ 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+ 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+ 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+ 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+ 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+ 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+ 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+ 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+ 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+ 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+ 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+ 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+ 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+ 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+ 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+ 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+ 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+ 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+ 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+ 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+ 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+ 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+ 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+ 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+ 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+ 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+ 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+ 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+ 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+ 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+ 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+ 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+ 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+ 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+ 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+ 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+ 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+ 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+ 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+ 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+ 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+ 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+ 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+ 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+ 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+ 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+ 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+ 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+ 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+ 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+ 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+ 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+ 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+ 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+ 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+ 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+ 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+ 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+ 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+ 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+ 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+ 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+ 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+ 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+ 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+ 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+ 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+ 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+ 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+ 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+ 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+ 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+ 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+ 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+ 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+ 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+ 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+ 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+ 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+ 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+ 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+ 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+ 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+ 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+ 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+ 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+ 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+ 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+ 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+ 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+ 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+ 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+ 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+ 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+ 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+ 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+ 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+ 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+ 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+ 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+ 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+ 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+ 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+ 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+ 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+ 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+ 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+ 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+ 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+ 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+ 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+ 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+ 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+ 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+ 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+ 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+ 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+ 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+ 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+ 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+ 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+ 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+ 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u32 Td4[256] = {
+ 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+ 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+ 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+ 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+ 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+ 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+ 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+ 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+ 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+ 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+ 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+ 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+ 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+ 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+ 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+ 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+ 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+ 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+ 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+ 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+ 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+ 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+ 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+ 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+ 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+ 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+ 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+ 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+ 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+ 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+ 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+ 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+ 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+ 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+ 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+ 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+ 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+ 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+ 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+ 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+ 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+ 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+ 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+ 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+ 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+ 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+ 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+ 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+ 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+ 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+ 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+ 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+ 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+ 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+ 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+ 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+ 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+ 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+ 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+ 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+ 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+ 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+ 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+ 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+static const u32 rcon[] = {
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+#else /* AES_SMALL_TABLES */
+static const u8 Td4s[256] = {
+ 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+ 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+ 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+ 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+ 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+ 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+ 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+ 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+ 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+ 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+ 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+ 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+ 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+ 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+ 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+ 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+ 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+ 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+ 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+ 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+ 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+ 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+ 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+ 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+ 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+ 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+ 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+ 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+ 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+ 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+ 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+ 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+static const u8 rcons[] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
+ /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+#endif /* AES_SMALL_TABLES */
+
+
+#ifndef AES_SMALL_TABLES
+
+#define RCON(i) rcon[(i)]
+
+#define TE0(i) Te0[((i) >> 24) & 0xff]
+#define TE1(i) Te1[((i) >> 16) & 0xff]
+#define TE2(i) Te2[((i) >> 8) & 0xff]
+#define TE3(i) Te3[(i) & 0xff]
+#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
+#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
+#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
+#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff)
+#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000)
+#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000)
+#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00)
+#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff)
+#define TE4(i) (Te4[(i)] & 0x000000ff)
+
+#define TD0(i) Td0[((i) >> 24) & 0xff]
+#define TD1(i) Td1[((i) >> 16) & 0xff]
+#define TD2(i) Td2[((i) >> 8) & 0xff]
+#define TD3(i) Td3[(i) & 0xff]
+#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000)
+#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000)
+#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00)
+#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff)
+#define TD0_(i) Td0[(i) & 0xff]
+#define TD1_(i) Td1[(i) & 0xff]
+#define TD2_(i) Td2[(i) & 0xff]
+#define TD3_(i) Td3[(i) & 0xff]
+
+#else /* AES_SMALL_TABLES */
+
+#define RCON(i) (rcons[(i)] << 24)
+
+static inline u32 rotr(u32 val, int bits)
+{
+ return (val >> bits) | (val << (32 - bits));
+}
+
+#define TE0(i) Te0[((i) >> 24) & 0xff]
+#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8)
+#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16)
+#define TE3(i) rotr(Te0[(i) & 0xff], 24)
+#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
+#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
+#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
+#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
+#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000)
+#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
+#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
+#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
+#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
+
+#define TD0(i) Td0[((i) >> 24) & 0xff]
+#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8)
+#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16)
+#define TD3(i) rotr(Td0[(i) & 0xff], 24)
+#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24)
+#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16)
+#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8)
+#define TD44(i) (Td4s[(i) & 0xff])
+#define TD0_(i) Td0[(i) & 0xff]
+#define TD1_(i) rotr(Td0[(i) & 0xff], 8)
+#define TD2_(i) rotr(Td0[(i) & 0xff], 16)
+#define TD3_(i) rotr(Td0[(i) & 0xff], 24)
+
+#endif /* AES_SMALL_TABLES */
+
+#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+
+#ifdef _MSC_VER
+#define GETU32(p) SWAP(*((u32 *)(p)))
+#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+#else
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
+((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) { \
+(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \
+(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
+#endif
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ *
+ * @return the number of rounds for the given cipher key size.
+ */
+static void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])
+{
+ int i;
+ u32 temp;
+
+ rk[0] = GETU32(cipherKey );
+ rk[1] = GETU32(cipherKey + 4);
+ rk[2] = GETU32(cipherKey + 8);
+ rk[3] = GETU32(cipherKey + 12);
+ for (i = 0; i < 10; i++) {
+ temp = rk[3];
+ rk[4] = rk[0] ^
+ TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^
+ RCON(i);
+ rk[5] = rk[1] ^ rk[4];
+ rk[6] = rk[2] ^ rk[5];
+ rk[7] = rk[3] ^ rk[6];
+ rk += 4;
+ }
+}
+
+#ifndef CONFIG_NO_AES_DECRYPT
+/**
+ * Expand the cipher key into the decryption key schedule.
+ *
+ * @return the number of rounds for the given cipher key size.
+ */
+static void rijndaelKeySetupDec(u32 rk[/*44*/], const u8 cipherKey[])
+{
+ int Nr = 10, i, j;
+ u32 temp;
+
+ /* expand the cipher key: */
+ rijndaelKeySetupEnc(rk, cipherKey);
+ /* invert the order of the round keys: */
+ for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
+ temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
+ temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+ temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+ temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+ }
+ /* apply the inverse MixColumn transform to all round keys but the
+ * first and the last: */
+ for (i = 1; i < Nr; i++) {
+ rk += 4;
+ for (j = 0; j < 4; j++) {
+ rk[j] = TD0_(TE4((rk[j] >> 24) )) ^
+ TD1_(TE4((rk[j] >> 16) & 0xff)) ^
+ TD2_(TE4((rk[j] >> 8) & 0xff)) ^
+ TD3_(TE4((rk[j] ) & 0xff));
+ }
+ }
+}
+#endif /* CONFIG_NO_AES_DECRYPT */
+
+#ifndef CONFIG_NO_AES_ENCRYPT
+static void rijndaelEncrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16])
+{
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+ const int Nr = 10;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(pt ) ^ rk[0];
+ s1 = GETU32(pt + 4) ^ rk[1];
+ s2 = GETU32(pt + 8) ^ rk[2];
+ s3 = GETU32(pt + 12) ^ rk[3];
+
+#define ROUND(i,d,s) \
+d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
+d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
+d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
+d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
+
+#ifdef FULL_UNROLL
+
+ ROUND(1,t,s);
+ ROUND(2,s,t);
+ ROUND(3,t,s);
+ ROUND(4,s,t);
+ ROUND(5,t,s);
+ ROUND(6,s,t);
+ ROUND(7,t,s);
+ ROUND(8,s,t);
+ ROUND(9,t,s);
+
+ rk += Nr << 2;
+
+#else /* !FULL_UNROLL */
+
+ /* Nr - 1 full rounds: */
+ r = Nr >> 1;
+ for (;;) {
+ ROUND(1,t,s);
+ rk += 8;
+ if (--r == 0)
+ break;
+ ROUND(0,s,t);
+ }
+
+#endif /* ?FULL_UNROLL */
+
+#undef ROUND
+
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];
+ PUTU32(ct , s0);
+ s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];
+ PUTU32(ct + 4, s1);
+ s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];
+ PUTU32(ct + 8, s2);
+ s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
+ PUTU32(ct + 12, s3);
+}
+#endif /* CONFIG_NO_AES_ENCRYPT */
+
+static void rijndaelDecrypt(const u32 rk[/*44*/], const u8 ct[16], u8 pt[16])
+{
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+ const int Nr = 10;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(ct ) ^ rk[0];
+ s1 = GETU32(ct + 4) ^ rk[1];
+ s2 = GETU32(ct + 8) ^ rk[2];
+ s3 = GETU32(ct + 12) ^ rk[3];
+
+#define ROUND(i,d,s) \
+d##0 = TD0(s##0) ^ TD1(s##3) ^ TD2(s##2) ^ TD3(s##1) ^ rk[4 * i]; \
+d##1 = TD0(s##1) ^ TD1(s##0) ^ TD2(s##3) ^ TD3(s##2) ^ rk[4 * i + 1]; \
+d##2 = TD0(s##2) ^ TD1(s##1) ^ TD2(s##0) ^ TD3(s##3) ^ rk[4 * i + 2]; \
+d##3 = TD0(s##3) ^ TD1(s##2) ^ TD2(s##1) ^ TD3(s##0) ^ rk[4 * i + 3]
+
+#ifdef FULL_UNROLL
+
+ ROUND(1,t,s);
+ ROUND(2,s,t);
+ ROUND(3,t,s);
+ ROUND(4,s,t);
+ ROUND(5,t,s);
+ ROUND(6,s,t);
+ ROUND(7,t,s);
+ ROUND(8,s,t);
+ ROUND(9,t,s);
+
+ rk += Nr << 2;
+
+#else /* !FULL_UNROLL */
+
+ /* Nr - 1 full rounds: */
+ r = Nr >> 1;
+ for (;;) {
+ ROUND(1,t,s);
+ rk += 8;
+ if (--r == 0)
+ break;
+ ROUND(0,s,t);
+ }
+
+#endif /* ?FULL_UNROLL */
+
+#undef ROUND
+
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 = TD41(t0) ^ TD42(t3) ^ TD43(t2) ^ TD44(t1) ^ rk[0];
+ PUTU32(pt , s0);
+ s1 = TD41(t1) ^ TD42(t0) ^ TD43(t3) ^ TD44(t2) ^ rk[1];
+ PUTU32(pt + 4, s1);
+ s2 = TD41(t2) ^ TD42(t1) ^ TD43(t0) ^ TD44(t3) ^ rk[2];
+ PUTU32(pt + 8, s2);
+ s3 = TD41(t3) ^ TD42(t2) ^ TD43(t1) ^ TD44(t0) ^ rk[3];
+ PUTU32(pt + 12, s3);
+}
+
+#define AES_PRIV_SIZE 44
diff --git a/package/network/services/ead/src/ead-client.c b/package/network/services/ead/src/ead-client.c
new file mode 100644
index 0000000..6d7e07d
--- /dev/null
+++ b/package/network/services/ead/src/ead-client.c
@@ -0,0 +1,433 @@
+/*
+ * Client for the Emergency Access Daemon
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * 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.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <t_pwd.h>
+#include <t_read.h>
+#include <t_sha.h>
+#include <t_defines.h>
+#include <t_client.h>
+#include "ead.h"
+#include "ead-crypt.h"
+
+#include "pw_encrypt_md5.c"
+
+#define EAD_TIMEOUT 400
+#define EAD_TIMEOUT_LONG 2000
+
+static char msgbuf[1500];
+static struct ead_msg *msg = (struct ead_msg *) msgbuf;
+static uint16_t nid = 0xffff;
+struct sockaddr_in local, remote;
+static int s = 0;
+static int sockflags;
+static struct in_addr serverip = {
+ .s_addr = 0x01010101 /* dummy */
+};
+
+static unsigned char *skey = NULL;
+static unsigned char bbuf[MAXPARAMLEN];
+static unsigned char saltbuf[MAXSALTLEN];
+static char *username = NULL;
+static char password[MAXPARAMLEN] = "";
+static char pw_md5[MD5_OUT_BUFSIZE];
+static char pw_salt[MAXSALTLEN];
+
+static struct t_client *tc = NULL;
+static struct t_num salt = { .data = saltbuf };
+static struct t_num *A, B;
+static struct t_preconf *tcp;
+static int auth_type = EAD_AUTH_DEFAULT;
+static int timeout = EAD_TIMEOUT;
+static uint16_t sid = 0;
+
+static void
+set_nonblock(int enable)
+{
+ if (enable == !!(sockflags & O_NONBLOCK))
+ return;
+
+ sockflags ^= O_NONBLOCK;
+ fcntl(s, F_SETFL, sockflags);
+}
+
+static int
+send_packet(int type, bool (*handler)(void), unsigned int max)
+{
+ struct timeval tv;
+ fd_set fds;
+ int nfds;
+ int len;
+ int res = 0;
+
+ type = htonl(type);
+ memcpy(&msg->ip, &serverip.s_addr, sizeof(msg->ip));
+ set_nonblock(0);
+ sendto(s, msgbuf, sizeof(struct ead_msg) + ntohl(msg->len), 0, (struct sockaddr *) &remote, sizeof(remote));
+ set_nonblock(1);
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+ FD_ZERO(&fds);
+ do {
+ FD_SET(s, &fds);
+ nfds = select(s + 1, &fds, NULL, NULL, &tv);
+
+ if (nfds <= 0)
+ break;
+
+ if (!FD_ISSET(s, &fds))
+ break;
+
+ len = read(s, msgbuf, sizeof(msgbuf));
+ if (len < 0)
+ break;
+
+ if (len < sizeof(struct ead_msg))
+ continue;
+
+ if (len < sizeof(struct ead_msg) + ntohl(msg->len))
+ continue;
+
+ if (msg->magic != htonl(EAD_MAGIC))
+ continue;
+
+ if ((nid != 0xffff) && (ntohs(msg->nid) != nid))
+ continue;
+
+ if (msg->type != type)
+ continue;
+
+ if (handler())
+ res++;
+
+ if ((max > 0) && (res >= max))
+ break;
+ } while (1);
+
+ return res;
+}
+
+static void
+prepare_password(void)
+{
+ switch(auth_type) {
+ case EAD_AUTH_DEFAULT:
+ break;
+ case EAD_AUTH_MD5:
+ md5_crypt(pw_md5, (unsigned char *) password, (unsigned char *) pw_salt);
+ strncpy(password, pw_md5, sizeof(password));
+ break;
+ }
+}
+
+static bool
+handle_pong(void)
+{
+ struct ead_msg_pong *pong = EAD_DATA(msg, pong);
+ int len = ntohl(msg->len) - sizeof(struct ead_msg_pong);
+
+ if (len <= 0)
+ return false;
+
+ pong->name[len] = 0;
+ auth_type = ntohs(pong->auth_type);
+ if (nid == 0xffff)
+ printf("%04x: %s\n", ntohs(msg->nid), pong->name);
+ sid = msg->sid;
+ return true;
+}
+
+static bool
+handle_prime(void)
+{
+ struct ead_msg_salt *sb = EAD_DATA(msg, salt);
+
+ salt.len = sb->len;
+ memcpy(salt.data, sb->salt, salt.len);
+
+ if (auth_type == EAD_AUTH_MD5) {
+ memcpy(pw_salt, sb->ext_salt, MAXSALTLEN);
+ pw_salt[MAXSALTLEN - 1] = 0;
+ }
+
+ tcp = t_getpreparam(sb->prime);
+ tc = t_clientopen(username, &tcp->modulus, &tcp->generator, &salt);
+ if (!tc) {
+ fprintf(stderr, "Client open failed\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+handle_b(void)
+{
+ struct ead_msg_number *num = EAD_DATA(msg, number);
+ int len = ntohl(msg->len) - sizeof(struct ead_msg_number);
+
+ B.data = bbuf;
+ B.len = len;
+ memcpy(bbuf, num->data, len);
+ return true;
+}
+
+static bool
+handle_none(void)
+{
+ return true;
+}
+
+static bool
+handle_done_auth(void)
+{
+ struct ead_msg_auth *auth = EAD_DATA(msg, auth);
+ if (t_clientverify(tc, auth->data) != 0) {
+ fprintf(stderr, "Client auth verify failed\n");
+ return false;
+ }
+ return true;
+}
+
+static bool
+handle_cmd_data(void)
+{
+ struct ead_msg_cmd_data *cmd = EAD_ENC_DATA(msg, cmd_data);
+ int datalen = ead_decrypt_message(msg) - sizeof(struct ead_msg_cmd_data);
+
+ if (datalen < 0)
+ return false;
+
+ if (datalen > 0) {
+ write(1, cmd->data, datalen);
+ }
+
+ return !!cmd->done;
+}
+static int
+send_ping(void)
+{
+ msg->type = htonl(EAD_TYPE_PING);
+ msg->len = 0;
+ return send_packet(EAD_TYPE_PONG, handle_pong, (nid == 0xffff ? 0 : 1));
+}
+
+static int
+send_username(void)
+{
+ msg->type = htonl(EAD_TYPE_SET_USERNAME);
+ msg->len = htonl(sizeof(struct ead_msg_user));
+ strcpy(EAD_DATA(msg, user)->username, username);
+ return send_packet(EAD_TYPE_ACK_USERNAME, handle_none, 1);
+}
+
+static int
+get_prime(void)
+{
+ msg->type = htonl(EAD_TYPE_GET_PRIME);
+ msg->len = 0;
+ return send_packet(EAD_TYPE_PRIME, handle_prime, 1);
+}
+
+static int
+send_a(void)
+{
+ struct ead_msg_number *num = EAD_DATA(msg, number);
+ A = t_clientgenexp(tc);
+ msg->type = htonl(EAD_TYPE_SEND_A);
+ msg->len = htonl(sizeof(struct ead_msg_number) + A->len);
+ memcpy(num->data, A->data, A->len);
+ return send_packet(EAD_TYPE_SEND_B, handle_b, 1);
+}
+
+static int
+send_auth(void)
+{
+ struct ead_msg_auth *auth = EAD_DATA(msg, auth);
+
+ prepare_password();
+ t_clientpasswd(tc, password);
+ skey = t_clientgetkey(tc, &B);
+ if (!skey)
+ return 0;
+
+ ead_set_key(skey);
+ msg->type = htonl(EAD_TYPE_SEND_AUTH);
+ msg->len = htonl(sizeof(struct ead_msg_auth));
+ memcpy(auth->data, t_clientresponse(tc), sizeof(auth->data));
+ return send_packet(EAD_TYPE_DONE_AUTH, handle_done_auth, 1);
+}
+
+static int
+send_command(const char *command)
+{
+ struct ead_msg_cmd *cmd = EAD_ENC_DATA(msg, cmd);
+
+ msg->type = htonl(EAD_TYPE_SEND_CMD);
+ cmd->type = htons(EAD_CMD_NORMAL);
+ cmd->timeout = htons(10);
+ strncpy((char *)cmd->data, command, 1024);
+ ead_encrypt_message(msg, sizeof(struct ead_msg_cmd) + strlen(command) + 1);
+ return send_packet(EAD_TYPE_RESULT_CMD, handle_cmd_data, 1);
+}
+
+
+static int
+usage(const char *prog)
+{
+ fprintf(stderr, "Usage: %s [-s <addr>] [-b <addr>] <node> <username>[:<password>] <command>\n"
+ "\n"
+ "\t-s <addr>: Set the server's source address to <addr>\n"
+ "\t-b <addr>: Set the broadcast address to <addr>\n"
+ "\t<node>: Node ID (4 digits hex)\n"
+ "\t<username>: Username to authenticate with\n"
+ "\n"
+ "\tPassing no arguments shows a list of active nodes on the network\n"
+ "\n", prog);
+ return -1;
+}
+
+
+int main(int argc, char **argv)
+{
+ int val = 1;
+ char *st = NULL;
+ const char *command = NULL;
+ const char *prog = argv[0];
+ int ch;
+
+ msg->magic = htonl(EAD_MAGIC);
+ msg->sid = 0;
+
+ memset(&local, 0, sizeof(local));
+ memset(&remote, 0, sizeof(remote));
+
+ remote.sin_family = AF_INET;
+ remote.sin_addr.s_addr = 0xffffffff;
+ remote.sin_port = htons(EAD_PORT);
+
+ local.sin_family = AF_INET;
+ local.sin_addr.s_addr = INADDR_ANY;
+ local.sin_port = 0;
+
+ while ((ch = getopt(argc, argv, "b:s:h")) != -1) {
+ switch(ch) {
+ case 's':
+ inet_aton(optarg, &serverip);
+ break;
+ case 'b':
+ inet_aton(optarg, &remote.sin_addr);
+ break;
+ case 'h':
+ return usage(prog);
+ }
+ }
+ argv += optind;
+ argc -= optind;
+
+ switch(argc) {
+ case 3:
+ command = argv[2];
+ /* fall through */
+ case 2:
+ username = argv[1];
+ st = strchr(username, ':');
+ if (st) {
+ *st = 0;
+ st++;
+ strncpy(password, st, sizeof(password));
+ password[sizeof(password) - 1] = 0;
+ /* hide command line password */
+ memset(st, 0, strlen(st));
+ }
+ /* fall through */
+ case 1:
+ nid = strtoul(argv[0], &st, 16);
+ if (st && st[0] != 0)
+ return usage(prog);
+ /* fall through */
+ case 0:
+ break;
+ default:
+ return usage(prog);
+ }
+
+ msg->nid = htons(nid);
+ s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0) {
+ perror("socket");
+ return -1;
+ }
+
+ setsockopt(s, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val));
+
+ if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0) {
+ perror("bind");
+ return -1;
+ }
+ sockflags = fcntl(s, F_GETFL);
+
+ if (!send_ping()) {
+ fprintf(stderr, "No devices found\n");
+ return 1;
+ }
+
+ if (nid == 0xffff)
+ return 0;
+
+ if (!username || !password[0])
+ return 0;
+
+ if (!send_username()) {
+ fprintf(stderr, "Device did not accept user name\n");
+ return 1;
+ }
+ timeout = EAD_TIMEOUT_LONG;
+ if (!get_prime()) {
+ fprintf(stderr, "Failed to get user password info\n");
+ return 1;
+ }
+ if (!send_a()) {
+ fprintf(stderr, "Failed to send local authentication data\n");
+ return 1;
+ }
+ if (!send_auth()) {
+ fprintf(stderr, "Authentication failed\n");
+ return 1;
+ }
+ if (!command) {
+ fprintf(stderr, "Authentication succesful\n");
+ return 0;
+ }
+ if (!send_command(command)) {
+ fprintf(stderr, "Command failed\n");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/package/network/services/ead/src/ead-crypt.c b/package/network/services/ead/src/ead-crypt.c
new file mode 100644
index 0000000..0372172
--- /dev/null
+++ b/package/network/services/ead/src/ead-crypt.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "ead.h"
+
+#include "sha1.c"
+#include "aes.c"
+
+#if EAD_DEBUGLEVEL >= 1
+#define DEBUG(n, format, ...) do { \
+ if (EAD_DEBUGLEVEL >= n) \
+ fprintf(stderr, format, ##__VA_ARGS__); \
+} while (0);
+
+#else
+#define DEBUG(n, format, ...) do {} while(0)
+#endif
+
+
+static uint32_t aes_enc_ctx[AES_PRIV_SIZE];
+static uint32_t aes_dec_ctx[AES_PRIV_SIZE];
+static uint32_t ead_rx_iv;
+static uint32_t ead_tx_iv;
+static uint32_t ivofs_vec;
+static unsigned int ivofs_idx = 0;
+static uint32_t W[80]; /* work space for sha1 */
+
+#define EAD_ENC_PAD 64
+
+void
+ead_set_key(unsigned char *skey)
+{
+ uint32_t *ivp = (uint32_t *)skey;
+
+ memset(aes_enc_ctx, 0, sizeof(aes_enc_ctx));
+ memset(aes_dec_ctx, 0, sizeof(aes_dec_ctx));
+
+ /* first 32 bytes of skey are used as aes key for
+ * encryption and decryption */
+ rijndaelKeySetupEnc(aes_enc_ctx, skey);
+ rijndaelKeySetupDec(aes_dec_ctx, skey);
+
+ /* the following bytes are used as initialization vector for messages
+ * (highest byte cleared to avoid overflow) */
+ ivp += 8;
+ ead_rx_iv = ntohl(*ivp) & 0x00ffffff;
+ ead_tx_iv = ead_rx_iv;
+
+ /* the last bytes are used to feed the random iv increment */
+ ivp++;
+ ivofs_vec = *ivp;
+}
+
+
+static bool
+ead_check_rx_iv(uint32_t iv)
+{
+ if (iv <= ead_rx_iv)
+ return false;
+
+ if (iv > ead_rx_iv + EAD_MAX_IV_INCR)
+ return false;
+
+ ead_rx_iv = iv;
+ return true;
+}
+
+
+static uint32_t
+ead_get_tx_iv(void)
+{
+ unsigned int ofs;
+
+ ofs = 1 + ((ivofs_vec >> 2 * ivofs_idx) & 0x3);
+ ivofs_idx = (ivofs_idx + 1) % 16;
+ ead_tx_iv += ofs;
+
+ return ead_tx_iv;
+}
+
+static void
+ead_hash_message(struct ead_msg_encrypted *enc, uint32_t *hash, int len)
+{
+ unsigned char *data = (unsigned char *) enc;
+
+ /* hash the packet with the stored hash part initialized to zero */
+ sha_init(hash);
+ memset(enc->hash, 0, sizeof(enc->hash));
+ while (len > 0) {
+ sha_transform(hash, data, W);
+ len -= 64;
+ data += 64;
+ }
+}
+
+void
+ead_encrypt_message(struct ead_msg *msg, unsigned int len)
+{
+ struct ead_msg_encrypted *enc = EAD_DATA(msg, enc);
+ unsigned char *data = (unsigned char *) enc;
+ uint32_t hash[5];
+ int enclen, i;
+
+ len += sizeof(struct ead_msg_encrypted);
+ enc->pad = (EAD_ENC_PAD - (len % EAD_ENC_PAD)) % EAD_ENC_PAD;
+ enclen = len + enc->pad;
+ msg->len = htonl(enclen);
+ enc->iv = htonl(ead_get_tx_iv());
+
+ ead_hash_message(enc, hash, enclen);
+ for (i = 0; i < 5; i++)
+ enc->hash[i] = htonl(hash[i]);
+ DEBUG(2, "SHA1 generate (0x%08x), len=%d\n", enc->hash[0], enclen);
+
+ while (enclen > 0) {
+ rijndaelEncrypt(aes_enc_ctx, data, data);
+ data += 16;
+ enclen -= 16;
+ }
+}
+
+int
+ead_decrypt_message(struct ead_msg *msg)
+{
+ struct ead_msg_encrypted *enc = EAD_DATA(msg, enc);
+ unsigned char *data = (unsigned char *) enc;
+ uint32_t hash_old[5], hash_new[5];
+ int len = ntohl(msg->len);
+ int i, enclen = len;
+
+ if (!len || (len % EAD_ENC_PAD > 0))
+ return 0;
+
+ while (len > 0) {
+ rijndaelDecrypt(aes_dec_ctx, data, data);
+ data += 16;
+ len -= 16;
+ }
+
+ data = (unsigned char *) enc;
+
+ if (enc->pad >= EAD_ENC_PAD) {
+ DEBUG(2, "Invalid padding length\n");
+ return 0;
+ }
+
+ if (!ead_check_rx_iv(ntohl(enc->iv))) {
+ DEBUG(2, "RX IV mismatch (0x%08x <> 0x%08x)\n", ead_rx_iv, ntohl(enc->iv));
+ return 0;
+ }
+
+ for (i = 0; i < 5; i++)
+ hash_old[i] = ntohl(enc->hash[i]);
+ ead_hash_message(enc, hash_new, enclen);
+ if (memcmp(hash_old, hash_new, sizeof(hash_old)) != 0) {
+ DEBUG(2, "SHA1 mismatch (0x%08x != 0x%08x), len=%d\n", hash_old[0], hash_new[0], enclen);
+ return 0;
+ }
+
+ enclen -= enc->pad + sizeof(struct ead_msg_encrypted);
+ return enclen;
+}
diff --git a/package/network/services/ead/src/ead-crypt.h b/package/network/services/ead/src/ead-crypt.h
new file mode 100644
index 0000000..831ec8a
--- /dev/null
+++ b/package/network/services/ead/src/ead-crypt.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * 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.
+ */
+
+#ifndef __EAD_CRYPT_H
+#define __EAD_CRYPT_H
+
+extern void ead_set_key(unsigned char *skey);
+extern void ead_encrypt_message(struct ead_msg *msg, unsigned int len);
+extern int ead_decrypt_message(struct ead_msg *msg);
+
+#endif
diff --git a/package/network/services/ead/src/ead-pcap.h b/package/network/services/ead/src/ead-pcap.h
new file mode 100644
index 0000000..0652ab4
--- /dev/null
+++ b/package/network/services/ead/src/ead-pcap.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file was part of the uIP TCP/IP stack.
+ *
+ */
+#ifndef __EAD_PCAP_H
+#define __EAD_PCAP_H
+
+#include <net/ethernet.h>
+#include <stdint.h>
+#include "ead.h"
+
+typedef uint8_t u8_t;
+typedef uint16_t u16_t;
+
+/* The UDP and IP headers. */
+struct ead_packet {
+ struct ether_header eh;
+ /* IP header. */
+ u8_t vhl,
+ tos,
+ len[2],
+ ipid[2],
+ ipoffset[2],
+ ttl,
+ proto;
+ u16_t ipchksum;
+ u16_t srcipaddr[2],
+ destipaddr[2];
+
+ /* UDP header. */
+ u16_t srcport,
+ destport;
+ u16_t udplen;
+ u16_t udpchksum;
+
+ struct ead_msg msg;
+} __attribute__((packed));
+
+#define UIP_PROTO_UDP 17
+#define UIP_IPH_LEN 20 /* Size of IP header */
+#define UIP_UDPH_LEN 8 /* Size of UDP header */
+#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN)
+
+#endif
diff --git a/package/network/services/ead/src/ead.c b/package/network/services/ead/src/ead.c
new file mode 100644
index 0000000..bded769
--- /dev/null
+++ b/package/network/services/ead/src/ead.c
@@ -0,0 +1,976 @@
+/*
+ * Emergency Access Daemon
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * 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.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pcap.h>
+#include <pcap-bpf.h>
+#include <t_pwd.h>
+#include <t_read.h>
+#include <t_sha.h>
+#include <t_defines.h>
+#include <t_server.h>
+#include <net/if.h>
+
+#include "list.h"
+#include "ead.h"
+#include "ead-pcap.h"
+#include "ead-crypt.h"
+#include "libbridge.h"
+
+#include "filter.c"
+
+#ifdef linux
+#include <linux/if_packet.h>
+#endif
+
+#define PASSWD_FILE "/etc/passwd"
+
+#ifndef DEFAULT_IFNAME
+#define DEFAULT_IFNAME "eth0"
+#endif
+
+#ifndef DEFAULT_DEVNAME
+#define DEFAULT_DEVNAME "Unknown"
+#endif
+
+#define PCAP_MRU 1600
+#define PCAP_TIMEOUT 200
+
+#if EAD_DEBUGLEVEL >= 1
+#define DEBUG(n, format, ...) do { \
+ if (EAD_DEBUGLEVEL >= n) \
+ fprintf(stderr, format, ##__VA_ARGS__); \
+} while (0);
+
+#else
+#define DEBUG(n, format, ...) do {} while(0)
+#endif
+
+struct ead_instance {
+ struct list_head list;
+ char ifname[16];
+ int pid;
+ char id;
+ char bridge[16];
+ bool br_check;
+};
+
+static char ethmac[6] = "\x00\x13\x37\x00\x00\x00"; /* last 3 bytes will be randomized */
+static pcap_t *pcap_fp = NULL;
+static pcap_t *pcap_fp_rx = NULL;
+static char pktbuf_b[PCAP_MRU];
+static struct ead_packet *pktbuf = (struct ead_packet *)pktbuf_b;
+static u16_t nid = 0xffff; /* node id */
+static char username[32] = "";
+static int state = EAD_TYPE_SET_USERNAME;
+static const char *passwd_file = PASSWD_FILE;
+static const char password[MAXPARAMLEN];
+static bool child_pending = false;
+
+static unsigned char abuf[MAXPARAMLEN + 1];
+static unsigned char pwbuf[MAXPARAMLEN];
+static unsigned char saltbuf[MAXSALTLEN];
+static unsigned char pw_saltbuf[MAXSALTLEN];
+static struct list_head instances;
+static const char *dev_name = DEFAULT_DEVNAME;
+static bool nonfork = false;
+static struct ead_instance *instance = NULL;
+
+static struct t_pwent tpe = {
+ .name = username,
+ .index = 1,
+ .password.data = pwbuf,
+ .password.len = 0,
+ .salt.data = saltbuf,
+ .salt.len = 0,
+};
+struct t_confent *tce = NULL;
+static struct t_server *ts = NULL;
+static struct t_num A, *B = NULL;
+unsigned char *skey;
+
+static void
+set_recv_type(pcap_t *p, bool rx)
+{
+#ifdef PACKET_RECV_TYPE
+ struct sockaddr_ll sll;
+ struct ifreq ifr;
+ int mask;
+ int fd;
+
+ fd = pcap_get_selectable_fd(p);
+ if (fd < 0)
+ return;
+
+ if (rx)
+ mask = 1 << PACKET_BROADCAST;
+ else
+ mask = 0;
+
+ setsockopt(fd, SOL_PACKET, PACKET_RECV_TYPE, &mask, sizeof(mask));
+#endif
+}
+
+
+static pcap_t *
+ead_open_pcap(const char *ifname, char *errbuf, bool rx)
+{
+ pcap_t *p;
+
+ p = pcap_create(ifname, errbuf);
+ if (p == NULL)
+ goto out;
+
+ pcap_set_snaplen(p, PCAP_MRU);
+ pcap_set_promisc(p, rx);
+ pcap_set_timeout(p, PCAP_TIMEOUT);
+#ifdef HAS_PROTO_EXTENSION
+ pcap_set_protocol(p, (rx ? htons(ETH_P_IP) : 0));
+#endif
+ pcap_set_buffer_size(p, (rx ? 10 : 1) * PCAP_MRU);
+ pcap_activate(p);
+ set_recv_type(p, rx);
+out:
+ return p;
+}
+
+static void
+get_random_bytes(void *ptr, int len)
+{
+ int fd;
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ read(fd, ptr, len);
+ close(fd);
+}
+
+static bool
+prepare_password(void)
+{
+ static char lbuf[1024];
+ unsigned char dig[SHA_DIGESTSIZE];
+ BigInteger x, v, n, g;
+ SHA1_CTX ctxt;
+ int ulen = strlen(username);
+ FILE *f;
+
+ lbuf[sizeof(lbuf) - 1] = 0;
+
+ f = fopen(passwd_file, "r");
+ if (!f)
+ return false;
+
+ while (fgets(lbuf, sizeof(lbuf) - 1, f) != NULL) {
+ char *str, *s2;
+
+ if (strncmp(lbuf, username, ulen) != 0)
+ continue;
+
+ if (lbuf[ulen] != ':')
+ continue;
+
+ str = &lbuf[ulen + 1];
+
+ if (strncmp(str, "$1$", 3) != 0)
+ continue;
+
+ s2 = strchr(str + 3, '$');
+ if (!s2)
+ continue;
+
+ if (s2 - str >= MAXSALTLEN)
+ continue;
+
+ strncpy((char *) pw_saltbuf, str, s2 - str);
+ pw_saltbuf[s2 - str] = 0;
+
+ s2 = strchr(s2, ':');
+ if (!s2)
+ continue;
+
+ *s2 = 0;
+ if (s2 - str >= MAXPARAMLEN)
+ continue;
+
+ strncpy((char *)password, str, MAXPARAMLEN);
+ fclose(f);
+ goto hash_password;
+ }
+
+ /* not found */
+ fclose(f);
+ return false;
+
+hash_password:
+ tce = gettcid(tpe.index);
+ do {
+ t_random(tpe.password.data, SALTLEN);
+ } while (memcmp(saltbuf, (char *)dig, sizeof(saltbuf)) == 0);
+ if (saltbuf[0] == 0)
+ saltbuf[0] = 0xff;
+
+ n = BigIntegerFromBytes(tce->modulus.data, tce->modulus.len);
+ g = BigIntegerFromBytes(tce->generator.data, tce->generator.len);
+ v = BigIntegerFromInt(0);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, (unsigned char *) username, strlen(username));
+ SHA1Update(&ctxt, (unsigned char *) ":", 1);
+ SHA1Update(&ctxt, (unsigned char *) password, strlen(password));
+ SHA1Final(dig, &ctxt);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, saltbuf, tpe.salt.len);
+ SHA1Update(&ctxt, dig, sizeof(dig));
+ SHA1Final(dig, &ctxt);
+
+ /* x = H(s, H(u, ':', p)) */
+ x = BigIntegerFromBytes(dig, sizeof(dig));
+
+ BigIntegerModExp(v, g, x, n);
+ tpe.password.len = BigIntegerToBytes(v, (unsigned char *)pwbuf);
+
+ BigIntegerFree(v);
+ BigIntegerFree(x);
+ BigIntegerFree(g);
+ BigIntegerFree(n);
+ return true;
+}
+
+static u16_t
+chksum(u16_t sum, const u8_t *data, u16_t len)
+{
+ u16_t t;
+ const u8_t *dataptr;
+ const u8_t *last_byte;
+
+ dataptr = data;
+ last_byte = data + len - 1;
+
+ while(dataptr < last_byte) { /* At least two more bytes */
+ t = (dataptr[0] << 8) + dataptr[1];
+ sum += t;
+ if(sum < t) {
+ sum++; /* carry */
+ }
+ dataptr += 2;
+ }
+
+ if(dataptr == last_byte) {
+ t = (dataptr[0] << 8) + 0;
+ sum += t;
+ if(sum < t) {
+ sum++; /* carry */
+ }
+ }
+
+ /* Return sum in host byte order. */
+ return sum;
+}
+
+static void
+ead_send_packet_clone(struct ead_packet *pkt)
+{
+ u16_t len, sum;
+
+ memcpy(pktbuf, pkt, offsetof(struct ead_packet, msg));
+ memcpy(pktbuf->eh.ether_shost, ethmac, 6);
+ memcpy(pktbuf->eh.ether_dhost, pkt->eh.ether_shost, 6);
+
+ /* ip header */
+ len = sizeof(struct ead_packet) - sizeof(struct ether_header) + ntohl(pktbuf->msg.len);
+ pktbuf->len[0] = len >> 8;
+ pktbuf->len[1] = len & 0xff;
+ memcpy(pktbuf->srcipaddr, &pkt->msg.ip, 4);
+ memcpy(pktbuf->destipaddr, pkt->srcipaddr, 4);
+
+ /* ip checksum */
+ pktbuf->ipchksum = 0;
+ sum = chksum(0, (void *) &pktbuf->vhl, UIP_IPH_LEN);
+ if (sum == 0)
+ sum = 0xffff;
+ pktbuf->ipchksum = htons(~sum);
+
+ /* udp header */
+ pktbuf->srcport = pkt->destport;
+ pktbuf->destport = pkt->srcport;
+
+ /* udp checksum */
+ len -= UIP_IPH_LEN;
+ pktbuf->udplen = htons(len);
+ pktbuf->udpchksum = 0;
+ sum = len + UIP_PROTO_UDP;
+ sum = chksum(sum, (void *) &pktbuf->srcipaddr[0], 8); /* src, dest ip */
+ sum = chksum(sum, (void *) &pktbuf->srcport, len);
+ if (sum == 0)
+ sum = 0xffff;
+ pktbuf->udpchksum = htons(~sum);
+ pcap_sendpacket(pcap_fp, (void *) pktbuf, sizeof(struct ead_packet) + ntohl(pktbuf->msg.len));
+}
+
+static void
+set_state(int nstate)
+{
+ if (state == nstate)
+ return;
+
+ if (nstate < state) {
+ if ((nstate < EAD_TYPE_GET_PRIME) &&
+ (state >= EAD_TYPE_GET_PRIME)) {
+ t_serverclose(ts);
+ ts = NULL;
+ }
+ goto done;
+ }
+
+ switch(state) {
+ case EAD_TYPE_SET_USERNAME:
+ if (!prepare_password())
+ goto error;
+ ts = t_serveropenraw(&tpe, tce);
+ if (!ts)
+ goto error;
+ break;
+ case EAD_TYPE_GET_PRIME:
+ B = t_servergenexp(ts);
+ break;
+ case EAD_TYPE_SEND_A:
+ skey = t_servergetkey(ts, &A);
+ if (!skey)
+ goto error;
+
+ ead_set_key(skey);
+ break;
+ }
+done:
+ state = nstate;
+error:
+ return;
+}
+
+static bool
+handle_ping(struct ead_packet *pkt, int len, int *nstate)
+{
+ struct ead_msg *msg = &pktbuf->msg;
+ struct ead_msg_pong *pong = EAD_DATA(msg, pong);
+ int slen;
+
+ slen = strlen(dev_name);
+ if (slen > 1024)
+ slen = 1024;
+
+ msg->len = htonl(sizeof(struct ead_msg_pong) + slen);
+ strncpy(pong->name, dev_name, slen);
+ pong->name[slen] = 0;
+ pong->auth_type = htons(EAD_AUTH_MD5);
+
+ return true;
+}
+
+static bool
+handle_set_username(struct ead_packet *pkt, int len, int *nstate)
+{
+ struct ead_msg *msg = &pkt->msg;
+ struct ead_msg_user *user = EAD_DATA(msg, user);
+
+ set_state(EAD_TYPE_SET_USERNAME); /* clear old state */
+ strncpy(username, user->username, sizeof(username));
+ username[sizeof(username) - 1] = 0;
+
+ msg = &pktbuf->msg;
+ msg->len = 0;
+
+ *nstate = EAD_TYPE_GET_PRIME;
+ return true;
+}
+
+static bool
+handle_get_prime(struct ead_packet *pkt, int len, int *nstate)
+{
+ struct ead_msg *msg = &pktbuf->msg;
+ struct ead_msg_salt *salt = EAD_DATA(msg, salt);
+
+ msg->len = htonl(sizeof(struct ead_msg_salt));
+ salt->prime = tce->index - 1;
+ salt->len = ts->s.len;
+ memcpy(salt->salt, ts->s.data, ts->s.len);
+ memcpy(salt->ext_salt, pw_saltbuf, MAXSALTLEN);
+
+ *nstate = EAD_TYPE_SEND_A;
+ return true;
+}
+
+static bool
+handle_send_a(struct ead_packet *pkt, int len, int *nstate)
+{
+ struct ead_msg *msg = &pkt->msg;
+ struct ead_msg_number *number = EAD_DATA(msg, number);
+ len = ntohl(msg->len) - sizeof(struct ead_msg_number);
+
+ if (len > MAXPARAMLEN + 1)
+ return false;
+
+ A.len = len;
+ A.data = abuf;
+ memcpy(A.data, number->data, len);
+
+ msg = &pktbuf->msg;
+ number = EAD_DATA(msg, number);
+ msg->len = htonl(sizeof(struct ead_msg_number) + B->len);
+ memcpy(number->data, B->data, B->len);
+
+ *nstate = EAD_TYPE_SEND_AUTH;
+ return true;
+}
+
+static bool
+handle_send_auth(struct ead_packet *pkt, int len, int *nstate)
+{
+ struct ead_msg *msg = &pkt->msg;
+ struct ead_msg_auth *auth = EAD_DATA(msg, auth);
+
+ if (t_serververify(ts, auth->data) != 0) {
+ DEBUG(2, "Client authentication failed\n");
+ *nstate = EAD_TYPE_SET_USERNAME;
+ return false;
+ }
+
+ msg = &pktbuf->msg;
+ auth = EAD_DATA(msg, auth);
+ msg->len = htonl(sizeof(struct ead_msg_auth));
+
+ DEBUG(2, "Client authentication successful\n");
+ memcpy(auth->data, t_serverresponse(ts), sizeof(auth->data));
+
+ *nstate = EAD_TYPE_SEND_CMD;
+ return true;
+}
+
+static bool
+handle_send_cmd(struct ead_packet *pkt, int len, int *nstate)
+{
+ struct ead_msg *msg = &pkt->msg;
+ struct ead_msg_cmd *cmd = EAD_ENC_DATA(msg, cmd);
+ struct ead_msg_cmd_data *cmddata;
+ struct timeval tv, to, tn;
+ int pfd[2], fd;
+ fd_set fds;
+ pid_t pid;
+ bool stream = false;
+ int timeout;
+ int type;
+ int datalen;
+
+ datalen = ead_decrypt_message(msg) - sizeof(struct ead_msg_cmd);
+ if (datalen <= 0)
+ return false;
+
+ type = ntohs(cmd->type);
+ timeout = ntohs(cmd->timeout);
+
+ FD_ZERO(&fds);
+ cmd->data[datalen] = 0;
+ switch(type) {
+ case EAD_CMD_NORMAL:
+ if (pipe(pfd) < 0)
+ return false;
+
+ fcntl(pfd[0], F_SETFL, O_NONBLOCK | fcntl(pfd[0], F_GETFL));
+ child_pending = true;
+ pid = fork();
+ if (pid == 0) {
+ close(pfd[0]);
+ fd = open("/dev/null", O_RDWR);
+ if (fd > 0) {
+ dup2(fd, 0);
+ dup2(pfd[1], 1);
+ dup2(pfd[1], 2);
+ }
+ system((char *)cmd->data);
+ exit(0);
+ } else if (pid > 0) {
+ close(pfd[1]);
+ if (!timeout)
+ timeout = EAD_CMD_TIMEOUT;
+
+ stream = true;
+ break;
+ }
+ return false;
+ case EAD_CMD_BACKGROUND:
+ pid = fork();
+ if (pid == 0) {
+ /* close stdin, stdout, stderr, replace with fd to /dev/null */
+ fd = open("/dev/null", O_RDWR);
+ if (fd > 0) {
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ }
+ system((char *)cmd->data);
+ exit(0);
+ } else if (pid > 0) {
+ break;
+ }
+ return false;
+ default:
+ return false;
+ }
+
+ msg = &pktbuf->msg;
+ cmddata = EAD_ENC_DATA(msg, cmd_data);
+
+ if (stream) {
+ int nfds, bytes;
+
+ /* send keepalive packets every 200 ms so that the client doesn't timeout */
+ gettimeofday(&to, NULL);
+ memcpy(&tn, &to, sizeof(tn));
+ tv.tv_usec = PCAP_TIMEOUT * 1000;
+ tv.tv_sec = 0;
+ do {
+ cmddata->done = 0;
+ FD_SET(pfd[0], &fds);
+ nfds = select(pfd[0] + 1, &fds, NULL, NULL, &tv);
+ bytes = 0;
+ if (nfds > 0) {
+ bytes = read(pfd[0], cmddata->data, 1024);
+ if (bytes < 0)
+ bytes = 0;
+ }
+ if (!bytes && !child_pending)
+ break;
+ DEBUG(3, "Sending %d bytes of console data, type=%d, timeout=%d\n", bytes, ntohl(msg->type), timeout);
+ ead_encrypt_message(msg, sizeof(struct ead_msg_cmd_data) + bytes);
+ ead_send_packet_clone(pkt);
+ gettimeofday(&tn, NULL);
+ } while (tn.tv_sec < to.tv_sec + timeout);
+ if (child_pending) {
+ kill(pid, SIGKILL);
+ return false;
+ }
+ }
+ cmddata->done = 1;
+ ead_encrypt_message(msg, sizeof(struct ead_msg_cmd_data));
+
+ return true;
+}
+
+
+
+static void
+parse_message(struct ead_packet *pkt, int len)
+{
+ bool (*handler)(struct ead_packet *pkt, int len, int *nstate);
+ int min_len = sizeof(struct ead_packet);
+ int nstate = state;
+ int type = ntohl(pkt->msg.type);
+
+ if ((type >= EAD_TYPE_GET_PRIME) &&
+ (state != type))
+ return;
+
+ if ((type != EAD_TYPE_PING) &&
+ ((ntohs(pkt->msg.sid) & EAD_INSTANCE_MASK) >>
+ EAD_INSTANCE_SHIFT) != instance->id)
+ return;
+
+ switch(type) {
+ case EAD_TYPE_PING:
+ handler = handle_ping;
+ break;
+ case EAD_TYPE_SET_USERNAME:
+ handler = handle_set_username;
+ min_len += sizeof(struct ead_msg_user);
+ break;
+ case EAD_TYPE_GET_PRIME:
+ handler = handle_get_prime;
+ break;
+ case EAD_TYPE_SEND_A:
+ handler = handle_send_a;
+ min_len += sizeof(struct ead_msg_number);
+ break;
+ case EAD_TYPE_SEND_AUTH:
+ handler = handle_send_auth;
+ min_len += sizeof(struct ead_msg_auth);
+ break;
+ case EAD_TYPE_SEND_CMD:
+ handler = handle_send_cmd;
+ min_len += sizeof(struct ead_msg_cmd) + sizeof(struct ead_msg_encrypted);
+ break;
+ default:
+ return;
+ }
+
+ if (len < min_len) {
+ DEBUG(2, "discarding packet: message too small\n");
+ return;
+ }
+
+ pktbuf->msg.magic = htonl(EAD_MAGIC);
+ pktbuf->msg.type = htonl(type + 1);
+ pktbuf->msg.nid = htons(nid);
+ pktbuf->msg.sid = pkt->msg.sid;
+ pktbuf->msg.len = 0;
+
+ if (handler(pkt, len, &nstate)) {
+ DEBUG(2, "sending response to packet type %d: %d\n", type + 1, ntohl(pktbuf->msg.len));
+ /* format response packet */
+ ead_send_packet_clone(pkt);
+ }
+ set_state(nstate);
+}
+
+static void
+handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
+{
+ struct ead_packet *pkt = (struct ead_packet *) bytes;
+
+ if (h->len < sizeof(struct ead_packet))
+ return;
+
+ if (pkt->eh.ether_type != htons(ETHERTYPE_IP))
+ return;
+
+ if (memcmp(pkt->eh.ether_dhost, "\xff\xff\xff\xff\xff\xff", 6) != 0)
+ return;
+
+ if (pkt->proto != UIP_PROTO_UDP)
+ return;
+
+ if (pkt->destport != htons(EAD_PORT))
+ return;
+
+ if (pkt->msg.magic != htonl(EAD_MAGIC))
+ return;
+
+ if (h->len < sizeof(struct ead_packet) + ntohl(pkt->msg.len))
+ return;
+
+ if ((pkt->msg.nid != 0xffff) &&
+ (pkt->msg.nid != htons(nid)))
+ return;
+
+ parse_message(pkt, h->len);
+}
+
+static void
+ead_pcap_reopen(bool first)
+{
+ static char errbuf[PCAP_ERRBUF_SIZE] = "";
+
+ if (pcap_fp_rx && (pcap_fp_rx != pcap_fp))
+ pcap_close(pcap_fp_rx);
+
+ if (pcap_fp)
+ pcap_close(pcap_fp);
+
+ pcap_fp_rx = NULL;
+ do {
+ if (instance->bridge[0]) {
+ pcap_fp_rx = ead_open_pcap(instance->bridge, errbuf, 1);
+ pcap_fp = ead_open_pcap(instance->ifname, errbuf, 0);
+ } else {
+ pcap_fp = ead_open_pcap(instance->ifname, errbuf, 1);
+ }
+
+ if (!pcap_fp_rx)
+ pcap_fp_rx = pcap_fp;
+ if (first && !pcap_fp) {
+ DEBUG(1, "WARNING: unable to open interface '%s'\n", instance->ifname);
+ first = false;
+ }
+ if (!pcap_fp)
+ sleep(1);
+ } while (!pcap_fp);
+ pcap_setfilter(pcap_fp_rx, &pktfilter);
+}
+
+
+static void
+ead_pktloop(void)
+{
+ while (1) {
+ if (pcap_dispatch(pcap_fp_rx, 1, handle_packet, NULL) < 0) {
+ ead_pcap_reopen(false);
+ continue;
+ }
+ }
+}
+
+
+static int
+usage(const char *prog)
+{
+ fprintf(stderr, "Usage: %s [<options>]\n"
+ "Options:\n"
+ "\t-B Run in background mode\n"
+ "\t-d <device> Set the device to listen on\n"
+ "\t-D <name> Set the name of the device visible to clients\n"
+ "\t-p <file> Set the password file for authenticating\n"
+ "\t-P <file> Write a pidfile\n"
+ "\n", prog);
+ return -1;
+}
+
+static void
+server_handle_sigchld(int sig)
+{
+ struct ead_instance *in;
+ struct list_head *p;
+ int pid = 0;
+ wait(&pid);
+
+ list_for_each(p, &instances) {
+ in = list_entry(p, struct ead_instance, list);
+ if (pid != in->pid)
+ continue;
+
+ in->pid = 0;
+ break;
+ }
+}
+
+static void
+instance_handle_sigchld(int sig)
+{
+ int pid = 0;
+ wait(&pid);
+ child_pending = false;
+}
+
+static void
+start_server(struct ead_instance *i)
+{
+ if (!nonfork) {
+ i->pid = fork();
+ if (i->pid != 0) {
+ if (i->pid < 0)
+ i->pid = 0;
+ return;
+ }
+ }
+
+ instance = i;
+ signal(SIGCHLD, instance_handle_sigchld);
+ ead_pcap_reopen(true);
+ ead_pktloop();
+ pcap_close(pcap_fp);
+ if (pcap_fp_rx != pcap_fp)
+ pcap_close(pcap_fp_rx);
+
+ exit(0);
+}
+
+
+static void
+start_servers(bool restart)
+{
+ struct ead_instance *in;
+ struct list_head *p;
+
+ list_for_each(p, &instances) {
+ in = list_entry(p, struct ead_instance, list);
+ if (in->pid > 0)
+ continue;
+
+ sleep(1);
+ start_server(in);
+ }
+}
+
+static void
+stop_server(struct ead_instance *in, bool do_free)
+{
+ if (in->pid > 0)
+ kill(in->pid, SIGKILL);
+ in->pid = 0;
+ if (do_free) {
+ list_del(&in->list);
+ free(in);
+ }
+}
+
+static void
+server_handle_sigint(int sig)
+{
+ struct ead_instance *in;
+ struct list_head *p, *tmp;
+
+ list_for_each_safe(p, tmp, &instances) {
+ in = list_entry(p, struct ead_instance, list);
+ stop_server(in, true);
+ }
+ exit(1);
+}
+
+static int
+check_bridge_port(const char *br, const char *port, void *arg)
+{
+ struct ead_instance *in;
+ struct list_head *p;
+
+ list_for_each(p, &instances) {
+ in = list_entry(p, struct ead_instance, list);
+
+ if (strcmp(in->ifname, port) != 0)
+ continue;
+
+ in->br_check = true;
+ if (strcmp(in->bridge, br) == 0)
+ break;
+
+ strncpy(in->bridge, br, sizeof(in->bridge));
+ DEBUG(2, "assigning port %s to bridge %s\n", in->ifname, in->bridge);
+ stop_server(in, false);
+ }
+ return 0;
+}
+
+static int
+check_bridge(const char *name, void *arg)
+{
+ br_foreach_port(name, check_bridge_port, arg);
+ return 0;
+}
+
+static void
+check_all_interfaces(void)
+{
+ struct ead_instance *in;
+ struct list_head *p;
+
+ br_foreach_bridge(check_bridge, NULL);
+
+ /* look for interfaces that are no longer part of a bridge */
+ list_for_each(p, &instances) {
+ in = list_entry(p, struct ead_instance, list);
+
+ if (in->br_check) {
+ in->br_check = false;
+ } else if (in->bridge[0]) {
+ DEBUG(2, "removing port %s from bridge %s\n", in->ifname, in->bridge);
+ in->bridge[0] = 0;
+ stop_server(in, false);
+ }
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ struct ead_instance *in;
+ struct timeval tv;
+ const char *pidfile = NULL;
+ bool background = false;
+ int n_iface = 0;
+ int fd, ch;
+
+ if (argc == 1)
+ return usage(argv[0]);
+
+ INIT_LIST_HEAD(&instances);
+ while ((ch = getopt(argc, argv, "Bd:D:fhp:P:")) != -1) {
+ switch(ch) {
+ case 'B':
+ background = true;
+ break;
+ case 'f':
+ nonfork = true;
+ break;
+ case 'h':
+ return usage(argv[0]);
+ case 'd':
+ in = malloc(sizeof(struct ead_instance));
+ memset(in, 0, sizeof(struct ead_instance));
+ INIT_LIST_HEAD(&in->list);
+ strncpy(in->ifname, optarg, sizeof(in->ifname) - 1);
+ list_add(&in->list, &instances);
+ in->id = n_iface++;
+ break;
+ case 'D':
+ dev_name = optarg;
+ break;
+ case 'p':
+ passwd_file = optarg;
+ break;
+ case 'P':
+ pidfile = optarg;
+ break;
+ }
+ }
+ signal(SIGCHLD, server_handle_sigchld);
+ signal(SIGINT, server_handle_sigint);
+ signal(SIGTERM, server_handle_sigint);
+ signal(SIGKILL, server_handle_sigint);
+
+ if (!n_iface) {
+ fprintf(stderr, "Error: ead needs at least one interface\n");
+ return -1;
+ }
+
+ if (background) {
+ if (fork() > 0)
+ exit(0);
+
+ fd = open("/dev/null", O_RDWR);
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ }
+
+ if (pidfile) {
+ char pid[8];
+ int len;
+
+ unlink(pidfile);
+ fd = open(pidfile, O_CREAT|O_WRONLY|O_EXCL, 0644);
+ if (fd > 0) {
+ len = sprintf(pid, "%d\n", getpid());
+ write(fd, pid, len);
+ close(fd);
+ }
+ }
+
+ /* randomize the mac address */
+ get_random_bytes(ethmac + 3, 3);
+ nid = *(((u16_t *) ethmac) + 2);
+
+ start_servers(false);
+ br_init();
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ while (1) {
+ check_all_interfaces();
+ start_servers(true);
+ sleep(1);
+ }
+ br_shutdown();
+
+ return 0;
+}
diff --git a/package/network/services/ead/src/ead.h b/package/network/services/ead/src/ead.h
new file mode 100644
index 0000000..54505ce
--- /dev/null
+++ b/package/network/services/ead/src/ead.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * 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.
+ */
+
+#ifndef __EAD_H
+#define __EAD_H
+
+#define EAD_DEBUGLEVEL 1
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifndef MAXSALTLEN
+#define MAXSALTLEN 32
+#endif
+
+#define EAD_PORT 56026UL
+#define EAD_MAGIC 3671771902UL
+#define EAD_CMD_TIMEOUT 10
+
+#define EAD_MAX_IV_INCR 128
+
+/* request/response types */
+/* response id == request id + 1 */
+enum ead_type {
+ EAD_TYPE_PING,
+ EAD_TYPE_PONG,
+
+ EAD_TYPE_SET_USERNAME,
+ EAD_TYPE_ACK_USERNAME,
+
+ EAD_TYPE_GET_PRIME,
+ EAD_TYPE_PRIME,
+
+ EAD_TYPE_SEND_A,
+ EAD_TYPE_SEND_B,
+
+ EAD_TYPE_SEND_AUTH,
+ EAD_TYPE_DONE_AUTH,
+
+ EAD_TYPE_SEND_CMD,
+ EAD_TYPE_RESULT_CMD,
+
+ EAD_TYPE_LAST
+};
+
+enum ead_auth_type {
+ EAD_AUTH_DEFAULT,
+ EAD_AUTH_MD5
+};
+
+enum ead_cmd_type {
+ EAD_CMD_NORMAL,
+ EAD_CMD_BACKGROUND,
+ EAD_CMD_LAST
+};
+
+struct ead_msg_pong {
+ uint16_t auth_type;
+ char name[];
+} __attribute__((packed));
+
+struct ead_msg_number {
+ uint8_t id;
+ unsigned char data[];
+} __attribute__((packed));
+
+struct ead_msg_salt {
+ uint8_t prime;
+ uint8_t len;
+ unsigned char salt[MAXSALTLEN];
+ unsigned char ext_salt[MAXSALTLEN];
+} __attribute__((packed));
+
+struct ead_msg_user {
+ char username[32];
+} __attribute__((packed));
+
+struct ead_msg_auth {
+ unsigned char data[20];
+} __attribute__((packed));
+
+struct ead_msg_cmd {
+ uint8_t type;
+ uint16_t timeout;
+ unsigned char data[];
+} __attribute__((packed));
+
+struct ead_msg_cmd_data {
+ uint8_t done;
+ unsigned char data[];
+} __attribute__((packed));
+
+struct ead_msg_encrypted {
+ uint32_t hash[5];
+ uint32_t iv;
+ uint8_t pad;
+ union {
+ struct ead_msg_cmd cmd;
+ struct ead_msg_cmd_data cmd_data;
+ } data[];
+} __attribute__((packed));
+
+
+#define EAD_DATA(_msg, _type) (&((_msg)->data[0]._type))
+#define EAD_ENC_DATA(_msg, _type) (&((_msg)->data[0].enc.data[0]._type))
+
+/* for ead_msg::sid */
+#define EAD_INSTANCE_MASK 0xf000
+#define EAD_INSTANCE_SHIFT 12
+
+struct ead_msg {
+ uint32_t magic;
+ uint32_t len;
+ uint32_t type;
+ uint16_t nid; /* node id */
+ uint16_t sid; /* session id */
+ uint32_t ip; /* source ip for responses from the server */
+ union {
+ struct ead_msg_pong pong;
+ struct ead_msg_user user;
+ struct ead_msg_number number;
+ struct ead_msg_auth auth;
+ struct ead_msg_salt salt;
+ struct ead_msg_encrypted enc;
+ } data[];
+} __attribute__((packed));
+
+
+#endif
diff --git a/package/network/services/ead/src/filter.c b/package/network/services/ead/src/filter.c
new file mode 100644
index 0000000..0759dc3
--- /dev/null
+++ b/package/network/services/ead/src/filter.c
@@ -0,0 +1,25 @@
+/* precompiled expression: udp and dst port 56026 */
+
+static struct bpf_insn pktfilter_insns[] = {
+ { .code = 0x0028, .jt = 0x00, .jf = 0x00, .k = 0x0000000c },
+ { .code = 0x0015, .jt = 0x00, .jf = 0x04, .k = 0x000086dd },
+ { .code = 0x0030, .jt = 0x00, .jf = 0x00, .k = 0x00000014 },
+ { .code = 0x0015, .jt = 0x00, .jf = 0x0b, .k = 0x00000011 },
+ { .code = 0x0028, .jt = 0x00, .jf = 0x00, .k = 0x00000038 },
+ { .code = 0x0015, .jt = 0x08, .jf = 0x09, .k = 0x0000dada },
+ { .code = 0x0015, .jt = 0x00, .jf = 0x08, .k = 0x00000800 },
+ { .code = 0x0030, .jt = 0x00, .jf = 0x00, .k = 0x00000017 },
+ { .code = 0x0015, .jt = 0x00, .jf = 0x06, .k = 0x00000011 },
+ { .code = 0x0028, .jt = 0x00, .jf = 0x00, .k = 0x00000014 },
+ { .code = 0x0045, .jt = 0x04, .jf = 0x00, .k = 0x00001fff },
+ { .code = 0x00b1, .jt = 0x00, .jf = 0x00, .k = 0x0000000e },
+ { .code = 0x0048, .jt = 0x00, .jf = 0x00, .k = 0x00000010 },
+ { .code = 0x0015, .jt = 0x00, .jf = 0x01, .k = 0x0000dada },
+ { .code = 0x0006, .jt = 0x00, .jf = 0x00, .k = 0x000005dc },
+ { .code = 0x0006, .jt = 0x00, .jf = 0x00, .k = 0x00000000 },
+};
+
+static struct bpf_program pktfilter = {
+ .bf_len = 16,
+ .bf_insns = pktfilter_insns,
+};
diff --git a/package/network/services/ead/src/libbridge.h b/package/network/services/ead/src/libbridge.h
new file mode 100644
index 0000000..d7bbdc4
--- /dev/null
+++ b/package/network/services/ead/src/libbridge.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2000 Lennert Buytenhek
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LIBBRIDGE_H
+#define _LIBBRIDGE_H
+
+#ifdef linux
+
+int br_init(void);
+void br_shutdown(void);
+
+int br_foreach_port(const char *brname,
+ int (*iterator)(const char *br, const char *port, void *arg),
+ void *arg);
+
+int br_foreach_bridge(int (*iterator)(const char *, void *), void *arg);
+
+#else
+
+static inline int br_init(void)
+{
+ return 0;
+}
+
+static inline void br_shutdown(void)
+{
+}
+
+static inline int
+br_foreach_port(const char *brname,
+ int (*iterator)(const char *br, const char *port, void *arg),
+ void *arg)
+{
+ return 0;
+}
+
+static inline int
+br_foreach_bridge(int (*iterator)(const char *, void *), void *arg)
+{
+ return 0;
+}
+
+#endif
+
+#endif
diff --git a/package/network/services/ead/src/libbridge_init.c b/package/network/services/ead/src/libbridge_init.c
new file mode 100644
index 0000000..687ef62
--- /dev/null
+++ b/package/network/services/ead/src/libbridge_init.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2000 Lennert Buytenhek
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef linux
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <linux/if.h>
+#include <linux/in6.h>
+#include <linux/if_bridge.h>
+
+#include "libbridge.h"
+#include "libbridge_private.h"
+
+static int br_socket_fd = -1;
+
+int br_init(void)
+{
+ if ((br_socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
+ return errno;
+ return 0;
+}
+
+void br_shutdown(void)
+{
+ close(br_socket_fd);
+ br_socket_fd = -1;
+}
+
+/* If /sys/class/net/XXX/bridge exists then it must be a bridge */
+static int isbridge(const struct dirent *entry)
+{
+ char path[SYSFS_PATH_MAX];
+ struct stat st;
+
+ snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/bridge", entry->d_name);
+ return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
+}
+
+/*
+ * New interface uses sysfs to find bridges
+ */
+static int new_foreach_bridge(int (*iterator)(const char *name, void *),
+ void *arg)
+{
+ struct dirent **namelist;
+ int i, count = 0;
+
+ count = scandir(SYSFS_CLASS_NET, &namelist, isbridge, alphasort);
+ if (count < 0)
+ return -1;
+
+ for (i = 0; i < count; i++) {
+ if (iterator(namelist[i]->d_name, arg))
+ break;
+ }
+
+ for (i = 0; i < count; i++)
+ free(namelist[i]);
+ free(namelist);
+
+ return count;
+}
+
+/*
+ * Go over all bridges and call iterator function.
+ * if iterator returns non-zero then stop.
+ */
+int br_foreach_bridge(int (*iterator)(const char *, void *), void *arg)
+{
+ return new_foreach_bridge(iterator, arg);
+}
+
+/*
+ * Iterate over all ports in bridge (using sysfs).
+ */
+int br_foreach_port(const char *brname,
+ int (*iterator)(const char *br, const char *port, void *arg),
+ void *arg)
+{
+ int i, count;
+ struct dirent **namelist;
+ char path[SYSFS_PATH_MAX];
+
+ snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/brif", brname);
+ count = scandir(path, &namelist, 0, alphasort);
+
+ for (i = 0; i < count; i++) {
+ if (namelist[i]->d_name[0] == '.'
+ && (namelist[i]->d_name[1] == '\0'
+ || (namelist[i]->d_name[1] == '.'
+ && namelist[i]->d_name[2] == '\0')))
+ continue;
+
+ if (iterator(brname, namelist[i]->d_name, arg))
+ break;
+ }
+ for (i = 0; i < count; i++)
+ free(namelist[i]);
+ free(namelist);
+
+ return count;
+}
+
+#endif
diff --git a/package/network/services/ead/src/libbridge_private.h b/package/network/services/ead/src/libbridge_private.h
new file mode 100644
index 0000000..38fd60e
--- /dev/null
+++ b/package/network/services/ead/src/libbridge_private.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2000 Lennert Buytenhek
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LIBBRIDGE_PRIVATE_H
+#define _LIBBRIDGE_PRIVATE_H
+
+#include <linux/sockios.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <linux/if_bridge.h>
+
+#define MAX_BRIDGES 1024
+#define MAX_PORTS 1024
+
+#define SYSFS_CLASS_NET "/sys/class/net/"
+#define SYSFS_PATH_MAX 256
+
+#define dprintf(fmt,arg...)
+
+#endif
diff --git a/package/network/services/ead/src/list.h b/package/network/services/ead/src/list.h
new file mode 100644
index 0000000..ac429c8
--- /dev/null
+++ b/package/network/services/ead/src/list.h
@@ -0,0 +1,602 @@
+/* GPL v2, adapted from the Linux kernel */
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+#include <stddef.h>
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#ifndef container_of
+#define container_of(ptr, type, member) ( \
+ (type *)( (char *)ptr - offsetof(type,member) ))
+#endif
+
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = NULL;
+ entry->prev = NULL;
+}
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old,
+ struct list_head *new)
+{
+ new->next = old->next;
+ new->next->prev = new;
+ new->prev = old->prev;
+ new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+ struct list_head *new)
+{
+ list_replace(old, new);
+ INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+ const struct list_head *head)
+{
+ return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+ struct list_head *next = head->next;
+ return (next == head) && (next == head->prev);
+}
+
+static inline void __list_splice(struct list_head *list,
+ struct list_head *head)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+ struct list_head *at = head->next;
+
+ first->prev = head;
+ head->next = first;
+
+ last->next = at;
+ at->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); \
+ pos = pos->next)
+
+/**
+ * __list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; pos != (head); \
+ pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+ for (pos = (head)->prev, n = pos->prev; \
+ pos != (head); \
+ pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos: the type * to use as a start point
+ * @head: the head of the list
+ * @member: the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+ ((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, head, member) \
+ for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member) \
+ for (; &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member) \
+ for (n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+/*
+ * Double linked lists with a single pointer list head.
+ * Mostly useful for hash tables where the two pointer list head is
+ * too wasteful.
+ * You lose the ability to access the tail in O(1).
+ */
+
+struct hlist_head {
+ struct hlist_node *first;
+};
+
+struct hlist_node {
+ struct hlist_node *next, **pprev;
+};
+
+#define HLIST_HEAD_INIT { .first = NULL }
+#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
+#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
+static inline void INIT_HLIST_NODE(struct hlist_node *h)
+{
+ h->next = NULL;
+ h->pprev = NULL;
+}
+
+static inline int hlist_unhashed(const struct hlist_node *h)
+{
+ return !h->pprev;
+}
+
+static inline int hlist_empty(const struct hlist_head *h)
+{
+ return !h->first;
+}
+
+static inline void __hlist_del(struct hlist_node *n)
+{
+ struct hlist_node *next = n->next;
+ struct hlist_node **pprev = n->pprev;
+ *pprev = next;
+ if (next)
+ next->pprev = pprev;
+}
+
+static inline void hlist_del(struct hlist_node *n)
+{
+ __hlist_del(n);
+ n->next = NULL;
+ n->pprev = NULL;
+}
+
+static inline void hlist_del_init(struct hlist_node *n)
+{
+ if (!hlist_unhashed(n)) {
+ __hlist_del(n);
+ INIT_HLIST_NODE(n);
+ }
+}
+
+
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+ struct hlist_node *first = h->first;
+ n->next = first;
+ if (first)
+ first->pprev = &n->next;
+ h->first = n;
+ n->pprev = &h->first;
+}
+
+
+/* next must be != NULL */
+static inline void hlist_add_before(struct hlist_node *n,
+ struct hlist_node *next)
+{
+ n->pprev = next->pprev;
+ n->next = next;
+ next->pprev = &n->next;
+ *(n->pprev) = n;
+}
+
+static inline void hlist_add_after(struct hlist_node *n,
+ struct hlist_node *next)
+{
+ next->next = n->next;
+ n->next = next;
+ next->pprev = &n->next;
+
+ if(next->next)
+ next->next->pprev = &next->next;
+}
+
+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+
+#define hlist_for_each(pos, head) \
+ for (pos = (head)->first; pos; pos = pos->next)
+
+#define hlist_for_each_safe(pos, n, head) \
+ for (pos = (head)->first; pos; pos = n)
+
+/**
+ * hlist_for_each_entry - iterate over list of given type
+ * @tpos: the type * to use as a loop cursor.
+ * @pos: the &struct hlist_node to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry(tpos, pos, head, member) \
+ for (pos = (head)->first; pos && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
+ * @tpos: the type * to use as a loop cursor.
+ * @pos: the &struct hlist_node to use as a loop cursor.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_continue(tpos, pos, member) \
+ for (pos = (pos)->next; pos && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_for_each_entry_from - iterate over a hlist continuing from current point
+ * @tpos: the type * to use as a loop cursor.
+ * @pos: the &struct hlist_node to use as a loop cursor.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_from(tpos, pos, member) \
+ for (; pos && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @tpos: the type * to use as a loop cursor.
+ * @pos: the &struct hlist_node to use as a loop cursor.
+ * @n: another &struct hlist_node to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
+ for (pos = (head)->first; \
+ pos && ({ n = pos->next; 1; }) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = n)
+
+#endif
diff --git a/package/network/services/ead/src/passwd b/package/network/services/ead/src/passwd
new file mode 100644
index 0000000..eee7a89
--- /dev/null
+++ b/package/network/services/ead/src/passwd
@@ -0,0 +1,3 @@
+root:$1$MCGAgYw.$Ip1GcyeUliId3wzVcKR/e/:0:0:root:/root:/bin/ash
+nobody:*:65534:65534:nobody:/var:/bin/false
+daemon:*:65534:65534:daemon:/var:/bin/false
diff --git a/package/network/services/ead/src/pfc.c b/package/network/services/ead/src/pfc.c
new file mode 100644
index 0000000..402e37f
--- /dev/null
+++ b/package/network/services/ead/src/pfc.c
@@ -0,0 +1,54 @@
+/*
+ * Small pcap precompiler
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * 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.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pcap.h>
+
+int main (int argc, char ** argv)
+{
+ struct bpf_program filter;
+ pcap_t *pc;
+ int i;
+
+ if (argc != 2)
+ {
+ printf ("Usage: %s <expression>\n", argv[0]);
+ return 1;
+ }
+
+ pc = pcap_open_dead(DLT_EN10MB, 1500);
+ if (pcap_compile(pc, &filter, argv[1], 1, 0) != 0) {
+ printf("error in active-filter expression: %s\n", pcap_geterr(pc));
+ return 1;
+ }
+
+ printf("/* precompiled expression: %s */\n\n"
+ "static struct bpf_insn pktfilter_insns[] = {\n",
+ argv[1]);
+
+ for (i = 0; i < filter.bf_len; i++) {
+ struct bpf_insn *in = &filter.bf_insns[i];
+ printf("\t{ .code = 0x%04x, .jt = 0x%02x, .jf = 0x%02x, .k = 0x%08x },\n", in->code, in->jt, in->jf, in->k);
+ }
+ printf("};\n\n"
+ "static struct bpf_program pktfilter = {\n"
+ "\t.bf_len = %d,\n"
+ "\t.bf_insns = pktfilter_insns,\n"
+ "};\n", filter.bf_len);
+ return 0;
+
+}
diff --git a/package/network/services/ead/src/pw_encrypt_md5.c b/package/network/services/ead/src/pw_encrypt_md5.c
new file mode 100644
index 0000000..bc9f249
--- /dev/null
+++ b/package/network/services/ead/src/pw_encrypt_md5.c
@@ -0,0 +1,646 @@
+/*
+ * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ *
+ * $FreeBSD: src/lib/libmd/md5c.c,v 1.9.2.1 1999/08/29 14:57:12 peter Exp $
+ *
+ * This code is the same as the code published by RSA Inc. It has been
+ * edited for clarity and style only.
+ *
+ * ----------------------------------------------------------------------------
+ * The md5_crypt() function was taken from freeBSD's libcrypt and contains
+ * this license:
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ *
+ * $FreeBSD: src/lib/libcrypt/crypt.c,v 1.7.2.1 1999/08/29 14:56:33 peter Exp $
+ *
+ * ----------------------------------------------------------------------------
+ * On April 19th, 2001 md5_crypt() was modified to make it reentrant
+ * by Erik Andersen <andersen@uclibc.org>
+ *
+ *
+ * June 28, 2001 Manuel Novoa III
+ *
+ * "Un-inlined" code using loops and static const tables in order to
+ * reduce generated code size (on i386 from approx 4k to approx 2.5k).
+ *
+ * June 29, 2001 Manuel Novoa III
+ *
+ * Completely removed static PADDING array.
+ *
+ * Reintroduced the loop unrolling in MD5_Transform and added the
+ * MD5_SIZE_OVER_SPEED option for configurability. Define below as:
+ * 0 fully unrolled loops
+ * 1 partially unrolled (4 ops per loop)
+ * 2 no unrolling -- introduces the need to swap 4 variables (slow)
+ * 3 no unrolling and all 4 loops merged into one with switch
+ * in each loop (glacial)
+ * On i386, sizes are roughly (-Os -fno-builtin):
+ * 0: 3k 1: 2.5k 2: 2.2k 3: 2k
+ *
+ *
+ * Since SuSv3 does not require crypt_r, modified again August 7, 2002
+ * by Erik Andersen to remove reentrance stuff...
+ */
+
+static const uint8_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+/*
+ * Valid values are 1 (fastest/largest) to 3 (smallest/slowest).
+ */
+#define MD5_SIZE_OVER_SPEED 3
+
+/**********************************************************************/
+
+/* MD5 context. */
+struct MD5Context {
+ uint32_t state[4]; /* state (ABCD) */
+ uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+};
+
+static void __md5_Init(struct MD5Context *);
+static void __md5_Update(struct MD5Context *, const unsigned char *, unsigned int);
+static void __md5_Pad(struct MD5Context *);
+static void __md5_Final(unsigned char [16], struct MD5Context *);
+static void __md5_Transform(uint32_t [4], const unsigned char [64]);
+
+
+#define MD5_MAGIC_STR "$1$"
+#define MD5_MAGIC_LEN (sizeof(MD5_MAGIC_STR) - 1)
+static const unsigned char __md5__magic[] = MD5_MAGIC_STR;
+
+
+#ifdef i386
+#define __md5_Encode memcpy
+#define __md5_Decode memcpy
+#else /* i386 */
+
+/*
+ * __md5_Encodes input (uint32_t) into output (unsigned char). Assumes len is
+ * a multiple of 4.
+ */
+static void
+__md5_Encode(unsigned char *output, uint32_t *input, unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = input[i];
+ output[j+1] = (input[i] >> 8);
+ output[j+2] = (input[i] >> 16);
+ output[j+3] = (input[i] >> 24);
+ }
+}
+
+/*
+ * __md5_Decodes input (unsigned char) into output (uint32_t). Assumes len is
+ * a multiple of 4.
+ */
+static void
+__md5_Decode(uint32_t *output, const unsigned char *input, unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
+ (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
+}
+#endif /* i386 */
+
+/* F, G, H and I are basic MD5 functions. */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+
+/* ROTATE_LEFT rotates x left n bits. */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/*
+ * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ * Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+ (a) = ROTATE_LEFT((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+ (a) = ROTATE_LEFT((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+ (a) = ROTATE_LEFT((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+ (a) = ROTATE_LEFT((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context. */
+static void __md5_Init(struct MD5Context *context)
+{
+ context->count[0] = context->count[1] = 0;
+
+ /* Load magic initialization constants. */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/*
+ * MD5 block update operation. Continues an MD5 message-digest
+ * operation, processing another message block, and updating the
+ * context.
+ */
+static void __md5_Update(struct MD5Context *context, const unsigned char *input, unsigned int inputLen)
+{
+ unsigned int i, idx, partLen;
+
+ /* Compute number of bytes mod 64 */
+ idx = (context->count[0] >> 3) & 0x3F;
+
+ /* Update number of bits */
+ context->count[0] += (inputLen << 3);
+ if (context->count[0] < (inputLen << 3))
+ context->count[1]++;
+ context->count[1] += (inputLen >> 29);
+
+ partLen = 64 - idx;
+
+ /* Transform as many times as possible. */
+ if (inputLen >= partLen) {
+ memcpy(&context->buffer[idx], input, partLen);
+ __md5_Transform(context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ __md5_Transform(context->state, &input[i]);
+
+ idx = 0;
+ } else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy(&context->buffer[idx], &input[i], inputLen - i);
+}
+
+/*
+ * MD5 padding. Adds padding followed by original length.
+ */
+static void __md5_Pad(struct MD5Context *context)
+{
+ unsigned char bits[8];
+ unsigned int idx, padLen;
+ unsigned char PADDING[64];
+
+ memset(PADDING, 0, sizeof(PADDING));
+ PADDING[0] = 0x80;
+
+ /* Save number of bits */
+ __md5_Encode(bits, context->count, 8);
+
+ /* Pad out to 56 mod 64. */
+ idx = (context->count[0] >> 3) & 0x3f;
+ padLen = (idx < 56) ? (56 - idx) : (120 - idx);
+ __md5_Update(context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ __md5_Update(context, bits, 8);
+}
+
+/*
+ * MD5 finalization. Ends an MD5 message-digest operation, writing the
+ * the message digest and zeroizing the context.
+ */
+static void __md5_Final(unsigned char digest[16], struct MD5Context *context)
+{
+ /* Do padding. */
+ __md5_Pad(context);
+
+ /* Store state in digest */
+ __md5_Encode(digest, context->state, 16);
+
+ /* Zeroize sensitive information. */
+ memset(context, 0, sizeof(*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+static void __md5_Transform(uint32_t state[4], const unsigned char block[64])
+{
+ uint32_t a, b, c, d, x[16];
+#if MD5_SIZE_OVER_SPEED > 1
+ uint32_t temp;
+ const unsigned char *ps;
+
+ static const unsigned char S[] = {
+ 7, 12, 17, 22,
+ 5, 9, 14, 20,
+ 4, 11, 16, 23,
+ 6, 10, 15, 21
+ };
+#endif /* MD5_SIZE_OVER_SPEED > 1 */
+
+#if MD5_SIZE_OVER_SPEED > 0
+ const uint32_t *pc;
+ const unsigned char *pp;
+ int i;
+
+ static const uint32_t C[] = {
+ /* round 1 */
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+ /* round 2 */
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+ 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+ /* round 3 */
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+ /* round 4 */
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+ };
+
+ static const unsigned char P[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
+ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
+ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
+ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */
+ };
+
+#endif /* MD5_SIZE_OVER_SPEED > 0 */
+
+ __md5_Decode(x, block, 64);
+
+ a = state[0]; b = state[1]; c = state[2]; d = state[3];
+
+#if MD5_SIZE_OVER_SPEED > 2
+ pc = C; pp = P; ps = S - 4;
+
+ for (i = 0; i < 64; i++) {
+ if ((i & 0x0f) == 0) ps += 4;
+ temp = a;
+ switch (i>>4) {
+ case 0:
+ temp += F(b, c, d);
+ break;
+ case 1:
+ temp += G(b, c, d);
+ break;
+ case 2:
+ temp += H(b, c, d);
+ break;
+ case 3:
+ temp += I(b, c, d);
+ break;
+ }
+ temp += x[*pp++] + *pc++;
+ temp = ROTATE_LEFT(temp, ps[i & 3]);
+ temp += b;
+ a = d; d = c; c = b; b = temp;
+ }
+#elif MD5_SIZE_OVER_SPEED > 1
+ pc = C; pp = P; ps = S;
+
+ /* Round 1 */
+ for (i = 0; i < 16; i++) {
+ FF(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
+ temp = d; d = c; c = b; b = a; a = temp;
+ }
+
+ /* Round 2 */
+ ps += 4;
+ for (; i < 32; i++) {
+ GG(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
+ temp = d; d = c; c = b; b = a; a = temp;
+ }
+ /* Round 3 */
+ ps += 4;
+ for (; i < 48; i++) {
+ HH(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
+ temp = d; d = c; c = b; b = a; a = temp;
+ }
+
+ /* Round 4 */
+ ps += 4;
+ for (; i < 64; i++) {
+ II(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++;
+ temp = d; d = c; c = b; b = a; a = temp;
+ }
+#elif MD5_SIZE_OVER_SPEED > 0
+ pc = C; pp = P;
+
+ /* Round 1 */
+ for (i = 0; i < 4; i++) {
+ FF(a, b, c, d, x[*pp], 7, *pc); pp++; pc++;
+ FF(d, a, b, c, x[*pp], 12, *pc); pp++; pc++;
+ FF(c, d, a, b, x[*pp], 17, *pc); pp++; pc++;
+ FF(b, c, d, a, x[*pp], 22, *pc); pp++; pc++;
+ }
+
+ /* Round 2 */
+ for (i = 0; i < 4; i++) {
+ GG(a, b, c, d, x[*pp], 5, *pc); pp++; pc++;
+ GG(d, a, b, c, x[*pp], 9, *pc); pp++; pc++;
+ GG(c, d, a, b, x[*pp], 14, *pc); pp++; pc++;
+ GG(b, c, d, a, x[*pp], 20, *pc); pp++; pc++;
+ }
+ /* Round 3 */
+ for (i = 0; i < 4; i++) {
+ HH(a, b, c, d, x[*pp], 4, *pc); pp++; pc++;
+ HH(d, a, b, c, x[*pp], 11, *pc); pp++; pc++;
+ HH(c, d, a, b, x[*pp], 16, *pc); pp++; pc++;
+ HH(b, c, d, a, x[*pp], 23, *pc); pp++; pc++;
+ }
+
+ /* Round 4 */
+ for (i = 0; i < 4; i++) {
+ II(a, b, c, d, x[*pp], 6, *pc); pp++; pc++;
+ II(d, a, b, c, x[*pp], 10, *pc); pp++; pc++;
+ II(c, d, a, b, x[*pp], 15, *pc); pp++; pc++;
+ II(b, c, d, a, x[*pp], 21, *pc); pp++; pc++;
+ }
+#else
+ /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+ FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+ GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+ HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+ II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+#endif
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information. */
+ memset(x, 0, sizeof(x));
+}
+
+
+static char*
+__md5_to64(char *s, unsigned v, int n)
+{
+ while (--n >= 0) {
+ *s++ = ascii64[v & 0x3f];
+ v >>= 6;
+ }
+ return s;
+}
+
+/*
+ * UNIX password
+ *
+ * Use MD5 for what it is best at...
+ */
+#define MD5_OUT_BUFSIZE 36
+static char *
+md5_crypt(char passwd[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned char *salt)
+{
+ const unsigned char *sp, *ep;
+ char *p;
+ unsigned char final[17]; /* final[16] exists only to aid in looping */
+ int sl, pl, i, pw_len;
+ struct MD5Context ctx, ctx1;
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ sp += MD5_MAGIC_LEN;
+
+ /* It stops at the first '$', max 8 chars */
+ for (ep = sp; *ep && *ep != '$' && ep < (sp+8); ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+ __md5_Init(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ pw_len = strlen((char*)pw);
+ __md5_Update(&ctx, pw, pw_len);
+
+ /* Then our magic string */
+ __md5_Update(&ctx, __md5__magic, MD5_MAGIC_LEN);
+
+ /* Then the raw salt */
+ __md5_Update(&ctx, sp, sl);
+
+ /* Then just as many characters of the MD5(pw, salt, pw) */
+ __md5_Init(&ctx1);
+ __md5_Update(&ctx1, pw, pw_len);
+ __md5_Update(&ctx1, sp, sl);
+ __md5_Update(&ctx1, pw, pw_len);
+ __md5_Final(final, &ctx1);
+ for (pl = pw_len; pl > 0; pl -= 16)
+ __md5_Update(&ctx, final, pl > 16 ? 16 : pl);
+
+ /* Don't leave anything around in vm they could use. */
+//TODO: the above comment seems to be wrong. final is used later.
+ memset(final, 0, sizeof(final));
+
+ /* Then something really weird... */
+ for (i = pw_len; i; i >>= 1) {
+ __md5_Update(&ctx, ((i & 1) ? final : (const unsigned char *) pw), 1);
+ }
+
+ /* Now make the output string */
+ passwd[0] = '$';
+ passwd[1] = '1';
+ passwd[2] = '$';
+ strncpy(passwd + 3, (char*)sp, sl);
+ passwd[sl + 3] = '$';
+
+ __md5_Final(final, &ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for (i = 0; i < 1000; i++) {
+ __md5_Init(&ctx1);
+ if (i & 1)
+ __md5_Update(&ctx1, pw, pw_len);
+ else
+ __md5_Update(&ctx1, final, 16);
+
+ if (i % 3)
+ __md5_Update(&ctx1, sp, sl);
+
+ if (i % 7)
+ __md5_Update(&ctx1, pw, pw_len);
+
+ if (i & 1)
+ __md5_Update(&ctx1, final, 16);
+ else
+ __md5_Update(&ctx1, pw, pw_len);
+ __md5_Final(final, &ctx1);
+ }
+
+ p = passwd + sl + 4; /* 12 bytes max (sl is up to 8 bytes) */
+
+ /* Add 5*4+2 = 22 bytes of hash, + NUL byte. */
+ final[16] = final[5];
+ for (i = 0; i < 5; i++) {
+ unsigned l = (final[i] << 16) | (final[i+6] << 8) | final[i+12];
+ p = __md5_to64(p, l, 4);
+ }
+ p = __md5_to64(p, final[11], 2);
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final, 0, sizeof(final));
+
+ return passwd;
+}
+
+#undef MD5_SIZE_OVER_SPEED
+#undef MD5_MAGIC_STR
+#undef MD5_MAGIC_LEN
+#undef __md5_Encode
+#undef __md5_Decode
+#undef F
+#undef G
+#undef H
+#undef I
+#undef ROTATE_LEFT
+#undef FF
+#undef GG
+#undef HH
+#undef II
+#undef S11
+#undef S12
+#undef S13
+#undef S14
+#undef S21
+#undef S22
+#undef S23
+#undef S24
+#undef S31
+#undef S32
+#undef S33
+#undef S34
+#undef S41
+#undef S42
+#undef S43
+#undef S44
diff --git a/package/network/services/ead/src/sha1.c b/package/network/services/ead/src/sha1.c
new file mode 100644
index 0000000..3683a7d
--- /dev/null
+++ b/package/network/services/ead/src/sha1.c
@@ -0,0 +1,104 @@
+/*
+ * SHA transform algorithm, originally taken from code written by
+ * Peter Gutmann, and placed in the public domain.
+ */
+
+static uint32_t
+rol32(uint32_t word, int shift)
+{
+ return (word << shift) | (word >> (32 - shift));
+}
+
+/* The SHA f()-functions. */
+
+#define f1(x,y,z) (z ^ (x & (y ^ z))) /* x ? y : z */
+#define f2(x,y,z) (x ^ y ^ z) /* XOR */
+#define f3(x,y,z) ((x & y) + (z & (x ^ y))) /* majority */
+
+/* The SHA Mysterious Constants */
+
+#define K1 0x5A827999L /* Rounds 0-19: sqrt(2) * 2^30 */
+#define K2 0x6ED9EBA1L /* Rounds 20-39: sqrt(3) * 2^30 */
+#define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */
+#define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */
+
+/**
+ * sha_transform - single block SHA1 transform
+ *
+ * @digest: 160 bit digest to update
+ * @data: 512 bits of data to hash
+ * @W: 80 words of workspace (see note)
+ *
+ * This function generates a SHA1 digest for a single 512-bit block.
+ * Be warned, it does not handle padding and message digest, do not
+ * confuse it with the full FIPS 180-1 digest algorithm for variable
+ * length messages.
+ *
+ * Note: If the hash is security sensitive, the caller should be sure
+ * to clear the workspace. This is left to the caller to avoid
+ * unnecessary clears between chained hashing operations.
+ */
+static void sha_transform(uint32_t *digest, const unsigned char *in, uint32_t *W)
+{
+ uint32_t a, b, c, d, e, t, i;
+
+ for (i = 0; i < 16; i++) {
+ int ofs = 4 * i;
+
+ /* word load/store may be unaligned here, so use bytes instead */
+ W[i] =
+ (in[ofs+0] << 24) |
+ (in[ofs+1] << 16) |
+ (in[ofs+2] << 8) |
+ in[ofs+3];
+ }
+
+ for (i = 0; i < 64; i++)
+ W[i+16] = rol32(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 1);
+
+ a = digest[0];
+ b = digest[1];
+ c = digest[2];
+ d = digest[3];
+ e = digest[4];
+
+ for (i = 0; i < 20; i++) {
+ t = f1(b, c, d) + K1 + rol32(a, 5) + e + W[i];
+ e = d; d = c; c = rol32(b, 30); b = a; a = t;
+ }
+
+ for (; i < 40; i ++) {
+ t = f2(b, c, d) + K2 + rol32(a, 5) + e + W[i];
+ e = d; d = c; c = rol32(b, 30); b = a; a = t;
+ }
+
+ for (; i < 60; i ++) {
+ t = f3(b, c, d) + K3 + rol32(a, 5) + e + W[i];
+ e = d; d = c; c = rol32(b, 30); b = a; a = t;
+ }
+
+ for (; i < 80; i ++) {
+ t = f2(b, c, d) + K4 + rol32(a, 5) + e + W[i];
+ e = d; d = c; c = rol32(b, 30); b = a; a = t;
+ }
+
+ digest[0] += a;
+ digest[1] += b;
+ digest[2] += c;
+ digest[3] += d;
+ digest[4] += e;
+}
+
+/**
+ * sha_init - initialize the vectors for a SHA1 digest
+ * @buf: vector to initialize
+ */
+static void sha_init(uint32_t *buf)
+{
+ buf[0] = 0x67452301;
+ buf[1] = 0xefcdab89;
+ buf[2] = 0x98badcfe;
+ buf[3] = 0x10325476;
+ buf[4] = 0xc3d2e1f0;
+}
+
diff --git a/package/network/services/ead/src/tinysrp/Makefile.am b/package/network/services/ead/src/tinysrp/Makefile.am
new file mode 100644
index 0000000..a8f899f
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/Makefile.am
@@ -0,0 +1,28 @@
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+noinst_HEADERS = t_client.h t_pwd.h t_server.h t_sha.h \
+ bn.h bn_lcl.h bn_prime.h t_defines.h t_read.h
+
+include_HEADERS = tinysrp.h
+
+lib_LIBRARIES = libtinysrp.a
+
+CFLAGS = -O2 @signed@
+
+libtinysrp_a_SOURCES = \
+ tinysrp.c t_client.c t_getconf.c t_conv.c t_getpass.c t_sha.c t_math.c \
+ t_misc.c t_pw.c t_read.c t_server.c t_truerand.c \
+ bn_add.c bn_ctx.c bn_div.c bn_exp.c bn_mul.c bn_word.c bn_asm.c bn_lib.c \
+ bn_shift.c bn_sqr.c
+
+noinst_PROGRAMS = srvtest clitest
+srvtest_SOURCES = srvtest.c
+clitest_SOURCES = clitest.c
+
+bin_PROGRAMS = tconf tphrase
+tconf_SOURCES = tconf.c t_conf.c
+tphrase_SOURCES = tphrase.c
+
+LDADD = libtinysrp.a
+
+EXTRA_DIST = tpasswd Notes
diff --git a/package/network/services/ead/src/tinysrp/Makefile.in b/package/network/services/ead/src/tinysrp/Makefile.in
new file mode 100644
index 0000000..4701cd5
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/Makefile.in
@@ -0,0 +1,477 @@
+# Makefile.in generated automatically by automake 1.4a from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_FLAG =
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+CC = @CC@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+signed = @signed@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+noinst_HEADERS = t_client.h t_pwd.h t_server.h t_sha.h bn.h bn_lcl.h bn_prime.h t_defines.h t_read.h
+
+
+include_HEADERS = tinysrp.h
+
+lib_LIBRARIES = libtinysrp.a
+
+CFLAGS = -O2 @signed@
+
+libtinysrp_a_SOURCES = tinysrp.c t_client.c t_getconf.c t_conv.c t_getpass.c t_sha.c t_math.c t_misc.c t_pw.c t_read.c t_server.c t_truerand.c bn_add.c bn_ctx.c bn_div.c bn_exp.c bn_mul.c bn_word.c bn_asm.c bn_lib.c bn_shift.c bn_sqr.c
+
+
+noinst_PROGRAMS = srvtest clitest
+srvtest_SOURCES = srvtest.c
+clitest_SOURCES = clitest.c
+
+bin_PROGRAMS = tconf tphrase
+tconf_SOURCES = tconf.c t_conf.c
+tphrase_SOURCES = tphrase.c
+
+LDADD = libtinysrp.a
+
+EXTRA_DIST = tpasswd Notes
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(lib_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libtinysrp_a_LIBADD =
+libtinysrp_a_OBJECTS = tinysrp.o t_client.o t_getconf.o t_conv.o \
+t_getpass.o t_sha.o t_math.o t_misc.o t_pw.o t_read.o t_server.o \
+t_truerand.o bn_add.o bn_ctx.o bn_div.o bn_exp.o bn_mul.o bn_word.o \
+bn_asm.o bn_lib.o bn_shift.o bn_sqr.o
+AR = ar
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+
+tconf_OBJECTS = tconf.o t_conf.o
+tconf_LDADD = $(LDADD)
+tconf_DEPENDENCIES = libtinysrp.a
+tconf_LDFLAGS =
+tphrase_OBJECTS = tphrase.o
+tphrase_LDADD = $(LDADD)
+tphrase_DEPENDENCIES = libtinysrp.a
+tphrase_LDFLAGS =
+srvtest_OBJECTS = srvtest.o
+srvtest_LDADD = $(LDADD)
+srvtest_DEPENDENCIES = libtinysrp.a
+srvtest_LDFLAGS =
+clitest_OBJECTS = clitest.o
+clitest_LDADD = $(LDADD)
+clitest_DEPENDENCIES = libtinysrp.a
+clitest_LDFLAGS =
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS) $(noinst_HEADERS)
+
+DIST_COMMON = ./stamp-h.in Makefile.am Makefile.in acconfig.h \
+acinclude.m4 aclocal.m4 config.h.in configure configure.in install-sh \
+missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+SOURCES = $(libtinysrp_a_SOURCES) $(tconf_SOURCES) $(tphrase_SOURCES) $(srvtest_SOURCES) $(clitest_SOURCES)
+OBJECTS = $(libtinysrp_a_OBJECTS) $(tconf_OBJECTS) $(tphrase_OBJECTS) $(srvtest_OBJECTS) $(clitest_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-libLIBRARIES:
+
+clean-libLIBRARIES:
+ -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
+
+distclean-libLIBRARIES:
+
+maintainer-clean-libLIBRARIES:
+
+install-libLIBRARIES: $(lib_LIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+ @$(POST_INSTALL)
+ @list='$(lib_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \
+ $(RANLIB) $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LIBRARIES)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libtinysrp.a: $(libtinysrp_a_OBJECTS) $(libtinysrp_a_DEPENDENCIES)
+ -rm -f libtinysrp.a
+ $(AR) cru libtinysrp.a $(libtinysrp_a_OBJECTS) $(libtinysrp_a_LIBADD)
+ $(RANLIB) libtinysrp.a
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+tconf: $(tconf_OBJECTS) $(tconf_DEPENDENCIES)
+ @rm -f tconf
+ $(LINK) $(tconf_LDFLAGS) $(tconf_OBJECTS) $(tconf_LDADD) $(LIBS)
+
+tphrase: $(tphrase_OBJECTS) $(tphrase_DEPENDENCIES)
+ @rm -f tphrase
+ $(LINK) $(tphrase_LDFLAGS) $(tphrase_OBJECTS) $(tphrase_LDADD) $(LIBS)
+
+srvtest: $(srvtest_OBJECTS) $(srvtest_DEPENDENCIES)
+ @rm -f srvtest
+ $(LINK) $(srvtest_LDFLAGS) $(srvtest_OBJECTS) $(srvtest_LDADD) $(LIBS)
+
+clitest: $(clitest_OBJECTS) $(clitest_DEPENDENCIES)
+ @rm -f clitest
+ $(LINK) $(clitest_LDFLAGS) $(clitest_OBJECTS) $(clitest_LDADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-libLIBRARIES install-binPROGRAMS
+install-exec: install-exec-am
+
+install-data-am: install-includeHEADERS
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLIBRARIES uninstall-binPROGRAMS \
+ uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS) config.h
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) \
+ $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-hdr mostlyclean-libLIBRARIES \
+ mostlyclean-compile mostlyclean-binPROGRAMS \
+ mostlyclean-noinstPROGRAMS mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-hdr clean-libLIBRARIES clean-compile clean-binPROGRAMS \
+ clean-noinstPROGRAMS clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-hdr distclean-libLIBRARIES distclean-compile \
+ distclean-binPROGRAMS distclean-noinstPROGRAMS \
+ distclean-tags distclean-generic clean-am
+
+distclean: distclean-am
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr maintainer-clean-libLIBRARIES \
+ maintainer-clean-compile maintainer-clean-binPROGRAMS \
+ maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-libLIBRARIES distclean-libLIBRARIES clean-libLIBRARIES \
+maintainer-clean-libLIBRARIES uninstall-libLIBRARIES \
+install-libLIBRARIES mostlyclean-compile distclean-compile \
+clean-compile maintainer-clean-compile mostlyclean-binPROGRAMS \
+distclean-binPROGRAMS clean-binPROGRAMS maintainer-clean-binPROGRAMS \
+uninstall-binPROGRAMS install-binPROGRAMS mostlyclean-noinstPROGRAMS \
+distclean-noinstPROGRAMS clean-noinstPROGRAMS \
+maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \
+install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck all-recursive-am install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/package/network/services/ead/src/tinysrp/Notes b/package/network/services/ead/src/tinysrp/Notes
new file mode 100644
index 0000000..a8620aa
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/Notes
@@ -0,0 +1,110 @@
+t_* stuff is from the srp 1.7.1 dist
+bn_* stuff is from openssl 0.9.6
+
+(The 7 in libtinysrp's version number reflects the srp version.)
+
+Licensing and copyright for srp and openssl are as indicated in the relevant
+source files. Everything else here is GPL, including the tinysrp protocol.
+
+Changelog since initial release:
+
+0.7.4 more robust terminal modes in t_getpass
+ a potential buffer overflow in tinysrp
+0.7.5 uninitialized pointer bug in tconf
+
+Changes from the base srp and openssl distributions:
+
+I've removed everything that's not needed for client/server operations, and
+all the bn_* stuff that's only used for prime generation has been moved to
+t_conf.c, which isn't part of the library anymore. Also, all the routines
+used for passphrase file maintenance have been moved to tphrase.c.
+
+The library has been optimized (a bit) for space instead of speed. Since
+authentication is usually only done once, this isn't a big problem. Modern
+CPUs are plenty fast for this task, and even 100 MHz CPUs are fine. If you
+really need the speed, get the regular distributions.
+
+Note that if the server sends the client a prime that the client doesn't
+know about, the client MUST test for primality. Since this is pretty
+expensive, and takes 30 seconds on a 100 MHz machine, and uses lots of code,
+I've removed that ability from the client. So only KNOWN primes can be
+used. You can still generate new ones with tconf, but you have to install
+them in the table of known primes (pre_params) in t_getconf.c that's common
+to the client and server, and recompile. The configuration file is gone.
+
+The default prime (the last entry in the table) is 1024 bits; there are
+others with more bits but they will be correspondingly slower.
+
+The default tpasswd file (which is an ascii file that may be editted with a
+regular text editor) contains two users: moo (passphrase "glub glub") and
+"new user" (passphrase "this is a test"). Passphrases may be added or
+changed with tphrase; you can also change the user's prime. To delete a
+user, edit the tpasswd file and remove that line. The tpasswd file's
+default name is DEFAULT_PASSWD in t_pwd.h. Note that you can't change a
+user's username by editting the file: the username is encoded in the
+verifier. If you change a username you must set a new passphrase with
+tphrase.
+
+Here is an example session, using the supplied srvtest and clitest. First,
+start both programs in different windows, and enter the user names. Normally,
+the client would send the username to the server. Server lines are marked
+with S>, client lines with C>.
+
+S> % srvtest
+S> Enter username: moo
+S> index (to client): 5
+S> salt (to client): 19AI0Hc9jEkdFc
+
+C> % clitest
+C> Enter username: moo
+C> Enter index (from server): 5
+C> Enter salt (from server): 19AI0Hc9jEkdFc
+
+The server reports the index and salt values used for that user. They
+are sent over the network to the client. (Simulate this by cutting and
+pasting from one window to the other.)
+
+C> A (to server): 5wCDXRxLIv/zLazYfKupV/OY3BlhTZuJ71wVgI0HcL1kSJEpkMuWF.xEz/BV2wlJl7vk5Eoz9KMS1ccnaatsVP5D6CBm7UA.yVB59EQFN0dNBirvX29NAFdtdMsMppo5tHRy987XjJWrWSLpeibq6emr.gP8nYyX75GQqSiMY1j
+C> Enter password:
+
+S> Enter A (from client): 5wCDXRxLIv/zLazYfKupV/OY3BlhTZuJ71wVgI0HcL1kSJEpkMuWF.xEz/BV2wlJl7vk5Eoz9KMS1ccnaatsVP5D6CBm7UA.yVB59EQFN0dNBirvX29NAFdtdMsMppo5tHRy987XjJWrWSLpeibq6emr.gP8nYyX75GQqSiMY1j
+
+Now the client calculates A and sends it to the server, and while the
+server is munching on that, the client gets the password from the user.
+
+S> B (to client): 9dcCpulxQAbaDXI0NHWY6B.QH6B9fsoXs/x/5SCNBNJm/6H6bYfbVrwNmdquhLZjYMvpcgGc2mBYqL77RNfw1kVQo17//GfsByECBIjRnrAn02ffX9Y/llJcfscAQiii0hyZhJf9PT5wE7pC7WUjIgSqckIZ0JLNDbSr7fJcrgw
+S> Session key: ebbcf3a45c968defdcfff6e144ad8d4f5412167c9716e79cbf7cacfe18257947ad46fa5d6418a1fd
+
+The server now calculates B and sends it to the client. The session key
+is not sent -- it is a shared secret that can be used for encryption.
+
+C> Enter B (from server): 9dcCpulxQAbaDXI0NHWY6B.QH6B9fsoXs/x/5SCNBNJm/6H6bYfbVrwNmdquhLZjYMvpcgGc2mBYqL77RNfw1kVQo17//GfsByECBIjRnrAn02ffX9Y/llJcfscAQiii0hyZhJf9PT5wE7pC7WUjIgSqckIZ0JLNDbSr7fJcrgw
+C> Session key: ebbcf3a45c968defdcfff6e144ad8d4f5412167c9716e79cbf7cacfe18257947ad46fa5d6418a1fd
+C> Response (to server): b9ea99094a176c4be28eb469982066cc7146d180
+
+The client uses the B value to calculate its own copy of the shared secret
+session key, and sends a response to the server proving that it does know
+the correct key.
+
+S> Enter response (from client): b9ea99094a176c4be28eb469982066cc7146d180
+S> Authentication successful.
+S> Response (to client): cd46c839ccad2d0c76f3ca1905ae8ceda8d1c1dc
+
+The server authenticates the client. (You're in!)
+
+C> Enter server response: cd46c839ccad2d0c76f3ca1905ae8ceda8d1c1dc
+C> Server authentication successful.
+
+The client authenticates the server (prevents server spoofing in the case
+where the session key isn't used to encrypt the channel -- a spoofed server
+might just respond with random values and _pretend_ to authenticate the
+client; but the spoofed server won't know the session key and this check
+catches that).
+
+Final note:
+
+Remember that many breaches of security involve buggy software, such as
+servers susceptible to buffer overflow exploits that totally bypass any
+passphrase, secure or not. If an attacker roots your client, or the server,
+no form of authentication will work. Consider MAC-based schemes if this
+worries you.
diff --git a/package/network/services/ead/src/tinysrp/acconfig.h b/package/network/services/ead/src/tinysrp/acconfig.h
new file mode 100644
index 0000000..b74aed0
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/acconfig.h
@@ -0,0 +1,9 @@
+#undef SHA1HANDSOFF
+
+#undef POSIX_TERMIOS
+
+#undef POSIX_SIGTYPE
+
+#undef VERSION
+
+#undef volatile
diff --git a/package/network/services/ead/src/tinysrp/acinclude.m4 b/package/network/services/ead/src/tinysrp/acinclude.m4
new file mode 100644
index 0000000..e0d0d04
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/acinclude.m4
@@ -0,0 +1,27 @@
+dnl
+dnl check for signal type
+dnl
+dnl AC_RETSIGTYPE isn't quite right, but almost.
+dnl
+define(TYPE_SIGNAL,[
+AC_MSG_CHECKING([POSIX signal handlers])
+AC_CACHE_VAL(cv_has_posix_signals,
+[AC_TRY_COMPILE(
+[#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+extern void (*signal ()) ();], [],
+cv_has_posix_signals=yes, cv_has_posix_signals=no)])
+AC_MSG_RESULT($cv_has_posix_signals)
+if test $cv_has_posix_signals = yes; then
+ AC_DEFINE(RETSIGTYPE, void, [Return type is void])
+ AC_DEFINE(POSIX_SIGTYPE, [], [Have POSIX signals])
+else
+ if test $ac_cv_type_signal = void; then
+ AC_DEFINE(RETSIGTYPE, void, [Return type is void])
+ else
+ AC_DEFINE(RETSIGTYPE, int, [Return type is int])
+ fi
+fi])dnl
diff --git a/package/network/services/ead/src/tinysrp/aclocal.m4 b/package/network/services/ead/src/tinysrp/aclocal.m4
new file mode 100644
index 0000000..703fce4
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/aclocal.m4
@@ -0,0 +1,157 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4a
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+dnl
+dnl check for signal type
+dnl
+dnl AC_RETSIGTYPE isn't quite right, but almost.
+dnl
+define(TYPE_SIGNAL,[
+AC_MSG_CHECKING([POSIX signal handlers])
+AC_CACHE_VAL(cv_has_posix_signals,
+[AC_TRY_COMPILE(
+[#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+extern void (*signal ()) ();], [],
+cv_has_posix_signals=yes, cv_has_posix_signals=no)])
+AC_MSG_RESULT($cv_has_posix_signals)
+if test $cv_has_posix_signals = yes; then
+ AC_DEFINE(RETSIGTYPE, void, [Return type is void])
+ AC_DEFINE(POSIX_SIGTYPE, [], [Have POSIX signals])
+else
+ if test $ac_cv_type_signal = void; then
+ AC_DEFINE(RETSIGTYPE, void, [Return type is void])
+ else
+ AC_DEFINE(RETSIGTYPE, int, [Return type is int])
+ fi
+fi])dnl
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+dnl We require 2.13 because we rely on SHELL being computed by configure.
+AC_PREREQ([2.13])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
diff --git a/package/network/services/ead/src/tinysrp/bn.h b/package/network/services/ead/src/tinysrp/bn.h
new file mode 100644
index 0000000..0144dd9
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn.h
@@ -0,0 +1,471 @@
+/* crypto/bn/bn.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BN_H
+#define HEADER_BN_H
+
+#include <stdio.h> /* FILE */
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef VMS
+#undef BN_LLONG /* experimental, so far... */
+#endif
+
+#undef BN_MUL_COMBA
+#undef BN_SQR_COMBA
+#undef BN_RECURSION
+#undef RECP_MUL_MOD
+#undef MONT_MUL_MOD
+
+#if defined(SIZEOF_LONG_LONG) && SIZEOF_LONG_LONG == 8
+# if SIZEOF_LONG == 4
+# define THIRTY_TWO_BIT
+# else
+# define SIXTY_FOUR_BIT_LONG
+# endif
+#else
+# if SIZEOF_LONG == 4
+# define THIRTY_TWO_BIT
+# endif
+#endif
+
+#undef BN_LLONG
+
+/* assuming long is 64bit - this is the DEC Alpha
+ * unsigned long long is only 64 bits :-(, don't define
+ * BN_LLONG for the DEC Alpha */
+#ifdef SIXTY_FOUR_BIT_LONG
+#define BN_ULLONG unsigned long long
+#define BN_ULONG unsigned long
+#define BN_LONG long
+#define BN_BITS 128
+#define BN_BYTES 8
+#define BN_BITS2 64
+#define BN_BITS4 32
+#define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
+#define BN_MASK2 (0xffffffffffffffffL)
+#define BN_MASK2l (0xffffffffL)
+#define BN_MASK2h (0xffffffff00000000L)
+#define BN_MASK2h1 (0xffffffff80000000L)
+#define BN_TBIT (0x8000000000000000L)
+#define BN_DEC_CONV (10000000000000000000UL)
+#define BN_DEC_FMT1 "%lu"
+#define BN_DEC_FMT2 "%019lu"
+#define BN_DEC_NUM 19
+#endif
+
+/* This is where the long long data type is 64 bits, but long is 32.
+ * For machines where there are 64bit registers, this is the mode to use.
+ * IRIX, on R4000 and above should use this mode, along with the relevant
+ * assembler code :-). Do NOT define BN_LLONG.
+ */
+#ifdef SIXTY_FOUR_BIT
+#undef BN_LLONG
+#undef BN_ULLONG
+#define BN_ULONG unsigned long long
+#define BN_LONG long long
+#define BN_BITS 128
+#define BN_BYTES 8
+#define BN_BITS2 64
+#define BN_BITS4 32
+#define BN_MASK2 (0xffffffffffffffffLL)
+#define BN_MASK2l (0xffffffffL)
+#define BN_MASK2h (0xffffffff00000000LL)
+#define BN_MASK2h1 (0xffffffff80000000LL)
+#define BN_TBIT (0x8000000000000000LL)
+#define BN_DEC_CONV (10000000000000000000LL)
+#define BN_DEC_FMT1 "%llu"
+#define BN_DEC_FMT2 "%019llu"
+#define BN_DEC_NUM 19
+#endif
+
+#ifdef THIRTY_TWO_BIT
+#if defined(WIN32) && !defined(__GNUC__)
+#define BN_ULLONG unsigned _int64
+#else
+#define BN_ULLONG unsigned long long
+#endif
+#define BN_ULONG unsigned long
+#define BN_LONG long
+#define BN_BITS 64
+#define BN_BYTES 4
+#define BN_BITS2 32
+#define BN_BITS4 16
+#ifdef WIN32
+/* VC++ doesn't like the LL suffix */
+#define BN_MASK (0xffffffffffffffffL)
+#else
+#define BN_MASK (0xffffffffffffffffLL)
+#endif
+#define BN_MASK2 (0xffffffffL)
+#define BN_MASK2l (0xffff)
+#define BN_MASK2h1 (0xffff8000L)
+#define BN_MASK2h (0xffff0000L)
+#define BN_TBIT (0x80000000L)
+#define BN_DEC_CONV (1000000000L)
+#define BN_DEC_FMT1 "%lu"
+#define BN_DEC_FMT2 "%09lu"
+#define BN_DEC_NUM 9
+#endif
+
+#ifdef SIXTEEN_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG unsigned long
+#define BN_ULONG unsigned short
+#define BN_LONG short
+#define BN_BITS 32
+#define BN_BYTES 2
+#define BN_BITS2 16
+#define BN_BITS4 8
+#define BN_MASK (0xffffffff)
+#define BN_MASK2 (0xffff)
+#define BN_MASK2l (0xff)
+#define BN_MASK2h1 (0xff80)
+#define BN_MASK2h (0xff00)
+#define BN_TBIT (0x8000)
+#define BN_DEC_CONV (100000)
+#define BN_DEC_FMT1 "%u"
+#define BN_DEC_FMT2 "%05u"
+#define BN_DEC_NUM 5
+#endif
+
+#ifdef EIGHT_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG unsigned short
+#define BN_ULONG unsigned char
+#define BN_LONG char
+#define BN_BITS 16
+#define BN_BYTES 1
+#define BN_BITS2 8
+#define BN_BITS4 4
+#define BN_MASK (0xffff)
+#define BN_MASK2 (0xff)
+#define BN_MASK2l (0xf)
+#define BN_MASK2h1 (0xf8)
+#define BN_MASK2h (0xf0)
+#define BN_TBIT (0x80)
+#define BN_DEC_CONV (100)
+#define BN_DEC_FMT1 "%u"
+#define BN_DEC_FMT2 "%02u"
+#define BN_DEC_NUM 2
+#endif
+
+#define BN_DEFAULT_BITS 1280
+
+#ifdef BIGNUM
+#undef BIGNUM
+#endif
+
+#define BN_FLG_MALLOCED 0x01
+#define BN_FLG_STATIC_DATA 0x02
+#define BN_FLG_FREE 0x8000 /* used for debuging */
+#define BN_set_flags(b,n) ((b)->flags|=(n))
+#define BN_get_flags(b,n) ((b)->flags&(n))
+
+typedef struct bignum_st
+ {
+ BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
+ int top; /* Index of last used d +1. */
+ /* The next are internal book keeping for bn_expand. */
+ int dmax; /* Size of the d array. */
+ int neg; /* one if the number is negative */
+ int flags;
+ } BIGNUM;
+
+/* Used for temp variables */
+#define BN_CTX_NUM 12
+#define BN_CTX_NUM_POS 12
+typedef struct bignum_ctx
+ {
+ int tos;
+ BIGNUM bn[BN_CTX_NUM];
+ int flags;
+ int depth;
+ int pos[BN_CTX_NUM_POS];
+ int too_many;
+ } BN_CTX;
+
+/* Used for montgomery multiplication */
+typedef struct bn_mont_ctx_st
+ {
+ int ri; /* number of bits in R */
+ BIGNUM RR; /* used to convert to montgomery form */
+ BIGNUM N; /* The modulus */
+ BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1
+ * (Ni is only stored for bignum algorithm) */
+ BN_ULONG n0; /* least significant word of Ni */
+ int flags;
+ } BN_MONT_CTX;
+
+/* Used for reciprocal division/mod functions
+ * It cannot be shared between threads
+ */
+typedef struct bn_recp_ctx_st
+ {
+ BIGNUM N; /* the divisor */
+ BIGNUM Nr; /* the reciprocal */
+ int num_bits;
+ int shift;
+ int flags;
+ } BN_RECP_CTX;
+
+#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\
+ r,a,&((mont)->RR),(mont),ctx)
+
+#define BN_prime_checks 0 /* default: select number of iterations
+ based on the size of the number */
+
+/* number of Miller-Rabin iterations for an error rate of less than 2^-80
+ * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
+ * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
+ * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
+#define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \
+ (b) >= 850 ? 3 : \
+ (b) >= 650 ? 4 : \
+ (b) >= 550 ? 5 : \
+ (b) >= 450 ? 6 : \
+ (b) >= 400 ? 7 : \
+ (b) >= 350 ? 8 : \
+ (b) >= 300 ? 9 : \
+ (b) >= 250 ? 12 : \
+ (b) >= 200 ? 15 : \
+ (b) >= 150 ? 18 : \
+ /* b >= 100 */ 27)
+
+#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
+#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w)))
+#define BN_is_zero(a) (((a)->top == 0) || BN_is_word(a,0))
+#define BN_is_one(a) (BN_is_word((a),1))
+#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1))
+#define BN_one(a) (BN_set_word((a),1))
+#define BN_zero(a) (BN_set_word((a),0))
+
+BIGNUM *BN_value_one(void);
+char * BN_options(void);
+BN_CTX *BN_CTX_new(void);
+void BN_CTX_init(BN_CTX *c);
+void BN_CTX_free(BN_CTX *c);
+void BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void BN_CTX_end(BN_CTX *ctx);
+int BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int BN_num_bits(const BIGNUM *a);
+int BN_num_bits_word(BN_ULONG);
+BIGNUM *BN_new(void);
+void BN_init(BIGNUM *);
+void BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
+int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+ BN_CTX *ctx);
+int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx);
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int BN_mul_word(BIGNUM *a, BN_ULONG w);
+int BN_add_word(BIGNUM *a, BN_ULONG w);
+int BN_sub_word(BIGNUM *a, BN_ULONG w);
+int BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(BIGNUM *a);
+int BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void BN_free(BIGNUM *a);
+int BN_is_bit_set(const BIGNUM *a, int n);
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_lshift1(BIGNUM *r, BIGNUM *a);
+int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx);
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m,BN_CTX *ctx);
+int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m,BN_CTX *ctx);
+int BN_mask_bits(BIGNUM *a,int n);
+int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx);
+int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+int BN_rshift1(BIGNUM *r, BIGNUM *a);
+void BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int BN_set_bit(BIGNUM *a, int n);
+int BN_clear_bit(BIGNUM *a, int n);
+int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx);
+BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,BIGNUM *add,
+ BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
+int BN_is_prime(const BIGNUM *p,int nchecks,
+ void (*callback)(int,int,void *),
+ BN_CTX *ctx,void *cb_arg);
+int BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
+ void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
+ int do_trial_division);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void );
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont,
+ BN_CTX *ctx);
+int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
+
+void BN_set_params(int mul,int high,int low,int mont);
+int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
+int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y,
+ BN_RECP_CTX *recp,BN_CTX *ctx);
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
+ BN_RECP_CTX *recp, BN_CTX *ctx);
+
+/* library internal functions */
+
+#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
+ (a):bn_expand2((a),(bits)/BN_BITS2+1))
+#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+
+#define bn_fix_top(a) \
+ { \
+ BN_ULONG *ftl; \
+ if ((a)->top > 0) \
+ { \
+ for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
+ if (*(ftl--)) break; \
+ } \
+ }
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+
+#ifdef BN_DEBUG
+ void bn_dump1(FILE *o, const char *a, BN_ULONG *b,int n);
+# define bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \
+ fprintf(stderr,"\n");}
+# define bn_dump(a,n) bn_dump1(stderr,#a,a,n);
+#else
+# define bn_print(a)
+# define bn_dump(a,b)
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+#define BN_F_BN_CTX_GET 116
+#define BN_F_BN_CTX_NEW 106
+#define BN_F_BN_DIV 107
+#define BN_F_BN_EXPAND2 108
+#define BN_F_BN_MOD_EXP2_MONT 118
+#define BN_F_BN_MOD_EXP_MONT 109
+#define BN_F_BN_MOD_EXP_MONT_WORD 117
+#define BN_F_BN_MOD_INVERSE 110
+#define BN_F_BN_MOD_MUL_RECIPROCAL 111
+#define BN_F_BN_MPI2BN 112
+#define BN_F_BN_NEW 113
+#define BN_F_BN_RAND 114
+#define BN_F_BN_USUB 115
+
+/* Reason codes. */
+#define BN_R_ARG2_LT_ARG3 100
+#define BN_R_BAD_RECIPROCAL 101
+#define BN_R_CALLED_WITH_EVEN_MODULUS 102
+#define BN_R_DIV_BY_ZERO 103
+#define BN_R_ENCODING_ERROR 104
+#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105
+#define BN_R_INVALID_LENGTH 106
+#define BN_R_NOT_INITIALIZED 107
+#define BN_R_NO_INVERSE 108
+#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/package/network/services/ead/src/tinysrp/bn_add.c b/package/network/services/ead/src/tinysrp/bn_add.c
new file mode 100644
index 0000000..aae4f2b
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_add.c
@@ -0,0 +1,305 @@
+/* crypto/bn/bn_add.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+ {
+ const BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /* a + b a+b
+ * a + -b a-b
+ * -a + b b-a
+ * -a + -b -(a+b)
+ */
+ if (a->neg ^ b->neg)
+ {
+ /* only one is negative */
+ if (a->neg)
+ { tmp=a; a=b; b=tmp; }
+
+ /* we are now a - b */
+
+ if (BN_ucmp(a,b) < 0)
+ {
+ if (!BN_usub(r,b,a)) return(0);
+ r->neg=1;
+ }
+ else
+ {
+ if (!BN_usub(r,a,b)) return(0);
+ r->neg=0;
+ }
+ return(1);
+ }
+
+ if (a->neg) /* both are neg */
+ r->neg=1;
+ else
+ r->neg=0;
+
+ if (!BN_uadd(r,a,b)) return(0);
+ return(1);
+ }
+
+/* unsigned add of b to a, r must be large enough */
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+ {
+ register int i;
+ int max,min;
+ BN_ULONG *ap,*bp,*rp,carry,t1;
+ const BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->top < b->top)
+ { tmp=a; a=b; b=tmp; }
+ max=a->top;
+ min=b->top;
+
+ if (bn_wexpand(r,max+1) == NULL)
+ return(0);
+
+ r->top=max;
+
+
+ ap=a->d;
+ bp=b->d;
+ rp=r->d;
+ carry=0;
+
+ carry=bn_add_words(rp,ap,bp,min);
+ rp+=min;
+ ap+=min;
+ bp+=min;
+ i=min;
+
+ if (carry)
+ {
+ while (i < max)
+ {
+ i++;
+ t1= *(ap++);
+ if ((*(rp++)=(t1+1)&BN_MASK2) >= t1)
+ {
+ carry=0;
+ break;
+ }
+ }
+ if ((i >= max) && carry)
+ {
+ *(rp++)=1;
+ r->top++;
+ }
+ }
+ if (rp != ap)
+ {
+ for (; i<max; i++)
+ *(rp++)= *(ap++);
+ }
+ /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
+ return(1);
+ }
+
+/* unsigned subtraction of b from a, a must be larger than b. */
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+ {
+ int max,min;
+ register BN_ULONG t1,t2,*ap,*bp,*rp;
+ int i,carry;
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+ int dummy;
+#endif
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->top < b->top) /* hmm... should not be happening */
+ {
+ return(0);
+ }
+
+ max=a->top;
+ min=b->top;
+ if (bn_wexpand(r,max) == NULL) return(0);
+
+ ap=a->d;
+ bp=b->d;
+ rp=r->d;
+
+#if 1
+ carry=0;
+ for (i=0; i<min; i++)
+ {
+ t1= *(ap++);
+ t2= *(bp++);
+ if (carry)
+ {
+ carry=(t1 <= t2);
+ t1=(t1-t2-1)&BN_MASK2;
+ }
+ else
+ {
+ carry=(t1 < t2);
+ t1=(t1-t2)&BN_MASK2;
+ }
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+ dummy=t1;
+#endif
+ *(rp++)=t1&BN_MASK2;
+ }
+#else
+ carry=bn_sub_words(rp,ap,bp,min);
+ ap+=min;
+ bp+=min;
+ rp+=min;
+ i=min;
+#endif
+ if (carry) /* subtracted */
+ {
+ while (i < max)
+ {
+ i++;
+ t1= *(ap++);
+ t2=(t1-1)&BN_MASK2;
+ *(rp++)=t2;
+ if (t1 > t2) break;
+ }
+ }
+#if 0
+ memcpy(rp,ap,sizeof(*rp)*(max-i));
+#else
+ if (rp != ap)
+ {
+ for (;;)
+ {
+ if (i++ >= max) break;
+ rp[0]=ap[0];
+ if (i++ >= max) break;
+ rp[1]=ap[1];
+ if (i++ >= max) break;
+ rp[2]=ap[2];
+ if (i++ >= max) break;
+ rp[3]=ap[3];
+ rp+=4;
+ ap+=4;
+ }
+ }
+#endif
+
+ r->top=max;
+ bn_fix_top(r);
+ return(1);
+ }
+
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+ {
+ int max;
+ int add=0,neg=0;
+ const BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /* a - b a-b
+ * a - -b a+b
+ * -a - b -(a+b)
+ * -a - -b b-a
+ */
+ if (a->neg)
+ {
+ if (b->neg)
+ { tmp=a; a=b; b=tmp; }
+ else
+ { add=1; neg=1; }
+ }
+ else
+ {
+ if (b->neg) { add=1; neg=0; }
+ }
+
+ if (add)
+ {
+ if (!BN_uadd(r,a,b)) return(0);
+ r->neg=neg;
+ return(1);
+ }
+
+ /* We are actually doing a - b :-) */
+
+ max=(a->top > b->top)?a->top:b->top;
+ if (bn_wexpand(r,max) == NULL) return(0);
+ if (BN_ucmp(a,b) < 0)
+ {
+ if (!BN_usub(r,b,a)) return(0);
+ r->neg=1;
+ }
+ else
+ {
+ if (!BN_usub(r,a,b)) return(0);
+ r->neg=0;
+ }
+ return(1);
+ }
+
diff --git a/package/network/services/ead/src/tinysrp/bn_asm.c b/package/network/services/ead/src/tinysrp/bn_asm.c
new file mode 100644
index 0000000..b24c9af
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_asm.c
@@ -0,0 +1,382 @@
+/* crypto/bn/bn_asm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include "bn_lcl.h"
+
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG c1=0;
+
+ assert(num >= 0);
+ if (num <= 0) return(c1);
+
+ while (num&~3)
+ {
+ mul_add(rp[0],ap[0],w,c1);
+ mul_add(rp[1],ap[1],w,c1);
+ mul_add(rp[2],ap[2],w,c1);
+ mul_add(rp[3],ap[3],w,c1);
+ ap+=4; rp+=4; num-=4;
+ }
+ if (num)
+ {
+ mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
+ mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
+ mul_add(rp[2],ap[2],w,c1); return c1;
+ }
+
+ return(c1);
+ }
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG c1=0;
+
+ assert(num >= 0);
+ if (num <= 0) return(c1);
+
+ while (num&~3)
+ {
+ mul(rp[0],ap[0],w,c1);
+ mul(rp[1],ap[1],w,c1);
+ mul(rp[2],ap[2],w,c1);
+ mul(rp[3],ap[3],w,c1);
+ ap+=4; rp+=4; num-=4;
+ }
+ if (num)
+ {
+ mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
+ mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
+ mul(rp[2],ap[2],w,c1);
+ }
+ return(c1);
+ }
+
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+ {
+ assert(n >= 0);
+ if (n <= 0) return;
+ while (n&~3)
+ {
+ sqr(r[0],r[1],a[0]);
+ sqr(r[2],r[3],a[1]);
+ sqr(r[4],r[5],a[2]);
+ sqr(r[6],r[7],a[3]);
+ a+=4; r+=8; n-=4;
+ }
+ if (n)
+ {
+ sqr(r[0],r[1],a[0]); if (--n == 0) return;
+ sqr(r[2],r[3],a[1]); if (--n == 0) return;
+ sqr(r[4],r[5],a[2]);
+ }
+ }
+
+#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG c=0;
+ BN_ULONG bl,bh;
+
+ assert(num >= 0);
+ if (num <= 0) return((BN_ULONG)0);
+
+ bl=LBITS(w);
+ bh=HBITS(w);
+
+ for (;;)
+ {
+ mul_add(rp[0],ap[0],bl,bh,c);
+ if (--num == 0) break;
+ mul_add(rp[1],ap[1],bl,bh,c);
+ if (--num == 0) break;
+ mul_add(rp[2],ap[2],bl,bh,c);
+ if (--num == 0) break;
+ mul_add(rp[3],ap[3],bl,bh,c);
+ if (--num == 0) break;
+ ap+=4;
+ rp+=4;
+ }
+ return(c);
+ }
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG carry=0;
+ BN_ULONG bl,bh;
+
+ assert(num >= 0);
+ if (num <= 0) return((BN_ULONG)0);
+
+ bl=LBITS(w);
+ bh=HBITS(w);
+
+ for (;;)
+ {
+ mul(rp[0],ap[0],bl,bh,carry);
+ if (--num == 0) break;
+ mul(rp[1],ap[1],bl,bh,carry);
+ if (--num == 0) break;
+ mul(rp[2],ap[2],bl,bh,carry);
+ if (--num == 0) break;
+ mul(rp[3],ap[3],bl,bh,carry);
+ if (--num == 0) break;
+ ap+=4;
+ rp+=4;
+ }
+ return(carry);
+ }
+
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+ {
+ assert(n >= 0);
+ if (n <= 0) return;
+ for (;;)
+ {
+ sqr64(r[0],r[1],a[0]);
+ if (--n == 0) break;
+
+ sqr64(r[2],r[3],a[1]);
+ if (--n == 0) break;
+
+ sqr64(r[4],r[5],a[2]);
+ if (--n == 0) break;
+
+ sqr64(r[6],r[7],a[3]);
+ if (--n == 0) break;
+
+ a+=4;
+ r+=8;
+ }
+ }
+
+#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+#if defined(BN_LLONG) && defined(BN_DIV2W)
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+ {
+ return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d));
+ }
+
+#else
+
+/* Divide h,l by d and return the result. */
+/* I need to test this some more :-( */
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+ {
+ BN_ULONG dh,dl,q,ret=0,th,tl,t;
+ int i,count=2;
+
+ if (d == 0) return(BN_MASK2);
+
+ i=BN_num_bits_word(d);
+ assert((i == BN_BITS2) || (h > (BN_ULONG)1<<i));
+
+ i=BN_BITS2-i;
+ if (h >= d) h-=d;
+
+ if (i)
+ {
+ d<<=i;
+ h=(h<<i)|(l>>(BN_BITS2-i));
+ l<<=i;
+ }
+ dh=(d&BN_MASK2h)>>BN_BITS4;
+ dl=(d&BN_MASK2l);
+ for (;;)
+ {
+ if ((h>>BN_BITS4) == dh)
+ q=BN_MASK2l;
+ else
+ q=h/dh;
+
+ th=q*dh;
+ tl=dl*q;
+ for (;;)
+ {
+ t=h-th;
+ if ((t&BN_MASK2h) ||
+ ((tl) <= (
+ (t<<BN_BITS4)|
+ ((l&BN_MASK2h)>>BN_BITS4))))
+ break;
+ q--;
+ th-=dh;
+ tl-=dl;
+ }
+ t=(tl>>BN_BITS4);
+ tl=(tl<<BN_BITS4)&BN_MASK2h;
+ th+=t;
+
+ if (l < tl) th++;
+ l-=tl;
+ if (h < th)
+ {
+ h+=d;
+ q--;
+ }
+ h-=th;
+
+ if (--count == 0) break;
+
+ ret=q<<BN_BITS4;
+ h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2;
+ l=(l&BN_MASK2l)<<BN_BITS4;
+ }
+ ret|=q;
+ return(ret);
+ }
+#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
+
+#ifdef BN_LLONG
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+ {
+ BN_ULLONG ll=0;
+
+ assert(n >= 0);
+ if (n <= 0) return((BN_ULONG)0);
+
+ for (;;)
+ {
+ ll+=(BN_ULLONG)a[0]+b[0];
+ r[0]=(BN_ULONG)ll&BN_MASK2;
+ ll>>=BN_BITS2;
+ if (--n <= 0) break;
+
+ ll+=(BN_ULLONG)a[1]+b[1];
+ r[1]=(BN_ULONG)ll&BN_MASK2;
+ ll>>=BN_BITS2;
+ if (--n <= 0) break;
+
+ ll+=(BN_ULLONG)a[2]+b[2];
+ r[2]=(BN_ULONG)ll&BN_MASK2;
+ ll>>=BN_BITS2;
+ if (--n <= 0) break;
+
+ ll+=(BN_ULLONG)a[3]+b[3];
+ r[3]=(BN_ULONG)ll&BN_MASK2;
+ ll>>=BN_BITS2;
+ if (--n <= 0) break;
+
+ a+=4;
+ b+=4;
+ r+=4;
+ }
+ return((BN_ULONG)ll);
+ }
+#else /* !BN_LLONG */
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+ {
+ BN_ULONG c,l,t;
+
+ assert(n >= 0);
+ if (n <= 0) return((BN_ULONG)0);
+
+ c=0;
+ for (;;)
+ {
+ t=a[0];
+ t=(t+c)&BN_MASK2;
+ c=(t < c);
+ l=(t+b[0])&BN_MASK2;
+ c+=(l < t);
+ r[0]=l;
+ if (--n <= 0) break;
+
+ t=a[1];
+ t=(t+c)&BN_MASK2;
+ c=(t < c);
+ l=(t+b[1])&BN_MASK2;
+ c+=(l < t);
+ r[1]=l;
+ if (--n <= 0) break;
+
+ t=a[2];
+ t=(t+c)&BN_MASK2;
+ c=(t < c);
+ l=(t+b[2])&BN_MASK2;
+ c+=(l < t);
+ r[2]=l;
+ if (--n <= 0) break;
+
+ t=a[3];
+ t=(t+c)&BN_MASK2;
+ c=(t < c);
+ l=(t+b[3])&BN_MASK2;
+ c+=(l < t);
+ r[3]=l;
+ if (--n <= 0) break;
+
+ a+=4;
+ b+=4;
+ r+=4;
+ }
+ return((BN_ULONG)c);
+ }
+#endif /* !BN_LLONG */
diff --git a/package/network/services/ead/src/tinysrp/bn_ctx.c b/package/network/services/ead/src/tinysrp/bn_ctx.c
new file mode 100644
index 0000000..20a6605
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_ctx.c
@@ -0,0 +1,142 @@
+/* crypto/bn/bn_ctx.c */
+/* Written by Ulf Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef BN_CTX_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <bn.h>
+
+
+BN_CTX *BN_CTX_new(void)
+ {
+ BN_CTX *ret;
+
+ ret=(BN_CTX *)malloc(sizeof(BN_CTX));
+ if (ret == NULL)
+ {
+ return(NULL);
+ }
+
+ BN_CTX_init(ret);
+ ret->flags=BN_FLG_MALLOCED;
+ return(ret);
+ }
+
+void BN_CTX_init(BN_CTX *ctx)
+ {
+ int i;
+ ctx->tos = 0;
+ ctx->flags = 0;
+ ctx->depth = 0;
+ ctx->too_many = 0;
+ for (i = 0; i < BN_CTX_NUM; i++)
+ BN_init(&(ctx->bn[i]));
+ }
+
+void BN_CTX_free(BN_CTX *ctx)
+ {
+ int i;
+
+ if (ctx == NULL) return;
+ assert(ctx->depth == 0);
+
+ for (i=0; i < BN_CTX_NUM; i++)
+ BN_clear_free(&(ctx->bn[i]));
+ if (ctx->flags & BN_FLG_MALLOCED)
+ free(ctx);
+ }
+
+void BN_CTX_start(BN_CTX *ctx)
+ {
+ if (ctx->depth < BN_CTX_NUM_POS)
+ ctx->pos[ctx->depth] = ctx->tos;
+ ctx->depth++;
+ }
+
+BIGNUM *BN_CTX_get(BN_CTX *ctx)
+ {
+ if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM)
+ {
+ if (!ctx->too_many)
+ {
+ /* disable error code until BN_CTX_end is called: */
+ ctx->too_many = 1;
+ }
+ return NULL;
+ }
+ return (&(ctx->bn[ctx->tos++]));
+ }
+
+void BN_CTX_end(BN_CTX *ctx)
+ {
+ if (ctx == NULL) return;
+ assert(ctx->depth > 0);
+ if (ctx->depth == 0)
+ /* should never happen, but we can tolerate it if not in
+ * debug mode (could be a 'goto err' in the calling function
+ * before BN_CTX_start was reached) */
+ BN_CTX_start(ctx);
+
+ ctx->too_many = 0;
+ ctx->depth--;
+ if (ctx->depth < BN_CTX_NUM_POS)
+ ctx->tos = ctx->pos[ctx->depth];
+ }
diff --git a/package/network/services/ead/src/tinysrp/bn_div.c b/package/network/services/ead/src/tinysrp/bn_div.c
new file mode 100644
index 0000000..fd21913
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_div.c
@@ -0,0 +1,378 @@
+/* crypto/bn/bn_div.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "bn_lcl.h"
+
+#define NO_ASM
+
+/* The old slow way */
+#if 0
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+ BN_CTX *ctx)
+ {
+ int i,nm,nd;
+ int ret = 0;
+ BIGNUM *D;
+
+ bn_check_top(m);
+ bn_check_top(d);
+ if (BN_is_zero(d))
+ {
+ return(0);
+ }
+
+ if (BN_ucmp(m,d) < 0)
+ {
+ if (rem != NULL)
+ { if (BN_copy(rem,m) == NULL) return(0); }
+ if (dv != NULL) BN_zero(dv);
+ return(1);
+ }
+
+ BN_CTX_start(ctx);
+ D = BN_CTX_get(ctx);
+ if (dv == NULL) dv = BN_CTX_get(ctx);
+ if (rem == NULL) rem = BN_CTX_get(ctx);
+ if (D == NULL || dv == NULL || rem == NULL)
+ goto end;
+
+ nd=BN_num_bits(d);
+ nm=BN_num_bits(m);
+ if (BN_copy(D,d) == NULL) goto end;
+ if (BN_copy(rem,m) == NULL) goto end;
+
+ /* The next 2 are needed so we can do a dv->d[0]|=1 later
+ * since BN_lshift1 will only work once there is a value :-) */
+ BN_zero(dv);
+ bn_wexpand(dv,1);
+ dv->top=1;
+
+ if (!BN_lshift(D,D,nm-nd)) goto end;
+ for (i=nm-nd; i>=0; i--)
+ {
+ if (!BN_lshift1(dv,dv)) goto end;
+ if (BN_ucmp(rem,D) >= 0)
+ {
+ dv->d[0]|=1;
+ if (!BN_usub(rem,rem,D)) goto end;
+ }
+/* CAN IMPROVE (and have now :=) */
+ if (!BN_rshift1(D,D)) goto end;
+ }
+ rem->neg=BN_is_zero(rem)?0:m->neg;
+ dv->neg=m->neg^d->neg;
+ ret = 1;
+ end:
+ BN_CTX_end(ctx);
+ return(ret);
+ }
+
+#else
+
+#if !defined(NO_ASM) && !defined(NO_INLINE_ASM) && !defined(PEDANTIC) && !defined(BN_DIV3W)
+# if defined(__GNUC__) && __GNUC__>=2
+# if defined(__i386)
+ /*
+ * There were two reasons for implementing this template:
+ * - GNU C generates a call to a function (__udivdi3 to be exact)
+ * in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
+ * understand why...);
+ * - divl doesn't only calculate quotient, but also leaves
+ * remainder in %edx which we can definitely use here:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+# define bn_div_words(n0,n1,d0) \
+ ({ asm volatile ( \
+ "divl %4" \
+ : "=a"(q), "=d"(rem) \
+ : "a"(n1), "d"(n0), "g"(d0) \
+ : "cc"); \
+ q; \
+ })
+# define REMAINDER_IS_ALREADY_CALCULATED
+# endif /* __<cpu> */
+# endif /* __GNUC__ */
+#endif /* NO_ASM */
+
+int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
+ BN_CTX *ctx)
+ {
+ int norm_shift,i,j,loop;
+ BIGNUM *tmp,wnum,*snum,*sdiv,*res;
+ BN_ULONG *resp,*wnump;
+ BN_ULONG d0,d1;
+ int num_n,div_n;
+
+ bn_check_top(num);
+ bn_check_top(divisor);
+
+ if (BN_is_zero(divisor))
+ {
+ return(0);
+ }
+
+ if (BN_ucmp(num,divisor) < 0)
+ {
+ if (rm != NULL)
+ { if (BN_copy(rm,num) == NULL) return(0); }
+ if (dv != NULL) BN_zero(dv);
+ return(1);
+ }
+
+ BN_CTX_start(ctx);
+ tmp=BN_CTX_get(ctx);
+ tmp->neg=0;
+ snum=BN_CTX_get(ctx);
+ sdiv=BN_CTX_get(ctx);
+ if (dv == NULL)
+ res=BN_CTX_get(ctx);
+ else res=dv;
+ if (res == NULL) goto err;
+
+ /* First we normalise the numbers */
+ norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
+ BN_lshift(sdiv,divisor,norm_shift);
+ sdiv->neg=0;
+ norm_shift+=BN_BITS2;
+ BN_lshift(snum,num,norm_shift);
+ snum->neg=0;
+ div_n=sdiv->top;
+ num_n=snum->top;
+ loop=num_n-div_n;
+
+ /* Lets setup a 'window' into snum
+ * This is the part that corresponds to the current
+ * 'area' being divided */
+ BN_init(&wnum);
+ wnum.d= &(snum->d[loop]);
+ wnum.top= div_n;
+ wnum.dmax= snum->dmax+1; /* a bit of a lie */
+
+ /* Get the top 2 words of sdiv */
+ /* i=sdiv->top; */
+ d0=sdiv->d[div_n-1];
+ d1=(div_n == 1)?0:sdiv->d[div_n-2];
+
+ /* pointer to the 'top' of snum */
+ wnump= &(snum->d[num_n-1]);
+
+ /* Setup to 'res' */
+ res->neg= (num->neg^divisor->neg);
+ if (!bn_wexpand(res,(loop+1))) goto err;
+ res->top=loop;
+ resp= &(res->d[loop-1]);
+
+ /* space for temp */
+ if (!bn_wexpand(tmp,(div_n+1))) goto err;
+
+ if (BN_ucmp(&wnum,sdiv) >= 0)
+ {
+ if (!BN_usub(&wnum,&wnum,sdiv)) goto err;
+ *resp=1;
+ res->d[res->top-1]=1;
+ }
+ else
+ res->top--;
+ resp--;
+
+ for (i=0; i<loop-1; i++)
+ {
+ BN_ULONG q,l0;
+#ifdef BN_DIV3W
+ q=bn_div_3_words(wnump,d1,d0);
+#else
+ BN_ULONG n0,n1,rem=0;
+
+ n0=wnump[0];
+ n1=wnump[-1];
+ if (n0 == d0)
+ q=BN_MASK2;
+ else /* n0 < d0 */
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t2;
+
+#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+ q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
+#else
+ q=bn_div_words(n0,n1,d0);
+#endif
+
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+ /*
+ * rem doesn't have to be BN_ULLONG. The least we
+ * know it's less that d0, isn't it?
+ */
+ rem=(n1-q*d0)&BN_MASK2;
+#endif
+ t2=(BN_ULLONG)d1*q;
+
+ for (;;)
+ {
+ if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
+ break;
+ q--;
+ rem += d0;
+ if (rem < d0) break; /* don't let rem overflow */
+ t2 -= d1;
+ }
+#else /* !BN_LLONG */
+ BN_ULONG t2l,t2h,ql,qh;
+
+ q=bn_div_words(n0,n1,d0);
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+ rem=(n1-q*d0)&BN_MASK2;
+#endif
+
+#ifdef BN_UMULT_HIGH
+ t2l = d1 * q;
+ t2h = BN_UMULT_HIGH(d1,q);
+#else
+ t2l=LBITS(d1); t2h=HBITS(d1);
+ ql =LBITS(q); qh =HBITS(q);
+ mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+#endif
+
+ for (;;)
+ {
+ if ((t2h < rem) ||
+ ((t2h == rem) && (t2l <= wnump[-2])))
+ break;
+ q--;
+ rem += d0;
+ if (rem < d0) break; /* don't let rem overflow */
+ if (t2l < d1) t2h--; t2l -= d1;
+ }
+#endif /* !BN_LLONG */
+ }
+#endif /* !BN_DIV3W */
+
+ l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
+ wnum.d--; wnum.top++;
+ tmp->d[div_n]=l0;
+ for (j=div_n+1; j>0; j--)
+ if (tmp->d[j-1]) break;
+ tmp->top=j;
+
+ j=wnum.top;
+ BN_sub(&wnum,&wnum,tmp);
+
+ snum->top=snum->top+wnum.top-j;
+
+ if (wnum.neg)
+ {
+ q--;
+ j=wnum.top;
+ BN_add(&wnum,&wnum,sdiv);
+ snum->top+=wnum.top-j;
+ }
+ *(resp--)=q;
+ wnump--;
+ }
+ if (rm != NULL)
+ {
+ BN_rshift(rm,snum,norm_shift);
+ rm->neg=num->neg;
+ }
+ BN_CTX_end(ctx);
+ return(1);
+err:
+ BN_CTX_end(ctx);
+ return(0);
+ }
+
+#endif
+
+/* rem != m */
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+ {
+#if 0 /* The old slow way */
+ int i,nm,nd;
+ BIGNUM *dv;
+
+ if (BN_ucmp(m,d) < 0)
+ return((BN_copy(rem,m) == NULL)?0:1);
+
+ BN_CTX_start(ctx);
+ dv=BN_CTX_get(ctx);
+
+ if (!BN_copy(rem,m)) goto err;
+
+ nm=BN_num_bits(rem);
+ nd=BN_num_bits(d);
+ if (!BN_lshift(dv,d,nm-nd)) goto err;
+ for (i=nm-nd; i>=0; i--)
+ {
+ if (BN_cmp(rem,dv) >= 0)
+ {
+ if (!BN_sub(rem,rem,dv)) goto err;
+ }
+ if (!BN_rshift1(dv,dv)) goto err;
+ }
+ BN_CTX_end(ctx);
+ return(1);
+ err:
+ BN_CTX_end(ctx);
+ return(0);
+#else
+ return(BN_div(NULL,rem,m,d,ctx));
+#endif
+ }
+
diff --git a/package/network/services/ead/src/tinysrp/bn_exp.c b/package/network/services/ead/src/tinysrp/bn_exp.c
new file mode 100644
index 0000000..09afb79
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_exp.c
@@ -0,0 +1,395 @@
+/* crypto/bn/bn_exp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include "bn_lcl.h"
+
+#define TABLE_SIZE 32
+
+/* slow but works */
+int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
+ {
+ BIGNUM *t;
+ int r=0;
+
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(m);
+
+ BN_CTX_start(ctx);
+ if ((t = BN_CTX_get(ctx)) == NULL) goto err;
+ if (a == b)
+ { if (!BN_sqr(t,a,ctx)) goto err; }
+ else
+ { if (!BN_mul(t,a,b,ctx)) goto err; }
+ if (!BN_mod(ret,t,m,ctx)) goto err;
+ r=1;
+err:
+ BN_CTX_end(ctx);
+ return(r);
+ }
+
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+ BN_CTX *ctx)
+ {
+ int ret;
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+#ifdef MONT_MUL_MOD
+ /* I have finally been able to take out this pre-condition of
+ * the top bit being set. It was caused by an error in BN_div
+ * with negatives. There was also another problem when for a^b%m
+ * a >= m. eay 07-May-97 */
+/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
+
+ if (BN_is_odd(m))
+ {
+ if (a->top == 1)
+ {
+ BN_ULONG A = a->d[0];
+ ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
+ }
+ else
+ ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL);
+ }
+ else
+#endif
+#ifdef RECP_MUL_MOD
+ { ret=BN_mod_exp_recp(r,a,p,m,ctx); }
+#else
+ { ret=BN_mod_exp_simple(r,a,p,m,ctx); }
+#endif
+
+ return(ret);
+ }
+
+
+#ifdef RECP_MUL_MOD
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ int i,j,bits,ret=0,wstart,wend,window,wvalue;
+ int start=1,ts=0;
+ BIGNUM *aa;
+ BIGNUM val[TABLE_SIZE];
+ BN_RECP_CTX recp;
+
+ bits=BN_num_bits(p);
+
+ if (bits == 0)
+ {
+ BN_one(r);
+ return(1);
+ }
+
+ BN_CTX_start(ctx);
+ if ((aa = BN_CTX_get(ctx)) == NULL) goto err;
+
+ BN_RECP_CTX_init(&recp);
+ if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
+
+ BN_init(&(val[0]));
+ ts=1;
+
+ if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */
+
+ window = BN_window_bits_for_exponent_size(bits);
+ if (window > 1)
+ {
+ if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
+ goto err; /* 2 */
+ j=1<<(window-1);
+ for (i=1; i<j; i++)
+ {
+ BN_init(&val[i]);
+ if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))
+ goto err;
+ }
+ ts=i;
+ }
+
+ start=1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue=0; /* The 'value' of the window */
+ wstart=bits-1; /* The top bit of the window */
+ wend=0; /* The bottom bit of the window */
+
+ if (!BN_one(r)) goto err;
+
+ for (;;)
+ {
+ if (BN_is_bit_set(p,wstart) == 0)
+ {
+ if (!start)
+ if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+ goto err;
+ if (wstart == 0) break;
+ wstart--;
+ continue;
+ }
+ /* We now have wstart on a 'set' bit, we now need to work out
+ * how bit a window to do. To do this we need to scan
+ * forward until the last set bit before the end of the
+ * window */
+ j=wstart;
+ wvalue=1;
+ wend=0;
+ for (i=1; i<window; i++)
+ {
+ if (wstart-i < 0) break;
+ if (BN_is_bit_set(p,wstart-i))
+ {
+ wvalue<<=(i-wend);
+ wvalue|=1;
+ wend=i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j=wend+1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i=0; i<j; i++)
+ {
+ if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart-=wend+1;
+ wvalue=0;
+ start=0;
+ if (wstart < 0) break;
+ }
+ ret=1;
+err:
+ BN_CTX_end(ctx);
+ for (i=0; i<ts; i++)
+ BN_clear_free(&(val[i]));
+ BN_RECP_CTX_free(&recp);
+ return(ret);
+ }
+#else
+
+/* The old fallback, simple version :-) */
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0;
+ int start=1;
+ BIGNUM *d;
+ BIGNUM val[TABLE_SIZE];
+
+ bits=BN_num_bits(p);
+
+ if (bits == 0)
+ {
+ BN_one(r);
+ return(1);
+ }
+
+ BN_CTX_start(ctx);
+ if ((d = BN_CTX_get(ctx)) == NULL) goto err;
+
+ BN_init(&(val[0]));
+ ts=1;
+ if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */
+
+ window = BN_window_bits_for_exponent_size(bits);
+ if (window > 1)
+ {
+ if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx))
+ goto err; /* 2 */
+ j=1<<(window-1);
+ for (i=1; i<j; i++)
+ {
+ BN_init(&(val[i]));
+ if (!BN_mod_mul(&(val[i]),&(val[i-1]),d,m,ctx))
+ goto err;
+ }
+ ts=i;
+ }
+
+ start=1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue=0; /* The 'value' of the window */
+ wstart=bits-1; /* The top bit of the window */
+ wend=0; /* The bottom bit of the window */
+
+ if (!BN_one(r)) goto err;
+
+ for (;;)
+ {
+ if (BN_is_bit_set(p,wstart) == 0)
+ {
+ if (!start)
+ if (!BN_mod_mul(r,r,r,m,ctx))
+ goto err;
+ if (wstart == 0) break;
+ wstart--;
+ continue;
+ }
+ /* We now have wstart on a 'set' bit, we now need to work out
+ * how bit a window to do. To do this we need to scan
+ * forward until the last set bit before the end of the
+ * window */
+ j=wstart;
+ wvalue=1;
+ wend=0;
+ for (i=1; i<window; i++)
+ {
+ if (wstart-i < 0) break;
+ if (BN_is_bit_set(p,wstart-i))
+ {
+ wvalue<<=(i-wend);
+ wvalue|=1;
+ wend=i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j=wend+1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i=0; i<j; i++)
+ {
+ if (!BN_mod_mul(r,r,r,m,ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul(r,r,&(val[wvalue>>1]),m,ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart-=wend+1;
+ wvalue=0;
+ start=0;
+ if (wstart < 0) break;
+ }
+ ret=1;
+err:
+ BN_CTX_end(ctx);
+ for (i=0; i<ts; i++)
+ BN_clear_free(&(val[i]));
+ return(ret);
+ }
+#endif
diff --git a/package/network/services/ead/src/tinysrp/bn_lcl.h b/package/network/services/ead/src/tinysrp/bn_lcl.h
new file mode 100644
index 0000000..129ad65
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_lcl.h
@@ -0,0 +1,419 @@
+/* crypto/bn/bn_lcl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_BN_LCL_H
+#define HEADER_BN_LCL_H
+
+#include <bn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
+ *
+ *
+ * For window size 'w' (w >= 2) and a random 'b' bits exponent,
+ * the number of multiplications is a constant plus on average
+ *
+ * 2^(w-1) + (b-w)/(w+1);
+ *
+ * here 2^(w-1) is for precomputing the table (we actually need
+ * entries only for windows that have the lowest bit set), and
+ * (b-w)/(w+1) is an approximation for the expected number of
+ * w-bit windows, not counting the first one.
+ *
+ * Thus we should use
+ *
+ * w >= 6 if b > 671
+ * w = 5 if 671 > b > 239
+ * w = 4 if 239 > b > 79
+ * w = 3 if 79 > b > 23
+ * w <= 2 if 23 > b
+ *
+ * (with draws in between). Very small exponents are often selected
+ * with low Hamming weight, so we use w = 1 for b <= 23.
+ */
+#if 1
+#define BN_window_bits_for_exponent_size(b) \
+ ((b) > 671 ? 6 : \
+ (b) > 239 ? 5 : \
+ (b) > 79 ? 4 : \
+ (b) > 23 ? 3 : 1)
+#else
+/* Old SSLeay/OpenSSL table.
+ * Maximum window size was 5, so this table differs for b==1024;
+ * but it coincides for other interesting values (b==160, b==512).
+ */
+#define BN_window_bits_for_exponent_size(b) \
+ ((b) > 255 ? 5 : \
+ (b) > 127 ? 4 : \
+ (b) > 17 ? 3 : 1)
+#endif
+
+
+
+/* Pentium pro 16,16,16,32,64 */
+/* Alpha 16,16,16,16.64 */
+#define BN_MULL_SIZE_NORMAL (16) /* 32 */
+#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 less than */
+#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */
+#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
+#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
+
+#if !defined(NO_ASM) && !defined(NO_INLINE_ASM) && !defined(PEDANTIC)
+/*
+ * BN_UMULT_HIGH section.
+ *
+ * No, I'm not trying to overwhelm you when stating that the
+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
+ * you to be impressed when I say that if the compiler doesn't
+ * support 2*N integer type, then you have to replace every N*N
+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
+ * and additions which unavoidably results in severe performance
+ * penalties. Of course provided that the hardware is capable of
+ * producing 2*N result... That's when you normally start
+ * considering assembler implementation. However! It should be
+ * pointed out that some CPUs (most notably Alpha, PowerPC and
+ * upcoming IA-64 family:-) provide *separate* instruction
+ * calculating the upper half of the product placing the result
+ * into a general purpose register. Now *if* the compiler supports
+ * inline assembler, then it's not impossible to implement the
+ * "bignum" routines (and have the compiler optimize 'em)
+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
+ * macro is about:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+# if defined(__DECC)
+# include <c_asm.h>
+# define BN_UMULT_HIGH(a,b) (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
+# elif defined(__GNUC__)
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("umulh %1,%2,%0" \
+ : "=r"(ret) \
+ : "r"(a), "r"(b)); \
+ ret; })
+# endif /* compiler */
+# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
+# if defined(__GNUC__)
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("mulhdu %0,%1,%2" \
+ : "=r"(ret) \
+ : "r"(a), "r"(b)); \
+ ret; })
+# endif /* compiler */
+# endif /* cpu */
+#endif /* NO_ASM */
+
+/*************************************************************
+ * Using the long long type
+ */
+#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
+#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+/* This is used for internal error checking and is not normally used */
+#ifdef BN_DEBUG
+# include <assert.h>
+# define bn_check_top(a) assert ((a)->top >= 0 && (a)->top <= (a)->dmax);
+#else
+# define bn_check_top(a)
+#endif
+
+/* This macro is to add extra stuff for development checking */
+#ifdef BN_DEBUG
+#define bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA))
+#else
+#define bn_set_max(r)
+#endif
+
+/* These macros are used to 'take' a section of a bignum for read only use */
+#define bn_set_low(r,a,n) \
+ { \
+ (r)->top=((a)->top > (n))?(n):(a)->top; \
+ (r)->d=(a)->d; \
+ (r)->neg=(a)->neg; \
+ (r)->flags|=BN_FLG_STATIC_DATA; \
+ bn_set_max(r); \
+ }
+
+#define bn_set_high(r,a,n) \
+ { \
+ if ((a)->top > (n)) \
+ { \
+ (r)->top=(a)->top-n; \
+ (r)->d= &((a)->d[n]); \
+ } \
+ else \
+ (r)->top=0; \
+ (r)->neg=(a)->neg; \
+ (r)->flags|=BN_FLG_STATIC_DATA; \
+ bn_set_max(r); \
+ }
+
+#ifdef BN_LLONG
+#define mul_add(r,a,w,c) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)w * (a) + (r) + (c); \
+ (r)= Lw(t); \
+ (c)= Hw(t); \
+ }
+
+#define mul(r,a,w,c) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)w * (a) + (c); \
+ (r)= Lw(t); \
+ (c)= Hw(t); \
+ }
+
+#define sqr(r0,r1,a) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)(a)*(a); \
+ (r0)=Lw(t); \
+ (r1)=Hw(t); \
+ }
+
+#elif defined(BN_UMULT_HIGH)
+#define mul_add(r,a,w,c) { \
+ BN_ULONG high,low,ret,tmp=(a); \
+ ret = (r); \
+ high= BN_UMULT_HIGH(w,tmp); \
+ ret += (c); \
+ low = (w) * tmp; \
+ (c) = (ret<(c))?1:0; \
+ (c) += high; \
+ ret += low; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+#define mul(r,a,w,c) { \
+ BN_ULONG high,low,ret,ta=(a); \
+ low = (w) * ta; \
+ high= BN_UMULT_HIGH(w,ta); \
+ ret = low + (c); \
+ (c) = high; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+#define sqr(r0,r1,a) { \
+ BN_ULONG tmp=(a); \
+ (r0) = tmp * tmp; \
+ (r1) = BN_UMULT_HIGH(tmp,tmp); \
+ }
+
+#else
+/*************************************************************
+ * No long long type
+ */
+
+#define LBITS(a) ((a)&BN_MASK2l)
+#define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l)
+#define L2HBITS(a) ((BN_ULONG)((a)&BN_MASK2l)<<BN_BITS4)
+
+#define LLBITS(a) ((a)&BN_MASKl)
+#define LHBITS(a) (((a)>>BN_BITS2)&BN_MASKl)
+#define LL2HBITS(a) ((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
+
+#define mul64(l,h,bl,bh) \
+ { \
+ BN_ULONG m,m1,lt,ht; \
+ \
+ lt=l; \
+ ht=h; \
+ m =(bh)*(lt); \
+ lt=(bl)*(lt); \
+ m1=(bl)*(ht); \
+ ht =(bh)*(ht); \
+ m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS(1L); \
+ ht+=HBITS(m); \
+ m1=L2HBITS(m); \
+ lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
+ (l)=lt; \
+ (h)=ht; \
+ }
+
+#define sqr64(lo,ho,in) \
+ { \
+ BN_ULONG l,h,m; \
+ \
+ h=(in); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ m =(l)*(h); \
+ l*=l; \
+ h*=h; \
+ h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
+ m =(m&BN_MASK2l)<<(BN_BITS4+1); \
+ l=(l+m)&BN_MASK2; if (l < m) h++; \
+ (lo)=l; \
+ (ho)=h; \
+ }
+
+#define mul_add(r,a,bl,bh,c) { \
+ BN_ULONG l,h; \
+ \
+ h= (a); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ mul64(l,h,(bl),(bh)); \
+ \
+ /* non-multiply part */ \
+ l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+ (c)=(r); \
+ l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+ (c)=h&BN_MASK2; \
+ (r)=l; \
+ }
+
+#define mul(r,a,bl,bh,c) { \
+ BN_ULONG l,h; \
+ \
+ h= (a); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ mul64(l,h,(bl),(bh)); \
+ \
+ /* non-multiply part */ \
+ l+=(c); if ((l&BN_MASK2) < (c)) h++; \
+ (c)=h&BN_MASK2; \
+ (r)=l&BN_MASK2; \
+ }
+#endif /* !BN_LLONG */
+
+void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
+void bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r,BN_ULONG *a);
+void bn_sqr_comba4(BN_ULONG *r,BN_ULONG *a);
+int bn_cmp_words(BN_ULONG *a,BN_ULONG *b,int n);
+void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,BN_ULONG *t);
+void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
+ int tn, int n,BN_ULONG *t);
+void bn_sqr_recursive(BN_ULONG *r,BN_ULONG *a, int n2, BN_ULONG *t);
+void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
+void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
+ BN_ULONG *t);
+void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2,
+ BN_ULONG *t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/package/network/services/ead/src/tinysrp/bn_lib.c b/package/network/services/ead/src/tinysrp/bn_lib.c
new file mode 100644
index 0000000..cfa0d75
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_lib.c
@@ -0,0 +1,576 @@
+/* crypto/bn/bn_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "bn_lcl.h"
+
+const char *BN_version="Big Number";
+
+/* For a 32 bit machine
+ * 2 - 4 == 128
+ * 3 - 8 == 256
+ * 4 - 16 == 512
+ * 5 - 32 == 1024
+ * 6 - 64 == 2048
+ * 7 - 128 == 4096
+ * 8 - 256 == 8192
+ */
+static int bn_limit_bits=0;
+static int bn_limit_num=8; /* (1<<bn_limit_bits) */
+static int bn_limit_bits_low=0;
+static int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */
+static int bn_limit_bits_high=0;
+static int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */
+static int bn_limit_bits_mont=0;
+static int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */
+
+int BN_num_bits_word(BN_ULONG l)
+ {
+ static const char bits[256]={
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ };
+
+#if defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xffffffff00000000L)
+ {
+ if (l & 0xffff000000000000L)
+ {
+ if (l & 0xff00000000000000L)
+ {
+ return(bits[(int)(l>>56)]+56);
+ }
+ else return(bits[(int)(l>>48)]+48);
+ }
+ else
+ {
+ if (l & 0x0000ff0000000000L)
+ {
+ return(bits[(int)(l>>40)]+40);
+ }
+ else return(bits[(int)(l>>32)]+32);
+ }
+ }
+ else
+#else
+#ifdef SIXTY_FOUR_BIT
+ if (l & 0xffffffff00000000LL)
+ {
+ if (l & 0xffff000000000000LL)
+ {
+ if (l & 0xff00000000000000LL)
+ {
+ return(bits[(int)(l>>56)]+56);
+ }
+ else return(bits[(int)(l>>48)]+48);
+ }
+ else
+ {
+ if (l & 0x0000ff0000000000LL)
+ {
+ return(bits[(int)(l>>40)]+40);
+ }
+ else return(bits[(int)(l>>32)]+32);
+ }
+ }
+ else
+#endif
+#endif
+ {
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xffff0000L)
+ {
+ if (l & 0xff000000L)
+ return(bits[(int)(l>>24L)]+24);
+ else return(bits[(int)(l>>16L)]+16);
+ }
+ else
+#endif
+ {
+#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xff00L)
+ return(bits[(int)(l>>8)]+8);
+ else
+#endif
+ return(bits[(int)(l )] );
+ }
+ }
+ }
+
+int BN_num_bits(const BIGNUM *a)
+ {
+ BN_ULONG l;
+ int i;
+
+ bn_check_top(a);
+
+ if (a->top == 0) return(0);
+ l=a->d[a->top-1];
+ assert(l != 0);
+ i=(a->top-1)*BN_BITS2;
+ return(i+BN_num_bits_word(l));
+ }
+
+void BN_clear_free(BIGNUM *a)
+ {
+ int i;
+
+ if (a == NULL) return;
+ if (a->d != NULL)
+ {
+ memset(a->d,0,a->dmax*sizeof(a->d[0]));
+ if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+ free(a->d);
+ }
+ i=BN_get_flags(a,BN_FLG_MALLOCED);
+ memset(a,0,sizeof(BIGNUM));
+ if (i)
+ free(a);
+ }
+
+void BN_free(BIGNUM *a)
+ {
+ if (a == NULL) return;
+ if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+ free(a->d);
+ a->flags|=BN_FLG_FREE; /* REMOVE? */
+ if (a->flags & BN_FLG_MALLOCED)
+ free(a);
+ }
+
+void BN_init(BIGNUM *a)
+ {
+ memset(a,0,sizeof(BIGNUM));
+ }
+
+BIGNUM *BN_new(void)
+ {
+ BIGNUM *ret;
+
+ if ((ret=(BIGNUM *)malloc(sizeof(BIGNUM))) == NULL)
+ {
+ return(NULL);
+ }
+ ret->flags=BN_FLG_MALLOCED;
+ ret->top=0;
+ ret->neg=0;
+ ret->dmax=0;
+ ret->d=NULL;
+ return(ret);
+ }
+
+/* This is an internal function that should not be used in applications.
+ * It ensures that 'b' has enough room for a 'words' word number number.
+ * It is mostly used by the various BIGNUM routines. If there is an error,
+ * NULL is returned. If not, 'b' is returned. */
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+ {
+ BN_ULONG *A,*a;
+ const BN_ULONG *B;
+ int i;
+
+ bn_check_top(b);
+
+ if (words > b->dmax)
+ {
+ bn_check_top(b);
+ if (BN_get_flags(b,BN_FLG_STATIC_DATA))
+ {
+ return(NULL);
+ }
+ a=A=(BN_ULONG *)malloc(sizeof(BN_ULONG)*(words+1));
+ if (A == NULL)
+ {
+ return(NULL);
+ }
+#if 1
+ B=b->d;
+ /* Check if the previous number needs to be copied */
+ if (B != NULL)
+ {
+#if 0
+ /* This lot is an unrolled loop to copy b->top
+ * BN_ULONGs from B to A
+ */
+/*
+ * I have nothing against unrolling but it's usually done for
+ * several reasons, namely:
+ * - minimize percentage of decision making code, i.e. branches;
+ * - avoid cache trashing;
+ * - make it possible to schedule loads earlier;
+ * Now let's examine the code below. The cornerstone of C is
+ * "programmer is always right" and that's what we love it for:-)
+ * For this very reason C compilers have to be paranoid when it
+ * comes to data aliasing and assume the worst. Yeah, but what
+ * does it mean in real life? This means that loop body below will
+ * be compiled to sequence of loads immediately followed by stores
+ * as compiler assumes the worst, something in A==B+1 style. As a
+ * result CPU pipeline is going to starve for incoming data. Secondly
+ * if A and B happen to share same cache line such code is going to
+ * cause severe cache trashing. Both factors have severe impact on
+ * performance of modern CPUs and this is the reason why this
+ * particular piece of code is #ifdefed away and replaced by more
+ * "friendly" version found in #else section below. This comment
+ * also applies to BN_copy function.
+ *
+ * <appro@fy.chalmers.se>
+ */
+ for (i=b->top&(~7); i>0; i-=8)
+ {
+ A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
+ A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
+ A+=8;
+ B+=8;
+ }
+ switch (b->top&7)
+ {
+ case 7:
+ A[6]=B[6];
+ case 6:
+ A[5]=B[5];
+ case 5:
+ A[4]=B[4];
+ case 4:
+ A[3]=B[3];
+ case 3:
+ A[2]=B[2];
+ case 2:
+ A[1]=B[1];
+ case 1:
+ A[0]=B[0];
+ case 0:
+ /* I need the 'case 0' entry for utrix cc.
+ * If the optimizer is turned on, it does the
+ * switch table by doing
+ * a=top&7
+ * a--;
+ * goto jump_table[a];
+ * If top is 0, this makes us jump to 0xffffffc
+ * which is rather bad :-(.
+ * eric 23-Apr-1998
+ */
+ ;
+ }
+#else
+ for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+ {
+ /*
+ * The fact that the loop is unrolled
+ * 4-wise is a tribute to Intel. It's
+ * the one that doesn't have enough
+ * registers to accomodate more data.
+ * I'd unroll it 8-wise otherwise:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+ BN_ULONG a0,a1,a2,a3;
+ a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+ A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+ }
+ switch (b->top&3)
+ {
+ case 3: A[2]=B[2];
+ case 2: A[1]=B[1];
+ case 1: A[0]=B[0];
+ case 0: ; /* ultrix cc workaround, see above */
+ }
+#endif
+ free(b->d);
+ }
+
+ b->d=a;
+ b->dmax=words;
+
+ /* Now need to zero any data between b->top and b->max */
+
+ A= &(b->d[b->top]);
+ for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
+ {
+ A[0]=0; A[1]=0; A[2]=0; A[3]=0;
+ A[4]=0; A[5]=0; A[6]=0; A[7]=0;
+ }
+ for (i=(b->dmax - b->top)&7; i>0; i--,A++)
+ A[0]=0;
+#else
+ memset(A,0,sizeof(BN_ULONG)*(words+1));
+ memcpy(A,b->d,sizeof(b->d[0])*b->top);
+ b->d=a;
+ b->max=words;
+#endif
+
+/* memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
+/* { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
+
+ }
+ return(b);
+ }
+
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
+ {
+ int i;
+ BN_ULONG *A;
+ const BN_ULONG *B;
+
+ bn_check_top(b);
+
+ if (a == b) return(a);
+ if (bn_wexpand(a,b->top) == NULL) return(NULL);
+
+#if 1
+ A=a->d;
+ B=b->d;
+ for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+ {
+ BN_ULONG a0,a1,a2,a3;
+ a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+ A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+ }
+ switch (b->top&3)
+ {
+ case 3: A[2]=B[2];
+ case 2: A[1]=B[1];
+ case 1: A[0]=B[0];
+ case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
+ }
+#else
+ memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
+#endif
+
+/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
+ a->top=b->top;
+ if ((a->top == 0) && (a->d != NULL))
+ a->d[0]=0;
+ a->neg=b->neg;
+ return(a);
+ }
+
+int BN_set_word(BIGNUM *a, BN_ULONG w)
+ {
+ int i,n;
+ if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
+
+ n=sizeof(BN_ULONG)/BN_BYTES;
+ a->neg=0;
+ a->top=0;
+ a->d[0]=(BN_ULONG)w&BN_MASK2;
+ if (a->d[0] != 0) a->top=1;
+ for (i=1; i<n; i++)
+ {
+ /* the following is done instead of
+ * w>>=BN_BITS2 so compilers don't complain
+ * on builds where sizeof(long) == BN_TYPES */
+#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
+ w>>=BN_BITS4;
+ w>>=BN_BITS4;
+#else
+ w=0;
+#endif
+ a->d[i]=(BN_ULONG)w&BN_MASK2;
+ if (a->d[i] != 0) a->top=i+1;
+ }
+ return(1);
+ }
+
+/* ignore negative */
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+ {
+ unsigned int i,m;
+ unsigned int n;
+ BN_ULONG l;
+
+ if (ret == NULL) ret=BN_new();
+ if (ret == NULL) return(NULL);
+ l=0;
+ n=len;
+ if (n == 0)
+ {
+ ret->top=0;
+ return(ret);
+ }
+ if (bn_expand(ret,(int)(n+2)*8) == NULL)
+ return(NULL);
+ i=((n-1)/BN_BYTES)+1;
+ m=((n-1)%(BN_BYTES));
+ ret->top=i;
+ while (n-- > 0)
+ {
+ l=(l<<8L)| *(s++);
+ if (m-- == 0)
+ {
+ ret->d[--i]=l;
+ l=0;
+ m=BN_BYTES-1;
+ }
+ }
+ /* need to call this due to clear byte at top if avoiding
+ * having the top bit set (-ve number) */
+ bn_fix_top(ret);
+ return(ret);
+ }
+
+/* ignore negative */
+int BN_bn2bin(const BIGNUM *a, unsigned char *to)
+ {
+ int n,i;
+ BN_ULONG l;
+
+ n=i=BN_num_bytes(a);
+ while (i-- > 0)
+ {
+ l=a->d[i/BN_BYTES];
+ *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
+ }
+ return(n);
+ }
+
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
+ {
+ int i;
+ BN_ULONG t1,t2,*ap,*bp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ i=a->top-b->top;
+ if (i != 0) return(i);
+ ap=a->d;
+ bp=b->d;
+ for (i=a->top-1; i>=0; i--)
+ {
+ t1= ap[i];
+ t2= bp[i];
+ if (t1 != t2)
+ return(t1 > t2?1:-1);
+ }
+ return(0);
+ }
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b)
+ {
+ int i;
+ int gt,lt;
+ BN_ULONG t1,t2;
+
+ if ((a == NULL) || (b == NULL))
+ {
+ if (a != NULL)
+ return(-1);
+ else if (b != NULL)
+ return(1);
+ else
+ return(0);
+ }
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->neg != b->neg)
+ {
+ if (a->neg)
+ return(-1);
+ else return(1);
+ }
+ if (a->neg == 0)
+ { gt=1; lt= -1; }
+ else { gt= -1; lt=1; }
+
+ if (a->top > b->top) return(gt);
+ if (a->top < b->top) return(lt);
+ for (i=a->top-1; i>=0; i--)
+ {
+ t1=a->d[i];
+ t2=b->d[i];
+ if (t1 > t2) return(gt);
+ if (t1 < t2) return(lt);
+ }
+ return(0);
+ }
+
+int BN_is_bit_set(const BIGNUM *a, int n)
+ {
+ int i,j;
+
+ if (n < 0) return(0);
+ i=n/BN_BITS2;
+ j=n%BN_BITS2;
+ if (a->top <= i) return(0);
+ return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
+ }
diff --git a/package/network/services/ead/src/tinysrp/bn_mul.c b/package/network/services/ead/src/tinysrp/bn_mul.c
new file mode 100644
index 0000000..92330e5
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_mul.c
@@ -0,0 +1,172 @@
+/* crypto/bn/bn_mul.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "bn_lcl.h"
+
+int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+ {
+ int top,al,bl;
+ BIGNUM *rr;
+ int ret = 0;
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ int i;
+#endif
+
+#ifdef BN_COUNT
+ printf("BN_mul %d * %d\n",a->top,b->top);
+#endif
+
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(r);
+
+ al=a->top;
+ bl=b->top;
+
+ if ((al == 0) || (bl == 0))
+ {
+ BN_zero(r);
+ return(1);
+ }
+ top=al+bl;
+
+ BN_CTX_start(ctx);
+ if ((r == a) || (r == b))
+ {
+ if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
+ }
+ else
+ rr = r;
+ rr->neg=a->neg^b->neg;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ i = al-bl;
+#endif
+#ifdef BN_MUL_COMBA
+ if (i == 0)
+ {
+# if 0
+ if (al == 4)
+ {
+ if (bn_wexpand(rr,8) == NULL) goto err;
+ rr->top=8;
+ bn_mul_comba4(rr->d,a->d,b->d);
+ goto end;
+ }
+# endif
+ if (al == 8)
+ {
+ if (bn_wexpand(rr,16) == NULL) goto err;
+ rr->top=16;
+ bn_mul_comba8(rr->d,a->d,b->d);
+ goto end;
+ }
+ }
+#endif /* BN_MUL_COMBA */
+ if (bn_wexpand(rr,top) == NULL) goto err;
+ rr->top=top;
+ bn_mul_normal(rr->d,a->d,al,b->d,bl);
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+end:
+#endif
+ bn_fix_top(rr);
+ if (r != rr) BN_copy(r,rr);
+ ret=1;
+err:
+ BN_CTX_end(ctx);
+ return(ret);
+ }
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
+ {
+ BN_ULONG *rr;
+
+#ifdef BN_COUNT
+ printf(" bn_mul_normal %d * %d\n",na,nb);
+#endif
+
+ if (na < nb)
+ {
+ int itmp;
+ BN_ULONG *ltmp;
+
+ itmp=na; na=nb; nb=itmp;
+ ltmp=a; a=b; b=ltmp;
+
+ }
+ rr= &(r[na]);
+ rr[0]=bn_mul_words(r,a,na,b[0]);
+
+ for (;;)
+ {
+ if (--nb <= 0) return;
+ rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
+ if (--nb <= 0) return;
+ rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
+ if (--nb <= 0) return;
+ rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
+ if (--nb <= 0) return;
+ rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
+ rr+=4;
+ r+=4;
+ b+=4;
+ }
+ }
diff --git a/package/network/services/ead/src/tinysrp/bn_prime.h b/package/network/services/ead/src/tinysrp/bn_prime.h
new file mode 100644
index 0000000..b7cf9a9
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_prime.h
@@ -0,0 +1,325 @@
+/* Auto generated by bn_prime.pl */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef EIGHT_BIT
+#define NUMPRIMES 2048
+#else
+#define NUMPRIMES 54
+#endif
+static const unsigned int primes[NUMPRIMES]=
+ {
+ 2, 3, 5, 7, 11, 13, 17, 19,
+ 23, 29, 31, 37, 41, 43, 47, 53,
+ 59, 61, 67, 71, 73, 79, 83, 89,
+ 97, 101, 103, 107, 109, 113, 127, 131,
+ 137, 139, 149, 151, 157, 163, 167, 173,
+ 179, 181, 191, 193, 197, 199, 211, 223,
+ 227, 229, 233, 239, 241, 251,
+#ifndef EIGHT_BIT
+ 257, 263,
+ 269, 271, 277, 281, 283, 293, 307, 311,
+ 313, 317, 331, 337, 347, 349, 353, 359,
+ 367, 373, 379, 383, 389, 397, 401, 409,
+ 419, 421, 431, 433, 439, 443, 449, 457,
+ 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569,
+ 571, 577, 587, 593, 599, 601, 607, 613,
+ 617, 619, 631, 641, 643, 647, 653, 659,
+ 661, 673, 677, 683, 691, 701, 709, 719,
+ 727, 733, 739, 743, 751, 757, 761, 769,
+ 773, 787, 797, 809, 811, 821, 823, 827,
+ 829, 839, 853, 857, 859, 863, 877, 881,
+ 883, 887, 907, 911, 919, 929, 937, 941,
+ 947, 953, 967, 971, 977, 983, 991, 997,
+ 1009,1013,1019,1021,1031,1033,1039,1049,
+ 1051,1061,1063,1069,1087,1091,1093,1097,
+ 1103,1109,1117,1123,1129,1151,1153,1163,
+ 1171,1181,1187,1193,1201,1213,1217,1223,
+ 1229,1231,1237,1249,1259,1277,1279,1283,
+ 1289,1291,1297,1301,1303,1307,1319,1321,
+ 1327,1361,1367,1373,1381,1399,1409,1423,
+ 1427,1429,1433,1439,1447,1451,1453,1459,
+ 1471,1481,1483,1487,1489,1493,1499,1511,
+ 1523,1531,1543,1549,1553,1559,1567,1571,
+ 1579,1583,1597,1601,1607,1609,1613,1619,
+ 1621,1627,1637,1657,1663,1667,1669,1693,
+ 1697,1699,1709,1721,1723,1733,1741,1747,
+ 1753,1759,1777,1783,1787,1789,1801,1811,
+ 1823,1831,1847,1861,1867,1871,1873,1877,
+ 1879,1889,1901,1907,1913,1931,1933,1949,
+ 1951,1973,1979,1987,1993,1997,1999,2003,
+ 2011,2017,2027,2029,2039,2053,2063,2069,
+ 2081,2083,2087,2089,2099,2111,2113,2129,
+ 2131,2137,2141,2143,2153,2161,2179,2203,
+ 2207,2213,2221,2237,2239,2243,2251,2267,
+ 2269,2273,2281,2287,2293,2297,2309,2311,
+ 2333,2339,2341,2347,2351,2357,2371,2377,
+ 2381,2383,2389,2393,2399,2411,2417,2423,
+ 2437,2441,2447,2459,2467,2473,2477,2503,
+ 2521,2531,2539,2543,2549,2551,2557,2579,
+ 2591,2593,2609,2617,2621,2633,2647,2657,
+ 2659,2663,2671,2677,2683,2687,2689,2693,
+ 2699,2707,2711,2713,2719,2729,2731,2741,
+ 2749,2753,2767,2777,2789,2791,2797,2801,
+ 2803,2819,2833,2837,2843,2851,2857,2861,
+ 2879,2887,2897,2903,2909,2917,2927,2939,
+ 2953,2957,2963,2969,2971,2999,3001,3011,
+ 3019,3023,3037,3041,3049,3061,3067,3079,
+ 3083,3089,3109,3119,3121,3137,3163,3167,
+ 3169,3181,3187,3191,3203,3209,3217,3221,
+ 3229,3251,3253,3257,3259,3271,3299,3301,
+ 3307,3313,3319,3323,3329,3331,3343,3347,
+ 3359,3361,3371,3373,3389,3391,3407,3413,
+ 3433,3449,3457,3461,3463,3467,3469,3491,
+ 3499,3511,3517,3527,3529,3533,3539,3541,
+ 3547,3557,3559,3571,3581,3583,3593,3607,
+ 3613,3617,3623,3631,3637,3643,3659,3671,
+ 3673,3677,3691,3697,3701,3709,3719,3727,
+ 3733,3739,3761,3767,3769,3779,3793,3797,
+ 3803,3821,3823,3833,3847,3851,3853,3863,
+ 3877,3881,3889,3907,3911,3917,3919,3923,
+ 3929,3931,3943,3947,3967,3989,4001,4003,
+ 4007,4013,4019,4021,4027,4049,4051,4057,
+ 4073,4079,4091,4093,4099,4111,4127,4129,
+ 4133,4139,4153,4157,4159,4177,4201,4211,
+ 4217,4219,4229,4231,4241,4243,4253,4259,
+ 4261,4271,4273,4283,4289,4297,4327,4337,
+ 4339,4349,4357,4363,4373,4391,4397,4409,
+ 4421,4423,4441,4447,4451,4457,4463,4481,
+ 4483,4493,4507,4513,4517,4519,4523,4547,
+ 4549,4561,4567,4583,4591,4597,4603,4621,
+ 4637,4639,4643,4649,4651,4657,4663,4673,
+ 4679,4691,4703,4721,4723,4729,4733,4751,
+ 4759,4783,4787,4789,4793,4799,4801,4813,
+ 4817,4831,4861,4871,4877,4889,4903,4909,
+ 4919,4931,4933,4937,4943,4951,4957,4967,
+ 4969,4973,4987,4993,4999,5003,5009,5011,
+ 5021,5023,5039,5051,5059,5077,5081,5087,
+ 5099,5101,5107,5113,5119,5147,5153,5167,
+ 5171,5179,5189,5197,5209,5227,5231,5233,
+ 5237,5261,5273,5279,5281,5297,5303,5309,
+ 5323,5333,5347,5351,5381,5387,5393,5399,
+ 5407,5413,5417,5419,5431,5437,5441,5443,
+ 5449,5471,5477,5479,5483,5501,5503,5507,
+ 5519,5521,5527,5531,5557,5563,5569,5573,
+ 5581,5591,5623,5639,5641,5647,5651,5653,
+ 5657,5659,5669,5683,5689,5693,5701,5711,
+ 5717,5737,5741,5743,5749,5779,5783,5791,
+ 5801,5807,5813,5821,5827,5839,5843,5849,
+ 5851,5857,5861,5867,5869,5879,5881,5897,
+ 5903,5923,5927,5939,5953,5981,5987,6007,
+ 6011,6029,6037,6043,6047,6053,6067,6073,
+ 6079,6089,6091,6101,6113,6121,6131,6133,
+ 6143,6151,6163,6173,6197,6199,6203,6211,
+ 6217,6221,6229,6247,6257,6263,6269,6271,
+ 6277,6287,6299,6301,6311,6317,6323,6329,
+ 6337,6343,6353,6359,6361,6367,6373,6379,
+ 6389,6397,6421,6427,6449,6451,6469,6473,
+ 6481,6491,6521,6529,6547,6551,6553,6563,
+ 6569,6571,6577,6581,6599,6607,6619,6637,
+ 6653,6659,6661,6673,6679,6689,6691,6701,
+ 6703,6709,6719,6733,6737,6761,6763,6779,
+ 6781,6791,6793,6803,6823,6827,6829,6833,
+ 6841,6857,6863,6869,6871,6883,6899,6907,
+ 6911,6917,6947,6949,6959,6961,6967,6971,
+ 6977,6983,6991,6997,7001,7013,7019,7027,
+ 7039,7043,7057,7069,7079,7103,7109,7121,
+ 7127,7129,7151,7159,7177,7187,7193,7207,
+ 7211,7213,7219,7229,7237,7243,7247,7253,
+ 7283,7297,7307,7309,7321,7331,7333,7349,
+ 7351,7369,7393,7411,7417,7433,7451,7457,
+ 7459,7477,7481,7487,7489,7499,7507,7517,
+ 7523,7529,7537,7541,7547,7549,7559,7561,
+ 7573,7577,7583,7589,7591,7603,7607,7621,
+ 7639,7643,7649,7669,7673,7681,7687,7691,
+ 7699,7703,7717,7723,7727,7741,7753,7757,
+ 7759,7789,7793,7817,7823,7829,7841,7853,
+ 7867,7873,7877,7879,7883,7901,7907,7919,
+ 7927,7933,7937,7949,7951,7963,7993,8009,
+ 8011,8017,8039,8053,8059,8069,8081,8087,
+ 8089,8093,8101,8111,8117,8123,8147,8161,
+ 8167,8171,8179,8191,8209,8219,8221,8231,
+ 8233,8237,8243,8263,8269,8273,8287,8291,
+ 8293,8297,8311,8317,8329,8353,8363,8369,
+ 8377,8387,8389,8419,8423,8429,8431,8443,
+ 8447,8461,8467,8501,8513,8521,8527,8537,
+ 8539,8543,8563,8573,8581,8597,8599,8609,
+ 8623,8627,8629,8641,8647,8663,8669,8677,
+ 8681,8689,8693,8699,8707,8713,8719,8731,
+ 8737,8741,8747,8753,8761,8779,8783,8803,
+ 8807,8819,8821,8831,8837,8839,8849,8861,
+ 8863,8867,8887,8893,8923,8929,8933,8941,
+ 8951,8963,8969,8971,8999,9001,9007,9011,
+ 9013,9029,9041,9043,9049,9059,9067,9091,
+ 9103,9109,9127,9133,9137,9151,9157,9161,
+ 9173,9181,9187,9199,9203,9209,9221,9227,
+ 9239,9241,9257,9277,9281,9283,9293,9311,
+ 9319,9323,9337,9341,9343,9349,9371,9377,
+ 9391,9397,9403,9413,9419,9421,9431,9433,
+ 9437,9439,9461,9463,9467,9473,9479,9491,
+ 9497,9511,9521,9533,9539,9547,9551,9587,
+ 9601,9613,9619,9623,9629,9631,9643,9649,
+ 9661,9677,9679,9689,9697,9719,9721,9733,
+ 9739,9743,9749,9767,9769,9781,9787,9791,
+ 9803,9811,9817,9829,9833,9839,9851,9857,
+ 9859,9871,9883,9887,9901,9907,9923,9929,
+ 9931,9941,9949,9967,9973,10007,10009,10037,
+ 10039,10061,10067,10069,10079,10091,10093,10099,
+ 10103,10111,10133,10139,10141,10151,10159,10163,
+ 10169,10177,10181,10193,10211,10223,10243,10247,
+ 10253,10259,10267,10271,10273,10289,10301,10303,
+ 10313,10321,10331,10333,10337,10343,10357,10369,
+ 10391,10399,10427,10429,10433,10453,10457,10459,
+ 10463,10477,10487,10499,10501,10513,10529,10531,
+ 10559,10567,10589,10597,10601,10607,10613,10627,
+ 10631,10639,10651,10657,10663,10667,10687,10691,
+ 10709,10711,10723,10729,10733,10739,10753,10771,
+ 10781,10789,10799,10831,10837,10847,10853,10859,
+ 10861,10867,10883,10889,10891,10903,10909,10937,
+ 10939,10949,10957,10973,10979,10987,10993,11003,
+ 11027,11047,11057,11059,11069,11071,11083,11087,
+ 11093,11113,11117,11119,11131,11149,11159,11161,
+ 11171,11173,11177,11197,11213,11239,11243,11251,
+ 11257,11261,11273,11279,11287,11299,11311,11317,
+ 11321,11329,11351,11353,11369,11383,11393,11399,
+ 11411,11423,11437,11443,11447,11467,11471,11483,
+ 11489,11491,11497,11503,11519,11527,11549,11551,
+ 11579,11587,11593,11597,11617,11621,11633,11657,
+ 11677,11681,11689,11699,11701,11717,11719,11731,
+ 11743,11777,11779,11783,11789,11801,11807,11813,
+ 11821,11827,11831,11833,11839,11863,11867,11887,
+ 11897,11903,11909,11923,11927,11933,11939,11941,
+ 11953,11959,11969,11971,11981,11987,12007,12011,
+ 12037,12041,12043,12049,12071,12073,12097,12101,
+ 12107,12109,12113,12119,12143,12149,12157,12161,
+ 12163,12197,12203,12211,12227,12239,12241,12251,
+ 12253,12263,12269,12277,12281,12289,12301,12323,
+ 12329,12343,12347,12373,12377,12379,12391,12401,
+ 12409,12413,12421,12433,12437,12451,12457,12473,
+ 12479,12487,12491,12497,12503,12511,12517,12527,
+ 12539,12541,12547,12553,12569,12577,12583,12589,
+ 12601,12611,12613,12619,12637,12641,12647,12653,
+ 12659,12671,12689,12697,12703,12713,12721,12739,
+ 12743,12757,12763,12781,12791,12799,12809,12821,
+ 12823,12829,12841,12853,12889,12893,12899,12907,
+ 12911,12917,12919,12923,12941,12953,12959,12967,
+ 12973,12979,12983,13001,13003,13007,13009,13033,
+ 13037,13043,13049,13063,13093,13099,13103,13109,
+ 13121,13127,13147,13151,13159,13163,13171,13177,
+ 13183,13187,13217,13219,13229,13241,13249,13259,
+ 13267,13291,13297,13309,13313,13327,13331,13337,
+ 13339,13367,13381,13397,13399,13411,13417,13421,
+ 13441,13451,13457,13463,13469,13477,13487,13499,
+ 13513,13523,13537,13553,13567,13577,13591,13597,
+ 13613,13619,13627,13633,13649,13669,13679,13681,
+ 13687,13691,13693,13697,13709,13711,13721,13723,
+ 13729,13751,13757,13759,13763,13781,13789,13799,
+ 13807,13829,13831,13841,13859,13873,13877,13879,
+ 13883,13901,13903,13907,13913,13921,13931,13933,
+ 13963,13967,13997,13999,14009,14011,14029,14033,
+ 14051,14057,14071,14081,14083,14087,14107,14143,
+ 14149,14153,14159,14173,14177,14197,14207,14221,
+ 14243,14249,14251,14281,14293,14303,14321,14323,
+ 14327,14341,14347,14369,14387,14389,14401,14407,
+ 14411,14419,14423,14431,14437,14447,14449,14461,
+ 14479,14489,14503,14519,14533,14537,14543,14549,
+ 14551,14557,14561,14563,14591,14593,14621,14627,
+ 14629,14633,14639,14653,14657,14669,14683,14699,
+ 14713,14717,14723,14731,14737,14741,14747,14753,
+ 14759,14767,14771,14779,14783,14797,14813,14821,
+ 14827,14831,14843,14851,14867,14869,14879,14887,
+ 14891,14897,14923,14929,14939,14947,14951,14957,
+ 14969,14983,15013,15017,15031,15053,15061,15073,
+ 15077,15083,15091,15101,15107,15121,15131,15137,
+ 15139,15149,15161,15173,15187,15193,15199,15217,
+ 15227,15233,15241,15259,15263,15269,15271,15277,
+ 15287,15289,15299,15307,15313,15319,15329,15331,
+ 15349,15359,15361,15373,15377,15383,15391,15401,
+ 15413,15427,15439,15443,15451,15461,15467,15473,
+ 15493,15497,15511,15527,15541,15551,15559,15569,
+ 15581,15583,15601,15607,15619,15629,15641,15643,
+ 15647,15649,15661,15667,15671,15679,15683,15727,
+ 15731,15733,15737,15739,15749,15761,15767,15773,
+ 15787,15791,15797,15803,15809,15817,15823,15859,
+ 15877,15881,15887,15889,15901,15907,15913,15919,
+ 15923,15937,15959,15971,15973,15991,16001,16007,
+ 16033,16057,16061,16063,16067,16069,16073,16087,
+ 16091,16097,16103,16111,16127,16139,16141,16183,
+ 16187,16189,16193,16217,16223,16229,16231,16249,
+ 16253,16267,16273,16301,16319,16333,16339,16349,
+ 16361,16363,16369,16381,16411,16417,16421,16427,
+ 16433,16447,16451,16453,16477,16481,16487,16493,
+ 16519,16529,16547,16553,16561,16567,16573,16603,
+ 16607,16619,16631,16633,16649,16651,16657,16661,
+ 16673,16691,16693,16699,16703,16729,16741,16747,
+ 16759,16763,16787,16811,16823,16829,16831,16843,
+ 16871,16879,16883,16889,16901,16903,16921,16927,
+ 16931,16937,16943,16963,16979,16981,16987,16993,
+ 17011,17021,17027,17029,17033,17041,17047,17053,
+ 17077,17093,17099,17107,17117,17123,17137,17159,
+ 17167,17183,17189,17191,17203,17207,17209,17231,
+ 17239,17257,17291,17293,17299,17317,17321,17327,
+ 17333,17341,17351,17359,17377,17383,17387,17389,
+ 17393,17401,17417,17419,17431,17443,17449,17467,
+ 17471,17477,17483,17489,17491,17497,17509,17519,
+ 17539,17551,17569,17573,17579,17581,17597,17599,
+ 17609,17623,17627,17657,17659,17669,17681,17683,
+ 17707,17713,17729,17737,17747,17749,17761,17783,
+ 17789,17791,17807,17827,17837,17839,17851,17863,
+#endif
+ };
diff --git a/package/network/services/ead/src/tinysrp/bn_shift.c b/package/network/services/ead/src/tinysrp/bn_shift.c
new file mode 100644
index 0000000..f403720
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_shift.c
@@ -0,0 +1,139 @@
+/* crypto/bn/bn_shift.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "bn_lcl.h"
+
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
+ {
+ int i,nw,lb,rb;
+ BN_ULONG *t,*f;
+ BN_ULONG l;
+
+ r->neg=a->neg;
+ if (bn_wexpand(r,a->top+(n/BN_BITS2)+1) == NULL) return(0);
+ nw=n/BN_BITS2;
+ lb=n%BN_BITS2;
+ rb=BN_BITS2-lb;
+ f=a->d;
+ t=r->d;
+ t[a->top+nw]=0;
+ if (lb == 0)
+ for (i=a->top-1; i>=0; i--)
+ t[nw+i]=f[i];
+ else
+ for (i=a->top-1; i>=0; i--)
+ {
+ l=f[i];
+ t[nw+i+1]|=(l>>rb)&BN_MASK2;
+ t[nw+i]=(l<<lb)&BN_MASK2;
+ }
+ memset(t,0,nw*sizeof(t[0]));
+/* for (i=0; i<nw; i++)
+ t[i]=0;*/
+ r->top=a->top+nw+1;
+ bn_fix_top(r);
+ return(1);
+ }
+
+int BN_rshift(BIGNUM *r, BIGNUM *a, int n)
+ {
+ int i,j,nw,lb,rb;
+ BN_ULONG *t,*f;
+ BN_ULONG l,tmp;
+
+ nw=n/BN_BITS2;
+ rb=n%BN_BITS2;
+ lb=BN_BITS2-rb;
+ if (nw > a->top || a->top == 0)
+ {
+ BN_zero(r);
+ return(1);
+ }
+ if (r != a)
+ {
+ r->neg=a->neg;
+ if (bn_wexpand(r,a->top-nw+1) == NULL) return(0);
+ }
+
+ f= &(a->d[nw]);
+ t=r->d;
+ j=a->top-nw;
+ r->top=j;
+
+ if (rb == 0)
+ {
+ for (i=j+1; i > 0; i--)
+ *(t++)= *(f++);
+ }
+ else
+ {
+ l= *(f++);
+ for (i=1; i<j; i++)
+ {
+ tmp =(l>>rb)&BN_MASK2;
+ l= *(f++);
+ *(t++) =(tmp|(l<<lb))&BN_MASK2;
+ }
+ *(t++) =(l>>rb)&BN_MASK2;
+ }
+ *t=0;
+ bn_fix_top(r);
+ return(1);
+ }
diff --git a/package/network/services/ead/src/tinysrp/bn_sqr.c b/package/network/services/ead/src/tinysrp/bn_sqr.c
new file mode 100644
index 0000000..2d3db70
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_sqr.c
@@ -0,0 +1,160 @@
+/* crypto/bn/bn_sqr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "bn_lcl.h"
+
+/* r must not be a */
+/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
+int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx)
+ {
+ int max,al;
+ int ret = 0;
+ BIGNUM *tmp,*rr;
+
+#ifdef BN_COUNT
+printf("BN_sqr %d * %d\n",a->top,a->top);
+#endif
+ bn_check_top(a);
+
+ al=a->top;
+ if (al <= 0)
+ {
+ r->top=0;
+ return(1);
+ }
+
+ BN_CTX_start(ctx);
+ rr=(a != r) ? r : BN_CTX_get(ctx);
+ tmp=BN_CTX_get(ctx);
+ if (tmp == NULL) goto err;
+
+ max=(al+al);
+ if (bn_wexpand(rr,max+1) == NULL) goto err;
+
+ r->neg=0;
+ if (al == 4)
+ {
+#ifndef BN_SQR_COMBA
+ BN_ULONG t[8];
+ bn_sqr_normal(rr->d,a->d,4,t);
+#else
+ bn_sqr_comba4(rr->d,a->d);
+#endif
+ }
+ else if (al == 8)
+ {
+#ifndef BN_SQR_COMBA
+ BN_ULONG t[16];
+ bn_sqr_normal(rr->d,a->d,8,t);
+#else
+ bn_sqr_comba8(rr->d,a->d);
+#endif
+ }
+ else
+ {
+ if (bn_wexpand(tmp,max) == NULL) goto err;
+ bn_sqr_normal(rr->d,a->d,al,tmp->d);
+ }
+
+ rr->top=max;
+ if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
+ if (rr != r) BN_copy(r,rr);
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return(ret);
+ }
+
+/* tmp must have 2*n words */
+void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp)
+ {
+ int i,j,max;
+ BN_ULONG *ap,*rp;
+
+ max=n*2;
+ ap=a;
+ rp=r;
+ rp[0]=rp[max-1]=0;
+ rp++;
+ j=n;
+
+ if (--j > 0)
+ {
+ ap++;
+ rp[j]=bn_mul_words(rp,ap,j,ap[-1]);
+ rp+=2;
+ }
+
+ for (i=n-2; i>0; i--)
+ {
+ j--;
+ ap++;
+ rp[j]=bn_mul_add_words(rp,ap,j,ap[-1]);
+ rp+=2;
+ }
+
+ bn_add_words(r,r,r,max);
+
+ /* There will not be a carry */
+
+ bn_sqr_words(tmp,a,n);
+
+ bn_add_words(r,r,tmp,max);
+ }
diff --git a/package/network/services/ead/src/tinysrp/bn_word.c b/package/network/services/ead/src/tinysrp/bn_word.c
new file mode 100644
index 0000000..7820e08
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/bn_word.c
@@ -0,0 +1,130 @@
+/* crypto/bn/bn_word.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "bn_lcl.h"
+
+int BN_add_word(BIGNUM *a, BN_ULONG w)
+ {
+ BN_ULONG l;
+ int i;
+
+ if (a->neg)
+ {
+ a->neg=0;
+ i=BN_sub_word(a,w);
+ if (!BN_is_zero(a))
+ a->neg=!(a->neg);
+ return(i);
+ }
+ w&=BN_MASK2;
+ if (bn_wexpand(a,a->top+1) == NULL) return(0);
+ i=0;
+ for (;;)
+ {
+ l=(a->d[i]+(BN_ULONG)w)&BN_MASK2;
+ a->d[i]=l;
+ if (w > l)
+ w=1;
+ else
+ break;
+ i++;
+ }
+ if (i >= a->top)
+ a->top++;
+ return(1);
+ }
+
+int BN_sub_word(BIGNUM *a, BN_ULONG w)
+ {
+ int i;
+
+ if (BN_is_zero(a) || a->neg)
+ {
+ a->neg=0;
+ i=BN_add_word(a,w);
+ a->neg=1;
+ return(i);
+ }
+
+ w&=BN_MASK2;
+ if ((a->top == 1) && (a->d[0] < w))
+ {
+ a->d[0]=w-a->d[0];
+ a->neg=1;
+ return(1);
+ }
+ i=0;
+ for (;;)
+ {
+ if (a->d[i] >= w)
+ {
+ a->d[i]-=w;
+ break;
+ }
+ else
+ {
+ a->d[i]=(a->d[i]-w)&BN_MASK2;
+ i++;
+ w=1;
+ }
+ }
+ if ((a->d[i] == 0) && (i == (a->top-1)))
+ a->top--;
+ return(1);
+ }
diff --git a/package/network/services/ead/src/tinysrp/clitest.c b/package/network/services/ead/src/tinysrp/clitest.c
new file mode 100644
index 0000000..338f41f
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/clitest.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_client.h"
+
+int
+main()
+{
+ int index;
+ struct t_client * tc;
+ struct t_preconf *tcp;
+ struct t_num s;
+ struct t_num B;
+ char username[MAXUSERLEN];
+ char hexbuf[MAXHEXPARAMLEN];
+ char buf1[MAXPARAMLEN], buf2[MAXPARAMLEN], buf3[MAXSALTLEN];
+ unsigned char cbuf[20];
+ struct t_num * A;
+ unsigned char * skey;
+ char pass[128];
+
+ printf("Enter username: ");
+ fgets(username, sizeof(username), stdin);
+ username[strlen(username) - 1] = '\0';
+ printf("Enter index (from server): ");
+ fgets(hexbuf, sizeof(hexbuf), stdin);
+ index = atoi(hexbuf);
+ tcp = t_getpreparam(index - 1);
+ printf("Enter salt (from server): ");
+ fgets(hexbuf, sizeof(hexbuf), stdin);
+ s.data = buf3;
+ s.len = t_fromb64(s.data, hexbuf);
+
+ tc = t_clientopen(username, &tcp->modulus, &tcp->generator, &s);
+ if (tc == 0) {
+ printf("invalid n, g\n");
+ exit(1);
+ }
+
+ A = t_clientgenexp(tc);
+ printf("A (to server): %s\n", t_tob64(hexbuf, A->data, A->len));
+
+ t_getpass(pass, 128, "Enter password:");
+ t_clientpasswd(tc, pass);
+
+ printf("Enter B (from server): ");
+ fgets(hexbuf, sizeof(hexbuf), stdin);
+ B.data = buf1;
+ B.len = t_fromb64(B.data, hexbuf);
+
+ skey = t_clientgetkey(tc, &B);
+ printf("Session key: %s\n", t_tohex(hexbuf, skey, 40));
+ printf("Response (to server): %s\n",
+ t_tohex(hexbuf, t_clientresponse(tc), RESPONSE_LEN));
+
+ printf("Enter server response: ");
+ fgets(hexbuf, sizeof(hexbuf), stdin);
+ hexbuf[strlen(hexbuf) - 1] = '\0';
+ t_fromhex(cbuf, hexbuf);
+
+ if (t_clientverify(tc, cbuf) == 0)
+ printf("Server authentication successful.\n");
+ else
+ printf("Server authentication failed.\n");
+
+ t_clientclose(tc);
+
+ return 0;
+}
diff --git a/package/network/services/ead/src/tinysrp/config.h.in b/package/network/services/ead/src/tinysrp/config.h.in
new file mode 100644
index 0000000..a4b50c7
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/config.h.in
@@ -0,0 +1,79 @@
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if type char is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+#undef __CHAR_UNSIGNED__
+#endif
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+#undef SHA1HANDSOFF
+
+#undef POSIX_TERMIOS
+
+#undef POSIX_SIGTYPE
+
+#undef volatile
+
+/* The number of bytes in a int. */
+#undef SIZEOF_INT
+
+/* The number of bytes in a long. */
+#undef SIZEOF_LONG
+
+/* The number of bytes in a long long. */
+#undef SIZEOF_LONG_LONG
+
+/* The number of bytes in a short. */
+#undef SIZEOF_SHORT
+
+/* Define if you have the memcpy function. */
+#undef HAVE_MEMCPY
+
+/* Define if you have the sigaction function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the <sgtty.h> header file. */
+#undef HAVE_SGTTY_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
diff --git a/package/network/services/ead/src/tinysrp/configure b/package/network/services/ead/src/tinysrp/configure
new file mode 100755
index 0000000..6ee76bf
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/configure
@@ -0,0 +1,2421 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=t_pwd.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:559: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:612: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:669: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+
+PACKAGE=libtinysrp
+
+VERSION=0.7.5
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:716: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:729: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:742: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:755: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:768: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+test "$CFLAGS" = "" && CFLAGS="-O2"
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:788: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:818: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:869: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:901: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 912 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:943: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:948: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:957: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:976: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1019: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1072: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1095: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1144: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1159 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1165: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1176 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1193 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1199: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1224: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1229 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1237: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1254 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1272 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1293 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1304: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in sgtty.h sys/ioctl.h sys/time.h termio.h termios.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1331: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1336 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1341: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1370: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1375 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1424: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1445: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 1452 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1459: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1485: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1490 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1499: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:1520: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 1527 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1538: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 1542 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_bigendian=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1573 "configure"
+#include "confdefs.h"
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:1586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_bigendian=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+ cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:1610: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1618 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(short));
+ exit(0);
+}
+EOF
+if { (eval echo configure:1629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_short=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:1649: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1657 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(int));
+ exit(0);
+}
+EOF
+if { (eval echo configure:1668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_int=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:1688: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1696 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(long));
+ exit(0);
+}
+EOF
+if { (eval echo configure:1707: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_long=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+echo $ac_n "checking size of long long""... $ac_c" 1>&6
+echo "configure:1727: checking size of long long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1735 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(long long));
+ exit(0);
+}
+EOF
+if { (eval echo configure:1746: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_long_long=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_long_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+EOF
+
+
+cat > conftest.$ac_ext <<EOF
+#line 1766 "configure"
+#include "confdefs.h"
+
+int main() {
+volatile int i;
+; return 0; }
+EOF
+if { (eval echo configure:1773: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define volatile
+EOF
+
+fi
+rm -f conftest*
+echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
+echo "configure:1786: checking whether char is unsigned" >&5
+if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$GCC" = yes; then
+ # GCC predefines this symbol on systems where it applies.
+cat > conftest.$ac_ext <<EOF
+#line 1793 "configure"
+#include "confdefs.h"
+#ifdef __CHAR_UNSIGNED__
+ yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_c_char_unsigned=yes
+else
+ rm -rf conftest*
+ ac_cv_c_char_unsigned=no
+fi
+rm -f conftest*
+
+else
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1815 "configure"
+#include "confdefs.h"
+/* volatile prevents gcc2 from optimizing the test away on sparcs. */
+#if !defined(__STDC__) || __STDC__ != 1
+#define volatile
+#endif
+main() {
+ volatile char c = 255; exit(c < 0);
+}
+EOF
+if { (eval echo configure:1825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_char_unsigned=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_char_unsigned=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6
+if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
+ cat >> confdefs.h <<\EOF
+#define __CHAR_UNSIGNED__ 1
+EOF
+
+fi
+
+
+if test "$ac_cv_c_char_unsigned" = "yes"; then
+ signed=-signed
+fi
+
+
+for ac_func in sigaction strchr memcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1857: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1862 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1885: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking POSIX signal handlers""... $ac_c" 1>&6
+echo "configure:1911: checking POSIX signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_has_posix_signals'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1916 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+extern void (*signal ()) ();
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1928: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_has_posix_signals=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_has_posix_signals=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_has_posix_signals" 1>&6
+if test $ac_cv_has_posix_signals = yes; then
+ cat >> confdefs.h <<\EOF
+#define RETSIGTYPE void
+EOF
+ cat >> confdefs.h <<\EOF
+#define POSIX_SIGTYPE 1
+EOF
+
+else
+ if test $ac_cv_type_signal = void; then
+ cat >> confdefs.h <<\EOF
+#define RETSIGTYPE void
+EOF
+
+ else
+ cat >> confdefs.h <<\EOF
+#define RETSIGTYPE int
+EOF
+
+ fi
+fi
+ac_safe=`echo "termios.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for termios.h""... $ac_c" 1>&6
+echo "configure:1964: checking for termios.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1969 "configure"
+#include "confdefs.h"
+#include <termios.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1974: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for cfsetispeed""... $ac_c" 1>&6
+echo "configure:1991: checking for cfsetispeed" >&5
+if eval "test \"`echo '$''{'ac_cv_func_cfsetispeed'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1996 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char cfsetispeed(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char cfsetispeed();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_cfsetispeed) || defined (__stub___cfsetispeed)
+choke me
+#else
+cfsetispeed();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_cfsetispeed=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_cfsetispeed=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'cfsetispeed`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define POSIX_TERMIOS 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+cat >> confdefs.h <<\EOF
+#define SHA1HANDSOFF 1
+EOF
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@LN_S@%$LN_S%g
+s%@RANLIB@%$RANLIB%g
+s%@CPP@%$CPP%g
+s%@signed@%$signed%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/package/network/services/ead/src/tinysrp/configure.in b/package/network/services/ead/src/tinysrp/configure.in
new file mode 100644
index 0000000..627d15a
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/configure.in
@@ -0,0 +1,52 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(t_pwd.h)
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(libtinysrp, 0.7.5)
+
+test "$CFLAGS" = "" && CFLAGS="-O2"
+
+dnl Checks for programs.
+
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_RANLIB
+AC_ARG_PROGRAM
+
+dnl Checks for header files.
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(sgtty.h sys/ioctl.h sys/time.h termio.h termios.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+
+AC_C_CONST
+AC_C_INLINE
+AC_HEADER_TIME
+AC_C_BIGENDIAN
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
+AC_TRY_COMPILE(, [volatile int i;], , AC_DEFINE(volatile, ))
+AC_C_CHAR_UNSIGNED
+
+AC_SUBST(signed)dnl
+if test "$ac_cv_c_char_unsigned" = "yes"; then
+ signed=-signed
+fi
+
+dnl Checks for library functions.
+
+AC_CHECK_FUNCS(sigaction strchr memcpy)
+TYPE_SIGNAL
+AC_HEADER_CHECK(termios.h,AC_FUNC_CHECK(cfsetispeed,AC_DEFINE(POSIX_TERMIOS)))
+
+dnl User options
+
+dnl Some defines for now.
+
+AC_DEFINE(SHA1HANDSOFF)
+
+AC_OUTPUT(Makefile)
diff --git a/package/network/services/ead/src/tinysrp/install-sh b/package/network/services/ead/src/tinysrp/install-sh
new file mode 100755
index 0000000..e843669
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/install-sh
@@ -0,0 +1,250 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/package/network/services/ead/src/tinysrp/missing b/package/network/services/ead/src/tinysrp/missing
new file mode 100755
index 0000000..a6abd06
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/missing
@@ -0,0 +1,134 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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, 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.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison touch file \`y.tab.c'
+ makeinfo touch the output file
+ yacc touch file \`y.tab.c'"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing - GNU libit 0.0"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acinclude.m4' or \`configure.in'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`configure.in'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acconfig.h' or \`configure.in'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ touch config.h.in
+ ;;
+
+ automake)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print \
+ | sed 's/^\(.*\).am$/touch \1.in/' \
+ | sh
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ touch y.tab.c
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/package/network/services/ead/src/tinysrp/mkinstalldirs b/package/network/services/ead/src/tinysrp/mkinstalldirs
new file mode 100755
index 0000000..3bc1836
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/mkinstalldirs
@@ -0,0 +1,39 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+
+errstatus=0
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/package/network/services/ead/src/tinysrp/srvtest.c b/package/network/services/ead/src/tinysrp/srvtest.c
new file mode 100644
index 0000000..e09d501
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/srvtest.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_server.h"
+
+int
+main(argc, argv)
+ int argc;
+ char * argv[];
+{
+ struct t_server * ts;
+ struct t_pw * tpw;
+ struct t_conf * tcnf;
+ struct t_num * B;
+ char username[MAXUSERLEN];
+ char hexbuf[MAXHEXPARAMLEN];
+ char buf[MAXPARAMLEN];
+ struct t_num A;
+ unsigned char * skey;
+ unsigned char cbuf[20];
+ FILE * fp;
+ FILE * fp2;
+ char confname[256];
+
+ printf("Enter username: ");
+ fgets(username, sizeof(username), stdin);
+ username[strlen(username) - 1] = '\0';
+ ts = t_serveropen(username);
+
+ if(ts == NULL) {
+ fprintf(stderr, "User %s not found\n", username);
+ exit(1);
+ }
+
+#if 0
+ printf("n: %s\n", t_tob64(hexbuf, ts->n.data, ts->n.len));
+ printf("g: %s\n", t_tob64(hexbuf, ts->g.data, ts->g.len));
+#endif
+ printf("index (to client): %d\n", ts->index);
+ printf("salt (to client): %s\n", t_tob64(hexbuf, ts->s.data, ts->s.len));
+
+ B = t_servergenexp(ts);
+ printf("Enter A (from client): ");
+ fgets(hexbuf, sizeof(hexbuf), stdin);
+ A.data = buf;
+ A.len = t_fromb64(A.data, hexbuf);
+
+ printf("B (to client): %s\n", t_tob64(hexbuf, B->data, B->len));
+
+ skey = t_servergetkey(ts, &A);
+ printf("Session key: %s\n", t_tohex(hexbuf, skey, 40));
+
+ /* printf("[Expected response: %s]\n", t_tohex(hexbuf, cbuf, 16)); */
+
+ printf("Enter response (from client): ");
+ fgets(hexbuf, sizeof(hexbuf), stdin);
+ hexbuf[strlen(hexbuf) - 1] = '\0';
+ t_fromhex(cbuf, hexbuf);
+
+ if(t_serververify(ts, cbuf) == 0) {
+ printf("Authentication successful.\n");
+ printf("Response (to client): %s\n",
+ t_tohex(hexbuf, t_serverresponse(ts), RESPONSE_LEN));
+ } else
+ printf("Authentication failed.\n");
+
+ t_serverclose(ts);
+
+ return 0;
+}
diff --git a/package/network/services/ead/src/tinysrp/stamp-h.in b/package/network/services/ead/src/tinysrp/stamp-h.in
new file mode 100644
index 0000000..9788f70
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/package/network/services/ead/src/tinysrp/t_client.c b/package/network/services/ead/src/tinysrp/t_client.c
new file mode 100644
index 0000000..692215a
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_client.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_client.h"
+#include "t_sha.h"
+
+_TYPE( struct t_client * )
+t_clientopen(u, n, g, s)
+ const char * u;
+ struct t_num * n;
+ struct t_num * g;
+ struct t_num * s;
+{
+ struct t_client * tc;
+ unsigned char buf1[SHA_DIGESTSIZE], buf2[SHA_DIGESTSIZE];
+ SHA1_CTX ctxt;
+ int i, validated;
+ struct t_preconf * tpc;
+
+ validated = 0;
+ if(n->len < MIN_MOD_BYTES)
+ return 0;
+ for(i = 0; i < t_getprecount(); ++i) {
+ tpc = t_getpreparam(i);
+ if(tpc->modulus.len == n->len && tpc->generator.len == g->len &&
+ memcmp(tpc->modulus.data, n->data, n->len) == 0 &&
+ memcmp(tpc->generator.data, g->data, g->len) == 0) {
+ validated = 1; /* Match found, done */
+ break;
+ }
+ }
+
+ if(validated == 0)
+ return 0;
+
+ if((tc = malloc(sizeof(struct t_client))) == 0)
+ return 0;
+
+ strncpy(tc->username, u, MAXUSERLEN);
+
+ SHA1Init(&tc->hash);
+
+ tc->n.len = n->len;
+ tc->n.data = tc->nbuf;
+ memcpy(tc->n.data, n->data, tc->n.len);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, tc->n.data, tc->n.len);
+ SHA1Final(buf1, &ctxt);
+
+ tc->g.len = g->len;
+ tc->g.data = tc->gbuf;
+ memcpy(tc->g.data, g->data, tc->g.len);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, tc->g.data, tc->g.len);
+ SHA1Final(buf2, &ctxt);
+
+ for(i = 0; i < sizeof(buf1); ++i)
+ buf1[i] ^= buf2[i];
+
+ SHA1Update(&tc->hash, buf1, sizeof(buf1));
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, tc->username, strlen(tc->username));
+ SHA1Final(buf1, &ctxt);
+
+ SHA1Update(&tc->hash, buf1, sizeof(buf1));
+
+ tc->s.len = s->len;
+ tc->s.data = tc->sbuf;
+ memcpy(tc->s.data, s->data, tc->s.len);
+
+ SHA1Update(&tc->hash, tc->s.data, tc->s.len);
+
+ tc->a.data = tc->abuf;
+ tc->A.data = tc->Abuf;
+ tc->p.data = tc->pbuf;
+ tc->v.data = tc->vbuf;
+
+ SHA1Init(&tc->ckhash);
+
+ return tc;
+}
+
+_TYPE( struct t_num * )
+t_clientgenexp(tc)
+ struct t_client * tc;
+{
+ BigInteger a, A, n, g;
+
+ if(tc->n.len < ALEN)
+ tc->a.len = tc->n.len;
+ else
+ tc->a.len = ALEN;
+
+ t_random(tc->a.data, tc->a.len);
+ a = BigIntegerFromBytes(tc->a.data, tc->a.len);
+ n = BigIntegerFromBytes(tc->n.data, tc->n.len);
+ g = BigIntegerFromBytes(tc->g.data, tc->g.len);
+ A = BigIntegerFromInt(0);
+ BigIntegerModExp(A, g, a, n);
+ tc->A.len = BigIntegerToBytes(A, tc->A.data);
+
+ BigIntegerFree(A);
+ BigIntegerFree(a);
+ BigIntegerFree(g);
+ BigIntegerFree(n);
+
+ SHA1Update(&tc->hash, tc->A.data, tc->A.len);
+ SHA1Update(&tc->ckhash, tc->A.data, tc->A.len);
+
+ return &tc->A;
+}
+
+_TYPE( void )
+t_clientpasswd(tc, password)
+ struct t_client * tc;
+ char * password;
+{
+ BigInteger n, g, p, v;
+ SHA1_CTX ctxt;
+ unsigned char dig[SHA_DIGESTSIZE];
+
+ n = BigIntegerFromBytes(tc->n.data, tc->n.len);
+ g = BigIntegerFromBytes(tc->g.data, tc->g.len);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, tc->username, strlen(tc->username));
+ SHA1Update(&ctxt, ":", 1);
+ SHA1Update(&ctxt, password, strlen(password));
+ SHA1Final(dig, &ctxt);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, tc->s.data, tc->s.len);
+ SHA1Update(&ctxt, dig, sizeof(dig));
+ SHA1Final(dig, &ctxt);
+
+ p = BigIntegerFromBytes(dig, sizeof(dig));
+
+ v = BigIntegerFromInt(0);
+ BigIntegerModExp(v, g, p, n);
+
+ tc->p.len = BigIntegerToBytes(p, tc->p.data);
+ BigIntegerFree(p);
+
+ tc->v.len = BigIntegerToBytes(v, tc->v.data);
+ BigIntegerFree(v);
+}
+
+_TYPE( unsigned char * )
+t_clientgetkey(tc, serverval)
+ struct t_client * tc;
+ struct t_num * serverval;
+{
+ BigInteger n, B, v, p, a, sum, S;
+ unsigned char sbuf[MAXPARAMLEN];
+ unsigned char dig[SHA_DIGESTSIZE];
+ unsigned slen;
+ unsigned int u;
+ SHA1_CTX ctxt;
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, serverval->data, serverval->len);
+ SHA1Final(dig, &ctxt);
+ u = (dig[0] << 24) | (dig[1] << 16) | (dig[2] << 8) | dig[3];
+ if(u == 0)
+ return NULL;
+
+ SHA1Update(&tc->hash, serverval->data, serverval->len);
+
+ B = BigIntegerFromBytes(serverval->data, serverval->len);
+ n = BigIntegerFromBytes(tc->n.data, tc->n.len);
+
+ if(BigIntegerCmp(B, n) >= 0 || BigIntegerCmpInt(B, 0) == 0) {
+ BigIntegerFree(B);
+ BigIntegerFree(n);
+ return NULL;
+ }
+ v = BigIntegerFromBytes(tc->v.data, tc->v.len);
+ if(BigIntegerCmp(B, v) < 0)
+ BigIntegerAdd(B, B, n);
+ BigIntegerSub(B, B, v);
+ BigIntegerFree(v);
+
+ a = BigIntegerFromBytes(tc->a.data, tc->a.len);
+ p = BigIntegerFromBytes(tc->p.data, tc->p.len);
+
+ sum = BigIntegerFromInt(0);
+ BigIntegerMulInt(sum, p, u);
+ BigIntegerAdd(sum, sum, a);
+
+ BigIntegerFree(p);
+ BigIntegerFree(a);
+
+ S = BigIntegerFromInt(0);
+ BigIntegerModExp(S, B, sum, n);
+ slen = BigIntegerToBytes(S, sbuf);
+
+ BigIntegerFree(S);
+ BigIntegerFree(sum);
+ BigIntegerFree(B);
+ BigIntegerFree(n);
+
+ t_sessionkey(tc->session_key, sbuf, slen);
+ memset(sbuf, 0, slen);
+
+ SHA1Update(&tc->hash, tc->session_key, sizeof(tc->session_key));
+
+ SHA1Final(tc->session_response, &tc->hash);
+ SHA1Update(&tc->ckhash, tc->session_response, sizeof(tc->session_response));
+ SHA1Update(&tc->ckhash, tc->session_key, sizeof(tc->session_key));
+
+ return tc->session_key;
+}
+
+_TYPE( int )
+t_clientverify(tc, resp)
+ struct t_client * tc;
+ unsigned char * resp;
+{
+ unsigned char expected[SHA_DIGESTSIZE];
+
+ SHA1Final(expected, &tc->ckhash);
+ return memcmp(expected, resp, sizeof(expected));
+}
+
+_TYPE( unsigned char * )
+t_clientresponse(tc)
+ struct t_client * tc;
+{
+ return tc->session_response;
+}
+
+_TYPE( void )
+t_clientclose(tc)
+ struct t_client * tc;
+{
+ memset(tc->abuf, 0, sizeof(tc->abuf));
+ memset(tc->pbuf, 0, sizeof(tc->pbuf));
+ memset(tc->vbuf, 0, sizeof(tc->vbuf));
+ memset(tc->session_key, 0, sizeof(tc->session_key));
+ free(tc);
+}
diff --git a/package/network/services/ead/src/tinysrp/t_client.h b/package/network/services/ead/src/tinysrp/t_client.h
new file mode 100644
index 0000000..42922af
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_client.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#ifndef T_CLIENT_H
+#define T_CLIENT_H
+
+#include "t_sha.h"
+
+#if !defined(P)
+#ifdef __STDC__
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+/* For building dynamic link libraries under windows, windows NT
+ * using MSVC1.5 or MSVC2.0
+ */
+
+#ifndef _DLLDECL
+#define _DLLDECL
+
+#ifdef MSVC15 /* MSVC1.5 support for 16 bit apps */
+#define _MSVC15EXPORT _export
+#define _MSVC20EXPORT
+#define _DLLAPI _export _pascal
+#define _TYPE(a) a _MSVC15EXPORT
+#define DLLEXPORT 1
+
+#elif MSVC20
+#define _MSVC15EXPORT
+#define _MSVC20EXPORT _declspec(dllexport)
+#define _DLLAPI
+#define _TYPE(a) _MSVC20EXPORT a
+#define DLLEXPORT 1
+
+#else /* Default, non-dll. Use this for Unix or DOS */
+#define _MSVC15DEXPORT
+#define _MSVC20EXPORT
+#define _DLLAPI
+#define _TYPE(a) a
+#endif
+#endif
+
+#define ALEN 32
+#define MIN_MOD_BYTES 64 /* 512 bits */
+
+struct t_client {
+ struct t_num n;
+ struct t_num g;
+ struct t_num s;
+
+ struct t_num a;
+ struct t_num A;
+
+ struct t_num p;
+ struct t_num v;
+
+ SHA1_CTX hash, ckhash;
+
+ char username[MAXUSERLEN];
+ unsigned char session_key[SESSION_KEY_LEN];
+ unsigned char session_response[RESPONSE_LEN];
+
+ unsigned char nbuf[MAXPARAMLEN], gbuf[MAXPARAMLEN], sbuf[MAXSALTLEN];
+ unsigned char pbuf[MAXPARAMLEN], vbuf[MAXPARAMLEN];
+ unsigned char abuf[ALEN], Abuf[MAXPARAMLEN];
+};
+
+/*
+ * SRP client-side negotiation
+ *
+ * This code negotiates the client side of an SRP exchange.
+ * "t_clientopen" accepts a username, and N, g, and s parameters,
+ * which are usually sent by the server in the first round.
+ * The client should then call...
+ * "t_clientgenexp" will generate a random 256-bit exponent and
+ * raise g to that power, returning the result. This result
+ * should be sent to the server as w(p).
+ * "t_clientpasswd" accepts the user's password, which should be
+ * entered locally and updates the client's state.
+ * "t_clientgetkey" accepts the exponential y(p), which should
+ * be sent by the server in the next round and computes the
+ * 256-bit session key. This data should be saved before the
+ * session is closed.
+ * "t_clientresponse" computes the session key proof as SHA(y(p), K).
+ * "t_clientclose" closes the session and frees its memory.
+ *
+ * Note that authentication is not performed per se; it is up
+ * to either/both sides of the protocol to now verify securely
+ * that their session keys agree in order to establish authenticity.
+ * One possible way is through "oracle hashing"; one side sends
+ * r, the other replies with H(r,K), where H() is a hash function.
+ *
+ * t_clientresponse and t_clientverify now implement a version of
+ * the session-key verification described above.
+ */
+_TYPE( struct t_client * )
+ t_clientopen P((const char *, struct t_num *, struct t_num *,
+ struct t_num *));
+_TYPE( struct t_num * ) t_clientgenexp P((struct t_client *));
+_TYPE( void ) t_clientpasswd P((struct t_client *, char *));
+_TYPE( unsigned char * )
+ t_clientgetkey P((struct t_client *, struct t_num *));
+_TYPE( int ) t_clientverify P((struct t_client *, unsigned char *));
+_TYPE( unsigned char * ) t_clientresponse P((struct t_client *));
+_TYPE( void ) t_clientclose P((struct t_client *));
+
+#endif
diff --git a/package/network/services/ead/src/tinysrp/t_conf.c b/package/network/services/ead/src/tinysrp/t_conf.c
new file mode 100644
index 0000000..fbe6f41
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_conf.c
@@ -0,0 +1,1080 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_read.h"
+#include "bn.h"
+#include "bn_lcl.h"
+#include "bn_prime.h"
+
+#define TABLE_SIZE 32
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+ const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
+
+/*
+ * This is the safe prime generation logic.
+ * To generate a safe prime p (where p = 2q+1 and q is prime), we start
+ * with a random odd q that is one bit shorter than the desired length
+ * of p. We use a simple 30-element sieve to filter the values of q
+ * and consider only those that are 11, 23, or 29 (mod 30). (If q were
+ * anything else, either q or p would be divisible by 2, 3, or 5).
+ * For the values of q that are left, we apply the following tests in
+ * this order:
+ *
+ * trial divide q
+ * let p = 2q + 1
+ * trial divide p
+ * apply Fermat test to q (2^q == 2 (mod q))
+ * apply Fermat test to p (2^p == 2 (mod p))
+ * apply real probablistic primality test to q
+ * apply real probablistic primality test to p
+ *
+ * A number that passes all these tests is considered a safe prime for
+ * our purposes. The tests are ordered this way for efficiency; the
+ * slower tests are run rarely if ever at all.
+ */
+
+static int
+trialdiv(x)
+ const BigInteger x;
+{
+ static int primes[] = { /* All odd primes < 256 */
+ 3, 5, 7, 11, 13, 17, 19, 23, 29,
+ 31, 37, 41, 43, 47, 53, 59, 61, 67,
+ 71, 73, 79, 83, 89, 97, 101, 103,
+ 107, 109, 113, 127, 131, 137, 139, 149, 151,
+ 157, 163, 167, 173, 179, 181, 191, 193, 197,
+ 199, 211, 223, 227, 229, 233, 239, 241, 251
+ };
+ static int nprimes = sizeof(primes) / sizeof(int);
+ int i;
+
+ for(i = 0; i < nprimes; ++i) {
+ if(BigIntegerModInt(x, primes[i]) == 0)
+ return primes[i];
+ }
+ return 1;
+}
+
+/* x + sieve30[x%30] == 11, 23, or 29 (mod 30) */
+
+static int sieve30[] =
+{ 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
+ 1, 12, 11, 10, 9, 8, 7, 6, 5, 4,
+ 3, 2, 1, 6, 5, 4, 3, 2, 1, 12
+};
+
+/* Find a Sophie-Germain prime between "lo" and "hi". NOTE: this is not
+ a "safe prime", but the smaller prime. Take 2q+1 to get the safe prime. */
+
+static void
+sophie_germain(q, lo, hi)
+ BigInteger q; /* assumed initialized */
+ const BigInteger lo;
+ const BigInteger hi;
+{
+ BigInteger m, p, r;
+ char parambuf[MAXPARAMLEN];
+ int foundprime = 0;
+ int i, mod30;
+
+ m = BigIntegerFromInt(0);
+ BigIntegerSub(m, hi, lo);
+ i = (BigIntegerBitLen(m) + 7) / 8;
+ t_random(parambuf, i);
+ r = BigIntegerFromBytes(parambuf, i);
+ BigIntegerMod(r, r, m);
+
+ BigIntegerAdd(q, r, lo);
+ if(BigIntegerModInt(q, 2) == 0)
+ BigIntegerAddInt(q, q, 1); /* make q odd */
+
+ mod30 = BigIntegerModInt(q, 30); /* mod30 = q % 30 */
+
+ BigIntegerFree(m);
+ m = BigIntegerFromInt(2); /* m = 2 */
+ p = BigIntegerFromInt(0);
+
+ while(BigIntegerCmp(q, hi) < 0) {
+ if(trialdiv(q) < 2) {
+ BigIntegerMulInt(p, q, 2); /* p = 2 * q */
+ BigIntegerAddInt(p, p, 1); /* p += 1 */
+ if(trialdiv(p) < 2) {
+ BigIntegerModExp(r, m, q, q); /* r = 2^q % q */
+ if(BigIntegerCmpInt(r, 2) == 0) { /* if(r == 2) */
+ BigIntegerModExp(r, m, p, p); /* r = 2^p % p */
+ if(BigIntegerCmpInt(r, 2) == 0) { /* if(r == 2) */
+ if(BigIntegerCheckPrime(q) && BigIntegerCheckPrime(p)) {
+ ++foundprime;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ i = sieve30[mod30];
+ BigIntegerAddInt(q, q, i); /* q += i */
+ mod30 = (mod30 + i) % 30;
+ }
+
+ /* should wrap around on failure */
+ if(!foundprime) {
+ fprintf(stderr, "Prime generation failed!\n");
+ exit(1);
+ }
+
+ BigIntegerFree(r);
+ BigIntegerFree(m);
+ BigIntegerFree(p);
+}
+
+_TYPE( struct t_confent * )
+t_makeconfent(tc, nsize)
+ struct t_conf * tc;
+ int nsize;
+{
+ BigInteger n, g, q, t, u;
+
+ t = BigIntegerFromInt(0);
+ u = BigIntegerFromInt(1); /* u = 1 */
+ BigIntegerLShift(t, u, nsize - 2); /* t = 2^(nsize-2) */
+ BigIntegerMulInt(u, t, 2); /* u = 2^(nsize-1) */
+
+ q = BigIntegerFromInt(0);
+ sophie_germain(q, t, u);
+
+ n = BigIntegerFromInt(0);
+ BigIntegerMulInt(n, q, 2);
+ BigIntegerAddInt(n, n, 1);
+
+ /* Look for a generator mod n */
+ g = BigIntegerFromInt(2);
+ while(1) {
+ BigIntegerModExp(t, g, q, n); /* t = g^q % n */
+ if(BigIntegerCmpInt(t, 1) == 0) /* if(t == 1) */
+ BigIntegerAddInt(g, g, 1); /* ++g */
+ else
+ break;
+ }
+ BigIntegerFree(t);
+ BigIntegerFree(u);
+ BigIntegerFree(q);
+
+ tc->tcbuf.modulus.data = tc->modbuf;
+ tc->tcbuf.modulus.len = BigIntegerToBytes(n, tc->tcbuf.modulus.data);
+ BigIntegerFree(n);
+
+ tc->tcbuf.generator.data = tc->genbuf;
+ tc->tcbuf.generator.len = BigIntegerToBytes(g, tc->tcbuf.generator.data);
+ BigIntegerFree(g);
+
+ tc->tcbuf.index = 1;
+ return &tc->tcbuf;
+}
+
+_TYPE( struct t_confent * )
+t_makeconfent_c(tc, nsize)
+ struct t_conf * tc;
+ int nsize;
+{
+ BigInteger g, n, p, q, j, k, t, u;
+ int psize, qsize;
+
+ psize = nsize / 2;
+ qsize = nsize - psize;
+
+ t = BigIntegerFromInt(1); /* t = 1 */
+ u = BigIntegerFromInt(0);
+ BigIntegerLShift(u, t, psize - 3); /* u = t*2^(psize-3) = 2^(psize-3) */
+ BigIntegerMulInt(t, u, 3); /* t = 3*u = 1.5*2^(psize-2) */
+ BigIntegerAdd(u, u, t); /* u += t [u = 2^(psize-1)] */
+ j = BigIntegerFromInt(0);
+ sophie_germain(j, t, u);
+
+ k = BigIntegerFromInt(0);
+ if(qsize != psize) {
+ BigIntegerFree(t);
+ t = BigIntegerFromInt(1); /* t = 1 */
+ BigIntegerLShift(u, t, qsize - 3); /* u = t*2^(qsize-3) = 2^(qsize-3) */
+ BigIntegerMulInt(t, u, 3); /* t = 3*u = 1.5*2^(qsize-2) */
+ BigIntegerAdd(u, u, t); /* u += t [u = 2^(qsize-1)] */
+ }
+ sophie_germain(k, t, u);
+
+ p = BigIntegerFromInt(0);
+ BigIntegerMulInt(p, j, 2); /* p = 2 * j */
+ BigIntegerAddInt(p, p, 1); /* p += 1 */
+
+ q = BigIntegerFromInt(0);
+ BigIntegerMulInt(q, k, 2); /* q = 2 * k */
+ BigIntegerAddInt(q, q, 1); /* q += 1 */
+
+ n = BigIntegerFromInt(0);
+ BigIntegerMul(n, p, q); /* n = p * q */
+ BigIntegerMul(u, j, k); /* u = j * k */
+
+ BigIntegerFree(p);
+ BigIntegerFree(q);
+ BigIntegerFree(j);
+ BigIntegerFree(k);
+
+ g = BigIntegerFromInt(2); /* g = 2 */
+
+ /* Look for a generator mod n */
+ while(1) {
+ BigIntegerModExp(t, g, u, n); /* t = g^u % n */
+ if(BigIntegerCmpInt(t, 1) == 0)
+ BigIntegerAddInt(g, g, 1); /* ++g */
+ else
+ break;
+ }
+
+ BigIntegerFree(u);
+ BigIntegerFree(t);
+
+ tc->tcbuf.modulus.data = tc->modbuf;
+ tc->tcbuf.modulus.len = BigIntegerToBytes(n, tc->tcbuf.modulus.data);
+ BigIntegerFree(n);
+
+ tc->tcbuf.generator.data = tc->genbuf;
+ tc->tcbuf.generator.len = BigIntegerToBytes(g, tc->tcbuf.generator.data);
+ BigIntegerFree(g);
+
+ tc->tcbuf.index = 1;
+ return &tc->tcbuf;
+}
+
+_TYPE( struct t_confent * )
+t_newconfent(tc)
+ struct t_conf * tc;
+{
+ tc->tcbuf.index = 0;
+ tc->tcbuf.modulus.data = tc->modbuf;
+ tc->tcbuf.modulus.len = 0;
+ tc->tcbuf.generator.data = tc->genbuf;
+ tc->tcbuf.generator.len = 0;
+ return &tc->tcbuf;
+}
+
+_TYPE( void )
+t_putconfent(ent, fp)
+ const struct t_confent * ent;
+ FILE * fp;
+{
+ char strbuf[MAXB64PARAMLEN];
+
+ fprintf(fp, "%d:%s:", ent->index,
+ t_tob64(strbuf, ent->modulus.data, ent->modulus.len));
+ fprintf(fp, "%s\n",
+ t_tob64(strbuf, ent->generator.data, ent->generator.len));
+}
+
+int
+BigIntegerBitLen(b)
+ BigInteger b;
+{
+ return BN_num_bits(b);
+}
+
+int
+BigIntegerCheckPrime(n)
+ BigInteger n;
+{
+ BN_CTX * ctx = BN_CTX_new();
+ int rv = BN_is_prime(n, 25, NULL, ctx, NULL);
+ BN_CTX_free(ctx);
+ return rv;
+}
+
+unsigned int
+BigIntegerModInt(d, m)
+ BigInteger d;
+ unsigned int m;
+{
+ return BN_mod_word(d, m);
+}
+
+void
+BigIntegerMod(result, d, m)
+ BigInteger result, d, m;
+{
+ BN_CTX * ctx = BN_CTX_new();
+ BN_mod(result, d, m, ctx);
+ BN_CTX_free(ctx);
+}
+
+void
+BigIntegerMul(result, m1, m2)
+ BigInteger result, m1, m2;
+{
+ BN_CTX * ctx = BN_CTX_new();
+ BN_mul(result, m1, m2, ctx);
+ BN_CTX_free(ctx);
+}
+
+void
+BigIntegerLShift(result, x, bits)
+ BigInteger result, x;
+ unsigned int bits;
+{
+ BN_lshift(result, x, bits);
+}
+
+int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *),
+ BN_CTX *ctx_passed, void *cb_arg)
+ {
+ return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0);
+ }
+
+int BN_is_prime_fasttest(const BIGNUM *a, int checks,
+ void (*callback)(int,int,void *),
+ BN_CTX *ctx_passed, void *cb_arg,
+ int do_trial_division)
+ {
+ int i, j, ret = -1;
+ int k;
+ BN_CTX *ctx = NULL;
+ BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
+ BN_MONT_CTX *mont = NULL;
+ const BIGNUM *A = NULL;
+
+ if (checks == BN_prime_checks)
+ checks = BN_prime_checks_for_size(BN_num_bits(a));
+
+ /* first look for small factors */
+ if (!BN_is_odd(a))
+ return(0);
+ if (do_trial_division)
+ {
+ for (i = 1; i < NUMPRIMES; i++)
+ if (BN_mod_word(a, primes[i]) == 0)
+ return 0;
+ if (callback != NULL) callback(1, -1, cb_arg);
+ }
+
+ if (ctx_passed != NULL)
+ ctx = ctx_passed;
+ else
+ if ((ctx=BN_CTX_new()) == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+
+ /* A := abs(a) */
+ if (a->neg)
+ {
+ BIGNUM *t;
+ if ((t = BN_CTX_get(ctx)) == NULL) goto err;
+ BN_copy(t, a);
+ t->neg = 0;
+ A = t;
+ }
+ else
+ A = a;
+ A1 = BN_CTX_get(ctx);
+ A1_odd = BN_CTX_get(ctx);
+ check = BN_CTX_get(ctx);
+ if (check == NULL) goto err;
+
+ /* compute A1 := A - 1 */
+ if (!BN_copy(A1, A))
+ goto err;
+ if (!BN_sub_word(A1, 1))
+ goto err;
+ if (BN_is_zero(A1))
+ {
+ ret = 0;
+ goto err;
+ }
+
+ /* write A1 as A1_odd * 2^k */
+ k = 1;
+ while (!BN_is_bit_set(A1, k))
+ k++;
+ if (!BN_rshift(A1_odd, A1, k))
+ goto err;
+
+ /* Montgomery setup for computations mod A */
+ mont = BN_MONT_CTX_new();
+ if (mont == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, A, ctx))
+ goto err;
+
+ for (i = 0; i < checks; i++)
+ {
+ if (!BN_pseudo_rand(check, BN_num_bits(A1), 0, 0))
+ goto err;
+ if (BN_cmp(check, A1) >= 0)
+ if (!BN_sub(check, check, A1))
+ goto err;
+ if (!BN_add_word(check, 1))
+ goto err;
+ /* now 1 <= check < A */
+
+ j = witness(check, A, A1, A1_odd, k, ctx, mont);
+ if (j == -1) goto err;
+ if (j)
+ {
+ ret=0;
+ goto err;
+ }
+ if (callback != NULL) callback(1,i,cb_arg);
+ }
+ ret=1;
+err:
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ if (ctx_passed == NULL)
+ BN_CTX_free(ctx);
+ }
+ if (mont != NULL)
+ BN_MONT_CTX_free(mont);
+
+ return(ret);
+ }
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+ const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont)
+ {
+ if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
+ return -1;
+ if (BN_is_one(w))
+ return 0; /* probably prime */
+ if (BN_cmp(w, a1) == 0)
+ return 0; /* w == -1 (mod a), 'a' is probably prime */
+ while (--k)
+ {
+ if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
+ return -1;
+ if (BN_is_one(w))
+ return 1; /* 'a' is composite, otherwise a previous 'w' would
+ * have been == -1 (mod 'a') */
+ if (BN_cmp(w, a1) == 0)
+ return 0; /* w == -1 (mod a), 'a' is probably prime */
+ }
+ /* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
+ * and it is neither -1 nor +1 -- so 'a' cannot be prime */
+ return 1;
+ }
+
+int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+ {
+ int i,j,bits,ret=0,wstart,wend,window,wvalue;
+ int start=1,ts=0;
+ BIGNUM *d,*r;
+ BIGNUM *aa;
+ BIGNUM val[TABLE_SIZE];
+ BN_MONT_CTX *mont=NULL;
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+ if (!(m->d[0] & 1))
+ {
+ return(0);
+ }
+ bits=BN_num_bits(p);
+ if (bits == 0)
+ {
+ BN_one(rr);
+ return(1);
+ }
+ BN_CTX_start(ctx);
+ d = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ if (d == NULL || r == NULL) goto err;
+
+ /* If this is not done, things will break in the montgomery
+ * part */
+
+ if (in_mont != NULL)
+ mont=in_mont;
+ else
+ {
+ if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+ if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+ }
+
+ BN_init(&val[0]);
+ ts=1;
+ if (BN_ucmp(a,m) >= 0)
+ {
+ if (!BN_mod(&(val[0]),a,m,ctx))
+ goto err;
+ aa= &(val[0]);
+ }
+ else
+ aa=a;
+ if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */
+
+ window = BN_window_bits_for_exponent_size(bits);
+ if (window > 1)
+ {
+ if (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err; /* 2 */
+ j=1<<(window-1);
+ for (i=1; i<j; i++)
+ {
+ BN_init(&(val[i]));
+ if (!BN_mod_mul_montgomery(&(val[i]),&(val[i-1]),d,mont,ctx))
+ goto err;
+ }
+ ts=i;
+ }
+
+ start=1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue=0; /* The 'value' of the window */
+ wstart=bits-1; /* The top bit of the window */
+ wend=0; /* The bottom bit of the window */
+
+ if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+ for (;;)
+ {
+ if (BN_is_bit_set(p,wstart) == 0)
+ {
+ if (!start)
+ {
+ if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+ goto err;
+ }
+ if (wstart == 0) break;
+ wstart--;
+ continue;
+ }
+ /* We now have wstart on a 'set' bit, we now need to work out
+ * how bit a window to do. To do this we need to scan
+ * forward until the last set bit before the end of the
+ * window */
+ j=wstart;
+ wvalue=1;
+ wend=0;
+ for (i=1; i<window; i++)
+ {
+ if (wstart-i < 0) break;
+ if (BN_is_bit_set(p,wstart-i))
+ {
+ wvalue<<=(i-wend);
+ wvalue|=1;
+ wend=i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j=wend+1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i=0; i<j; i++)
+ {
+ if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul_montgomery(r,r,&(val[wvalue>>1]),mont,ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart-=wend+1;
+ wvalue=0;
+ start=0;
+ if (wstart < 0) break;
+ }
+ if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
+ ret=1;
+err:
+ if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+ BN_CTX_end(ctx);
+ for (i=0; i<ts; i++)
+ BN_clear_free(&(val[i]));
+ return(ret);
+ }
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
+ {
+#ifndef BN_LLONG
+ BN_ULONG ret=0;
+#else
+ BN_ULLONG ret=0;
+#endif
+ int i;
+
+ w&=BN_MASK2;
+ for (i=a->top-1; i>=0; i--)
+ {
+#ifndef BN_LLONG
+ ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%w;
+ ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%w;
+#else
+ ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])%
+ (BN_ULLONG)w);
+#endif
+ }
+ return((BN_ULONG)ret);
+ }
+
+static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
+ {
+ unsigned char *buf=NULL;
+ int ret=0,bit,bytes,mask;
+
+ if (bits == 0)
+ {
+ BN_zero(rnd);
+ return 1;
+ }
+
+ bytes=(bits+7)/8;
+ bit=(bits-1)%8;
+ mask=0xff<<bit;
+
+ buf=(unsigned char *)malloc(bytes);
+ if (buf == NULL)
+ {
+ goto err;
+ }
+
+ /* make a random number and set the top and bottom bits */
+ /* this ignores the pseudorand flag */
+
+ t_random(buf, bytes);
+
+ if (top)
+ {
+ if (bit == 0)
+ {
+ buf[0]=1;
+ buf[1]|=0x80;
+ }
+ else
+ {
+ buf[0]|=(3<<(bit-1));
+ buf[0]&= ~(mask<<1);
+ }
+ }
+ else
+ {
+ buf[0]|=(1<<bit);
+ buf[0]&= ~(mask<<1);
+ }
+ if (bottom) /* set bottom bits to whatever odd is */
+ buf[bytes-1]|=1;
+ if (!BN_bin2bn(buf,bytes,rnd)) goto err;
+ ret=1;
+err:
+ if (buf != NULL)
+ {
+ memset(buf,0,bytes);
+ free(buf);
+ }
+ return(ret);
+ }
+
+/* BN_pseudo_rand is the same as BN_rand, now. */
+
+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
+ {
+ return bnrand(1, rnd, bits, top, bottom);
+ }
+
+#define MONT_WORD /* use the faster word-based algorithm */
+
+int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+ BN_MONT_CTX *mont, BN_CTX *ctx)
+ {
+ BIGNUM *tmp,*tmp2;
+ int ret=0;
+
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ tmp2 = BN_CTX_get(ctx);
+ if (tmp == NULL || tmp2 == NULL) goto err;
+
+ bn_check_top(tmp);
+ bn_check_top(tmp2);
+
+ if (a == b)
+ {
+ if (!BN_sqr(tmp,a,ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_mul(tmp,a,b,ctx)) goto err;
+ }
+ /* reduce from aRR to aR */
+ if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
+ ret=1;
+err:
+ BN_CTX_end(ctx);
+ return(ret);
+ }
+
+int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont,
+ BN_CTX *ctx)
+ {
+ int retn=0;
+
+#ifdef MONT_WORD
+ BIGNUM *n,*r;
+ BN_ULONG *ap,*np,*rp,n0,v,*nrp;
+ int al,nl,max,i,x,ri;
+
+ BN_CTX_start(ctx);
+ if ((r = BN_CTX_get(ctx)) == NULL) goto err;
+
+ if (!BN_copy(r,a)) goto err;
+ n= &(mont->N);
+
+ ap=a->d;
+ /* mont->ri is the size of mont->N in bits (rounded up
+ to the word size) */
+ al=ri=mont->ri/BN_BITS2;
+
+ nl=n->top;
+ if ((al == 0) || (nl == 0)) { r->top=0; return(1); }
+
+ max=(nl+al+1); /* allow for overflow (no?) XXX */
+ if (bn_wexpand(r,max) == NULL) goto err;
+ if (bn_wexpand(ret,max) == NULL) goto err;
+
+ r->neg=a->neg^n->neg;
+ np=n->d;
+ rp=r->d;
+ nrp= &(r->d[nl]);
+
+ /* clear the top words of T */
+#if 1
+ for (i=r->top; i<max; i++) /* memset? XXX */
+ r->d[i]=0;
+#else
+ memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG));
+#endif
+
+ r->top=max;
+ n0=mont->n0;
+
+#ifdef BN_COUNT
+ printf("word BN_from_montgomery %d * %d\n",nl,nl);
+#endif
+ for (i=0; i<nl; i++)
+ {
+#ifdef __TANDEM
+ {
+ long long t1;
+ long long t2;
+ long long t3;
+ t1 = rp[0] * (n0 & 0177777);
+ t2 = 037777600000l;
+ t2 = n0 & t2;
+ t3 = rp[0] & 0177777;
+ t2 = (t3 * t2) & BN_MASK2;
+ t1 = t1 + t2;
+ v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
+ }
+#else
+ v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
+#endif
+ nrp++;
+ rp++;
+ if (((nrp[-1]+=v)&BN_MASK2) >= v)
+ continue;
+ else
+ {
+ if (((++nrp[0])&BN_MASK2) != 0) continue;
+ if (((++nrp[1])&BN_MASK2) != 0) continue;
+ for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
+ }
+ }
+ bn_fix_top(r);
+
+ /* mont->ri will be a multiple of the word size */
+#if 0
+ BN_rshift(ret,r,mont->ri);
+#else
+ ret->neg = r->neg;
+ x=ri;
+ rp=ret->d;
+ ap= &(r->d[x]);
+ if (r->top < x)
+ al=0;
+ else
+ al=r->top-x;
+ ret->top=al;
+ al-=4;
+ for (i=0; i<al; i+=4)
+ {
+ BN_ULONG t1,t2,t3,t4;
+
+ t1=ap[i+0];
+ t2=ap[i+1];
+ t3=ap[i+2];
+ t4=ap[i+3];
+ rp[i+0]=t1;
+ rp[i+1]=t2;
+ rp[i+2]=t3;
+ rp[i+3]=t4;
+ }
+ al+=4;
+ for (; i<al; i++)
+ rp[i]=ap[i];
+#endif
+#else /* !MONT_WORD */
+ BIGNUM *t1,*t2;
+
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ t2 = BN_CTX_get(ctx);
+ if (t1 == NULL || t2 == NULL) goto err;
+
+ if (!BN_copy(t1,a)) goto err;
+ BN_mask_bits(t1,mont->ri);
+
+ if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err;
+ BN_mask_bits(t2,mont->ri);
+
+ if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
+ if (!BN_add(t2,a,t1)) goto err;
+ BN_rshift(ret,t2,mont->ri);
+#endif /* MONT_WORD */
+
+ if (BN_ucmp(ret, &(mont->N)) >= 0)
+ {
+ BN_usub(ret,ret,&(mont->N));
+ }
+ retn=1;
+ err:
+ BN_CTX_end(ctx);
+ return(retn);
+ }
+
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
+ {
+ ctx->ri=0;
+ BN_init(&(ctx->RR));
+ BN_init(&(ctx->N));
+ BN_init(&(ctx->Ni));
+ ctx->flags=0;
+ }
+
+BN_MONT_CTX *BN_MONT_CTX_new(void)
+ {
+ BN_MONT_CTX *ret;
+
+ if ((ret=(BN_MONT_CTX *)malloc(sizeof(BN_MONT_CTX))) == NULL)
+ return(NULL);
+
+ BN_MONT_CTX_init(ret);
+ ret->flags=BN_FLG_MALLOCED;
+ return(ret);
+ }
+
+void BN_MONT_CTX_free(BN_MONT_CTX *mont)
+ {
+ if(mont == NULL)
+ return;
+
+ BN_free(&(mont->RR));
+ BN_free(&(mont->N));
+ BN_free(&(mont->Ni));
+ if (mont->flags & BN_FLG_MALLOCED)
+ free(mont);
+ }
+
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
+ {
+ BIGNUM Ri,*R;
+
+ BN_init(&Ri);
+ R= &(mont->RR); /* grab RR as a temp */
+ BN_copy(&(mont->N),mod); /* Set N */
+
+#ifdef MONT_WORD
+ {
+ BIGNUM tmod;
+ BN_ULONG buf[2];
+
+ mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
+ BN_zero(R);
+ BN_set_bit(R,BN_BITS2); /* R */
+
+ buf[0]=mod->d[0]; /* tmod = N mod word size */
+ buf[1]=0;
+ tmod.d=buf;
+ tmod.top=1;
+ tmod.dmax=2;
+ tmod.neg=mod->neg;
+ /* Ri = R^-1 mod N*/
+ if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
+ goto err;
+ BN_lshift(&Ri,&Ri,BN_BITS2); /* R*Ri */
+ if (!BN_is_zero(&Ri))
+ BN_sub_word(&Ri,1);
+ else /* if N mod word size == 1 */
+ BN_set_word(&Ri,BN_MASK2); /* Ri-- (mod word size) */
+ BN_div(&Ri,NULL,&Ri,&tmod,ctx); /* Ni = (R*Ri-1)/N,
+ * keep only least significant word: */
+ mont->n0=Ri.d[0];
+ BN_free(&Ri);
+ }
+#else /* !MONT_WORD */
+ { /* bignum version */
+ mont->ri=BN_num_bits(mod);
+ BN_zero(R);
+ BN_set_bit(R,mont->ri); /* R = 2^ri */
+ /* Ri = R^-1 mod N*/
+ if ((BN_mod_inverse(&Ri,R,mod,ctx)) == NULL)
+ goto err;
+ BN_lshift(&Ri,&Ri,mont->ri); /* R*Ri */
+ BN_sub_word(&Ri,1);
+ /* Ni = (R*Ri-1) / N */
+ BN_div(&(mont->Ni),NULL,&Ri,mod,ctx);
+ BN_free(&Ri);
+ }
+#endif
+
+ /* setup RR for conversions */
+ BN_zero(&(mont->RR));
+ BN_set_bit(&(mont->RR),mont->ri*2);
+ BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx);
+
+ return(1);
+err:
+ return(0);
+ }
+
+BIGNUM *BN_value_one(void)
+ {
+ static BN_ULONG data_one=1L;
+ static BIGNUM const_one={&data_one,1,1,0};
+
+ return(&const_one);
+ }
+
+/* solves ax == 1 (mod n) */
+BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+ {
+ BIGNUM *A,*B,*X,*Y,*M,*D,*R=NULL;
+ BIGNUM *T,*ret=NULL;
+ int sign;
+
+ bn_check_top(a);
+ bn_check_top(n);
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ B = BN_CTX_get(ctx);
+ X = BN_CTX_get(ctx);
+ D = BN_CTX_get(ctx);
+ M = BN_CTX_get(ctx);
+ Y = BN_CTX_get(ctx);
+ if (Y == NULL) goto err;
+
+ if (in == NULL)
+ R=BN_new();
+ else
+ R=in;
+ if (R == NULL) goto err;
+
+ BN_zero(X);
+ BN_one(Y);
+ if (BN_copy(A,a) == NULL) goto err;
+ if (BN_copy(B,n) == NULL) goto err;
+ sign=1;
+
+ while (!BN_is_zero(B))
+ {
+ if (!BN_div(D,M,A,B,ctx)) goto err;
+ T=A;
+ A=B;
+ B=M;
+ /* T has a struct, M does not */
+
+ if (!BN_mul(T,D,X,ctx)) goto err;
+ if (!BN_add(T,T,Y)) goto err;
+ M=Y;
+ Y=X;
+ X=T;
+ sign= -sign;
+ }
+ if (sign < 0)
+ {
+ if (!BN_sub(Y,n,Y)) goto err;
+ }
+
+ if (BN_is_one(A))
+ { if (!BN_mod(R,Y,n,ctx)) goto err; }
+ else
+ {
+ goto err;
+ }
+ ret=R;
+err:
+ if ((ret == NULL) && (in == NULL)) BN_free(R);
+ BN_CTX_end(ctx);
+ return(ret);
+ }
+
+int BN_set_bit(BIGNUM *a, int n)
+ {
+ int i,j,k;
+
+ i=n/BN_BITS2;
+ j=n%BN_BITS2;
+ if (a->top <= i)
+ {
+ if (bn_wexpand(a,i+1) == NULL) return(0);
+ for(k=a->top; k<i+1; k++)
+ a->d[k]=0;
+ a->top=i+1;
+ }
+
+ a->d[i]|=(((BN_ULONG)1)<<j);
+ return(1);
+ }
+
diff --git a/package/network/services/ead/src/tinysrp/t_conv.c b/package/network/services/ead/src/tinysrp/t_conv.c
new file mode 100644
index 0000000..3be6d85
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_conv.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+/*#define _POSIX_SOURCE*/
+#include <stdio.h>
+#include "t_defines.h"
+
+static int
+hexDigitToInt(c)
+ char c;
+{
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ else if(c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ else if(c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ else
+ return 0;
+}
+
+/*
+ * Convert a hex string to a string of bytes; return size of dst
+ */
+_TYPE( int )
+t_fromhex(dst, src)
+ register char *dst, *src;
+{
+ register char *chp = dst;
+ register unsigned size = strlen(src);
+
+ /* FIXME: handle whitespace and non-hex digits by setting size and src
+ appropriately. */
+
+ if(size % 2 == 1) {
+ *chp++ = hexDigitToInt(*src++);
+ --size;
+ }
+ while(size > 0) {
+ *chp++ = (hexDigitToInt(*src) << 4) | hexDigitToInt(*(src + 1));
+ src += 2;
+ size -= 2;
+ }
+ return chp - dst;
+}
+
+/*
+ * Convert a string of bytes to their hex representation
+ */
+_TYPE( char * )
+t_tohex(dst, src, size)
+ register char *dst, *src;
+ register unsigned size;
+{
+ int notleading = 0;
+
+ register char *chp = dst;
+ if (size != 0) do {
+ if(notleading || *src != '\0') {
+ notleading = 1;
+ sprintf(chp, "%.2x", * (unsigned char *) src);
+ chp += 2;
+ }
+ ++src;
+ } while (--size != 0);
+ return dst;
+}
+
+static char b64table[] =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
+
+/*
+ * Convert a base64 string into raw byte array representation.
+ */
+_TYPE( int )
+t_fromb64(dst, src)
+ register char *dst, *src;
+{
+ unsigned char *a;
+ char *loc;
+ int i, j;
+ unsigned int size;
+
+ while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
+ ++src;
+ size = strlen(src);
+
+ a = malloc((size + 1) * sizeof(unsigned char));
+ if(a == (unsigned char *) 0)
+ return -1;
+
+ i = 0;
+ while(i < size) {
+ loc = strchr(b64table, src[i]);
+ if(loc == (char *) 0)
+ break;
+ else
+ a[i] = loc - b64table;
+ ++i;
+ }
+ size = i;
+
+ i = size - 1;
+ j = size;
+ while(1) {
+ a[j] = a[i];
+ if(--i < 0)
+ break;
+ a[j] |= (a[i] & 3) << 6;
+ --j;
+ a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
+ if(--i < 0)
+ break;
+ a[j] |= (a[i] & 0xf) << 4;
+ --j;
+ a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
+ if(--i < 0)
+ break;
+ a[j] |= (a[i] << 2);
+
+ a[--j] = 0;
+ if(--i < 0)
+ break;
+ }
+
+ while(j <= size && a[j] == 0)
+ ++j;
+
+ memcpy(dst, a + j, size - j + 1);
+ free(a);
+ return size - j + 1;
+}
+
+/*
+ * Convert a raw byte string into a null-terminated base64 ASCII string.
+ */
+_TYPE( char * )
+t_tob64(dst, src, size)
+ register char *dst, *src;
+ register unsigned size;
+{
+ int c, pos = size % 3;
+ unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
+ char *olddst = dst;
+
+ switch(pos) {
+ case 1:
+ b2 = src[0];
+ break;
+ case 2:
+ b1 = src[0];
+ b2 = src[1];
+ break;
+ }
+
+ while(1) {
+ c = (b0 & 0xfc) >> 2;
+ if(notleading || c != 0) {
+ *dst++ = b64table[c];
+ notleading = 1;
+ }
+ c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
+ if(notleading || c != 0) {
+ *dst++ = b64table[c];
+ notleading = 1;
+ }
+ c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
+ if(notleading || c != 0) {
+ *dst++ = b64table[c];
+ notleading = 1;
+ }
+ c = b2 & 0x3f;
+ if(notleading || c != 0) {
+ *dst++ = b64table[c];
+ notleading = 1;
+ }
+ if(pos >= size)
+ break;
+ else {
+ b0 = src[pos++];
+ b1 = src[pos++];
+ b2 = src[pos++];
+ }
+ }
+
+ *dst++ = '\0';
+ return olddst;
+}
diff --git a/package/network/services/ead/src/tinysrp/t_defines.h b/package/network/services/ead/src/tinysrp/t_defines.h
new file mode 100644
index 0000000..4128093
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_defines.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#ifndef T_DEFINES_H
+#define T_DEFINES_H
+
+#ifndef P
+#if defined(__STDC__) || defined(__cplusplus)
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifndef _DLLDECL
+#define _DLLDECL
+
+#ifdef MSVC15 /* MSVC1.5 support for 16 bit apps */
+#define _MSVC15EXPORT _export
+#define _MSVC20EXPORT
+#define _DLLAPI _export _pascal
+#define _TYPE(a) a _MSVC15EXPORT
+#define DLLEXPORT 1
+
+#elif MSVC20
+#define _MSVC15EXPORT
+#define _MSVC20EXPORT _declspec(dllexport)
+#define _DLLAPI
+#define _TYPE(a) _MSVC20EXPORT a
+#define DLLEXPORT 1
+
+#else /* Default, non-dll. Use this for Unix or DOS */
+#define _MSVC15DEXPORT
+#define _MSVC20EXPORT
+#define _DLLAPI
+#define _TYPE(a) a
+#endif
+#endif
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <string.h>
+#else /* not STDC_HEADERS */
+#ifndef HAVE_STRCHR
+#define strchr index
+#define strrchr rindex
+#endif
+char *strchr(), *strrchr(), *strtok();
+#ifndef HAVE_MEMCPY
+#define memcpy(d, s, n) bcopy((s), (d), (n))
+#endif
+#endif /* not STDC_HEADERS */
+
+#include <sys/types.h>
+
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else /* not TIME_WITH_SYS_TIME */
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif /* not TIME_WITH_SYS_TIME */
+
+#if HAVE_TERMIOS_H
+#include <termios.h>
+#define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
+#define GTTY(fd, termio) tcgetattr(fd, termio)
+#define TERMIO struct termios
+#define USE_TERMIOS
+#elif HAVE_TERMIO_H
+#include <sys/ioctl.h>
+#include <termio.h>
+#define STTY(fd, termio) ioctl(fd, TCSETA, termio)
+#define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
+#define TEMRIO struct termio
+#define USE_TERMIO
+#elif HAVE_SGTTY_H
+#include <sgtty.h>
+#define STTY(fd, termio) stty(fd, termio)
+#define GTTY(fd, termio) gtty(fd, termio)
+#define TERMIO struct sgttyb
+#define USE_SGTTY
+#endif
+
+#ifdef USE_FTIME
+#include <sys/timeb.h>
+#endif
+
+#ifndef MATH_PRIV
+typedef void * BigInteger;
+#endif
+
+_TYPE( BigInteger ) BigIntegerFromInt P((unsigned int number));
+_TYPE( BigInteger ) BigIntegerFromBytes P((unsigned char * bytes, int length));
+_TYPE( int ) BigIntegerToBytes P((BigInteger src, unsigned char * dest));
+_TYPE( int ) BigIntegerBitLen P((BigInteger b));
+_TYPE( int ) BigIntegerCmp P((BigInteger c1, BigInteger c2));
+_TYPE( int ) BigIntegerCmpInt P((BigInteger c1, unsigned int c2));
+_TYPE( void ) BigIntegerLShift P((BigInteger result, BigInteger x,
+ unsigned int bits));
+_TYPE( void ) BigIntegerAdd P((BigInteger result, BigInteger a1, BigInteger a2));
+_TYPE( void ) BigIntegerAddInt P((BigInteger result,
+ BigInteger a1, unsigned int a2));
+_TYPE( void ) BigIntegerSub P((BigInteger result, BigInteger s1, BigInteger s2));
+_TYPE( void ) BigIntegerSubInt P((BigInteger result,
+ BigInteger s1, unsigned int s2));
+/* For BigIntegerMul{,Int}: result != m1, m2 */
+_TYPE( void ) BigIntegerMul P((BigInteger result, BigInteger m1, BigInteger m2));
+_TYPE( void ) BigIntegerMulInt P((BigInteger result,
+ BigInteger m1, unsigned int m2));
+_TYPE( void ) BigIntegerDivInt P((BigInteger result,
+ BigInteger d, unsigned int m));
+_TYPE( void ) BigIntegerMod P((BigInteger result, BigInteger d, BigInteger m));
+_TYPE( unsigned int ) BigIntegerModInt P((BigInteger d, unsigned int m));
+_TYPE( void ) BigIntegerModMul P((BigInteger result,
+ BigInteger m1, BigInteger m2, BigInteger m));
+_TYPE( void ) BigIntegerModExp P((BigInteger result, BigInteger base,
+ BigInteger expt, BigInteger modulus));
+_TYPE( void ) BigIntegerModExpInt P((BigInteger result, BigInteger base,
+ unsigned int expt, BigInteger modulus));
+_TYPE( int ) BigIntegerCheckPrime P((BigInteger n));
+_TYPE( void ) BigIntegerFree P((BigInteger b));
+
+#endif
diff --git a/package/network/services/ead/src/tinysrp/t_getconf.c b/package/network/services/ead/src/tinysrp/t_getconf.c
new file mode 100644
index 0000000..db6de61
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_getconf.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_read.h"
+
+/* Master builtin parameter storage object. The default that tphrase
+uses is the last one. */
+
+static struct pre_struct {
+ struct t_preconf preconf;
+ int state; /* 0 == uninitialized/first time */
+ unsigned char modbuf[MAXPARAMLEN];
+ unsigned char genbuf[MAXPARAMLEN];
+} pre_params[] = {
+ { { "2iQzj1CagQc/5ctbuJYLWlhtAsPHc7xWVyCPAKFRLWKADpASkqe9djWPFWTNTdeJtL8nAhImCn3Sr/IAdQ1FrGw0WvQUstPx3FO9KNcXOwisOQ1VlL.gheAHYfbYyBaxXL.NcJx9TUwgWDT0hRzFzqSrdGGTN3FgSTA1v4QnHtEygNj3eZ.u0MThqWUaDiP87nqha7XnT66bkTCkQ8.7T8L4KZjIImrNrUftedTTBi.WCi.zlrBxDuOM0da0JbUkQlXqvp0yvJAPpC11nxmmZOAbQOywZGmu9nhZNuwTlxjfIro0FOdthaDTuZRL9VL7MRPUDo/DQEyW.d4H.UIlzp",
+ "2",
+ NULL }, 0 },
+ { { "dUyyhxav9tgnyIg65wHxkzkb7VIPh4o0lkwfOKiPp4rVJrzLRYVBtb76gKlaO7ef5LYGEw3G.4E0jbMxcYBetDy2YdpiP/3GWJInoBbvYHIRO9uBuxgsFKTKWu7RnR7yTau/IrFTdQ4LY/q.AvoCzMxV0PKvD9Odso/LFIItn8PbTov3VMn/ZEH2SqhtpBUkWtmcIkEflhX/YY/fkBKfBbe27/zUaKUUZEUYZ2H2nlCL60.JIPeZJSzsu/xHDVcx",
+ "2",
+ NULL }, 0 },
+ { { "3NUKQ2Re4P5BEK0TLg2dX3gETNNNECPoe92h4OVMaDn3Xo/0QdjgG/EvM.hiVV1BdIGklSI14HA38Mpe5k04juR5/EXMU0r1WtsLhNXwKBlf2zEfoOh0zVmDvqInpU695f29Iy7sNW3U5RIogcs740oUp2Kdv5wuITwnIx84cnO.e467/IV1lPnvMCr0pd1dgS0a.RV5eBJr03Q65Xy61R",
+ "2",
+ NULL }, 0 },
+ { { "F//////////oG/QeY5emZJ4ncABWDmSqIa2JWYAPynq0Wk.fZiJco9HIWXvZZG4tU.L6RFDEaCRC2iARV9V53TFuJLjRL72HUI5jNPYNdx6z4n2wQOtxMiB/rosz0QtxUuuQ/jQYP.bhfya4NnB7.P9A6PHxEPJWV//////////",
+ "5",
+ "oakley prime 2" }, 0 },
+ { { "Ewl2hcjiutMd3Fu2lgFnUXWSc67TVyy2vwYCKoS9MLsrdJVT9RgWTCuEqWJrfB6uE3LsE9GkOlaZabS7M29sj5TnzUqOLJMjiwEzArfiLr9WbMRANlF68N5AVLcPWvNx6Zjl3m5Scp0BzJBz9TkgfhzKJZ.WtP3Mv/67I/0wmRZ",
+ "2",
+ NULL }, 0 },
+};
+
+_TYPE( int )
+t_getprecount()
+{
+ return (sizeof(pre_params) / sizeof(struct pre_struct));
+}
+
+static struct t_confent sysconf;
+
+/* id is index origin 1 */
+
+_TYPE( struct t_confent * )
+gettcid
+(id)
+ int id;
+{
+ struct t_preconf *tcp;
+
+ if (id <= 0 || id > t_getprecount()) {
+ return NULL;
+ }
+ tcp = t_getpreparam(id - 1);
+ sysconf.index = id;
+ sysconf.modulus = tcp->modulus;
+ sysconf.generator = tcp->generator;
+
+ return &sysconf;
+}
+
+_TYPE( struct t_preconf * )
+t_getpreparam(idx)
+ int idx;
+{
+ if(pre_params[idx].state == 0) {
+ /* Wire up storage */
+ pre_params[idx].preconf.modulus.data = pre_params[idx].modbuf;
+ pre_params[idx].preconf.generator.data = pre_params[idx].genbuf;
+
+ /* Convert from b64 to t_num */
+ pre_params[idx].preconf.modulus.len = t_fromb64(pre_params[idx].preconf.modulus.data, pre_params[idx].preconf.mod_b64);
+ pre_params[idx].preconf.generator.len = t_fromb64(pre_params[idx].preconf.generator.data, pre_params[idx].preconf.gen_b64);
+
+ pre_params[idx].state = 1;
+ }
+ return &(pre_params[idx].preconf);
+}
diff --git a/package/network/services/ead/src/tinysrp/t_getpass.c b/package/network/services/ead/src/tinysrp/t_getpass.c
new file mode 100644
index 0000000..6ae7fca
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_getpass.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright 1990 - 1995, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "t_defines.h"
+#ifdef _WIN32
+#include <windows.h>
+#include <io.h>
+#endif /* _WIN32 */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <signal.h>
+#include <stdio.h>
+
+static int sig_caught;
+#ifdef HAVE_SIGACTION
+static struct sigaction sigact;
+#endif
+
+/*ARGSUSED*/
+static RETSIGTYPE
+sig_catch (sig)
+int sig;
+{
+ sig_caught = 1;
+}
+
+_TYPE( int )
+t_getpass (buf, maxlen, prompt)
+ char *buf;
+ unsigned maxlen;
+ const char *prompt;
+{
+ char *cp;
+#ifdef _WIN32
+ HANDLE handle = (HANDLE) _get_osfhandle(_fileno(stdin));
+ DWORD mode;
+
+ GetConsoleMode( handle, &mode );
+ SetConsoleMode( handle, mode & ~ENABLE_ECHO_INPUT );
+
+ if(fputs(prompt, stdout) == EOF ||
+ fgets(buf, maxlen, stdin) == NULL) {
+ SetConsoleMode(handle,mode);
+ return -1;
+ }
+ cp = buf + strlen(buf) - 1;
+ if ( *cp == 0x0a )
+ *cp = '\0';
+ printf("\n");
+ SetConsoleMode(handle,mode);
+#else
+ FILE *fp;
+ int tty_opened = 0;
+
+#ifdef HAVE_SIGACTION
+ struct sigaction old_sigact;
+#else
+ RETSIGTYPE (*old_signal)();
+#endif
+ TERMIO new_modes;
+ TERMIO old_modes;
+
+ /*
+ * set a flag so the SIGINT signal can be re-sent if it
+ * is caught
+ */
+
+ sig_caught = 0;
+
+ /*
+ * if /dev/tty can't be opened, getpass() needs to read
+ * from stdin instead.
+ */
+
+ if ((fp = fopen ("/dev/tty", "r")) == 0) {
+ fp = stdin;
+ setbuf (fp, (char *) 0);
+ } else {
+ tty_opened = 1;
+ }
+
+ /*
+ * the current tty modes must be saved so they can be
+ * restored later on. echo will be turned off, except
+ * for the newline character (BSD has to punt on this)
+ */
+
+ if (GTTY (fileno (fp), &new_modes))
+ return -1;
+
+ old_modes = new_modes;
+
+#ifdef HAVE_SIGACTION
+ sigact.sa_handler = sig_catch;
+ (void) sigaction (SIGINT, &sigact, &old_sigact);
+#else
+ old_signal = signal (SIGINT, sig_catch);
+#endif
+
+#ifdef USE_SGTTY
+ new_modes.sg_flags &= ~ECHO;
+#else
+ new_modes.c_iflag &= ~IGNCR;
+ new_modes.c_iflag |= ICRNL;
+ new_modes.c_oflag |= OPOST|ONLCR;
+ new_modes.c_lflag &= ~(ECHO|ECHOE|ECHOK);
+ new_modes.c_lflag |= ICANON|ECHONL;
+#endif
+
+ if (STTY (fileno (fp), &new_modes))
+ goto out;
+
+ /*
+ * the prompt is output, and the response read without
+ * echoing. the trailing newline must be removed. if
+ * the fgets() returns an error, a NULL pointer is
+ * returned.
+ */
+
+ if (fputs (prompt, stdout) == EOF)
+ goto out;
+
+ (void) fflush (stdout);
+
+ if (fgets (buf, maxlen, fp) == buf) {
+ if ((cp = strchr (buf, '\n')))
+ *cp = '\0';
+ else
+ buf[maxlen - 1] = '\0';
+
+#ifdef USE_SGTTY
+ putc ('\n', stdout);
+#endif
+ }
+ else buf[0] = '\0';
+out:
+ /*
+ * the old SIGINT handler is restored after the tty
+ * modes. then /dev/tty is closed if it was opened in
+ * the beginning. finally, if a signal was caught it
+ * is sent to this process for normal processing.
+ */
+
+ if (STTY (fileno (fp), &old_modes))
+ { memset (buf, 0, maxlen); return -1; }
+
+#ifdef HAVE_SIGACTION
+ (void) sigaction (SIGINT, &old_sigact, NULL);
+#else
+ (void) signal (SIGINT, old_signal);
+#endif
+
+ if (tty_opened)
+ (void) fclose (fp);
+
+ if (sig_caught) {
+ kill (getpid (), SIGINT);
+ memset (buf, 0, maxlen);
+ return -1;
+ }
+#endif
+
+ return 0;
+}
diff --git a/package/network/services/ead/src/tinysrp/t_math.c b/package/network/services/ead/src/tinysrp/t_math.c
new file mode 100644
index 0000000..20161a0
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_math.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "config.h"
+
+#include "bn.h"
+typedef BIGNUM * BigInteger;
+#define MATH_PRIV
+
+#include "t_defines.h"
+#include "t_pwd.h"
+
+/* Math library interface stubs */
+
+BigInteger
+BigIntegerFromInt(n)
+ unsigned int n;
+{
+ BIGNUM * a = BN_new();
+ BN_set_word(a, n);
+ return a;
+}
+
+BigInteger
+BigIntegerFromBytes(bytes, length)
+ unsigned char * bytes;
+ int length;
+{
+ BIGNUM * a = BN_new();
+ BN_bin2bn(bytes, length, a);
+ return a;
+}
+
+int
+BigIntegerToBytes(src, dest)
+ BigInteger src;
+ unsigned char * dest;
+{
+ return BN_bn2bin(src, dest);
+}
+
+int
+BigIntegerCmp(c1, c2)
+ BigInteger c1, c2;
+{
+ return BN_cmp(c1, c2);
+}
+
+int
+BigIntegerCmpInt(c1, c2)
+ BigInteger c1;
+ unsigned int c2;
+{
+ BIGNUM * a = BN_new();
+ int rv;
+ BN_set_word(a, c2);
+ rv = BN_cmp(c1, a);
+ BN_free(a);
+ return rv;
+}
+
+void
+BigIntegerAdd(result, a1, a2)
+ BigInteger result, a1, a2;
+{
+ BN_add(result, a1, a2);
+}
+
+void
+BigIntegerAddInt(result, a1, a2)
+ BigInteger result, a1;
+ unsigned int a2;
+{
+ BIGNUM * a = BN_new();
+ BN_set_word(a, a2);
+ BN_add(result, a1, a);
+ BN_free(a);
+}
+
+void
+BigIntegerSub(result, s1, s2)
+ BigInteger result, s1, s2;
+{
+ BN_sub(result, s1, s2);
+}
+
+void
+BigIntegerMulInt(result, m1, m2)
+ BigInteger result, m1;
+ unsigned int m2;
+{
+ BN_CTX * ctx = BN_CTX_new();
+ BIGNUM * m = BN_new();
+ BN_set_word(m, m2);
+ BN_mul(result, m1, m, ctx);
+ BN_CTX_free(ctx);
+}
+
+void
+BigIntegerModMul(r, m1, m2, modulus)
+ BigInteger r, m1, m2, modulus;
+{
+ BN_CTX * ctx = BN_CTX_new();
+ BN_mod_mul(r, m1, m2, modulus, ctx);
+ BN_CTX_free(ctx);
+}
+
+void
+BigIntegerModExp(r, b, e, m)
+ BigInteger r, b, e, m;
+{
+ BN_CTX * ctx = BN_CTX_new();
+ BN_mod_exp(r, b, e, m, ctx);
+ BN_CTX_free(ctx);
+}
+
+void
+BigIntegerModExpInt(r, b, e, m)
+ BigInteger r, b;
+ unsigned int e;
+ BigInteger m;
+{
+ BN_CTX * ctx = BN_CTX_new();
+ BIGNUM * p = BN_new();
+ BN_set_word(p, e);
+ BN_mod_exp(r, b, p, m, ctx);
+ BN_free(p);
+ BN_CTX_free(ctx);
+}
+
+void
+BigIntegerFree(b)
+ BigInteger b;
+{
+ BN_free(b);
+}
diff --git a/package/network/services/ead/src/tinysrp/t_misc.c b/package/network/services/ead/src/tinysrp/t_misc.c
new file mode 100644
index 0000000..a23986f
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_misc.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include "t_defines.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "t_sha.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+static unsigned char randpool[SHA_DIGESTSIZE], randout[SHA_DIGESTSIZE];
+static unsigned long randcnt = 0;
+static unsigned int outpos = 0;
+SHA1_CTX randctxt;
+
+/*
+ * t_envhash - Generate a 160-bit SHA hash of the environment
+ *
+ * This routine performs an SHA hash of all the "name=value" pairs
+ * in the environment concatenated together and dumps them in the
+ * output. While it is true that anyone on the system can see
+ * your environment, someone not on the system will have a very
+ * difficult time guessing it, especially since some systems play
+ * tricks with variable ordering and sometimes define quirky
+ * environment variables like $WINDOWID or $_.
+ */
+extern char ** environ;
+
+static void
+t_envhash(out)
+ unsigned char * out;
+{
+ char ** ptr;
+ char ebuf[256];
+ SHA1_CTX ctxt;
+
+ SHA1Init(&ctxt);
+ for(ptr = environ; *ptr; ++ptr) {
+ strncpy(ebuf, *ptr, 255);
+ ebuf[255] = '\0';
+ SHA1Update(&ctxt, ebuf, strlen(ebuf));
+ }
+ SHA1Final(out, &ctxt);
+}
+
+/*
+ * t_fshash - Generate a 160-bit SHA hash from the file system
+ *
+ * This routine climbs up the directory tree from the current
+ * directory, running stat() on each directory until it hits the
+ * root directory. This information is sensitive to the last
+ * access/modification times of all the directories above you,
+ * so someone who lists one of those directories injects some
+ * entropy into the system. Obviously, this hash is very sensitive
+ * to your current directory when the program is run.
+ *
+ * For good measure, it also performs an fstat on the standard input,
+ * usually your tty, throws that into the buffer, creates a file in
+ * /tmp (the inode is unpredictable on a busy system), and runs stat()
+ * on that before deleting it.
+ *
+ * The entire buffer is run once through SHA to obtain the final result.
+ */
+static void
+t_fshash(out)
+ unsigned char * out;
+{
+ char dotpath[128];
+ struct stat st;
+ SHA1_CTX ctxt;
+ int i, pinode;
+ dev_t pdev;
+
+ SHA1Init(&ctxt);
+ if(stat(".", &st) >= 0) {
+ SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
+ pinode = st.st_ino;
+ pdev = st.st_dev;
+ strcpy(dotpath, "..");
+ for(i = 0; i < 40; ++i) {
+ if(stat(dotpath, &st) < 0)
+ break;
+ if(st.st_ino == pinode && st.st_dev == pdev)
+ break;
+ SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
+ pinode = st.st_ino;
+ pdev = st.st_dev;
+ strcat(dotpath, "/..");
+ }
+ }
+
+ if(fstat(0, &st) >= 0)
+ SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
+
+ sprintf(dotpath, "/tmp/rnd.%d", getpid());
+ if(creat(dotpath, 0600) >= 0 && stat(dotpath, &st) >= 0)
+ SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
+ unlink(dotpath);
+
+ SHA1Final(out, &ctxt);
+}
+
+/*
+ * Generate a high-entropy seed for the strong random number generator.
+ * This uses a wide variety of quickly gathered and somewhat unpredictable
+ * system information. The 'preseed' structure is assembled from:
+ *
+ * The system time in seconds
+ * The system time in microseconds
+ * The current process ID
+ * The parent process ID
+ * A hash of the user's environment
+ * A hash gathered from the file system
+ * Input from a random device, if available
+ * Timings of system interrupts
+ *
+ * The entire structure (60 bytes on most systems) is fed to SHA to produce
+ * a 160-bit seed for the strong random number generator. It is believed
+ * that in the worst case (on a quiet system with no random device versus
+ * an attacker who has access to the system already), the seed contains at
+ * least about 80 bits of entropy. Versus an attacker who does not have
+ * access to the system, the entropy should be slightly over 128 bits.
+ */
+static char initialized = 0;
+
+static struct {
+ unsigned int trand1;
+ time_t sec;
+ time_t usec;
+ short pid;
+ short ppid;
+ unsigned char envh[SHA_DIGESTSIZE];
+ unsigned char fsh[SHA_DIGESTSIZE];
+ unsigned char devrand[20];
+ unsigned int trand2;
+} preseed;
+
+unsigned long raw_truerand();
+
+void
+t_initrand()
+{
+ SHA1_CTX ctxt;
+#ifdef USE_FTIME
+ struct timeb t;
+#else
+ struct timeval t;
+#endif
+ int i, r=0;
+
+ if(initialized)
+ return;
+
+ initialized = 1;
+
+ i = open("/dev/urandom", O_RDONLY);
+ if(i > 0) {
+ r += read(i, preseed.devrand, sizeof(preseed.devrand));
+ close(i);
+ }
+
+ /* Resort to truerand only if desperate for some Real entropy */
+ if(r == 0)
+ preseed.trand1 = raw_truerand();
+
+#ifdef USE_FTIME
+ ftime(&t);
+#else
+ gettimeofday(&t, NULL);
+#endif
+
+#ifdef USE_FTIME
+ preseed.sec = t.time;
+ preseed.usec = t.millitm;
+#else
+ preseed.sec = t.tv_sec;
+ preseed.usec = t.tv_usec;
+#endif
+ preseed.pid = getpid();
+ preseed.ppid = getppid();
+ t_envhash(preseed.envh);
+ t_fshash(preseed.fsh);
+
+ if(r == 0)
+ preseed.trand2 = raw_truerand();
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, (unsigned char *) &preseed, sizeof(preseed));
+ SHA1Final(randpool, &ctxt);
+ outpos = 0;
+ memset((unsigned char *) &preseed, 0, sizeof(preseed));
+ memset((unsigned char *) &ctxt, 0, sizeof(ctxt));
+}
+
+#define NUM_RANDOMS 12
+
+/*
+ * The strong random number generator. This uses a 160-bit seed
+ * and uses SHA-1 in a feedback configuration to generate successive
+ * outputs. If S[0] is set to the initial seed, then:
+ *
+ * S[i+1] = SHA-1(i || S[i])
+ * A[i] = SHA-1(S[i])
+ *
+ * where the A[i] are the output blocks starting with i=0.
+ * Each cycle generates 20 bytes of new output.
+ */
+_TYPE( void )
+t_random(data, size)
+ unsigned char * data;
+ unsigned size;
+{
+ if(!initialized)
+ t_initrand();
+
+ if(size <= 0) /* t_random(NULL, 0) forces seed initialization */
+ return;
+
+ while(size > outpos) {
+ if(outpos > 0) {
+ memcpy(data, randout + (sizeof(randout) - outpos), outpos);
+ data += outpos;
+ size -= outpos;
+ }
+
+ /* Recycle */
+ SHA1Init(&randctxt);
+ SHA1Update(&randctxt, randpool, sizeof(randpool));
+ SHA1Final(randout, &randctxt);
+ SHA1Init(&randctxt);
+ SHA1Update(&randctxt, (unsigned char *) &randcnt, sizeof(randcnt));
+ SHA1Update(&randctxt, randpool, sizeof(randpool));
+ SHA1Final(randpool, &randctxt);
+ ++randcnt;
+ outpos = sizeof(randout);
+ }
+
+ if(size > 0) {
+ memcpy(data, randout + (sizeof(randout) - outpos), size);
+ outpos -= size;
+ }
+}
+
+/*
+ * The interleaved session-key hash. This separates the even and the odd
+ * bytes of the input (ignoring the first byte if the input length is odd),
+ * hashes them separately, and re-interleaves the two outputs to form a
+ * single 320-bit value.
+ */
+_TYPE( unsigned char * )
+t_sessionkey(key, sk, sklen)
+ unsigned char * key;
+ unsigned char * sk;
+ unsigned sklen;
+{
+ unsigned i, klen;
+ unsigned char * hbuf;
+ unsigned char hout[SHA_DIGESTSIZE];
+ SHA1_CTX ctxt;
+
+ while(sklen > 0 && *sk == 0) { /* Skip leading 0's */
+ --sklen;
+ ++sk;
+ }
+
+ klen = sklen / 2;
+ if((hbuf = malloc(klen * sizeof(char))) == 0)
+ return 0;
+
+ for(i = 0; i < klen; ++i)
+ hbuf[i] = sk[sklen - 2 * i - 1];
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, hbuf, klen);
+ SHA1Final(hout, &ctxt);
+ for(i = 0; i < sizeof(hout); ++i)
+ key[2 * i] = hout[i];
+
+ for(i = 0; i < klen; ++i)
+ hbuf[i] = sk[sklen - 2 * i - 2];
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, hbuf, klen);
+ SHA1Final(hout, &ctxt);
+ for(i = 0; i < sizeof(hout); ++i)
+ key[2 * i + 1] = hout[i];
+
+ memset(hout, 0, sizeof(hout));
+ memset(hbuf, 0, klen);
+ free(hbuf);
+ return key;
+}
diff --git a/package/network/services/ead/src/tinysrp/t_pw.c b/package/network/services/ead/src/tinysrp/t_pw.c
new file mode 100644
index 0000000..18e929b
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_pw.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 1997-2000 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include "t_defines.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef USE_HOMEDIR
+#include <pwd.h>
+#endif
+#ifdef WIN32
+#include <io.h>
+#endif
+
+#include "t_pwd.h"
+#include "t_read.h"
+#include "t_sha.h"
+#include "t_server.h"
+
+static struct t_pw * syspw = NULL;
+static struct t_passwd tpass;
+
+_TYPE( struct t_server * )
+t_serveropen(username)
+ const char * username;
+{
+ struct t_passwd * p;
+ p = gettpnam(username);
+ if(p == NULL) {
+ return NULL;
+ } else {
+ return t_serveropenraw(&p->tp, &p->tc);
+ }
+}
+
+
+/* t_openpw(NULL) is deprecated - use settpent()/gettpnam() instead */
+
+_TYPE( struct t_pw * )
+t_openpw(fp)
+ FILE * fp;
+{
+ struct t_pw * tpw;
+ char close_flag = 0;
+
+ if(fp == NULL) { /* Deprecated */
+ if((fp = fopen(DEFAULT_PASSWD, "r")) == NULL)
+ return NULL;
+ close_flag = 1;
+ }
+ else
+ close_flag = 0;
+
+ if((tpw = malloc(sizeof(struct t_pw))) == NULL)
+ return NULL;
+ tpw->instream = fp;
+ tpw->close_on_exit = close_flag;
+ tpw->state = FILE_ONLY;
+
+ return tpw;
+}
+
+_TYPE( struct t_pw * )
+t_openpwbyname(pwname)
+ const char * pwname;
+{
+ FILE * fp;
+ struct t_pw * t;
+
+ if(pwname == NULL) /* Deprecated */
+ return t_openpw(NULL);
+
+ if((fp = fopen(pwname, "r")) == NULL)
+ return NULL;
+
+ t = t_openpw(fp);
+ t->close_on_exit = 1;
+ return t;
+}
+
+_TYPE( void )
+t_closepw(tpw)
+ struct t_pw * tpw;
+{
+ if(tpw->close_on_exit)
+ fclose(tpw->instream);
+ free(tpw);
+}
+
+_TYPE( void )
+t_rewindpw(tpw)
+ struct t_pw * tpw;
+{
+#ifdef ENABLE_YP
+ if(tpw->state == IN_NIS)
+ tpw->state = FILE_NIS;
+#endif
+ rewind(tpw->instream);
+}
+
+#ifdef ENABLE_YP
+static void
+savepwent(tpw, pwent)
+ struct t_pw * tpw;
+ struct t_pwent *pwent;
+{
+ tpw->pebuf.name = tpw->userbuf;
+ tpw->pebuf.password.data = tpw->pwbuf;
+ tpw->pebuf.salt.data = tpw->saltbuf;
+ strcpy(tpw->pebuf.name, pwent->name);
+ tpw->pebuf.password.len = pwent->password.len;
+ memcpy(tpw->pebuf.password.data, pwent->password.data, pwent->password.len);
+ tpw->pebuf.salt.len = pwent->salt.len;
+ memcpy(tpw->pebuf.salt.data, pwent->salt.data, pwent->salt.len);
+ tpw->pebuf.index = pwent->index;
+}
+#endif /* ENABLE_YP */
+
+_TYPE( struct t_pwent * )
+t_getpwbyname(tpw, user)
+ struct t_pw * tpw;
+ const char * user;
+{
+ char indexbuf[16];
+ char passbuf[MAXB64PARAMLEN];
+ char saltstr[MAXB64SALTLEN];
+ char username[MAXUSERLEN];
+#ifdef ENABLE_YP
+ struct t_passwd * nisent;
+#endif
+
+ t_rewindpw(tpw);
+
+ while(t_nextfield(tpw->instream, username, MAXUSERLEN) > 0) {
+#ifdef ENABLE_YP
+ if(tpw->state == FILE_NIS && *username == '+') {
+ if(strlen(username) == 1 || strcmp(user, username+1) == 0) {
+ nisent = _yp_gettpnam(user); /* Entry is +username or + */
+ if(nisent != NULL) {
+ savepwent(tpw, &nisent->tp);
+ return &tpw->pebuf;
+ }
+ }
+ }
+#endif
+ if(strcmp(user, username) == 0)
+ if(t_nextfield(tpw->instream, passbuf, MAXB64PARAMLEN) > 0 &&
+ (tpw->pebuf.password.len = t_fromb64(tpw->pwbuf, passbuf)) > 0 &&
+ t_nextfield(tpw->instream, saltstr, MAXB64SALTLEN) > 0 &&
+ (tpw->pebuf.salt.len = t_fromb64(tpw->saltbuf, saltstr)) > 0 &&
+ t_nextfield(tpw->instream, indexbuf, 16) > 0 &&
+ (tpw->pebuf.index = atoi(indexbuf)) > 0) {
+ strcpy(tpw->userbuf, username);
+ tpw->pebuf.name = tpw->userbuf;
+ tpw->pebuf.password.data = tpw->pwbuf;
+ tpw->pebuf.salt.data = tpw->saltbuf;
+ t_nextline(tpw->instream);
+ return &tpw->pebuf;
+ }
+ if(t_nextline(tpw->instream) < 0)
+ return NULL;
+ }
+ return NULL;
+}
+
+/* System password file accessors */
+
+static int
+pwinit()
+{
+ if(syspw == NULL) {
+ if((syspw = t_openpwbyname(DEFAULT_PASSWD)) == NULL)
+ return -1;
+ syspw->state = FILE_NIS;
+ }
+ return 0;
+}
+
+static void
+pwsetup(out, tpwd, tcnf)
+ struct t_passwd * out;
+ struct t_pwent * tpwd;
+ struct t_confent * tcnf;
+{
+ out->tp.name = tpwd->name;
+ out->tp.password.len = tpwd->password.len;
+ out->tp.password.data = tpwd->password.data;
+ out->tp.salt.len = tpwd->salt.len;
+ out->tp.salt.data = tpwd->salt.data;
+ out->tp.index = tpwd->index;
+
+ out->tc.index = tcnf->index;
+ out->tc.modulus.len = tcnf->modulus.len;
+ out->tc.modulus.data = tcnf->modulus.data;
+ out->tc.generator.len = tcnf->generator.len;
+ out->tc.generator.data = tcnf->generator.data;
+}
+
+_TYPE( struct t_passwd * )
+gettpnam
+(user)
+ const char * user;
+{
+ struct t_pwent * tpptr;
+ struct t_confent * tcptr;
+
+ if(pwinit() < 0)
+ return NULL;
+ tpptr = t_getpwbyname(syspw, user);
+ if(tpptr == NULL)
+ return NULL;
+ tcptr =
+ gettcid
+ (tpptr->index);
+ if(tcptr == NULL)
+ return NULL;
+ pwsetup(&tpass, tpptr, tcptr);
+ return &tpass;
+}
diff --git a/package/network/services/ead/src/tinysrp/t_pwd.h b/package/network/services/ead/src/tinysrp/t_pwd.h
new file mode 100644
index 0000000..73697be
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_pwd.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#ifndef T_PWD_H
+#define T_PWD_H
+
+#ifndef P
+#if defined (__STDC__) || defined (__cplusplus)
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+/* For building dynamic link libraries under windows, windows NT
+ * using MSVC1.5 or MSVC2.0
+ */
+
+#ifndef _DLLDECL
+#define _DLLDECL
+
+#ifdef MSVC15 /* MSVC1.5 support for 16 bit apps */
+#define _MSVC15EXPORT _export
+#define _MSVC20EXPORT
+#define _DLLAPI _export _pascal
+#define _TYPE(a) a _MSVC15EXPORT
+#define DLLEXPORT 1
+
+#elif MSVC20
+#define _MSVC15EXPORT
+#define _MSVC20EXPORT _declspec(dllexport)
+#define _DLLAPI
+#define _TYPE(a) _MSVC20EXPORT a
+#define DLLEXPORT 1
+
+#else /* Default, non-dll. Use this for Unix or DOS */
+#define _MSVC15DEXPORT
+#define _MSVC20EXPORT
+#define _DLLAPI
+#define _TYPE(a) a
+#endif
+#endif
+
+#define MAXPARAMBITS 2048
+#define MAXPARAMLEN ((MAXPARAMBITS + 7) / 8)
+#define MAXB64PARAMLEN ((MAXPARAMBITS + 5) / 6 + 1)
+#define MAXHEXPARAMLEN ((MAXPARAMBITS + 3) / 4 + 1)
+#define MAXOCTPARAMLEN ((MAXPARAMBITS + 2) / 3 + 1)
+
+#define MAXUSERLEN 32
+#define MAXSALTLEN 32
+#define MAXB64SALTLEN 44 /* 256 bits in b64 + null */
+#define SALTLEN 10 /* Normally 80 bits */
+
+#define RESPONSE_LEN 20 /* 160-bit proof hashes */
+#define SESSION_KEY_LEN (2 * RESPONSE_LEN) /* 320-bit session key */
+
+#define DEFAULT_PASSWD "tpasswd"
+
+struct t_num { /* Standard byte-oriented integer representation */
+ int len;
+ unsigned char * data;
+};
+
+struct t_preconf { /* Structure returned by t_getpreparam() */
+ char * mod_b64;
+ char * gen_b64;
+ char * comment;
+
+ struct t_num modulus;
+ struct t_num generator;
+};
+
+/*
+ * The built-in (known good) parameters access routines
+ *
+ * "t_getprecount" returns the number of precompiled parameter sets.
+ * "t_getpreparam" returns the indicated parameter set.
+ * Memory is statically allocated - callers need not perform any memory mgmt.
+ */
+_TYPE( int ) t_getprecount();
+_TYPE( struct t_preconf * ) t_getpreparam P((int));
+
+struct t_confent { /* One configuration file entry (index, N, g) */
+ int index;
+ struct t_num modulus;
+ struct t_num generator;
+};
+
+struct t_conf { /* An open configuration file */
+ FILE * instream;
+ char close_on_exit;
+ unsigned char modbuf[MAXPARAMLEN];
+ unsigned char genbuf[MAXPARAMLEN];
+ struct t_confent tcbuf;
+};
+
+/*
+ * The configuration file routines are designed along the lines of the
+ * "getpw" functions in the standard C library.
+ *
+ * "t_openconf" accepts a stdio stream and interprets it as a config file.
+ * "t_openconfbyname" accepts a filename and does the same thing.
+ * "t_closeconf" closes the config file.
+ * "t_getconfent" fetches the next sequential configuration entry.
+ * "t_getconfbyindex" fetches the configuration entry whose index
+ * matches the one supplied, or NULL if one can't be found.
+ * "t_getconflast" fetches the last configuration entry in the file.
+ * "t_makeconfent" generates a set of configuration entry parameters
+ * randomly.
+ * "t_newconfent" returns an empty configuration entry.
+ * "t_cmpconfent" compares two configuration entries a la strcmp.
+ * "t_checkconfent" verifies that a set of configuration parameters
+ * are suitable. N must be prime and should be a safe prime.
+ * "t_putconfent" writes a configuration entry to a stream.
+ */
+_TYPE( struct t_conf * ) t_openconf P((FILE *));
+_TYPE( struct t_conf * ) t_openconfbyname P((const char *));
+_TYPE( void ) t_closeconf P((struct t_conf *));
+_TYPE( void ) t_rewindconf P((struct t_conf *));
+_TYPE( struct t_confent * ) t_getconfent P((struct t_conf *));
+_TYPE( struct t_confent * ) t_getconfbyindex P((struct t_conf *, int));
+_TYPE( struct t_confent * ) t_getconflast P((struct t_conf *));
+_TYPE( struct t_confent * ) t_makeconfent P((struct t_conf *, int));
+_TYPE( struct t_confent * ) t_makeconfent_c P((struct t_conf *, int));
+_TYPE( struct t_confent * ) t_newconfent P((struct t_conf *));
+_TYPE( int ) t_cmpconfent P((const struct t_confent *, const struct t_confent *));
+_TYPE( int ) t_checkconfent P((const struct t_confent *));
+_TYPE( void ) t_putconfent P((const struct t_confent *, FILE *));
+
+/* libc-style system conf file access */
+_TYPE( struct t_confent *) gettcent();
+_TYPE( struct t_confent *) gettcid P((int));
+_TYPE( void ) settcent();
+_TYPE( void ) endtcent();
+
+#ifdef ENABLE_NSW
+extern struct t_confent * _gettcent();
+extern struct t_confent * _gettcid P((int));
+extern void _settcent();
+extern void _endtcent();
+#endif
+
+/* A hack to support '+'-style entries in the passwd file */
+
+typedef enum fstate {
+ FILE_ONLY, /* Ordinary file, don't consult NIS ever */
+ FILE_NIS, /* Currently accessing file, use NIS if encountered */
+ IN_NIS, /* Currently in a '+' entry; use NIS for getXXent */
+} FILE_STATE;
+
+struct t_pwent { /* A single password file entry */
+ char * name;
+ struct t_num password;
+ struct t_num salt;
+ int index;
+};
+
+struct t_pw { /* An open password file */
+ FILE * instream;
+ char close_on_exit;
+ FILE_STATE state;
+ char userbuf[MAXUSERLEN];
+ unsigned char pwbuf[MAXPARAMLEN];
+ unsigned char saltbuf[SALTLEN];
+ struct t_pwent pebuf;
+};
+
+/*
+ * The password manipulation routines are patterned after the getpw*
+ * standard C library function calls.
+ *
+ * "t_openpw" reads a stream as if it were a password file.
+ * "t_openpwbyname" opens the named file as a password file.
+ * "t_closepw" closes an open password file.
+ * "t_rewindpw" starts the internal file pointer from the beginning
+ * of the password file.
+ * "t_getpwent" retrieves the next sequential password entry.
+ * "t_getpwbyname" looks up the password entry corresponding to the
+ * specified user.
+ * "t_makepwent" constructs a password entry from a username, password,
+ * numeric salt, and configuration entry.
+ * "t_putpwent" writes a password entry to a stream.
+ */
+_TYPE( struct t_pw * ) t_openpw P((FILE *));
+_TYPE( struct t_pw * ) t_openpwbyname P((const char *));
+_TYPE( void ) t_closepw P((struct t_pw *));
+_TYPE( void ) t_rewindpw P((struct t_pw *));
+_TYPE( struct t_pwent * ) t_getpwent P((struct t_pw *));
+_TYPE( struct t_pwent * ) t_getpwbyname P((struct t_pw *, const char *));
+_TYPE( struct t_pwent * ) t_makepwent P((struct t_pw *, const char *,
+ const char *, const struct t_num *,
+ const struct t_confent *));
+_TYPE( void ) t_putpwent P((const struct t_pwent *, FILE *));
+
+struct t_passwd {
+ struct t_pwent tp;
+ struct t_confent tc;
+};
+
+/* libc-style system password file access */
+_TYPE( struct t_passwd * ) gettpent();
+_TYPE( struct t_passwd * ) gettpnam P((const char *));
+_TYPE( void ) settpent();
+_TYPE( void ) endtpent();
+
+#ifdef ENABLE_NSW
+extern struct t_passwd * _gettpent();
+extern struct t_passwd * _gettpnam P((const char *));
+extern void _settpent();
+extern void _endtpent();
+#endif
+
+/*
+ * Utility functions
+ *
+ * "t_verifypw" accepts a username and password, and checks against the
+ * system password file to see if the password for that user is correct.
+ * Returns > 0 if it is correct, 0 if not, and -1 if some error occurred
+ * (i.e. the user doesn't exist on the system). This is intended ONLY
+ * for local authentication; for remote authentication, look at the
+ * t_client and t_server source. (That's the whole point of SRP!)
+ * "t_changepw" modifies the specified file, substituting the given password
+ * entry for the one already in the file. If no matching entry is found,
+ * the new entry is simply appended to the file.
+ * "t_deletepw" removes the specified user from the specified file.
+ */
+_TYPE( int ) t_verifypw P((const char *, const char *));
+_TYPE( int ) t_changepw P((const char *, const struct t_pwent *));
+_TYPE( int ) t_deletepw P((const char *, const char *));
+
+/* Conversion utilities */
+
+/*
+ * All these calls accept output as the first parameter. In the case of
+ * t_tohex and t_tob64, the last argument is the length of the byte-string
+ * input.
+ */
+_TYPE( char * t_tohex ) P((char *, char *, unsigned));
+_TYPE( int ) t_fromhex P((char *, char *));
+_TYPE( char * ) t_tob64 P((char *, char *, unsigned));
+_TYPE( int ) t_fromb64 P((char *, char *));
+
+/* Miscellaneous utilities */
+
+/*
+ * "t_random" is a cryptographic random number generator, which is seeded
+ * from various high-entropy sources and uses a one-way hash function
+ * in a feedback configuration.
+ * "t_sessionkey" is the interleaved hash used to generate session keys
+ * from a large integer.
+ * "t_getpass" reads a password from the terminal without echoing.
+ */
+_TYPE( void ) t_random P((unsigned char *, unsigned));
+_TYPE( void ) t_stronginitrand();
+_TYPE( unsigned char * )
+ t_sessionkey P((unsigned char *, unsigned char *, unsigned));
+_TYPE( int ) t_getpass P((char *, unsigned, const char *));
+
+/*
+ * Return value of t_checkprime:
+ * < 0 : not prime
+ * = 0 : prime, but not safe
+ * > 0 : safe
+ */
+#define NUM_NOTPRIME -1
+#define NUM_NOTSAFE 0
+#define NUM_SAFE 1
+
+_TYPE( int ) t_checkprime P((const struct t_num *));
+
+#endif
diff --git a/package/network/services/ead/src/tinysrp/t_read.c b/package/network/services/ead/src/tinysrp/t_read.c
new file mode 100644
index 0000000..087b7d5
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_read.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "config.h"
+
+#define FSEPARATOR ':'
+
+int
+t_nextfield(fp, s, max)
+FILE * fp;
+char * s;
+unsigned max;
+{
+ int c, count = 0;
+
+ while((c = getc(fp)) != EOF) {
+ if(c == '\n') {
+ ungetc(c, fp);
+ break;
+ }
+ else if(c == FSEPARATOR)
+ break;
+ if(count < max - 1) {
+ *s++ = c;
+ ++count;
+ }
+ }
+ *s++ = '\0';
+ return count;
+}
+
+int
+t_nextline(fp)
+FILE * fp;
+{
+ int c;
+
+ while((c = getc(fp)) != '\n')
+ if(c == EOF)
+ return -1;
+ return 0;
+}
diff --git a/package/network/services/ead/src/tinysrp/t_read.h b/package/network/services/ead/src/tinysrp/t_read.h
new file mode 100644
index 0000000..e621f79
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_read.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#ifndef _T_READ_H_
+#define _T_READ_H_
+
+#if !defined(P)
+#ifdef __STDC__
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+extern int t_nextfield P((FILE *, char *, unsigned));
+extern int t_nextline P((FILE *));
+#endif
diff --git a/package/network/services/ead/src/tinysrp/t_server.c b/package/network/services/ead/src/tinysrp/t_server.c
new file mode 100644
index 0000000..6ab501b
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_server.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include <stdio.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_server.h"
+
+_TYPE( struct t_server * )
+t_serveropenraw(ent, tce)
+ struct t_pwent * ent;
+ struct t_confent * tce;
+{
+ struct t_server * ts;
+ unsigned char buf1[SHA_DIGESTSIZE], buf2[SHA_DIGESTSIZE];
+ SHA1_CTX ctxt;
+ int i;
+
+ if((ts = malloc(sizeof(struct t_server))) == 0)
+ return 0;
+
+ SHA1Init(&ts->ckhash);
+
+ ts->index = ent->index;
+ ts->n.len = tce->modulus.len;
+ ts->n.data = ts->nbuf;
+ memcpy(ts->n.data, tce->modulus.data, ts->n.len);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, ts->n.data, ts->n.len);
+ SHA1Final(buf1, &ctxt);
+
+ ts->g.len = tce->generator.len;
+ ts->g.data = ts->gbuf;
+ memcpy(ts->g.data, tce->generator.data, ts->g.len);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, ts->g.data, ts->g.len);
+ SHA1Final(buf2, &ctxt);
+
+ for(i = 0; i < sizeof(buf1); ++i)
+ buf1[i] ^= buf2[i];
+
+ SHA1Update(&ts->ckhash, buf1, sizeof(buf1));
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, ent->name, strlen(ent->name));
+ SHA1Final(buf1, &ctxt);
+
+ SHA1Update(&ts->ckhash, buf1, sizeof(buf1));
+
+ ts->v.len = ent->password.len;
+ ts->v.data = ts->vbuf;
+ memcpy(ts->v.data, ent->password.data, ts->v.len);
+
+ ts->s.len = ent->salt.len;
+ ts->s.data = ts->saltbuf;
+ memcpy(ts->s.data, ent->salt.data, ts->s.len);
+
+ SHA1Update(&ts->ckhash, ts->s.data, ts->s.len);
+
+ ts->b.data = ts->bbuf;
+ ts->B.data = ts->Bbuf;
+
+ SHA1Init(&ts->hash);
+ SHA1Init(&ts->oldhash);
+ SHA1Init(&ts->oldckhash);
+
+ return ts;
+}
+
+_TYPE( struct t_num * )
+t_servergenexp(ts)
+ struct t_server * ts;
+{
+ BigInteger b, B, v, n, g;
+
+ if(ts->n.len < BLEN)
+ ts->b.len = ts->n.len;
+ else
+ ts->b.len = BLEN;
+
+ t_random(ts->b.data, ts->b.len);
+ b = BigIntegerFromBytes(ts->b.data, ts->b.len);
+ n = BigIntegerFromBytes(ts->n.data, ts->n.len);
+ g = BigIntegerFromBytes(ts->g.data, ts->g.len);
+ B = BigIntegerFromInt(0);
+ BigIntegerModExp(B, g, b, n);
+
+ v = BigIntegerFromBytes(ts->v.data, ts->v.len);
+ BigIntegerAdd(B, B, v);
+ if(BigIntegerCmp(B, n) > 0)
+ BigIntegerSub(B, B, n);
+
+ ts->B.len = BigIntegerToBytes(B, ts->B.data);
+
+ BigIntegerFree(v);
+ BigIntegerFree(B);
+ BigIntegerFree(b);
+ BigIntegerFree(g);
+ BigIntegerFree(n);
+
+ SHA1Update(&ts->oldckhash, ts->B.data, ts->B.len);
+
+ return &ts->B;
+}
+
+_TYPE( unsigned char * )
+t_servergetkey(ts, clientval)
+ struct t_server * ts;
+ struct t_num * clientval;
+{
+ BigInteger n, v, A, b, prod, res, S;
+ SHA1_CTX ctxt;
+ unsigned char sbuf[MAXPARAMLEN];
+ unsigned char dig[SHA_DIGESTSIZE];
+ unsigned slen;
+ unsigned int u;
+
+ SHA1Update(&ts->ckhash, clientval->data, clientval->len);
+ SHA1Update(&ts->ckhash, ts->B.data, ts->B.len);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, ts->B.data, ts->B.len);
+ SHA1Final(dig, &ctxt);
+ u = (dig[0] << 24) | (dig[1] << 16) | (dig[2] << 8) | dig[3];
+
+ SHA1Update(&ts->oldhash, clientval->data, clientval->len);
+ SHA1Update(&ts->hash, clientval->data, clientval->len);
+
+ n = BigIntegerFromBytes(ts->n.data, ts->n.len);
+ b = BigIntegerFromBytes(ts->b.data, ts->b.len);
+ v = BigIntegerFromBytes(ts->v.data, ts->v.len);
+ A = BigIntegerFromBytes(clientval->data, clientval->len);
+
+ prod = BigIntegerFromInt(0);
+ BigIntegerModExpInt(prod, v, u, n);
+ res = BigIntegerFromInt(0);
+ BigIntegerModMul(res, prod, A, n);
+
+ BigIntegerFree(A);
+ BigIntegerFree(v);
+ BigIntegerFree(prod);
+
+ if(BigIntegerCmpInt(res, 1) <= 0) { /* Check for Av^u == 1 (mod n) */
+ BigIntegerFree(res);
+ BigIntegerFree(b);
+ BigIntegerFree(n);
+ return NULL;
+ }
+
+ S = BigIntegerFromInt(0);
+
+ BigIntegerAddInt(S, res, 1);
+ if(BigIntegerCmp(S, n) == 0) { /* Check for Av^u == -1 (mod n) */
+ BigIntegerFree(res);
+ BigIntegerFree(b);
+ BigIntegerFree(n);
+ BigIntegerFree(S);
+ return NULL;
+ }
+
+ BigIntegerModExp(S, res, b, n);
+ slen = BigIntegerToBytes(S, sbuf);
+
+ BigIntegerFree(S);
+ BigIntegerFree(res);
+ BigIntegerFree(b);
+ BigIntegerFree(n);
+
+ t_sessionkey(ts->session_key, sbuf, slen);
+ memset(sbuf, 0, slen);
+
+ SHA1Update(&ts->oldhash, ts->session_key, sizeof(ts->session_key));
+ SHA1Update(&ts->oldckhash, ts->session_key, sizeof(ts->session_key));
+ SHA1Update(&ts->ckhash, ts->session_key, sizeof(ts->session_key));
+
+ return ts->session_key;
+}
+
+_TYPE( int )
+t_serververify(ts, resp)
+ struct t_server * ts;
+ unsigned char * resp;
+{
+ unsigned char expected[SHA_DIGESTSIZE];
+ int i;
+
+ SHA1Final(expected, &ts->oldckhash);
+ i = memcmp(expected, resp, sizeof(expected));
+ if(i == 0) {
+ SHA1Final(ts->session_response, &ts->oldhash);
+ return 0;
+ }
+ SHA1Final(expected, &ts->ckhash);
+ i = memcmp(expected, resp, sizeof(expected));
+ if(i == 0) {
+ SHA1Update(&ts->hash, expected, sizeof(expected));
+ SHA1Update(&ts->hash, ts->session_key, sizeof(ts->session_key));
+ SHA1Final(ts->session_response, &ts->hash);
+ }
+ return i;
+}
+
+_TYPE( unsigned char * )
+t_serverresponse(ts)
+ struct t_server * ts;
+{
+ return ts->session_response;
+}
+
+_TYPE( void )
+t_serverclose(ts)
+ struct t_server * ts;
+{
+ memset(ts->bbuf, 0, sizeof(ts->bbuf));
+ memset(ts->vbuf, 0, sizeof(ts->vbuf));
+ memset(ts->saltbuf, 0, sizeof(ts->saltbuf));
+ memset(ts->session_key, 0, sizeof(ts->session_key));
+ free(ts);
+}
diff --git a/package/network/services/ead/src/tinysrp/t_server.h b/package/network/services/ead/src/tinysrp/t_server.h
new file mode 100644
index 0000000..20970ff
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_server.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#ifndef T_SERVER_H
+#define T_SERVER_H
+
+#include "t_sha.h"
+
+#if !defined(P)
+#ifdef __STDC__
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+#ifndef _DLLDECL
+#define _DLLDECL
+
+#ifdef MSVC15 /* MSVC1.5 support for 16 bit apps */
+#define _MSVC15EXPORT _export
+#define _MSVC20EXPORT
+#define _DLLAPI _export _pascal
+#define _TYPE(a) a _MSVC15EXPORT
+#define DLLEXPORT 1
+
+#elif MSVC20
+#define _MSVC15EXPORT
+#define _MSVC20EXPORT _declspec(dllexport)
+#define _DLLAPI
+#define _TYPE(a) _MSVC20EXPORT a
+#define DLLEXPORT 1
+
+#else /* Default, non-dll. Use this for Unix or DOS */
+#define _MSVC15DEXPORT
+#define _MSVC20EXPORT
+#define _DLLAPI
+#define _TYPE(a) a
+#endif
+#endif
+
+#define BLEN 32
+
+struct t_server {
+ int index;
+ struct t_num n;
+ struct t_num g;
+ struct t_num v;
+ struct t_num s;
+
+ struct t_num b;
+ struct t_num B;
+
+ SHA1_CTX oldhash, hash, oldckhash, ckhash;
+
+ unsigned char session_key[SESSION_KEY_LEN];
+ unsigned char session_response[RESPONSE_LEN];
+
+ unsigned char nbuf[MAXPARAMLEN], gbuf[MAXPARAMLEN], vbuf[MAXPARAMLEN];
+ unsigned char saltbuf[MAXSALTLEN], bbuf[BLEN], Bbuf[MAXPARAMLEN];
+};
+
+/*
+ * SRP server-side negotiation
+ *
+ * This code negotiates the server side of an SRP exchange.
+ * "t_serveropen" accepts a username (sent by the client), a pointer
+ * to an open password file, and a pointer to an open configuration
+ * file. The server should then call...
+ * "t_servergenexp" will generate a random 256-bit exponent and
+ * raise g (from the configuration file) to that power, returning
+ * the result. This result should be sent to the client as y(p).
+ * "t_servergetkey" accepts the exponential w(p), which should be
+ * sent by the client, and computes the 256-bit session key.
+ * This data should be saved before the session is closed.
+ * "t_serverresponse" computes the session key proof as SHA(w(p), K).
+ * "t_serverclose" closes the session and frees its memory.
+ *
+ * Note that authentication is not performed per se; it is up
+ * to either/both sides of the protocol to now verify securely
+ * that their session keys agree in order to establish authenticity.
+ * One possible way is through "oracle hashing"; one side sends
+ * r, the other replies with H(r,K), where H() is a hash function.
+ *
+ * t_serverresponse and t_serververify now implement a version of
+ * the session-key verification described above.
+ */
+_TYPE( struct t_server * )
+ t_serveropen P((const char *));
+_TYPE( struct t_server * )
+ t_serveropenfromfiles P((const char *, struct t_pw *, struct t_conf *));
+_TYPE( struct t_server * )
+ t_serveropenraw P((struct t_pwent *, struct t_confent *));
+_TYPE( struct t_num * ) t_servergenexp P((struct t_server *));
+_TYPE( unsigned char * ) t_servergetkey P((struct t_server *, struct t_num *));
+_TYPE( int ) t_serververify P((struct t_server *, unsigned char *));
+_TYPE( unsigned char * ) t_serverresponse P((struct t_server *));
+_TYPE( void ) t_serverclose P((struct t_server *));
+
+#endif
diff --git a/package/network/services/ead/src/tinysrp/t_sha.c b/package/network/services/ead/src/tinysrp/t_sha.c
new file mode 100644
index 0000000..cc41d64
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_sha.c
@@ -0,0 +1,166 @@
+#include "t_defines.h"
+#include "t_sha.h"
+
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+/* #define WORDS_BIGENDIAN * This should be #define'd if true. */
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+#include <stdio.h>
+#include <string.h>
+
+static void SHA1Transform(uint32 state[5], const unsigned char buffer[64]);
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifndef WORDS_BIGENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+ |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+ ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+static void SHA1Transform(uint32 state[5], const unsigned char buffer[64])
+{
+uint32 a, b, c, d, e;
+typedef union {
+ unsigned char c[64];
+ uint32 l[16];
+} CHAR64LONG16;
+CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+static unsigned char workspace[64];
+ block = (CHAR64LONG16*)workspace;
+ memcpy(block, buffer, 64);
+#else
+ block = (CHAR64LONG16*)buffer;
+#endif
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
+{
+unsigned int i, j;
+
+ j = (context->count[0] >> 3) & 63;
+ if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+ context->count[1] += (len >> 29);
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64-j));
+ SHA1Transform(context->state, context->buffer);
+ for ( ; i + 63 < len; i += 64) {
+ SHA1Transform(context->state, &data[i]);
+ }
+ j = 0;
+ }
+ else i = 0;
+ memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+{
+uint32 i, j;
+unsigned char finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
+ }
+ SHA1Update(context, (unsigned char *)"\200", 1);
+ while ((context->count[0] & 504) != 448) {
+ SHA1Update(context, (unsigned char *)"\0", 1);
+ }
+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
+ for (i = 0; i < 20; i++) {
+ digest[i] = (unsigned char)
+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+ }
+ /* Wipe variables */
+ i = j = 0;
+ memset(context->buffer, 0, 64);
+ memset(context->state, 0, 20);
+ memset(context->count, 0, 8);
+ memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
+ SHA1Transform(context->state, context->buffer);
+#endif
+}
diff --git a/package/network/services/ead/src/tinysrp/t_sha.h b/package/network/services/ead/src/tinysrp/t_sha.h
new file mode 100644
index 0000000..d10115e
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_sha.h
@@ -0,0 +1,26 @@
+#ifndef T_SHA_H
+#define T_SHA_H
+
+#if !defined(P)
+#ifdef __STDC__
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+#define SHA_DIGESTSIZE 20
+
+typedef unsigned int uint32;
+
+typedef struct {
+ uint32 state[5];
+ uint32 count[2];
+ unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Init P((SHA1_CTX* context));
+void SHA1Update P((SHA1_CTX* context, const unsigned char* data, unsigned int len));
+void SHA1Final P((unsigned char digest[20], SHA1_CTX* context));
+
+#endif /* T_SHA_H */
diff --git a/package/network/services/ead/src/tinysrp/t_truerand.c b/package/network/services/ead/src/tinysrp/t_truerand.c
new file mode 100644
index 0000000..fa0d6ce
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/t_truerand.c
@@ -0,0 +1,151 @@
+/*
+ * Physically random numbers (very nearly uniform)
+ * D. P. Mitchell
+ * Modified by Matt Blaze 7/95
+ */
+/*
+ * The authors of this software are Don Mitchell and Matt Blaze.
+ * Copyright (c) 1995 by AT&T.
+ * Permission to use, copy, and modify this software without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * This software may be subject to United States export controls.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ */
+
+/*
+ * WARNING: depending on the particular platform, raw_truerand()
+ * output may be biased or correlated. In general, you can expect
+ * about 16 bits of "pseudo-entropy" out of each 32 bit word returned
+ * by truerand(), but it may not be uniformly diffused. You should
+ * raw_therefore run the output through some post-whitening function
+ * (like MD5 or DES or whatever) before using it to generate key
+ * material. (RSAREF's random package does this for you when you feed
+ * raw_truerand() bits to the seed input function.)
+ *
+ * The application interface, for 8, 16, and 32 bit properly "whitened"
+ * random numbers, can be found in trand8(), trand16(), and trand32().
+ * Use those instead of calling raw_truerand() directly.
+ *
+ * The basic idea here is that between clock "skew" and various
+ * hard-to-predict OS event arrivals, counting a tight loop will yield
+ * a little (maybe a third of a bit or so) of "good" randomness per
+ * interval clock tick. This seems to work well even on unloaded
+ * machines. If there is a human operator at the machine, you should
+ * augment truerand with other measure, like keyboard event timing.
+ * On server machines (e.g., when you need to generate a
+ * Diffie-Hellman secret) truerand alone may be good enough.
+ *
+ * Test these assumptions on your own platform before fielding a
+ * system based on this software or these techniques.
+ *
+ * This software seems to work well (at 10 or so bits per
+ * raw_truerand() call) on a Sun Sparc-20 under SunOS 4.1.3 and on a
+ * P100 under BSDI 2.0. You're on your own elsewhere.
+ *
+ */
+
+#include "t_defines.h"
+
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/time.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifdef OLD_TRUERAND
+static jmp_buf env;
+#endif
+static unsigned volatile count
+#ifndef OLD_TRUERAND
+ , done = 0
+#endif
+;
+
+static unsigned ocount;
+static unsigned buffer;
+
+static void
+tick()
+{
+ struct itimerval it, oit;
+
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 0;
+ it.it_value.tv_sec = 0;
+ it.it_value.tv_usec = 16665;
+ if (setitimer(ITIMER_REAL, &it, &oit) < 0)
+ perror("tick");
+}
+
+static void
+interrupt()
+{
+ if (count) {
+#ifdef OLD_TRUERAND
+ longjmp(env, 1);
+#else
+ ++done;
+ return;
+#endif
+ }
+
+ (void) signal(SIGALRM, interrupt);
+ tick();
+}
+
+static unsigned long
+roulette()
+{
+#ifdef OLD_TRUERAND
+ if (setjmp(env)) {
+ count ^= (count>>3) ^ (count>>6) ^ ocount;
+ count &= 0x7;
+ ocount=count;
+ buffer = (buffer<<3) ^ count;
+ return buffer;
+ }
+#else
+ done = 0;
+#endif
+ (void) signal(SIGALRM, interrupt);
+ count = 0;
+ tick();
+#ifdef OLD_TRUERAND
+ for (;;)
+#else
+ while(done == 0)
+#endif
+ count++; /* about 1 MHz on VAX 11/780 */
+#ifndef OLD_TRUERAND
+ count ^= (count>>3) ^ (count>>6) ^ ocount;
+ count &= 0x7;
+ ocount=count;
+ buffer = (buffer<<3) ^ count;
+ return buffer;
+#endif
+}
+
+unsigned long
+raw_truerand()
+{
+ count=0;
+ (void) roulette();
+ (void) roulette();
+ (void) roulette();
+ (void) roulette();
+ (void) roulette();
+ (void) roulette();
+ (void) roulette();
+ (void) roulette();
+ (void) roulette();
+ (void) roulette();
+ return roulette();
+}
diff --git a/package/network/services/ead/src/tinysrp/tconf.c b/package/network/services/ead/src/tinysrp/tconf.c
new file mode 100644
index 0000000..ad77f4c
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/tconf.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1997-2000 The Stanford SRP Authentication Project
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following conditions apply:
+ *
+ * 1. Any software that incorporates the SRP authentication technology
+ * must display the following acknowlegment:
+ * "This product uses the 'Secure Remote Password' cryptographic
+ * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
+ *
+ * 2. Any software that incorporates all or part of the SRP distribution
+ * itself must also display the following acknowledgment:
+ * "This product includes software developed by Tom Wu and Eugene
+ * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
+ *
+ * 3. Redistributions in source or binary form must retain an intact copy
+ * of this copyright notice and list of conditions.
+ */
+
+#include <unistd.h> /* close getlogin */
+#include <stdlib.h> /* atexit exit */
+#include <stdio.h>
+#include <string.h>
+
+#include "t_pwd.h"
+
+#define MIN_BASIS_BITS 512
+#define BASIS_BITS 2048
+
+extern int optind;
+extern char *optarg;
+
+extern int errno;
+
+char *progName;
+
+int debug = 0;
+int verbose = 0;
+int composite = 0;
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *chp;
+ char *configFile = NULL;
+ char cbuf[256];
+ char b64buf[MAXB64PARAMLEN];
+ int c, ch, i, lastidx, keylen, yesno, fsize, status, nparams;
+ FILE *efp;
+
+ struct t_preconf * tpc;
+ struct t_conf tcs;
+ struct t_conf * tc = &tcs;
+ struct t_confent * tcent;
+
+ progName = *argv;
+ if ((chp = strrchr(progName, '/')) != (char *) 0) progName = chp + 1;
+
+ while ((ch = getopt(argc, argv, "dv2c:")) != EOF)
+ switch(ch) {
+ case 'c':
+ configFile = optarg;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'd':
+ debug++;
+ break;
+ case '2':
+ composite++;
+ break;
+ default:
+ fprintf(stderr, "usage: %s [-dv2] [-c configfile]\n", progName);
+ exit(1);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ lastidx = 0;
+ keylen = 0;
+
+ tcent = t_newconfent(tc);
+
+ printf("\nThis program will generate a set of parameters for the EPS\n");
+ printf("password file. The size of these parameters, measured in bits,\n");
+ printf("determines the level of security offered by SRP, and is related\n");
+ printf("to the security of similarly-sized RSA or Diffie-Hellman keys.\n");
+ printf("Choosing a predefined field is generally preferable to generating\n");
+ printf("a new field because clients can avoid costly parameter verification.\n");
+ printf("Either way, the values generated by this program are public and\n");
+ printf("can even shared between systems.\n");
+
+ printf("\nEnter the new field size, in bits. Suggested sizes:\n\n");
+ printf(" 512 (fast, minimally secure)\n");
+ printf(" 768 (moderate security)\n");
+ printf("1024 (most popular default)\n");
+ printf("1536 (additional security, possibly slow)\n");
+ printf("2048 (maximum supported security level)\n");
+ printf("\nField size (%d to %d): ", MIN_BASIS_BITS, BASIS_BITS);
+
+ fgets(cbuf, sizeof(cbuf), stdin);
+ fsize = atoi(cbuf);
+ if(fsize < MIN_BASIS_BITS || fsize > BASIS_BITS) {
+ fprintf(stderr, "%s: field size must be between %d and %d\n",
+ progName, MIN_BASIS_BITS, BASIS_BITS);
+ exit(1);
+ }
+
+ if(fsize <= keylen)
+ fprintf(stderr, "Warning: new field size is not larger than old field size\n");
+
+ printf("\nInitializing random number generator...");
+ fflush(stdout);
+ t_initrand();
+
+ if(composite)
+ printf("done.\n\nGenerating a %d-bit composite with safe prime factors. This may take a while.\n", fsize);
+ else
+ printf("done.\n\nGenerating a %d-bit safe prime. This may take a while.\n", fsize);
+
+ while((tcent = (composite ? t_makeconfent_c(tc, fsize) :
+ t_makeconfent(tc, fsize))) == NULL)
+ printf("Parameter generation failed, retrying...\n");
+ tcent->index = lastidx + 1;
+
+ printf("\nParameters successfully generated.\n");
+ printf("N = [%s]\n", t_tob64(b64buf,
+ tcent->modulus.data, tcent->modulus.len));
+ printf("g = [%s]\n", t_tob64(b64buf,
+ tcent->generator.data, tcent->generator.len));
+ printf("\nYou must update the pre_params array in t_getconf.c\n");
+}
diff --git a/package/network/services/ead/src/tinysrp/tinysrp.c b/package/network/services/ead/src/tinysrp/tinysrp.c
new file mode 100644
index 0000000..fc01055
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/tinysrp.c
@@ -0,0 +1,235 @@
+/* This bit implements a simple API for using the SRP library over sockets. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include "t_defines.h"
+#include "t_pwd.h"
+#include "t_server.h"
+#include "t_client.h"
+#include "tinysrp.h"
+
+#ifndef MSG_WAITALL
+#ifdef linux
+#define MSG_WAITALL 0x100 /* somehow not defined on my box */
+#endif
+#endif
+
+/* This is called by the client with a connected socket, username, and
+passphrase. pass can be NULL in which case the user is queried. */
+
+int tsrp_client_authenticate(int s, char *user, char *pass, TSRP_SESSION *tsrp)
+{
+ int i, index;
+ unsigned char username[MAXUSERLEN + 1], sbuf[MAXSALTLEN];
+ unsigned char msgbuf[MAXPARAMLEN + 1], bbuf[MAXPARAMLEN];
+ unsigned char passbuf[128], *skey;
+ struct t_client *tc;
+ struct t_preconf *tcp; /* @@@ should go away */
+ struct t_num salt, *A, B;
+
+ /* Send the username. */
+
+ i = strlen(user);
+ if (i > MAXUSERLEN) {
+ i = MAXUSERLEN;
+ }
+ msgbuf[0] = i;
+ memcpy(msgbuf + 1, user, i);
+ if (send(s, msgbuf, i + 1, 0) < 0) {
+ return 0;
+ }
+ memcpy(username, user, i);
+ username[i] = '\0';
+
+ /* Get the prime index and salt. */
+
+ i = recv(s, msgbuf, 2, MSG_WAITALL);
+ if (i <= 0) {
+ return 0;
+ }
+ index = msgbuf[0];
+ if (index <= 0 || index > t_getprecount()) {
+ return 0;
+ }
+ tcp = t_getpreparam(index - 1);
+ salt.len = msgbuf[1];
+ if (salt.len > MAXSALTLEN) {
+ return 0;
+ }
+ salt.data = sbuf;
+ i = recv(s, sbuf, salt.len, MSG_WAITALL);
+ if (i <= 0) {
+ return 0;
+ }
+
+ /* @@@ t_clientopen() needs a variant that takes the index */
+
+ tc = t_clientopen(username, &tcp->modulus, &tcp->generator, &salt);
+ if (tc == NULL) {
+ return 0;
+ }
+
+ /* Calculate A and send it to the server. */
+
+ A = t_clientgenexp(tc);
+ msgbuf[0] = A->len - 1; /* len is max 256 */
+ memcpy(msgbuf + 1, A->data, A->len);
+ if (send(s, msgbuf, A->len + 1, 0) < 0) {
+ return 0;
+ }
+
+ /* Ask the user for the passphrase. */
+
+ if (pass == NULL) {
+ t_getpass(passbuf, sizeof(passbuf), "Enter password:");
+ pass = passbuf;
+ }
+ t_clientpasswd(tc, pass);
+
+ /* Get B from the server. */
+
+ i = recv(s, msgbuf, 1, 0);
+ if (i <= 0) {
+ return 0;
+ }
+ B.len = msgbuf[0] + 1;
+ B.data = bbuf;
+ i = recv(s, bbuf, B.len, MSG_WAITALL);
+ if (i <= 0) {
+ return 0;
+ }
+
+ /* Compute the session key. */
+
+ skey = t_clientgetkey(tc, &B);
+ if (skey == NULL) {
+ return 0;
+ }
+
+ /* Send the response. */
+
+ if (send(s, t_clientresponse(tc), RESPONSE_LEN, 0) < 0) {
+ return 0;
+ }
+
+ /* Get the server's response. */
+
+ i = recv(s, msgbuf, RESPONSE_LEN, MSG_WAITALL);
+ if (i <= 0) {
+ return 0;
+ }
+ if (t_clientverify(tc, msgbuf) != 0) {
+ return 0;
+ }
+
+ /* All done. Now copy the key and clean up. */
+
+ if (tsrp) {
+ memcpy(tsrp->username, username, strlen(username) + 1);
+ memcpy(tsrp->key, skey, SESSION_KEY_LEN);
+ }
+ t_clientclose(tc);
+
+ return 1;
+}
+
+/* This is called by the server with a connected socket. */
+
+int tsrp_server_authenticate(int s, TSRP_SESSION *tsrp)
+{
+ int i, j;
+ unsigned char username[MAXUSERLEN], *skey;
+ unsigned char msgbuf[MAXPARAMLEN + 1], abuf[MAXPARAMLEN];
+ struct t_server *ts;
+ struct t_num A, *B;
+
+ /* Get the username. */
+
+ i = recv(s, msgbuf, 1, 0);
+ if (i <= 0) {
+ return 0;
+ }
+ j = msgbuf[0];
+ i = recv(s, username, j, MSG_WAITALL);
+ if (i <= 0) {
+ return 0;
+ }
+ username[j] = '\0';
+
+ ts = t_serveropen(username);
+ if (ts == NULL) {
+ return 0;
+ }
+
+ /* Send the prime index and the salt. */
+
+ msgbuf[0] = ts->index; /* max 256 primes... */
+ i = ts->s.len;
+ msgbuf[1] = i;
+ memcpy(msgbuf + 2, ts->s.data, i);
+ if (send(s, msgbuf, i + 2, 0) < 0) {
+ return 0;
+ }
+
+ /* Calculate B while we're waiting. */
+
+ B = t_servergenexp(ts);
+
+ /* Get A from the client. */
+
+ i = recv(s, msgbuf, 1, 0);
+ if (i <= 0) {
+ return 0;
+ }
+ A.len = msgbuf[0] + 1;
+ A.data = abuf;
+ i = recv(s, abuf, A.len, MSG_WAITALL);
+ if (i <= 0) {
+ return 0;
+ }
+
+ /* Now send B. */
+
+ msgbuf[0] = B->len - 1;
+ memcpy(msgbuf + 1, B->data, B->len);
+ if (send(s, msgbuf, B->len + 1, 0) < 0) {
+ return 0;
+ }
+
+ /* Calculate the session key while we're waiting. */
+
+ skey = t_servergetkey(ts, &A);
+ if (skey == NULL) {
+ return 0;
+ }
+
+ /* Get the response from the client. */
+
+ i = recv(s, msgbuf, RESPONSE_LEN, MSG_WAITALL);
+ if (i <= 0) {
+ return 0;
+ }
+ if (t_serververify(ts, msgbuf) != 0) {
+ return 0;
+ }
+
+ /* Client authenticated. Now authenticate ourselves to the client. */
+
+ if (send(s, t_serverresponse(ts), RESPONSE_LEN, 0) < 0) {
+ return 0;
+ }
+
+ /* Copy the key and clean up. */
+
+ if (tsrp) {
+ memcpy(tsrp->username, username, strlen(username) + 1);
+ memcpy(tsrp->key, skey, SESSION_KEY_LEN);
+ }
+ t_serverclose(ts);
+
+ return 1;
+}
diff --git a/package/network/services/ead/src/tinysrp/tinysrp.h b/package/network/services/ead/src/tinysrp/tinysrp.h
new file mode 100644
index 0000000..4420a19
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/tinysrp.h
@@ -0,0 +1,18 @@
+/* Simple API for the tinysrp library. */
+
+#ifndef T_PWD_H
+#define MAXUSERLEN 32
+#define SESSION_KEY_LEN 40 /* 320-bit session key */
+#endif
+
+typedef struct {
+ char username[MAXUSERLEN + 1];
+ unsigned char key[SESSION_KEY_LEN];
+} TSRP_SESSION;
+
+/* These functions are passed a connected socket, and return true for a
+successful authentication. If tsrp is not NULL, the username and key
+fields are filled in. */
+
+extern int tsrp_server_authenticate(int s, TSRP_SESSION *tsrp);
+extern int tsrp_client_authenticate(int s, char *user, char *pass, TSRP_SESSION *tsrp);
diff --git a/package/network/services/ead/src/tinysrp/tpasswd b/package/network/services/ead/src/tinysrp/tpasswd
new file mode 100644
index 0000000..2ac7e2a
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/tpasswd
@@ -0,0 +1,2 @@
+moo:A9lHvOGAMJvw1m3vcDsQRUFovh6/QUmLDKqwhv.drKQzbE9nS7HrOZLUPx2MmS6ewwybN8RHqpWqnUJRCMFT14FMbYXR7kYNUUQNx43A7F.xrVOU7tlFq5NjoK9sfFtp6PMdbIOP5wzWmipiNFlCOu4sjlSZb.o7C1chLzTKU.0:19AI0Hc9jEkdFc:5
+new user:1FsanML2fbTOEsa072bLjyRD1LEqoRD2GwElfN0VmHeR.FAg5A.2.G5bTjIHmMmHL60kgoAHJZhRrgopalYmujlyAuQoKiHJb98SHm1oJaQ9nl/DrZCvfyw5LpVMqg.CupdiWz6OtmOz8fwC96ItExFnNDt6SmsVDIOn4HqXG6C0lLaqEvcqlN3gFDlJXyP2yldM.LJ1TkHTHmA3DjRkmWEUL3mWEgzkEHyPcRB3Jd5ncDT7jaNbJTTLRoOtgRsaqE7OXuPADoK8MGBcUquYBRrGwyU4Y/wW4gLc3QmV793zxkk.P3.dxkLSjro/Kk94D7kC6fx3K9tadLJyzd94rr:3v/KRlxT0.oYF1:1
diff --git a/package/network/services/ead/src/tinysrp/tphrase.c b/package/network/services/ead/src/tinysrp/tphrase.c
new file mode 100644
index 0000000..0ab1e08
--- /dev/null
+++ b/package/network/services/ead/src/tinysrp/tphrase.c
@@ -0,0 +1,354 @@
+/* Add passphrases to the tpasswd file. Use the last entry in the config
+file by default or a particular one specified by index. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "config.h"
+#include "t_pwd.h"
+#include "t_read.h"
+#include "t_sha.h"
+#include "t_defines.h"
+
+char *Progname;
+char Usage[] = "usage: %s [-n configindex] [-p passfile] user\n";
+#define USAGE() fprintf(stderr, Usage, Progname)
+
+void doit(char *);
+
+int Configindex = -1;
+char *Passfile = DEFAULT_PASSWD;
+
+int main(int argc, char **argv)
+{
+ int c;
+
+ Progname = *argv;
+
+ /* Parse option arguments. */
+
+ while ((c = getopt(argc, argv, "n:p:")) != EOF) {
+ switch (c) {
+
+ case 'n':
+ Configindex = atoi(optarg);
+ break;
+
+ case 'p':
+ Passfile = optarg;
+ break;
+
+ default:
+ USAGE();
+ exit(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ USAGE();
+ exit(1);
+ }
+ doit(argv[0]);
+
+ return 0;
+}
+
+void doit(char *name)
+{
+ char passphrase[128], passphrase1[128];
+ FILE *f;
+ struct t_confent *tcent;
+ struct t_pw eps_passwd;
+
+ /* Get the config entry. */
+
+ if (Configindex <= 0) {
+ Configindex = t_getprecount();
+ }
+ tcent = gettcid(Configindex);
+ if (tcent == NULL) {
+ fprintf(stderr, "Invalid configuration file entry.\n");
+ exit(1);
+ }
+
+ /* Ask for the passphrase twice. */
+
+ printf("Setting passphrase for %s\n", name);
+
+ if (t_getpass(passphrase, sizeof(passphrase), "Enter passphrase: ") < 0) {
+ exit(1);
+ }
+ if (t_getpass(passphrase1, sizeof(passphrase1), "Verify: ") < 0) {
+ exit(1);
+ }
+ if (strcmp(passphrase, passphrase1) != 0) {
+ fprintf(stderr, "mismatch\n");
+ exit(1);
+ }
+
+ /* Create the passphrase verifier. */
+
+ t_makepwent(&eps_passwd, name, passphrase, NULL, tcent);
+
+ /* Don't need these anymore. */
+
+ memset(passphrase, 0, sizeof(passphrase));
+ memset(passphrase1, 0, sizeof(passphrase1));
+
+ /* See if the passphrase file is there; create it if not. */
+
+ if ((f = fopen(Passfile, "r+")) == NULL) {
+ creat(Passfile, 0400);
+ } else {
+ fclose(f);
+ }
+
+ /* Change the passphrase. */
+
+ if (t_changepw(Passfile, &eps_passwd.pebuf) < 0) {
+ fprintf(stderr, "Error changing passphrase\n");
+ exit(1);
+ }
+}
+
+/* TODO: Implement a more general method to handle delete/change */
+
+_TYPE( int )
+t_changepw(pwname, diff)
+ const char * pwname;
+ const struct t_pwent * diff;
+{
+ char * bakfile;
+ char * bakfile2;
+ struct stat st;
+ FILE * passfp;
+ FILE * bakfp;
+
+ if(pwname == NULL)
+ pwname = DEFAULT_PASSWD;
+
+ if((passfp = fopen(pwname, "rb")) == NULL || fstat(fileno(passfp), &st) < 0)
+ return -1;
+
+ if((bakfile = malloc(strlen(pwname) + 5)) == NULL) {
+ fclose(passfp);
+ return -1;
+ }
+ else if((bakfile2 = malloc(strlen(pwname) + 5)) == NULL) {
+ fclose(passfp);
+ free(bakfile);
+ return -1;
+ }
+
+ sprintf(bakfile, "%s.bak", pwname);
+ sprintf(bakfile2, "%s.sav", pwname);
+
+ if((bakfp = fopen(bakfile2, "wb")) == NULL &&
+ (unlink(bakfile2) < 0 || (bakfp = fopen(bakfile2, "wb")) == NULL)) {
+ fclose(passfp);
+ free(bakfile);
+ free(bakfile2);
+ return -1;
+ }
+
+#ifdef NO_FCHMOD
+ chmod(bakfile2, st.st_mode & 0777);
+#else
+ fchmod(fileno(bakfp), st.st_mode & 0777);
+#endif
+
+ t_pwcopy(bakfp, passfp, diff);
+
+ fclose(bakfp);
+ fclose(passfp);
+
+#ifdef USE_RENAME
+ unlink(bakfile);
+ if(rename(pwname, bakfile) < 0) {
+ free(bakfile);
+ free(bakfile2);
+ return -1;
+ }
+ if(rename(bakfile2, pwname) < 0) {
+ free(bakfile);
+ free(bakfile2);
+ return -1;
+ }
+#else
+ unlink(bakfile);
+ link(pwname, bakfile);
+ unlink(pwname);
+ link(bakfile2, pwname);
+ unlink(bakfile2);
+#endif
+ free(bakfile);
+ free(bakfile2);
+
+ return 0;
+}
+
+_TYPE( struct t_pwent * )
+t_makepwent(tpw, user, pass, salt, confent)
+ struct t_pw * tpw;
+ const char * user;
+ const char * pass;
+ const struct t_num * salt;
+ const struct t_confent * confent;
+{
+ BigInteger x, v, n, g;
+ unsigned char dig[SHA_DIGESTSIZE];
+ SHA1_CTX ctxt;
+
+ tpw->pebuf.name = tpw->userbuf;
+ tpw->pebuf.password.data = tpw->pwbuf;
+ tpw->pebuf.salt.data = tpw->saltbuf;
+
+ strncpy(tpw->pebuf.name, user, MAXUSERLEN);
+ tpw->pebuf.index = confent->index;
+
+ if(salt) {
+ tpw->pebuf.salt.len = salt->len;
+ memcpy(tpw->pebuf.salt.data, salt->data, salt->len);
+ }
+ else {
+ memset(dig, 0, SALTLEN); /* salt is 80 bits */
+ tpw->pebuf.salt.len = SALTLEN;
+ do {
+ t_random(tpw->pebuf.salt.data, SALTLEN);
+ } while(memcmp(tpw->pebuf.salt.data, dig, SALTLEN) == 0);
+ if(tpw->pebuf.salt.data[0] == 0)
+ tpw->pebuf.salt.data[0] = 0xff;
+ }
+
+ n = BigIntegerFromBytes(confent->modulus.data, confent->modulus.len);
+ g = BigIntegerFromBytes(confent->generator.data, confent->generator.len);
+ v = BigIntegerFromInt(0);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, user, strlen(user));
+ SHA1Update(&ctxt, ":", 1);
+ SHA1Update(&ctxt, pass, strlen(pass));
+ SHA1Final(dig, &ctxt);
+
+ SHA1Init(&ctxt);
+ SHA1Update(&ctxt, tpw->pebuf.salt.data, tpw->pebuf.salt.len);
+ SHA1Update(&ctxt, dig, sizeof(dig));
+ SHA1Final(dig, &ctxt);
+
+ /* x = H(s, H(u, ':', p)) */
+ x = BigIntegerFromBytes(dig, sizeof(dig));
+
+ BigIntegerModExp(v, g, x, n);
+ tpw->pebuf.password.len = BigIntegerToBytes(v, tpw->pebuf.password.data);
+
+ BigIntegerFree(v);
+ BigIntegerFree(x);
+ BigIntegerFree(g);
+ BigIntegerFree(n);
+
+ return &tpw->pebuf;
+}
+
+int
+t_pwcopy(pwdest, pwsrc, diff)
+ FILE * pwdest;
+ FILE * pwsrc;
+ struct t_pwent * diff;
+{
+ struct t_pw * src;
+ struct t_pwent * ent;
+
+ if((src = t_openpw(pwsrc)) == NULL)
+ return -1;
+
+ while((ent = t_getpwent(src)) != NULL)
+ if(diff && strcmp(diff->name, ent->name) == 0) {
+ t_putpwent(diff, pwdest);
+ diff = NULL;
+ }
+ else
+ t_putpwent(ent, pwdest);
+
+ if(diff)
+ t_putpwent(diff, pwdest);
+
+ return 0;
+}
+
+_TYPE( struct t_pwent * )
+t_getpwent(tpw)
+ struct t_pw * tpw;
+{
+ char indexbuf[16];
+ char passbuf[MAXB64PARAMLEN];
+ char saltstr[MAXB64SALTLEN];
+
+#ifdef ENABLE_YP
+ struct t_passwd * nisent;
+ /* FIXME: should tell caller to get conf entry from NIS also */
+
+ if(tpw->state == IN_NIS) {
+ nisent = _yp_gettpent();
+ if(nisent != NULL) {
+ savepwent(tpw, &nisent->tp);
+ return &tpw->pebuf;
+ }
+ tpw->state = FILE_NIS;
+ }
+#endif
+
+ while(1) {
+ if(t_nextfield(tpw->instream, tpw->userbuf, MAXUSERLEN) > 0) {
+#ifdef ENABLE_YP
+ if(tpw->state == FILE_NIS && *tpw->userbuf == '+') {
+ t_nextline(tpw->instream);
+ if(strlen(tpw->userbuf) > 1) { /* +name:... */
+ nisent = _yp_gettpnam(tpw->userbuf + 1);
+ if(nisent != NULL) {
+ savepwent(tpw, nisent);
+ return &tpw->pebuf;
+ }
+ }
+ else { /* +:... */
+ tpw->state = IN_NIS;
+ _yp_settpent();
+ return t_getpwent(tpw);
+ }
+ }
+#endif
+ if(t_nextfield(tpw->instream, passbuf, MAXB64PARAMLEN) > 0 &&
+ (tpw->pebuf.password.len = t_fromb64(tpw->pwbuf, passbuf)) > 0 &&
+ t_nextfield(tpw->instream, saltstr, MAXB64SALTLEN) > 0 &&
+ (tpw->pebuf.salt.len = t_fromb64(tpw->saltbuf, saltstr)) > 0 &&
+ t_nextfield(tpw->instream, indexbuf, 16) > 0 &&
+ (tpw->pebuf.index = atoi(indexbuf)) > 0) {
+ tpw->pebuf.name = tpw->userbuf;
+ tpw->pebuf.password.data = tpw->pwbuf;
+ tpw->pebuf.salt.data = tpw->saltbuf;
+ t_nextline(tpw->instream);
+ return &tpw->pebuf;
+ }
+ }
+ if(t_nextline(tpw->instream) < 0)
+ return NULL;
+ }
+}
+
+_TYPE( void )
+t_putpwent(ent, fp)
+ const struct t_pwent * ent;
+ FILE * fp;
+{
+ char strbuf[MAXB64PARAMLEN];
+ char saltbuf[MAXB64SALTLEN];
+
+ fprintf(fp, "%s:%s:%s:%d\n", ent->name,
+ t_tob64(strbuf, ent->password.data, ent->password.len),
+ t_tob64(saltbuf, ent->salt.data, ent->salt.len), ent->index);
+}
+
diff --git a/package/network/services/hostapd/Config.in b/package/network/services/hostapd/Config.in
new file mode 100644
index 0000000..aee2a15
--- /dev/null
+++ b/package/network/services/hostapd/Config.in
@@ -0,0 +1,52 @@
+# wpa_supplicant config
+config WPA_SUPPLICANT_NO_TIMESTAMP_CHECK
+ bool "Disable timestamp check"
+ depends on PACKAGE_wpa-supplicant || PACKAGE_wpa-supplicant-mesh || PACKAGE_wpa-supplicant-mini || PACKAGE_wpad || PACKAGE_wpad-mini || PACAKGE_wpad-mesh
+ default n
+ help
+ This disables the timestamp check for certificates in wpa_supplicant
+ Useful for devices without RTC that cannot reliably get the real date/time
+
+choice
+ prompt "Choose TLS provider"
+ default WPA_SUPPLICANT_INTERNAL
+ depends on PACKAGE_wpa-supplicant || PACKAGE_wpa-supplicant-mesh || PACKAGE_wpad || PACKAGE_wpad-mesh
+
+config WPA_SUPPLICANT_INTERNAL
+ bool "internal"
+ depends on PACKAGE_wpa-supplicant || PACKAGE_wpad
+
+config WPA_SUPPLICANT_OPENSSL
+ bool "openssl"
+ select PACKAGE_libopenssl
+
+endchoice
+
+config WPA_RFKILL_SUPPORT
+ bool "Add rfkill support"
+ depends on PACKAGE_wpa-supplicant || PACKAGE_wpa-supplicant-mesh || PACKAGE_wpa-supplicant-mini || PACKAGE_wpad || PACKAGE_wpad-mini || PACKAGE_wpad-mesh
+ default n
+
+config WPA_MSG_MIN_PRIORITY
+ int "Minimum debug message priority"
+ default 3
+ help
+ Useful values are:
+ 0 = all messages
+ 1 = raw message dumps
+ 2 = most debugging messages
+ 3 = info messages
+ 4 = warnings
+ 5 = errors
+
+config DRIVER_WEXT_SUPPORT
+ bool
+ default n
+
+config DRIVER_11N_SUPPORT
+ bool
+ default n
+
+config DRIVER_11W_SUPPORT
+ bool
+ default n
diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile
new file mode 100644
index 0000000..edcfd1b
--- /dev/null
+++ b/package/network/services/hostapd/Makefile
@@ -0,0 +1,446 @@
+# 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:=hostapd
+PKG_VERSION:=2015-03-25
+PKG_RELEASE:=1
+PKG_REV:=8278138e679174b1ec8af7f169c2810a8888e202
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=git://w1.fi/srv/git/hostap.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_SOURCE_PROTO:=git
+# PKG_MIRROR_MD5SUM:=4e7c1f97edd7514535056fce54ae053a
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=BSD-3-Clause
+
+PKG_BUILD_PARALLEL:=1
+
+PKG_CONFIG_DEPENDS:= \
+ CONFIG_WPA_SUPPLICANT_NO_TIMESTAMP_CHECK \
+ CONFIG_PACKAGE_kmod-ath9k \
+ CONFIG_PACKAGE_kmod-cfg80211 \
+ CONFIG_PACKAGE_hostapd \
+ CONFIG_PACKAGE_hostapd-mini \
+ CONFIG_PACKAGE_kmod-hostap \
+ CONFIG_WPA_RFKILL_SUPPORT \
+ CONFIG_DRIVER_WEXT_SUPPORT \
+ CONFIG_DRIVER_11N_SUPPORT
+
+LOCAL_TYPE=$(strip \
+ $(if $(findstring wpad,$(BUILD_VARIANT)),wpad, \
+ $(if $(findstring supplicant,$(BUILD_VARIANT)),supplicant, \
+ hostapd \
+ )))
+LOCAL_VARIANT=$(patsubst wpad-%,%,$(patsubst supplicant-%,%,$(BUILD_VARIANT)))
+
+ifeq ($(LOCAL_TYPE),supplicant)
+ ifeq ($(LOCAL_VARIANT),full)
+ PKG_CONFIG_DEPENDS += \
+ CONFIG_WPA_SUPPLICANT_INTERNAL \
+ CONFIG_WPA_SUPPLICANT_OPENSSL
+ endif
+ ifeq ($(LOCAL_VARIANT),mesh)
+ PKG_CONFIG_DEPENDS += \
+ CONFIG_WPA_SUPPLICANT_OPENSSL
+ endif
+endif
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+STAMP_CONFIGURED:=$(STAMP_CONFIGURED)_$(CONFIG_WPA_MSG_MIN_PRIORITY)
+
+ifneq ($(CONFIG_DRIVER_11N_SUPPORT),)
+ HOSTAPD_IEEE80211N:=y
+endif
+
+DRIVER_MAKEOPTS= \
+ CONFIG_ACS=$(CONFIG_PACKAGE_kmod-cfg80211) \
+ CONFIG_DRIVER_NL80211=$(CONFIG_PACKAGE_kmod-cfg80211) \
+ CONFIG_DRIVER_HOSTAP=$(CONFIG_PACKAGE_kmod-hostap) \
+ CONFIG_IEEE80211N=$(HOSTAPD_IEEE80211N) \
+ CONFIG_DRIVER_WEXT=$(CONFIG_DRIVER_WEXT_SUPPORT) \
+
+ifeq ($(LOCAL_VARIANT),full)
+ DRIVER_MAKEOPTS += CONFIG_IEEE80211W=$(CONFIG_DRIVER_11W_SUPPORT)
+endif
+
+ifneq ($(LOCAL_TYPE),hostapd)
+ ifdef CONFIG_WPA_SUPPLICANT_OPENSSL
+ ifeq ($(LOCAL_VARIANT),full)
+ DRIVER_MAKEOPTS += CONFIG_TLS=openssl
+ TARGET_LDFLAGS += -lcrypto -lssl
+ endif
+ endif
+ ifeq ($(LOCAL_VARIANT),mesh)
+ DRIVER_MAKEOPTS += CONFIG_TLS=openssl
+ TARGET_LDFLAGS += -lcrypto -lssl
+ endif
+ ifdef CONFIG_WPA_SUPPLICANT_NO_TIMESTAMP_CHECK
+ TARGET_CFLAGS += -DNO_TIMESTAMP_CHECK
+ endif
+ ifdef CONFIG_WPA_RFKILL_SUPPORT
+ DRIVER_MAKEOPTS += NEED_RFKILL=y
+ endif
+ DRIVER_MAKEOPTS += \
+ CONFIG_DRIVER_ROBOSWITCH=$(CONFIG_PACKAGE_kmod-switch)
+endif
+
+ifdef CONFIG_USE_GLIBC
+ TARGET_LDFLAGS += -lrt
+ TARGET_LDFLAGS_C += -lrt
+endif
+
+DRV_DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny
+
+define Package/hostapd/Default
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=IEEE 802.1x Authenticator
+ URL:=http://hostap.epitest.fi/
+ DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus
+endef
+
+define Package/hostapd
+$(call Package/hostapd/Default)
+ TITLE+= (full)
+ VARIANT:=full
+ CONFLICTS:=wpad wpad-mini wpad-mesh
+endef
+
+define Package/hostapd/description
+ This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS
+ Authenticator.
+endef
+
+define Package/hostapd-mini
+$(call Package/hostapd/Default)
+ TITLE+= (WPA-PSK only)
+ VARIANT:=mini
+ CONFLICTS:=wpad wpad-mini wpad-mesh
+endef
+
+define Package/hostapd-mini/description
+ This package contains a minimal IEEE 802.1x/WPA Authenticator (WPA-PSK only).
+endef
+
+define Package/hostapd-utils
+ $(call Package/hostapd/Default)
+ TITLE+= (utils)
+ DEPENDS:=@PACKAGE_hostapd||PACKAGE_hostapd-mini||PACKAGE_wpad||PACKAGE_wpad-mesh||PACKAGE_wpad-mini
+endef
+
+define Package/hostapd-utils/description
+ This package contains a command line utility to control the
+ IEEE 802.1x/WPA/EAP/RADIUS Authenticator.
+endef
+
+define Package/wpad/Default
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=IEEE 802.1x Authenticator/Supplicant
+ DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus
+ URL:=http://hostap.epitest.fi/
+endef
+
+define Package/wpad
+$(call Package/wpad/Default)
+ TITLE+= (full)
+ DEPENDS+=+WPA_SUPPLICANT_OPENSSL:libopenssl
+ VARIANT:=wpad-full
+endef
+
+define Package/wpad/description
+ This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS
+ Authenticator and Supplicant
+endef
+
+define Package/wpad-mini
+$(call Package/wpad/Default)
+ TITLE+= (WPA-PSK only)
+ VARIANT:=wpad-mini
+endef
+
+define Package/wpad-mini/description
+ This package contains a minimal IEEE 802.1x/WPA Authenticator and Supplicant (WPA-PSK only).
+endef
+
+define Package/wpad-mesh
+$(call Package/wpad/Default)
+ TITLE+= (with 802.11s mesh and SAE support)
+ DEPENDS:=$(DRV_DEPENDS) +libubus +PACKAGE_wpad-mesh:libopenssl +@CONFIG_WPA_SUPPLICANT_OPENSSL @(!TARGET_uml||BROKEN)
+ CONFLICTS:=@WPA_SUPPLICANT_INTERNAL
+ VARIANT:=wpad-mesh
+endef
+
+define Package/wpad-mesh/description
+ This package contains a minimal IEEE 802.1x/WPA Authenticator and Supplicant (with 802.11s mesh and SAE support).
+endef
+
+define Package/wpa-supplicant
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=WPA Supplicant
+ URL:=http://hostap.epitest.fi/wpa_supplicant/
+ DEPENDS:=$(DRV_DEPENDS) +WPA_SUPPLICANT_OPENSSL:libopenssl
+ CONFLICTS:=wpad wpad-mini wpad-mesh
+ VARIANT:=supplicant-full
+endef
+
+define Package/wpa-supplicant/Description
+ WPA Supplicant
+endef
+
+define Package/wpa-supplicant/config
+ source "$(SOURCE)/Config.in"
+endef
+
+define Package/wpa-supplicant-p2p
+ $(Package/wpa-supplicant)
+ TITLE:=WPA Supplicant (with Wi-Fi P2P support)
+ DEPENDS:=$(DRV_DEPENDS)
+ CONFLICTS:=wpad wpad-mini wpad-mesh
+ VARIANT:=supplicant-p2p
+endef
+
+define Package/wpa-supplicant-p2p/Description
+ WPA Supplicant (with Wi-Fi P2P support)
+endef
+
+define Package/wpa-supplicant-mesh
+ $(Package/wpa-supplicant)
+ TITLE:=WPA Supplicant (with 802.11s and SAE)
+ DEPENDS:=$(DRV_DEPENDS) @(!TARGET_uml||BROKEN)
+ CONFLICTS:=wpad wpad-mesh wpad-mesh
+ VARIANT:=supplicant-mesh
+endef
+
+define Package/wpa-supplicant-mesh/Description
+ WPA Supplicant (variant with 802.11s and SAE support)
+endef
+
+define Package/wpa-supplicant-mini
+ $(Package/wpa-supplicant)
+ TITLE:=WPA Supplicant (minimal version)
+ DEPENDS:=$(DRV_DEPENDS)
+ CONFLICTS:=wpad wpad-mini wpad-mesh
+ VARIANT:=supplicant-mini
+endef
+
+define Package/wpa-supplicant-mini/Description
+ WPA Supplicant (minimal version)
+endef
+
+define Package/wpa-cli
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=@PACKAGE_wpa-supplicant||PACKAGE_wpa-supplicant-p2p||PACKAGE_wpad-mini||PACKAGE_wpad||PACKAGE_wpad-mesh
+ TITLE:=WPA Supplicant command line interface
+endef
+
+define Package/wpa-cli/Description
+ WPA Supplicant control utility
+endef
+
+define Package/hostapd-common
+ TITLE:=hostapd/wpa_supplicant common support files
+ SECTION:=net
+ CATEGORY:=Network
+endef
+
+define Package/hostapd-common-old
+ TITLE:=hostapd/wpa_supplicant common support files (legacy drivers)
+ SECTION:=net
+ CATEGORY:=Network
+endef
+
+define Package/eapol-test
+ TITLE:=802.1x authentication test utility
+ SECTION:=net
+ CATEGORY:=Network
+ VARIANT:=supplicant-full
+ DEPENDS:=$(DRV_DEPENDS)
+endef
+
+
+ifneq ($(wildcard $(PKG_BUILD_DIR)/.config_*),$(subst .configured_,.config_,$(STAMP_CONFIGURED)))
+ define Build/Configure/rebuild
+ $(FIND) $(PKG_BUILD_DIR) -name \*.o -or -name \*.a | $(XARGS) rm -f
+ rm -f $(PKG_BUILD_DIR)/hostapd/hostapd
+ rm -f $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant
+ rm -f $(PKG_BUILD_DIR)/.config_*
+ touch $(subst .configured_,.config_,$(STAMP_CONFIGURED))
+ endef
+endif
+
+define Build/Configure
+ $(Build/Configure/rebuild)
+ $(if $(wildcard ./files/hostapd-$(LOCAL_VARIANT).config), \
+ $(CP) ./files/hostapd-$(LOCAL_VARIANT).config $(PKG_BUILD_DIR)/hostapd/.config \
+ )
+ $(CP) ./files/wpa_supplicant-$(LOCAL_VARIANT).config $(PKG_BUILD_DIR)/wpa_supplicant/.config
+endef
+
+TARGET_CPPFLAGS := \
+ -I$(STAGING_DIR)/usr/include/libnl-tiny \
+ -I$(PKG_BUILD_DIR)/src/crypto \
+ $(TARGET_CPPFLAGS) \
+ -DCONFIG_LIBNL20 \
+ -D_GNU_SOURCE \
+ $(if $(CONFIG_WPA_MSG_MIN_PRIORITY),-DCONFIG_MSG_MIN_PRIORITY=$(CONFIG_WPA_MSG_MIN_PRIORITY))
+
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+TARGET_LDFLAGS += -Wl,--gc-sections
+ifeq ($(findstring supplicant,$(BUILD_VARIANT)),)
+ TARGET_LDFLAGS += -lubox -lubus
+endif
+
+ifdef CONFIG_PACKAGE_kmod-cfg80211
+ TARGET_LDFLAGS += -lm -lnl-tiny
+endif
+
+define Build/RunMake
+ CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
+ $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(1) \
+ $(TARGET_CONFIGURE_OPTS) \
+ $(DRIVER_MAKEOPTS) \
+ LIBS="$(TARGET_LDFLAGS)" \
+ LIBS_c="$(TARGET_LDFLAGS_C)" \
+ BCHECK= \
+ $(2)
+endef
+
+define Build/Compile/wpad
+ echo ` \
+ $(call Build/RunMake,hostapd,-s MULTICALL=1 dump_cflags); \
+ $(call Build/RunMake,wpa_supplicant,-s MULTICALL=1 dump_cflags) | \
+ sed -e 's,-n ,,g' -e 's^$(TARGET_CFLAGS)^^' \
+ ` > $(PKG_BUILD_DIR)/.cflags
+ +$(call Build/RunMake,hostapd, \
+ CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \
+ MULTICALL=1 \
+ hostapd_cli hostapd_multi.a \
+ )
+ +$(call Build/RunMake,wpa_supplicant, \
+ CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \
+ MULTICALL=1 \
+ wpa_cli wpa_supplicant_multi.a \
+ )
+ $(TARGET_CC) -o $(PKG_BUILD_DIR)/wpad \
+ $(TARGET_CFLAGS) \
+ ./files/multicall.c \
+ $(PKG_BUILD_DIR)/hostapd/hostapd_multi.a \
+ $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant_multi.a \
+ $(TARGET_LDFLAGS)
+endef
+
+define Build/Compile/hostapd
+ $(call Build/RunMake,hostapd, \
+ hostapd hostapd_cli \
+ )
+endef
+
+define Build/Compile/supplicant
+ $(call Build/RunMake,wpa_supplicant, \
+ wpa_cli wpa_supplicant \
+ )
+endef
+
+define Build/Compile/supplicant-full
+ $(call Build/RunMake,wpa_supplicant, \
+ eapol_test \
+ )
+endef
+
+define Build/Compile
+ $(Build/Compile/$(LOCAL_TYPE))
+ $(Build/Compile/$(BUILD_VARIANT))
+endef
+
+define Install/hostapd
+ $(INSTALL_DIR) $(1)/usr/sbin
+endef
+
+define Install/supplicant
+ $(INSTALL_DIR) $(1)/usr/sbin
+endef
+
+define Package/hostapd-common/install
+ $(INSTALL_DIR) $(1)/lib/netifd
+ $(INSTALL_DATA) ./files/netifd.sh $(1)/lib/netifd/hostapd.sh
+endef
+
+define Package/hostapd-common-old/install
+ $(INSTALL_DIR) $(1)/lib/wifi
+ $(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/wifi/hostapd.sh
+ $(INSTALL_DATA) ./files/wpa_supplicant.sh $(1)/lib/wifi/wpa_supplicant.sh
+endef
+
+define Package/hostapd/install
+ $(call Install/hostapd,$(1))
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd $(1)/usr/sbin/
+endef
+Package/hostapd-mini/install = $(Package/hostapd/install)
+
+ifneq ($(LOCAL_TYPE),supplicant)
+ define Package/hostapd-utils/install
+ $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/rc.button
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd_cli $(1)/usr/sbin/
+ $(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps
+ endef
+endif
+
+define Package/wpad/install
+ $(call Install/hostapd,$(1))
+ $(call Install/supplicant,$(1))
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/wpad $(1)/usr/sbin/
+ $(LN) wpad $(1)/usr/sbin/hostapd
+ $(LN) wpad $(1)/usr/sbin/wpa_supplicant
+endef
+Package/wpad-mini/install = $(Package/wpad/install)
+Package/wpad-mesh/install = $(Package/wpad/install)
+
+define Package/wpa-supplicant/install
+ $(call Install/supplicant,$(1))
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant $(1)/usr/sbin/
+endef
+Package/wpa-supplicant-mini/install = $(Package/wpa-supplicant/install)
+Package/wpa-supplicant-p2p/install = $(Package/wpa-supplicant/install)
+
+ifneq ($(LOCAL_TYPE),hostapd)
+ define Package/wpa-cli/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/wpa_cli $(1)/usr/sbin/
+ endef
+endif
+
+ifeq ($(BUILD_VARIANT),supplicant-full)
+ define Package/eapol-test/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/
+ endef
+endif
+
+$(eval $(call BuildPackage,hostapd))
+$(eval $(call BuildPackage,hostapd-mini))
+$(eval $(call BuildPackage,wpad))
+$(eval $(call BuildPackage,wpad-mesh))
+$(eval $(call BuildPackage,wpad-mini))
+$(eval $(call BuildPackage,wpa-supplicant))
+$(eval $(call BuildPackage,wpa-supplicant-mesh))
+$(eval $(call BuildPackage,wpa-supplicant-mini))
+$(eval $(call BuildPackage,wpa-supplicant-p2p))
+$(eval $(call BuildPackage,wpa-cli))
+$(eval $(call BuildPackage,hostapd-utils))
+$(eval $(call BuildPackage,hostapd-common))
+$(eval $(call BuildPackage,hostapd-common-old))
+$(eval $(call BuildPackage,eapol-test))
diff --git a/package/network/services/hostapd/files/hostapd-full.config b/package/network/services/hostapd/files/hostapd-full.config
new file mode 100644
index 0000000..f1b2655
--- /dev/null
+++ b/package/network/services/hostapd/files/hostapd-full.config
@@ -0,0 +1,166 @@
+# Example hostapd build time configuration
+#
+# This file lists the configuration options that are used when building the
+# hostapd binary. All lines starting with # are ignored. Configuration option
+# lines must be commented out complete, if they are not to be included, i.e.,
+# just setting VARIABLE=n is not disabling that variable.
+#
+# This file is included in Makefile, so variables like CFLAGS and LIBS can also
+# be modified from here. In most cass, these lines should use += in order not
+# to override previous values of the variables.
+
+# Driver interface for Host AP driver
+CONFIG_DRIVER_HOSTAP=y
+
+# Driver interface for wired authenticator
+CONFIG_DRIVER_WIRED=y
+
+# Driver interface for Prism54 driver
+#CONFIG_DRIVER_PRISM54=y
+
+# Driver interface for drivers using the nl80211 kernel interface
+CONFIG_DRIVER_NL80211=y
+# driver_nl80211.c requires a rather new libnl (version 1.1) which may not be
+# shipped with your distribution yet. If that is the case, you need to build
+# newer libnl version and point the hostapd build to use it.
+#LIBNL=/usr/src/libnl
+#CFLAGS += -I$(LIBNL)/include
+#LIBS += -L$(LIBNL)/lib
+
+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
+#CONFIG_DRIVER_BSD=y
+#CFLAGS += -I/usr/local/include
+#LIBS += -L/usr/local/lib
+
+# Driver interface for no driver (e.g., RADIUS server only)
+#CONFIG_DRIVER_NONE=y
+
+# IEEE 802.11F/IAPP
+CONFIG_IAPP=y
+
+# WPA2/IEEE 802.11i RSN pre-authentication
+CONFIG_RSN_PREAUTH=y
+
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Integrated EAP server
+CONFIG_EAP=y
+
+# EAP-MD5 for the integrated EAP server
+CONFIG_EAP_MD5=y
+
+# EAP-TLS for the integrated EAP server
+CONFIG_EAP_TLS=y
+
+# EAP-MSCHAPv2 for the integrated EAP server
+CONFIG_EAP_MSCHAPV2=y
+
+# EAP-PEAP for the integrated EAP server
+CONFIG_EAP_PEAP=y
+
+# EAP-GTC for the integrated EAP server
+CONFIG_EAP_GTC=y
+
+# EAP-TTLS for the integrated EAP server
+CONFIG_EAP_TTLS=y
+
+# EAP-SIM for the integrated EAP server
+#CONFIG_EAP_SIM=y
+
+# EAP-AKA for the integrated EAP server
+#CONFIG_EAP_AKA=y
+
+# EAP-AKA' for the integrated EAP server
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
+# EAP-PAX for the integrated EAP server
+#CONFIG_EAP_PAX=y
+
+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-SAKE for the integrated EAP server
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK for the integrated EAP server
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-FAST for the integrated EAP server
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
+# Wi-Fi Protected Setup (WPS)
+CONFIG_WPS=y
+CONFIG_WPS2=y
+# Enable UPnP support for external WPS Registrars
+#CONFIG_WPS_UPNP=y
+
+# EAP-IKEv2
+#CONFIG_EAP_IKEV2=y
+
+# Trusted Network Connect (EAP-TNC)
+#CONFIG_EAP_TNC=y
+
+# PKCS#12 (PFX) support (used to read private key and certificate file from
+# a file that usually has extension .p12 or .pfx)
+CONFIG_PKCS12=y
+
+# RADIUS authentication server. This provides access to the integrated EAP
+# server from external hosts using RADIUS.
+#CONFIG_RADIUS_SERVER=y
+
+# Build IPv6 support for RADIUS operations
+CONFIG_IPV6=y
+
+# IEEE Std 802.11r-2008 (Fast BSS Transition)
+CONFIG_IEEE80211R=y
+
+# Use the hostapd's IEEE 802.11 authentication (ACL), but without
+# the IEEE 802.11 Management capability (e.g. FreeBSD/net80211)
+#CONFIG_DRIVER_RADIUS_ACL=y
+
+# IEEE 802.11n (High Throughput) support
+CONFIG_IEEE80211N=y
+
+# IEEE 802.11ac (Very High Throughput) support
+CONFIG_IEEE80211AC=y
+
+# Remove debugging code that is printing out debug messages to stdout.
+# This can be used to reduce the size of the hostapd considerably if debugging
+# code is not needed.
+#CONFIG_NO_STDOUT_DEBUG=y
+
+# Remove support for RADIUS accounting
+#CONFIG_NO_ACCOUNTING=y
+
+# Remove support for RADIUS
+#CONFIG_NO_RADIUS=y
+
+# Remove support for VLANs
+#CONFIG_NO_VLAN=y
+
+CONFIG_TLS=internal
+CONFIG_INTERNAL_LIBTOMMATH=y
+CONFIG_INTERNAL_AES=y
+NEED_AES_DEC=y
+
+CONFIG_NO_RANDOM_POOL=y
+CONFIG_NO_DUMP_STATE=y
+
+CONFIG_WPS=y
+CONFIG_FULL_DYNAMIC_VLAN=y
+
+CONFIG_UBUS=y
diff --git a/package/network/services/hostapd/files/hostapd-mini.config b/package/network/services/hostapd/files/hostapd-mini.config
new file mode 100644
index 0000000..118d97c
--- /dev/null
+++ b/package/network/services/hostapd/files/hostapd-mini.config
@@ -0,0 +1,159 @@
+# Example hostapd build time configuration
+#
+# This file lists the configuration options that are used when building the
+# hostapd binary. All lines starting with # are ignored. Configuration option
+# lines must be commented out complete, if they are not to be included, i.e.,
+# just setting VARIABLE=n is not disabling that variable.
+#
+# This file is included in Makefile, so variables like CFLAGS and LIBS can also
+# be modified from here. In most cass, these lines should use += in order not
+# to override previous values of the variables.
+
+# Driver interface for Host AP driver
+CONFIG_DRIVER_HOSTAP=y
+
+# Driver interface for wired authenticator
+CONFIG_DRIVER_WIRED=y
+
+# Driver interface for Prism54 driver
+#CONFIG_DRIVER_PRISM54=y
+
+# Driver interface for drivers using the nl80211 kernel interface
+CONFIG_DRIVER_NL80211=y
+# driver_nl80211.c requires a rather new libnl (version 1.1) which may not be
+# shipped with your distribution yet. If that is the case, you need to build
+# newer libnl version and point the hostapd build to use it.
+#LIBNL=/usr/src/libnl
+#CFLAGS += -I$(LIBNL)/include
+#LIBS += -L$(LIBNL)/lib
+
+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
+#CONFIG_DRIVER_BSD=y
+#CFLAGS += -I/usr/local/include
+#LIBS += -L/usr/local/lib
+
+# Driver interface for no driver (e.g., RADIUS server only)
+#CONFIG_DRIVER_NONE=y
+
+# IEEE 802.11F/IAPP
+# CONFIG_IAPP=y
+
+# WPA2/IEEE 802.11i RSN pre-authentication
+CONFIG_RSN_PREAUTH=y
+
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Integrated EAP server
+#CONFIG_EAP=y
+
+# EAP-MD5 for the integrated EAP server
+#CONFIG_EAP_MD5=y
+
+# EAP-TLS for the integrated EAP server
+#CONFIG_EAP_TLS=y
+
+# EAP-MSCHAPv2 for the integrated EAP server
+#CONFIG_EAP_MSCHAPV2=y
+
+# EAP-PEAP for the integrated EAP server
+#CONFIG_EAP_PEAP=y
+
+# EAP-GTC for the integrated EAP server
+#CONFIG_EAP_GTC=y
+
+# EAP-TTLS for the integrated EAP server
+#CONFIG_EAP_TTLS=y
+
+# EAP-SIM for the integrated EAP server
+#CONFIG_EAP_SIM=y
+
+# EAP-AKA for the integrated EAP server
+#CONFIG_EAP_AKA=y
+
+# EAP-AKA' for the integrated EAP server
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
+# EAP-PAX for the integrated EAP server
+#CONFIG_EAP_PAX=y
+
+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-SAKE for the integrated EAP server
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK for the integrated EAP server
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-FAST for the integrated EAP server
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
+# Wi-Fi Protected Setup (WPS)
+#CONFIG_WPS=y
+# Enable UPnP support for external WPS Registrars
+#CONFIG_WPS_UPNP=y
+
+# EAP-IKEv2
+#CONFIG_EAP_IKEV2=y
+
+# Trusted Network Connect (EAP-TNC)
+#CONFIG_EAP_TNC=y
+
+# PKCS#12 (PFX) support (used to read private key and certificate file from
+# a file that usually has extension .p12 or .pfx)
+#CONFIG_PKCS12=y
+
+# RADIUS authentication server. This provides access to the integrated EAP
+# server from external hosts using RADIUS.
+#CONFIG_RADIUS_SERVER=y
+
+# Build IPv6 support for RADIUS operations
+#CONFIG_IPV6=y
+
+# IEEE Std 802.11r-2008 (Fast BSS Transition)
+#CONFIG_IEEE80211R=y
+
+# Use the hostapd's IEEE 802.11 authentication (ACL), but without
+# the IEEE 802.11 Management capability (e.g. FreeBSD/net80211)
+#CONFIG_DRIVER_RADIUS_ACL=y
+
+# IEEE 802.11n (High Throughput) support
+CONFIG_IEEE80211N=y
+
+# IEEE 802.11ac (Very High Throughput) support
+CONFIG_IEEE80211AC=y
+
+# Remove debugging code that is printing out debug messages to stdout.
+# This can be used to reduce the size of the hostapd considerably if debugging
+# code is not needed.
+#CONFIG_NO_STDOUT_DEBUG=y
+
+# Remove support for RADIUS accounting
+CONFIG_NO_ACCOUNTING=y
+
+# Remove support for RADIUS
+CONFIG_NO_RADIUS=y
+
+# Remove support for VLANs
+#CONFIG_NO_VLAN=y
+
+CONFIG_TLS=internal
+
+CONFIG_NO_RANDOM_POOL=y
+CONFIG_NO_DUMP_STATE=y
+
+CONFIG_UBUS=y
diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh
new file mode 100644
index 0000000..7aec7ad
--- /dev/null
+++ b/package/network/services/hostapd/files/hostapd.sh
@@ -0,0 +1,394 @@
+hostapd_set_bss_options() {
+ local var="$1"
+ local vif="$2"
+ local enc wep_rekey wpa_group_rekey wpa_pair_rekey wpa_master_rekey wps_possible wpa_key_mgmt
+
+ config_get enc "$vif" encryption "none"
+ config_get wep_rekey "$vif" wep_rekey # 300
+ config_get wpa_group_rekey "$vif" wpa_group_rekey # 300
+ config_get wpa_pair_rekey "$vif" wpa_pair_rekey # 300
+ config_get wpa_master_rekey "$vif" wpa_master_rekey # 640
+ config_get_bool ap_isolate "$vif" isolate 0
+ config_get_bool disassoc_low_ack "$vif" disassoc_low_ack 1
+ config_get max_num_sta "$vif" max_num_sta 0
+ config_get max_inactivity "$vif" max_inactivity 0
+ config_get_bool preamble "$vif" short_preamble 1
+
+ config_get device "$vif" device
+ config_get hwmode "$device" hwmode
+ config_get phy "$device" phy
+
+ append "$var" "ctrl_interface=/var/run/hostapd-$phy" "$N"
+
+ if [ "$ap_isolate" -gt 0 ]; then
+ append "$var" "ap_isolate=$ap_isolate" "$N"
+ fi
+ if [ "$max_num_sta" -gt 0 ]; then
+ append "$var" "max_num_sta=$max_num_sta" "$N"
+ fi
+ if [ "$max_inactivity" -gt 0 ]; then
+ append "$var" "ap_max_inactivity=$max_inactivity" "$N"
+ fi
+ append "$var" "disassoc_low_ack=$disassoc_low_ack" "$N"
+ if [ "$preamble" -gt 0 ]; then
+ append "$var" "preamble=$preamble" "$N"
+ fi
+
+ # Examples:
+ # psk-mixed/tkip => WPA1+2 PSK, TKIP
+ # wpa-psk2/tkip+aes => WPA2 PSK, CCMP+TKIP
+ # wpa2/tkip+aes => WPA2 RADIUS, CCMP+TKIP
+ # ...
+
+ # TODO: move this parsing function somewhere generic, so that
+ # later it can be reused by drivers that don't use hostapd
+
+ # crypto defaults: WPA2 vs WPA1
+ case "$enc" in
+ wpa2*|*psk2*)
+ wpa=2
+ crypto="CCMP"
+ ;;
+ *mixed*)
+ wpa=3
+ crypto="CCMP TKIP"
+ ;;
+ *)
+ wpa=1
+ crypto="TKIP"
+ ;;
+ esac
+
+ # explicit override for crypto setting
+ case "$enc" in
+ *tkip+aes|*tkip+ccmp|*aes+tkip|*ccmp+tkip) crypto="CCMP TKIP";;
+ *aes|*ccmp) crypto="CCMP";;
+ *tkip) crypto="TKIP";;
+ esac
+
+ # enforce CCMP for 11ng and 11na
+ case "$hwmode:$crypto" in
+ *ng:TKIP|*na:TKIP) crypto="CCMP TKIP";;
+ esac
+
+ # use crypto/auth settings for building the hostapd config
+ case "$enc" in
+ none)
+ wps_possible=1
+ wpa=0
+ crypto=
+ # Here we make the assumption that if we're in open mode
+ # with WPS enabled, we got to be in unconfigured state.
+ wps_not_configured=1
+ ;;
+ *psk*)
+ config_get psk "$vif" key
+ if [ ${#psk} -eq 64 ]; then
+ append "$var" "wpa_psk=$psk" "$N"
+ else
+ append "$var" "wpa_passphrase=$psk" "$N"
+ fi
+ wps_possible=1
+ [ -n "$wpa_group_rekey" ] && append "$var" "wpa_group_rekey=$wpa_group_rekey" "$N"
+ [ -n "$wpa_pair_rekey" ] && append "$var" "wpa_ptk_rekey=$wpa_pair_rekey" "$N"
+ [ -n "$wpa_master_rekey" ] && append "$var" "wpa_gmk_rekey=$wpa_master_rekey" "$N"
+ append wpa_key_mgmt "WPA-PSK"
+ ;;
+ *wpa*|*8021x*)
+ # required fields? formats?
+ # hostapd is particular, maybe a default configuration for failures
+ config_get auth_server "$vif" auth_server
+ [ -z "$auth_server" ] && config_get auth_server "$vif" server
+ append "$var" "auth_server_addr=$auth_server" "$N"
+ config_get auth_port "$vif" auth_port
+ [ -z "$auth_port" ] && config_get auth_port "$vif" port
+ auth_port=${auth_port:-1812}
+ append "$var" "auth_server_port=$auth_port" "$N"
+ config_get auth_secret "$vif" auth_secret
+ [ -z "$auth_secret" ] && config_get auth_secret "$vif" key
+ append "$var" "auth_server_shared_secret=$auth_secret" "$N"
+ # You don't really want to enable this unless you are doing
+ # some corner case testing or are using OpenWrt as a work around
+ # for some systematic issues.
+ config_get_bool auth_cache "$vif" auth_cache 0
+ config_get rsn_preauth "$vif" rsn_preauth
+ [ "$auth_cache" -gt 0 ] || [[ "$rsn_preauth" = 1 ]] || append "$var" "disable_pmksa_caching=1" "$N"
+ [ "$auth_cache" -gt 0 ] || [[ "$rsn_preauth" = 1 ]] || append "$var" "okc=0" "$N"
+ config_get acct_server "$vif" acct_server
+ [ -n "$acct_server" ] && append "$var" "acct_server_addr=$acct_server" "$N"
+ config_get acct_port "$vif" acct_port
+ [ -n "$acct_port" ] && acct_port=${acct_port:-1813}
+ [ -n "$acct_port" ] && append "$var" "acct_server_port=$acct_port" "$N"
+ config_get acct_secret "$vif" acct_secret
+ [ -n "$acct_secret" ] && append "$var" "acct_server_shared_secret=$acct_secret" "$N"
+ config_get eap_reauth_period "$vif" eap_reauth_period
+ [ -n "$eap_reauth_period" ] && append "$var" "eap_reauth_period=$eap_reauth_period" "$N"
+ config_get dae_client "$vif" dae_client
+ config_get dae_secret "$vif" dae_secret
+ [ -n "$dae_client" -a -n "$dae_secret" ] && {
+ config_get dae_port "$vif" dae_port
+ append "$var" "radius_das_port=${dae_port:-3799}" "$N"
+ append "$var" "radius_das_client=$dae_client $dae_secret" "$N"
+ }
+ config_get ownip "$vif" ownip
+ append "$var" "own_ip_addr=$ownip" "$N"
+ append "$var" "eapol_key_index_workaround=1" "$N"
+ append "$var" "ieee8021x=1" "$N"
+ append wpa_key_mgmt "WPA-EAP"
+ [ -n "$wpa_group_rekey" ] && append "$var" "wpa_group_rekey=$wpa_group_rekey" "$N"
+ [ -n "$wpa_pair_rekey" ] && append "$var" "wpa_ptk_rekey=$wpa_pair_rekey" "$N"
+ [ -n "$wpa_master_rekey" ] && append "$var" "wpa_gmk_rekey=$wpa_master_rekey" "$N"
+ ;;
+ *wep*)
+ config_get key "$vif" key
+ key="${key:-1}"
+ case "$key" in
+ [1234])
+ for idx in 1 2 3 4; do
+ local zidx
+ zidx=$(($idx - 1))
+ config_get ckey "$vif" "key${idx}"
+ [ -n "$ckey" ] && \
+ append "$var" "wep_key${zidx}=$(prepare_key_wep "$ckey")" "$N"
+ done
+ append "$var" "wep_default_key=$((key - 1))" "$N"
+ ;;
+ *)
+ append "$var" "wep_key0=$(prepare_key_wep "$key")" "$N"
+ append "$var" "wep_default_key=0" "$N"
+ [ -n "$wep_rekey" ] && append "$var" "wep_rekey_period=$wep_rekey" "$N"
+ ;;
+ esac
+ case "$enc" in
+ *shared*)
+ auth_algs=2
+ ;;
+ *mixed*)
+ auth_algs=3
+ ;;
+ esac
+ wpa=0
+ crypto=
+ ;;
+ *)
+ wpa=0
+ crypto=
+ ;;
+ esac
+ append "$var" "auth_algs=${auth_algs:-1}" "$N"
+ append "$var" "wpa=$wpa" "$N"
+ [ -n "$crypto" ] && append "$var" "wpa_pairwise=$crypto" "$N"
+ [ -n "$wpa_group_rekey" ] && append "$var" "wpa_group_rekey=$wpa_group_rekey" "$N"
+
+ config_get ssid "$vif" ssid
+ config_get bridge "$vif" bridge
+ config_get ieee80211d "$vif" ieee80211d
+ config_get iapp_interface "$vif" iapp_interface
+
+ config_get_bool wps_pbc "$vif" wps_pushbutton 0
+ config_get_bool wps_label "$vif" wps_label 0
+
+ config_get config_methods "$vif" wps_config
+ [ "$wps_pbc" -gt 0 ] && append config_methods push_button
+
+ [ -n "$wps_possible" -a -n "$config_methods" ] && {
+ config_get device_type "$vif" wps_device_type "6-0050F204-1"
+ config_get device_name "$vif" wps_device_name "OpenWrt AP"
+ config_get manufacturer "$vif" wps_manufacturer "openwrt.org"
+ config_get wps_pin "$vif" wps_pin
+
+ config_get_bool ext_registrar "$vif" ext_registrar 0
+ [ "$ext_registrar" -gt 0 -a -n "$bridge" ] && append "$var" "upnp_iface=$bridge" "$N"
+
+ append "$var" "eap_server=1" "$N"
+ [ -n "$wps_pin" ] && append "$var" "ap_pin=$wps_pin" "$N"
+ append "$var" "wps_state=${wps_not_configured:-2}" "$N"
+ append "$var" "ap_setup_locked=0" "$N"
+ append "$var" "device_type=$device_type" "$N"
+ append "$var" "device_name=$device_name" "$N"
+ append "$var" "manufacturer=$manufacturer" "$N"
+ append "$var" "config_methods=$config_methods" "$N"
+ }
+
+ append "$var" "ssid=$ssid" "$N"
+ [ -n "$bridge" ] && append "$var" "bridge=$bridge" "$N"
+ [ -n "$ieee80211d" ] && append "$var" "ieee80211d=$ieee80211d" "$N"
+ [ -n "$iapp_interface" ] && append "$var" iapp_interface=$(uci_get_state network "$iapp_interface" ifname "$iapp_interface") "$N"
+
+ if [ "$wpa" -ge "1" ]
+ then
+ config_get nasid "$vif" nasid
+ [ -n "$nasid" ] && append "$var" "nas_identifier=$nasid" "$N"
+
+ config_get_bool ieee80211r "$vif" ieee80211r 0
+ if [ "$ieee80211r" -gt 0 ]
+ then
+ config_get mobility_domain "$vif" mobility_domain "4f57"
+ config_get r0_key_lifetime "$vif" r0_key_lifetime "10000"
+ config_get r1_key_holder "$vif" r1_key_holder "00004f577274"
+ config_get reassociation_deadline "$vif" reassociation_deadline "1000"
+ config_get r0kh "$vif" r0kh
+ config_get r1kh "$vif" r1kh
+ config_get_bool pmk_r1_push "$vif" pmk_r1_push 0
+
+ append "$var" "mobility_domain=$mobility_domain" "$N"
+ append "$var" "r0_key_lifetime=$r0_key_lifetime" "$N"
+ append "$var" "r1_key_holder=$r1_key_holder" "$N"
+ append "$var" "reassociation_deadline=$reassociation_deadline" "$N"
+ append "$var" "pmk_r1_push=$pmk_r1_push" "$N"
+
+ for kh in $r0kh; do
+ "$var" "r0kh=${kh//,/ }" "$N"
+ done
+ for kh in $r1kh; do
+ "$var" "r1kh=${kh//,/ }" "$N"
+ done
+
+ [ "$wpa_key_mgmt" != "${wpa_key_mgmt/EAP/}" ] && append wpa_key_mgmt "FT-EAP"
+ [ "$wpa_key_mgmt" != "${wpa_key_mgmt/PSK/}" ] && append wpa_key_mgmt "FT-PSK"
+ fi
+
+ [ -n "wpa_key_mgmt" ] && append "$var" "wpa_key_mgmt=$wpa_key_mgmt"
+ fi
+
+ if [ "$wpa" -ge "2" ]
+ then
+ # RSN -> allow preauthentication. You have two
+ # options, rsn_preauth for production or rsn_preauth_testing
+ # for validation / testing.
+ if [ -n "$bridge" -a "$rsn_preauth" = 1 ]
+ then
+ append "$var" "rsn_preauth=1" "$N"
+ append "$var" "rsn_preauth_interfaces=$bridge" "$N"
+ append "$var" "okc=1" "$N"
+ else
+ # RSN preauthentication testings hould disable
+ # Opportunistic Key Caching (okc) as otherwise the PMKSA
+ # entry for a test could come from the Opportunistic Key Caching
+ config_get rsn_preauth_testing "$vif" rsn_preauth_testing
+ if [ -n "$bridge" -a "$rsn_preauth_testing" = 1 ]
+ then
+ append "$var" "rsn_preauth=1" "$N"
+ append "$var" "rsn_preauth_interfaces=$bridge" "$N"
+ append "$var" "okc=0" "$N"
+ fi
+ fi
+
+ # RSN -> allow management frame protection
+ config_get ieee80211w "$vif" ieee80211w
+ case "$ieee80211w" in
+ [012])
+ append "$var" "ieee80211w=$ieee80211w" "$N"
+ [ "$ieee80211w" -gt "0" ] && {
+ config_get ieee80211w_max_timeout "$vif" ieee80211w_max_timeout
+ config_get ieee80211w_retry_timeout "$vif" ieee80211w_retry_timeout
+ [ -n "$ieee80211w_max_timeout" ] && \
+ append "$var" "assoc_sa_query_max_timeout=$ieee80211w_max_timeout" "$N"
+ [ -n "$ieee80211w_retry_timeout" ] && \
+ append "$var" "assoc_sa_query_retry_timeout=$ieee80211w_retry_timeout" "$N"
+ }
+ ;;
+ esac
+ fi
+
+ config_get macfile "$vif" macfile
+ config_get maclist "$vif" maclist
+ if [ -z "$macfile" ]
+ then
+ # if no macfile has been specified, fallback to the default name
+ # and truncate file to avoid aggregating entries over time
+ macfile="/var/run/hostapd-$ifname.maclist"
+ echo "" > "$macfile"
+ else
+ if [ -n "$maclist" ]
+ then
+ # to avoid to overwrite the original file, make a copy
+ # before appending the entries specified by the maclist
+ # option
+ cp $macfile $macfile.maclist
+ macfile=$macfile.maclist
+ fi
+ fi
+
+ if [ -n "$maclist" ]
+ then
+ for mac in $maclist; do
+ echo "$mac" >> $macfile
+ done
+ fi
+
+ config_get macfilter "$vif" macfilter
+ case "$macfilter" in
+ allow)
+ append "$var" "macaddr_acl=1" "$N"
+ append "$var" "accept_mac_file=$macfile" "$N"
+ ;;
+ deny)
+ append "$var" "macaddr_acl=0" "$N"
+ append "$var" "deny_mac_file=$macfile" "$N"
+ ;;
+ esac
+}
+
+hostapd_set_log_options() {
+ local var="$1"
+ local cfg="$2"
+ local log_level log_80211 log_8021x log_radius log_wpa log_driver log_iapp log_mlme
+
+ config_get log_level "$cfg" log_level 2
+
+ config_get_bool log_80211 "$cfg" log_80211 1
+ config_get_bool log_8021x "$cfg" log_8021x 1
+ config_get_bool log_radius "$cfg" log_radius 1
+ config_get_bool log_wpa "$cfg" log_wpa 1
+ config_get_bool log_driver "$cfg" log_driver 1
+ config_get_bool log_iapp "$cfg" log_iapp 1
+ config_get_bool log_mlme "$cfg" log_mlme 1
+
+ local log_mask=$(( \
+ ($log_80211 << 0) | \
+ ($log_8021x << 1) | \
+ ($log_radius << 2) | \
+ ($log_wpa << 3) | \
+ ($log_driver << 4) | \
+ ($log_iapp << 5) | \
+ ($log_mlme << 6) \
+ ))
+
+ append "$var" "logger_syslog=$log_mask" "$N"
+ append "$var" "logger_syslog_level=$log_level" "$N"
+ append "$var" "logger_stdout=$log_mask" "$N"
+ append "$var" "logger_stdout_level=$log_level" "$N"
+}
+
+hostapd_setup_vif() {
+ local vif="$1"
+ local driver="$2"
+ local ifname device channel hwmode
+
+ hostapd_cfg=
+
+ config_get ifname "$vif" ifname
+ config_get device "$vif" device
+ config_get channel "$device" channel
+ config_get hwmode "$device" hwmode
+
+ hostapd_set_log_options hostapd_cfg "$device"
+ hostapd_set_bss_options hostapd_cfg "$vif"
+
+ case "$hwmode" in
+ *bg|*gdt|*gst|*fh) hwmode=g;;
+ *adt|*ast) hwmode=a;;
+ esac
+ [ "$channel" = auto ] && channel=
+ [ -n "$channel" -a -z "$hwmode" ] && wifi_fixup_hwmode "$device"
+ cat > /var/run/hostapd-$ifname.conf <<EOF
+driver=$driver
+interface=$ifname
+${hwmode:+hw_mode=${hwmode#11}}
+${channel:+channel=$channel}
+$hostapd_cfg
+EOF
+ hostapd -P /var/run/wifi-$ifname.pid -B /var/run/hostapd-$ifname.conf
+}
+
diff --git a/package/network/services/hostapd/files/multicall.c b/package/network/services/hostapd/files/multicall.c
new file mode 100644
index 0000000..c8e814b
--- /dev/null
+++ b/package/network/services/hostapd/files/multicall.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+
+extern int hostapd_main(int argc, char **argv);
+extern int wpa_supplicant_main(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ bool restart = false;
+ const char *prog = argv[0];
+
+restart:
+ if (strstr(argv[0], "hostapd"))
+ return hostapd_main(argc, argv);
+ else if (strstr(argv[0], "wpa_supplicant"))
+ return wpa_supplicant_main(argc, argv);
+
+ if (!restart && argc > 1) {
+ argv++;
+ argc--;
+ restart = true;
+ goto restart;
+ }
+
+ fprintf(stderr, "Invalid command.\nUsage: %s wpa_supplicant|hostapd [<arguments>]\n", prog);
+ return 255;
+}
diff --git a/package/network/services/hostapd/files/netifd.sh b/package/network/services/hostapd/files/netifd.sh
new file mode 100644
index 0000000..9b40a23
--- /dev/null
+++ b/package/network/services/hostapd/files/netifd.sh
@@ -0,0 +1,715 @@
+wpa_supplicant_add_rate() {
+ local var="$1"
+ local val="$(($2 / 1000))"
+ local sub="$((($2 / 100) % 10))"
+ append $var "$val" ","
+ [ $sub -gt 0 ] && append $var "."
+}
+
+hostapd_add_rate() {
+ local var="$1"
+ local val="$(($2 / 100))"
+ append $var "$val" " "
+}
+
+hostapd_append_wep_key() {
+ local var="$1"
+
+ wep_keyidx=0
+ set_default key 1
+ case "$key" in
+ [1234])
+ for idx in 1 2 3 4; do
+ local zidx
+ zidx=$(($idx - 1))
+ json_get_var ckey "key${idx}"
+ [ -n "$ckey" ] && \
+ append $var "wep_key${zidx}=$(prepare_key_wep "$ckey")" "$N$T"
+ done
+ wep_keyidx=$((key - 1))
+ ;;
+ *)
+ append $var "wep_key0=$(prepare_key_wep "$key")" "$N$T"
+ ;;
+ esac
+}
+
+hostapd_add_log_config() {
+ config_add_boolean \
+ log_80211 \
+ log_8021x \
+ log_radius \
+ log_wpa \
+ log_driver \
+ log_iapp \
+ log_mlme
+
+ config_add_int log_level
+}
+
+hostapd_common_add_device_config() {
+ config_add_array basic_rate
+ config_add_array supported_rates
+
+ config_add_string country
+ config_add_boolean country_ie doth
+ config_add_string require_mode
+
+ hostapd_add_log_config
+}
+
+hostapd_prepare_device_config() {
+ local config="$1"
+ local driver="$2"
+
+ local base="${config%%.conf}"
+ local base_cfg=
+
+ json_get_vars country country_ie beacon_int doth require_mode
+
+ hostapd_set_log_options base_cfg
+
+ set_default country_ie 1
+ set_default doth 1
+
+ [ -n "$country" ] && {
+ append base_cfg "country_code=$country" "$N"
+
+ [ "$country_ie" -gt 0 ] && append base_cfg "ieee80211d=1" "$N"
+ [ "$hwmode" = "a" -a "$doth" -gt 0 ] && append base_cfg "ieee80211h=1" "$N"
+ }
+ [ -n "$hwmode" ] && append base_cfg "hw_mode=$hwmode" "$N"
+
+ local brlist= br
+ json_get_values basic_rate_list basic_rate
+ for br in $basic_rate_list; do
+ hostapd_add_rate brlist "$br"
+ done
+ case "$require_mode" in
+ g) brlist="60 120 240" ;;
+ n) append base_cfg "require_ht=1" "$N";;
+ ac) append base_cfg "require_vht=1" "$N";;
+ esac
+
+ local rlist= r
+ json_get_values rate_list supported_rates
+ for r in $rate_list; do
+ hostapd_add_rate rlist "$r"
+ done
+
+ [ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N"
+ [ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
+ [ -n "$beacon_int" ] && append base_cfg "beacon_int=$beacon_int" "$N"
+
+ cat > "$config" <<EOF
+driver=$driver
+$base_cfg
+EOF
+}
+
+hostapd_common_add_bss_config() {
+ config_add_string 'bssid:macaddr' 'ssid:string'
+ config_add_boolean wds wmm uapsd hidden
+
+ config_add_int maxassoc max_inactivity
+ config_add_boolean disassoc_low_ack isolate short_preamble
+
+ config_add_int \
+ wep_rekey eap_reauth_period \
+ wpa_group_rekey wpa_pair_rekey wpa_master_rekey
+
+ config_add_boolean rsn_preauth auth_cache
+ config_add_int ieee80211w
+ config_add_int eapol_version
+
+ config_add_string 'auth_server:host' 'server:host'
+ config_add_string auth_secret
+ config_add_int 'auth_port:port' 'port:port'
+
+ config_add_string acct_server
+ config_add_string acct_secret
+ config_add_int acct_port
+
+ config_add_string dae_client
+ config_add_string dae_secret
+ config_add_int dae_port
+
+ config_add_string nasid
+ config_add_string ownip
+ config_add_string iapp_interface
+ config_add_string eap_type ca_cert client_cert identity auth priv_key priv_key_pwd
+
+ config_add_int dynamic_vlan vlan_naming
+ config_add_string vlan_tagged_interface vlan_bridge
+ config_add_string vlan_file
+
+ config_add_string 'key1:wepkey' 'key2:wepkey' 'key3:wepkey' 'key4:wepkey' 'password:wpakey'
+
+ config_add_string wpa_psk_file
+
+ config_add_boolean wps_pushbutton wps_label ext_registrar wps_pbc_in_m1
+ config_add_string wps_device_type wps_device_name wps_manufacturer wps_pin
+
+ config_add_boolean ieee80211r pmk_r1_push
+ config_add_int r0_key_lifetime reassociation_deadline
+ config_add_string mobility_domain r1_key_holder
+ config_add_array r0kh r1kh
+
+ config_add_int ieee80211w_max_timeout ieee80211w_retry_timeout
+
+ config_add_string macfilter 'macfile:file'
+ config_add_array 'maclist:list(macaddr)'
+
+ config_add_array bssid_blacklist
+ config_add_array bssid_whitelist
+
+ config_add_int mcast_rate
+ config_add_array basic_rate
+ config_add_array supported_rates
+}
+
+hostapd_set_bss_options() {
+ local var="$1"
+ local phy="$2"
+ local vif="$3"
+
+ wireless_vif_parse_encryption
+
+ local bss_conf
+ local wep_rekey wpa_group_rekey wpa_pair_rekey wpa_master_rekey wpa_key_mgmt
+
+ json_get_vars \
+ wep_rekey wpa_group_rekey wpa_pair_rekey wpa_master_rekey \
+ maxassoc max_inactivity disassoc_low_ack isolate auth_cache \
+ wps_pushbutton wps_label ext_registrar wps_pbc_in_m1 \
+ wps_device_type wps_device_name wps_manufacturer wps_pin \
+ macfilter ssid wmm uapsd hidden short_preamble rsn_preauth \
+ iapp_interface eapol_version
+
+ set_default isolate 0
+ set_default maxassoc 0
+ set_default max_inactivity 0
+ set_default short_preamble 1
+ set_default disassoc_low_ack 1
+ set_default hidden 0
+ set_default wmm 1
+ set_default uapsd 1
+ set_default eapol_version 0
+
+ append bss_conf "ctrl_interface=/var/run/hostapd"
+ if [ "$isolate" -gt 0 ]; then
+ append bss_conf "ap_isolate=$isolate" "$N"
+ fi
+ if [ "$maxassoc" -gt 0 ]; then
+ append bss_conf "max_num_sta=$maxassoc" "$N"
+ fi
+ if [ "$max_inactivity" -gt 0 ]; then
+ append bss_conf "ap_max_inactivity=$max_inactivity" "$N"
+ fi
+
+ append bss_conf "disassoc_low_ack=$disassoc_low_ack" "$N"
+ append bss_conf "preamble=$short_preamble" "$N"
+ append bss_conf "wmm_enabled=$wmm" "$N"
+ append bss_conf "ignore_broadcast_ssid=$hidden" "$N"
+ append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
+
+ [ "$wpa" -gt 0 ] && {
+ [ -n "$wpa_group_rekey" ] && append bss_conf "wpa_group_rekey=$wpa_group_rekey" "$N"
+ [ -n "$wpa_pair_rekey" ] && append bss_conf "wpa_ptk_rekey=$wpa_pair_rekey" "$N"
+ [ -n "$wpa_master_rekey" ] && append bss_conf "wpa_gmk_rekey=$wpa_master_rekey" "$N"
+ }
+
+ case "$auth_type" in
+ none)
+ wps_possible=1
+ # Here we make the assumption that if we're in open mode
+ # with WPS enabled, we got to be in unconfigured state.
+ wps_not_configured=1
+ ;;
+ psk)
+ json_get_vars key wpa_psk_file
+ if [ ${#key} -lt 8 ]; then
+ wireless_setup_vif_failed INVALID_WPA_PSK
+ return 1
+ elif [ ${#key} -eq 64 ]; then
+ append bss_conf "wpa_psk=$key" "$N"
+ else
+ append bss_conf "wpa_passphrase=$key" "$N"
+ fi
+ [ -n "$wpa_psk_file" ] && {
+ [ -e "$wpa_psk_file" ] || touch "$wpa_psk_file"
+ append bss_conf "wpa_psk_file=$wpa_psk_file" "$N"
+ }
+ [ "$eapol_version" -ge "1" -a "$eapol_version" -le "2" ] && append bss_conf "eapol_version=$eapol_version" "$N"
+
+ wps_possible=1
+ append wpa_key_mgmt "WPA-PSK"
+ ;;
+ eap)
+ json_get_vars \
+ auth_server auth_secret auth_port \
+ acct_server acct_secret acct_port \
+ dae_client dae_secret dae_port \
+ ownip \
+ eap_reauth_period dynamic_vlan \
+ vlan_naming vlan_tagged_interface \
+ vlan_bridge vlan_file
+
+ # legacy compatibility
+ [ -n "$auth_server" ] || json_get_var auth_server server
+ [ -n "$auth_port" ] || json_get_var auth_port port
+ [ -n "$auth_secret" ] || json_get_var auth_secret key
+
+ set_default auth_port 1812
+ set_default acct_port 1813
+ set_default dae_port 3799
+
+ set_default vlan_naming 1
+
+ append bss_conf "auth_server_addr=$auth_server" "$N"
+ append bss_conf "auth_server_port=$auth_port" "$N"
+ append bss_conf "auth_server_shared_secret=$auth_secret" "$N"
+
+ [ -n "$acct_server" ] && {
+ append bss_conf "acct_server_addr=$acct_server" "$N"
+ append bss_conf "acct_server_port=$acct_port" "$N"
+ [ -n "$acct_secret" ] && \
+ append bss_conf "acct_server_shared_secret=$acct_secret" "$N"
+ }
+
+ [ -n "$eap_reauth_period" ] && append bss_conf "eap_reauth_period=$eap_reauth_period" "$N"
+
+ [ -n "$dae_client" -a -n "$dae_secret" ] && {
+ append bss_conf "radius_das_port=$dae_port" "$N"
+ append bss_conf "radius_das_client=$dae_client $dae_secret" "$N"
+ }
+
+ [ -n "$ownip" ] && append bss_conf "own_ip_addr=$ownip" "$N"
+ append bss_conf "eapol_key_index_workaround=1" "$N"
+ append bss_conf "ieee8021x=1" "$N"
+ append wpa_key_mgmt "WPA-EAP"
+
+ [ -n "$dynamic_vlan" ] && {
+ append bss_conf "dynamic_vlan=$dynamic_vlan" "$N"
+ append bss_conf "vlan_naming=$vlan_naming" "$N"
+ [ -n "$vlan_bridge" ] && \
+ append bss_conf "vlan_bridge=$vlan_bridge" "$N"
+ [ -n "$vlan_tagged_interface" ] && \
+ append bss_conf "vlan_tagged_interface=$vlan_tagged_interface" "$N"
+ [ -n "$vlan_file" ] && {
+ [ -e "$vlan_file" ] || touch "$vlan_file"
+ append bss_conf "vlan_file=$vlan_file" "$N"
+ }
+ }
+
+ [ "$eapol_version" -ge "1" -a "$eapol_version" -le "2" ] && append bss_conf "eapol_version=$eapol_version" "$N"
+ ;;
+ wep)
+ local wep_keyidx=0
+ json_get_vars key
+ hostapd_append_wep_key bss_conf
+ append bss_conf "wep_default_key=$wep_keyidx" "$N"
+ [ -n "$wep_rekey" ] && append bss_conf "wep_rekey_period=$wep_rekey" "$N"
+ ;;
+ esac
+
+ local auth_algs=$((($auth_mode_shared << 1) | $auth_mode_open))
+ append bss_conf "auth_algs=${auth_algs:-1}" "$N"
+ append bss_conf "wpa=$wpa" "$N"
+ [ -n "$wpa_pairwise" ] && append bss_conf "wpa_pairwise=$wpa_pairwise" "$N"
+
+ set_default wps_pushbutton 0
+ set_default wps_label 0
+ set_default wps_pbc_in_m1 0
+
+ config_methods=
+ [ "$wps_pushbutton" -gt 0 ] && append config_methods push_button
+ [ "$wps_label" -gt 0 ] && append config_methods label
+
+ [ -n "$wps_possible" -a -n "$config_methods" ] && {
+ set_default ext_registrar 0
+ set_default wps_device_type "6-0050F204-1"
+ set_default wps_device_name "OpenWrt AP"
+ set_default wps_manufacturer "openwrt.org"
+
+ wps_state=2
+ [ -n "$wps_configured" ] && wps_state=1
+
+ [ "$ext_registrar" -gt 0 -a -n "$network_bridge" ] && append bss_conf "upnp_iface=$network_bridge" "$N"
+
+ append bss_conf "eap_server=1" "$N"
+ [ -n "$wps_pin" ] && append bss_conf "ap_pin=$wps_pin" "$N"
+ append bss_conf "wps_state=$wps_state" "$N"
+ append bss_conf "ap_setup_locked=0" "$N"
+ append bss_conf "device_type=$wps_device_type" "$N"
+ append bss_conf "device_name=$wps_device_name" "$N"
+ append bss_conf "manufacturer=$wps_manufacturer" "$N"
+ append bss_conf "config_methods=$config_methods" "$N"
+ [ "$wps_pbc_in_m1" -gt 0 ] && append bss_conf "pbc_in_m1=$wps_pbc_in_m1" "$N"
+ }
+
+ append bss_conf "ssid=$ssid" "$N"
+ [ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N"
+ [ -n "$iapp_interface" ] && {
+ iapp_interface="$(uci_get_state network "$iapp_interface" ifname "$iapp_interface")"
+ [ -n "$iapp_interface" ] && append bss_conf "iapp_interface=$iapp_interface" "$N"
+ }
+
+ if [ "$wpa" -ge "1" ]; then
+ json_get_vars nasid ieee80211r
+ set_default ieee80211r 0
+ [ -n "$nasid" ] && append bss_conf "nas_identifier=$nasid" "$N"
+
+ if [ "$ieee80211r" -gt "0" ]; then
+ json_get_vars mobility_domain r0_key_lifetime r1_key_holder \
+ reassociation_deadline pmk_r1_push
+ json_get_values r0kh r0kh
+ json_get_values r1kh r1kh
+
+ set_default mobility_domain "4f57"
+ set_default r0_key_lifetime 10000
+ set_default r1_key_holder "00004f577274"
+ set_default reassociation_deadline 1000
+ set_default pmk_r1_push 0
+
+ append bss_conf "mobility_domain=$mobility_domain" "$N"
+ append bss_conf "r0_key_lifetime=$r0_key_lifetime" "$N"
+ append bss_conf "r1_key_holder=$r1_key_holder" "$N"
+ append bss_conf "reassociation_deadline=$reassociation_deadline" "$N"
+ append bss_conf "pmk_r1_push=$pmk_r1_push" "$N"
+
+ for kh in $r0kh; do
+ append bss_conf "r0kh=${kh//,/ }" "$N"
+ done
+ for kh in $r1kh; do
+ append bss_conf "r1kh=${kh//,/ }" "$N"
+ done
+
+ [ "$wpa_key_mgmt" != "${wpa_key_mgmt/EAP/}" ] && append wpa_key_mgmt "FT-EAP"
+ [ "$wpa_key_mgmt" != "${wpa_key_mgmt/PSK/}" ] && append wpa_key_mgmt "FT-PSK"
+ fi
+
+ [ -n "$wpa_key_mgmt" ] && append bss_conf "wpa_key_mgmt=$wpa_key_mgmt" "$N"
+ fi
+
+ if [ "$wpa" -ge "2" ]; then
+ if [ -n "$network_bridge" -a "$rsn_preauth" = 1 ]; then
+ set_default auth_cache 1
+ append bss_conf "rsn_preauth=1" "$N"
+ append bss_conf "rsn_preauth_interfaces=$network_bridge" "$N"
+ else
+ set_default auth_cache 0
+ fi
+
+ append bss_conf "okc=$auth_cache" "$N"
+ [ "$auth_cache" = 0 ] && append bss_conf "disable_pmksa_caching=1" "$N"
+
+ # RSN -> allow management frame protection
+ json_get_var ieee80211w ieee80211w
+ case "$ieee80211w" in
+ [012])
+ json_get_vars ieee80211w_max_timeout ieee80211w_retry_timeout
+ append bss_conf "ieee80211w=$ieee80211w" "$N"
+ [ "$ieee80211w" -gt "0" ] && {
+ [ -n "$ieee80211w_max_timeout" ] && \
+ append bss_conf "assoc_sa_query_max_timeout=$ieee80211w_max_timeout" "$N"
+ [ -n "$ieee80211w_retry_timeout" ] && \
+ append bss_conf "assoc_sa_query_retry_timeout=$ieee80211w_retry_timeout" "$N"
+ }
+ ;;
+ esac
+ fi
+
+ _macfile="/var/run/hostapd-$ifname.maclist"
+ case "$macfilter" in
+ allow)
+ append bss_conf "macaddr_acl=1" "$N"
+ append bss_conf "accept_mac_file=$_macfile" "$N"
+ ;;
+ deny)
+ append bss_conf "macaddr_acl=0" "$N"
+ append bss_conf "deny_mac_file=$_macfile" "$N"
+ ;;
+ *)
+ _macfile=""
+ ;;
+ esac
+
+ [ -n "$_macfile" ] && {
+ json_get_vars macfile
+ json_get_values maclist maclist
+
+ rm -f "$_macfile"
+ (
+ for mac in $maclist; do
+ echo "$mac"
+ done
+ [ -n "$macfile" -a -f "$macfile" ] && cat "$macfile"
+ ) > "$_macfile"
+ }
+
+ append "$var" "$bss_conf" "$N"
+ return 0
+}
+
+hostapd_set_log_options() {
+ local var="$1"
+
+ local log_level log_80211 log_8021x log_radius log_wpa log_driver log_iapp log_mlme
+ json_get_vars log_level log_80211 log_8021x log_radius log_wpa log_driver log_iapp log_mlme
+
+ set_default log_level 2
+ set_default log_80211 1
+ set_default log_8021x 1
+ set_default log_radius 1
+ set_default log_wpa 1
+ set_default log_driver 1
+ set_default log_iapp 1
+ set_default log_mlme 1
+
+ local log_mask=$(( \
+ ($log_80211 << 0) | \
+ ($log_8021x << 1) | \
+ ($log_radius << 2) | \
+ ($log_wpa << 3) | \
+ ($log_driver << 4) | \
+ ($log_iapp << 5) | \
+ ($log_mlme << 6) \
+ ))
+
+ append "$var" "logger_syslog=$log_mask" "$N"
+ append "$var" "logger_syslog_level=$log_level" "$N"
+ append "$var" "logger_stdout=$log_mask" "$N"
+ append "$var" "logger_stdout_level=$log_level" "$N"
+
+ return 0
+}
+
+_wpa_supplicant_common() {
+ local ifname="$1"
+
+ _rpath="/var/run/wpa_supplicant"
+ _config="${_rpath}-$ifname.conf"
+}
+
+wpa_supplicant_teardown_interface() {
+ _wpa_supplicant_common "$1"
+ rm -rf "$_rpath/$1" "$_config"
+}
+
+wpa_supplicant_prepare_interface() {
+ local ifname="$1"
+ _w_driver="$2"
+
+ _wpa_supplicant_common "$1"
+
+ json_get_vars mode wds
+
+ [ -n "$network_bridge" ] && {
+ fail=
+ case "$mode" in
+ adhoc)
+ fail=1
+ ;;
+ sta)
+ [ "$wds" = 1 ] || fail=1
+ ;;
+ esac
+
+ [ -n "$fail" ] && {
+ wireless_setup_vif_failed BRIDGE_NOT_ALLOWED
+ return 1
+ }
+ }
+
+ local ap_scan=
+
+ _w_mode="$mode"
+ _w_modestr=
+
+ [[ "$mode" = adhoc ]] && {
+ ap_scan="ap_scan=2"
+
+ _w_modestr="mode=1"
+ }
+
+ wpa_supplicant_teardown_interface "$ifname"
+ cat > "$_config" <<EOF
+$ap_scan
+EOF
+ return 0
+}
+
+wpa_supplicant_add_network() {
+ local ifname="$1"
+
+ _wpa_supplicant_common "$1"
+ wireless_vif_parse_encryption
+
+ json_get_vars \
+ ssid bssid key \
+ basic_rate mcast_rate \
+ ieee80211w ieee80211r
+
+ set_default ieee80211r 0
+
+ local key_mgmt='NONE'
+ local enc_str=
+ local network_data=
+ local T=" "
+
+ local wpa_key_mgmt="WPA-PSK"
+ local scan_ssid="scan_ssid=1"
+ local freq
+
+ [ "$ieee80211r" -gt 0 ] && wpa_key_mgmt="FT-PSK $wpa_key_mgmt"
+
+ [[ "$_w_mode" = "adhoc" ]] && {
+ append network_data "mode=1" "$N$T"
+ [ -n "$channel" ] && {
+ freq="$(get_freq "$phy" "$channel")"
+ append network_data "fixed_freq=1" "$N$T"
+ append network_data "frequency=$freq" "$N$T"
+ }
+
+ scan_ssid="scan_ssid=0"
+
+ [ "$_w_driver" = "nl80211" ] || wpa_key_mgmt="WPA-NONE"
+ }
+
+ [[ "$_w_mode" = "mesh" ]] && {
+ append network_data "mode=5" "$N$T"
+ [ -n "$channel" ] && {
+ freq="$(get_freq "$phy" "$channel")"
+ append network_data "frequency=$freq" "$N$T"
+ }
+ wpa_key_mgmt="SAE"
+ scan_ssid=""
+ }
+
+ [[ "$_w_mode" = "adhoc" -o "$_w_mode" = "mesh" ]] && append network_data "$_w_modestr" "$N$T"
+
+ case "$auth_type" in
+ none) ;;
+ wep)
+ local wep_keyidx=0
+ hostapd_append_wep_key network_data
+ append network_data "wep_tx_keyidx=$wep_keyidx" "$N$T"
+ ;;
+ psk)
+ local passphrase
+
+ key_mgmt="$wpa_key_mgmt"
+ if [ ${#key} -eq 64 ]; then
+ passphrase="psk=${key}"
+ else
+ passphrase="psk=\"${key}\""
+ fi
+ append network_data "$passphrase" "$N$T"
+ ;;
+ eap)
+ key_mgmt='WPA-EAP'
+ [ "$ieee80211r" -gt 0 ] && key_mgmt="FT-EAP $key_mgmt"
+
+ json_get_vars eap_type identity ca_cert
+ [ -n "$ca_cert" ] && append network_data "ca_cert=\"$ca_cert\"" "$N$T"
+ [ -n "$identity" ] && append network_data "identity=\"$identity\"" "$N$T"
+ case "$eap_type" in
+ tls)
+ json_get_vars client_cert priv_key priv_key_pwd
+ append network_data "client_cert=\"$client_cert\"" "$N$T"
+ append network_data "private_key=\"$priv_key\"" "$N$T"
+ append network_data "private_key_passwd=\"$priv_key_pwd\"" "$N$T"
+ ;;
+ peap|ttls)
+ json_get_vars auth password
+ set_default auth MSCHAPV2
+ append network_data "phase2=\"$auth\"" "$N$T"
+ append network_data "password=\"$password\"" "$N$T"
+ ;;
+ esac
+ append network_data "eap=$(echo $eap_type | tr 'a-z' 'A-Z')" "$N$T"
+ ;;
+ esac
+
+ [ "$mode" = mesh ] || {
+ case "$wpa" in
+ 1)
+ append network_data "proto=WPA" "$N$T"
+ ;;
+ 2)
+ append network_data "proto=RSN" "$N$T"
+ ;;
+ esac
+
+ case "$ieee80211w" in
+ [012])
+ [ "$wpa" -ge 2 ] && append network_data "ieee80211w=$ieee80211w" "$N$T"
+ ;;
+ esac
+ }
+ local beacon_int brates mrate
+ [ -n "$bssid" ] && append network_data "bssid=$bssid" "$N$T"
+ [ -n "$beacon_int" ] && append network_data "beacon_int=$beacon_int" "$N$T"
+
+ local bssid_blacklist bssid_whitelist
+ json_get_values bssid_blacklist bssid_blacklist
+ json_get_values bssid_whitelist bssid_whitelist
+
+ [ -n "$bssid_blacklist" ] && append network_data "bssid_blacklist=$bssid_blacklist" "$N$T"
+ [ -n "$bssid_whitelist" ] && append network_data "bssid_whitelist=$bssid_whitelist" "$N$T"
+
+ [ -n "$basic_rate" ] && {
+ local br rate_list=
+ for br in $basic_rate; do
+ wpa_supplicant_add_rate rate_list "$br"
+ done
+ [ -n "$rate_list" ] && append network_data "rates=$rate_list" "$N$T"
+ }
+
+ [ -n "$mcast_rate" ] && {
+ local mc_rate=
+ wpa_supplicant_add_rate mc_rate "$mcast_rate"
+ append network_data "mcast_rate=$mc_rate" "$N$T"
+ }
+
+ local ht_str
+ [[ "$_w_mode" = adhoc ]] || ibss_htmode=
+ [ -n "$ibss_htmode" ] && append network_data "htmode=$ibss_htmode" "$N$T"
+
+ cat >> "$_config" <<EOF
+network={
+ $scan_ssid
+ ssid="$ssid"
+ key_mgmt=$key_mgmt
+ $network_data
+}
+EOF
+ return 0
+}
+
+wpa_supplicant_run() {
+ local ifname="$1"; shift
+
+ _wpa_supplicant_common "$ifname"
+
+ /usr/sbin/wpa_supplicant -B \
+ ${network_bridge:+-b $network_bridge} \
+ -P "/var/run/wpa_supplicant-${ifname}.pid" \
+ -D ${_w_driver:-wext} \
+ -i "$ifname" \
+ -c "$_config" \
+ -C "$_rpath" \
+ "$@"
+
+ ret="$?"
+ wireless_add_process "$(cat "/var/run/wpa_supplicant-${ifname}.pid")" /usr/sbin/wpa_supplicant 1
+
+ [ "$ret" != 0 ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED
+
+ return $ret
+}
+
+hostapd_common_cleanup() {
+ killall hostapd wpa_supplicant meshd-nl80211
+}
diff --git a/package/network/services/hostapd/files/wpa_supplicant-full.config b/package/network/services/hostapd/files/wpa_supplicant-full.config
new file mode 100644
index 0000000..26e3c80
--- /dev/null
+++ b/package/network/services/hostapd/files/wpa_supplicant-full.config
@@ -0,0 +1,403 @@
+# Example wpa_supplicant build time configuration
+#
+# This file lists the configuration options that are used when building the
+# hostapd binary. All lines starting with # are ignored. Configuration option
+# lines must be commented out complete, if they are not to be included, i.e.,
+# just setting VARIABLE=n is not disabling that variable.
+#
+# This file is included in Makefile, so variables like CFLAGS and LIBS can also
+# be modified from here. In most cases, these lines should use += in order not
+# to override previous values of the variables.
+
+
+# Uncomment following two lines and fix the paths if you have installed OpenSSL
+# or GnuTLS in non-default location
+#CFLAGS += -I/usr/local/openssl/include
+#LIBS += -L/usr/local/openssl/lib
+
+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
+# the kerberos files are not in the default include path. Following line can be
+# used to fix build issues on such systems (krb5.h not found).
+#CFLAGS += -I/usr/include/kerberos
+
+# Example configuration for various cross-compilation platforms
+
+#### sveasoft (e.g., for Linksys WRT54G) ######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS += -I../src/include -I../../src/router/openssl/include
+#LIBS += -L/opt/brcm/hndtools-mipsel-uclibc-0.9.19/lib -lssl
+###############################################################################
+
+#### openwrt (e.g., for Linksys WRT54G) #######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS=-I../src/include -I../openssl-0.9.7d/include \
+# -I../WRT54GS/release/src/include
+#LIBS = -lssl
+###############################################################################
+
+
+# Driver interface for Host AP driver
+CONFIG_DRIVER_HOSTAP=y
+
+# Driver interface for Agere driver
+#CONFIG_DRIVER_HERMES=y
+# Change include directories to match with the local setup
+#CFLAGS += -I../../hcf -I../../include -I../../include/hcf
+#CFLAGS += -I../../include/wireless
+
+# Driver interface for ndiswrapper
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_NDISWRAPPER=y
+
+# Driver interface for Atmel driver
+# CONFIG_DRIVER_ATMEL=y
+
+# Driver interface for old Broadcom driver
+# Please note that the newer Broadcom driver ("hybrid Linux driver") supports
+# Linux wireless extensions and does not need (or even work) with the old
+# driver wrapper. Use CONFIG_DRIVER_WEXT=y with that driver.
+#CONFIG_DRIVER_BROADCOM=y
+# Example path for wlioctl.h; change to match your configuration
+#CFLAGS += -I/opt/WRT54GS/release/src/include
+
+# Driver interface for Intel ipw2100/2200 driver
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_IPW=y
+
+# Driver interface for Ralink driver
+#CONFIG_DRIVER_RALINK=y
+
+# Driver interface for generic Linux wireless extensions
+CONFIG_DRIVER_WEXT=y
+
+# Driver interface for Linux drivers using the nl80211 kernel interface
+CONFIG_DRIVER_NL80211=y
+
+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
+#CONFIG_DRIVER_BSD=y
+#CFLAGS += -I/usr/local/include
+#LIBS += -L/usr/local/lib
+#LIBS_p += -L/usr/local/lib
+#LIBS_c += -L/usr/local/lib
+
+# Driver interface for Windows NDIS
+#CONFIG_DRIVER_NDIS=y
+#CFLAGS += -I/usr/include/w32api/ddk
+#LIBS += -L/usr/local/lib
+# For native build using mingw
+#CONFIG_NATIVE_WINDOWS=y
+# Additional directories for cross-compilation on Linux host for mingw target
+#CFLAGS += -I/opt/mingw/mingw32/include/ddk
+#LIBS += -L/opt/mingw/mingw32/lib
+#CC=mingw32-gcc
+# By default, driver_ndis uses WinPcap for low-level operations. This can be
+# replaced with the following option which replaces WinPcap calls with NDISUIO.
+# However, this requires that WZC is disabled (net stop wzcsvc) before starting
+# wpa_supplicant.
+# CONFIG_USE_NDISUIO=y
+
+# Driver interface for development testing
+#CONFIG_DRIVER_TEST=y
+
+# Include client MLME (management frame processing) for test driver
+# This can be used to test MLME operations in hostapd with the test interface.
+# space.
+#CONFIG_CLIENT_MLME=y
+
+# Driver interface for wired Ethernet drivers
+CONFIG_DRIVER_WIRED=y
+
+# Driver interface for the Broadcom RoboSwitch family
+#CONFIG_DRIVER_ROBOSWITCH=y
+
+# Driver interface for no driver (e.g., WPS ER only)
+#CONFIG_DRIVER_NONE=y
+
+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is
+# included)
+CONFIG_IEEE8021X_EAPOL=y
+
+# EAP-MD5
+CONFIG_EAP_MD5=y
+
+# EAP-MSCHAPv2
+CONFIG_EAP_MSCHAPV2=y
+
+# EAP-TLS
+CONFIG_EAP_TLS=y
+
+# EAL-PEAP
+CONFIG_EAP_PEAP=y
+
+# EAP-TTLS
+CONFIG_EAP_TTLS=y
+
+# EAP-FAST
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.8d-tls-extensions.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
+# EAP-GTC
+CONFIG_EAP_GTC=y
+
+# EAP-OTP
+CONFIG_EAP_OTP=y
+
+# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
+#CONFIG_EAP_SIM=y
+
+# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-PAX
+#CONFIG_EAP_PAX=y
+
+# LEAP
+CONFIG_EAP_LEAP=y
+
+# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
+#CONFIG_EAP_AKA=y
+
+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
+# Enable USIM simulator (Milenage) for EAP-AKA
+#CONFIG_USIM_SIMULATOR=y
+
+# EAP-SAKE
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-TNC and related Trusted Network Connect support (experimental)
+#CONFIG_EAP_TNC=y
+
+# Wi-Fi Protected Setup (WPS)
+CONFIG_WPS=y
+
+# EAP-IKEv2
+#CONFIG_EAP_IKEV2=y
+
+# PKCS#12 (PFX) support (used to read private key and certificate file from
+# a file that usually has extension .p12 or .pfx)
+CONFIG_PKCS12=y
+
+# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
+# engine.
+CONFIG_SMARTCARD=y
+
+# PC/SC interface for smartcards (USIM, GSM SIM)
+# Enable this if EAP-SIM or EAP-AKA is included
+#CONFIG_PCSC=y
+
+# Development testing
+#CONFIG_EAPOL_TEST=y
+
+# Select control interface backend for external programs, e.g, wpa_cli:
+# unix = UNIX domain sockets (default for Linux/*BSD)
+# udp = UDP sockets using localhost (127.0.0.1)
+# named_pipe = Windows Named Pipe (default for Windows)
+# y = use default (backwards compatibility)
+# If this option is commented out, control interface is not included in the
+# build.
+CONFIG_CTRL_IFACE=y
+
+# Include support for GNU Readline and History Libraries in wpa_cli.
+# When building a wpa_cli binary for distribution, please note that these
+# libraries are licensed under GPL and as such, BSD license may not apply for
+# the resulting binary.
+#CONFIG_READLINE=y
+
+# Remove debugging code that is printing out debug message to stdout.
+# This can be used to reduce the size of the wpa_supplicant considerably
+# if debugging code is not needed. The size reduction can be around 35%
+# (e.g., 90 kB).
+#CONFIG_NO_STDOUT_DEBUG=y
+
+# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
+# 35-50 kB in code size.
+#CONFIG_NO_WPA=y
+
+# Remove WPA2 support. This allows WPA to be used, but removes WPA2 code to
+# save about 1 kB in code size when building only WPA-Personal (no EAP support)
+# or 6 kB if building for WPA-Enterprise.
+#CONFIG_NO_WPA2=y
+
+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
+# This option can be used to reduce code size by removing support for
+# converting ASCII passphrases into PSK. If this functionality is removed, the
+# PSK can only be configured as the 64-octet hexstring (e.g., from
+# wpa_passphrase). This saves about 0.5 kB in code size.
+#CONFIG_NO_WPA_PASSPHRASE=y
+
+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
+# This can be used if ap_scan=1 mode is never enabled.
+#CONFIG_NO_SCAN_PROCESSING=y
+
+# Select configuration backend:
+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
+# path is given on command line, not here; this option is just used to
+# select the backend that allows configuration files to be used)
+# winreg = Windows registry (see win_example.reg for an example)
+CONFIG_BACKEND=file
+
+# Remove configuration write functionality (i.e., to allow the configuration
+# file to be updated based on runtime configuration changes). The runtime
+# configuration can still be changed, the changes are just not going to be
+# persistent over restarts. This option can be used to reduce code size by
+# about 3.5 kB.
+#CONFIG_NO_CONFIG_WRITE=y
+
+# Remove support for configuration blobs to reduce code size by about 1.5 kB.
+#CONFIG_NO_CONFIG_BLOBS=y
+
+# Select program entry point implementation:
+# main = UNIX/POSIX like main() function (default)
+# main_winsvc = Windows service (read parameters from registry)
+# main_none = Very basic example (development use only)
+#CONFIG_MAIN=main
+
+# Select wrapper for operatins system and C library specific functions
+# unix = UNIX/POSIX like systems (default)
+# win32 = Windows systems
+# none = Empty template
+#CONFIG_OS=unix
+
+# Select event loop implementation
+# eloop = select() loop (default)
+# eloop_win = Windows events and WaitForMultipleObject() loop
+# eloop_none = Empty template
+#CONFIG_ELOOP=eloop
+
+# Select layer 2 packet implementation
+# linux = Linux packet socket (default)
+# pcap = libpcap/libdnet/WinPcap
+# freebsd = FreeBSD libpcap
+# winpcap = WinPcap with receive thread
+# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
+# none = Empty template
+#CONFIG_L2_PACKET=linux
+
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+CONFIG_IEEE80211W=y
+
+# Select TLS implementation
+# openssl = OpenSSL (default)
+# gnutls = GnuTLS (needed for TLS/IA, see also CONFIG_GNUTLS_EXTRA)
+# internal = Internal TLSv1 implementation (experimental)
+# none = Empty template
+CONFIG_TLS=internal
+
+# Whether to enable TLS/IA support, which is required for EAP-TTLSv1.
+# You need CONFIG_TLS=gnutls for this to have any effect. Please note that
+# even though the core GnuTLS library is released under LGPL, this extra
+# library uses GPL and as such, the terms of GPL apply to the combination
+# of wpa_supplicant and GnuTLS if this option is enabled. BSD license may not
+# apply for distribution of the resulting binary.
+#CONFIG_GNUTLS_EXTRA=y
+
+# If CONFIG_TLS=internal is used, additional library and include paths are
+# needed for LibTomMath. Alternatively, an integrated, minimal version of
+# LibTomMath can be used. See beginning of libtommath.c for details on benefits
+# and drawbacks of this option.
+CONFIG_INTERNAL_LIBTOMMATH=y
+#ifndef CONFIG_INTERNAL_LIBTOMMATH
+#LTM_PATH=/usr/src/libtommath-0.39
+#CFLAGS += -I$(LTM_PATH)
+#LIBS += -L$(LTM_PATH)
+#LIBS_p += -L$(LTM_PATH)
+#endif
+# At the cost of about 4 kB of additional binary size, the internal LibTomMath
+# can be configured to include faster routines for exptmod, sqr, and div to
+# speed up DH and RSA calculation considerably
+CONFIG_INTERNAL_LIBTOMMATH_FAST=y
+
+# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
+# This is only for Windows builds and requires WMI-related header files and
+# WbemUuid.Lib from Platform SDK even when building with MinGW.
+#CONFIG_NDIS_EVENTS_INTEGRATED=y
+#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
+
+# Add support for old DBus control interface
+# (fi.epitest.hostap.WPASupplicant)
+#CONFIG_CTRL_IFACE_DBUS=y
+
+# Add support for new DBus control interface
+# (fi.w1.hostap.wpa_supplicant1)
+#CONFIG_CTRL_IFACE_DBUS_NEW=y
+
+# Add introspection support for new DBus control interface
+#CONFIG_CTRL_IFACE_DBUS_INTRO=y
+
+# Add support for loading EAP methods dynamically as shared libraries.
+# When this option is enabled, each EAP method can be either included
+# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
+# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
+# be loaded in the beginning of the wpa_supplicant configuration file
+# (see load_dynamic_eap parameter in the example file) before being used in
+# the network blocks.
+#
+# Note that some shared parts of EAP methods are included in the main program
+# and in order to be able to use dynamic EAP methods using these parts, the
+# main program must have been build with the EAP method enabled (=y or =dyn).
+# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
+# unless at least one of them was included in the main build to force inclusion
+# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
+# in the main build to be able to load these methods dynamically.
+#
+# Please also note that using dynamic libraries will increase the total binary
+# size. Thus, it may not be the best option for targets that have limited
+# amount of memory/flash.
+#CONFIG_DYNAMIC_EAP_METHODS=y
+
+# IEEE Std 802.11r-2008 (Fast BSS Transition)
+CONFIG_IEEE80211R=y
+
+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
+#CONFIG_DEBUG_FILE=y
+
+# Enable privilege separation (see README 'Privilege separation' for details)
+#CONFIG_PRIVSEP=y
+
+# Enable mitigation against certain attacks against TKIP by delaying Michael
+# MIC error reports by a random amount of time between 0 and 60 seconds
+#CONFIG_DELAYED_MIC_ERROR_REPORT=y
+
+# Enable tracing code for developer debugging
+# This tracks use of memory allocations and other registrations and reports
+# incorrect use with a backtrace of call (or allocation) location.
+#CONFIG_WPA_TRACE=y
+# For BSD, comment out these.
+#LIBS += -lexecinfo
+#LIBS_p += -lexecinfo
+#LIBS_c += -lexecinfo
+
+# Use libbfd to get more details for developer debugging
+# This enables use of libbfd to get more detailed symbols for the backtraces
+# generated by CONFIG_WPA_TRACE=y.
+#CONFIG_WPA_TRACE_BFD=y
+# For BSD, comment out these.
+#LIBS += -lbfd -liberty -lz
+#LIBS_p += -lbfd -liberty -lz
+#LIBS_c += -lbfd -liberty -lz
+
+CONFIG_NO_RANDOM_POOL=y
+NEED_80211_COMMON=y
+
+CONFIG_IBSS_RSN=y
diff --git a/package/network/services/hostapd/files/wpa_supplicant-mesh.config b/package/network/services/hostapd/files/wpa_supplicant-mesh.config
new file mode 100644
index 0000000..36e2908
--- /dev/null
+++ b/package/network/services/hostapd/files/wpa_supplicant-mesh.config
@@ -0,0 +1,407 @@
+# Example wpa_supplicant build time configuration
+#
+# This file lists the configuration options that are used when building the
+# hostapd binary. All lines starting with # are ignored. Configuration option
+# lines must be commented out complete, if they are not to be included, i.e.,
+# just setting VARIABLE=n is not disabling that variable.
+#
+# This file is included in Makefile, so variables like CFLAGS and LIBS can also
+# be modified from here. In most cases, these lines should use += in order not
+# to override previous values of the variables.
+
+
+# Uncomment following two lines and fix the paths if you have installed OpenSSL
+# or GnuTLS in non-default location
+#CFLAGS += -I/usr/local/openssl/include
+#LIBS += -L/usr/local/openssl/lib
+
+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
+# the kerberos files are not in the default include path. Following line can be
+# used to fix build issues on such systems (krb5.h not found).
+#CFLAGS += -I/usr/include/kerberos
+
+# Example configuration for various cross-compilation platforms
+
+#### sveasoft (e.g., for Linksys WRT54G) ######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS += -I../src/include -I../../src/router/openssl/include
+#LIBS += -L/opt/brcm/hndtools-mipsel-uclibc-0.9.19/lib -lssl
+###############################################################################
+
+#### openwrt (e.g., for Linksys WRT54G) #######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS=-I../src/include -I../openssl-0.9.7d/include \
+# -I../WRT54GS/release/src/include
+#LIBS = -lssl
+###############################################################################
+
+
+# Driver interface for Host AP driver
+CONFIG_DRIVER_HOSTAP=y
+
+# Driver interface for Agere driver
+#CONFIG_DRIVER_HERMES=y
+# Change include directories to match with the local setup
+#CFLAGS += -I../../hcf -I../../include -I../../include/hcf
+#CFLAGS += -I../../include/wireless
+
+# Driver interface for ndiswrapper
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_NDISWRAPPER=y
+
+# Driver interface for Atmel driver
+# CONFIG_DRIVER_ATMEL=y
+
+# Driver interface for old Broadcom driver
+# Please note that the newer Broadcom driver ("hybrid Linux driver") supports
+# Linux wireless extensions and does not need (or even work) with the old
+# driver wrapper. Use CONFIG_DRIVER_WEXT=y with that driver.
+#CONFIG_DRIVER_BROADCOM=y
+# Example path for wlioctl.h; change to match your configuration
+#CFLAGS += -I/opt/WRT54GS/release/src/include
+
+# Driver interface for Intel ipw2100/2200 driver
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_IPW=y
+
+# Driver interface for Ralink driver
+#CONFIG_DRIVER_RALINK=y
+
+# Driver interface for generic Linux wireless extensions
+CONFIG_DRIVER_WEXT=y
+
+# Driver interface for Linux drivers using the nl80211 kernel interface
+CONFIG_DRIVER_NL80211=y
+
+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
+#CONFIG_DRIVER_BSD=y
+#CFLAGS += -I/usr/local/include
+#LIBS += -L/usr/local/lib
+#LIBS_p += -L/usr/local/lib
+#LIBS_c += -L/usr/local/lib
+
+# Driver interface for Windows NDIS
+#CONFIG_DRIVER_NDIS=y
+#CFLAGS += -I/usr/include/w32api/ddk
+#LIBS += -L/usr/local/lib
+# For native build using mingw
+#CONFIG_NATIVE_WINDOWS=y
+# Additional directories for cross-compilation on Linux host for mingw target
+#CFLAGS += -I/opt/mingw/mingw32/include/ddk
+#LIBS += -L/opt/mingw/mingw32/lib
+#CC=mingw32-gcc
+# By default, driver_ndis uses WinPcap for low-level operations. This can be
+# replaced with the following option which replaces WinPcap calls with NDISUIO.
+# However, this requires that WZC is disabled (net stop wzcsvc) before starting
+# wpa_supplicant.
+# CONFIG_USE_NDISUIO=y
+
+# Driver interface for development testing
+#CONFIG_DRIVER_TEST=y
+
+# Include client MLME (management frame processing) for test driver
+# This can be used to test MLME operations in hostapd with the test interface.
+# space.
+#CONFIG_CLIENT_MLME=y
+
+# Driver interface for wired Ethernet drivers
+CONFIG_DRIVER_WIRED=y
+
+# Driver interface for the Broadcom RoboSwitch family
+#CONFIG_DRIVER_ROBOSWITCH=y
+
+# Driver interface for no driver (e.g., WPS ER only)
+#CONFIG_DRIVER_NONE=y
+
+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is
+# included)
+CONFIG_IEEE8021X_EAPOL=y
+
+# EAP-MD5
+CONFIG_EAP_MD5=y
+
+# EAP-MSCHAPv2
+CONFIG_EAP_MSCHAPV2=y
+
+# EAP-TLS
+CONFIG_EAP_TLS=y
+
+# EAL-PEAP
+CONFIG_EAP_PEAP=y
+
+# EAP-TTLS
+CONFIG_EAP_TTLS=y
+
+# EAP-FAST
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.8d-tls-extensions.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
+# EAP-GTC
+CONFIG_EAP_GTC=y
+
+# EAP-OTP
+CONFIG_EAP_OTP=y
+
+# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
+#CONFIG_EAP_SIM=y
+
+# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-PAX
+#CONFIG_EAP_PAX=y
+
+# LEAP
+CONFIG_EAP_LEAP=y
+
+# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
+#CONFIG_EAP_AKA=y
+
+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
+# Enable USIM simulator (Milenage) for EAP-AKA
+#CONFIG_USIM_SIMULATOR=y
+
+# EAP-SAKE
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-TNC and related Trusted Network Connect support (experimental)
+#CONFIG_EAP_TNC=y
+
+# Wi-Fi Protected Setup (WPS)
+CONFIG_WPS=y
+
+# EAP-IKEv2
+#CONFIG_EAP_IKEV2=y
+
+# PKCS#12 (PFX) support (used to read private key and certificate file from
+# a file that usually has extension .p12 or .pfx)
+CONFIG_PKCS12=y
+
+# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
+# engine.
+CONFIG_SMARTCARD=y
+
+# PC/SC interface for smartcards (USIM, GSM SIM)
+# Enable this if EAP-SIM or EAP-AKA is included
+#CONFIG_PCSC=y
+
+# Development testing
+#CONFIG_EAPOL_TEST=y
+
+# Select control interface backend for external programs, e.g, wpa_cli:
+# unix = UNIX domain sockets (default for Linux/*BSD)
+# udp = UDP sockets using localhost (127.0.0.1)
+# named_pipe = Windows Named Pipe (default for Windows)
+# y = use default (backwards compatibility)
+# If this option is commented out, control interface is not included in the
+# build.
+CONFIG_CTRL_IFACE=y
+
+# Include support for GNU Readline and History Libraries in wpa_cli.
+# When building a wpa_cli binary for distribution, please note that these
+# libraries are licensed under GPL and as such, BSD license may not apply for
+# the resulting binary.
+#CONFIG_READLINE=y
+
+# Remove debugging code that is printing out debug message to stdout.
+# This can be used to reduce the size of the wpa_supplicant considerably
+# if debugging code is not needed. The size reduction can be around 35%
+# (e.g., 90 kB).
+#CONFIG_NO_STDOUT_DEBUG=y
+
+# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
+# 35-50 kB in code size.
+#CONFIG_NO_WPA=y
+
+# Remove WPA2 support. This allows WPA to be used, but removes WPA2 code to
+# save about 1 kB in code size when building only WPA-Personal (no EAP support)
+# or 6 kB if building for WPA-Enterprise.
+#CONFIG_NO_WPA2=y
+
+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
+# This option can be used to reduce code size by removing support for
+# converting ASCII passphrases into PSK. If this functionality is removed, the
+# PSK can only be configured as the 64-octet hexstring (e.g., from
+# wpa_passphrase). This saves about 0.5 kB in code size.
+#CONFIG_NO_WPA_PASSPHRASE=y
+
+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
+# This can be used if ap_scan=1 mode is never enabled.
+#CONFIG_NO_SCAN_PROCESSING=y
+
+# Select configuration backend:
+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
+# path is given on command line, not here; this option is just used to
+# select the backend that allows configuration files to be used)
+# winreg = Windows registry (see win_example.reg for an example)
+CONFIG_BACKEND=file
+
+# Remove configuration write functionality (i.e., to allow the configuration
+# file to be updated based on runtime configuration changes). The runtime
+# configuration can still be changed, the changes are just not going to be
+# persistent over restarts. This option can be used to reduce code size by
+# about 3.5 kB.
+#CONFIG_NO_CONFIG_WRITE=y
+
+# Remove support for configuration blobs to reduce code size by about 1.5 kB.
+#CONFIG_NO_CONFIG_BLOBS=y
+
+# Select program entry point implementation:
+# main = UNIX/POSIX like main() function (default)
+# main_winsvc = Windows service (read parameters from registry)
+# main_none = Very basic example (development use only)
+#CONFIG_MAIN=main
+
+# Select wrapper for operatins system and C library specific functions
+# unix = UNIX/POSIX like systems (default)
+# win32 = Windows systems
+# none = Empty template
+#CONFIG_OS=unix
+
+# Select event loop implementation
+# eloop = select() loop (default)
+# eloop_win = Windows events and WaitForMultipleObject() loop
+# eloop_none = Empty template
+#CONFIG_ELOOP=eloop
+
+# Select layer 2 packet implementation
+# linux = Linux packet socket (default)
+# pcap = libpcap/libdnet/WinPcap
+# freebsd = FreeBSD libpcap
+# winpcap = WinPcap with receive thread
+# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
+# none = Empty template
+#CONFIG_L2_PACKET=linux
+
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+CONFIG_IEEE80211W=y
+
+# Select TLS implementation
+# openssl = OpenSSL (default)
+# gnutls = GnuTLS (needed for TLS/IA, see also CONFIG_GNUTLS_EXTRA)
+# internal = Internal TLSv1 implementation (experimental)
+# none = Empty template
+CONFIG_TLS=internal
+
+# Whether to enable TLS/IA support, which is required for EAP-TTLSv1.
+# You need CONFIG_TLS=gnutls for this to have any effect. Please note that
+# even though the core GnuTLS library is released under LGPL, this extra
+# library uses GPL and as such, the terms of GPL apply to the combination
+# of wpa_supplicant and GnuTLS if this option is enabled. BSD license may not
+# apply for distribution of the resulting binary.
+#CONFIG_GNUTLS_EXTRA=y
+
+# If CONFIG_TLS=internal is used, additional library and include paths are
+# needed for LibTomMath. Alternatively, an integrated, minimal version of
+# LibTomMath can be used. See beginning of libtommath.c for details on benefits
+# and drawbacks of this option.
+CONFIG_INTERNAL_LIBTOMMATH=y
+#ifndef CONFIG_INTERNAL_LIBTOMMATH
+#LTM_PATH=/usr/src/libtommath-0.39
+#CFLAGS += -I$(LTM_PATH)
+#LIBS += -L$(LTM_PATH)
+#LIBS_p += -L$(LTM_PATH)
+#endif
+# At the cost of about 4 kB of additional binary size, the internal LibTomMath
+# can be configured to include faster routines for exptmod, sqr, and div to
+# speed up DH and RSA calculation considerably
+CONFIG_INTERNAL_LIBTOMMATH_FAST=y
+
+# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
+# This is only for Windows builds and requires WMI-related header files and
+# WbemUuid.Lib from Platform SDK even when building with MinGW.
+#CONFIG_NDIS_EVENTS_INTEGRATED=y
+#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
+
+# Add support for old DBus control interface
+# (fi.epitest.hostap.WPASupplicant)
+#CONFIG_CTRL_IFACE_DBUS=y
+
+# Add support for new DBus control interface
+# (fi.w1.hostap.wpa_supplicant1)
+#CONFIG_CTRL_IFACE_DBUS_NEW=y
+
+# Add introspection support for new DBus control interface
+#CONFIG_CTRL_IFACE_DBUS_INTRO=y
+
+# Add support for loading EAP methods dynamically as shared libraries.
+# When this option is enabled, each EAP method can be either included
+# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
+# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
+# be loaded in the beginning of the wpa_supplicant configuration file
+# (see load_dynamic_eap parameter in the example file) before being used in
+# the network blocks.
+#
+# Note that some shared parts of EAP methods are included in the main program
+# and in order to be able to use dynamic EAP methods using these parts, the
+# main program must have been build with the EAP method enabled (=y or =dyn).
+# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
+# unless at least one of them was included in the main build to force inclusion
+# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
+# in the main build to be able to load these methods dynamically.
+#
+# Please also note that using dynamic libraries will increase the total binary
+# size. Thus, it may not be the best option for targets that have limited
+# amount of memory/flash.
+#CONFIG_DYNAMIC_EAP_METHODS=y
+
+# IEEE Std 802.11r-2008 (Fast BSS Transition)
+#CONFIG_IEEE80211R=y
+
+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
+#CONFIG_DEBUG_FILE=y
+
+# Enable privilege separation (see README 'Privilege separation' for details)
+#CONFIG_PRIVSEP=y
+
+# Enable mitigation against certain attacks against TKIP by delaying Michael
+# MIC error reports by a random amount of time between 0 and 60 seconds
+#CONFIG_DELAYED_MIC_ERROR_REPORT=y
+
+# Enable tracing code for developer debugging
+# This tracks use of memory allocations and other registrations and reports
+# incorrect use with a backtrace of call (or allocation) location.
+#CONFIG_WPA_TRACE=y
+# For BSD, comment out these.
+#LIBS += -lexecinfo
+#LIBS_p += -lexecinfo
+#LIBS_c += -lexecinfo
+
+# Use libbfd to get more details for developer debugging
+# This enables use of libbfd to get more detailed symbols for the backtraces
+# generated by CONFIG_WPA_TRACE=y.
+#CONFIG_WPA_TRACE_BFD=y
+# For BSD, comment out these.
+#LIBS += -lbfd -liberty -lz
+#LIBS_p += -lbfd -liberty -lz
+#LIBS_c += -lbfd -liberty -lz
+
+CONFIG_NO_RANDOM_POOL=y
+NEED_80211_COMMON=y
+
+CONFIG_IBSS_RSN=y
+
+CONFIG_MESH=y
+CONFIG_SAE=y
+CONFIG_AP=y
diff --git a/package/network/services/hostapd/files/wpa_supplicant-mini.config b/package/network/services/hostapd/files/wpa_supplicant-mini.config
new file mode 100644
index 0000000..a8d334d
--- /dev/null
+++ b/package/network/services/hostapd/files/wpa_supplicant-mini.config
@@ -0,0 +1,401 @@
+# Example wpa_supplicant build time configuration
+#
+# This file lists the configuration options that are used when building the
+# hostapd binary. All lines starting with # are ignored. Configuration option
+# lines must be commented out complete, if they are not to be included, i.e.,
+# just setting VARIABLE=n is not disabling that variable.
+#
+# This file is included in Makefile, so variables like CFLAGS and LIBS can also
+# be modified from here. In most cases, these lines should use += in order not
+# to override previous values of the variables.
+
+
+# Uncomment following two lines and fix the paths if you have installed OpenSSL
+# or GnuTLS in non-default location
+#CFLAGS += -I/usr/local/openssl/include
+#LIBS += -L/usr/local/openssl/lib
+
+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
+# the kerberos files are not in the default include path. Following line can be
+# used to fix build issues on such systems (krb5.h not found).
+#CFLAGS += -I/usr/include/kerberos
+
+# Example configuration for various cross-compilation platforms
+
+#### sveasoft (e.g., for Linksys WRT54G) ######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS += -I../src/include -I../../src/router/openssl/include
+#LIBS += -L/opt/brcm/hndtools-mipsel-uclibc-0.9.19/lib -lssl
+###############################################################################
+
+#### openwrt (e.g., for Linksys WRT54G) #######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS=-I../src/include -I../openssl-0.9.7d/include \
+# -I../WRT54GS/release/src/include
+#LIBS = -lssl
+###############################################################################
+
+
+# Driver interface for Host AP driver
+CONFIG_DRIVER_HOSTAP=y
+
+# Driver interface for Agere driver
+#CONFIG_DRIVER_HERMES=y
+# Change include directories to match with the local setup
+#CFLAGS += -I../../hcf -I../../include -I../../include/hcf
+#CFLAGS += -I../../include/wireless
+
+# Driver interface for ndiswrapper
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_NDISWRAPPER=y
+
+# Driver interface for Atmel driver
+# CONFIG_DRIVER_ATMEL=y
+
+# Driver interface for old Broadcom driver
+# Please note that the newer Broadcom driver ("hybrid Linux driver") supports
+# Linux wireless extensions and does not need (or even work) with the old
+# driver wrapper. Use CONFIG_DRIVER_WEXT=y with that driver.
+#CONFIG_DRIVER_BROADCOM=y
+# Example path for wlioctl.h; change to match your configuration
+#CFLAGS += -I/opt/WRT54GS/release/src/include
+
+# Driver interface for Intel ipw2100/2200 driver
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_IPW=y
+
+# Driver interface for Ralink driver
+#CONFIG_DRIVER_RALINK=y
+
+# Driver interface for generic Linux wireless extensions
+CONFIG_DRIVER_WEXT=y
+
+# Driver interface for Linux drivers using the nl80211 kernel interface
+CONFIG_DRIVER_NL80211=y
+
+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
+#CONFIG_DRIVER_BSD=y
+#CFLAGS += -I/usr/local/include
+#LIBS += -L/usr/local/lib
+#LIBS_p += -L/usr/local/lib
+#LIBS_c += -L/usr/local/lib
+
+# Driver interface for Windows NDIS
+#CONFIG_DRIVER_NDIS=y
+#CFLAGS += -I/usr/include/w32api/ddk
+#LIBS += -L/usr/local/lib
+# For native build using mingw
+#CONFIG_NATIVE_WINDOWS=y
+# Additional directories for cross-compilation on Linux host for mingw target
+#CFLAGS += -I/opt/mingw/mingw32/include/ddk
+#LIBS += -L/opt/mingw/mingw32/lib
+#CC=mingw32-gcc
+# By default, driver_ndis uses WinPcap for low-level operations. This can be
+# replaced with the following option which replaces WinPcap calls with NDISUIO.
+# However, this requires that WZC is disabled (net stop wzcsvc) before starting
+# wpa_supplicant.
+# CONFIG_USE_NDISUIO=y
+
+# Driver interface for development testing
+#CONFIG_DRIVER_TEST=y
+
+# Include client MLME (management frame processing) for test driver
+# This can be used to test MLME operations in hostapd with the test interface.
+# space.
+#CONFIG_CLIENT_MLME=y
+
+# Driver interface for wired Ethernet drivers
+CONFIG_DRIVER_WIRED=y
+
+# Driver interface for the Broadcom RoboSwitch family
+#CONFIG_DRIVER_ROBOSWITCH=y
+
+# Driver interface for no driver (e.g., WPS ER only)
+#CONFIG_DRIVER_NONE=y
+
+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is
+# included)
+# CONFIG_IEEE8021X_EAPOL=y
+
+# EAP-MD5
+# CONFIG_EAP_MD5=y
+
+# EAP-MSCHAPv2
+# CONFIG_EAP_MSCHAPV2=y
+
+# EAP-TLS
+# CONFIG_EAP_TLS=y
+
+# EAL-PEAP
+# CONFIG_EAP_PEAP=y
+
+# EAP-TTLS
+# CONFIG_EAP_TTLS=y
+
+# EAP-FAST
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.8d-tls-extensions.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
+# EAP-GTC
+# CONFIG_EAP_GTC=y
+
+# EAP-OTP
+# CONFIG_EAP_OTP=y
+
+# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
+#CONFIG_EAP_SIM=y
+
+# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-PAX
+#CONFIG_EAP_PAX=y
+
+# LEAP
+# CONFIG_EAP_LEAP=y
+
+# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
+#CONFIG_EAP_AKA=y
+
+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
+# Enable USIM simulator (Milenage) for EAP-AKA
+#CONFIG_USIM_SIMULATOR=y
+
+# EAP-SAKE
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-TNC and related Trusted Network Connect support (experimental)
+#CONFIG_EAP_TNC=y
+
+# Wi-Fi Protected Setup (WPS)
+#CONFIG_WPS=y
+
+# EAP-IKEv2
+#CONFIG_EAP_IKEV2=y
+
+# PKCS#12 (PFX) support (used to read private key and certificate file from
+# a file that usually has extension .p12 or .pfx)
+# CONFIG_PKCS12=y
+
+# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
+# engine.
+# CONFIG_SMARTCARD=y
+
+# PC/SC interface for smartcards (USIM, GSM SIM)
+# Enable this if EAP-SIM or EAP-AKA is included
+#CONFIG_PCSC=y
+
+# Development testing
+#CONFIG_EAPOL_TEST=y
+
+# Select control interface backend for external programs, e.g, wpa_cli:
+# unix = UNIX domain sockets (default for Linux/*BSD)
+# udp = UDP sockets using localhost (127.0.0.1)
+# named_pipe = Windows Named Pipe (default for Windows)
+# y = use default (backwards compatibility)
+# If this option is commented out, control interface is not included in the
+# build.
+CONFIG_CTRL_IFACE=y
+
+# Include support for GNU Readline and History Libraries in wpa_cli.
+# When building a wpa_cli binary for distribution, please note that these
+# libraries are licensed under GPL and as such, BSD license may not apply for
+# the resulting binary.
+#CONFIG_READLINE=y
+
+# Remove debugging code that is printing out debug message to stdout.
+# This can be used to reduce the size of the wpa_supplicant considerably
+# if debugging code is not needed. The size reduction can be around 35%
+# (e.g., 90 kB).
+#CONFIG_NO_STDOUT_DEBUG=y
+
+# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
+# 35-50 kB in code size.
+#CONFIG_NO_WPA=y
+
+# Remove WPA2 support. This allows WPA to be used, but removes WPA2 code to
+# save about 1 kB in code size when building only WPA-Personal (no EAP support)
+# or 6 kB if building for WPA-Enterprise.
+#CONFIG_NO_WPA2=y
+
+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
+# This option can be used to reduce code size by removing support for
+# converting ASCII passphrases into PSK. If this functionality is removed, the
+# PSK can only be configured as the 64-octet hexstring (e.g., from
+# wpa_passphrase). This saves about 0.5 kB in code size.
+#CONFIG_NO_WPA_PASSPHRASE=y
+
+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
+# This can be used if ap_scan=1 mode is never enabled.
+#CONFIG_NO_SCAN_PROCESSING=y
+
+# Select configuration backend:
+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
+# path is given on command line, not here; this option is just used to
+# select the backend that allows configuration files to be used)
+# winreg = Windows registry (see win_example.reg for an example)
+CONFIG_BACKEND=file
+
+# Remove configuration write functionality (i.e., to allow the configuration
+# file to be updated based on runtime configuration changes). The runtime
+# configuration can still be changed, the changes are just not going to be
+# persistent over restarts. This option can be used to reduce code size by
+# about 3.5 kB.
+#CONFIG_NO_CONFIG_WRITE=y
+
+# Remove support for configuration blobs to reduce code size by about 1.5 kB.
+#CONFIG_NO_CONFIG_BLOBS=y
+
+# Select program entry point implementation:
+# main = UNIX/POSIX like main() function (default)
+# main_winsvc = Windows service (read parameters from registry)
+# main_none = Very basic example (development use only)
+#CONFIG_MAIN=main
+
+# Select wrapper for operatins system and C library specific functions
+# unix = UNIX/POSIX like systems (default)
+# win32 = Windows systems
+# none = Empty template
+#CONFIG_OS=unix
+
+# Select event loop implementation
+# eloop = select() loop (default)
+# eloop_win = Windows events and WaitForMultipleObject() loop
+# eloop_none = Empty template
+#CONFIG_ELOOP=eloop
+
+# Select layer 2 packet implementation
+# linux = Linux packet socket (default)
+# pcap = libpcap/libdnet/WinPcap
+# freebsd = FreeBSD libpcap
+# winpcap = WinPcap with receive thread
+# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
+# none = Empty template
+#CONFIG_L2_PACKET=linux
+
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+# CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Select TLS implementation
+# openssl = OpenSSL (default)
+# gnutls = GnuTLS (needed for TLS/IA, see also CONFIG_GNUTLS_EXTRA)
+# internal = Internal TLSv1 implementation (experimental)
+# none = Empty template
+CONFIG_TLS=internal
+
+# Whether to enable TLS/IA support, which is required for EAP-TTLSv1.
+# You need CONFIG_TLS=gnutls for this to have any effect. Please note that
+# even though the core GnuTLS library is released under LGPL, this extra
+# library uses GPL and as such, the terms of GPL apply to the combination
+# of wpa_supplicant and GnuTLS if this option is enabled. BSD license may not
+# apply for distribution of the resulting binary.
+#CONFIG_GNUTLS_EXTRA=y
+
+# If CONFIG_TLS=internal is used, additional library and include paths are
+# needed for LibTomMath. Alternatively, an integrated, minimal version of
+# LibTomMath can be used. See beginning of libtommath.c for details on benefits
+# and drawbacks of this option.
+#CONFIG_INTERNAL_LIBTOMMATH=y
+#ifndef CONFIG_INTERNAL_LIBTOMMATH
+#LTM_PATH=/usr/src/libtommath-0.39
+#CFLAGS += -I$(LTM_PATH)
+#LIBS += -L$(LTM_PATH)
+#LIBS_p += -L$(LTM_PATH)
+#endif
+# At the cost of about 4 kB of additional binary size, the internal LibTomMath
+# can be configured to include faster routines for exptmod, sqr, and div to
+# speed up DH and RSA calculation considerably
+#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
+
+# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
+# This is only for Windows builds and requires WMI-related header files and
+# WbemUuid.Lib from Platform SDK even when building with MinGW.
+#CONFIG_NDIS_EVENTS_INTEGRATED=y
+#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
+
+# Add support for old DBus control interface
+# (fi.epitest.hostap.WPASupplicant)
+#CONFIG_CTRL_IFACE_DBUS=y
+
+# Add support for new DBus control interface
+# (fi.w1.hostap.wpa_supplicant1)
+#CONFIG_CTRL_IFACE_DBUS_NEW=y
+
+# Add introspection support for new DBus control interface
+#CONFIG_CTRL_IFACE_DBUS_INTRO=y
+
+# Add support for loading EAP methods dynamically as shared libraries.
+# When this option is enabled, each EAP method can be either included
+# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
+# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
+# be loaded in the beginning of the wpa_supplicant configuration file
+# (see load_dynamic_eap parameter in the example file) before being used in
+# the network blocks.
+#
+# Note that some shared parts of EAP methods are included in the main program
+# and in order to be able to use dynamic EAP methods using these parts, the
+# main program must have been build with the EAP method enabled (=y or =dyn).
+# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
+# unless at least one of them was included in the main build to force inclusion
+# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
+# in the main build to be able to load these methods dynamically.
+#
+# Please also note that using dynamic libraries will increase the total binary
+# size. Thus, it may not be the best option for targets that have limited
+# amount of memory/flash.
+#CONFIG_DYNAMIC_EAP_METHODS=y
+
+# IEEE Std 802.11r-2008 (Fast BSS Transition)
+#CONFIG_IEEE80211R=y
+
+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
+#CONFIG_DEBUG_FILE=y
+
+# Enable privilege separation (see README 'Privilege separation' for details)
+#CONFIG_PRIVSEP=y
+
+# Enable mitigation against certain attacks against TKIP by delaying Michael
+# MIC error reports by a random amount of time between 0 and 60 seconds
+#CONFIG_DELAYED_MIC_ERROR_REPORT=y
+
+# Enable tracing code for developer debugging
+# This tracks use of memory allocations and other registrations and reports
+# incorrect use with a backtrace of call (or allocation) location.
+#CONFIG_WPA_TRACE=y
+# For BSD, comment out these.
+#LIBS += -lexecinfo
+#LIBS_p += -lexecinfo
+#LIBS_c += -lexecinfo
+
+# Use libbfd to get more details for developer debugging
+# This enables use of libbfd to get more detailed symbols for the backtraces
+# generated by CONFIG_WPA_TRACE=y.
+#CONFIG_WPA_TRACE_BFD=y
+# For BSD, comment out these.
+#LIBS += -lbfd -liberty -lz
+#LIBS_p += -lbfd -liberty -lz
+#LIBS_c += -lbfd -liberty -lz
+
+CONFIG_NO_RANDOM_POOL=y
+NEED_80211_COMMON=y
diff --git a/package/network/services/hostapd/files/wpa_supplicant-p2p.config b/package/network/services/hostapd/files/wpa_supplicant-p2p.config
new file mode 100644
index 0000000..1c307d0
--- /dev/null
+++ b/package/network/services/hostapd/files/wpa_supplicant-p2p.config
@@ -0,0 +1,406 @@
+# Example wpa_supplicant build time configuration
+#
+# This file lists the configuration options that are used when building the
+# hostapd binary. All lines starting with # are ignored. Configuration option
+# lines must be commented out complete, if they are not to be included, i.e.,
+# just setting VARIABLE=n is not disabling that variable.
+#
+# This file is included in Makefile, so variables like CFLAGS and LIBS can also
+# be modified from here. In most cases, these lines should use += in order not
+# to override previous values of the variables.
+
+
+# Uncomment following two lines and fix the paths if you have installed OpenSSL
+# or GnuTLS in non-default location
+#CFLAGS += -I/usr/local/openssl/include
+#LIBS += -L/usr/local/openssl/lib
+
+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
+# the kerberos files are not in the default include path. Following line can be
+# used to fix build issues on such systems (krb5.h not found).
+#CFLAGS += -I/usr/include/kerberos
+
+# Example configuration for various cross-compilation platforms
+
+#### sveasoft (e.g., for Linksys WRT54G) ######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS += -I../src/include -I../../src/router/openssl/include
+#LIBS += -L/opt/brcm/hndtools-mipsel-uclibc-0.9.19/lib -lssl
+###############################################################################
+
+#### openwrt (e.g., for Linksys WRT54G) #######################################
+#CC=mipsel-uclibc-gcc
+#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc
+#CFLAGS += -Os
+#CPPFLAGS=-I../src/include -I../openssl-0.9.7d/include \
+# -I../WRT54GS/release/src/include
+#LIBS = -lssl
+###############################################################################
+
+
+# Driver interface for Host AP driver
+CONFIG_DRIVER_HOSTAP=y
+
+# Driver interface for Agere driver
+#CONFIG_DRIVER_HERMES=y
+# Change include directories to match with the local setup
+#CFLAGS += -I../../hcf -I../../include -I../../include/hcf
+#CFLAGS += -I../../include/wireless
+
+# Driver interface for ndiswrapper
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_NDISWRAPPER=y
+
+# Driver interface for Atmel driver
+# CONFIG_DRIVER_ATMEL=y
+
+# Driver interface for old Broadcom driver
+# Please note that the newer Broadcom driver ("hybrid Linux driver") supports
+# Linux wireless extensions and does not need (or even work) with the old
+# driver wrapper. Use CONFIG_DRIVER_WEXT=y with that driver.
+#CONFIG_DRIVER_BROADCOM=y
+# Example path for wlioctl.h; change to match your configuration
+#CFLAGS += -I/opt/WRT54GS/release/src/include
+
+# Driver interface for Intel ipw2100/2200 driver
+# Deprecated; use CONFIG_DRIVER_WEXT=y instead.
+#CONFIG_DRIVER_IPW=y
+
+# Driver interface for Ralink driver
+#CONFIG_DRIVER_RALINK=y
+
+# Driver interface for generic Linux wireless extensions
+CONFIG_DRIVER_WEXT=y
+
+# Driver interface for Linux drivers using the nl80211 kernel interface
+CONFIG_DRIVER_NL80211=y
+
+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
+#CONFIG_DRIVER_BSD=y
+#CFLAGS += -I/usr/local/include
+#LIBS += -L/usr/local/lib
+#LIBS_p += -L/usr/local/lib
+#LIBS_c += -L/usr/local/lib
+
+# Driver interface for Windows NDIS
+#CONFIG_DRIVER_NDIS=y
+#CFLAGS += -I/usr/include/w32api/ddk
+#LIBS += -L/usr/local/lib
+# For native build using mingw
+#CONFIG_NATIVE_WINDOWS=y
+# Additional directories for cross-compilation on Linux host for mingw target
+#CFLAGS += -I/opt/mingw/mingw32/include/ddk
+#LIBS += -L/opt/mingw/mingw32/lib
+#CC=mingw32-gcc
+# By default, driver_ndis uses WinPcap for low-level operations. This can be
+# replaced with the following option which replaces WinPcap calls with NDISUIO.
+# However, this requires that WZC is disabled (net stop wzcsvc) before starting
+# wpa_supplicant.
+# CONFIG_USE_NDISUIO=y
+
+# Driver interface for development testing
+#CONFIG_DRIVER_TEST=y
+
+# Include client MLME (management frame processing) for test driver
+# This can be used to test MLME operations in hostapd with the test interface.
+# space.
+#CONFIG_CLIENT_MLME=y
+
+# Driver interface for wired Ethernet drivers
+CONFIG_DRIVER_WIRED=y
+
+# Driver interface for the Broadcom RoboSwitch family
+#CONFIG_DRIVER_ROBOSWITCH=y
+
+# Driver interface for no driver (e.g., WPS ER only)
+#CONFIG_DRIVER_NONE=y
+
+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is
+# included)
+CONFIG_IEEE8021X_EAPOL=y
+
+# EAP-MD5
+CONFIG_EAP_MD5=y
+
+# EAP-MSCHAPv2
+CONFIG_EAP_MSCHAPV2=y
+
+# EAP-TLS
+CONFIG_EAP_TLS=y
+
+# EAL-PEAP
+CONFIG_EAP_PEAP=y
+
+# EAP-TTLS
+CONFIG_EAP_TTLS=y
+
+# EAP-FAST
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.8d-tls-extensions.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
+# EAP-GTC
+CONFIG_EAP_GTC=y
+
+# EAP-OTP
+CONFIG_EAP_OTP=y
+
+# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
+#CONFIG_EAP_SIM=y
+
+# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-PAX
+#CONFIG_EAP_PAX=y
+
+# LEAP
+CONFIG_EAP_LEAP=y
+
+# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
+#CONFIG_EAP_AKA=y
+
+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
+# Enable USIM simulator (Milenage) for EAP-AKA
+#CONFIG_USIM_SIMULATOR=y
+
+# EAP-SAKE
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-TNC and related Trusted Network Connect support (experimental)
+#CONFIG_EAP_TNC=y
+
+# Wi-Fi Protected Setup (WPS)
+CONFIG_WPS=y
+
+# EAP-IKEv2
+#CONFIG_EAP_IKEV2=y
+
+# PKCS#12 (PFX) support (used to read private key and certificate file from
+# a file that usually has extension .p12 or .pfx)
+CONFIG_PKCS12=y
+
+# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
+# engine.
+CONFIG_SMARTCARD=y
+
+# PC/SC interface for smartcards (USIM, GSM SIM)
+# Enable this if EAP-SIM or EAP-AKA is included
+#CONFIG_PCSC=y
+
+# Development testing
+#CONFIG_EAPOL_TEST=y
+
+# Select control interface backend for external programs, e.g, wpa_cli:
+# unix = UNIX domain sockets (default for Linux/*BSD)
+# udp = UDP sockets using localhost (127.0.0.1)
+# named_pipe = Windows Named Pipe (default for Windows)
+# y = use default (backwards compatibility)
+# If this option is commented out, control interface is not included in the
+# build.
+CONFIG_CTRL_IFACE=y
+
+# Include support for GNU Readline and History Libraries in wpa_cli.
+# When building a wpa_cli binary for distribution, please note that these
+# libraries are licensed under GPL and as such, BSD license may not apply for
+# the resulting binary.
+#CONFIG_READLINE=y
+
+# Remove debugging code that is printing out debug message to stdout.
+# This can be used to reduce the size of the wpa_supplicant considerably
+# if debugging code is not needed. The size reduction can be around 35%
+# (e.g., 90 kB).
+#CONFIG_NO_STDOUT_DEBUG=y
+
+# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
+# 35-50 kB in code size.
+#CONFIG_NO_WPA=y
+
+# Remove WPA2 support. This allows WPA to be used, but removes WPA2 code to
+# save about 1 kB in code size when building only WPA-Personal (no EAP support)
+# or 6 kB if building for WPA-Enterprise.
+#CONFIG_NO_WPA2=y
+
+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
+# This option can be used to reduce code size by removing support for
+# converting ASCII passphrases into PSK. If this functionality is removed, the
+# PSK can only be configured as the 64-octet hexstring (e.g., from
+# wpa_passphrase). This saves about 0.5 kB in code size.
+#CONFIG_NO_WPA_PASSPHRASE=y
+
+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
+# This can be used if ap_scan=1 mode is never enabled.
+#CONFIG_NO_SCAN_PROCESSING=y
+
+# Select configuration backend:
+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
+# path is given on command line, not here; this option is just used to
+# select the backend that allows configuration files to be used)
+# winreg = Windows registry (see win_example.reg for an example)
+CONFIG_BACKEND=file
+
+# Remove configuration write functionality (i.e., to allow the configuration
+# file to be updated based on runtime configuration changes). The runtime
+# configuration can still be changed, the changes are just not going to be
+# persistent over restarts. This option can be used to reduce code size by
+# about 3.5 kB.
+#CONFIG_NO_CONFIG_WRITE=y
+
+# Remove support for configuration blobs to reduce code size by about 1.5 kB.
+#CONFIG_NO_CONFIG_BLOBS=y
+
+# Select program entry point implementation:
+# main = UNIX/POSIX like main() function (default)
+# main_winsvc = Windows service (read parameters from registry)
+# main_none = Very basic example (development use only)
+#CONFIG_MAIN=main
+
+# Select wrapper for operatins system and C library specific functions
+# unix = UNIX/POSIX like systems (default)
+# win32 = Windows systems
+# none = Empty template
+#CONFIG_OS=unix
+
+# Select event loop implementation
+# eloop = select() loop (default)
+# eloop_win = Windows events and WaitForMultipleObject() loop
+# eloop_none = Empty template
+#CONFIG_ELOOP=eloop
+
+# Select layer 2 packet implementation
+# linux = Linux packet socket (default)
+# pcap = libpcap/libdnet/WinPcap
+# freebsd = FreeBSD libpcap
+# winpcap = WinPcap with receive thread
+# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
+# none = Empty template
+#CONFIG_L2_PACKET=linux
+
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+CONFIG_IEEE80211W=y
+
+# Select TLS implementation
+# openssl = OpenSSL (default)
+# gnutls = GnuTLS (needed for TLS/IA, see also CONFIG_GNUTLS_EXTRA)
+# internal = Internal TLSv1 implementation (experimental)
+# none = Empty template
+CONFIG_TLS=internal
+
+# Whether to enable TLS/IA support, which is required for EAP-TTLSv1.
+# You need CONFIG_TLS=gnutls for this to have any effect. Please note that
+# even though the core GnuTLS library is released under LGPL, this extra
+# library uses GPL and as such, the terms of GPL apply to the combination
+# of wpa_supplicant and GnuTLS if this option is enabled. BSD license may not
+# apply for distribution of the resulting binary.
+#CONFIG_GNUTLS_EXTRA=y
+
+# If CONFIG_TLS=internal is used, additional library and include paths are
+# needed for LibTomMath. Alternatively, an integrated, minimal version of
+# LibTomMath can be used. See beginning of libtommath.c for details on benefits
+# and drawbacks of this option.
+CONFIG_INTERNAL_LIBTOMMATH=y
+#ifndef CONFIG_INTERNAL_LIBTOMMATH
+#LTM_PATH=/usr/src/libtommath-0.39
+#CFLAGS += -I$(LTM_PATH)
+#LIBS += -L$(LTM_PATH)
+#LIBS_p += -L$(LTM_PATH)
+#endif
+# At the cost of about 4 kB of additional binary size, the internal LibTomMath
+# can be configured to include faster routines for exptmod, sqr, and div to
+# speed up DH and RSA calculation considerably
+CONFIG_INTERNAL_LIBTOMMATH_FAST=y
+
+# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
+# This is only for Windows builds and requires WMI-related header files and
+# WbemUuid.Lib from Platform SDK even when building with MinGW.
+#CONFIG_NDIS_EVENTS_INTEGRATED=y
+#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
+
+# Add support for old DBus control interface
+# (fi.epitest.hostap.WPASupplicant)
+#CONFIG_CTRL_IFACE_DBUS=y
+
+# Add support for new DBus control interface
+# (fi.w1.hostap.wpa_supplicant1)
+#CONFIG_CTRL_IFACE_DBUS_NEW=y
+
+# Add introspection support for new DBus control interface
+#CONFIG_CTRL_IFACE_DBUS_INTRO=y
+
+# Add support for loading EAP methods dynamically as shared libraries.
+# When this option is enabled, each EAP method can be either included
+# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
+# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
+# be loaded in the beginning of the wpa_supplicant configuration file
+# (see load_dynamic_eap parameter in the example file) before being used in
+# the network blocks.
+#
+# Note that some shared parts of EAP methods are included in the main program
+# and in order to be able to use dynamic EAP methods using these parts, the
+# main program must have been build with the EAP method enabled (=y or =dyn).
+# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
+# unless at least one of them was included in the main build to force inclusion
+# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
+# in the main build to be able to load these methods dynamically.
+#
+# Please also note that using dynamic libraries will increase the total binary
+# size. Thus, it may not be the best option for targets that have limited
+# amount of memory/flash.
+#CONFIG_DYNAMIC_EAP_METHODS=y
+
+# IEEE Std 802.11r-2008 (Fast BSS Transition)
+#CONFIG_IEEE80211R=y
+
+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
+#CONFIG_DEBUG_FILE=y
+
+# Enable privilege separation (see README 'Privilege separation' for details)
+#CONFIG_PRIVSEP=y
+
+# Enable mitigation against certain attacks against TKIP by delaying Michael
+# MIC error reports by a random amount of time between 0 and 60 seconds
+#CONFIG_DELAYED_MIC_ERROR_REPORT=y
+
+# Enable tracing code for developer debugging
+# This tracks use of memory allocations and other registrations and reports
+# incorrect use with a backtrace of call (or allocation) location.
+#CONFIG_WPA_TRACE=y
+# For BSD, comment out these.
+#LIBS += -lexecinfo
+#LIBS_p += -lexecinfo
+#LIBS_c += -lexecinfo
+
+# Use libbfd to get more details for developer debugging
+# This enables use of libbfd to get more detailed symbols for the backtraces
+# generated by CONFIG_WPA_TRACE=y.
+#CONFIG_WPA_TRACE_BFD=y
+# For BSD, comment out these.
+#LIBS += -lbfd -liberty -lz
+#LIBS_p += -lbfd -liberty -lz
+#LIBS_c += -lbfd -liberty -lz
+
+CONFIG_NO_RANDOM_POOL=y
+NEED_80211_COMMON=y
+
+CONFIG_IBSS_RSN=y
+
+CONFIG_P2P=y
+CONFIG_AP=y
diff --git a/package/network/services/hostapd/files/wpa_supplicant.sh b/package/network/services/hostapd/files/wpa_supplicant.sh
new file mode 100644
index 0000000..b678484
--- /dev/null
+++ b/package/network/services/hostapd/files/wpa_supplicant.sh
@@ -0,0 +1,194 @@
+wpa_supplicant_setup_vif() {
+ local vif="$1"
+ local driver="$2"
+ local key="$key"
+ local options="$3"
+ local freq=""
+ local ht="$5"
+ local ap_scan=""
+ local scan_ssid="1"
+ [ -n "$4" ] && freq="frequency=$4"
+
+ config_get enc "$vif" encryption
+ config_get key "$vif" key
+
+ local net_cfg bridge
+ config_get bridge "$vif" bridge
+ [ -z "$bridge" ] && {
+ net_cfg="$(find_net_config "$vif")"
+ [ -z "$net_cfg" ] || bridge="$(bridge_interface "$net_cfg")"
+ config_set "$vif" bridge "$bridge"
+ }
+
+ local mode ifname wds modestr=""
+ config_get mode "$vif" mode
+ config_get ifname "$vif" ifname
+ config_get_bool wds "$vif" wds 0
+ [ -z "$bridge" ] || [ "$mode" = ap ] || [ "$mode" = sta -a $wds -eq 1 ] || {
+ echo "wpa_supplicant_setup_vif($ifname): Refusing to bridge $mode mode interface"
+ return 1
+ }
+ [ "$mode" = "adhoc" ] && {
+ modestr="mode=1"
+ scan_ssid="0"
+ ap_scan="ap_scan=2"
+ }
+
+ key_mgmt='NONE'
+ case "$enc" in
+ *none*) ;;
+ *wep*)
+ config_get key "$vif" key
+ key="${key:-1}"
+ case "$key" in
+ [1234])
+ for idx in 1 2 3 4; do
+ local zidx
+ zidx=$(($idx - 1))
+ config_get ckey "$vif" "key${idx}"
+ [ -n "$ckey" ] && \
+ append "wep_key${zidx}" "wep_key${zidx}=$(prepare_key_wep "$ckey")"
+ done
+ wep_tx_keyidx="wep_tx_keyidx=$((key - 1))"
+ ;;
+ *)
+ wep_key0="wep_key0=$(prepare_key_wep "$key")"
+ wep_tx_keyidx="wep_tx_keyidx=0"
+ ;;
+ esac
+ ;;
+ *psk*)
+ key_mgmt='WPA-PSK'
+ # if you want to use PSK with a non-nl80211 driver you
+ # have to use WPA-NONE and wext driver for wpa_s
+ [ "$mode" = "adhoc" -a "$driver" != "nl80211" ] && {
+ key_mgmt='WPA-NONE'
+ driver='wext'
+ }
+ if [ ${#key} -eq 64 ]; then
+ passphrase="psk=${key}"
+ else
+ passphrase="psk=\"${key}\""
+ fi
+ case "$enc" in
+ *psk2*)
+ proto='proto=RSN'
+ config_get ieee80211w "$vif" ieee80211w
+ ;;
+ *psk*)
+ proto='proto=WPA'
+ ;;
+ esac
+ ;;
+ *wpa*|*8021x*)
+ proto='proto=WPA2'
+ key_mgmt='WPA-EAP'
+ config_get ieee80211w "$vif" ieee80211w
+ config_get ca_cert "$vif" ca_cert
+ config_get eap_type "$vif" eap_type
+ ca_cert=${ca_cert:+"ca_cert=\"$ca_cert\""}
+ case "$eap_type" in
+ tls)
+ pairwise='pairwise=CCMP'
+ group='group=CCMP'
+ config_get identity "$vif" identity
+ config_get client_cert "$vif" client_cert
+ config_get priv_key "$vif" priv_key
+ config_get priv_key_pwd "$vif" priv_key_pwd
+ identity="identity=\"$identity\""
+ client_cert="client_cert=\"$client_cert\""
+ priv_key="private_key=\"$priv_key\""
+ priv_key_pwd="private_key_passwd=\"$priv_key_pwd\""
+ ;;
+ peap|ttls)
+ config_get auth "$vif" auth
+ config_get identity "$vif" identity
+ config_get password "$vif" password
+ phase2="phase2=\"auth=${auth:-MSCHAPV2}\""
+ identity="identity=\"$identity\""
+ password="${password:+password=\"$password\"}"
+ ;;
+ esac
+ eap_type="eap=$(echo $eap_type | tr 'a-z' 'A-Z')"
+ ;;
+ esac
+
+ case "$ieee80211w" in
+ [012])
+ ieee80211w="ieee80211w=$ieee80211w"
+ ;;
+ esac
+
+ local fixed_freq bssid1 beacon_int brates mrate
+ config_get ifname "$vif" ifname
+ config_get bridge "$vif" bridge
+ config_get ssid "$vif" ssid
+ config_get bssid "$vif" bssid
+ bssid1=${bssid:+"bssid=$bssid"}
+ beacon_int=${beacon_int:+"beacon_int=$beacon_int"}
+
+ local br brval brsub brstr
+ [ -n "$basic_rate_list" ] && {
+ for br in $basic_rate_list; do
+ brval="$(($br / 1000))"
+ brsub="$((($br / 100) % 10))"
+ [ "$brsub" -gt 0 ] && brval="$brval.$brsub"
+ [ -n "$brstr" ] && brstr="$brstr,"
+ brstr="$brstr$brval"
+ done
+ brates=${basic_rate_list:+"rates=$brstr"}
+ }
+
+ local mcval=""
+ [ -n "$mcast_rate" ] && {
+ mcval="$(($mcast_rate / 1000))"
+ mcsub="$(( ($mcast_rate / 100) % 10 ))"
+ [ "$mcsub" -gt 0 ] && mcval="$mcval.$mcsub"
+ mrate=${mcast_rate:+"mcast_rate=$mcval"}
+ }
+
+ local ht_str
+ [ -n "$ht" ] && ht_str="htmode=$ht"
+
+ rm -rf /var/run/wpa_supplicant-$ifname
+ cat > /var/run/wpa_supplicant-$ifname.conf <<EOF
+ctrl_interface=/var/run/wpa_supplicant-$ifname
+$ap_scan
+network={
+ $modestr
+ scan_ssid=$scan_ssid
+ ssid="$ssid"
+ $bssid1
+ key_mgmt=$key_mgmt
+ $proto
+ $freq
+ ${fixed:+"fixed_freq=1"}
+ $beacon_int
+ $brates
+ $mrate
+ $ht_str
+ $ieee80211w
+ $passphrase
+ $pairwise
+ $group
+ $eap_type
+ $ca_cert
+ $client_cert
+ $priv_key
+ $priv_key_pwd
+ $phase2
+ $identity
+ $password
+ $wep_key0
+ $wep_key1
+ $wep_key2
+ $wep_key3
+ $wep_tx_keyidx
+}
+EOF
+ if [ -n "$proto" -o "$key_mgmt" = "NONE" ]; then
+ wpa_supplicant ${bridge:+ -b $bridge} -B -P "/var/run/wifi-${ifname}.pid" -D ${driver:-wext} -i "$ifname" -c /var/run/wpa_supplicant-$ifname.conf $options
+ else
+ return 0
+ fi
+}
diff --git a/package/network/services/hostapd/files/wps-hotplug.sh b/package/network/services/hostapd/files/wps-hotplug.sh
new file mode 100644
index 0000000..24af80e
--- /dev/null
+++ b/package/network/services/hostapd/files/wps-hotplug.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then
+ cd /var/run/hostapd
+ for socket in *; do
+ [ -S "$socket" ] || continue
+ hostapd_cli -i "$socket" wps_pbc
+ done
+fi
+
+return 0
diff --git a/package/network/services/hostapd/patches/001-P2P-Validate-SSID-element-length-before-copying-it-C.patch b/package/network/services/hostapd/patches/001-P2P-Validate-SSID-element-length-before-copying-it-C.patch
new file mode 100644
index 0000000..e408fbe
--- /dev/null
+++ b/package/network/services/hostapd/patches/001-P2P-Validate-SSID-element-length-before-copying-it-C.patch
@@ -0,0 +1,37 @@
+From 9ed4eee345f85e3025c33c6e20aa25696e341ccd Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@qca.qualcomm.com>
+Date: Tue, 7 Apr 2015 11:32:11 +0300
+Subject: [PATCH] P2P: Validate SSID element length before copying it
+ (CVE-2015-1863)
+
+This fixes a possible memcpy overflow for P2P dev->oper_ssid in
+p2p_add_device(). The length provided by the peer device (0..255 bytes)
+was used without proper bounds checking and that could have resulted in
+arbitrary data of up to 223 bytes being written beyond the end of the
+dev->oper_ssid[] array (of which about 150 bytes would be beyond the
+heap allocation) when processing a corrupted management frame for P2P
+peer discovery purposes.
+
+This could result in corrupted state in heap, unexpected program
+behavior due to corrupted P2P peer device information, denial of service
+due to process crash, exposure of memory contents during GO Negotiation,
+and potentially arbitrary code execution.
+
+Thanks to Google security team for reporting this issue and smart
+hardware research group of Alibaba security team for discovering it.
+
+Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
+---
+ src/p2p/p2p.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/src/p2p/p2p.c
++++ b/src/p2p/p2p.c
+@@ -778,6 +778,7 @@ int p2p_add_device(struct p2p_data *p2p,
+ if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0)
+ os_memcpy(dev->interface_addr, addr, ETH_ALEN);
+ if (msg.ssid &&
++ msg.ssid[1] <= sizeof(dev->oper_ssid) &&
+ (msg.ssid[1] != P2P_WILDCARD_SSID_LEN ||
+ os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN)
+ != 0)) {
diff --git a/package/network/services/hostapd/patches/002-AP-WMM-Fix-integer-underflow-in-WMM-Action-frame-par.patch b/package/network/services/hostapd/patches/002-AP-WMM-Fix-integer-underflow-in-WMM-Action-frame-par.patch
new file mode 100644
index 0000000..bc4d60f
--- /dev/null
+++ b/package/network/services/hostapd/patches/002-AP-WMM-Fix-integer-underflow-in-WMM-Action-frame-par.patch
@@ -0,0 +1,36 @@
+From ef566a4d4f74022e1fdb0a2addfe81e6de9f4aae Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Wed, 29 Apr 2015 02:21:53 +0300
+Subject: [PATCH] AP WMM: Fix integer underflow in WMM Action frame parser
+
+The length of the WMM Action frame was not properly validated and the
+length of the information elements (int left) could end up being
+negative. This would result in reading significantly past the stack
+buffer while parsing the IEs in ieee802_11_parse_elems() and while doing
+so, resulting in segmentation fault.
+
+This can result in an invalid frame being used for a denial of service
+attack (hostapd process killed) against an AP with a driver that uses
+hostapd for management frame processing (e.g., all mac80211-based
+drivers).
+
+Thanks to Kostya Kortchinsky of Google security team for discovering and
+reporting this issue.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ src/ap/wmm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/src/ap/wmm.c
++++ b/src/ap/wmm.c
+@@ -274,6 +274,9 @@ void hostapd_wmm_action(struct hostapd_d
+ return;
+ }
+
++ if (left < 0)
++ return; /* not a valid WMM Action frame */
++
+ /* extract the tspec info element */
+ if (ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
+ hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
diff --git a/package/network/services/hostapd/patches/110-bool_fix.patch b/package/network/services/hostapd/patches/110-bool_fix.patch
new file mode 100644
index 0000000..865c014
--- /dev/null
+++ b/package/network/services/hostapd/patches/110-bool_fix.patch
@@ -0,0 +1,14 @@
+--- a/src/ap/ieee802_1x.c
++++ b/src/ap/ieee802_1x.c
+@@ -2332,9 +2332,9 @@ void ieee802_1x_notify_pre_auth(struct e
+ }
+
+
+-static const char * bool_txt(Boolean bool)
++static const char * bool_txt(Boolean bool_val)
+ {
+- return bool ? "TRUE" : "FALSE";
++ return bool_val ? "TRUE" : "FALSE";
+ }
+
+
diff --git a/package/network/services/hostapd/patches/120-daemonize_fix.patch b/package/network/services/hostapd/patches/120-daemonize_fix.patch
new file mode 100644
index 0000000..032e207
--- /dev/null
+++ b/package/network/services/hostapd/patches/120-daemonize_fix.patch
@@ -0,0 +1,97 @@
+--- a/src/utils/os_unix.c
++++ b/src/utils/os_unix.c
+@@ -10,6 +10,7 @@
+
+ #include <time.h>
+ #include <sys/wait.h>
++#include <fcntl.h>
+
+ #ifdef ANDROID
+ #include <sys/capability.h>
+@@ -155,59 +156,46 @@ int os_gmtime(os_time_t t, struct os_tm
+ return 0;
+ }
+
+-
+-#ifdef __APPLE__
+-#include <fcntl.h>
+-static int os_daemon(int nochdir, int noclose)
++int os_daemonize(const char *pid_file)
+ {
+- int devnull;
++ int pid = 0, i, devnull;
+
+- if (chdir("/") < 0)
+- return -1;
++#if defined(__uClinux__) || defined(__sun__)
++ return -1;
++#else /* defined(__uClinux__) || defined(__sun__) */
+
+- devnull = open("/dev/null", O_RDWR);
+- if (devnull < 0)
++#ifndef __APPLE__
++ pid = fork();
++ if (pid < 0)
+ return -1;
++#endif
+
+- if (dup2(devnull, STDIN_FILENO) < 0) {
+- close(devnull);
+- return -1;
++ if (pid > 0) {
++ if (pid_file) {
++ FILE *f = fopen(pid_file, "w");
++ if (f) {
++ fprintf(f, "%u\n", pid);
++ fclose(f);
++ }
++ }
++ _exit(0);
+ }
+
+- if (dup2(devnull, STDOUT_FILENO) < 0) {
+- close(devnull);
++ if (setsid() < 0)
+ return -1;
+- }
+
+- if (dup2(devnull, STDERR_FILENO) < 0) {
+- close(devnull);
++ if (chdir("/") < 0)
+ return -1;
+- }
+-
+- return 0;
+-}
+-#else /* __APPLE__ */
+-#define os_daemon daemon
+-#endif /* __APPLE__ */
+
+-
+-int os_daemonize(const char *pid_file)
+-{
+-#if defined(__uClinux__) || defined(__sun__)
+- return -1;
+-#else /* defined(__uClinux__) || defined(__sun__) */
+- if (os_daemon(0, 0)) {
+- perror("daemon");
++ devnull = open("/dev/null", O_RDWR);
++ if (devnull < 0)
+ return -1;
+- }
+
+- if (pid_file) {
+- FILE *f = fopen(pid_file, "w");
+- if (f) {
+- fprintf(f, "%u\n", getpid());
+- fclose(f);
+- }
+- }
++ for (i = 0; i <= STDERR_FILENO; i++)
++ dup2(devnull, i);
++
++ if (devnull > 2)
++ close(devnull);
+
+ return -0;
+ #endif /* defined(__uClinux__) || defined(__sun__) */
diff --git a/package/network/services/hostapd/patches/130-no_eapol_fix.patch b/package/network/services/hostapd/patches/130-no_eapol_fix.patch
new file mode 100644
index 0000000..d23b47b
--- /dev/null
+++ b/package/network/services/hostapd/patches/130-no_eapol_fix.patch
@@ -0,0 +1,14 @@
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -252,9 +252,10 @@ void wpa_supplicant_cancel_auth_timeout(
+ */
+ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
+ {
++ struct wpa_ssid *ssid = wpa_s->current_ssid;
++
+ #ifdef IEEE8021X_EAPOL
+ struct eapol_config eapol_conf;
+- struct wpa_ssid *ssid = wpa_s->current_ssid;
+
+ #ifdef CONFIG_IBSS_RSN
+ if (ssid->mode == WPAS_MODE_IBSS &&
diff --git a/package/network/services/hostapd/patches/140-disable_bridge_packet_workaround.patch b/package/network/services/hostapd/patches/140-disable_bridge_packet_workaround.patch
new file mode 100644
index 0000000..6337d8d
--- /dev/null
+++ b/package/network/services/hostapd/patches/140-disable_bridge_packet_workaround.patch
@@ -0,0 +1,12 @@
+--- a/src/l2_packet/l2_packet_linux.c
++++ b/src/l2_packet/l2_packet_linux.c
+@@ -307,8 +307,7 @@ struct l2_packet_data * l2_packet_init_b
+
+ l2 = l2_packet_init(br_ifname, own_addr, protocol, rx_callback,
+ rx_callback_ctx, l2_hdr);
+- if (!l2)
+- return NULL;
++ return l2;
+
+ /*
+ * The Linux packet socket behavior has changed over the years and there
diff --git a/package/network/services/hostapd/patches/200-multicall.patch b/package/network/services/hostapd/patches/200-multicall.patch
new file mode 100644
index 0000000..de4a3a8
--- /dev/null
+++ b/package/network/services/hostapd/patches/200-multicall.patch
@@ -0,0 +1,276 @@
+--- a/hostapd/Makefile
++++ b/hostapd/Makefile
+@@ -17,6 +17,7 @@ export BINDIR ?= /usr/local/bin/
+ # CFLAGS += -DUSE_KERNEL_HEADERS -I/usr/src/linux/include
+
+ -include .config
++-include $(if $(MULTICALL), ../wpa_supplicant/.config)
+
+ ifdef CONFIG_TESTING_OPTIONS
+ CFLAGS += -DCONFIG_TESTING_OPTIONS
+@@ -242,10 +243,14 @@ ifdef CONFIG_IEEE80211AC
+ CFLAGS += -DCONFIG_IEEE80211AC
+ endif
+
++ifndef MULTICALL
++CFLAGS += -DNO_SUPPLICANT
++endif
++
+ include ../src/drivers/drivers.mak
+-OBJS += $(DRV_AP_OBJS)
+-CFLAGS += $(DRV_AP_CFLAGS)
+-LDFLAGS += $(DRV_AP_LDFLAGS)
++OBJS += $(sort $(DRV_AP_OBJS) $(if $(MULTICALL),$(DRV_WPA_OBJS)))
++CFLAGS += $(DRV_AP_CFLAGS) $(if $(MULTICALL),$(DRV_WPA_CFLAGS))
++LDFLAGS += $(DRV_AP_LDFLAGS) $(if $(MULTICALL),$(DRV_WPA_LDFLAGS))
+ LIBS += $(DRV_AP_LIBS)
+
+ ifdef CONFIG_L2_PACKET
+@@ -941,6 +946,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
+
+ BCHECK=../src/drivers/build.hostapd
+
++hostapd_multi.a: $(BCHECK) $(OBJS)
++ $(Q)$(CC) -c -o hostapd_multi.o -Dmain=hostapd_main $(CFLAGS) main.c
++ @$(E) " CC " $<
++ @rm -f $@
++ @$(AR) cr $@ hostapd_multi.o $(OBJS)
++
+ hostapd: $(BCHECK) $(OBJS)
+ $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
+ @$(E) " LD " $@
+@@ -980,6 +991,12 @@ HOBJS += ../src/crypto/aes-internal.o
+ HOBJS += ../src/crypto/aes-internal-enc.o
+ endif
+
++dump_cflags:
++ @echo -n $(CFLAGS) " "
++
++dump_ldflags:
++ @echo -n $(LDFLAGS) $(LIBS) $(EXTRALIBS) " "
++
+ nt_password_hash: $(NOBJS)
+ $(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n)
+ @$(E) " LD " $@
+--- a/wpa_supplicant/Makefile
++++ b/wpa_supplicant/Makefile
+@@ -15,6 +15,7 @@ CFLAGS += -I$(abspath ../src)
+ CFLAGS += -I$(abspath ../src/utils)
+
+ -include .config
++-include $(if $(MULTICALL),../hostapd/.config)
+
+ ifdef CONFIG_TESTING_OPTIONS
+ CFLAGS += -DCONFIG_TESTING_OPTIONS
+@@ -773,6 +774,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
+ CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
+ LIBS += -ldl -rdynamic
+ endif
++else
++ ifdef MULTICALL
++ OBJS += ../src/eap_common/eap_common.o
++ endif
+ endif
+
+ ifdef CONFIG_MACSEC
+@@ -793,9 +798,11 @@ NEED_EAP_COMMON=y
+ NEED_RSN_AUTHENTICATOR=y
+ CFLAGS += -DCONFIG_AP
+ OBJS += ap.o
++ifndef MULTICALL
+ CFLAGS += -DCONFIG_NO_RADIUS
+ CFLAGS += -DCONFIG_NO_ACCOUNTING
+ CFLAGS += -DCONFIG_NO_VLAN
++endif
+ OBJS += ../src/ap/hostapd.o
+ OBJS += ../src/ap/wpa_auth_glue.o
+ OBJS += ../src/ap/utils.o
+@@ -858,10 +865,18 @@ endif
+ ifdef CONFIG_HS20
+ OBJS += ../src/ap/hs20.o
+ endif
++else
++ ifdef MULTICALL
++ OBJS += ../src/eap_server/eap_server.o
++ OBJS += ../src/eap_server/eap_server_identity.o
++ OBJS += ../src/eap_server/eap_server_methods.o
++ endif
+ endif
+
+ ifdef NEED_RSN_AUTHENTICATOR
++ifndef MULTICALL
+ CFLAGS += -DCONFIG_NO_RADIUS
++endif
+ NEED_AES_WRAP=y
+ OBJS += ../src/ap/wpa_auth.o
+ OBJS += ../src/ap/wpa_auth_ie.o
+@@ -1603,6 +1618,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
+
+ $(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config
+
++wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs)
++ $(Q)$(CC) -c -o wpa_supplicant_multi.o -Dmain=wpa_supplicant_main $(CFLAGS) main.c
++ @$(E) " CC " $<
++ @rm -f $@
++ @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS)
++
+ wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
+ $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
+ @$(E) " LD " $@
+@@ -1694,6 +1715,12 @@ endif
+ $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
+ @$(E) " sed" $<
+
++dump_cflags:
++ @echo -n $(CFLAGS) " "
++
++dump_ldflags:
++ @echo -n $(LDFLAGS) $(LIBS) $(EXTRALIBS) " "
++
+ wpa_supplicant.exe: wpa_supplicant
+ mv -f $< $@
+ wpa_cli.exe: wpa_cli
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -4581,8 +4581,8 @@ union wpa_event_data {
+ * Driver wrapper code should call this function whenever an event is received
+ * from the driver.
+ */
+-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
+- union wpa_event_data *data);
++extern void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event,
++ union wpa_event_data *data);
+
+
+ /*
+--- a/src/ap/drv_callbacks.c
++++ b/src/ap/drv_callbacks.c
+@@ -1075,8 +1075,8 @@ static void hostapd_event_dfs_cac_starte
+ #endif /* NEED_AP_MLME */
+
+
+-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
+- union wpa_event_data *data)
++void hostapd_wpa_event(void *ctx, enum wpa_event_type event,
++ union wpa_event_data *data)
+ {
+ struct hostapd_data *hapd = ctx;
+ #ifndef CONFIG_NO_STDOUT_DEBUG
+--- a/wpa_supplicant/wpa_priv.c
++++ b/wpa_supplicant/wpa_priv.c
+@@ -819,8 +819,8 @@ static void wpa_priv_send_ft_response(st
+ }
+
+
+-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
+- union wpa_event_data *data)
++static void supplicant_event(void *ctx, enum wpa_event_type event,
++ union wpa_event_data *data)
+ {
+ struct wpa_priv_interface *iface = ctx;
+
+@@ -961,6 +961,7 @@ int main(int argc, char *argv[])
+ if (os_program_init())
+ return -1;
+
++ wpa_supplicant_event = supplicant_event;
+ wpa_priv_fd_workaround();
+
+ for (;;) {
+--- a/wpa_supplicant/events.c
++++ b/wpa_supplicant/events.c
+@@ -3138,8 +3138,8 @@ static void wpa_supplicant_event_assoc_a
+ }
+
+
+-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
+- union wpa_event_data *data)
++void supplicant_event(void *ctx, enum wpa_event_type event,
++ union wpa_event_data *data)
+ {
+ struct wpa_supplicant *wpa_s = ctx;
+
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -4300,6 +4300,9 @@ static void wpa_supplicant_deinit_iface(
+ os_free(wpa_s);
+ }
+
++extern void supplicant_event(void *ctx, enum wpa_event_type event,
++ union wpa_event_data *data);
++
+
+ /**
+ * wpa_supplicant_add_iface - Add a new network interface
+@@ -4526,6 +4529,7 @@ struct wpa_global * wpa_supplicant_init(
+ #ifndef CONFIG_NO_WPA_MSG
+ wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
+ #endif /* CONFIG_NO_WPA_MSG */
++ wpa_supplicant_event = supplicant_event;
+
+ if (params->wpa_debug_file_path)
+ wpa_debug_open_file(params->wpa_debug_file_path);
+--- a/hostapd/main.c
++++ b/hostapd/main.c
+@@ -511,6 +511,9 @@ static int hostapd_get_ctrl_iface_group(
+ return 0;
+ }
+
++void hostapd_wpa_event(void *ctx, enum wpa_event_type event,
++ union wpa_event_data *data);
++
+
+ #ifdef CONFIG_WPS
+ static int gen_uuid(const char *txt_addr)
+@@ -562,6 +565,7 @@ int main(int argc, char *argv[])
+ interfaces.global_iface_name = NULL;
+ interfaces.global_ctrl_sock = -1;
+
++ wpa_supplicant_event = hostapd_wpa_event;
+ for (;;) {
+ c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:");
+ if (c < 0)
+--- a/src/drivers/drivers.c
++++ b/src/drivers/drivers.c
+@@ -10,6 +10,9 @@
+ #include "utils/common.h"
+ #include "driver.h"
+
++void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event,
++ union wpa_event_data *data);
++
+ #ifdef CONFIG_DRIVER_WEXT
+ extern struct wpa_driver_ops wpa_driver_wext_ops; /* driver_wext.c */
+ #endif /* CONFIG_DRIVER_WEXT */
+--- a/wpa_supplicant/eapol_test.c
++++ b/wpa_supplicant/eapol_test.c
+@@ -28,8 +28,12 @@
+ #include "ctrl_iface.h"
+ #include "pcsc_funcs.h"
+ #include "wpas_glue.h"
++#include "drivers/driver.h"
+
+
++void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event,
++ union wpa_event_data *data);
++
+ struct wpa_driver_ops *wpa_drivers[] = { NULL };
+
+
+@@ -1203,6 +1207,8 @@ static void usage(void)
+ "option several times.\n");
+ }
+
++extern void supplicant_event(void *ctx, enum wpa_event_type event,
++ union wpa_event_data *data);
+
+ int main(int argc, char *argv[])
+ {
+@@ -1221,6 +1227,7 @@ int main(int argc, char *argv[])
+ if (os_program_init())
+ return -1;
+
++ wpa_supplicant_event = supplicant_event;
+ hostapd_logger_register_cb(hostapd_logger_cb);
+
+ os_memset(&eapol_test, 0, sizeof(eapol_test));
diff --git a/package/network/services/hostapd/patches/300-noscan.patch b/package/network/services/hostapd/patches/300-noscan.patch
new file mode 100644
index 0000000..57d8fe2
--- /dev/null
+++ b/package/network/services/hostapd/patches/300-noscan.patch
@@ -0,0 +1,57 @@
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -2771,6 +2771,10 @@ static int hostapd_config_fill(struct ho
+ }
+ #endif /* CONFIG_IEEE80211W */
+ #ifdef CONFIG_IEEE80211N
++ } else if (os_strcmp(buf, "noscan") == 0) {
++ conf->noscan = atoi(pos);
++ } else if (os_strcmp(buf, "ht_coex") == 0) {
++ conf->no_ht_coex = !atoi(pos);
+ } else if (os_strcmp(buf, "ieee80211n") == 0) {
+ conf->ieee80211n = atoi(pos);
+ } else if (os_strcmp(buf, "ht_capab") == 0) {
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -619,6 +619,8 @@ struct hostapd_config {
+
+ int ht_op_mode_fixed;
+ u16 ht_capab;
++ int noscan;
++ int no_ht_coex;
+ int ieee80211n;
+ int secondary_channel;
+ int require_ht;
+--- a/src/ap/hw_features.c
++++ b/src/ap/hw_features.c
+@@ -461,7 +461,7 @@ static int ieee80211n_check_40mhz(struct
+ struct wpa_driver_scan_params params;
+ int ret;
+
+- if (!iface->conf->secondary_channel)
++ if (!iface->conf->secondary_channel || iface->conf->noscan)
+ return 0; /* HT40 not used */
+
+ hostapd_set_state(iface, HAPD_IFACE_HT_SCAN);
+--- a/src/ap/ieee802_11_ht.c
++++ b/src/ap/ieee802_11_ht.c
+@@ -221,6 +221,9 @@ void hostapd_2040_coex_action(struct hos
+ if (!(iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
+ return;
+
++ if (iface->conf->noscan || iface->conf->no_ht_coex)
++ return;
++
+ if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie))
+ return;
+
+@@ -346,6 +349,9 @@ void ht40_intolerant_add(struct hostapd_
+ if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
+ return;
+
++ if (iface->conf->noscan || iface->conf->no_ht_coex)
++ return;
++
+ wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR
+ " in Association Request", MAC2STR(sta->addr));
+
diff --git a/package/network/services/hostapd/patches/310-rescan_immediately.patch b/package/network/services/hostapd/patches/310-rescan_immediately.patch
new file mode 100644
index 0000000..7be8c32
--- /dev/null
+++ b/package/network/services/hostapd/patches/310-rescan_immediately.patch
@@ -0,0 +1,11 @@
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -3249,7 +3249,7 @@ wpa_supplicant_alloc(struct wpa_supplica
+ if (wpa_s == NULL)
+ return NULL;
+ wpa_s->scan_req = INITIAL_SCAN_REQ;
+- wpa_s->scan_interval = 5;
++ wpa_s->scan_interval = 1;
+ wpa_s->new_connection = 1;
+ wpa_s->parent = parent ? parent : wpa_s;
+ wpa_s->sched_scanning = 0;
diff --git a/package/network/services/hostapd/patches/320-optional_rfkill.patch b/package/network/services/hostapd/patches/320-optional_rfkill.patch
new file mode 100644
index 0000000..75b4b07
--- /dev/null
+++ b/package/network/services/hostapd/patches/320-optional_rfkill.patch
@@ -0,0 +1,61 @@
+--- a/src/drivers/drivers.mak
++++ b/src/drivers/drivers.mak
+@@ -34,7 +34,6 @@ NEED_SME=y
+ NEED_AP_MLME=y
+ NEED_NETLINK=y
+ NEED_LINUX_IOCTL=y
+-NEED_RFKILL=y
+
+ ifdef CONFIG_LIBNL32
+ DRV_LIBS += -lnl-3
+@@ -116,7 +115,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
+ CONFIG_WIRELESS_EXTENSION=y
+ NEED_NETLINK=y
+ NEED_LINUX_IOCTL=y
+-NEED_RFKILL=y
+ endif
+
+ ifdef CONFIG_DRIVER_NDIS
+@@ -142,7 +140,6 @@ endif
+ ifdef CONFIG_WIRELESS_EXTENSION
+ DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION
+ DRV_WPA_OBJS += ../src/drivers/driver_wext.o
+-NEED_RFKILL=y
+ endif
+
+ ifdef NEED_NETLINK
+@@ -155,6 +152,7 @@ endif
+
+ ifdef NEED_RFKILL
+ DRV_OBJS += ../src/drivers/rfkill.o
++DRV_WPA_CFLAGS += -DCONFIG_RFKILL
+ endif
+
+ ifdef CONFIG_VLAN_NETLINK
+--- a/src/drivers/rfkill.h
++++ b/src/drivers/rfkill.h
+@@ -18,8 +18,24 @@ struct rfkill_config {
+ void (*unblocked_cb)(void *ctx);
+ };
+
++#ifdef CONFIG_RFKILL
+ struct rfkill_data * rfkill_init(struct rfkill_config *cfg);
+ void rfkill_deinit(struct rfkill_data *rfkill);
+ int rfkill_is_blocked(struct rfkill_data *rfkill);
++#else
++static inline struct rfkill_data * rfkill_init(struct rfkill_config *cfg)
++{
++ return (void *) 1;
++}
++
++static inline void rfkill_deinit(struct rfkill_data *rfkill)
++{
++}
++
++static inline int rfkill_is_blocked(struct rfkill_data *rfkill)
++{
++ return 0;
++}
++#endif
+
+ #endif /* RFKILL_H */
diff --git a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch
new file mode 100644
index 0000000..dd90877
--- /dev/null
+++ b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch
@@ -0,0 +1,11 @@
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -3616,7 +3616,7 @@ static int nl80211_set_channel(struct i8
+ freq->freq, freq->ht_enabled, freq->vht_enabled,
+ freq->bandwidth, freq->center_freq1, freq->center_freq2);
+
+- msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
++ msg = nl80211_bss_msg(bss, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
+ NL80211_CMD_SET_WIPHY);
+ if (!msg || nl80211_put_freq_params(msg, freq) < 0) {
+ nlmsg_free(msg);
diff --git a/package/network/services/hostapd/patches/340-reload_freq_change.patch b/package/network/services/hostapd/patches/340-reload_freq_change.patch
new file mode 100644
index 0000000..91b6196
--- /dev/null
+++ b/package/network/services/hostapd/patches/340-reload_freq_change.patch
@@ -0,0 +1,44 @@
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -76,6 +76,16 @@ static void hostapd_reload_bss(struct ho
+ #endif /* CONFIG_NO_RADIUS */
+
+ ssid = &hapd->conf->ssid;
++
++ hostapd_set_freq(hapd, hapd->iconf->hw_mode, hapd->iface->freq,
++ hapd->iconf->channel,
++ hapd->iconf->ieee80211n,
++ hapd->iconf->ieee80211ac,
++ hapd->iconf->secondary_channel,
++ hapd->iconf->vht_oper_chwidth,
++ hapd->iconf->vht_oper_centr_freq_seg0_idx,
++ hapd->iconf->vht_oper_centr_freq_seg1_idx);
++
+ if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
+ ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
+ /*
+@@ -175,21 +185,12 @@ int hostapd_reload_config(struct hostapd
+ oldconf = hapd->iconf;
+ iface->conf = newconf;
+
++ if (iface->conf->channel)
++ iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel);
++
+ for (j = 0; j < iface->num_bss; j++) {
+ hapd = iface->bss[j];
+ hapd->iconf = newconf;
+- hapd->iconf->channel = oldconf->channel;
+- hapd->iconf->acs = oldconf->acs;
+- hapd->iconf->secondary_channel = oldconf->secondary_channel;
+- hapd->iconf->ieee80211n = oldconf->ieee80211n;
+- hapd->iconf->ieee80211ac = oldconf->ieee80211ac;
+- hapd->iconf->ht_capab = oldconf->ht_capab;
+- hapd->iconf->vht_capab = oldconf->vht_capab;
+- hapd->iconf->vht_oper_chwidth = oldconf->vht_oper_chwidth;
+- hapd->iconf->vht_oper_centr_freq_seg0_idx =
+- oldconf->vht_oper_centr_freq_seg0_idx;
+- hapd->iconf->vht_oper_centr_freq_seg1_idx =
+- oldconf->vht_oper_centr_freq_seg1_idx;
+ hapd->conf = newconf->bss[j];
+ hostapd_reload_bss(hapd);
+ }
diff --git a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch
new file mode 100644
index 0000000..a14fa03
--- /dev/null
+++ b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch
@@ -0,0 +1,72 @@
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -2254,13 +2254,18 @@ wpa_driver_nl80211_finish_drv_init(struc
+ }
+
+
+-static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
++static int wpa_driver_nl80211_del_beacon(struct i802_bss *bss)
+ {
++ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+
++ if (!bss->beacon_set)
++ return 0;
++
++ bss->beacon_set = 0;
+ wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
+- drv->ifindex);
+- msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON);
++ bss->ifindex);
++ msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_BEACON);
+ return send_and_recv_msgs(drv, msg, NULL, NULL);
+ }
+
+@@ -2311,7 +2316,7 @@ static void wpa_driver_nl80211_deinit(st
+ nl80211_remove_monitor_interface(drv);
+
+ if (is_ap_interface(drv->nlmode))
+- wpa_driver_nl80211_del_beacon(drv);
++ wpa_driver_nl80211_del_beacon(bss);
+
+ if (drv->eapol_sock >= 0) {
+ eloop_unregister_read_sock(drv->eapol_sock);
+@@ -4140,8 +4145,7 @@ static void nl80211_teardown_ap(struct i
+ nl80211_remove_monitor_interface(drv);
+ else
+ nl80211_mgmt_unsubscribe(bss, "AP teardown");
+-
+- bss->beacon_set = 0;
++ wpa_driver_nl80211_del_beacon(bss);
+ }
+
+
+@@ -6066,8 +6070,6 @@ static int wpa_driver_nl80211_if_remove(
+ } else {
+ wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
+ nl80211_teardown_ap(bss);
+- if (!bss->added_if && !drv->first_bss->next)
+- wpa_driver_nl80211_del_beacon(drv);
+ nl80211_destroy_bss(bss);
+ if (!bss->added_if)
+ i802_set_iface_flags(bss, 0);
+@@ -6389,8 +6391,7 @@ static int wpa_driver_nl80211_deinit_ap(
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ if (!is_ap_interface(drv->nlmode))
+ return -1;
+- wpa_driver_nl80211_del_beacon(drv);
+- bss->beacon_set = 0;
++ wpa_driver_nl80211_del_beacon(bss);
+
+ /*
+ * If the P2P GO interface was dynamically added, then it is
+@@ -6409,8 +6410,7 @@ static int wpa_driver_nl80211_stop_ap(vo
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ if (!is_ap_interface(drv->nlmode))
+ return -1;
+- wpa_driver_nl80211_del_beacon(drv);
+- bss->beacon_set = 0;
++ wpa_driver_nl80211_del_beacon(bss);
+ return 0;
+ }
+
diff --git a/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch b/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch
new file mode 100644
index 0000000..06b005e
--- /dev/null
+++ b/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch
@@ -0,0 +1,104 @@
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -45,6 +45,7 @@
+ #include "wps/wps.h"
+ #include "config_file.h"
+ #include "ctrl_iface.h"
++#include "config_file.h"
+
+
+ struct wpa_ctrl_dst {
+@@ -55,6 +56,7 @@ struct wpa_ctrl_dst {
+ int errors;
+ };
+
++static char *reload_opts = NULL;
+
+ static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
+ const char *buf, size_t len);
+@@ -164,6 +166,61 @@ static int hostapd_ctrl_iface_new_sta(st
+ return 0;
+ }
+
++static char *get_option(char *opt, char *str)
++{
++ int len = strlen(str);
++
++ if (!strncmp(opt, str, len))
++ return opt + len;
++ else
++ return NULL;
++}
++
++static struct hostapd_config *hostapd_ctrl_iface_config_read(const char *fname)
++{
++ struct hostapd_config *conf;
++ char *opt, *val;
++
++ conf = hostapd_config_read(fname);
++ if (!conf)
++ return NULL;
++
++ for (opt = strtok(reload_opts, " ");
++ opt;
++ opt = strtok(NULL, " ")) {
++
++ if ((val = get_option(opt, "channel=")))
++ conf->channel = atoi(val);
++ else if ((val = get_option(opt, "ht_capab=")))
++ conf->ht_capab = atoi(val);
++ else if ((val = get_option(opt, "ht_capab_mask=")))
++ conf->ht_capab &= atoi(val);
++ else if ((val = get_option(opt, "sec_chan=")))
++ conf->secondary_channel = atoi(val);
++ else if ((val = get_option(opt, "hw_mode=")))
++ conf->hw_mode = atoi(val);
++ else if ((val = get_option(opt, "ieee80211n=")))
++ conf->ieee80211n = atoi(val);
++ else
++ break;
++ }
++
++ return conf;
++}
++
++static int hostapd_ctrl_iface_update(struct hostapd_data *hapd, char *txt)
++{
++ struct hostapd_config * (*config_read_cb)(const char *config_fname);
++ struct hostapd_iface *iface = hapd->iface;
++
++ config_read_cb = iface->interfaces->config_read_cb;
++ iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read;
++ reload_opts = txt;
++
++ hostapd_reload_config(iface);
++
++ iface->interfaces->config_read_cb = config_read_cb;
++}
+
+ #ifdef CONFIG_IEEE80211W
+ #ifdef NEED_AP_MLME
+@@ -2086,6 +2143,8 @@ static void hostapd_ctrl_iface_receive(i
+ } else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
+ reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
+ reply_size);
++ } else if (os_strncmp(buf, "UPDATE ", 7) == 0) {
++ hostapd_ctrl_iface_update(hapd, buf + 7);
+ } else if (os_strcmp(buf, "ERP_FLUSH") == 0) {
+ ieee802_1x_erp_flush(hapd);
+ #ifdef RADIUS_SERVER
+--- a/src/ap/ctrl_iface_ap.c
++++ b/src/ap/ctrl_iface_ap.c
+@@ -541,5 +541,11 @@ int hostapd_parse_csa_settings(const cha
+
+ int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd)
+ {
+- return hostapd_drv_stop_ap(hapd);
++ struct hostapd_iface *iface = hapd->iface;
++ int i;
++
++ for (i = 0; i < iface->num_bss; i++)
++ hostapd_drv_stop_ap(iface->bss[i]);
++
++ return 0;
+ }
diff --git a/package/network/services/hostapd/patches/370-ap_sta_support.patch b/package/network/services/hostapd/patches/370-ap_sta_support.patch
new file mode 100644
index 0000000..ea235e6
--- /dev/null
+++ b/package/network/services/hostapd/patches/370-ap_sta_support.patch
@@ -0,0 +1,237 @@
+--- a/wpa_supplicant/wpa_supplicant_i.h
++++ b/wpa_supplicant/wpa_supplicant_i.h
+@@ -110,6 +110,11 @@ struct wpa_interface {
+ const char *ifname;
+
+ /**
++ * hostapd_ctrl - path to hostapd control socket for notification
++ */
++ const char *hostapd_ctrl;
++
++ /**
+ * bridge_ifname - Optional bridge interface name
+ *
+ * If the driver interface (ifname) is included in a Linux bridge
+@@ -442,6 +447,8 @@ struct wpa_supplicant {
+ #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
+ char bridge_ifname[16];
+
++ struct wpa_ctrl *hostapd;
++
+ char *confname;
+ char *confanother;
+
+--- a/wpa_supplicant/Makefile
++++ b/wpa_supplicant/Makefile
+@@ -14,6 +14,10 @@ CFLAGS += $(EXTRA_CFLAGS)
+ CFLAGS += -I$(abspath ../src)
+ CFLAGS += -I$(abspath ../src/utils)
+
++ifdef MULTICALL
++CFLAGS += -DMULTICALL
++endif
++
+ -include .config
+ -include $(if $(MULTICALL),../hostapd/.config)
+
+@@ -84,6 +88,8 @@ OBJS_c += ../src/utils/wpa_debug.o
+ OBJS_c += ../src/utils/common.o
+ OBJS += wmm_ac.o
+
++OBJS += ../src/common/wpa_ctrl.o
++
+ ifndef CONFIG_OS
+ ifdef CONFIG_NATIVE_WINDOWS
+ CONFIG_OS=win32
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -107,6 +107,55 @@ const char *wpa_supplicant_full_license5
+ "\n";
+ #endif /* CONFIG_NO_STDOUT_DEBUG */
+
++static int hostapd_stop(struct wpa_supplicant *wpa_s)
++{
++ const char *cmd = "STOP_AP";
++ char buf[256];
++ size_t len = sizeof(buf);
++
++ if (wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL) < 0) {
++ wpa_printf(MSG_ERROR, "\nFailed to stop hostapd AP interfaces\n");
++ return -1;
++ }
++ return 0;
++}
++
++static int hostapd_reload(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
++{
++ char *cmd = NULL;
++ char buf[256];
++ size_t len = sizeof(buf);
++ enum hostapd_hw_mode hw_mode;
++ u8 channel;
++ int sec_chan = 0;
++ int ret;
++
++ if (!bss)
++ return;
++
++ if (bss->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) {
++ int sec = bss->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
++ if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
++ sec_chan = 1;
++ else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
++ sec_chan = -1;
++ }
++
++ hw_mode = ieee80211_freq_to_chan(bss->freq, &channel);
++ if (asprintf(&cmd, "UPDATE channel=%d sec_chan=%d hw_mode=%d",
++ channel, sec_chan, hw_mode) < 0)
++ return -1;
++
++ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL);
++ free(cmd);
++
++ if (ret < 0) {
++ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n");
++ return -1;
++ }
++ return 0;
++}
++
+ /* Configure default/group WEP keys for static WEP */
+ int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+ {
+@@ -743,8 +792,12 @@ void wpa_supplicant_set_state(struct wpa
+ wpas_p2p_completed(wpa_s);
+
+ sme_sched_obss_scan(wpa_s, 1);
++ if (wpa_s->hostapd)
++ hostapd_reload(wpa_s, wpa_s->current_bss);
+ } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
+ state == WPA_ASSOCIATED) {
++ if (wpa_s->hostapd)
++ hostapd_stop(wpa_s);
+ wpa_s->new_connection = 1;
+ wpa_drv_set_operstate(wpa_s, 0);
+ #ifndef IEEE8021X_EAPOL
+@@ -4038,6 +4091,20 @@ static int wpa_supplicant_init_iface(str
+ sizeof(wpa_s->bridge_ifname));
+ }
+
++ if (iface->hostapd_ctrl) {
++ char *cmd = "STOP_AP";
++ char buf[256];
++ int len = sizeof(buf);
++
++ wpa_s->hostapd = wpa_ctrl_open(iface->hostapd_ctrl);
++ if (!wpa_s->hostapd) {
++ wpa_printf(MSG_ERROR, "\nFailed to connect to hostapd\n");
++ return -1;
++ }
++ if (hostapd_stop(wpa_s) < 0)
++ return -1;
++ }
++
+ /* RSNA Supplicant Key Management - INITIALIZE */
+ eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
+ eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
+@@ -4280,6 +4347,11 @@ static void wpa_supplicant_deinit_iface(
+ if (terminate)
+ wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
+
++ if (wpa_s->hostapd) {
++ wpa_ctrl_close(wpa_s->hostapd);
++ wpa_s->hostapd = NULL;
++ }
++
+ if (wpa_s->ctrl_iface) {
+ wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
+ wpa_s->ctrl_iface = NULL;
+--- a/wpa_supplicant/bss.c
++++ b/wpa_supplicant/bss.c
+@@ -11,6 +11,7 @@
+ #include "utils/common.h"
+ #include "utils/eloop.h"
+ #include "common/ieee802_11_defs.h"
++#include "common/ieee802_11_common.h"
+ #include "drivers/driver.h"
+ #include "wpa_supplicant_i.h"
+ #include "config.h"
+@@ -277,6 +278,10 @@ static void calculate_update_time(const
+ static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src,
+ struct os_reltime *fetch_time)
+ {
++ struct ieee80211_ht_capabilities *capab;
++ struct ieee80211_ht_operation *oper;
++ struct ieee802_11_elems elems;
++
+ dst->flags = src->flags;
+ os_memcpy(dst->bssid, src->bssid, ETH_ALEN);
+ dst->freq = src->freq;
+@@ -289,6 +294,15 @@ static void wpa_bss_copy_res(struct wpa_
+ dst->est_throughput = src->est_throughput;
+ dst->snr = src->snr;
+
++ memset(&elems, 0, sizeof(elems));
++ ieee802_11_parse_elems((u8 *) (src + 1), src->ie_len, &elems, 0);
++ capab = (struct ieee80211_ht_capabilities *) elems.ht_capabilities;
++ oper = (struct ieee80211_ht_operation *) elems.ht_operation;
++ if (capab)
++ dst->ht_capab = le_to_host16(capab->ht_capabilities_info);
++ if (oper)
++ dst->ht_param = oper->ht_param;
++
+ calculate_update_time(fetch_time, src->age, &dst->last_update);
+ }
+
+--- a/wpa_supplicant/main.c
++++ b/wpa_supplicant/main.c
+@@ -33,7 +33,7 @@ static void usage(void)
+ "vW] [-P<pid file>] "
+ "[-g<global ctrl>] \\\n"
+ " [-G<group>] \\\n"
+- " -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
++ " -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-H<hostapd path>] "
+ "[-p<driver_param>] \\\n"
+ " [-b<br_ifname>] [-e<entropy file>]"
+ #ifdef CONFIG_DEBUG_FILE
+@@ -84,6 +84,7 @@ static void usage(void)
+ #endif /* CONFIG_DEBUG_LINUX_TRACING */
+ printf(" -t = include timestamp in debug messages\n"
+ " -h = show this help text\n"
++ " -H = connect to a hostapd instance to manage state changes\n"
+ " -L = show license (BSD)\n"
+ " -o = override driver parameter for new interfaces\n"
+ " -O = override ctrl_interface parameter for new interfaces\n"
+@@ -175,7 +176,7 @@ int main(int argc, char *argv[])
+
+ for (;;) {
+ c = getopt(argc, argv,
+- "b:Bc:C:D:de:f:g:G:hi:I:KLm:No:O:p:P:qsTtuvW");
++ "b:Bc:C:D:de:f:g:G:hH:i:I:KLm:No:O:p:P:qsTtuvW");
+ if (c < 0)
+ break;
+ switch (c) {
+@@ -222,6 +223,9 @@ int main(int argc, char *argv[])
+ usage();
+ exitcode = 0;
+ goto out;
++ case 'H':
++ iface->hostapd_ctrl = optarg;
++ break;
+ case 'i':
+ iface->ifname = optarg;
+ break;
+--- a/wpa_supplicant/bss.h
++++ b/wpa_supplicant/bss.h
+@@ -72,6 +72,10 @@ struct wpa_bss {
+ u8 ssid[32];
+ /** Length of SSID */
+ size_t ssid_len;
++ /** HT caapbilities */
++ u16 ht_capab;
++ /* Five octets of HT Operation Information */
++ u8 ht_param;
+ /** Frequency of the channel in MHz (e.g., 2412 = channel 1) */
+ int freq;
+ /** Beacon interval in TUs (host byte order) */
diff --git a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch
new file mode 100644
index 0000000..3a41b82
--- /dev/null
+++ b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch
@@ -0,0 +1,178 @@
+--- a/hostapd/Makefile
++++ b/hostapd/Makefile
+@@ -168,6 +168,9 @@ endif
+ ifdef CONFIG_NO_CTRL_IFACE
+ CFLAGS += -DCONFIG_NO_CTRL_IFACE
+ else
++ifdef CONFIG_CTRL_IFACE_MIB
++CFLAGS += -DCONFIG_CTRL_IFACE_MIB
++endif
+ OBJS += ctrl_iface.o
+ OBJS += ../src/ap/ctrl_iface_ap.o
+ endif
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -1953,6 +1953,7 @@ static void hostapd_ctrl_iface_receive(i
+ reply_size);
+ } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) {
+ reply_len = hostapd_drv_status(hapd, reply, reply_size);
++#ifdef CONFIG_CTRL_IFACE_MIB
+ } else if (os_strcmp(buf, "MIB") == 0) {
+ reply_len = ieee802_11_get_mib(hapd, reply, reply_size);
+ if (reply_len >= 0) {
+@@ -1994,6 +1995,7 @@ static void hostapd_ctrl_iface_receive(i
+ } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
+ reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply,
+ reply_size);
++#endif
+ } else if (os_strcmp(buf, "ATTACH") == 0) {
+ if (hostapd_ctrl_iface_attach(hapd, &from, fromlen))
+ reply_len = -1;
+--- a/wpa_supplicant/Makefile
++++ b/wpa_supplicant/Makefile
+@@ -837,6 +837,9 @@ ifdef CONFIG_WNM
+ OBJS += ../src/ap/wnm_ap.o
+ endif
+ ifdef CONFIG_CTRL_IFACE
++ifdef CONFIG_CTRL_IFACE_MIB
++CFLAGS += -DCONFIG_CTRL_IFACE_MIB
++endif
+ OBJS += ../src/ap/ctrl_iface_ap.o
+ endif
+
+--- a/wpa_supplicant/ctrl_iface.c
++++ b/wpa_supplicant/ctrl_iface.c
+@@ -1795,7 +1795,7 @@ static int wpa_supplicant_ctrl_iface_sta
+ pos += ret;
+ }
+
+-#ifdef CONFIG_AP
++#if defined(CONFIG_AP) && defined(CONFIG_CTRL_IFACE_MIB)
+ if (wpa_s->ap_iface) {
+ pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
+ end - pos,
+@@ -7896,6 +7896,7 @@ char * wpa_supplicant_ctrl_iface_process
+ reply_len = -1;
+ } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
+ wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
++#ifdef CONFIG_CTRL_IFACE_MIB
+ } else if (os_strcmp(buf, "MIB") == 0) {
+ reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
+ if (reply_len >= 0) {
+@@ -7903,6 +7904,7 @@ char * wpa_supplicant_ctrl_iface_process
+ reply + reply_len,
+ reply_size - reply_len);
+ }
++#endif
+ } else if (os_strncmp(buf, "STATUS", 6) == 0) {
+ reply_len = wpa_supplicant_ctrl_iface_status(
+ wpa_s, buf + 6, reply, reply_size);
+@@ -8353,6 +8355,7 @@ char * wpa_supplicant_ctrl_iface_process
+ reply_len = wpa_supplicant_ctrl_iface_bss(
+ wpa_s, buf + 4, reply, reply_size);
+ #ifdef CONFIG_AP
++#ifdef CONFIG_CTRL_IFACE_MIB
+ } else if (os_strcmp(buf, "STA-FIRST") == 0) {
+ reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
+ } else if (os_strncmp(buf, "STA ", 4) == 0) {
+@@ -8361,12 +8364,15 @@ char * wpa_supplicant_ctrl_iface_process
+ } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
+ reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
+ reply_size);
++#endif
++#ifdef CONFIG_CTRL_IFACE_MIB
+ } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
+ if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15))
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
+ if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13))
+ reply_len = -1;
++#endif
+ } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
+ if (ap_ctrl_iface_chanswitch(wpa_s, buf + 12))
+ reply_len = -1;
+--- a/src/ap/ctrl_iface_ap.c
++++ b/src/ap/ctrl_iface_ap.c
+@@ -22,6 +22,7 @@
+ #include "ctrl_iface_ap.h"
+ #include "ap_drv_ops.h"
+
++#ifdef CONFIG_CTRL_IFACE_MIB
+
+ static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd,
+ struct sta_info *sta,
+@@ -224,6 +225,7 @@ int hostapd_ctrl_iface_sta_next(struct h
+ return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
+ }
+
++#endif
+
+ #ifdef CONFIG_P2P_MANAGER
+ static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
+--- a/src/ap/ieee802_1x.c
++++ b/src/ap/ieee802_1x.c
+@@ -2337,6 +2337,7 @@ static const char * bool_txt(Boolean boo
+ return bool_val ? "TRUE" : "FALSE";
+ }
+
++#ifdef CONFIG_CTRL_IFACE_MIB
+
+ int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
+ {
+@@ -2512,6 +2513,7 @@ int ieee802_1x_get_mib_sta(struct hostap
+ return len;
+ }
+
++#endif
+
+ static void ieee802_1x_finished(struct hostapd_data *hapd,
+ struct sta_info *sta, int success,
+--- a/src/ap/wpa_auth.c
++++ b/src/ap/wpa_auth.c
+@@ -2999,6 +2999,7 @@ static const char * wpa_bool_txt(int boo
+ return bool ? "TRUE" : "FALSE";
+ }
+
++#ifdef CONFIG_CTRL_IFACE_MIB
+
+ #define RSN_SUITE "%02x-%02x-%02x-%d"
+ #define RSN_SUITE_ARG(s) \
+@@ -3143,7 +3144,7 @@ int wpa_get_mib_sta(struct wpa_state_mac
+
+ return len;
+ }
+-
++#endif
+
+ void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth)
+ {
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -2032,6 +2032,8 @@ static u32 wpa_key_mgmt_suite(struct wpa
+ }
+
+
++#ifdef CONFIG_CTRL_IFACE_MIB
++
+ #define RSN_SUITE "%02x-%02x-%02x-%d"
+ #define RSN_SUITE_ARG(s) \
+ ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
+@@ -2115,6 +2117,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch
+
+ return (int) len;
+ }
++#endif
+ #endif /* CONFIG_CTRL_IFACE */
+
+
+--- a/wpa_supplicant/ap.c
++++ b/wpa_supplicant/ap.c
+@@ -1015,7 +1015,7 @@ int wpas_ap_wps_nfc_report_handover(stru
+ #endif /* CONFIG_WPS */
+
+
+-#ifdef CONFIG_CTRL_IFACE
++#if defined(CONFIG_CTRL_IFACE) && defined(CONFIG_CTRL_IFACE_MIB)
+
+ int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
+ char *buf, size_t buflen)
diff --git a/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch
new file mode 100644
index 0000000..1065a7f
--- /dev/null
+++ b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch
@@ -0,0 +1,56 @@
+--- a/src/common/wpa_common.c
++++ b/src/common/wpa_common.c
+@@ -1228,6 +1228,31 @@ u32 wpa_akm_to_suite(int akm)
+ }
+
+
++static void wpa_fixup_wpa_ie_rsn(u8 *assoc_ie, const u8 *wpa_msg_ie,
++ size_t rsn_ie_len)
++{
++ int pos, count;
++
++ pos = sizeof(struct rsn_ie_hdr) + RSN_SELECTOR_LEN;
++ if (rsn_ie_len < pos + 2)
++ return;
++
++ count = WPA_GET_LE16(wpa_msg_ie + pos);
++ pos += 2 + count * RSN_SELECTOR_LEN;
++ if (rsn_ie_len < pos + 2)
++ return;
++
++ count = WPA_GET_LE16(wpa_msg_ie + pos);
++ pos += 2 + count * RSN_SELECTOR_LEN;
++ if (rsn_ie_len < pos + 2)
++ return;
++
++ if (!assoc_ie[pos] && !assoc_ie[pos + 1] &&
++ (wpa_msg_ie[pos] || wpa_msg_ie[pos + 1]))
++ memcpy(&assoc_ie[pos], &wpa_msg_ie[pos], 2);
++}
++
++
+ int wpa_compare_rsn_ie(int ft_initial_assoc,
+ const u8 *ie1, size_t ie1len,
+ const u8 *ie2, size_t ie2len)
+@@ -1235,8 +1260,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
+ if (ie1 == NULL || ie2 == NULL)
+ return -1;
+
+- if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
+- return 0; /* identical IEs */
++ if (ie1len == ie2len) {
++ u8 *ie_tmp;
++
++ if (os_memcmp(ie1, ie2, ie1len) == 0)
++ return 0; /* identical IEs */
++
++ ie_tmp = alloca(ie1len);
++ memcpy(ie_tmp, ie1, ie1len);
++ wpa_fixup_wpa_ie_rsn(ie_tmp, ie2, ie1len);
++
++ if (os_memcmp(ie_tmp, ie2, ie1len) == 0)
++ return 0; /* only mismatch in RSN capabilties */
++ }
+
+ #ifdef CONFIG_IEEE80211R
+ if (ft_initial_assoc) {
diff --git a/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch b/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch
new file mode 100644
index 0000000..083af5b
--- /dev/null
+++ b/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch
@@ -0,0 +1,25 @@
+--- a/src/ap/wps_hostapd.c
++++ b/src/ap/wps_hostapd.c
+@@ -1052,11 +1052,9 @@ int hostapd_init_wps(struct hostapd_data
+
+ if (conf->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP))
+ wps->encr_types |= WPS_ENCR_AES;
+- if (conf->rsn_pairwise & WPA_CIPHER_TKIP)
++ else if (conf->rsn_pairwise & WPA_CIPHER_TKIP)
+ wps->encr_types |= WPS_ENCR_TKIP;
+- }
+-
+- if (conf->wpa & WPA_PROTO_WPA) {
++ } else if (conf->wpa & WPA_PROTO_WPA) {
+ if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK)
+ wps->auth_types |= WPS_AUTH_WPAPSK;
+ if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
+@@ -1064,7 +1062,7 @@ int hostapd_init_wps(struct hostapd_data
+
+ if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
+ wps->encr_types |= WPS_ENCR_AES;
+- if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
++ else if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
+ wps->encr_types |= WPS_ENCR_TKIP;
+ }
+
diff --git a/package/network/services/hostapd/patches/410-limit_debug_messages.patch b/package/network/services/hostapd/patches/410-limit_debug_messages.patch
new file mode 100644
index 0000000..da88732
--- /dev/null
+++ b/package/network/services/hostapd/patches/410-limit_debug_messages.patch
@@ -0,0 +1,214 @@
+--- a/src/utils/wpa_debug.c
++++ b/src/utils/wpa_debug.c
+@@ -201,7 +201,7 @@ void wpa_debug_close_linux_tracing(void)
+ *
+ * Note: New line '\n' is added to the end of the text when printing to stdout.
+ */
+-void wpa_printf(int level, const char *fmt, ...)
++void _wpa_printf(int level, const char *fmt, ...)
+ {
+ va_list ap;
+
+@@ -248,8 +248,8 @@ void wpa_printf(int level, const char *f
+ }
+
+
+-static void _wpa_hexdump(int level, const char *title, const u8 *buf,
+- size_t len, int show)
++void _wpa_hexdump(int level, const char *title, const u8 *buf,
++ size_t len, int show)
+ {
+ size_t i;
+
+@@ -375,20 +375,8 @@ static void _wpa_hexdump(int level, cons
+ #endif /* CONFIG_ANDROID_LOG */
+ }
+
+-void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
+-{
+- _wpa_hexdump(level, title, buf, len, 1);
+-}
+-
+-
+-void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
+-{
+- _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
+-}
+-
+-
+-static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
+- size_t len, int show)
++void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
++ size_t len, int show)
+ {
+ size_t i, llen;
+ const u8 *pos = buf;
+@@ -495,20 +483,6 @@ static void _wpa_hexdump_ascii(int level
+ }
+
+
+-void wpa_hexdump_ascii(int level, const char *title, const void *buf,
+- size_t len)
+-{
+- _wpa_hexdump_ascii(level, title, buf, len, 1);
+-}
+-
+-
+-void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
+- size_t len)
+-{
+- _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
+-}
+-
+-
+ #ifdef CONFIG_DEBUG_FILE
+ static char *last_path = NULL;
+ #endif /* CONFIG_DEBUG_FILE */
+@@ -602,7 +576,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_
+ }
+
+
+-void wpa_msg(void *ctx, int level, const char *fmt, ...)
++void _wpa_msg(void *ctx, int level, const char *fmt, ...)
+ {
+ va_list ap;
+ char *buf;
+@@ -640,7 +614,7 @@ void wpa_msg(void *ctx, int level, const
+ }
+
+
+-void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
++void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
+ {
+ va_list ap;
+ char *buf;
+--- a/src/utils/wpa_debug.h
++++ b/src/utils/wpa_debug.h
+@@ -49,6 +49,17 @@ int wpa_debug_reopen_file(void);
+ void wpa_debug_close_file(void);
+ void wpa_debug_setup_stdout(void);
+
++/* internal */
++void _wpa_hexdump(int level, const char *title, const u8 *buf,
++ size_t len, int show);
++void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
++ size_t len, int show);
++extern int wpa_debug_show_keys;
++
++#ifndef CONFIG_MSG_MIN_PRIORITY
++#define CONFIG_MSG_MIN_PRIORITY 0
++#endif
++
+ /**
+ * wpa_debug_printf_timestamp - Print timestamp for debug output
+ *
+@@ -69,9 +80,15 @@ void wpa_debug_print_timestamp(void);
+ *
+ * Note: New line '\n' is added to the end of the text when printing to stdout.
+ */
+-void wpa_printf(int level, const char *fmt, ...)
++void _wpa_printf(int level, const char *fmt, ...)
+ PRINTF_FORMAT(2, 3);
+
++#define wpa_printf(level, ...) \
++ do { \
++ if (level >= CONFIG_MSG_MIN_PRIORITY) \
++ _wpa_printf(level, __VA_ARGS__); \
++ } while(0)
++
+ /**
+ * wpa_hexdump - conditional hex dump
+ * @level: priority level (MSG_*) of the message
+@@ -83,7 +100,13 @@ PRINTF_FORMAT(2, 3);
+ * output may be directed to stdout, stderr, and/or syslog based on
+ * configuration. The contents of buf is printed out has hex dump.
+ */
+-void wpa_hexdump(int level, const char *title, const void *buf, size_t len);
++static inline void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
++{
++ if (level < CONFIG_MSG_MIN_PRIORITY)
++ return;
++
++ _wpa_hexdump(level, title, buf, len, 1);
++}
+
+ static inline void wpa_hexdump_buf(int level, const char *title,
+ const struct wpabuf *buf)
+@@ -105,7 +128,13 @@ static inline void wpa_hexdump_buf(int l
+ * like wpa_hexdump(), but by default, does not include secret keys (passwords,
+ * etc.) in debug output.
+ */
+-void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len);
++static inline void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
++{
++ if (level < CONFIG_MSG_MIN_PRIORITY)
++ return;
++
++ _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
++}
+
+ static inline void wpa_hexdump_buf_key(int level, const char *title,
+ const struct wpabuf *buf)
+@@ -127,8 +156,14 @@ static inline void wpa_hexdump_buf_key(i
+ * the hex numbers and ASCII characters (for printable range) are shown. 16
+ * bytes per line will be shown.
+ */
+-void wpa_hexdump_ascii(int level, const char *title, const void *buf,
+- size_t len);
++static inline void wpa_hexdump_ascii(int level, const char *title,
++ const u8 *buf, size_t len)
++{
++ if (level < CONFIG_MSG_MIN_PRIORITY)
++ return;
++
++ _wpa_hexdump_ascii(level, title, buf, len, 1);
++}
+
+ /**
+ * wpa_hexdump_ascii_key - conditional hex dump, hide keys
+@@ -144,8 +179,14 @@ void wpa_hexdump_ascii(int level, const
+ * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by
+ * default, does not include secret keys (passwords, etc.) in debug output.
+ */
+-void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
+- size_t len);
++static inline void wpa_hexdump_ascii_key(int level, const char *title,
++ const u8 *buf, size_t len)
++{
++ if (level < CONFIG_MSG_MIN_PRIORITY)
++ return;
++
++ _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
++}
+
+ /*
+ * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce
+@@ -181,7 +222,12 @@ void wpa_hexdump_ascii_key(int level, co
+ *
+ * Note: New line '\n' is added to the end of the text when printing to stdout.
+ */
+-void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4);
++void _wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4);
++#define wpa_msg(ctx, level, ...) \
++ do { \
++ if (level >= CONFIG_MSG_MIN_PRIORITY) \
++ _wpa_msg(ctx, level, __VA_ARGS__); \
++ } while(0)
+
+ /**
+ * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors
+@@ -195,8 +241,13 @@ void wpa_msg(void *ctx, int level, const
+ * attached ctrl_iface monitors. In other words, it can be used for frequent
+ * events that do not need to be sent to syslog.
+ */
+-void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
++void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
+ PRINTF_FORMAT(3, 4);
++#define wpa_msg_ctrl(ctx, level, ...) \
++ do { \
++ if (level >= CONFIG_MSG_MIN_PRIORITY) \
++ _wpa_msg_ctrl(ctx, level, __VA_ARGS__); \
++ } while(0)
+
+ /**
+ * wpa_msg_global - Global printf for ctrl_iface monitors
diff --git a/package/network/services/hostapd/patches/420-indicate-features.patch b/package/network/services/hostapd/patches/420-indicate-features.patch
new file mode 100644
index 0000000..64c92df
--- /dev/null
+++ b/package/network/services/hostapd/patches/420-indicate-features.patch
@@ -0,0 +1,82 @@
+--- a/hostapd/main.c
++++ b/hostapd/main.c
+@@ -15,6 +15,7 @@
+ #include "utils/common.h"
+ #include "utils/eloop.h"
+ #include "utils/uuid.h"
++#include "utils/build_features.h"
+ #include "crypto/random.h"
+ #include "crypto/tls.h"
+ #include "common/version.h"
+@@ -567,7 +568,7 @@ int main(int argc, char *argv[])
+
+ wpa_supplicant_event = hostapd_wpa_event;
+ for (;;) {
+- c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:");
++ c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:g:G:v::");
+ if (c < 0)
+ break;
+ switch (c) {
+@@ -604,6 +605,8 @@ int main(int argc, char *argv[])
+ break;
+ #endif /* CONFIG_DEBUG_LINUX_TRACING */
+ case 'v':
++ if (optarg)
++ exit(!has_feature(optarg));
+ show_version();
+ exit(1);
+ break;
+--- a/wpa_supplicant/main.c
++++ b/wpa_supplicant/main.c
+@@ -12,6 +12,7 @@
+ #endif /* __linux__ */
+
+ #include "common.h"
++#include "build_features.h"
+ #include "wpa_supplicant_i.h"
+ #include "driver_i.h"
+ #include "p2p_supplicant.h"
+@@ -176,7 +177,7 @@ int main(int argc, char *argv[])
+
+ for (;;) {
+ c = getopt(argc, argv,
+- "b:Bc:C:D:de:f:g:G:hH:i:I:KLm:No:O:p:P:qsTtuvW");
++ "b:Bc:C:D:de:f:g:G:hH:i:I:KLm:No:O:p:P:qsTtuv::W");
+ if (c < 0)
+ break;
+ switch (c) {
+@@ -279,8 +280,12 @@ int main(int argc, char *argv[])
+ break;
+ #endif /* CONFIG_DBUS */
+ case 'v':
+- printf("%s\n", wpa_supplicant_version);
+- exitcode = 0;
++ if (optarg) {
++ exitcode = !has_feature(optarg);
++ } else {
++ printf("%s\n", wpa_supplicant_version);
++ exitcode = 0;
++ }
+ goto out;
+ case 'W':
+ params.wait_for_monitor++;
+--- /dev/null
++++ b/src/utils/build_features.h
+@@ -0,0 +1,17 @@
++#ifndef BUILD_FEATURES_H
++#define BUILD_FEATURES_H
++
++static inline int has_feature(const char *feat)
++{
++#ifdef IEEE8021X_EAPOL
++ if (!strcmp(feat, "eap"))
++ return 1;
++#endif
++#ifdef IEEE80211N
++ if (!strcmp(feat, "11n"))
++ return 1;
++#endif
++ return 0;
++}
++
++#endif /* BUILD_FEATURES_H */
diff --git a/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch b/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch
new file mode 100644
index 0000000..85d2e16
--- /dev/null
+++ b/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch
@@ -0,0 +1,50 @@
+--- a/hostapd/hostapd_cli.c
++++ b/hostapd/hostapd_cli.c
+@@ -67,7 +67,6 @@ static const char *commands_help =
+ #ifdef CONFIG_IEEE80211W
+ " sa_query <addr> send SA Query to a station\n"
+ #endif /* CONFIG_IEEE80211W */
+-#ifdef CONFIG_WPS
+ " wps_pin <uuid> <pin> [timeout] [addr] add WPS Enrollee PIN\n"
+ " wps_check_pin <PIN> verify PIN checksum\n"
+ " wps_pbc indicate button pushed to initiate PBC\n"
+@@ -80,7 +79,6 @@ static const char *commands_help =
+ " wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
+ " wps_config <SSID> <auth> <encr> <key> configure AP\n"
+ " wps_get_status show current WPS status\n"
+-#endif /* CONFIG_WPS */
+ " get_config show current configuration\n"
+ " help show this usage help\n"
+ " interface [ifname] show interfaces/select interface\n"
+@@ -353,7 +351,6 @@ static int hostapd_cli_cmd_sa_query(stru
+ #endif /* CONFIG_IEEE80211W */
+
+
+-#ifdef CONFIG_WPS
+ static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+ {
+@@ -579,7 +576,6 @@ static int hostapd_cli_cmd_wps_config(st
+ ssid_hex, argv[1]);
+ return wpa_ctrl_command(ctrl, buf);
+ }
+-#endif /* CONFIG_WPS */
+
+
+ static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc,
+@@ -1027,7 +1023,6 @@ static struct hostapd_cli_cmd hostapd_cl
+ #ifdef CONFIG_IEEE80211W
+ { "sa_query", hostapd_cli_cmd_sa_query },
+ #endif /* CONFIG_IEEE80211W */
+-#ifdef CONFIG_WPS
+ { "wps_pin", hostapd_cli_cmd_wps_pin },
+ { "wps_check_pin", hostapd_cli_cmd_wps_check_pin },
+ { "wps_pbc", hostapd_cli_cmd_wps_pbc },
+@@ -1041,7 +1036,6 @@ static struct hostapd_cli_cmd hostapd_cl
+ { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
+ { "wps_config", hostapd_cli_cmd_wps_config },
+ { "wps_get_status", hostapd_cli_cmd_wps_get_status },
+-#endif /* CONFIG_WPS */
+ { "disassoc_imminent", hostapd_cli_cmd_disassoc_imminent },
+ { "ess_disassoc", hostapd_cli_cmd_ess_disassoc },
+ { "bss_tm_req", hostapd_cli_cmd_bss_tm_req },
diff --git a/package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch b/package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch
new file mode 100644
index 0000000..874ff4b
--- /dev/null
+++ b/package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch
@@ -0,0 +1,13 @@
+--- a/wpa_supplicant/wpa_cli.c
++++ b/wpa_supplicant/wpa_cli.c
+@@ -26,6 +26,10 @@
+ #endif /* ANDROID */
+
+
++#ifndef CONFIG_P2P
++#define CONFIG_P2P
++#endif
++
+ static const char *wpa_cli_version =
+ "wpa_cli v" VERSION_STR "\n"
+ "Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors";
diff --git a/package/network/services/hostapd/patches/440-max_num_sta_probe.patch b/package/network/services/hostapd/patches/440-max_num_sta_probe.patch
new file mode 100644
index 0000000..74aef26
--- /dev/null
+++ b/package/network/services/hostapd/patches/440-max_num_sta_probe.patch
@@ -0,0 +1,13 @@
+--- a/src/ap/beacon.c
++++ b/src/ap/beacon.c
+@@ -664,6 +664,10 @@ void handle_probe_req(struct hostapd_dat
+ return;
+ }
+
++ if (!sta && hapd->num_sta >= hapd->conf->max_num_sta)
++ wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " ignored,"
++ " too many connected stations.", MAC2STR(mgmt->sa));
++
+ #ifdef CONFIG_INTERWORKING
+ if (hapd->conf->interworking &&
+ elems.interworking && elems.interworking_len >= 1) {
diff --git a/package/network/services/hostapd/patches/450-scan_wait.patch b/package/network/services/hostapd/patches/450-scan_wait.patch
new file mode 100644
index 0000000..87ebd45
--- /dev/null
+++ b/package/network/services/hostapd/patches/450-scan_wait.patch
@@ -0,0 +1,66 @@
+--- a/hostapd/main.c
++++ b/hostapd/main.c
+@@ -36,6 +36,8 @@ struct hapd_global {
+ };
+
+ static struct hapd_global global;
++static int daemonize = 0;
++static char *pid_file = NULL;
+
+
+ #ifndef CONFIG_NO_HOSTAPD_LOGGER
+@@ -142,6 +144,14 @@ static void hostapd_logger_cb(void *ctx,
+ }
+ #endif /* CONFIG_NO_HOSTAPD_LOGGER */
+
++static void hostapd_setup_complete_cb(void *ctx)
++{
++ if (daemonize && os_daemonize(pid_file)) {
++ perror("daemon");
++ return;
++ }
++ daemonize = 0;
++}
+
+ /**
+ * hostapd_driver_init - Preparate driver interface
+@@ -160,6 +170,8 @@ static int hostapd_driver_init(struct ho
+ return -1;
+ }
+
++ hapd->setup_complete_cb = hostapd_setup_complete_cb;
++
+ /* Initialize the driver interface */
+ if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
+ b = NULL;
+@@ -381,8 +393,6 @@ static void hostapd_global_deinit(const
+ #endif /* CONFIG_NATIVE_WINDOWS */
+
+ eap_server_unregister_methods();
+-
+- os_daemonize_terminate(pid_file);
+ }
+
+
+@@ -408,11 +418,6 @@ static int hostapd_global_run(struct hap
+ }
+ #endif /* EAP_SERVER_TNC */
+
+- if (daemonize && os_daemonize(pid_file)) {
+- wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno));
+- return -1;
+- }
+-
+ eloop_run();
+
+ return 0;
+@@ -542,8 +547,7 @@ int main(int argc, char *argv[])
+ struct hapd_interfaces interfaces;
+ int ret = 1;
+ size_t i, j;
+- int c, debug = 0, daemonize = 0;
+- char *pid_file = NULL;
++ int c, debug = 0;
+ const char *log_file = NULL;
+ const char *entropy_file = NULL;
+ char **bss_config = NULL, **tmp_bss;
diff --git a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
new file mode 100644
index 0000000..217e701
--- /dev/null
+++ b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
@@ -0,0 +1,188 @@
+From 4bb69d15477e0f2b00e166845341dc933de47c58 Mon Sep 17 00:00:00 2001
+From: Antonio Quartulli <ordex@autistici.org>
+Date: Sun, 3 Jun 2012 18:22:56 +0200
+Subject: [PATCHv2 601/602] wpa_supplicant: add new config params to be used
+ with the ibss join command
+
+Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+---
+ src/drivers/driver.h | 6 +++
+ wpa_supplicant/config.c | 96 +++++++++++++++++++++++++++++++++++++++
+ wpa_supplicant/config_ssid.h | 6 +++
+ wpa_supplicant/wpa_supplicant.c | 23 +++++++---
+ 4 files changed, 124 insertions(+), 7 deletions(-)
+
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -19,6 +19,7 @@
+
+ #define WPA_SUPPLICANT_DRIVER_VERSION 4
+
++#include "drivers/nl80211_copy.h"
+ #include "common/defs.h"
+ #include "utils/list.h"
+
+@@ -538,6 +539,9 @@ struct wpa_driver_associate_params {
+ * responsible for selecting with which BSS to associate. */
+ const u8 *bssid;
+
++ unsigned char rates[NL80211_MAX_SUPP_RATES];
++ int mcast_rate;
++
+ /**
+ * bssid_hint - BSSID of a proposed AP
+ *
+--- a/wpa_supplicant/config.c
++++ b/wpa_supplicant/config.c
+@@ -15,6 +15,7 @@
+ #include "rsn_supp/wpa.h"
+ #include "eap_peer/eap.h"
+ #include "p2p/p2p.h"
++#include "drivers/nl80211_copy.h"
+ #include "config.h"
+
+
+@@ -1722,6 +1723,97 @@ static char * wpa_config_write_mesh_basi
+ #endif /* CONFIG_MESH */
+
+
++static int wpa_config_parse_mcast_rate(const struct parse_data *data,
++ struct wpa_ssid *ssid, int line,
++ const char *value)
++{
++ ssid->mcast_rate = (int)(strtod(value, NULL) * 10);
++
++ return 0;
++}
++
++#ifndef NO_CONFIG_WRITE
++static char * wpa_config_write_mcast_rate(const struct parse_data *data,
++ struct wpa_ssid *ssid)
++{
++ char *value;
++ int res;
++
++ if (!ssid->mcast_rate == 0)
++ return NULL;
++
++ value = os_malloc(6); /* longest: 300.0 */
++ if (value == NULL)
++ return NULL;
++ res = os_snprintf(value, 5, "%.1f", (double)ssid->mcast_rate / 10);
++ if (res < 0) {
++ os_free(value);
++ return NULL;
++ }
++ return value;
++}
++#endif /* NO_CONFIG_WRITE */
++
++static int wpa_config_parse_rates(const struct parse_data *data,
++ struct wpa_ssid *ssid, int line,
++ const char *value)
++{
++ int i;
++ char *pos, *r, *sptr, *end;
++ double rate;
++
++ pos = (char *)value;
++ r = strtok_r(pos, ",", &sptr);
++ i = 0;
++ while (pos && i < NL80211_MAX_SUPP_RATES) {
++ rate = 0.0;
++ if (r)
++ rate = strtod(r, &end);
++ ssid->rates[i] = rate * 2;
++ if (*end != '\0' || rate * 2 != ssid->rates[i])
++ return 1;
++
++ i++;
++ r = strtok_r(NULL, ",", &sptr);
++ }
++
++ return 0;
++}
++
++#ifndef NO_CONFIG_WRITE
++static char * wpa_config_write_rates(const struct parse_data *data,
++ struct wpa_ssid *ssid)
++{
++ char *value, *pos;
++ int res, i;
++
++ if (ssid->rates[0] <= 0)
++ return NULL;
++
++ value = os_malloc(6 * NL80211_MAX_SUPP_RATES + 1);
++ if (value == NULL)
++ return NULL;
++ pos = value;
++ for (i = 0; i < NL80211_MAX_SUPP_RATES - 1; i++) {
++ res = os_snprintf(pos, 6, "%.1f,", (double)ssid->rates[i] / 2);
++ if (res < 0) {
++ os_free(value);
++ return NULL;
++ }
++ pos += res;
++ }
++ res = os_snprintf(pos, 6, "%.1f",
++ (double)ssid->rates[NL80211_MAX_SUPP_RATES - 1] / 2);
++ if (res < 0) {
++ os_free(value);
++ return NULL;
++ }
++
++ value[6 * NL80211_MAX_SUPP_RATES] = '\0';
++ return value;
++}
++#endif /* NO_CONFIG_WRITE */
++
+ /* Helper macros for network block parser */
+
+ #ifdef OFFSET
+@@ -1947,6 +2039,9 @@ static const struct parse_data ssid_fiel
+ { INT(ap_max_inactivity) },
+ { INT(dtim_period) },
+ { INT(beacon_int) },
++ { INT_RANGE(fixed_freq, 0, 1) },
++ { FUNC(rates) },
++ { FUNC(mcast_rate) },
+ #ifdef CONFIG_MACSEC
+ { INT_RANGE(macsec_policy, 0, 1) },
+ #endif /* CONFIG_MACSEC */
+--- a/wpa_supplicant/config_ssid.h
++++ b/wpa_supplicant/config_ssid.h
+@@ -12,6 +12,7 @@
+ #include "common/defs.h"
+ #include "utils/list.h"
+ #include "eap_peer/eap_config.h"
++#include "drivers/nl80211_copy.h"
+
+ #define MAX_SSID_LEN 32
+
+@@ -675,6 +676,9 @@ struct wpa_ssid {
+ */
+ void *parent_cred;
+
++ unsigned char rates[NL80211_MAX_SUPP_RATES];
++ double mcast_rate;
++
+ #ifdef CONFIG_MACSEC
+ /**
+ * macsec_policy - Determines the policy for MACsec secure session
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -2266,6 +2266,13 @@ static void wpas_start_assoc_cb(struct w
+ params.beacon_int = ssid->beacon_int;
+ else
+ params.beacon_int = wpa_s->conf->beacon_int;
++ params.fixed_freq = ssid->fixed_freq;
++ i = 0;
++ while (i < NL80211_MAX_SUPP_RATES) {
++ params.rates[i] = ssid->rates[i];
++ i++;
++ }
++ params.mcast_rate = ssid->mcast_rate;
+ }
+
+ params.wpa_ie = wpa_ie;
diff --git a/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch b/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch
new file mode 100644
index 0000000..730cc31
--- /dev/null
+++ b/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch
@@ -0,0 +1,59 @@
+From ffc4445958a3ed4064f2e1bf73fa478a61c5cf7b Mon Sep 17 00:00:00 2001
+From: Antonio Quartulli <ordex@autistici.org>
+Date: Sun, 3 Jun 2012 18:42:25 +0200
+Subject: [PATCHv2 602/602] driver_nl80211: use new parameters during ibss join
+
+Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+---
+ src/drivers/driver_nl80211.c | 33 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 32 insertions(+), 1 deletion(-)
+
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -4398,7 +4398,7 @@ static int wpa_driver_nl80211_ibss(struc
+ struct wpa_driver_associate_params *params)
+ {
+ struct nl_msg *msg;
+- int ret = -1;
++ int ret = -1, i;
+ int count = 0;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
+@@ -4425,6 +4425,37 @@ retry:
+ nl80211_put_beacon_int(msg, params->beacon_int))
+ goto fail;
+
++ if (params->fixed_freq) {
++ wpa_printf(MSG_DEBUG, " * fixed_freq");
++ nla_put_flag(msg, NL80211_ATTR_FREQ_FIXED);
++ }
++
++ if (params->beacon_int > 0) {
++ wpa_printf(MSG_DEBUG, " * beacon_int=%d",
++ params->beacon_int);
++ nla_put_u32(msg, NL80211_ATTR_BEACON_INTERVAL,
++ params->beacon_int);
++ }
++
++ if (params->rates[0] > 0) {
++ wpa_printf(MSG_DEBUG, " * basic_rates:");
++ i = 0;
++ while (i < NL80211_MAX_SUPP_RATES &&
++ params->rates[i] > 0) {
++ wpa_printf(MSG_DEBUG, " %.1f",
++ (double)params->rates[i] / 2);
++ i++;
++ }
++ nla_put(msg, NL80211_ATTR_BSS_BASIC_RATES, i,
++ params->rates);
++ }
++
++ if (params->mcast_rate > 0) {
++ wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f",
++ (double)params->mcast_rate / 10);
++ nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate);
++ }
++
+ ret = nl80211_set_conn_keys(params, msg);
+ if (ret)
+ goto fail;
diff --git a/package/network/services/hostapd/patches/462-wpa_s-support-htmode-param.patch b/package/network/services/hostapd/patches/462-wpa_s-support-htmode-param.patch
new file mode 100644
index 0000000..30bb2dc
--- /dev/null
+++ b/package/network/services/hostapd/patches/462-wpa_s-support-htmode-param.patch
@@ -0,0 +1,156 @@
+From b9329c5dfeed7d5c55d2117d8dfe326fc40c8fb1 Mon Sep 17 00:00:00 2001
+From: Antonio Quartulli <ordex@autistici.org>
+Date: Tue, 3 Jul 2012 00:36:24 +0200
+Subject: [PATCH] wpa_s: support htmode param
+
+possible values are HT20, HT40-, HT40+ and NOHT
+
+Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+---
+ src/drivers/driver.h | 2 ++
+ src/drivers/driver_nl80211.c | 16 ++++++++++
+ wpa_supplicant/config.c | 66 +++++++++++++++++++++++++++++++++++++++
+ wpa_supplicant/config_ssid.h | 2 ++
+ wpa_supplicant/wpa_supplicant.c | 2 ++
+ 5 files changed, 88 insertions(+)
+
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -541,6 +541,8 @@ struct wpa_driver_associate_params {
+
+ unsigned char rates[NL80211_MAX_SUPP_RATES];
+ int mcast_rate;
++ int ht_set;
++ unsigned int htmode;
+
+ /**
+ * bssid_hint - BSSID of a proposed AP
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -4456,6 +4456,22 @@ retry:
+ nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate);
+ }
+
++ if (params->ht_set) {
++ switch(params->htmode) {
++ case NL80211_CHAN_HT20:
++ wpa_printf(MSG_DEBUG, " * ht=HT20");
++ break;
++ case NL80211_CHAN_HT40PLUS:
++ wpa_printf(MSG_DEBUG, " * ht=HT40+");
++ break;
++ case NL80211_CHAN_HT40MINUS:
++ wpa_printf(MSG_DEBUG, " * ht=HT40-");
++ break;
++ }
++ nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
++ params->htmode);
++ }
++
+ ret = nl80211_set_conn_keys(params, msg);
+ if (ret)
+ goto fail;
+--- a/wpa_supplicant/config.c
++++ b/wpa_supplicant/config.c
+@@ -1754,6 +1754,71 @@ static char * wpa_config_write_mcast_rat
+ }
+ #endif /* NO_CONFIG_WRITE */
+
++static int wpa_config_parse_htmode(const struct parse_data *data,
++ struct wpa_ssid *ssid, int line,
++ const char *value)
++{
++ int i;
++ static const struct {
++ const char *name;
++ unsigned int val;
++ } htmap[] = {
++ { .name = "HT20", .val = NL80211_CHAN_HT20, },
++ { .name = "HT40+", .val = NL80211_CHAN_HT40PLUS, },
++ { .name = "HT40-", .val = NL80211_CHAN_HT40MINUS, },
++ { .name = "NOHT", .val = NL80211_CHAN_NO_HT, },
++ };
++ ssid->ht_set = 0;;
++ for (i = 0; i < 4; i++) {
++ if (strcasecmp(htmap[i].name, value) == 0) {
++ ssid->htmode = htmap[i].val;
++ ssid->ht_set = 1;
++ break;
++ }
++ }
++
++ return 0;
++}
++
++#ifndef NO_CONFIG_WRITE
++static char * wpa_config_write_htmode(const struct parse_data *data,
++ struct wpa_ssid *ssid)
++{
++ char *value;
++ int res;
++
++ value = os_malloc(6); /* longest: HT40+ */
++ if (value == NULL)
++ return NULL;
++
++ switch(ssid->htmode) {
++ case NL80211_CHAN_HT20:
++ res = os_snprintf(value, 4, "HT20");
++ break;
++ case NL80211_CHAN_HT40PLUS:
++ res = os_snprintf(value, 5, "HT40+");
++ break;
++ case NL80211_CHAN_HT40MINUS:
++ res = os_snprintf(value, 5, "HT40-");
++ break;
++ case NL80211_CHAN_NO_HT:
++ res = os_snprintf(value, 4, "NOHT");
++ break;
++ default:
++ os_free(value);
++ return NULL;
++ }
++
++ if (res < 0) {
++ os_free(value);
++ return NULL;
++ }
++
++ return value;
++}
++#endif /* NO_CONFIG_WRITE */
++
++
+ static int wpa_config_parse_rates(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+@@ -2042,6 +2107,7 @@ static const struct parse_data ssid_fiel
+ { INT_RANGE(fixed_freq, 0, 1) },
+ { FUNC(rates) },
+ { FUNC(mcast_rate) },
++ { FUNC(htmode) },
+ #ifdef CONFIG_MACSEC
+ { INT_RANGE(macsec_policy, 0, 1) },
+ #endif /* CONFIG_MACSEC */
+--- a/wpa_supplicant/config_ssid.h
++++ b/wpa_supplicant/config_ssid.h
+@@ -678,6 +678,8 @@ struct wpa_ssid {
+
+ unsigned char rates[NL80211_MAX_SUPP_RATES];
+ double mcast_rate;
++ int ht_set;
++ unsigned int htmode;
+
+ #ifdef CONFIG_MACSEC
+ /**
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -2273,6 +2273,8 @@ static void wpas_start_assoc_cb(struct w
+ i++;
+ }
+ params.mcast_rate = ssid->mcast_rate;
++ params.ht_set = ssid->ht_set;
++ params.htmode = ssid->htmode;
+ }
+
+ params.wpa_ie = wpa_ie;
diff --git a/package/network/services/hostapd/patches/470-wait-for-nullfunc-longer.patch b/package/network/services/hostapd/patches/470-wait-for-nullfunc-longer.patch
new file mode 100644
index 0000000..e6bbddd
--- /dev/null
+++ b/package/network/services/hostapd/patches/470-wait-for-nullfunc-longer.patch
@@ -0,0 +1,11 @@
+--- a/src/ap/sta_info.h
++++ b/src/ap/sta_info.h
+@@ -179,7 +179,7 @@ struct sta_info {
+ * AP_DISASSOC_DELAY seconds. Similarly, the station will be deauthenticated
+ * after AP_DEAUTH_DELAY seconds has passed after disassociation. */
+ #define AP_MAX_INACTIVITY (5 * 60)
+-#define AP_DISASSOC_DELAY (1)
++#define AP_DISASSOC_DELAY (3)
+ #define AP_DEAUTH_DELAY (1)
+ /* Number of seconds to keep STA entry with Authenticated flag after it has
+ * been disassociated. */
diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch
new file mode 100644
index 0000000..df2eac8
--- /dev/null
+++ b/package/network/services/hostapd/patches/600-ubus_support.patch
@@ -0,0 +1,858 @@
+--- a/hostapd/Makefile
++++ b/hostapd/Makefile
+@@ -121,6 +121,11 @@ OBJS += ../src/common/hw_features_common
+
+ OBJS += ../src/eapol_auth/eapol_auth_sm.o
+
++ifdef CONFIG_UBUS
++CFLAGS += -DUBUS_SUPPORT
++OBJS += ../src/ap/ubus.o
++LIBS += -lubox -lubus
++endif
+
+ ifdef CONFIG_CODE_COVERAGE
+ CFLAGS += -O0 -fprofile-arcs -ftest-coverage
+--- a/src/ap/hostapd.h
++++ b/src/ap/hostapd.h
+@@ -13,6 +13,7 @@
+ #include "utils/list.h"
+ #include "ap_config.h"
+ #include "drivers/driver.h"
++#include "ubus.h"
+
+ struct wpa_ctrl_dst;
+ struct radius_server_data;
+@@ -103,6 +104,7 @@ struct hostapd_data {
+ struct hostapd_iface *iface;
+ struct hostapd_config *iconf;
+ struct hostapd_bss_config *conf;
++ struct hostapd_ubus_bss ubus;
+ int interface_added; /* virtual interface added for this BSS */
+ unsigned int started:1;
+ unsigned int disabled:1;
+@@ -286,6 +288,8 @@ struct hostapd_iface {
+ struct hostapd_config *conf;
+ char phy[16]; /* Name of the PHY (radio) */
+
++ struct hostapd_ubus_iface ubus;
++
+ enum hostapd_iface_state {
+ HAPD_IFACE_UNINITIALIZED,
+ HAPD_IFACE_DISABLED,
+--- /dev/null
++++ b/src/ap/ubus.c
+@@ -0,0 +1,511 @@
++/*
++ * hostapd / ubus support
++ * Copyright (c) 2013, Felix Fietkau <nbd@openwrt.org>
++ *
++ * This software may be distributed under the terms of the BSD license.
++ * See README for more details.
++ */
++
++#include "utils/includes.h"
++#include "utils/common.h"
++#include "utils/eloop.h"
++#include "common/ieee802_11_defs.h"
++#include "hostapd.h"
++#include "wps_hostapd.h"
++#include "sta_info.h"
++#include "ubus.h"
++
++static struct ubus_context *ctx;
++static struct blob_buf b;
++static int ctx_ref;
++
++static inline struct hostapd_data *get_hapd_from_object(struct ubus_object *obj)
++{
++ return container_of(obj, struct hostapd_data, ubus.obj);
++}
++
++
++struct ubus_banned_client {
++ struct avl_node avl;
++ u8 addr[ETH_ALEN];
++};
++
++static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx)
++{
++ struct ubus_context *ctx = eloop_ctx;
++ ubus_handle_event(ctx);
++}
++
++static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx)
++{
++ if (ubus_reconnect(ctx, NULL)) {
++ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL);
++ return;
++ }
++
++ eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL);
++}
++
++static void hostapd_ubus_connection_lost(struct ubus_context *ctx)
++{
++ eloop_unregister_read_sock(ctx->sock.fd);
++ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL);
++}
++
++static bool hostapd_ubus_init(void)
++{
++ if (ctx)
++ return true;
++
++ ctx = ubus_connect(NULL);
++ if (!ctx)
++ return false;
++
++ ctx->connection_lost = hostapd_ubus_connection_lost;
++ eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL);
++ return true;
++}
++
++static void hostapd_ubus_ref_inc(void)
++{
++ ctx_ref++;
++}
++
++static void hostapd_ubus_ref_dec(void)
++{
++ ctx_ref--;
++ if (!ctx)
++ return;
++
++ if (ctx_ref)
++ return;
++
++ eloop_unregister_read_sock(ctx->sock.fd);
++ ubus_free(ctx);
++ ctx = NULL;
++}
++
++void hostapd_ubus_add_iface(struct hostapd_iface *iface)
++{
++ if (!hostapd_ubus_init())
++ return;
++}
++
++void hostapd_ubus_free_iface(struct hostapd_iface *iface)
++{
++ if (!ctx)
++ return;
++}
++
++static void
++hostapd_bss_del_ban(void *eloop_data, void *user_ctx)
++{
++ struct ubus_banned_client *ban = eloop_data;
++ struct hostapd_data *hapd = user_ctx;
++
++ avl_delete(&hapd->ubus.banned, &ban->avl);
++ free(ban);
++}
++
++static void
++hostapd_bss_ban_client(struct hostapd_data *hapd, u8 *addr, int time)
++{
++ struct ubus_banned_client *ban;
++
++ if (time < 0)
++ time = 0;
++
++ ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl);
++ if (!ban) {
++ if (!time)
++ return;
++
++ ban = os_zalloc(sizeof(*ban));
++ memcpy(ban->addr, addr, sizeof(ban->addr));
++ ban->avl.key = ban->addr;
++ avl_insert(&hapd->ubus.banned, &ban->avl);
++ } else {
++ eloop_cancel_timeout(hostapd_bss_del_ban, ban, hapd);
++ if (!time) {
++ hostapd_bss_del_ban(ban, hapd);
++ return;
++ }
++ }
++
++ eloop_register_timeout(0, time * 1000, hostapd_bss_del_ban, ban, hapd);
++}
++
++static int
++hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj,
++ struct ubus_request_data *req, const char *method,
++ struct blob_attr *msg)
++{
++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj);
++ struct sta_info *sta;
++ void *list, *c;
++ char mac_buf[20];
++ static const struct {
++ const char *name;
++ uint32_t flag;
++ } sta_flags[] = {
++ { "auth", WLAN_STA_AUTH },
++ { "assoc", WLAN_STA_ASSOC },
++ { "authorized", WLAN_STA_AUTHORIZED },
++ { "preauth", WLAN_STA_PREAUTH },
++ { "wds", WLAN_STA_WDS },
++ { "wmm", WLAN_STA_WMM },
++ { "ht", WLAN_STA_HT },
++ { "vht", WLAN_STA_VHT },
++ { "wps", WLAN_STA_WPS },
++ { "mfp", WLAN_STA_MFP },
++ };
++
++ blob_buf_init(&b, 0);
++ blobmsg_add_u32(&b, "freq", hapd->iface->freq);
++ list = blobmsg_open_table(&b, "clients");
++ for (sta = hapd->sta_list; sta; sta = sta->next) {
++ int i;
++
++ sprintf(mac_buf, MACSTR, MAC2STR(sta->addr));
++ c = blobmsg_open_table(&b, mac_buf);
++ for (i = 0; i < ARRAY_SIZE(sta_flags); i++)
++ blobmsg_add_u8(&b, sta_flags[i].name,
++ !!(sta->flags & sta_flags[i].flag));
++ blobmsg_add_u32(&b, "aid", sta->aid);
++ blobmsg_close_table(&b, c);
++ }
++ blobmsg_close_array(&b, list);
++ ubus_send_reply(ctx, req, b.head);
++
++ return 0;
++}
++
++enum {
++ DEL_CLIENT_ADDR,
++ DEL_CLIENT_REASON,
++ DEL_CLIENT_DEAUTH,
++ DEL_CLIENT_BAN_TIME,
++ __DEL_CLIENT_MAX
++};
++
++static const struct blobmsg_policy del_policy[__DEL_CLIENT_MAX] = {
++ [DEL_CLIENT_ADDR] = { "addr", BLOBMSG_TYPE_STRING },
++ [DEL_CLIENT_REASON] = { "reason", BLOBMSG_TYPE_INT32 },
++ [DEL_CLIENT_DEAUTH] = { "deauth", BLOBMSG_TYPE_INT8 },
++ [DEL_CLIENT_BAN_TIME] = { "ban_time", BLOBMSG_TYPE_INT32 },
++};
++
++static int
++hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj,
++ struct ubus_request_data *req, const char *method,
++ struct blob_attr *msg)
++{
++ struct blob_attr *tb[__DEL_CLIENT_MAX];
++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj);
++ struct sta_info *sta;
++ bool deauth = false;
++ int reason;
++ u8 addr[ETH_ALEN];
++
++ blobmsg_parse(del_policy, __DEL_CLIENT_MAX, tb, blob_data(msg), blob_len(msg));
++
++ if (!tb[DEL_CLIENT_ADDR])
++ return UBUS_STATUS_INVALID_ARGUMENT;
++
++ if (hwaddr_aton(blobmsg_data(tb[DEL_CLIENT_ADDR]), addr))
++ return UBUS_STATUS_INVALID_ARGUMENT;
++
++ if (tb[DEL_CLIENT_REASON])
++ reason = blobmsg_get_u32(tb[DEL_CLIENT_REASON]);
++
++ if (tb[DEL_CLIENT_DEAUTH])
++ deauth = blobmsg_get_bool(tb[DEL_CLIENT_DEAUTH]);
++
++ sta = ap_get_sta(hapd, addr);
++ if (sta) {
++ if (deauth) {
++ hostapd_drv_sta_deauth(hapd, addr, reason);
++ ap_sta_deauthenticate(hapd, sta, reason);
++ } else {
++ hostapd_drv_sta_disassoc(hapd, addr, reason);
++ ap_sta_disassociate(hapd, sta, reason);
++ }
++ }
++
++ if (tb[DEL_CLIENT_BAN_TIME])
++ hostapd_bss_ban_client(hapd, addr, blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME]));
++
++ return 0;
++}
++
++static void
++blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const u8 *addr)
++{
++ char *s;
++
++ s = blobmsg_alloc_string_buffer(buf, name, 20);
++ sprintf(s, MACSTR, MAC2STR(addr));
++ blobmsg_add_string_buffer(buf);
++}
++
++static int
++hostapd_bss_list_bans(struct ubus_context *ctx, struct ubus_object *obj,
++ struct ubus_request_data *req, const char *method,
++ struct blob_attr *msg)
++{
++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj);
++ struct ubus_banned_client *ban;
++ void *c;
++
++ blob_buf_init(&b, 0);
++ c = blobmsg_open_array(&b, "clients");
++ avl_for_each_element(&hapd->ubus.banned, ban, avl)
++ blobmsg_add_macaddr(&b, NULL, ban->addr);
++ blobmsg_close_array(&b, c);
++ ubus_send_reply(ctx, req, b.head);
++
++ return 0;
++}
++
++static int
++hostapd_bss_wps_start(struct ubus_context *ctx, struct ubus_object *obj,
++ struct ubus_request_data *req, const char *method,
++ struct blob_attr *msg)
++{
++ int rc;
++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj);
++
++ rc = hostapd_wps_button_pushed(hapd, NULL);
++
++ if (rc != 0)
++ return UBUS_STATUS_NOT_SUPPORTED;
++
++ return 0;
++}
++
++static int
++hostapd_bss_wps_cancel(struct ubus_context *ctx, struct ubus_object *obj,
++ struct ubus_request_data *req, const char *method,
++ struct blob_attr *msg)
++{
++ int rc;
++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj);
++
++ rc = hostapd_wps_cancel(hapd);
++
++ if (rc != 0)
++ return UBUS_STATUS_NOT_SUPPORTED;
++
++ return 0;
++}
++
++static int
++hostapd_bss_update_beacon(struct ubus_context *ctx, struct ubus_object *obj,
++ struct ubus_request_data *req, const char *method,
++ struct blob_attr *msg)
++{
++ int rc;
++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj);
++
++ rc = ieee802_11_set_beacon(hapd);
++
++ if (rc != 0)
++ return UBUS_STATUS_NOT_SUPPORTED;
++
++ return 0;
++}
++
++enum {
++ CSA_FREQ,
++ CSA_BCN_COUNT,
++ __CSA_MAX
++};
++
++static const struct blobmsg_policy csa_policy[__CSA_MAX] = {
++ /*
++ * for now, frequency and beacon count are enough, add more
++ * parameters on demand
++ */
++ [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 },
++ [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 },
++};
++
++#ifdef NEED_AP_MLME
++static int
++hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj,
++ struct ubus_request_data *req, const char *method,
++ struct blob_attr *msg)
++{
++ struct blob_attr *tb[__CSA_MAX];
++ struct hostapd_data *hapd = get_hapd_from_object(obj);
++ struct csa_settings css;
++
++ blobmsg_parse(csa_policy, __CSA_MAX, tb, blob_data(msg), blob_len(msg));
++
++ if (!tb[CSA_FREQ])
++ return UBUS_STATUS_INVALID_ARGUMENT;
++
++ memset(&css, 0, sizeof(css));
++ css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]);
++ if (tb[CSA_BCN_COUNT])
++ css.cs_count = blobmsg_get_u32(tb[CSA_BCN_COUNT]);
++
++ if (hostapd_switch_channel(hapd, &css) != 0)
++ return UBUS_STATUS_NOT_SUPPORTED;
++ return UBUS_STATUS_OK;
++}
++#endif
++
++enum {
++ VENDOR_ELEMENTS,
++ __VENDOR_ELEMENTS_MAX
++};
++
++static const struct blobmsg_policy ve_policy[__VENDOR_ELEMENTS_MAX] = {
++ /* vendor elements are provided as hex-string */
++ [VENDOR_ELEMENTS] = { "vendor_elements", BLOBMSG_TYPE_STRING },
++};
++
++static int
++hostapd_vendor_elements(struct ubus_context *ctx, struct ubus_object *obj,
++ struct ubus_request_data *req, const char *method,
++ struct blob_attr *msg)
++{
++ struct blob_attr *tb[__VENDOR_ELEMENTS_MAX];
++ struct hostapd_data *hapd = get_hapd_from_object(obj);
++
++ blobmsg_parse(ve_policy, __VENDOR_ELEMENTS_MAX, tb,
++ blob_data(msg), blob_len(msg));
++
++ if (!tb[VENDOR_ELEMENTS])
++ return UBUS_STATUS_INVALID_ARGUMENT;
++
++ const char *vendor_elements = blobmsg_data(tb[VENDOR_ELEMENTS]);
++ if (hostapd_set_iface(hapd->iconf, hapd->conf, "vendor_elements",
++ vendor_elements) != 0)
++ return UBUS_STATUS_NOT_SUPPORTED;
++
++ /* update beacons if vendor elements were set successfully */
++ if (ieee802_11_update_beacons(hapd->iface) != 0)
++ return UBUS_STATUS_NOT_SUPPORTED;
++ return UBUS_STATUS_OK;
++}
++
++static const struct ubus_method bss_methods[] = {
++ UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients),
++ UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy),
++ UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans),
++ UBUS_METHOD_NOARG("wps_start", hostapd_bss_wps_start),
++ UBUS_METHOD_NOARG("wps_cancel", hostapd_bss_wps_cancel),
++ UBUS_METHOD_NOARG("update_beacon", hostapd_bss_update_beacon),
++#ifdef NEED_AP_MLME
++ UBUS_METHOD("switch_chan", hostapd_switch_chan, csa_policy),
++#endif
++ UBUS_METHOD("set_vendor_elements", hostapd_vendor_elements, ve_policy),
++};
++
++static struct ubus_object_type bss_object_type =
++ UBUS_OBJECT_TYPE("hostapd_bss", bss_methods);
++
++static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr)
++{
++ return memcmp(k1, k2, ETH_ALEN);
++}
++
++void hostapd_ubus_add_bss(struct hostapd_data *hapd)
++{
++ struct ubus_object *obj = &hapd->ubus.obj;
++ char *name;
++ int ret;
++
++ if (!hostapd_ubus_init())
++ return;
++
++ if (asprintf(&name, "hostapd.%s", hapd->conf->iface) < 0)
++ return;
++
++ avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL);
++ obj->name = name;
++ obj->type = &bss_object_type;
++ obj->methods = bss_object_type.methods;
++ obj->n_methods = bss_object_type.n_methods;
++ ret = ubus_add_object(ctx, obj);
++ hostapd_ubus_ref_inc();
++}
++
++void hostapd_ubus_free_bss(struct hostapd_data *hapd)
++{
++ struct ubus_object *obj = &hapd->ubus.obj;
++ char *name = (char *) obj->name;
++
++ if (!ctx)
++ return;
++
++ if (obj->id) {
++ ubus_remove_object(ctx, obj);
++ hostapd_ubus_ref_dec();
++ }
++
++ free(name);
++}
++
++struct ubus_event_req {
++ struct ubus_notify_request nreq;
++ bool deny;
++};
++
++static void
++ubus_event_cb(struct ubus_notify_request *req, int idx, int ret)
++{
++ struct ubus_event_req *ureq = container_of(req, struct ubus_event_req, nreq);
++
++ if (ret)
++ ureq->deny = true;
++}
++
++int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req)
++{
++ struct ubus_banned_client *ban;
++ const char *types[HOSTAPD_UBUS_TYPE_MAX] = {
++ [HOSTAPD_UBUS_PROBE_REQ] = "probe",
++ [HOSTAPD_UBUS_AUTH_REQ] = "auth",
++ [HOSTAPD_UBUS_ASSOC_REQ] = "assoc",
++ };
++ const char *type = "mgmt";
++ struct ubus_event_req ureq = {};
++ const u8 *addr;
++
++ if (req->mgmt_frame)
++ addr = req->mgmt_frame->sa;
++ else
++ addr = req->addr;
++
++ ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl);
++ if (ban)
++ return -2;
++
++ if (!hapd->ubus.obj.has_subscribers)
++ return 0;
++
++ if (req->type < ARRAY_SIZE(types))
++ type = types[req->type];
++
++ blob_buf_init(&b, 0);
++ blobmsg_add_macaddr(&b, "address", addr);
++ if (req->mgmt_frame)
++ blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da);
++ if (req->frame_info)
++ blobmsg_add_u32(&b, "signal", req->frame_info->ssi_signal);
++ blobmsg_add_u32(&b, "freq", hapd->iface->freq);
++
++ if (ubus_notify_async(ctx, &hapd->ubus.obj, type, b.head, &ureq.nreq))
++ return 0;
++
++ ureq.nreq.status_cb = ubus_event_cb;
++ ubus_complete_request(ctx, &ureq.nreq.req, 100);
++
++ if (ureq.deny)
++ return -1;
++
++ return 0;
++}
+--- /dev/null
++++ b/src/ap/ubus.h
+@@ -0,0 +1,78 @@
++/*
++ * hostapd / ubus support
++ * Copyright (c) 2013, Felix Fietkau <nbd@openwrt.org>
++ *
++ * This software may be distributed under the terms of the BSD license.
++ * See README for more details.
++ */
++#ifndef __HOSTAPD_UBUS_H
++#define __HOSTAPD_UBUS_H
++
++enum hostapd_ubus_event_type {
++ HOSTAPD_UBUS_PROBE_REQ,
++ HOSTAPD_UBUS_AUTH_REQ,
++ HOSTAPD_UBUS_ASSOC_REQ,
++ HOSTAPD_UBUS_TYPE_MAX
++};
++
++struct hostapd_ubus_request {
++ enum hostapd_ubus_event_type type;
++ const struct ieee80211_mgmt *mgmt_frame;
++ const struct hostapd_frame_info *frame_info;
++ const u8 *addr;
++};
++
++struct hostapd_iface;
++struct hostapd_data;
++
++#ifdef UBUS_SUPPORT
++
++#include <libubox/avl.h>
++#include <libubus.h>
++
++struct hostapd_ubus_iface {
++ struct ubus_object obj;
++};
++
++struct hostapd_ubus_bss {
++ struct ubus_object obj;
++ struct avl_tree banned;
++};
++
++void hostapd_ubus_add_iface(struct hostapd_iface *iface);
++void hostapd_ubus_free_iface(struct hostapd_iface *iface);
++void hostapd_ubus_add_bss(struct hostapd_data *hapd);
++void hostapd_ubus_free_bss(struct hostapd_data *hapd);
++
++int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req);
++
++#else
++
++struct hostapd_ubus_iface {};
++
++struct hostapd_ubus_bss {};
++
++static inline void hostapd_ubus_add_iface(struct hostapd_iface *iface)
++{
++}
++
++static inline void hostapd_ubus_free_iface(struct hostapd_iface *iface)
++{
++}
++
++static inline void hostapd_ubus_add_bss(struct hostapd_data *hapd)
++{
++}
++
++static inline void hostapd_ubus_free_bss(struct hostapd_data *hapd)
++{
++}
++
++static inline int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req)
++{
++ return 0;
++}
++
++#endif
++
++#endif
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -277,6 +277,7 @@ static void hostapd_free_hapd_data(struc
+ hapd->started = 0;
+
+ wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
++ hostapd_ubus_free_bss(hapd);
+ iapp_deinit(hapd->iapp);
+ hapd->iapp = NULL;
+ accounting_deinit(hapd);
+@@ -1098,6 +1099,8 @@ static int hostapd_setup_bss(struct host
+ if (hapd->driver && hapd->driver->set_operstate)
+ hapd->driver->set_operstate(hapd->drv_priv, 1);
+
++ hostapd_ubus_add_bss(hapd);
++
+ return 0;
+ }
+
+@@ -1384,6 +1387,7 @@ int hostapd_setup_interface_complete(str
+ if (err)
+ goto fail;
+
++ hostapd_ubus_add_iface(iface);
+ wpa_printf(MSG_DEBUG, "Completing interface initialization");
+ if (iface->conf->channel) {
+ #ifdef NEED_AP_MLME
+@@ -1544,6 +1548,7 @@ dfs_offload:
+
+ fail:
+ wpa_printf(MSG_ERROR, "Interface initialization failed");
++ hostapd_ubus_free_iface(iface);
+ hostapd_set_state(iface, HAPD_IFACE_DISABLED);
+ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
+ if (iface->interfaces && iface->interfaces->terminate_on_error)
+@@ -1873,6 +1878,7 @@ void hostapd_interface_deinit_free(struc
+ (unsigned int) iface->conf->num_bss);
+ driver = iface->bss[0]->driver;
+ drv_priv = iface->bss[0]->drv_priv;
++ hostapd_ubus_free_iface(iface);
+ hostapd_interface_deinit(iface);
+ wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
+ __func__, driver, drv_priv);
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -881,7 +881,8 @@ int auth_sae_init_committed(struct hosta
+
+
+ static void handle_auth(struct hostapd_data *hapd,
+- const struct ieee80211_mgmt *mgmt, size_t len)
++ const struct ieee80211_mgmt *mgmt, size_t len,
++ struct hostapd_frame_info *fi)
+ {
+ u16 auth_alg, auth_transaction, status_code;
+ u16 resp = WLAN_STATUS_SUCCESS;
+@@ -897,6 +898,11 @@ static void handle_auth(struct hostapd_d
+ char *identity = NULL;
+ char *radius_cui = NULL;
+ u16 seq_ctrl;
++ struct hostapd_ubus_request req = {
++ .type = HOSTAPD_UBUS_AUTH_REQ,
++ .mgmt_frame = mgmt,
++ .frame_info = fi,
++ };
+
+ if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
+ wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
+@@ -983,6 +989,14 @@ static void handle_auth(struct hostapd_d
+ resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ goto fail;
+ }
++
++ if (hostapd_ubus_handle_event(hapd, &req)) {
++ wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n",
++ MAC2STR(mgmt->sa));
++ resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
++ goto fail;
++ }
++
+ if (res == HOSTAPD_ACL_PENDING) {
+ wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
+ " waiting for an external authentication",
+@@ -1694,13 +1708,18 @@ static void send_assoc_resp(struct hosta
+
+ static void handle_assoc(struct hostapd_data *hapd,
+ const struct ieee80211_mgmt *mgmt, size_t len,
+- int reassoc)
++ int reassoc, struct hostapd_frame_info *fi)
+ {
+ u16 capab_info, listen_interval, seq_ctrl, fc;
+ u16 resp = WLAN_STATUS_SUCCESS;
+ const u8 *pos;
+ int left, i;
+ struct sta_info *sta;
++ struct hostapd_ubus_request req = {
++ .type = HOSTAPD_UBUS_ASSOC_REQ,
++ .mgmt_frame = mgmt,
++ .frame_info = fi,
++ };
+
+ if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
+ sizeof(mgmt->u.assoc_req))) {
+@@ -1820,6 +1839,13 @@ static void handle_assoc(struct hostapd_
+ goto fail;
+ }
+
++ if (hostapd_ubus_handle_event(hapd, &req)) {
++ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
++ MAC2STR(mgmt->sa));
++ resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
++ goto fail;
++ }
++
+ sta->capability = capab_info;
+ sta->listen_interval = listen_interval;
+
+@@ -2236,7 +2262,7 @@ int ieee802_11_mgmt(struct hostapd_data
+
+
+ if (stype == WLAN_FC_STYPE_PROBE_REQ) {
+- handle_probe_req(hapd, mgmt, len, fi->ssi_signal);
++ handle_probe_req(hapd, mgmt, len, fi);
+ return 1;
+ }
+
+@@ -2251,17 +2277,17 @@ int ieee802_11_mgmt(struct hostapd_data
+ switch (stype) {
+ case WLAN_FC_STYPE_AUTH:
+ wpa_printf(MSG_DEBUG, "mgmt::auth");
+- handle_auth(hapd, mgmt, len);
++ handle_auth(hapd, mgmt, len, fi);
+ ret = 1;
+ break;
+ case WLAN_FC_STYPE_ASSOC_REQ:
+ wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
+- handle_assoc(hapd, mgmt, len, 0);
++ handle_assoc(hapd, mgmt, len, 0, fi);
+ ret = 1;
+ break;
+ case WLAN_FC_STYPE_REASSOC_REQ:
+ wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
+- handle_assoc(hapd, mgmt, len, 1);
++ handle_assoc(hapd, mgmt, len, 1, fi);
+ ret = 1;
+ break;
+ case WLAN_FC_STYPE_DISASSOC:
+--- a/src/ap/beacon.c
++++ b/src/ap/beacon.c
+@@ -542,7 +542,7 @@ static enum ssid_match_result ssid_match
+
+ void handle_probe_req(struct hostapd_data *hapd,
+ const struct ieee80211_mgmt *mgmt, size_t len,
+- int ssi_signal)
++ struct hostapd_frame_info *fi)
+ {
+ u8 *resp;
+ struct ieee802_11_elems elems;
+@@ -550,8 +550,14 @@ void handle_probe_req(struct hostapd_dat
+ size_t ie_len;
+ struct sta_info *sta = NULL;
+ size_t i, resp_len;
++ int ssi_signal = fi->ssi_signal;
+ int noack;
+ enum ssid_match_result res;
++ struct hostapd_ubus_request req = {
++ .type = HOSTAPD_UBUS_PROBE_REQ,
++ .mgmt_frame = mgmt,
++ .frame_info = fi,
++ };
+
+ ie = mgmt->u.probe_req.variable;
+ if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
+@@ -710,6 +716,12 @@ void handle_probe_req(struct hostapd_dat
+ }
+ #endif /* CONFIG_P2P */
+
++ if (hostapd_ubus_handle_event(hapd, &req)) {
++ wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n",
++ MAC2STR(mgmt->sa));
++ return;
++ }
++
+ /* TODO: verify that supp_rates contains at least one matching rate
+ * with AP configuration */
+
+--- a/src/ap/beacon.h
++++ b/src/ap/beacon.h
+@@ -14,7 +14,7 @@ struct ieee80211_mgmt;
+
+ void handle_probe_req(struct hostapd_data *hapd,
+ const struct ieee80211_mgmt *mgmt, size_t len,
+- int ssi_signal);
++ struct hostapd_frame_info *fi);
+ int ieee802_11_set_beacon(struct hostapd_data *hapd);
+ int ieee802_11_set_beacons(struct hostapd_iface *iface);
+ int ieee802_11_update_beacons(struct hostapd_iface *iface);
+--- a/src/ap/drv_callbacks.c
++++ b/src/ap/drv_callbacks.c
+@@ -49,6 +49,10 @@ int hostapd_notif_assoc(struct hostapd_d
+ u16 reason = WLAN_REASON_UNSPECIFIED;
+ u16 status = WLAN_STATUS_SUCCESS;
+ const u8 *p2p_dev_addr = NULL;
++ struct hostapd_ubus_request req = {
++ .type = HOSTAPD_UBUS_ASSOC_REQ,
++ .addr = addr,
++ };
+
+ if (addr == NULL) {
+ /*
+@@ -113,6 +117,12 @@ int hostapd_notif_assoc(struct hostapd_d
+ }
+ sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
+
++ if (hostapd_ubus_handle_event(hapd, &req)) {
++ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
++ MAC2STR(req.addr));
++ goto fail;
++ }
++
+ #ifdef CONFIG_P2P
+ if (elems.p2p) {
+ wpabuf_free(sta->p2p_ie);
diff --git a/package/network/services/igmpproxy/Makefile b/package/network/services/igmpproxy/Makefile
new file mode 100644
index 0000000..03ad258
--- /dev/null
+++ b/package/network/services/igmpproxy/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2006-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:=igmpproxy
+PKG_VERSION:=0.1
+PKG_RELEASE:=8
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/igmpproxy
+PKG_MD5SUM:=c56f41ec195bc1fe016369bf74efc5a1
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+PKG_FIXUP:=autoreconf
+PKG_LICENSE:=GPL-2.0+
+
+define Package/igmpproxy
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Routing and Redirection
+ DEPENDS:=+USE_GLIBC:librt
+ TITLE:=Multicast Routing Daemon
+ URL:=http://sourceforge.net/projects/igmpproxy
+endef
+
+define Package/igmpproxy/description
+ IGMPproxy is a simple dynamic Multicast Routing Daemon using
+ only IGMP signalling (Internet Group Management Protocol).
+endef
+
+define Package/igmpproxy/conffiles
+/etc/config/igmpproxy
+endef
+
+TARGET_CFLAGS += -Dlog=igmpproxy_log
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR)/src \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -std=gnu99"
+endef
+
+define Package/igmpproxy/install
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_CONF) ./files/igmpproxy.config $(1)/etc/config/igmpproxy
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/igmpproxy.init $(1)/etc/init.d/igmpproxy
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/igmpproxy $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,igmpproxy))
diff --git a/package/network/services/igmpproxy/files/igmpproxy.config b/package/network/services/igmpproxy/files/igmpproxy.config
new file mode 100644
index 0000000..d290632
--- /dev/null
+++ b/package/network/services/igmpproxy/files/igmpproxy.config
@@ -0,0 +1,11 @@
+config igmpproxy
+ option quickleave 1
+
+config phyint wan
+ option network wan
+ option direction upstream
+ list altnet 192.168.1.0/24
+
+config phyint lan
+ option network lan
+ option direction downstream
diff --git a/package/network/services/igmpproxy/files/igmpproxy.init b/package/network/services/igmpproxy/files/igmpproxy.init
new file mode 100644
index 0000000..d03f90f
--- /dev/null
+++ b/package/network/services/igmpproxy/files/igmpproxy.init
@@ -0,0 +1,146 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2010-2014 OpenWrt.org
+
+START=99
+USE_PROCD=1
+PROG=/usr/sbin/igmpproxy
+CONFIGFILE=/var/etc/igmpproxy.conf
+
+# igmpproxy supports both a debug mode and verbosity, which are very useful
+# when something isn't working.
+#
+# Debug mode will print everything to stdout instead of syslog. Generally
+# verbosity should NOT be set as it will quickly fill your syslog.
+#
+# Put any debug or verbosity options into IGMP_OPTS
+#
+# Examples:
+# OPTIONS="-d -v -v" - debug mode and very verbose, this will land in
+# stdout and not in syslog
+# OPTIONS="-v" - be verbose, this will write aditional information to syslog
+
+OPTIONS=""
+
+igmp_header() {
+ local quickleave
+ config_get_bool quickleave "$1" quickleave 0
+
+ mkdir -p /var/etc
+ rm -f /var/etc/igmpproxy.conf
+ [ $quickleave -gt 0 ] && echo "quickleave" >> /var/etc/igmpproxy.conf
+
+ [ -L /etc/igmpproxy.conf ] || ln -nsf /var/etc/igmpproxy.conf /etc/igmpproxy.conf
+}
+
+igmp_add_phyint() {
+ local network direction altnets device up
+
+ config_get network $1 network
+ config_get direction $1 direction
+ config_get altnets $1 altnet
+
+ local status="$(ubus -S call "network.interface.$network" status)"
+ [ -n "$status" ] || return
+
+ json_load "$status"
+ json_get_var device l3_device
+ json_get_var up up
+
+ [ -n "$device" -a "$up" = "1" ] || {
+ procd_append_param error "$network is not up"
+ return;
+ }
+
+ append netdevs "$device"
+
+ [[ "$direction" = "upstream" ]] && has_upstream=1
+
+ echo -e "\nphyint $device $direction ratelimit 0 threshold 1" >> /var/etc/igmpproxy.conf
+
+ if [ -n "$altnets" ]; then
+ local altnet
+ for altnet in $altnets; do
+ echo -e "\taltnet $altnet" >> /var/etc/igmpproxy.conf
+ done
+ fi
+}
+
+igmp_add_network() {
+ local network
+
+ config_get network $1 network
+ procd_add_interface_trigger "interface.*" $network /etc/init.d/igmpproxy reload
+}
+
+igmp_add_firewall_routing() {
+ config_get network $1 network
+ config_get direction $1 direction
+
+ [[ "$direction" = "downstream" ]] || return 0
+
+ json_add_object ""
+ json_add_string type rule
+ json_add_string src "$upstream"
+ json_add_string dest "$network"
+ json_add_string family ipv4
+ json_add_string proto udp
+ json_add_string dest_ip "224.0.0.0/4"
+ json_add_string target ACCEPT
+ json_close_object
+}
+
+igmp_add_firewall_network() {
+ config_get network $1 network
+ config_get direction $1 direction
+
+ json_add_object ""
+ json_add_string type rule
+ json_add_string src "$network"
+ json_add_string proto igmp
+ json_add_string target ACCEPT
+ json_close_object
+
+ [[ "$direction" = "upstream" ]] && {
+ upstream="$network"
+ config_foreach igmp_add_firewall_routing phyint
+ }
+}
+
+service_triggers() {
+ procd_add_reload_trigger "igmpproxy"
+}
+
+start_service() {
+ has_upstream=
+ netdevs=
+ config_load igmpproxy
+
+ config_foreach igmp_header igmpproxy
+ config_foreach igmp_add_phyint phyint
+ [ -n "$has_upstream" ] || return
+
+ procd_open_instance
+ procd_set_param command $PROG
+ [ -n "$OPTIONS" ] && procd_append_param $OPTIONS
+ procd_append_param command $CONFIGFILE
+ procd_set_param file $CONFIGFILE
+ procd_set_param netdev $netdevs
+ procd_set_param respawn
+ procd_open_trigger
+ config_foreach igmp_add_network phyint
+ procd_close_trigger
+
+ procd_open_data
+
+ json_add_array firewall
+ config_foreach igmp_add_firewall_network phyint
+ json_close_array
+
+ procd_close_data
+
+ procd_close_instance
+}
+
+service_started() {
+ procd_set_config_changed firewall
+}
diff --git a/package/network/services/igmpproxy/patches/001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch b/package/network/services/igmpproxy/patches/001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch
new file mode 100644
index 0000000..ffe1cf1
--- /dev/null
+++ b/package/network/services/igmpproxy/patches/001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch
@@ -0,0 +1,79 @@
+From fed8c3db10bc9d3a1e799a774924c00522595d0c Mon Sep 17 00:00:00 2001
+From: Evgeny Yurchenko <evg.yurch@rogers.com>
+Date: Mon, 4 Jan 2010 05:13:59 +0500
+Subject: [PATCH] Send IGMP packets with IP Router Alert option [RFC 2113] included in IP header
+
+---
+ src/igmp.c | 17 ++++++++++++-----
+ src/igmpproxy.h | 1 +
+ 2 files changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/src/igmp.c b/src/igmp.c
+index a0cd27d..b547688 100644
+--- a/src/igmp.c
++++ b/src/igmp.c
+@@ -67,7 +67,7 @@ void initIgmp() {
+ * - Checksum (let the kernel fill it in)
+ */
+ ip->ip_v = IPVERSION;
+- ip->ip_hl = sizeof(struct ip) >> 2;
++ ip->ip_hl = (sizeof(struct ip) + 4) >> 2; /* +4 for Router Alert option */
+ ip->ip_tos = 0xc0; /* Internet Control */
+ ip->ip_ttl = MAXTTL; /* applies to unicasts only */
+ ip->ip_p = IPPROTO_IGMP;
+@@ -213,7 +213,7 @@ void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, i
+ ip = (struct ip *)send_buf;
+ ip->ip_src.s_addr = src;
+ ip->ip_dst.s_addr = dst;
+- ip_set_len(ip, MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen);
++ ip_set_len(ip, IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen);
+
+ if (IN_MULTICAST(ntohl(dst))) {
+ ip->ip_ttl = curttl;
+@@ -221,13 +221,20 @@ void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, i
+ ip->ip_ttl = MAXTTL;
+ }
+
+- igmp = (struct igmp *)(send_buf + MIN_IP_HEADER_LEN);
++ /* Add Router Alert option */
++ ((u_char*)send_buf+MIN_IP_HEADER_LEN)[0] = IPOPT_RA;
++ ((u_char*)send_buf+MIN_IP_HEADER_LEN)[1] = 0x04;
++ ((u_char*)send_buf+MIN_IP_HEADER_LEN)[2] = 0x00;
++ ((u_char*)send_buf+MIN_IP_HEADER_LEN)[3] = 0x00;
++
++ igmp = (struct igmp *)(send_buf + IP_HEADER_RAOPT_LEN);
+ igmp->igmp_type = type;
+ igmp->igmp_code = code;
+ igmp->igmp_group.s_addr = group;
+ igmp->igmp_cksum = 0;
+ igmp->igmp_cksum = inetChksum((u_short *)igmp,
+- IGMP_MINLEN + datalen);
++ IP_HEADER_RAOPT_LEN + datalen);
++
+ }
+
+ /*
+@@ -257,7 +264,7 @@ void sendIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, in
+ #endif
+ sdst.sin_addr.s_addr = dst;
+ if (sendto(MRouterFD, send_buf,
+- MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen, 0,
++ IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen, 0,
+ (struct sockaddr *)&sdst, sizeof(sdst)) < 0) {
+ if (errno == ENETDOWN)
+ my_log(LOG_ERR, errno, "Sender VIF was down.");
+diff --git a/src/igmpproxy.h b/src/igmpproxy.h
+index 0de7791..4df8a79 100644
+--- a/src/igmpproxy.h
++++ b/src/igmpproxy.h
+@@ -64,6 +64,7 @@
+ #define MAX_IP_PACKET_LEN 576
+ #define MIN_IP_HEADER_LEN 20
+ #define MAX_IP_HEADER_LEN 60
++#define IP_HEADER_RAOPT_LEN 24
+
+ #define MAX_MC_VIFS 32 // !!! check this const in the specific includes
+
+--
+1.7.2.5
+
diff --git a/package/network/services/igmpproxy/patches/002-Change-default-interface-state-to-disabled-wrt-29458.patch b/package/network/services/igmpproxy/patches/002-Change-default-interface-state-to-disabled-wrt-29458.patch
new file mode 100644
index 0000000..d7550d7
--- /dev/null
+++ b/package/network/services/igmpproxy/patches/002-Change-default-interface-state-to-disabled-wrt-29458.patch
@@ -0,0 +1,43 @@
+From 85e240727305b156097ee7aa0f0c4473a136291f Mon Sep 17 00:00:00 2001
+From: Constantin Baranov <const@mimas.ru>
+Date: Tue, 23 Feb 2010 21:08:02 +0400
+Subject: [PATCH] Change default interface state to disabled (wrt #2945877)
+
+---
+ src/ifvc.c | 2 +-
+ src/igmpproxy.c | 6 ++++--
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/src/ifvc.c b/src/ifvc.c
+index 545b3b4..9d7ee97 100644
+--- a/src/ifvc.c
++++ b/src/ifvc.c
+@@ -139,7 +139,7 @@ void buildIfVc() {
+ IfDescEp->allowednets->subnet_addr = subnet;
+
+ // Set the default params for the IF...
+- IfDescEp->state = IF_STATE_DOWNSTREAM;
++ IfDescEp->state = IF_STATE_DISABLED;
+ IfDescEp->robustness = DEFAULT_ROBUSTNESS;
+ IfDescEp->threshold = DEFAULT_THRESHOLD; /* ttl limit */
+ IfDescEp->ratelimit = DEFAULT_RATELIMIT;
+diff --git a/src/igmpproxy.c b/src/igmpproxy.c
+index 1ece15a..35000c7 100644
+--- a/src/igmpproxy.c
++++ b/src/igmpproxy.c
+@@ -186,8 +186,10 @@ int igmpProxyInit() {
+ }
+ }
+
+- addVIF( Dp );
+- vifcount++;
++ if (Dp->state != IF_STATE_DISABLED) {
++ addVIF( Dp );
++ vifcount++;
++ }
+ }
+ }
+
+--
+1.7.2.5
+
diff --git a/package/network/services/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch b/package/network/services/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch
new file mode 100644
index 0000000..90d4d5f
--- /dev/null
+++ b/package/network/services/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch
@@ -0,0 +1,164 @@
+From 65f777e7f66b55239d935c1cf81bb5abc0f6c89f Mon Sep 17 00:00:00 2001
+From: Grinch <grinch79@users.sourceforge.net>
+Date: Sun, 16 Aug 2009 19:58:26 +0500
+Subject: [PATCH] Restrict igmp reports for downstream interfaces (wrt #2833339)
+
+atm all igmp membership reports are forwarded to the upstream interface.
+Unfortunately some ISP Providers restrict some multicast groups (esp. those
+that are defined as local link groups and that are not supposed to be
+forwarded to the wan, i.e 224.0.0.0/24). Therefore there should be some
+kind of black oder whitelisting.
+As whitelisting can be accomplished quite easy I wrote a litte patch, which
+is attached to this request.
+---
+ doc/igmpproxy.conf.5.in | 19 +++++++++++++++++++
+ src/config.c | 23 ++++++++++++++++++++++-
+ src/igmpproxy.h | 1 +
+ src/request.c | 20 ++++++++++++++++----
+ 4 files changed, 58 insertions(+), 5 deletions(-)
+
+diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
+index a4ea7d0..56efa22 100644
+--- a/doc/igmpproxy.conf.5.in
++++ b/doc/igmpproxy.conf.5.in
+@@ -116,6 +116,25 @@ This is especially useful for the upstream interface, since the source for multi
+ traffic is often from a remote location. Any number of altnet parameters can be specified.
+ .RE
+
++.B whitelist
++.I networkaddr
++.RS
++Defines a whitelist for multicast groups. The network address must be in the following
++format 'a.b.c.d/n'. If you want to allow one single group use a network mask of /32,
++i.e. 'a.b.c.d/32'.
++
++By default all multicast groups are allowed on any downstream interface. If at least one
++whitelist entry is defined, all igmp membership reports for not explicitly whitelisted
++multicast groups will be ignored and therefore not be served by igmpproxy. This is especially
++useful, if your provider does only allow a predefined set of multicast groups. These whitelists
++are only obeyed by igmpproxy itself, they won't prevent any other igmp client running on the
++same machine as igmpproxy from requesting 'unallowed' multicast groups.
++
++You may specify as many whitelist entries as needed. Although you should keep it as simple as
++possible, as this list is parsed for every membership report and therefore this increases igmp
++response times. Often used or large groups should be defined first, as parsing ends as soon as
++a group matches an entry.
++.RE
+
+ .SH EXAMPLE
+ ## Enable quickleave
+diff --git a/src/config.c b/src/config.c
+index 5a96ce0..d72619f 100644
+--- a/src/config.c
++++ b/src/config.c
+@@ -46,6 +46,9 @@ struct vifconfig {
+
+ // Keep allowed nets for VIF.
+ struct SubnetList* allowednets;
++
++ // Allowed Groups
++ struct SubnetList* allowedgroups;
+
+ // Next config in list...
+ struct vifconfig* next;
+@@ -202,6 +205,8 @@ void configureVifs() {
+ // Insert the configured nets...
+ vifLast->next = confPtr->allowednets;
+
++ Dp->allowedgroups = confPtr->allowedgroups;
++
+ break;
+ }
+ }
+@@ -215,7 +220,7 @@ void configureVifs() {
+ */
+ struct vifconfig *parsePhyintToken() {
+ struct vifconfig *tmpPtr;
+- struct SubnetList **anetPtr;
++ struct SubnetList **anetPtr, **agrpPtr;
+ char *token;
+ short parseError = 0;
+
+@@ -239,6 +244,7 @@ struct vifconfig *parsePhyintToken() {
+ tmpPtr->threshold = 1;
+ tmpPtr->state = IF_STATE_DOWNSTREAM;
+ tmpPtr->allowednets = NULL;
++ tmpPtr->allowedgroups = NULL;
+
+ // Make a copy of the token to store the IF name
+ tmpPtr->name = strdup( token );
+@@ -248,6 +254,7 @@ struct vifconfig *parsePhyintToken() {
+
+ // Set the altnet pointer to the allowednets pointer.
+ anetPtr = &tmpPtr->allowednets;
++ agrpPtr = &tmpPtr->allowedgroups;
+
+ // Parse the rest of the config..
+ token = nextConfigToken();
+@@ -266,6 +273,20 @@ struct vifconfig *parsePhyintToken() {
+ anetPtr = &(*anetPtr)->next;
+ }
+ }
++ else if(strcmp("whitelist", token)==0) {
++ // Whitelist
++ token = nextConfigToken();
++ my_log(LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token);
++
++ *agrpPtr = parseSubnetAddress(token);
++ if(*agrpPtr == NULL) {
++ parseError = 1;
++ my_log(LOG_WARNING, 0, "Unable to parse subnet address.");
++ break;
++ } else {
++ agrpPtr = &(*agrpPtr)->next;
++ }
++ }
+ else if(strcmp("upstream", token)==0) {
+ // Upstream
+ my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token.");
+diff --git a/src/igmpproxy.h b/src/igmpproxy.h
+index 4dabd1c..0de7791 100644
+--- a/src/igmpproxy.h
++++ b/src/igmpproxy.h
+@@ -145,6 +145,7 @@ struct IfDesc {
+ short Flags;
+ short state;
+ struct SubnetList* allowednets;
++ struct SubnetList* allowedgroups;
+ unsigned int robustness;
+ unsigned char threshold; /* ttl limit */
+ unsigned int ratelimit;
+diff --git a/src/request.c b/src/request.c
+index e3589f6..89b91de 100644
+--- a/src/request.c
++++ b/src/request.c
+@@ -82,10 +82,22 @@ void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) {
+ my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d",
+ inetFmt(group,s1), inetFmt(src,s2), sourceVif->index);
+
+- // The membership report was OK... Insert it into the route table..
+- insertRoute(group, sourceVif->index);
+-
+-
++ // If we don't have a whitelist we insertRoute and done
++ if(sourceVif->allowedgroups == NULL)
++ {
++ insertRoute(group, sourceVif->index);
++ return;
++ }
++ // Check if this Request is legit on this interface
++ struct SubnetList *sn;
++ for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next)
++ if((group & sn->subnet_mask) == sn->subnet_addr)
++ {
++ // The membership report was OK... Insert it into the route table..
++ insertRoute(group, sourceVif->index);
++ return;
++ }
++ my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1));
+ } else {
+ // Log the state of the interface the report was recieved on.
+ my_log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.",
+--
+1.7.2.5
+
diff --git a/package/network/services/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch b/package/network/services/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch
new file mode 100644
index 0000000..a4caed7
--- /dev/null
+++ b/package/network/services/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch
@@ -0,0 +1,62 @@
+From bcd7c648e86d97263c931de53a008c9629e7797e Mon Sep 17 00:00:00 2001
+From: Stefan Becker <stefan.becker@nokia.com>
+Date: Fri, 11 Dec 2009 21:08:57 +0200
+Subject: [PATCH] Restrict igmp reports forwarding to upstream interface
+
+Utilize the new "whitelist" keyword also on the upstream interface definition.
+If specified then only whitelisted multicast groups will be forwarded upstream.
+
+This can be used to avoid publishing private multicast groups to the world,
+e.g. SSDP from a UPnP server on the internal network.
+---
+ doc/igmpproxy.conf.5.in | 5 +++++
+ src/rttable.c | 17 +++++++++++++++++
+ 2 files changed, 22 insertions(+), 0 deletions(-)
+
+diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
+index 56efa22..d916f05 100644
+--- a/doc/igmpproxy.conf.5.in
++++ b/doc/igmpproxy.conf.5.in
+@@ -134,6 +134,11 @@ You may specify as many whitelist entries as needed. Although you should keep it
+ possible, as this list is parsed for every membership report and therefore this increases igmp
+ response times. Often used or large groups should be defined first, as parsing ends as soon as
+ a group matches an entry.
++
++You may also specify whitelist entries for the upstream interface. Only igmp membership reports
++for explicitely whitelisted multicast groups will be sent out on the upstream interface. This
++is useful if you want to use multicast groups only between your downstream interfaces, like SSDP
++from a UPnP server.
+ .RE
+
+ .SH EXAMPLE
+diff --git a/src/rttable.c b/src/rttable.c
+index f0701a8..77dd791 100644
+--- a/src/rttable.c
++++ b/src/rttable.c
+@@ -117,6 +117,23 @@ void sendJoinLeaveUpstream(struct RouteTable* route, int join) {
+ my_log(LOG_ERR, 0 ,"FATAL: Unable to get Upstream IF.");
+ }
+
++ // Check if there is a white list for the upstram VIF
++ if (upstrIf->allowedgroups != NULL) {
++ uint32_t group = route->group;
++ struct SubnetList* sn;
++
++ // Check if this Request is legit to be forwarded to upstream
++ for(sn = upstrIf->allowedgroups; sn != NULL; sn = sn->next)
++ if((group & sn->subnet_mask) == sn->subnet_addr)
++ // Forward is OK...
++ break;
++
++ if (sn == NULL) {
++ my_log(LOG_INFO, 0, "The group address %s may not be forwarded upstream. Ignoring.", inetFmt(group, s1));
++ return;
++ }
++ }
++
+ // Send join or leave request...
+ if(join) {
+
+--
+1.7.2.5
+
diff --git a/package/network/services/igmpproxy/patches/010-missing_include.patch b/package/network/services/igmpproxy/patches/010-missing_include.patch
new file mode 100644
index 0000000..af0eab8
--- /dev/null
+++ b/package/network/services/igmpproxy/patches/010-missing_include.patch
@@ -0,0 +1,10 @@
+--- a/src/os-linux.h
++++ b/src/os-linux.h
+@@ -3,6 +3,7 @@
+ #include <linux/mroute.h>
+ #include <netinet/ip.h>
+ #include <netinet/igmp.h>
++#include <sys/types.h>
+
+ static inline u_short ip_data_len(const struct ip *ip)
+ {
diff --git a/package/network/services/igmpproxy/patches/020-Silence-downstream-interface-igmp-messages.patch b/package/network/services/igmpproxy/patches/020-Silence-downstream-interface-igmp-messages.patch
new file mode 100644
index 0000000..ccd000c
--- /dev/null
+++ b/package/network/services/igmpproxy/patches/020-Silence-downstream-interface-igmp-messages.patch
@@ -0,0 +1,19 @@
+--- a/src/igmp.c
++++ b/src/igmp.c
+@@ -139,8 +139,14 @@
+ return;
+ }
+ else if(!isAdressValidForIf(checkVIF, src)) {
+- my_log(LOG_WARNING, 0, "The source address %s for group %s, is not in any valid net for upstream VIF.",
+- inetFmt(src, s1), inetFmt(dst, s2));
++ struct IfDesc *downVIF = getIfByAddress(src);
++ if (downVIF && downVIF->state & IF_STATE_DOWNSTREAM) {
++ my_log(LOG_NOTICE, 0, "The source address %s for group %s is from downstream VIF. Ignoring.",
++ inetFmt(src, s1), inetFmt(dst, s2));
++ } else {
++ my_log(LOG_WARNING, 0, "The source address %s for group %s, is not in any valid net for upstream VIF.",
++ inetFmt(src, s1), inetFmt(dst, s2));
++ }
+ return;
+ }
+
diff --git a/package/network/services/igmpproxy/patches/100-use-monotic-clock-instead-of-time-of-day.patch b/package/network/services/igmpproxy/patches/100-use-monotic-clock-instead-of-time-of-day.patch
new file mode 100644
index 0000000..e75283c
--- /dev/null
+++ b/package/network/services/igmpproxy/patches/100-use-monotic-clock-instead-of-time-of-day.patch
@@ -0,0 +1,120 @@
+From d0e66e0719ae8eb549f7cc220fdc66575d3db332 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski@gmail.com>
+Date: Thu, 29 Mar 2012 17:01:11 +0200
+Subject: [PATCH 4/4] use monotic clock instead of time of day
+
+The time of day might chance e.g. by daylight savings time during the
+runtime, which causes timers to fire repeatedly for a long time.
+
+Contributed by T-Labs, Deutsche Telekom Innovation Laboratories
+
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ configure.ac | 2 ++
+ src/igmpproxy.c | 26 +++++++++++++-------------
+ src/igmpproxy.h | 3 ++-
+ 3 files changed, 17 insertions(+), 14 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 85beb08..bd84eba 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -25,6 +25,8 @@ AC_CHECK_MEMBERS([struct sockaddr_in.sin_len], [], [], [[
+ #include <netinet/in.h>
+ ]])
+
++AC_SEARCH_LIBS([clock_gettime],[rt])
++
+ AC_CONFIG_FILES([
+ Makefile
+ doc/Makefile
+diff --git a/src/igmpproxy.c b/src/igmpproxy.c
+index 35000c7..3a9ccad 100644
+--- a/src/igmpproxy.c
++++ b/src/igmpproxy.c
+@@ -234,13 +234,13 @@ void igmpProxyRun() {
+ int MaxFD, Rt, secs;
+ fd_set ReadFDS;
+ socklen_t dummy = 0;
+- struct timeval curtime, lasttime, difftime, tv;
++ struct timespec curtime, lasttime, difftime, tv;
+ // The timeout is a pointer in order to set it to NULL if nessecary.
+- struct timeval *timeout = &tv;
++ struct timespec *timeout = &tv;
+
+ // Initialize timer vars
+- difftime.tv_usec = 0;
+- gettimeofday(&curtime, NULL);
++ difftime.tv_nsec = 0;
++ clock_gettime(CLOCK_MONOTONIC, &curtime);
+ lasttime = curtime;
+
+ // First thing we send a membership query in downstream VIF's...
+@@ -263,7 +263,7 @@ void igmpProxyRun() {
+ if(secs == -1) {
+ timeout = NULL;
+ } else {
+- timeout->tv_usec = 0;
++ timeout->tv_nsec = 0;
+ timeout->tv_sec = secs;
+ }
+
+@@ -274,7 +274,7 @@ void igmpProxyRun() {
+ FD_SET( MRouterFD, &ReadFDS );
+
+ // wait for input
+- Rt = select( MaxFD +1, &ReadFDS, NULL, NULL, timeout );
++ Rt = pselect( MaxFD +1, &ReadFDS, NULL, NULL, timeout, NULL );
+
+ // log and ignore failures
+ if( Rt < 0 ) {
+@@ -307,20 +307,20 @@ void igmpProxyRun() {
+ */
+ if (Rt == 0) {
+ curtime.tv_sec = lasttime.tv_sec + secs;
+- curtime.tv_usec = lasttime.tv_usec;
++ curtime.tv_nsec = lasttime.tv_nsec;
+ Rt = -1; /* don't do this next time through the loop */
+ } else {
+- gettimeofday(&curtime, NULL);
++ clock_gettime(CLOCK_MONOTONIC, &curtime);
+ }
+ difftime.tv_sec = curtime.tv_sec - lasttime.tv_sec;
+- difftime.tv_usec += curtime.tv_usec - lasttime.tv_usec;
+- while (difftime.tv_usec > 1000000) {
++ difftime.tv_nsec += curtime.tv_nsec - lasttime.tv_nsec;
++ while (difftime.tv_nsec > 1000000000) {
+ difftime.tv_sec++;
+- difftime.tv_usec -= 1000000;
++ difftime.tv_nsec -= 1000000000;
+ }
+- if (difftime.tv_usec < 0) {
++ if (difftime.tv_nsec < 0) {
+ difftime.tv_sec--;
+- difftime.tv_usec += 1000000;
++ difftime.tv_nsec += 1000000000;
+ }
+ lasttime = curtime;
+ if (secs == 0 || difftime.tv_sec > 0)
+diff --git a/src/igmpproxy.h b/src/igmpproxy.h
+index 4df8a79..36a4f04 100644
+--- a/src/igmpproxy.h
++++ b/src/igmpproxy.h
+@@ -44,12 +44,13 @@
+ #include <string.h>
+ #include <fcntl.h>
+ #include <stdbool.h>
++#include <time.h>
+
+ #include <sys/socket.h>
+ #include <sys/un.h>
+-#include <sys/time.h>
+ #include <sys/ioctl.h>
+ #include <sys/param.h>
++#include <sys/select.h>
+
+ #include <net/if.h>
+ #include <netinet/in.h>
+--
+1.7.2.5
+
diff --git a/package/network/services/igmpproxy/patches/200-allow_wildcard_addr.patch b/package/network/services/igmpproxy/patches/200-allow_wildcard_addr.patch
new file mode 100644
index 0000000..0dd7720
--- /dev/null
+++ b/package/network/services/igmpproxy/patches/200-allow_wildcard_addr.patch
@@ -0,0 +1,24 @@
+--- a/src/config.c
++++ b/src/config.c
+@@ -357,15 +357,18 @@ struct SubnetList *parseSubnetAddress(ch
+ tmpStr = strtok(NULL, "/");
+ if(tmpStr != NULL) {
+ int bitcnt = atoi(tmpStr);
+- if(bitcnt <= 0 || bitcnt > 32) {
++ if(bitcnt < 0 || bitcnt > 32) {
+ my_log(LOG_WARNING, 0, "The bits part of the address is invalid : %d.",tmpStr);
+ return NULL;
+ }
+
+- mask <<= (32 - bitcnt);
++ if (bitcnt == 0)
++ mask = 0;
++ else
++ mask <<= (32 - bitcnt);
+ }
+
+- if(addr == -1 || addr == 0) {
++ if(addr == -1) {
+ my_log(LOG_WARNING, 0, "Unable to parse address token '%s'.", addrstr);
+ return NULL;
+ }
diff --git a/package/network/services/igmpproxy/patches/250-fix_multiple_downlink_interfaces.patch b/package/network/services/igmpproxy/patches/250-fix_multiple_downlink_interfaces.patch
new file mode 100644
index 0000000..24aefce
--- /dev/null
+++ b/package/network/services/igmpproxy/patches/250-fix_multiple_downlink_interfaces.patch
@@ -0,0 +1,154 @@
+--- a/src/igmpproxy.h
++++ b/src/igmpproxy.h
+@@ -251,6 +251,7 @@ int activateRoute(uint32_t group, uint32
+ void ageActiveRoutes();
+ void setRouteLastMemberMode(uint32_t group);
+ int lastMemberGroupAge(uint32_t group);
++int interfaceInRoute(int32_t group, int Ix);
+
+ /* request.c
+ */
+--- a/src/request.c
++++ b/src/request.c
+@@ -41,10 +41,10 @@
+
+ // Prototypes...
+ void sendGroupSpecificMemberQuery(void *argument);
+-
++
+ typedef struct {
+ uint32_t group;
+- uint32_t vifAddr;
++ // uint32_t vifAddr;
+ short started;
+ } GroupVifDesc;
+
+@@ -142,7 +142,7 @@ void acceptLeaveMessage(uint32_t src, ui
+
+ // Call the group spesific membership querier...
+ gvDesc->group = group;
+- gvDesc->vifAddr = sourceVif->InAdr.s_addr;
++ // gvDesc->vifAddr = sourceVif->InAdr.s_addr;
+ gvDesc->started = 0;
+
+ sendGroupSpecificMemberQuery(gvDesc);
+@@ -159,6 +159,9 @@ void acceptLeaveMessage(uint32_t src, ui
+ */
+ void sendGroupSpecificMemberQuery(void *argument) {
+ struct Config *conf = getCommonConfig();
++ struct IfDesc *Dp;
++ struct RouteTable *croute;
++ int Ix;
+
+ // Cast argument to correct type...
+ GroupVifDesc *gvDesc = (GroupVifDesc*) argument;
+@@ -166,22 +169,38 @@ void sendGroupSpecificMemberQuery(void *
+ if(gvDesc->started) {
+ // If aging returns false, we don't do any further action...
+ if(!lastMemberGroupAge(gvDesc->group)) {
++ // FIXME: Should we free gvDesc here?
+ return;
+ }
+ } else {
+ gvDesc->started = 1;
+ }
+
+- // Send a group specific membership query...
+- sendIgmp(gvDesc->vifAddr, gvDesc->group,
+- IGMP_MEMBERSHIP_QUERY,
+- conf->lastMemberQueryInterval * IGMP_TIMER_SCALE,
+- gvDesc->group, 0);
+-
+- my_log(LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d",
+- inetFmt(gvDesc->vifAddr,s1), inetFmt(gvDesc->group,s2),
+- conf->lastMemberQueryInterval);
+-
++ /**
++ * FIXME: This loops through all interfaces the group is active on an sends queries.
++ * It might be better to send only a query on the interface the leave was accepted on and remove only that interface from the route.
++ */
++
++ // Loop through all downstream interfaces
++ for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) {
++ if ( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) ) {
++ if(Dp->state == IF_STATE_DOWNSTREAM) {
++ // Is that interface used in the group?
++ if (interfaceInRoute(gvDesc->group ,Dp->index)) {
++
++ // Send a group specific membership query...
++ sendIgmp(Dp->InAdr.s_addr, gvDesc->group,
++ IGMP_MEMBERSHIP_QUERY,
++ conf->lastMemberQueryInterval * IGMP_TIMER_SCALE,
++ gvDesc->group, 0);
++
++ my_log(LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d",
++ inetFmt(Dp->InAdr.s_addr,s1), inetFmt(gvDesc->group,s2),
++ conf->lastMemberQueryInterval);
++ }
++ }
++ }
++ }
+ // Set timeout for next round...
+ timer_setTimer(conf->lastMemberQueryInterval, sendGroupSpecificMemberQuery, gvDesc);
+
+--- a/src/rttable.c
++++ b/src/rttable.c
+@@ -428,6 +428,25 @@ void ageActiveRoutes() {
+ }
+
+ /**
++* Counts the number of interfaces a given route is active on
++*/
++int numberOfInterfaces(struct RouteTable *croute) {
++ int Ix;
++ struct IfDesc *Dp;
++ int result = 0;
++ // Loop through all interfaces
++ for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) {
++ // If the interface is used by the route, increase counter
++ if(BIT_TST(croute->vifBits, Dp->index)) {
++ result++;
++ }
++ }
++ my_log(LOG_DEBUG, 0, "counted %d interfaces", result);
++ return result;
++}
++
++
++/**
+ * Should be called when a leave message is recieved, to
+ * mark a route for the last member probe state.
+ */
+@@ -439,8 +458,11 @@ void setRouteLastMemberMode(uint32_t gro
+ if(croute!=NULL) {
+ // Check for fast leave mode...
+ if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) {
+- // Send a leave message right away..
+- sendJoinLeaveUpstream(croute, 0);
++ // Send a leave message right away only when the route has been active on only one interface
++ if (numberOfInterfaces(croute) <= 1) {
++ my_log(LOG_DEBUG, 0, "Leaving group %d now", group);
++ sendJoinLeaveUpstream(croute, 0);
++ }
+ }
+ // Set the routingstate to Last member check...
+ croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER;
+@@ -677,3 +699,18 @@ void logRouteTable(char *header) {
+
+ my_log(LOG_DEBUG, 0, "-----------------------------------------------------");
+ }
++
++/**
++* Returns true when the given group belongs to the given interface
++*/
++int interfaceInRoute(int32_t group, int Ix) {
++ struct RouteTable* croute;
++ croute = findRoute(group);
++ if (croute != NULL) {
++ my_log(LOG_DEBUG, 0, "Interface id %d is in group $d", Ix, group);
++ return BIT_TST(croute->vifBits, Ix);
++ } else {
++ return 0;
++ }
++}
++
diff --git a/package/network/services/ipset-dns/Makefile b/package/network/services/ipset-dns/Makefile
new file mode 100644
index 0000000..37cf7c5
--- /dev/null
+++ b/package/network/services/ipset-dns/Makefile
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2013 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:=ipset-dns
+PKG_VERSION:=2013-05-03
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=http://git.zx2c4.com/ipset-dns
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=6be3afd819a86136b51c5ae722ab48266187155b
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ipset-dns/Default
+endef
+
+define Package/ipset-dns
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=A lightweight DNS forwarder to populate ipsets
+ URL:=http://git.zx2c4.com/ipset-dns/about/
+ DEPENDS:=+libmnl
+endef
+
+define Package/ipset-dns/description
+ The ipset-dns daemon is a lightweight DNS forwarding server that adds all
+ resolved IPs to a given netfilter ipset. It is designed to be used in
+ conjunction with dnsmasq's upstream server directive.
+
+ Practical use cases include routing over a given gateway traffic for
+ particular web services or webpages that do not have a priori predictable
+ IP addresses and instead rely on dizzying arrays of DNS resolutions.
+endef
+
+define Package/ipset-dns/conffiles
+/etc/config/ipset-dns
+endef
+
+define Package/ipset-dns/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ipset-dns $(1)/usr/sbin/ipset-dns
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/ipset-dns.init $(1)/etc/init.d/ipset-dns
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_CONF) ./files/ipset-dns.config $(1)/etc/config/ipset-dns
+endef
+
+$(eval $(call BuildPackage,ipset-dns))
diff --git a/package/network/services/ipset-dns/files/ipset-dns.config b/package/network/services/ipset-dns/files/ipset-dns.config
new file mode 100644
index 0000000..0270366
--- /dev/null
+++ b/package/network/services/ipset-dns/files/ipset-dns.config
@@ -0,0 +1,16 @@
+# declare an ipset-dns listener instance, multiple allowed
+config ipset-dns
+ # use given ipset for type A (IPv4) responses
+ option ipset 'domain-filter-ipv4'
+
+ # use given ipset for type AAAA (IPv6) responses
+ option ipset6 'domain-filter-ipv6'
+
+ # use given listening port
+ # defaults to 53000 + instance number
+ #option port '53001'
+
+ # use given upstream DNS server,
+ # defaults to first entry in /tmp/resolv.conf.auto
+ #option dns '8.8.8.8'
+
diff --git a/package/network/services/ipset-dns/files/ipset-dns.init b/package/network/services/ipset-dns/files/ipset-dns.init
new file mode 100755
index 0000000..0a76fcc
--- /dev/null
+++ b/package/network/services/ipset-dns/files/ipset-dns.init
@@ -0,0 +1,57 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2013 OpenWrt.org
+
+START=61
+
+USE_PROCD=1
+
+find_nameserver() {
+ . /lib/functions/network.sh
+
+ local tmp
+ if network_find_wan tmp && network_get_dnsserver tmp "$tmp"; then
+ echo "${tmp%% *}"
+ return 0
+ fi
+
+ return 1
+}
+
+start_instance() {
+ local cfg="$1"
+ local ipset ipset6 port dns
+
+ config_get ipset "$cfg" ipset
+ config_get ipset6 "$cfg" ipset6
+ [ -n "$ipset$ipset6" ] || {
+ echo "No ipset specified for instance $cfg" >&2
+ return 1
+ }
+
+ config_get dns "$cfg" dns "$DEFNS"
+ [ -n "$dns" ] || {
+ echo "No DNS server specified for instance $cfg" >&2
+ return 1
+ }
+
+ config_get port "$cfg" port $((PORT++))
+
+ procd_open_instance
+ procd_set_param command /usr/sbin/ipset-dns "$ipset" "$ipset6" "$port" "$dns"
+ procd_set_param env NO_DAEMONIZE=1
+ procd_set_param respawn
+ procd_close_instance
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger "ipset-dns"
+}
+
+start_service() {
+ PORT=53001
+ DEFNS="$(find_nameserver)"
+
+ config_load ipset-dns
+ config_foreach start_instance ipset-dns
+}
diff --git a/package/network/services/ipset-dns/patches/100-simultaneous-ipv4-ipv6.patch b/package/network/services/ipset-dns/patches/100-simultaneous-ipv4-ipv6.patch
new file mode 100644
index 0000000..19669a0
--- /dev/null
+++ b/package/network/services/ipset-dns/patches/100-simultaneous-ipv4-ipv6.patch
@@ -0,0 +1,57 @@
+--- a/ipset-dns.c
++++ b/ipset-dns.c
+@@ -307,19 +307,20 @@ int main(int argc, char *argv[])
+ struct timeval tv;
+ char msg[512];
+ char ip[INET6_ADDRSTRLEN];
+- char *ipset;
++ char *ipset, *ipset6;
+ int listen_sock, upstream_sock;
+ int pos, i, size, af;
+ socklen_t len;
+ size_t received;
+ pid_t child;
+
+- if (argc != 4) {
+- fprintf(stderr, "Usage: %s ipset port upstream\n", argv[0]);
++ if (argc != 5) {
++ fprintf(stderr, "Usage: %s ipv4-ipset ipv6-ipset port upstream\n", argv[0]);
+ return 1;
+ }
+
+ ipset = argv[1];
++ ipset6 = argv[2];
+
+ listen_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (listen_sock < 0) {
+@@ -329,7 +330,7 @@ int main(int argc, char *argv[])
+
+ memset(&listen_addr, 0, sizeof(listen_addr));
+ listen_addr.sin_family = AF_INET;
+- listen_addr.sin_port = htons(atoi(argv[2]));
++ listen_addr.sin_port = htons(atoi(argv[3]));
+ listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ i = 1;
+ setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
+@@ -341,7 +342,7 @@ int main(int argc, char *argv[])
+ memset(&upstream_addr, 0, sizeof(upstream_addr));
+ upstream_addr.sin_family = AF_INET;
+ upstream_addr.sin_port = htons(53);
+- inet_aton(argv[3], &upstream_addr.sin_addr);
++ inet_aton(argv[4], &upstream_addr.sin_addr);
+
+ /* TODO: Put all of the below code in several forks all listening on the same sock. */
+
+@@ -434,8 +435,11 @@ int main(int argc, char *argv[])
+ continue;
+ }
+
++ if ((af == AF_INET && !*ipset) || (af == AF_INET6 && !*ipset6))
++ continue;
++
+ printf("%s: %s\n", answer.dotted, ip);
+- if (add_to_ipset(ipset, answer.rdata, af) < 0)
++ if (add_to_ipset((af == AF_INET) ? ipset : ipset6, answer.rdata, af) < 0)
+ perror("add_to_ipset");
+ }
+
diff --git a/package/network/services/lldpd/Config.in b/package/network/services/lldpd/Config.in
new file mode 100644
index 0000000..93d84e2
--- /dev/null
+++ b/package/network/services/lldpd/Config.in
@@ -0,0 +1,54 @@
+menu "Configuration"
+ depends on PACKAGE_lldpd
+
+config LLDPD_WITH_PRIVSEP
+ bool
+ default y
+ prompt "Enable privilege separation (run lldpd with a chrooted 'lldp' user)"
+
+config LLDPD_WITH_CDP
+ bool
+ default y
+ prompt "Enable support for the Cisco Discovery Protocol (CDP) version 1 and 2"
+
+config LLDPD_WITH_FDP
+ bool
+ default y
+ prompt "Enable support for the Foundry Discovery Protocol (FDP)"
+
+config LLDPD_WITH_EDP
+ bool
+ default y
+ prompt "Enable support for the Extreme Discovery Protocol (EDP)"
+
+config LLDPD_WITH_SONMP
+ bool
+ default y
+ prompt "Enable support for the SynOptics Network Management Protocol"
+
+config LLDPD_WITH_LLDPMED
+ bool
+ prompt "Enable LLDP-MED extension"
+ default y
+
+config LLDPD_WITH_DOT1
+ bool
+ prompt "Enable Dot1 extension (VLAN stuff)"
+ default y
+
+config LLDPD_WITH_DOT3
+ bool
+ prompt "Enable Dot3 extension (PHY stuff)"
+ default y
+
+config LLDPD_WITH_CUSTOM
+ bool
+ prompt "Enable Custom TLVs"
+ default y
+
+config LLDPD_WITH_JSON
+ bool
+ prompt "Enable JSON output for the LLDP Command-Line Interface"
+ default n
+
+endmenu
diff --git a/package/network/services/lldpd/Makefile b/package/network/services/lldpd/Makefile
new file mode 100644
index 0000000..81e4a8f
--- /dev/null
+++ b/package/network/services/lldpd/Makefile
@@ -0,0 +1,108 @@
+#
+# Copyright (C) 2008-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:=lldpd
+PKG_VERSION:=0.7.15
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://media.luffy.cx/files/lldpd
+PKG_MD5SUM:=46f7ad97fc1d04084ab11b32fc0ed708
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=ISC
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+TARGET_CFLAGS+=--std=c99
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/lldpd
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Routing and Redirection
+ TITLE:=Link Layer Discovery Protocol daemon
+ URL:=https://github.com/vincentbernat/lldpd/wiki
+ DEPENDS:=+libevent2 +USE_GLIBC:libbsd +LLDPD_WITH_JSON:libjson-c
+ USERID:=lldp=121:lldp=129
+ MENU:=1
+endef
+
+define Package/lldpd/config
+source "$(SOURCE)/Config.in"
+endef
+
+define Package/lldpd/description
+ LLDP (Link Layer Discovery Protocol) is an industry standard protocol designed
+ to supplant proprietary Link-Layer protocols such as
+ Extreme's EDP (Extreme Discovery Protocol) and
+ CDP (Cisco Discovery Protocol).
+ The goal of LLDP is to provide an inter-vendor compatible mechanism to deliver
+ Link-Layer notifications to adjacent network devices.
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/liblldpctl.so* $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/lldpctl.h $(1)/usr/include/lldpctl.h
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/lldp-const.h $(1)/usr/include/lldp-const.h
+endef
+
+define Package/lldpd/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_DIR) $(1)/etc/lldpd.d
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_DIR) $(1)/usr/lib $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/lldp{cli,ctl,d} $(1)/usr/sbin/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/liblldpctl.so* $(1)/usr/lib/
+ $(INSTALL_BIN) ./files/lldpd.init $(1)/etc/init.d/lldpd
+ $(INSTALL_DATA) ./files/lldpd.config $(1)/etc/config/lldpd
+ifneq ($(CONFIG_LLDPD_WITH_CDP),y)
+ sed -i -e '/cdp/d' $(1)/etc/init.d/lldpd $(1)/etc/config/lldpd
+endif
+ifneq ($(CONFIG_LLDPD_WITH_FDP),y)
+ sed -i -e '/fdp/d' $(1)/etc/init.d/lldpd $(1)/etc/config/lldpd
+endif
+ifneq ($(CONFIG_LLDPD_WITH_EDP),y)
+ sed -i -e '/edp/d' $(1)/etc/init.d/lldpd $(1)/etc/config/lldpd
+endif
+ifneq ($(CONFIG_LLDPD_WITH_SONMP),y)
+ sed -i -e '/sonmp/d' $(1)/etc/init.d/lldpd $(1)/etc/config/lldpd
+endif
+endef
+
+define Package/lldpd/conffiles
+/etc/config/lldpd
+endef
+
+CONFIGURE_ARGS += \
+ $(if $(CONFIG_LLDPD_WITH_PRIVSEP), \
+ --with-privsep-user=lldp \
+ --with-privsep-group=lldp \
+ --with-privsep-chroot=/var/run/lldp \
+ ,--disable-privsep) \
+ --with-readline=no \
+ --with-embedded-libevent=no \
+ --disable-hardening \
+ --without-xml \
+ $(if $(CONFIG_LLDPD_WITH_CDP),,--disable-cdp) \
+ $(if $(CONFIG_LLDPD_WITH_FDP),,--disable-fdp) \
+ $(if $(CONFIG_LLDPD_WITH_EDP),,--disable-edp) \
+ $(if $(CONFIG_LLDPD_WITH_LLDPMED),,--disable-lldpmed) \
+ $(if $(CONFIG_LLDPD_WITH_DOT1),,--disable-dot1) \
+ $(if $(CONFIG_LLDPD_WITH_DOT3),,--disable-dot3) \
+ $(if $(CONFIG_LLDPD_WITH_CUSTOM),,--disable-custom) \
+ $(if $(CONFIG_LLDPD_WITH_SONMP),,--disable-sonmp) \
+ $(if $(CONFIG_LLDPD_WITH_JSON),--with-json=json-c,--with-json=no)
+
+
+$(eval $(call BuildPackage,lldpd))
diff --git a/package/network/services/lldpd/files/lldpd.config b/package/network/services/lldpd/files/lldpd.config
new file mode 100644
index 0000000..48728e0
--- /dev/null
+++ b/package/network/services/lldpd/files/lldpd.config
@@ -0,0 +1,15 @@
+config lldpd config
+ option enable_cdp 1
+ option enable_fdp 1
+ option enable_sonmp 1
+ option enable_edp 1
+
+ option lldp_class 4
+ option lldp_location "2:FR:6:Commercial Rd:3:Roseville:19:4"
+
+ # if empty, the distribution description is sent
+ #option lldp_description "OpenWrt System"
+
+ # interfaces to listen on
+ list interface "loopback"
+ list interface "lan"
diff --git a/package/network/services/lldpd/files/lldpd.init b/package/network/services/lldpd/files/lldpd.init
new file mode 100644
index 0000000..04e5b8c
--- /dev/null
+++ b/package/network/services/lldpd/files/lldpd.init
@@ -0,0 +1,93 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2008-2012 OpenWrt.org
+
+START=90
+
+USE_PROCD=1
+LLDPCLI=/usr/sbin/lldpcli
+LLDPSOCKET=/var/run/lldpd.socket
+
+find_release_info()
+{
+ [ -s /etc/openwrt_release ] && . /etc/openwrt_release
+ [ -z "$DISTRIB_DESCRIPTION" ] && [ -s /etc/openwrt_version ] && \
+ DISTRIB_DESCRIPTION="$(cat /etc/openwrt_version)"
+
+ echo "${DISTRIB_DESCRIPTION:-Unknown OpenWrt release} @ $(cat /proc/sys/kernel/hostname)"
+}
+
+start_service() {
+ . /lib/functions/network.sh
+
+ local enable_cdp
+ local enable_fdp
+ local enable_sonmp
+ local enable_edp
+ local lldp_class
+ local lldp_location
+ local lldp_description
+ local readonly_mode
+
+ config_load 'lldpd'
+ config_get_bool enable_cdp 'config' 'enable_cdp' 0
+ config_get_bool enable_fdp 'config' 'enable_fdp' 0
+ config_get_bool enable_sonmp 'config' 'enable_sonmp' 0
+ config_get_bool enable_edp 'config' 'enable_edp' 0
+ config_get lldp_class 'config' 'lldp_class'
+ config_get lldp_location 'config' 'lldp_location'
+ config_get lldp_description 'config' 'lldp_description' "$(find_release_info)"
+ config_get_bool readonly_mode 'config' 'readonly_mode' 0
+
+ local ifaces
+ config_get ifaces 'config' 'interface'
+
+ local iface ifnames=""
+ for iface in $ifaces; do
+ local ifname=""
+ if network_get_device ifname "$iface" || [ -e "/sys/class/net/$iface" ]; then
+ append ifnames "${ifname:-$iface}" ","
+ fi
+ done
+
+ mkdir -p /var/run/lldp
+ chown lldp:lldp /var/run/lldp
+
+ procd_open_instance
+ procd_set_param command /usr/sbin/lldpd
+ procd_append_param command -d # don't daemonize, procd will handle that for us
+
+ [ -n "$ifnames" ] && procd_append_param command -I "$ifnames"
+ [ $enable_cdp -gt 0 ] && procd_append_param command '-c'
+ [ $enable_fdp -gt 0 ] && procd_append_param command '-f'
+ [ $enable_sonmp -gt 0 ] && procd_append_param command '-s'
+ [ $enable_edp -gt 0 ] && procd_append_param command '-e'
+ [ $readonly_mode -gt 0 ] && procd_append_param command '-r'
+ [ -n "$lldp_class" ] && procd_append_param command -M "$lldp_class"
+ [ -n "$lldp_description" ] && procd_append_param command -S "$lldp_description"
+
+ # set auto respawn behavior
+ procd_set_param respawn
+ procd_append_param respawn 3600
+ procd_append_param respawn 5
+ procd_append_param respawn -1
+ procd_close_instance
+}
+
+service_running() {
+ pgrep -x /usr/sbin/lldpd &> /dev/null
+}
+
+reload_service() {
+ running || return 1
+ # Custom TLVs are special and should be
+ # reloaded from config during lldpd reload
+ $LLDPCLI -u $LLDPSOCKET unconfigure lldp custom-tlv &> /dev/null
+ $LLDPCLI -u $LLDPSOCKET -c /etc/lldpd.conf -c /etc/lldpd.d &> /dev/null
+ # Broadcast update over the wire
+ $LLDPCLI -u $LLDPSOCKET update &> /dev/null
+ return 0
+}
+
+stop_service() {
+ rm -rf /var/run/lldp $LLDPSOCKET
+}
diff --git a/package/network/services/lldpd/patches/100-os-release.patch b/package/network/services/lldpd/patches/100-os-release.patch
new file mode 100644
index 0000000..a906f39
--- /dev/null
+++ b/package/network/services/lldpd/patches/100-os-release.patch
@@ -0,0 +1,39 @@
+Index: lldpd-0.7.15/src/daemon/lldpd.c
+===================================================================
+--- lldpd-0.7.15.orig/src/daemon/lldpd.c
++++ lldpd-0.7.15/src/daemon/lldpd.c
+@@ -736,6 +736,10 @@ lldpd_get_os_release() {
+ fp = fopen("/usr/lib/os-release", "r");
+ }
+ if (!fp) {
++ log_debug("localchassis", "could not open /usr/lib/os-release");
++ fp = fopen("/etc/openwrt_release", "r");
++ }
++ if (!fp) {
+ log_info("localchassis",
+ "could not open either /etc/os-release or /usr/lib/os-release");
+ return NULL;
+@@ -745,7 +749,8 @@ lldpd_get_os_release() {
+ key = strtok(line, "=");
+ val = strtok(NULL, "=");
+
+- if (strncmp(key, "PRETTY_NAME", sizeof(line)) == 0) {
++ if (strncmp(key, "PRETTY_NAME", sizeof(line)) == 0 ||
++ strncmp(key, "DISTRIB_DESCRIPTION", sizeof(line)) == 0) {
+ strlcpy(release, val, sizeof(line));
+ break;
+ }
+@@ -755,11 +760,11 @@ lldpd_get_os_release() {
+ /* Remove trailing newline and all " in the string. */
+ ptr1 = release + strlen(release) - 1;
+ while (ptr1 != release &&
+- ((*ptr1 == '"') || (*ptr1 == '\n'))) {
++ ((*ptr1 == '"') || (*ptr1 == '\n') || (*ptr1 == '\''))) {
+ *ptr1 = '\0';
+ ptr1--;
+ }
+- if (release[0] == '"')
++ if (release[0] == '"' || release[0] == '\'')
+ return release+1;
+ return release;
+ }
diff --git a/package/network/services/mdns/Makefile b/package/network/services/mdns/Makefile
new file mode 100644
index 0000000..74e2693
--- /dev/null
+++ b/package/network/services/mdns/Makefile
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 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:=mdns
+PKG_VERSION:=2015-09-03
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=git://git.openwrt.org/project/mdnsd.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=ae8773477c31b741ba8b47f8898e4c0a1c834b85
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=LGPL-2.1
+
+include $(INCLUDE_DIR)/package-seccomp.mk
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/mdns
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=OpenWrt Multicast DNS Daemon
+ DEPENDS:=+libubox +libubus +libblobmsg-json
+endef
+
+TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
+
+define Package/mdns/conffiles
+/etc/config/mdns
+endef
+
+define Package/mdns/install
+ $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/mdns $(1)/usr/sbin/
+ $(INSTALL_BIN) ./files/mdns.init $(1)/etc/init.d/mdns
+ $(INSTALL_CONF) ./files/mdns.config $(1)/etc/config/mdns
+ $(call InstallSeccomp,$(1),./files/mdns.json)
+endef
+
+$(eval $(call BuildPackage,mdns))
diff --git a/package/network/services/mdns/files/mdns.config b/package/network/services/mdns/files/mdns.config
new file mode 100644
index 0000000..b09eaf5
--- /dev/null
+++ b/package/network/services/mdns/files/mdns.config
@@ -0,0 +1,3 @@
+config mdns
+ option jail 1
+ list network lan
diff --git a/package/network/services/mdns/files/mdns.init b/package/network/services/mdns/files/mdns.init
new file mode 100644
index 0000000..c0f9155
--- /dev/null
+++ b/package/network/services/mdns/files/mdns.init
@@ -0,0 +1,54 @@
+#!/bin/sh /etc/rc.common
+# Copyright (c) 2014 OpenWrt.org
+
+. /lib/functions/network.sh
+
+START=80
+
+USE_PROCD=1
+PROG=/usr/sbin/mdns
+IFACES=""
+
+load_ifaces() {
+ local network="$(uci get mdns.@mdns[-1].network)"
+ for n in $network; do
+ local device
+ json_load "$(ifstatus $n)"
+ json_get_var device l3_device
+ echo -n "$device "
+ done
+}
+
+reload_service() {
+ json_init
+ json_add_array interfaces
+ for i in $(load_ifaces); do
+ json_add_string "" "$i"
+ done
+ json_close_array
+
+ ubus call mdns set_config "$(json_dump)"
+}
+
+start_service() {
+ local network="$(uci get mdns.@mdns[-1].network)"
+
+ procd_open_instance
+ procd_set_param command "$PROG"
+ procd_set_param seccomp /etc/seccomp/mdns.json
+ procd_set_param respawn
+ procd_open_trigger
+ procd_add_config_trigger "config.change" "mdns" /etc/init.d/mdns reload
+ for n in $network; do
+ procd_add_interface_trigger "interface.*" $n /etc/init.d/mdns reload
+ done
+ procd_add_raw_trigger "instance.update" 5000 "/bin/ubus" "call" "mdns" "reload"
+ procd_close_trigger
+ [ "$(uci get mdns.@mdns[-1].jail)" = 1 ] && procd_add_jail mdns ubus log
+ procd_close_instance
+}
+
+service_started() {
+ ubus -t 10 wait_for mdns
+ [ $? = 0 ] && reload_service
+}
diff --git a/package/network/services/mdns/files/mdns.json b/package/network/services/mdns/files/mdns.json
new file mode 100644
index 0000000..c22ba6f
--- /dev/null
+++ b/package/network/services/mdns/files/mdns.json
@@ -0,0 +1,32 @@
+{
+ "whitelist": [
+ "read",
+ "write",
+ "open",
+ "close",
+ "time",
+ "brk",
+ "ioctl",
+ "uname",
+ "bind",
+ "connect",
+ "getsockname",
+ "recvmsg",
+ "sendmsg",
+ "sendto",
+ "setsockopt",
+ "socket",
+ "poll",
+ "fcntl64",
+ "epoll_create",
+ "epoll_ctl",
+ "epoll_wait",
+ "rt_sigaction",
+ "sigreturn",
+ "rt_sigreturn",
+ "exit_group",
+ "exit",
+ "clock_gettime"
+ ],
+ "policy": 1
+}
diff --git a/package/network/services/odhcpd/Makefile b/package/network/services/odhcpd/Makefile
new file mode 100644
index 0000000..0ec4769
--- /dev/null
+++ b/package/network/services/odhcpd/Makefile
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2013 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:=odhcpd
+PKG_VERSION:=2015-09-07-1
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=git://github.com/sbyx/odhcpd.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=cb1842c117030e6779f9556cd5d86b1a0ef145d7
+
+PKG_MAINTAINER:=Steven Barth <steven@midlink.org>
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS += -DUBUS=1
+
+ifneq ($(CONFIG_PACKAGE_odhcpd_ext_cer_id),0)
+ CMAKE_OPTIONS += -DEXT_CER_ID=$(CONFIG_PACKAGE_odhcpd_ext_cer_id)
+endif
+
+
+define Package/odhcpd
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=OpenWrt DHCP/DHCPv6(-PD)/RA Server & Relay
+ DEPENDS:=+libubox +libuci +libubus
+endef
+
+define Package/odhcpd/config
+ config PACKAGE_odhcpd_ext_cer_id
+ int "CER-ID Extension ID (0 = disabled)"
+ depends on PACKAGE_odhcpd
+ default 0
+endef
+
+define Package/odhcpd/description
+ odhcpd is a daemon for serving and relaying IP management protocols to
+ configure clients and downstream routers. It tries to follow the RFC 6204
+ requirements for IPv6 home routers.
+
+ odhcpd provides server services for DHCP, RA, stateless and stateful DHCPv6,
+ prefix delegation and can be used to relay RA, DHCPv6 and NDP between routed
+ (non-bridged) interfaces in case no delegated prefixes are available.
+endef
+
+define Package/odhcpd/install
+ $(INSTALL_DIR) $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/odhcpd $(1)/usr/sbin/
+ $(INSTALL_BIN) ./files/odhcpd-update $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/odhcpd.init $(1)/etc/init.d/odhcpd
+ $(INSTALL_DIR) $(1)/etc/uci-defaults
+ $(INSTALL_BIN) ./files/odhcpd.defaults $(1)/etc/uci-defaults
+endef
+
+$(eval $(call BuildPackage,odhcpd))
diff --git a/package/network/services/odhcpd/files/odhcpd-update b/package/network/services/odhcpd/files/odhcpd-update
new file mode 100755
index 0000000..e17cd0b
--- /dev/null
+++ b/package/network/services/odhcpd/files/odhcpd-update
@@ -0,0 +1,5 @@
+#!/bin/sh
+# Make dnsmasq reread hostfile
+
+pid=$(pidof dnsmasq)
+[ "$(readlink /proc/$pid/exe)" = "/usr/sbin/dnsmasq" ] && kill -SIGHUP $pid
diff --git a/package/network/services/odhcpd/files/odhcpd.defaults b/package/network/services/odhcpd/files/odhcpd.defaults
new file mode 100644
index 0000000..d079ec0
--- /dev/null
+++ b/package/network/services/odhcpd/files/odhcpd.defaults
@@ -0,0 +1,13 @@
+#!/bin/sh
+uci -q get dhcp.odhcpd && exit 0
+touch /etc/config/dhcp
+
+uci batch <<EOF
+set dhcp.odhcpd=odhcpd
+set dhcp.odhcpd.maindhcp=0
+set dhcp.odhcpd.leasefile=/tmp/hosts/odhcpd
+set dhcp.odhcpd.leasetrigger=/usr/sbin/odhcpd-update
+set dhcp.lan.dhcpv6=server
+set dhcp.lan.ra=server
+commit dhcp
+EOF
diff --git a/package/network/services/odhcpd/files/odhcpd.init b/package/network/services/odhcpd/files/odhcpd.init
new file mode 100644
index 0000000..c8a3114
--- /dev/null
+++ b/package/network/services/odhcpd/files/odhcpd.init
@@ -0,0 +1,18 @@
+#!/bin/sh /etc/rc.common
+
+START=35
+STOP=85
+USE_PROCD=1
+
+start_service() {
+ procd_open_instance
+ procd_set_param command /usr/sbin/odhcpd
+ procd_set_param respawn
+ procd_close_instance
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger "dhcp"
+}
+
diff --git a/package/network/services/omcproxy/Makefile b/package/network/services/omcproxy/Makefile
new file mode 100644
index 0000000..75997fe
--- /dev/null
+++ b/package/network/services/omcproxy/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 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:=omcproxy
+PKG_VERSION:=2015-08-24
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=https://github.com/sbyx/omcproxy.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=8de9fa84e018e152e45c342f10b5b5140b63e4b1
+PKG_MAINTAINER:=Steven Barth <cyrus@openwrt.org>
+PKG_LICENSE:=Apache-2.0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/omcproxy
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=+libubox +libubus
+ TITLE:=IGMPv3 and MLDv2 Multicast Proxy
+endef
+
+CMAKE_OPTIONS += -DWITH_LIBUBOX=1
+
+define Package/omcproxy/install
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_CONF) ./files/omcproxy.config $(1)/etc/config/omcproxy
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/omcproxy.init $(1)/etc/init.d/omcproxy
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/omcproxy $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,omcproxy))
diff --git a/package/network/services/omcproxy/files/omcproxy.config b/package/network/services/omcproxy/files/omcproxy.config
new file mode 100644
index 0000000..b0f9bb0
--- /dev/null
+++ b/package/network/services/omcproxy/files/omcproxy.config
@@ -0,0 +1,9 @@
+config proxy
+ option scope global
+ option uplink wan
+ list downlink lan
+
+config proxy
+ option scope global
+ option uplink wan6
+ list downlink lan
diff --git a/package/network/services/omcproxy/files/omcproxy.init b/package/network/services/omcproxy/files/omcproxy.init
new file mode 100644
index 0000000..a129792
--- /dev/null
+++ b/package/network/services/omcproxy/files/omcproxy.init
@@ -0,0 +1,143 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2010-2014 OpenWrt.org
+
+START=99
+USE_PROCD=1
+PROG=/usr/sbin/omcproxy
+
+# Uncomment to enable verbosity
+#OPTIONS="-v"
+PROXIES=""
+
+
+omcproxy_add_proxy() {
+ local uplink downlink scope proxy
+ config_get uplink $1 uplink
+ config_get downlink $1 downlink
+ config_get scope $1 scope
+
+ proxy=""
+
+ network_get_device updev $uplink
+ [ -n "$updev" ] || return 0
+
+ for network in $downlink; do
+ network_get_device downdev $network
+ [ -n "$downdev" ] && proxy="$proxy,$downdev"
+
+ # Disable in-kernel querier while ours is active
+ [ -f /sys/class/net/$downdev/bridge/multicast_querier ] && \
+ echo 0 > /sys/class/net/$downdev/bridge/multicast_querier
+ done
+
+ [ -n "$proxy" ] || return 0
+ [ -n "$scope" ] && proxy="$proxy,scope=$scope"
+
+ PROXIES="$PROXIES $updev$proxy"
+
+}
+
+omcproxy_add_trigger() {
+ local uplink downlink
+ config_get uplink $1 uplink
+ config_get downlink $1 downlink
+
+ for network in $uplink $downlink; do
+ procd_add_interface_trigger "interface.*" $network /etc/init.d/omcproxy restart
+ done
+}
+
+omcproxy_add_firewall() {
+ config_get uplink $1 uplink
+ config_get downlink $1 downlink
+
+ upzone=$(fw3 network $uplink)
+ [ -n "$upzone" ] || return 0
+
+ json_add_object ""
+ json_add_string type rule
+ json_add_string src "$upzone"
+ json_add_string proto igmp
+ json_add_string target ACCEPT
+ json_close_object
+
+ json_add_object ""
+ json_add_string type rule
+ json_add_string family ipv6
+ json_add_string src "$upzone"
+ json_add_string proto icmp
+ json_add_string src_ip fe80::/10
+ json_add_array icmp_type
+ json_add_string "" 130/0
+ json_add_string "" 131/0
+ json_add_string "" 132/0
+ json_add_string "" 143/0
+ json_close_array
+ json_add_string target ACCEPT
+ json_close_object
+
+ for network in $downlink; do
+ downzone=$(fw3 network $network)
+ [ -n "$downzone" ] || continue
+
+ json_add_object ""
+ json_add_string type rule
+ json_add_string src "$upzone"
+ json_add_string dest "$downzone"
+ json_add_string family ipv4
+ json_add_string proto any
+ json_add_string dest_ip "224.0.0.0/4"
+ json_add_string target ACCEPT
+ json_close_object
+
+ json_add_object ""
+ json_add_string type rule
+ json_add_string src "$upzone"
+ json_add_string dest "$downzone"
+ json_add_string family ipv6
+ json_add_string proto any
+ json_add_string dest_ip "ff00::/8"
+ json_add_string target ACCEPT
+ json_close_object
+ done
+}
+
+service_triggers() {
+ procd_add_reload_trigger "omcproxy"
+}
+
+start_service() {
+ include /lib/functions
+
+ config_load omcproxy
+ config_foreach omcproxy_add_proxy proxy
+
+ [ -n "$PROXIES" ] || return 0
+
+ procd_open_instance
+ procd_set_param command $PROG
+ [ -n "$OPTIONS" ] && procd_append_param command $OPTIONS
+ procd_append_param command $PROXIES
+ procd_set_param respawn
+
+ procd_open_trigger
+ config_foreach omcproxy_add_trigger proxy
+ procd_close_trigger
+
+ procd_open_data
+
+ json_add_array firewall
+ config_foreach omcproxy_add_firewall proxy
+ json_close_array
+
+ procd_close_data
+
+ procd_close_instance
+
+ # Increase maximum IPv4 group memberships per socket
+ echo 128 > /proc/sys/net/ipv4/igmp_max_memberships
+}
+
+service_started() {
+ procd_set_config_changed firewall
+}
diff --git a/package/network/services/openvpn-easy-rsa/Makefile b/package/network/services/openvpn-easy-rsa/Makefile
new file mode 100644
index 0000000..fe03cbd
--- /dev/null
+++ b/package/network/services/openvpn-easy-rsa/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2010-2013 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:=openvpn-easy-rsa
+
+PKG_REV:=ff5bfd1dd8e548cb24d302742af3894f893ef92f
+PKG_VERSION:=2013-01-30
+PKG_RELEASE=2
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/OpenVPN/easy-rsa.git
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_REV).tar.gz
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/openvpn-easy-rsa
+ TITLE:=Simple shell scripts to manage a Certificate Authority
+ SECTION:=net
+ CATEGORY:=Network
+ URL:=http://openvpn.net
+ SUBMENU:=VPN
+ DEPENDS:=+openssl-util
+endef
+
+define Package/openvpn-easy-rsa/conffiles
+/etc/easy-rsa/keys/serial
+/etc/easy-rsa/keys/index.txt
+/etc/easy-rsa/vars
+endef
+
+define Build/Configure
+
+endef
+
+define Build/Compile
+
+endef
+
+define Package/openvpn-easy-rsa/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_BUILD_DIR)/easy-rsa/2.0/{build-*,clean-all,inherit-inter,list-crl,pkitool,revoke-full,sign-req,whichopensslcnf} $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/etc/easy-rsa
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/easy-rsa/2.0/openssl-1.0.0.cnf $(1)/etc/easy-rsa/openssl-1.0.0.cnf
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/easy-rsa/2.0/vars $(1)/etc/easy-rsa/vars
+ $(INSTALL_DIR) $(1)/etc/easy-rsa/keys
+ $(INSTALL_DATA) files/easy-rsa.index $(1)/etc/easy-rsa/keys/index.txt
+ $(INSTALL_DATA) files/easy-rsa.serial $(1)/etc/easy-rsa/keys/serial
+endef
+
+$(eval $(call BuildPackage,openvpn-easy-rsa))
diff --git a/package/network/services/openvpn-easy-rsa/files/easy-rsa.index b/package/network/services/openvpn-easy-rsa/files/easy-rsa.index
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/package/network/services/openvpn-easy-rsa/files/easy-rsa.index
diff --git a/package/network/services/openvpn-easy-rsa/files/easy-rsa.serial b/package/network/services/openvpn-easy-rsa/files/easy-rsa.serial
new file mode 100644
index 0000000..8a0f05e
--- /dev/null
+++ b/package/network/services/openvpn-easy-rsa/files/easy-rsa.serial
@@ -0,0 +1 @@
+01
diff --git a/package/network/services/openvpn-easy-rsa/patches/100-run-ootb.patch b/package/network/services/openvpn-easy-rsa/patches/100-run-ootb.patch
new file mode 100644
index 0000000..4c1b889
--- /dev/null
+++ b/package/network/services/openvpn-easy-rsa/patches/100-run-ootb.patch
@@ -0,0 +1,152 @@
+--- a/easy-rsa/2.0/build-ca
++++ b/easy-rsa/2.0/build-ca
+@@ -5,4 +5,4 @@
+ #
+
+ export EASY_RSA="${EASY_RSA:-.}"
+-"$EASY_RSA/pkitool" --interact --initca $*
++"/usr/sbin/pkitool" --interact --initca $*
+--- a/easy-rsa/2.0/build-dh
++++ b/easy-rsa/2.0/build-dh
+@@ -1,5 +1,7 @@
+ #!/bin/sh
+
++. /etc/easy-rsa/vars
++
+ # Build Diffie-Hellman parameters for the server side
+ # of an SSL/TLS connection.
+
+--- a/easy-rsa/2.0/build-inter
++++ b/easy-rsa/2.0/build-inter
+@@ -4,4 +4,4 @@
+ # root certificate.
+
+ export EASY_RSA="${EASY_RSA:-.}"
+-"$EASY_RSA/pkitool" --interact --inter $*
++"/usr/sbin/pkitool" --interact --inter $*
+--- a/easy-rsa/2.0/build-key
++++ b/easy-rsa/2.0/build-key
+@@ -4,4 +4,4 @@
+ # root certificate.
+
+ export EASY_RSA="${EASY_RSA:-.}"
+-"$EASY_RSA/pkitool" --interact $*
++"/usr/sbin/pkitool" --interact $*
+--- a/easy-rsa/2.0/build-key-pass
++++ b/easy-rsa/2.0/build-key-pass
+@@ -4,4 +4,4 @@
+ # with a password.
+
+ export EASY_RSA="${EASY_RSA:-.}"
+-"$EASY_RSA/pkitool" --interact --pass $*
++"/usr/sbin/pkitool" --interact --pass $*
+--- a/easy-rsa/2.0/build-key-pkcs12
++++ b/easy-rsa/2.0/build-key-pkcs12
+@@ -5,4 +5,4 @@
+ # the CA certificate as well.
+
+ export EASY_RSA="${EASY_RSA:-.}"
+-"$EASY_RSA/pkitool" --interact --pkcs12 $*
++"/usr/sbin/pkitool" --interact --pkcs12 $*
+--- a/easy-rsa/2.0/build-key-server
++++ b/easy-rsa/2.0/build-key-server
+@@ -7,4 +7,4 @@
+ # extension in the openssl.cnf file.
+
+ export EASY_RSA="${EASY_RSA:-.}"
+-"$EASY_RSA/pkitool" --interact --server $*
++"/usr/sbin/pkitool" --interact --server $*
+--- a/easy-rsa/2.0/build-req
++++ b/easy-rsa/2.0/build-req
+@@ -4,4 +4,4 @@
+ # when your root certificate and key is not available locally.
+
+ export EASY_RSA="${EASY_RSA:-.}"
+-"$EASY_RSA/pkitool" --interact --csr $*
++"/usr/sbin/pkitool" --interact --csr $*
+--- a/easy-rsa/2.0/build-req-pass
++++ b/easy-rsa/2.0/build-req-pass
+@@ -4,4 +4,4 @@
+ # with a password.
+
+ export EASY_RSA="${EASY_RSA:-.}"
+-"$EASY_RSA/pkitool" --interact --csr --pass $*
++"/usr/sbin/pkitool" --interact --csr --pass $*
+--- a/easy-rsa/2.0/clean-all
++++ b/easy-rsa/2.0/clean-all
+@@ -1,5 +1,7 @@
+ #!/bin/sh
+
++. /etc/easy-rsa/vars
++
+ # Initialize the $KEY_DIR directory.
+ # Note that this script does a
+ # rm -rf on $KEY_DIR so be careful!
+--- a/easy-rsa/2.0/inherit-inter
++++ b/easy-rsa/2.0/inherit-inter
+@@ -1,5 +1,7 @@
+ #!/bin/sh
+
++. /etc/easy-rsa/vars
++
+ # Build a new PKI which is rooted on an intermediate certificate generated
+ # by ./build-inter or ./pkitool --inter from a parent PKI. The new PKI should
+ # have independent vars settings, and must use a different KEY_DIR directory
+--- a/easy-rsa/2.0/list-crl
++++ b/easy-rsa/2.0/list-crl
+@@ -1,5 +1,7 @@
+ #!/bin/sh
+
++. /etc/easy-rsa/vars
++
+ # list revoked certificates
+
+ CRL="${1:-crl.pem}"
+--- a/easy-rsa/2.0/pkitool
++++ b/easy-rsa/2.0/pkitool
+@@ -1,5 +1,7 @@
+ #!/bin/sh
+
++. /etc/easy-rsa/vars
++
+ # OpenVPN -- An application to securely tunnel IP networks
+ # over a single TCP/UDP port, with support for SSL/TLS-based
+ # session authentication and key exchange,
+--- a/easy-rsa/2.0/revoke-full
++++ b/easy-rsa/2.0/revoke-full
+@@ -1,5 +1,7 @@
+ #!/bin/sh
+
++. /etc/easy-rsa/vars
++
+ # revoke a certificate, regenerate CRL,
+ # and verify revocation
+
+--- a/easy-rsa/2.0/sign-req
++++ b/easy-rsa/2.0/sign-req
+@@ -4,4 +4,4 @@
+ # with a local root certificate and key.
+
+ export EASY_RSA="${EASY_RSA:-.}"
+-"$EASY_RSA/pkitool" --interact --sign $*
++"/usr/sbin/pkitool" --interact --sign $*
+--- a/easy-rsa/2.0/vars
++++ b/easy-rsa/2.0/vars
+@@ -12,7 +12,7 @@
+ # This variable should point to
+ # the top level of the easy-rsa
+ # tree.
+-export EASY_RSA="`pwd`"
++export EASY_RSA="/etc/easy-rsa"
+
+ #
+ # This variable should point to
+@@ -26,7 +26,7 @@
+ # This variable should point to
+ # the openssl.cnf file included
+ # with easy-rsa.
+-export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
++export KEY_CONFIG=`/usr/sbin/whichopensslcnf $EASY_RSA`
+
+ # Edit this variable to point to
+ # your soon-to-be-created key
diff --git a/package/network/services/openvpn/Config-nossl.in b/package/network/services/openvpn/Config-nossl.in
new file mode 100644
index 0000000..3eaa228
--- /dev/null
+++ b/package/network/services/openvpn/Config-nossl.in
@@ -0,0 +1,54 @@
+if PACKAGE_openvpn-nossl
+
+config OPENVPN_nossl_ENABLE_LZO
+ bool "Enable LZO compression support"
+ default y
+
+config OPENVPN_nossl_ENABLE_SERVER
+ bool "Enable server support (otherwise only client mode is support)"
+ default y
+
+config OPENVPN_nossl_ENABLE_MANAGEMENT
+ bool "Enable management server support"
+ default n
+
+config OPENVPN_nossl_ENABLE_HTTP
+ bool "Enable HTTP proxy support"
+ default y
+
+config OPENVPN_nossl_ENABLE_SOCKS
+ bool "Enable SOCKS proxy support"
+ default y
+
+config OPENVPN_nossl_ENABLE_FRAGMENT
+ bool "Enable internal fragmentation support (--fragment)"
+ default y
+
+config OPENVPN_nossl_ENABLE_MULTIHOME
+ bool "Enable multi-homed UDP server support (--multihome)"
+ default y
+
+config OPENVPN_nossl_ENABLE_PORT_SHARE
+ bool "Enable TCP server port-share support (--port-share)"
+ default y
+
+config OPENVPN_nossl_ENABLE_DEF_AUTH
+ bool "Enable deferred authentication"
+ default y
+
+config OPENVPN_nossl_ENABLE_PF
+ bool "Enable internal packet filter"
+ default y
+
+config OPENVPN_nossl_ENABLE_IPROUTE2
+ bool "Enable support for iproute2"
+ default n
+
+config OPENVPN_nossl_ENABLE_SMALL
+ bool "Enable size optimization"
+ default y
+ help
+ enable smaller executable size (disable OCC, usage
+ message, and verb 4 parm list)
+
+endif
diff --git a/package/network/services/openvpn/Config-openssl.in b/package/network/services/openvpn/Config-openssl.in
new file mode 100644
index 0000000..ac4c774
--- /dev/null
+++ b/package/network/services/openvpn/Config-openssl.in
@@ -0,0 +1,66 @@
+if PACKAGE_openvpn-openssl
+
+config OPENVPN_openssl_ENABLE_LZO
+ bool "Enable LZO compression support"
+ default y
+
+config OPENVPN_openssl_ENABLE_X509_ALT_USERNAME
+ bool "Enable the --x509-username-field feature"
+ default n
+
+config OPENVPN_openssl_ENABLE_SERVER
+ bool "Enable server support (otherwise only client mode is support)"
+ default y
+
+#config OPENVPN_openssl_ENABLE_EUREPHIA
+# bool "Enable support for the eurephia plug-in"
+# default n
+
+config OPENVPN_openssl_ENABLE_MANAGEMENT
+ bool "Enable management server support"
+ default n
+
+#config OPENVPN_openssl_ENABLE_PKCS11
+# bool "Enable pkcs11 support"
+# default n
+
+config OPENVPN_openssl_ENABLE_HTTP
+ bool "Enable HTTP proxy support"
+ default y
+
+config OPENVPN_openssl_ENABLE_SOCKS
+ bool "Enable SOCKS proxy support"
+ default y
+
+config OPENVPN_openssl_ENABLE_FRAGMENT
+ bool "Enable internal fragmentation support (--fragment)"
+ default y
+
+config OPENVPN_openssl_ENABLE_MULTIHOME
+ bool "Enable multi-homed UDP server support (--multihome)"
+ default y
+
+config OPENVPN_openssl_ENABLE_PORT_SHARE
+ bool "Enable TCP server port-share support (--port-share)"
+ default y
+
+config OPENVPN_openssl_ENABLE_DEF_AUTH
+ bool "Enable deferred authentication"
+ default y
+
+config OPENVPN_openssl_ENABLE_PF
+ bool "Enable internal packet filter"
+ default y
+
+config OPENVPN_openssl_ENABLE_IPROUTE2
+ bool "Enable support for iproute2"
+ default n
+
+config OPENVPN_openssl_ENABLE_SMALL
+ bool "Enable size optimization"
+ default y
+ help
+ enable smaller executable size (disable OCC, usage
+ message, and verb 4 parm list)
+
+endif
diff --git a/package/network/services/openvpn/Config-polarssl.in b/package/network/services/openvpn/Config-polarssl.in
new file mode 100644
index 0000000..26692ce
--- /dev/null
+++ b/package/network/services/openvpn/Config-polarssl.in
@@ -0,0 +1,66 @@
+if PACKAGE_openvpn-polarssl
+
+config OPENVPN_polarssl_ENABLE_LZO
+ bool "Enable LZO compression support"
+ default y
+
+config OPENVPN_polarssl_ENABLE_X509_ALT_USERNAME
+ bool "Enable the --x509-username-field feature"
+ default n
+
+config OPENVPN_polarssl_ENABLE_SERVER
+ bool "Enable server support (otherwise only client mode is support)"
+ default y
+
+#config OPENVPN_polarssl_ENABLE_EUREPHIA
+# bool "Enable support for the eurephia plug-in"
+# default n
+
+config OPENVPN_polarssl_ENABLE_MANAGEMENT
+ bool "Enable management server support"
+ default n
+
+#config OPENVPN_polarssl_ENABLE_PKCS11
+# bool "Enable pkcs11 support"
+# default n
+
+config OPENVPN_polarssl_ENABLE_HTTP
+ bool "Enable HTTP proxy support"
+ default y
+
+config OPENVPN_polarssl_ENABLE_SOCKS
+ bool "Enable SOCKS proxy support"
+ default y
+
+config OPENVPN_polarssl_ENABLE_FRAGMENT
+ bool "Enable internal fragmentation support (--fragment)"
+ default y
+
+config OPENVPN_polarssl_ENABLE_MULTIHOME
+ bool "Enable multi-homed UDP server support (--multihome)"
+ default y
+
+config OPENVPN_polarssl_ENABLE_PORT_SHARE
+ bool "Enable TCP server port-share support (--port-share)"
+ default y
+
+config OPENVPN_polarssl_ENABLE_DEF_AUTH
+ bool "Enable deferred authentication"
+ default y
+
+config OPENVPN_polarssl_ENABLE_PF
+ bool "Enable internal packet filter"
+ default y
+
+config OPENVPN_polarssl_ENABLE_IPROUTE2
+ bool "Enable support for iproute2"
+ default n
+
+config OPENVPN_polarssl_ENABLE_SMALL
+ bool "Enable size optimization"
+ default y
+ help
+ enable smaller executable size (disable OCC, usage
+ message, and verb 4 parm list)
+
+endif
diff --git a/package/network/services/openvpn/Makefile b/package/network/services/openvpn/Makefile
new file mode 100644
index 0000000..a1784f4
--- /dev/null
+++ b/package/network/services/openvpn/Makefile
@@ -0,0 +1,125 @@
+#
+# Copyright (C) 2010-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:=openvpn
+
+PKG_VERSION:=2.3.7
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=http://swupdate.openvpn.net/community/releases
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_MD5SUM:=070bca95e478f88dff9ec6a221e2c3f7
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_INSTALL:=1
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/openvpn/Default
+ TITLE:=Open source VPN solution using $(2)
+ SECTION:=net
+ CATEGORY:=Network
+ URL:=http://openvpn.net
+ SUBMENU:=VPN
+ MENU:=1
+ DEPENDS:=+kmod-tun +OPENVPN_$(1)_ENABLE_LZO:liblzo +OPENVPN_$(1)_ENABLE_IPROUTE2:ip $(3)
+ VARIANT:=$(1)
+ MAINTAINER:=Mirko Vogt <mirko@openwrt.org>
+endef
+
+Package/openvpn-openssl=$(call Package/openvpn/Default,openssl,OpenSSL,+libopenssl)
+Package/openvpn-polarssl=$(call Package/openvpn/Default,polarssl,PolarSSL,+libpolarssl)
+Package/openvpn-nossl=$(call Package/openvpn/Default,nossl,plaintext (no SSL))
+
+define Package/openvpn/config/Default
+ source "$(SOURCE)/Config-$(1).in"
+endef
+
+Package/openvpn-openssl/config=$(call Package/openvpn/config/Default,openssl)
+Package/openvpn-polarssl/config=$(call Package/openvpn/config/Default,polarssl)
+Package/openvpn-nossl/config=$(call Package/openvpn/config/Default,nossl)
+
+ifeq ($(BUILD_VARIANT),polarssl)
+CONFIG_OPENVPN_POLARSSL:=y
+endif
+ifeq ($(BUILD_VARIANT),openssl)
+CONFIG_OPENVPN_OPENSSL:=y
+endif
+ifeq ($(BUILD_VARIANT),nossl)
+CONFIG_OPENVPN_NOSSL:=y
+endif
+
+CONFIGURE_VARS += \
+ IFCONFIG=/sbin/ifconfig \
+ ROUTE=/sbin/route \
+ IPROUTE=/sbin/ip \
+ NETSTAT=/sbin/netstat
+
+define Build/Configure
+ $(call Build/Configure/Default, \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_SMALL),--enable-small) \
+ --disable-selinux \
+ --disable-systemd \
+ --disable-plugins \
+ --disable-debug \
+ --disable-eurephia \
+ --disable-pkcs11 \
+ --enable-password-save \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_LZO),--enable,--disable)-lzo \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_X509_ALT_USERNAME),enable,disable-x509-alt-username)-ssl \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_SERVER),--enable,--disable)-server \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_MANAGEMENT),--enable,--disable)-management \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_SOCKS),--enable,--disable)-socks \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_HTTP),--enable,--disable)-http \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_FRAGMENT),--enable,--disable)-fragment \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_MULTIHOME),--enable,--disable)-multihome \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_IPROUTE2),--enable,--disable)-iproute2 \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_DEF_AUTH),--enable,--disable)-def-auth \
+ $(if $(CONFIG_OPENVPN_$(BUILD_VARIANT)_ENABLE_PF),--enable,--disable)-pf \
+ $(if $(CONFIG_OPENVPN_NOSSL),--disable-ssl --disable-crypto,--enable-ssl --enable-crypto) \
+ $(if $(CONFIG_OPENVPN_OPENSSL),--with-crypto-library=openssl) \
+ $(if $(CONFIG_OPENVPN_POLARSSL),--with-crypto-library=polarssl) \
+ )
+endef
+
+define Package/openvpn-$(BUILD_VARIANT)/conffiles
+/etc/config/openvpn
+endef
+
+define Package/openvpn-$(BUILD_VARIANT)/install
+ $(INSTALL_DIR) \
+ $(1)/usr/sbin \
+ $(1)/etc/init.d \
+ $(1)/etc/config \
+ $(1)/etc/openvpn \
+ $(1)/lib/upgrade/keep.d
+
+ $(INSTALL_BIN) \
+ $(PKG_INSTALL_DIR)/usr/sbin/openvpn \
+ $(1)/usr/sbin/
+
+ $(INSTALL_BIN) \
+ files/openvpn.init \
+ $(1)/etc/init.d/openvpn
+
+ $(INSTALL_CONF) files/openvpn.config \
+ $(1)/etc/config/openvpn
+
+ $(INSTALL_DATA) \
+ files/openvpn.upgrade \
+ $(1)/lib/upgrade/keep.d/openvpn
+endef
+
+$(eval $(call BuildPackage,openvpn-openssl))
+$(eval $(call BuildPackage,openvpn-polarssl))
+$(eval $(call BuildPackage,openvpn-nossl))
diff --git a/package/network/services/openvpn/files/openvpn.config b/package/network/services/openvpn/files/openvpn.config
new file mode 100644
index 0000000..3e053c3
--- /dev/null
+++ b/package/network/services/openvpn/files/openvpn.config
@@ -0,0 +1,400 @@
+package openvpn
+
+#################################################
+# Sample to include a custom config file. #
+#################################################
+
+config openvpn custom_config
+
+ # Set to 1 to enable this instance:
+ option enabled 0
+
+ # Include OpenVPN configuration
+ option config /etc/openvpn/my-vpn.conf
+
+
+#################################################
+# Sample OpenVPN 2.0 uci config for #
+# multi-client server. #
+#################################################
+
+config openvpn sample_server
+
+ # Set to 1 to enable this instance:
+ option enabled 0
+
+ # Which local IP address should OpenVPN
+ # listen on? (optional)
+# option local 0.0.0.0
+
+ # Which TCP/UDP port should OpenVPN listen on?
+ # If you want to run multiple OpenVPN instances
+ # on the same machine, use a different port
+ # number for each one. You will need to
+ # open up this port on your firewall.
+ option port 1194
+
+ # TCP or UDP server?
+# option proto tcp
+ option proto udp
+
+ # "dev tun" will create a routed IP tunnel,
+ # "dev tap" will create an ethernet tunnel.
+ # Use "dev tap0" if you are ethernet bridging
+ # and have precreated a tap0 virtual interface
+ # and bridged it with your ethernet interface.
+ # If you want to control access policies
+ # over the VPN, you must create firewall
+ # rules for the the TUN/TAP interface.
+ # On non-Windows systems, you can give
+ # an explicit unit number, such as tun0.
+ # On Windows, use "dev-node" for this.
+ # On most systems, the VPN will not function
+ # unless you partially or fully disable
+ # the firewall for the TUN/TAP interface.
+# option dev tap
+ option dev tun
+
+ # SSL/TLS root certificate (ca), certificate
+ # (cert), and private key (key). Each client
+ # and the server must have their own cert and
+ # key file. The server and all clients will
+ # use the same ca file.
+ #
+ # See the "easy-rsa" directory for a series
+ # of scripts for generating RSA certificates
+ # and private keys. Remember to use
+ # a unique Common Name for the server
+ # and each of the client certificates.
+ #
+ # Any X509 key management system can be used.
+ # OpenVPN can also use a PKCS #12 formatted key file
+ # (see "pkcs12" directive in man page).
+ option ca /etc/openvpn/ca.crt
+ option cert /etc/openvpn/server.crt
+ # This file should be kept secret:
+ option key /etc/openvpn/server.key
+
+ # Diffie hellman parameters.
+ # Generate your own with:
+ # openssl dhparam -out dh1024.pem 1024
+ # Substitute 2048 for 1024 if you are using
+ # 2048 bit keys.
+ option dh /etc/openvpn/dh1024.pem
+
+ # Configure server mode and supply a VPN subnet
+ # for OpenVPN to draw client addresses from.
+ # The server will take 10.8.0.1 for itself,
+ # the rest will be made available to clients.
+ # Each client will be able to reach the server
+ # on 10.8.0.1. Comment this line out if you are
+ # ethernet bridging. See the man page for more info.
+ option server "10.8.0.0 255.255.255.0"
+
+ # Maintain a record of client <-> virtual IP address
+ # associations in this file. If OpenVPN goes down or
+ # is restarted, reconnecting clients can be assigned
+ # the same virtual IP address from the pool that was
+ # previously assigned.
+ option ifconfig_pool_persist /tmp/ipp.txt
+
+ # Configure server mode for ethernet bridging.
+ # You must first use your OS's bridging capability
+ # to bridge the TAP interface with the ethernet
+ # NIC interface. Then you must manually set the
+ # IP/netmask on the bridge interface, here we
+ # assume 10.8.0.4/255.255.255.0. Finally we
+ # must set aside an IP range in this subnet
+ # (start=10.8.0.50 end=10.8.0.100) to allocate
+ # to connecting clients. Leave this line commented
+ # out unless you are ethernet bridging.
+# option server_bridge "10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100"
+
+ # Push routes to the client to allow it
+ # to reach other private subnets behind
+ # the server. Remember that these
+ # private subnets will also need
+ # to know to route the OpenVPN client
+ # address pool (10.8.0.0/255.255.255.0)
+ # back to the OpenVPN server.
+# list push "route 192.168.10.0 255.255.255.0"
+# list push "route 192.168.20.0 255.255.255.0"
+
+ # To assign specific IP addresses to specific
+ # clients or if a connecting client has a private
+ # subnet behind it that should also have VPN access,
+ # use the subdirectory "ccd" for client-specific
+ # configuration files (see man page for more info).
+
+ # EXAMPLE: Suppose the client
+ # having the certificate common name "Thelonious"
+ # also has a small subnet behind his connecting
+ # machine, such as 192.168.40.128/255.255.255.248.
+ # First, uncomment out these lines:
+# option client_config_dir /etc/openvpn/ccd
+# list route "192.168.40.128 255.255.255.248"
+ # Then create a file ccd/Thelonious with this line:
+ # iroute 192.168.40.128 255.255.255.248
+ # This will allow Thelonious' private subnet to
+ # access the VPN. This example will only work
+ # if you are routing, not bridging, i.e. you are
+ # using "dev tun" and "server" directives.
+
+ # EXAMPLE: Suppose you want to give
+ # Thelonious a fixed VPN IP address of 10.9.0.1.
+ # First uncomment out these lines:
+# option client_config_dir /etc/openvpn/ccd
+# list route "10.9.0.0 255.255.255.252"
+# list route "192.168.100.0 255.255.255.0"
+ # Then add this line to ccd/Thelonious:
+ # ifconfig-push "10.9.0.1 10.9.0.2"
+
+ # Suppose that you want to enable different
+ # firewall access policies for different groups
+ # of clients. There are two methods:
+ # (1) Run multiple OpenVPN daemons, one for each
+ # group, and firewall the TUN/TAP interface
+ # for each group/daemon appropriately.
+ # (2) (Advanced) Create a script to dynamically
+ # modify the firewall in response to access
+ # from different clients. See man
+ # page for more info on learn-address script.
+# option learn_address /etc/openvpn/script
+
+ # If enabled, this directive will configure
+ # all clients to redirect their default
+ # network gateway through the VPN, causing
+ # all IP traffic such as web browsing and
+ # and DNS lookups to go through the VPN
+ # (The OpenVPN server machine may need to NAT
+ # the TUN/TAP interface to the internet in
+ # order for this to work properly).
+ # CAVEAT: May break client's network config if
+ # client's local DHCP server packets get routed
+ # through the tunnel. Solution: make sure
+ # client's local DHCP server is reachable via
+ # a more specific route than the default route
+ # of 0.0.0.0/0.0.0.0.
+# list push "redirect-gateway"
+
+ # Certain Windows-specific network settings
+ # can be pushed to clients, such as DNS
+ # or WINS server addresses. CAVEAT:
+ # http://openvpn.net/faq.html#dhcpcaveats
+# list push "dhcp-option DNS 10.8.0.1"
+# list push "dhcp-option WINS 10.8.0.1"
+
+ # Uncomment this directive to allow different
+ # clients to be able to "see" each other.
+ # By default, clients will only see the server.
+ # To force clients to only see the server, you
+ # will also need to appropriately firewall the
+ # server's TUN/TAP interface.
+# option client_to_client 1
+
+ # Uncomment this directive if multiple clients
+ # might connect with the same certificate/key
+ # files or common names. This is recommended
+ # only for testing purposes. For production use,
+ # each client should have its own certificate/key
+ # pair.
+ #
+ # IF YOU HAVE NOT GENERATED INDIVIDUAL
+ # CERTIFICATE/KEY PAIRS FOR EACH CLIENT,
+ # EACH HAVING ITS OWN UNIQUE "COMMON NAME",
+ # UNCOMMENT THIS LINE OUT.
+# option duplicate_cn 1
+
+ # The keepalive directive causes ping-like
+ # messages to be sent back and forth over
+ # the link so that each side knows when
+ # the other side has gone down.
+ # Ping every 10 seconds, assume that remote
+ # peer is down if no ping received during
+ # a 120 second time period.
+ option keepalive "10 120"
+
+ # For extra security beyond that provided
+ # by SSL/TLS, create an "HMAC firewall"
+ # to help block DoS attacks and UDP port flooding.
+ #
+ # Generate with:
+ # openvpn --genkey --secret ta.key
+ #
+ # The server and each client must have
+ # a copy of this key.
+ # The second parameter should be '0'
+ # on the server and '1' on the clients.
+ # This file is secret:
+# option tls_auth "/etc/openvpn/ta.key 0"
+
+ # Select a cryptographic cipher.
+ # This config item must be copied to
+ # the client config file as well.
+ # Blowfish (default):
+# option cipher BF-CBC
+ # AES:
+# option cipher AES-128-CBC
+ # Triple-DES:
+# option cipher DES-EDE3-CBC
+
+ # Enable compression on the VPN link.
+ # If you enable it here, you must also
+ # enable it in the client config file.
+ option comp_lzo yes
+
+ # The maximum number of concurrently connected
+ # clients we want to allow.
+# option max_clients 100
+
+ # The persist options will try to avoid
+ # accessing certain resources on restart
+ # that may no longer be accessible because
+ # of the privilege downgrade.
+ option persist_key 1
+ option persist_tun 1
+ option user nobody
+
+ # Output a short status file showing
+ # current connections, truncated
+ # and rewritten every minute.
+ option status /tmp/openvpn-status.log
+
+ # By default, log messages will go to the syslog (or
+ # on Windows, if running as a service, they will go to
+ # the "\Program Files\OpenVPN\log" directory).
+ # Use log or log-append to override this default.
+ # "log" will truncate the log file on OpenVPN startup,
+ # while "log-append" will append to it. Use one
+ # or the other (but not both).
+# option log /tmp/openvpn.log
+# option log_append /tmp/openvpn.log
+
+ # Set the appropriate level of log
+ # file verbosity.
+ #
+ # 0 is silent, except for fatal errors
+ # 4 is reasonable for general usage
+ # 5 and 6 can help to debug connection problems
+ # 9 is extremely verbose
+ option verb 3
+
+ # Silence repeating messages. At most 20
+ # sequential messages of the same message
+ # category will be output to the log.
+# option mute 20
+
+
+##############################################
+# Sample client-side OpenVPN 2.0 uci config #
+# for connecting to multi-client server. #
+##############################################
+
+config openvpn sample_client
+
+ # Set to 1 to enable this instance:
+ option enabled 0
+
+ # Specify that we are a client and that we
+ # will be pulling certain config file directives
+ # from the server.
+ option client 1
+
+ # Use the same setting as you are using on
+ # the server.
+ # On most systems, the VPN will not function
+ # unless you partially or fully disable
+ # the firewall for the TUN/TAP interface.
+# option dev tap
+ option dev tun
+
+ # Are we connecting to a TCP or
+ # UDP server? Use the same setting as
+ # on the server.
+# option proto tcp
+ option proto udp
+
+ # The hostname/IP and port of the server.
+ # You can have multiple remote entries
+ # to load balance between the servers.
+ list remote "my_server_1 1194"
+# list remote "my_server_2 1194"
+
+ # Choose a random host from the remote
+ # list for load_balancing. Otherwise
+ # try hosts in the order specified.
+# option remote_random 1
+
+ # Keep trying indefinitely to resolve the
+ # host name of the OpenVPN server. Very useful
+ # on machines which are not permanently connected
+ # to the internet such as laptops.
+ option resolv_retry infinite
+
+ # Most clients don't need to bind to
+ # a specific local port number.
+ option nobind 1
+
+ # Try to preserve some state across restarts.
+ option persist_key 1
+ option persist_tun 1
+ option user nobody
+
+ # If you are connecting through an
+ # HTTP proxy to reach the actual OpenVPN
+ # server, put the proxy server/IP and
+ # port number here. See the man page
+ # if your proxy server requires
+ # authentication.
+ # retry on connection failures:
+# option http_proxy_retry 1
+ # specify http proxy address and port:
+# option http_proxy "192.168.1.100 8080"
+
+ # Wireless networks often produce a lot
+ # of duplicate packets. Set this flag
+ # to silence duplicate packet warnings.
+# option mute_replay_warnings 1
+
+ # SSL/TLS parms.
+ # See the server config file for more
+ # description. It's best to use
+ # a separate .crt/.key file pair
+ # for each client. A single ca
+ # file can be used for all clients.
+ option ca /etc/openvpn/ca.crt
+ option cert /etc/openvpn/client.crt
+ option key /etc/openvpn/client.key
+
+ # Verify server certificate by checking
+ # that the certicate has the nsCertType
+ # field set to "server". This is an
+ # important precaution to protect against
+ # a potential attack discussed here:
+ # http://openvpn.net/howto.html#mitm
+ #
+ # To use this feature, you will need to generate
+ # your server certificates with the nsCertType
+ # field set to "server". The build_key_server
+ # script in the easy_rsa folder will do this.
+# option ns_cert_type server
+
+ # If a tls_auth key is used on the server
+ # then every client must also have the key.
+# option tls_auth "/etc/openvpn/ta.key 1"
+
+ # Select a cryptographic cipher.
+ # If the cipher option is used on the server
+ # then you must also specify it here.
+# option cipher x
+
+ # Enable compression on the VPN link.
+ # Don't enable this unless it is also
+ # enabled in the server config file.
+ option comp_lzo yes
+
+ # Set log file verbosity.
+ option verb 3
+
+ # Silence repeating messages
+# option mute 20
diff --git a/package/network/services/openvpn/files/openvpn.init b/package/network/services/openvpn/files/openvpn.init
new file mode 100644
index 0000000..994973b
--- /dev/null
+++ b/package/network/services/openvpn/files/openvpn.init
@@ -0,0 +1,154 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2008-2013 OpenWrt.org
+# Copyright (C) 2008 Jo-Philipp Wich
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+START=90
+STOP=10
+
+USE_PROCD=1
+PROG=/usr/sbin/openvpn
+
+LIST_SEP="
+"
+
+UCI_STARTED=
+UCI_DISABLED=
+
+append_param() {
+ local s="$1"
+ local v="$2"
+ case "$v" in
+ *_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
+ *_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
+ *_*) v=${v%%_*}-${v#*_} ;;
+ esac
+ echo -n "$v" >> "/var/etc/openvpn-$s.conf"
+ return 0
+}
+
+append_bools() {
+ local p; local v; local s="$1"; shift
+ for p in $*; do
+ config_get_bool v "$s" "$p"
+ [ "$v" = 1 ] && append_param "$s" "$p" && echo >> "/var/etc/openvpn-$s.conf"
+ done
+}
+
+append_params() {
+ local p; local v; local s="$1"; shift
+ for p in $*; do
+ config_get v "$s" "$p"
+ IFS="$LIST_SEP"
+ for v in $v; do
+ [ -n "$v" ] && append_param "$s" "$p" && echo " $v" >> "/var/etc/openvpn-$s.conf"
+ done
+ unset IFS
+ done
+}
+
+section_enabled() {
+ config_get_bool enable "$1" 'enable' 0
+ config_get_bool enabled "$1" 'enabled' 0
+ [ $enable -gt 0 ] || [ $enabled -gt 0 ]
+}
+
+openvpn_add_instance() {
+ local name="$1"
+ local dir="$2"
+ local conf="$3"
+
+ procd_open_instance
+ procd_set_param command "$PROG" \
+ --syslog "openvpn($name)" \
+ --status "/var/run/openvpn.$name.status" \
+ --cd "$dir" \
+ --config "$conf"
+ procd_set_param file "$dir/$conf"
+ procd_set_param respawn
+ procd_close_instance
+}
+
+start_instance() {
+ local s="$1"
+
+ config_get config "$s" config
+ config="${config:+$(readlink -f "$config")}"
+
+ section_enabled "$s" || {
+ append UCI_DISABLED "$config" "$LIST_SEP"
+ return 1
+ }
+
+ [ ! -d "/var/run" ] && mkdir -p "/var/run"
+
+ if [ ! -z "$config" ]; then
+ append UCI_STARTED "$config" "$LIST_SEP"
+ openvpn_add_instance "$s" "${config%/*}" "$config"
+ return
+ fi
+
+ [ ! -d "/var/etc" ] && mkdir -p "/var/etc"
+ [ -f "/var/etc/openvpn-$s.conf" ] && rm "/var/etc/openvpn-$s.conf"
+
+ # append flags
+ append_bools "$s" \
+ auth_nocache auth_user_pass_optional bind ccd_exclusive client client_cert_not_required \
+ client_to_client comp_noadapt disable \
+ disable_occ down_pre duplicate_cn fast_io float http_proxy_retry \
+ ifconfig_noexec ifconfig_nowarn ifconfig_pool_linear management_forget_disconnect management_hold \
+ management_query_passwords management_signal mktun mlock mtu_test multihome mute_replay_warnings \
+ nobind no_iv no_name_remapping no_replay opt_verify passtos persist_key persist_local_ip \
+ persist_remote_ip persist_tun ping_timer_rem pull push_reset \
+ remote_random rmtun route_noexec route_nopull single_session socks_proxy_retry \
+ suppress_timestamps tcp_nodelay test_crypto tls_client tls_exit tls_server \
+ tun_ipv6 up_delay up_restart username_as_common_name
+
+ # append params
+ append_params "$s" \
+ cd askpass auth auth_retry auth_user_pass auth_user_pass_verify bcast_buffers ca cert \
+ chroot cipher client_config_dir client_connect client_disconnect comp_lzo connect_freq \
+ connect_retry connect_timeout connect_retry_max crl_verify dev dev_node dev_type dh \
+ echo engine explicit_exit_notify fragment group hand_window hash_size \
+ http_proxy http_proxy_option http_proxy_timeout ifconfig ifconfig_pool \
+ ifconfig_pool_persist ifconfig_push inactive ipchange iroute keepalive \
+ key key_method keysize learn_address link_mtu lladdr local log log_append \
+ lport management management_log_cache max_clients \
+ max_routes_per_client mode mssfix mtu_disc mute nice ns_cert_type ping \
+ ping_exit ping_restart pkcs12 plugin port port_share prng proto rcvbuf \
+ redirect_gateway remap_usr1 remote remote_cert_eku remote_cert_ku remote_cert_tls \
+ reneg_bytes reneg_pkts reneg_sec \
+ replay_persist replay_window resolv_retry route route_delay route_gateway \
+ route_metric route_pre_down route_up rport script_security secret server server_bridge setenv shaper sndbuf \
+ socks_proxy status status_version syslog tcp_queue_limit tls_auth \
+ tls_cipher tls_remote tls_timeout tls_verify tmp_dir topology tran_window \
+ tun_mtu tun_mtu_extra txqueuelen user verb down push up \
+ ifconfig_ipv6 route_ipv6 server_ipv6 ifconfig_ipv6_pool ifconfig_ipv6_push iroute_ipv6
+
+ openvpn_add_instance "$s" "/var/etc" "openvpn-$s.conf"
+}
+
+start_service() {
+ config_load 'openvpn'
+ config_foreach start_instance 'openvpn'
+
+ local path name
+ for path in /etc/openvpn/*.conf; do
+ if [ -f "$path" ]; then
+ name="${path##*/}"; name="${name%.conf}"
+
+ # don't start configs again that are already started by uci
+ if echo "$UCI_STARTED" | grep -qxF "$path"; then
+ continue
+
+ # don't start configs which are set to disabled in uci
+ elif echo "$UCI_DISABLED" | grep -qxF "$path"; then
+ logger -t openvpn "$name.conf is disabled in /etc/config/openvpn"
+ continue
+ fi
+
+ openvpn_add_instance "$name" "${path%/*}" "$path"
+ fi
+ done
+}
diff --git a/package/network/services/openvpn/files/openvpn.upgrade b/package/network/services/openvpn/files/openvpn.upgrade
new file mode 100644
index 0000000..6ae49d2
--- /dev/null
+++ b/package/network/services/openvpn/files/openvpn.upgrade
@@ -0,0 +1 @@
+/etc/openvpn/
diff --git a/package/network/services/openvpn/patches/001-reproducible-remove_DATE.patch b/package/network/services/openvpn/patches/001-reproducible-remove_DATE.patch
new file mode 100644
index 0000000..3ceef6f
--- /dev/null
+++ b/package/network/services/openvpn/patches/001-reproducible-remove_DATE.patch
@@ -0,0 +1,10 @@
+--- a/src/openvpn/options.c
++++ b/src/openvpn/options.c
+@@ -102,7 +102,6 @@ const char title_string[] =
+ " [MH]"
+ #endif
+ " [IPv6]"
+- " built on " __DATE__
+ ;
+
+ #ifndef ENABLE_SMALL
diff --git a/package/network/services/openvpn/patches/100-polarssl_compat.h b/package/network/services/openvpn/patches/100-polarssl_compat.h
new file mode 100644
index 0000000..a1c83b0
--- /dev/null
+++ b/package/network/services/openvpn/patches/100-polarssl_compat.h
@@ -0,0 +1,257 @@
+--- a/src/openvpn/ssl_polarssl.h
++++ b/src/openvpn/ssl_polarssl.h
+@@ -38,6 +38,8 @@
+ #include <polarssl/pkcs11.h>
+ #endif
+
++#include <polarssl/compat-1.2.h>
++
+ typedef struct _buffer_entry buffer_entry;
+
+ struct _buffer_entry {
+--- a/src/openvpn/ssl_polarssl.c
++++ b/src/openvpn/ssl_polarssl.c
+@@ -46,7 +46,7 @@
+ #include "manage.h"
+ #include "ssl_common.h"
+
+-#include <polarssl/sha2.h>
++#include <polarssl/sha256.h>
+ #include <polarssl/havege.h>
+
+ #include "ssl_verify_polarssl.h"
+@@ -212,13 +212,13 @@ tls_ctx_load_dh_params (struct tls_root_
+ {
+ if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_inline)
+ {
+- if (0 != x509parse_dhm(ctx->dhm_ctx, (const unsigned char *) dh_inline,
++ if (0 != dhm_parse_dhm(ctx->dhm_ctx, (const unsigned char *) dh_inline,
+ strlen(dh_inline)))
+ msg (M_FATAL, "Cannot read inline DH parameters");
+ }
+ else
+ {
+- if (0 != x509parse_dhmfile(ctx->dhm_ctx, dh_file))
++ if (0 != dhm_parse_dhmfile(ctx->dhm_ctx, dh_file))
+ msg (M_FATAL, "Cannot read DH parameters from file %s", dh_file);
+ }
+
+@@ -253,13 +253,13 @@ tls_ctx_load_cert_file (struct tls_root_
+
+ if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_inline)
+ {
+- if (0 != x509parse_crt(ctx->crt_chain,
++ if (0 != x509_crt_parse(ctx->crt_chain,
+ (const unsigned char *) cert_inline, strlen(cert_inline)))
+ msg (M_FATAL, "Cannot load inline certificate file");
+ }
+ else
+ {
+- if (0 != x509parse_crtfile(ctx->crt_chain, cert_file))
++ if (0 != x509_crt_parse_file(ctx->crt_chain, cert_file))
+ msg (M_FATAL, "Cannot load certificate file %s", cert_file);
+ }
+ }
+@@ -277,7 +277,7 @@ tls_ctx_load_priv_file (struct tls_root_
+ status = x509parse_key(ctx->priv_key,
+ (const unsigned char *) priv_key_inline, strlen(priv_key_inline),
+ NULL, 0);
+- if (POLARSSL_ERR_X509_PASSWORD_REQUIRED == status)
++ if (POLARSSL_ERR_PK_PASSWORD_REQUIRED == status)
+ {
+ char passbuf[512] = {0};
+ pem_password_callback(passbuf, 512, 0, NULL);
+@@ -289,7 +289,7 @@ tls_ctx_load_priv_file (struct tls_root_
+ else
+ {
+ status = x509parse_keyfile(ctx->priv_key, priv_key_file, NULL);
+- if (POLARSSL_ERR_X509_PASSWORD_REQUIRED == status)
++ if (POLARSSL_ERR_PK_PASSWORD_REQUIRED == status)
+ {
+ char passbuf[512] = {0};
+ pem_password_callback(passbuf, 512, 0, NULL);
+@@ -480,14 +480,14 @@ void tls_ctx_load_ca (struct tls_root_ct
+
+ if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_inline)
+ {
+- if (0 != x509parse_crt(ctx->ca_chain, (const unsigned char *) ca_inline,
++ if (0 != x509_crt_parse(ctx->ca_chain, (const unsigned char *) ca_inline,
+ strlen(ca_inline)))
+ msg (M_FATAL, "Cannot load inline CA certificates");
+ }
+ else
+ {
+ /* Load CA file for verifying peer supplied certificate */
+- if (0 != x509parse_crtfile(ctx->ca_chain, ca_file))
++ if (0 != x509_crt_parse_file(ctx->ca_chain, ca_file))
+ msg (M_FATAL, "Cannot load CA certificate file %s", ca_file);
+ }
+ }
+@@ -501,14 +501,14 @@ tls_ctx_load_extra_certs (struct tls_roo
+
+ if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline)
+ {
+- if (0 != x509parse_crt(ctx->crt_chain,
++ if (0 != x509_crt_parse(ctx->crt_chain,
+ (const unsigned char *) extra_certs_inline,
+ strlen(extra_certs_inline)))
+ msg (M_FATAL, "Cannot load inline extra-certs file");
+ }
+ else
+ {
+- if (0 != x509parse_crtfile(ctx->crt_chain, extra_certs_file))
++ if (0 != x509_crt_parse_file(ctx->crt_chain, extra_certs_file))
+ msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);
+ }
+ }
+@@ -724,7 +724,7 @@ void key_state_ssl_init(struct key_state
+ external_key_len );
+ else
+ #endif
+- ssl_set_own_cert( ks_ssl->ctx, ssl_ctx->crt_chain, ssl_ctx->priv_key );
++ ssl_set_own_cert_rsa( ks_ssl->ctx, ssl_ctx->crt_chain, ssl_ctx->priv_key );
+
+ /* Initialise SSL verification */
+ #if P2MP_SERVER
+@@ -1068,7 +1068,7 @@ print_details (struct key_state_ssl * ks
+ cert = ssl_get_peer_cert(ks_ssl->ctx);
+ if (cert != NULL)
+ {
+- openvpn_snprintf (s2, sizeof (s2), ", " counter_format " bit RSA", (counter_type) cert->rsa.len * 8);
++ openvpn_snprintf (s2, sizeof (s2), ", " counter_format " bit RSA", (counter_type) pk_rsa(cert->pk)->len * 8);
+ }
+
+ msg (D_HANDSHAKE, "%s%s", s1, s2);
+--- a/src/openvpn/crypto_polarssl.c
++++ b/src/openvpn/crypto_polarssl.c
+@@ -487,7 +487,12 @@ cipher_ctx_get_cipher_kt (const cipher_c
+
+ int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf)
+ {
+- return 0 == cipher_reset(ctx, iv_buf);
++ int retval = cipher_reset(ctx);
++
++ if (0 == retval)
++ cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size);
++
++ return 0 == retval;
+ }
+
+ int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len,
+--- a/src/openvpn/ssl_verify_polarssl.h
++++ b/src/openvpn/ssl_verify_polarssl.h
+@@ -34,6 +34,7 @@
+ #include "misc.h"
+ #include "manage.h"
+ #include <polarssl/x509.h>
++#include <polarssl/compat-1.2.h>
+
+ #ifndef __OPENVPN_X509_CERT_T_DECLARED
+ #define __OPENVPN_X509_CERT_T_DECLARED
+--- a/src/openvpn/ssl_verify_polarssl.c
++++ b/src/openvpn/ssl_verify_polarssl.c
+@@ -40,6 +40,7 @@
+ #include "ssl_verify.h"
+ #include <polarssl/error.h>
+ #include <polarssl/bignum.h>
++#include <polarssl/oid.h>
+ #include <polarssl/sha1.h>
+
+ #define MAX_SUBJECT_LENGTH 256
+@@ -102,7 +103,7 @@ x509_get_username (char *cn, int cn_len,
+ /* Find common name */
+ while( name != NULL )
+ {
+- if( memcmp( name->oid.p, OID_CN, OID_SIZE(OID_CN) ) == 0)
++ if( memcmp( name->oid.p, OID_AT_CN, OID_SIZE(OID_AT_CN) ) == 0)
+ break;
+
+ name = name->next;
+@@ -224,60 +225,18 @@ x509_setenv (struct env_set *es, int cer
+ while( name != NULL )
+ {
+ char name_expand[64+8];
++ const char *shortname;
+
+- if( name->oid.len == 2 && memcmp( name->oid.p, OID_X520, 2 ) == 0 )
++ if( 0 == oid_get_attr_short_name(&name->oid, &shortname) )
+ {
+- switch( name->oid.p[2] )
+- {
+- case X520_COMMON_NAME:
+- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_CN",
+- cert_depth); break;
+-
+- case X520_COUNTRY:
+- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_C",
+- cert_depth); break;
+-
+- case X520_LOCALITY:
+- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_L",
+- cert_depth); break;
+-
+- case X520_STATE:
+- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_ST",
+- cert_depth); break;
+-
+- case X520_ORGANIZATION:
+- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_O",
+- cert_depth); break;
+-
+- case X520_ORG_UNIT:
+- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_OU",
+- cert_depth); break;
+-
+- default:
+- openvpn_snprintf (name_expand, sizeof(name_expand),
+- "X509_%d_0x%02X", cert_depth, name->oid.p[2]);
+- break;
+- }
++ openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_%s",
++ cert_depth, shortname);
++ }
++ else
++ {
++ openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?",
++ cert_depth);
+ }
+- else if( name->oid.len == 8 && memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
+- {
+- switch( name->oid.p[8] )
+- {
+- case PKCS9_EMAIL:
+- openvpn_snprintf (name_expand, sizeof(name_expand),
+- "X509_%d_emailAddress", cert_depth); break;
+-
+- default:
+- openvpn_snprintf (name_expand, sizeof(name_expand),
+- "X509_%d_0x%02X", cert_depth, name->oid.p[8]);
+- break;
+- }
+- }
+- else
+- {
+- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?",
+- cert_depth);
+- }
+
+ for( i = 0; i < name->val.len; i++ )
+ {
+--- a/configure.ac
++++ b/configure.ac
+@@ -832,13 +832,13 @@ if test "${with_crypto_library}" = "pola
+ #include <polarssl/version.h>
+ ]],
+ [[
+-#if POLARSSL_VERSION_NUMBER < 0x01020A00 || POLARSSL_VERSION_NUMBER >= 0x01030000
++#if POLARSSL_VERSION_NUMBER < 0x01030000
+ #error invalid version
+ #endif
+ ]]
+ )],
+ [AC_MSG_RESULT([ok])],
+- [AC_MSG_ERROR([PolarSSL 1.2.x required and must be 1.2.10 or later])]
++ [AC_MSG_ERROR([PolarSSL 1.3.x required])]
+ )
+
+ polarssl_with_pkcs11="no"
diff --git a/package/network/services/openvpn/patches/120-polarssl-disable-record-splitting.patch b/package/network/services/openvpn/patches/120-polarssl-disable-record-splitting.patch
new file mode 100644
index 0000000..b05592e
--- /dev/null
+++ b/package/network/services/openvpn/patches/120-polarssl-disable-record-splitting.patch
@@ -0,0 +1,14 @@
+--- a/src/openvpn/ssl_polarssl.c
++++ b/src/openvpn/ssl_polarssl.c
+@@ -707,6 +707,11 @@ void key_state_ssl_init(struct key_state
+ if (ssl_ctx->allowed_ciphers)
+ ssl_set_ciphersuites (ks_ssl->ctx, ssl_ctx->allowed_ciphers);
+
++ /* Disable record splitting (breaks current ssl handling) */
++#if defined(POLARSSL_SSL_CBC_RECORD_SPLITTING)
++ ssl_set_cbc_record_splitting (ks_ssl->ctx, SSL_CBC_RECORD_SPLITTING_DISABLED);
++#endif /* POLARSSL_SSL_CBC_RECORD_SPLITTING */
++
+ /* Initialise authentication information */
+ if (is_server)
+ ssl_set_dh_param_ctx (ks_ssl->ctx, ssl_ctx->dhm_ctx );
diff --git a/package/network/services/openvpn/patches/130-polarssl-disable-runtime-version-check.patch b/package/network/services/openvpn/patches/130-polarssl-disable-runtime-version-check.patch
new file mode 100644
index 0000000..c97e9f2
--- /dev/null
+++ b/package/network/services/openvpn/patches/130-polarssl-disable-runtime-version-check.patch
@@ -0,0 +1,11 @@
+--- a/src/openvpn/ssl_polarssl.c
++++ b/src/openvpn/ssl_polarssl.c
+@@ -1119,7 +1119,7 @@ const char *
+ get_ssl_library_version(void)
+ {
+ static char polar_version[30];
+- unsigned int pv = version_get_number();
++ unsigned int pv = POLARSSL_VERSION_NUMBER;
+ sprintf( polar_version, "PolarSSL %d.%d.%d",
+ (pv>>24)&0xff, (pv>>16)&0xff, (pv>>8)&0xff );
+ return polar_version;
diff --git a/package/network/services/ppp/Makefile b/package/network/services/ppp/Makefile
new file mode 100644
index 0000000..e0acf59
--- /dev/null
+++ b/package/network/services/ppp/Makefile
@@ -0,0 +1,265 @@
+#
+# 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
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ppp
+PKG_VERSION:=2.4.7
+PKG_RELEASE:=8
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://download.samba.org/pub/ppp/
+PKG_MD5SUM:=78818f40e6d33a1d1de68a1551f6595a
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=BSD-4-Clause
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_BUILD_DEPENDS:=libpcap
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ppp/Default
+ SECTION:=net
+ CATEGORY:=Network
+ URL:=http://ppp.samba.org/
+endef
+
+define Package/ppp
+$(call Package/ppp/Default)
+ DEPENDS:=+kmod-ppp
+ TITLE:=PPP daemon
+ VARIANT:=default
+endef
+
+define Package/ppp-multilink
+$(call Package/ppp/Default)
+ DEPENDS:=+kmod-ppp
+ TITLE:=PPP daemon (with multilink support)
+ VARIANT:=multilink
+endef
+
+define Package/ppp/description
+This package contains the PPP (Point-to-Point Protocol) daemon.
+endef
+
+define Package/ppp/conffiles
+/etc/ppp/chap-secrets
+/etc/ppp/filter
+/etc/ppp/ip-down
+/etc/ppp/ip-up
+/etc/ppp/ipv6-down
+/etc/ppp/ipv6-up
+/etc/ppp/options
+endef
+
+define Package/ppp-mod-pppoa
+$(call Package/ppp/Default)
+ DEPENDS:=@(PACKAGE_ppp||PACKAGE_ppp-multilink) +linux-atm +kmod-pppoa
+ TITLE:=PPPoA plugin
+endef
+
+define Package/ppp-mod-pppoa/description
+This package contains a PPPoA (PPP over ATM) plugin for ppp.
+endef
+
+define Package/ppp-mod-pppoe
+$(call Package/ppp/Default)
+ DEPENDS:=@(PACKAGE_ppp||PACKAGE_ppp-multilink) +kmod-pppoe
+ TITLE:=PPPoE plugin
+endef
+
+define Package/ppp-mod-pppoe/description
+This package contains a PPPoE (PPP over Ethernet) plugin for ppp.
+endef
+
+define Package/ppp-mod-radius
+$(call Package/ppp/Default)
+ DEPENDS:=@(PACKAGE_ppp||PACKAGE_ppp-multilink)
+ TITLE:=RADIUS plugin
+endef
+
+define Package/ppp-mod-radius/description
+This package contains a RADIUS (Remote Authentication Dial-In User Service)
+plugin for ppp.
+endef
+
+define Package/ppp-mod-radius/conffiles
+/etc/ppp/radius.conf
+/etc/ppp/radius/
+endef
+
+define Package/ppp-mod-pppol2tp
+$(call Package/ppp/Default)
+ DEPENDS:=@(PACKAGE_ppp||PACKAGE_ppp-multilink) +kmod-pppol2tp
+ TITLE:=PPPoL2TP plugin
+endef
+
+define Package/ppp-mod-pppol2tp/description
+This package contains a PPPoL2TP (PPP over L2TP) plugin for ppp.
+endef
+
+define Package/ppp-mod-pptp
+$(call Package/ppp/Default)
+ DEPENDS:=@(PACKAGE_ppp||PACKAGE_ppp-multilink) +kmod-pptp +kmod-mppe +resolveip
+ TITLE:=PPtP plugin
+endef
+
+define Package/ppp-mod-pptp/description
+This package contains a PPtP plugin for ppp.
+endef
+
+define Package/chat
+$(call Package/ppp/Default)
+ TITLE:=Establish conversation with a modem
+endef
+
+define Package/chat/description
+This package contains an utility to establish conversation with other PPP servers
+(via a modem).
+endef
+
+define Package/pppdump
+$(call Package/ppp/Default)
+ DEPENDS:=@(PACKAGE_ppp||PACKAGE_ppp-multilink)
+ TITLE:=Read PPP record file
+endef
+
+define Package/pppdump/description
+This package contains an utility to read PPP record file.
+endef
+
+define Package/pppstats
+$(call Package/ppp/Default)
+ DEPENDS:=@(PACKAGE_ppp||PACKAGE_ppp-multilink)
+ TITLE:=Report PPP statistics
+endef
+
+define Package/pppstats/description
+This package contains an utility to report PPP statistics.
+endef
+
+
+define Build/Configure
+$(call Build/Configure/Default,, \
+ UNAME_S="Linux" \
+ UNAME_R="$(LINUX_VERSION)" \
+ UNAME_M="$(ARCH)" \
+)
+ mkdir -p $(PKG_BUILD_DIR)/pppd/plugins/pppoatm/linux
+ cp \
+ $(LINUX_DIR)/include/linux/compiler.h \
+ $(LINUX_DIR)/include/$(LINUX_UAPI_DIR)linux/atm*.h \
+ $(PKG_BUILD_DIR)/pppd/plugins/pppoatm/linux/
+endef
+
+MAKE_FLAGS += COPTS="$(TARGET_CFLAGS)" \
+ PRECOMPILED_FILTER=1 \
+ STAGING_DIR="$(STAGING_DIR)"
+
+ifeq ($(BUILD_VARIANT),multilink)
+ MAKE_FLAGS += HAVE_MULTILINK=y
+else
+ MAKE_FLAGS += HAVE_MULTILINK=
+endif
+
+ifdef CONFIG_USE_MUSL
+ MAKE_FLAGS += USE_LIBUTIL=
+endif
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/include/pppd $(1)/usr/include/
+endef
+
+define Package/ppp/script_install
+endef
+
+define Package/ppp/install
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/pppd $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/etc/ppp
+ $(INSTALL_CONF) ./files/etc/ppp/chap-secrets $(1)/etc/ppp/
+ $(INSTALL_DATA) ./files/etc/ppp/filter $(1)/etc/ppp/
+ $(INSTALL_DATA) ./files/etc/ppp/options $(1)/etc/ppp/
+ $(LN) /tmp/resolv.conf.ppp $(1)/etc/ppp/resolv.conf
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/ppp.sh $(1)/lib/netifd/proto/
+ $(INSTALL_BIN) ./files/lib/netifd/ppp-up $(1)/lib/netifd/
+ $(INSTALL_BIN) ./files/lib/netifd/ppp-down $(1)/lib/netifd/
+endef
+Package/ppp-multilink/install=$(Package/ppp/install)
+
+define Package/ppp-mod-pppoa/install
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_VERSION)/pppoatm.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
+endef
+
+define Package/ppp-mod-pppoe/install
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_VERSION)/rp-pppoe.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
+endef
+
+define Package/ppp-mod-radius/install
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_VERSION)/radius.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
+ $(INSTALL_DIR) $(1)/etc/ppp
+ $(INSTALL_DATA) ./files/etc/ppp/radius.conf $(1)/etc/ppp/
+ $(INSTALL_DIR) $(1)/etc/ppp/radius
+ $(INSTALL_DATA) ./files/etc/ppp/radius/dictionary* \
+ $(1)/etc/ppp/radius/
+ $(INSTALL_CONF) ./files/etc/ppp/radius/servers \
+ $(1)/etc/ppp/radius/
+endef
+
+define Package/ppp-mod-pppol2tp/install
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_VERSION)/pppol2tp.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
+endef
+
+define Package/ppp-mod-pptp/install
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_VERSION)/pptp.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
+ $(INSTALL_DIR) $(1)/etc/ppp
+ $(INSTALL_DATA) ./files/etc/ppp/options.pptp $(1)/etc/ppp/
+endef
+
+define Package/chat/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/chat $(1)/usr/sbin/
+endef
+
+define Package/pppdump/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/pppdump $(1)/usr/sbin/
+endef
+
+define Package/pppstats/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/pppstats $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,ppp))
+$(eval $(call BuildPackage,ppp-multilink))
+$(eval $(call BuildPackage,ppp-mod-pppoa))
+$(eval $(call BuildPackage,ppp-mod-pppoe))
+$(eval $(call BuildPackage,ppp-mod-radius))
+$(eval $(call BuildPackage,ppp-mod-pppol2tp))
+$(eval $(call BuildPackage,ppp-mod-pptp))
+$(eval $(call BuildPackage,chat))
+$(eval $(call BuildPackage,pppdump))
+$(eval $(call BuildPackage,pppstats))
diff --git a/package/network/services/ppp/files/etc/ppp/chap-secrets b/package/network/services/ppp/files/etc/ppp/chap-secrets
new file mode 100644
index 0000000..6ab76e4
--- /dev/null
+++ b/package/network/services/ppp/files/etc/ppp/chap-secrets
@@ -0,0 +1 @@
+#USERNAME PROVIDER PASSWORD IPADDRESS
diff --git a/package/network/services/ppp/files/etc/ppp/filter b/package/network/services/ppp/files/etc/ppp/filter
new file mode 100644
index 0000000..ec72a81
--- /dev/null
+++ b/package/network/services/ppp/files/etc/ppp/filter
@@ -0,0 +1,23 @@
+#
+# Expression: outbound and not icmp[0] != 8 and not tcp[13] & 4 != 0
+#
+19
+48 0 0 0
+21 0 16 1
+40 0 0 2
+21 0 13 33
+48 0 0 13
+21 0 5 1
+40 0 0 10
+69 9 0 8191
+177 0 0 4
+80 0 0 4
+21 6 7 8
+21 0 5 6
+40 0 0 10
+69 3 0 8191
+177 0 0 4
+80 0 0 17
+69 1 0 4
+6 0 0 4
+6 0 0 0
diff --git a/package/network/services/ppp/files/etc/ppp/options b/package/network/services/ppp/files/etc/ppp/options
new file mode 100644
index 0000000..6b93f7b
--- /dev/null
+++ b/package/network/services/ppp/files/etc/ppp/options
@@ -0,0 +1,10 @@
+#debug
+logfile /dev/null
+noipdefault
+noaccomp
+nopcomp
+nocrtscts
+lock
+maxfail 0
+lcp-echo-failure 5
+lcp-echo-interval 1
diff --git a/package/network/services/ppp/files/etc/ppp/options.pptp b/package/network/services/ppp/files/etc/ppp/options.pptp
new file mode 100644
index 0000000..46a3f48
--- /dev/null
+++ b/package/network/services/ppp/files/etc/ppp/options.pptp
@@ -0,0 +1,7 @@
+noipdefault
+noauth
+nobsdcomp
+nodeflate
+idle 0
+mppe required,no40,no56,stateless
+maxfail 0
diff --git a/package/network/services/ppp/files/etc/ppp/radius.conf b/package/network/services/ppp/files/etc/ppp/radius.conf
new file mode 100644
index 0000000..0f24a8c
--- /dev/null
+++ b/package/network/services/ppp/files/etc/ppp/radius.conf
@@ -0,0 +1,8 @@
+authserver localhost:1812
+acctserver localhost:1813
+dictionary /etc/ppp/radius/dictionary
+servers /etc/ppp/radius/servers
+mapfile /dev/null
+seqfile /tmp/radius.seq
+radius_timeout 5
+radius_retries 3
diff --git a/package/network/services/ppp/files/etc/ppp/radius/dictionary b/package/network/services/ppp/files/etc/ppp/radius/dictionary
new file mode 100644
index 0000000..706d1ce
--- /dev/null
+++ b/package/network/services/ppp/files/etc/ppp/radius/dictionary
@@ -0,0 +1,253 @@
+#
+# Updated 97/06/13 to livingston-radius-2.01 miquels@cistron.nl
+#
+# This file contains dictionary translations for parsing
+# requests and generating responses. All transactions are
+# composed of Attribute/Value Pairs. The value of each attribute
+# is specified as one of 4 data types. Valid data types are:
+#
+# string - 0-253 octets
+# ipaddr - 4 octets in network byte order
+# integer - 32 bit value in big endian order (high byte first)
+# date - 32 bit value in big endian order - seconds since
+# 00:00:00 GMT, Jan. 1, 1970
+#
+# Enumerated values are stored in the user file with dictionary
+# VALUE translations for easy administration.
+#
+# Example:
+#
+# ATTRIBUTE VALUE
+# --------------- -----
+# Framed-Protocol = PPP
+# 7 = 1 (integer encoding)
+#
+
+# The dictionary format now supports vendor-specific attributes.
+# Vendors are introduced like this:
+#
+# VENDOR vendor_name vendor_number
+#
+# For example:
+#
+# VENDOR RoaringPenguin 10055
+#
+# Vendor-specific attributes have a fifth field with the name of the
+# vendor. For example:
+#
+# ATTRIBUTE RP-Upstream-Speed-Limit 1 integer RoaringPenguin
+#
+# introduces a Roaring Penguin vendor-specific attribbute with name
+# RP-Upstream-Speed-Limit, number 1, type integer and vendor RoaringPenguin.
+
+#
+# Following are the proper new names. Use these.
+#
+ATTRIBUTE User-Name 1 string
+ATTRIBUTE Password 2 string
+ATTRIBUTE CHAP-Password 3 string
+ATTRIBUTE NAS-IP-Address 4 ipaddr
+ATTRIBUTE NAS-Port-Id 5 integer
+ATTRIBUTE Service-Type 6 integer
+ATTRIBUTE Framed-Protocol 7 integer
+ATTRIBUTE Framed-IP-Address 8 ipaddr
+ATTRIBUTE Framed-IP-Netmask 9 ipaddr
+ATTRIBUTE Framed-Routing 10 integer
+ATTRIBUTE Filter-Id 11 string
+ATTRIBUTE Framed-MTU 12 integer
+ATTRIBUTE Framed-Compression 13 integer
+ATTRIBUTE Login-IP-Host 14 ipaddr
+ATTRIBUTE Login-Service 15 integer
+ATTRIBUTE Login-TCP-Port 16 integer
+ATTRIBUTE Reply-Message 18 string
+ATTRIBUTE Callback-Number 19 string
+ATTRIBUTE Callback-Id 20 string
+ATTRIBUTE Framed-Route 22 string
+ATTRIBUTE Framed-IPX-Network 23 ipaddr
+ATTRIBUTE State 24 string
+ATTRIBUTE Class 25 string
+ATTRIBUTE Session-Timeout 27 integer
+ATTRIBUTE Idle-Timeout 28 integer
+ATTRIBUTE Termination-Action 29 integer
+ATTRIBUTE Called-Station-Id 30 string
+ATTRIBUTE Calling-Station-Id 31 string
+ATTRIBUTE NAS-Identifier 32 string
+ATTRIBUTE Acct-Status-Type 40 integer
+ATTRIBUTE Acct-Delay-Time 41 integer
+ATTRIBUTE Acct-Input-Octets 42 integer
+ATTRIBUTE Acct-Output-Octets 43 integer
+ATTRIBUTE Acct-Session-Id 44 string
+ATTRIBUTE Acct-Authentic 45 integer
+ATTRIBUTE Acct-Session-Time 46 integer
+ATTRIBUTE Acct-Input-Packets 47 integer
+ATTRIBUTE Acct-Output-Packets 48 integer
+ATTRIBUTE Acct-Terminate-Cause 49 integer
+ATTRIBUTE Chap-Challenge 60 string
+ATTRIBUTE NAS-Port-Type 61 integer
+ATTRIBUTE Port-Limit 62 integer
+ATTRIBUTE Connect-Info 77 string
+
+# RFC 2869
+ATTRIBUTE Acct-Interim-Interval 85 integer
+
+#
+# Experimental Non Protocol Attributes used by Cistron-Radiusd
+#
+ATTRIBUTE Huntgroup-Name 221 string
+ATTRIBUTE User-Category 1029 string
+ATTRIBUTE Group-Name 1030 string
+ATTRIBUTE Simultaneous-Use 1034 integer
+ATTRIBUTE Strip-User-Name 1035 integer
+ATTRIBUTE Fall-Through 1036 integer
+ATTRIBUTE Add-Port-To-IP-Address 1037 integer
+ATTRIBUTE Exec-Program 1038 string
+ATTRIBUTE Exec-Program-Wait 1039 string
+ATTRIBUTE Hint 1040 string
+
+#
+# Non-Protocol Attributes
+# These attributes are used internally by the server
+#
+ATTRIBUTE Expiration 21 date
+ATTRIBUTE Auth-Type 1000 integer
+ATTRIBUTE Menu 1001 string
+ATTRIBUTE Termination-Menu 1002 string
+ATTRIBUTE Prefix 1003 string
+ATTRIBUTE Suffix 1004 string
+ATTRIBUTE Group 1005 string
+ATTRIBUTE Crypt-Password 1006 string
+ATTRIBUTE Connect-Rate 1007 integer
+
+#
+# Experimental, implementation specific attributes
+#
+# Limit session traffic
+ATTRIBUTE Session-Octets-Limit 227 integer
+# What to assume as limit - 0 in+out, 1 in, 2 out, 3 max(in,out)
+ATTRIBUTE Octets-Direction 228 integer
+
+#
+# Integer Translations
+#
+
+# User Types
+
+VALUE Service-Type Login-User 1
+VALUE Service-Type Framed-User 2
+VALUE Service-Type Callback-Login-User 3
+VALUE Service-Type Callback-Framed-User 4
+VALUE Service-Type Outbound-User 5
+VALUE Service-Type Administrative-User 6
+VALUE Service-Type NAS-Prompt-User 7
+
+# Framed Protocols
+
+VALUE Framed-Protocol PPP 1
+VALUE Framed-Protocol SLIP 2
+
+# Framed Routing Values
+
+VALUE Framed-Routing None 0
+VALUE Framed-Routing Broadcast 1
+VALUE Framed-Routing Listen 2
+VALUE Framed-Routing Broadcast-Listen 3
+
+# Framed Compression Types
+
+VALUE Framed-Compression None 0
+VALUE Framed-Compression Van-Jacobson-TCP-IP 1
+
+# Login Services
+
+VALUE Login-Service Telnet 0
+VALUE Login-Service Rlogin 1
+VALUE Login-Service TCP-Clear 2
+VALUE Login-Service PortMaster 3
+
+# Status Types
+
+VALUE Acct-Status-Type Start 1
+VALUE Acct-Status-Type Stop 2
+VALUE Acct-Status-Type Accounting-On 7
+VALUE Acct-Status-Type Accounting-Off 8
+
+# Authentication Types
+
+VALUE Acct-Authentic RADIUS 1
+VALUE Acct-Authentic Local 2
+VALUE Acct-Authentic PowerLink128 100
+
+# Termination Options
+
+VALUE Termination-Action Default 0
+VALUE Termination-Action RADIUS-Request 1
+
+# NAS Port Types, available in 3.3.1 and later
+
+VALUE NAS-Port-Type Async 0
+VALUE NAS-Port-Type Sync 1
+VALUE NAS-Port-Type ISDN 2
+VALUE NAS-Port-Type ISDN-V120 3
+VALUE NAS-Port-Type ISDN-V110 4
+
+# Acct Terminate Causes, available in 3.3.2 and later
+
+VALUE Acct-Terminate-Cause User-Request 1
+VALUE Acct-Terminate-Cause Lost-Carrier 2
+VALUE Acct-Terminate-Cause Lost-Service 3
+VALUE Acct-Terminate-Cause Idle-Timeout 4
+VALUE Acct-Terminate-Cause Session-Timeout 5
+VALUE Acct-Terminate-Cause Admin-Reset 6
+VALUE Acct-Terminate-Cause Admin-Reboot 7
+VALUE Acct-Terminate-Cause Port-Error 8
+VALUE Acct-Terminate-Cause NAS-Error 9
+VALUE Acct-Terminate-Cause NAS-Request 10
+VALUE Acct-Terminate-Cause NAS-Reboot 11
+VALUE Acct-Terminate-Cause Port-Unneeded 12
+VALUE Acct-Terminate-Cause Port-Preempted 13
+VALUE Acct-Terminate-Cause Port-Suspended 14
+VALUE Acct-Terminate-Cause Service-Unavailable 15
+VALUE Acct-Terminate-Cause Callback 16
+VALUE Acct-Terminate-Cause User-Error 17
+VALUE Acct-Terminate-Cause Host-Request 18
+
+#
+# Non-Protocol Integer Translations
+#
+
+VALUE Auth-Type Local 0
+VALUE Auth-Type System 1
+VALUE Auth-Type SecurID 2
+VALUE Auth-Type Crypt-Local 3
+VALUE Auth-Type Reject 4
+
+#
+# Cistron extensions
+#
+VALUE Auth-Type Pam 253
+VALUE Auth-Type None 254
+
+#
+# Experimental Non-Protocol Integer Translations for Cistron-Radiusd
+#
+VALUE Fall-Through No 0
+VALUE Fall-Through Yes 1
+VALUE Add-Port-To-IP-Address No 0
+VALUE Add-Port-To-IP-Address Yes 1
+
+#
+# Configuration Values
+# uncomment these two lines to turn account expiration on
+#
+
+#VALUE Server-Config Password-Expiration 30
+#VALUE Server-Config Password-Warning 5
+
+# Octets-Direction
+VALUE Octets-Direction Sum 0
+VALUE Octets-Direction Input 1
+VALUE Octets-Direction Output 2
+VALUE Octets-Direction MaxOveral 3
+VALUE Octets-Direction MaxSession 4
+
+INCLUDE /etc/ppp/radius/dictionary.microsoft
diff --git a/package/network/services/ppp/files/etc/ppp/radius/dictionary.asnet b/package/network/services/ppp/files/etc/ppp/radius/dictionary.asnet
new file mode 100644
index 0000000..337d1e1
--- /dev/null
+++ b/package/network/services/ppp/files/etc/ppp/radius/dictionary.asnet
@@ -0,0 +1,3 @@
+VENDOR ASNET 50000
+ATTRIBUTE Speed-Down 1 string ASNET
+ATTRIBUTE Speed-Up 2 string ASNET
diff --git a/package/network/services/ppp/files/etc/ppp/radius/dictionary.microsoft b/package/network/services/ppp/files/etc/ppp/radius/dictionary.microsoft
new file mode 100644
index 0000000..2a6c20e
--- /dev/null
+++ b/package/network/services/ppp/files/etc/ppp/radius/dictionary.microsoft
@@ -0,0 +1,80 @@
+#
+# Microsoft's VSA's, from RFC 2548
+#
+#
+
+VENDOR Microsoft 311 Microsoft
+
+ATTRIBUTE MS-CHAP-Response 1 string Microsoft
+ATTRIBUTE MS-CHAP-Error 2 string Microsoft
+ATTRIBUTE MS-CHAP-CPW-1 3 string Microsoft
+ATTRIBUTE MS-CHAP-CPW-2 4 string Microsoft
+ATTRIBUTE MS-CHAP-LM-Enc-PW 5 string Microsoft
+ATTRIBUTE MS-CHAP-NT-Enc-PW 6 string Microsoft
+ATTRIBUTE MS-MPPE-Encryption-Policy 7 string Microsoft
+# This is referred to as both singular and plural in the RFC.
+# Plural seems to make more sense.
+ATTRIBUTE MS-MPPE-Encryption-Type 8 string Microsoft
+ATTRIBUTE MS-MPPE-Encryption-Types 8 string Microsoft
+ATTRIBUTE MS-RAS-Vendor 9 integer Microsoft
+ATTRIBUTE MS-CHAP-Domain 10 string Microsoft
+ATTRIBUTE MS-CHAP-Challenge 11 string Microsoft
+ATTRIBUTE MS-CHAP-MPPE-Keys 12 string Microsoft
+ATTRIBUTE MS-BAP-Usage 13 integer Microsoft
+ATTRIBUTE MS-Link-Utilization-Threshold 14 integer Microsoft
+ATTRIBUTE MS-Link-Drop-Time-Limit 15 integer Microsoft
+ATTRIBUTE MS-MPPE-Send-Key 16 string Microsoft
+ATTRIBUTE MS-MPPE-Recv-Key 17 string Microsoft
+ATTRIBUTE MS-RAS-Version 18 string Microsoft
+ATTRIBUTE MS-Old-ARAP-Password 19 string Microsoft
+ATTRIBUTE MS-New-ARAP-Password 20 string Microsoft
+ATTRIBUTE MS-ARAP-PW-Change-Reason 21 integer Microsoft
+
+ATTRIBUTE MS-Filter 22 string Microsoft
+ATTRIBUTE MS-Acct-Auth-Type 23 integer Microsoft
+ATTRIBUTE MS-Acct-EAP-Type 24 integer Microsoft
+
+ATTRIBUTE MS-CHAP2-Response 25 string Microsoft
+ATTRIBUTE MS-CHAP2-Success 26 string Microsoft
+ATTRIBUTE MS-CHAP2-CPW 27 string Microsoft
+
+ATTRIBUTE MS-Primary-DNS-Server 28 ipaddr Microsoft
+ATTRIBUTE MS-Secondary-DNS-Server 29 ipaddr Microsoft
+ATTRIBUTE MS-Primary-NBNS-Server 30 ipaddr Microsoft
+ATTRIBUTE MS-Secondary-NBNS-Server 31 ipaddr Microsoft
+
+#ATTRIBUTE MS-ARAP-Challenge 33 string Microsoft
+
+
+#
+# Integer Translations
+#
+
+# MS-BAP-Usage Values
+
+VALUE MS-BAP-Usage Not-Allowed 0
+VALUE MS-BAP-Usage Allowed 1
+VALUE MS-BAP-Usage Required 2
+
+# MS-ARAP-Password-Change-Reason Values
+
+VALUE MS-ARAP-PW-Change-Reason Just-Change-Password 1
+VALUE MS-ARAP-PW-Change-Reason Expired-Password 2
+VALUE MS-ARAP-PW-Change-Reason Admin-Requires-Password-Change 3
+VALUE MS-ARAP-PW-Change-Reason Password-Too-Short 4
+
+# MS-Acct-Auth-Type Values
+
+VALUE MS-Acct-Auth-Type PAP 1
+VALUE MS-Acct-Auth-Type CHAP 2
+VALUE MS-Acct-Auth-Type MS-CHAP-1 3
+VALUE MS-Acct-Auth-Type MS-CHAP-2 4
+VALUE MS-Acct-Auth-Type EAP 5
+
+# MS-Acct-EAP-Type Values
+
+VALUE MS-Acct-EAP-Type MD5 4
+VALUE MS-Acct-EAP-Type OTP 5
+VALUE MS-Acct-EAP-Type Generic-Token-Card 6
+VALUE MS-Acct-EAP-Type TLS 13
+
diff --git a/package/network/services/ppp/files/etc/ppp/radius/servers b/package/network/services/ppp/files/etc/ppp/radius/servers
new file mode 100644
index 0000000..0d4f069
--- /dev/null
+++ b/package/network/services/ppp/files/etc/ppp/radius/servers
@@ -0,0 +1,2 @@
+# SERVER SECRET
+localhost secret
diff --git a/package/network/services/ppp/files/lib/netifd/ppp-down b/package/network/services/ppp/files/lib/netifd/ppp-down
new file mode 100755
index 0000000..94cefc4
--- /dev/null
+++ b/package/network/services/ppp/files/lib/netifd/ppp-down
@@ -0,0 +1,13 @@
+#!/bin/sh
+PPP_IPPARAM="$6"
+
+. /lib/netifd/netifd-proto.sh
+proto_init_update "$IFNAME" 0
+proto_send_update "$PPP_IPPARAM"
+
+[ -d /etc/ppp/ip-down.d ] && {
+ for SCRIPT in /etc/ppp/ip-down.d/*
+ do
+ [ -x "$SCRIPT" ] && "$SCRIPT" "$@"
+ done
+}
diff --git a/package/network/services/ppp/files/lib/netifd/ppp-up b/package/network/services/ppp/files/lib/netifd/ppp-up
new file mode 100755
index 0000000..7511042
--- /dev/null
+++ b/package/network/services/ppp/files/lib/netifd/ppp-up
@@ -0,0 +1,31 @@
+#!/bin/sh
+PPP_IPPARAM="$6"
+
+. /lib/netifd/netifd-proto.sh
+proto_init_update "$IFNAME" 1 1
+proto_set_keep 1
+[ -n "$PPP_IPPARAM" ] && {
+ [ -n "$IPLOCAL" ] && proto_add_ipv4_address "$IPLOCAL" 32 "" "${IPREMOTE:-2.2.2.2}"
+ [ -n "$IPREMOTE" ] && proto_add_ipv4_route 0.0.0.0 0 "$IPREMOTE"
+ [ -n "$LLLOCAL" ] && proto_add_ipv6_address "$LLLOCAL" 128
+ [ -n "$DNS1" ] && proto_add_dns_server "$DNS1"
+ [ -n "$DNS2" -a "$DNS1" != "$DNS2" ] && proto_add_dns_server "$DNS2"
+}
+proto_send_update "$PPP_IPPARAM"
+
+[ -d /etc/ppp/ip-up.d ] && {
+ for SCRIPT in /etc/ppp/ip-up.d/*
+ do
+ [ -x "$SCRIPT" ] && "$SCRIPT" "$@"
+ done
+}
+
+if [ -n "$AUTOIPV6" ]; then
+ json_init
+ json_add_string name "${PPP_IPPARAM}_6"
+ json_add_string ifname "@$PPP_IPPARAM"
+ json_add_string proto "dhcpv6"
+ [ -n "$EXTENDPREFIX" ] && json_add_string extendprefix 1
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+fi
diff --git a/package/network/services/ppp/files/ppp.sh b/package/network/services/ppp/files/ppp.sh
new file mode 100755
index 0000000..2a7e76b
--- /dev/null
+++ b/package/network/services/ppp/files/ppp.sh
@@ -0,0 +1,314 @@
+#!/bin/sh
+
+[ -x /usr/sbin/pppd ] || exit 0
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+ppp_select_ipaddr()
+{
+ local subnets=$1
+ local res
+ local res_mask
+
+ for subnet in $subnets; do
+ local addr="${subnet%%/*}"
+ local mask="${subnet#*/}"
+
+ if [ -n "$res_mask" -a "$mask" != 32 ]; then
+ [ "$mask" -gt "$res_mask" ] || [ "$res_mask" = 32 ] && {
+ res="$addr"
+ res_mask="$mask"
+ }
+ elif [ -z "$res_mask" ]; then
+ res="$addr"
+ res_mask="$mask"
+ fi
+ done
+
+ echo "$res"
+}
+
+ppp_exitcode_tostring()
+{
+ local errorcode=$1
+ [ -n "$errorcode" ] || errorcode=5
+
+ case "$errorcode" in
+ 0) echo "OK" ;;
+ 1) echo "FATAL_ERROR" ;;
+ 2) echo "OPTION_ERROR" ;;
+ 3) echo "NOT_ROOT" ;;
+ 4) echo "NO_KERNEL_SUPPORT" ;;
+ 5) echo "USER_REQUEST" ;;
+ 6) echo "LOCK_FAILED" ;;
+ 7) echo "OPEN_FAILED" ;;
+ 8) echo "CONNECT_FAILED" ;;
+ 9) echo "PTYCMD_FAILED" ;;
+ 10) echo "NEGOTIATION_FAILED" ;;
+ 11) echo "PEER_AUTH_FAILED" ;;
+ 12) echo "IDLE_TIMEOUT" ;;
+ 13) echo "CONNECT_TIME" ;;
+ 14) echo "CALLBACK" ;;
+ 15) echo "PEER_DEAD" ;;
+ 16) echo "HANGUP" ;;
+ 17) echo "LOOPBACK" ;;
+ 18) echo "INIT_FAILED" ;;
+ 19) echo "AUTH_TOPEER_FAILED" ;;
+ 20) echo "TRAFFIC_LIMIT" ;;
+ 21) echo "CNID_AUTH_FAILED";;
+ *) echo "UNKNOWN_ERROR" ;;
+ esac
+}
+
+ppp_generic_init_config() {
+ proto_config_add_string username
+ proto_config_add_string password
+ proto_config_add_string keepalive
+ proto_config_add_boolean keepalive_adaptive
+ proto_config_add_int demand
+ proto_config_add_string pppd_options
+ proto_config_add_string 'connect:file'
+ proto_config_add_string 'disconnect:file'
+ proto_config_add_string ipv6
+ proto_config_add_boolean authfail
+ proto_config_add_int mtu
+ proto_config_add_string pppname
+ proto_config_add_string unnumbered
+}
+
+ppp_generic_setup() {
+ local config="$1"; shift
+ local localip
+
+ json_get_vars ipv6 demand keepalive keepalive_adaptive username password pppd_options pppname unnumbered
+ if [ "$ipv6" = 0 ]; then
+ ipv6=""
+ elif [ -z "$ipv6" -o "$ipv6" = auto ]; then
+ ipv6=1
+ autoipv6=1
+ fi
+
+ if [ "${demand:-0}" -gt 0 ]; then
+ demand="precompiled-active-filter /etc/ppp/filter demand idle $demand"
+ else
+ demand=""
+ fi
+ [ -n "$mtu" ] || json_get_var mtu mtu
+ [ -n "$pppname" ] || pppname="${proto:-ppp}-$config"
+ [ -n "$unnumbered" ] && {
+ local subnets
+ ( proto_add_host_dependency "$config" "" "$unnumbered" )
+ network_get_subnets subnets "$unnumbered"
+ localip=$(ppp_select_ipaddr "$subnets")
+ [ -n "$localip" ] || {
+ proto_block_restart "$config"
+ return
+ }
+ }
+
+ local lcp_failure="${keepalive%%[, ]*}"
+ local lcp_interval="${keepalive##*[, ]}"
+ local lcp_adaptive="lcp-echo-adaptive"
+ [ "${lcp_failure:-0}" -lt 1 ] && lcp_failure=""
+ [ "$lcp_interval" != "$keepalive" ] || lcp_interval=5
+ [ "${keepalive_adaptive:-1}" -lt 1 ] && lcp_adaptive=""
+ [ -n "$connect" ] || json_get_var connect connect
+ [ -n "$disconnect" ] || json_get_var disconnect disconnect
+
+ proto_run_command "$config" /usr/sbin/pppd \
+ nodetach ipparam "$config" \
+ ifname "$pppname" \
+ ${localip:+$localip:} \
+ ${lcp_failure:+lcp-echo-interval $lcp_interval lcp-echo-failure $lcp_failure $lcp_adaptive} \
+ ${ipv6:++ipv6} \
+ ${autoipv6:+set AUTOIPV6=1} \
+ nodefaultroute \
+ usepeerdns \
+ $demand maxfail 1 \
+ ${username:+user "$username" password "$password"} \
+ ${connect:+connect "$connect"} \
+ ${disconnect:+disconnect "$disconnect"} \
+ ip-up-script /lib/netifd/ppp-up \
+ ipv6-up-script /lib/netifd/ppp-up \
+ ip-down-script /lib/netifd/ppp-down \
+ ipv6-down-script /lib/netifd/ppp-down \
+ ${mtu:+mtu $mtu mru $mtu} \
+ "$@" $pppd_options
+}
+
+ppp_generic_teardown() {
+ local interface="$1"
+ local errorstring=$(ppp_exitcode_tostring $ERROR)
+
+ case "$ERROR" in
+ 0)
+ ;;
+ 2)
+ proto_notify_error "$interface" "$errorstring"
+ proto_block_restart "$interface"
+ ;;
+ 11|19)
+ json_get_var authfail authfail
+ proto_notify_error "$interface" "$errorstring"
+ if [ "${authfail:-0}" -gt 0 ]; then
+ proto_block_restart "$interface"
+ fi
+ ;;
+ *)
+ proto_notify_error "$interface" "$errorstring"
+ ;;
+ esac
+
+ proto_kill_command "$interface"
+}
+
+# PPP on serial device
+
+proto_ppp_init_config() {
+ proto_config_add_string "device"
+ ppp_generic_init_config
+ no_device=1
+ available=1
+ lasterror=1
+}
+
+proto_ppp_setup() {
+ local config="$1"
+
+ json_get_var device device
+ ppp_generic_setup "$config" "$device"
+}
+
+proto_ppp_teardown() {
+ ppp_generic_teardown "$@"
+}
+
+proto_pppoe_init_config() {
+ ppp_generic_init_config
+ proto_config_add_string "ac"
+ proto_config_add_string "service"
+ proto_config_add_string "host_uniq"
+ lasterror=1
+}
+
+proto_pppoe_setup() {
+ local config="$1"
+ local iface="$2"
+
+ for module in slhc ppp_generic pppox pppoe; do
+ /sbin/insmod $module 2>&- >&-
+ done
+
+ json_get_var mtu mtu
+ mtu="${mtu:-1492}"
+
+ json_get_var ac ac
+ json_get_var service service
+ json_get_var host_uniq host_uniq
+
+ ppp_generic_setup "$config" \
+ plugin rp-pppoe.so \
+ ${ac:+rp_pppoe_ac "$ac"} \
+ ${service:+rp_pppoe_service "$service"} \
+ ${host_uniq:+host-uniq "$host_uniq"} \
+ "nic-$iface"
+}
+
+proto_pppoe_teardown() {
+ ppp_generic_teardown "$@"
+}
+
+proto_pppoa_init_config() {
+ ppp_generic_init_config
+ proto_config_add_int "atmdev"
+ proto_config_add_int "vci"
+ proto_config_add_int "vpi"
+ proto_config_add_string "encaps"
+ no_device=1
+ available=1
+ lasterror=1
+}
+
+proto_pppoa_setup() {
+ local config="$1"
+ local iface="$2"
+
+ for module in slhc ppp_generic pppox pppoatm; do
+ /sbin/insmod $module 2>&- >&-
+ done
+
+ json_get_vars atmdev vci vpi encaps
+
+ case "$encaps" in
+ 1|vc) encaps="vc-encaps" ;;
+ *) encaps="llc-encaps" ;;
+ esac
+
+ ppp_generic_setup "$config" \
+ plugin pppoatm.so \
+ ${atmdev:+$atmdev.}${vpi:-8}.${vci:-35} \
+ ${encaps}
+}
+
+proto_pppoa_teardown() {
+ ppp_generic_teardown "$@"
+}
+
+proto_pptp_init_config() {
+ ppp_generic_init_config
+ proto_config_add_string "server"
+ proto_config_add_string "interface"
+ available=1
+ no_device=1
+ lasterror=1
+}
+
+proto_pptp_setup() {
+ local config="$1"
+ local iface="$2"
+
+ local ip serv_addr server interface
+ json_get_vars interface server
+ [ -n "$server" ] && {
+ for ip in $(resolveip -t 5 "$server"); do
+ ( proto_add_host_dependency "$config" "$ip" $interface )
+ serv_addr=1
+ done
+ }
+ [ -n "$serv_addr" ] || {
+ echo "Could not resolve server address"
+ sleep 5
+ proto_setup_failed "$config"
+ exit 1
+ }
+
+ local load
+ for module in slhc ppp_generic ppp_async ppp_mppe ip_gre gre pptp; do
+ grep -q "^$module " /proc/modules && continue
+ /sbin/insmod $module 2>&- >&-
+ load=1
+ done
+ [ "$load" = "1" ] && sleep 1
+
+ ppp_generic_setup "$config" \
+ plugin pptp.so \
+ pptp_server $server \
+ file /etc/ppp/options.pptp
+}
+
+proto_pptp_teardown() {
+ ppp_generic_teardown "$@"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol ppp
+ [ -f /usr/lib/pppd/*/rp-pppoe.so ] && add_protocol pppoe
+ [ -f /usr/lib/pppd/*/pppoatm.so ] && add_protocol pppoa
+ [ -f /usr/lib/pppd/*/pptp.so ] && add_protocol pptp
+}
+
diff --git a/package/network/services/ppp/patches/001-honor-ldflags.patch b/package/network/services/ppp/patches/001-honor-ldflags.patch
new file mode 100644
index 0000000..1328811
--- /dev/null
+++ b/package/network/services/ppp/patches/001-honor-ldflags.patch
@@ -0,0 +1,39 @@
+--- a/pppd/plugins/radius/Makefile.linux
++++ b/pppd/plugins/radius/Makefile.linux
+@@ -43,13 +43,13 @@ install: all
+ $(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
+
+ radius.so: radius.o libradiusclient.a
+- $(CC) -o radius.so -shared radius.o libradiusclient.a
++ $(CC) $(COPTS) -o radius.so -shared radius.o libradiusclient.a
+
+ radattr.so: radattr.o
+- $(CC) -o radattr.so -shared radattr.o
++ $(CC) $(COPTS) -o radattr.so -shared radattr.o
+
+ radrealms.so: radrealms.o
+- $(CC) -o radrealms.so -shared radrealms.o
++ $(CC) $(COPTS) -o radrealms.so -shared radrealms.o
+
+ CLIENTOBJS = avpair.o buildreq.o config.o dict.o ip_util.o \
+ clientid.o sendserver.o lock.o util.o md5.o
+--- a/pppd/plugins/rp-pppoe/Makefile.linux
++++ b/pppd/plugins/rp-pppoe/Makefile.linux
+@@ -30,7 +30,7 @@ CFLAGS=$(COPTS) -I../../../include '-DRP
+ all: rp-pppoe.so pppoe-discovery
+
+ pppoe-discovery: pppoe-discovery.o debug.o
+- $(CC) -o pppoe-discovery pppoe-discovery.o debug.o
++ $(CC) $(CFLAGS) -o pppoe-discovery pppoe-discovery.o debug.o
+
+ pppoe-discovery.o: pppoe-discovery.c
+ $(CC) $(CFLAGS) -c -o pppoe-discovery.o pppoe-discovery.c
+@@ -39,7 +39,7 @@ debug.o: debug.c
+ $(CC) $(CFLAGS) -c -o debug.o debug.c
+
+ rp-pppoe.so: plugin.o discovery.o if.o common.o
+- $(CC) -o rp-pppoe.so -shared plugin.o discovery.o if.o common.o
++ $(CC) $(CFLAGS) -o rp-pppoe.so -shared plugin.o discovery.o if.o common.o
+
+ install: all
+ $(INSTALL) -d -m 755 $(LIBDIR)
diff --git a/package/network/services/ppp/patches/010-use_target_for_configure.patch b/package/network/services/ppp/patches/010-use_target_for_configure.patch
new file mode 100644
index 0000000..aff0df6
--- /dev/null
+++ b/package/network/services/ppp/patches/010-use_target_for_configure.patch
@@ -0,0 +1,24 @@
+configure: Allow overriding uname results
+
+In a cross compile setting it makes no sense to rely on the "uname" values
+reported by the build host system. This patch allows overriding the
+"uname -r", "uname -s" and "uname -m" results with the "UNAME_R", "UNAME_S"
+and "UNAME_M" environment variables.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/configure
++++ b/configure
+@@ -8,9 +8,9 @@ SYSCONF=/etc
+ # if [ -d /NextApps ]; then
+ # system="NeXTStep"
+ # else
+- system=`uname -s`
+- release=`uname -r`
+- arch=`uname -m`
++ system=${UNAME_S:-`uname -s`}
++ release=${UNAME_R:-`uname -r`}
++ arch=${UNAME_M:-`uname -m`}
+ # fi
+ state="unknown"
+
diff --git a/package/network/services/ppp/patches/100-debian_ip-ip_option.patch b/package/network/services/ppp/patches/100-debian_ip-ip_option.patch
new file mode 100644
index 0000000..1017e0f
--- /dev/null
+++ b/package/network/services/ppp/patches/100-debian_ip-ip_option.patch
@@ -0,0 +1,96 @@
+pppd: Allow specifying ip-up and ip-down scripts
+
+This patch implements the "ip-up-script" and "ip-down-script" options which
+allow to specify the path of the ip-up and ip-down scripts to call.
+
+These options default to _PATH_IPUP and _PATH_IPDOWN to retain the
+existing behaviour.
+
+The patch originated from the Debian project.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/ipcp.c
++++ b/pppd/ipcp.c
+@@ -1958,7 +1958,7 @@ ipcp_up(f)
+ */
+ if (ipcp_script_state == s_down && ipcp_script_pid == 0) {
+ ipcp_script_state = s_up;
+- ipcp_script(_PATH_IPUP, 0);
++ ipcp_script(path_ipup, 0);
+ }
+ }
+
+@@ -2008,7 +2008,7 @@ ipcp_down(f)
+ /* Execute the ip-down script */
+ if (ipcp_script_state == s_up && ipcp_script_pid == 0) {
+ ipcp_script_state = s_down;
+- ipcp_script(_PATH_IPDOWN, 0);
++ ipcp_script(path_ipdown, 0);
+ }
+ }
+
+@@ -2062,13 +2062,13 @@ ipcp_script_done(arg)
+ case s_up:
+ if (ipcp_fsm[0].state != OPENED) {
+ ipcp_script_state = s_down;
+- ipcp_script(_PATH_IPDOWN, 0);
++ ipcp_script(path_ipdown, 0);
+ }
+ break;
+ case s_down:
+ if (ipcp_fsm[0].state == OPENED) {
+ ipcp_script_state = s_up;
+- ipcp_script(_PATH_IPUP, 0);
++ ipcp_script(path_ipup, 0);
+ }
+ break;
+ }
+--- a/pppd/main.c
++++ b/pppd/main.c
+@@ -316,6 +316,9 @@ main(argc, argv)
+ struct protent *protp;
+ char numbuf[16];
+
++ strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup));
++ strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown));
++
+ link_stats_valid = 0;
+ new_phase(PHASE_INITIALIZE);
+
+--- a/pppd/options.c
++++ b/pppd/options.c
+@@ -114,6 +114,8 @@ char linkname[MAXPATHLEN]; /* logical na
+ bool tune_kernel; /* may alter kernel settings */
+ int connect_delay = 1000; /* wait this many ms after connect script */
+ int req_unit = -1; /* requested interface unit */
++char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
++char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
+ bool multilink = 0; /* Enable multilink operation */
+ char *bundle_name = NULL; /* bundle name for multilink */
+ bool dump_options; /* print out option values */
+@@ -299,6 +301,13 @@ option_t general_options[] = {
+ "Unset user environment variable",
+ OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint },
+
++ { "ip-up-script", o_string, path_ipup,
++ "Set pathname of ip-up script",
++ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
++ { "ip-down-script", o_string, path_ipdown,
++ "Set pathname of ip-down script",
++ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
++
+ #ifdef HAVE_MULTILINK
+ { "multilink", o_bool, &multilink,
+ "Enable multilink operation", OPT_PRIO | 1 },
+--- a/pppd/pppd.h
++++ b/pppd/pppd.h
+@@ -318,6 +318,8 @@ extern bool tune_kernel; /* May alter ke
+ extern int connect_delay; /* Time to delay after connect script */
+ extern int max_data_rate; /* max bytes/sec through charshunt */
+ extern int req_unit; /* interface unit number to use */
++extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
++extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
+ extern bool multilink; /* enable multilink operation */
+ extern bool noendpoint; /* don't send or accept endpt. discrim. */
+ extern char *bundle_name; /* bundle name for multilink */
diff --git a/package/network/services/ppp/patches/101-debian_close_dev_ppp.patch b/package/network/services/ppp/patches/101-debian_close_dev_ppp.patch
new file mode 100644
index 0000000..7c6765b
--- /dev/null
+++ b/package/network/services/ppp/patches/101-debian_close_dev_ppp.patch
@@ -0,0 +1,28 @@
+pppd: Close already open ppp descriptors
+
+When using the kernel PPPoE driver in conjunction with the "persist" option,
+the already open descriptor to /dev/ppp is not closed when the link is
+reestablished. This eventually leads to high CPU load because the stray
+descriptors are always reported as ready by select().
+
+This patch closes the descriptor if it is already open when establishing a
+new connection. It originated from the Debian project.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/sys-linux.c
++++ b/pppd/sys-linux.c
+@@ -458,6 +458,13 @@ int generic_establish_ppp (int fd)
+ if (new_style_driver) {
+ int flags;
+
++ /* if a ppp_fd is already open, close it first */
++ if(ppp_fd > 0) {
++ close(ppp_fd);
++ remove_fd(ppp_fd);
++ ppp_fd = -1;
++ }
++
+ /* Open an instance of /dev/ppp and connect the channel to it */
+ if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
+ error("Couldn't get channel number: %m");
diff --git a/package/network/services/ppp/patches/103-debian_fix_link_pidfile.patch b/package/network/services/ppp/patches/103-debian_fix_link_pidfile.patch
new file mode 100644
index 0000000..c8a23ed
--- /dev/null
+++ b/package/network/services/ppp/patches/103-debian_fix_link_pidfile.patch
@@ -0,0 +1,23 @@
+pppd: Fix creation of linkpidfile
+
+When pppd is run without "nodetach" or with "updetach", the linkpidfile is
+never created. The call to create_linkpidfile() is protected by a check for
+linkpidfile[0] but this is only filled in when create_linkpidfile() is called.
+
+This patch changes to code to allways uncondiationally call
+create_linkpidfile(), it originated from the Debian project.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/main.c
++++ b/pppd/main.c
+@@ -773,8 +773,7 @@ detach()
+ /* update pid files if they have been written already */
+ if (pidfilename[0])
+ create_pidfile(pid);
+- if (linkpidfile[0])
+- create_linkpidfile(pid);
++ create_linkpidfile(pid);
+ exit(0); /* parent dies */
+ }
+ setsid();
diff --git a/package/network/services/ppp/patches/105-debian_demand.patch b/package/network/services/ppp/patches/105-debian_demand.patch
new file mode 100644
index 0000000..2502d49
--- /dev/null
+++ b/package/network/services/ppp/patches/105-debian_demand.patch
@@ -0,0 +1,172 @@
+--- a/pppd/demand.c
++++ b/pppd/demand.c
+@@ -36,6 +36,8 @@
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <netdb.h>
++#include <unistd.h>
++#include <syslog.h>
+ #include <sys/param.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+@@ -43,6 +45,8 @@
+ #include <sys/resource.h>
+ #include <sys/stat.h>
+ #include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
+ #ifdef PPP_FILTER
+ #include <pcap-bpf.h>
+ #endif
+@@ -221,6 +225,14 @@ loop_chars(p, n)
+ int c, rv;
+
+ rv = 0;
++
++/* check for synchronous connection... */
++
++ if ( (p[0] == 0xFF) && (p[1] == 0x03) ) {
++ rv = loop_frame(p,n);
++ return rv;
++ }
++
+ for (; n > 0; --n) {
+ c = *p++;
+ if (c == PPP_FLAG) {
+@@ -299,17 +311,102 @@ loop_frame(frame, len)
+ * loopback, now that the real serial link is up.
+ */
+ void
+-demand_rexmit(proto)
++demand_rexmit(proto, newip)
+ int proto;
++ u_int32_t newip;
+ {
+ struct packet *pkt, *prev, *nextpkt;
++ unsigned short checksum;
++ unsigned short pkt_checksum = 0;
++ unsigned iphdr;
++ struct timeval tv;
++ char cv = 0;
++ char ipstr[16];
+
+ prev = NULL;
+ pkt = pend_q;
+ pend_q = NULL;
++ tv.tv_sec = 1;
++ tv.tv_usec = 0;
++ select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */
+ for (; pkt != NULL; pkt = nextpkt) {
+ nextpkt = pkt->next;
+ if (PPP_PROTOCOL(pkt->data) == proto) {
++ if ( (proto == PPP_IP) && newip ) {
++ /* Get old checksum */
++
++ iphdr = (pkt->data[4] & 15) << 2;
++ checksum = *((unsigned short *) (pkt->data+14));
++ if (checksum == 0xFFFF) {
++ checksum = 0;
++ }
++
++
++ if (pkt->data[13] == 17) {
++ pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr));
++ if (pkt_checksum) {
++ cv = 1;
++ if (pkt_checksum == 0xFFFF) {
++ pkt_checksum = 0;
++ }
++ }
++ else {
++ cv = 0;
++ }
++ }
++
++ if (pkt->data[13] == 6) {
++ pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr));
++ cv = 1;
++ if (pkt_checksum == 0xFFFF) {
++ pkt_checksum = 0;
++ }
++ }
++
++ /* Delete old Source-IP-Address */
++ checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
++ checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
++
++ pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
++ pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
++
++ /* Change Source-IP-Address */
++ * ((u_int32_t *) (pkt->data + 16)) = newip;
++
++ /* Add new Source-IP-Address */
++ checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
++ checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
++
++ pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
++ pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
++
++ /* Write new checksum */
++ if (!checksum) {
++ checksum = 0xFFFF;
++ }
++ *((unsigned short *) (pkt->data+14)) = checksum;
++ if (pkt->data[13] == 6) {
++ *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum;
++ }
++ if (cv && (pkt->data[13] == 17) ) {
++ *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum;
++ }
++
++ /* Log Packet */
++ strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16))));
++ if (pkt->data[13] == 1) {
++ syslog(LOG_INFO,"Open ICMP %s -> %s\n",
++ ipstr,
++ inet_ntoa(*( (struct in_addr *) (pkt->data+20))));
++ } else {
++ syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n",
++ pkt->data[13] == 6 ? "TCP" : "UDP",
++ ipstr,
++ ntohs(*( (short *) (pkt->data+iphdr+4))),
++ inet_ntoa(*( (struct in_addr *) (pkt->data+20))),
++ ntohs(*( (short *) (pkt->data+iphdr+6))));
++ }
++ }
+ output(0, pkt->data, pkt->length);
+ free(pkt);
+ } else {
+--- a/pppd/ipcp.c
++++ b/pppd/ipcp.c
+@@ -1883,7 +1883,7 @@ ipcp_up(f)
+ proxy_arp_set[f->unit] = 1;
+
+ }
+- demand_rexmit(PPP_IP);
++ demand_rexmit(PPP_IP,go->ouraddr);
+ sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
+
+ } else {
+--- a/pppd/ipv6cp.c
++++ b/pppd/ipv6cp.c
+@@ -1232,7 +1232,7 @@ ipv6cp_up(f)
+ }
+
+ }
+- demand_rexmit(PPP_IPV6);
++ demand_rexmit(PPP_IPV6,0);
+ sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
+
+ } else {
+--- a/pppd/pppd.h
++++ b/pppd/pppd.h
+@@ -585,7 +585,7 @@ void demand_conf __P((void)); /* config
+ void demand_block __P((void)); /* set all NPs to queue up packets */
+ void demand_unblock __P((void)); /* set all NPs to pass packets */
+ void demand_discard __P((void)); /* set all NPs to discard packets */
+-void demand_rexmit __P((int)); /* retransmit saved frames for an NP */
++void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/
+ int loop_chars __P((unsigned char *, int)); /* process chars from loopback */
+ int loop_frame __P((unsigned char *, int)); /* should we bring link up? */
+
diff --git a/package/network/services/ppp/patches/106-debian_stripMSdomain.patch b/package/network/services/ppp/patches/106-debian_stripMSdomain.patch
new file mode 100644
index 0000000..86af1ef
--- /dev/null
+++ b/package/network/services/ppp/patches/106-debian_stripMSdomain.patch
@@ -0,0 +1,47 @@
+pppd: Implement option to strip domain part from MS CHAP response
+
+This patch implements a new boolean option "chapms-strip-domain" which
+strips the leading domain part of the username in a received MS Chap
+response.
+
+When the option is set, all leading chars up to and including the last
+backslash in the username are stripped. The option defaults to false.
+
+The patch originated from the Debian project.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/chap-new.c
++++ b/pppd/chap-new.c
+@@ -58,6 +58,7 @@ int (*chap_verify_hook)(char *name, char
+ int chap_timeout_time = 3;
+ int chap_max_transmits = 10;
+ int chap_rechallenge_time = 0;
++int chapms_strip_domain = 0;
+
+ /*
+ * Command-line options.
+@@ -69,6 +70,8 @@ static option_t chap_option_list[] = {
+ "Set max #xmits for challenge", OPT_PRIO },
+ { "chap-interval", o_int, &chap_rechallenge_time,
+ "Set interval for rechallenge", OPT_PRIO },
++ { "chapms-strip-domain", o_bool, &chapms_strip_domain,
++ "Strip the domain prefix before the Username", 1 },
+ { NULL }
+ };
+
+@@ -336,6 +339,14 @@ chap_handle_response(struct chap_server_
+ /* Null terminate and clean remote name. */
+ slprintf(rname, sizeof(rname), "%.*v", len, name);
+ name = rname;
++
++ /* strip the MS domain name */
++ if (chapms_strip_domain && strrchr(rname, '\\')) {
++ char tmp[MAXNAMELEN+1];
++
++ strcpy(tmp, strrchr(rname, '\\') + 1);
++ strcpy(rname, tmp);
++ }
+ }
+
+ if (chap_verify_hook)
diff --git a/package/network/services/ppp/patches/107-debian_pppoatm_wildcard.patch b/package/network/services/ppp/patches/107-debian_pppoatm_wildcard.patch
new file mode 100644
index 0000000..eaad2cd
--- /dev/null
+++ b/package/network/services/ppp/patches/107-debian_pppoatm_wildcard.patch
@@ -0,0 +1,25 @@
+pppoatm: Allow wildcard ATM devices
+
+When operating pppd's pppoatm plugin with an USB ADSL modem, e.g. an
+Alcatel Speedtouch, the ATM device number might change when the modem is
+reconnected to the USB port or when the host controller resets the USB
+device.
+
+This patch allows to specify the ATM device as wildcard which gives
+enough flexibility to cope with changing device names.
+
+The patch originated from the Debain project.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/plugins/pppoatm/pppoatm.c
++++ b/pppd/plugins/pppoatm/pppoatm.c
+@@ -75,7 +75,7 @@ static int setdevname_pppoatm(const char
+ //info("PPPoATM setdevname_pppoatm: '%s'", cp);
+ memset(&addr, 0, sizeof addr);
+ if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr),
+- T2A_PVC | T2A_NAME) < 0) {
++ T2A_PVC | T2A_NAME | T2A_WILDCARD) < 0) {
+ if(doit)
+ info("atm does not recognize: %s", cp);
+ return 0;
diff --git a/package/network/services/ppp/patches/110-debian_defaultroute.patch b/package/network/services/ppp/patches/110-debian_defaultroute.patch
new file mode 100644
index 0000000..e8659ea
--- /dev/null
+++ b/package/network/services/ppp/patches/110-debian_defaultroute.patch
@@ -0,0 +1,313 @@
+pppd: Add "replacedefaultroute" and "noreplacedefaultroute" options
+
+This patch implements two new options, "replacedefaultroute" to replace any
+existing system default route when specified and "noreplacedefaultroute" to
+disable the "replacedefaultroute" option, which is useful in multi user
+environments where the administrator wants to allow users to dial pppd
+connections but not allow them to change the system default route.
+
+The patch originated from the Debian project.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/ipcp.c
++++ b/pppd/ipcp.c
+@@ -198,6 +198,14 @@ static option_t ipcp_option_list[] = {
+ "disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
+ &ipcp_wantoptions[0].default_route },
+
++ { "replacedefaultroute", o_bool,
++ &ipcp_wantoptions[0].replace_default_route,
++ "Replace default route", 1
++ },
++ { "noreplacedefaultroute", o_bool,
++ &ipcp_allowoptions[0].replace_default_route,
++ "Never replace default route", OPT_A2COPY,
++ &ipcp_wantoptions[0].replace_default_route },
+ { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
+ "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
+ { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
+@@ -271,7 +279,7 @@ struct protent ipcp_protent = {
+ ip_active_pkt
+ };
+
+-static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
++static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool));
+ static void ipcp_script __P((char *, int)); /* Run an up/down script */
+ static void ipcp_script_done __P((void *));
+
+@@ -1761,7 +1769,8 @@ ip_demand_conf(u)
+ if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
+ return 0;
+ if (wo->default_route)
+- if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
++ if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr,
++ wo->replace_default_route))
+ default_route_set[u] = 1;
+ if (wo->proxy_arp)
+ if (sifproxyarp(u, wo->hisaddr))
+@@ -1849,7 +1858,8 @@ ipcp_up(f)
+ */
+ if (demand) {
+ if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
+- ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
++ ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr,
++ wo->replace_default_route);
+ if (go->ouraddr != wo->ouraddr) {
+ warn("Local IP address changed to %I", go->ouraddr);
+ script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
+@@ -1874,7 +1884,8 @@ ipcp_up(f)
+
+ /* assign a default route through the interface if required */
+ if (ipcp_wantoptions[f->unit].default_route)
+- if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
++ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
++ wo->replace_default_route))
+ default_route_set[f->unit] = 1;
+
+ /* Make a proxy ARP entry if requested. */
+@@ -1924,7 +1935,8 @@ ipcp_up(f)
+
+ /* assign a default route through the interface if required */
+ if (ipcp_wantoptions[f->unit].default_route)
+- if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
++ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
++ wo->replace_default_route))
+ default_route_set[f->unit] = 1;
+
+ /* Make a proxy ARP entry if requested. */
+@@ -2002,7 +2014,7 @@ ipcp_down(f)
+ sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
+ sifdown(f->unit);
+ ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
+- ipcp_hisoptions[f->unit].hisaddr);
++ ipcp_hisoptions[f->unit].hisaddr, 0);
+ }
+
+ /* Execute the ip-down script */
+@@ -2018,16 +2030,25 @@ ipcp_down(f)
+ * proxy arp entries, etc.
+ */
+ static void
+-ipcp_clear_addrs(unit, ouraddr, hisaddr)
++ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute)
+ int unit;
+ u_int32_t ouraddr; /* local address */
+ u_int32_t hisaddr; /* remote address */
++ bool replacedefaultroute;
+ {
+ if (proxy_arp_set[unit]) {
+ cifproxyarp(unit, hisaddr);
+ proxy_arp_set[unit] = 0;
+ }
+- if (default_route_set[unit]) {
++ /* If replacedefaultroute, sifdefaultroute will be called soon
++ * with replacedefaultroute set and that will overwrite the current
++ * default route. This is the case only when doing demand, otherwise
++ * during demand, this cifdefaultroute would restore the old default
++ * route which is not what we want in this case. In the non-demand
++ * case, we'll delete the default route and restore the old if there
++ * is one saved by an sifdefaultroute with replacedefaultroute.
++ */
++ if (!replacedefaultroute && default_route_set[unit]) {
+ cifdefaultroute(unit, ouraddr, hisaddr);
+ default_route_set[unit] = 0;
+ }
+--- a/pppd/ipcp.h
++++ b/pppd/ipcp.h
+@@ -70,6 +70,7 @@ typedef struct ipcp_options {
+ bool old_addrs; /* Use old (IP-Addresses) option? */
+ bool req_addr; /* Ask peer to send IP address? */
+ bool default_route; /* Assign default route through interface? */
++ bool replace_default_route; /* Replace default route through interface? */
+ bool proxy_arp; /* Make proxy ARP entry for peer? */
+ bool neg_vj; /* Van Jacobson Compression? */
+ bool old_vj; /* use old (short) form of VJ option? */
+--- a/pppd/pppd.8
++++ b/pppd/pppd.8
+@@ -121,6 +121,11 @@ the gateway, when IPCP negotiation is su
+ This entry is removed when the PPP connection is broken. This option
+ is privileged if the \fInodefaultroute\fR option has been specified.
+ .TP
++.B replacedefaultroute
++This option is a flag to the defaultroute option. If defaultroute is
++set and this flag is also set, pppd replaces an existing default route
++with the new default route.
++.TP
+ .B disconnect \fIscript
+ Execute the command specified by \fIscript\fR, by passing it to a
+ shell, after
+@@ -734,7 +739,12 @@ disable both forms of hardware flow cont
+ .TP
+ .B nodefaultroute
+ Disable the \fIdefaultroute\fR option. The system administrator who
+-wishes to prevent users from creating default routes with pppd
++wishes to prevent users from adding a default route with pppd
++can do so by placing this option in the /etc/ppp/options file.
++.TP
++.B noreplacedefaultroute
++Disable the \fIreplacedefaultroute\fR option. The system administrator who
++wishes to prevent users from replacing a default route with pppd
+ can do so by placing this option in the /etc/ppp/options file.
+ .TP
+ .B nodeflate
+--- a/pppd/pppd.h
++++ b/pppd/pppd.h
+@@ -667,7 +667,7 @@ int sif6addr __P((int, eui64_t, eui64_t
+ int cif6addr __P((int, eui64_t, eui64_t));
+ /* Remove an IPv6 address from i/f */
+ #endif
+-int sifdefaultroute __P((int, u_int32_t, u_int32_t));
++int sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt));
+ /* Create default route through i/f */
+ int cifdefaultroute __P((int, u_int32_t, u_int32_t));
+ /* Delete default route through i/f */
+--- a/pppd/sys-linux.c
++++ b/pppd/sys-linux.c
+@@ -207,6 +207,8 @@ static unsigned char inbuf[512]; /* buff
+ static int if_is_up; /* Interface has been marked up */
+ static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
+ static int have_default_route; /* Gateway for default route added */
++static struct rtentry old_def_rt; /* Old default route */
++static int default_rt_repl_rest; /* replace and restore old default rt */
+ static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
+ static char proxy_arp_dev[16]; /* Device for proxy arp entry */
+ static u_int32_t our_old_addr; /* for detecting address changes */
+@@ -1552,6 +1554,9 @@ static int read_route_table(struct rtent
+ p = NULL;
+ }
+
++ SET_SA_FAMILY (rt->rt_dst, AF_INET);
++ SET_SA_FAMILY (rt->rt_gateway, AF_INET);
++
+ SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
+ SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
+ SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
+@@ -1621,20 +1626,51 @@ int have_route_to(u_int32_t addr)
+ /********************************************************************
+ *
+ * sifdefaultroute - assign a default route through the address given.
+- */
+-
+-int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
+-{
+- struct rtentry rt;
+-
+- if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
+- if (rt.rt_flags & RTF_GATEWAY)
+- error("not replacing existing default route via %I",
+- SIN_ADDR(rt.rt_gateway));
+- else
++ *
++ * If the global default_rt_repl_rest flag is set, then this function
++ * already replaced the original system defaultroute with some other
++ * route and it should just replace the current defaultroute with
++ * another one, without saving the current route. Use: demand mode,
++ * when pppd sets first a defaultroute it it's temporary ppp0 addresses
++ * and then changes the temporary addresses to the addresses for the real
++ * ppp connection when it has come up.
++ */
++
++int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
++{
++ struct rtentry rt, tmp_rt;
++ struct rtentry *del_rt = NULL;
++
++ if (default_rt_repl_rest) {
++ /* We have already reclaced the original defaultroute, if we
++ are called again, we will delete the current default route
++ and set the new default route in this function.
++ - this is normally only the case the doing demand: */
++ if (defaultroute_exists(&tmp_rt))
++ del_rt = &tmp_rt;
++ } else if (defaultroute_exists(&old_def_rt) &&
++ strcmp(old_def_rt.rt_dev, ifname) != 0) {
++ /* We did not yet replace an existing default route, let's
++ check if we should save and replace a default route: */
++ if (old_def_rt.rt_flags & RTF_GATEWAY) {
++ if (!replace) {
++ error("not replacing existing default route via %I",
++ SIN_ADDR(old_def_rt.rt_gateway));
++ return 0;
++ } else {
++ /* we need to copy rt_dev because we need it permanent too: */
++ char *tmp_dev = malloc(strlen(old_def_rt.rt_dev) + 1);
++ strcpy(tmp_dev, old_def_rt.rt_dev);
++ old_def_rt.rt_dev = tmp_dev;
++
++ notice("replacing old default route to %s [%I]",
++ old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
++ default_rt_repl_rest = 1;
++ del_rt = &old_def_rt;
++ }
++ } else
+ error("not replacing existing default route through %s",
+- rt.rt_dev);
+- return 0;
++ old_def_rt.rt_dev);
+ }
+
+ memset (&rt, 0, sizeof (rt));
+@@ -1649,10 +1685,16 @@ int sifdefaultroute (int unit, u_int32_t
+
+ rt.rt_flags = RTF_UP;
+ if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
+- if ( ! ok_error ( errno ))
++ if (!ok_error(errno))
+ error("default route ioctl(SIOCADDRT): %m");
+ return 0;
+ }
++ if (default_rt_repl_rest && del_rt)
++ if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
++ if (!ok_error(errno))
++ error("del old default route ioctl(SIOCDELRT): %m");
++ return 0;
++ }
+
+ have_default_route = 1;
+ return 1;
+@@ -1683,11 +1725,21 @@ int cifdefaultroute (int unit, u_int32_t
+ rt.rt_flags = RTF_UP;
+ if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
+ if (still_ppp()) {
+- if ( ! ok_error ( errno ))
++ if (!ok_error(errno))
+ error("default route ioctl(SIOCDELRT): %m");
+ return 0;
+ }
+ }
++ if (default_rt_repl_rest) {
++ notice("restoring old default route to %s [%I]",
++ old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
++ if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
++ if (!ok_error(errno))
++ error("restore default route ioctl(SIOCADDRT): %m");
++ return 0;
++ }
++ default_rt_repl_rest = 0;
++ }
+
+ return 1;
+ }
+--- a/pppd/sys-solaris.c
++++ b/pppd/sys-solaris.c
+@@ -2039,12 +2039,18 @@ cifaddr(u, o, h)
+ * sifdefaultroute - assign a default route through the address given.
+ */
+ int
+-sifdefaultroute(u, l, g)
++sifdefaultroute(u, l, g, replace)
+ int u;
+ u_int32_t l, g;
++ bool replace;
+ {
+ struct rtentry rt;
+
++ if (replace) {
++ error("replacedefaultroute not supported on this platform");
++ return 0;
++ }
++
+ #if defined(__USLC__)
+ g = l; /* use the local address as gateway */
+ #endif
diff --git a/package/network/services/ppp/patches/120-debian_ipv6_updown_option.patch b/package/network/services/ppp/patches/120-debian_ipv6_updown_option.patch
new file mode 100644
index 0000000..0e57029
--- /dev/null
+++ b/package/network/services/ppp/patches/120-debian_ipv6_updown_option.patch
@@ -0,0 +1,95 @@
+pppd: Allow specifying ipv6-up and ipv6-down scripts
+
+This patch implements the "ipv6-up-script" and "ipv6-down-script" options
+which allow to specify the path of the ipv6-up and ipv6-down scripts to call.
+
+These options default to _PATH_IPV6UP and _PATH_IPV6DOWN to retain the
+existing behaviour.
+
+The patch originated from the Debian project.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/main.c
++++ b/pppd/main.c
+@@ -318,6 +318,8 @@ main(argc, argv)
+
+ strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup));
+ strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown));
++ strlcpy(path_ipv6up, _PATH_IPV6UP, sizeof(path_ipv6up));
++ strlcpy(path_ipv6down, _PATH_IPV6DOWN, sizeof(path_ipv6down));
+
+ link_stats_valid = 0;
+ new_phase(PHASE_INITIALIZE);
+--- a/pppd/options.c
++++ b/pppd/options.c
+@@ -116,6 +116,8 @@ int connect_delay = 1000; /* wait this m
+ int req_unit = -1; /* requested interface unit */
+ char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
+ char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
++char path_ipv6up[MAXPATHLEN]; /* pathname of ipv6-up script */
++char path_ipv6down[MAXPATHLEN];/* pathname of ipv6-down script */
+ bool multilink = 0; /* Enable multilink operation */
+ char *bundle_name = NULL; /* bundle name for multilink */
+ bool dump_options; /* print out option values */
+@@ -308,6 +310,13 @@ option_t general_options[] = {
+ "Set pathname of ip-down script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+
++ { "ipv6-up-script", o_string, path_ipv6up,
++ "Set pathname of ipv6-up script",
++ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
++ { "ipv6-down-script", o_string, path_ipv6down,
++ "Set pathname of ipv6-down script",
++ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
++
+ #ifdef HAVE_MULTILINK
+ { "multilink", o_bool, &multilink,
+ "Enable multilink operation", OPT_PRIO | 1 },
+--- a/pppd/ipv6cp.c
++++ b/pppd/ipv6cp.c
+@@ -1269,7 +1269,7 @@ ipv6cp_up(f)
+ */
+ if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) {
+ ipv6cp_script_state = s_up;
+- ipv6cp_script(_PATH_IPV6UP);
++ ipv6cp_script(path_ipv6up);
+ }
+ }
+
+@@ -1321,7 +1321,7 @@ ipv6cp_down(f)
+ /* Execute the ipv6-down script */
+ if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) {
+ ipv6cp_script_state = s_down;
+- ipv6cp_script(_PATH_IPV6DOWN);
++ ipv6cp_script(path_ipv6down);
+ }
+ }
+
+@@ -1364,13 +1364,13 @@ ipv6cp_script_done(arg)
+ case s_up:
+ if (ipv6cp_fsm[0].state != OPENED) {
+ ipv6cp_script_state = s_down;
+- ipv6cp_script(_PATH_IPV6DOWN);
++ ipv6cp_script(path_ipv6down);
+ }
+ break;
+ case s_down:
+ if (ipv6cp_fsm[0].state == OPENED) {
+ ipv6cp_script_state = s_up;
+- ipv6cp_script(_PATH_IPV6UP);
++ ipv6cp_script(path_ipv6up);
+ }
+ break;
+ }
+--- a/pppd/pppd.h
++++ b/pppd/pppd.h
+@@ -320,6 +320,8 @@ extern int max_data_rate; /* max bytes/s
+ extern int req_unit; /* interface unit number to use */
+ extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
+ extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
++extern char path_ipv6up[MAXPATHLEN]; /* pathname of ipv6-up script */
++extern char path_ipv6down[MAXPATHLEN]; /* pathname of ipv6-down script */
+ extern bool multilink; /* enable multilink operation */
+ extern bool noendpoint; /* don't send or accept endpt. discrim. */
+ extern char *bundle_name; /* bundle name for multilink */
diff --git a/package/network/services/ppp/patches/121-debian_adaptive_lcp_echo.patch b/package/network/services/ppp/patches/121-debian_adaptive_lcp_echo.patch
new file mode 100644
index 0000000..b7a6240
--- /dev/null
+++ b/package/network/services/ppp/patches/121-debian_adaptive_lcp_echo.patch
@@ -0,0 +1,56 @@
+--- a/pppd/lcp.c
++++ b/pppd/lcp.c
+@@ -73,6 +73,7 @@ static void lcp_delayed_up __P((void *))
+ */
+ int lcp_echo_interval = 0; /* Interval between LCP echo-requests */
+ int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */
++bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */
+ bool lax_recv = 0; /* accept control chars in asyncmap */
+ bool noendpoint = 0; /* don't send/accept endpoint discriminator */
+
+@@ -151,6 +152,8 @@ static option_t lcp_option_list[] = {
+ OPT_PRIO },
+ { "lcp-echo-interval", o_int, &lcp_echo_interval,
+ "Set time in seconds between LCP echo requests", OPT_PRIO },
++ { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive,
++ "Suppress LCP echo requests if traffic was received", 1 },
+ { "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
+ "Set time in seconds between LCP retransmissions", OPT_PRIO },
+ { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
+@@ -2331,6 +2334,22 @@ LcpSendEchoRequest (f)
+ }
+ }
+
++ /*
++ * If adaptive echos have been enabled, only send the echo request if
++ * no traffic was received since the last one.
++ */
++ if (lcp_echo_adaptive) {
++ static unsigned int last_pkts_in = 0;
++
++ update_link_stats(f->unit);
++ link_stats_valid = 0;
++
++ if (link_stats.pkts_in != last_pkts_in) {
++ last_pkts_in = link_stats.pkts_in;
++ return;
++ }
++ }
++
+ /*
+ * Make and send the echo request frame.
+ */
+--- a/pppd/pppd.8
++++ b/pppd/pppd.8
+@@ -563,6 +563,11 @@ to 1) if the \fIproxyarp\fR option is us
+ dynamic IP address option (i.e. set /proc/sys/net/ipv4/ip_dynaddr to
+ 1) in demand mode if the local address changes.
+ .TP
++.B lcp\-echo\-adaptive
++If this option is used with the \fIlcp\-echo\-failure\fR option then
++pppd will send LCP echo\-request frames only if no traffic was received
++from the peer since the last echo\-request was sent.
++.TP
+ .B lcp\-echo\-failure \fIn
+ If this option is given, pppd will presume the peer to be dead
+ if \fIn\fR LCP echo\-requests are sent without receiving a valid LCP
diff --git a/package/network/services/ppp/patches/130-no_cdefs_h.patch b/package/network/services/ppp/patches/130-no_cdefs_h.patch
new file mode 100644
index 0000000..caa892e
--- /dev/null
+++ b/package/network/services/ppp/patches/130-no_cdefs_h.patch
@@ -0,0 +1,11 @@
+--- a/pppd/plugins/rp-pppoe/config.h
++++ b/pppd/plugins/rp-pppoe/config.h
+@@ -102,7 +102,7 @@
+ #define HAVE_NETPACKET_PACKET_H 1
+
+ /* Define if you have the <sys/cdefs.h> header file. */
+-#define HAVE_SYS_CDEFS_H 1
++/* #undef HAVE_SYS_CDEFS_H */
+
+ /* Define if you have the <sys/dlpi.h> header file. */
+ /* #undef HAVE_SYS_DLPI_H */
diff --git a/package/network/services/ppp/patches/131-missing_prototype_macro.patch b/package/network/services/ppp/patches/131-missing_prototype_macro.patch
new file mode 100644
index 0000000..868a08b
--- /dev/null
+++ b/package/network/services/ppp/patches/131-missing_prototype_macro.patch
@@ -0,0 +1,23 @@
+--- a/pppd/pppd.h
++++ b/pppd/pppd.h
+@@ -67,6 +67,9 @@
+ #define volatile
+ #endif
+
++#undef __P
++#define __P(args) args
++
+ #ifdef INET6
+ #include "eui64.h"
+ #endif
+--- a/pppd/magic.h
++++ b/pppd/magic.h
+@@ -42,6 +42,8 @@
+ * $Id: magic.h,v 1.5 2003/06/11 23:56:26 paulus Exp $
+ */
+
++#include "pppd.h"
++
+ void magic_init __P((void)); /* Initialize the magic number generator */
+ u_int32_t magic __P((void)); /* Returns the next magic number */
+
diff --git a/package/network/services/ppp/patches/132-fix_linux_includes.patch b/package/network/services/ppp/patches/132-fix_linux_includes.patch
new file mode 100644
index 0000000..696dad1
--- /dev/null
+++ b/package/network/services/ppp/patches/132-fix_linux_includes.patch
@@ -0,0 +1,40 @@
+--- a/pppd/sys-linux.c
++++ b/pppd/sys-linux.c
+@@ -73,12 +73,12 @@
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/time.h>
+-#include <sys/errno.h>
+ #include <sys/file.h>
+ #include <sys/stat.h>
+ #include <sys/utsname.h>
+ #include <sys/sysmacros.h>
+
++#include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <syslog.h>
+@@ -102,22 +102,15 @@
+ #define MAX_ADDR_LEN 7
+ #endif
+
+-#if __GLIBC__ >= 2
+ #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
+ #include <net/if.h>
+ #include <net/if_arp.h>
+ #include <net/route.h>
+ #include <netinet/if_ether.h>
+-#else
+-#include <linux/types.h>
+-#include <linux/if.h>
+-#include <linux/if_arp.h>
+-#include <linux/route.h>
+-#include <linux/if_ether.h>
+-#endif
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+
++#include <linux/sockios.h>
+ #include <linux/ppp_defs.h>
+ #include <linux/if_ppp.h>
+
diff --git a/package/network/services/ppp/patches/133-fix_sha1_include.patch b/package/network/services/ppp/patches/133-fix_sha1_include.patch
new file mode 100644
index 0000000..b5ccd08
--- /dev/null
+++ b/package/network/services/ppp/patches/133-fix_sha1_include.patch
@@ -0,0 +1,11 @@
+--- a/pppd/sha1.c
++++ b/pppd/sha1.c
+@@ -18,7 +18,7 @@
+
+ #include <string.h>
+ #include <netinet/in.h> /* htonl() */
+-#include <net/ppp_defs.h>
++#include "pppd.h"
+ #include "sha1.h"
+
+ static void
diff --git a/package/network/services/ppp/patches/140-pppoe_compile_fix.patch b/package/network/services/ppp/patches/140-pppoe_compile_fix.patch
new file mode 100644
index 0000000..2983a75
--- /dev/null
+++ b/package/network/services/ppp/patches/140-pppoe_compile_fix.patch
@@ -0,0 +1,101 @@
+--- a/pppd/plugins/rp-pppoe/plugin.c
++++ b/pppd/plugins/rp-pppoe/plugin.c
+@@ -46,10 +46,10 @@ static char const RCSID[] =
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <signal.h>
+-#include <net/ethernet.h>
+ #include <net/if_arp.h>
+ #include <linux/ppp_defs.h>
+ #include <linux/if_pppox.h>
++#include <linux/if_ether.h>
+
+ #ifndef _ROOT_PATH
+ #define _ROOT_PATH ""
+--- a/pppd/plugins/rp-pppoe/pppoe.h
++++ b/pppd/plugins/rp-pppoe/pppoe.h
+@@ -86,17 +86,6 @@ typedef unsigned long UINT32_t;
+
+ #include <netinet/in.h>
+
+-#ifdef HAVE_NETINET_IF_ETHER_H
+-#include <sys/types.h>
+-
+-#ifdef HAVE_SYS_SOCKET_H
+-#include <sys/socket.h>
+-#endif
+-#ifndef HAVE_SYS_DLPI_H
+-#include <netinet/if_ether.h>
+-#endif
+-#endif
+-
+
+
+ /* Ethernet frame types according to RFC 2516 */
+--- a/pppd/plugins/rp-pppoe/if.c
++++ b/pppd/plugins/rp-pppoe/if.c
+@@ -31,7 +31,7 @@ static char const RCSID[] =
+ #endif
+
+ #ifdef HAVE_NET_ETHERNET_H
+-#include <net/ethernet.h>
++#include <linux/if_ether.h>
+ #endif
+
+ #ifdef HAVE_ASM_TYPES_H
+--- a/pppd/plugins/rp-pppoe/pppoe-discovery.c
++++ b/pppd/plugins/rp-pppoe/pppoe-discovery.c
+@@ -16,6 +16,7 @@
+ #include <string.h>
+
+ #include "pppoe.h"
++#include "pppd/pppd.h"
+
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+@@ -27,10 +28,6 @@
+ #include <linux/if_packet.h>
+ #endif
+
+-#ifdef HAVE_NET_ETHERNET_H
+-#include <net/ethernet.h>
+-#endif
+-
+ #ifdef HAVE_ASM_TYPES_H
+ #include <asm/types.h>
+ #endif
+@@ -717,6 +714,23 @@ char *xstrdup(const char *s)
+ return ret;
+ }
+
++void
++error(char *fmt, ...)
++{
++ va_list pvar;
++
++#if defined(__STDC__)
++ va_start(pvar, fmt);
++#else
++ char *fmt;
++ va_start(pvar);
++ fmt = va_arg(pvar, char *);
++#endif
++
++ fprintf(stderr, fmt, pvar);
++ va_end(pvar);
++}
++
+ void usage(void)
+ {
+ fprintf(stderr, "Usage: pppoe-discovery [options]\n");
+--- a/pppd/plugins/rp-pppoe/Makefile.linux
++++ b/pppd/plugins/rp-pppoe/Makefile.linux
+@@ -33,7 +33,7 @@ pppoe-discovery: pppoe-discovery.o debug
+ $(CC) $(CFLAGS) -o pppoe-discovery pppoe-discovery.o debug.o
+
+ pppoe-discovery.o: pppoe-discovery.c
+- $(CC) $(CFLAGS) -c -o pppoe-discovery.o pppoe-discovery.c
++ $(CC) $(CFLAGS) -I../../.. -c -o pppoe-discovery.o pppoe-discovery.c
+
+ debug.o: debug.c
+ $(CC) $(CFLAGS) -c -o debug.o debug.c
diff --git a/package/network/services/ppp/patches/200-makefile.patch b/package/network/services/ppp/patches/200-makefile.patch
new file mode 100644
index 0000000..d5e5719
--- /dev/null
+++ b/package/network/services/ppp/patches/200-makefile.patch
@@ -0,0 +1,49 @@
+pppd: tune Linux config defaults for OpenWrt
+
+This patch adjusts a number defaults to properly match the OpenWrt environment.
+It is not intended for upstream.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/Makefile.linux
++++ b/pppd/Makefile.linux
+@@ -48,7 +48,7 @@ MPPE=y
+ # Uncomment the next line to include support for PPP packet filtering.
+ # This requires that the libpcap library and headers be installed
+ # and that the kernel driver support PPP packet filtering.
+-FILTER=y
++#FILTER=y
+
+ # Uncomment the next line to enable multilink PPP (enabled by default)
+ # Linux distributions: Please leave multilink ENABLED in your builds
+@@ -58,7 +58,7 @@ HAVE_MULTILINK=y
+ # Uncomment the next line to enable the TDB database (enabled by default.)
+ # If you enable multilink, then TDB is automatically enabled also.
+ # Linux distributions: Please leave TDB ENABLED in your builds.
+-USE_TDB=y
++#USE_TDB=y
+
+ HAS_SHADOW=y
+ #USE_PAM=y
+@@ -80,7 +80,7 @@ MAXOCTETS=y
+
+ INCLUDE_DIRS= -I../include
+
+-COMPILE_FLAGS= -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP
++COMPILE_FLAGS= -DHAVE_PATHS_H -DHAVE_MMAP
+
+ CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) '-DDESTDIR="@DESTDIR@"'
+
+@@ -120,10 +120,10 @@ CFLAGS += -DHAS_SHADOW
+ #LIBS += -lshadow $(LIBS)
+ endif
+
+-ifneq ($(wildcard /usr/include/crypt.h),)
++#ifneq ($(wildcard /usr/include/crypt.h),)
+ CFLAGS += -DHAVE_CRYPT_H=1
+ LIBS += -lcrypt
+-endif
++#endif
+
+ ifdef USE_LIBUTIL
+ CFLAGS += -DHAVE_LOGWTMP=1
diff --git a/package/network/services/ppp/patches/201-mppe_mppc_1.1.patch b/package/network/services/ppp/patches/201-mppe_mppc_1.1.patch
new file mode 100644
index 0000000..0bc42d4
--- /dev/null
+++ b/package/network/services/ppp/patches/201-mppe_mppc_1.1.patch
@@ -0,0 +1,1495 @@
+pppd: add support for MPPE and MPPC encryption and compression protocols
+
+This is a forward ported version of ppp-2.4.3-mppe-mppc-1.1.patch.gz found on
+http://mppe-mppc.alphacron.de/ .
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/include/linux/ppp-comp.h
++++ b/include/linux/ppp-comp.h
+@@ -36,7 +36,7 @@
+ */
+
+ /*
+- * ==FILEVERSION 20020319==
++ * ==FILEVERSION 20020715==
+ *
+ * NOTE TO MAINTAINERS:
+ * If you modify this file at all, please set the above date.
+@@ -201,6 +201,33 @@ struct compressor {
+ #define CI_MPPE 18 /* config option for MPPE */
+ #define CILEN_MPPE 6 /* length of config option */
+
++/* MPPE/MPPC definitions by J.D.*/
++#define MPPE_STATELESS MPPE_H_BIT /* configuration bit H */
++#define MPPE_40BIT MPPE_L_BIT /* configuration bit L */
++#define MPPE_56BIT MPPE_M_BIT /* configuration bit M */
++#define MPPE_128BIT MPPE_S_BIT /* configuration bit S */
++#define MPPE_MPPC MPPE_C_BIT /* configuration bit C */
++
++/*
++ * Definitions for Stac LZS.
++ */
++
++#define CI_LZS 17 /* config option for Stac LZS */
++#define CILEN_LZS 5 /* length of config option */
++
++#define LZS_OVHD 4 /* max. LZS overhead */
++#define LZS_HIST_LEN 2048 /* LZS history size */
++#define LZS_MAX_CCOUNT 0x0FFF /* max. coherency counter value */
++
++#define LZS_MODE_NONE 0
++#define LZS_MODE_LCB 1
++#define LZS_MODE_CRC 2
++#define LZS_MODE_SEQ 3
++#define LZS_MODE_EXT 4
++
++#define LZS_EXT_BIT_FLUSHED 0x80 /* bit A */
++#define LZS_EXT_BIT_COMP 0x20 /* bit C */
++
+ /*
+ * Definitions for other, as yet unsupported, compression methods.
+ */
+--- a/include/net/ppp-comp.h
++++ b/include/net/ppp-comp.h
+@@ -168,6 +168,33 @@ struct compressor {
+ #define CI_MPPE 18 /* config option for MPPE */
+ #define CILEN_MPPE 6 /* length of config option */
+
++/* MPPE/MPPC definitions by J.D.*/
++#define MPPE_STATELESS MPPE_H_BIT /* configuration bit H */
++#define MPPE_40BIT MPPE_L_BIT /* configuration bit L */
++#define MPPE_56BIT MPPE_M_BIT /* configuration bit M */
++#define MPPE_128BIT MPPE_S_BIT /* configuration bit S */
++#define MPPE_MPPC MPPE_C_BIT /* configuration bit C */
++
++/*
++ * Definitions for Stac LZS.
++ */
++
++#define CI_LZS 17 /* config option for Stac LZS */
++#define CILEN_LZS 5 /* length of config option */
++
++#define LZS_OVHD 4 /* max. LZS overhead */
++#define LZS_HIST_LEN 2048 /* LZS history size */
++#define LZS_MAX_CCOUNT 0x0FFF /* max. coherency counter value */
++
++#define LZS_MODE_NONE 0
++#define LZS_MODE_LCB 1
++#define LZS_MODE_CRC 2
++#define LZS_MODE_SEQ 3
++#define LZS_MODE_EXT 4
++
++#define LZS_EXT_BIT_FLUSHED 0x80 /* bit A */
++#define LZS_EXT_BIT_COMP 0x20 /* bit C */
++
+ /*
+ * Definitions for other, as yet unsupported, compression methods.
+ */
+--- a/pppd/ccp.c
++++ b/pppd/ccp.c
+@@ -62,12 +62,10 @@ static int setdeflate __P((char **));
+ static char bsd_value[8];
+ static char deflate_value[8];
+
+-/*
+- * Option variables.
+- */
+ #ifdef MPPE
+-bool refuse_mppe_stateful = 1; /* Allow stateful mode? */
+-#endif
++static int setmppe(char **);
++static int setnomppe(void);
++#endif /* MPPE */
+
+ static option_t ccp_option_list[] = {
+ { "noccp", o_bool, &ccp_protent.enabled_flag,
+@@ -108,54 +106,36 @@ static option_t ccp_option_list[] = {
+ "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
+ &ccp_allowoptions[0].predictor_1 },
+
++ { "lzs", o_bool, &ccp_wantoptions[0].lzs,
++ "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_PRIO },
++ { "+lzs", o_bool, &ccp_wantoptions[0].lzs,
++ "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_ALIAS | OPT_PRIO },
++ { "nolzs", o_bool, &ccp_wantoptions[0].lzs,
++ "don't allow Stac LZS", OPT_PRIOSUB | OPT_A2CLR,
++ &ccp_allowoptions[0].lzs },
++ { "-lzs", o_bool, &ccp_wantoptions[0].lzs,
++ "don't allow Stac LZS", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
++ &ccp_allowoptions[0].lzs },
++
+ #ifdef MPPE
+- /* MPPE options are symmetrical ... we only set wantoptions here */
+- { "require-mppe", o_bool, &ccp_wantoptions[0].mppe,
+- "require MPPE encryption",
+- OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
+- { "+mppe", o_bool, &ccp_wantoptions[0].mppe,
+- "require MPPE encryption",
+- OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
+- { "nomppe", o_bool, &ccp_wantoptions[0].mppe,
+- "don't allow MPPE encryption", OPT_PRIO },
+- { "-mppe", o_bool, &ccp_wantoptions[0].mppe,
+- "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO },
+-
+- /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */
+- { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
+- "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
+- &ccp_wantoptions[0].mppe },
+- { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe,
+- "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
+- &ccp_wantoptions[0].mppe },
+- { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe,
+- "don't allow MPPE 40-bit encryption",
+- OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe },
+- { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
+- "don't allow MPPE 40-bit encryption",
+- OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40,
+- &ccp_wantoptions[0].mppe },
+-
+- { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
+- "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
+- &ccp_wantoptions[0].mppe },
+- { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe,
+- "require MPPE 128-bit encryption",
+- OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
+- &ccp_wantoptions[0].mppe },
+- { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe,
+- "don't allow MPPE 128-bit encryption",
+- OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe },
+- { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
+- "don't allow MPPE 128-bit encryption",
+- OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128,
+- &ccp_wantoptions[0].mppe },
+-
+- /* strange one; we always request stateless, but will we allow stateful? */
+- { "mppe-stateful", o_bool, &refuse_mppe_stateful,
+- "allow MPPE stateful mode", OPT_PRIO },
+- { "nomppe-stateful", o_bool, &refuse_mppe_stateful,
+- "disallow MPPE stateful mode", OPT_PRIO | 1 },
++ { "mppc", o_bool, &ccp_wantoptions[0].mppc,
++ "request MPPC compression", 1, &ccp_allowoptions[0].mppc },
++ { "+mppc", o_bool, &ccp_wantoptions[0].mppc,
++ "request MPPC compression", 1, &ccp_allowoptions[0].mppc, OPT_ALIAS },
++ { "nomppc", o_bool, &ccp_wantoptions[0].mppc,
++ "don't allow MPPC compression", OPT_PRIOSUB | OPT_A2CLR,
++ &ccp_allowoptions[0].mppc },
++ { "-mppc", o_bool, &ccp_wantoptions[0].mppc,
++ "don't allow MPPC compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
++ &ccp_allowoptions[0].mppc },
++ { "mppe", o_special, (void *)setmppe,
++ "request MPPE encryption" },
++ { "+mppe", o_special, (void *)setmppe,
++ "request MPPE encryption" },
++ { "nomppe", o_special_noarg, (void *)setnomppe,
++ "don't allow MPPE encryption" },
++ { "-mppe", o_special_noarg, (void *)setnomppe,
++ "don't allow MPPE encryption" },
+ #endif /* MPPE */
+
+ { NULL }
+@@ -241,7 +221,7 @@ static fsm_callbacks ccp_callbacks = {
+ */
+ #define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
+ || (opt).predictor_1 || (opt).predictor_2 \
+- || (opt).mppe)
++ || (opt).lzs || (opt).mppc || (opt).mppe)
+
+ /*
+ * Local state (mainly for handling reset-reqs and reset-acks).
+@@ -344,6 +324,100 @@ setdeflate(argv)
+ return 1;
+ }
+
++#ifdef MPPE
++/*
++ * Functions called from config options
++ */
++/*
++ MPPE suboptions:
++ required - require MPPE; disconnect if peer doesn't support it
++ stateless - use stateless mode
++ no40 - disable 40 bit keys
++ no56 - disable 56 bit keys
++ no128 - disable 128 bit keys
++*/
++int setmppe(char **argv)
++{
++ int i;
++ char *str, cmdbuf[16];
++
++ ccp_allowoptions[0].mppe = 1;
++ ccp_allowoptions[0].mppe_40 = 1;
++ ccp_allowoptions[0].mppe_56 = 1;
++ ccp_allowoptions[0].mppe_128 = 1;
++ ccp_allowoptions[0].mppe_stateless = 0;
++ ccp_wantoptions[0].mppe = 0;
++
++ str = *argv;
++
++ while (1) {
++ i = 0;
++ memset(cmdbuf, '\0', 16);
++ while ((i < 16) && (*str != ',') && (*str != '\0'))
++ cmdbuf[i++] = *str++;
++ cmdbuf[i] = '\0';
++ if (!strncasecmp(cmdbuf, "no40", strlen("no40"))) {
++ ccp_allowoptions[0].mppe_40 = 0;
++ goto next_param;
++ } else if (!strncasecmp(cmdbuf, "no56", strlen("no56"))) {
++ ccp_allowoptions[0].mppe_56 = 0;
++ goto next_param;
++ } else if (!strncasecmp(cmdbuf, "no128", strlen("no128"))) {
++ ccp_allowoptions[0].mppe_128 = 0;
++ goto next_param;
++ } else if (!strncasecmp(cmdbuf, "stateless", strlen("stateless"))) {
++ ccp_allowoptions[0].mppe_stateless = 1;
++ goto next_param;
++ } else if (!strncasecmp(cmdbuf, "required", strlen("required"))) {
++ ccp_wantoptions[0].mppe = 1;
++ goto next_param;
++ } else {
++ option_error("invalid parameter '%s' for mppe option", cmdbuf);
++ return 0;
++ }
++
++ next_param:
++ if (*str == ',') {
++ str++;
++ continue;
++ }
++ if (*str == '\0') {
++ if (!(ccp_allowoptions[0].mppe_40 || ccp_allowoptions[0].mppe_56 ||
++ ccp_allowoptions[0].mppe_128)) {
++ if (ccp_wantoptions[0].mppe == 1) {
++ option_error("You require MPPE but you have switched off "
++ "all encryption key lengths.");
++ return 0;
++ }
++ ccp_wantoptions[0].mppe = ccp_allowoptions[0].mppe = 0;
++ ccp_wantoptions[0].mppe_stateless =
++ ccp_allowoptions[0].mppe_stateless = 0;
++ } else {
++ ccp_allowoptions[0].mppe = 1;
++ ccp_wantoptions[0].mppe_stateless =
++ ccp_allowoptions[0].mppe_stateless;
++ if (ccp_wantoptions[0].mppe == 1) {
++ ccp_wantoptions[0].mppe_40 = ccp_allowoptions[0].mppe_40;
++ ccp_wantoptions[0].mppe_56 = ccp_allowoptions[0].mppe_56;
++ ccp_wantoptions[0].mppe_128 = ccp_allowoptions[0].mppe_128;
++ }
++ }
++ return 1;
++ }
++ }
++}
++
++int setnomppe(void)
++{
++ ccp_wantoptions[0].mppe = ccp_allowoptions[0].mppe = 0;
++ ccp_wantoptions[0].mppe_40 = ccp_allowoptions[0].mppe_40 = 0;
++ ccp_wantoptions[0].mppe_56 = ccp_allowoptions[0].mppe_56 = 0;
++ ccp_wantoptions[0].mppe_128 = ccp_allowoptions[0].mppe_128 = 0;
++ ccp_wantoptions[0].mppe_stateless = ccp_allowoptions[0].mppe_stateless = 0;
++ return 1;
++}
++#endif /* MPPE */
++
+ /*
+ * ccp_init - initialize CCP.
+ */
+@@ -378,6 +452,30 @@ ccp_init(unit)
+ ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
+
+ ccp_allowoptions[0].predictor_1 = 1;
++
++ ccp_wantoptions[0].lzs = 0; /* Stac LZS - will be enabled in the future */
++ ccp_wantoptions[0].lzs_mode = LZS_MODE_SEQ;
++ ccp_wantoptions[0].lzs_hists = 1;
++ ccp_allowoptions[0].lzs = 0; /* Stac LZS - will be enabled in the future */
++ ccp_allowoptions[0].lzs_mode = LZS_MODE_SEQ;
++ ccp_allowoptions[0].lzs_hists = 1;
++
++#ifdef MPPE
++ /* by default allow and request MPPC... */
++ ccp_wantoptions[0].mppc = ccp_allowoptions[0].mppc = 1;
++
++ /* ... and allow but don't request MPPE */
++ ccp_allowoptions[0].mppe = 1;
++ ccp_allowoptions[0].mppe_40 = 1;
++ ccp_allowoptions[0].mppe_56 = 1;
++ ccp_allowoptions[0].mppe_128 = 1;
++ ccp_allowoptions[0].mppe_stateless = 1;
++ ccp_wantoptions[0].mppe = 0;
++ ccp_wantoptions[0].mppe_40 = 0;
++ ccp_wantoptions[0].mppe_56 = 0;
++ ccp_wantoptions[0].mppe_128 = 0;
++ ccp_wantoptions[0].mppe_stateless = 0;
++#endif /* MPPE */
+ }
+
+ /*
+@@ -455,11 +553,11 @@ ccp_input(unit, p, len)
+ if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) {
+ notice("Compression disabled by peer.");
+ #ifdef MPPE
+- if (ccp_gotoptions[unit].mppe) {
++ if (ccp_wantoptions[unit].mppe) {
+ error("MPPE disabled, closing LCP");
+ lcp_close(unit, "MPPE disabled by peer");
+ }
+-#endif
++#endif /* MPPE */
+ }
+
+ /*
+@@ -487,6 +585,15 @@ ccp_extcode(f, code, id, p, len)
+ break;
+ /* send a reset-ack, which the transmitter will see and
+ reset its compression state. */
++
++ /* In case of MPPE/MPPC or LZS we shouldn't send CCP_RESETACK,
++ but we do it in order to reset compressor; CCP_RESETACK is
++ then silently discarded. See functions ppp_send_frame and
++ ppp_ccp_peek in ppp_generic.c (Linux only !!!). All the
++ confusion is caused by the fact that CCP code is splited
++ into two parts - one part is handled by pppd, the other one
++ is handled by kernel. */
++
+ fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
+ break;
+
+@@ -515,12 +622,11 @@ ccp_protrej(unit)
+ fsm_lowerdown(&ccp_fsm[unit]);
+
+ #ifdef MPPE
+- if (ccp_gotoptions[unit].mppe) {
++ if (ccp_wantoptions[unit].mppe) {
+ error("MPPE required but peer negotiation failed");
+ lcp_close(unit, "MPPE required but peer negotiation failed");
+ }
+-#endif
+-
++#endif /* MPPE */
+ }
+
+ /*
+@@ -537,7 +643,7 @@ ccp_resetci(f)
+ all_rejected[f->unit] = 0;
+
+ #ifdef MPPE
+- if (go->mppe) {
++ if (go->mppe || go->mppc) {
+ ccp_options *ao = &ccp_allowoptions[f->unit];
+ int auth_mschap_bits = auth_done[f->unit];
+ int numbits;
+@@ -551,80 +657,109 @@ ccp_resetci(f)
+ * NB: If MPPE is required, all other compression opts are invalid.
+ * So, we return right away if we can't do it.
+ */
++ if (ccp_wantoptions[f->unit].mppe) {
++ /* Leave only the mschap auth bits set */
++ auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER |
++ CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
++ /* Count the mschap auths */
++ auth_mschap_bits >>= CHAP_MS_SHIFT;
++ numbits = 0;
++ do {
++ numbits += auth_mschap_bits & 1;
++ auth_mschap_bits >>= 1;
++ } while (auth_mschap_bits);
++ if (numbits > 1) {
++ error("MPPE required, but auth done in both directions.");
++ lcp_close(f->unit, "MPPE required but not available");
++ return;
++ }
++ if (!numbits) {
++ error("MPPE required, but MS-CHAP[v2] auth not performed.");
++ lcp_close(f->unit, "MPPE required but not available");
++ return;
++ }
+
+- /* Leave only the mschap auth bits set */
+- auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER |
+- CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
+- /* Count the mschap auths */
+- auth_mschap_bits >>= CHAP_MS_SHIFT;
+- numbits = 0;
+- do {
+- numbits += auth_mschap_bits & 1;
+- auth_mschap_bits >>= 1;
+- } while (auth_mschap_bits);
+- if (numbits > 1) {
+- error("MPPE required, but auth done in both directions.");
+- lcp_close(f->unit, "MPPE required but not available");
+- return;
+- }
+- if (!numbits) {
+- error("MPPE required, but MS-CHAP[v2] auth not performed.");
+- lcp_close(f->unit, "MPPE required but not available");
+- return;
+- }
+-
+- /* A plugin (eg radius) may not have obtained key material. */
+- if (!mppe_keys_set) {
+- error("MPPE required, but keys are not available. "
+- "Possible plugin problem?");
+- lcp_close(f->unit, "MPPE required but not available");
+- return;
+- }
+-
+- /* LM auth not supported for MPPE */
+- if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) {
+- /* This might be noise */
+- if (go->mppe & MPPE_OPT_40) {
+- notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
+- go->mppe &= ~MPPE_OPT_40;
+- ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40;
++ /* A plugin (eg radius) may not have obtained key material. */
++ if (!mppe_keys_set) {
++ error("MPPE required, but keys are not available. "
++ "Possible plugin problem?");
++ lcp_close(f->unit, "MPPE required but not available");
++ return;
+ }
+ }
+
+- /* Last check: can we actually negotiate something? */
+- if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) {
+- /* Could be misconfig, could be 40-bit disabled above. */
+- error("MPPE required, but both 40-bit and 128-bit disabled.");
+- lcp_close(f->unit, "MPPE required but not available");
+- return;
++ /*
++ * Check whether the kernel knows about the various
++ * compression methods we might request. Key material
++ * unimportant here.
++ */
++ if (go->mppc) {
++ opt_buf[0] = CI_MPPE;
++ opt_buf[1] = CILEN_MPPE;
++ opt_buf[2] = 0;
++ opt_buf[3] = 0;
++ opt_buf[4] = 0;
++ opt_buf[5] = MPPE_MPPC;
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 0) <= 0)
++ go->mppc = 0;
++ }
++ if (go->mppe_40) {
++ opt_buf[0] = CI_MPPE;
++ opt_buf[1] = CILEN_MPPE;
++ opt_buf[2] = MPPE_STATELESS;
++ opt_buf[3] = 0;
++ opt_buf[4] = 0;
++ opt_buf[5] = MPPE_40BIT;
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
++ go->mppe_40 = 0;
++ }
++ if (go->mppe_56) {
++ opt_buf[0] = CI_MPPE;
++ opt_buf[1] = CILEN_MPPE;
++ opt_buf[2] = MPPE_STATELESS;
++ opt_buf[3] = 0;
++ opt_buf[4] = 0;
++ opt_buf[5] = MPPE_56BIT;
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
++ go->mppe_56 = 0;
++ }
++ if (go->mppe_128) {
++ opt_buf[0] = CI_MPPE;
++ opt_buf[1] = CILEN_MPPE;
++ opt_buf[2] = MPPE_STATELESS;
++ opt_buf[3] = 0;
++ opt_buf[4] = 0;
++ opt_buf[5] = MPPE_128BIT;
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
++ go->mppe_128 = 0;
++ }
++ if (!go->mppe_40 && !go->mppe_56 && !go->mppe_128) {
++ if (ccp_wantoptions[f->unit].mppe) {
++ error("MPPE required, but kernel has no support.");
++ lcp_close(f->unit, "MPPE required but not available");
++ }
++ go->mppe = go->mppe_stateless = 0;
++ } else {
++ /* MPPE is not compatible with other compression types */
++ if (ccp_wantoptions[f->unit].mppe) {
++ ao->bsd_compress = go->bsd_compress = 0;
++ ao->predictor_1 = go->predictor_1 = 0;
++ ao->predictor_2 = go->predictor_2 = 0;
++ ao->deflate = go->deflate = 0;
++ ao->lzs = go->lzs = 0;
++ }
+ }
+-
+- /* sync options */
+- ao->mppe = go->mppe;
+- /* MPPE is not compatible with other compression types */
+- ao->bsd_compress = go->bsd_compress = 0;
+- ao->predictor_1 = go->predictor_1 = 0;
+- ao->predictor_2 = go->predictor_2 = 0;
+- ao->deflate = go->deflate = 0;
+ }
+ #endif /* MPPE */
+-
+- /*
+- * Check whether the kernel knows about the various
+- * compression methods we might request.
+- */
+-#ifdef MPPE
+- if (go->mppe) {
+- opt_buf[0] = CI_MPPE;
+- opt_buf[1] = CILEN_MPPE;
+- MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
+- /* Key material unimportant here. */
+- if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) {
+- error("MPPE required, but kernel has no support.");
+- lcp_close(f->unit, "MPPE required but not available");
+- }
++ if (go->lzs) {
++ opt_buf[0] = CI_LZS;
++ opt_buf[1] = CILEN_LZS;
++ opt_buf[2] = go->lzs_hists >> 8;
++ opt_buf[3] = go->lzs_hists & 0xff;
++ opt_buf[4] = LZS_MODE_SEQ;
++ if (ccp_test(f->unit, opt_buf, CILEN_LZS, 0) <= 0)
++ go->lzs = 0;
+ }
+-#endif
+ if (go->bsd_compress) {
+ opt_buf[0] = CI_BSD_COMPRESS;
+ opt_buf[1] = CILEN_BSD_COMPRESS;
+@@ -679,7 +814,8 @@ ccp_cilen(f)
+ + (go->deflate? CILEN_DEFLATE: 0)
+ + (go->predictor_1? CILEN_PREDICTOR_1: 0)
+ + (go->predictor_2? CILEN_PREDICTOR_2: 0)
+- + (go->mppe? CILEN_MPPE: 0);
++ + (go->lzs? CILEN_LZS: 0)
++ + ((go->mppe || go->mppc)? CILEN_MPPE: 0);
+ }
+
+ /*
+@@ -693,6 +829,8 @@ ccp_addci(f, p, lenp)
+ {
+ int res;
+ ccp_options *go = &ccp_gotoptions[f->unit];
++ ccp_options *ao = &ccp_allowoptions[f->unit];
++ ccp_options *wo = &ccp_wantoptions[f->unit];
+ u_char *p0 = p;
+
+ /*
+@@ -701,22 +839,43 @@ ccp_addci(f, p, lenp)
+ * in case it gets Acked.
+ */
+ #ifdef MPPE
+- if (go->mppe) {
++ if (go->mppe || go->mppc || (!wo->mppe && ao->mppe)) {
+ u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
+
+- p[0] = opt_buf[0] = CI_MPPE;
+- p[1] = opt_buf[1] = CILEN_MPPE;
+- MPPE_OPTS_TO_CI(go->mppe, &p[2]);
+- MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
++ p[0] = CI_MPPE;
++ p[1] = CILEN_MPPE;
++ p[2] = (go->mppe_stateless ? MPPE_STATELESS : 0);
++ p[3] = 0;
++ p[4] = 0;
++ p[5] = (go->mppe_40 ? MPPE_40BIT : 0) | (go->mppe_56 ? MPPE_56BIT : 0) |
++ (go->mppe_128 ? MPPE_128BIT : 0) | (go->mppc ? MPPE_MPPC : 0);
++
++ BCOPY(p, opt_buf, CILEN_MPPE);
+ BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
+ res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0);
+- if (res > 0)
++ if (res > 0) {
+ p += CILEN_MPPE;
+- else
++ } else {
+ /* This shouldn't happen, we've already tested it! */
+- lcp_close(f->unit, "MPPE required but not available in kernel");
++ go->mppe = go->mppe_40 = go->mppe_56 = go->mppe_128 =
++ go->mppe_stateless = go->mppc = 0;
++ if (ccp_wantoptions[f->unit].mppe)
++ lcp_close(f->unit, "MPPE required but not available in kernel");
++ }
++ }
++#endif /* MPPE */
++ if (go->lzs) {
++ p[0] = CI_LZS;
++ p[1] = CILEN_LZS;
++ p[2] = go->lzs_hists >> 8;
++ p[3] = go->lzs_hists & 0xff;
++ p[4] = LZS_MODE_SEQ;
++ res = ccp_test(f->unit, p, CILEN_LZS, 0);
++ if (res > 0) {
++ p += CILEN_LZS;
++ } else
++ go->lzs = 0;
+ }
+-#endif
+ if (go->deflate) {
+ p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
+ p[1] = CILEN_DEFLATE;
+@@ -802,7 +961,7 @@ ccp_addci(f, p, lenp)
+
+ /*
+ * ccp_ackci - process a received configure-ack, and return
+- * 1 iff the packet was OK.
++ * 1 if the packet was OK.
+ */
+ static int
+ ccp_ackci(f, p, len)
+@@ -811,24 +970,44 @@ ccp_ackci(f, p, len)
+ int len;
+ {
+ ccp_options *go = &ccp_gotoptions[f->unit];
++ ccp_options *ao = &ccp_allowoptions[f->unit];
++ ccp_options *wo = &ccp_wantoptions[f->unit];
+ u_char *p0 = p;
+
+ #ifdef MPPE
+- if (go->mppe) {
+- u_char opt_buf[CILEN_MPPE];
+-
+- opt_buf[0] = CI_MPPE;
+- opt_buf[1] = CILEN_MPPE;
+- MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
+- if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE))
++ if (go->mppe || go->mppc || (!wo->mppe && ao->mppe)) {
++ if (len < CILEN_MPPE
++ || p[1] != CILEN_MPPE || p[0] != CI_MPPE
++ || p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0)
++ || p[3] != 0
++ || p[4] != 0
++ || (p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) |
++ (go->mppc ? MPPE_MPPC : 0))
++ && p[5] != ((go->mppe_56 ? MPPE_56BIT : 0) |
++ (go->mppc ? MPPE_MPPC : 0))
++ && p[5] != ((go->mppe_128 ? MPPE_128BIT : 0) |
++ (go->mppc ? MPPE_MPPC : 0))))
+ return 0;
++ if (go->mppe_40 || go->mppe_56 || go->mppe_128)
++ go->mppe = 1;
+ p += CILEN_MPPE;
+ len -= CILEN_MPPE;
++ /* Cope with first/fast ack */
++ if (p == p0 && len == 0)
++ return 1;
++ }
++#endif /* MPPE */
++ if (go->lzs) {
++ if (len < CILEN_LZS || p[0] != CI_LZS || p[1] != CILEN_LZS
++ || p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff)
++ || p[4] != LZS_MODE_SEQ)
++ return 0;
++ p += CILEN_LZS;
++ len -= CILEN_LZS;
+ /* XXX Cope with first/fast ack */
+- if (len == 0)
++ if (p == p0 && len == 0)
+ return 1;
+ }
+-#endif
+ if (go->deflate) {
+ if (len < CILEN_DEFLATE
+ || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+@@ -901,6 +1080,8 @@ ccp_nakci(f, p, len, treat_as_reject)
+ int treat_as_reject;
+ {
+ ccp_options *go = &ccp_gotoptions[f->unit];
++ ccp_options *ao = &ccp_allowoptions[f->unit];
++ ccp_options *wo = &ccp_wantoptions[f->unit];
+ ccp_options no; /* options we've seen already */
+ ccp_options try; /* options to ask for next time */
+
+@@ -908,28 +1089,100 @@ ccp_nakci(f, p, len, treat_as_reject)
+ try = *go;
+
+ #ifdef MPPE
+- if (go->mppe && len >= CILEN_MPPE
+- && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
+- no.mppe = 1;
+- /*
+- * Peer wants us to use a different strength or other setting.
+- * Fail if we aren't willing to use his suggestion.
+- */
+- MPPE_CI_TO_OPTS(&p[2], try.mppe);
+- if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) {
+- error("Refusing MPPE stateful mode offered by peer");
+- try.mppe = 0;
+- } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) {
+- /* Peer must have set options we didn't request (suggest) */
+- try.mppe = 0;
+- }
++ if ((go->mppe || go->mppc || (!wo->mppe && ao->mppe)) &&
++ len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
+
+- if (!try.mppe) {
+- error("MPPE required but peer negotiation failed");
+- lcp_close(f->unit, "MPPE required but peer negotiation failed");
++ if (go->mppc) {
++ no.mppc = 1;
++ if (!(p[5] & MPPE_MPPC))
++ try.mppc = 0;
++ }
++
++ if (go->mppe)
++ no.mppe = 1;
++ if (go->mppe_40)
++ no.mppe_40 = 1;
++ if (go->mppe_56)
++ no.mppe_56 = 1;
++ if (go->mppe_128)
++ no.mppe_128 = 1;
++ if (go->mppe_stateless)
++ no.mppe_stateless = 1;
++
++ if (ao->mppe_40) {
++ if ((p[5] & MPPE_40BIT))
++ try.mppe_40 = 1;
++ else
++ try.mppe_40 = (p[5] == 0) ? 1 : 0;
++ }
++ if (ao->mppe_56) {
++ if ((p[5] & MPPE_56BIT))
++ try.mppe_56 = 1;
++ else
++ try.mppe_56 = (p[5] == 0) ? 1 : 0;
++ }
++ if (ao->mppe_128) {
++ if ((p[5] & MPPE_128BIT))
++ try.mppe_128 = 1;
++ else
++ try.mppe_128 = (p[5] == 0) ? 1 : 0;
++ }
++
++ if (ao->mppe_stateless) {
++ if ((p[2] & MPPE_STATELESS) || wo->mppe_stateless)
++ try.mppe_stateless = 1;
++ else
++ try.mppe_stateless = 0;
++ }
++
++ if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128) {
++ try.mppe = try.mppe_stateless = 0;
++ if (wo->mppe) {
++ /* we require encryption, but peer doesn't support it
++ so we close connection */
++ wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
++ wo->mppe_56 = wo->mppe_128 = 0;
++ lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
++ "key length");
++ }
++ }
++ if (wo->mppe && (wo->mppe_40 != try.mppe_40) &&
++ (wo->mppe_56 != try.mppe_56) && (wo->mppe_128 != try.mppe_128)) {
++ /* cannot negotiate key length */
++ wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
++ wo->mppe_56 = wo->mppe_128 = 0;
++ lcp_close(f->unit, "Cannot negotiate MPPE key length");
+ }
++ if (try.mppe_40 && try.mppe_56 && try.mppe_128)
++ try.mppe_40 = try.mppe_56 = 0;
++ else
++ if (try.mppe_56 && try.mppe_128)
++ try.mppe_56 = 0;
++ else
++ if (try.mppe_40 && try.mppe_128)
++ try.mppe_40 = 0;
++ else
++ if (try.mppe_40 && try.mppe_56)
++ try.mppe_40 = 0;
++
++ p += CILEN_MPPE;
++ len -= CILEN_MPPE;
+ }
+ #endif /* MPPE */
++
++ if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
++ no.lzs = 1;
++ if (((p[2]<<8)|p[3]) > 1 || (p[4] != LZS_MODE_SEQ &&
++ p[4] != LZS_MODE_EXT))
++ try.lzs = 0;
++ else {
++ try.lzs_mode = p[4];
++ try.lzs_hists = (p[2] << 8) | p[3];
++ }
++ p += CILEN_LZS;
++ len -= CILEN_LZS;
++ }
++
+ if (go->deflate && len >= CILEN_DEFLATE
+ && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+ && p[1] == CILEN_DEFLATE) {
+@@ -1002,14 +1255,50 @@ ccp_rejci(f, p, len)
+ return -1;
+
+ #ifdef MPPE
+- if (go->mppe && len >= CILEN_MPPE
++ if ((go->mppe || go->mppc) && len >= CILEN_MPPE
+ && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
+- error("MPPE required but peer refused");
+- lcp_close(f->unit, "MPPE required but peer refused");
++ ccp_options *wo = &ccp_wantoptions[f->unit];
++ if (p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0) ||
++ p[3] != 0 ||
++ p[4] != 0 ||
++ p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) |
++ (go->mppe_56 ? MPPE_56BIT : 0) |
++ (go->mppe_128 ? MPPE_128BIT : 0) |
++ (go->mppc ? MPPE_MPPC : 0)))
++ return 0;
++ if (go->mppc)
++ try.mppc = 0;
++ if (go->mppe) {
++ try.mppe = 0;
++ if (go->mppe_40)
++ try.mppe_40 = 0;
++ if (go->mppe_56)
++ try.mppe_56 = 0;
++ if (go->mppe_128)
++ try.mppe_128 = 0;
++ if (go->mppe_stateless)
++ try.mppe_stateless = 0;
++ if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128)
++ try.mppe = try.mppe_stateless = 0;
++ if (wo->mppe) { /* we want MPPE but cannot negotiate key length */
++ wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
++ wo->mppe_56 = wo->mppe_128 = 0;
++ lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
++ "key length");
++ }
++ }
+ p += CILEN_MPPE;
+ len -= CILEN_MPPE;
+ }
+-#endif
++#endif /* MPPE */
++ if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
++ if (p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff)
++ || p[4] != go->lzs_mode)
++ return 0;
++ try.lzs = 0;
++ p += CILEN_LZS;
++ len -= CILEN_LZS;
++ }
+ if (go->deflate_correct && len >= CILEN_DEFLATE
+ && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
+ if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+@@ -1073,14 +1362,15 @@ ccp_reqci(f, p, lenp, dont_nak)
+ int dont_nak;
+ {
+ int ret, newret, res;
+- u_char *p0, *retp;
++ u_char *p0, *retp, p2, p5;
+ int len, clen, type, nb;
+ ccp_options *ho = &ccp_hisoptions[f->unit];
+ ccp_options *ao = &ccp_allowoptions[f->unit];
++ ccp_options *wo = &ccp_wantoptions[f->unit];
+ #ifdef MPPE
+- bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */
+- /* CI_MPPE, or due to other options? */
+-#endif
++ u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
++/* int mtu; */
++#endif /* MPPE */
+
+ ret = CONFACK;
+ retp = p0 = p;
+@@ -1103,106 +1393,302 @@ ccp_reqci(f, p, lenp, dont_nak)
+ switch (type) {
+ #ifdef MPPE
+ case CI_MPPE:
+- if (!ao->mppe || clen != CILEN_MPPE) {
++ if ((!ao->mppc && !ao->mppe) || clen != CILEN_MPPE) {
+ newret = CONFREJ;
+ break;
+ }
+- MPPE_CI_TO_OPTS(&p[2], ho->mppe);
+-
+- /* Nak if anything unsupported or unknown are set. */
+- if (ho->mppe & MPPE_OPT_UNSUPPORTED) {
+- newret = CONFNAK;
+- ho->mppe &= ~MPPE_OPT_UNSUPPORTED;
+- }
+- if (ho->mppe & MPPE_OPT_UNKNOWN) {
++ p2 = p[2];
++ p5 = p[5];
++ /* not sure what they want, tell 'em what we got */
++ if (((p[2] & ~MPPE_STATELESS) != 0 || p[3] != 0 || p[4] != 0 ||
++ (p[5] & ~(MPPE_40BIT | MPPE_56BIT | MPPE_128BIT |
++ MPPE_MPPC)) != 0 || p[5] == 0) ||
++ (p[2] == 0 && p[3] == 0 && p[4] == 0 && p[5] == 0)) {
+ newret = CONFNAK;
+- ho->mppe &= ~MPPE_OPT_UNKNOWN;
+- }
+-
+- /* Check state opt */
+- if (ho->mppe & MPPE_OPT_STATEFUL) {
+- /*
+- * We can Nak and request stateless, but it's a
+- * lot easier to just assume the peer will request
+- * it if he can do it; stateful mode is bad over
+- * the Internet -- which is where we expect MPPE.
+- */
+- if (refuse_mppe_stateful) {
+- error("Refusing MPPE stateful mode offered by peer");
+- newret = CONFREJ;
+- break;
++ p[2] = (wo->mppe_stateless ? MPPE_STATELESS : 0);
++ p[3] = 0;
++ p[4] = 0;
++ p[5] = (wo->mppe_40 ? MPPE_40BIT : 0) |
++ (wo->mppe_56 ? MPPE_56BIT : 0) |
++ (wo->mppe_128 ? MPPE_128BIT : 0) |
++ (wo->mppc ? MPPE_MPPC : 0);
++ break;
++ }
++
++ if ((p[5] & MPPE_MPPC)) {
++ if (ao->mppc) {
++ ho->mppc = 1;
++ BCOPY(p, opt_buf, CILEN_MPPE);
++ opt_buf[2] = opt_buf[3] = opt_buf[4] = 0;
++ opt_buf[5] = MPPE_MPPC;
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 1) <= 0) {
++ ho->mppc = 0;
++ p[5] &= ~MPPE_MPPC;
++ newret = CONFNAK;
++ }
++ } else {
++ newret = CONFREJ;
++ if (wo->mppe || ao->mppe) {
++ p[5] &= ~MPPE_MPPC;
++ newret = CONFNAK;
++ }
+ }
+ }
+-
+- /* Find out which of {S,L} are set. */
+- if ((ho->mppe & MPPE_OPT_128)
+- && (ho->mppe & MPPE_OPT_40)) {
+- /* Both are set, negotiate the strongest. */
+- newret = CONFNAK;
+- if (ao->mppe & MPPE_OPT_128)
+- ho->mppe &= ~MPPE_OPT_40;
+- else if (ao->mppe & MPPE_OPT_40)
+- ho->mppe &= ~MPPE_OPT_128;
+- else {
+- newret = CONFREJ;
+- break;
+- }
+- } else if (ho->mppe & MPPE_OPT_128) {
+- if (!(ao->mppe & MPPE_OPT_128)) {
+- newret = CONFREJ;
+- break;
+- }
+- } else if (ho->mppe & MPPE_OPT_40) {
+- if (!(ao->mppe & MPPE_OPT_40)) {
+- newret = CONFREJ;
+- break;
+- }
++ if (ao->mppe)
++ ho->mppe = 1;
++
++ if ((p[2] & MPPE_STATELESS)) {
++ if (ao->mppe_stateless) {
++ if (wo->mppe_stateless)
++ ho->mppe_stateless = 1;
++ else {
++ newret = CONFNAK;
++ if (!dont_nak)
++ p[2] &= ~MPPE_STATELESS;
++ }
++ } else {
++ newret = CONFNAK;
++ if (!dont_nak)
++ p[2] &= ~MPPE_STATELESS;
++ }
++ } else {
++ if (wo->mppe_stateless && !dont_nak) {
++ wo->mppe_stateless = 0;
++ newret = CONFNAK;
++ p[2] |= MPPE_STATELESS;
++ }
++ }
++
++ if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT|MPPE_128BIT)) {
++ newret = CONFNAK;
++ if (ao->mppe_128) {
++ ho->mppe_128 = 1;
++ p[5] &= ~(MPPE_40BIT|MPPE_56BIT);
++ BCOPY(p, opt_buf, CILEN_MPPE);
++ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++ MPPE_MAX_KEY_LEN);
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++ MPPE_MAX_KEY_LEN, 1) <= 0) {
++ ho->mppe_128 = 0;
++ p[5] |= (MPPE_40BIT|MPPE_56BIT);
++ p[5] &= ~MPPE_128BIT;
++ goto check_mppe_56_40;
++ }
++ goto check_mppe;
++ }
++ p[5] &= ~MPPE_128BIT;
++ goto check_mppe_56_40;
++ }
++ if ((p[5] & ~MPPE_MPPC) == (MPPE_56BIT|MPPE_128BIT)) {
++ newret = CONFNAK;
++ if (ao->mppe_128) {
++ ho->mppe_128 = 1;
++ p[5] &= ~MPPE_56BIT;
++ BCOPY(p, opt_buf, CILEN_MPPE);
++ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++ MPPE_MAX_KEY_LEN);
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++ MPPE_MAX_KEY_LEN, 1) <= 0) {
++ ho->mppe_128 = 0;
++ p[5] |= MPPE_56BIT;
++ p[5] &= ~MPPE_128BIT;
++ goto check_mppe_56;
++ }
++ goto check_mppe;
++ }
++ p[5] &= ~MPPE_128BIT;
++ goto check_mppe_56;
++ }
++ if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_128BIT)) {
++ newret = CONFNAK;
++ if (ao->mppe_128) {
++ ho->mppe_128 = 1;
++ p[5] &= ~MPPE_40BIT;
++ BCOPY(p, opt_buf, CILEN_MPPE);
++ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++ MPPE_MAX_KEY_LEN);
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++ MPPE_MAX_KEY_LEN, 1) <= 0) {
++ ho->mppe_128 = 0;
++ p[5] |= MPPE_40BIT;
++ p[5] &= ~MPPE_128BIT;
++ goto check_mppe_40;
++ }
++ goto check_mppe;
++ }
++ p[5] &= ~MPPE_128BIT;
++ goto check_mppe_40;
++ }
++ if ((p[5] & ~MPPE_MPPC) == MPPE_128BIT) {
++ if (ao->mppe_128) {
++ ho->mppe_128 = 1;
++ BCOPY(p, opt_buf, CILEN_MPPE);
++ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++ MPPE_MAX_KEY_LEN);
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++ MPPE_MAX_KEY_LEN, 1) <= 0) {
++ ho->mppe_128 = 0;
++ p[5] &= ~MPPE_128BIT;
++ newret = CONFNAK;
++ }
++ goto check_mppe;
++ }
++ p[5] &= ~MPPE_128BIT;
++ newret = CONFNAK;
++ goto check_mppe;
++ }
++ check_mppe_56_40:
++ if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT)) {
++ newret = CONFNAK;
++ if (ao->mppe_56) {
++ ho->mppe_56 = 1;
++ p[5] &= ~MPPE_40BIT;
++ BCOPY(p, opt_buf, CILEN_MPPE);
++ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++ MPPE_MAX_KEY_LEN);
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++ MPPE_MAX_KEY_LEN, 1) <= 0) {
++ ho->mppe_56 = 0;
++ p[5] |= MPPE_40BIT;
++ p[5] &= ~MPPE_56BIT;
++ newret = CONFNAK;
++ goto check_mppe_40;
++ }
++ goto check_mppe;
++ }
++ p[5] &= ~MPPE_56BIT;
++ goto check_mppe_40;
++ }
++ check_mppe_56:
++ if ((p[5] & ~MPPE_MPPC) == MPPE_56BIT) {
++ if (ao->mppe_56) {
++ ho->mppe_56 = 1;
++ BCOPY(p, opt_buf, CILEN_MPPE);
++ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++ MPPE_MAX_KEY_LEN);
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++ MPPE_MAX_KEY_LEN, 1) <= 0) {
++ ho->mppe_56 = 0;
++ p[5] &= ~MPPE_56BIT;
++ newret = CONFNAK;
++ }
++ goto check_mppe;
++ }
++ p[5] &= ~MPPE_56BIT;
++ newret = CONFNAK;
++ goto check_mppe;
++ }
++ check_mppe_40:
++ if ((p[5] & ~MPPE_MPPC) == MPPE_40BIT) {
++ if (ao->mppe_40) {
++ ho->mppe_40 = 1;
++ BCOPY(p, opt_buf, CILEN_MPPE);
++ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++ MPPE_MAX_KEY_LEN);
++ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++ MPPE_MAX_KEY_LEN, 1) <= 0) {
++ ho->mppe_40 = 0;
++ p[5] &= ~MPPE_40BIT;
++ newret = CONFNAK;
++ }
++ goto check_mppe;
++ }
++ p[5] &= ~MPPE_40BIT;
++ }
++
++ check_mppe:
++ if (!ho->mppe_40 && !ho->mppe_56 && !ho->mppe_128) {
++ if (wo->mppe_40 || wo->mppe_56 || wo->mppe_128) {
++ newret = CONFNAK;
++ p[2] |= (wo->mppe_stateless ? MPPE_STATELESS : 0);
++ p[5] |= (wo->mppe_40 ? MPPE_40BIT : 0) |
++ (wo->mppe_56 ? MPPE_56BIT : 0) |
++ (wo->mppe_128 ? MPPE_128BIT : 0) |
++ (wo->mppc ? MPPE_MPPC : 0);
++ } else {
++ ho->mppe = ho->mppe_stateless = 0;
++ }
+ } else {
+- /* Neither are set. */
+- /* We cannot accept this. */
+- newret = CONFNAK;
+- /* Give the peer our idea of what can be used,
+- so it can choose and confirm */
+- ho->mppe = ao->mppe;
+- }
+-
+- /* rebuild the opts */
+- MPPE_OPTS_TO_CI(ho->mppe, &p[2]);
+- if (newret == CONFACK) {
+- u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
+- int mtu;
+-
+- BCOPY(p, opt_buf, CILEN_MPPE);
+- BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
+- MPPE_MAX_KEY_LEN);
+- if (ccp_test(f->unit, opt_buf,
+- CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) {
+- /* This shouldn't happen, we've already tested it! */
+- error("MPPE required, but kernel has no support.");
+- lcp_close(f->unit, "MPPE required but not available");
+- newret = CONFREJ;
+- break;
+- }
+- /*
+- * We need to decrease the interface MTU by MPPE_PAD
+- * because MPPE frames **grow**. The kernel [must]
+- * allocate MPPE_PAD extra bytes in xmit buffers.
+- */
+- mtu = netif_get_mtu(f->unit);
+- if (mtu)
+- netif_set_mtu(f->unit, mtu - MPPE_PAD);
+- else
+- newret = CONFREJ;
+- }
+-
+- /*
+- * We have accepted MPPE or are willing to negotiate
+- * MPPE parameters. A CONFREJ is due to subsequent
+- * (non-MPPE) processing.
+- */
+- rej_for_ci_mppe = 0;
+- break;
+-#endif /* MPPE */
++ /* MPPE is not compatible with other compression types */
++ if (wo->mppe) {
++ ao->bsd_compress = 0;
++ ao->predictor_1 = 0;
++ ao->predictor_2 = 0;
++ ao->deflate = 0;
++ ao->lzs = 0;
++ }
++ }
++ if ((!ho->mppc || !ao->mppc) && !ho->mppe) {
++ p[2] = p2;
++ p[5] = p5;
++ newret = CONFREJ;
++ break;
++ }
++
++ /*
++ * I have commented the code below because according to RFC1547
++ * MTU is only information for higher level protocols about
++ * "the maximum allowable length for a packet (q.v.) transmitted
++ * over a point-to-point link without incurring network layer
++ * fragmentation." Of course a PPP implementation should be able
++ * to handle overhead added by MPPE - in our case apropriate code
++ * is located in drivers/net/ppp_generic.c in the kernel sources.
++ *
++ * According to RFC1661:
++ * - when negotiated MRU is less than 1500 octets, a PPP
++ * implementation must still be able to receive at least 1500
++ * octets,
++ * - when PFC is negotiated, a PPP implementation is still
++ * required to receive frames with uncompressed protocol field.
++ *
++ * So why not to handle MPPE overhead without changing MTU value?
++ * I am sure that RFC3078, unfortunately silently, assumes that.
++ */
++
++ /*
++ * We need to decrease the interface MTU by MPPE_PAD
++ * because MPPE frames **grow**. The kernel [must]
++ * allocate MPPE_PAD extra bytes in xmit buffers.
++ */
++ /*
++ mtu = netif_get_mtu(f->unit);
++ if (mtu) {
++ netif_set_mtu(f->unit, mtu - MPPE_PAD);
++ } else {
++ newret = CONFREJ;
++ if (ccp_wantoptions[f->unit].mppe) {
++ error("Cannot adjust MTU needed by MPPE.");
++ lcp_close(f->unit, "Cannot adjust MTU needed by MPPE.");
++ }
++ }
++ */
++ break;
++ #endif /* MPPE */
++
++ case CI_LZS:
++ if (!ao->lzs || clen != CILEN_LZS) {
++ newret = CONFREJ;
++ break;
++ }
++
++ ho->lzs = 1;
++ ho->lzs_hists = (p[2] << 8) | p[3];
++ ho->lzs_mode = p[4];
++ if ((ho->lzs_hists != ao->lzs_hists) ||
++ (ho->lzs_mode != ao->lzs_mode)) {
++ newret = CONFNAK;
++ if (!dont_nak) {
++ p[2] = ao->lzs_hists >> 8;
++ p[3] = ao->lzs_hists & 0xff;
++ p[4] = ao->lzs_mode;
++ } else
++ break;
++ }
++
++ if (p == p0 && ccp_test(f->unit, p, CILEN_LZS, 1) <= 0) {
++ newret = CONFREJ;
++ }
++ break;
+ case CI_DEFLATE:
+ case CI_DEFLATE_DRAFT:
+ if (!ao->deflate || clen != CILEN_DEFLATE
+@@ -1344,12 +1830,6 @@ ccp_reqci(f, p, lenp, dont_nak)
+ else
+ *lenp = retp - p0;
+ }
+-#ifdef MPPE
+- if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {
+- error("MPPE required but peer negotiation failed");
+- lcp_close(f->unit, "MPPE required but peer negotiation failed");
+- }
+-#endif
+ return ret;
+ }
+
+@@ -1371,24 +1851,35 @@ method_name(opt, opt2)
+ char *p = result;
+ char *q = result + sizeof(result); /* 1 past result */
+
+- slprintf(p, q - p, "MPPE ");
+- p += 5;
+- if (opt->mppe & MPPE_OPT_128) {
+- slprintf(p, q - p, "128-bit ");
+- p += 8;
+- }
+- if (opt->mppe & MPPE_OPT_40) {
+- slprintf(p, q - p, "40-bit ");
+- p += 7;
+- }
+- if (opt->mppe & MPPE_OPT_STATEFUL)
+- slprintf(p, q - p, "stateful");
+- else
+- slprintf(p, q - p, "stateless");
+-
++ if (opt->mppe) {
++ if (opt->mppc) {
++ slprintf(p, q - p, "MPPC/MPPE ");
++ p += 10;
++ } else {
++ slprintf(p, q - p, "MPPE ");
++ p += 5;
++ }
++ if (opt->mppe_128) {
++ slprintf(p, q - p, "128-bit ");
++ p += 8;
++ } else if (opt->mppe_56) {
++ slprintf(p, q - p, "56-bit ");
++ p += 7;
++ } else if (opt->mppe_40) {
++ slprintf(p, q - p, "40-bit ");
++ p += 7;
++ }
++ if (opt->mppe_stateless)
++ slprintf(p, q - p, "stateless");
++ else
++ slprintf(p, q - p, "stateful");
++ } else if (opt->mppc)
++ slprintf(p, q - p, "MPPC");
+ break;
+ }
+-#endif
++#endif /* MPPE */
++ case CI_LZS:
++ return "Stac LZS";
+ case CI_DEFLATE:
+ case CI_DEFLATE_DRAFT:
+ if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
+@@ -1444,12 +1935,12 @@ ccp_up(f)
+ } else if (ANY_COMPRESS(*ho))
+ notice("%s transmit compression enabled", method_name(ho, NULL));
+ #ifdef MPPE
+- if (go->mppe) {
++ if (go->mppe || go->mppc) {
+ BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);
+ BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);
+ continue_networks(f->unit); /* Bring up IP et al */
+ }
+-#endif
++#endif /* MPPE */
+ }
+
+ /*
+@@ -1472,7 +1963,7 @@ ccp_down(f)
+ lcp_close(f->unit, "MPPE disabled");
+ }
+ }
+-#endif
++#endif /* MPPE */
+ }
+
+ /*
+@@ -1532,24 +2023,28 @@ ccp_printpkt(p, plen, printer, arg)
+ #ifdef MPPE
+ case CI_MPPE:
+ if (optlen >= CILEN_MPPE) {
+- u_char mppe_opts;
+-
+- MPPE_CI_TO_OPTS(&p[2], mppe_opts);
+- printer(arg, "mppe %s %s %s %s %s %s%s",
+- (p[2] & MPPE_H_BIT)? "+H": "-H",
+- (p[5] & MPPE_M_BIT)? "+M": "-M",
+- (p[5] & MPPE_S_BIT)? "+S": "-S",
+- (p[5] & MPPE_L_BIT)? "+L": "-L",
++ printer(arg, "mppe %s %s %s %s %s %s",
++ (p[2] & MPPE_STATELESS)? "+H": "-H",
++ (p[5] & MPPE_56BIT)? "+M": "-M",
++ (p[5] & MPPE_128BIT)? "+S": "-S",
++ (p[5] & MPPE_40BIT)? "+L": "-L",
+ (p[5] & MPPE_D_BIT)? "+D": "-D",
+- (p[5] & MPPE_C_BIT)? "+C": "-C",
+- (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");
+- if (mppe_opts & MPPE_OPT_UNKNOWN)
++ (p[5] & MPPE_MPPC)? "+C": "-C");
++ if ((p[5] & ~(MPPE_56BIT | MPPE_128BIT | MPPE_40BIT |
++ MPPE_D_BIT | MPPE_MPPC)) ||
++ (p[2] & ~MPPE_STATELESS))
+ printer(arg, " (%.2x %.2x %.2x %.2x)",
+ p[2], p[3], p[4], p[5]);
+ p += CILEN_MPPE;
+ }
+ break;
+-#endif
++#endif /* MPPE */
++ case CI_LZS:
++ if (optlen >= CILEN_LZS) {
++ printer(arg, "lzs %.2x %.2x %.2x", p[2], p[3], p[4]);
++ p += CILEN_LZS;
++ }
++ break;
+ case CI_DEFLATE:
+ case CI_DEFLATE_DRAFT:
+ if (optlen >= CILEN_DEFLATE) {
+@@ -1635,6 +2130,7 @@ ccp_datainput(unit, pkt, len)
+ error("Lost compression sync: disabling compression");
+ ccp_close(unit, "Lost compression sync");
+ #ifdef MPPE
++ /* My module dosn't need this. J.D., 2003-07-06 */
+ /*
+ * If we were doing MPPE, we must also take the link down.
+ */
+@@ -1642,9 +2138,18 @@ ccp_datainput(unit, pkt, len)
+ error("Too many MPPE errors, closing LCP");
+ lcp_close(unit, "Too many MPPE errors");
+ }
+-#endif
++#endif /* MPPE */
+ } else {
+ /*
++ * When LZS or MPPE/MPPC is negotiated we just send CCP_RESETREQ
++ * and don't wait for CCP_RESETACK
++ */
++ if ((ccp_gotoptions[f->unit].method == CI_LZS) ||
++ (ccp_gotoptions[f->unit].method == CI_MPPE)) {
++ fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
++ return;
++ }
++ /*
+ * Send a reset-request to reset the peer's compressor.
+ * We don't do that if we are still waiting for an
+ * acknowledgement to a previous reset-request.
+--- a/pppd/ccp.h
++++ b/pppd/ccp.h
+@@ -37,9 +37,17 @@ typedef struct ccp_options {
+ bool predictor_2; /* do Predictor-2? */
+ bool deflate_correct; /* use correct code for deflate? */
+ bool deflate_draft; /* use draft RFC code for deflate? */
++ bool lzs; /* do Stac LZS? */
++ bool mppc; /* do MPPC? */
+ bool mppe; /* do MPPE? */
++ bool mppe_40; /* allow 40 bit encryption? */
++ bool mppe_56; /* allow 56 bit encryption? */
++ bool mppe_128; /* allow 128 bit encryption? */
++ bool mppe_stateless; /* allow stateless encryption */
+ u_short bsd_bits; /* # bits/code for BSD Compress */
+ u_short deflate_size; /* lg(window size) for Deflate */
++ u_short lzs_mode; /* LZS check mode */
++ u_short lzs_hists; /* number of LZS histories */
+ short method; /* code for chosen compression method */
+ } ccp_options;
+
+--- a/pppd/chap_ms.c
++++ b/pppd/chap_ms.c
+@@ -963,13 +963,17 @@ set_mppe_enc_types(int policy, int types
+ /*
+ * Disable undesirable encryption types. Note that we don't ENABLE
+ * any encryption types, to avoid overriding manual configuration.
++ *
++ * It seems that 56 bit keys are unsupported in MS-RADIUS (see RFC 2548)
+ */
+ switch(types) {
+ case MPPE_ENC_TYPES_RC4_40:
+- ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */
++ ccp_wantoptions[0].mppe_128 = 0; /* disable 128-bit */
++ ccp_wantoptions[0].mppe_56 = 0; /* disable 56-bit */
+ break;
+ case MPPE_ENC_TYPES_RC4_128:
+- ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */
++ ccp_wantoptions[0].mppe_56 = 0; /* disable 56-bit */
++ ccp_wantoptions[0].mppe_40 = 0; /* disable 40-bit */
+ break;
+ default:
+ break;
diff --git a/package/network/services/ppp/patches/202-no_strip.patch b/package/network/services/ppp/patches/202-no_strip.patch
new file mode 100644
index 0000000..375f449
--- /dev/null
+++ b/package/network/services/ppp/patches/202-no_strip.patch
@@ -0,0 +1,88 @@
+build: Do not strip binaries on install
+
+Strippign executables should be handled by the distro packaging, not by ppp
+itself. This patch removes the "-s" (strip) switch from all "install" commands
+in order to install unstripped binaries into the destination prefix.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/chat/Makefile.linux
++++ b/chat/Makefile.linux
+@@ -25,7 +25,7 @@ chat.o: chat.c
+
+ install: chat
+ mkdir -p $(BINDIR) $(MANDIR)
+- $(INSTALL) -s -c chat $(BINDIR)
++ $(INSTALL) -c chat $(BINDIR)
+ $(INSTALL) -c -m 644 chat.8 $(MANDIR)
+
+ clean:
+--- a/pppd/Makefile.linux
++++ b/pppd/Makefile.linux
+@@ -102,7 +102,7 @@ ifdef USE_SRP
+ CFLAGS += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include
+ LIBS += -lsrp -L/usr/local/ssl/lib -lcrypto
+ TARGETS += srp-entry
+-EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry
++EXTRAINSTALL = $(INSTALL) -c -m 555 srp-entry $(BINDIR)/srp-entry
+ MANPAGES += srp-entry.8
+ EXTRACLEAN += srp-entry.o
+ NEEDDES=y
+@@ -208,7 +208,7 @@ all: $(TARGETS)
+ install: pppd
+ mkdir -p $(BINDIR) $(MANDIR)
+ $(EXTRAINSTALL)
+- $(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd
++ $(INSTALL) -c -m 555 pppd $(BINDIR)/pppd
+ if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \
+ chmod o-rx,u+s $(BINDIR)/pppd; fi
+ $(INSTALL) -c -m 444 pppd.8 $(MANDIR)
+--- a/pppd/plugins/radius/Makefile.linux
++++ b/pppd/plugins/radius/Makefile.linux
+@@ -36,9 +36,9 @@ all: $(PLUGIN)
+
+ install: all
+ $(INSTALL) -d -m 755 $(LIBDIR)
+- $(INSTALL) -s -c -m 755 radius.so $(LIBDIR)
+- $(INSTALL) -s -c -m 755 radattr.so $(LIBDIR)
+- $(INSTALL) -s -c -m 755 radrealms.so $(LIBDIR)
++ $(INSTALL) -c -m 755 radius.so $(LIBDIR)
++ $(INSTALL) -c -m 755 radattr.so $(LIBDIR)
++ $(INSTALL) -c -m 755 radrealms.so $(LIBDIR)
+ $(INSTALL) -c -m 444 pppd-radius.8 $(MANDIR)
+ $(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
+
+--- a/pppd/plugins/rp-pppoe/Makefile.linux
++++ b/pppd/plugins/rp-pppoe/Makefile.linux
+@@ -43,9 +43,9 @@ rp-pppoe.so: plugin.o discovery.o if.o c
+
+ install: all
+ $(INSTALL) -d -m 755 $(LIBDIR)
+- $(INSTALL) -s -c -m 4550 rp-pppoe.so $(LIBDIR)
++ $(INSTALL) -c -m 4550 rp-pppoe.so $(LIBDIR)
+ $(INSTALL) -d -m 755 $(BINDIR)
+- $(INSTALL) -s -c -m 555 pppoe-discovery $(BINDIR)
++ $(INSTALL) -c -m 555 pppoe-discovery $(BINDIR)
+
+ clean:
+ rm -f *.o *.so pppoe-discovery
+--- a/pppdump/Makefile.linux
++++ b/pppdump/Makefile.linux
+@@ -17,5 +17,5 @@ clean:
+
+ install:
+ mkdir -p $(BINDIR) $(MANDIR)
+- $(INSTALL) -s -c pppdump $(BINDIR)
++ $(INSTALL) -c pppdump $(BINDIR)
+ $(INSTALL) -c -m 444 pppdump.8 $(MANDIR)
+--- a/pppstats/Makefile.linux
++++ b/pppstats/Makefile.linux
+@@ -22,7 +22,7 @@ all: pppstats
+
+ install: pppstats
+ -mkdir -p $(MANDIR)
+- $(INSTALL) -s -c pppstats $(BINDIR)
++ $(INSTALL) -c pppstats $(BINDIR)
+ $(INSTALL) -c -m 444 pppstats.8 $(MANDIR)
+
+ pppstats: $(PPPSTATSRCS)
diff --git a/package/network/services/ppp/patches/203-opt_flags.patch b/package/network/services/ppp/patches/203-opt_flags.patch
new file mode 100644
index 0000000..906d081
--- /dev/null
+++ b/package/network/services/ppp/patches/203-opt_flags.patch
@@ -0,0 +1,32 @@
+build: Move optimization flags into a separate variable
+
+Isolate optimization related compiler flags from CFLAGS and move them into a
+separate COPTS variable so that it is easier to override optimizations from
+the environment.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/plugins/radius/Makefile.linux
++++ b/pppd/plugins/radius/Makefile.linux
+@@ -12,7 +12,8 @@ VERSION = $(shell awk -F '"' '/VERSION/
+ INSTALL = install
+
+ PLUGIN=radius.so radattr.so radrealms.so
+-CFLAGS=-I. -I../.. -I../../../include -O2 -fPIC -DRC_LOG_FACILITY=LOG_DAEMON
++COPTS = -O2
++CFLAGS=-I. -I../.. -I../../../include $(COPTS) -fPIC -DRC_LOG_FACILITY=LOG_DAEMON
+
+ # Uncomment the next line to include support for Microsoft's
+ # MS-CHAP authentication protocol.
+--- a/pppdump/Makefile.linux
++++ b/pppdump/Makefile.linux
+@@ -2,7 +2,8 @@ DESTDIR = $(INSTROOT)@DESTDIR@
+ BINDIR = $(DESTDIR)/sbin
+ MANDIR = $(DESTDIR)/share/man/man8
+
+-CFLAGS= -O -I../include/net
++COPTS = -O
++CFLAGS= $(COPTS) -I../include/net
+ OBJS = pppdump.o bsd-comp.o deflate.o zlib.o
+
+ INSTALL= install
diff --git a/package/network/services/ppp/patches/204-radius_config.patch b/package/network/services/ppp/patches/204-radius_config.patch
new file mode 100644
index 0000000..c97a535
--- /dev/null
+++ b/package/network/services/ppp/patches/204-radius_config.patch
@@ -0,0 +1,72 @@
+--- a/pppd/plugins/radius/config.c
++++ b/pppd/plugins/radius/config.c
+@@ -369,31 +369,37 @@ static int test_config(char *filename)
+ }
+ #endif
+
++#if 0
+ if (rc_conf_int("login_tries") <= 0)
+ {
+ error("%s: login_tries <= 0 is illegal", filename);
+ return (-1);
+ }
++#endif
+ if (rc_conf_str("seqfile") == NULL)
+ {
+ error("%s: seqfile not specified", filename);
+ return (-1);
+ }
++#if 0
+ if (rc_conf_int("login_timeout") <= 0)
+ {
+ error("%s: login_timeout <= 0 is illegal", filename);
+ return (-1);
+ }
++#endif
+ if (rc_conf_str("mapfile") == NULL)
+ {
+ error("%s: mapfile not specified", filename);
+ return (-1);
+ }
++#if 0
+ if (rc_conf_str("nologin") == NULL)
+ {
+ error("%s: nologin not specified", filename);
+ return (-1);
+ }
++#endif
+
+ return 0;
+ }
+--- a/pppd/plugins/radius/options.h
++++ b/pppd/plugins/radius/options.h
+@@ -31,24 +31,21 @@ typedef struct _option {
+ static SERVER acctserver = {0};
+ static SERVER authserver = {0};
+
+-int default_tries = 4;
+-int default_timeout = 60;
+-
+ static OPTION config_options[] = {
+ /* internally used options */
+ {"config_file", OT_STR, ST_UNDEF, NULL},
+ /* General options */
+ {"auth_order", OT_AUO, ST_UNDEF, NULL},
+-{"login_tries", OT_INT, ST_UNDEF, &default_tries},
+-{"login_timeout", OT_INT, ST_UNDEF, &default_timeout},
+-{"nologin", OT_STR, ST_UNDEF, "/etc/nologin"},
+-{"issue", OT_STR, ST_UNDEF, "/etc/radiusclient/issue"},
++{"login_tries", OT_INT, ST_UNDEF, NULL},
++{"login_timeout", OT_INT, ST_UNDEF, NULL},
++{"nologin", OT_STR, ST_UNDEF, NULL},
++{"issue", OT_STR, ST_UNDEF, NULL},
+ /* RADIUS specific options */
+ {"authserver", OT_SRV, ST_UNDEF, &authserver},
+ {"acctserver", OT_SRV, ST_UNDEF, &acctserver},
+ {"servers", OT_STR, ST_UNDEF, NULL},
+ {"dictionary", OT_STR, ST_UNDEF, NULL},
+-{"login_radius", OT_STR, ST_UNDEF, "/usr/sbin/login.radius"},
++{"login_radius", OT_STR, ST_UNDEF, NULL},
+ {"seqfile", OT_STR, ST_UNDEF, NULL},
+ {"mapfile", OT_STR, ST_UNDEF, NULL},
+ {"default_realm", OT_STR, ST_UNDEF, NULL},
diff --git a/package/network/services/ppp/patches/205-no_exponential_timeout.patch b/package/network/services/ppp/patches/205-no_exponential_timeout.patch
new file mode 100644
index 0000000..68aea12
--- /dev/null
+++ b/package/network/services/ppp/patches/205-no_exponential_timeout.patch
@@ -0,0 +1,29 @@
+pppd: Don't use exponential timeout in discovery phase
+
+This patch removes the exponential timeout increase between PADO or PADS
+discovery attempts.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/plugins/rp-pppoe/discovery.c
++++ b/pppd/plugins/rp-pppoe/discovery.c
+@@ -644,7 +644,9 @@ discovery(PPPoEConnection *conn)
+ conn->discoveryState = STATE_SENT_PADI;
+ waitForPADO(conn, timeout);
+
++#if 0
+ timeout *= 2;
++#endif
+ } while (conn->discoveryState == STATE_SENT_PADI);
+
+ timeout = conn->discoveryTimeout;
+@@ -659,7 +661,9 @@ discovery(PPPoEConnection *conn)
+ sendPADR(conn);
+ conn->discoveryState = STATE_SENT_PADR;
+ waitForPADS(conn, timeout);
++#if 0
+ timeout *= 2;
++#endif
+ } while (conn->discoveryState == STATE_SENT_PADR);
+
+ if (!conn->seenMaxPayload) {
diff --git a/package/network/services/ppp/patches/206-compensate_time_change.patch b/package/network/services/ppp/patches/206-compensate_time_change.patch
new file mode 100644
index 0000000..fb6c656
--- /dev/null
+++ b/package/network/services/ppp/patches/206-compensate_time_change.patch
@@ -0,0 +1,94 @@
+pppd: Watch out for time warps
+
+On many embedded systems there is no battery backed RTC and a proper system
+time only becomes available through NTP after establishing a connection.
+
+When the clock suddenly jumps forward, the internal accounting (connect time)
+is confused resulting in unreliable data.
+
+This patch implements periodic clock checking to look for time warps, if one
+is detected, the internal counters are adjusted accordingly.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/main.c
++++ b/pppd/main.c
+@@ -90,6 +90,7 @@
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
++#include <sys/sysinfo.h>
+
+ #include "pppd.h"
+ #include "magic.h"
+@@ -228,6 +229,7 @@ static struct subprocess *children;
+
+ /* Prototypes for procedures local to this file. */
+
++static void check_time(void);
+ static void setup_signals __P((void));
+ static void create_pidfile __P((int pid));
+ static void create_linkpidfile __P((int pid));
+@@ -535,6 +537,7 @@ main(argc, argv)
+ info("Starting link");
+ }
+
++ check_time();
+ gettimeofday(&start_time, NULL);
+ script_unsetenv("CONNECT_TIME");
+ script_unsetenv("BYTES_SENT");
+@@ -1267,6 +1270,36 @@ struct callout {
+
+ static struct callout *callout = NULL; /* Callout list */
+ static struct timeval timenow; /* Current time */
++static long uptime_diff = 0;
++static int uptime_diff_set = 0;
++
++static void check_time(void)
++{
++ long new_diff;
++ struct timeval t;
++ struct sysinfo i;
++ struct callout *p;
++
++ gettimeofday(&t, NULL);
++ sysinfo(&i);
++ new_diff = t.tv_sec - i.uptime;
++
++ if (!uptime_diff_set) {
++ uptime_diff = new_diff;
++ uptime_diff_set = 1;
++ return;
++ }
++
++ if ((new_diff - 5 > uptime_diff) || (new_diff + 5 < uptime_diff)) {
++ /* system time has changed, update counters and timeouts */
++ info("System time change detected.");
++ start_time.tv_sec += new_diff - uptime_diff;
++
++ for (p = callout; p != NULL; p = p->c_next)
++ p->c_time.tv_sec += new_diff - uptime_diff;
++ }
++ uptime_diff = new_diff;
++}
+
+ /*
+ * timeout - Schedule a timeout.
+@@ -1337,6 +1370,8 @@ calltimeout()
+ {
+ struct callout *p;
+
++ check_time();
++
+ while (callout != NULL) {
+ p = callout;
+
+@@ -1364,6 +1399,8 @@ timeleft(tvp)
+ {
+ if (callout == NULL)
+ return NULL;
++
++ check_time();
+
+ gettimeofday(&timenow, NULL);
+ tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
diff --git a/package/network/services/ppp/patches/207-lcp_mtu_max.patch b/package/network/services/ppp/patches/207-lcp_mtu_max.patch
new file mode 100644
index 0000000..240701b
--- /dev/null
+++ b/package/network/services/ppp/patches/207-lcp_mtu_max.patch
@@ -0,0 +1,25 @@
+pppd: Cap MTU to the user configured value
+
+This patchs caps the calculated MTU value in lcp.c to the user specified "mru"
+option value. Without this patch pppd would advertise a different MTU value
+compared to what is set on the local interface in some cases.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/lcp.c
++++ b/pppd/lcp.c
+@@ -1917,12 +1917,12 @@ lcp_up(f)
+ * the interface MTU is set to the lowest of that, the
+ * MTU we want to use, and our link MRU.
+ */
+- mtu = ho->neg_mru? ho->mru: PPP_MRU;
++ mtu = MIN(ho->neg_mru? ho->mru: PPP_MRU, ao->mru);
+ mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
+ #ifdef HAVE_MULTILINK
+ if (!(multilink && go->neg_mrru && ho->neg_mrru))
+ #endif /* HAVE_MULTILINK */
+- netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru));
++ netif_set_mtu(f->unit, MIN(mtu, mru));
+ ppp_send_config(f->unit, mtu,
+ (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
+ ho->neg_pcompression, ho->neg_accompression);
diff --git a/package/network/services/ppp/patches/208-fix_status_code.patch b/package/network/services/ppp/patches/208-fix_status_code.patch
new file mode 100644
index 0000000..25e2a10
--- /dev/null
+++ b/package/network/services/ppp/patches/208-fix_status_code.patch
@@ -0,0 +1,24 @@
+pppd: Do not clobber exit codes on hangup
+
+When a modem hangup occurs, pppd unconditionally sets the exit status code
+to EXIT_HANGUP. This patch only sets EXIT_HANGUP if the exit status code is
+not already set to an error value.
+
+The motiviation of this patch is to allow applications which remote control
+pppd to react properly on errors, e.g. only redial (relaunch pppd) if there
+was a hangup, but not if the CHAP authentication failed.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/main.c
++++ b/pppd/main.c
+@@ -1048,7 +1048,8 @@ get_input()
+ }
+ notice("Modem hangup");
+ hungup = 1;
+- status = EXIT_HANGUP;
++ if (status == EXIT_OK)
++ status = EXIT_HANGUP;
+ lcp_lowerdown(0); /* serial link is no longer available */
+ link_terminated(0);
+ return;
diff --git a/package/network/services/ppp/patches/300-filter-pcap-includes-lib.patch b/package/network/services/ppp/patches/300-filter-pcap-includes-lib.patch
new file mode 100644
index 0000000..843c9f2
--- /dev/null
+++ b/package/network/services/ppp/patches/300-filter-pcap-includes-lib.patch
@@ -0,0 +1,20 @@
+build: Add required CFLAGS for libpcap
+
+This patch adds some flags to required to properly link libpcap within the
+OpenWrt environment.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/Makefile.linux
++++ b/pppd/Makefile.linux
+@@ -178,8 +178,8 @@ endif
+
+ ifdef FILTER
+ ifneq ($(wildcard /usr/include/pcap-bpf.h),)
+-LIBS += -lpcap
+-CFLAGS += -DPPP_FILTER
++LIBS += -lpcap -L$(STAGING_DIR)/usr/lib
++CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)/usr/include
+ endif
+ endif
+
diff --git a/package/network/services/ppp/patches/310-precompile_filter.patch b/package/network/services/ppp/patches/310-precompile_filter.patch
new file mode 100644
index 0000000..877ca6b
--- /dev/null
+++ b/package/network/services/ppp/patches/310-precompile_filter.patch
@@ -0,0 +1,196 @@
+pppd: Implement support for precompiled pcap filters
+
+This patch implements support for precompiled pcap filters which is useful to
+support dial-on-demand on memory constrained embedded devices without having
+to link the full libpcap into pppd to generate the filters during runtime.
+
+Two new options are introduced; "precompiled-pass-filter" specifies a pre-
+compiled filter file containing rules to match packets which should be passed,
+"precompiled-active-filter" specifies a filter file containing rules to match
+packets which are treated as active.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/Makefile.linux
++++ b/pppd/Makefile.linux
+@@ -50,6 +50,9 @@ MPPE=y
+ # and that the kernel driver support PPP packet filtering.
+ #FILTER=y
+
++# Support for precompiled filters
++PRECOMPILED_FILTER=y
++
+ # Uncomment the next line to enable multilink PPP (enabled by default)
+ # Linux distributions: Please leave multilink ENABLED in your builds
+ # of pppd!
+@@ -183,6 +186,14 @@ CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)
+ endif
+ endif
+
++ifdef PRECOMPILED_FILTER
++PPPDSRCS += pcap_pcc.c
++HEADERS += pcap_pcc.h
++PPPDOBJS += pcap_pcc.o
++LIBS += $(STAGING_DIR)/usr/lib/libpcap.a
++CFLAGS += -DPPP_FILTER -DPPP_PRECOMPILED_FILTER -I$(STAGING_DIR)/usr/include
++endif
++
+ ifdef HAVE_INET6
+ PPPDSRCS += ipv6cp.c eui64.c
+ HEADERS += ipv6cp.h eui64.h
+--- a/pppd/options.c
++++ b/pppd/options.c
+@@ -57,6 +57,7 @@
+
+ #ifdef PPP_FILTER
+ #include <pcap.h>
++#include <pcap-bpf.h>
+ /*
+ * There have been 3 or 4 different names for this in libpcap CVS, but
+ * this seems to be what they have settled on...
+@@ -165,6 +166,13 @@ static int setlogfile __P((char **));
+ static int loadplugin __P((char **));
+ #endif
+
++#ifdef PPP_PRECOMPILED_FILTER
++#include "pcap_pcc.h"
++static int setprecompiledpassfilter __P((char **));
++static int setprecompiledactivefilter __P((char **));
++#undef PPP_FILTER
++#endif
++
+ #ifdef PPP_FILTER
+ static int setpassfilter __P((char **));
+ static int setactivefilter __P((char **));
+@@ -344,6 +352,14 @@ option_t general_options[] = {
+ "set filter for active pkts", OPT_PRIO },
+ #endif
+
++#ifdef PPP_PRECOMPILED_FILTER
++ { "precompiled-pass-filter", 1, setprecompiledpassfilter,
++ "set precompiled filter for packets to pass", OPT_PRIO },
++
++ { "precompiled-active-filter", 1, setprecompiledactivefilter,
++ "set precompiled filter for active pkts", OPT_PRIO },
++#endif
++
+ #ifdef MAXOCTETS
+ { "maxoctets", o_int, &maxoctets,
+ "Set connection traffic limit",
+@@ -1493,6 +1509,29 @@ callfile(argv)
+ return ok;
+ }
+
++#ifdef PPP_PRECOMPILED_FILTER
++/*
++ * setprecompiledpassfilter - Set the pass filter for packets using a
++ * precompiled expression
++ */
++static int
++setprecompiledpassfilter(argv)
++ char **argv;
++{
++ return pcap_pre_compiled (*argv, &pass_filter);
++}
++
++/*
++ * setactivefilter - Set the active filter for packets
++ */
++static int
++setprecompiledactivefilter(argv)
++ char **argv;
++{
++ return pcap_pre_compiled (*argv, &active_filter);
++}
++#endif
++
+ #ifdef PPP_FILTER
+ /*
+ * setpassfilter - Set the pass filter for packets
+--- /dev/null
++++ b/pppd/pcap_pcc.c
+@@ -0,0 +1,74 @@
++#include <pcap.h>
++#include <pcap-bpf.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include "pppd.h"
++
++int pcap_pre_compiled (char * fname, struct bpf_program *p)
++{
++ char buf[128];
++ int line = 0, size = 0, index=0, ret=1;
++ FILE *f = fopen (fname, "r");
++ if (!f)
++ {
++ option_error("error opening precompiled active-filter '%s': %s",
++ fname, strerror (errno));
++ return 0;
++ }
++ while (fgets (buf, 127, f))
++ {
++ line++;
++ if (*buf == '#')
++ continue;
++ if (size)
++ {
++ /*
++ struct bpf_insn {
++ u_short code;
++ u_char jt;
++ u_char jf;
++ bpf_int32 k;
++ }
++ */
++ struct bpf_insn * insn = & p->bf_insns[index];
++ unsigned code, jt, jf, k;
++ if (sscanf (buf, "%u %u %u %u", &code, &jt, &jf, &k) != 4)
++ {
++ goto err;
++ }
++ insn->code = code;
++ insn->jt = jt;
++ insn->jf = jf;
++ insn->k = k;
++ index++;
++ }
++ else
++ {
++ if (sscanf (buf, "%u", &size) != 1)
++ {
++ goto err;
++ }
++ p->bf_len = size;
++ p->bf_insns = (struct bpf_insn *)
++ malloc (size * sizeof (struct bpf_insn));
++ }
++ }
++ if (size != index)
++ {
++ option_error("error in precompiled active-filter,"
++ " expected %d expressions, got %dn",
++ size, index);
++ ret = 0;
++ }
++ fclose(f);
++ return ret;
++
++err:
++ option_error("error in precompiled active-filter"
++ " expression line %s:%d (wrong size)\n",
++ fname, line);
++ fclose (f);
++ return 0;
++}
+--- /dev/null
++++ b/pppd/pcap_pcc.h
+@@ -0,0 +1,7 @@
++#ifndef PCAP_PCC_H
++#define PCAP_PCC_H
++
++#include <pcap.h>
++
++int pcap_pre_compiled (char * fname, struct bpf_program *p);
++#endif /* PCAP_PCC_H */
diff --git a/package/network/services/ppp/patches/320-custom_iface_names.patch b/package/network/services/ppp/patches/320-custom_iface_names.patch
new file mode 100644
index 0000000..ccda0c6
--- /dev/null
+++ b/package/network/services/ppp/patches/320-custom_iface_names.patch
@@ -0,0 +1,135 @@
+pppd: Support arbitrary interface names
+
+This patch implements a new string option "ifname" which allows to specify
+fully custom PPP interface names on Linux. It does so by renaming the
+allocated pppX device immediately after it has been created to the requested
+interface name.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/main.c
++++ b/pppd/main.c
+@@ -745,8 +745,11 @@ void
+ set_ifunit(iskey)
+ int iskey;
+ {
+- info("Using interface %s%d", PPP_DRV_NAME, ifunit);
+- slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
++ if (use_ifname[0] == 0)
++ slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
++ else
++ slprintf(ifname, sizeof(ifname), "%s", use_ifname);
++ info("Using interface %s", ifname);
+ script_setenv("IFNAME", ifname, iskey);
+ if (iskey) {
+ create_pidfile(getpid()); /* write pid to file */
+--- a/pppd/options.c
++++ b/pppd/options.c
+@@ -112,6 +112,7 @@ int log_to_fd = 1; /* send log messages
+ bool log_default = 1; /* log_to_fd is default (stdout) */
+ int maxfail = 10; /* max # of unsuccessful connection attempts */
+ char linkname[MAXPATHLEN]; /* logical name for link */
++char use_ifname[IFNAMSIZ]; /* physical name for PPP link */
+ bool tune_kernel; /* may alter kernel settings */
+ int connect_delay = 1000; /* wait this many ms after connect script */
+ int req_unit = -1; /* requested interface unit */
+@@ -277,6 +278,9 @@ option_t general_options[] = {
+ { "linkname", o_string, linkname,
+ "Set logical name for link",
+ OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXPATHLEN },
++ { "ifname", o_string, use_ifname,
++ "Set physical name for PPP interface",
++ OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, IFNAMSIZ },
+
+ { "maxfail", o_int, &maxfail,
+ "Maximum number of unsuccessful connection attempts to allow",
+--- a/pppd/pppd.h
++++ b/pppd/pppd.h
+@@ -74,6 +74,10 @@
+ #include "eui64.h"
+ #endif
+
++#ifndef IFNAMSIZ
++#define IFNAMSIZ 16
++#endif
++
+ /*
+ * Limits.
+ */
+@@ -317,6 +321,7 @@ extern char *record_file; /* File to rec
+ extern bool sync_serial; /* Device is synchronous serial device */
+ extern int maxfail; /* Max # of unsuccessful connection attempts */
+ extern char linkname[MAXPATHLEN]; /* logical name for link */
++extern char use_ifname[IFNAMSIZ]; /* physical name for PPP interface */
+ extern bool tune_kernel; /* May alter kernel settings as necessary */
+ extern int connect_delay; /* Time to delay after connect script */
+ extern int max_data_rate; /* max bytes/sec through charshunt */
+--- a/pppd/sys-linux.c
++++ b/pppd/sys-linux.c
+@@ -161,6 +161,10 @@ struct in6_ifreq {
+ /* We can get an EIO error on an ioctl if the modem has hung up */
+ #define ok_error(num) ((num)==EIO)
+
++#if !defined(PPP_DRV_NAME)
++#define PPP_DRV_NAME "ppp"
++#endif /* !defined(PPP_DRV_NAME) */
++
+ static int tty_disc = N_TTY; /* The TTY discipline */
+ static int ppp_disc = N_PPP; /* The PPP discpline */
+ static int initfdflags = -1; /* Initial file descriptor flags for fd */
+@@ -620,7 +624,8 @@ void generic_disestablish_ppp(int dev_fd
+ */
+ static int make_ppp_unit()
+ {
+- int x, flags;
++ struct ifreq ifr;
++ int x, flags, s;
+
+ if (ppp_dev_fd >= 0) {
+ dbglog("in make_ppp_unit, already had /dev/ppp open?");
+@@ -643,6 +648,30 @@ static int make_ppp_unit()
+ }
+ if (x < 0)
+ error("Couldn't create new ppp unit: %m");
++
++ if (use_ifname[0] != 0) {
++ s = socket(PF_INET, SOCK_DGRAM, 0);
++ if (s < 0)
++ s = socket(PF_PACKET, SOCK_DGRAM, 0);
++ if (s < 0)
++ s = socket(PF_INET6, SOCK_DGRAM, 0);
++ if (s < 0)
++ s = socket(PF_UNIX, SOCK_DGRAM, 0);
++ if (s >= 0) {
++ slprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", PPP_DRV_NAME, ifunit);
++ slprintf(ifr.ifr_newname, sizeof(ifr.ifr_newname), "%s", use_ifname);
++ x = ioctl(s, SIOCSIFNAME, &ifr);
++ close(s);
++ } else {
++ x = s;
++ }
++ if (x < 0) {
++ error("Couldn't rename %s to %s", ifr.ifr_name, ifr.ifr_newname);
++ close(ppp_dev_fd);
++ ppp_dev_fd = -1;
++ }
++ }
++
+ return x;
+ }
+
+--- a/pppstats/pppstats.c
++++ b/pppstats/pppstats.c
+@@ -506,10 +506,12 @@ main(argc, argv)
+ if (argc > 0)
+ interface = argv[0];
+
++#if 0
+ if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) {
+ fprintf(stderr, "%s: invalid interface '%s' specified\n",
+ progname, interface);
+ }
++#endif
+
+ #ifndef STREAMS
+ {
diff --git a/package/network/services/ppp/patches/321-multilink_support_custom_iface_names.patch b/package/network/services/ppp/patches/321-multilink_support_custom_iface_names.patch
new file mode 100644
index 0000000..bba5884
--- /dev/null
+++ b/package/network/services/ppp/patches/321-multilink_support_custom_iface_names.patch
@@ -0,0 +1,146 @@
+From: George Kashperko <george@znau.edu.ua>
+
+Make mlppp support more generic interface naming other than pppX
+Signed-off-by: George Kashperko <george@znau.edu.ua>
+---
+ pppd/multilink.c | 55 +++++++++++++++++++++++++++++++++------------
+ pppd/sys-linux.c | 12 +++++++++
+ 2 files changed, 53 insertions(+), 14 deletions(-)
+--- a/pppd/multilink.c
++++ b/pppd/multilink.c
+@@ -56,7 +56,8 @@ static void iterate_bundle_links __P((vo
+
+ static int get_default_epdisc __P((struct epdisc *));
+ static int parse_num __P((char *str, const char *key, int *valp));
+-static int owns_unit __P((TDB_DATA pid, int unit));
++static int parse_str __P((char *str, const char *key, char *buf, int buflen));
++static int owns_link __P((TDB_DATA pid, char *ifname));
+
+ #define set_ip_epdisc(ep, addr) do { \
+ ep->length = 4; \
+@@ -197,35 +198,38 @@ mp_join_bundle()
+ key.dptr = bundle_id;
+ key.dsize = p - bundle_id;
+ pid = tdb_fetch(pppdb, key);
++
+ if (pid.dptr != NULL) {
++ char tmp[IFNAMSIZ];
++
+ /* bundle ID exists, see if the pppd record exists */
+ rec = tdb_fetch(pppdb, pid);
++
+ if (rec.dptr != NULL && rec.dsize > 0) {
+ /* make sure the string is null-terminated */
+ rec.dptr[rec.dsize-1] = 0;
+- /* parse the interface number */
+- parse_num(rec.dptr, "IFNAME=ppp", &unit);
++
+ /* check the pid value */
+ if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid)
++ || !parse_str(rec.dptr, "IFNAME=", tmp, sizeof(tmp))
++ || !parse_num(rec.dptr, "IFUNIT=", &unit)
+ || !process_exists(pppd_pid)
+- || !owns_unit(pid, unit))
++ || !owns_link(pid, tmp))
+ unit = -1;
+ free(rec.dptr);
+ }
+ free(pid.dptr);
+- }
+
+- if (unit >= 0) {
+ /* attach to existing unit */
+- if (bundle_attach(unit)) {
++ if (unit >= 0 && bundle_attach(unit)) {
+ set_ifunit(0);
+ script_setenv("BUNDLE", bundle_id + 7, 0);
+ make_bundle_links(1);
+ unlock_db();
+- info("Link attached to %s", ifname);
++ info("Link attached to %s", tmp);
+ return 1;
++ /* attach failed because bundle doesn't exist */
+ }
+- /* attach failed because bundle doesn't exist */
+ }
+
+ /* we have to make a new bundle */
+@@ -408,22 +412,45 @@ parse_num(str, key, valp)
+ return 0;
+ }
+
++static int
++parse_str(str, key, buf, buflen)
++ char *str;
++ const char *key;
++ char *buf;
++ int buflen;
++{
++ char *p, *endp;
++ int i;
++
++ p = strstr(str, key);
++ if (p) {
++ p += strlen(key);
++ while (--buflen && *p != 0 && *p != ';')
++ *(buf++) = *(p++);
++ *buf = 0;
++ return 1;
++ }
++ return 0;
++}
++
+ /*
+- * Check whether the pppd identified by `key' still owns ppp unit `unit'.
++ * Check whether the pppd identified by `key' still owns ppp link `ifname'.
+ */
+ static int
+-owns_unit(key, unit)
++owns_link(key, ifname)
+ TDB_DATA key;
+- int unit;
++ char *ifname;
+ {
+- char ifkey[32];
++ char ifkey[7 + IFNAMSIZ];
+ TDB_DATA kd, vd;
+ int ret = 0;
+
+- slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit);
++ slprintf(ifkey, sizeof(ifkey), "IFNAME=%s", ifname);
++
+ kd.dptr = ifkey;
+ kd.dsize = strlen(ifkey);
+ vd = tdb_fetch(pppdb, kd);
++
+ if (vd.dptr != NULL) {
+ ret = vd.dsize == key.dsize
+ && memcmp(vd.dptr, key.dptr, vd.dsize) == 0;
+--- a/pppd/sys-linux.c
++++ b/pppd/sys-linux.c
+@@ -698,6 +698,16 @@ void cfg_bundle(int mrru, int mtru, int
+ add_fd(ppp_dev_fd);
+ }
+
++static void
++setenv_ifunit(void)
++{
++#ifdef USE_TDB
++ char tmp[11];
++ slprintf(tmp, sizeof(tmp), "%d", ifunit);
++ script_setenv("IFUNIT", tmp, 0);
++#endif
++}
++
+ /*
+ * make_new_bundle - create a new PPP unit (i.e. a bundle)
+ * and connect our channel to it. This should only get called
+@@ -716,6 +726,8 @@ void make_new_bundle(int mrru, int mtru,
+
+ /* set the mrru and flags */
+ cfg_bundle(mrru, mtru, rssn, tssn);
++
++ setenv_ifunit();
+ }
+
+ /*
diff --git a/package/network/services/ppp/patches/330-retain_foreign_default_routes.patch b/package/network/services/ppp/patches/330-retain_foreign_default_routes.patch
new file mode 100644
index 0000000..f68b466
--- /dev/null
+++ b/package/network/services/ppp/patches/330-retain_foreign_default_routes.patch
@@ -0,0 +1,22 @@
+pppd: Retain foreign default routes on Linux
+
+On Linux, when pppd attempts to delete its default route it does not fill
+the rt_dev field of the struct rtentry used to match the system default route.
+As a consequence, pppd happily deletes any default route even if it belongs
+to another interface.
+
+This patch makes pppd fill out the rt_dev field so that only own default
+routes are ever matched.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/sys-linux.c
++++ b/pppd/sys-linux.c
+@@ -1756,6 +1756,7 @@ int cifdefaultroute (int unit, u_int32_t
+ SIN_ADDR(rt.rt_genmask) = 0L;
+ }
+
++ rt.rt_dev = ifname;
+ rt.rt_flags = RTF_UP;
+ if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
+ if (still_ppp()) {
diff --git a/package/network/services/ppp/patches/340-populate_default_gateway.patch b/package/network/services/ppp/patches/340-populate_default_gateway.patch
new file mode 100644
index 0000000..a1451de
--- /dev/null
+++ b/package/network/services/ppp/patches/340-populate_default_gateway.patch
@@ -0,0 +1,34 @@
+pppd: Fill in default gateway on Linux
+
+On Linux, when pppd creates the default route, it does not set the peer
+address as gateway, leading to a default route without gateway address.
+
+This behaviour breaks various downstream programs which attempt to infer
+the default gateway IP address from the system default route entry.
+
+This patch addresses the issue by filling in the peer address as gateway
+when generating the default route entry.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/sys-linux.c
++++ b/pppd/sys-linux.c
+@@ -1710,6 +1710,9 @@ int sifdefaultroute (int unit, u_int32_t
+ memset (&rt, 0, sizeof (rt));
+ SET_SA_FAMILY (rt.rt_dst, AF_INET);
+
++ SET_SA_FAMILY(rt.rt_gateway, AF_INET);
++ SIN_ADDR(rt.rt_gateway) = gateway;
++
+ rt.rt_dev = ifname;
+
+ if (kernel_version > KVERSION(2,1,0)) {
+@@ -1717,7 +1720,7 @@ int sifdefaultroute (int unit, u_int32_t
+ SIN_ADDR(rt.rt_genmask) = 0L;
+ }
+
+- rt.rt_flags = RTF_UP;
++ rt.rt_flags = RTF_UP | RTF_GATEWAY;
+ if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
+ if (!ok_error(errno))
+ error("default route ioctl(SIOCADDRT): %m");
diff --git a/package/network/services/ppp/patches/400-simplify_kernel_checks.patch b/package/network/services/ppp/patches/400-simplify_kernel_checks.patch
new file mode 100644
index 0000000..11af6d8
--- /dev/null
+++ b/package/network/services/ppp/patches/400-simplify_kernel_checks.patch
@@ -0,0 +1,154 @@
+pppd: Remove runtime kernel checks
+
+On embedded system distributions the required kernel features for pppd are
+more or less guaranteed to be present, so there is not much point in
+performing runtime checks, it just increases the binary size.
+
+This patch removes the runtime kernel feature checks.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/sys-linux.c
++++ b/pppd/sys-linux.c
+@@ -196,7 +196,7 @@ static int driver_is_old = 0;
+ static int restore_term = 0; /* 1 => we've munged the terminal */
+ static struct termios inittermios; /* Initial TTY termios */
+
+-int new_style_driver = 0;
++static const int new_style_driver = 1;
+
+ static char loop_name[20];
+ static unsigned char inbuf[512]; /* buffer for chars read from loopback */
+@@ -214,8 +214,8 @@ static int looped; /* 1 if using loop
+ static int link_mtu; /* mtu for the link (not bundle) */
+
+ static struct utsname utsname; /* for the kernel version */
+-static int kernel_version;
+ #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
++static const int kernel_version = KVERSION(2,6,37);
+
+ #define MAX_IFS 100
+
+@@ -1451,11 +1451,12 @@ int ccp_fatal_error (int unit)
+ *
+ * path_to_procfs - find the path to the proc file system mount point
+ */
+-static char proc_path[MAXPATHLEN];
+-static int proc_path_len;
++static char proc_path[MAXPATHLEN] = "/proc";
++static int proc_path_len = 5;
+
+ static char *path_to_procfs(const char *tail)
+ {
++#if 0
+ struct mntent *mntent;
+ FILE *fp;
+
+@@ -1477,6 +1478,7 @@ static char *path_to_procfs(const char *
+ fclose (fp);
+ }
+ }
++#endif
+
+ strlcpy(proc_path + proc_path_len, tail,
+ sizeof(proc_path) - proc_path_len);
+@@ -2129,15 +2131,19 @@ int ppp_available(void)
+ int my_version, my_modification, my_patch;
+ int osmaj, osmin, ospatch;
+
++#if 0
+ /* get the kernel version now, since we are called before sys_init */
+ uname(&utsname);
+ osmaj = osmin = ospatch = 0;
+ sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
+ kernel_version = KVERSION(osmaj, osmin, ospatch);
++#endif
+
+ fd = open("/dev/ppp", O_RDWR);
+ if (fd >= 0) {
++#if 0
+ new_style_driver = 1;
++#endif
+
+ /* XXX should get from driver */
+ driver_version = 2;
+@@ -2197,6 +2203,7 @@ int ppp_available(void)
+
+ if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
+ ok = 0;
++ return ok;
+
+ /*
+ * This is the PPP device. Validate the version of the driver at this
+@@ -2730,6 +2737,7 @@ get_pty(master_fdp, slave_fdp, slave_nam
+ }
+ #endif /* TIOCGPTN */
+
++#if 0
+ if (sfd < 0) {
+ /* the old way - scan through the pty name space */
+ for (i = 0; i < 64; ++i) {
+@@ -2748,6 +2756,7 @@ get_pty(master_fdp, slave_fdp, slave_nam
+ }
+ }
+ }
++#endif
+
+ if (sfd < 0)
+ return 0;
+--- a/pppd/plugins/pppoatm/pppoatm.c
++++ b/pppd/plugins/pppoatm/pppoatm.c
+@@ -168,14 +168,6 @@ static void disconnect_pppoatm(void)
+
+ void plugin_init(void)
+ {
+-#if defined(__linux__)
+- extern int new_style_driver; /* From sys-linux.c */
+- if (!ppp_available() && !new_style_driver)
+- fatal("Kernel doesn't support ppp_generic - "
+- "needed for PPPoATM");
+-#else
+- fatal("No PPPoATM support on this OS");
+-#endif
+ info("PPPoATM plugin_init");
+ add_options(pppoa_options);
+ }
+--- a/pppd/plugins/rp-pppoe/plugin.c
++++ b/pppd/plugins/rp-pppoe/plugin.c
+@@ -59,9 +59,6 @@ static char const RCSID[] =
+
+ char pppd_version[] = VERSION;
+
+-/* From sys-linux.c in pppd -- MUST FIX THIS! */
+-extern int new_style_driver;
+-
+ char *pppd_pppoe_service = NULL;
+ static char *acName = NULL;
+ static char *existingSession = NULL;
+@@ -371,10 +368,6 @@ PPPoEDevnameHook(char *cmd, char **argv,
+ void
+ plugin_init(void)
+ {
+- if (!ppp_available() && !new_style_driver) {
+- fatal("Linux kernel does not support PPPoE -- are you running 2.4.x?");
+- }
+-
+ add_options(Options);
+
+ info("RP-PPPoE plugin version %s compiled against pppd %s",
+--- a/pppd/plugins/pppol2tp/pppol2tp.c
++++ b/pppd/plugins/pppol2tp/pppol2tp.c
+@@ -486,12 +486,7 @@ static void pppol2tp_cleanup(void)
+
+ void plugin_init(void)
+ {
+-#if defined(__linux__)
+- extern int new_style_driver; /* From sys-linux.c */
+- if (!ppp_available() && !new_style_driver)
+- fatal("Kernel doesn't support ppp_generic - "
+- "needed for PPPoL2TP");
+-#else
++#if !defined(__linux__)
+ fatal("No PPPoL2TP support on this OS");
+ #endif
+ add_options(pppol2tp_options);
diff --git a/package/network/services/ppp/patches/401-no_record_file.patch b/package/network/services/ppp/patches/401-no_record_file.patch
new file mode 100644
index 0000000..f3c13ec
--- /dev/null
+++ b/package/network/services/ppp/patches/401-no_record_file.patch
@@ -0,0 +1,39 @@
+pppd: Remove the "record" option
+
+On many embedded systems there is not enough space to record PPP session
+information to the permanent storage, therfore remove this option.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/pppd.h
++++ b/pppd/pppd.h
+@@ -317,7 +317,6 @@ extern int holdoff; /* Dead time before
+ extern bool holdoff_specified; /* true if user gave a holdoff value */
+ extern bool notty; /* Stdin/out is not a tty */
+ extern char *pty_socket; /* Socket to connect to pty */
+-extern char *record_file; /* File to record chars sent/received */
+ extern bool sync_serial; /* Device is synchronous serial device */
+ extern int maxfail; /* Max # of unsuccessful connection attempts */
+ extern char linkname[MAXPATHLEN]; /* logical name for link */
+--- a/pppd/tty.c
++++ b/pppd/tty.c
+@@ -146,7 +146,7 @@ char *disconnect_script = NULL; /* Scrip
+ char *welcomer = NULL; /* Script to run after phys link estab. */
+ char *ptycommand = NULL; /* Command to run on other side of pty */
+ bool notty = 0; /* Stdin/out is not a tty */
+-char *record_file = NULL; /* File to record chars sent/received */
++static char *const record_file = NULL; /* File to record chars sent/received */
+ int max_data_rate; /* max bytes/sec through charshunt */
+ bool sync_serial = 0; /* Device is synchronous serial device */
+ char *pty_socket = NULL; /* Socket to connect to pty */
+@@ -202,8 +202,10 @@ option_t tty_options[] = {
+ "Send and receive over socket, arg is host:port",
+ OPT_PRIO | OPT_DEVNAM },
+
++#if 0
+ { "record", o_string, &record_file,
+ "Record characters sent/received to file", OPT_PRIO },
++#endif
+
+ { "crtscts", o_int, &crtscts,
+ "Set hardware (RTS/CTS) flow control",
diff --git a/package/network/services/ppp/patches/403-no_wtmp.patch b/package/network/services/ppp/patches/403-no_wtmp.patch
new file mode 100644
index 0000000..3c78894
--- /dev/null
+++ b/package/network/services/ppp/patches/403-no_wtmp.patch
@@ -0,0 +1,25 @@
+pppd: Disable wtmp support
+
+Many uClibc based environments lack wtmp and utmp support, therfore remove
+the code updating the wtmp information.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/sys-linux.c
++++ b/pppd/sys-linux.c
+@@ -2267,6 +2267,7 @@ int ppp_available(void)
+
+ void logwtmp (const char *line, const char *name, const char *host)
+ {
++#if 0
+ struct utmp ut, *utp;
+ pid_t mypid = getpid();
+ #if __GLIBC__ < 2
+@@ -2332,6 +2333,7 @@ void logwtmp (const char *line, const ch
+ close (wtmp);
+ }
+ #endif
++#endif
+ }
+ #endif /* HAVE_LOGWTMP */
+
diff --git a/package/network/services/ppp/patches/404-remove_obsolete_protocol_names.patch b/package/network/services/ppp/patches/404-remove_obsolete_protocol_names.patch
new file mode 100644
index 0000000..edbca76
--- /dev/null
+++ b/package/network/services/ppp/patches/404-remove_obsolete_protocol_names.patch
@@ -0,0 +1,151 @@
+pppd: Remove historical protocol names
+
+Remove a number of historical protocol entries from pppd's builtin list, this
+reduced the binary size without loss of features.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/main.c
++++ b/pppd/main.c
+@@ -882,14 +882,17 @@ struct protocol_list {
+ const char *name;
+ } protocol_list[] = {
+ { 0x21, "IP" },
++#if 0
+ { 0x23, "OSI Network Layer" },
+ { 0x25, "Xerox NS IDP" },
+ { 0x27, "DECnet Phase IV" },
+ { 0x29, "Appletalk" },
+ { 0x2b, "Novell IPX" },
++#endif
+ { 0x2d, "VJ compressed TCP/IP" },
+ { 0x2f, "VJ uncompressed TCP/IP" },
+ { 0x31, "Bridging PDU" },
++#if 0
+ { 0x33, "Stream Protocol ST-II" },
+ { 0x35, "Banyan Vines" },
+ { 0x39, "AppleTalk EDDP" },
+@@ -903,8 +906,11 @@ struct protocol_list {
+ { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
+ { 0x4b, "SNA over 802.2" },
+ { 0x4d, "SNA" },
++#endif
+ { 0x4f, "IP6 Header Compression" },
++#if 0
+ { 0x51, "KNX Bridging Data" },
++#endif
+ { 0x53, "Encryption" },
+ { 0x55, "Individual Link Encryption" },
+ { 0x57, "IPv6" },
+@@ -915,12 +921,15 @@ struct protocol_list {
+ { 0x65, "RTP IPHC Compressed non-TCP" },
+ { 0x67, "RTP IPHC Compressed UDP 8" },
+ { 0x69, "RTP IPHC Compressed RTP 8" },
++#if 0
+ { 0x6f, "Stampede Bridging" },
+ { 0x73, "MP+" },
+ { 0xc1, "NTCITS IPI" },
++#endif
+ { 0xfb, "single-link compression" },
+ { 0xfd, "Compressed Datagram" },
+ { 0x0201, "802.1d Hello Packets" },
++#if 0
+ { 0x0203, "IBM Source Routing BPDU" },
+ { 0x0205, "DEC LANBridge100 Spanning Tree" },
+ { 0x0207, "Cisco Discovery Protocol" },
+@@ -932,15 +941,19 @@ struct protocol_list {
+ { 0x0231, "Luxcom" },
+ { 0x0233, "Sigma Network Systems" },
+ { 0x0235, "Apple Client Server Protocol" },
++#endif
+ { 0x0281, "MPLS Unicast" },
+ { 0x0283, "MPLS Multicast" },
++#if 0
+ { 0x0285, "IEEE p1284.4 standard - data packets" },
+ { 0x0287, "ETSI TETRA Network Protocol Type 1" },
++#endif
+ { 0x0289, "Multichannel Flow Treatment Protocol" },
+ { 0x2063, "RTP IPHC Compressed TCP No Delta" },
+ { 0x2065, "RTP IPHC Context State" },
+ { 0x2067, "RTP IPHC Compressed UDP 16" },
+ { 0x2069, "RTP IPHC Compressed RTP 16" },
++#if 0
+ { 0x4001, "Cray Communications Control Protocol" },
+ { 0x4003, "CDPD Mobile Network Registration Protocol" },
+ { 0x4005, "Expand accelerator protocol" },
+@@ -951,8 +964,10 @@ struct protocol_list {
+ { 0x4023, "RefTek Protocol" },
+ { 0x4025, "Fibre Channel" },
+ { 0x4027, "EMIT Protocols" },
++#endif
+ { 0x405b, "Vendor-Specific Protocol (VSP)" },
+ { 0x8021, "Internet Protocol Control Protocol" },
++#if 0
+ { 0x8023, "OSI Network Layer Control Protocol" },
+ { 0x8025, "Xerox NS IDP Control Protocol" },
+ { 0x8027, "DECnet Phase IV Control Protocol" },
+@@ -961,7 +976,9 @@ struct protocol_list {
+ { 0x8031, "Bridging NCP" },
+ { 0x8033, "Stream Protocol Control Protocol" },
+ { 0x8035, "Banyan Vines Control Protocol" },
++#endif
+ { 0x803d, "Multi-Link Control Protocol" },
++#if 0
+ { 0x803f, "NETBIOS Framing Control Protocol" },
+ { 0x8041, "Cisco Systems Control Protocol" },
+ { 0x8043, "Ascom Timeplex" },
+@@ -970,18 +987,24 @@ struct protocol_list {
+ { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
+ { 0x804b, "SNA over 802.2 Control Protocol" },
+ { 0x804d, "SNA Control Protocol" },
++#endif
+ { 0x804f, "IP6 Header Compression Control Protocol" },
++#if 0
+ { 0x8051, "KNX Bridging Control Protocol" },
++#endif
+ { 0x8053, "Encryption Control Protocol" },
+ { 0x8055, "Individual Link Encryption Control Protocol" },
+ { 0x8057, "IPv6 Control Protocol" },
+ { 0x8059, "PPP Muxing Control Protocol" },
+ { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" },
++#if 0
+ { 0x806f, "Stampede Bridging Control Protocol" },
+ { 0x8073, "MP+ Control Protocol" },
+ { 0x80c1, "NTCITS IPI Control Protocol" },
++#endif
+ { 0x80fb, "Single Link Compression Control Protocol" },
+ { 0x80fd, "Compression Control Protocol" },
++#if 0
+ { 0x8207, "Cisco Discovery Protocol Control" },
+ { 0x8209, "Netcs Twin Routing" },
+ { 0x820b, "STP - Control Protocol" },
+@@ -990,24 +1013,29 @@ struct protocol_list {
+ { 0x8281, "MPLSCP" },
+ { 0x8285, "IEEE p1284.4 standard - Protocol Control" },
+ { 0x8287, "ETSI TETRA TNP1 Control Protocol" },
++#endif
+ { 0x8289, "Multichannel Flow Treatment Protocol" },
+ { 0xc021, "Link Control Protocol" },
+ { 0xc023, "Password Authentication Protocol" },
+ { 0xc025, "Link Quality Report" },
++#if 0
+ { 0xc027, "Shiva Password Authentication Protocol" },
+ { 0xc029, "CallBack Control Protocol (CBCP)" },
+ { 0xc02b, "BACP Bandwidth Allocation Control Protocol" },
+ { 0xc02d, "BAP" },
++#endif
+ { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" },
+ { 0xc081, "Container Control Protocol" },
+ { 0xc223, "Challenge Handshake Authentication Protocol" },
+ { 0xc225, "RSA Authentication Protocol" },
+ { 0xc227, "Extensible Authentication Protocol" },
++#if 0
+ { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" },
+ { 0xc26f, "Stampede Bridging Authorization Protocol" },
+ { 0xc281, "Proprietary Authentication Protocol" },
+ { 0xc283, "Proprietary Authentication Protocol" },
+ { 0xc481, "Proprietary Node ID Authentication Protocol" },
++#endif
+ { 0, NULL },
+ };
+
diff --git a/package/network/services/ppp/patches/405-no_multilink_option.patch b/package/network/services/ppp/patches/405-no_multilink_option.patch
new file mode 100644
index 0000000..e8f99e5
--- /dev/null
+++ b/package/network/services/ppp/patches/405-no_multilink_option.patch
@@ -0,0 +1,28 @@
+pppd: Support "nomp" option even if multilink support is off
+
+This patch moves the "nomp" option entry outside of the defines protecting
+the multilink specific code. The motivation is to allow "nomp" even if pppd
+does not support multilink, so that controlling programs can unconditionally
+pass it to pppd regardless of the compile time features.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/options.c
++++ b/pppd/options.c
+@@ -336,13 +336,14 @@ option_t general_options[] = {
+ "Enable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 1 },
+ { "nomultilink", o_bool, &multilink,
+ "Disable multilink operation", OPT_PRIOSUB | 0 },
+- { "nomp", o_bool, &multilink,
+- "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 },
+
+ { "bundle", o_string, &bundle_name,
+ "Bundle name for multilink", OPT_PRIO },
+ #endif /* HAVE_MULTILINK */
+
++ { "nomp", o_bool, &multilink,
++ "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 },
++
+ #ifdef PLUGIN
+ { "plugin", o_special, (void *)loadplugin,
+ "Load a plug-in module into pppd", OPT_PRIV | OPT_A2LIST },
diff --git a/package/network/services/ppp/patches/500-add-pptp-plugin.patch b/package/network/services/ppp/patches/500-add-pptp-plugin.patch
new file mode 100644
index 0000000..d984e1b
--- /dev/null
+++ b/package/network/services/ppp/patches/500-add-pptp-plugin.patch
@@ -0,0 +1,3065 @@
+--- a/configure
++++ b/configure
+@@ -195,7 +195,7 @@ if [ -d "$ksrc" ]; then
+ mkmkf $ksrc/Makedefs$compiletype Makedefs.com
+ for dir in pppd pppstats chat pppdump pppd/plugins pppd/plugins/rp-pppoe \
+ pppd/plugins/radius pppd/plugins/pppoatm \
+- pppd/plugins/pppol2tp; do
++ pppd/plugins/pppol2tp pppd/plugins/pptp ; do
+ mkmkf $dir/Makefile.$makext $dir/Makefile
+ done
+ if [ -f $ksrc/Makefile.$makext$archvariant ]; then
+--- a/pppd/plugins/Makefile.linux
++++ b/pppd/plugins/Makefile.linux
+@@ -9,7 +9,7 @@ BINDIR = $(DESTDIR)/sbin
+ MANDIR = $(DESTDIR)/share/man/man8
+ LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION)
+
+-SUBDIRS := rp-pppoe pppoatm pppol2tp
++SUBDIRS := rp-pppoe pppoatm pppol2tp pptp
+ # Uncomment the next line to include the radius authentication plugin
+ SUBDIRS += radius
+ PLUGINS := minconn.so passprompt.so passwordfd.so winbind.so
+--- /dev/null
++++ b/pppd/plugins/pptp/Makefile.linux
+@@ -0,0 +1,31 @@
++#
++# This program may be distributed according to the terms of the GNU
++# General Public License, version 2 or (at your option) any later version.
++#
++# $Id: Makefile.linux,v 1.9 2012/05/04 21:48:00 dgolle Exp $
++#***********************************************************************
++
++DESTDIR = $(INSTROOT)@DESTDIR@
++LIBDIR = $(DESTDIR)/lib/pppd/$(PPPDVERSION)
++
++PPPDVERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h)
++
++INSTALL = install
++
++COPTS=-O2 -g
++CFLAGS = $(COPTS) -I. -I../.. -I../../../include -fPIC -DPPPD_VERSION=\"$(PPPDVERSION)\"
++all: pptp.so
++
++%.o: %.c
++ $(CC) $(CFLAGS) -c -o $@ $<
++
++pptp.so: dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
++ $(CC) -o pptp.so -shared dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
++
++install: all
++ $(INSTALL) -d -m 755 $(LIBDIR)
++ $(INSTALL) -c -m 4550 pptp.so $(LIBDIR)
++
++clean:
++ rm -f *.o *.so
++
+--- /dev/null
++++ b/pppd/plugins/pptp/dirutil.c
+@@ -0,0 +1,68 @@
++/* dirutil.c ... directory utilities.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: dirutil.c,v 1.2 2003/06/17 17:25:47 reink Exp $
++ */
++
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdlib.h>
++#include "dirutil.h"
++
++/* Returned malloc'ed string representing basename */
++char *basenamex(char *pathname)
++{
++ char *dup = strdup(pathname);
++ char *ptr = strrchr(stripslash(dup), '/');
++ if (ptr == NULL) return dup;
++ ptr = strdup(ptr+1);
++ free(dup);
++ return ptr;
++}
++
++/* Return malloc'ed string representing directory name (no trailing slash) */
++char *dirnamex(char *pathname)
++{
++ char *dup = strdup(pathname);
++ char *ptr = strrchr(stripslash(dup), '/');
++ if (ptr == NULL) { free(dup); return strdup("."); }
++ if (ptr == dup && dup[0] == '/') ptr++;
++ *ptr = '\0';
++ return dup;
++}
++
++/* In-place modify a string to remove trailing slashes. Returns arg.
++ * stripslash("/") returns "/";
++ */
++char *stripslash(char *pathname) {
++ int len = strlen(pathname);
++ while (len > 1 && pathname[len - 1] == '/')
++ pathname[--len] = '\0';
++ return pathname;
++}
++
++/* ensure dirname exists, creating it if necessary. */
++int make_valid_path(char *dir, mode_t mode)
++{
++ struct stat st;
++ char *tmp = NULL, *path = stripslash(strdup(dir));
++ int retval;
++ if (stat(path, &st) == 0) { /* file exists */
++ if (S_ISDIR(st.st_mode)) { retval = 1; goto end; }
++ else { retval = 0; goto end; } /* not a directory. Oops. */
++ }
++ /* Directory doesn't exist. Let's make it. */
++ /* Make parent first. */
++ if (!make_valid_path(tmp = dirnamex(path), mode)) { retval = 0; goto end; }
++ /* Now make this 'un. */
++ if (mkdir(path, mode) < 0) { retval = 0; goto end; }
++ /* Success. */
++ retval = 1;
++
++end:
++ if (tmp != NULL) free(tmp);
++ if (path != NULL) free(path);
++ return retval;
++}
+--- /dev/null
++++ b/pppd/plugins/pptp/dirutil.h
+@@ -0,0 +1,14 @@
++/* dirutil.h ... directory utilities.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: dirutil.h,v 1.1.1.1 2000/12/23 08:19:51 scott Exp $
++ */
++
++/* Returned malloc'ed string representing basename */
++char *basenamex(char *pathname);
++/* Return malloc'ed string representing directory name (no trailing slash) */
++char *dirnamex(char *pathname);
++/* In-place modify a string to remove trailing slashes. Returns arg. */
++char *stripslash(char *pathname);
++/* ensure dirname exists, creating it if necessary. */
++int make_valid_path(char *dirname, mode_t mode);
+--- /dev/null
++++ b/pppd/plugins/pptp/orckit_quirks.c
+@@ -0,0 +1,86 @@
++/* orckit_quirks.c ...... fix quirks in orckit adsl modems
++ * mulix <mulix@actcom.co.il>
++ *
++ * $Id: orckit_quirks.c,v 1.3 2002/03/01 01:23:36 quozl Exp $
++ */
++
++#include <string.h>
++#include <sys/types.h>
++#include <netinet/in.h>
++#include "pptp_msg.h"
++#include "pptp_options.h"
++#include "pptp_ctrl.h"
++#include "util.h"
++
++
++
++/* return 0 on success, non zero otherwise */
++int
++orckit_atur3_build_hook(struct pptp_out_call_rqst* packet)
++{
++ unsigned int name_length = 10;
++
++ struct pptp_out_call_rqst fixed_packet = {
++ PPTP_HEADER_CTRL(PPTP_OUT_CALL_RQST),
++ 0, /* hton16(call->callid) */
++ 0, /* hton16(call->sernum) */
++ hton32(PPTP_BPS_MIN), hton32(PPTP_BPS_MAX),
++ hton32(PPTP_BEARER_DIGITAL), hton32(PPTP_FRAME_ANY),
++ hton16(PPTP_WINDOW), 0, hton16(name_length), 0,
++ {'R','E','L','A','Y','_','P','P','P','1',0}, {0}
++ };
++
++ if (!packet)
++ return -1;
++
++ memcpy(packet, &fixed_packet, sizeof(*packet));
++
++ return 0;
++}
++
++/* return 0 on success, non zero otherwise */
++int
++orckit_atur3_set_link_hook(struct pptp_set_link_info* packet,
++ int peer_call_id)
++{
++ struct pptp_set_link_info fixed_packet = {
++ PPTP_HEADER_CTRL(PPTP_SET_LINK_INFO),
++ hton16(peer_call_id),
++ 0,
++ 0xffffffff,
++ 0xffffffff};
++
++ if (!packet)
++ return -1;
++
++ memcpy(packet, &fixed_packet, sizeof(*packet));
++ return 0;
++}
++
++/* return 0 on success, non 0 otherwise */
++int
++orckit_atur3_start_ctrl_conn_hook(struct pptp_start_ctrl_conn* packet)
++{
++ struct pptp_start_ctrl_conn fixed_packet = {
++ {0}, /* we'll set the header later */
++ hton16(PPTP_VERSION), 0, 0,
++ hton32(PPTP_FRAME_ASYNC), hton32(PPTP_BEARER_ANALOG),
++ hton16(0) /* max channels */,
++ hton16(0x6021),
++ {'R','E','L','A','Y','_','P','P','P','1',0}, /* hostname */
++ {'M','S',' ','W','i','n',' ','N','T',0} /* vendor */
++ };
++
++ if (!packet)
++ return -1;
++
++ /* grab the header from the original packet, since we dont
++ know if this is a request or a reply */
++ memcpy(&fixed_packet.header, &packet->header, sizeof(struct pptp_header));
++
++ /* and now overwrite the full packet, effectively preserving the header */
++ memcpy(packet, &fixed_packet, sizeof(*packet));
++ return 0;
++}
++
++
+--- /dev/null
++++ b/pppd/plugins/pptp/orckit_quirks.h
+@@ -0,0 +1,27 @@
++/* orckit_quirks.h ...... fix quirks in orckit adsl modems
++ * mulix <mulix@actcom.co.il>
++ *
++ * $Id: orckit_quirks.h,v 1.2 2001/11/23 03:42:51 quozl Exp $
++ */
++
++#ifndef INC_ORCKIT_QUIRKS_H_
++#define INC_ORCKIT_QUIRKS_H_
++
++#include "pptp_options.h"
++#include "pptp_ctrl.h"
++#include "pptp_msg.h"
++
++/* return 0 on success, non zero otherwise */
++int
++orckit_atur3_build_hook(struct pptp_out_call_rqst* packt);
++
++/* return 0 on success, non zero otherwise */
++int
++orckit_atur3_set_link_hook(struct pptp_set_link_info* packet,
++ int peer_call_id);
++
++/* return 0 on success, non zero otherwise */
++int
++orckit_atur3_start_ctrl_conn_hook(struct pptp_start_ctrl_conn* packet);
++
++#endif /* INC_ORCKIT_QUIRKS_H_ */
+--- /dev/null
++++ b/pppd/plugins/pptp/pppd-pptp.8
+@@ -0,0 +1,68 @@
++.\" manual page [] for PPTP plugin for pppd 2.4
++.\" $Id: pppd-pptp.8,v 1.0 2007/10/17 13:27:17 kad Exp $
++.\" SH section heading
++.\" SS subsection heading
++.\" LP paragraph
++.\" IP indented paragraph
++.\" TP hanging label
++.TH PPPD-PPTP 8
++.SH NAME
++pptp.so \- PPTP VPN plugin for
++.BR pppd (8)
++.SH SYNOPSIS
++.B pppd
++[
++.I options
++]
++plugin pptp.so
++.SH DESCRIPTION
++.LP
++The PPTP plugin for pppd performs interaction with pptp kernel module
++and has built-in call manager (client part of PPTP).
++It pasees necessary paremeters from \fIoptions\fR into kernel module
++to configure ppp-pptp channel. If it runs in client mode, then additionally
++call manager starts up. PPTPD daemon automaticaly invokes this plugin
++in server mode and passes necessary options, so additional configuration
++is not needed.
++
++.SH OPTIONS for client mode
++The PPTP plugin introduces one additional pppd option:
++.TP
++.BI "pptp_server " server " (required)"
++Specifies ip address or hostname of pptp server.
++.TP
++.BI "pptp_window " packets " (optional)"
++The amount of sliding window size.
++Set to 0 to turn off sliding window.
++ to 3-10 for low speed connections.
++ to >10 for hi speed connections.
++Default is 50
++.TP
++.BI "pptp_phone " phone " (optional)"
++The phone string that sended to pptp server.
++.SH USAGE
++Sample configuration file:
++.nf
++plugin "pptp.so"
++pptp_server 192.168.0.1
++pptp_window 100
++name myname
++remotename pptp
++noauth
++refuse-eap
++refuse-chap
++refuse-mschap
++nobsdcomp
++nodeflate
++novj
++novjccomp
++require-mppe-128
++lcp-echo-interval 20
++lcp-echo-failure 3
++.fi
++
++.SH SEE ALSO
++.BR pppd (8) " " pptpd (8) " " pptpd.conf (5)
++
++.SH AUTHOR
++xeb xeb@mail.ru
+--- /dev/null
++++ b/pppd/plugins/pptp/pptp.c
+@@ -0,0 +1,323 @@
++/***************************************************************************
++ * Copyright (C) 2006 by Kozlov D. <xeb@mail.ru> *
++ * some cleanup done (C) 2012 by 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. *
++ ***************************************************************************/
++
++#define PPTP_VERSION "1.00"
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <sys/un.h>
++#include <netdb.h>
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <syslog.h>
++#include <unistd.h>
++#include <signal.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <sys/wait.h>
++#include <sys/ioctl.h>
++
++#include "pppd.h"
++#include "fsm.h"
++#include "lcp.h"
++#include "ipcp.h"
++#include "ccp.h"
++#include "pathnames.h"
++
++#include "pptp_callmgr.h"
++#include <net/if.h>
++#include <net/ethernet.h>
++#include <linux/if_pppox.h>
++
++#include <stdio.h>
++#include <stdlib.h>
++
++
++
++extern char** environ;
++
++char pppd_version[] = PPPD_VERSION;
++extern int new_style_driver;
++
++
++char *pptp_server = NULL;
++char *pptp_client = NULL;
++char *pptp_phone = NULL;
++int pptp_window=50;
++int pptp_sock=-1;
++struct in_addr localbind = { INADDR_NONE };
++
++static int callmgr_sock;
++static int pptp_fd;
++int call_ID;
++
++static int open_callmgr(int call_id,struct in_addr inetaddr, char *phonenr,int window);
++static void launch_callmgr(int call_is,struct in_addr inetaddr, char *phonenr,int window);
++static int get_call_id(int sock, pid_t gre, pid_t pppd, u_int16_t *peer_call_id);
++
++static option_t Options[] =
++{
++ { "pptp_server", o_string, &pptp_server,
++ "PPTP Server" },
++ { "pptp_client", o_string, &pptp_client,
++ "PPTP Client" },
++ { "pptp_sock",o_int, &pptp_sock,
++ "PPTP socket" },
++ { "pptp_phone", o_string, &pptp_phone,
++ "PPTP Phone number" },
++ { "pptp_window",o_int, &pptp_window,
++ "PPTP window" },
++ { NULL }
++};
++
++static int pptp_connect(void);
++static void pptp_disconnect(void);
++
++struct channel pptp_channel = {
++ options: Options,
++ check_options: NULL,
++ connect: &pptp_connect,
++ disconnect: &pptp_disconnect,
++ establish_ppp: &generic_establish_ppp,
++ disestablish_ppp: &generic_disestablish_ppp,
++ close: NULL,
++ cleanup: NULL
++};
++
++static int pptp_start_server(void)
++{
++ pptp_fd=pptp_sock;
++ sprintf(ppp_devnam,"pptp (%s)",pptp_client);
++
++ return pptp_fd;
++}
++static int pptp_start_client(void)
++{
++ socklen_t len;
++ struct sockaddr_pppox src_addr,dst_addr;
++ struct hostent *hostinfo;
++
++ hostinfo=gethostbyname(pptp_server);
++ if (!hostinfo)
++ {
++ error("PPTP: Unknown host %s\n", pptp_server);
++ return -1;
++ }
++ dst_addr.sa_addr.pptp.sin_addr=*(struct in_addr*)hostinfo->h_addr;
++ {
++ int sock;
++ struct sockaddr_in addr;
++ len=sizeof(addr);
++ addr.sin_addr=dst_addr.sa_addr.pptp.sin_addr;
++ addr.sin_family=AF_INET;
++ addr.sin_port=htons(1700);
++ sock=socket(AF_INET,SOCK_DGRAM,0);
++ if (connect(sock,(struct sockaddr*)&addr,sizeof(addr)))
++ {
++ close(sock);
++ error("PPTP: connect failed (%s)\n",strerror(errno));
++ return -1;
++ }
++ getsockname(sock,(struct sockaddr*)&addr,&len);
++ src_addr.sa_addr.pptp.sin_addr=addr.sin_addr;
++ close(sock);
++ }
++
++ src_addr.sa_family=AF_PPPOX;
++ src_addr.sa_protocol=PX_PROTO_PPTP;
++ src_addr.sa_addr.pptp.call_id=0;
++
++ dst_addr.sa_family=AF_PPPOX;
++ dst_addr.sa_protocol=PX_PROTO_PPTP;
++ dst_addr.sa_addr.pptp.call_id=0;
++
++ pptp_fd=socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_PPTP);
++ if (pptp_fd<0)
++ {
++ error("PPTP: failed to create PPTP socket (%s)\n",strerror(errno));
++ return -1;
++ }
++ if (bind(pptp_fd,(struct sockaddr*)&src_addr,sizeof(src_addr)))
++ {
++ close(pptp_fd);
++ error("PPTP: failed to bind PPTP socket (%s)\n",strerror(errno));
++ return -1;
++ }
++ len=sizeof(src_addr);
++ getsockname(pptp_fd,(struct sockaddr*)&src_addr,&len);
++ call_ID=src_addr.sa_addr.pptp.call_id;
++
++ do {
++ /*
++ * Open connection to call manager (Launch call manager if necessary.)
++ */
++ callmgr_sock = open_callmgr(src_addr.sa_addr.pptp.call_id,dst_addr.sa_addr.pptp.sin_addr, pptp_phone, pptp_window);
++ if (callmgr_sock<0)
++ {
++ close(pptp_fd);
++ return -1;
++ }
++ /* Exchange PIDs, get call ID */
++ } while (get_call_id(callmgr_sock, getpid(), getpid(), &dst_addr.sa_addr.pptp.call_id) < 0);
++
++ if (connect(pptp_fd,(struct sockaddr*)&dst_addr,sizeof(dst_addr)))
++ {
++ close(callmgr_sock);
++ close(pptp_fd);
++ error("PPTP: failed to connect PPTP socket (%s)\n",strerror(errno));
++ return -1;
++ }
++
++ sprintf(ppp_devnam,"pptp (%s)",pptp_server);
++
++ return pptp_fd;
++}
++static int pptp_connect(void)
++{
++ if ((!pptp_server && !pptp_client) || (pptp_server && pptp_client))
++ {
++ fatal("PPTP: unknown mode (you must specify pptp_server or pptp_client option)");
++ return -1;
++ }
++
++ if (pptp_server) return pptp_start_client();
++ return pptp_start_server();
++}
++
++static void pptp_disconnect(void)
++{
++ if (pptp_server) close(callmgr_sock);
++ close(pptp_fd);
++}
++
++static int open_callmgr(int call_id,struct in_addr inetaddr, char *phonenr,int window)
++{
++ /* Try to open unix domain socket to call manager. */
++ struct sockaddr_un where;
++ const int NUM_TRIES = 3;
++ int i, fd;
++ pid_t pid;
++ int status;
++ /* Open socket */
++ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
++ {
++ fatal("Could not create unix domain socket: %s", strerror(errno));
++ }
++ /* Make address */
++ callmgr_name_unixsock(&where, inetaddr, localbind);
++ for (i = 0; i < NUM_TRIES; i++)
++ {
++ if (connect(fd, (struct sockaddr *) &where, sizeof(where)) < 0)
++ {
++ /* couldn't connect. We'll have to launch this guy. */
++
++ unlink (where.sun_path);
++
++ /* fork and launch call manager process */
++ switch (pid = fork())
++ {
++ case -1: /* failure */
++ fatal("fork() to launch call manager failed.");
++ case 0: /* child */
++ {
++ /* close the pty and gre in the call manager */
++ close(fd);
++ close(pptp_fd);
++ launch_callmgr(call_id,inetaddr,phonenr,window);
++ }
++ default: /* parent */
++ waitpid(pid, &status, 0);
++ if (status!= 0)
++ {
++ close(fd);
++ error("Call manager exited with error %d", status);
++ return -1;
++ }
++ break;
++ }
++ sleep(1);
++ }
++ else return fd;
++ }
++ close(fd);
++ error("Could not launch call manager after %d tries.", i);
++ return -1; /* make gcc happy */
++}
++
++/*** call the call manager main ***********************************************/
++static void launch_callmgr(int call_id,struct in_addr inetaddr, char *phonenr,int window)
++{
++ dbglog("pptp: call manager for %s\n", inet_ntoa(inetaddr));
++ dbglog("window size:\t%d\n",window);
++ if (phonenr) dbglog("phone number:\t'%s'\n",phonenr);
++ dbglog("call id:\t%d\n",call_id);
++ exit(callmgr_main(inetaddr, phonenr, window, call_id));
++}
++
++/*** exchange data with the call manager *************************************/
++/* XXX need better error checking XXX */
++static int get_call_id(int sock, pid_t gre, pid_t pppd,
++ u_int16_t *peer_call_id)
++{
++ u_int16_t m_call_id, m_peer_call_id;
++ /* write pid's to socket */
++ /* don't bother with network byte order, because pid's are meaningless
++ * outside the local host.
++ */
++ int rc;
++ rc = write(sock, &gre, sizeof(gre));
++ if (rc != sizeof(gre))
++ return -1;
++ rc = write(sock, &pppd, sizeof(pppd));
++ if (rc != sizeof(pppd))
++ return -1;
++ rc = read(sock, &m_call_id, sizeof(m_call_id));
++ if (rc != sizeof(m_call_id))
++ return -1;
++ rc = read(sock, &m_peer_call_id, sizeof(m_peer_call_id));
++ if (rc != sizeof(m_peer_call_id))
++ return -1;
++ /*
++ * XXX FIXME ... DO ERROR CHECKING & TIME-OUTS XXX
++ * (Rhialto: I am assuming for now that timeouts are not relevant
++ * here, because the read and write calls would return -1 (fail) when
++ * the peer goes away during the process. We know it is (or was)
++ * running because the connect() call succeeded.)
++ * (James: on the other hand, if the route to the peer goes away, we
++ * wouldn't get told by read() or write() for quite some time.)
++ */
++ *peer_call_id = m_peer_call_id;
++ return 0;
++}
++
++void plugin_init(void)
++{
++ add_options(Options);
++
++ info("PPTP plugin version %s", PPTP_VERSION);
++
++ the_channel = &pptp_channel;
++ modem = 0;
++}
+--- /dev/null
++++ b/pppd/plugins/pptp/pptp_callmgr.c
+@@ -0,0 +1,381 @@
++/* pptp_callmgr.c ... Call manager for PPTP connections.
++ * Handles TCP port 1723 protocol.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: pptp_callmgr.c,v 1.20 2005/03/31 07:42:39 quozl Exp $
++ */
++#include <signal.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <sys/un.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++#include <setjmp.h>
++#include <stdio.h>
++#include <errno.h>
++#include "pptp_callmgr.h"
++#include "pptp_ctrl.h"
++#include "pptp_msg.h"
++#include "dirutil.h"
++#include "vector.h"
++#include "util.h"
++#include "pppd.h"
++
++extern struct in_addr localbind; /* from pptp.c */
++extern int call_ID;
++
++int open_inetsock(struct in_addr inetaddr);
++int open_unixsock(struct in_addr inetaddr);
++void close_inetsock(int fd, struct in_addr inetaddr);
++void close_unixsock(int fd, struct in_addr inetaddr);
++
++sigjmp_buf callmgr_env;
++
++void callmgr_sighandler(int sig) {
++ /* TODO: according to signal(2), siglongjmp() is unsafe used here */
++ siglongjmp (callmgr_env, 1);
++}
++
++void callmgr_do_nothing(int sig) {
++ /* do nothing signal handler */
++}
++
++struct local_callinfo {
++ int unix_sock;
++ pid_t pid[2];
++};
++
++struct local_conninfo {
++ VECTOR * call_list;
++ fd_set * call_set;
++};
++
++/* Call callback */
++void call_callback(PPTP_CONN *conn, PPTP_CALL *call, enum call_state state)
++{
++ struct local_callinfo *lci;
++ struct local_conninfo *conninfo;
++ u_int16_t call_id[2];
++ switch(state) {
++ case CALL_OPEN_DONE:
++ /* okey dokey. This means that the call_id and peer_call_id are
++ * now valid, so lets send them on to our friends who requested
++ * this call. */
++ lci = pptp_call_closure_get(conn, call); assert(lci != NULL);
++ pptp_call_get_ids(conn, call, &call_id[0], &call_id[1]);
++ write(lci->unix_sock, &call_id, sizeof(call_id));
++ /* Our duty to the fatherland is now complete. */
++ break;
++ case CALL_OPEN_FAIL:
++ case CALL_CLOSE_RQST:
++ case CALL_CLOSE_DONE:
++ /* don't need to do anything here, except make sure tables
++ * are sync'ed */
++ dbglog("Closing connection (call state)");
++ conninfo = pptp_conn_closure_get(conn);
++ lci = pptp_call_closure_get(conn, call);
++ assert(lci != NULL && conninfo != NULL);
++ if (vector_contains(conninfo->call_list, lci->unix_sock)) {
++ vector_remove(conninfo->call_list, lci->unix_sock);
++ close(lci->unix_sock);
++ FD_CLR(lci->unix_sock, conninfo->call_set);
++ }
++ break;
++ default:
++ dbglog("Unhandled call callback state [%d].", (int) state);
++ break;
++ }
++}
++
++/******************************************************************************
++ * NOTE ABOUT 'VOLATILE':
++ * several variables here get a volatile qualifier to silence warnings
++ * from older (before 3.0) gccs. if the longjmp stuff is removed,
++ * the volatile qualifiers should be removed as well.
++ *****************************************************************************/
++
++/*** Call Manager *************************************************************/
++int callmgr_main(struct in_addr inetaddr, char phonenr[], int window, int pcallid)
++{
++ int inet_sock, unix_sock;
++ fd_set call_set;
++ PPTP_CONN * conn;
++ VECTOR * call_list;
++ int max_fd = 0;
++ volatile int first = 1;
++ int retval;
++ int i;
++ if (pcallid>0) call_ID=pcallid;
++
++ /* Step 1: Open sockets. */
++ if ((inet_sock = open_inetsock(inetaddr)) < 0)
++ fatal("Could not open control connection to %s", inet_ntoa(inetaddr));
++ dbglog("control connection");
++ if ((unix_sock = open_unixsock(inetaddr)) < 0)
++ fatal("Could not open unix socket for %s", inet_ntoa(inetaddr));
++ /* Step 1b: FORK and return status to calling process. */
++ dbglog("unix_sock");
++
++ switch (fork()) {
++ case 0: /* child. stick around. */
++ break;
++ case -1: /* failure. Fatal. */
++ fatal("Could not fork.");
++ default: /* Parent. Return status to caller. */
++ exit(0);
++ }
++ /* re-open stderr as /dev/null to release it */
++ file2fd("/dev/null", "wb", STDERR_FILENO);
++ /* Step 1c: Clean up unix socket on TERM */
++ if (sigsetjmp(callmgr_env, 1) != 0)
++ goto cleanup;
++ signal(SIGINT, callmgr_sighandler);
++ signal(SIGTERM, callmgr_sighandler);
++ signal(SIGPIPE, callmgr_do_nothing);
++ signal(SIGUSR1, callmgr_do_nothing); /* signal state change
++ wake up accept */
++ /* Step 2: Open control connection and register callback */
++ if ((conn = pptp_conn_open(inet_sock, 1, NULL/* callback */)) == NULL) {
++ close(unix_sock); close(inet_sock); fatal("Could not open connection.");
++ }
++ FD_ZERO(&call_set);
++ call_list = vector_create();
++ {
++ struct local_conninfo *conninfo = malloc(sizeof(*conninfo));
++ if (conninfo == NULL) {
++ close(unix_sock); close(inet_sock); fatal("No memory.");
++ }
++ conninfo->call_list = call_list;
++ conninfo->call_set = &call_set;
++ pptp_conn_closure_put(conn, conninfo);
++ }
++ if (sigsetjmp(callmgr_env, 1) != 0) goto shutdown;
++ /* Step 3: Get FD_SETs */
++ max_fd = unix_sock;
++ do {
++ int rc;
++ fd_set read_set = call_set, write_set;
++ FD_ZERO (&write_set);
++ if (pptp_conn_established(conn)) {
++ FD_SET (unix_sock, &read_set);
++ if (unix_sock > max_fd) max_fd = unix_sock;
++ }
++ pptp_fd_set(conn, &read_set, &write_set, &max_fd);
++ for (; max_fd > 0 ; max_fd--) {
++ if (FD_ISSET (max_fd, &read_set) ||
++ FD_ISSET (max_fd, &write_set))
++ break;
++ }
++ /* Step 4: Wait on INET or UNIX event */
++ if ((rc = select(max_fd + 1, &read_set, &write_set, NULL, NULL)) <0) {
++ if (errno == EBADF) break;
++ /* a signal or somesuch. */
++ continue;
++ }
++ /* Step 5a: Handle INET events */
++ rc = pptp_dispatch(conn, &read_set, &write_set);
++ if (rc < 0)
++ break;
++ /* Step 5b: Handle new connection to UNIX socket */
++ if (FD_ISSET(unix_sock, &read_set)) {
++ /* New call! */
++ struct sockaddr_un from;
++ int len = sizeof(from);
++ PPTP_CALL * call;
++ struct local_callinfo *lci;
++ int s;
++ /* Accept the socket */
++ FD_CLR (unix_sock, &read_set);
++ if ((s = accept(unix_sock, (struct sockaddr *) &from, &len)) < 0) {
++ warn("Socket not accepted: %s", strerror(errno));
++ goto skip_accept;
++ }
++ /* Allocate memory for local call information structure. */
++ if ((lci = malloc(sizeof(*lci))) == NULL) {
++ warn("Out of memory."); close(s); goto skip_accept;
++ }
++ lci->unix_sock = s;
++ /* Give the initiator time to write the PIDs while we open
++ * the call */
++ call = pptp_call_open(conn, call_ID,call_callback, phonenr,window);
++ /* Read and store the associated pids */
++ read(s, &lci->pid[0], sizeof(lci->pid[0]));
++ read(s, &lci->pid[1], sizeof(lci->pid[1]));
++ /* associate the local information with the call */
++ pptp_call_closure_put(conn, call, (void *) lci);
++ /* The rest is done on callback. */
++ /* Keep alive; wait for close */
++ retval = vector_insert(call_list, s, call); assert(retval);
++ if (s > max_fd) max_fd = s;
++ FD_SET(s, &call_set);
++ first = 0;
++ }
++skip_accept: /* Step 5c: Handle socket close */
++ for (i = 0; i < max_fd + 1; i++)
++ if (FD_ISSET(i, &read_set)) {
++ /* close it */
++ PPTP_CALL * call;
++ retval = vector_search(call_list, i, &call);
++ if (retval) {
++ struct local_callinfo *lci =
++ pptp_call_closure_get(conn, call);
++ dbglog("Closing connection (unhandled)");
++ free(lci);
++ /* soft shutdown. Callback will do hard shutdown later */
++ pptp_call_close(conn, call);
++ vector_remove(call_list, i);
++ }
++ FD_CLR(i, &call_set);
++ close(i);
++ }
++ } while (vector_size(call_list) > 0 || first);
++shutdown:
++ {
++ int rc;
++ fd_set read_set, write_set;
++ struct timeval tv;
++ signal(SIGINT, callmgr_do_nothing);
++ signal(SIGTERM, callmgr_do_nothing);
++ /* warn("Shutdown"); */
++ /* kill all open calls */
++ for (i = 0; i < vector_size(call_list); i++) {
++ PPTP_CALL *call = vector_get_Nth(call_list, i);
++ dbglog("Closing connection (shutdown)");
++ pptp_call_close(conn, call);
++ }
++ /* attempt to dispatch these messages */
++ FD_ZERO(&read_set);
++ FD_ZERO(&write_set);
++ pptp_fd_set(conn, &read_set, &write_set, &max_fd);
++ tv.tv_sec = 0;
++ tv.tv_usec = 0;
++ select(max_fd + 1, &read_set, &write_set, NULL, &tv);
++ rc = pptp_dispatch(conn, &read_set, &write_set);
++ if (rc > 0) {
++ /* wait for a respond, a timeout because there might not be one */
++ FD_ZERO(&read_set);
++ FD_ZERO(&write_set);
++ pptp_fd_set(conn, &read_set, &write_set, &max_fd);
++ tv.tv_sec = 2;
++ tv.tv_usec = 0;
++ select(max_fd + 1, &read_set, &write_set, NULL, &tv);
++ rc = pptp_dispatch(conn, &read_set, &write_set);
++ if (rc > 0) {
++ if (i > 0) sleep(2);
++ /* no more open calls. Close the connection. */
++ pptp_conn_close(conn, PPTP_STOP_LOCAL_SHUTDOWN);
++ /* wait for a respond, a timeout because there might not be one */
++ FD_ZERO(&read_set);
++ FD_ZERO(&write_set);
++ pptp_fd_set(conn, &read_set, &write_set, &max_fd);
++ tv.tv_sec = 2;
++ tv.tv_usec = 0;
++ select(max_fd + 1, &read_set, &write_set, NULL, &tv);
++ pptp_dispatch(conn, &read_set, &write_set);
++ if (rc > 0) sleep(2);
++ }
++ }
++ /* with extreme prejudice */
++ pptp_conn_destroy(conn);
++ vector_destroy(call_list);
++ }
++cleanup:
++ signal(SIGINT, callmgr_do_nothing);
++ signal(SIGTERM, callmgr_do_nothing);
++ close_inetsock(inet_sock, inetaddr);
++ close_unixsock(unix_sock, inetaddr);
++ return 0;
++}
++
++/*** open_inetsock ************************************************************/
++int open_inetsock(struct in_addr inetaddr)
++{
++ struct sockaddr_in dest, src;
++ int s;
++ dest.sin_family = AF_INET;
++ dest.sin_port = htons(PPTP_PORT);
++ dest.sin_addr = inetaddr;
++ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
++ warn("socket: %s", strerror(errno));
++ return s;
++ }
++ if (localbind.s_addr != INADDR_NONE) {
++ bzero(&src, sizeof(src));
++ src.sin_family = AF_INET;
++ src.sin_addr = localbind;
++ if (bind(s, (struct sockaddr *) &src, sizeof(src)) != 0) {
++ warn("bind: %s", strerror(errno));
++ close(s); return -1;
++ }
++ }
++ if (connect(s, (struct sockaddr *) &dest, sizeof(dest)) < 0) {
++ warn("connect: %s", strerror(errno));
++ close(s); return -1;
++ }
++ return s;
++}
++
++/*** open_unixsock ************************************************************/
++int open_unixsock(struct in_addr inetaddr)
++{
++ struct sockaddr_un where;
++ struct stat st;
++ char *dir;
++ int s;
++ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
++ warn("socket: %s", strerror(errno));
++ return s;
++ }
++ callmgr_name_unixsock( &where, inetaddr, localbind);
++ if (stat(where.sun_path, &st) >= 0)
++ {
++ warn("Call manager for %s is already running.", inet_ntoa(inetaddr));
++ close(s); return -1;
++ }
++ /* Make sure path is valid. */
++ dir = dirnamex(where.sun_path);
++ if (!make_valid_path(dir, 0770))
++ fatal("Could not make path to %s: %s", where.sun_path, strerror(errno));
++ free(dir);
++ if (bind(s, (struct sockaddr *) &where, sizeof(where)) < 0) {
++ warn("bind: %s", strerror(errno));
++ close(s); return -1;
++ }
++ chmod(where.sun_path, 0777);
++ listen(s, 127);
++ return s;
++}
++
++/*** close_inetsock ***********************************************************/
++void close_inetsock(int fd, struct in_addr inetaddr)
++{
++ close(fd);
++}
++
++/*** close_unixsock ***********************************************************/
++void close_unixsock(int fd, struct in_addr inetaddr)
++{
++ struct sockaddr_un where;
++ close(fd);
++ callmgr_name_unixsock(&where, inetaddr, localbind);
++ unlink(where.sun_path);
++}
++
++/*** make a unix socket address ***********************************************/
++void callmgr_name_unixsock(struct sockaddr_un *where,
++ struct in_addr inetaddr,
++ struct in_addr localbind)
++{
++ char localaddr[16], remoteaddr[16];
++ where->sun_family = AF_UNIX;
++ strncpy(localaddr, inet_ntoa(localbind), 16);
++ strncpy(remoteaddr, inet_ntoa(inetaddr), 16);
++ snprintf(where->sun_path, sizeof(where->sun_path),
++ PPTP_SOCKET_PREFIX "%s:%i", remoteaddr,call_ID);
++}
+--- /dev/null
++++ b/pppd/plugins/pptp/pptp_callmgr.h
+@@ -0,0 +1,17 @@
++/* pptp_callmgr.h ... Call manager for PPTP connections.
++ * Handles TCP port 1723 protocol.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: pptp_callmgr.h,v 1.3 2003/02/17 00:22:17 quozl Exp $
++ */
++
++#define PPTP_SOCKET_PREFIX "/var/run/pptp/"
++
++int callmgr_main(struct in_addr inetaddr,
++ char phonenr[],
++ int window,
++ int pcallid);
++
++void callmgr_name_unixsock(struct sockaddr_un *where,
++ struct in_addr inetaddr,
++ struct in_addr localbind);
+--- /dev/null
++++ b/pppd/plugins/pptp/pptp_ctrl.c
+@@ -0,0 +1,1077 @@
++/* pptp_ctrl.c ... handle PPTP control connection.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: pptp_ctrl.c,v 1.31 2005/03/31 07:42:39 quozl Exp $
++ */
++
++#include <errno.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <assert.h>
++#include <signal.h>
++#include <string.h>
++#include <ctype.h>
++#include <fcntl.h>
++#include "pptp_msg.h"
++#include "pptp_ctrl.h"
++#include "pptp_options.h"
++#include "vector.h"
++#include "util.h"
++#include "pptp_quirks.h"
++
++/* BECAUSE OF SIGNAL LIMITATIONS, EACH PROCESS CAN ONLY MANAGE ONE
++ * CONNECTION. SO THIS 'PPTP_CONN' STRUCTURE IS A BIT MISLEADING.
++ * WE'LL KEEP CONNECTION-SPECIFIC INFORMATION IN THERE ANYWAY (AS
++ * OPPOSED TO USING GLOBAL VARIABLES), BUT BEWARE THAT THE ENTIRE
++ * UNIX SIGNAL-HANDLING SEMANTICS WOULD HAVE TO CHANGE (OR THE
++ * TIME-OUT CODE DRASTICALLY REWRITTEN) BEFORE YOU COULD DO A
++ * PPTP_CONN_OPEN MORE THAN ONCE PER PROCESS AND GET AWAY WITH IT.
++ */
++
++/* This structure contains connection-specific information that the
++ * signal handler needs to see. Thus, it needs to be in a global
++ * variable. If you end up using pthreads or something (why not
++ * just processes?), this would have to be placed in a thread-specific
++ * data area, using pthread_get|set_specific, etc., so I've
++ * conveniently encapsulated it for you.
++ * [linux threads will have to support thread-specific signals
++ * before this would work at all, which, as of this writing
++ * (linux-threads v0.6, linux kernel 2.1.72), it does not.]
++ */
++
++/* Globals */
++
++/* control the number of times echo packets will be logged */
++static int nlogecho = 10;
++
++static struct thread_specific {
++ struct sigaction old_sigaction; /* evil signals */
++ PPTP_CONN * conn;
++} global;
++
++#define INITIAL_BUFSIZE 512 /* initial i/o buffer size. */
++
++struct PPTP_CONN {
++ int inet_sock;
++ /* Connection States */
++ enum {
++ CONN_IDLE, CONN_WAIT_CTL_REPLY, CONN_WAIT_STOP_REPLY, CONN_ESTABLISHED
++ } conn_state; /* on startup: CONN_IDLE */
++ /* Keep-alive states */
++ enum {
++ KA_NONE, KA_OUTSTANDING
++ } ka_state; /* on startup: KA_NONE */
++ /* Keep-alive ID; monotonically increasing (watch wrap-around!) */
++ u_int32_t ka_id; /* on startup: 1 */
++ /* Other properties. */
++ u_int16_t version;
++ u_int16_t firmware_rev;
++ u_int8_t hostname[64], vendor[64];
++ /* XXX these are only PNS properties, currently XXX */
++ /* Call assignment information. */
++ u_int16_t call_serial_number;
++ VECTOR *call;
++ void * closure;
++ pptp_conn_cb callback;
++ /******* IO buffers ******/
++ char * read_buffer, *write_buffer;
++ size_t read_alloc, write_alloc;
++ size_t read_size, write_size;
++};
++
++struct PPTP_CALL {
++ /* Call properties */
++ enum {
++ PPTP_CALL_PAC, PPTP_CALL_PNS
++ } call_type;
++ union {
++ enum pptp_pac_state {
++ PAC_IDLE, PAC_WAIT_REPLY, PAC_ESTABLISHED, PAC_WAIT_CS_ANS
++ } pac;
++ enum pptp_pns_state {
++ PNS_IDLE, PNS_WAIT_REPLY, PNS_ESTABLISHED, PNS_WAIT_DISCONNECT
++ } pns;
++ } state;
++ u_int16_t call_id, peer_call_id;
++ u_int16_t sernum;
++ u_int32_t speed;
++ /* For user data: */
++ pptp_call_cb callback;
++ void * closure;
++};
++
++
++/* PPTP error codes: ----------------------------------------------*/
++
++/* (General Error Codes) */
++static const struct {
++ const char *name, *desc;
++} pptp_general_errors[] = {
++#define PPTP_GENERAL_ERROR_NONE 0
++ { "(None)", "No general error" },
++#define PPTP_GENERAL_ERROR_NOT_CONNECTED 1
++ { "(Not-Connected)", "No control connection exists yet for this "
++ "PAC-PNS pair" },
++#define PPTP_GENERAL_ERROR_BAD_FORMAT 2
++ { "(Bad-Format)", "Length is wrong or Magic Cookie value is incorrect" },
++#define PPTP_GENERAL_ERROR_BAD_VALUE 3
++ { "(Bad-Value)", "One of the field values was out of range or "
++ "reserved field was non-zero" },
++#define PPTP_GENERAL_ERROR_NO_RESOURCE 4
++ { "(No-Resource)", "Insufficient resources to handle this command now" },
++#define PPTP_GENERAL_ERROR_BAD_CALLID 5
++ { "(Bad-Call ID)", "The Call ID is invalid in this context" },
++#define PPTP_GENERAL_ERROR_PAC_ERROR 6
++ { "(PAC-Error)", "A generic vendor-specific error occured in the PAC" }
++};
++
++#define MAX_GENERAL_ERROR ( sizeof(pptp_general_errors) / \
++ sizeof(pptp_general_errors[0]) - 1)
++
++/* Outgoing Call Reply Result Codes */
++static const char *pptp_out_call_reply_result[] = {
++/* 0 */ "Unknown Result Code",
++/* 1 */ "Connected",
++/* 2 */ "General Error",
++/* 3 */ "No Carrier Detected",
++/* 4 */ "Busy Signal",
++/* 5 */ "No Dial Tone",
++/* 6 */ "Time Out",
++/* 7 */ "Not Accepted, Call is administratively prohibited" };
++
++#define MAX_OUT_CALL_REPLY_RESULT 7
++
++/* Call Disconnect Notify Result Codes */
++static const char *pptp_call_disc_ntfy[] = {
++/* 0 */ "Unknown Result Code",
++/* 1 */ "Lost Carrier",
++/* 2 */ "General Error",
++/* 3 */ "Administrative Shutdown",
++/* 4 */ "(your) Request" };
++
++#define MAX_CALL_DISC_NTFY 4
++
++/* Call Disconnect Notify Result Codes */
++static const char *pptp_start_ctrl_conn_rply[] = {
++/* 0 */ "Unknown Result Code",
++/* 1 */ "Successful Channel Establishment",
++/* 2 */ "General Error",
++/* 3 */ "Command Channel Already Exists",
++/* 4 */ "Requester is not Authorized" };
++
++#define MAX_START_CTRL_CONN_REPLY 4
++
++/* timing options */
++int idle_wait = PPTP_TIMEOUT;
++int max_echo_wait = PPTP_TIMEOUT;
++
++/* Local prototypes */
++static void pptp_reset_timer(void);
++static void pptp_handle_timer();
++/* Write/read as much as we can without blocking. */
++int pptp_write_some(PPTP_CONN * conn);
++int pptp_read_some(PPTP_CONN * conn);
++/* Make valid packets from read_buffer */
++int pptp_make_packet(PPTP_CONN * conn, void **buf, size_t *size);
++/* Add packet to write_buffer */
++int pptp_send_ctrl_packet(PPTP_CONN * conn, void * buffer, size_t size);
++/* Dispatch packets (general) */
++int pptp_dispatch_packet(PPTP_CONN * conn, void * buffer, size_t size);
++/* Dispatch packets (control messages) */
++int ctrlp_disp(PPTP_CONN * conn, void * buffer, size_t size);
++/* Set link info, for pptp servers that need it.
++ this is a noop, unless the user specified a quirk and
++ there's a set_link hook defined in the quirks table
++ for that quirk */
++void pptp_set_link(PPTP_CONN * conn, int peer_call_id);
++
++/*** log error information in control packets *********************************/
++static void ctrlp_error( int result, int error, int cause,
++ const char *result_text[], int max_result)
++{
++ if( cause >= 0)
++ warn("Result code is %d '%s'. Error code is %d, Cause code is %d",
++ result, result_text[result <= max_result ? result : 0], error,
++ cause );
++ else
++ warn("Reply result code is %d '%s'. Error code is %d",
++ result, result_text[result <= max_result ? result : 0], error);
++ if ((error > 0) && (error <= MAX_GENERAL_ERROR)){
++ if( result != PPTP_RESULT_GENERAL_ERROR )
++ warn("Result code is something else then \"general error\", "
++ "so the following error is probably bogus.");
++ warn("Error is '%s', Error message: '%s'",
++ pptp_general_errors[error].name,
++ pptp_general_errors[error].desc);
++ }
++}
++
++static const char *ctrl_msg_types[] = {
++ "invalid control message type",
++/* (Control Connection Management) */
++ "Start-Control-Connection-Request", /* 1 */
++ "Start-Control-Connection-Reply", /* 2 */
++ "Stop-Control-Connection-Request", /* 3 */
++ "Stop-Control-Connection-Reply", /* 4 */
++ "Echo-Request", /* 5 */
++ "Echo-Reply", /* 6 */
++/* (Call Management) */
++ "Outgoing-Call-Request", /* 7 */
++ "Outgoing-Call-Reply", /* 8 */
++ "Incoming-Call-Request", /* 9 */
++ "Incoming-Call-Reply", /* 10 */
++ "Incoming-Call-Connected", /* 11 */
++ "Call-Clear-Request", /* 12 */
++ "Call-Disconnect-Notify", /* 13 */
++/* (Error Reporting) */
++ "WAN-Error-Notify", /* 14 */
++/* (PPP Session Control) */
++ "Set-Link-Info" /* 15 */
++};
++#define MAX_CTRLMSG_TYPE 15
++
++/*** report a sent packet ****************************************************/
++static void ctrlp_rep( void * buffer, int size, int isbuff)
++{
++ struct pptp_header *packet = buffer;
++ unsigned int type;
++ if(size < sizeof(struct pptp_header)) return;
++ type = ntoh16(packet->ctrl_type);
++ /* FIXME: do not report sending echo requests as long as they are
++ * sent in a signal handler. This may dead lock as the syslog call
++ * is not reentrant */
++ if( type == PPTP_ECHO_RQST ) return;
++ /* don't keep reporting sending of echo's */
++ if( (type == PPTP_ECHO_RQST || type == PPTP_ECHO_RPLY) && nlogecho <= 0 ) return;
++ dbglog("%s control packet type is %d '%s'\n",isbuff ? "Buffered" : "Sent",
++ type, ctrl_msg_types[type <= MAX_CTRLMSG_TYPE ? type : 0]);
++
++}
++
++
++
++/* Open new pptp_connection. Returns NULL on failure. */
++PPTP_CONN * pptp_conn_open(int inet_sock, int isclient, pptp_conn_cb callback)
++{
++ PPTP_CONN *conn;
++ /* Allocate structure */
++ if ((conn = malloc(sizeof(*conn))) == NULL) return NULL;
++ if ((conn->call = vector_create()) == NULL) { free(conn); return NULL; }
++ /* Initialize */
++ conn->inet_sock = inet_sock;
++ conn->conn_state = CONN_IDLE;
++ conn->ka_state = KA_NONE;
++ conn->ka_id = 1;
++ conn->call_serial_number = 0;
++ conn->callback = callback;
++ /* Create I/O buffers */
++ conn->read_size = conn->write_size = 0;
++ conn->read_alloc = conn->write_alloc = INITIAL_BUFSIZE;
++ conn->read_buffer =
++ malloc(sizeof(*(conn->read_buffer)) * conn->read_alloc);
++ conn->write_buffer =
++ malloc(sizeof(*(conn->write_buffer)) * conn->write_alloc);
++ if (conn->read_buffer == NULL || conn->write_buffer == NULL) {
++ if (conn->read_buffer != NULL) free(conn->read_buffer);
++ if (conn->write_buffer != NULL) free(conn->write_buffer);
++ vector_destroy(conn->call); free(conn); return NULL;
++ }
++ /* Make this socket non-blocking. */
++ fcntl(conn->inet_sock, F_SETFL, O_NONBLOCK);
++ /* Request connection from server, if this is a client */
++ if (isclient) {
++ struct pptp_start_ctrl_conn packet = {
++ PPTP_HEADER_CTRL(PPTP_START_CTRL_CONN_RQST),
++ hton16(PPTP_VERSION), 0, 0,
++ hton32(PPTP_FRAME_CAP), hton32(PPTP_BEARER_CAP),
++ hton16(PPTP_MAX_CHANNELS), hton16(PPTP_FIRMWARE_VERSION),
++ PPTP_HOSTNAME, PPTP_VENDOR
++ };
++ /* fix this packet, if necessary */
++ int idx, rc;
++ idx = get_quirk_index();
++ if (idx != -1 && pptp_fixups[idx].start_ctrl_conn) {
++ if ((rc = pptp_fixups[idx].start_ctrl_conn(&packet)))
++ warn("calling the start_ctrl_conn hook failed (%d)", rc);
++ }
++ if (pptp_send_ctrl_packet(conn, &packet, sizeof(packet)))
++ conn->conn_state = CONN_WAIT_CTL_REPLY;
++ else
++ return NULL; /* could not send initial start request. */
++ }
++ /* Set up interval/keep-alive timer */
++ /* First, register handler for SIGALRM */
++ sigpipe_create();
++ sigpipe_assign(SIGALRM);
++ global.conn = conn;
++ /* Reset event timer */
++ pptp_reset_timer();
++ /* all done. */
++ return conn;
++}
++
++int pptp_conn_established(PPTP_CONN *conn) {
++ return (conn->conn_state == CONN_ESTABLISHED);
++}
++
++/* This currently *only* works for client call requests.
++ * We need to do something else to allocate calls for incoming requests.
++ */
++PPTP_CALL * pptp_call_open(PPTP_CONN * conn, int call_id,pptp_call_cb callback,
++ char *phonenr,int window)
++{
++ PPTP_CALL * call;
++ int idx, rc;
++ /* Send off the call request */
++ struct pptp_out_call_rqst packet = {
++ PPTP_HEADER_CTRL(PPTP_OUT_CALL_RQST),
++ 0,0, /*call_id, sernum */
++ hton32(PPTP_BPS_MIN), hton32(PPTP_BPS_MAX),
++ hton32(PPTP_BEARER_CAP), hton32(PPTP_FRAME_CAP),
++ hton16(window), 0, 0, 0, {0}, {0}
++ };
++ assert(conn && conn->call);
++ assert(conn->conn_state == CONN_ESTABLISHED);
++ /* Assign call id */
++ if (!call_id && !vector_scan(conn->call, 0, PPTP_MAX_CHANNELS - 1, &call_id))
++ /* no more calls available! */
++ return NULL;
++ /* allocate structure. */
++ if ((call = malloc(sizeof(*call))) == NULL) return NULL;
++ /* Initialize call structure */
++ call->call_type = PPTP_CALL_PNS;
++ call->state.pns = PNS_IDLE;
++ call->call_id = (u_int16_t) call_id;
++ call->sernum = conn->call_serial_number++;
++ call->callback = callback;
++ call->closure = NULL;
++ packet.call_id = htons(call->call_id);
++ packet.call_sernum = htons(call->sernum);
++ /* if we have a quirk, build a new packet to fit it */
++ idx = get_quirk_index();
++ if (idx != -1 && pptp_fixups[idx].out_call_rqst_hook) {
++ if ((rc = pptp_fixups[idx].out_call_rqst_hook(&packet)))
++ warn("calling the out_call_rqst hook failed (%d)", rc);
++ }
++ /* fill in the phone number if it was specified */
++ if (phonenr) {
++ strncpy(packet.phone_num, phonenr, sizeof(packet.phone_num));
++ packet.phone_len = strlen(phonenr);
++ if( packet.phone_len > sizeof(packet.phone_num))
++ packet.phone_len = sizeof(packet.phone_num);
++ packet.phone_len = hton16 (packet.phone_len);
++ }
++ if (pptp_send_ctrl_packet(conn, &packet, sizeof(packet))) {
++ pptp_reset_timer();
++ call->state.pns = PNS_WAIT_REPLY;
++ /* and add it to the call vector */
++ vector_insert(conn->call, call_id, call);
++ return call;
++ } else { /* oops, unsuccessful. Deallocate. */
++ free(call);
++ return NULL;
++ }
++}
++
++/*** pptp_call_close **********************************************************/
++void pptp_call_close(PPTP_CONN * conn, PPTP_CALL * call)
++{
++ struct pptp_call_clear_rqst rqst = {
++ PPTP_HEADER_CTRL(PPTP_CALL_CLEAR_RQST), 0, 0
++ };
++ assert(conn && conn->call); assert(call);
++ assert(vector_contains(conn->call, call->call_id));
++ /* haven't thought about PAC yet */
++ assert(call->call_type == PPTP_CALL_PNS);
++ assert(call->state.pns != PNS_IDLE);
++ rqst.call_id = hton16(call->call_id);
++ /* don't check state against WAIT_DISCONNECT... allow multiple disconnect
++ * requests to be made.
++ */
++ pptp_send_ctrl_packet(conn, &rqst, sizeof(rqst));
++ pptp_reset_timer();
++ call->state.pns = PNS_WAIT_DISCONNECT;
++ /* call structure will be freed when we have confirmation of disconnect. */
++}
++
++/*** hard close ***************************************************************/
++void pptp_call_destroy(PPTP_CONN *conn, PPTP_CALL *call)
++{
++ assert(conn && conn->call); assert(call);
++ assert(vector_contains(conn->call, call->call_id));
++ /* notify */
++ if (call->callback != NULL) call->callback(conn, call, CALL_CLOSE_DONE);
++ /* deallocate */
++ vector_remove(conn->call, call->call_id);
++ free(call);
++}
++
++/*** this is a soft close *****************************************************/
++void pptp_conn_close(PPTP_CONN * conn, u_int8_t close_reason)
++{
++ struct pptp_stop_ctrl_conn rqst = {
++ PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RQST),
++ hton8(close_reason), 0, 0
++ };
++ int i;
++ assert(conn && conn->call);
++ /* avoid repeated close attempts */
++ if (conn->conn_state == CONN_IDLE || conn->conn_state == CONN_WAIT_STOP_REPLY)
++ return;
++ /* close open calls, if any */
++ for (i = 0; i < vector_size(conn->call); i++)
++ pptp_call_close(conn, vector_get_Nth(conn->call, i));
++ /* now close connection */
++ info("Closing PPTP connection");
++ pptp_send_ctrl_packet(conn, &rqst, sizeof(rqst));
++ pptp_reset_timer(); /* wait 60 seconds for reply */
++ conn->conn_state = CONN_WAIT_STOP_REPLY;
++ return;
++}
++
++/*** this is a hard close *****************************************************/
++void pptp_conn_destroy(PPTP_CONN * conn)
++{
++ int i;
++ assert(conn != NULL); assert(conn->call != NULL);
++ /* destroy all open calls */
++ for (i = 0; i < vector_size(conn->call); i++)
++ pptp_call_destroy(conn, vector_get_Nth(conn->call, i));
++ /* notify */
++ if (conn->callback != NULL) conn->callback(conn, CONN_CLOSE_DONE);
++ sigpipe_close();
++ close(conn->inet_sock);
++ /* deallocate */
++ vector_destroy(conn->call);
++ free(conn);
++}
++
++/*** Deal with messages, in a non-blocking manner
++ * Add file descriptors used by pptp to fd_set.
++ */
++void pptp_fd_set(PPTP_CONN * conn, fd_set * read_set, fd_set * write_set,
++ int * max_fd)
++{
++ assert(conn && conn->call);
++ /* Add fd to write_set if there are outstanding writes. */
++ if (conn->write_size > 0)
++ FD_SET(conn->inet_sock, write_set);
++ /* Always add fd to read_set. (always want something to read) */
++ FD_SET(conn->inet_sock, read_set);
++ if (*max_fd < conn->inet_sock) *max_fd = conn->inet_sock;
++ /* Add signal pipe file descriptor to set */
++ int sig_fd = sigpipe_fd();
++ FD_SET(sig_fd, read_set);
++ if (*max_fd < sig_fd) *max_fd = sig_fd;
++}
++
++/*** handle any pptp file descriptors set in fd_set, and clear them ***********/
++int pptp_dispatch(PPTP_CONN * conn, fd_set * read_set, fd_set * write_set)
++{
++ int r = 0;
++ assert(conn && conn->call);
++ /* Check for signals */
++ if (FD_ISSET(sigpipe_fd(), read_set)) {
++ if (sigpipe_read() == SIGALRM) pptp_handle_timer();
++ FD_CLR(sigpipe_fd(), read_set);
++ }
++ /* Check write_set could be set. */
++ if (FD_ISSET(conn->inet_sock, write_set)) {
++ FD_CLR(conn->inet_sock, write_set);
++ if (conn->write_size > 0)
++ r = pptp_write_some(conn);/* write as much as we can without blocking */
++ }
++ /* Check read_set */
++ if (r >= 0 && FD_ISSET(conn->inet_sock, read_set)) {
++ void *buffer; size_t size;
++ FD_CLR(conn->inet_sock, read_set);
++ r = pptp_read_some(conn); /* read as much as we can without blocking */
++ if (r < 0)
++ return r;
++ /* make packets of the buffer, while we can. */
++ while (r >= 0 && pptp_make_packet(conn, &buffer, &size)) {
++ r = pptp_dispatch_packet(conn, buffer, size);
++ free(buffer);
++ }
++ }
++ /* That's all, folks. Simple, eh? */
++ return r;
++}
++
++/*** Non-blocking write *******************************************************/
++int pptp_write_some(PPTP_CONN * conn) {
++ ssize_t retval;
++ assert(conn && conn->call);
++ retval = write(conn->inet_sock, conn->write_buffer, conn->write_size);
++ if (retval < 0) { /* error. */
++ if (errno == EAGAIN || errno == EINTR) {
++ return 0;
++ } else { /* a real error */
++ warn("write error: %s", strerror(errno));
++ return -1;
++ }
++ }
++ assert(retval <= conn->write_size);
++ conn->write_size -= retval;
++ memmove(conn->write_buffer, conn->write_buffer + retval, conn->write_size);
++ ctrlp_rep(conn->write_buffer, retval, 0);
++ return 0;
++}
++
++/*** Non-blocking read ********************************************************/
++int pptp_read_some(PPTP_CONN * conn)
++{
++ ssize_t retval;
++ assert(conn && conn->call);
++ if (conn->read_size == conn->read_alloc) { /* need to alloc more memory */
++ char *new_buffer = realloc(conn->read_buffer,
++ sizeof(*(conn->read_buffer)) * conn->read_alloc * 2);
++ if (new_buffer == NULL) {
++ warn("Out of memory"); return -1;
++ }
++ conn->read_alloc *= 2;
++ conn->read_buffer = new_buffer;
++ }
++ retval = read(conn->inet_sock, conn->read_buffer + conn->read_size,
++ conn->read_alloc - conn->read_size);
++ if (retval == 0) {
++ warn("read returned zero, peer has closed");
++ return -1;
++ }
++ if (retval < 0) {
++ if (errno == EINTR || errno == EAGAIN)
++ return 0;
++ else { /* a real error */
++ warn("read error: %s", strerror(errno));
++ return -1;
++ }
++ }
++ conn->read_size += retval;
++ assert(conn->read_size <= conn->read_alloc);
++ return 0;
++}
++
++/*** Packet formation *********************************************************/
++int pptp_make_packet(PPTP_CONN * conn, void **buf, size_t *size)
++{
++ struct pptp_header *header;
++ size_t bad_bytes = 0;
++ assert(conn && conn->call); assert(buf != NULL); assert(size != NULL);
++ /* Give up unless there are at least sizeof(pptp_header) bytes */
++ while ((conn->read_size-bad_bytes) >= sizeof(struct pptp_header)) {
++ /* Throw out bytes until we have a valid header. */
++ header = (struct pptp_header *) (conn->read_buffer + bad_bytes);
++ if (ntoh32(header->magic) != PPTP_MAGIC) goto throwitout;
++ if (ntoh16(header->reserved0) != 0)
++ warn("reserved0 field is not zero! (0x%x) Cisco feature? \n",
++ ntoh16(header->reserved0));
++ if (ntoh16(header->length) < sizeof(struct pptp_header)) goto throwitout;
++ if (ntoh16(header->length) > PPTP_CTRL_SIZE_MAX) goto throwitout;
++ /* well. I guess it's good. Let's see if we've got it all. */
++ if (ntoh16(header->length) > (conn->read_size-bad_bytes))
++ /* nope. Let's wait until we've got it, then. */
++ goto flushbadbytes;
++ /* One last check: */
++ if ((ntoh16(header->pptp_type) == PPTP_MESSAGE_CONTROL) &&
++ (ntoh16(header->length) !=
++ PPTP_CTRL_SIZE(ntoh16(header->ctrl_type))))
++ goto throwitout;
++ /* well, I guess we've got it. */
++ *size = ntoh16(header->length);
++ *buf = malloc(*size);
++ if (*buf == NULL) { warn("Out of memory."); return 0; /* ack! */ }
++ memcpy(*buf, conn->read_buffer + bad_bytes, *size);
++ /* Delete this packet from the read_buffer. */
++ conn->read_size -= (bad_bytes + *size);
++ memmove(conn->read_buffer, conn->read_buffer + bad_bytes + *size,
++ conn->read_size);
++ if (bad_bytes > 0)
++ warn("%lu bad bytes thrown away.", (unsigned long) bad_bytes);
++ return 1;
++throwitout:
++ bad_bytes++;
++ }
++flushbadbytes:
++ /* no more packets. Let's get rid of those bad bytes */
++ conn->read_size -= bad_bytes;
++ memmove(conn->read_buffer, conn->read_buffer + bad_bytes, conn->read_size);
++ if (bad_bytes > 0)
++ warn("%lu bad bytes thrown away.", (unsigned long) bad_bytes);
++ return 0;
++}
++
++/*** pptp_send_ctrl_packet ****************************************************/
++int pptp_send_ctrl_packet(PPTP_CONN * conn, void * buffer, size_t size)
++{
++ assert(conn && conn->call); assert(buffer);
++ if( conn->write_size > 0) pptp_write_some( conn);
++ if( conn->write_size == 0) {
++ ssize_t retval;
++ retval = write(conn->inet_sock, buffer, size);
++ if (retval < 0) { /* error. */
++ if (errno == EAGAIN || errno == EINTR) {
++ /* ignore */;
++ retval = 0;
++ } else { /* a real error */
++ warn("write error: %s", strerror(errno));
++ pptp_conn_destroy(conn); /* shut down fast. */
++ return 0;
++ }
++ }
++ ctrlp_rep( buffer, retval, 0);
++ size -= retval;
++ if( size <= 0) return 1;
++ }
++ /* Shove anything not written into the write buffer */
++ if (conn->write_size + size > conn->write_alloc) { /* need more memory */
++ char *new_buffer = realloc(conn->write_buffer,
++ sizeof(*(conn->write_buffer)) * conn->write_alloc * 2);
++ if (new_buffer == NULL) {
++ warn("Out of memory"); return 0;
++ }
++ conn->write_alloc *= 2;
++ conn->write_buffer = new_buffer;
++ }
++ memcpy(conn->write_buffer + conn->write_size, buffer, size);
++ conn->write_size += size;
++ ctrlp_rep( buffer,size,1);
++ return 1;
++}
++
++/*** Packet Dispatch **********************************************************/
++int pptp_dispatch_packet(PPTP_CONN * conn, void * buffer, size_t size)
++{
++ int r = 0;
++ struct pptp_header *header = (struct pptp_header *)buffer;
++ assert(conn && conn->call); assert(buffer);
++ assert(ntoh32(header->magic) == PPTP_MAGIC);
++ assert(ntoh16(header->length) == size);
++ switch (ntoh16(header->pptp_type)) {
++ case PPTP_MESSAGE_CONTROL:
++ r = ctrlp_disp(conn, buffer, size);
++ break;
++ case PPTP_MESSAGE_MANAGE:
++ /* MANAGEMENT messages aren't even part of the spec right now. */
++ dbglog("PPTP management message received, but not understood.");
++ break;
++ default:
++ dbglog("Unknown PPTP control message type received: %u",
++ (unsigned int) ntoh16(header->pptp_type));
++ break;
++ }
++ return r;
++}
++
++/*** log echo request/replies *************************************************/
++static void logecho( int type)
++{
++ /* hack to stop flooding the log files (the most interesting part is right
++ * after the connection built-up) */
++ if( nlogecho > 0) {
++ dbglog("Echo Re%s received.", type == PPTP_ECHO_RQST ? "quest" :"ply");
++ if( --nlogecho == 0)
++ dbglog("no more Echo Reply/Request packets will be reported.");
++ }
++}
++
++/*** pptp_dispatch_ctrl_packet ************************************************/
++int ctrlp_disp(PPTP_CONN * conn, void * buffer, size_t size)
++{
++ struct pptp_header *header = (struct pptp_header *)buffer;
++ u_int8_t close_reason = PPTP_STOP_NONE;
++ assert(conn && conn->call); assert(buffer);
++ assert(ntoh32(header->magic) == PPTP_MAGIC);
++ assert(ntoh16(header->length) == size);
++ assert(ntoh16(header->pptp_type) == PPTP_MESSAGE_CONTROL);
++ if (size < PPTP_CTRL_SIZE(ntoh16(header->ctrl_type))) {
++ warn("Invalid packet received [type: %d; length: %d].",
++ (int) ntoh16(header->ctrl_type), (int) size);
++ return 0;
++ }
++ switch (ntoh16(header->ctrl_type)) {
++ /* ----------- STANDARD Start-Session MESSAGES ------------ */
++ case PPTP_START_CTRL_CONN_RQST:
++ {
++ struct pptp_start_ctrl_conn *packet =
++ (struct pptp_start_ctrl_conn *) buffer;
++ struct pptp_start_ctrl_conn reply = {
++ PPTP_HEADER_CTRL(PPTP_START_CTRL_CONN_RPLY),
++ hton16(PPTP_VERSION), 0, 0,
++ hton32(PPTP_FRAME_CAP), hton32(PPTP_BEARER_CAP),
++ hton16(PPTP_MAX_CHANNELS), hton16(PPTP_FIRMWARE_VERSION),
++ PPTP_HOSTNAME, PPTP_VENDOR };
++ int idx, rc;
++ dbglog("Received Start Control Connection Request");
++ /* fix this packet, if necessary */
++ idx = get_quirk_index();
++ if (idx != -1 && pptp_fixups[idx].start_ctrl_conn) {
++ if ((rc = pptp_fixups[idx].start_ctrl_conn(&reply)))
++ warn("calling the start_ctrl_conn hook failed (%d)", rc);
++ }
++ if (conn->conn_state == CONN_IDLE) {
++ if (ntoh16(packet->version) < PPTP_VERSION) {
++ /* Can't support this (earlier) PPTP_VERSION */
++ reply.version = packet->version;
++ /* protocol version not supported */
++ reply.result_code = hton8(5);
++ pptp_send_ctrl_packet(conn, &reply, sizeof(reply));
++ pptp_reset_timer(); /* give sender a chance for a retry */
++ } else { /* same or greater version */
++ if (pptp_send_ctrl_packet(conn, &reply, sizeof(reply))) {
++ conn->conn_state = CONN_ESTABLISHED;
++ dbglog("server connection ESTABLISHED.");
++ pptp_reset_timer();
++ }
++ }
++ }
++ break;
++ }
++ case PPTP_START_CTRL_CONN_RPLY:
++ {
++ struct pptp_start_ctrl_conn *packet =
++ (struct pptp_start_ctrl_conn *) buffer;
++ dbglog("Received Start Control Connection Reply");
++ if (conn->conn_state == CONN_WAIT_CTL_REPLY) {
++ /* XXX handle collision XXX [see rfc] */
++ if (ntoh16(packet->version) != PPTP_VERSION) {
++ if (conn->callback != NULL)
++ conn->callback(conn, CONN_OPEN_FAIL);
++ close_reason = PPTP_STOP_PROTOCOL;
++ goto pptp_conn_close;
++ }
++ if (ntoh8(packet->result_code) != 1 &&
++ /* J'ai change le if () afin que la connection ne se ferme
++ * pas pour un "rien" :p adel@cybercable.fr -
++ *
++ * Don't close the connection if the result code is zero
++ * (feature found in certain ADSL modems)
++ */
++ ntoh8(packet->result_code) != 0) {
++ dbglog("Negative reply received to our Start Control "
++ "Connection Request");
++ ctrlp_error(packet->result_code, packet->error_code,
++ -1, pptp_start_ctrl_conn_rply,
++ MAX_START_CTRL_CONN_REPLY);
++ if (conn->callback != NULL)
++ conn->callback(conn, CONN_OPEN_FAIL);
++ close_reason = PPTP_STOP_PROTOCOL;
++ goto pptp_conn_close;
++ }
++ conn->conn_state = CONN_ESTABLISHED;
++ /* log session properties */
++ conn->version = ntoh16(packet->version);
++ conn->firmware_rev = ntoh16(packet->firmware_rev);
++ memcpy(conn->hostname, packet->hostname, sizeof(conn->hostname));
++ memcpy(conn->vendor, packet->vendor, sizeof(conn->vendor));
++ pptp_reset_timer(); /* 60 seconds until keep-alive */
++ dbglog("Client connection established.");
++ if (conn->callback != NULL)
++ conn->callback(conn, CONN_OPEN_DONE);
++ } /* else goto pptp_conn_close; */
++ break;
++ }
++ /* ----------- STANDARD Stop-Session MESSAGES ------------ */
++ case PPTP_STOP_CTRL_CONN_RQST:
++ {
++ /* conn_state should be CONN_ESTABLISHED, but it could be
++ * something else */
++ struct pptp_stop_ctrl_conn reply = {
++ PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RPLY),
++ hton8(1), hton8(PPTP_GENERAL_ERROR_NONE), 0
++ };
++ dbglog("Received Stop Control Connection Request.");
++ if (conn->conn_state == CONN_IDLE) break;
++ if (pptp_send_ctrl_packet(conn, &reply, sizeof(reply))) {
++ if (conn->callback != NULL)
++ conn->callback(conn, CONN_CLOSE_RQST);
++ conn->conn_state = CONN_IDLE;
++ return -1;
++ }
++ break;
++ }
++ case PPTP_STOP_CTRL_CONN_RPLY:
++ {
++ dbglog("Received Stop Control Connection Reply.");
++ /* conn_state should be CONN_WAIT_STOP_REPLY, but it
++ * could be something else */
++ if (conn->conn_state == CONN_IDLE) break;
++ conn->conn_state = CONN_IDLE;
++ return -1;
++ }
++ /* ----------- STANDARD Echo/Keepalive MESSAGES ------------ */
++ case PPTP_ECHO_RPLY:
++ {
++ struct pptp_echo_rply *packet =
++ (struct pptp_echo_rply *) buffer;
++ logecho( PPTP_ECHO_RPLY);
++ if ((conn->ka_state == KA_OUTSTANDING) &&
++ (ntoh32(packet->identifier) == conn->ka_id)) {
++ conn->ka_id++;
++ conn->ka_state = KA_NONE;
++ pptp_reset_timer();
++ }
++ break;
++ }
++ case PPTP_ECHO_RQST:
++ {
++ struct pptp_echo_rqst *packet =
++ (struct pptp_echo_rqst *) buffer;
++ struct pptp_echo_rply reply = {
++ PPTP_HEADER_CTRL(PPTP_ECHO_RPLY),
++ packet->identifier, /* skip hton32(ntoh32(id)) */
++ hton8(1), hton8(PPTP_GENERAL_ERROR_NONE), 0
++ };
++ logecho( PPTP_ECHO_RQST);
++ pptp_send_ctrl_packet(conn, &reply, sizeof(reply));
++ pptp_reset_timer();
++ break;
++ }
++ /* ----------- OUTGOING CALL MESSAGES ------------ */
++ case PPTP_OUT_CALL_RQST:
++ {
++ struct pptp_out_call_rqst *packet =
++ (struct pptp_out_call_rqst *)buffer;
++ struct pptp_out_call_rply reply = {
++ PPTP_HEADER_CTRL(PPTP_OUT_CALL_RPLY),
++ 0 /* callid */, packet->call_id, 1, PPTP_GENERAL_ERROR_NONE, 0,
++ hton32(PPTP_CONNECT_SPEED),
++ hton16(PPTP_WINDOW), hton16(PPTP_DELAY), 0
++ };
++ dbglog("Received Outgoing Call Request.");
++ /* XXX PAC: eventually this should make an outgoing call. XXX */
++ reply.result_code = hton8(7); /* outgoing calls verboten */
++ pptp_send_ctrl_packet(conn, &reply, sizeof(reply));
++ break;
++ }
++ case PPTP_OUT_CALL_RPLY:
++ {
++ struct pptp_out_call_rply *packet =
++ (struct pptp_out_call_rply *)buffer;
++ PPTP_CALL * call;
++ u_int16_t callid = ntoh16(packet->call_id_peer);
++ dbglog("Received Outgoing Call Reply.");
++ if (!vector_search(conn->call, (int) callid, &call)) {
++ dbglog("PPTP_OUT_CALL_RPLY received for non-existant call: "
++ "peer call ID (us) %d call ID (them) %d.",
++ callid, ntoh16(packet->call_id));
++ break;
++ }
++ if (call->call_type != PPTP_CALL_PNS) {
++ dbglog("Ack! How did this call_type get here?"); /* XXX? */
++ break;
++ }
++ if (call->state.pns != PNS_WAIT_REPLY) {
++ warn("Unexpected(?) Outgoing Call Reply will be ignored.");
++ break;
++ }
++ /* check for errors */
++ if (packet->result_code != 1) {
++ /* An error. Log it verbosely. */
++ dbglog("Our outgoing call request [callid %d] has not been "
++ "accepted.", (int) callid);
++ ctrlp_error(packet->result_code, packet->error_code,
++ packet->cause_code, pptp_out_call_reply_result,
++ MAX_OUT_CALL_REPLY_RESULT);
++ call->state.pns = PNS_IDLE;
++ if (call->callback != NULL)
++ call->callback(conn, call, CALL_OPEN_FAIL);
++ pptp_call_destroy(conn, call);
++ } else {
++ /* connection established */
++ call->state.pns = PNS_ESTABLISHED;
++ call->peer_call_id = ntoh16(packet->call_id);
++ call->speed = ntoh32(packet->speed);
++ pptp_reset_timer();
++ /* call pptp_set_link. unless the user specified a quirk
++ and this quirk has a set_link hook, this is a noop */
++ pptp_set_link(conn, call->peer_call_id);
++ if (call->callback != NULL)
++ call->callback(conn, call, CALL_OPEN_DONE);
++ dbglog("Outgoing call established (call ID %u, peer's "
++ "call ID %u).\n", call->call_id, call->peer_call_id);
++ }
++ break;
++ }
++ /* ----------- INCOMING CALL MESSAGES ------------ */
++ /* XXX write me XXX */
++ /* ----------- CALL CONTROL MESSAGES ------------ */
++ case PPTP_CALL_CLEAR_RQST:
++ {
++ struct pptp_call_clear_rqst *packet =
++ (struct pptp_call_clear_rqst *)buffer;
++ struct pptp_call_clear_ntfy reply = {
++ PPTP_HEADER_CTRL(PPTP_CALL_CLEAR_NTFY), packet->call_id,
++ 1, PPTP_GENERAL_ERROR_NONE, 0, 0, {0}
++ };
++ dbglog("Received Call Clear Request.");
++ if (vector_contains(conn->call, ntoh16(packet->call_id))) {
++ PPTP_CALL * call;
++ vector_search(conn->call, ntoh16(packet->call_id), &call);
++ if (call->callback != NULL)
++ call->callback(conn, call, CALL_CLOSE_RQST);
++ pptp_send_ctrl_packet(conn, &reply, sizeof(reply));
++ pptp_call_destroy(conn, call);
++ dbglog("Call closed (RQST) (call id %d)", (int) call->call_id);
++ }
++ break;
++ }
++ case PPTP_CALL_CLEAR_NTFY:
++ {
++ struct pptp_call_clear_ntfy *packet =
++ (struct pptp_call_clear_ntfy *)buffer;
++ dbglog("Call disconnect notification received (call id %d)",
++ ntoh16(packet->call_id));
++ if (vector_contains(conn->call, ntoh16(packet->call_id))) {
++ PPTP_CALL * call;
++ ctrlp_error(packet->result_code, packet->error_code,
++ packet->cause_code, pptp_call_disc_ntfy,
++ MAX_CALL_DISC_NTFY);
++ vector_search(conn->call, ntoh16(packet->call_id), &call);
++ pptp_call_destroy(conn, call);
++ }
++ /* XXX we could log call stats here XXX */
++ /* XXX not all servers send this XXX */
++ break;
++ }
++ case PPTP_SET_LINK_INFO:
++ {
++ /* I HAVE NO CLUE WHAT TO DO IF send_accm IS NOT 0! */
++ /* this is really dealt with in the HDLC deencapsulation, anyway. */
++ struct pptp_set_link_info *packet =
++ (struct pptp_set_link_info *)buffer;
++ /* log it. */
++ dbglog("PPTP_SET_LINK_INFO received from peer_callid %u",
++ (unsigned int) ntoh16(packet->call_id_peer));
++ dbglog(" send_accm is %08lX, recv_accm is %08lX",
++ (unsigned long) ntoh32(packet->send_accm),
++ (unsigned long) ntoh32(packet->recv_accm));
++ if (!(ntoh32(packet->send_accm) == 0 &&
++ ntoh32(packet->recv_accm) == 0))
++ warn("Non-zero Async Control Character Maps are not supported!");
++ break;
++ }
++ default:
++ dbglog("Unrecognized Packet %d received.",
++ (int) ntoh16(((struct pptp_header *)buffer)->ctrl_type));
++ /* goto pptp_conn_close; */
++ break;
++ }
++ return 0;
++pptp_conn_close:
++ warn("pptp_conn_close(%d)", (int) close_reason);
++ pptp_conn_close(conn, close_reason);
++ return 0;
++}
++
++/*** pptp_set_link **************************************************************/
++void pptp_set_link(PPTP_CONN* conn, int peer_call_id)
++{
++ int idx, rc;
++ /* if we need to send a set_link packet because of buggy
++ hardware or pptp server, do it now */
++ if ((idx = get_quirk_index()) != -1 && pptp_fixups[idx].set_link_hook) {
++ struct pptp_set_link_info packet;
++ if ((rc = pptp_fixups[idx].set_link_hook(&packet, peer_call_id)))
++ warn("calling the set_link hook failed (%d)", rc);
++ if (pptp_send_ctrl_packet(conn, &packet, sizeof(packet))) {
++ pptp_reset_timer();
++ }
++ }
++}
++
++/*** Get info from call structure *********************************************/
++/* NOTE: The peer_call_id is undefined until we get a server response. */
++void pptp_call_get_ids(PPTP_CONN * conn, PPTP_CALL * call,
++ u_int16_t * call_id, u_int16_t * peer_call_id)
++{
++ assert(conn != NULL); assert(call != NULL);
++ *call_id = call->call_id;
++ *peer_call_id = call->peer_call_id;
++}
++
++/*** pptp_call_closure_put ****************************************************/
++void pptp_call_closure_put(PPTP_CONN * conn, PPTP_CALL * call, void *cl)
++{
++ assert(conn != NULL); assert(call != NULL);
++ call->closure = cl;
++}
++
++/*** pptp_call_closure_get ****************************************************/
++void * pptp_call_closure_get(PPTP_CONN * conn, PPTP_CALL * call)
++{
++ assert(conn != NULL); assert(call != NULL);
++ return call->closure;
++}
++
++/*** pptp_conn_closure_put ****************************************************/
++void pptp_conn_closure_put(PPTP_CONN * conn, void *cl)
++{
++ assert(conn != NULL);
++ conn->closure = cl;
++}
++
++/*** pptp_conn_closure_get ****************************************************/
++void * pptp_conn_closure_get(PPTP_CONN * conn)
++{
++ assert(conn != NULL);
++ return conn->closure;
++}
++
++/*** Reset keep-alive timer ***************************************************/
++static void pptp_reset_timer(void)
++{
++ const struct itimerval tv = { { 0, 0 }, /* stop on time-out */
++ { idle_wait, 0 } };
++ if (idle_wait) setitimer(ITIMER_REAL, &tv, NULL);
++}
++
++
++/*** Handle keep-alive timer **************************************************/
++static void pptp_handle_timer()
++{
++ int i;
++ /* "Keep Alives and Timers, 1": check connection state */
++ if (global.conn->conn_state != CONN_ESTABLISHED) {
++ if (global.conn->conn_state == CONN_WAIT_STOP_REPLY)
++ /* hard close. */
++ pptp_conn_destroy(global.conn);
++ else /* soft close */
++ pptp_conn_close(global.conn, PPTP_STOP_NONE);
++ }
++ /* "Keep Alives and Timers, 2": check echo status */
++ if (global.conn->ka_state == KA_OUTSTANDING) {
++ /* no response to keep-alive */
++ info("closing control connection due to missing echo reply");
++ pptp_conn_close(global.conn, PPTP_STOP_NONE);
++ } else { /* ka_state == NONE */ /* send keep-alive */
++ struct pptp_echo_rqst rqst = {
++ PPTP_HEADER_CTRL(PPTP_ECHO_RQST), hton32(global.conn->ka_id) };
++ pptp_send_ctrl_packet(global.conn, &rqst, sizeof(rqst));
++ global.conn->ka_state = KA_OUTSTANDING;
++ }
++ /* check incoming/outgoing call states for !IDLE && !ESTABLISHED */
++ for (i = 0; i < vector_size(global.conn->call); i++) {
++ PPTP_CALL * call = vector_get_Nth(global.conn->call, i);
++ if (call->call_type == PPTP_CALL_PNS) {
++ if (call->state.pns == PNS_WAIT_REPLY) {
++ /* send close request */
++ pptp_call_close(global.conn, call);
++ assert(call->state.pns == PNS_WAIT_DISCONNECT);
++ } else if (call->state.pns == PNS_WAIT_DISCONNECT) {
++ /* hard-close the call */
++ pptp_call_destroy(global.conn, call);
++ }
++ } else if (call->call_type == PPTP_CALL_PAC) {
++ if (call->state.pac == PAC_WAIT_REPLY) {
++ /* XXX FIXME -- drop the PAC connection XXX */
++ } else if (call->state.pac == PAC_WAIT_CS_ANS) {
++ /* XXX FIXME -- drop the PAC connection XXX */
++ }
++ }
++ }
++ pptp_reset_timer();
++}
+--- /dev/null
++++ b/pppd/plugins/pptp/pptp_ctrl.h
+@@ -0,0 +1,57 @@
++/* pptp_ctrl.h ... handle PPTP control connection.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: pptp_ctrl.h,v 1.5 2004/11/09 01:42:32 quozl Exp $
++ */
++
++#ifndef INC_PPTP_CTRL_H
++#define INC_PPTP_CTRL_H
++#include <sys/types.h>
++
++typedef struct PPTP_CONN PPTP_CONN;
++typedef struct PPTP_CALL PPTP_CALL;
++
++enum call_state { CALL_OPEN_RQST, CALL_OPEN_DONE, CALL_OPEN_FAIL,
++ CALL_CLOSE_RQST, CALL_CLOSE_DONE };
++enum conn_state { CONN_OPEN_RQST, CONN_OPEN_DONE, CONN_OPEN_FAIL,
++ CONN_CLOSE_RQST, CONN_CLOSE_DONE };
++
++typedef void (*pptp_call_cb)(PPTP_CONN*, PPTP_CALL*, enum call_state);
++typedef void (*pptp_conn_cb)(PPTP_CONN*, enum conn_state);
++
++/* if 'isclient' is true, then will send 'conn open' packet to other host.
++ * not necessary if this is being opened by a server process after
++ * receiving a conn_open packet from client.
++ */
++PPTP_CONN * pptp_conn_open(int inet_sock, int isclient,
++ pptp_conn_cb callback);
++PPTP_CALL * pptp_call_open(PPTP_CONN * conn, int call_id,
++ pptp_call_cb callback, char *phonenr,int window);
++int pptp_conn_established(PPTP_CONN * conn);
++/* soft close. Will callback on completion. */
++void pptp_call_close(PPTP_CONN * conn, PPTP_CALL * call);
++/* hard close. */
++void pptp_call_destroy(PPTP_CONN *conn, PPTP_CALL *call);
++/* soft close. Will callback on completion. */
++void pptp_conn_close(PPTP_CONN * conn, u_int8_t close_reason);
++/* hard close */
++void pptp_conn_destroy(PPTP_CONN * conn);
++
++/* Add file descriptors used by pptp to fd_set. */
++void pptp_fd_set(PPTP_CONN * conn, fd_set * read_set, fd_set * write_set, int *max_fd);
++/* handle any pptp file descriptors set in fd_set, and clear them */
++int pptp_dispatch(PPTP_CONN * conn, fd_set * read_set, fd_set * write_set);
++
++/* Get info about connection, call */
++void pptp_call_get_ids(PPTP_CONN * conn, PPTP_CALL * call,
++ u_int16_t * call_id, u_int16_t * peer_call_id);
++/* Arbitrary user data about this call/connection.
++ * It is the caller's responsibility to free this data before calling
++ * pptp_call|conn_close()
++ */
++void * pptp_conn_closure_get(PPTP_CONN * conn);
++void pptp_conn_closure_put(PPTP_CONN * conn, void *cl);
++void * pptp_call_closure_get(PPTP_CONN * conn, PPTP_CALL * call);
++void pptp_call_closure_put(PPTP_CONN * conn, PPTP_CALL * call, void *cl);
++
++#endif /* INC_PPTP_CTRL_H */
+--- /dev/null
++++ b/pppd/plugins/pptp/pptp_msg.h
+@@ -0,0 +1,303 @@
++/* pptp.h: packet structures and magic constants for the PPTP protocol
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: pptp_msg.h,v 1.3 2003/02/15 10:37:21 quozl Exp $
++ */
++
++#ifndef INC_PPTP_H
++#define INC_PPTP_H
++
++/* Grab definitions of int16, int32, etc. */
++#include <sys/types.h>
++/* define "portable" htons, etc. */
++#define hton8(x) (x)
++#define ntoh8(x) (x)
++#define hton16(x) htons(x)
++#define ntoh16(x) ntohs(x)
++#define hton32(x) htonl(x)
++#define ntoh32(x) ntohl(x)
++
++/* PPTP magic numbers: ----------------------------------------- */
++
++#define PPTP_MAGIC 0x1A2B3C4D /* Magic cookie for PPTP datagrams */
++#define PPTP_PORT 1723 /* PPTP TCP port number */
++#define PPTP_PROTO 47 /* PPTP IP protocol number */
++
++/* Control Connection Message Types: --------------------------- */
++
++#define PPTP_MESSAGE_CONTROL 1
++#define PPTP_MESSAGE_MANAGE 2
++
++/* Control Message Types: -------------------------------------- */
++
++/* (Control Connection Management) */
++#define PPTP_START_CTRL_CONN_RQST 1
++#define PPTP_START_CTRL_CONN_RPLY 2
++#define PPTP_STOP_CTRL_CONN_RQST 3
++#define PPTP_STOP_CTRL_CONN_RPLY 4
++#define PPTP_ECHO_RQST 5
++#define PPTP_ECHO_RPLY 6
++
++/* (Call Management) */
++#define PPTP_OUT_CALL_RQST 7
++#define PPTP_OUT_CALL_RPLY 8
++#define PPTP_IN_CALL_RQST 9
++#define PPTP_IN_CALL_RPLY 10
++#define PPTP_IN_CALL_CONNECT 11
++#define PPTP_CALL_CLEAR_RQST 12
++#define PPTP_CALL_CLEAR_NTFY 13
++
++/* (Error Reporting) */
++#define PPTP_WAN_ERR_NTFY 14
++
++/* (PPP Session Control) */
++#define PPTP_SET_LINK_INFO 15
++
++/* PPTP version information: --------------------------------------*/
++#define PPTP_VERSION_STRING "1.00"
++#define PPTP_VERSION 0x100
++#define PPTP_FIRMWARE_STRING "0.01"
++#define PPTP_FIRMWARE_VERSION 0x001
++
++/* PPTP capabilities: ---------------------------------------------*/
++
++/* (Framing capabilities for msg sender) */
++#define PPTP_FRAME_ASYNC 1
++#define PPTP_FRAME_SYNC 2
++#define PPTP_FRAME_ANY 3
++
++/* (Bearer capabilities for msg sender) */
++#define PPTP_BEARER_ANALOG 1
++#define PPTP_BEARER_DIGITAL 2
++#define PPTP_BEARER_ANY 3
++
++#define PPTP_RESULT_GENERAL_ERROR 2
++
++/* (Reasons to close a connection) */
++#define PPTP_STOP_NONE 1 /* no good reason */
++#define PPTP_STOP_PROTOCOL 2 /* can't support peer's protocol version */
++#define PPTP_STOP_LOCAL_SHUTDOWN 3 /* requester is being shut down */
++
++/* PPTP datagram structures (all data in network byte order): ----------*/
++
++struct pptp_header {
++ u_int16_t length; /* message length in octets, including header */
++ u_int16_t pptp_type; /* PPTP message type. 1 for control message. */
++ u_int32_t magic; /* this should be PPTP_MAGIC. */
++ u_int16_t ctrl_type; /* Control message type (0-15) */
++ u_int16_t reserved0; /* reserved. MUST BE ZERO. */
++};
++
++struct pptp_start_ctrl_conn { /* for control message types 1 and 2 */
++ struct pptp_header header;
++
++ u_int16_t version; /* PPTP protocol version. = PPTP_VERSION */
++ u_int8_t result_code; /* these two fields should be zero on rqst msg*/
++ u_int8_t error_code; /* 0 unless result_code==2 (General Error) */
++ u_int32_t framing_cap; /* Framing capabilities */
++ u_int32_t bearer_cap; /* Bearer Capabilities */
++ u_int16_t max_channels; /* Maximum Channels (=0 for PNS, PAC ignores) */
++ u_int16_t firmware_rev; /* Firmware or Software Revision */
++ u_int8_t hostname[64]; /* Host Name (64 octets, zero terminated) */
++ u_int8_t vendor[64]; /* Vendor string (64 octets, zero term.) */
++ /* MS says that end of hostname/vendor fields should be filled with */
++ /* octets of value 0, but Win95 PPTP driver doesn't do this. */
++};
++
++struct pptp_stop_ctrl_conn { /* for control message types 3 and 4 */
++ struct pptp_header header;
++
++ u_int8_t reason_result; /* reason for rqst, result for rply */
++ u_int8_t error_code; /* MUST be 0, unless rply result==2 (general err)*/
++ u_int16_t reserved1; /* MUST be 0 */
++};
++
++struct pptp_echo_rqst { /* for control message type 5 */
++ struct pptp_header header;
++ u_int32_t identifier; /* arbitrary value set by sender which is used */
++ /* to match up reply and request */
++};
++
++struct pptp_echo_rply { /* for control message type 6 */
++ struct pptp_header header;
++ u_int32_t identifier; /* should correspond to id of rqst */
++ u_int8_t result_code;
++ u_int8_t error_code; /* =0, unless result_code==2 (general error) */
++ u_int16_t reserved1; /* MUST BE ZERO */
++};
++
++struct pptp_out_call_rqst { /* for control message type 7 */
++ struct pptp_header header;
++ u_int16_t call_id; /* Call ID (unique id used to multiplex data) */
++ u_int16_t call_sernum; /* Call Serial Number (used for logging) */
++ u_int32_t bps_min; /* Minimum BPS (lowest acceptable line speed) */
++ u_int32_t bps_max; /* Maximum BPS (highest acceptable line speed) */
++ u_int32_t bearer; /* Bearer type */
++ u_int32_t framing; /* Framing type */
++ u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */
++ u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */
++ u_int16_t phone_len; /* Phone Number Length (num. of valid digits) */
++ u_int16_t reserved1; /* MUST BE ZERO */
++ u_int8_t phone_num[64]; /* Phone Number (64 octets, null term.) */
++ u_int8_t subaddress[64]; /* Subaddress (64 octets, null term.) */
++};
++
++struct pptp_out_call_rply { /* for control message type 8 */
++ struct pptp_header header;
++ u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/
++ u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/
++ u_int8_t result_code; /* Result Code (1 is no errors) */
++ u_int8_t error_code; /* Error Code (=0 unless result_code==2) */
++ u_int16_t cause_code; /* Cause Code (addt'l failure information) */
++ u_int32_t speed; /* Connect Speed (in BPS) */
++ u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */
++ u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */
++ u_int32_t channel; /* Physical Channel ID (for logging) */
++};
++
++struct pptp_in_call_rqst { /* for control message type 9 */
++ struct pptp_header header;
++ u_int16_t call_id; /* Call ID (unique id used to multiplex data) */
++ u_int16_t call_sernum; /* Call Serial Number (used for logging) */
++ u_int32_t bearer; /* Bearer type */
++ u_int32_t channel; /* Physical Channel ID (for logging) */
++ u_int16_t dialed_len; /* Dialed Number Length (# of valid digits) */
++ u_int16_t dialing_len; /* Dialing Number Length (# of valid digits) */
++ u_int8_t dialed_num[64]; /* Dialed Number (64 octets, zero term.) */
++ u_int8_t dialing_num[64]; /* Dialing Number (64 octets, zero term.) */
++ u_int8_t subaddress[64]; /* Subaddress (64 octets, zero term.) */
++};
++
++struct pptp_in_call_rply { /* for control message type 10 */
++ struct pptp_header header;
++ u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/
++ u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/
++ u_int8_t result_code; /* Result Code (1 is no errors) */
++ u_int8_t error_code; /* Error Code (=0 unless result_code==2) */
++ u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */
++ u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */
++ u_int16_t reserved1; /* MUST BE ZERO */
++};
++
++struct pptp_in_call_connect { /* for control message type 11 */
++ struct pptp_header header;
++ u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/
++ u_int16_t reserved1; /* MUST BE ZERO */
++ u_int32_t speed; /* Connect Speed (in BPS) */
++ u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */
++ u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */
++ u_int32_t framing; /* Framing type */
++};
++
++struct pptp_call_clear_rqst { /* for control message type 12 */
++ struct pptp_header header;
++ u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/
++ u_int16_t reserved1; /* MUST BE ZERO */
++};
++
++struct pptp_call_clear_ntfy { /* for control message type 13 */
++ struct pptp_header header;
++ u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/
++ u_int8_t result_code; /* Result Code */
++ u_int8_t error_code; /* Error Code (=0 unless result_code==2) */
++ u_int16_t cause_code; /* Cause Code (for ISDN, is Q.931 cause code) */
++ u_int16_t reserved1; /* MUST BE ZERO */
++ u_int8_t call_stats[128]; /* Call Statistics: 128 octets, ascii, 0-term */
++};
++
++struct pptp_wan_err_ntfy { /* for control message type 14 */
++ struct pptp_header header;
++ u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/
++ u_int16_t reserved1; /* MUST BE ZERO */
++ u_int32_t crc_errors; /* CRC errors */
++ u_int32_t frame_errors; /* Framing errors */
++ u_int32_t hard_errors; /* Hardware overruns */
++ u_int32_t buff_errors; /* Buffer overruns */
++ u_int32_t time_errors; /* Time-out errors */
++ u_int32_t align_errors; /* Alignment errors */
++};
++
++struct pptp_set_link_info { /* for control message type 15 */
++ struct pptp_header header;
++ u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst) */
++ u_int16_t reserved1; /* MUST BE ZERO */
++ u_int32_t send_accm; /* Send ACCM (for PPP packets; default 0xFFFFFFFF)*/
++ u_int32_t recv_accm; /* Receive ACCM (for PPP pack.;default 0xFFFFFFFF)*/
++};
++
++/* helpful #defines: -------------------------------------------- */
++#define pptp_isvalid_ctrl(header, type, length) \
++ (!( ( ntoh16(((struct pptp_header *)header)->length) < (length) ) || \
++ ( ntoh16(((struct pptp_header *)header)->pptp_type) !=(type) ) || \
++ ( ntoh32(((struct pptp_header *)header)->magic) !=PPTP_MAGIC) || \
++ ( ntoh16(((struct pptp_header *)header)->ctrl_type) > PPTP_SET_LINK_INFO) || \
++ ( ntoh16(((struct pptp_header *)header)->reserved0) !=0 ) ))
++
++#define PPTP_HEADER_CTRL(type) \
++{ hton16(PPTP_CTRL_SIZE(type)), \
++ hton16(PPTP_MESSAGE_CONTROL), \
++ hton32(PPTP_MAGIC), \
++ hton16(type), 0 }
++
++#define PPTP_CTRL_SIZE(type) ( \
++(type==PPTP_START_CTRL_CONN_RQST)?sizeof(struct pptp_start_ctrl_conn): \
++(type==PPTP_START_CTRL_CONN_RPLY)?sizeof(struct pptp_start_ctrl_conn): \
++(type==PPTP_STOP_CTRL_CONN_RQST )?sizeof(struct pptp_stop_ctrl_conn): \
++(type==PPTP_STOP_CTRL_CONN_RPLY )?sizeof(struct pptp_stop_ctrl_conn): \
++(type==PPTP_ECHO_RQST )?sizeof(struct pptp_echo_rqst): \
++(type==PPTP_ECHO_RPLY )?sizeof(struct pptp_echo_rply): \
++(type==PPTP_OUT_CALL_RQST )?sizeof(struct pptp_out_call_rqst): \
++(type==PPTP_OUT_CALL_RPLY )?sizeof(struct pptp_out_call_rply): \
++(type==PPTP_IN_CALL_RQST )?sizeof(struct pptp_in_call_rqst): \
++(type==PPTP_IN_CALL_RPLY )?sizeof(struct pptp_in_call_rply): \
++(type==PPTP_IN_CALL_CONNECT )?sizeof(struct pptp_in_call_connect): \
++(type==PPTP_CALL_CLEAR_RQST )?sizeof(struct pptp_call_clear_rqst): \
++(type==PPTP_CALL_CLEAR_NTFY )?sizeof(struct pptp_call_clear_ntfy): \
++(type==PPTP_WAN_ERR_NTFY )?sizeof(struct pptp_wan_err_ntfy): \
++(type==PPTP_SET_LINK_INFO )?sizeof(struct pptp_set_link_info): \
++0)
++#define max(a,b) (((a)>(b))?(a):(b))
++#define PPTP_CTRL_SIZE_MAX ( \
++max(sizeof(struct pptp_start_ctrl_conn), \
++max(sizeof(struct pptp_echo_rqst), \
++max(sizeof(struct pptp_echo_rply), \
++max(sizeof(struct pptp_out_call_rqst), \
++max(sizeof(struct pptp_out_call_rply), \
++max(sizeof(struct pptp_in_call_rqst), \
++max(sizeof(struct pptp_in_call_rply), \
++max(sizeof(struct pptp_in_call_connect), \
++max(sizeof(struct pptp_call_clear_rqst), \
++max(sizeof(struct pptp_call_clear_ntfy), \
++max(sizeof(struct pptp_wan_err_ntfy), \
++max(sizeof(struct pptp_set_link_info), 0)))))))))))))
++
++
++/* gre header structure: -------------------------------------------- */
++
++#define PPTP_GRE_PROTO 0x880B
++#define PPTP_GRE_VER 0x1
++
++#define PPTP_GRE_FLAG_C 0x80
++#define PPTP_GRE_FLAG_R 0x40
++#define PPTP_GRE_FLAG_K 0x20
++#define PPTP_GRE_FLAG_S 0x10
++#define PPTP_GRE_FLAG_A 0x80
++
++#define PPTP_GRE_IS_C(f) ((f)&PPTP_GRE_FLAG_C)
++#define PPTP_GRE_IS_R(f) ((f)&PPTP_GRE_FLAG_R)
++#define PPTP_GRE_IS_K(f) ((f)&PPTP_GRE_FLAG_K)
++#define PPTP_GRE_IS_S(f) ((f)&PPTP_GRE_FLAG_S)
++#define PPTP_GRE_IS_A(f) ((f)&PPTP_GRE_FLAG_A)
++
++struct pptp_gre_header {
++ u_int8_t flags; /* bitfield */
++ u_int8_t ver; /* should be PPTP_GRE_VER (enhanced GRE) */
++ u_int16_t protocol; /* should be PPTP_GRE_PROTO (ppp-encaps) */
++ u_int16_t payload_len; /* size of ppp payload, not inc. gre header */
++ u_int16_t call_id; /* peer's call_id for this session */
++ u_int32_t seq; /* sequence number. Present if S==1 */
++ u_int32_t ack; /* seq number of highest packet recieved by */
++ /* sender in this session */
++};
++
++#endif /* INC_PPTP_H */
+--- /dev/null
++++ b/pppd/plugins/pptp/pptp_options.h
+@@ -0,0 +1,41 @@
++/* pptp_options.h ...... various constants used in the PPTP protocol.
++ * #define STANDARD to emulate NT 4.0 exactly.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: pptp_options.h,v 1.3 2004/11/09 01:42:32 quozl Exp $
++ */
++
++#ifndef INC_PPTP_OPTIONS_H
++#define INC_PPTP_OPTIONS_H
++
++#undef PPTP_FIRMWARE_STRING
++#undef PPTP_FIRMWARE_VERSION
++#define PPTP_BUF_MAX 65536
++#define PPTP_TIMEOUT 60 /* seconds */
++extern int idle_wait;
++extern int max_echo_wait;
++#define PPTP_CONNECT_SPEED 1000000000
++#define PPTP_WINDOW 3
++#define PPTP_DELAY 0
++#define PPTP_BPS_MIN 2400
++#define PPTP_BPS_MAX 1000000000
++
++#ifndef STANDARD
++#define PPTP_MAX_CHANNELS 65535
++#define PPTP_FIRMWARE_STRING "0.01"
++#define PPTP_FIRMWARE_VERSION 0x001
++#define PPTP_HOSTNAME {'l','o','c','a','l',0}
++#define PPTP_VENDOR {'c','a','n','a','n','i','a','n',0}
++#define PPTP_FRAME_CAP PPTP_FRAME_ANY
++#define PPTP_BEARER_CAP PPTP_BEARER_ANY
++#else
++#define PPTP_MAX_CHANNELS 5
++#define PPTP_FIRMWARE_STRING "0.01"
++#define PPTP_FIRMWARE_VERSION 0
++#define PPTP_HOSTNAME {'l','o','c','a','l',0}
++#define PPTP_VENDOR {'N','T',0}
++#define PPTP_FRAME_CAP 2
++#define PPTP_BEARER_CAP 1
++#endif
++
++#endif /* INC_PPTP_OPTIONS_H */
+--- /dev/null
++++ b/pppd/plugins/pptp/pptp_quirks.c
+@@ -0,0 +1,54 @@
++/* pptp_quirks.c ...... various options to fix quirks found in buggy adsl modems
++ * mulix <mulix@actcom.co.il>
++ *
++ * $Id: pptp_quirks.c,v 1.2 2001/11/23 03:42:51 quozl Exp $
++ */
++
++#include <string.h>
++#include "orckit_quirks.h"
++#include "pptp_quirks.h"
++
++static int quirk_index = -1;
++
++struct pptp_fixup pptp_fixups[] = {
++ {BEZEQ_ISRAEL, ORCKIT, ORCKIT_ATUR3,
++ orckit_atur3_build_hook,
++ orckit_atur3_start_ctrl_conn_hook,
++ orckit_atur3_set_link_hook}
++};
++
++static int fixups_sz = sizeof(pptp_fixups)/sizeof(pptp_fixups[0]);
++
++/* return 0 on success, non 0 otherwise */
++int set_quirk_index(int index)
++{
++ if (index >= 0 && index < fixups_sz) {
++ quirk_index = index;
++ return 0;
++ }
++
++ return -1;
++}
++
++int get_quirk_index()
++{
++ return quirk_index;
++}
++
++/* return the index for this isp in the quirks table, -1 if not found */
++int find_quirk(const char* isp_name)
++{
++ int i = 0;
++ if (isp_name) {
++ while (i < fixups_sz && pptp_fixups[i].isp) {
++ if (!strcmp(pptp_fixups[i].isp, isp_name)) {
++ return i;
++ }
++ ++i;
++ }
++ }
++
++ return -1;
++}
++
++
+--- /dev/null
++++ b/pppd/plugins/pptp/pptp_quirks.h
+@@ -0,0 +1,59 @@
++/* pptp_quirks.h ...... various options to fix quirks found in buggy adsl modems
++ * mulix <mulix@actcom.co.il>
++ *
++ * $Id: pptp_quirks.h,v 1.1 2001/11/20 06:30:10 quozl Exp $
++ */
++
++#ifndef INC_PPTP_QUIRKS_H
++#define INC_PPTP_QUIRKS_H
++
++/* isp defs - correspond to slots in the fixups table */
++#define BEZEQ_ISRAEL "BEZEQ_ISRAEL"
++
++/* vendor defs */
++
++#define ORCKIT 1
++#define ALCATEL 2
++
++/* device defs */
++
++#define ORCKIT_ATUR2 1
++#define ORCKIT_ATUR3 2
++
++#include "pptp_msg.h"
++#include "pptp_ctrl.h"
++
++struct pptp_fixup {
++ const char* isp; /* which isp? e.g. Bezeq in Israel */
++ int vendor; /* which vendor? e.g. Orckit */
++ int device; /* which device? e.g. Orckit Atur3 */
++
++ /* use this hook to build your own out call request packet */
++ int (*out_call_rqst_hook)(struct pptp_out_call_rqst* packet);
++
++ /* use this hook to build your own start control connection packet */
++ /* note that this hook is called from two different places, depending
++ on whether this is a request or reply */
++ int (*start_ctrl_conn)(struct pptp_start_ctrl_conn* packet);
++
++ /* use this hook if you need to send a 'set_link' packet once
++ the connection is established */
++ int (*set_link_hook)(struct pptp_set_link_info* packet,
++ int peer_call_id);
++};
++
++extern struct pptp_fixup pptp_fixups[];
++
++/* find the index for this isp in the quirks table */
++/* return the index on success, -1 if not found */
++int find_quirk(const char* isp_name);
++
++/* set the global quirk index. return 0 on success, non 0 otherwise */
++int set_quirk_index(int index);
++
++/* get the global quirk index. return the index on success,
++ -1 if no quirk is defined */
++int get_quirk_index();
++
++
++#endif /* INC_PPTP_QUIRKS_H */
+--- /dev/null
++++ b/pppd/plugins/pptp/util.c
+@@ -0,0 +1,109 @@
++/* util.c ....... error message utilities.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: util.c,v 1.11 2005/08/22 00:49:48 quozl Exp $
++ */
++
++#include <stdio.h>
++#include <stdarg.h>
++#include <syslog.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include "util.h"
++
++#define MAKE_STRING(label) \
++va_list ap; \
++char buf[256], string[256]; \
++va_start(ap, format); \
++vsnprintf(buf, sizeof(buf), format, ap); \
++snprintf(string, sizeof(string), "%s %s[%s:%s:%d]: %s", \
++ log_string, label, func, file, line, buf); \
++va_end(ap)
++
++/*** connect a file to a file descriptor **************************************/
++int file2fd(const char *path, const char *mode, int fd)
++{
++ int ok = 0;
++ FILE *file = NULL;
++ file = fopen(path, mode);
++ if (file != NULL && dup2(fileno(file), fd) != -1)
++ ok = 1;
++ if (file) fclose(file);
++ return ok;
++}
++
++/* signal to pipe delivery implementation */
++#include <unistd.h>
++#include <fcntl.h>
++#include <signal.h>
++#include <string.h>
++
++/* pipe private to process */
++static int sigpipe[2];
++
++/* create a signal pipe, returns 0 for success, -1 with errno for failure */
++int sigpipe_create()
++{
++ int rc;
++
++ rc = pipe(sigpipe);
++ if (rc < 0) return rc;
++
++ fcntl(sigpipe[0], F_SETFD, FD_CLOEXEC);
++ fcntl(sigpipe[1], F_SETFD, FD_CLOEXEC);
++
++#ifdef O_NONBLOCK
++#define FLAG_TO_SET O_NONBLOCK
++#else
++#ifdef SYSV
++#define FLAG_TO_SET O_NDELAY
++#else /* BSD */
++#define FLAG_TO_SET FNDELAY
++#endif
++#endif
++
++ rc = fcntl(sigpipe[1], F_GETFL);
++ if (rc != -1)
++ rc = fcntl(sigpipe[1], F_SETFL, rc | FLAG_TO_SET);
++ if (rc < 0) return rc;
++ return 0;
++#undef FLAG_TO_SET
++}
++
++/* generic handler for signals, writes signal number to pipe */
++void sigpipe_handler(int signum)
++{
++ write(sigpipe[1], &signum, sizeof(signum));
++ signal(signum, sigpipe_handler);
++}
++
++/* assign a signal number to the pipe */
++void sigpipe_assign(int signum)
++{
++ struct sigaction sa;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.sa_handler = sigpipe_handler;
++ sigaction(signum, &sa, NULL);
++}
++
++/* return the signal pipe read file descriptor for select(2) */
++int sigpipe_fd()
++{
++ return sigpipe[0];
++}
++
++/* read and return the pending signal from the pipe */
++int sigpipe_read()
++{
++ int signum;
++ read(sigpipe[0], &signum, sizeof(signum));
++ return signum;
++}
++
++void sigpipe_close()
++{
++ close(sigpipe[0]);
++ close(sigpipe[1]);
++}
++
+--- /dev/null
++++ b/pppd/plugins/pptp/util.h
+@@ -0,0 +1,31 @@
++/* util.h ....... error message utilities.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: util.h,v 1.6 2005/03/10 01:18:20 quozl Exp $
++ */
++
++#ifndef INC_UTIL_H
++#define INC_UTIL_H
++
++int file2fd(const char *path, const char *mode, int fd);
++
++/* signal to pipe delivery implementation */
++
++/* create a signal pipe, returns 0 for success, -1 with errno for failure */
++int sigpipe_create();
++
++/* generic handler for signals, writes signal number to pipe */
++void sigpipe_handler(int signum);
++
++/* assign a signal number to the pipe */
++void sigpipe_assign(int signum);
++
++/* return the signal pipe read file descriptor for select(2) */
++int sigpipe_fd();
++
++/* read and return the pending signal from the pipe */
++int sigpipe_read();
++
++void sigpipe_close();
++
++#endif /* INC_UTIL_H */
+--- /dev/null
++++ b/pppd/plugins/pptp/vector.c
+@@ -0,0 +1,209 @@
++/* vector.c ..... store a vector of PPTP_CALL information and search it
++ * efficiently.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: vector.c,v 1.3 2003/06/17 10:12:55 reink Exp $
++ */
++
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++#include "pptp_ctrl.h"
++#include "vector.h"
++/* #define VECTOR_DEBUG */
++#ifndef TRUE
++#define TRUE 1
++#endif
++#ifndef FALSE
++#define FALSE 0
++#endif
++
++struct vector_item {
++ int key;
++ PPTP_CALL *call;
++};
++
++struct vector_struct {
++ struct vector_item *item;
++ int size;
++ int alloc;
++#ifdef VECTOR_DEBUG
++ int key_max;
++#endif
++};
++
++static struct vector_item *binary_search(VECTOR *v, int key);
++
++/*** vector_create ************************************************************/
++VECTOR *vector_create()
++{
++ const int INITIAL_SIZE = 4;
++
++ VECTOR *v = malloc(sizeof(*v));
++ if (v == NULL) return v;
++
++ v->size = 0;
++ v->alloc = INITIAL_SIZE;
++ v->item = malloc(sizeof(*(v->item)) * (v->alloc));
++#ifdef VECTOR_DEBUG
++ v->key_max = -1;
++#endif
++ if (v->item == NULL) { free(v); return NULL; }
++ else return v;
++}
++
++/*** vector_destroy ***********************************************************/
++void vector_destroy(VECTOR *v)
++{
++ free(v->item);
++#ifdef VECTOR_DEBUG
++ v->item = NULL;
++#endif
++ free(v);
++}
++
++/*** vector_size **************************************************************/
++int vector_size(VECTOR *v)
++{
++ assert(v != NULL);
++ return v->size;
++}
++
++/*** vector_insert*************************************************************
++ * nice thing about file descriptors is that we are assured by POSIX
++ * that they are monotonically increasing.
++ */
++int vector_insert(VECTOR *v, int key, PPTP_CALL * call)
++{
++ int i;
++ assert(v != NULL && call != NULL);
++ assert(!vector_contains(v, key));
++#ifdef VECTOR_DEBUG
++ assert(v->key_max < key);
++#endif
++ if (!(v->size < v->alloc)) {
++ void *tmp = realloc(v->item, sizeof(*(v->item)) * 2 * v->alloc);
++ if (tmp != NULL) {
++ v->alloc *= 2;
++ v->item = tmp;
++ } else return FALSE; /* failed to alloc memory. */
++ }
++ assert(v->size < v->alloc);
++ /* for safety, we make this work in the general case;
++ * but this is optimized for adding call to the end of the vector.
++ */
++ for(i = v->size - 1; i >= 0; i--)
++ if (v->item[i].key < key)
++ break;
++ /* insert after item i */
++ memmove(&v->item[i + 2], &v->item[i + 1],
++ (v->size - i - 1) * sizeof(*(v->item)));
++ v->item[i + 1].key = key;
++ v->item[i + 1].call = call;
++ v->size++;
++#ifdef VECTOR_DEBUG
++ if (v->key_max < key) /* ie, always. */
++ v->key_max = key;
++#endif
++ return TRUE;
++}
++
++/*** vector_remove ************************************************************/
++int vector_remove(VECTOR *v, int key)
++{
++ struct vector_item *tmp;
++ assert(v != NULL);
++ if ((tmp =binary_search(v,key)) == NULL) return FALSE;
++ assert(tmp >= v->item && tmp < v->item + v->size);
++ memmove(tmp, tmp + 1, (v->size - (v->item - tmp) - 1) * sizeof(*(v->item)));
++ v->size--;
++ return TRUE;
++}
++
++/*** vector_search ************************************************************/
++int vector_search(VECTOR *v, int key, PPTP_CALL **call)
++{
++ struct vector_item *tmp;
++ assert(v != NULL);
++ tmp = binary_search(v, key);
++ if (tmp ==NULL) return FALSE;
++ *call = tmp->call;
++ return TRUE;
++}
++
++/*** vector_contains **********************************************************/
++int vector_contains(VECTOR *v, int key)
++{
++ assert(v != NULL);
++ return (binary_search(v, key) != NULL);
++}
++
++/*** vector_item **************************************************************/
++static struct vector_item *binary_search(VECTOR *v, int key)
++{
++ int l,r,x;
++ l = 0;
++ r = v->size - 1;
++ while (r >= l) {
++ x = (l + r)/2;
++ if (key < v->item[x].key) r = x - 1; else l = x + 1;
++ if (key == v->item[x].key) return &(v->item[x]);
++ }
++ return NULL;
++}
++
++/*** vector_scan ***************************************************************
++ * Hmm. Let's be fancy and use a binary search for the first
++ * unused key, taking advantage of the list is stored sorted; ie
++ * we can look at pointers and keys at two different locations,
++ * and if (ptr1 - ptr2) = (key1 - key2) then all the slots
++ * between ptr1 and ptr2 are filled. Note that ptr1-ptr2 should
++ * never be greater than key1-key2 (no duplicate keys!)... we
++ * check for this.
++ */
++int vector_scan(VECTOR *v, int lo, int hi, int *key)
++{
++ int l,r,x;
++ assert(v != NULL);
++ assert(key != NULL);
++ if ((v->size<1) || (lo < v->item[0].key)) { *key = lo; return TRUE; }
++ /* our array bounds */
++ l = 0; r = v->size - 1;
++ while (r > l) {
++ /* check for a free spot right after l */
++ if (v->item[l].key + 1 < v->item[l + 1].key) { /* found it! */
++ *key = v->item[l].key + 1;
++ return TRUE;
++ }
++ /* no dice. Let's see if the free spot is before or after the midpoint */
++ x = (l + r)/2;
++ /* Okay, we have right (r), left (l) and the probe (x). */
++ assert(x - l <= v->item[x].key - v->item[l].key);
++ assert(r - x <= v->item[r].key - v->item[x].key);
++ if (x - l < v->item[x].key - v->item[l].key)
++ /* room between l and x */
++ r = x;
++ else /* no room between l and x */
++ if (r - x < v->item[r].key - v->item[x].key)
++ /* room between x and r */
++ l = x;
++ else /* no room between x and r, either */
++ break; /* game over, man. */
++ }
++ /* no room found in already allocated space. Check to see if
++ * there's free space above allocated entries. */
++ if (v->item[v->size - 1].key < hi) {
++ *key = v->item[v->size - 1].key + 1;
++ return TRUE;
++ }
++ /* outta luck */
++ return FALSE;
++}
++
++/*** vector_get_Nth ***********************************************************/
++PPTP_CALL * vector_get_Nth(VECTOR *v, int n)
++{
++ assert(v != NULL);
++ assert(0 <= n && n < vector_size(v));
++ return v->item[n].call;
++}
+--- /dev/null
++++ b/pppd/plugins/pptp/vector.h
+@@ -0,0 +1,31 @@
++/* vector.h ..... store a vector of PPTP_CALL information and search it
++ * efficiently.
++ * C. Scott Ananian <cananian@alumni.princeton.edu>
++ *
++ * $Id: vector.h,v 1.1.1.1 2000/12/23 08:19:51 scott Exp $
++ */
++
++#ifndef INC_VECTOR_H
++#define INC_VECTOR_H
++
++#include "pptp_ctrl.h" /* for definition of PPTP_CALL */
++
++typedef struct vector_struct VECTOR;
++
++VECTOR *vector_create();
++void vector_destroy(VECTOR *v);
++
++int vector_size(VECTOR *v);
++
++/* vector_insert and vector_search return TRUE on success, FALSE on failure. */
++int vector_insert(VECTOR *v, int key, PPTP_CALL * call);
++int vector_remove(VECTOR *v, int key);
++int vector_search(VECTOR *v, int key, PPTP_CALL ** call);
++/* vector_contains returns FALSE if not found, TRUE if found. */
++int vector_contains(VECTOR *v, int key);
++/* find first unused key. Returns TRUE on success, FALSE if no. */
++int vector_scan(VECTOR *v, int lo, int hi, int *key);
++/* get a specific PPTP_CALL ... useful only when iterating. */
++PPTP_CALL * vector_get_Nth(VECTOR *v, int n);
++
++#endif /* INC_VECTOR_H */
diff --git a/package/network/services/ppp/patches/510-pptp_compile_fix.patch b/package/network/services/ppp/patches/510-pptp_compile_fix.patch
new file mode 100644
index 0000000..04bb620
--- /dev/null
+++ b/package/network/services/ppp/patches/510-pptp_compile_fix.patch
@@ -0,0 +1,11 @@
+--- a/pppd/plugins/pptp/pptp.c
++++ b/pppd/plugins/pptp/pptp.c
+@@ -48,7 +48,7 @@
+
+ #include "pptp_callmgr.h"
+ #include <net/if.h>
+-#include <net/ethernet.h>
++#include <linux/if_ether.h>
+ #include <linux/if_pppox.h>
+
+ #include <stdio.h>
diff --git a/package/network/services/ppp/patches/520-uniq.patch b/package/network/services/ppp/patches/520-uniq.patch
new file mode 100644
index 0000000..54c0d62
--- /dev/null
+++ b/package/network/services/ppp/patches/520-uniq.patch
@@ -0,0 +1,269 @@
+--- a/pppd/plugins/rp-pppoe/common.c
++++ b/pppd/plugins/rp-pppoe/common.c
+@@ -119,15 +119,11 @@ sendPADT(PPPoEConnection *conn, char con
+ conn->session = 0;
+
+ /* If we're using Host-Uniq, copy it over */
+- if (conn->useHostUniq) {
+- PPPoETag hostUniq;
+- pid_t pid = getpid();
+- hostUniq.type = htons(TAG_HOST_UNIQ);
+- hostUniq.length = htons(sizeof(pid));
+- memcpy(hostUniq.payload, &pid, sizeof(pid));
+- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
+- cursor += sizeof(pid) + TAG_HDR_SIZE;
+- plen += sizeof(pid) + TAG_HDR_SIZE;
++ if (conn->hostUniq.length) {
++ int len = ntohs(conn->hostUniq.length);
++ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
++ cursor += len + TAG_HDR_SIZE;
++ plen += len + TAG_HDR_SIZE;
+ }
+
+ /* Copy error message */
+--- a/pppd/plugins/rp-pppoe/discovery.c
++++ b/pppd/plugins/rp-pppoe/discovery.c
+@@ -80,13 +80,10 @@ static void
+ parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data,
+ void *extra)
+ {
+- int *val = (int *) extra;
+- if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) {
+- pid_t tmp;
+- memcpy(&tmp, data, len);
+- if (tmp == getpid()) {
+- *val = 1;
+- }
++ PPPoETag *tag = extra;
++
++ if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) {
++ tag->length = memcmp(data, tag->payload, len);
+ }
+ }
+
+@@ -104,16 +101,16 @@ parseForHostUniq(UINT16_t type, UINT16_t
+ static int
+ packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
+ {
+- int forMe = 0;
++ PPPoETag hostUniq = conn->hostUniq;
+
+ /* If packet is not directed to our MAC address, forget it */
+ if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
+
+ /* If we're not using the Host-Unique tag, then accept the packet */
+- if (!conn->useHostUniq) return 1;
++ if (!conn->hostUniq.length) return 1;
+
+- parsePacket(packet, parseForHostUniq, &forMe);
+- return forMe;
++ parsePacket(packet, parseForHostUniq, &hostUniq);
++ return (hostUniq.length == 0);
+ }
+
+ /**********************************************************************
+@@ -301,16 +298,12 @@ sendPADI(PPPoEConnection *conn)
+ }
+
+ /* If we're using Host-Uniq, copy it over */
+- if (conn->useHostUniq) {
+- PPPoETag hostUniq;
+- pid_t pid = getpid();
+- hostUniq.type = htons(TAG_HOST_UNIQ);
+- hostUniq.length = htons(sizeof(pid));
+- memcpy(hostUniq.payload, &pid, sizeof(pid));
+- CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
+- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
+- cursor += sizeof(pid) + TAG_HDR_SIZE;
+- plen += sizeof(pid) + TAG_HDR_SIZE;
++ if (conn->hostUniq.length) {
++ int len = ntohs(conn->hostUniq.length);
++ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
++ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
++ cursor += len + TAG_HDR_SIZE;
++ plen += len + TAG_HDR_SIZE;
+ }
+
+ /* Add our maximum MTU/MRU */
+@@ -478,16 +471,12 @@ sendPADR(PPPoEConnection *conn)
+ cursor += namelen + TAG_HDR_SIZE;
+
+ /* If we're using Host-Uniq, copy it over */
+- if (conn->useHostUniq) {
+- PPPoETag hostUniq;
+- pid_t pid = getpid();
+- hostUniq.type = htons(TAG_HOST_UNIQ);
+- hostUniq.length = htons(sizeof(pid));
+- memcpy(hostUniq.payload, &pid, sizeof(pid));
+- CHECK_ROOM(cursor, packet.payload, sizeof(pid)+TAG_HDR_SIZE);
+- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
+- cursor += sizeof(pid) + TAG_HDR_SIZE;
+- plen += sizeof(pid) + TAG_HDR_SIZE;
++ if (conn->hostUniq.length) {
++ int len = ntohs(conn->hostUniq.length);
++ CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE);
++ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
++ cursor += len + TAG_HDR_SIZE;
++ plen += len + TAG_HDR_SIZE;
+ }
+
+ /* Add our maximum MTU/MRU */
+--- a/pppd/plugins/rp-pppoe/plugin.c
++++ b/pppd/plugins/rp-pppoe/plugin.c
+@@ -65,6 +65,7 @@ static char *existingSession = NULL;
+ static int printACNames = 0;
+ static char *pppoe_reqd_mac = NULL;
+ unsigned char pppoe_reqd_mac_addr[6];
++static char *host_uniq = NULL;
+
+ static int PPPoEDevnameHook(char *cmd, char **argv, int doit);
+ static option_t Options[] = {
+@@ -82,6 +83,8 @@ static option_t Options[] = {
+ "Be verbose about discovered access concentrators"},
+ { "pppoe-mac", o_string, &pppoe_reqd_mac,
+ "Only connect to specified MAC address" },
++ { "host-uniq", o_string, &host_uniq,
++ "Specify custom Host-Uniq" },
+ { NULL }
+ };
+ int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL;
+@@ -107,7 +110,6 @@ PPPOEInitDevice(void)
+ conn->ifName = devnam;
+ conn->discoverySocket = -1;
+ conn->sessionSocket = -1;
+- conn->useHostUniq = 1;
+ conn->printACNames = printACNames;
+ conn->discoveryTimeout = PADI_TIMEOUT;
+ return 1;
+@@ -163,6 +165,9 @@ PPPOEConnectDevice(void)
+ if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
+ lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
+
++ if (host_uniq && !parseHostUniq(host_uniq, &conn->hostUniq))
++ fatal("Illegal value for host-uniq option");
++
+ conn->acName = acName;
+ conn->serviceName = pppd_pppoe_service;
+ strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
+--- a/pppd/plugins/rp-pppoe/pppoe-discovery.c
++++ b/pppd/plugins/rp-pppoe/pppoe-discovery.c
+@@ -344,7 +344,7 @@ packetIsForMe(PPPoEConnection *conn, PPP
+ if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
+
+ /* If we're not using the Host-Unique tag, then accept the packet */
+- if (!conn->useHostUniq) return 1;
++ if (!conn->hostUniq.length) return 1;
+
+ parsePacket(packet, parseForHostUniq, &forMe);
+ return forMe;
+@@ -470,16 +470,12 @@ sendPADI(PPPoEConnection *conn)
+ cursor += namelen + TAG_HDR_SIZE;
+
+ /* If we're using Host-Uniq, copy it over */
+- if (conn->useHostUniq) {
+- PPPoETag hostUniq;
+- pid_t pid = getpid();
+- hostUniq.type = htons(TAG_HOST_UNIQ);
+- hostUniq.length = htons(sizeof(pid));
+- memcpy(hostUniq.payload, &pid, sizeof(pid));
+- CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
+- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
+- cursor += sizeof(pid) + TAG_HDR_SIZE;
+- plen += sizeof(pid) + TAG_HDR_SIZE;
++ if (conn->hostUniq.length) {
++ int len = ntohs(conn->hostUniq.length);
++ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
++ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
++ cursor += len + TAG_HDR_SIZE;
++ plen += len + TAG_HDR_SIZE;
+ }
+
+ packet.length = htons(plen);
+@@ -641,7 +637,7 @@ int main(int argc, char *argv[])
+
+ memset(conn, 0, sizeof(PPPoEConnection));
+
+- while ((opt = getopt(argc, argv, "I:D:VUAS:C:h")) > 0) {
++ while ((opt = getopt(argc, argv, "I:D:VUW:AS:C:h")) > 0) {
+ switch(opt) {
+ case 'S':
+ conn->serviceName = xstrdup(optarg);
+@@ -650,7 +646,23 @@ int main(int argc, char *argv[])
+ conn->acName = xstrdup(optarg);
+ break;
+ case 'U':
+- conn->useHostUniq = 1;
++ if(conn->hostUniq.length) {
++ fprintf(stderr, "-U and -W are mutually exclusive\n");
++ exit(EXIT_FAILURE);
++ }
++ char pidbuf[5];
++ snprintf(pidbuf, sizeof(pidbuf), "%04x", getpid());
++ parseHostUniq(pidbuf, &conn->hostUniq);
++ break;
++ case 'W':
++ if(conn->hostUniq.length) {
++ fprintf(stderr, "-U and -W are mutually exclusive\n");
++ exit(EXIT_FAILURE);
++ }
++ if (!parseHostUniq(optarg, &conn->hostUniq)) {
++ fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg);
++ exit(EXIT_FAILURE);
++ }
+ break;
+ case 'D':
+ conn->debugFile = fopen(optarg, "w");
+--- a/pppd/plugins/rp-pppoe/pppoe.h
++++ b/pppd/plugins/rp-pppoe/pppoe.h
+@@ -21,6 +21,8 @@
+
+ #include <stdio.h> /* For FILE */
+ #include <sys/types.h> /* For pid_t */
++#include <ctype.h>
++#include <string.h>
+
+ /* How do we access raw Ethernet devices? */
+ #undef USE_LINUX_PACKET
+@@ -224,7 +226,7 @@ typedef struct PPPoEConnectionStruct {
+ char *serviceName; /* Desired service name, if any */
+ char *acName; /* Desired AC name, if any */
+ int synchronous; /* Use synchronous PPP */
+- int useHostUniq; /* Use Host-Uniq tag */
++ PPPoETag hostUniq; /* Use Host-Uniq tag */
+ int printACNames; /* Just print AC names */
+ FILE *debugFile; /* Debug file for dumping packets */
+ int numPADOs; /* Number of PADO packets received */
+@@ -280,6 +282,33 @@ void pppoe_printpkt(PPPoEPacket *packet,
+ void (*printer)(void *, char *, ...), void *arg);
+ void pppoe_log_packet(const char *prefix, PPPoEPacket *packet);
+
++static inline int parseHostUniq(const char *uniq, PPPoETag *tag)
++{
++ int i, len = strlen(uniq);
++
++#define hex(x) \
++ (((x) <= '9') ? ((x) - '0') : \
++ (((x) <= 'F') ? ((x) - 'A' + 10) : \
++ ((x) - 'a' + 10)))
++
++ if (len % 2)
++ return 0;
++
++ for (i = 0; i < len; i += 2)
++ {
++ if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1]))
++ return 0;
++
++ tag->payload[i / 2] = (char)(16 * hex(uniq[i]) + hex(uniq[i+1]));
++ }
++
++#undef hex
++
++ tag->type = htons(TAG_HOST_UNIQ);
++ tag->length = htons(len / 2);
++ return 1;
++}
++
+ #define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0);
+
+ #define CHECK_ROOM(cursor, start, len) \
diff --git a/package/network/services/ppp/patches/530-pppoe_send_padt.patch b/package/network/services/ppp/patches/530-pppoe_send_padt.patch
new file mode 100644
index 0000000..40fa420
--- /dev/null
+++ b/package/network/services/ppp/patches/530-pppoe_send_padt.patch
@@ -0,0 +1,11 @@
+--- a/pppd/plugins/rp-pppoe/plugin.c
++++ b/pppd/plugins/rp-pppoe/plugin.c
+@@ -275,7 +275,7 @@ PPPOEDisconnectDevice(void)
+ sizeof(struct sockaddr_pppox)) < 0)
+ error("Failed to disconnect PPPoE socket: %d %m", errno);
+ close(conn->sessionSocket);
+- /* don't send PADT?? */
++ sendPADT(conn, NULL);
+ if (conn->discoverySocket >= 0)
+ close(conn->discoverySocket);
+ }
diff --git a/package/network/services/ppp/patches/531-pppoe_no_disconnect_warning.patch b/package/network/services/ppp/patches/531-pppoe_no_disconnect_warning.patch
new file mode 100644
index 0000000..799e961
--- /dev/null
+++ b/package/network/services/ppp/patches/531-pppoe_no_disconnect_warning.patch
@@ -0,0 +1,14 @@
+--- a/pppd/plugins/rp-pppoe/plugin.c
++++ b/pppd/plugins/rp-pppoe/plugin.c
+@@ -271,9 +271,8 @@ PPPOEDisconnectDevice(void)
+ sp.sa_addr.pppoe.sid = 0;
+ memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ);
+ memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN);
+- if (connect(conn->sessionSocket, (struct sockaddr *) &sp,
+- sizeof(struct sockaddr_pppox)) < 0)
+- error("Failed to disconnect PPPoE socket: %d %m", errno);
++ connect(conn->sessionSocket, (struct sockaddr *) &sp,
++ sizeof(struct sockaddr_pppox));
+ close(conn->sessionSocket);
+ sendPADT(conn, NULL);
+ if (conn->discoverySocket >= 0)
diff --git a/package/network/services/ppp/patches/540-save-pppol2tp_fd_str.patch b/package/network/services/ppp/patches/540-save-pppol2tp_fd_str.patch
new file mode 100644
index 0000000..7dd2ad8
--- /dev/null
+++ b/package/network/services/ppp/patches/540-save-pppol2tp_fd_str.patch
@@ -0,0 +1,13 @@
+--- a/pppd/plugins/pppol2tp/pppol2tp.c
++++ b/pppd/plugins/pppol2tp/pppol2tp.c
+@@ -148,6 +148,10 @@ static int setdevname_pppol2tp(char **ar
+ fatal("PPPoL2TP kernel driver not installed");
+ }
+
++ pppol2tp_fd_str = strdup(*argv);
++ if (pppol2tp_fd_str == NULL)
++ novm("PPPoL2TP FD");
++
+ /* Setup option defaults. Compression options are disabled! */
+
+ modem = 0;
diff --git a/package/network/services/ppp/patches/550-fix-printer-args.patch b/package/network/services/ppp/patches/550-fix-printer-args.patch
new file mode 100644
index 0000000..0eed942
--- /dev/null
+++ b/package/network/services/ppp/patches/550-fix-printer-args.patch
@@ -0,0 +1,11 @@
+--- a/pppd/options.c
++++ b/pppd/options.c
+@@ -1013,7 +1013,7 @@ print_option(opt, mainopt, printer, arg)
+ p = (char *) opt->addr2;
+ if ((opt->flags & OPT_STATIC) == 0)
+ p = *(char **)p;
+- printer("%q", p);
++ printer(arg, "%q", p);
+ } else if (opt->flags & OPT_A2LIST) {
+ struct option_value *ovp;
+
diff --git a/package/network/services/ppp/utils/pfc.c b/package/network/services/ppp/utils/pfc.c
new file mode 100644
index 0000000..5476be1
--- /dev/null
+++ b/package/network/services/ppp/utils/pfc.c
@@ -0,0 +1,51 @@
+/*
+ * Taken from fli4l 3.0
+ * Make sure you compile it against the same libpcap version used in OpenWrt
+ */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <string.h>
+
+#include <linux/types.h>
+#include <linux/ppp_defs.h>
+
+#include <pcap.h>
+#include <pcap-bpf.h>
+
+int main (int argc, char ** argv)
+{
+ pcap_t *pc; /* Fake struct pcap so we can compile expr */
+ struct bpf_program filter; /* Filter program for link-active pkts */
+ u_int32_t netmask=0;
+
+ int dflag = 3;
+ if (argc == 4)
+ {
+ if (!strcmp (argv[1], "-d"))
+ {
+ dflag = atoi (argv[2]);
+ argv += 2;
+ argc -=2;
+ }
+ }
+ if (argc != 2)
+ {
+ printf ("usage; %s [ -d <debug_level> ] expression\n", argv[0]);
+ return 1;
+ }
+
+ pc = pcap_open_dead(DLT_PPP_PPPD, PPP_HDRLEN);
+ if (pcap_compile(pc, &filter, argv[1], 1, netmask) == 0)
+ {
+ printf ("#\n# Expression: %s\n#\n", argv[1]);
+ bpf_dump (&filter, dflag);
+ return 0;
+ }
+ else
+ {
+ printf("error in active-filter expression: %s\n", pcap_geterr(pc));
+ }
+ return 1;
+}
diff --git a/package/network/services/relayd/Makefile b/package/network/services/relayd/Makefile
new file mode 100644
index 0000000..8bfddba
--- /dev/null
+++ b/package/network/services/relayd/Makefile
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2010-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:=relayd
+PKG_VERSION:=2015-10-29
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=git://nbd.name/relayd.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=83dba5d525a3b7c2ae4fcb24961143bfcfc93ba7
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/relayd
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Routing and Redirection
+ TITLE:=Transparent routing / relay daemon
+ DEPENDS:=+libubox
+endef
+
+TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
+
+define Package/relayd/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/relayd $(1)/usr/sbin/relayd
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+ $(INSTALL_DATA) ./files/relay.hotplug $(1)/etc/hotplug.d/iface/30-relay
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/relay.init $(1)/etc/init.d/relayd
+endef
+
+$(eval $(call BuildPackage,relayd))
diff --git a/package/network/services/relayd/files/relay.hotplug b/package/network/services/relayd/files/relay.hotplug
new file mode 100644
index 0000000..afffbfe
--- /dev/null
+++ b/package/network/services/relayd/files/relay.hotplug
@@ -0,0 +1,2 @@
+#!/bin/sh
+/etc/init.d/relayd enabled && /etc/init.d/relayd start
diff --git a/package/network/services/relayd/files/relay.init b/package/network/services/relayd/files/relay.init
new file mode 100644
index 0000000..c628863
--- /dev/null
+++ b/package/network/services/relayd/files/relay.init
@@ -0,0 +1,115 @@
+#!/bin/sh /etc/rc.common
+# Copyright (c) 2011-2012 OpenWrt.org
+
+START=80
+
+USE_PROCD=1
+PROG=/usr/sbin/relayd
+
+validate_proto_relayd()
+{
+ uci_validate_section network "interface" "${1}" \
+ 'network:list(string)' \
+ 'expiry:uinteger:30' \
+ 'retry:uinteger:5' \
+ 'table:range(0, 65535):16800' \
+ 'forward_bcast:bool:1' \
+ 'forward_dhcp:bool:1'
+}
+
+resolve_ifname() {
+ grep -qs "^ *$1:" /proc/net/dev && {
+ procd_append_param command -I "$1"
+ append ifaces "$1"
+ }
+}
+
+resolve_network() {
+ local ifn
+ fixup_interface "$1"
+ config_get ifn "$1" ifname
+ [ -z "$ifn" ] && return 1
+ resolve_ifname "$ifn"
+}
+
+start_relay() {
+ local cfg="$1"
+
+ local args=""
+ local ifaces=""
+
+ config_get proto "$cfg" proto
+ [ "$proto" = "relay" ] || return 0
+
+ config_get_bool disabled "$cfg" disabled 0
+ [ "$disabled" -gt 0 ] && return 0
+
+ SERVICE_DAEMONIZE=1
+ SERVICE_WRITE_PID=1
+ SERVICE_PID_FILE="/var/run/relay-$cfg.pid"
+ [ -f "$SERVICE_PID_FILE" ] && {
+ if grep -q relayd "/proc/$(cat $SERVICE_PID_FILE)/cmdline"; then
+ return 0
+ else
+ rm -f "$SERVICE_PID_FILE"
+ fi
+ }
+
+ procd_open_instance
+ procd_set_param command "$PROG"
+
+ local net networks
+ config_get networks "$cfg" network
+ for net in $networks; do
+ resolve_network "$net" || {
+ return 1
+ }
+ done
+
+ local ifn ifnames
+ config_get ifnames "$cfg" ifname
+ for ifn in $ifnames; do
+ resolve_ifname "$ifn"
+ done
+
+ local ipaddr
+ config_get ipaddr "$cfg" ipaddr
+ [ -n "$ipaddr" ] && procd_append_param command -L "$ipaddr"
+
+ local gateway
+ config_get gateway "$cfg" gateway
+ [ -n "$gateway" ] && procd_append_param command -G "$gateway"
+
+ local expiry # = 30
+ config_get expiry "$cfg" expiry
+ [ -n "$expiry" ] && procd_append_param command "$expiry"
+
+ local retry # = 5
+ config_get retry "$cfg" retry
+ [ -n "$retry" ] && procd_append_param command -p "$retry"
+
+ local table # = 16800
+ config_get table "$cfg" table
+ [ -n "$table" ] && procd_append_param command -T "$table"
+
+ local fwd_bcast # = 1
+ config_get_bool fwd_bcast "$cfg" forward_bcast 1
+ [ $fwd_bcast -eq 1 ] && procd_append_param command "-B"
+
+ local fwd_dhcp # = 1
+ config_get_bool fwd_dhcp "$cfg" forward_dhcp 1
+ [ $fwd_dhcp -eq 1 ] && procd_append_param command "-D"
+
+ procd_close_instance
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger "network"
+}
+
+start_service() {
+ include /lib/network
+ config_load network
+ config_foreach start_relay interface
+}
diff --git a/package/network/services/samba36/Makefile b/package/network/services/samba36/Makefile
new file mode 100644
index 0000000..9e282f0
--- /dev/null
+++ b/package/network/services/samba36/Makefile
@@ -0,0 +1,160 @@
+#
+# Copyright (C) 2007-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:=samba
+PKG_VERSION:=3.6.25
+PKG_RELEASE:=4
+
+PKG_SOURCE_URL:=http://ftp.samba.org/pub/samba \
+ http://ftp.samba.org/pub/samba/stable
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_MD5SUM:=76da2fa64edd94a0188531e7ecb27c4e
+
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+MAKE_PATH:=source3
+CONFIGURE_PATH:=source3
+
+PKG_BUILD_BIN:=$(PKG_BUILD_DIR)/$(MAKE_PATH)/bin
+
+define Package/samba36-server
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Samba 3.6 SMB/CIFS server
+ URL:=http://www.samba.org/
+ DEPENDS:=+USE_GLIBC:librt $(ICONV_DEPENDS)
+endef
+
+define Package/samba36-client
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Samba 3.6 SMB/CIFS client
+ URL:=http://www.samba.org/
+ DEPENDS:=+libreadline +libncurses
+endef
+
+define Package/samba36-server/config
+ config PACKAGE_SAMBA_MAX_DEBUG_LEVEL
+ int "Maximum level of compiled-in debug messages"
+ depends on PACKAGE_samba36-server || PACKAGE_samba36-client
+ default -1
+
+endef
+
+define Package/samba36-server/description
+ The Samba software suite is a collection of programs that implements the
+ SMB protocol for UNIX systems, allowing you to serve files and printers to
+ Windows, NT, OS/2 and DOS clients. This protocol is sometimes also referred
+ to as the LanManager or Netbios protocol.
+endef
+
+TARGET_CFLAGS += -DMAX_DEBUG_LEVEL=$(CONFIG_PACKAGE_SAMBA_MAX_DEBUG_LEVEL) -D__location__=\\\"\\\" -ffunction-sections -fdata-sections
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+CONFIGURE_VARS += \
+ ac_cv_lib_attr_getxattr=no \
+ ac_cv_search_getxattr=no \
+ ac_cv_file__proc_sys_kernel_core_pattern=yes \
+ libreplace_cv_HAVE_C99_VSNPRINTF=yes \
+ libreplace_cv_HAVE_GETADDRINFO=yes \
+ libreplace_cv_HAVE_IFACE_IFCONF=yes \
+ LINUX_LFS_SUPPORT=yes \
+ samba_cv_CC_NEGATIVE_ENUM_VALUES=yes \
+ samba_cv_HAVE_GETTIMEOFDAY_TZ=yes \
+ samba_cv_HAVE_IFACE_IFCONF=yes \
+ samba_cv_HAVE_KERNEL_OPLOCKS_LINUX=yes \
+ samba_cv_HAVE_SECURE_MKSTEMP=yes \
+ samba_cv_HAVE_WRFILE_KEYTAB=no \
+ samba_cv_USE_SETREUID=yes \
+ samba_cv_USE_SETRESUID=yes \
+ samba_cv_have_setreuid=yes \
+ samba_cv_have_setresuid=yes \
+ ac_cv_header_zlib_h=no \
+ samba_cv_zlib_1_2_3=no \
+ ac_cv_path_PYTHON="" \
+ ac_cv_path_PYTHON_CONFIG=""
+
+CONFIGURE_ARGS += \
+ --exec-prefix=/usr \
+ --prefix=/ \
+ --disable-avahi \
+ --disable-cups \
+ --disable-pie \
+ --disable-relro \
+ --disable-static \
+ --disable-swat \
+ --disable-shared-libs \
+ --with-libiconv="$(ICONV_PREFIX)" \
+ --with-codepagedir=/etc/samba \
+ --with-configdir=/etc/samba \
+ --with-included-iniparser \
+ --with-included-popt \
+ --with-lockdir=/var/lock \
+ --with-logfilebase=/var/log \
+ --with-nmbdsocketdir=/var/nmbd \
+ --with-piddir=/var/run \
+ --with-privatedir=/etc/samba \
+ --with-sendfile-support \
+ --without-acl-support \
+ --without-cluster-support \
+ --without-ads \
+ --without-krb5 \
+ --without-ldap \
+ --without-pam \
+ --without-winbind \
+ --without-libtdb \
+ --without-libtalloc \
+ --without-libnetapi \
+ --without-libsmbclient \
+ --without-libsmbsharemodes \
+ --without-libtevent \
+ --without-libaddns \
+ --with-shared-modules=pdb_tdbsam,pdb_wbc_sam,idmap_nss,nss_info_template,auth_winbind,auth_wbc,auth_domain
+
+MAKE_FLAGS += DYNEXP= PICFLAG= MODULES=
+
+define Package/samba36-server/conffiles
+/etc/config/samba
+/etc/samba/smb.conf.template
+/etc/samba/smbpasswd
+endef
+
+define Package/samba36-server/install
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_CONF) ./files/samba.config $(1)/etc/config/samba
+ $(INSTALL_DIR) $(1)/etc/samba
+ $(INSTALL_DATA) ./files/smb.conf.template $(1)/etc/samba
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/codepages/lowcase.dat $(1)/etc/samba
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/codepages/upcase.dat $(1)/etc/samba
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/codepages/valid.dat $(1)/etc/samba
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/samba.init $(1)/etc/init.d/samba
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_BIN)/samba_multicall $(1)/usr/sbin
+ $(LN) samba_multicall $(1)/usr/sbin/smbd
+ $(LN) samba_multicall $(1)/usr/sbin/nmbd
+ $(LN) samba_multicall $(1)/usr/sbin/smbpasswd
+endef
+
+define Package/samba36-client/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_BIN)/smbclient $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_BIN)/nmblookup $(1)/usr/sbin
+endef
+
+$(eval $(call BuildPackage,samba36-client))
+$(eval $(call BuildPackage,samba36-server))
+
diff --git a/package/network/services/samba36/files/samba.config b/package/network/services/samba36/files/samba.config
new file mode 100644
index 0000000..c79db0d
--- /dev/null
+++ b/package/network/services/samba36/files/samba.config
@@ -0,0 +1,6 @@
+config samba
+ option 'name' 'OpenWrt'
+ option 'workgroup' 'WORKGROUP'
+ option 'description' 'OpenWrt'
+ option 'homes' '1'
+
diff --git a/package/network/services/samba36/files/samba.init b/package/network/services/samba36/files/samba.init
new file mode 100755
index 0000000..376ae89
--- /dev/null
+++ b/package/network/services/samba36/files/samba.init
@@ -0,0 +1,118 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2008-2012 OpenWrt.org
+
+START=60
+USE_PROCD=1
+
+smb_header() {
+ local interface
+ config_get interface $1 interface "loopback lan"
+
+ # resolve interfaces
+ local interfaces=$(
+ . /lib/functions/network.sh
+
+ local net
+ for net in $interface; do
+ local device
+ network_get_device device "$net" && {
+ local subnet
+ network_get_subnet subnet "$net" && echo -n "$subnet "
+ network_get_subnet6 subnet "$net" && echo -n "$subnet "
+ }
+
+ echo -n "${device:-$net} "
+ done
+ )
+
+ local name workgroup description charset
+ local hostname="$(uci_get system.@system[0].hostname)"
+
+ config_get name $1 name "${hostname:-OpenWrt}"
+ config_get workgroup $1 workgroup "${hostname:-OpenWrt}"
+ config_get description $1 description "Samba on ${hostname:-OpenWrt}"
+ config_get charset $1 charset "UTF-8"
+
+ mkdir -p /var/etc
+ sed -e "s#|NAME|#$name#g" \
+ -e "s#|WORKGROUP|#$workgroup#g" \
+ -e "s#|DESCRIPTION|#$description#g" \
+ -e "s#|INTERFACES|#$interfaces#g" \
+ -e "s#|CHARSET|#$charset#g" \
+ /etc/samba/smb.conf.template > /var/etc/smb.conf
+
+ local homes
+ config_get_bool homes $1 homes 0
+ [ $homes -gt 0 ] && {
+ cat <<EOT >> /var/etc/smb.conf
+
+[homes]
+ comment = Home Directories
+ browsable = no
+ read only = no
+ create mode = 0750
+EOT
+ }
+
+ [ -L /etc/samba/smb.conf ] || ln -nsf /var/etc/smb.conf /etc/samba/smb.conf
+}
+
+smb_add_share() {
+ local name
+ local path
+ local users
+ local read_only
+ local guest_ok
+ local create_mask
+ local dir_mask
+ local browseable
+
+ config_get name $1 name
+ config_get path $1 path
+ config_get users $1 users
+ config_get read_only $1 read_only
+ config_get guest_ok $1 guest_ok
+ config_get create_mask $1 create_mask
+ config_get dir_mask $1 dir_mask
+ config_get browseable $1 browseable
+
+ [ -z "$name" -o -z "$path" ] && return
+
+ echo -e "\n[$name]\n\tpath = $path" >> /var/etc/smb.conf
+ [ -n "$users" ] && echo -e "\tvalid users = $users" >> /var/etc/smb.conf
+ [ -n "$read_only" ] && echo -e "\tread only = $read_only" >> /var/etc/smb.conf
+ [ -n "$guest_ok" ] && echo -e "\tguest ok = $guest_ok" >> /var/etc/smb.conf
+ [ -n "$create_mask" ] && echo -e "\tcreate mask = $create_mask" >> /var/etc/smb.conf
+ [ -n "$dir_mask" ] && echo -e "\tdirectory mask = $dir_mask" >> /var/etc/smb.conf
+ [ -n "$browseable" ] && echo -e "\tbrowseable = $browseable" >> /var/etc/smb.conf
+}
+
+init_config() {
+ config_load samba
+ config_foreach smb_header samba
+ config_foreach smb_add_share sambashare
+}
+
+reload_service() {
+ init_config
+
+ killall -HUP smbd
+}
+
+service_triggers() {
+ procd_add_reload_trigger samba
+}
+
+start_service() {
+ init_config
+
+ procd_open_instance
+ procd_set_param command /usr/sbin/smbd -F
+ procd_set_param respawn
+ procd_close_instance
+
+ procd_open_instance
+ procd_set_param command /usr/sbin/nmbd -F
+ procd_set_param respawn
+ procd_close_instance
+}
diff --git a/package/network/services/samba36/files/smb.conf.template b/package/network/services/samba36/files/smb.conf.template
new file mode 100644
index 0000000..38a3855
--- /dev/null
+++ b/package/network/services/samba36/files/smb.conf.template
@@ -0,0 +1,34 @@
+[global]
+ netbios name = |NAME|
+ display charset = |CHARSET|
+ interfaces = |INTERFACES|
+ server string = |DESCRIPTION|
+ unix charset = |CHARSET|
+ workgroup = |WORKGROUP|
+ browseable = yes
+ deadtime = 30
+ domain master = yes
+ encrypt passwords = true
+ enable core files = no
+ guest account = nobody
+ guest ok = yes
+ invalid users = root
+ local master = yes
+ load printers = no
+ map to guest = Bad User
+ max protocol = SMB2
+ min receivefile size = 16384
+ null passwords = yes
+ obey pam restrictions = yes
+ os level = 20
+ passdb backend = smbpasswd
+ preferred master = yes
+ printable = no
+ security = user
+ smb encrypt = disabled
+ smb passwd file = /etc/samba/smbpasswd
+ socket options = TCP_NODELAY IPTOS_LOWDELAY
+ syslog = 2
+ use sendfile = yes
+ writeable = yes
+
diff --git a/package/network/services/samba36/patches/100-configure_fixes.patch b/package/network/services/samba36/patches/100-configure_fixes.patch
new file mode 100644
index 0000000..16e35c8
--- /dev/null
+++ b/package/network/services/samba36/patches/100-configure_fixes.patch
@@ -0,0 +1,14 @@
+--- a/source3/configure
++++ b/source3/configure
+@@ -13294,10 +13294,7 @@ if test x"$libreplace_cv_HAVE_GETADDRINF
+ # see bug 5910, use our replacements if we detect
+ # a broken system.
+ if test "$cross_compiling" = yes; then :
+- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "cannot run test program while cross compiling
+-See \`config.log' for more details" "$LINENO" 5; }
++ $as_echo "assuming valid getaddrinfo without bug 5910" >&2
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
diff --git a/package/network/services/samba36/patches/110-multicall.patch b/package/network/services/samba36/patches/110-multicall.patch
new file mode 100644
index 0000000..22e6a3c
--- /dev/null
+++ b/package/network/services/samba36/patches/110-multicall.patch
@@ -0,0 +1,119 @@
+--- a/source3/Makefile.in
++++ b/source3/Makefile.in
+@@ -73,22 +73,22 @@ LDAP_LIBS=@LDAP_LIBS@
+ NSCD_LIBS=@NSCD_LIBS@
+ UUID_LIBS=@UUID_LIBS@
+ LIBWBCLIENT=@LIBWBCLIENT_STATIC@ @LIBWBCLIENT_SHARED@
+-LIBWBCLIENT_LIBS=@LIBWBCLIENT_LIBS@
++LIBWBCLIENT_LIBS=@LIBWBCLIENT_STATIC@
+ PTHREAD_LDFLAGS=@PTHREAD_LDFLAGS@
+ PTHREAD_CFLAGS=@PTHREAD_CFLAGS@
+ DNSSD_LIBS=@DNSSD_LIBS@
+ AVAHI_LIBS=@AVAHI_LIBS@
+ POPT_LIBS=@POPTLIBS@
+ LIBTALLOC=@LIBTALLOC_STATIC@ @LIBTALLOC_SHARED@
+-LIBTALLOC_LIBS=@LIBTALLOC_LIBS@
++LIBTALLOC_LIBS=@LIBTALLOC_STATIC@
+ LIBTEVENT=@LIBTEVENT_STATIC@ @LIBTEVENT_SHARED@
+ LIBTEVENT_LIBS=@LIBTEVENT_LIBS@
+ LIBREPLACE_LIBS=@LIBREPLACE_LIBS@
+ LIBTDB=@LIBTDB_STATIC@ @LIBTDB_SHARED@
+-LIBTDB_LIBS=@LIBTDB_LIBS@
++LIBTDB_LIBS=@LIBTDB_STATIC@
+ TDB_DEPS=@TDB_DEPS@
+ LIBNETAPI=@LIBNETAPI_STATIC@ @LIBNETAPI_SHARED@
+-LIBNETAPI_LIBS=@LIBNETAPI_LIBS@
++LIBNETAPI_LIBS=@LIBNETAPI_STATIC@
+ LIBSMBCLIENT_LIBS=@LIBSMBCLIENT_LIBS@
+ LIBSMBSHAREMODES_LIBS=@LIBSMBSHAREMODES_LIBS@
+
+@@ -216,7 +216,7 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_P
+
+ # Note that all executable programs now provide for an optional executable suffix.
+
+-SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ @SWAT_SBIN_TARGETS@ @EXTRA_SBIN_PROGS@
++SBIN_PROGS = bin/samba_multicall@EXEEXT@ bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ @SWAT_SBIN_TARGETS@ @EXTRA_SBIN_PROGS@
+
+ BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \
+ bin/testparm@EXEEXT@ bin/smbstatus@EXEEXT@ bin/smbget@EXEEXT@ \
+@@ -1777,6 +1777,42 @@ bin/.dummy:
+ dir=bin $(MAKEDIR); fi
+ @: >> $@ || : > $@ # what a fancy emoticon!
+
++smbd/server_multicall.o: smbd/server.c smbd/server.o
++ @echo Compiling $<.c
++ @$(COMPILE_CC_PATH) -Dmain=smbd_main && exit 0;\
++ echo "The following command failed:" 1>&2;\
++ echo "$(COMPILE_CC_PATH)" 1>&2;\
++ $(COMPILE_CC_PATH) >/dev/null 2>&1
++
++nmbd/nmbd_multicall.o: nmbd/nmbd.c nmbd/nmbd.o
++ @echo Compiling $<.c
++ @$(COMPILE_CC_PATH) -Dmain=nmbd_main && exit 0;\
++ echo "The following command failed:" 1>&2;\
++ echo "$(COMPILE_CC_PATH)" 1>&2;\
++ $(COMPILE_CC_PATH) >/dev/null 2>&1
++
++utils/smbpasswd_multicall.o: utils/smbpasswd.c utils/smbpasswd.o
++ @echo Compiling $<.c
++ @$(COMPILE_CC_PATH) -Dmain=smbpasswd_main && exit 0;\
++ echo "The following command failed:" 1>&2;\
++ echo "$(COMPILE_CC_PATH)" 1>&2;\
++ $(COMPILE_CC_PATH) >/dev/null 2>&1
++
++SMBD_MULTI_O = $(patsubst smbd/server.o,smbd/server_multicall.o,$(SMBD_OBJ))
++NMBD_MULTI_O = $(patsubst nmbd/nmbd.o,nmbd/nmbd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(NMBD_OBJ)))
++SMBPASSWD_MULTI_O = $(patsubst utils/smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ)))
++MULTI_O = multi.o
++
++MULTICALL_O = $(sort $(SMBD_MULTI_O) $(NMBD_MULTI_O) $(SMBPASSWD_MULTI_O) $(MULTI_O))
++
++bin/samba_multicall@EXEEXT@: $(BINARY_PREREQS) $(MULTICALL_O) $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @BUILD_POPT@
++ @echo Linking $@
++ @$(CC) -o $@ $(MULTICALL_O) $(LDFLAGS) $(LDAP_LIBS) @SMBD_FAM_LIBS@ \
++ $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
++ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) $(AVAHI_LIBS) \
++ $(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTEVENT_LIBS) $(LIBTDB_LIBS) \
++ $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS)
++
+ bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) $(LIBTALLOC) $(LIBTEVENT) $(LIBTDB) $(LIBWBCLIENT) @BUILD_POPT@
+ @echo Linking $@
+ @$(CC) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) @SMBD_FAM_LIBS@ \
+--- /dev/null
++++ b/source3/multi.c
+@@ -0,0 +1,35 @@
++#include <stdio.h>
++#include <string.h>
++
++extern int smbd_main(int argc, char **argv);
++extern int nmbd_main(int argc, char **argv);
++extern int smbpasswd_main(int argc, char **argv);
++
++static struct {
++ const char *name;
++ int (*func)(int argc, char **argv);
++} multicall[] = {
++ { "smbd", smbd_main },
++ { "nmbd", nmbd_main },
++ { "smbpasswd", smbpasswd_main },
++};
++
++#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
++
++int main(int argc, char **argv)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(multicall); i++) {
++ if (strstr(argv[0], multicall[i].name))
++ return multicall[i].func(argc, argv);
++ }
++
++ fprintf(stderr, "Invalid multicall command, available commands:");
++ for (i = 0; i < ARRAY_SIZE(multicall); i++)
++ fprintf(stderr, " %s", multicall[i].name);
++
++ fprintf(stderr, "\n");
++
++ return 1;
++}
diff --git a/package/network/services/samba36/patches/111-owrt_smbpasswd.patch b/package/network/services/samba36/patches/111-owrt_smbpasswd.patch
new file mode 100644
index 0000000..79abea5
--- /dev/null
+++ b/package/network/services/samba36/patches/111-owrt_smbpasswd.patch
@@ -0,0 +1,281 @@
+--- a/source3/Makefile.in
++++ b/source3/Makefile.in
+@@ -1019,7 +1019,7 @@ TEST_LP_LOAD_OBJ = param/test_lp_load.o
+
+ PASSWD_UTIL_OBJ = utils/passwd_util.o
+
+-SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \
++SMBPASSWD_OBJ = utils/owrt_smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
+ $(GROUPDB_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
+ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) \
+@@ -1791,7 +1791,7 @@ nmbd/nmbd_multicall.o: nmbd/nmbd.c nmbd/
+ echo "$(COMPILE_CC_PATH)" 1>&2;\
+ $(COMPILE_CC_PATH) >/dev/null 2>&1
+
+-utils/smbpasswd_multicall.o: utils/smbpasswd.c utils/smbpasswd.o
++utils/smbpasswd_multicall.o: utils/owrt_smbpasswd.c utils/owrt_smbpasswd.o
+ @echo Compiling $<.c
+ @$(COMPILE_CC_PATH) -Dmain=smbpasswd_main && exit 0;\
+ echo "The following command failed:" 1>&2;\
+@@ -1800,7 +1800,7 @@ utils/smbpasswd_multicall.o: utils/smbpa
+
+ SMBD_MULTI_O = $(patsubst smbd/server.o,smbd/server_multicall.o,$(SMBD_OBJ))
+ NMBD_MULTI_O = $(patsubst nmbd/nmbd.o,nmbd/nmbd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(NMBD_OBJ)))
+-SMBPASSWD_MULTI_O = $(patsubst utils/smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ)))
++SMBPASSWD_MULTI_O = $(patsubst utils/owrt_smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ)))
+ MULTI_O = multi.o
+
+ MULTICALL_O = $(sort $(SMBD_MULTI_O) $(NMBD_MULTI_O) $(SMBPASSWD_MULTI_O) $(MULTI_O))
+--- /dev/null
++++ b/source3/utils/owrt_smbpasswd.c
+@@ -0,0 +1,249 @@
++/*
++ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
++ *
++ * 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., 675
++ * Mass Ave, Cambridge, MA 02139, USA. */
++
++#include "includes.h"
++#include <endian.h>
++#include <stdio.h>
++
++static char buf[256];
++
++static void md4hash(const char *passwd, uchar p16[16])
++{
++ int len;
++ smb_ucs2_t wpwd[129];
++ int i;
++
++ len = strlen(passwd);
++ for (i = 0; i < len; i++) {
++#if __BYTE_ORDER == __LITTLE_ENDIAN
++ wpwd[i] = (unsigned char)passwd[i];
++#else
++ wpwd[i] = (unsigned char)passwd[i] << 8;
++#endif
++ }
++ wpwd[i] = 0;
++
++ len = len * sizeof(int16);
++ mdfour(p16, (unsigned char *)wpwd, len);
++ ZERO_STRUCT(wpwd);
++}
++
++
++static bool find_passwd_line(FILE *fp, const char *user, char **next)
++{
++ char *p1;
++
++ while (!feof(fp)) {
++ if(!fgets(buf, sizeof(buf) - 1, fp))
++ continue;
++
++ p1 = strchr(buf, ':');
++
++ if (p1 - buf != strlen(user))
++ continue;
++
++ if (strncmp(buf, user, p1 - buf) != 0)
++ continue;
++
++ if (next)
++ *next = p1;
++ return true;
++ }
++ return false;
++}
++
++/* returns -1 if user is not present in /etc/passwd*/
++static int find_uid_for_user(const char *user)
++{
++ FILE *fp;
++ char *p1, *p2, *p3;
++ int ret = -1;
++
++ fp = fopen("/etc/passwd", "r");
++ if (!fp) {
++ printf("failed to open /etc/passwd");
++ goto out;
++ }
++
++ if (!find_passwd_line(fp, user, &p1)) {
++ printf("User %s not found or invalid in /etc/passwd\n", user);
++ goto out;
++ }
++
++ p2 = strchr(p1 + 1, ':');
++ if (!p2)
++ goto out;
++
++ p2++;
++ p3 = strchr(p2, ':');
++ if (!p1)
++ goto out;
++
++ *p3 = '\0';
++ ret = atoi(p2);
++
++out:
++ if(fp)
++ fclose(fp);
++ return ret;
++}
++
++static void smbpasswd_write_user(FILE *fp, const char *user, int uid, const char *password)
++{
++ static uchar nt_p16[NT_HASH_LEN];
++ int len = 0;
++ int i;
++
++ md4hash(strdup(password), nt_p16);
++
++ len += snprintf(buf + len, sizeof(buf) - len, "%s:%u:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:", user, uid);
++ for(i = 0; i < NT_HASH_LEN; i++)
++ len += snprintf(buf + len, sizeof(buf) - len, "%02X", nt_p16[i]);
++
++ snprintf(buf + len, sizeof(buf) - len, ":[U ]:LCT-00000001:\n");
++ fputs(buf, fp);
++}
++
++static void smbpasswd_delete_user(FILE *fp)
++{
++ fpos_t r_pos, w_pos;
++ int len = strlen(buf);
++
++ fgetpos(fp, &r_pos);
++ fseek(fp, -len, SEEK_CUR);
++ fgetpos(fp, &w_pos);
++ fsetpos(fp, &r_pos);
++
++ while (fgets(buf, sizeof(buf) - 1, fp)) {
++ int cur_len = strlen(buf);
++
++ fsetpos(fp, &w_pos);
++ fputs(buf, fp);
++ fgetpos(fp, &w_pos);
++
++ fsetpos(fp, &r_pos);
++ fseek(fp, cur_len, SEEK_CUR);
++ fgetpos(fp, &r_pos);
++ }
++
++ fsetpos(fp, &w_pos);
++ ftruncate(fileno(fp), ftello(fp));
++}
++
++static int usage(const char *progname)
++{
++ fprintf(stderr,
++ "Usage: %s [options] <username>\n"
++ "\n"
++ "Options:\n"
++ " -s read password from stdin\n"
++ " -a add user\n"
++ " -x delete user\n",
++ progname);
++ return 1;
++}
++
++int main(int argc, char **argv)
++{
++ const char *prog = argv[0];
++ const char *user;
++ char *pw1, *pw2;
++ FILE *fp;
++ bool add = false, delete = false, get_stdin = false, found;
++ int ch;
++ int uid;
++
++ TALLOC_CTX *frame = talloc_stackframe();
++
++ while ((ch = getopt(argc, argv, "asx")) != EOF) {
++ switch (ch) {
++ case 's':
++ get_stdin = true;
++ break;
++ case 'a':
++ add = true;
++ break;
++ case 'x':
++ delete = true;
++ break;
++ default:
++ return usage(prog);
++ }
++ }
++
++ if (add && delete)
++ return usage(prog);
++
++ argc -= optind;
++ argv += optind;
++
++ if (!argc)
++ return usage(prog);
++
++ user = argv[0];
++ if (!delete) {
++ uid = find_uid_for_user(user);
++ if (uid < 0) {
++ fprintf(stderr, "Could not find user '%s' in /etc/passwd\n", user);
++ return 2;
++ }
++ }
++
++ fp = fopen("/etc/samba/smbpasswd", "r+");
++ if(!fp) {
++ fprintf(stderr, "Failed to open /etc/samba/smbpasswd");
++ return 3;
++ }
++
++ found = find_passwd_line(fp, user, NULL);
++ if (!add && !found) {
++ fprintf(stderr, "Could not find user '%s' in /etc/samba/smbpasswd\n", user);
++ return 3;
++ }
++
++ if (delete) {
++ smbpasswd_delete_user(fp);
++ goto out;
++ }
++
++ pw1 = get_pass("New SMB password:", get_stdin);
++ if (!pw1)
++ pw1 = strdup("");
++
++ pw2 = get_pass("Retype SMB password:", get_stdin);
++ if (!pw2)
++ pw2 = strdup("");
++
++ if (strcmp(pw1, pw2) != 0) {
++ fprintf(stderr, "Mismatch - password unchanged.\n");
++ goto out_free;
++ }
++
++ if (found)
++ fseek(fp, -strlen(buf), SEEK_CUR);
++ smbpasswd_write_user(fp, user, uid, pw2);
++
++out_free:
++ free(pw1);
++ free(pw2);
++out:
++ fclose(fp);
++ TALLOC_FREE(frame);
++
++ return 0;
++}
diff --git a/package/network/services/samba36/patches/120-add_missing_ifdef.patch b/package/network/services/samba36/patches/120-add_missing_ifdef.patch
new file mode 100644
index 0000000..dbd9adc
--- /dev/null
+++ b/package/network/services/samba36/patches/120-add_missing_ifdef.patch
@@ -0,0 +1,26 @@
+--- a/source3/librpc/rpc/rpc_common.c
++++ b/source3/librpc/rpc/rpc_common.c
+@@ -119,9 +119,11 @@ static bool initialize_interfaces(void)
+ if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
+ return false;
+ }
++#ifdef DEVELOPER
+ if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
+ return false;
+ }
++#endif
+ if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
+ return false;
+ }
+--- a/source3/rpcclient/rpcclient.c
++++ b/source3/rpcclient/rpcclient.c
+@@ -628,7 +628,9 @@ static struct cmd_set *rpcclient_command
+ netlogon_commands,
+ srvsvc_commands,
+ dfs_commands,
++#ifdef DEVELOPER
+ echo_commands,
++#endif
+ epmapper_commands,
+ shutdown_commands,
+ test_commands,
diff --git a/package/network/services/samba36/patches/200-remove_printer_support.patch b/package/network/services/samba36/patches/200-remove_printer_support.patch
new file mode 100644
index 0000000..de567a7
--- /dev/null
+++ b/package/network/services/samba36/patches/200-remove_printer_support.patch
@@ -0,0 +1,346 @@
+--- a/source3/rpc_server/rpc_ep_setup.c
++++ b/source3/rpc_server/rpc_ep_setup.c
+@@ -1110,6 +1110,10 @@ bool dcesrv_ep_setup(struct tevent_conte
+ "rpc_server",
+ "spoolss",
+ "embedded");
++#ifndef PRINTER_SUPPORT
++ if (1) {
++ } else
++#endif
+ if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
+ spoolss_cb.init = spoolss_init_cb;
+ spoolss_cb.shutdown = spoolss_shutdown_cb;
+--- a/source3/rpcclient/rpcclient.c
++++ b/source3/rpcclient/rpcclient.c
+@@ -624,7 +624,9 @@ static struct cmd_set *rpcclient_command
+ lsarpc_commands,
+ ds_commands,
+ samr_commands,
++#ifdef PRINTER_SUPPORT
+ spoolss_commands,
++#endif
+ netlogon_commands,
+ srvsvc_commands,
+ dfs_commands,
+--- a/source3/printing/spoolssd.c
++++ b/source3/printing/spoolssd.c
+@@ -165,6 +165,10 @@ void start_spoolssd(struct tevent_contex
+ NTSTATUS status;
+ int ret;
+
++#ifndef PRINTER_SUPPORT
++ return;
++#endif
++
+ DEBUG(1, ("Forking SPOOLSS Daemon\n"));
+
+ pid = sys_fork();
+--- a/source3/utils/net_rpc.c
++++ b/source3/utils/net_rpc.c
+@@ -7841,6 +7841,10 @@ int net_rpc_printer(struct net_context *
+ {NULL, NULL, 0, NULL, NULL}
+ };
+
++#ifndef PRINTER_SUPPORT
++ return 0;
++#endif
++
+ if (argc == 0) {
+ if (c->display_usage) {
+ d_printf(_("Usage:\n"));
+--- a/source3/smbd/reply.c
++++ b/source3/smbd/reply.c
+@@ -5208,7 +5208,11 @@ void reply_printopen(struct smb_request
+ return;
+ }
+
+- if (!CAN_PRINT(conn)) {
++
++#ifdef PRINTER_SUPPORT
++ if (!CAN_PRINT(conn))
++#endif
++ {
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ END_PROFILE(SMBsplopen);
+ return;
+@@ -5314,7 +5318,10 @@ void reply_printqueue(struct smb_request
+ is really quite gross and only worked when there was only
+ one printer - I think we should now only accept it if they
+ get it right (tridge) */
+- if (!CAN_PRINT(conn)) {
++#ifdef PRINTER_SUPPORT
++ if (!CAN_PRINT(conn))
++#endif
++ {
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ END_PROFILE(SMBsplretq);
+ return;
+--- a/source3/smbd/lanman.c
++++ b/source3/smbd/lanman.c
+@@ -784,6 +784,10 @@ static bool api_DosPrintQGetInfo(struct
+ union spoolss_JobInfo *job_info = NULL;
+ union spoolss_PrinterInfo printer_info;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -999,6 +1003,10 @@ static bool api_DosPrintQEnum(struct smb
+ union spoolss_DriverInfo *driver_info;
+ union spoolss_JobInfo **job_info;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!param_format || !output_format1 || !p) {
+ return False;
+ }
+@@ -3105,6 +3113,10 @@ static bool api_RDosPrintJobDel(struct s
+ struct spoolss_DevmodeContainer devmode_ctr;
+ enum spoolss_JobControl command;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -3238,6 +3250,10 @@ static bool api_WPrintQueueCtrl(struct s
+ struct sec_desc_buf secdesc_ctr;
+ enum spoolss_PrinterControl command;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !QueueName) {
+ return False;
+ }
+@@ -3404,6 +3420,10 @@ static bool api_PrintJobInfo(struct smbd
+ union spoolss_JobInfo info;
+ struct spoolss_SetJobInfo1 info1;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -4547,6 +4567,10 @@ static bool api_WPrintJobGetInfo(struct
+ struct spoolss_DevmodeContainer devmode_ctr;
+ union spoolss_JobInfo info;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -4685,6 +4709,10 @@ static bool api_WPrintJobEnumerate(struc
+ uint32_t count = 0;
+ union spoolss_JobInfo *info;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -4890,6 +4918,10 @@ static bool api_WPrintDestGetInfo(struct
+ struct spoolss_DevmodeContainer devmode_ctr;
+ union spoolss_PrinterInfo info;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -5026,6 +5058,10 @@ static bool api_WPrintDestEnum(struct sm
+ union spoolss_PrinterInfo *info;
+ uint32_t count;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -5129,6 +5165,10 @@ static bool api_WPrintDriverEnum(struct
+ int succnt;
+ struct pack_desc desc;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -5193,6 +5233,10 @@ static bool api_WPrintQProcEnum(struct s
+ int succnt;
+ struct pack_desc desc;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -5257,6 +5301,10 @@ static bool api_WPrintPortEnum(struct sm
+ int succnt;
+ struct pack_desc desc;
+
++#ifndef PRINTER_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+--- a/source3/smbd/server_exit.c
++++ b/source3/smbd/server_exit.c
+@@ -141,7 +141,9 @@ static void exit_server_common(enum serv
+ rpc_eventlog_shutdown();
+ rpc_ntsvcs_shutdown();
+ rpc_svcctl_shutdown();
++#ifdef PRINTER_SUPPORT
+ rpc_spoolss_shutdown();
++#endif
+
+ rpc_srvsvc_shutdown();
+ rpc_winreg_shutdown();
+--- a/source3/smbd/open.c
++++ b/source3/smbd/open.c
+@@ -1608,6 +1608,9 @@ static NTSTATUS open_file_ntcreate(conne
+ * Most of the passed parameters are ignored.
+ */
+
++#ifndef PRINTER_SUPPORT
++ return NT_STATUS_ACCESS_DENIED;
++#endif
+ if (pinfo) {
+ *pinfo = FILE_WAS_CREATED;
+ }
+--- a/source3/smbd/close.c
++++ b/source3/smbd/close.c
+@@ -643,6 +643,9 @@ static NTSTATUS close_normal_file(struct
+ status = ntstatus_keeperror(status, tmp);
+
+ if (fsp->print_file) {
++#ifndef PRINTER_SUPPORT
++ return NT_STATUS_OK;
++#endif
+ /* FIXME: return spool errors */
+ print_spool_end(fsp, close_type);
+ file_free(req, fsp);
+--- a/source3/smbd/fileio.c
++++ b/source3/smbd/fileio.c
+@@ -298,6 +298,10 @@ ssize_t write_file(struct smb_request *r
+ uint32_t t;
+ int ret;
+
++#ifndef PRINTER_SUPPORT
++ return -1;
++#endif
++
+ ret = print_spool_write(fsp, data, n, pos, &t);
+ if (ret) {
+ errno = ret;
+--- a/source3/smbd/smb2_create.c
++++ b/source3/smbd/smb2_create.c
+@@ -486,7 +486,10 @@ static struct tevent_req *smbd_smb2_crea
+ info = FILE_WAS_OPENED;
+ } else if (CAN_PRINT(smb1req->conn)) {
+ status = file_new(smb1req, smb1req->conn, &result);
+- if(!NT_STATUS_IS_OK(status)) {
++#ifdef PRINTER_SUPPORT
++ if(!NT_STATUS_IS_OK(status))
++#endif
++ {
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+--- a/source3/rpc_server/svcctl/srv_svcctl_nt.c
++++ b/source3/rpc_server/svcctl/srv_svcctl_nt.c
+@@ -85,9 +85,11 @@ bool init_service_op_table( void )
+
+ /* add builtin services */
+
++#ifdef PRINTER_SUPPORT
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, "Spooler" );
+ svcctl_ops[i].ops = &spoolss_svc_ops;
+ i++;
++#endif
+
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, "NETLOGON" );
+ svcctl_ops[i].ops = &netlogon_svc_ops;
+--- a/source3/librpc/rpc/rpc_common.c
++++ b/source3/librpc/rpc/rpc_common.c
+@@ -113,9 +113,11 @@ static bool initialize_interfaces(void)
+ if (!smb_register_ndr_interface(&ndr_table_winreg)) {
+ return false;
+ }
++#ifdef PRINTER_SUPPORT
+ if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
+ return false;
+ }
++#endif
+ if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
+ return false;
+ }
+--- a/source3/smbd/process.c
++++ b/source3/smbd/process.c
+@@ -2423,8 +2423,10 @@ static bool housekeeping_fn(const struct
+
+ change_to_root_user();
+
++#ifdef PRINTER_SUPPORT
+ /* update printer queue caches if necessary */
+ update_monitored_printq_cache(sconn->msg_ctx);
++#endif
+
+ /* check if we need to reload services */
+ check_reload(sconn, time_mono(NULL));
+--- a/source3/smbd/server.c
++++ b/source3/smbd/server.c
+@@ -123,7 +123,9 @@ static void smb_pcap_updated(struct mess
+ {
+ struct tevent_context *ev_ctx =
+ talloc_get_type_abort(private_data, struct tevent_context);
+-
++#ifndef PRINTER_SUPPORT
++ return;
++#endif
+ DEBUG(10,("Got message saying pcap was updated. Reloading.\n"));
+ change_to_root_user();
+ reload_printers(ev_ctx, msg);
+@@ -1277,6 +1279,7 @@ extern void build_options(bool screen);
+ * The print backend init also migrates the printing tdb's,
+ * this requires a winreg pipe.
+ */
++#ifdef PRINTER_SUPPORT
+ if (!print_backend_init(smbd_messaging_context()))
+ exit(1);
+
+@@ -1315,7 +1318,7 @@ extern void build_options(bool screen);
+ smbd_messaging_context());
+ }
+ }
+-
++#endif
+ if (!is_daemon) {
+ /* inetd mode */
+ TALLOC_FREE(frame);
diff --git a/package/network/services/samba36/patches/210-remove_ad_support.patch b/package/network/services/samba36/patches/210-remove_ad_support.patch
new file mode 100644
index 0000000..6742dc0
--- /dev/null
+++ b/package/network/services/samba36/patches/210-remove_ad_support.patch
@@ -0,0 +1,88 @@
+--- a/source3/librpc/rpc/rpc_common.c
++++ b/source3/librpc/rpc/rpc_common.c
+@@ -95,9 +95,11 @@ static bool initialize_interfaces(void)
+ if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
+ return false;
+ }
++#ifdef ACTIVE_DIRECTORY
+ if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
+ return false;
+ }
++#endif
+ if (!smb_register_ndr_interface(&ndr_table_samr)) {
+ return false;
+ }
+@@ -141,9 +143,11 @@ static bool initialize_interfaces(void)
+ if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
+ return false;
+ }
++#ifdef ACTIVE_DIRECTORY
+ if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
+ return false;
+ }
++#endif
+ return true;
+ }
+
+--- a/source3/rpc_server/rpc_ep_setup.c
++++ b/source3/rpc_server/rpc_ep_setup.c
+@@ -918,6 +918,7 @@ static bool netdfs_init_cb(void *ptr)
+ return true;
+ }
+
++#ifdef ACTIVE_DIRECTORY
+ static bool dssetup_init_cb(void *ptr)
+ {
+ struct dcesrv_ep_context *ep_ctx =
+@@ -966,6 +967,7 @@ static bool dssetup_init_cb(void *ptr)
+
+ return true;
+ }
++#endif
+
+ static bool wkssvc_init_cb(void *ptr)
+ {
+@@ -1172,12 +1174,14 @@ bool dcesrv_ep_setup(struct tevent_conte
+ }
+ #endif
+
++#ifdef ACTIVE_DIRECTORY
+ dssetup_cb.init = dssetup_init_cb;
+ dssetup_cb.shutdown = NULL;
+ dssetup_cb.private_data = ep_ctx;
+ if (!NT_STATUS_IS_OK(rpc_dssetup_init(&dssetup_cb))) {
+ return false;
+ }
++#endif
+
+ wkssvc_cb.init = wkssvc_init_cb;
+ wkssvc_cb.shutdown = NULL;
+--- a/source3/smbd/server_exit.c
++++ b/source3/smbd/server_exit.c
+@@ -132,7 +132,9 @@ static void exit_server_common(enum serv
+
+ if (am_parent) {
+ rpc_wkssvc_shutdown();
++#ifdef ACTIVE_DIRECTORY
+ rpc_dssetup_shutdown();
++#endif
+ #ifdef DEVELOPER
+ rpc_rpcecho_shutdown();
+ #endif
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -2904,12 +2904,14 @@ NTSTATUS cli_rpc_pipe_open_noauth_transp
+ status = rpc_pipe_bind(result, auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ int lvl = 0;
++#ifdef ACTIVE_DIRECTORY
+ if (ndr_syntax_id_equal(interface,
+ &ndr_table_dssetup.syntax_id)) {
+ /* non AD domains just don't have this pipe, avoid
+ * level 0 statement in that case - gd */
+ lvl = 3;
+ }
++#endif
+ DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
+ "%s failed with error %s\n",
+ get_pipe_name_from_syntax(talloc_tos(), interface),
diff --git a/package/network/services/samba36/patches/220-remove_services.patch b/package/network/services/samba36/patches/220-remove_services.patch
new file mode 100644
index 0000000..498232d
--- /dev/null
+++ b/package/network/services/samba36/patches/220-remove_services.patch
@@ -0,0 +1,98 @@
+--- a/source3/librpc/rpc/rpc_common.c
++++ b/source3/librpc/rpc/rpc_common.c
+@@ -131,6 +131,7 @@ static bool initialize_interfaces(void)
+ if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
+ return false;
+ }
++#ifdef EXTRA_SERVICES
+ if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
+ return false;
+ }
+@@ -140,6 +141,7 @@ static bool initialize_interfaces(void)
+ if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
+ return false;
+ }
++#endif
+ if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
+ return false;
+ }
+--- a/source3/rpc_server/rpc_ep_setup.c
++++ b/source3/rpc_server/rpc_ep_setup.c
+@@ -697,6 +697,7 @@ static bool spoolss_shutdown_cb(void *pt
+ return true;
+ }
+
++#ifdef EXTRA_SERVICES
+ static bool svcctl_init_cb(void *ptr)
+ {
+ struct dcesrv_ep_context *ep_ctx =
+@@ -733,6 +734,7 @@ static bool svcctl_init_cb(void *ptr)
+
+ return true;
+ }
++#endif
+
+ static bool svcctl_shutdown_cb(void *ptr)
+ {
+@@ -741,6 +743,8 @@ static bool svcctl_shutdown_cb(void *ptr
+ return true;
+ }
+
++#ifdef EXTRA_SERVICES
++
+ static bool ntsvcs_init_cb(void *ptr)
+ {
+ struct dcesrv_ep_context *ep_ctx =
+@@ -802,6 +806,7 @@ static bool eventlog_init_cb(void *ptr)
+
+ return true;
+ }
++#endif
+
+ static bool initshutdown_init_cb(void *ptr)
+ {
+@@ -1130,6 +1135,7 @@ bool dcesrv_ep_setup(struct tevent_conte
+ }
+ }
+
++#ifdef EXTRA_SERVICES
+ svcctl_cb.init = svcctl_init_cb;
+ svcctl_cb.shutdown = svcctl_shutdown_cb;
+ svcctl_cb.private_data = ep_ctx;
+@@ -1150,6 +1156,7 @@ bool dcesrv_ep_setup(struct tevent_conte
+ if (!NT_STATUS_IS_OK(rpc_eventlog_init(&eventlog_cb))) {
+ return false;
+ }
++#endif
+
+ initshutdown_cb.init = initshutdown_init_cb;
+ initshutdown_cb.shutdown = NULL;
+--- a/source3/smbd/server_exit.c
++++ b/source3/smbd/server_exit.c
+@@ -140,9 +140,11 @@ static void exit_server_common(enum serv
+ #endif
+ rpc_netdfs_shutdown();
+ rpc_initshutdown_shutdown();
++#ifdef EXTRA_SERVICES
+ rpc_eventlog_shutdown();
+- rpc_ntsvcs_shutdown();
+ rpc_svcctl_shutdown();
++ rpc_ntsvcs_shutdown();
++#endif
+ #ifdef PRINTER_SUPPORT
+ rpc_spoolss_shutdown();
+ #endif
+--- a/source3/rpcclient/rpcclient.c
++++ b/source3/rpcclient/rpcclient.c
+@@ -637,9 +637,11 @@ static struct cmd_set *rpcclient_command
+ shutdown_commands,
+ test_commands,
+ wkssvc_commands,
++#ifdef EXTRA_SERVICES
+ ntsvcs_commands,
+ drsuapi_commands,
+ eventlog_commands,
++#endif
+ winreg_commands,
+ NULL
+ };
diff --git a/package/network/services/samba36/patches/230-remove_winreg_support.patch b/package/network/services/samba36/patches/230-remove_winreg_support.patch
new file mode 100644
index 0000000..df2be4f
--- /dev/null
+++ b/package/network/services/samba36/patches/230-remove_winreg_support.patch
@@ -0,0 +1,146 @@
+--- a/source3/rpc_server/rpc_ep_setup.c
++++ b/source3/rpc_server/rpc_ep_setup.c
+@@ -409,6 +409,7 @@ static bool epmapper_shutdown_cb(void *p
+ return true;
+ }
+
++#ifdef WINREG_SUPPORT
+ static bool winreg_init_cb(void *ptr)
+ {
+ struct dcesrv_ep_context *ep_ctx =
+@@ -456,6 +457,7 @@ static bool winreg_init_cb(void *ptr)
+
+ return true;
+ }
++#endif
+
+ static bool srvsvc_init_cb(void *ptr)
+ {
+@@ -710,10 +712,12 @@ static bool svcctl_init_cb(void *ptr)
+ "epmapper",
+ "none");
+
++#ifdef WINREG_SUPPORT
+ ok = svcctl_init_winreg(ep_ctx->msg_ctx);
+ if (!ok) {
+ return false;
+ }
++#endif
+
+ /* initialize the control hooks */
+ init_service_op_table();
+@@ -785,10 +789,12 @@ static bool eventlog_init_cb(void *ptr)
+ "epmapper",
+ "none");
+
++#ifdef WINREG_SUPPORT
+ ok = eventlog_init_winreg(ep_ctx->msg_ctx);
+ if (!ok) {
+ return false;
+ }
++#endif
+
+ if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
+ StrCaseCmp(rpcsrv_type, "daemon") == 0) {
+@@ -1077,12 +1083,14 @@ bool dcesrv_ep_setup(struct tevent_conte
+ }
+ }
+
++#ifdef WINREG_SUPPORT
+ winreg_cb.init = winreg_init_cb;
+ winreg_cb.shutdown = NULL;
+ winreg_cb.private_data = ep_ctx;
+ if (!NT_STATUS_IS_OK(rpc_winreg_init(&winreg_cb))) {
+ return false;
+ }
++#endif
+
+ srvsvc_cb.init = srvsvc_init_cb;
+ srvsvc_cb.shutdown = NULL;
+--- a/source3/smbd/server_exit.c
++++ b/source3/smbd/server_exit.c
+@@ -150,7 +150,9 @@ static void exit_server_common(enum serv
+ #endif
+
+ rpc_srvsvc_shutdown();
++#ifdef WINREG_SUPPORT
+ rpc_winreg_shutdown();
++#endif
+
+ rpc_netlogon_shutdown();
+ rpc_samr_shutdown();
+--- a/source3/librpc/rpc/rpc_common.c
++++ b/source3/librpc/rpc/rpc_common.c
+@@ -112,9 +112,11 @@ static bool initialize_interfaces(void)
+ if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
+ return false;
+ }
++#ifdef WINREG_SUPPORT
+ if (!smb_register_ndr_interface(&ndr_table_winreg)) {
+ return false;
+ }
++#endif
+ #ifdef PRINTER_SUPPORT
+ if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
+ return false;
+--- a/source3/rpc_server/svcctl/srv_svcctl_nt.c
++++ b/source3/rpc_server/svcctl/srv_svcctl_nt.c
+@@ -95,9 +95,11 @@ bool init_service_op_table( void )
+ svcctl_ops[i].ops = &netlogon_svc_ops;
+ i++;
+
++#ifdef WINREG_SUPPORT
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, "RemoteRegistry" );
+ svcctl_ops[i].ops = &winreg_svc_ops;
+ i++;
++#endif
+
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, "WINS" );
+ svcctl_ops[i].ops = &wins_svc_ops;
+--- a/source3/services/svc_winreg_glue.c
++++ b/source3/services/svc_winreg_glue.c
+@@ -88,6 +88,10 @@ struct security_descriptor *svcctl_get_s
+ NTSTATUS status;
+ WERROR result = WERR_OK;
+
++#ifndef WINREG_SUPPORT
++ return NULL;
++#endif
++
+ key = talloc_asprintf(mem_ctx,
+ "%s\\%s\\Security",
+ TOP_LEVEL_SERVICES_KEY, name);
+@@ -161,6 +165,10 @@ bool svcctl_set_secdesc(struct messaging
+ NTSTATUS status;
+ WERROR result = WERR_OK;
+
++#ifndef WINREG_SUPPORT
++ return false;
++#endif
++
+ tmp_ctx = talloc_stackframe();
+ if (tmp_ctx == NULL) {
+ return false;
+@@ -272,6 +280,10 @@ const char *svcctl_get_string_value(TALL
+ NTSTATUS status;
+ WERROR result = WERR_OK;
+
++#ifndef WINREG_SUPPORT
++ return NULL;
++#endif
++
+ tmp_ctx = talloc_stackframe();
+ if (tmp_ctx == NULL) {
+ return NULL;
+--- a/source3/rpcclient/rpcclient.c
++++ b/source3/rpcclient/rpcclient.c
+@@ -642,7 +642,9 @@ static struct cmd_set *rpcclient_command
+ drsuapi_commands,
+ eventlog_commands,
+ #endif
++#ifdef WINREG_SUPPORT
+ winreg_commands,
++#endif
+ NULL
+ };
+
diff --git a/package/network/services/samba36/patches/240-remove_dfs_api.patch b/package/network/services/samba36/patches/240-remove_dfs_api.patch
new file mode 100644
index 0000000..f4d432e
--- /dev/null
+++ b/package/network/services/samba36/patches/240-remove_dfs_api.patch
@@ -0,0 +1,71 @@
+--- a/source3/rpc_server/rpc_ep_setup.c
++++ b/source3/rpc_server/rpc_ep_setup.c
+@@ -881,6 +881,7 @@ static bool rpcecho_init_cb(void *ptr) {
+
+ #endif
+
++#ifdef DFS_SUPPORT
+ static bool netdfs_init_cb(void *ptr)
+ {
+ struct dcesrv_ep_context *ep_ctx =
+@@ -928,6 +929,7 @@ static bool netdfs_init_cb(void *ptr)
+
+ return true;
+ }
++#endif
+
+ #ifdef ACTIVE_DIRECTORY
+ static bool dssetup_init_cb(void *ptr)
+@@ -1173,12 +1175,14 @@ bool dcesrv_ep_setup(struct tevent_conte
+ return false;
+ }
+
++#ifdef DFS_SUPPORT
+ netdfs_cb.init = netdfs_init_cb;
+ netdfs_cb.shutdown = NULL;
+ netdfs_cb.private_data = ep_ctx;
+ if (!NT_STATUS_IS_OK(rpc_netdfs_init(&netdfs_cb))) {
+ return false;
+ }
++#endif
+
+ #ifdef DEVELOPER
+ rpcecho_cb.init = rpcecho_init_cb;
+--- a/source3/librpc/rpc/rpc_common.c
++++ b/source3/librpc/rpc/rpc_common.c
+@@ -122,9 +122,11 @@ static bool initialize_interfaces(void)
+ return false;
+ }
+ #endif
++#ifdef DFS_SUPPORT
+ if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
+ return false;
+ }
++#endif
+ #ifdef DEVELOPER
+ if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
+ return false;
+--- a/source3/smbd/server_exit.c
++++ b/source3/smbd/server_exit.c
+@@ -138,7 +138,9 @@ static void exit_server_common(enum serv
+ #ifdef DEVELOPER
+ rpc_rpcecho_shutdown();
+ #endif
++#ifdef DFS_SUPPORT
+ rpc_netdfs_shutdown();
++#endif
+ rpc_initshutdown_shutdown();
+ #ifdef EXTRA_SERVICES
+ rpc_eventlog_shutdown();
+--- a/source3/rpcclient/rpcclient.c
++++ b/source3/rpcclient/rpcclient.c
+@@ -629,7 +629,9 @@ static struct cmd_set *rpcclient_command
+ #endif
+ netlogon_commands,
+ srvsvc_commands,
++#ifdef DFS_SUPPORT
+ dfs_commands,
++#endif
+ #ifdef DEVELOPER
+ echo_commands,
+ #endif
diff --git a/package/network/services/samba36/patches/250-remove_domain_logon.patch b/package/network/services/samba36/patches/250-remove_domain_logon.patch
new file mode 100644
index 0000000..f7582ef
--- /dev/null
+++ b/package/network/services/samba36/patches/250-remove_domain_logon.patch
@@ -0,0 +1,185 @@
+--- a/source3/rpc_server/rpc_ep_setup.c
++++ b/source3/rpc_server/rpc_ep_setup.c
+@@ -606,6 +606,7 @@ static bool samr_init_cb(void *ptr)
+ return true;
+ }
+
++#ifdef NETLOGON_SUPPORT
+ static bool netlogon_init_cb(void *ptr)
+ {
+ struct dcesrv_ep_context *ep_ctx =
+@@ -654,6 +655,7 @@ static bool netlogon_init_cb(void *ptr)
+
+ return true;
+ }
++#endif
+
+ static bool spoolss_init_cb(void *ptr)
+ {
+@@ -1116,12 +1118,15 @@ bool dcesrv_ep_setup(struct tevent_conte
+ return false;
+ }
+
++#ifdef NETLOGON_SUPPORT
+ netlogon_cb.init = netlogon_init_cb;
+ netlogon_cb.shutdown = NULL;
+ netlogon_cb.private_data = ep_ctx;
+ if (!NT_STATUS_IS_OK(rpc_netlogon_init(&netlogon_cb))) {
+ return false;
+ }
++#endif
++
+
+ rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
+ "rpc_server",
+--- a/source3/librpc/rpc/rpc_common.c
++++ b/source3/librpc/rpc/rpc_common.c
+@@ -103,9 +103,11 @@ static bool initialize_interfaces(void)
+ if (!smb_register_ndr_interface(&ndr_table_samr)) {
+ return false;
+ }
++#ifdef NETLOGON_SUPPORT
+ if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
+ return false;
+ }
++#endif
+ if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
+ return false;
+ }
+--- a/source3/smbd/server_exit.c
++++ b/source3/smbd/server_exit.c
+@@ -156,7 +156,9 @@ static void exit_server_common(enum serv
+ rpc_winreg_shutdown();
+ #endif
+
++#ifdef NETLOGON_SUPPORT
+ rpc_netlogon_shutdown();
++#endif
+ rpc_samr_shutdown();
+ rpc_lsarpc_shutdown();
+ }
+--- a/source3/rpc_server/svcctl/srv_svcctl_nt.c
++++ b/source3/rpc_server/svcctl/srv_svcctl_nt.c
+@@ -91,9 +91,11 @@ bool init_service_op_table( void )
+ i++;
+ #endif
+
++#ifdef NETLOGON_SUPPORT
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, "NETLOGON" );
+ svcctl_ops[i].ops = &netlogon_svc_ops;
+ i++;
++#endif
+
+ #ifdef WINREG_SUPPORT
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, "RemoteRegistry" );
+--- a/source3/nmbd/nmbd_processlogon.c
++++ b/source3/nmbd/nmbd_processlogon.c
+@@ -320,6 +320,10 @@ void process_logon_packet(struct packet_
+ NTSTATUS status;
+ const char *pdc_name;
+
++#ifndef NETLOGON_SUPPORT
++ return;
++#endif
++
+ in_addr_to_sockaddr_storage(&ss, p->ip);
+ pss = iface_ip((struct sockaddr *)&ss);
+ if (!pss) {
+--- a/source3/rpcclient/rpcclient.c
++++ b/source3/rpcclient/rpcclient.c
+@@ -627,7 +627,9 @@ static struct cmd_set *rpcclient_command
+ #ifdef PRINTER_SUPPORT
+ spoolss_commands,
+ #endif
++#ifdef NETLOGON_SUPPORT
+ netlogon_commands,
++#endif
+ srvsvc_commands,
+ #ifdef DFS_SUPPORT
+ dfs_commands,
+--- a/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
++++ b/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
+@@ -824,6 +824,10 @@ WERROR _wkssvc_NetrJoinDomain2(struct pi
+ WERROR werr;
+ struct security_token *token = p->session_info->security_token;
+
++#ifndef NETLOGON_SUPPORT
++ return WERR_NOT_SUPPORTED;
++#endif
++
+ if (!r->in.domain_name) {
+ return WERR_INVALID_PARAM;
+ }
+@@ -901,6 +905,10 @@ WERROR _wkssvc_NetrUnjoinDomain2(struct
+ WERROR werr;
+ struct security_token *token = p->session_info->security_token;
+
++#ifndef NETLOGON_SUPPORT
++ return WERR_NOT_SUPPORTED;
++#endif
++
+ if (!r->in.account || !r->in.encrypted_password) {
+ return WERR_INVALID_PARAM;
+ }
+--- a/source3/libsmb/trusts_util.c
++++ b/source3/libsmb/trusts_util.c
+@@ -46,9 +46,11 @@ NTSTATUS trust_pw_change_and_store_it(st
+ NTSTATUS nt_status;
+
+ switch (sec_channel_type) {
++#ifdef NETLOGON_SUPPORT
+ case SEC_CHAN_WKSTA:
+ case SEC_CHAN_DOMAIN:
+ break;
++#endif
+ default:
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+@@ -159,6 +161,11 @@ bool enumerate_domain_trusts( TALLOC_CTX
+ *num_domains = 0;
+ *sids = NULL;
+
++#ifndef NETLOGON_SUPPORT
++ return False;
++#endif
++
++
+ /* lookup a DC first */
+
+ if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) {
+@@ -243,6 +250,10 @@ NTSTATUS change_trust_account_password(
+ struct cli_state *cli = NULL;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+
++#ifndef NETLOGON_SUPPORT
++ return NT_STATUS_UNSUCCESSFUL;
++#endif
++
+ DEBUG(5,("change_trust_account_password: Attempting to change trust account password in domain %s....\n",
+ domain));
+
+--- a/source3/auth/auth_domain.c
++++ b/source3/auth/auth_domain.c
+@@ -538,7 +538,9 @@ static NTSTATUS auth_init_trustdomain(st
+
+ NTSTATUS auth_domain_init(void)
+ {
++#ifdef NETLOGON_SUPPORT
+ smb_register_auth(AUTH_INTERFACE_VERSION, "trustdomain", auth_init_trustdomain);
+ smb_register_auth(AUTH_INTERFACE_VERSION, "ntdomain", auth_init_ntdomain);
++#endif
+ return NT_STATUS_OK;
+ }
+--- a/source3/smbd/process.c
++++ b/source3/smbd/process.c
+@@ -2431,8 +2431,10 @@ static bool housekeeping_fn(const struct
+ /* check if we need to reload services */
+ check_reload(sconn, time_mono(NULL));
+
++#ifdef NETLOGON_SUPPORT
+ /* Change machine password if neccessary. */
+ attempt_machine_password_change();
++#endif
+
+ /*
+ * Force a log file check.
diff --git a/package/network/services/samba36/patches/260-remove_samr.patch b/package/network/services/samba36/patches/260-remove_samr.patch
new file mode 100644
index 0000000..7e55573
--- /dev/null
+++ b/package/network/services/samba36/patches/260-remove_samr.patch
@@ -0,0 +1,144 @@
+--- a/source3/rpc_server/rpc_handles.c
++++ b/source3/rpc_server/rpc_handles.c
+@@ -59,8 +59,11 @@ struct handle_list {
+
+ static bool is_samr_lsa_pipe(const struct ndr_syntax_id *syntax)
+ {
+- return (ndr_syntax_id_equal(syntax, &ndr_table_samr.syntax_id)
+- || ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id));
++ return
++#ifdef SAMR_SUPPORT
++ ndr_syntax_id_equal(syntax, &ndr_table_samr.syntax_id) ||
++#endif
++ ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id);
+ }
+
+ size_t num_pipe_handles(struct pipes_struct *p)
+--- a/source3/librpc/rpc/rpc_common.c
++++ b/source3/librpc/rpc/rpc_common.c
+@@ -100,9 +100,11 @@ static bool initialize_interfaces(void)
+ return false;
+ }
+ #endif
++#ifdef SAMR_SUPPORT
+ if (!smb_register_ndr_interface(&ndr_table_samr)) {
+ return false;
+ }
++#endif
+ #ifdef NETLOGON_SUPPORT
+ if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
+ return false;
+--- a/source3/rpc_server/rpc_ep_setup.c
++++ b/source3/rpc_server/rpc_ep_setup.c
+@@ -557,6 +557,7 @@ static bool lsarpc_init_cb(void *ptr)
+ return true;
+ }
+
++#ifdef SAMR_SUPPORT
+ static bool samr_init_cb(void *ptr)
+ {
+ struct dcesrv_ep_context *ep_ctx =
+@@ -605,6 +606,7 @@ static bool samr_init_cb(void *ptr)
+
+ return true;
+ }
++#endif
+
+ #ifdef NETLOGON_SUPPORT
+ static bool netlogon_init_cb(void *ptr)
+@@ -1111,12 +1113,14 @@ bool dcesrv_ep_setup(struct tevent_conte
+ return false;
+ }
+
++#ifdef SAMR_SUPPORT
+ samr_cb.init = samr_init_cb;
+ samr_cb.shutdown = NULL;
+ samr_cb.private_data = ep_ctx;
+ if (!NT_STATUS_IS_OK(rpc_samr_init(&samr_cb))) {
+ return false;
+ }
++#endif
+
+ #ifdef NETLOGON_SUPPORT
+ netlogon_cb.init = netlogon_init_cb;
+--- a/source3/smbd/server_exit.c
++++ b/source3/smbd/server_exit.c
+@@ -159,7 +159,9 @@ static void exit_server_common(enum serv
+ #ifdef NETLOGON_SUPPORT
+ rpc_netlogon_shutdown();
+ #endif
++#ifdef SAMR_SUPPORT
+ rpc_samr_shutdown();
++#endif
+ rpc_lsarpc_shutdown();
+ }
+
+--- a/source3/rpcclient/rpcclient.c
++++ b/source3/rpcclient/rpcclient.c
+@@ -623,7 +623,9 @@ static struct cmd_set *rpcclient_command
+ rpcclient_commands,
+ lsarpc_commands,
+ ds_commands,
++#ifdef SAMR_SUPPORT
+ samr_commands,
++#endif
+ #ifdef PRINTER_SUPPORT
+ spoolss_commands,
+ #endif
+--- a/source3/smbd/lanman.c
++++ b/source3/smbd/lanman.c
+@@ -2353,6 +2353,10 @@ static bool api_RNetGroupEnum(struct smb
+ NTSTATUS status, result;
+ struct dcerpc_binding_handle *b;
+
++#ifndef SAMR_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -2541,6 +2545,10 @@ static bool api_NetUserGetGroups(struct
+ NTSTATUS status, result;
+ struct dcerpc_binding_handle *b;
+
++#ifndef SAMR_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !UserName || !p) {
+ return False;
+ }
+@@ -2741,6 +2749,10 @@ static bool api_RNetUserEnum(struct smbd
+
+ struct dcerpc_binding_handle *b;
+
++#ifndef SAMR_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -2979,6 +2991,10 @@ static bool api_SamOEMChangePassword(str
+ int bufsize;
+ struct dcerpc_binding_handle *b;
+
++#ifndef SAMR_SUPPORT
++ return False;
++#endif
++
+ *rparam_len = 4;
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+@@ -4020,6 +4036,10 @@ static bool api_RNetUserGetInfo(struct s
+ union samr_UserInfo *info;
+ struct dcerpc_binding_handle *b = NULL;
+
++#ifndef SAMR_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !UserName || !p) {
+ return False;
+ }
diff --git a/package/network/services/samba36/patches/270-remove_registry_backend.patch b/package/network/services/samba36/patches/270-remove_registry_backend.patch
new file mode 100644
index 0000000..147b1ce
--- /dev/null
+++ b/package/network/services/samba36/patches/270-remove_registry_backend.patch
@@ -0,0 +1,43 @@
+--- a/source3/lib/smbconf/smbconf_init.c
++++ b/source3/lib/smbconf/smbconf_init.c
+@@ -68,9 +68,12 @@ sbcErr smbconf_init(TALLOC_CTX *mem_ctx,
+ }
+ }
+
++#ifdef REGISTRY_BACKEND
+ if (strequal(backend, "registry") || strequal(backend, "reg")) {
+ err = smbconf_init_reg(mem_ctx, conf_ctx, path);
+- } else if (strequal(backend, "file") || strequal(backend, "txt")) {
++ } else
++#endif
++ if (strequal(backend, "file") || strequal(backend, "txt")) {
+ err = smbconf_init_txt(mem_ctx, conf_ctx, path);
+ } else if (sep == NULL) {
+ /*
+--- a/source3/lib/netapi/serverinfo.c
++++ b/source3/lib/netapi/serverinfo.c
+@@ -557,7 +557,10 @@ static WERROR NetServerSetInfo_l_1005(st
+ return WERR_INVALID_PARAM;
+ }
+
+- if (!lp_config_backend_is_registry()) {
++#ifdef REGISTRY_BACKEND
++ if (!lp_config_backend_is_registry())
++#endif
++ {
+ libnetapi_set_error_string(ctx,
+ "Configuration manipulation requested but not "
+ "supported by backend");
+--- a/source3/smbd/server.c
++++ b/source3/smbd/server.c
+@@ -1230,8 +1230,10 @@ extern void build_options(bool screen);
+ exit(1);
+ }
+
++#ifdef REGISTRY_BACKEND
+ if (!W_ERROR_IS_OK(registry_init_full()))
+ exit(1);
++#endif
+
+ /* Open the share_info.tdb here, so we don't have to open
+ after the fork on every single connection. This is a small
diff --git a/package/network/services/samba36/patches/280-strip_srvsvc.patch b/package/network/services/samba36/patches/280-strip_srvsvc.patch
new file mode 100644
index 0000000..348cfbe
--- /dev/null
+++ b/package/network/services/samba36/patches/280-strip_srvsvc.patch
@@ -0,0 +1,143 @@
+--- a/source3/smbd/lanman.c
++++ b/source3/smbd/lanman.c
+@@ -2197,6 +2197,10 @@ static bool api_RNetShareAdd(struct smbd
+ struct srvsvc_NetShareInfo2 info2;
+ struct dcerpc_binding_handle *b;
+
++#ifndef SRVSVC_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+@@ -3589,10 +3593,7 @@ static bool api_RNetServerGetInfo(struct
+ NTSTATUS status;
+ WERROR werr;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+- struct rpc_pipe_client *cli = NULL;
+- union srvsvc_NetSrvInfo info;
+ int errcode;
+- struct dcerpc_binding_handle *b;
+
+ if (!str1 || !str2 || !p) {
+ return False;
+@@ -3655,66 +3656,16 @@ static bool api_RNetServerGetInfo(struct
+ p = *rdata;
+ p2 = p + struct_len;
+
+- status = rpc_pipe_open_interface(mem_ctx, &ndr_table_srvsvc.syntax_id,
+- conn->session_info,
+- &conn->sconn->client_id,
+- conn->sconn->msg_ctx,
+- &cli);
+- if (!NT_STATUS_IS_OK(status)) {
+- DEBUG(0,("api_RNetServerGetInfo: could not connect to srvsvc: %s\n",
+- nt_errstr(status)));
+- errcode = W_ERROR_V(ntstatus_to_werror(status));
+- goto out;
+- }
+-
+- b = cli->binding_handle;
+-
+- status = dcerpc_srvsvc_NetSrvGetInfo(b, mem_ctx,
+- NULL,
+- 101,
+- &info,
+- &werr);
+- if (!NT_STATUS_IS_OK(status)) {
+- errcode = W_ERROR_V(ntstatus_to_werror(status));
+- goto out;
+- }
+- if (!W_ERROR_IS_OK(werr)) {
+- errcode = W_ERROR_V(werr);
+- goto out;
+- }
+-
+- if (info.info101 == NULL) {
+- errcode = W_ERROR_V(WERR_INVALID_PARAM);
+- goto out;
+- }
+-
+ if (uLevel != 20) {
+- srvstr_push(NULL, 0, p, info.info101->server_name, 16,
++ srvstr_push(NULL, 0, p, global_myname(), 16,
+ STR_ASCII|STR_UPPER|STR_TERMINATE);
+- }
++ }
+ p += 16;
+ if (uLevel > 0) {
+- SCVAL(p,0,info.info101->version_major);
+- SCVAL(p,1,info.info101->version_minor);
+- SIVAL(p,2,info.info101->server_type);
+-
+- if (mdrcnt == struct_len) {
+- SIVAL(p,6,0);
+- } else {
+- SIVAL(p,6,PTR_DIFF(p2,*rdata));
+- if (mdrcnt - struct_len <= 0) {
+- return false;
+- }
+- push_ascii(p2,
+- info.info101->comment,
+- MIN(mdrcnt - struct_len,
+- MAX_SERVER_STRING_LENGTH),
+- STR_TERMINATE);
+- p2 = skip_string(*rdata,*rdata_len,p2);
+- if (!p2) {
+- return False;
+- }
+- }
++ SCVAL(p,0,lp_major_announce_version());
++ SCVAL(p,1,lp_minor_announce_version());
++ SIVAL(p,2,lp_default_server_announce());
++ SIVAL(p,6,0);
+ }
+
+ if (uLevel > 1) {
+@@ -5405,6 +5356,10 @@ static bool api_RNetSessionEnum(struct s
+ uint32_t totalentries, resume_handle = 0;
+ uint32_t count = 0;
+
++#ifndef SRVSVC_SUPPORT
++ return False;
++#endif
++
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
++++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+@@ -1533,6 +1533,10 @@ WERROR _srvsvc_NetShareSetInfo(struct pi
+ TALLOC_CTX *ctx = p->mem_ctx;
+ union srvsvc_NetShareInfo *info = r->in.info;
+
++#ifndef FULL_SRVSVC
++ return WERR_ACCESS_DENIED;
++#endif
++
+ DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
+
+ if (!r->in.share_name) {
+@@ -1763,6 +1767,10 @@ WERROR _srvsvc_NetShareAdd(struct pipes_
+ int max_connections = 0;
+ TALLOC_CTX *ctx = p->mem_ctx;
+
++#ifndef FULL_SRVSVC
++ return WERR_ACCESS_DENIED;
++#endif
++
+ DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
+
+ if (r->out.parm_error) {
+@@ -1945,6 +1953,10 @@ WERROR _srvsvc_NetShareDel(struct pipes_
+ struct share_params *params;
+ TALLOC_CTX *ctx = p->mem_ctx;
+
++#ifndef FULL_SRVSVC
++ return WERR_ACCESS_DENIED;
++#endif
++
+ DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
+
+ if (!r->in.share_name) {
diff --git a/package/network/services/samba36/patches/290-remove_lsa.patch b/package/network/services/samba36/patches/290-remove_lsa.patch
new file mode 100644
index 0000000..fe37d5d
--- /dev/null
+++ b/package/network/services/samba36/patches/290-remove_lsa.patch
@@ -0,0 +1,73 @@
+--- a/source3/librpc/rpc/rpc_common.c
++++ b/source3/librpc/rpc/rpc_common.c
+@@ -92,9 +92,11 @@ bool smb_register_ndr_interface(const st
+
+ static bool initialize_interfaces(void)
+ {
++#ifdef LSA_SUPPORT
+ if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
+ return false;
+ }
++#endif
+ #ifdef ACTIVE_DIRECTORY
+ if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
+ return false;
+--- a/source3/smbd/server_exit.c
++++ b/source3/smbd/server_exit.c
+@@ -162,7 +162,9 @@ static void exit_server_common(enum serv
+ #ifdef SAMR_SUPPORT
+ rpc_samr_shutdown();
+ #endif
++#ifdef LSA_SUPPORT
+ rpc_lsarpc_shutdown();
++#endif
+ }
+
+ /*
+--- a/source3/rpc_server/rpc_ep_setup.c
++++ b/source3/rpc_server/rpc_ep_setup.c
+@@ -508,6 +508,7 @@ static bool srvsvc_init_cb(void *ptr)
+ return true;
+ }
+
++#ifdef LSA_SUPPORT
+ static bool lsarpc_init_cb(void *ptr)
+ {
+ struct dcesrv_ep_context *ep_ctx =
+@@ -556,6 +557,7 @@ static bool lsarpc_init_cb(void *ptr)
+
+ return true;
+ }
++#endif
+
+ #ifdef SAMR_SUPPORT
+ static bool samr_init_cb(void *ptr)
+@@ -1106,12 +1108,14 @@ bool dcesrv_ep_setup(struct tevent_conte
+ }
+
+
++#ifdef LSA_SUPPORT
+ lsarpc_cb.init = lsarpc_init_cb;
+ lsarpc_cb.shutdown = NULL;
+ lsarpc_cb.private_data = ep_ctx;
+ if (!NT_STATUS_IS_OK(rpc_lsarpc_init(&lsarpc_cb))) {
+ return false;
+ }
++#endif
+
+ #ifdef SAMR_SUPPORT
+ samr_cb.init = samr_init_cb;
+--- a/source3/rpc_server/rpc_handles.c
++++ b/source3/rpc_server/rpc_handles.c
+@@ -63,7 +63,10 @@ static bool is_samr_lsa_pipe(const struc
+ #ifdef SAMR_SUPPORT
+ ndr_syntax_id_equal(syntax, &ndr_table_samr.syntax_id) ||
+ #endif
+- ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id);
++#ifdef LSA_SUPPORT
++ ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id) ||
++#endif
++ false;
+ }
+
+ size_t num_pipe_handles(struct pipes_struct *p)
diff --git a/package/network/services/samba36/patches/300-assert_debug_level.patch b/package/network/services/samba36/patches/300-assert_debug_level.patch
new file mode 100644
index 0000000..c5b0716
--- /dev/null
+++ b/package/network/services/samba36/patches/300-assert_debug_level.patch
@@ -0,0 +1,11 @@
+--- a/lib/util/util.h
++++ b/lib/util/util.h
+@@ -53,7 +53,7 @@ extern const char *panic_action;
+ #else
+ /* redefine the assert macro for non-developer builds */
+ #define SMB_ASSERT(b) do { if (!(b)) { \
+- DEBUG(0,("PANIC: assert failed at %s(%d): %s\n", \
++ DEBUG(3,("PANIC: assert failed at %s(%d): %s\n", \
+ __FILE__, __LINE__, #b)); }} while (0)
+ #endif
+
diff --git a/package/network/services/samba36/patches/310-remove_error_strings.patch b/package/network/services/samba36/patches/310-remove_error_strings.patch
new file mode 100644
index 0000000..8c7ae2d
--- /dev/null
+++ b/package/network/services/samba36/patches/310-remove_error_strings.patch
@@ -0,0 +1,253 @@
+--- a/libcli/util/doserr.c
++++ b/libcli/util/doserr.c
+@@ -28,6 +28,7 @@ struct werror_code_struct {
+
+ static const struct werror_code_struct dos_errs[] =
+ {
++#ifdef VERBOSE_ERROR
+ { "WERR_OK", WERR_OK },
+ { "WERR_BADFILE", WERR_BADFILE },
+ { "WERR_ACCESS_DENIED", WERR_ACCESS_DENIED },
+@@ -2668,6 +2669,7 @@ static const struct werror_code_struct d
+ { "WERR_AMBIGUOUS_SYSTEM_DEVICE", WERR_AMBIGUOUS_SYSTEM_DEVICE },
+ { "WERR_SYSTEM_DEVICE_NOT_FOUND", WERR_SYSTEM_DEVICE_NOT_FOUND },
+ /* END GENERATED-WIN32-ERROR-CODES */
++#endif
+ { NULL, W_ERROR(0) }
+ };
+
+@@ -2684,12 +2686,14 @@ const char *win_errstr(WERROR werror)
+ static char msg[40];
+ int idx = 0;
+
++#ifdef VERBOSE_ERROR
+ while (dos_errs[idx].dos_errstr != NULL) {
+ if (W_ERROR_V(dos_errs[idx].werror) ==
+ W_ERROR_V(werror))
+ return dos_errs[idx].dos_errstr;
+ idx++;
+ }
++#endif
+
+ slprintf(msg, sizeof(msg), "DOS code 0x%08x", W_ERROR_V(werror));
+
+@@ -2702,6 +2706,7 @@ struct werror_str_struct {
+ };
+
+ const struct werror_str_struct dos_err_strs[] = {
++#ifdef VERBOSE_ERROR
+ { WERR_OK, "Success" },
+ { WERR_ACCESS_DENIED, "Access is denied" },
+ { WERR_INVALID_PARAM, "Invalid parameter" },
+@@ -5324,6 +5329,7 @@ const struct werror_str_struct dos_err_s
+ { WERR_AMBIGUOUS_SYSTEM_DEVICE, "The requested system device cannot be identified due to multiple indistinguishable devices potentially matching the identification criteria." },
+ { WERR_SYSTEM_DEVICE_NOT_FOUND, "The requested system device cannot be found." },
+ /* END GENERATED-WIN32-ERROR-CODES-DESC */
++#endif
+ };
+
+
+@@ -5334,6 +5340,7 @@ const struct werror_str_struct dos_err_s
+
+ const char *get_friendly_werror_msg(WERROR werror)
+ {
++#ifdef VERBOSE_ERROR
+ int i = 0;
+
+ for (i = 0; i < ARRAY_SIZE(dos_err_strs); i++) {
+@@ -5342,6 +5349,7 @@ const char *get_friendly_werror_msg(WERR
+ return dos_err_strs[i].friendly_errstr;
+ }
+ }
++#endif
+
+ return win_errstr(werror);
+ }
+--- a/librpc/ndr/libndr.h
++++ b/librpc/ndr/libndr.h
+@@ -604,4 +604,20 @@ _PUBLIC_ enum ndr_err_code ndr_push_enum
+
+ _PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b);
+
++#ifndef VERBOSE_ERROR
++#define ndr_print_bool(...) do {} while (0)
++#define ndr_print_struct(...) do {} while (0)
++#define ndr_print_null(...) do {} while (0)
++#define ndr_print_enum(...) do {} while (0)
++#define ndr_print_bitmap_flag(...) do {} while (0)
++#define ndr_print_ptr(...) do {} while (0)
++#define ndr_print_union(...) do {} while (0)
++#define ndr_print_bad_level(...) do {} while (0)
++#define ndr_print_array_uint8(...) do {} while (0)
++#define ndr_print_string_array(...) do {} while (0)
++#define ndr_print_string_array(...) do {} while (0)
++#define ndr_print_NTSTATUS(...) do {} while (0)
++#define ndr_print_WERROR(...) do {} while (0)
++#endif
++
+ #endif /* __LIBNDR_H__ */
+--- a/librpc/ndr/ndr_basic.c
++++ b/librpc/ndr/ndr_basic.c
+@@ -31,6 +31,19 @@
+ #define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
+ #define NDR_SIVALS(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVALS(ndr->data,ofs,v); } else SIVALS(ndr->data,ofs,v); } while (0)
+
++#undef ndr_print_bool
++#undef ndr_print_struct
++#undef ndr_print_null
++#undef ndr_print_enum
++#undef ndr_print_bitmap_flag
++#undef ndr_print_ptr
++#undef ndr_print_union
++#undef ndr_print_bad_level
++#undef ndr_print_array_uint8
++#undef ndr_print_string_array
++#undef ndr_print_string_array
++#undef ndr_print_NTSTATUS
++#undef ndr_print_WERROR
+
+ /*
+ check for data leaks from the server by looking for non-zero pad bytes
+--- a/librpc/ndr/ndr_string.c
++++ b/librpc/ndr/ndr_string.c
+@@ -588,6 +588,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_stri
+ return NDR_ERR_SUCCESS;
+ }
+
++#undef ndr_print_string_array
+ _PUBLIC_ void ndr_print_string_array(struct ndr_print *ndr, const char *name, const char **a)
+ {
+ uint32_t count;
+--- a/librpc/rpc/dcerpc_error.c
++++ b/librpc/rpc/dcerpc_error.c
+@@ -31,6 +31,7 @@ struct dcerpc_fault_table {
+ static const struct dcerpc_fault_table dcerpc_faults[] =
+ {
+ #define _FAULT_STR(x) { #x , x }
++#ifdef VERBOSE_ERROR
+ _FAULT_STR(DCERPC_NCA_S_COMM_FAILURE),
+ _FAULT_STR(DCERPC_NCA_S_OP_RNG_ERROR),
+ _FAULT_STR(DCERPC_NCA_S_UNKNOWN_IF),
+@@ -78,6 +79,7 @@ static const struct dcerpc_fault_table d
+ _FAULT_STR(DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR),
+ _FAULT_STR(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND),
+ _FAULT_STR(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB),
++#endif
+ { NULL, 0 }
+ #undef _FAULT_STR
+ };
+@@ -87,12 +89,14 @@ _PUBLIC_ const char *dcerpc_errstr(TALLO
+ int idx = 0;
+ WERROR werr = W_ERROR(fault_code);
+
++#ifdef VERBOSE_ERROR
+ while (dcerpc_faults[idx].errstr != NULL) {
+ if (dcerpc_faults[idx].faultcode == fault_code) {
+ return dcerpc_faults[idx].errstr;
+ }
+ idx++;
+ }
++#endif
+
+ return win_errstr(werr);
+ }
+--- a/source3/libsmb/nterr.c
++++ b/source3/libsmb/nterr.c
+@@ -702,6 +702,7 @@ const char *nt_errstr(NTSTATUS nt_code)
+ NT_STATUS_DOS_CODE(nt_code));
+ }
+
++#ifdef VERBOSE_ERROR
+ while (nt_errs[idx].nt_errstr != NULL) {
+ if (NT_STATUS_V(nt_errs[idx].nt_errcode) ==
+ NT_STATUS_V(nt_code)) {
+@@ -709,6 +710,7 @@ const char *nt_errstr(NTSTATUS nt_code)
+ }
+ idx++;
+ }
++#endif
+
+ result = talloc_asprintf(talloc_tos(), "NT code 0x%08x",
+ NT_STATUS_V(nt_code));
+@@ -724,12 +726,14 @@ const char *get_friendly_nt_error_msg(NT
+ {
+ int idx = 0;
+
++#ifdef VERBOSE_ERROR
+ while (nt_err_desc[idx].nt_errstr != NULL) {
+ if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) {
+ return nt_err_desc[idx].nt_errstr;
+ }
+ idx++;
+ }
++#endif
+
+ /* fall back to NT_STATUS_XXX string */
+
+@@ -745,6 +749,7 @@ const char *get_nt_error_c_code(NTSTATUS
+ char *result;
+ int idx = 0;
+
++#ifdef VERBOSE_ERROR
+ while (nt_errs[idx].nt_errstr != NULL) {
+ if (NT_STATUS_V(nt_errs[idx].nt_errcode) ==
+ NT_STATUS_V(nt_code)) {
+@@ -752,6 +757,7 @@ const char *get_nt_error_c_code(NTSTATUS
+ }
+ idx++;
+ }
++#endif
+
+ result = talloc_asprintf(talloc_tos(), "NT_STATUS(0x%08x)",
+ NT_STATUS_V(nt_code));
+@@ -767,12 +773,14 @@ NTSTATUS nt_status_string_to_code(const
+ {
+ int idx = 0;
+
++#ifdef VERBOSE_ERROR
+ while (nt_errs[idx].nt_errstr != NULL) {
+ if (strcasecmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) {
+ return nt_errs[idx].nt_errcode;
+ }
+ idx++;
+ }
++#endif
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+--- a/lib/tdb/common/tdb_private.h
++++ b/lib/tdb/common/tdb_private.h
+@@ -69,7 +69,11 @@ typedef uint32_t tdb_off_t;
+ /* NB assumes there is a local variable called "tdb" that is the
+ * current context, also takes doubly-parenthesized print-style
+ * argument. */
++#ifdef VERBOSE_DEBUG
+ #define TDB_LOG(x) tdb->log.log_fn x
++#else
++#define TDB_LOG(x) do {} while(0)
++#endif
+
+ #ifdef TDB_TRACE
+ void tdb_trace(struct tdb_context *tdb, const char *op);
+--- a/source3/script/mkbuildoptions.awk
++++ b/source3/script/mkbuildoptions.awk
+@@ -55,7 +55,7 @@ BEGIN {
+ print "****************************************************************************/";
+ print "void build_options(bool screen)";
+ print "{";
+- print " if ((DEBUGLEVEL < 4) && (!screen)) {";
++ print " if ((DEBUGLEVEL < 4) || (!screen)) {";
+ print " return;";
+ print " }";
+ print "";
+--- a/source3/script/mkbuildoptions-waf.awk
++++ b/source3/script/mkbuildoptions-waf.awk
+@@ -55,7 +55,7 @@ BEGIN {
+ print "****************************************************************************/";
+ print "void build_options(bool screen)";
+ print "{";
+- print " if ((DEBUGLEVEL < 4) && (!screen)) {";
++ print " if ((DEBUGLEVEL < 4) || (!screen)) {";
+ print " return;";
+ print " }";
+ print "";
diff --git a/package/network/services/samba36/patches/320-debug_level_checks.patch b/package/network/services/samba36/patches/320-debug_level_checks.patch
new file mode 100644
index 0000000..c6f2e6e
--- /dev/null
+++ b/package/network/services/samba36/patches/320-debug_level_checks.patch
@@ -0,0 +1,22 @@
+--- a/lib/util/debug.h
++++ b/lib/util/debug.h
+@@ -45,7 +45,7 @@ bool dbghdr( int level, const char *loca
+ * Redefine DEBUGLEVEL because so we don't have to change every source file
+ * that *unnecessarily* references it.
+ */
+-#define DEBUGLEVEL DEBUGLEVEL_CLASS[DBGC_ALL]
++#define DEBUGLEVEL 0
+
+ /*
+ * Define all new debug classes here. A class is represented by an entry in
+--- a/source3/nmbd/asyncdns.c
++++ b/source3/nmbd/asyncdns.c
+@@ -85,7 +85,7 @@ static void asyncdns_process(void)
+ struct query_record r;
+ unstring qname;
+
+- DEBUGLEVEL = -1;
++ DEBUGLEVEL_CLASS[DBGC_ALL] = -1;
+
+ while (1) {
+ NTSTATUS status;
diff --git a/package/network/services/samba36/patches/330-librpc_default_print.patch b/package/network/services/samba36/patches/330-librpc_default_print.patch
new file mode 100644
index 0000000..f9c2e0e
--- /dev/null
+++ b/package/network/services/samba36/patches/330-librpc_default_print.patch
@@ -0,0 +1,8854 @@
+--- a/source3/librpc/ndr/util.c
++++ b/source3/librpc/ndr/util.c
+@@ -28,3 +28,7 @@ _PUBLIC_ void ndr_print_sockaddr_storage
+ char addr[INET6_ADDRSTRLEN];
+ ndr->print(ndr, "%-25s: %s", name, print_sockaddr(addr, sizeof(addr), ss));
+ }
++
++_PUBLIC_ void ndr_print_disabled(struct ndr_print *ndr, const char *name, int flags, void *r)
++{
++}
+--- a/source3/librpc/gen_ndr/ndr_atsvc.c
++++ b/source3/librpc/gen_ndr/ndr_atsvc.c
+@@ -867,7 +867,7 @@ static const struct ndr_interface_call a
+ sizeof(struct atsvc_JobAdd),
+ (ndr_push_flags_fn_t) ndr_push_atsvc_JobAdd,
+ (ndr_pull_flags_fn_t) ndr_pull_atsvc_JobAdd,
+- (ndr_print_function_t) ndr_print_atsvc_JobAdd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -876,7 +876,7 @@ static const struct ndr_interface_call a
+ sizeof(struct atsvc_JobDel),
+ (ndr_push_flags_fn_t) ndr_push_atsvc_JobDel,
+ (ndr_pull_flags_fn_t) ndr_pull_atsvc_JobDel,
+- (ndr_print_function_t) ndr_print_atsvc_JobDel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -885,7 +885,7 @@ static const struct ndr_interface_call a
+ sizeof(struct atsvc_JobEnum),
+ (ndr_push_flags_fn_t) ndr_push_atsvc_JobEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_atsvc_JobEnum,
+- (ndr_print_function_t) ndr_print_atsvc_JobEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -894,7 +894,7 @@ static const struct ndr_interface_call a
+ sizeof(struct atsvc_JobGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_atsvc_JobGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_atsvc_JobGetInfo,
+- (ndr_print_function_t) ndr_print_atsvc_JobGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_audiosrv.c
++++ b/source3/librpc/gen_ndr/ndr_audiosrv.c
+@@ -594,7 +594,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_CreatezoneFactoriesList),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_CreatezoneFactoriesList,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_CreatezoneFactoriesList,
+- (ndr_print_function_t) ndr_print_audiosrv_CreatezoneFactoriesList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -603,7 +603,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_CreateGfxFactoriesList),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_CreateGfxFactoriesList,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_CreateGfxFactoriesList,
+- (ndr_print_function_t) ndr_print_audiosrv_CreateGfxFactoriesList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -612,7 +612,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_CreateGfxList),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_CreateGfxList,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_CreateGfxList,
+- (ndr_print_function_t) ndr_print_audiosrv_CreateGfxList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -621,7 +621,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_RemoveGfx),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_RemoveGfx,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_RemoveGfx,
+- (ndr_print_function_t) ndr_print_audiosrv_RemoveGfx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -630,7 +630,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_AddGfx),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_AddGfx,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_AddGfx,
+- (ndr_print_function_t) ndr_print_audiosrv_AddGfx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -639,7 +639,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_ModifyGfx),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_ModifyGfx,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_ModifyGfx,
+- (ndr_print_function_t) ndr_print_audiosrv_ModifyGfx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -648,7 +648,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_OpenGfx),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_OpenGfx,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_OpenGfx,
+- (ndr_print_function_t) ndr_print_audiosrv_OpenGfx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -657,7 +657,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_Logon),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_Logon,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_Logon,
+- (ndr_print_function_t) ndr_print_audiosrv_Logon,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -666,7 +666,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_Logoff),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_Logoff,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_Logoff,
+- (ndr_print_function_t) ndr_print_audiosrv_Logoff,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -675,7 +675,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_RegisterSessionNotificationEvent),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_RegisterSessionNotificationEvent,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_RegisterSessionNotificationEvent,
+- (ndr_print_function_t) ndr_print_audiosrv_RegisterSessionNotificationEvent,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -684,7 +684,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_UnregisterSessionNotificationEvent),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_UnregisterSessionNotificationEvent,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_UnregisterSessionNotificationEvent,
+- (ndr_print_function_t) ndr_print_audiosrv_UnregisterSessionNotificationEvent,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -693,7 +693,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_SessionConnectState),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_SessionConnectState,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_SessionConnectState,
+- (ndr_print_function_t) ndr_print_audiosrv_SessionConnectState,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -702,7 +702,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_DriverOpenDrvRegKey),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_DriverOpenDrvRegKey,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_DriverOpenDrvRegKey,
+- (ndr_print_function_t) ndr_print_audiosrv_DriverOpenDrvRegKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -711,7 +711,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_AdvisePreferredDeviceChange),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_AdvisePreferredDeviceChange,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_AdvisePreferredDeviceChange,
+- (ndr_print_function_t) ndr_print_audiosrv_AdvisePreferredDeviceChange,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -720,7 +720,7 @@ static const struct ndr_interface_call a
+ sizeof(struct audiosrv_GetPnpInfo),
+ (ndr_push_flags_fn_t) ndr_push_audiosrv_GetPnpInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_audiosrv_GetPnpInfo,
+- (ndr_print_function_t) ndr_print_audiosrv_GetPnpInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_backupkey.c
++++ b/source3/librpc/gen_ndr/ndr_backupkey.c
+@@ -740,7 +740,7 @@ static const struct ndr_interface_call b
+ sizeof(struct bkrp_BackupKey),
+ (ndr_push_flags_fn_t) ndr_push_bkrp_BackupKey,
+ (ndr_pull_flags_fn_t) ndr_pull_bkrp_BackupKey,
+- (ndr_print_function_t) ndr_print_bkrp_BackupKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_browser.c
++++ b/source3/librpc/gen_ndr/ndr_browser.c
+@@ -928,7 +928,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserrServerEnum),
+ (ndr_push_flags_fn_t) ndr_push_BrowserrServerEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserrServerEnum,
+- (ndr_print_function_t) ndr_print_BrowserrServerEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -937,7 +937,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserrDebugCall),
+ (ndr_push_flags_fn_t) ndr_push_BrowserrDebugCall,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserrDebugCall,
+- (ndr_print_function_t) ndr_print_BrowserrDebugCall,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -946,7 +946,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserrQueryOtherDomains),
+ (ndr_push_flags_fn_t) ndr_push_BrowserrQueryOtherDomains,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserrQueryOtherDomains,
+- (ndr_print_function_t) ndr_print_BrowserrQueryOtherDomains,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -955,7 +955,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserrResetNetlogonState),
+ (ndr_push_flags_fn_t) ndr_push_BrowserrResetNetlogonState,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserrResetNetlogonState,
+- (ndr_print_function_t) ndr_print_BrowserrResetNetlogonState,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -964,7 +964,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserrDebugTrace),
+ (ndr_push_flags_fn_t) ndr_push_BrowserrDebugTrace,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserrDebugTrace,
+- (ndr_print_function_t) ndr_print_BrowserrDebugTrace,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -973,7 +973,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserrQueryStatistics),
+ (ndr_push_flags_fn_t) ndr_push_BrowserrQueryStatistics,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserrQueryStatistics,
+- (ndr_print_function_t) ndr_print_BrowserrQueryStatistics,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -982,7 +982,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserResetStatistics),
+ (ndr_push_flags_fn_t) ndr_push_BrowserResetStatistics,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserResetStatistics,
+- (ndr_print_function_t) ndr_print_BrowserResetStatistics,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -991,7 +991,7 @@ static const struct ndr_interface_call b
+ sizeof(struct NetrBrowserStatisticsClear),
+ (ndr_push_flags_fn_t) ndr_push_NetrBrowserStatisticsClear,
+ (ndr_pull_flags_fn_t) ndr_pull_NetrBrowserStatisticsClear,
+- (ndr_print_function_t) ndr_print_NetrBrowserStatisticsClear,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1000,7 +1000,7 @@ static const struct ndr_interface_call b
+ sizeof(struct NetrBrowserStatisticsGet),
+ (ndr_push_flags_fn_t) ndr_push_NetrBrowserStatisticsGet,
+ (ndr_pull_flags_fn_t) ndr_pull_NetrBrowserStatisticsGet,
+- (ndr_print_function_t) ndr_print_NetrBrowserStatisticsGet,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1009,7 +1009,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserrSetNetlogonState),
+ (ndr_push_flags_fn_t) ndr_push_BrowserrSetNetlogonState,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserrSetNetlogonState,
+- (ndr_print_function_t) ndr_print_BrowserrSetNetlogonState,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1018,7 +1018,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserrQueryEmulatedDomains),
+ (ndr_push_flags_fn_t) ndr_push_BrowserrQueryEmulatedDomains,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserrQueryEmulatedDomains,
+- (ndr_print_function_t) ndr_print_BrowserrQueryEmulatedDomains,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1027,7 +1027,7 @@ static const struct ndr_interface_call b
+ sizeof(struct BrowserrServerEnumEx),
+ (ndr_push_flags_fn_t) ndr_push_BrowserrServerEnumEx,
+ (ndr_pull_flags_fn_t) ndr_pull_BrowserrServerEnumEx,
+- (ndr_print_function_t) ndr_print_BrowserrServerEnumEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_dbgidl.c
++++ b/source3/librpc/gen_ndr/ndr_dbgidl.c
+@@ -48,7 +48,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dummy_dbgidl),
+ (ndr_push_flags_fn_t) ndr_push_dummy_dbgidl,
+ (ndr_pull_flags_fn_t) ndr_pull_dummy_dbgidl,
+- (ndr_print_function_t) ndr_print_dummy_dbgidl,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_dcom.c
++++ b/source3/librpc/gen_ndr/ndr_dcom.c
+@@ -128,7 +128,7 @@ static const struct ndr_interface_call d
+ sizeof(struct UseProtSeq),
+ (ndr_push_flags_fn_t) ndr_push_UseProtSeq,
+ (ndr_pull_flags_fn_t) ndr_pull_UseProtSeq,
+- (ndr_print_function_t) ndr_print_UseProtSeq,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -137,7 +137,7 @@ static const struct ndr_interface_call d
+ sizeof(struct GetCustomProtseqInfo),
+ (ndr_push_flags_fn_t) ndr_push_GetCustomProtseqInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_GetCustomProtseqInfo,
+- (ndr_print_function_t) ndr_print_GetCustomProtseqInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -146,7 +146,7 @@ static const struct ndr_interface_call d
+ sizeof(struct UpdateResolverBindings),
+ (ndr_push_flags_fn_t) ndr_push_UpdateResolverBindings,
+ (ndr_pull_flags_fn_t) ndr_pull_UpdateResolverBindings,
+- (ndr_print_function_t) ndr_print_UpdateResolverBindings,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -450,7 +450,7 @@ static const struct ndr_interface_call I
+ sizeof(struct QueryInterface),
+ (ndr_push_flags_fn_t) ndr_push_QueryInterface,
+ (ndr_pull_flags_fn_t) ndr_pull_QueryInterface,
+- (ndr_print_function_t) ndr_print_QueryInterface,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -459,7 +459,7 @@ static const struct ndr_interface_call I
+ sizeof(struct AddRef),
+ (ndr_push_flags_fn_t) ndr_push_AddRef,
+ (ndr_pull_flags_fn_t) ndr_pull_AddRef,
+- (ndr_print_function_t) ndr_print_AddRef,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -468,7 +468,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Release),
+ (ndr_push_flags_fn_t) ndr_push_Release,
+ (ndr_pull_flags_fn_t) ndr_pull_Release,
+- (ndr_print_function_t) ndr_print_Release,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -849,7 +849,7 @@ static const struct ndr_interface_call I
+ sizeof(struct CreateInstance),
+ (ndr_push_flags_fn_t) ndr_push_CreateInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_CreateInstance,
+- (ndr_print_function_t) ndr_print_CreateInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -858,7 +858,7 @@ static const struct ndr_interface_call I
+ sizeof(struct RemoteCreateInstance),
+ (ndr_push_flags_fn_t) ndr_push_RemoteCreateInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_RemoteCreateInstance,
+- (ndr_print_function_t) ndr_print_RemoteCreateInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -867,7 +867,7 @@ static const struct ndr_interface_call I
+ sizeof(struct LockServer),
+ (ndr_push_flags_fn_t) ndr_push_LockServer,
+ (ndr_pull_flags_fn_t) ndr_pull_LockServer,
+- (ndr_print_function_t) ndr_print_LockServer,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -876,7 +876,7 @@ static const struct ndr_interface_call I
+ sizeof(struct RemoteLockServer),
+ (ndr_push_flags_fn_t) ndr_push_RemoteLockServer,
+ (ndr_pull_flags_fn_t) ndr_pull_RemoteLockServer,
+- (ndr_print_function_t) ndr_print_RemoteLockServer,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1434,7 +1434,7 @@ static const struct ndr_interface_call I
+ sizeof(struct RemQueryInterface),
+ (ndr_push_flags_fn_t) ndr_push_RemQueryInterface,
+ (ndr_pull_flags_fn_t) ndr_pull_RemQueryInterface,
+- (ndr_print_function_t) ndr_print_RemQueryInterface,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1443,7 +1443,7 @@ static const struct ndr_interface_call I
+ sizeof(struct RemAddRef),
+ (ndr_push_flags_fn_t) ndr_push_RemAddRef,
+ (ndr_pull_flags_fn_t) ndr_pull_RemAddRef,
+- (ndr_print_function_t) ndr_print_RemAddRef,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1452,7 +1452,7 @@ static const struct ndr_interface_call I
+ sizeof(struct RemRelease),
+ (ndr_push_flags_fn_t) ndr_push_RemRelease,
+ (ndr_pull_flags_fn_t) ndr_pull_RemRelease,
+- (ndr_print_function_t) ndr_print_RemRelease,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1590,7 +1590,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetClassObject),
+ (ndr_push_flags_fn_t) ndr_push_GetClassObject,
+ (ndr_pull_flags_fn_t) ndr_pull_GetClassObject,
+- (ndr_print_function_t) ndr_print_GetClassObject,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1701,7 +1701,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ISCMLocalActivator_CreateInstance),
+ (ndr_push_flags_fn_t) ndr_push_ISCMLocalActivator_CreateInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_ISCMLocalActivator_CreateInstance,
+- (ndr_print_function_t) ndr_print_ISCMLocalActivator_CreateInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1788,7 +1788,7 @@ static const struct ndr_interface_call I
+ sizeof(struct IMachineLocalActivator_foo),
+ (ndr_push_flags_fn_t) ndr_push_IMachineLocalActivator_foo,
+ (ndr_pull_flags_fn_t) ndr_pull_IMachineLocalActivator_foo,
+- (ndr_print_function_t) ndr_print_IMachineLocalActivator_foo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1875,7 +1875,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ILocalObjectExporter_Foo),
+ (ndr_push_flags_fn_t) ndr_push_ILocalObjectExporter_Foo,
+ (ndr_pull_flags_fn_t) ndr_pull_ILocalObjectExporter_Foo,
+- (ndr_print_function_t) ndr_print_ILocalObjectExporter_Foo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2031,7 +2031,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ISystemActivatorRemoteCreateInstance),
+ (ndr_push_flags_fn_t) ndr_push_ISystemActivatorRemoteCreateInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_ISystemActivatorRemoteCreateInstance,
+- (ndr_print_function_t) ndr_print_ISystemActivatorRemoteCreateInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2319,7 +2319,7 @@ static const struct ndr_interface_call I
+ sizeof(struct RemQueryInterface2),
+ (ndr_push_flags_fn_t) ndr_push_RemQueryInterface2,
+ (ndr_pull_flags_fn_t) ndr_pull_RemQueryInterface2,
+- (ndr_print_function_t) ndr_print_RemQueryInterface2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3040,7 +3040,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetTypeInfoCount),
+ (ndr_push_flags_fn_t) ndr_push_GetTypeInfoCount,
+ (ndr_pull_flags_fn_t) ndr_pull_GetTypeInfoCount,
+- (ndr_print_function_t) ndr_print_GetTypeInfoCount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3049,7 +3049,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetTypeInfo),
+ (ndr_push_flags_fn_t) ndr_push_GetTypeInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_GetTypeInfo,
+- (ndr_print_function_t) ndr_print_GetTypeInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3058,7 +3058,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetIDsOfNames),
+ (ndr_push_flags_fn_t) ndr_push_GetIDsOfNames,
+ (ndr_pull_flags_fn_t) ndr_pull_GetIDsOfNames,
+- (ndr_print_function_t) ndr_print_GetIDsOfNames,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3067,7 +3067,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Invoke),
+ (ndr_push_flags_fn_t) ndr_push_Invoke,
+ (ndr_pull_flags_fn_t) ndr_pull_Invoke,
+- (ndr_print_function_t) ndr_print_Invoke,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3243,7 +3243,7 @@ static const struct ndr_interface_call I
+ sizeof(struct MarshalInterface),
+ (ndr_push_flags_fn_t) ndr_push_MarshalInterface,
+ (ndr_pull_flags_fn_t) ndr_pull_MarshalInterface,
+- (ndr_print_function_t) ndr_print_MarshalInterface,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3252,7 +3252,7 @@ static const struct ndr_interface_call I
+ sizeof(struct UnMarshalInterface),
+ (ndr_push_flags_fn_t) ndr_push_UnMarshalInterface,
+ (ndr_pull_flags_fn_t) ndr_pull_UnMarshalInterface,
+- (ndr_print_function_t) ndr_print_UnMarshalInterface,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3385,7 +3385,7 @@ static const struct ndr_interface_call I
+ sizeof(struct MakeCoffee),
+ (ndr_push_flags_fn_t) ndr_push_MakeCoffee,
+ (ndr_pull_flags_fn_t) ndr_pull_MakeCoffee,
+- (ndr_print_function_t) ndr_print_MakeCoffee,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3681,7 +3681,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Read),
+ (ndr_push_flags_fn_t) ndr_push_Read,
+ (ndr_pull_flags_fn_t) ndr_pull_Read,
+- (ndr_print_function_t) ndr_print_Read,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3690,7 +3690,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Write),
+ (ndr_push_flags_fn_t) ndr_push_Write,
+ (ndr_pull_flags_fn_t) ndr_pull_Write,
+- (ndr_print_function_t) ndr_print_Write,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_dfs.c
++++ b/source3/librpc/gen_ndr/ndr_dfs.c
+@@ -5910,7 +5910,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_GetManagerVersion),
+ (ndr_push_flags_fn_t) ndr_push_dfs_GetManagerVersion,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_GetManagerVersion,
+- (ndr_print_function_t) ndr_print_dfs_GetManagerVersion,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5919,7 +5919,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_Add),
+ (ndr_push_flags_fn_t) ndr_push_dfs_Add,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_Add,
+- (ndr_print_function_t) ndr_print_dfs_Add,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5928,7 +5928,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_Remove),
+ (ndr_push_flags_fn_t) ndr_push_dfs_Remove,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_Remove,
+- (ndr_print_function_t) ndr_print_dfs_Remove,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5937,7 +5937,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_SetInfo),
+ (ndr_push_flags_fn_t) ndr_push_dfs_SetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_SetInfo,
+- (ndr_print_function_t) ndr_print_dfs_SetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5946,7 +5946,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_GetInfo),
+ (ndr_push_flags_fn_t) ndr_push_dfs_GetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_GetInfo,
+- (ndr_print_function_t) ndr_print_dfs_GetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5955,7 +5955,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_Enum),
+ (ndr_push_flags_fn_t) ndr_push_dfs_Enum,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_Enum,
+- (ndr_print_function_t) ndr_print_dfs_Enum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5964,7 +5964,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_Rename),
+ (ndr_push_flags_fn_t) ndr_push_dfs_Rename,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_Rename,
+- (ndr_print_function_t) ndr_print_dfs_Rename,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5973,7 +5973,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_Move),
+ (ndr_push_flags_fn_t) ndr_push_dfs_Move,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_Move,
+- (ndr_print_function_t) ndr_print_dfs_Move,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5982,7 +5982,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_ManagerGetConfigInfo),
+ (ndr_push_flags_fn_t) ndr_push_dfs_ManagerGetConfigInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_ManagerGetConfigInfo,
+- (ndr_print_function_t) ndr_print_dfs_ManagerGetConfigInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5991,7 +5991,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_ManagerSendSiteInfo),
+ (ndr_push_flags_fn_t) ndr_push_dfs_ManagerSendSiteInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_ManagerSendSiteInfo,
+- (ndr_print_function_t) ndr_print_dfs_ManagerSendSiteInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6000,7 +6000,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_AddFtRoot),
+ (ndr_push_flags_fn_t) ndr_push_dfs_AddFtRoot,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_AddFtRoot,
+- (ndr_print_function_t) ndr_print_dfs_AddFtRoot,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6009,7 +6009,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_RemoveFtRoot),
+ (ndr_push_flags_fn_t) ndr_push_dfs_RemoveFtRoot,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_RemoveFtRoot,
+- (ndr_print_function_t) ndr_print_dfs_RemoveFtRoot,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6018,7 +6018,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_AddStdRoot),
+ (ndr_push_flags_fn_t) ndr_push_dfs_AddStdRoot,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_AddStdRoot,
+- (ndr_print_function_t) ndr_print_dfs_AddStdRoot,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6027,7 +6027,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_RemoveStdRoot),
+ (ndr_push_flags_fn_t) ndr_push_dfs_RemoveStdRoot,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_RemoveStdRoot,
+- (ndr_print_function_t) ndr_print_dfs_RemoveStdRoot,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6036,7 +6036,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_ManagerInitialize),
+ (ndr_push_flags_fn_t) ndr_push_dfs_ManagerInitialize,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_ManagerInitialize,
+- (ndr_print_function_t) ndr_print_dfs_ManagerInitialize,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6045,7 +6045,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_AddStdRootForced),
+ (ndr_push_flags_fn_t) ndr_push_dfs_AddStdRootForced,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_AddStdRootForced,
+- (ndr_print_function_t) ndr_print_dfs_AddStdRootForced,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6054,7 +6054,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_GetDcAddress),
+ (ndr_push_flags_fn_t) ndr_push_dfs_GetDcAddress,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_GetDcAddress,
+- (ndr_print_function_t) ndr_print_dfs_GetDcAddress,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6063,7 +6063,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_SetDcAddress),
+ (ndr_push_flags_fn_t) ndr_push_dfs_SetDcAddress,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_SetDcAddress,
+- (ndr_print_function_t) ndr_print_dfs_SetDcAddress,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6072,7 +6072,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_FlushFtTable),
+ (ndr_push_flags_fn_t) ndr_push_dfs_FlushFtTable,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_FlushFtTable,
+- (ndr_print_function_t) ndr_print_dfs_FlushFtTable,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6081,7 +6081,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_Add2),
+ (ndr_push_flags_fn_t) ndr_push_dfs_Add2,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_Add2,
+- (ndr_print_function_t) ndr_print_dfs_Add2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6090,7 +6090,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_Remove2),
+ (ndr_push_flags_fn_t) ndr_push_dfs_Remove2,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_Remove2,
+- (ndr_print_function_t) ndr_print_dfs_Remove2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6099,7 +6099,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_EnumEx),
+ (ndr_push_flags_fn_t) ndr_push_dfs_EnumEx,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_EnumEx,
+- (ndr_print_function_t) ndr_print_dfs_EnumEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6108,7 +6108,7 @@ static const struct ndr_interface_call n
+ sizeof(struct dfs_SetInfo2),
+ (ndr_push_flags_fn_t) ndr_push_dfs_SetInfo2,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_SetInfo2,
+- (ndr_print_function_t) ndr_print_dfs_SetInfo2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_dfsblobs.c
++++ b/source3/librpc/gen_ndr/ndr_dfsblobs.c
+@@ -1398,7 +1398,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dfs_GetDFSReferral),
+ (ndr_push_flags_fn_t) ndr_push_dfs_GetDFSReferral,
+ (ndr_pull_flags_fn_t) ndr_pull_dfs_GetDFSReferral,
+- (ndr_print_function_t) ndr_print_dfs_GetDFSReferral,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_dns.c
++++ b/source3/librpc/gen_ndr/ndr_dns.c
+@@ -860,7 +860,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_dns_name_packet),
+ (ndr_push_flags_fn_t) ndr_push_decode_dns_name_packet,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_dns_name_packet,
+- (ndr_print_function_t) ndr_print_decode_dns_name_packet,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_dnsp.c
++++ b/source3/librpc/gen_ndr/ndr_dnsp.c
+@@ -700,7 +700,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_DnssrvRpcRecord),
+ (ndr_push_flags_fn_t) ndr_push_decode_DnssrvRpcRecord,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_DnssrvRpcRecord,
+- (ndr_print_function_t) ndr_print_decode_DnssrvRpcRecord,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_dnsserver.c
++++ b/source3/librpc/gen_ndr/ndr_dnsserver.c
+@@ -48,7 +48,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dnsserver_foo),
+ (ndr_push_flags_fn_t) ndr_push_dnsserver_foo,
+ (ndr_pull_flags_fn_t) ndr_pull_dnsserver_foo,
+- (ndr_print_function_t) ndr_print_dnsserver_foo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_drsblobs.c
++++ b/source3/librpc/gen_ndr/ndr_drsblobs.c
+@@ -5275,7 +5275,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_replPropertyMetaData),
+ (ndr_push_flags_fn_t) ndr_push_decode_replPropertyMetaData,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_replPropertyMetaData,
+- (ndr_print_function_t) ndr_print_decode_replPropertyMetaData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5284,7 +5284,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_replUpToDateVector),
+ (ndr_push_flags_fn_t) ndr_push_decode_replUpToDateVector,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_replUpToDateVector,
+- (ndr_print_function_t) ndr_print_decode_replUpToDateVector,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5293,7 +5293,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_repsFromTo),
+ (ndr_push_flags_fn_t) ndr_push_decode_repsFromTo,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_repsFromTo,
+- (ndr_print_function_t) ndr_print_decode_repsFromTo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5302,7 +5302,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_partialAttributeSet),
+ (ndr_push_flags_fn_t) ndr_push_decode_partialAttributeSet,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_partialAttributeSet,
+- (ndr_print_function_t) ndr_print_decode_partialAttributeSet,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5311,7 +5311,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_prefixMap),
+ (ndr_push_flags_fn_t) ndr_push_decode_prefixMap,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_prefixMap,
+- (ndr_print_function_t) ndr_print_decode_prefixMap,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5320,7 +5320,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_ldapControlDirSync),
+ (ndr_push_flags_fn_t) ndr_push_decode_ldapControlDirSync,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_ldapControlDirSync,
+- (ndr_print_function_t) ndr_print_decode_ldapControlDirSync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5329,7 +5329,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_supplementalCredentials),
+ (ndr_push_flags_fn_t) ndr_push_decode_supplementalCredentials,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_supplementalCredentials,
+- (ndr_print_function_t) ndr_print_decode_supplementalCredentials,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5338,7 +5338,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_Packages),
+ (ndr_push_flags_fn_t) ndr_push_decode_Packages,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_Packages,
+- (ndr_print_function_t) ndr_print_decode_Packages,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5347,7 +5347,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_PrimaryKerberos),
+ (ndr_push_flags_fn_t) ndr_push_decode_PrimaryKerberos,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_PrimaryKerberos,
+- (ndr_print_function_t) ndr_print_decode_PrimaryKerberos,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5356,7 +5356,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_PrimaryCLEARTEXT),
+ (ndr_push_flags_fn_t) ndr_push_decode_PrimaryCLEARTEXT,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_PrimaryCLEARTEXT,
+- (ndr_print_function_t) ndr_print_decode_PrimaryCLEARTEXT,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5365,7 +5365,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_PrimaryWDigest),
+ (ndr_push_flags_fn_t) ndr_push_decode_PrimaryWDigest,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_PrimaryWDigest,
+- (ndr_print_function_t) ndr_print_decode_PrimaryWDigest,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5374,7 +5374,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_trustAuthInOut),
+ (ndr_push_flags_fn_t) ndr_push_decode_trustAuthInOut,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_trustAuthInOut,
+- (ndr_print_function_t) ndr_print_decode_trustAuthInOut,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5383,7 +5383,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_trustDomainPasswords),
+ (ndr_push_flags_fn_t) ndr_push_decode_trustDomainPasswords,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_trustDomainPasswords,
+- (ndr_print_function_t) ndr_print_decode_trustDomainPasswords,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5392,7 +5392,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_ExtendedErrorInfo),
+ (ndr_push_flags_fn_t) ndr_push_decode_ExtendedErrorInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_ExtendedErrorInfo,
+- (ndr_print_function_t) ndr_print_decode_ExtendedErrorInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5401,7 +5401,7 @@ static const struct ndr_interface_call d
+ sizeof(struct decode_ForestTrustInfo),
+ (ndr_push_flags_fn_t) ndr_push_decode_ForestTrustInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_ForestTrustInfo,
+- (ndr_print_function_t) ndr_print_decode_ForestTrustInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_drsuapi.c
++++ b/source3/librpc/gen_ndr/ndr_drsuapi.c
+@@ -16500,7 +16500,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsBind),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsBind,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsBind,
+- (ndr_print_function_t) ndr_print_drsuapi_DsBind,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16509,7 +16509,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsUnbind),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsUnbind,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsUnbind,
+- (ndr_print_function_t) ndr_print_drsuapi_DsUnbind,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16518,7 +16518,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsReplicaSync),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsReplicaSync,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsReplicaSync,
+- (ndr_print_function_t) ndr_print_drsuapi_DsReplicaSync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16527,7 +16527,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsGetNCChanges),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsGetNCChanges,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsGetNCChanges,
+- (ndr_print_function_t) ndr_print_drsuapi_DsGetNCChanges,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16536,7 +16536,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsReplicaUpdateRefs),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsReplicaUpdateRefs,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsReplicaUpdateRefs,
+- (ndr_print_function_t) ndr_print_drsuapi_DsReplicaUpdateRefs,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16545,7 +16545,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsReplicaAdd),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsReplicaAdd,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsReplicaAdd,
+- (ndr_print_function_t) ndr_print_drsuapi_DsReplicaAdd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16554,7 +16554,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsReplicaDel),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsReplicaDel,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsReplicaDel,
+- (ndr_print_function_t) ndr_print_drsuapi_DsReplicaDel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16563,7 +16563,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsReplicaMod),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsReplicaMod,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsReplicaMod,
+- (ndr_print_function_t) ndr_print_drsuapi_DsReplicaMod,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16572,7 +16572,7 @@ static const struct ndr_interface_call d
+ sizeof(struct DRSUAPI_VERIFY_NAMES),
+ (ndr_push_flags_fn_t) ndr_push_DRSUAPI_VERIFY_NAMES,
+ (ndr_pull_flags_fn_t) ndr_pull_DRSUAPI_VERIFY_NAMES,
+- (ndr_print_function_t) ndr_print_DRSUAPI_VERIFY_NAMES,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16581,7 +16581,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsGetMemberships),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsGetMemberships,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsGetMemberships,
+- (ndr_print_function_t) ndr_print_drsuapi_DsGetMemberships,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16590,7 +16590,7 @@ static const struct ndr_interface_call d
+ sizeof(struct DRSUAPI_INTER_DOMAIN_MOVE),
+ (ndr_push_flags_fn_t) ndr_push_DRSUAPI_INTER_DOMAIN_MOVE,
+ (ndr_pull_flags_fn_t) ndr_pull_DRSUAPI_INTER_DOMAIN_MOVE,
+- (ndr_print_function_t) ndr_print_DRSUAPI_INTER_DOMAIN_MOVE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16599,7 +16599,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsGetNT4ChangeLog),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsGetNT4ChangeLog,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsGetNT4ChangeLog,
+- (ndr_print_function_t) ndr_print_drsuapi_DsGetNT4ChangeLog,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16608,7 +16608,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsCrackNames),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsCrackNames,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsCrackNames,
+- (ndr_print_function_t) ndr_print_drsuapi_DsCrackNames,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16617,7 +16617,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsWriteAccountSpn),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsWriteAccountSpn,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsWriteAccountSpn,
+- (ndr_print_function_t) ndr_print_drsuapi_DsWriteAccountSpn,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16626,7 +16626,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsRemoveDSServer),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsRemoveDSServer,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsRemoveDSServer,
+- (ndr_print_function_t) ndr_print_drsuapi_DsRemoveDSServer,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16635,7 +16635,7 @@ static const struct ndr_interface_call d
+ sizeof(struct DRSUAPI_REMOVE_DS_DOMAIN),
+ (ndr_push_flags_fn_t) ndr_push_DRSUAPI_REMOVE_DS_DOMAIN,
+ (ndr_pull_flags_fn_t) ndr_pull_DRSUAPI_REMOVE_DS_DOMAIN,
+- (ndr_print_function_t) ndr_print_DRSUAPI_REMOVE_DS_DOMAIN,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16644,7 +16644,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsGetDomainControllerInfo),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsGetDomainControllerInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsGetDomainControllerInfo,
+- (ndr_print_function_t) ndr_print_drsuapi_DsGetDomainControllerInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16653,7 +16653,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsAddEntry),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsAddEntry,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsAddEntry,
+- (ndr_print_function_t) ndr_print_drsuapi_DsAddEntry,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16662,7 +16662,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsExecuteKCC),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsExecuteKCC,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsExecuteKCC,
+- (ndr_print_function_t) ndr_print_drsuapi_DsExecuteKCC,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16671,7 +16671,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsReplicaGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsReplicaGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsReplicaGetInfo,
+- (ndr_print_function_t) ndr_print_drsuapi_DsReplicaGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16680,7 +16680,7 @@ static const struct ndr_interface_call d
+ sizeof(struct DRSUAPI_ADD_SID_HISTORY),
+ (ndr_push_flags_fn_t) ndr_push_DRSUAPI_ADD_SID_HISTORY,
+ (ndr_pull_flags_fn_t) ndr_pull_DRSUAPI_ADD_SID_HISTORY,
+- (ndr_print_function_t) ndr_print_DRSUAPI_ADD_SID_HISTORY,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16689,7 +16689,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_DsGetMemberships2),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_DsGetMemberships2,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_DsGetMemberships2,
+- (ndr_print_function_t) ndr_print_drsuapi_DsGetMemberships2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16698,7 +16698,7 @@ static const struct ndr_interface_call d
+ sizeof(struct DRSUAPI_REPLICA_VERIFY_OBJECTS),
+ (ndr_push_flags_fn_t) ndr_push_DRSUAPI_REPLICA_VERIFY_OBJECTS,
+ (ndr_pull_flags_fn_t) ndr_pull_DRSUAPI_REPLICA_VERIFY_OBJECTS,
+- (ndr_print_function_t) ndr_print_DRSUAPI_REPLICA_VERIFY_OBJECTS,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16707,7 +16707,7 @@ static const struct ndr_interface_call d
+ sizeof(struct DRSUAPI_GET_OBJECT_EXISTENCE),
+ (ndr_push_flags_fn_t) ndr_push_DRSUAPI_GET_OBJECT_EXISTENCE,
+ (ndr_pull_flags_fn_t) ndr_pull_DRSUAPI_GET_OBJECT_EXISTENCE,
+- (ndr_print_function_t) ndr_print_DRSUAPI_GET_OBJECT_EXISTENCE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -16716,7 +16716,7 @@ static const struct ndr_interface_call d
+ sizeof(struct drsuapi_QuerySitesByCost),
+ (ndr_push_flags_fn_t) ndr_push_drsuapi_QuerySitesByCost,
+ (ndr_pull_flags_fn_t) ndr_pull_drsuapi_QuerySitesByCost,
+- (ndr_print_function_t) ndr_print_drsuapi_QuerySitesByCost,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_dsbackup.c
++++ b/source3/librpc/gen_ndr/ndr_dsbackup.c
+@@ -360,7 +360,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRBackupPrepare),
+ (ndr_push_flags_fn_t) ndr_push_HrRBackupPrepare,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRBackupPrepare,
+- (ndr_print_function_t) ndr_print_HrRBackupPrepare,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -369,7 +369,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRBackupEnd),
+ (ndr_push_flags_fn_t) ndr_push_HrRBackupEnd,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRBackupEnd,
+- (ndr_print_function_t) ndr_print_HrRBackupEnd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -378,7 +378,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRBackupGetAttachmentInformation),
+ (ndr_push_flags_fn_t) ndr_push_HrRBackupGetAttachmentInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRBackupGetAttachmentInformation,
+- (ndr_print_function_t) ndr_print_HrRBackupGetAttachmentInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -387,7 +387,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRBackupOpenFile),
+ (ndr_push_flags_fn_t) ndr_push_HrRBackupOpenFile,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRBackupOpenFile,
+- (ndr_print_function_t) ndr_print_HrRBackupOpenFile,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -396,7 +396,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRBackupRead),
+ (ndr_push_flags_fn_t) ndr_push_HrRBackupRead,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRBackupRead,
+- (ndr_print_function_t) ndr_print_HrRBackupRead,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -405,7 +405,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRBackupClose),
+ (ndr_push_flags_fn_t) ndr_push_HrRBackupClose,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRBackupClose,
+- (ndr_print_function_t) ndr_print_HrRBackupClose,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -414,7 +414,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRBackupGetBackupLogs),
+ (ndr_push_flags_fn_t) ndr_push_HrRBackupGetBackupLogs,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRBackupGetBackupLogs,
+- (ndr_print_function_t) ndr_print_HrRBackupGetBackupLogs,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -423,7 +423,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRBackupTruncateLogs),
+ (ndr_push_flags_fn_t) ndr_push_HrRBackupTruncateLogs,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRBackupTruncateLogs,
+- (ndr_print_function_t) ndr_print_HrRBackupTruncateLogs,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -432,7 +432,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRBackupPing),
+ (ndr_push_flags_fn_t) ndr_push_HrRBackupPing,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRBackupPing,
+- (ndr_print_function_t) ndr_print_HrRBackupPing,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -789,7 +789,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRIsNTDSOnline),
+ (ndr_push_flags_fn_t) ndr_push_HrRIsNTDSOnline,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRIsNTDSOnline,
+- (ndr_print_function_t) ndr_print_HrRIsNTDSOnline,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -798,7 +798,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRRestorePrepare),
+ (ndr_push_flags_fn_t) ndr_push_HrRRestorePrepare,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRRestorePrepare,
+- (ndr_print_function_t) ndr_print_HrRRestorePrepare,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -807,7 +807,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRRestoreRegister),
+ (ndr_push_flags_fn_t) ndr_push_HrRRestoreRegister,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRRestoreRegister,
+- (ndr_print_function_t) ndr_print_HrRRestoreRegister,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -816,7 +816,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRRestoreRegisterComplete),
+ (ndr_push_flags_fn_t) ndr_push_HrRRestoreRegisterComplete,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRRestoreRegisterComplete,
+- (ndr_print_function_t) ndr_print_HrRRestoreRegisterComplete,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -825,7 +825,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRRestoreGetDatabaseLocations),
+ (ndr_push_flags_fn_t) ndr_push_HrRRestoreGetDatabaseLocations,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRRestoreGetDatabaseLocations,
+- (ndr_print_function_t) ndr_print_HrRRestoreGetDatabaseLocations,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -834,7 +834,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRRestoreEnd),
+ (ndr_push_flags_fn_t) ndr_push_HrRRestoreEnd,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRRestoreEnd,
+- (ndr_print_function_t) ndr_print_HrRRestoreEnd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -843,7 +843,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRRestoreSetCurrentLogNumber),
+ (ndr_push_flags_fn_t) ndr_push_HrRRestoreSetCurrentLogNumber,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRRestoreSetCurrentLogNumber,
+- (ndr_print_function_t) ndr_print_HrRRestoreSetCurrentLogNumber,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -852,7 +852,7 @@ static const struct ndr_interface_call a
+ sizeof(struct HrRRestoreCheckLogsForBackup),
+ (ndr_push_flags_fn_t) ndr_push_HrRRestoreCheckLogsForBackup,
+ (ndr_pull_flags_fn_t) ndr_pull_HrRRestoreCheckLogsForBackup,
+- (ndr_print_function_t) ndr_print_HrRRestoreCheckLogsForBackup,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_dssetup.c
++++ b/source3/librpc/gen_ndr/ndr_dssetup.c
+@@ -995,7 +995,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleGetPrimaryDomainInformation),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleGetPrimaryDomainInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleGetPrimaryDomainInformation,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleGetPrimaryDomainInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1004,7 +1004,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleDnsNameToFlatName),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleDnsNameToFlatName,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleDnsNameToFlatName,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleDnsNameToFlatName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1013,7 +1013,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleDcAsDc),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleDcAsDc,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleDcAsDc,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleDcAsDc,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1022,7 +1022,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleDcAsReplica),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleDcAsReplica,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleDcAsReplica,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleDcAsReplica,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1031,7 +1031,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleDemoteDc),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleDemoteDc,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleDemoteDc,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleDemoteDc,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1040,7 +1040,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleGetDcOperationProgress),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleGetDcOperationProgress,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleGetDcOperationProgress,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleGetDcOperationProgress,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1049,7 +1049,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleGetDcOperationResults),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleGetDcOperationResults,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleGetDcOperationResults,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleGetDcOperationResults,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1058,7 +1058,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleCancel),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleCancel,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleCancel,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleCancel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1067,7 +1067,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleServerSaveStateForUpgrade),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleServerSaveStateForUpgrade,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleServerSaveStateForUpgrade,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleServerSaveStateForUpgrade,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1076,7 +1076,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleUpgradeDownlevelServer),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleUpgradeDownlevelServer,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleUpgradeDownlevelServer,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleUpgradeDownlevelServer,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1085,7 +1085,7 @@ static const struct ndr_interface_call d
+ sizeof(struct dssetup_DsRoleAbortDownlevelServerUpgrade),
+ (ndr_push_flags_fn_t) ndr_push_dssetup_DsRoleAbortDownlevelServerUpgrade,
+ (ndr_pull_flags_fn_t) ndr_pull_dssetup_DsRoleAbortDownlevelServerUpgrade,
+- (ndr_print_function_t) ndr_print_dssetup_DsRoleAbortDownlevelServerUpgrade,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_echo.c
++++ b/source3/librpc/gen_ndr/ndr_echo.c
+@@ -1458,7 +1458,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_AddOne),
+ (ndr_push_flags_fn_t) ndr_push_echo_AddOne,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_AddOne,
+- (ndr_print_function_t) ndr_print_echo_AddOne,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1467,7 +1467,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_EchoData),
+ (ndr_push_flags_fn_t) ndr_push_echo_EchoData,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_EchoData,
+- (ndr_print_function_t) ndr_print_echo_EchoData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1476,7 +1476,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_SinkData),
+ (ndr_push_flags_fn_t) ndr_push_echo_SinkData,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_SinkData,
+- (ndr_print_function_t) ndr_print_echo_SinkData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1485,7 +1485,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_SourceData),
+ (ndr_push_flags_fn_t) ndr_push_echo_SourceData,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_SourceData,
+- (ndr_print_function_t) ndr_print_echo_SourceData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1494,7 +1494,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_TestCall),
+ (ndr_push_flags_fn_t) ndr_push_echo_TestCall,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_TestCall,
+- (ndr_print_function_t) ndr_print_echo_TestCall,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1503,7 +1503,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_TestCall2),
+ (ndr_push_flags_fn_t) ndr_push_echo_TestCall2,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_TestCall2,
+- (ndr_print_function_t) ndr_print_echo_TestCall2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1512,7 +1512,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_TestSleep),
+ (ndr_push_flags_fn_t) ndr_push_echo_TestSleep,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_TestSleep,
+- (ndr_print_function_t) ndr_print_echo_TestSleep,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1521,7 +1521,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_TestEnum),
+ (ndr_push_flags_fn_t) ndr_push_echo_TestEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_TestEnum,
+- (ndr_print_function_t) ndr_print_echo_TestEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1530,7 +1530,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_TestSurrounding),
+ (ndr_push_flags_fn_t) ndr_push_echo_TestSurrounding,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_TestSurrounding,
+- (ndr_print_function_t) ndr_print_echo_TestSurrounding,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1539,7 +1539,7 @@ static const struct ndr_interface_call r
+ sizeof(struct echo_TestDoublePointer),
+ (ndr_push_flags_fn_t) ndr_push_echo_TestDoublePointer,
+ (ndr_pull_flags_fn_t) ndr_pull_echo_TestDoublePointer,
+- (ndr_print_function_t) ndr_print_echo_TestDoublePointer,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_efs.c
++++ b/source3/librpc/gen_ndr/ndr_efs.c
+@@ -1327,7 +1327,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcOpenFileRaw),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcOpenFileRaw,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcOpenFileRaw,
+- (ndr_print_function_t) ndr_print_EfsRpcOpenFileRaw,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1336,7 +1336,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcReadFileRaw),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcReadFileRaw,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcReadFileRaw,
+- (ndr_print_function_t) ndr_print_EfsRpcReadFileRaw,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1345,7 +1345,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcWriteFileRaw),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcWriteFileRaw,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcWriteFileRaw,
+- (ndr_print_function_t) ndr_print_EfsRpcWriteFileRaw,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1354,7 +1354,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcCloseRaw),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcCloseRaw,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcCloseRaw,
+- (ndr_print_function_t) ndr_print_EfsRpcCloseRaw,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1363,7 +1363,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcEncryptFileSrv),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcEncryptFileSrv,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcEncryptFileSrv,
+- (ndr_print_function_t) ndr_print_EfsRpcEncryptFileSrv,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1372,7 +1372,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcDecryptFileSrv),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcDecryptFileSrv,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcDecryptFileSrv,
+- (ndr_print_function_t) ndr_print_EfsRpcDecryptFileSrv,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1381,7 +1381,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcQueryUsersOnFile),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcQueryUsersOnFile,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcQueryUsersOnFile,
+- (ndr_print_function_t) ndr_print_EfsRpcQueryUsersOnFile,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1390,7 +1390,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcQueryRecoveryAgents),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcQueryRecoveryAgents,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcQueryRecoveryAgents,
+- (ndr_print_function_t) ndr_print_EfsRpcQueryRecoveryAgents,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1399,7 +1399,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcRemoveUsersFromFile),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcRemoveUsersFromFile,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcRemoveUsersFromFile,
+- (ndr_print_function_t) ndr_print_EfsRpcRemoveUsersFromFile,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1408,7 +1408,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcAddUsersToFile),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcAddUsersToFile,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcAddUsersToFile,
+- (ndr_print_function_t) ndr_print_EfsRpcAddUsersToFile,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1417,7 +1417,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcSetFileEncryptionKey),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcSetFileEncryptionKey,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcSetFileEncryptionKey,
+- (ndr_print_function_t) ndr_print_EfsRpcSetFileEncryptionKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1426,7 +1426,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcNotSupported),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcNotSupported,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcNotSupported,
+- (ndr_print_function_t) ndr_print_EfsRpcNotSupported,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1435,7 +1435,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcFileKeyInfo),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcFileKeyInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcFileKeyInfo,
+- (ndr_print_function_t) ndr_print_EfsRpcFileKeyInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1444,7 +1444,7 @@ static const struct ndr_interface_call e
+ sizeof(struct EfsRpcDuplicateEncryptionInfoFile),
+ (ndr_push_flags_fn_t) ndr_push_EfsRpcDuplicateEncryptionInfoFile,
+ (ndr_pull_flags_fn_t) ndr_pull_EfsRpcDuplicateEncryptionInfoFile,
+- (ndr_print_function_t) ndr_print_EfsRpcDuplicateEncryptionInfoFile,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_epmapper.c
++++ b/source3/librpc/gen_ndr/ndr_epmapper.c
+@@ -2754,7 +2754,7 @@ static const struct ndr_interface_call e
+ sizeof(struct epm_Insert),
+ (ndr_push_flags_fn_t) ndr_push_epm_Insert,
+ (ndr_pull_flags_fn_t) ndr_pull_epm_Insert,
+- (ndr_print_function_t) ndr_print_epm_Insert,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2763,7 +2763,7 @@ static const struct ndr_interface_call e
+ sizeof(struct epm_Delete),
+ (ndr_push_flags_fn_t) ndr_push_epm_Delete,
+ (ndr_pull_flags_fn_t) ndr_pull_epm_Delete,
+- (ndr_print_function_t) ndr_print_epm_Delete,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2772,7 +2772,7 @@ static const struct ndr_interface_call e
+ sizeof(struct epm_Lookup),
+ (ndr_push_flags_fn_t) ndr_push_epm_Lookup,
+ (ndr_pull_flags_fn_t) ndr_pull_epm_Lookup,
+- (ndr_print_function_t) ndr_print_epm_Lookup,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2781,7 +2781,7 @@ static const struct ndr_interface_call e
+ sizeof(struct epm_Map),
+ (ndr_push_flags_fn_t) ndr_push_epm_Map,
+ (ndr_pull_flags_fn_t) ndr_pull_epm_Map,
+- (ndr_print_function_t) ndr_print_epm_Map,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2790,7 +2790,7 @@ static const struct ndr_interface_call e
+ sizeof(struct epm_LookupHandleFree),
+ (ndr_push_flags_fn_t) ndr_push_epm_LookupHandleFree,
+ (ndr_pull_flags_fn_t) ndr_pull_epm_LookupHandleFree,
+- (ndr_print_function_t) ndr_print_epm_LookupHandleFree,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2799,7 +2799,7 @@ static const struct ndr_interface_call e
+ sizeof(struct epm_InqObject),
+ (ndr_push_flags_fn_t) ndr_push_epm_InqObject,
+ (ndr_pull_flags_fn_t) ndr_pull_epm_InqObject,
+- (ndr_print_function_t) ndr_print_epm_InqObject,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2808,7 +2808,7 @@ static const struct ndr_interface_call e
+ sizeof(struct epm_MgmtDelete),
+ (ndr_push_flags_fn_t) ndr_push_epm_MgmtDelete,
+ (ndr_pull_flags_fn_t) ndr_pull_epm_MgmtDelete,
+- (ndr_print_function_t) ndr_print_epm_MgmtDelete,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2817,7 +2817,7 @@ static const struct ndr_interface_call e
+ sizeof(struct epm_MapAuth),
+ (ndr_push_flags_fn_t) ndr_push_epm_MapAuth,
+ (ndr_pull_flags_fn_t) ndr_pull_epm_MapAuth,
+- (ndr_print_function_t) ndr_print_epm_MapAuth,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_eventlog.c
++++ b/source3/librpc/gen_ndr/ndr_eventlog.c
+@@ -2983,7 +2983,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_ClearEventLogW),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_ClearEventLogW,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_ClearEventLogW,
+- (ndr_print_function_t) ndr_print_eventlog_ClearEventLogW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2992,7 +2992,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_BackupEventLogW),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_BackupEventLogW,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_BackupEventLogW,
+- (ndr_print_function_t) ndr_print_eventlog_BackupEventLogW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3001,7 +3001,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_CloseEventLog),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_CloseEventLog,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_CloseEventLog,
+- (ndr_print_function_t) ndr_print_eventlog_CloseEventLog,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3010,7 +3010,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_DeregisterEventSource),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_DeregisterEventSource,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_DeregisterEventSource,
+- (ndr_print_function_t) ndr_print_eventlog_DeregisterEventSource,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3019,7 +3019,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_GetNumRecords),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_GetNumRecords,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_GetNumRecords,
+- (ndr_print_function_t) ndr_print_eventlog_GetNumRecords,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3028,7 +3028,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_GetOldestRecord),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_GetOldestRecord,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_GetOldestRecord,
+- (ndr_print_function_t) ndr_print_eventlog_GetOldestRecord,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3037,7 +3037,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_ChangeNotify),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_ChangeNotify,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_ChangeNotify,
+- (ndr_print_function_t) ndr_print_eventlog_ChangeNotify,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3046,7 +3046,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_OpenEventLogW),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_OpenEventLogW,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_OpenEventLogW,
+- (ndr_print_function_t) ndr_print_eventlog_OpenEventLogW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3055,7 +3055,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_RegisterEventSourceW),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_RegisterEventSourceW,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_RegisterEventSourceW,
+- (ndr_print_function_t) ndr_print_eventlog_RegisterEventSourceW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3064,7 +3064,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_OpenBackupEventLogW),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_OpenBackupEventLogW,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_OpenBackupEventLogW,
+- (ndr_print_function_t) ndr_print_eventlog_OpenBackupEventLogW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3073,7 +3073,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_ReadEventLogW),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_ReadEventLogW,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_ReadEventLogW,
+- (ndr_print_function_t) ndr_print_eventlog_ReadEventLogW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3082,7 +3082,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_ReportEventW),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_ReportEventW,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_ReportEventW,
+- (ndr_print_function_t) ndr_print_eventlog_ReportEventW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3091,7 +3091,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_ClearEventLogA),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_ClearEventLogA,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_ClearEventLogA,
+- (ndr_print_function_t) ndr_print_eventlog_ClearEventLogA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3100,7 +3100,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_BackupEventLogA),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_BackupEventLogA,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_BackupEventLogA,
+- (ndr_print_function_t) ndr_print_eventlog_BackupEventLogA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3109,7 +3109,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_OpenEventLogA),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_OpenEventLogA,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_OpenEventLogA,
+- (ndr_print_function_t) ndr_print_eventlog_OpenEventLogA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3118,7 +3118,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_RegisterEventSourceA),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_RegisterEventSourceA,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_RegisterEventSourceA,
+- (ndr_print_function_t) ndr_print_eventlog_RegisterEventSourceA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3127,7 +3127,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_OpenBackupEventLogA),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_OpenBackupEventLogA,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_OpenBackupEventLogA,
+- (ndr_print_function_t) ndr_print_eventlog_OpenBackupEventLogA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3136,7 +3136,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_ReadEventLogA),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_ReadEventLogA,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_ReadEventLogA,
+- (ndr_print_function_t) ndr_print_eventlog_ReadEventLogA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3145,7 +3145,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_ReportEventA),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_ReportEventA,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_ReportEventA,
+- (ndr_print_function_t) ndr_print_eventlog_ReportEventA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3154,7 +3154,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_RegisterClusterSvc),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_RegisterClusterSvc,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_RegisterClusterSvc,
+- (ndr_print_function_t) ndr_print_eventlog_RegisterClusterSvc,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3163,7 +3163,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_DeregisterClusterSvc),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_DeregisterClusterSvc,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_DeregisterClusterSvc,
+- (ndr_print_function_t) ndr_print_eventlog_DeregisterClusterSvc,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3172,7 +3172,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_WriteClusterEvents),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_WriteClusterEvents,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_WriteClusterEvents,
+- (ndr_print_function_t) ndr_print_eventlog_WriteClusterEvents,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3181,7 +3181,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_GetLogInformation),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_GetLogInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_GetLogInformation,
+- (ndr_print_function_t) ndr_print_eventlog_GetLogInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3190,7 +3190,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_FlushEventLog),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_FlushEventLog,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_FlushEventLog,
+- (ndr_print_function_t) ndr_print_eventlog_FlushEventLog,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3199,7 +3199,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog_ReportEventAndSourceW),
+ (ndr_push_flags_fn_t) ndr_push_eventlog_ReportEventAndSourceW,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog_ReportEventAndSourceW,
+- (ndr_print_function_t) ndr_print_eventlog_ReportEventAndSourceW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_eventlog6.c
++++ b/source3/librpc/gen_ndr/ndr_eventlog6.c
+@@ -5482,7 +5482,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcRegisterRemoteSubscription),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcRegisterRemoteSubscription,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcRegisterRemoteSubscription,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcRegisterRemoteSubscription,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5491,7 +5491,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcRemoteSubscriptionNextAsync),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcRemoteSubscriptionNextAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcRemoteSubscriptionNextAsync,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcRemoteSubscriptionNextAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5500,7 +5500,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcRemoteSubscriptionNext),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcRemoteSubscriptionNext,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcRemoteSubscriptionNext,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcRemoteSubscriptionNext,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5509,7 +5509,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcRemoteSubscriptionWaitAsync),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcRemoteSubscriptionWaitAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcRemoteSubscriptionWaitAsync,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcRemoteSubscriptionWaitAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5518,7 +5518,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcRegisterControllableOperation),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcRegisterControllableOperation,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcRegisterControllableOperation,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcRegisterControllableOperation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5527,7 +5527,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcRegisterLogQuery),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcRegisterLogQuery,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcRegisterLogQuery,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcRegisterLogQuery,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5536,7 +5536,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcClearLog),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcClearLog,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcClearLog,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcClearLog,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5545,7 +5545,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcExportLog),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcExportLog,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcExportLog,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcExportLog,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5554,7 +5554,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcLocalizeExportLog),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcLocalizeExportLog,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcLocalizeExportLog,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcLocalizeExportLog,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5563,7 +5563,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcMessageRender),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcMessageRender,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcMessageRender,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcMessageRender,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5572,7 +5572,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcMessageRenderDefault),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcMessageRenderDefault,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcMessageRenderDefault,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcMessageRenderDefault,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5581,7 +5581,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcQueryNext),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcQueryNext,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcQueryNext,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcQueryNext,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5590,7 +5590,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcQuerySeek),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcQuerySeek,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcQuerySeek,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcQuerySeek,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5599,7 +5599,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcClose),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcClose,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcClose,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcClose,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5608,7 +5608,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcCancel),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcCancel,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcCancel,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcCancel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5617,7 +5617,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcAssertConfig),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcAssertConfig,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcAssertConfig,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcAssertConfig,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5626,7 +5626,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcRetractConfig),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcRetractConfig,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcRetractConfig,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcRetractConfig,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5635,7 +5635,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcOpenLogHandle),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcOpenLogHandle,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcOpenLogHandle,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcOpenLogHandle,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5644,7 +5644,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetLogFileInfo),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetLogFileInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetLogFileInfo,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetLogFileInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5653,7 +5653,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetChannelList),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetChannelList,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetChannelList,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetChannelList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5662,7 +5662,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetChannelConfig),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetChannelConfig,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetChannelConfig,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetChannelConfig,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5671,7 +5671,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcPutChannelConfig),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcPutChannelConfig,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcPutChannelConfig,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcPutChannelConfig,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5680,7 +5680,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetPublisherList),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetPublisherList,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetPublisherList,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetPublisherList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5689,7 +5689,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetPublisherListForChannel),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetPublisherListForChannel,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetPublisherListForChannel,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetPublisherListForChannel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5698,7 +5698,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetPublisherMetadata),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetPublisherMetadata,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetPublisherMetadata,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetPublisherMetadata,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5707,7 +5707,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetPublisherResourceMetadata),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetPublisherResourceMetadata,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetPublisherResourceMetadata,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetPublisherResourceMetadata,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5716,7 +5716,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetEventMetadataEnum),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetEventMetadataEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetEventMetadataEnum,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetEventMetadataEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5725,7 +5725,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetNextEventMetadata),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetNextEventMetadata,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetNextEventMetadata,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetNextEventMetadata,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5734,7 +5734,7 @@ static const struct ndr_interface_call e
+ sizeof(struct eventlog6_EvtRpcGetClassicLogDisplayName),
+ (ndr_push_flags_fn_t) ndr_push_eventlog6_EvtRpcGetClassicLogDisplayName,
+ (ndr_pull_flags_fn_t) ndr_pull_eventlog6_EvtRpcGetClassicLogDisplayName,
+- (ndr_print_function_t) ndr_print_eventlog6_EvtRpcGetClassicLogDisplayName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_frsapi.c
++++ b/source3/librpc/gen_ndr/ndr_frsapi.c
+@@ -979,7 +979,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSAPI_VERIFY_PROMOTION),
+ (ndr_push_flags_fn_t) ndr_push_FRSAPI_VERIFY_PROMOTION,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSAPI_VERIFY_PROMOTION,
+- (ndr_print_function_t) ndr_print_FRSAPI_VERIFY_PROMOTION,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -988,7 +988,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSAPI_PROMOTION_STATUS),
+ (ndr_push_flags_fn_t) ndr_push_FRSAPI_PROMOTION_STATUS,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSAPI_PROMOTION_STATUS,
+- (ndr_print_function_t) ndr_print_FRSAPI_PROMOTION_STATUS,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -997,7 +997,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSAPI_START_DEMOTION),
+ (ndr_push_flags_fn_t) ndr_push_FRSAPI_START_DEMOTION,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSAPI_START_DEMOTION,
+- (ndr_print_function_t) ndr_print_FRSAPI_START_DEMOTION,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1006,7 +1006,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSAPI_COMMIT_DEMOTION),
+ (ndr_push_flags_fn_t) ndr_push_FRSAPI_COMMIT_DEMOTION,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSAPI_COMMIT_DEMOTION,
+- (ndr_print_function_t) ndr_print_FRSAPI_COMMIT_DEMOTION,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1015,7 +1015,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsapi_SetDsPollingIntervalW),
+ (ndr_push_flags_fn_t) ndr_push_frsapi_SetDsPollingIntervalW,
+ (ndr_pull_flags_fn_t) ndr_pull_frsapi_SetDsPollingIntervalW,
+- (ndr_print_function_t) ndr_print_frsapi_SetDsPollingIntervalW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1024,7 +1024,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsapi_GetDsPollingIntervalW),
+ (ndr_push_flags_fn_t) ndr_push_frsapi_GetDsPollingIntervalW,
+ (ndr_pull_flags_fn_t) ndr_pull_frsapi_GetDsPollingIntervalW,
+- (ndr_print_function_t) ndr_print_frsapi_GetDsPollingIntervalW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1033,7 +1033,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSAPI_VERIFY_PROMOTION_W),
+ (ndr_push_flags_fn_t) ndr_push_FRSAPI_VERIFY_PROMOTION_W,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSAPI_VERIFY_PROMOTION_W,
+- (ndr_print_function_t) ndr_print_FRSAPI_VERIFY_PROMOTION_W,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1042,7 +1042,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsapi_InfoW),
+ (ndr_push_flags_fn_t) ndr_push_frsapi_InfoW,
+ (ndr_pull_flags_fn_t) ndr_pull_frsapi_InfoW,
+- (ndr_print_function_t) ndr_print_frsapi_InfoW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1051,7 +1051,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsapi_IsPathReplicated),
+ (ndr_push_flags_fn_t) ndr_push_frsapi_IsPathReplicated,
+ (ndr_pull_flags_fn_t) ndr_pull_frsapi_IsPathReplicated,
+- (ndr_print_function_t) ndr_print_frsapi_IsPathReplicated,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1060,7 +1060,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsapi_WriterCommand),
+ (ndr_push_flags_fn_t) ndr_push_frsapi_WriterCommand,
+ (ndr_pull_flags_fn_t) ndr_pull_frsapi_WriterCommand,
+- (ndr_print_function_t) ndr_print_frsapi_WriterCommand,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1069,7 +1069,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsapi_ForceReplication),
+ (ndr_push_flags_fn_t) ndr_push_frsapi_ForceReplication,
+ (ndr_pull_flags_fn_t) ndr_pull_frsapi_ForceReplication,
+- (ndr_print_function_t) ndr_print_frsapi_ForceReplication,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_frsrpc.c
++++ b/source3/librpc/gen_ndr/ndr_frsrpc.c
+@@ -2781,7 +2781,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsrpc_FrsSendCommPkt),
+ (ndr_push_flags_fn_t) ndr_push_frsrpc_FrsSendCommPkt,
+ (ndr_pull_flags_fn_t) ndr_pull_frsrpc_FrsSendCommPkt,
+- (ndr_print_function_t) ndr_print_frsrpc_FrsSendCommPkt,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2790,7 +2790,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsrpc_FrsVerifyPromotionParent),
+ (ndr_push_flags_fn_t) ndr_push_frsrpc_FrsVerifyPromotionParent,
+ (ndr_pull_flags_fn_t) ndr_pull_frsrpc_FrsVerifyPromotionParent,
+- (ndr_print_function_t) ndr_print_frsrpc_FrsVerifyPromotionParent,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2799,7 +2799,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsrpc_FrsStartPromotionParent),
+ (ndr_push_flags_fn_t) ndr_push_frsrpc_FrsStartPromotionParent,
+ (ndr_pull_flags_fn_t) ndr_pull_frsrpc_FrsStartPromotionParent,
+- (ndr_print_function_t) ndr_print_frsrpc_FrsStartPromotionParent,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2808,7 +2808,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frsrpc_FrsNOP),
+ (ndr_push_flags_fn_t) ndr_push_frsrpc_FrsNOP,
+ (ndr_pull_flags_fn_t) ndr_pull_frsrpc_FrsNOP,
+- (ndr_print_function_t) ndr_print_frsrpc_FrsNOP,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2817,7 +2817,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSRPC_BACKUP_COMPLETE),
+ (ndr_push_flags_fn_t) ndr_push_FRSRPC_BACKUP_COMPLETE,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSRPC_BACKUP_COMPLETE,
+- (ndr_print_function_t) ndr_print_FRSRPC_BACKUP_COMPLETE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2826,7 +2826,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSRPC_BACKUP_COMPLETE_5),
+ (ndr_push_flags_fn_t) ndr_push_FRSRPC_BACKUP_COMPLETE_5,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSRPC_BACKUP_COMPLETE_5,
+- (ndr_print_function_t) ndr_print_FRSRPC_BACKUP_COMPLETE_5,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2835,7 +2835,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSRPC_BACKUP_COMPLETE_6),
+ (ndr_push_flags_fn_t) ndr_push_FRSRPC_BACKUP_COMPLETE_6,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSRPC_BACKUP_COMPLETE_6,
+- (ndr_print_function_t) ndr_print_FRSRPC_BACKUP_COMPLETE_6,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2844,7 +2844,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSRPC_BACKUP_COMPLETE_7),
+ (ndr_push_flags_fn_t) ndr_push_FRSRPC_BACKUP_COMPLETE_7,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSRPC_BACKUP_COMPLETE_7,
+- (ndr_print_function_t) ndr_print_FRSRPC_BACKUP_COMPLETE_7,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2853,7 +2853,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSRPC_BACKUP_COMPLETE_8),
+ (ndr_push_flags_fn_t) ndr_push_FRSRPC_BACKUP_COMPLETE_8,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSRPC_BACKUP_COMPLETE_8,
+- (ndr_print_function_t) ndr_print_FRSRPC_BACKUP_COMPLETE_8,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2862,7 +2862,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSRPC_BACKUP_COMPLETE_9),
+ (ndr_push_flags_fn_t) ndr_push_FRSRPC_BACKUP_COMPLETE_9,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSRPC_BACKUP_COMPLETE_9,
+- (ndr_print_function_t) ndr_print_FRSRPC_BACKUP_COMPLETE_9,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2871,7 +2871,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSRPC_VERIFY_PROMOTION_PARENT_EX),
+ (ndr_push_flags_fn_t) ndr_push_FRSRPC_VERIFY_PROMOTION_PARENT_EX,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSRPC_VERIFY_PROMOTION_PARENT_EX,
+- (ndr_print_function_t) ndr_print_FRSRPC_VERIFY_PROMOTION_PARENT_EX,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_frstrans.c
++++ b/source3/librpc/gen_ndr/ndr_frstrans.c
+@@ -2331,7 +2331,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frstrans_CheckConnectivity),
+ (ndr_push_flags_fn_t) ndr_push_frstrans_CheckConnectivity,
+ (ndr_pull_flags_fn_t) ndr_pull_frstrans_CheckConnectivity,
+- (ndr_print_function_t) ndr_print_frstrans_CheckConnectivity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2340,7 +2340,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frstrans_EstablishConnection),
+ (ndr_push_flags_fn_t) ndr_push_frstrans_EstablishConnection,
+ (ndr_pull_flags_fn_t) ndr_pull_frstrans_EstablishConnection,
+- (ndr_print_function_t) ndr_print_frstrans_EstablishConnection,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2349,7 +2349,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frstrans_EstablishSession),
+ (ndr_push_flags_fn_t) ndr_push_frstrans_EstablishSession,
+ (ndr_pull_flags_fn_t) ndr_pull_frstrans_EstablishSession,
+- (ndr_print_function_t) ndr_print_frstrans_EstablishSession,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2358,7 +2358,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frstrans_RequestUpdates),
+ (ndr_push_flags_fn_t) ndr_push_frstrans_RequestUpdates,
+ (ndr_pull_flags_fn_t) ndr_pull_frstrans_RequestUpdates,
+- (ndr_print_function_t) ndr_print_frstrans_RequestUpdates,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2367,7 +2367,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frstrans_RequestVersionVector),
+ (ndr_push_flags_fn_t) ndr_push_frstrans_RequestVersionVector,
+ (ndr_pull_flags_fn_t) ndr_pull_frstrans_RequestVersionVector,
+- (ndr_print_function_t) ndr_print_frstrans_RequestVersionVector,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2376,7 +2376,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frstrans_AsyncPoll),
+ (ndr_push_flags_fn_t) ndr_push_frstrans_AsyncPoll,
+ (ndr_pull_flags_fn_t) ndr_pull_frstrans_AsyncPoll,
+- (ndr_print_function_t) ndr_print_frstrans_AsyncPoll,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2385,7 +2385,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSTRANS_REQUEST_RECORDS),
+ (ndr_push_flags_fn_t) ndr_push_FRSTRANS_REQUEST_RECORDS,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSTRANS_REQUEST_RECORDS,
+- (ndr_print_function_t) ndr_print_FRSTRANS_REQUEST_RECORDS,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2394,7 +2394,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSTRANS_UPDATE_CANCEL),
+ (ndr_push_flags_fn_t) ndr_push_FRSTRANS_UPDATE_CANCEL,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSTRANS_UPDATE_CANCEL,
+- (ndr_print_function_t) ndr_print_FRSTRANS_UPDATE_CANCEL,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2403,7 +2403,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSTRANS_RAW_GET_FILE_DATA),
+ (ndr_push_flags_fn_t) ndr_push_FRSTRANS_RAW_GET_FILE_DATA,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSTRANS_RAW_GET_FILE_DATA,
+- (ndr_print_function_t) ndr_print_FRSTRANS_RAW_GET_FILE_DATA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2412,7 +2412,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSTRANS_RDC_GET_SIGNATURES),
+ (ndr_push_flags_fn_t) ndr_push_FRSTRANS_RDC_GET_SIGNATURES,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSTRANS_RDC_GET_SIGNATURES,
+- (ndr_print_function_t) ndr_print_FRSTRANS_RDC_GET_SIGNATURES,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2421,7 +2421,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSTRANS_RDC_PUSH_SOURCE_NEEDS),
+ (ndr_push_flags_fn_t) ndr_push_FRSTRANS_RDC_PUSH_SOURCE_NEEDS,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSTRANS_RDC_PUSH_SOURCE_NEEDS,
+- (ndr_print_function_t) ndr_print_FRSTRANS_RDC_PUSH_SOURCE_NEEDS,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2430,7 +2430,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSTRANS_RDC_GET_FILE_DATA),
+ (ndr_push_flags_fn_t) ndr_push_FRSTRANS_RDC_GET_FILE_DATA,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSTRANS_RDC_GET_FILE_DATA,
+- (ndr_print_function_t) ndr_print_FRSTRANS_RDC_GET_FILE_DATA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2439,7 +2439,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSTRANS_RDC_CLOSE),
+ (ndr_push_flags_fn_t) ndr_push_FRSTRANS_RDC_CLOSE,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSTRANS_RDC_CLOSE,
+- (ndr_print_function_t) ndr_print_FRSTRANS_RDC_CLOSE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2448,7 +2448,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frstrans_InitializeFileTransferAsync),
+ (ndr_push_flags_fn_t) ndr_push_frstrans_InitializeFileTransferAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_frstrans_InitializeFileTransferAsync,
+- (ndr_print_function_t) ndr_print_frstrans_InitializeFileTransferAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2457,7 +2457,7 @@ static const struct ndr_interface_call f
+ sizeof(struct FRSTRANS_OPNUM_0E_NOT_USED_ON_THE_WIRE),
+ (ndr_push_flags_fn_t) ndr_push_FRSTRANS_OPNUM_0E_NOT_USED_ON_THE_WIRE,
+ (ndr_pull_flags_fn_t) ndr_pull_FRSTRANS_OPNUM_0E_NOT_USED_ON_THE_WIRE,
+- (ndr_print_function_t) ndr_print_FRSTRANS_OPNUM_0E_NOT_USED_ON_THE_WIRE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2466,7 +2466,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frstrans_RawGetFileDataAsync),
+ (ndr_push_flags_fn_t) ndr_push_frstrans_RawGetFileDataAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_frstrans_RawGetFileDataAsync,
+- (ndr_print_function_t) ndr_print_frstrans_RawGetFileDataAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 1, frstrans_RawGetFileDataAsync_out_pipes },
+ },
+@@ -2475,7 +2475,7 @@ static const struct ndr_interface_call f
+ sizeof(struct frstrans_RdcGetFileDataAsync),
+ (ndr_push_flags_fn_t) ndr_push_frstrans_RdcGetFileDataAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_frstrans_RdcGetFileDataAsync,
+- (ndr_print_function_t) ndr_print_frstrans_RdcGetFileDataAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 1, frstrans_RdcGetFileDataAsync_out_pipes },
+ },
+--- a/source3/librpc/gen_ndr/ndr_initshutdown.c
++++ b/source3/librpc/gen_ndr/ndr_initshutdown.c
+@@ -277,7 +277,7 @@ static const struct ndr_interface_call i
+ sizeof(struct initshutdown_Init),
+ (ndr_push_flags_fn_t) ndr_push_initshutdown_Init,
+ (ndr_pull_flags_fn_t) ndr_pull_initshutdown_Init,
+- (ndr_print_function_t) ndr_print_initshutdown_Init,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -286,7 +286,7 @@ static const struct ndr_interface_call i
+ sizeof(struct initshutdown_Abort),
+ (ndr_push_flags_fn_t) ndr_push_initshutdown_Abort,
+ (ndr_pull_flags_fn_t) ndr_pull_initshutdown_Abort,
+- (ndr_print_function_t) ndr_print_initshutdown_Abort,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -295,7 +295,7 @@ static const struct ndr_interface_call i
+ sizeof(struct initshutdown_InitEx),
+ (ndr_push_flags_fn_t) ndr_push_initshutdown_InitEx,
+ (ndr_pull_flags_fn_t) ndr_pull_initshutdown_InitEx,
+- (ndr_print_function_t) ndr_print_initshutdown_InitEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_keysvc.c
++++ b/source3/librpc/gen_ndr/ndr_keysvc.c
+@@ -51,7 +51,7 @@ static const struct ndr_interface_call k
+ sizeof(struct keysvc_Unknown0),
+ (ndr_push_flags_fn_t) ndr_push_keysvc_Unknown0,
+ (ndr_pull_flags_fn_t) ndr_pull_keysvc_Unknown0,
+- (ndr_print_function_t) ndr_print_keysvc_Unknown0,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_krb5pac.c
++++ b/source3/librpc/gen_ndr/ndr_krb5pac.c
+@@ -1002,7 +1002,7 @@ static const struct ndr_interface_call k
+ sizeof(struct decode_pac),
+ (ndr_push_flags_fn_t) ndr_push_decode_pac,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_pac,
+- (ndr_print_function_t) ndr_print_decode_pac,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1011,7 +1011,7 @@ static const struct ndr_interface_call k
+ sizeof(struct decode_pac_raw),
+ (ndr_push_flags_fn_t) ndr_push_decode_pac_raw,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_pac_raw,
+- (ndr_print_function_t) ndr_print_decode_pac_raw,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1020,7 +1020,7 @@ static const struct ndr_interface_call k
+ sizeof(struct decode_login_info),
+ (ndr_push_flags_fn_t) ndr_push_decode_login_info,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_login_info,
+- (ndr_print_function_t) ndr_print_decode_login_info,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1029,7 +1029,7 @@ static const struct ndr_interface_call k
+ sizeof(struct decode_login_info_ctr),
+ (ndr_push_flags_fn_t) ndr_push_decode_login_info_ctr,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_login_info_ctr,
+- (ndr_print_function_t) ndr_print_decode_login_info_ctr,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -1038,7 +1038,7 @@ static const struct ndr_interface_call k
+ sizeof(struct decode_pac_validate),
+ (ndr_push_flags_fn_t) ndr_push_decode_pac_validate,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_pac_validate,
+- (ndr_print_function_t) ndr_print_decode_pac_validate,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_lsa.c
++++ b/source3/librpc/gen_ndr/ndr_lsa.c
+@@ -13565,7 +13565,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_Close),
+ (ndr_push_flags_fn_t) ndr_push_lsa_Close,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_Close,
+- (ndr_print_function_t) ndr_print_lsa_Close,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13574,7 +13574,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_Delete),
+ (ndr_push_flags_fn_t) ndr_push_lsa_Delete,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_Delete,
+- (ndr_print_function_t) ndr_print_lsa_Delete,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13583,7 +13583,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_EnumPrivs),
+ (ndr_push_flags_fn_t) ndr_push_lsa_EnumPrivs,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_EnumPrivs,
+- (ndr_print_function_t) ndr_print_lsa_EnumPrivs,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13592,7 +13592,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_QuerySecurity),
+ (ndr_push_flags_fn_t) ndr_push_lsa_QuerySecurity,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_QuerySecurity,
+- (ndr_print_function_t) ndr_print_lsa_QuerySecurity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13601,7 +13601,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetSecObj),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetSecObj,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetSecObj,
+- (ndr_print_function_t) ndr_print_lsa_SetSecObj,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13610,7 +13610,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_ChangePassword),
+ (ndr_push_flags_fn_t) ndr_push_lsa_ChangePassword,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_ChangePassword,
+- (ndr_print_function_t) ndr_print_lsa_ChangePassword,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13619,7 +13619,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_OpenPolicy),
+ (ndr_push_flags_fn_t) ndr_push_lsa_OpenPolicy,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_OpenPolicy,
+- (ndr_print_function_t) ndr_print_lsa_OpenPolicy,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13628,7 +13628,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_QueryInfoPolicy),
+ (ndr_push_flags_fn_t) ndr_push_lsa_QueryInfoPolicy,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_QueryInfoPolicy,
+- (ndr_print_function_t) ndr_print_lsa_QueryInfoPolicy,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13637,7 +13637,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetInfoPolicy),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetInfoPolicy,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetInfoPolicy,
+- (ndr_print_function_t) ndr_print_lsa_SetInfoPolicy,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13646,7 +13646,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_ClearAuditLog),
+ (ndr_push_flags_fn_t) ndr_push_lsa_ClearAuditLog,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_ClearAuditLog,
+- (ndr_print_function_t) ndr_print_lsa_ClearAuditLog,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13655,7 +13655,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CreateAccount),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CreateAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CreateAccount,
+- (ndr_print_function_t) ndr_print_lsa_CreateAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13664,7 +13664,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_EnumAccounts),
+ (ndr_push_flags_fn_t) ndr_push_lsa_EnumAccounts,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_EnumAccounts,
+- (ndr_print_function_t) ndr_print_lsa_EnumAccounts,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13673,7 +13673,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CreateTrustedDomain),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CreateTrustedDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CreateTrustedDomain,
+- (ndr_print_function_t) ndr_print_lsa_CreateTrustedDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13682,7 +13682,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_EnumTrustDom),
+ (ndr_push_flags_fn_t) ndr_push_lsa_EnumTrustDom,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_EnumTrustDom,
+- (ndr_print_function_t) ndr_print_lsa_EnumTrustDom,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13691,7 +13691,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupNames),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupNames,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupNames,
+- (ndr_print_function_t) ndr_print_lsa_LookupNames,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13700,7 +13700,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupSids),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupSids,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupSids,
+- (ndr_print_function_t) ndr_print_lsa_LookupSids,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13709,7 +13709,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CreateSecret),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CreateSecret,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CreateSecret,
+- (ndr_print_function_t) ndr_print_lsa_CreateSecret,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13718,7 +13718,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_OpenAccount),
+ (ndr_push_flags_fn_t) ndr_push_lsa_OpenAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_OpenAccount,
+- (ndr_print_function_t) ndr_print_lsa_OpenAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13727,7 +13727,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_EnumPrivsAccount),
+ (ndr_push_flags_fn_t) ndr_push_lsa_EnumPrivsAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_EnumPrivsAccount,
+- (ndr_print_function_t) ndr_print_lsa_EnumPrivsAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13736,7 +13736,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_AddPrivilegesToAccount),
+ (ndr_push_flags_fn_t) ndr_push_lsa_AddPrivilegesToAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_AddPrivilegesToAccount,
+- (ndr_print_function_t) ndr_print_lsa_AddPrivilegesToAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13745,7 +13745,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_RemovePrivilegesFromAccount),
+ (ndr_push_flags_fn_t) ndr_push_lsa_RemovePrivilegesFromAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_RemovePrivilegesFromAccount,
+- (ndr_print_function_t) ndr_print_lsa_RemovePrivilegesFromAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13754,7 +13754,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_GetQuotasForAccount),
+ (ndr_push_flags_fn_t) ndr_push_lsa_GetQuotasForAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_GetQuotasForAccount,
+- (ndr_print_function_t) ndr_print_lsa_GetQuotasForAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13763,7 +13763,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetQuotasForAccount),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetQuotasForAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetQuotasForAccount,
+- (ndr_print_function_t) ndr_print_lsa_SetQuotasForAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13772,7 +13772,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_GetSystemAccessAccount),
+ (ndr_push_flags_fn_t) ndr_push_lsa_GetSystemAccessAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_GetSystemAccessAccount,
+- (ndr_print_function_t) ndr_print_lsa_GetSystemAccessAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13781,7 +13781,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetSystemAccessAccount),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetSystemAccessAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetSystemAccessAccount,
+- (ndr_print_function_t) ndr_print_lsa_SetSystemAccessAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13790,7 +13790,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_OpenTrustedDomain),
+ (ndr_push_flags_fn_t) ndr_push_lsa_OpenTrustedDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_OpenTrustedDomain,
+- (ndr_print_function_t) ndr_print_lsa_OpenTrustedDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13799,7 +13799,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_QueryTrustedDomainInfo),
+ (ndr_push_flags_fn_t) ndr_push_lsa_QueryTrustedDomainInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_QueryTrustedDomainInfo,
+- (ndr_print_function_t) ndr_print_lsa_QueryTrustedDomainInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13808,7 +13808,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetInformationTrustedDomain),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetInformationTrustedDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetInformationTrustedDomain,
+- (ndr_print_function_t) ndr_print_lsa_SetInformationTrustedDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13817,7 +13817,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_OpenSecret),
+ (ndr_push_flags_fn_t) ndr_push_lsa_OpenSecret,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_OpenSecret,
+- (ndr_print_function_t) ndr_print_lsa_OpenSecret,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13826,7 +13826,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetSecret),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetSecret,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetSecret,
+- (ndr_print_function_t) ndr_print_lsa_SetSecret,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13835,7 +13835,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_QuerySecret),
+ (ndr_push_flags_fn_t) ndr_push_lsa_QuerySecret,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_QuerySecret,
+- (ndr_print_function_t) ndr_print_lsa_QuerySecret,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13844,7 +13844,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupPrivValue),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupPrivValue,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupPrivValue,
+- (ndr_print_function_t) ndr_print_lsa_LookupPrivValue,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13853,7 +13853,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupPrivName),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupPrivName,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupPrivName,
+- (ndr_print_function_t) ndr_print_lsa_LookupPrivName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13862,7 +13862,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupPrivDisplayName),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupPrivDisplayName,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupPrivDisplayName,
+- (ndr_print_function_t) ndr_print_lsa_LookupPrivDisplayName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13871,7 +13871,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_DeleteObject),
+ (ndr_push_flags_fn_t) ndr_push_lsa_DeleteObject,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_DeleteObject,
+- (ndr_print_function_t) ndr_print_lsa_DeleteObject,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13880,7 +13880,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_EnumAccountsWithUserRight),
+ (ndr_push_flags_fn_t) ndr_push_lsa_EnumAccountsWithUserRight,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_EnumAccountsWithUserRight,
+- (ndr_print_function_t) ndr_print_lsa_EnumAccountsWithUserRight,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13889,7 +13889,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_EnumAccountRights),
+ (ndr_push_flags_fn_t) ndr_push_lsa_EnumAccountRights,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_EnumAccountRights,
+- (ndr_print_function_t) ndr_print_lsa_EnumAccountRights,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13898,7 +13898,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_AddAccountRights),
+ (ndr_push_flags_fn_t) ndr_push_lsa_AddAccountRights,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_AddAccountRights,
+- (ndr_print_function_t) ndr_print_lsa_AddAccountRights,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13907,7 +13907,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_RemoveAccountRights),
+ (ndr_push_flags_fn_t) ndr_push_lsa_RemoveAccountRights,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_RemoveAccountRights,
+- (ndr_print_function_t) ndr_print_lsa_RemoveAccountRights,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13916,7 +13916,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_QueryTrustedDomainInfoBySid),
+ (ndr_push_flags_fn_t) ndr_push_lsa_QueryTrustedDomainInfoBySid,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_QueryTrustedDomainInfoBySid,
+- (ndr_print_function_t) ndr_print_lsa_QueryTrustedDomainInfoBySid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13925,7 +13925,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetTrustedDomainInfo),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetTrustedDomainInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetTrustedDomainInfo,
+- (ndr_print_function_t) ndr_print_lsa_SetTrustedDomainInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13934,7 +13934,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_DeleteTrustedDomain),
+ (ndr_push_flags_fn_t) ndr_push_lsa_DeleteTrustedDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_DeleteTrustedDomain,
+- (ndr_print_function_t) ndr_print_lsa_DeleteTrustedDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13943,7 +13943,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_StorePrivateData),
+ (ndr_push_flags_fn_t) ndr_push_lsa_StorePrivateData,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_StorePrivateData,
+- (ndr_print_function_t) ndr_print_lsa_StorePrivateData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13952,7 +13952,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_RetrievePrivateData),
+ (ndr_push_flags_fn_t) ndr_push_lsa_RetrievePrivateData,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_RetrievePrivateData,
+- (ndr_print_function_t) ndr_print_lsa_RetrievePrivateData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13961,7 +13961,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_OpenPolicy2),
+ (ndr_push_flags_fn_t) ndr_push_lsa_OpenPolicy2,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_OpenPolicy2,
+- (ndr_print_function_t) ndr_print_lsa_OpenPolicy2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13970,7 +13970,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_GetUserName),
+ (ndr_push_flags_fn_t) ndr_push_lsa_GetUserName,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_GetUserName,
+- (ndr_print_function_t) ndr_print_lsa_GetUserName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13979,7 +13979,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_QueryInfoPolicy2),
+ (ndr_push_flags_fn_t) ndr_push_lsa_QueryInfoPolicy2,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_QueryInfoPolicy2,
+- (ndr_print_function_t) ndr_print_lsa_QueryInfoPolicy2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13988,7 +13988,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetInfoPolicy2),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetInfoPolicy2,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetInfoPolicy2,
+- (ndr_print_function_t) ndr_print_lsa_SetInfoPolicy2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13997,7 +13997,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_QueryTrustedDomainInfoByName),
+ (ndr_push_flags_fn_t) ndr_push_lsa_QueryTrustedDomainInfoByName,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_QueryTrustedDomainInfoByName,
+- (ndr_print_function_t) ndr_print_lsa_QueryTrustedDomainInfoByName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14006,7 +14006,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetTrustedDomainInfoByName),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetTrustedDomainInfoByName,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetTrustedDomainInfoByName,
+- (ndr_print_function_t) ndr_print_lsa_SetTrustedDomainInfoByName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14015,7 +14015,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_EnumTrustedDomainsEx),
+ (ndr_push_flags_fn_t) ndr_push_lsa_EnumTrustedDomainsEx,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_EnumTrustedDomainsEx,
+- (ndr_print_function_t) ndr_print_lsa_EnumTrustedDomainsEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14024,7 +14024,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CreateTrustedDomainEx),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CreateTrustedDomainEx,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CreateTrustedDomainEx,
+- (ndr_print_function_t) ndr_print_lsa_CreateTrustedDomainEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14033,7 +14033,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CloseTrustedDomainEx),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CloseTrustedDomainEx,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CloseTrustedDomainEx,
+- (ndr_print_function_t) ndr_print_lsa_CloseTrustedDomainEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14042,7 +14042,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_QueryDomainInformationPolicy),
+ (ndr_push_flags_fn_t) ndr_push_lsa_QueryDomainInformationPolicy,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_QueryDomainInformationPolicy,
+- (ndr_print_function_t) ndr_print_lsa_QueryDomainInformationPolicy,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14051,7 +14051,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_SetDomainInformationPolicy),
+ (ndr_push_flags_fn_t) ndr_push_lsa_SetDomainInformationPolicy,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_SetDomainInformationPolicy,
+- (ndr_print_function_t) ndr_print_lsa_SetDomainInformationPolicy,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14060,7 +14060,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_OpenTrustedDomainByName),
+ (ndr_push_flags_fn_t) ndr_push_lsa_OpenTrustedDomainByName,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_OpenTrustedDomainByName,
+- (ndr_print_function_t) ndr_print_lsa_OpenTrustedDomainByName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14069,7 +14069,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_TestCall),
+ (ndr_push_flags_fn_t) ndr_push_lsa_TestCall,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_TestCall,
+- (ndr_print_function_t) ndr_print_lsa_TestCall,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14078,7 +14078,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupSids2),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupSids2,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupSids2,
+- (ndr_print_function_t) ndr_print_lsa_LookupSids2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14087,7 +14087,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupNames2),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupNames2,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupNames2,
+- (ndr_print_function_t) ndr_print_lsa_LookupNames2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14096,7 +14096,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CreateTrustedDomainEx2),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CreateTrustedDomainEx2,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CreateTrustedDomainEx2,
+- (ndr_print_function_t) ndr_print_lsa_CreateTrustedDomainEx2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14105,7 +14105,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRWRITE),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRWRITE,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRWRITE,
+- (ndr_print_function_t) ndr_print_lsa_CREDRWRITE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14114,7 +14114,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRREAD),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRREAD,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRREAD,
+- (ndr_print_function_t) ndr_print_lsa_CREDRREAD,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14123,7 +14123,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRENUMERATE),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRENUMERATE,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRENUMERATE,
+- (ndr_print_function_t) ndr_print_lsa_CREDRENUMERATE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14132,7 +14132,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRWRITEDOMAINCREDENTIALS),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRWRITEDOMAINCREDENTIALS,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRWRITEDOMAINCREDENTIALS,
+- (ndr_print_function_t) ndr_print_lsa_CREDRWRITEDOMAINCREDENTIALS,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14141,7 +14141,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRREADDOMAINCREDENTIALS),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRREADDOMAINCREDENTIALS,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRREADDOMAINCREDENTIALS,
+- (ndr_print_function_t) ndr_print_lsa_CREDRREADDOMAINCREDENTIALS,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14150,7 +14150,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRDELETE),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRDELETE,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRDELETE,
+- (ndr_print_function_t) ndr_print_lsa_CREDRDELETE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14159,7 +14159,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRGETTARGETINFO),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRGETTARGETINFO,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRGETTARGETINFO,
+- (ndr_print_function_t) ndr_print_lsa_CREDRGETTARGETINFO,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14168,7 +14168,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRPROFILELOADED),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRPROFILELOADED,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRPROFILELOADED,
+- (ndr_print_function_t) ndr_print_lsa_CREDRPROFILELOADED,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14177,7 +14177,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupNames3),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupNames3,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupNames3,
+- (ndr_print_function_t) ndr_print_lsa_LookupNames3,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14186,7 +14186,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRGETSESSIONTYPES),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRGETSESSIONTYPES,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRGETSESSIONTYPES,
+- (ndr_print_function_t) ndr_print_lsa_CREDRGETSESSIONTYPES,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14195,7 +14195,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LSARREGISTERAUDITEVENT),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LSARREGISTERAUDITEVENT,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LSARREGISTERAUDITEVENT,
+- (ndr_print_function_t) ndr_print_lsa_LSARREGISTERAUDITEVENT,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14204,7 +14204,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LSARGENAUDITEVENT),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LSARGENAUDITEVENT,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LSARGENAUDITEVENT,
+- (ndr_print_function_t) ndr_print_lsa_LSARGENAUDITEVENT,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14213,7 +14213,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LSARUNREGISTERAUDITEVENT),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LSARUNREGISTERAUDITEVENT,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LSARUNREGISTERAUDITEVENT,
+- (ndr_print_function_t) ndr_print_lsa_LSARUNREGISTERAUDITEVENT,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14222,7 +14222,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_lsaRQueryForestTrustInformation),
+ (ndr_push_flags_fn_t) ndr_push_lsa_lsaRQueryForestTrustInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_lsaRQueryForestTrustInformation,
+- (ndr_print_function_t) ndr_print_lsa_lsaRQueryForestTrustInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14231,7 +14231,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_lsaRSetForestTrustInformation),
+ (ndr_push_flags_fn_t) ndr_push_lsa_lsaRSetForestTrustInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_lsaRSetForestTrustInformation,
+- (ndr_print_function_t) ndr_print_lsa_lsaRSetForestTrustInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14240,7 +14240,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_CREDRRENAME),
+ (ndr_push_flags_fn_t) ndr_push_lsa_CREDRRENAME,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_CREDRRENAME,
+- (ndr_print_function_t) ndr_print_lsa_CREDRRENAME,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14249,7 +14249,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupSids3),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupSids3,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupSids3,
+- (ndr_print_function_t) ndr_print_lsa_LookupSids3,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14258,7 +14258,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LookupNames4),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LookupNames4,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LookupNames4,
+- (ndr_print_function_t) ndr_print_lsa_LookupNames4,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14267,7 +14267,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LSAROPENPOLICYSCE),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LSAROPENPOLICYSCE,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LSAROPENPOLICYSCE,
+- (ndr_print_function_t) ndr_print_lsa_LSAROPENPOLICYSCE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14276,7 +14276,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LSARADTREGISTERSECURITYEVENTSOURCE,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LSARADTREGISTERSECURITYEVENTSOURCE,
+- (ndr_print_function_t) ndr_print_lsa_LSARADTREGISTERSECURITYEVENTSOURCE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14285,7 +14285,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE,
+- (ndr_print_function_t) ndr_print_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -14294,7 +14294,7 @@ static const struct ndr_interface_call l
+ sizeof(struct lsa_LSARADTREPORTSECURITYEVENT),
+ (ndr_push_flags_fn_t) ndr_push_lsa_LSARADTREPORTSECURITYEVENT,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_LSARADTREPORTSECURITYEVENT,
+- (ndr_print_function_t) ndr_print_lsa_LSARADTREPORTSECURITYEVENT,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_mgmt.c
++++ b/source3/librpc/gen_ndr/ndr_mgmt.c
+@@ -515,7 +515,7 @@ static const struct ndr_interface_call m
+ sizeof(struct mgmt_inq_if_ids),
+ (ndr_push_flags_fn_t) ndr_push_mgmt_inq_if_ids,
+ (ndr_pull_flags_fn_t) ndr_pull_mgmt_inq_if_ids,
+- (ndr_print_function_t) ndr_print_mgmt_inq_if_ids,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -524,7 +524,7 @@ static const struct ndr_interface_call m
+ sizeof(struct mgmt_inq_stats),
+ (ndr_push_flags_fn_t) ndr_push_mgmt_inq_stats,
+ (ndr_pull_flags_fn_t) ndr_pull_mgmt_inq_stats,
+- (ndr_print_function_t) ndr_print_mgmt_inq_stats,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -533,7 +533,7 @@ static const struct ndr_interface_call m
+ sizeof(struct mgmt_is_server_listening),
+ (ndr_push_flags_fn_t) ndr_push_mgmt_is_server_listening,
+ (ndr_pull_flags_fn_t) ndr_pull_mgmt_is_server_listening,
+- (ndr_print_function_t) ndr_print_mgmt_is_server_listening,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -542,7 +542,7 @@ static const struct ndr_interface_call m
+ sizeof(struct mgmt_stop_server_listening),
+ (ndr_push_flags_fn_t) ndr_push_mgmt_stop_server_listening,
+ (ndr_pull_flags_fn_t) ndr_pull_mgmt_stop_server_listening,
+- (ndr_print_function_t) ndr_print_mgmt_stop_server_listening,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -551,7 +551,7 @@ static const struct ndr_interface_call m
+ sizeof(struct mgmt_inq_princ_name),
+ (ndr_push_flags_fn_t) ndr_push_mgmt_inq_princ_name,
+ (ndr_pull_flags_fn_t) ndr_pull_mgmt_inq_princ_name,
+- (ndr_print_function_t) ndr_print_mgmt_inq_princ_name,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_msgsvc.c
++++ b/source3/librpc/gen_ndr/ndr_msgsvc.c
+@@ -165,7 +165,7 @@ static const struct ndr_interface_call m
+ sizeof(struct NetrMessageNameAdd),
+ (ndr_push_flags_fn_t) ndr_push_NetrMessageNameAdd,
+ (ndr_pull_flags_fn_t) ndr_pull_NetrMessageNameAdd,
+- (ndr_print_function_t) ndr_print_NetrMessageNameAdd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -174,7 +174,7 @@ static const struct ndr_interface_call m
+ sizeof(struct NetrMessageNameEnum),
+ (ndr_push_flags_fn_t) ndr_push_NetrMessageNameEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_NetrMessageNameEnum,
+- (ndr_print_function_t) ndr_print_NetrMessageNameEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -183,7 +183,7 @@ static const struct ndr_interface_call m
+ sizeof(struct NetrMessageNameGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_NetrMessageNameGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_NetrMessageNameGetInfo,
+- (ndr_print_function_t) ndr_print_NetrMessageNameGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -192,7 +192,7 @@ static const struct ndr_interface_call m
+ sizeof(struct NetrMessageNameDel),
+ (ndr_push_flags_fn_t) ndr_push_NetrMessageNameDel,
+ (ndr_pull_flags_fn_t) ndr_pull_NetrMessageNameDel,
+- (ndr_print_function_t) ndr_print_NetrMessageNameDel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -276,7 +276,7 @@ static const struct ndr_interface_call m
+ sizeof(struct NetrSendMessage),
+ (ndr_push_flags_fn_t) ndr_push_NetrSendMessage,
+ (ndr_pull_flags_fn_t) ndr_pull_NetrSendMessage,
+- (ndr_print_function_t) ndr_print_NetrSendMessage,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_nbt.c
++++ b/source3/librpc/gen_ndr/ndr_nbt.c
+@@ -3671,7 +3671,7 @@ static const struct ndr_interface_call n
+ sizeof(struct decode_nbt_netlogon_packet),
+ (ndr_push_flags_fn_t) ndr_push_decode_nbt_netlogon_packet,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_nbt_netlogon_packet,
+- (ndr_print_function_t) ndr_print_decode_nbt_netlogon_packet,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_netlogon.c
++++ b/source3/librpc/gen_ndr/ndr_netlogon.c
+@@ -17827,7 +17827,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonUasLogon),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonUasLogon,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonUasLogon,
+- (ndr_print_function_t) ndr_print_netr_LogonUasLogon,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17836,7 +17836,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonUasLogoff),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonUasLogoff,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonUasLogoff,
+- (ndr_print_function_t) ndr_print_netr_LogonUasLogoff,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17845,7 +17845,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonSamLogon),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonSamLogon,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonSamLogon,
+- (ndr_print_function_t) ndr_print_netr_LogonSamLogon,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17854,7 +17854,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonSamLogoff),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonSamLogoff,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonSamLogoff,
+- (ndr_print_function_t) ndr_print_netr_LogonSamLogoff,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17863,7 +17863,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_ServerReqChallenge),
+ (ndr_push_flags_fn_t) ndr_push_netr_ServerReqChallenge,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_ServerReqChallenge,
+- (ndr_print_function_t) ndr_print_netr_ServerReqChallenge,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17872,7 +17872,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_ServerAuthenticate),
+ (ndr_push_flags_fn_t) ndr_push_netr_ServerAuthenticate,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_ServerAuthenticate,
+- (ndr_print_function_t) ndr_print_netr_ServerAuthenticate,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17881,7 +17881,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_ServerPasswordSet),
+ (ndr_push_flags_fn_t) ndr_push_netr_ServerPasswordSet,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_ServerPasswordSet,
+- (ndr_print_function_t) ndr_print_netr_ServerPasswordSet,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17890,7 +17890,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DatabaseDeltas),
+ (ndr_push_flags_fn_t) ndr_push_netr_DatabaseDeltas,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DatabaseDeltas,
+- (ndr_print_function_t) ndr_print_netr_DatabaseDeltas,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17899,7 +17899,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DatabaseSync),
+ (ndr_push_flags_fn_t) ndr_push_netr_DatabaseSync,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DatabaseSync,
+- (ndr_print_function_t) ndr_print_netr_DatabaseSync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17908,7 +17908,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_AccountDeltas),
+ (ndr_push_flags_fn_t) ndr_push_netr_AccountDeltas,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_AccountDeltas,
+- (ndr_print_function_t) ndr_print_netr_AccountDeltas,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17917,7 +17917,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_AccountSync),
+ (ndr_push_flags_fn_t) ndr_push_netr_AccountSync,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_AccountSync,
+- (ndr_print_function_t) ndr_print_netr_AccountSync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17926,7 +17926,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_GetDcName),
+ (ndr_push_flags_fn_t) ndr_push_netr_GetDcName,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_GetDcName,
+- (ndr_print_function_t) ndr_print_netr_GetDcName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17935,7 +17935,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonControl),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonControl,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonControl,
+- (ndr_print_function_t) ndr_print_netr_LogonControl,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17944,7 +17944,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_GetAnyDCName),
+ (ndr_push_flags_fn_t) ndr_push_netr_GetAnyDCName,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_GetAnyDCName,
+- (ndr_print_function_t) ndr_print_netr_GetAnyDCName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17953,7 +17953,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonControl2),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonControl2,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonControl2,
+- (ndr_print_function_t) ndr_print_netr_LogonControl2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17962,7 +17962,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_ServerAuthenticate2),
+ (ndr_push_flags_fn_t) ndr_push_netr_ServerAuthenticate2,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_ServerAuthenticate2,
+- (ndr_print_function_t) ndr_print_netr_ServerAuthenticate2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17971,7 +17971,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DatabaseSync2),
+ (ndr_push_flags_fn_t) ndr_push_netr_DatabaseSync2,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DatabaseSync2,
+- (ndr_print_function_t) ndr_print_netr_DatabaseSync2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17980,7 +17980,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DatabaseRedo),
+ (ndr_push_flags_fn_t) ndr_push_netr_DatabaseRedo,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DatabaseRedo,
+- (ndr_print_function_t) ndr_print_netr_DatabaseRedo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17989,7 +17989,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonControl2Ex),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonControl2Ex,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonControl2Ex,
+- (ndr_print_function_t) ndr_print_netr_LogonControl2Ex,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -17998,7 +17998,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_NetrEnumerateTrustedDomains),
+ (ndr_push_flags_fn_t) ndr_push_netr_NetrEnumerateTrustedDomains,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_NetrEnumerateTrustedDomains,
+- (ndr_print_function_t) ndr_print_netr_NetrEnumerateTrustedDomains,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18007,7 +18007,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsRGetDCName),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsRGetDCName,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsRGetDCName,
+- (ndr_print_function_t) ndr_print_netr_DsRGetDCName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18016,7 +18016,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonGetCapabilities),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonGetCapabilities,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonGetCapabilities,
+- (ndr_print_function_t) ndr_print_netr_LogonGetCapabilities,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18025,7 +18025,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_NETRLOGONSETSERVICEBITS),
+ (ndr_push_flags_fn_t) ndr_push_netr_NETRLOGONSETSERVICEBITS,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_NETRLOGONSETSERVICEBITS,
+- (ndr_print_function_t) ndr_print_netr_NETRLOGONSETSERVICEBITS,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18034,7 +18034,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonGetTrustRid),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonGetTrustRid,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonGetTrustRid,
+- (ndr_print_function_t) ndr_print_netr_LogonGetTrustRid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18043,7 +18043,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_NETRLOGONCOMPUTESERVERDIGEST),
+ (ndr_push_flags_fn_t) ndr_push_netr_NETRLOGONCOMPUTESERVERDIGEST,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_NETRLOGONCOMPUTESERVERDIGEST,
+- (ndr_print_function_t) ndr_print_netr_NETRLOGONCOMPUTESERVERDIGEST,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18052,7 +18052,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_NETRLOGONCOMPUTECLIENTDIGEST),
+ (ndr_push_flags_fn_t) ndr_push_netr_NETRLOGONCOMPUTECLIENTDIGEST,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_NETRLOGONCOMPUTECLIENTDIGEST,
+- (ndr_print_function_t) ndr_print_netr_NETRLOGONCOMPUTECLIENTDIGEST,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18061,7 +18061,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_ServerAuthenticate3),
+ (ndr_push_flags_fn_t) ndr_push_netr_ServerAuthenticate3,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_ServerAuthenticate3,
+- (ndr_print_function_t) ndr_print_netr_ServerAuthenticate3,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18070,7 +18070,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsRGetDCNameEx),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsRGetDCNameEx,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsRGetDCNameEx,
+- (ndr_print_function_t) ndr_print_netr_DsRGetDCNameEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18079,7 +18079,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsRGetSiteName),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsRGetSiteName,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsRGetSiteName,
+- (ndr_print_function_t) ndr_print_netr_DsRGetSiteName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18088,7 +18088,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonGetDomainInfo),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonGetDomainInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonGetDomainInfo,
+- (ndr_print_function_t) ndr_print_netr_LogonGetDomainInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18097,7 +18097,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_ServerPasswordSet2),
+ (ndr_push_flags_fn_t) ndr_push_netr_ServerPasswordSet2,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_ServerPasswordSet2,
+- (ndr_print_function_t) ndr_print_netr_ServerPasswordSet2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18106,7 +18106,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_ServerPasswordGet),
+ (ndr_push_flags_fn_t) ndr_push_netr_ServerPasswordGet,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_ServerPasswordGet,
+- (ndr_print_function_t) ndr_print_netr_ServerPasswordGet,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18115,7 +18115,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_NETRLOGONSENDTOSAM),
+ (ndr_push_flags_fn_t) ndr_push_netr_NETRLOGONSENDTOSAM,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_NETRLOGONSENDTOSAM,
+- (ndr_print_function_t) ndr_print_netr_NETRLOGONSENDTOSAM,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18124,7 +18124,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsRAddressToSitenamesW),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsRAddressToSitenamesW,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsRAddressToSitenamesW,
+- (ndr_print_function_t) ndr_print_netr_DsRAddressToSitenamesW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18133,7 +18133,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsRGetDCNameEx2),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsRGetDCNameEx2,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsRGetDCNameEx2,
+- (ndr_print_function_t) ndr_print_netr_DsRGetDCNameEx2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18142,7 +18142,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN),
+ (ndr_push_flags_fn_t) ndr_push_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN,
+- (ndr_print_function_t) ndr_print_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18151,7 +18151,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_NetrEnumerateTrustedDomainsEx),
+ (ndr_push_flags_fn_t) ndr_push_netr_NetrEnumerateTrustedDomainsEx,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_NetrEnumerateTrustedDomainsEx,
+- (ndr_print_function_t) ndr_print_netr_NetrEnumerateTrustedDomainsEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18160,7 +18160,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsRAddressToSitenamesExW),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsRAddressToSitenamesExW,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsRAddressToSitenamesExW,
+- (ndr_print_function_t) ndr_print_netr_DsRAddressToSitenamesExW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18169,7 +18169,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsrGetDcSiteCoverageW),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsrGetDcSiteCoverageW,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsrGetDcSiteCoverageW,
+- (ndr_print_function_t) ndr_print_netr_DsrGetDcSiteCoverageW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18178,7 +18178,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonSamLogonEx),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonSamLogonEx,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonSamLogonEx,
+- (ndr_print_function_t) ndr_print_netr_LogonSamLogonEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18187,7 +18187,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsrEnumerateDomainTrusts),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsrEnumerateDomainTrusts,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsrEnumerateDomainTrusts,
+- (ndr_print_function_t) ndr_print_netr_DsrEnumerateDomainTrusts,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18196,7 +18196,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsrDeregisterDNSHostRecords),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsrDeregisterDNSHostRecords,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsrDeregisterDNSHostRecords,
+- (ndr_print_function_t) ndr_print_netr_DsrDeregisterDNSHostRecords,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18205,7 +18205,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_ServerTrustPasswordsGet),
+ (ndr_push_flags_fn_t) ndr_push_netr_ServerTrustPasswordsGet,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_ServerTrustPasswordsGet,
+- (ndr_print_function_t) ndr_print_netr_ServerTrustPasswordsGet,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18214,7 +18214,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsRGetForestTrustInformation),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsRGetForestTrustInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsRGetForestTrustInformation,
+- (ndr_print_function_t) ndr_print_netr_DsRGetForestTrustInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18223,7 +18223,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_GetForestTrustInformation),
+ (ndr_push_flags_fn_t) ndr_push_netr_GetForestTrustInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_GetForestTrustInformation,
+- (ndr_print_function_t) ndr_print_netr_GetForestTrustInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18232,7 +18232,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_LogonSamLogonWithFlags),
+ (ndr_push_flags_fn_t) ndr_push_netr_LogonSamLogonWithFlags,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_LogonSamLogonWithFlags,
+- (ndr_print_function_t) ndr_print_netr_LogonSamLogonWithFlags,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18241,7 +18241,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_ServerGetTrustInfo),
+ (ndr_push_flags_fn_t) ndr_push_netr_ServerGetTrustInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_ServerGetTrustInfo,
+- (ndr_print_function_t) ndr_print_netr_ServerGetTrustInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18250,7 +18250,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_Unused47),
+ (ndr_push_flags_fn_t) ndr_push_netr_Unused47,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_Unused47,
+- (ndr_print_function_t) ndr_print_netr_Unused47,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -18259,7 +18259,7 @@ static const struct ndr_interface_call n
+ sizeof(struct netr_DsrUpdateReadOnlyServerDnsRecords),
+ (ndr_push_flags_fn_t) ndr_push_netr_DsrUpdateReadOnlyServerDnsRecords,
+ (ndr_pull_flags_fn_t) ndr_pull_netr_DsrUpdateReadOnlyServerDnsRecords,
+- (ndr_print_function_t) ndr_print_netr_DsrUpdateReadOnlyServerDnsRecords,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_ntlmssp.c
++++ b/source3/librpc/gen_ndr/ndr_ntlmssp.c
+@@ -2408,7 +2408,7 @@ static const struct ndr_interface_call n
+ sizeof(struct decode_NEGOTIATE_MESSAGE),
+ (ndr_push_flags_fn_t) ndr_push_decode_NEGOTIATE_MESSAGE,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_NEGOTIATE_MESSAGE,
+- (ndr_print_function_t) ndr_print_decode_NEGOTIATE_MESSAGE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2417,7 +2417,7 @@ static const struct ndr_interface_call n
+ sizeof(struct decode_CHALLENGE_MESSAGE),
+ (ndr_push_flags_fn_t) ndr_push_decode_CHALLENGE_MESSAGE,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_CHALLENGE_MESSAGE,
+- (ndr_print_function_t) ndr_print_decode_CHALLENGE_MESSAGE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2426,7 +2426,7 @@ static const struct ndr_interface_call n
+ sizeof(struct decode_AUTHENTICATE_MESSAGE),
+ (ndr_push_flags_fn_t) ndr_push_decode_AUTHENTICATE_MESSAGE,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_AUTHENTICATE_MESSAGE,
+- (ndr_print_function_t) ndr_print_decode_AUTHENTICATE_MESSAGE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2435,7 +2435,7 @@ static const struct ndr_interface_call n
+ sizeof(struct decode_NTLMv2_CLIENT_CHALLENGE),
+ (ndr_push_flags_fn_t) ndr_push_decode_NTLMv2_CLIENT_CHALLENGE,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_NTLMv2_CLIENT_CHALLENGE,
+- (ndr_print_function_t) ndr_print_decode_NTLMv2_CLIENT_CHALLENGE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2444,7 +2444,7 @@ static const struct ndr_interface_call n
+ sizeof(struct decode_NTLMv2_RESPONSE),
+ (ndr_push_flags_fn_t) ndr_push_decode_NTLMv2_RESPONSE,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_NTLMv2_RESPONSE,
+- (ndr_print_function_t) ndr_print_decode_NTLMv2_RESPONSE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_ntprinting.c
++++ b/source3/librpc/gen_ndr/ndr_ntprinting.c
+@@ -914,7 +914,7 @@ static const struct ndr_interface_call n
+ sizeof(struct decode_ntprinting_form),
+ (ndr_push_flags_fn_t) ndr_push_decode_ntprinting_form,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_ntprinting_form,
+- (ndr_print_function_t) ndr_print_decode_ntprinting_form,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -923,7 +923,7 @@ static const struct ndr_interface_call n
+ sizeof(struct decode_ntprinting_driver),
+ (ndr_push_flags_fn_t) ndr_push_decode_ntprinting_driver,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_ntprinting_driver,
+- (ndr_print_function_t) ndr_print_decode_ntprinting_driver,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -932,7 +932,7 @@ static const struct ndr_interface_call n
+ sizeof(struct decode_ntprinting_printer),
+ (ndr_push_flags_fn_t) ndr_push_decode_ntprinting_printer,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_ntprinting_printer,
+- (ndr_print_function_t) ndr_print_decode_ntprinting_printer,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_ntsvcs.c
++++ b/source3/librpc/gen_ndr/ndr_ntsvcs.c
+@@ -3466,7 +3466,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_Disconnect),
+ (ndr_push_flags_fn_t) ndr_push_PNP_Disconnect,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_Disconnect,
+- (ndr_print_function_t) ndr_print_PNP_Disconnect,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3475,7 +3475,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_Connect),
+ (ndr_push_flags_fn_t) ndr_push_PNP_Connect,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_Connect,
+- (ndr_print_function_t) ndr_print_PNP_Connect,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3484,7 +3484,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetVersion),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetVersion,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetVersion,
+- (ndr_print_function_t) ndr_print_PNP_GetVersion,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3493,7 +3493,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetGlobalState),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetGlobalState,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetGlobalState,
+- (ndr_print_function_t) ndr_print_PNP_GetGlobalState,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3502,7 +3502,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_InitDetection),
+ (ndr_push_flags_fn_t) ndr_push_PNP_InitDetection,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_InitDetection,
+- (ndr_print_function_t) ndr_print_PNP_InitDetection,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3511,7 +3511,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_ReportLogOn),
+ (ndr_push_flags_fn_t) ndr_push_PNP_ReportLogOn,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_ReportLogOn,
+- (ndr_print_function_t) ndr_print_PNP_ReportLogOn,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3520,7 +3520,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_ValidateDeviceInstance),
+ (ndr_push_flags_fn_t) ndr_push_PNP_ValidateDeviceInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_ValidateDeviceInstance,
+- (ndr_print_function_t) ndr_print_PNP_ValidateDeviceInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3529,7 +3529,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetRootDeviceInstance),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetRootDeviceInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetRootDeviceInstance,
+- (ndr_print_function_t) ndr_print_PNP_GetRootDeviceInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3538,7 +3538,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetRelatedDeviceInstance),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetRelatedDeviceInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetRelatedDeviceInstance,
+- (ndr_print_function_t) ndr_print_PNP_GetRelatedDeviceInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3547,7 +3547,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_EnumerateSubKeys),
+ (ndr_push_flags_fn_t) ndr_push_PNP_EnumerateSubKeys,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_EnumerateSubKeys,
+- (ndr_print_function_t) ndr_print_PNP_EnumerateSubKeys,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3556,7 +3556,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetDeviceList),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetDeviceList,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDeviceList,
+- (ndr_print_function_t) ndr_print_PNP_GetDeviceList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3565,7 +3565,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetDeviceListSize),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetDeviceListSize,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDeviceListSize,
+- (ndr_print_function_t) ndr_print_PNP_GetDeviceListSize,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3574,7 +3574,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetDepth),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetDepth,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDepth,
+- (ndr_print_function_t) ndr_print_PNP_GetDepth,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3583,7 +3583,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetDeviceRegProp),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetDeviceRegProp,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDeviceRegProp,
+- (ndr_print_function_t) ndr_print_PNP_GetDeviceRegProp,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3592,7 +3592,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_SetDeviceRegProp),
+ (ndr_push_flags_fn_t) ndr_push_PNP_SetDeviceRegProp,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_SetDeviceRegProp,
+- (ndr_print_function_t) ndr_print_PNP_SetDeviceRegProp,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3601,7 +3601,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetClassInstance),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetClassInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetClassInstance,
+- (ndr_print_function_t) ndr_print_PNP_GetClassInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3610,7 +3610,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_CreateKey),
+ (ndr_push_flags_fn_t) ndr_push_PNP_CreateKey,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_CreateKey,
+- (ndr_print_function_t) ndr_print_PNP_CreateKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3619,7 +3619,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_DeleteRegistryKey),
+ (ndr_push_flags_fn_t) ndr_push_PNP_DeleteRegistryKey,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_DeleteRegistryKey,
+- (ndr_print_function_t) ndr_print_PNP_DeleteRegistryKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3628,7 +3628,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetClassCount),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetClassCount,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetClassCount,
+- (ndr_print_function_t) ndr_print_PNP_GetClassCount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3637,7 +3637,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetClassName),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetClassName,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetClassName,
+- (ndr_print_function_t) ndr_print_PNP_GetClassName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3646,7 +3646,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_DeleteClassKey),
+ (ndr_push_flags_fn_t) ndr_push_PNP_DeleteClassKey,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_DeleteClassKey,
+- (ndr_print_function_t) ndr_print_PNP_DeleteClassKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3655,7 +3655,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetInterfaceDeviceAlias),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetInterfaceDeviceAlias,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetInterfaceDeviceAlias,
+- (ndr_print_function_t) ndr_print_PNP_GetInterfaceDeviceAlias,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3664,7 +3664,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetInterfaceDeviceList),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetInterfaceDeviceList,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetInterfaceDeviceList,
+- (ndr_print_function_t) ndr_print_PNP_GetInterfaceDeviceList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3673,7 +3673,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetInterfaceDeviceListSize),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetInterfaceDeviceListSize,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetInterfaceDeviceListSize,
+- (ndr_print_function_t) ndr_print_PNP_GetInterfaceDeviceListSize,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3682,7 +3682,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_RegisterDeviceClassAssociation),
+ (ndr_push_flags_fn_t) ndr_push_PNP_RegisterDeviceClassAssociation,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_RegisterDeviceClassAssociation,
+- (ndr_print_function_t) ndr_print_PNP_RegisterDeviceClassAssociation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3691,7 +3691,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_UnregisterDeviceClassAssociation),
+ (ndr_push_flags_fn_t) ndr_push_PNP_UnregisterDeviceClassAssociation,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_UnregisterDeviceClassAssociation,
+- (ndr_print_function_t) ndr_print_PNP_UnregisterDeviceClassAssociation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3700,7 +3700,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetClassRegProp),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetClassRegProp,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetClassRegProp,
+- (ndr_print_function_t) ndr_print_PNP_GetClassRegProp,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3709,7 +3709,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_SetClassRegProp),
+ (ndr_push_flags_fn_t) ndr_push_PNP_SetClassRegProp,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_SetClassRegProp,
+- (ndr_print_function_t) ndr_print_PNP_SetClassRegProp,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3718,7 +3718,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_CreateDevInst),
+ (ndr_push_flags_fn_t) ndr_push_PNP_CreateDevInst,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_CreateDevInst,
+- (ndr_print_function_t) ndr_print_PNP_CreateDevInst,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3727,7 +3727,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_DeviceInstanceAction),
+ (ndr_push_flags_fn_t) ndr_push_PNP_DeviceInstanceAction,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_DeviceInstanceAction,
+- (ndr_print_function_t) ndr_print_PNP_DeviceInstanceAction,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3736,7 +3736,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetDeviceStatus),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetDeviceStatus,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDeviceStatus,
+- (ndr_print_function_t) ndr_print_PNP_GetDeviceStatus,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3745,7 +3745,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_SetDeviceProblem),
+ (ndr_push_flags_fn_t) ndr_push_PNP_SetDeviceProblem,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_SetDeviceProblem,
+- (ndr_print_function_t) ndr_print_PNP_SetDeviceProblem,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3754,7 +3754,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_DisableDevInst),
+ (ndr_push_flags_fn_t) ndr_push_PNP_DisableDevInst,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_DisableDevInst,
+- (ndr_print_function_t) ndr_print_PNP_DisableDevInst,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3763,7 +3763,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_UninstallDevInst),
+ (ndr_push_flags_fn_t) ndr_push_PNP_UninstallDevInst,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_UninstallDevInst,
+- (ndr_print_function_t) ndr_print_PNP_UninstallDevInst,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3772,7 +3772,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_AddID),
+ (ndr_push_flags_fn_t) ndr_push_PNP_AddID,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_AddID,
+- (ndr_print_function_t) ndr_print_PNP_AddID,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3781,7 +3781,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_RegisterDriver),
+ (ndr_push_flags_fn_t) ndr_push_PNP_RegisterDriver,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_RegisterDriver,
+- (ndr_print_function_t) ndr_print_PNP_RegisterDriver,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3790,7 +3790,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_QueryRemove),
+ (ndr_push_flags_fn_t) ndr_push_PNP_QueryRemove,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_QueryRemove,
+- (ndr_print_function_t) ndr_print_PNP_QueryRemove,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3799,7 +3799,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_RequestDeviceEject),
+ (ndr_push_flags_fn_t) ndr_push_PNP_RequestDeviceEject,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_RequestDeviceEject,
+- (ndr_print_function_t) ndr_print_PNP_RequestDeviceEject,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3808,7 +3808,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_IsDockStationPresent),
+ (ndr_push_flags_fn_t) ndr_push_PNP_IsDockStationPresent,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_IsDockStationPresent,
+- (ndr_print_function_t) ndr_print_PNP_IsDockStationPresent,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3817,7 +3817,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_RequestEjectPC),
+ (ndr_push_flags_fn_t) ndr_push_PNP_RequestEjectPC,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_RequestEjectPC,
+- (ndr_print_function_t) ndr_print_PNP_RequestEjectPC,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3826,7 +3826,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_HwProfFlags),
+ (ndr_push_flags_fn_t) ndr_push_PNP_HwProfFlags,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_HwProfFlags,
+- (ndr_print_function_t) ndr_print_PNP_HwProfFlags,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3835,7 +3835,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetHwProfInfo),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetHwProfInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetHwProfInfo,
+- (ndr_print_function_t) ndr_print_PNP_GetHwProfInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3844,7 +3844,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_AddEmptyLogConf),
+ (ndr_push_flags_fn_t) ndr_push_PNP_AddEmptyLogConf,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_AddEmptyLogConf,
+- (ndr_print_function_t) ndr_print_PNP_AddEmptyLogConf,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3853,7 +3853,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_FreeLogConf),
+ (ndr_push_flags_fn_t) ndr_push_PNP_FreeLogConf,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_FreeLogConf,
+- (ndr_print_function_t) ndr_print_PNP_FreeLogConf,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3862,7 +3862,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetFirstLogConf),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetFirstLogConf,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetFirstLogConf,
+- (ndr_print_function_t) ndr_print_PNP_GetFirstLogConf,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3871,7 +3871,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetNextLogConf),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetNextLogConf,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetNextLogConf,
+- (ndr_print_function_t) ndr_print_PNP_GetNextLogConf,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3880,7 +3880,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetLogConfPriority),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetLogConfPriority,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetLogConfPriority,
+- (ndr_print_function_t) ndr_print_PNP_GetLogConfPriority,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3889,7 +3889,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_AddResDes),
+ (ndr_push_flags_fn_t) ndr_push_PNP_AddResDes,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_AddResDes,
+- (ndr_print_function_t) ndr_print_PNP_AddResDes,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3898,7 +3898,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_FreeResDes),
+ (ndr_push_flags_fn_t) ndr_push_PNP_FreeResDes,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_FreeResDes,
+- (ndr_print_function_t) ndr_print_PNP_FreeResDes,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3907,7 +3907,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetNextResDes),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetNextResDes,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetNextResDes,
+- (ndr_print_function_t) ndr_print_PNP_GetNextResDes,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3916,7 +3916,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetResDesData),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetResDesData,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetResDesData,
+- (ndr_print_function_t) ndr_print_PNP_GetResDesData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3925,7 +3925,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetResDesDataSize),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetResDesDataSize,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetResDesDataSize,
+- (ndr_print_function_t) ndr_print_PNP_GetResDesDataSize,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3934,7 +3934,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_ModifyResDes),
+ (ndr_push_flags_fn_t) ndr_push_PNP_ModifyResDes,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_ModifyResDes,
+- (ndr_print_function_t) ndr_print_PNP_ModifyResDes,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3943,7 +3943,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_DetectResourceLimit),
+ (ndr_push_flags_fn_t) ndr_push_PNP_DetectResourceLimit,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_DetectResourceLimit,
+- (ndr_print_function_t) ndr_print_PNP_DetectResourceLimit,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3952,7 +3952,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_QueryResConfList),
+ (ndr_push_flags_fn_t) ndr_push_PNP_QueryResConfList,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_QueryResConfList,
+- (ndr_print_function_t) ndr_print_PNP_QueryResConfList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3961,7 +3961,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_SetHwProf),
+ (ndr_push_flags_fn_t) ndr_push_PNP_SetHwProf,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_SetHwProf,
+- (ndr_print_function_t) ndr_print_PNP_SetHwProf,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3970,7 +3970,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_QueryArbitratorFreeData),
+ (ndr_push_flags_fn_t) ndr_push_PNP_QueryArbitratorFreeData,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_QueryArbitratorFreeData,
+- (ndr_print_function_t) ndr_print_PNP_QueryArbitratorFreeData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3979,7 +3979,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_QueryArbitratorFreeSize),
+ (ndr_push_flags_fn_t) ndr_push_PNP_QueryArbitratorFreeSize,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_QueryArbitratorFreeSize,
+- (ndr_print_function_t) ndr_print_PNP_QueryArbitratorFreeSize,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3988,7 +3988,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_RunDetection),
+ (ndr_push_flags_fn_t) ndr_push_PNP_RunDetection,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_RunDetection,
+- (ndr_print_function_t) ndr_print_PNP_RunDetection,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3997,7 +3997,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_RegisterNotification),
+ (ndr_push_flags_fn_t) ndr_push_PNP_RegisterNotification,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_RegisterNotification,
+- (ndr_print_function_t) ndr_print_PNP_RegisterNotification,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4006,7 +4006,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_UnregisterNotification),
+ (ndr_push_flags_fn_t) ndr_push_PNP_UnregisterNotification,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_UnregisterNotification,
+- (ndr_print_function_t) ndr_print_PNP_UnregisterNotification,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4015,7 +4015,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetCustomDevProp),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetCustomDevProp,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetCustomDevProp,
+- (ndr_print_function_t) ndr_print_PNP_GetCustomDevProp,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4024,7 +4024,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetVersionInternal),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetVersionInternal,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetVersionInternal,
+- (ndr_print_function_t) ndr_print_PNP_GetVersionInternal,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4033,7 +4033,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetBlockedDriverInfo),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetBlockedDriverInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetBlockedDriverInfo,
+- (ndr_print_function_t) ndr_print_PNP_GetBlockedDriverInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4042,7 +4042,7 @@ static const struct ndr_interface_call n
+ sizeof(struct PNP_GetServerSideDeviceInstallFlags),
+ (ndr_push_flags_fn_t) ndr_push_PNP_GetServerSideDeviceInstallFlags,
+ (ndr_pull_flags_fn_t) ndr_pull_PNP_GetServerSideDeviceInstallFlags,
+- (ndr_print_function_t) ndr_print_PNP_GetServerSideDeviceInstallFlags,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_oxidresolver.c
++++ b/source3/librpc/gen_ndr/ndr_oxidresolver.c
+@@ -761,7 +761,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ResolveOxid),
+ (ndr_push_flags_fn_t) ndr_push_ResolveOxid,
+ (ndr_pull_flags_fn_t) ndr_pull_ResolveOxid,
+- (ndr_print_function_t) ndr_print_ResolveOxid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -770,7 +770,7 @@ static const struct ndr_interface_call I
+ sizeof(struct SimplePing),
+ (ndr_push_flags_fn_t) ndr_push_SimplePing,
+ (ndr_pull_flags_fn_t) ndr_pull_SimplePing,
+- (ndr_print_function_t) ndr_print_SimplePing,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -779,7 +779,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ComplexPing),
+ (ndr_push_flags_fn_t) ndr_push_ComplexPing,
+ (ndr_pull_flags_fn_t) ndr_pull_ComplexPing,
+- (ndr_print_function_t) ndr_print_ComplexPing,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -788,7 +788,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ServerAlive),
+ (ndr_push_flags_fn_t) ndr_push_ServerAlive,
+ (ndr_pull_flags_fn_t) ndr_pull_ServerAlive,
+- (ndr_print_function_t) ndr_print_ServerAlive,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -797,7 +797,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ResolveOxid2),
+ (ndr_push_flags_fn_t) ndr_push_ResolveOxid2,
+ (ndr_pull_flags_fn_t) ndr_pull_ResolveOxid2,
+- (ndr_print_function_t) ndr_print_ResolveOxid2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -806,7 +806,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ServerAlive2),
+ (ndr_push_flags_fn_t) ndr_push_ServerAlive2,
+ (ndr_pull_flags_fn_t) ndr_pull_ServerAlive2,
+- (ndr_print_function_t) ndr_print_ServerAlive2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_policyagent.c
++++ b/source3/librpc/gen_ndr/ndr_policyagent.c
+@@ -51,7 +51,7 @@ static const struct ndr_interface_call p
+ sizeof(struct policyagent_Dummy),
+ (ndr_push_flags_fn_t) ndr_push_policyagent_Dummy,
+ (ndr_pull_flags_fn_t) ndr_pull_policyagent_Dummy,
+- (ndr_print_function_t) ndr_print_policyagent_Dummy,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_preg.c
++++ b/source3/librpc/gen_ndr/ndr_preg.c
+@@ -204,7 +204,7 @@ static const struct ndr_interface_call p
+ sizeof(struct decode_preg_file),
+ (ndr_push_flags_fn_t) ndr_push_decode_preg_file,
+ (ndr_pull_flags_fn_t) ndr_pull_decode_preg_file,
+- (ndr_print_function_t) ndr_print_decode_preg_file,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_remact.c
++++ b/source3/librpc/gen_ndr/ndr_remact.c
+@@ -373,7 +373,7 @@ static const struct ndr_interface_call I
+ sizeof(struct RemoteActivation),
+ (ndr_push_flags_fn_t) ndr_push_RemoteActivation,
+ (ndr_pull_flags_fn_t) ndr_pull_RemoteActivation,
+- (ndr_print_function_t) ndr_print_RemoteActivation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_rot.c
++++ b/source3/librpc/gen_ndr/ndr_rot.c
+@@ -489,7 +489,7 @@ static const struct ndr_interface_call r
+ sizeof(struct rot_add),
+ (ndr_push_flags_fn_t) ndr_push_rot_add,
+ (ndr_pull_flags_fn_t) ndr_pull_rot_add,
+- (ndr_print_function_t) ndr_print_rot_add,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -498,7 +498,7 @@ static const struct ndr_interface_call r
+ sizeof(struct rot_remove),
+ (ndr_push_flags_fn_t) ndr_push_rot_remove,
+ (ndr_pull_flags_fn_t) ndr_pull_rot_remove,
+- (ndr_print_function_t) ndr_print_rot_remove,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -507,7 +507,7 @@ static const struct ndr_interface_call r
+ sizeof(struct rot_is_listed),
+ (ndr_push_flags_fn_t) ndr_push_rot_is_listed,
+ (ndr_pull_flags_fn_t) ndr_pull_rot_is_listed,
+- (ndr_print_function_t) ndr_print_rot_is_listed,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -516,7 +516,7 @@ static const struct ndr_interface_call r
+ sizeof(struct rot_get_interface_pointer),
+ (ndr_push_flags_fn_t) ndr_push_rot_get_interface_pointer,
+ (ndr_pull_flags_fn_t) ndr_pull_rot_get_interface_pointer,
+- (ndr_print_function_t) ndr_print_rot_get_interface_pointer,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -525,7 +525,7 @@ static const struct ndr_interface_call r
+ sizeof(struct rot_set_modification_time),
+ (ndr_push_flags_fn_t) ndr_push_rot_set_modification_time,
+ (ndr_pull_flags_fn_t) ndr_pull_rot_set_modification_time,
+- (ndr_print_function_t) ndr_print_rot_set_modification_time,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -534,7 +534,7 @@ static const struct ndr_interface_call r
+ sizeof(struct rot_get_modification_time),
+ (ndr_push_flags_fn_t) ndr_push_rot_get_modification_time,
+ (ndr_pull_flags_fn_t) ndr_pull_rot_get_modification_time,
+- (ndr_print_function_t) ndr_print_rot_get_modification_time,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -543,7 +543,7 @@ static const struct ndr_interface_call r
+ sizeof(struct rot_enum),
+ (ndr_push_flags_fn_t) ndr_push_rot_enum,
+ (ndr_pull_flags_fn_t) ndr_pull_rot_enum,
+- (ndr_print_function_t) ndr_print_rot_enum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_samr.c
++++ b/source3/librpc/gen_ndr/ndr_samr.c
+@@ -12674,7 +12674,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_Connect),
+ (ndr_push_flags_fn_t) ndr_push_samr_Connect,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_Connect,
+- (ndr_print_function_t) ndr_print_samr_Connect,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12683,7 +12683,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_Close),
+ (ndr_push_flags_fn_t) ndr_push_samr_Close,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_Close,
+- (ndr_print_function_t) ndr_print_samr_Close,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12692,7 +12692,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_SetSecurity),
+ (ndr_push_flags_fn_t) ndr_push_samr_SetSecurity,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_SetSecurity,
+- (ndr_print_function_t) ndr_print_samr_SetSecurity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12701,7 +12701,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QuerySecurity),
+ (ndr_push_flags_fn_t) ndr_push_samr_QuerySecurity,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QuerySecurity,
+- (ndr_print_function_t) ndr_print_samr_QuerySecurity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12710,7 +12710,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_Shutdown),
+ (ndr_push_flags_fn_t) ndr_push_samr_Shutdown,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_Shutdown,
+- (ndr_print_function_t) ndr_print_samr_Shutdown,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12719,7 +12719,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_LookupDomain),
+ (ndr_push_flags_fn_t) ndr_push_samr_LookupDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_LookupDomain,
+- (ndr_print_function_t) ndr_print_samr_LookupDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12728,7 +12728,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_EnumDomains),
+ (ndr_push_flags_fn_t) ndr_push_samr_EnumDomains,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_EnumDomains,
+- (ndr_print_function_t) ndr_print_samr_EnumDomains,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12737,7 +12737,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_OpenDomain),
+ (ndr_push_flags_fn_t) ndr_push_samr_OpenDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_OpenDomain,
+- (ndr_print_function_t) ndr_print_samr_OpenDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12746,7 +12746,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryDomainInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryDomainInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryDomainInfo,
+- (ndr_print_function_t) ndr_print_samr_QueryDomainInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12755,7 +12755,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_SetDomainInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_SetDomainInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_SetDomainInfo,
+- (ndr_print_function_t) ndr_print_samr_SetDomainInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12764,7 +12764,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_CreateDomainGroup),
+ (ndr_push_flags_fn_t) ndr_push_samr_CreateDomainGroup,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_CreateDomainGroup,
+- (ndr_print_function_t) ndr_print_samr_CreateDomainGroup,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12773,7 +12773,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_EnumDomainGroups),
+ (ndr_push_flags_fn_t) ndr_push_samr_EnumDomainGroups,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_EnumDomainGroups,
+- (ndr_print_function_t) ndr_print_samr_EnumDomainGroups,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12782,7 +12782,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_CreateUser),
+ (ndr_push_flags_fn_t) ndr_push_samr_CreateUser,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_CreateUser,
+- (ndr_print_function_t) ndr_print_samr_CreateUser,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12791,7 +12791,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_EnumDomainUsers),
+ (ndr_push_flags_fn_t) ndr_push_samr_EnumDomainUsers,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_EnumDomainUsers,
+- (ndr_print_function_t) ndr_print_samr_EnumDomainUsers,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12800,7 +12800,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_CreateDomAlias),
+ (ndr_push_flags_fn_t) ndr_push_samr_CreateDomAlias,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_CreateDomAlias,
+- (ndr_print_function_t) ndr_print_samr_CreateDomAlias,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12809,7 +12809,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_EnumDomainAliases),
+ (ndr_push_flags_fn_t) ndr_push_samr_EnumDomainAliases,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_EnumDomainAliases,
+- (ndr_print_function_t) ndr_print_samr_EnumDomainAliases,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12818,7 +12818,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_GetAliasMembership),
+ (ndr_push_flags_fn_t) ndr_push_samr_GetAliasMembership,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_GetAliasMembership,
+- (ndr_print_function_t) ndr_print_samr_GetAliasMembership,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12827,7 +12827,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_LookupNames),
+ (ndr_push_flags_fn_t) ndr_push_samr_LookupNames,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_LookupNames,
+- (ndr_print_function_t) ndr_print_samr_LookupNames,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12836,7 +12836,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_LookupRids),
+ (ndr_push_flags_fn_t) ndr_push_samr_LookupRids,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_LookupRids,
+- (ndr_print_function_t) ndr_print_samr_LookupRids,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12845,7 +12845,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_OpenGroup),
+ (ndr_push_flags_fn_t) ndr_push_samr_OpenGroup,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_OpenGroup,
+- (ndr_print_function_t) ndr_print_samr_OpenGroup,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12854,7 +12854,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryGroupInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryGroupInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryGroupInfo,
+- (ndr_print_function_t) ndr_print_samr_QueryGroupInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12863,7 +12863,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_SetGroupInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_SetGroupInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_SetGroupInfo,
+- (ndr_print_function_t) ndr_print_samr_SetGroupInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12872,7 +12872,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_AddGroupMember),
+ (ndr_push_flags_fn_t) ndr_push_samr_AddGroupMember,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_AddGroupMember,
+- (ndr_print_function_t) ndr_print_samr_AddGroupMember,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12881,7 +12881,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_DeleteDomainGroup),
+ (ndr_push_flags_fn_t) ndr_push_samr_DeleteDomainGroup,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_DeleteDomainGroup,
+- (ndr_print_function_t) ndr_print_samr_DeleteDomainGroup,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12890,7 +12890,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_DeleteGroupMember),
+ (ndr_push_flags_fn_t) ndr_push_samr_DeleteGroupMember,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_DeleteGroupMember,
+- (ndr_print_function_t) ndr_print_samr_DeleteGroupMember,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12899,7 +12899,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryGroupMember),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryGroupMember,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryGroupMember,
+- (ndr_print_function_t) ndr_print_samr_QueryGroupMember,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12908,7 +12908,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_SetMemberAttributesOfGroup),
+ (ndr_push_flags_fn_t) ndr_push_samr_SetMemberAttributesOfGroup,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_SetMemberAttributesOfGroup,
+- (ndr_print_function_t) ndr_print_samr_SetMemberAttributesOfGroup,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12917,7 +12917,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_OpenAlias),
+ (ndr_push_flags_fn_t) ndr_push_samr_OpenAlias,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_OpenAlias,
+- (ndr_print_function_t) ndr_print_samr_OpenAlias,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12926,7 +12926,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryAliasInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryAliasInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryAliasInfo,
+- (ndr_print_function_t) ndr_print_samr_QueryAliasInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12935,7 +12935,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_SetAliasInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_SetAliasInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_SetAliasInfo,
+- (ndr_print_function_t) ndr_print_samr_SetAliasInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12944,7 +12944,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_DeleteDomAlias),
+ (ndr_push_flags_fn_t) ndr_push_samr_DeleteDomAlias,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_DeleteDomAlias,
+- (ndr_print_function_t) ndr_print_samr_DeleteDomAlias,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12953,7 +12953,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_AddAliasMember),
+ (ndr_push_flags_fn_t) ndr_push_samr_AddAliasMember,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_AddAliasMember,
+- (ndr_print_function_t) ndr_print_samr_AddAliasMember,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12962,7 +12962,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_DeleteAliasMember),
+ (ndr_push_flags_fn_t) ndr_push_samr_DeleteAliasMember,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_DeleteAliasMember,
+- (ndr_print_function_t) ndr_print_samr_DeleteAliasMember,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12971,7 +12971,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_GetMembersInAlias),
+ (ndr_push_flags_fn_t) ndr_push_samr_GetMembersInAlias,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_GetMembersInAlias,
+- (ndr_print_function_t) ndr_print_samr_GetMembersInAlias,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12980,7 +12980,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_OpenUser),
+ (ndr_push_flags_fn_t) ndr_push_samr_OpenUser,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_OpenUser,
+- (ndr_print_function_t) ndr_print_samr_OpenUser,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12989,7 +12989,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_DeleteUser),
+ (ndr_push_flags_fn_t) ndr_push_samr_DeleteUser,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_DeleteUser,
+- (ndr_print_function_t) ndr_print_samr_DeleteUser,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -12998,7 +12998,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryUserInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryUserInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryUserInfo,
+- (ndr_print_function_t) ndr_print_samr_QueryUserInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13007,7 +13007,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_SetUserInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_SetUserInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_SetUserInfo,
+- (ndr_print_function_t) ndr_print_samr_SetUserInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13016,7 +13016,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_ChangePasswordUser),
+ (ndr_push_flags_fn_t) ndr_push_samr_ChangePasswordUser,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_ChangePasswordUser,
+- (ndr_print_function_t) ndr_print_samr_ChangePasswordUser,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13025,7 +13025,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_GetGroupsForUser),
+ (ndr_push_flags_fn_t) ndr_push_samr_GetGroupsForUser,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_GetGroupsForUser,
+- (ndr_print_function_t) ndr_print_samr_GetGroupsForUser,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13034,7 +13034,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryDisplayInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryDisplayInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryDisplayInfo,
+- (ndr_print_function_t) ndr_print_samr_QueryDisplayInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13043,7 +13043,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_GetDisplayEnumerationIndex),
+ (ndr_push_flags_fn_t) ndr_push_samr_GetDisplayEnumerationIndex,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_GetDisplayEnumerationIndex,
+- (ndr_print_function_t) ndr_print_samr_GetDisplayEnumerationIndex,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13052,7 +13052,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_TestPrivateFunctionsDomain),
+ (ndr_push_flags_fn_t) ndr_push_samr_TestPrivateFunctionsDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_TestPrivateFunctionsDomain,
+- (ndr_print_function_t) ndr_print_samr_TestPrivateFunctionsDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13061,7 +13061,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_TestPrivateFunctionsUser),
+ (ndr_push_flags_fn_t) ndr_push_samr_TestPrivateFunctionsUser,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_TestPrivateFunctionsUser,
+- (ndr_print_function_t) ndr_print_samr_TestPrivateFunctionsUser,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13070,7 +13070,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_GetUserPwInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_GetUserPwInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_GetUserPwInfo,
+- (ndr_print_function_t) ndr_print_samr_GetUserPwInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13079,7 +13079,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_RemoveMemberFromForeignDomain),
+ (ndr_push_flags_fn_t) ndr_push_samr_RemoveMemberFromForeignDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_RemoveMemberFromForeignDomain,
+- (ndr_print_function_t) ndr_print_samr_RemoveMemberFromForeignDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13088,7 +13088,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryDomainInfo2),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryDomainInfo2,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryDomainInfo2,
+- (ndr_print_function_t) ndr_print_samr_QueryDomainInfo2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13097,7 +13097,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryUserInfo2),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryUserInfo2,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryUserInfo2,
+- (ndr_print_function_t) ndr_print_samr_QueryUserInfo2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13106,7 +13106,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryDisplayInfo2),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryDisplayInfo2,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryDisplayInfo2,
+- (ndr_print_function_t) ndr_print_samr_QueryDisplayInfo2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13115,7 +13115,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_GetDisplayEnumerationIndex2),
+ (ndr_push_flags_fn_t) ndr_push_samr_GetDisplayEnumerationIndex2,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_GetDisplayEnumerationIndex2,
+- (ndr_print_function_t) ndr_print_samr_GetDisplayEnumerationIndex2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13124,7 +13124,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_CreateUser2),
+ (ndr_push_flags_fn_t) ndr_push_samr_CreateUser2,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_CreateUser2,
+- (ndr_print_function_t) ndr_print_samr_CreateUser2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13133,7 +13133,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_QueryDisplayInfo3),
+ (ndr_push_flags_fn_t) ndr_push_samr_QueryDisplayInfo3,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_QueryDisplayInfo3,
+- (ndr_print_function_t) ndr_print_samr_QueryDisplayInfo3,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13142,7 +13142,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_AddMultipleMembersToAlias),
+ (ndr_push_flags_fn_t) ndr_push_samr_AddMultipleMembersToAlias,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_AddMultipleMembersToAlias,
+- (ndr_print_function_t) ndr_print_samr_AddMultipleMembersToAlias,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13151,7 +13151,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_RemoveMultipleMembersFromAlias),
+ (ndr_push_flags_fn_t) ndr_push_samr_RemoveMultipleMembersFromAlias,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_RemoveMultipleMembersFromAlias,
+- (ndr_print_function_t) ndr_print_samr_RemoveMultipleMembersFromAlias,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13160,7 +13160,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_OemChangePasswordUser2),
+ (ndr_push_flags_fn_t) ndr_push_samr_OemChangePasswordUser2,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_OemChangePasswordUser2,
+- (ndr_print_function_t) ndr_print_samr_OemChangePasswordUser2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13169,7 +13169,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_ChangePasswordUser2),
+ (ndr_push_flags_fn_t) ndr_push_samr_ChangePasswordUser2,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_ChangePasswordUser2,
+- (ndr_print_function_t) ndr_print_samr_ChangePasswordUser2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13178,7 +13178,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_GetDomPwInfo),
+ (ndr_push_flags_fn_t) ndr_push_samr_GetDomPwInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_GetDomPwInfo,
+- (ndr_print_function_t) ndr_print_samr_GetDomPwInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13187,7 +13187,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_Connect2),
+ (ndr_push_flags_fn_t) ndr_push_samr_Connect2,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_Connect2,
+- (ndr_print_function_t) ndr_print_samr_Connect2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13196,7 +13196,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_SetUserInfo2),
+ (ndr_push_flags_fn_t) ndr_push_samr_SetUserInfo2,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_SetUserInfo2,
+- (ndr_print_function_t) ndr_print_samr_SetUserInfo2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13205,7 +13205,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_SetBootKeyInformation),
+ (ndr_push_flags_fn_t) ndr_push_samr_SetBootKeyInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_SetBootKeyInformation,
+- (ndr_print_function_t) ndr_print_samr_SetBootKeyInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13214,7 +13214,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_GetBootKeyInformation),
+ (ndr_push_flags_fn_t) ndr_push_samr_GetBootKeyInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_GetBootKeyInformation,
+- (ndr_print_function_t) ndr_print_samr_GetBootKeyInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13223,7 +13223,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_Connect3),
+ (ndr_push_flags_fn_t) ndr_push_samr_Connect3,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_Connect3,
+- (ndr_print_function_t) ndr_print_samr_Connect3,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13232,7 +13232,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_Connect4),
+ (ndr_push_flags_fn_t) ndr_push_samr_Connect4,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_Connect4,
+- (ndr_print_function_t) ndr_print_samr_Connect4,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13241,7 +13241,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_ChangePasswordUser3),
+ (ndr_push_flags_fn_t) ndr_push_samr_ChangePasswordUser3,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_ChangePasswordUser3,
+- (ndr_print_function_t) ndr_print_samr_ChangePasswordUser3,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13250,7 +13250,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_Connect5),
+ (ndr_push_flags_fn_t) ndr_push_samr_Connect5,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_Connect5,
+- (ndr_print_function_t) ndr_print_samr_Connect5,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13259,7 +13259,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_RidToSid),
+ (ndr_push_flags_fn_t) ndr_push_samr_RidToSid,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_RidToSid,
+- (ndr_print_function_t) ndr_print_samr_RidToSid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13268,7 +13268,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_SetDsrmPassword),
+ (ndr_push_flags_fn_t) ndr_push_samr_SetDsrmPassword,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_SetDsrmPassword,
+- (ndr_print_function_t) ndr_print_samr_SetDsrmPassword,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -13277,7 +13277,7 @@ static const struct ndr_interface_call s
+ sizeof(struct samr_ValidatePassword),
+ (ndr_push_flags_fn_t) ndr_push_samr_ValidatePassword,
+ (ndr_pull_flags_fn_t) ndr_pull_samr_ValidatePassword,
+- (ndr_print_function_t) ndr_print_samr_ValidatePassword,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_scerpc.c
++++ b/source3/librpc/gen_ndr/ndr_scerpc.c
+@@ -51,7 +51,7 @@ static const struct ndr_interface_call s
+ sizeof(struct scerpc_Unknown0),
+ (ndr_push_flags_fn_t) ndr_push_scerpc_Unknown0,
+ (ndr_pull_flags_fn_t) ndr_pull_scerpc_Unknown0,
+- (ndr_print_function_t) ndr_print_scerpc_Unknown0,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_spoolss.c
++++ b/source3/librpc/gen_ndr/ndr_spoolss.c
+@@ -32661,7 +32661,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumPrinters),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumPrinters,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumPrinters,
+- (ndr_print_function_t) ndr_print_spoolss_EnumPrinters,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32670,7 +32670,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_OpenPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_OpenPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_OpenPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_OpenPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32679,7 +32679,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_SetJob),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_SetJob,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_SetJob,
+- (ndr_print_function_t) ndr_print_spoolss_SetJob,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32688,7 +32688,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetJob),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetJob,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetJob,
+- (ndr_print_function_t) ndr_print_spoolss_GetJob,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32697,7 +32697,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumJobs),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumJobs,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumJobs,
+- (ndr_print_function_t) ndr_print_spoolss_EnumJobs,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32706,7 +32706,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_AddPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32715,7 +32715,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrinter,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32724,7 +32724,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_SetPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_SetPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_SetPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_SetPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32733,7 +32733,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_GetPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32742,7 +32742,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPrinterDriver),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPrinterDriver,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPrinterDriver,
+- (ndr_print_function_t) ndr_print_spoolss_AddPrinterDriver,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32751,7 +32751,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumPrinterDrivers),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumPrinterDrivers,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumPrinterDrivers,
+- (ndr_print_function_t) ndr_print_spoolss_EnumPrinterDrivers,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32760,7 +32760,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetPrinterDriver),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetPrinterDriver,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetPrinterDriver,
+- (ndr_print_function_t) ndr_print_spoolss_GetPrinterDriver,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32769,7 +32769,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetPrinterDriverDirectory),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetPrinterDriverDirectory,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetPrinterDriverDirectory,
+- (ndr_print_function_t) ndr_print_spoolss_GetPrinterDriverDirectory,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32778,7 +32778,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrinterDriver),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrinterDriver,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrinterDriver,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrinterDriver,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32787,7 +32787,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPrintProcessor),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPrintProcessor,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPrintProcessor,
+- (ndr_print_function_t) ndr_print_spoolss_AddPrintProcessor,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32796,7 +32796,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumPrintProcessors),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumPrintProcessors,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumPrintProcessors,
+- (ndr_print_function_t) ndr_print_spoolss_EnumPrintProcessors,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32805,7 +32805,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetPrintProcessorDirectory),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetPrintProcessorDirectory,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetPrintProcessorDirectory,
+- (ndr_print_function_t) ndr_print_spoolss_GetPrintProcessorDirectory,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32814,7 +32814,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_StartDocPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_StartDocPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_StartDocPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_StartDocPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32823,7 +32823,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_StartPagePrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_StartPagePrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_StartPagePrinter,
+- (ndr_print_function_t) ndr_print_spoolss_StartPagePrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32832,7 +32832,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_WritePrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_WritePrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_WritePrinter,
+- (ndr_print_function_t) ndr_print_spoolss_WritePrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32841,7 +32841,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EndPagePrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EndPagePrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EndPagePrinter,
+- (ndr_print_function_t) ndr_print_spoolss_EndPagePrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32850,7 +32850,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AbortPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AbortPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AbortPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_AbortPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32859,7 +32859,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_ReadPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_ReadPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_ReadPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_ReadPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32868,7 +32868,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EndDocPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EndDocPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EndDocPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_EndDocPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32877,7 +32877,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddJob),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddJob,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddJob,
+- (ndr_print_function_t) ndr_print_spoolss_AddJob,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32886,7 +32886,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_ScheduleJob),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_ScheduleJob,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_ScheduleJob,
+- (ndr_print_function_t) ndr_print_spoolss_ScheduleJob,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32895,7 +32895,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetPrinterData),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetPrinterData,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetPrinterData,
+- (ndr_print_function_t) ndr_print_spoolss_GetPrinterData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32904,7 +32904,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_SetPrinterData),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_SetPrinterData,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_SetPrinterData,
+- (ndr_print_function_t) ndr_print_spoolss_SetPrinterData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32913,7 +32913,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_WaitForPrinterChange),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_WaitForPrinterChange,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_WaitForPrinterChange,
+- (ndr_print_function_t) ndr_print_spoolss_WaitForPrinterChange,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32922,7 +32922,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_ClosePrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_ClosePrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_ClosePrinter,
+- (ndr_print_function_t) ndr_print_spoolss_ClosePrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32931,7 +32931,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddForm),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddForm,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddForm,
+- (ndr_print_function_t) ndr_print_spoolss_AddForm,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32940,7 +32940,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeleteForm),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeleteForm,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeleteForm,
+- (ndr_print_function_t) ndr_print_spoolss_DeleteForm,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32949,7 +32949,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetForm),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetForm,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetForm,
+- (ndr_print_function_t) ndr_print_spoolss_GetForm,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32958,7 +32958,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_SetForm),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_SetForm,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_SetForm,
+- (ndr_print_function_t) ndr_print_spoolss_SetForm,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32967,7 +32967,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumForms),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumForms,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumForms,
+- (ndr_print_function_t) ndr_print_spoolss_EnumForms,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32976,7 +32976,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumPorts),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumPorts,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumPorts,
+- (ndr_print_function_t) ndr_print_spoolss_EnumPorts,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32985,7 +32985,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumMonitors),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumMonitors,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumMonitors,
+- (ndr_print_function_t) ndr_print_spoolss_EnumMonitors,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -32994,7 +32994,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPort),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPort,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPort,
+- (ndr_print_function_t) ndr_print_spoolss_AddPort,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33003,7 +33003,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_ConfigurePort),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_ConfigurePort,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_ConfigurePort,
+- (ndr_print_function_t) ndr_print_spoolss_ConfigurePort,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33012,7 +33012,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePort),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePort,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePort,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePort,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33021,7 +33021,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_CreatePrinterIC),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_CreatePrinterIC,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_CreatePrinterIC,
+- (ndr_print_function_t) ndr_print_spoolss_CreatePrinterIC,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33030,7 +33030,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_PlayGDIScriptOnPrinterIC),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_PlayGDIScriptOnPrinterIC,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_PlayGDIScriptOnPrinterIC,
+- (ndr_print_function_t) ndr_print_spoolss_PlayGDIScriptOnPrinterIC,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33039,7 +33039,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrinterIC),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrinterIC,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrinterIC,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrinterIC,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33048,7 +33048,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPrinterConnection),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPrinterConnection,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPrinterConnection,
+- (ndr_print_function_t) ndr_print_spoolss_AddPrinterConnection,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33057,7 +33057,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrinterConnection),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrinterConnection,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrinterConnection,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrinterConnection,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33066,7 +33066,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_PrinterMessageBox),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_PrinterMessageBox,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_PrinterMessageBox,
+- (ndr_print_function_t) ndr_print_spoolss_PrinterMessageBox,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33075,7 +33075,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddMonitor),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddMonitor,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddMonitor,
+- (ndr_print_function_t) ndr_print_spoolss_AddMonitor,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33084,7 +33084,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeleteMonitor),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeleteMonitor,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeleteMonitor,
+- (ndr_print_function_t) ndr_print_spoolss_DeleteMonitor,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33093,7 +33093,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrintProcessor),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrintProcessor,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrintProcessor,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrintProcessor,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33102,7 +33102,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPrintProvidor),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPrintProvidor,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPrintProvidor,
+- (ndr_print_function_t) ndr_print_spoolss_AddPrintProvidor,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33111,7 +33111,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrintProvidor),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrintProvidor,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrintProvidor,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrintProvidor,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33120,7 +33120,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumPrintProcDataTypes),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumPrintProcDataTypes,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumPrintProcDataTypes,
+- (ndr_print_function_t) ndr_print_spoolss_EnumPrintProcDataTypes,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33129,7 +33129,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_ResetPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_ResetPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_ResetPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_ResetPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33138,7 +33138,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetPrinterDriver2),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetPrinterDriver2,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetPrinterDriver2,
+- (ndr_print_function_t) ndr_print_spoolss_GetPrinterDriver2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33147,7 +33147,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_FindFirstPrinterChangeNotification),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_FindFirstPrinterChangeNotification,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_FindFirstPrinterChangeNotification,
+- (ndr_print_function_t) ndr_print_spoolss_FindFirstPrinterChangeNotification,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33156,7 +33156,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_FindNextPrinterChangeNotification),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_FindNextPrinterChangeNotification,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_FindNextPrinterChangeNotification,
+- (ndr_print_function_t) ndr_print_spoolss_FindNextPrinterChangeNotification,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33165,7 +33165,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_FindClosePrinterNotify),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_FindClosePrinterNotify,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_FindClosePrinterNotify,
+- (ndr_print_function_t) ndr_print_spoolss_FindClosePrinterNotify,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33174,7 +33174,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_RouterFindFirstPrinterChangeNotificationOld),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_RouterFindFirstPrinterChangeNotificationOld,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_RouterFindFirstPrinterChangeNotificationOld,
+- (ndr_print_function_t) ndr_print_spoolss_RouterFindFirstPrinterChangeNotificationOld,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33183,7 +33183,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_ReplyOpenPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_ReplyOpenPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_ReplyOpenPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_ReplyOpenPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33192,7 +33192,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_RouterReplyPrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_RouterReplyPrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_RouterReplyPrinter,
+- (ndr_print_function_t) ndr_print_spoolss_RouterReplyPrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33201,7 +33201,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_ReplyClosePrinter),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_ReplyClosePrinter,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_ReplyClosePrinter,
+- (ndr_print_function_t) ndr_print_spoolss_ReplyClosePrinter,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33210,7 +33210,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPortEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPortEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPortEx,
+- (ndr_print_function_t) ndr_print_spoolss_AddPortEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33219,7 +33219,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_RouterFindFirstPrinterChangeNotification),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_RouterFindFirstPrinterChangeNotification,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_RouterFindFirstPrinterChangeNotification,
+- (ndr_print_function_t) ndr_print_spoolss_RouterFindFirstPrinterChangeNotification,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33228,7 +33228,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_SpoolerInit),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_SpoolerInit,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_SpoolerInit,
+- (ndr_print_function_t) ndr_print_spoolss_SpoolerInit,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33237,7 +33237,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_ResetPrinterEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_ResetPrinterEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_ResetPrinterEx,
+- (ndr_print_function_t) ndr_print_spoolss_ResetPrinterEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33246,7 +33246,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_RemoteFindFirstPrinterChangeNotifyEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_RemoteFindFirstPrinterChangeNotifyEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_RemoteFindFirstPrinterChangeNotifyEx,
+- (ndr_print_function_t) ndr_print_spoolss_RemoteFindFirstPrinterChangeNotifyEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33255,7 +33255,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_RouterReplyPrinterEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_RouterReplyPrinterEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_RouterReplyPrinterEx,
+- (ndr_print_function_t) ndr_print_spoolss_RouterReplyPrinterEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33264,7 +33264,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_RouterRefreshPrinterChangeNotify),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_RouterRefreshPrinterChangeNotify,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_RouterRefreshPrinterChangeNotify,
+- (ndr_print_function_t) ndr_print_spoolss_RouterRefreshPrinterChangeNotify,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33273,7 +33273,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_44),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_44,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_44,
+- (ndr_print_function_t) ndr_print_spoolss_44,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33282,7 +33282,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_OpenPrinterEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_OpenPrinterEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_OpenPrinterEx,
+- (ndr_print_function_t) ndr_print_spoolss_OpenPrinterEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33291,7 +33291,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPrinterEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPrinterEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPrinterEx,
+- (ndr_print_function_t) ndr_print_spoolss_AddPrinterEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33300,7 +33300,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_SetPort),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_SetPort,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_SetPort,
+- (ndr_print_function_t) ndr_print_spoolss_SetPort,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33309,7 +33309,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumPrinterData),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumPrinterData,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumPrinterData,
+- (ndr_print_function_t) ndr_print_spoolss_EnumPrinterData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33318,7 +33318,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrinterData),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrinterData,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrinterData,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrinterData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33327,7 +33327,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_4a),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_4a,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_4a,
+- (ndr_print_function_t) ndr_print_spoolss_4a,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33336,7 +33336,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_4b),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_4b,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_4b,
+- (ndr_print_function_t) ndr_print_spoolss_4b,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33345,7 +33345,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_4c),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_4c,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_4c,
+- (ndr_print_function_t) ndr_print_spoolss_4c,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33354,7 +33354,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_SetPrinterDataEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_SetPrinterDataEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_SetPrinterDataEx,
+- (ndr_print_function_t) ndr_print_spoolss_SetPrinterDataEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33363,7 +33363,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetPrinterDataEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetPrinterDataEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetPrinterDataEx,
+- (ndr_print_function_t) ndr_print_spoolss_GetPrinterDataEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33372,7 +33372,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumPrinterDataEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumPrinterDataEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumPrinterDataEx,
+- (ndr_print_function_t) ndr_print_spoolss_EnumPrinterDataEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33381,7 +33381,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumPrinterKey),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumPrinterKey,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumPrinterKey,
+- (ndr_print_function_t) ndr_print_spoolss_EnumPrinterKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33390,7 +33390,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrinterDataEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrinterDataEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrinterDataEx,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrinterDataEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33399,7 +33399,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrinterKey),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrinterKey,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrinterKey,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrinterKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33408,7 +33408,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_53),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_53,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_53,
+- (ndr_print_function_t) ndr_print_spoolss_53,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33417,7 +33417,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePrinterDriverEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePrinterDriverEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePrinterDriverEx,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePrinterDriverEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33426,7 +33426,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPerMachineConnection),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPerMachineConnection,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPerMachineConnection,
+- (ndr_print_function_t) ndr_print_spoolss_AddPerMachineConnection,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33435,7 +33435,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_DeletePerMachineConnection),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_DeletePerMachineConnection,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeletePerMachineConnection,
+- (ndr_print_function_t) ndr_print_spoolss_DeletePerMachineConnection,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33444,7 +33444,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_EnumPerMachineConnections),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_EnumPerMachineConnections,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_EnumPerMachineConnections,
+- (ndr_print_function_t) ndr_print_spoolss_EnumPerMachineConnections,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33453,7 +33453,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_XcvData),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_XcvData,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_XcvData,
+- (ndr_print_function_t) ndr_print_spoolss_XcvData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33462,7 +33462,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_AddPrinterDriverEx),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_AddPrinterDriverEx,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_AddPrinterDriverEx,
+- (ndr_print_function_t) ndr_print_spoolss_AddPrinterDriverEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33471,7 +33471,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_5a),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_5a,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_5a,
+- (ndr_print_function_t) ndr_print_spoolss_5a,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33480,7 +33480,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_5b),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_5b,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_5b,
+- (ndr_print_function_t) ndr_print_spoolss_5b,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33489,7 +33489,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_5c),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_5c,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_5c,
+- (ndr_print_function_t) ndr_print_spoolss_5c,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33498,7 +33498,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_5d),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_5d,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_5d,
+- (ndr_print_function_t) ndr_print_spoolss_5d,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33507,7 +33507,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_5e),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_5e,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_5e,
+- (ndr_print_function_t) ndr_print_spoolss_5e,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33516,7 +33516,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_5f),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_5f,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_5f,
+- (ndr_print_function_t) ndr_print_spoolss_5f,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33525,7 +33525,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_60),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_60,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_60,
+- (ndr_print_function_t) ndr_print_spoolss_60,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33534,7 +33534,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_61),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_61,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_61,
+- (ndr_print_function_t) ndr_print_spoolss_61,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33543,7 +33543,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_62),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_62,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_62,
+- (ndr_print_function_t) ndr_print_spoolss_62,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33552,7 +33552,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_63),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_63,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_63,
+- (ndr_print_function_t) ndr_print_spoolss_63,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33561,7 +33561,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_64),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_64,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_64,
+- (ndr_print_function_t) ndr_print_spoolss_64,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33570,7 +33570,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_65),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_65,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_65,
+- (ndr_print_function_t) ndr_print_spoolss_65,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33579,7 +33579,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetCorePrinterDrivers),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetCorePrinterDrivers,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetCorePrinterDrivers,
+- (ndr_print_function_t) ndr_print_spoolss_GetCorePrinterDrivers,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33588,7 +33588,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_67),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_67,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_67,
+- (ndr_print_function_t) ndr_print_spoolss_67,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33597,7 +33597,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_GetPrinterDriverPackagePath),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_GetPrinterDriverPackagePath,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_GetPrinterDriverPackagePath,
+- (ndr_print_function_t) ndr_print_spoolss_GetPrinterDriverPackagePath,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33606,7 +33606,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_69),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_69,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_69,
+- (ndr_print_function_t) ndr_print_spoolss_69,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33615,7 +33615,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_6a),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_6a,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_6a,
+- (ndr_print_function_t) ndr_print_spoolss_6a,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33624,7 +33624,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_6b),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_6b,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_6b,
+- (ndr_print_function_t) ndr_print_spoolss_6b,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33633,7 +33633,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_6c),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_6c,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_6c,
+- (ndr_print_function_t) ndr_print_spoolss_6c,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -33642,7 +33642,7 @@ static const struct ndr_interface_call s
+ sizeof(struct spoolss_6d),
+ (ndr_push_flags_fn_t) ndr_push_spoolss_6d,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_6d,
+- (ndr_print_function_t) ndr_print_spoolss_6d,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_srvsvc.c
++++ b/source3/librpc/gen_ndr/ndr_srvsvc.c
+@@ -20229,7 +20229,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetCharDevEnum),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetCharDevEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetCharDevEnum,
+- (ndr_print_function_t) ndr_print_srvsvc_NetCharDevEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20238,7 +20238,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetCharDevGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetCharDevGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetCharDevGetInfo,
+- (ndr_print_function_t) ndr_print_srvsvc_NetCharDevGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20247,7 +20247,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetCharDevControl),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetCharDevControl,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetCharDevControl,
+- (ndr_print_function_t) ndr_print_srvsvc_NetCharDevControl,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20256,7 +20256,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetCharDevQEnum),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetCharDevQEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetCharDevQEnum,
+- (ndr_print_function_t) ndr_print_srvsvc_NetCharDevQEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20265,7 +20265,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetCharDevQGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetCharDevQGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetCharDevQGetInfo,
+- (ndr_print_function_t) ndr_print_srvsvc_NetCharDevQGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20274,7 +20274,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetCharDevQSetInfo),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetCharDevQSetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetCharDevQSetInfo,
+- (ndr_print_function_t) ndr_print_srvsvc_NetCharDevQSetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20283,7 +20283,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetCharDevQPurge),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetCharDevQPurge,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetCharDevQPurge,
+- (ndr_print_function_t) ndr_print_srvsvc_NetCharDevQPurge,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20292,7 +20292,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetCharDevQPurgeSelf),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetCharDevQPurgeSelf,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetCharDevQPurgeSelf,
+- (ndr_print_function_t) ndr_print_srvsvc_NetCharDevQPurgeSelf,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20301,7 +20301,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetConnEnum),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetConnEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetConnEnum,
+- (ndr_print_function_t) ndr_print_srvsvc_NetConnEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20310,7 +20310,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetFileEnum),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetFileEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetFileEnum,
+- (ndr_print_function_t) ndr_print_srvsvc_NetFileEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20319,7 +20319,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetFileGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetFileGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetFileGetInfo,
+- (ndr_print_function_t) ndr_print_srvsvc_NetFileGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20328,7 +20328,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetFileClose),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetFileClose,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetFileClose,
+- (ndr_print_function_t) ndr_print_srvsvc_NetFileClose,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20337,7 +20337,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetSessEnum),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetSessEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetSessEnum,
+- (ndr_print_function_t) ndr_print_srvsvc_NetSessEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20346,7 +20346,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetSessDel),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetSessDel,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetSessDel,
+- (ndr_print_function_t) ndr_print_srvsvc_NetSessDel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20355,7 +20355,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareAdd),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareAdd,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareAdd,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareAdd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20364,7 +20364,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareEnumAll),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareEnumAll,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareEnumAll,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareEnumAll,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20373,7 +20373,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareGetInfo,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20382,7 +20382,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareSetInfo),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareSetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareSetInfo,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareSetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20391,7 +20391,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareDel),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareDel,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareDel,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareDel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20400,7 +20400,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareDelSticky),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareDelSticky,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareDelSticky,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareDelSticky,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20409,7 +20409,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareCheck),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareCheck,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareCheck,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareCheck,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20418,7 +20418,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetSrvGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetSrvGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetSrvGetInfo,
+- (ndr_print_function_t) ndr_print_srvsvc_NetSrvGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20427,7 +20427,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetSrvSetInfo),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetSrvSetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetSrvSetInfo,
+- (ndr_print_function_t) ndr_print_srvsvc_NetSrvSetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20436,7 +20436,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetDiskEnum),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetDiskEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetDiskEnum,
+- (ndr_print_function_t) ndr_print_srvsvc_NetDiskEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20445,7 +20445,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetServerStatisticsGet),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetServerStatisticsGet,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetServerStatisticsGet,
+- (ndr_print_function_t) ndr_print_srvsvc_NetServerStatisticsGet,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20454,7 +20454,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetTransportAdd),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetTransportAdd,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetTransportAdd,
+- (ndr_print_function_t) ndr_print_srvsvc_NetTransportAdd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20463,7 +20463,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetTransportEnum),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetTransportEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetTransportEnum,
+- (ndr_print_function_t) ndr_print_srvsvc_NetTransportEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20472,7 +20472,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetTransportDel),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetTransportDel,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetTransportDel,
+- (ndr_print_function_t) ndr_print_srvsvc_NetTransportDel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20481,7 +20481,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetRemoteTOD),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetRemoteTOD,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetRemoteTOD,
+- (ndr_print_function_t) ndr_print_srvsvc_NetRemoteTOD,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20490,7 +20490,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetSetServiceBits),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetSetServiceBits,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetSetServiceBits,
+- (ndr_print_function_t) ndr_print_srvsvc_NetSetServiceBits,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20499,7 +20499,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetPathType),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetPathType,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetPathType,
+- (ndr_print_function_t) ndr_print_srvsvc_NetPathType,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20508,7 +20508,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetPathCanonicalize),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetPathCanonicalize,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetPathCanonicalize,
+- (ndr_print_function_t) ndr_print_srvsvc_NetPathCanonicalize,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20517,7 +20517,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetPathCompare),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetPathCompare,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetPathCompare,
+- (ndr_print_function_t) ndr_print_srvsvc_NetPathCompare,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20526,7 +20526,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetNameValidate),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetNameValidate,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetNameValidate,
+- (ndr_print_function_t) ndr_print_srvsvc_NetNameValidate,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20535,7 +20535,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRPRNAMECANONICALIZE),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRPRNAMECANONICALIZE,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRPRNAMECANONICALIZE,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRPRNAMECANONICALIZE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20544,7 +20544,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetPRNameCompare),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetPRNameCompare,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetPRNameCompare,
+- (ndr_print_function_t) ndr_print_srvsvc_NetPRNameCompare,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20553,7 +20553,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareEnum),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareEnum,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20562,7 +20562,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareDelStart),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareDelStart,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareDelStart,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareDelStart,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20571,7 +20571,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetShareDelCommit),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetShareDelCommit,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetShareDelCommit,
+- (ndr_print_function_t) ndr_print_srvsvc_NetShareDelCommit,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20580,7 +20580,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetGetFileSecurity),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetGetFileSecurity,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetGetFileSecurity,
+- (ndr_print_function_t) ndr_print_srvsvc_NetGetFileSecurity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20589,7 +20589,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetSetFileSecurity),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetSetFileSecurity,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetSetFileSecurity,
+- (ndr_print_function_t) ndr_print_srvsvc_NetSetFileSecurity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20598,7 +20598,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetServerTransportAddEx),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetServerTransportAddEx,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetServerTransportAddEx,
+- (ndr_print_function_t) ndr_print_srvsvc_NetServerTransportAddEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20607,7 +20607,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NetServerSetServiceBitsEx),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NetServerSetServiceBitsEx,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NetServerSetServiceBitsEx,
+- (ndr_print_function_t) ndr_print_srvsvc_NetServerSetServiceBitsEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20616,7 +20616,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSGETVERSION),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSGETVERSION,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSGETVERSION,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSGETVERSION,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20625,7 +20625,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSCREATELOCALPARTITION),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSCREATELOCALPARTITION,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSCREATELOCALPARTITION,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSCREATELOCALPARTITION,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20634,7 +20634,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSDELETELOCALPARTITION),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSDELETELOCALPARTITION,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSDELETELOCALPARTITION,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSDELETELOCALPARTITION,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20643,7 +20643,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSSETLOCALVOLUMESTATE),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSSETLOCALVOLUMESTATE,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSSETLOCALVOLUMESTATE,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSSETLOCALVOLUMESTATE,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20652,7 +20652,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSSETSERVERINFO),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSSETSERVERINFO,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSSETSERVERINFO,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSSETSERVERINFO,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20661,7 +20661,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSCREATEEXITPOINT),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSCREATEEXITPOINT,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSCREATEEXITPOINT,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSCREATEEXITPOINT,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20670,7 +20670,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSDELETEEXITPOINT),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSDELETEEXITPOINT,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSDELETEEXITPOINT,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSDELETEEXITPOINT,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20679,7 +20679,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSMODIFYPREFIX),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSMODIFYPREFIX,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSMODIFYPREFIX,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSMODIFYPREFIX,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20688,7 +20688,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSFIXLOCALVOLUME),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSFIXLOCALVOLUME,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSFIXLOCALVOLUME,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSFIXLOCALVOLUME,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20697,7 +20697,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRDFSMANAGERREPORTSITEINFO),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRDFSMANAGERREPORTSITEINFO,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRDFSMANAGERREPORTSITEINFO,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRDFSMANAGERREPORTSITEINFO,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -20706,7 +20706,7 @@ static const struct ndr_interface_call s
+ sizeof(struct srvsvc_NETRSERVERTRANSPORTDELEX),
+ (ndr_push_flags_fn_t) ndr_push_srvsvc_NETRSERVERTRANSPORTDELEX,
+ (ndr_pull_flags_fn_t) ndr_pull_srvsvc_NETRSERVERTRANSPORTDELEX,
+- (ndr_print_function_t) ndr_print_srvsvc_NETRSERVERTRANSPORTDELEX,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_svcctl.c
++++ b/source3/librpc/gen_ndr/ndr_svcctl.c
+@@ -7175,7 +7175,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_CloseServiceHandle),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_CloseServiceHandle,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_CloseServiceHandle,
+- (ndr_print_function_t) ndr_print_svcctl_CloseServiceHandle,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7184,7 +7184,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_ControlService),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_ControlService,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_ControlService,
+- (ndr_print_function_t) ndr_print_svcctl_ControlService,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7193,7 +7193,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_DeleteService),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_DeleteService,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_DeleteService,
+- (ndr_print_function_t) ndr_print_svcctl_DeleteService,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7202,7 +7202,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_LockServiceDatabase),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_LockServiceDatabase,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_LockServiceDatabase,
+- (ndr_print_function_t) ndr_print_svcctl_LockServiceDatabase,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7211,7 +7211,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_QueryServiceObjectSecurity),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_QueryServiceObjectSecurity,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_QueryServiceObjectSecurity,
+- (ndr_print_function_t) ndr_print_svcctl_QueryServiceObjectSecurity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7220,7 +7220,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_SetServiceObjectSecurity),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_SetServiceObjectSecurity,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_SetServiceObjectSecurity,
+- (ndr_print_function_t) ndr_print_svcctl_SetServiceObjectSecurity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7229,7 +7229,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_QueryServiceStatus),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_QueryServiceStatus,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_QueryServiceStatus,
+- (ndr_print_function_t) ndr_print_svcctl_QueryServiceStatus,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7238,7 +7238,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_SetServiceStatus),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_SetServiceStatus,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_SetServiceStatus,
+- (ndr_print_function_t) ndr_print_svcctl_SetServiceStatus,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7247,7 +7247,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_UnlockServiceDatabase),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_UnlockServiceDatabase,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_UnlockServiceDatabase,
+- (ndr_print_function_t) ndr_print_svcctl_UnlockServiceDatabase,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7256,7 +7256,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_NotifyBootConfigStatus),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_NotifyBootConfigStatus,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_NotifyBootConfigStatus,
+- (ndr_print_function_t) ndr_print_svcctl_NotifyBootConfigStatus,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7265,7 +7265,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_SCSetServiceBitsW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_SCSetServiceBitsW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_SCSetServiceBitsW,
+- (ndr_print_function_t) ndr_print_svcctl_SCSetServiceBitsW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7274,7 +7274,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_ChangeServiceConfigW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_ChangeServiceConfigW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_ChangeServiceConfigW,
+- (ndr_print_function_t) ndr_print_svcctl_ChangeServiceConfigW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7283,7 +7283,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_CreateServiceW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_CreateServiceW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_CreateServiceW,
+- (ndr_print_function_t) ndr_print_svcctl_CreateServiceW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7292,7 +7292,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_EnumDependentServicesW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_EnumDependentServicesW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_EnumDependentServicesW,
+- (ndr_print_function_t) ndr_print_svcctl_EnumDependentServicesW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7301,7 +7301,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_EnumServicesStatusW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_EnumServicesStatusW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_EnumServicesStatusW,
+- (ndr_print_function_t) ndr_print_svcctl_EnumServicesStatusW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7310,7 +7310,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_OpenSCManagerW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_OpenSCManagerW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_OpenSCManagerW,
+- (ndr_print_function_t) ndr_print_svcctl_OpenSCManagerW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7319,7 +7319,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_OpenServiceW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_OpenServiceW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_OpenServiceW,
+- (ndr_print_function_t) ndr_print_svcctl_OpenServiceW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7328,7 +7328,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_QueryServiceConfigW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_QueryServiceConfigW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_QueryServiceConfigW,
+- (ndr_print_function_t) ndr_print_svcctl_QueryServiceConfigW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7337,7 +7337,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_QueryServiceLockStatusW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_QueryServiceLockStatusW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_QueryServiceLockStatusW,
+- (ndr_print_function_t) ndr_print_svcctl_QueryServiceLockStatusW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7346,7 +7346,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_StartServiceW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_StartServiceW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_StartServiceW,
+- (ndr_print_function_t) ndr_print_svcctl_StartServiceW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7355,7 +7355,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_GetServiceDisplayNameW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_GetServiceDisplayNameW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_GetServiceDisplayNameW,
+- (ndr_print_function_t) ndr_print_svcctl_GetServiceDisplayNameW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7364,7 +7364,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_GetServiceKeyNameW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_GetServiceKeyNameW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_GetServiceKeyNameW,
+- (ndr_print_function_t) ndr_print_svcctl_GetServiceKeyNameW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7373,7 +7373,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_SCSetServiceBitsA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_SCSetServiceBitsA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_SCSetServiceBitsA,
+- (ndr_print_function_t) ndr_print_svcctl_SCSetServiceBitsA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7382,7 +7382,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_ChangeServiceConfigA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_ChangeServiceConfigA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_ChangeServiceConfigA,
+- (ndr_print_function_t) ndr_print_svcctl_ChangeServiceConfigA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7391,7 +7391,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_CreateServiceA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_CreateServiceA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_CreateServiceA,
+- (ndr_print_function_t) ndr_print_svcctl_CreateServiceA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7400,7 +7400,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_EnumDependentServicesA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_EnumDependentServicesA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_EnumDependentServicesA,
+- (ndr_print_function_t) ndr_print_svcctl_EnumDependentServicesA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7409,7 +7409,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_EnumServicesStatusA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_EnumServicesStatusA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_EnumServicesStatusA,
+- (ndr_print_function_t) ndr_print_svcctl_EnumServicesStatusA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7418,7 +7418,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_OpenSCManagerA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_OpenSCManagerA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_OpenSCManagerA,
+- (ndr_print_function_t) ndr_print_svcctl_OpenSCManagerA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7427,7 +7427,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_OpenServiceA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_OpenServiceA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_OpenServiceA,
+- (ndr_print_function_t) ndr_print_svcctl_OpenServiceA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7436,7 +7436,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_QueryServiceConfigA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_QueryServiceConfigA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_QueryServiceConfigA,
+- (ndr_print_function_t) ndr_print_svcctl_QueryServiceConfigA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7445,7 +7445,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_QueryServiceLockStatusA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_QueryServiceLockStatusA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_QueryServiceLockStatusA,
+- (ndr_print_function_t) ndr_print_svcctl_QueryServiceLockStatusA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7454,7 +7454,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_StartServiceA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_StartServiceA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_StartServiceA,
+- (ndr_print_function_t) ndr_print_svcctl_StartServiceA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7463,7 +7463,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_GetServiceDisplayNameA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_GetServiceDisplayNameA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_GetServiceDisplayNameA,
+- (ndr_print_function_t) ndr_print_svcctl_GetServiceDisplayNameA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7472,7 +7472,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_GetServiceKeyNameA),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_GetServiceKeyNameA,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_GetServiceKeyNameA,
+- (ndr_print_function_t) ndr_print_svcctl_GetServiceKeyNameA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7481,7 +7481,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_GetCurrentGroupeStateW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_GetCurrentGroupeStateW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_GetCurrentGroupeStateW,
+- (ndr_print_function_t) ndr_print_svcctl_GetCurrentGroupeStateW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7490,7 +7490,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_EnumServiceGroupW),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_EnumServiceGroupW,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_EnumServiceGroupW,
+- (ndr_print_function_t) ndr_print_svcctl_EnumServiceGroupW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7499,7 +7499,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_ChangeServiceConfig2A),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_ChangeServiceConfig2A,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_ChangeServiceConfig2A,
+- (ndr_print_function_t) ndr_print_svcctl_ChangeServiceConfig2A,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7508,7 +7508,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_ChangeServiceConfig2W),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_ChangeServiceConfig2W,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_ChangeServiceConfig2W,
+- (ndr_print_function_t) ndr_print_svcctl_ChangeServiceConfig2W,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7517,7 +7517,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_QueryServiceConfig2A),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_QueryServiceConfig2A,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_QueryServiceConfig2A,
+- (ndr_print_function_t) ndr_print_svcctl_QueryServiceConfig2A,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7526,7 +7526,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_QueryServiceConfig2W),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_QueryServiceConfig2W,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_QueryServiceConfig2W,
+- (ndr_print_function_t) ndr_print_svcctl_QueryServiceConfig2W,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7535,7 +7535,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_QueryServiceStatusEx),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_QueryServiceStatusEx,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_QueryServiceStatusEx,
+- (ndr_print_function_t) ndr_print_svcctl_QueryServiceStatusEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7544,7 +7544,7 @@ static const struct ndr_interface_call s
+ sizeof(struct EnumServicesStatusExA),
+ (ndr_push_flags_fn_t) ndr_push_EnumServicesStatusExA,
+ (ndr_pull_flags_fn_t) ndr_pull_EnumServicesStatusExA,
+- (ndr_print_function_t) ndr_print_EnumServicesStatusExA,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7553,7 +7553,7 @@ static const struct ndr_interface_call s
+ sizeof(struct EnumServicesStatusExW),
+ (ndr_push_flags_fn_t) ndr_push_EnumServicesStatusExW,
+ (ndr_pull_flags_fn_t) ndr_pull_EnumServicesStatusExW,
+- (ndr_print_function_t) ndr_print_EnumServicesStatusExW,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7562,7 +7562,7 @@ static const struct ndr_interface_call s
+ sizeof(struct svcctl_SCSendTSMessage),
+ (ndr_push_flags_fn_t) ndr_push_svcctl_SCSendTSMessage,
+ (ndr_pull_flags_fn_t) ndr_pull_svcctl_SCSendTSMessage,
+- (ndr_print_function_t) ndr_print_svcctl_SCSendTSMessage,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_trkwks.c
++++ b/source3/librpc/gen_ndr/ndr_trkwks.c
+@@ -51,7 +51,7 @@ static const struct ndr_interface_call t
+ sizeof(struct trkwks_Unknown0),
+ (ndr_push_flags_fn_t) ndr_push_trkwks_Unknown0,
+ (ndr_pull_flags_fn_t) ndr_pull_trkwks_Unknown0,
+- (ndr_print_function_t) ndr_print_trkwks_Unknown0,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_unixinfo.c
++++ b/source3/librpc/gen_ndr/ndr_unixinfo.c
+@@ -472,7 +472,7 @@ static const struct ndr_interface_call u
+ sizeof(struct unixinfo_SidToUid),
+ (ndr_push_flags_fn_t) ndr_push_unixinfo_SidToUid,
+ (ndr_pull_flags_fn_t) ndr_pull_unixinfo_SidToUid,
+- (ndr_print_function_t) ndr_print_unixinfo_SidToUid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -481,7 +481,7 @@ static const struct ndr_interface_call u
+ sizeof(struct unixinfo_UidToSid),
+ (ndr_push_flags_fn_t) ndr_push_unixinfo_UidToSid,
+ (ndr_pull_flags_fn_t) ndr_pull_unixinfo_UidToSid,
+- (ndr_print_function_t) ndr_print_unixinfo_UidToSid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -490,7 +490,7 @@ static const struct ndr_interface_call u
+ sizeof(struct unixinfo_SidToGid),
+ (ndr_push_flags_fn_t) ndr_push_unixinfo_SidToGid,
+ (ndr_pull_flags_fn_t) ndr_pull_unixinfo_SidToGid,
+- (ndr_print_function_t) ndr_print_unixinfo_SidToGid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -499,7 +499,7 @@ static const struct ndr_interface_call u
+ sizeof(struct unixinfo_GidToSid),
+ (ndr_push_flags_fn_t) ndr_push_unixinfo_GidToSid,
+ (ndr_pull_flags_fn_t) ndr_pull_unixinfo_GidToSid,
+- (ndr_print_function_t) ndr_print_unixinfo_GidToSid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -508,7 +508,7 @@ static const struct ndr_interface_call u
+ sizeof(struct unixinfo_GetPWUid),
+ (ndr_push_flags_fn_t) ndr_push_unixinfo_GetPWUid,
+ (ndr_pull_flags_fn_t) ndr_pull_unixinfo_GetPWUid,
+- (ndr_print_function_t) ndr_print_unixinfo_GetPWUid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_w32time.c
++++ b/source3/librpc/gen_ndr/ndr_w32time.c
+@@ -135,7 +135,7 @@ static const struct ndr_interface_call w
+ sizeof(struct w32time_SyncTime),
+ (ndr_push_flags_fn_t) ndr_push_w32time_SyncTime,
+ (ndr_pull_flags_fn_t) ndr_pull_w32time_SyncTime,
+- (ndr_print_function_t) ndr_print_w32time_SyncTime,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -144,7 +144,7 @@ static const struct ndr_interface_call w
+ sizeof(struct w32time_GetNetLogonServiceBits),
+ (ndr_push_flags_fn_t) ndr_push_w32time_GetNetLogonServiceBits,
+ (ndr_pull_flags_fn_t) ndr_pull_w32time_GetNetLogonServiceBits,
+- (ndr_print_function_t) ndr_print_w32time_GetNetLogonServiceBits,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -153,7 +153,7 @@ static const struct ndr_interface_call w
+ sizeof(struct w32time_QueryProviderStatus),
+ (ndr_push_flags_fn_t) ndr_push_w32time_QueryProviderStatus,
+ (ndr_pull_flags_fn_t) ndr_pull_w32time_QueryProviderStatus,
+- (ndr_print_function_t) ndr_print_w32time_QueryProviderStatus,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_wbint.c
++++ b/source3/librpc/gen_ndr/ndr_wbint.c
+@@ -2696,7 +2696,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_Ping),
+ (ndr_push_flags_fn_t) ndr_push_wbint_Ping,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_Ping,
+- (ndr_print_function_t) ndr_print_wbint_Ping,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2705,7 +2705,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_LookupSid),
+ (ndr_push_flags_fn_t) ndr_push_wbint_LookupSid,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_LookupSid,
+- (ndr_print_function_t) ndr_print_wbint_LookupSid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2714,7 +2714,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_LookupSids),
+ (ndr_push_flags_fn_t) ndr_push_wbint_LookupSids,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_LookupSids,
+- (ndr_print_function_t) ndr_print_wbint_LookupSids,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2723,7 +2723,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_LookupName),
+ (ndr_push_flags_fn_t) ndr_push_wbint_LookupName,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_LookupName,
+- (ndr_print_function_t) ndr_print_wbint_LookupName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2732,7 +2732,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_Sid2Uid),
+ (ndr_push_flags_fn_t) ndr_push_wbint_Sid2Uid,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_Sid2Uid,
+- (ndr_print_function_t) ndr_print_wbint_Sid2Uid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2741,7 +2741,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_Sid2Gid),
+ (ndr_push_flags_fn_t) ndr_push_wbint_Sid2Gid,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_Sid2Gid,
+- (ndr_print_function_t) ndr_print_wbint_Sid2Gid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2750,7 +2750,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_Sids2UnixIDs),
+ (ndr_push_flags_fn_t) ndr_push_wbint_Sids2UnixIDs,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_Sids2UnixIDs,
+- (ndr_print_function_t) ndr_print_wbint_Sids2UnixIDs,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2759,7 +2759,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_Uid2Sid),
+ (ndr_push_flags_fn_t) ndr_push_wbint_Uid2Sid,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_Uid2Sid,
+- (ndr_print_function_t) ndr_print_wbint_Uid2Sid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2768,7 +2768,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_Gid2Sid),
+ (ndr_push_flags_fn_t) ndr_push_wbint_Gid2Sid,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_Gid2Sid,
+- (ndr_print_function_t) ndr_print_wbint_Gid2Sid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2777,7 +2777,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_AllocateUid),
+ (ndr_push_flags_fn_t) ndr_push_wbint_AllocateUid,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_AllocateUid,
+- (ndr_print_function_t) ndr_print_wbint_AllocateUid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2786,7 +2786,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_AllocateGid),
+ (ndr_push_flags_fn_t) ndr_push_wbint_AllocateGid,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_AllocateGid,
+- (ndr_print_function_t) ndr_print_wbint_AllocateGid,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2795,7 +2795,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_QueryUser),
+ (ndr_push_flags_fn_t) ndr_push_wbint_QueryUser,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_QueryUser,
+- (ndr_print_function_t) ndr_print_wbint_QueryUser,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2804,7 +2804,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_LookupUserAliases),
+ (ndr_push_flags_fn_t) ndr_push_wbint_LookupUserAliases,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_LookupUserAliases,
+- (ndr_print_function_t) ndr_print_wbint_LookupUserAliases,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2813,7 +2813,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_LookupUserGroups),
+ (ndr_push_flags_fn_t) ndr_push_wbint_LookupUserGroups,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_LookupUserGroups,
+- (ndr_print_function_t) ndr_print_wbint_LookupUserGroups,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2822,7 +2822,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_QuerySequenceNumber),
+ (ndr_push_flags_fn_t) ndr_push_wbint_QuerySequenceNumber,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_QuerySequenceNumber,
+- (ndr_print_function_t) ndr_print_wbint_QuerySequenceNumber,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2831,7 +2831,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_LookupGroupMembers),
+ (ndr_push_flags_fn_t) ndr_push_wbint_LookupGroupMembers,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_LookupGroupMembers,
+- (ndr_print_function_t) ndr_print_wbint_LookupGroupMembers,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2840,7 +2840,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_QueryUserList),
+ (ndr_push_flags_fn_t) ndr_push_wbint_QueryUserList,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_QueryUserList,
+- (ndr_print_function_t) ndr_print_wbint_QueryUserList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2849,7 +2849,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_QueryGroupList),
+ (ndr_push_flags_fn_t) ndr_push_wbint_QueryGroupList,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_QueryGroupList,
+- (ndr_print_function_t) ndr_print_wbint_QueryGroupList,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2858,7 +2858,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_DsGetDcName),
+ (ndr_push_flags_fn_t) ndr_push_wbint_DsGetDcName,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_DsGetDcName,
+- (ndr_print_function_t) ndr_print_wbint_DsGetDcName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2867,7 +2867,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_LookupRids),
+ (ndr_push_flags_fn_t) ndr_push_wbint_LookupRids,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_LookupRids,
+- (ndr_print_function_t) ndr_print_wbint_LookupRids,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2876,7 +2876,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_CheckMachineAccount),
+ (ndr_push_flags_fn_t) ndr_push_wbint_CheckMachineAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_CheckMachineAccount,
+- (ndr_print_function_t) ndr_print_wbint_CheckMachineAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2885,7 +2885,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_ChangeMachineAccount),
+ (ndr_push_flags_fn_t) ndr_push_wbint_ChangeMachineAccount,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_ChangeMachineAccount,
+- (ndr_print_function_t) ndr_print_wbint_ChangeMachineAccount,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -2894,7 +2894,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wbint_PingDc),
+ (ndr_push_flags_fn_t) ndr_push_wbint_PingDc,
+ (ndr_pull_flags_fn_t) ndr_pull_wbint_PingDc,
+- (ndr_print_function_t) ndr_print_wbint_PingDc,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_winreg.c
++++ b/source3/librpc/gen_ndr/ndr_winreg.c
+@@ -4864,7 +4864,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenHKCR),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenHKCR,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenHKCR,
+- (ndr_print_function_t) ndr_print_winreg_OpenHKCR,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4873,7 +4873,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenHKCU),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenHKCU,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenHKCU,
+- (ndr_print_function_t) ndr_print_winreg_OpenHKCU,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4882,7 +4882,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenHKLM),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenHKLM,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenHKLM,
+- (ndr_print_function_t) ndr_print_winreg_OpenHKLM,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4891,7 +4891,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenHKPD),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenHKPD,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenHKPD,
+- (ndr_print_function_t) ndr_print_winreg_OpenHKPD,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4900,7 +4900,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenHKU),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenHKU,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenHKU,
+- (ndr_print_function_t) ndr_print_winreg_OpenHKU,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4909,7 +4909,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_CloseKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_CloseKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_CloseKey,
+- (ndr_print_function_t) ndr_print_winreg_CloseKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4918,7 +4918,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_CreateKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_CreateKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_CreateKey,
+- (ndr_print_function_t) ndr_print_winreg_CreateKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4927,7 +4927,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_DeleteKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_DeleteKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_DeleteKey,
+- (ndr_print_function_t) ndr_print_winreg_DeleteKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4936,7 +4936,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_DeleteValue),
+ (ndr_push_flags_fn_t) ndr_push_winreg_DeleteValue,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_DeleteValue,
+- (ndr_print_function_t) ndr_print_winreg_DeleteValue,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4945,7 +4945,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_EnumKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_EnumKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_EnumKey,
+- (ndr_print_function_t) ndr_print_winreg_EnumKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4954,7 +4954,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_EnumValue),
+ (ndr_push_flags_fn_t) ndr_push_winreg_EnumValue,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_EnumValue,
+- (ndr_print_function_t) ndr_print_winreg_EnumValue,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4963,7 +4963,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_FlushKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_FlushKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_FlushKey,
+- (ndr_print_function_t) ndr_print_winreg_FlushKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4972,7 +4972,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_GetKeySecurity),
+ (ndr_push_flags_fn_t) ndr_push_winreg_GetKeySecurity,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_GetKeySecurity,
+- (ndr_print_function_t) ndr_print_winreg_GetKeySecurity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4981,7 +4981,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_LoadKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_LoadKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_LoadKey,
+- (ndr_print_function_t) ndr_print_winreg_LoadKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4990,7 +4990,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_NotifyChangeKeyValue),
+ (ndr_push_flags_fn_t) ndr_push_winreg_NotifyChangeKeyValue,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_NotifyChangeKeyValue,
+- (ndr_print_function_t) ndr_print_winreg_NotifyChangeKeyValue,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4999,7 +4999,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenKey,
+- (ndr_print_function_t) ndr_print_winreg_OpenKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5008,7 +5008,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_QueryInfoKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_QueryInfoKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_QueryInfoKey,
+- (ndr_print_function_t) ndr_print_winreg_QueryInfoKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5017,7 +5017,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_QueryValue),
+ (ndr_push_flags_fn_t) ndr_push_winreg_QueryValue,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_QueryValue,
+- (ndr_print_function_t) ndr_print_winreg_QueryValue,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5026,7 +5026,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_ReplaceKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_ReplaceKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_ReplaceKey,
+- (ndr_print_function_t) ndr_print_winreg_ReplaceKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5035,7 +5035,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_RestoreKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_RestoreKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_RestoreKey,
+- (ndr_print_function_t) ndr_print_winreg_RestoreKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5044,7 +5044,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_SaveKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_SaveKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_SaveKey,
+- (ndr_print_function_t) ndr_print_winreg_SaveKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5053,7 +5053,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_SetKeySecurity),
+ (ndr_push_flags_fn_t) ndr_push_winreg_SetKeySecurity,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_SetKeySecurity,
+- (ndr_print_function_t) ndr_print_winreg_SetKeySecurity,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5062,7 +5062,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_SetValue),
+ (ndr_push_flags_fn_t) ndr_push_winreg_SetValue,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_SetValue,
+- (ndr_print_function_t) ndr_print_winreg_SetValue,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5071,7 +5071,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_UnLoadKey),
+ (ndr_push_flags_fn_t) ndr_push_winreg_UnLoadKey,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_UnLoadKey,
+- (ndr_print_function_t) ndr_print_winreg_UnLoadKey,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5080,7 +5080,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_InitiateSystemShutdown),
+ (ndr_push_flags_fn_t) ndr_push_winreg_InitiateSystemShutdown,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_InitiateSystemShutdown,
+- (ndr_print_function_t) ndr_print_winreg_InitiateSystemShutdown,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5089,7 +5089,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_AbortSystemShutdown),
+ (ndr_push_flags_fn_t) ndr_push_winreg_AbortSystemShutdown,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_AbortSystemShutdown,
+- (ndr_print_function_t) ndr_print_winreg_AbortSystemShutdown,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5098,7 +5098,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_GetVersion),
+ (ndr_push_flags_fn_t) ndr_push_winreg_GetVersion,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_GetVersion,
+- (ndr_print_function_t) ndr_print_winreg_GetVersion,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5107,7 +5107,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenHKCC),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenHKCC,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenHKCC,
+- (ndr_print_function_t) ndr_print_winreg_OpenHKCC,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5116,7 +5116,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenHKDD),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenHKDD,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenHKDD,
+- (ndr_print_function_t) ndr_print_winreg_OpenHKDD,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5125,7 +5125,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_QueryMultipleValues),
+ (ndr_push_flags_fn_t) ndr_push_winreg_QueryMultipleValues,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_QueryMultipleValues,
+- (ndr_print_function_t) ndr_print_winreg_QueryMultipleValues,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5134,7 +5134,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_InitiateSystemShutdownEx),
+ (ndr_push_flags_fn_t) ndr_push_winreg_InitiateSystemShutdownEx,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_InitiateSystemShutdownEx,
+- (ndr_print_function_t) ndr_print_winreg_InitiateSystemShutdownEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5143,7 +5143,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_SaveKeyEx),
+ (ndr_push_flags_fn_t) ndr_push_winreg_SaveKeyEx,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_SaveKeyEx,
+- (ndr_print_function_t) ndr_print_winreg_SaveKeyEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5152,7 +5152,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenHKPT),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenHKPT,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenHKPT,
+- (ndr_print_function_t) ndr_print_winreg_OpenHKPT,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5161,7 +5161,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_OpenHKPN),
+ (ndr_push_flags_fn_t) ndr_push_winreg_OpenHKPN,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_OpenHKPN,
+- (ndr_print_function_t) ndr_print_winreg_OpenHKPN,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5170,7 +5170,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_QueryMultipleValues2),
+ (ndr_push_flags_fn_t) ndr_push_winreg_QueryMultipleValues2,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_QueryMultipleValues2,
+- (ndr_print_function_t) ndr_print_winreg_QueryMultipleValues2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5179,7 +5179,7 @@ static const struct ndr_interface_call w
+ sizeof(struct winreg_DeleteKeyEx),
+ (ndr_push_flags_fn_t) ndr_push_winreg_DeleteKeyEx,
+ (ndr_pull_flags_fn_t) ndr_pull_winreg_DeleteKeyEx,
+- (ndr_print_function_t) ndr_print_winreg_DeleteKeyEx,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_wkssvc.c
++++ b/source3/librpc/gen_ndr/ndr_wkssvc.c
+@@ -11005,7 +11005,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetWkstaGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetWkstaGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetWkstaGetInfo,
+- (ndr_print_function_t) ndr_print_wkssvc_NetWkstaGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11014,7 +11014,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetWkstaSetInfo),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetWkstaSetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetWkstaSetInfo,
+- (ndr_print_function_t) ndr_print_wkssvc_NetWkstaSetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11023,7 +11023,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetWkstaEnumUsers),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetWkstaEnumUsers,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetWkstaEnumUsers,
+- (ndr_print_function_t) ndr_print_wkssvc_NetWkstaEnumUsers,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11032,7 +11032,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrWkstaUserGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrWkstaUserGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrWkstaUserGetInfo,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrWkstaUserGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11041,7 +11041,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrWkstaUserSetInfo),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrWkstaUserSetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrWkstaUserSetInfo,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrWkstaUserSetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11050,7 +11050,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetWkstaTransportEnum),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetWkstaTransportEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetWkstaTransportEnum,
+- (ndr_print_function_t) ndr_print_wkssvc_NetWkstaTransportEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11059,7 +11059,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrWkstaTransportAdd),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrWkstaTransportAdd,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrWkstaTransportAdd,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrWkstaTransportAdd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11068,7 +11068,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrWkstaTransportDel),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrWkstaTransportDel,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrWkstaTransportDel,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrWkstaTransportDel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11077,7 +11077,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrUseAdd),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrUseAdd,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrUseAdd,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrUseAdd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11086,7 +11086,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrUseGetInfo),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrUseGetInfo,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrUseGetInfo,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrUseGetInfo,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11095,7 +11095,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrUseDel),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrUseDel,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrUseDel,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrUseDel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11104,7 +11104,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrUseEnum),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrUseEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrUseEnum,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrUseEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11113,7 +11113,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrMessageBufferSend),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrMessageBufferSend,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrMessageBufferSend,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrMessageBufferSend,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11122,7 +11122,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrWorkstationStatisticsGet),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrWorkstationStatisticsGet,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrWorkstationStatisticsGet,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrWorkstationStatisticsGet,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11131,7 +11131,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrLogonDomainNameAdd),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrLogonDomainNameAdd,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrLogonDomainNameAdd,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrLogonDomainNameAdd,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11140,7 +11140,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrLogonDomainNameDel),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrLogonDomainNameDel,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrLogonDomainNameDel,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrLogonDomainNameDel,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11149,7 +11149,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrJoinDomain),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrJoinDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrJoinDomain,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrJoinDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11158,7 +11158,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrUnjoinDomain),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrUnjoinDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrUnjoinDomain,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrUnjoinDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11167,7 +11167,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrRenameMachineInDomain),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrRenameMachineInDomain,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrRenameMachineInDomain,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrRenameMachineInDomain,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11176,7 +11176,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrValidateName),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrValidateName,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrValidateName,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrValidateName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11185,7 +11185,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrGetJoinInformation),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrGetJoinInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrGetJoinInformation,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrGetJoinInformation,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11194,7 +11194,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrGetJoinableOus),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrGetJoinableOus,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrGetJoinableOus,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrGetJoinableOus,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11203,7 +11203,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrJoinDomain2),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrJoinDomain2,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrJoinDomain2,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrJoinDomain2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11212,7 +11212,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrUnjoinDomain2),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrUnjoinDomain2,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrUnjoinDomain2,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrUnjoinDomain2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11221,7 +11221,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrRenameMachineInDomain2),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrRenameMachineInDomain2,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrRenameMachineInDomain2,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrRenameMachineInDomain2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11230,7 +11230,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrValidateName2),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrValidateName2,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrValidateName2,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrValidateName2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11239,7 +11239,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrGetJoinableOus2),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrGetJoinableOus2,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrGetJoinableOus2,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrGetJoinableOus2,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11248,7 +11248,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrAddAlternateComputerName),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrAddAlternateComputerName,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrAddAlternateComputerName,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrAddAlternateComputerName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11257,7 +11257,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrRemoveAlternateComputerName),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrRemoveAlternateComputerName,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrRemoveAlternateComputerName,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrRemoveAlternateComputerName,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11266,7 +11266,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrSetPrimaryComputername),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrSetPrimaryComputername,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrSetPrimaryComputername,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrSetPrimaryComputername,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -11275,7 +11275,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wkssvc_NetrEnumerateComputerNames),
+ (ndr_push_flags_fn_t) ndr_push_wkssvc_NetrEnumerateComputerNames,
+ (ndr_pull_flags_fn_t) ndr_pull_wkssvc_NetrEnumerateComputerNames,
+- (ndr_print_function_t) ndr_print_wkssvc_NetrEnumerateComputerNames,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_wmi.c
++++ b/source3/librpc/gen_ndr/ndr_wmi.c
+@@ -139,7 +139,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Delete),
+ (ndr_push_flags_fn_t) ndr_push_Delete,
+ (ndr_pull_flags_fn_t) ndr_pull_Delete,
+- (ndr_print_function_t) ndr_print_Delete,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3704,7 +3704,7 @@ static const struct ndr_interface_call I
+ sizeof(struct OpenNamespace),
+ (ndr_push_flags_fn_t) ndr_push_OpenNamespace,
+ (ndr_pull_flags_fn_t) ndr_pull_OpenNamespace,
+- (ndr_print_function_t) ndr_print_OpenNamespace,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3713,7 +3713,7 @@ static const struct ndr_interface_call I
+ sizeof(struct CancelAsyncCall),
+ (ndr_push_flags_fn_t) ndr_push_CancelAsyncCall,
+ (ndr_pull_flags_fn_t) ndr_pull_CancelAsyncCall,
+- (ndr_print_function_t) ndr_print_CancelAsyncCall,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3722,7 +3722,7 @@ static const struct ndr_interface_call I
+ sizeof(struct QueryObjectSink),
+ (ndr_push_flags_fn_t) ndr_push_QueryObjectSink,
+ (ndr_pull_flags_fn_t) ndr_pull_QueryObjectSink,
+- (ndr_print_function_t) ndr_print_QueryObjectSink,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3731,7 +3731,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetObject),
+ (ndr_push_flags_fn_t) ndr_push_GetObject,
+ (ndr_pull_flags_fn_t) ndr_pull_GetObject,
+- (ndr_print_function_t) ndr_print_GetObject,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3740,7 +3740,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetObjectAsync),
+ (ndr_push_flags_fn_t) ndr_push_GetObjectAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_GetObjectAsync,
+- (ndr_print_function_t) ndr_print_GetObjectAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3749,7 +3749,7 @@ static const struct ndr_interface_call I
+ sizeof(struct PutClass),
+ (ndr_push_flags_fn_t) ndr_push_PutClass,
+ (ndr_pull_flags_fn_t) ndr_pull_PutClass,
+- (ndr_print_function_t) ndr_print_PutClass,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3758,7 +3758,7 @@ static const struct ndr_interface_call I
+ sizeof(struct PutClassAsync),
+ (ndr_push_flags_fn_t) ndr_push_PutClassAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_PutClassAsync,
+- (ndr_print_function_t) ndr_print_PutClassAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3767,7 +3767,7 @@ static const struct ndr_interface_call I
+ sizeof(struct DeleteClass),
+ (ndr_push_flags_fn_t) ndr_push_DeleteClass,
+ (ndr_pull_flags_fn_t) ndr_pull_DeleteClass,
+- (ndr_print_function_t) ndr_print_DeleteClass,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3776,7 +3776,7 @@ static const struct ndr_interface_call I
+ sizeof(struct DeleteClassAsync),
+ (ndr_push_flags_fn_t) ndr_push_DeleteClassAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_DeleteClassAsync,
+- (ndr_print_function_t) ndr_print_DeleteClassAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3785,7 +3785,7 @@ static const struct ndr_interface_call I
+ sizeof(struct CreateClassEnum),
+ (ndr_push_flags_fn_t) ndr_push_CreateClassEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_CreateClassEnum,
+- (ndr_print_function_t) ndr_print_CreateClassEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3794,7 +3794,7 @@ static const struct ndr_interface_call I
+ sizeof(struct CreateClassEnumAsync),
+ (ndr_push_flags_fn_t) ndr_push_CreateClassEnumAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_CreateClassEnumAsync,
+- (ndr_print_function_t) ndr_print_CreateClassEnumAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3803,7 +3803,7 @@ static const struct ndr_interface_call I
+ sizeof(struct PutInstance),
+ (ndr_push_flags_fn_t) ndr_push_PutInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_PutInstance,
+- (ndr_print_function_t) ndr_print_PutInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3812,7 +3812,7 @@ static const struct ndr_interface_call I
+ sizeof(struct PutInstanceAsync),
+ (ndr_push_flags_fn_t) ndr_push_PutInstanceAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_PutInstanceAsync,
+- (ndr_print_function_t) ndr_print_PutInstanceAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3821,7 +3821,7 @@ static const struct ndr_interface_call I
+ sizeof(struct DeleteInstance),
+ (ndr_push_flags_fn_t) ndr_push_DeleteInstance,
+ (ndr_pull_flags_fn_t) ndr_pull_DeleteInstance,
+- (ndr_print_function_t) ndr_print_DeleteInstance,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3830,7 +3830,7 @@ static const struct ndr_interface_call I
+ sizeof(struct DeleteInstanceAsync),
+ (ndr_push_flags_fn_t) ndr_push_DeleteInstanceAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_DeleteInstanceAsync,
+- (ndr_print_function_t) ndr_print_DeleteInstanceAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3839,7 +3839,7 @@ static const struct ndr_interface_call I
+ sizeof(struct CreateInstanceEnum),
+ (ndr_push_flags_fn_t) ndr_push_CreateInstanceEnum,
+ (ndr_pull_flags_fn_t) ndr_pull_CreateInstanceEnum,
+- (ndr_print_function_t) ndr_print_CreateInstanceEnum,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3848,7 +3848,7 @@ static const struct ndr_interface_call I
+ sizeof(struct CreateInstanceEnumAsync),
+ (ndr_push_flags_fn_t) ndr_push_CreateInstanceEnumAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_CreateInstanceEnumAsync,
+- (ndr_print_function_t) ndr_print_CreateInstanceEnumAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3857,7 +3857,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ExecQuery),
+ (ndr_push_flags_fn_t) ndr_push_ExecQuery,
+ (ndr_pull_flags_fn_t) ndr_pull_ExecQuery,
+- (ndr_print_function_t) ndr_print_ExecQuery,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3866,7 +3866,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ExecQueryAsync),
+ (ndr_push_flags_fn_t) ndr_push_ExecQueryAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_ExecQueryAsync,
+- (ndr_print_function_t) ndr_print_ExecQueryAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3875,7 +3875,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ExecNotificationQuery),
+ (ndr_push_flags_fn_t) ndr_push_ExecNotificationQuery,
+ (ndr_pull_flags_fn_t) ndr_pull_ExecNotificationQuery,
+- (ndr_print_function_t) ndr_print_ExecNotificationQuery,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3884,7 +3884,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ExecNotificationQueryAsync),
+ (ndr_push_flags_fn_t) ndr_push_ExecNotificationQueryAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_ExecNotificationQueryAsync,
+- (ndr_print_function_t) ndr_print_ExecNotificationQueryAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3893,7 +3893,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ExecMethod),
+ (ndr_push_flags_fn_t) ndr_push_ExecMethod,
+ (ndr_pull_flags_fn_t) ndr_pull_ExecMethod,
+- (ndr_print_function_t) ndr_print_ExecMethod,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -3902,7 +3902,7 @@ static const struct ndr_interface_call I
+ sizeof(struct ExecMethodAsync),
+ (ndr_push_flags_fn_t) ndr_push_ExecMethodAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_ExecMethodAsync,
+- (ndr_print_function_t) ndr_print_ExecMethodAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4434,7 +4434,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Reset),
+ (ndr_push_flags_fn_t) ndr_push_Reset,
+ (ndr_pull_flags_fn_t) ndr_pull_Reset,
+- (ndr_print_function_t) ndr_print_Reset,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4443,7 +4443,7 @@ static const struct ndr_interface_call I
+ sizeof(struct IEnumWbemClassObject_Next),
+ (ndr_push_flags_fn_t) ndr_push_IEnumWbemClassObject_Next,
+ (ndr_pull_flags_fn_t) ndr_pull_IEnumWbemClassObject_Next,
+- (ndr_print_function_t) ndr_print_IEnumWbemClassObject_Next,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4452,7 +4452,7 @@ static const struct ndr_interface_call I
+ sizeof(struct NextAsync),
+ (ndr_push_flags_fn_t) ndr_push_NextAsync,
+ (ndr_pull_flags_fn_t) ndr_pull_NextAsync,
+- (ndr_print_function_t) ndr_print_NextAsync,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4461,7 +4461,7 @@ static const struct ndr_interface_call I
+ sizeof(struct IEnumWbemClassObject_Clone),
+ (ndr_push_flags_fn_t) ndr_push_IEnumWbemClassObject_Clone,
+ (ndr_pull_flags_fn_t) ndr_pull_IEnumWbemClassObject_Clone,
+- (ndr_print_function_t) ndr_print_IEnumWbemClassObject_Clone,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -4470,7 +4470,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Skip),
+ (ndr_push_flags_fn_t) ndr_push_Skip,
+ (ndr_pull_flags_fn_t) ndr_pull_Skip,
+- (ndr_print_function_t) ndr_print_Skip,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5143,7 +5143,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Clone),
+ (ndr_push_flags_fn_t) ndr_push_Clone,
+ (ndr_pull_flags_fn_t) ndr_pull_Clone,
+- (ndr_print_function_t) ndr_print_Clone,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5152,7 +5152,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetNames),
+ (ndr_push_flags_fn_t) ndr_push_GetNames,
+ (ndr_pull_flags_fn_t) ndr_pull_GetNames,
+- (ndr_print_function_t) ndr_print_GetNames,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5161,7 +5161,7 @@ static const struct ndr_interface_call I
+ sizeof(struct BeginEnumeration),
+ (ndr_push_flags_fn_t) ndr_push_BeginEnumeration,
+ (ndr_pull_flags_fn_t) ndr_pull_BeginEnumeration,
+- (ndr_print_function_t) ndr_print_BeginEnumeration,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5170,7 +5170,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Next),
+ (ndr_push_flags_fn_t) ndr_push_Next,
+ (ndr_pull_flags_fn_t) ndr_pull_Next,
+- (ndr_print_function_t) ndr_print_Next,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5179,7 +5179,7 @@ static const struct ndr_interface_call I
+ sizeof(struct EndEnumeration),
+ (ndr_push_flags_fn_t) ndr_push_EndEnumeration,
+ (ndr_pull_flags_fn_t) ndr_pull_EndEnumeration,
+- (ndr_print_function_t) ndr_print_EndEnumeration,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5188,7 +5188,7 @@ static const struct ndr_interface_call I
+ sizeof(struct SetValue),
+ (ndr_push_flags_fn_t) ndr_push_SetValue,
+ (ndr_pull_flags_fn_t) ndr_pull_SetValue,
+- (ndr_print_function_t) ndr_print_SetValue,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5197,7 +5197,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetValue),
+ (ndr_push_flags_fn_t) ndr_push_GetValue,
+ (ndr_pull_flags_fn_t) ndr_pull_GetValue,
+- (ndr_print_function_t) ndr_print_GetValue,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5206,7 +5206,7 @@ static const struct ndr_interface_call I
+ sizeof(struct DeleteValue),
+ (ndr_push_flags_fn_t) ndr_push_DeleteValue,
+ (ndr_pull_flags_fn_t) ndr_pull_DeleteValue,
+- (ndr_print_function_t) ndr_print_DeleteValue,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5215,7 +5215,7 @@ static const struct ndr_interface_call I
+ sizeof(struct DeleteAll),
+ (ndr_push_flags_fn_t) ndr_push_DeleteAll,
+ (ndr_pull_flags_fn_t) ndr_pull_DeleteAll,
+- (ndr_print_function_t) ndr_print_DeleteAll,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5963,7 +5963,7 @@ static const struct ndr_interface_call I
+ sizeof(struct EstablishPosition),
+ (ndr_push_flags_fn_t) ndr_push_EstablishPosition,
+ (ndr_pull_flags_fn_t) ndr_pull_EstablishPosition,
+- (ndr_print_function_t) ndr_print_EstablishPosition,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5972,7 +5972,7 @@ static const struct ndr_interface_call I
+ sizeof(struct RequestChallenge),
+ (ndr_push_flags_fn_t) ndr_push_RequestChallenge,
+ (ndr_pull_flags_fn_t) ndr_pull_RequestChallenge,
+- (ndr_print_function_t) ndr_print_RequestChallenge,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5981,7 +5981,7 @@ static const struct ndr_interface_call I
+ sizeof(struct WBEMLogin),
+ (ndr_push_flags_fn_t) ndr_push_WBEMLogin,
+ (ndr_pull_flags_fn_t) ndr_pull_WBEMLogin,
+- (ndr_print_function_t) ndr_print_WBEMLogin,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -5990,7 +5990,7 @@ static const struct ndr_interface_call I
+ sizeof(struct NTLMLogin),
+ (ndr_push_flags_fn_t) ndr_push_NTLMLogin,
+ (ndr_pull_flags_fn_t) ndr_pull_NTLMLogin,
+- (ndr_print_function_t) ndr_print_NTLMLogin,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6225,7 +6225,7 @@ static const struct ndr_interface_call I
+ sizeof(struct IWbemWCOSmartEnum_Next),
+ (ndr_push_flags_fn_t) ndr_push_IWbemWCOSmartEnum_Next,
+ (ndr_pull_flags_fn_t) ndr_pull_IWbemWCOSmartEnum_Next,
+- (ndr_print_function_t) ndr_print_IWbemWCOSmartEnum_Next,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6479,7 +6479,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Fetch),
+ (ndr_push_flags_fn_t) ndr_push_Fetch,
+ (ndr_pull_flags_fn_t) ndr_pull_Fetch,
+- (ndr_print_function_t) ndr_print_Fetch,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6488,7 +6488,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Test),
+ (ndr_push_flags_fn_t) ndr_push_Test,
+ (ndr_pull_flags_fn_t) ndr_pull_Test,
+- (ndr_print_function_t) ndr_print_Test,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6920,7 +6920,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetResultObject),
+ (ndr_push_flags_fn_t) ndr_push_GetResultObject,
+ (ndr_pull_flags_fn_t) ndr_pull_GetResultObject,
+- (ndr_print_function_t) ndr_print_GetResultObject,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6929,7 +6929,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetResultString),
+ (ndr_push_flags_fn_t) ndr_push_GetResultString,
+ (ndr_pull_flags_fn_t) ndr_pull_GetResultString,
+- (ndr_print_function_t) ndr_print_GetResultString,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6938,7 +6938,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetResultServices),
+ (ndr_push_flags_fn_t) ndr_push_GetResultServices,
+ (ndr_pull_flags_fn_t) ndr_pull_GetResultServices,
+- (ndr_print_function_t) ndr_print_GetResultServices,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -6947,7 +6947,7 @@ static const struct ndr_interface_call I
+ sizeof(struct GetCallStatus),
+ (ndr_push_flags_fn_t) ndr_push_GetCallStatus,
+ (ndr_pull_flags_fn_t) ndr_pull_GetCallStatus,
+- (ndr_print_function_t) ndr_print_GetCallStatus,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7211,7 +7211,7 @@ static const struct ndr_interface_call I
+ sizeof(struct SetStatus),
+ (ndr_push_flags_fn_t) ndr_push_SetStatus,
+ (ndr_pull_flags_fn_t) ndr_pull_SetStatus,
+- (ndr_print_function_t) ndr_print_SetStatus,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -7220,7 +7220,7 @@ static const struct ndr_interface_call I
+ sizeof(struct Indicate),
+ (ndr_push_flags_fn_t) ndr_push_Indicate,
+ (ndr_pull_flags_fn_t) ndr_pull_Indicate,
+- (ndr_print_function_t) ndr_print_Indicate,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_wzcsvc.c
++++ b/source3/librpc/gen_ndr/ndr_wzcsvc.c
+@@ -711,7 +711,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_EnumInterfaces),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_EnumInterfaces,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_EnumInterfaces,
+- (ndr_print_function_t) ndr_print_wzcsvc_EnumInterfaces,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -720,7 +720,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_QueryInterface),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_QueryInterface,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_QueryInterface,
+- (ndr_print_function_t) ndr_print_wzcsvc_QueryInterface,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -729,7 +729,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_SetInterface),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_SetInterface,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_SetInterface,
+- (ndr_print_function_t) ndr_print_wzcsvc_SetInterface,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -738,7 +738,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_RefreshInterface),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_RefreshInterface,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_RefreshInterface,
+- (ndr_print_function_t) ndr_print_wzcsvc_RefreshInterface,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -747,7 +747,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_QueryContext),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_QueryContext,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_QueryContext,
+- (ndr_print_function_t) ndr_print_wzcsvc_QueryContext,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -756,7 +756,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_SetContext),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_SetContext,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_SetContext,
+- (ndr_print_function_t) ndr_print_wzcsvc_SetContext,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -765,7 +765,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_EapolUIResponse),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_EapolUIResponse,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_EapolUIResponse,
+- (ndr_print_function_t) ndr_print_wzcsvc_EapolUIResponse,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -774,7 +774,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_EapolGetCustomAuthData),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_EapolGetCustomAuthData,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_EapolGetCustomAuthData,
+- (ndr_print_function_t) ndr_print_wzcsvc_EapolGetCustomAuthData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -783,7 +783,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_EapolSetCustomAuthData),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_EapolSetCustomAuthData,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_EapolSetCustomAuthData,
+- (ndr_print_function_t) ndr_print_wzcsvc_EapolSetCustomAuthData,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -792,7 +792,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_EapolGetInterfaceParams),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_EapolGetInterfaceParams,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_EapolGetInterfaceParams,
+- (ndr_print_function_t) ndr_print_wzcsvc_EapolGetInterfaceParams,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -801,7 +801,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_EapolSetInterfaceParams),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_EapolSetInterfaceParams,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_EapolSetInterfaceParams,
+- (ndr_print_function_t) ndr_print_wzcsvc_EapolSetInterfaceParams,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -810,7 +810,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_EapolReAuthenticateInterface),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_EapolReAuthenticateInterface,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_EapolReAuthenticateInterface,
+- (ndr_print_function_t) ndr_print_wzcsvc_EapolReAuthenticateInterface,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -819,7 +819,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_EapolQueryInterfaceState),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_EapolQueryInterfaceState,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_EapolQueryInterfaceState,
+- (ndr_print_function_t) ndr_print_wzcsvc_EapolQueryInterfaceState,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -828,7 +828,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_OpenWZCDbLogSession),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_OpenWZCDbLogSession,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_OpenWZCDbLogSession,
+- (ndr_print_function_t) ndr_print_wzcsvc_OpenWZCDbLogSession,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -837,7 +837,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_CloseWZCDbLogSession),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_CloseWZCDbLogSession,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_CloseWZCDbLogSession,
+- (ndr_print_function_t) ndr_print_wzcsvc_CloseWZCDbLogSession,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -846,7 +846,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_EnumWZCDbLogRecords),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_EnumWZCDbLogRecords,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_EnumWZCDbLogRecords,
+- (ndr_print_function_t) ndr_print_wzcsvc_EnumWZCDbLogRecords,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -855,7 +855,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_FlushWZCdbLog),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_FlushWZCdbLog,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_FlushWZCdbLog,
+- (ndr_print_function_t) ndr_print_wzcsvc_FlushWZCdbLog,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+@@ -864,7 +864,7 @@ static const struct ndr_interface_call w
+ sizeof(struct wzcsvc_GetWZCDbLogRecord),
+ (ndr_push_flags_fn_t) ndr_push_wzcsvc_GetWZCDbLogRecord,
+ (ndr_pull_flags_fn_t) ndr_pull_wzcsvc_GetWZCDbLogRecord,
+- (ndr_print_function_t) ndr_print_wzcsvc_GetWZCDbLogRecord,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- a/source3/librpc/gen_ndr/ndr_xattr.c
++++ b/source3/librpc/gen_ndr/ndr_xattr.c
+@@ -1101,7 +1101,7 @@ static const struct ndr_interface_call x
+ sizeof(struct xattr_parse_DOSATTRIB),
+ (ndr_push_flags_fn_t) ndr_push_xattr_parse_DOSATTRIB,
+ (ndr_pull_flags_fn_t) ndr_pull_xattr_parse_DOSATTRIB,
+- (ndr_print_function_t) ndr_print_xattr_parse_DOSATTRIB,
++ (ndr_print_function_t) ndr_print_disabled,
+ { 0, NULL },
+ { 0, NULL },
+ },
+--- /dev/null
++++ b/source3/remove-librpc-print-calls.sh
+@@ -0,0 +1,22 @@
++#!/usr/bin/env bash
++set -e
++for file in ${1:-librpc/gen_ndr/ndr_*.c}; do
++ quilt add "$file" || true
++ awk '
++$0 ~ /^static const struct ndr_interface_call .* = {$/ {
++ replace = 1
++}
++
++$0 ~ /^}$/ {
++ replace = 0;
++}
++
++replace == 1 {
++ gsub(/.ndr_print_function_t. .*,/, "(ndr_print_function_t) ndr_print_disabled,", $0)
++}
++{
++ print $0
++}
++ ' < "$file" > "$file.new"
++ mv "$file.new" "$file"
++done
+--- a/librpc/ndr/libndr.h
++++ b/librpc/ndr/libndr.h
+@@ -603,6 +603,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_enum
+ _PUBLIC_ enum ndr_err_code ndr_push_enum_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v);
+
+ _PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b);
++_PUBLIC_ void ndr_print_disabled(struct ndr_print *ndr, const char *name, int flags, void *r);
+
+ #ifndef VERBOSE_ERROR
+ #define ndr_print_bool(...) do {} while (0)
diff --git a/package/network/services/uhttpd/Makefile b/package/network/services/uhttpd/Makefile
new file mode 100644
index 0000000..d14e3a9
--- /dev/null
+++ b/package/network/services/uhttpd/Makefile
@@ -0,0 +1,146 @@
+#
+# Copyright (C) 2010-2015 Jo-Philipp Wich <jow@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:=uhttpd
+PKG_VERSION:=2015-10-20
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://nbd.name/uhttpd2.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=618315bc0729c3064e06af2900a86211354f81c9
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=ISC
+
+PKG_BUILD_DEPENDS = ustream-ssl
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/uhttpd/default
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Web Servers/Proxies
+ TITLE:=uHTTPd - tiny, single threaded HTTP server
+endef
+
+define Package/uhttpd
+ $(Package/uhttpd/default)
+ DEPENDS:=+libubox
+endef
+
+define Package/uhttpd/description
+ uHTTPd is a tiny single threaded HTTP server with TLS, CGI and Lua
+ support. It is intended as a drop-in replacement for the Busybox
+ HTTP daemon.
+endef
+
+define Package/uhttpd/config
+ config PACKAGE_uhttpd_debug
+ bool "Build with debug messages"
+ default n
+endef
+
+
+define Package/uhttpd-mod-tls
+ $(Package/uhttpd/default)
+ TITLE+= (TLS plugin)
+ DEPENDS:=uhttpd \
+ +PACKAGE_uhttpd-mod-tls_polarssl:libustream-polarssl \
+ +PACKAGE_uhttpd-mod-tls_cyassl:libustream-cyassl \
+ +PACKAGE_uhttpd-mod-tls_openssl:libustream-openssl
+endef
+
+define Package/uhttpd-mod-tls/description
+ The TLS plugin adds HTTPS support to uHTTPd.
+endef
+
+define Package/uhttpd-mod-tls/config
+ choice
+ depends on PACKAGE_uhttpd-mod-tls
+ prompt "TLS Provider"
+ default PACKAGE_uhttpd-mod-tls_polarssl
+
+ config PACKAGE_uhttpd-mod-tls_polarssl
+ bool "PolarSSL"
+
+ config PACKAGE_uhttpd-mod-tls_cyassl
+ bool "CyaSSL"
+
+ config PACKAGE_uhttpd-mod-tls_openssl
+ bool "OpenSSL"
+ endchoice
+endef
+
+define Package/uhttpd-mod-lua
+ $(Package/uhttpd/default)
+ TITLE+= (Lua plugin)
+ DEPENDS:=uhttpd +liblua
+endef
+
+define Package/uhttpd-mod-lua/description
+ The Lua plugin adds a CGI-like Lua runtime interface to uHTTPd.
+endef
+
+
+define Package/uhttpd-mod-ubus
+ $(Package/uhttpd/default)
+ TITLE+= (ubus plugin)
+ DEPENDS:=uhttpd +libubus +libblobmsg-json
+endef
+
+define Package/uhttpd-mod-ubus/description
+ The ubus plugin adds a HTTP/JSON RPC proxy for ubus and publishes the
+ session.* namespace and procedures.
+endef
+
+define Package/uhttpd/conffiles
+/etc/config/uhttpd
+/etc/uhttpd.crt
+/etc/uhttpd.key
+endef
+
+ifneq ($(CONFIG_USE_GLIBC),)
+ TARGET_CFLAGS += -D_DEFAULT_SOURCE
+endif
+
+TARGET_LDFLAGS += -lcrypt
+
+CMAKE_OPTIONS = -DTLS_SUPPORT=on
+
+define Package/uhttpd/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/uhttpd.init $(1)/etc/init.d/uhttpd
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_CONF) ./files/uhttpd.config $(1)/etc/config/uhttpd
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/uhttpd $(1)/usr/sbin/uhttpd
+endef
+
+define Package/uhttpd-mod-tls/install
+ true
+endef
+
+define Package/uhttpd-mod-lua/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/uhttpd_lua.so $(1)/usr/lib/
+endef
+
+define Package/uhttpd-mod-ubus/install
+ $(INSTALL_DIR) $(1)/usr/lib $(1)/etc/uci-defaults
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/uhttpd_ubus.so $(1)/usr/lib/
+ $(INSTALL_DATA) ./files/ubus.default $(1)/etc/uci-defaults/00_uhttpd_ubus
+endef
+
+
+$(eval $(call BuildPackage,uhttpd))
+$(eval $(call BuildPackage,uhttpd-mod-tls))
+$(eval $(call BuildPackage,uhttpd-mod-lua))
+$(eval $(call BuildPackage,uhttpd-mod-ubus))
diff --git a/package/network/services/uhttpd/files/ubus.default b/package/network/services/uhttpd/files/ubus.default
new file mode 100644
index 0000000..f0f71e9
--- /dev/null
+++ b/package/network/services/uhttpd/files/ubus.default
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [ -z "$(uci -q get uhttpd.main.ubus_prefix)" ]; then
+ uci set uhttpd.main.ubus_prefix=/ubus
+ uci commit uhttpd
+fi
+
+exit 0
diff --git a/package/network/services/uhttpd/files/uhttpd.config b/package/network/services/uhttpd/files/uhttpd.config
new file mode 100644
index 0000000..61f8a49
--- /dev/null
+++ b/package/network/services/uhttpd/files/uhttpd.config
@@ -0,0 +1,122 @@
+# Server configuration
+config uhttpd main
+
+ # HTTP listen addresses, multiple allowed
+ list listen_http 0.0.0.0:80
+ list listen_http [::]:80
+
+ # HTTPS listen addresses, multiple allowed
+ list listen_https 0.0.0.0:443
+ list listen_https [::]:443
+
+ # Redirect HTTP requests to HTTPS if possible
+ option redirect_https 1
+
+ # Server document root
+ option home /www
+
+ # Reject requests from RFC1918 IP addresses
+ # directed to the servers public IP(s).
+ # This is a DNS rebinding countermeasure.
+ option rfc1918_filter 1
+
+ # Maximum number of concurrent requests.
+ # If this number is exceeded, further requests are
+ # queued until the number of running requests drops
+ # below the limit again.
+ option max_requests 3
+
+ # Maximum number of concurrent connections.
+ # If this number is exceeded, further TCP connection
+ # attempts are queued until the number of active
+ # connections drops below the limit again.
+ option max_connections 100
+
+ # Certificate and private key for HTTPS.
+ # If no listen_https addresses are given,
+ # the key options are ignored.
+ option cert /etc/uhttpd.crt
+ option key /etc/uhttpd.key
+
+ # CGI url prefix, will be searched in docroot.
+ # Default is /cgi-bin
+ option cgi_prefix /cgi-bin
+
+ # List of extension->interpreter mappings.
+ # Files with an associated interpreter can
+ # be called outside of the CGI prefix and do
+ # not need to be executable.
+# list interpreter ".php=/usr/bin/php-cgi"
+# list interpreter ".cgi=/usr/bin/perl"
+
+ # Lua url prefix and handler script.
+ # Lua support is disabled if no prefix given.
+# option lua_prefix /luci
+# option lua_handler /usr/lib/lua/luci/sgi/uhttpd.lua
+
+ # Specify the ubus-rpc prefix and socket path.
+# option ubus_prefix /ubus
+# option ubus_socket /var/run/ubus.sock
+
+ # CGI/Lua timeout, if the called script does not
+ # write data within the given amount of seconds,
+ # the server will terminate the request with
+ # 504 Gateway Timeout response.
+ option script_timeout 60
+
+ # Network timeout, if the current connection is
+ # blocked for the specified amount of seconds,
+ # the server will terminate the associated
+ # request process.
+ option network_timeout 30
+
+ # HTTP Keep-Alive, specifies the timeout for persistent
+ # HTTP/1.1 connections. Setting this to 0 will disable
+ # persistent HTTP connections.
+ option http_keepalive 20
+
+ # TCP Keep-Alive, send periodic keep-alive probes
+ # over established connections to detect dead peers.
+ # The value is given in seconds to specify the
+ # interval between subsequent probes.
+ # Setting this to 0 will disable TCP keep-alive.
+ option tcp_keepalive 1
+
+ # Basic auth realm, defaults to local hostname
+# option realm OpenWrt
+
+ # Configuration file in busybox httpd format
+# option config /etc/httpd.conf
+
+ # Do not follow symlinks that point outside of the
+ # home directory.
+# option no_symlinks 0
+
+ # Do not produce directory listings but send 403
+ # instead if a client requests an url pointing to
+ # a directory without any index file.
+# option no_dirlists 0
+
+ # Do not authenticate any ubus-rpc requests against
+ # the ubus session/access procedure.
+ # This is dangerous and should be always left off
+ # except for development and debug purposes!
+# option no_ubusauth 0
+
+
+# Certificate defaults for px5g key generator
+config cert px5g
+
+ # Validity time
+ option days 730
+
+ # RSA key size
+ option bits 1024
+
+ # Location
+ option country ZZ
+ option state Somewhere
+ option location Uknown
+
+ # Common name
+ option commonname OpenWrt
diff --git a/package/network/services/uhttpd/files/uhttpd.init b/package/network/services/uhttpd/files/uhttpd.init
new file mode 100755
index 0000000..fcde52a
--- /dev/null
+++ b/package/network/services/uhttpd/files/uhttpd.init
@@ -0,0 +1,149 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2010 Jo-Philipp Wich
+
+START=50
+
+USE_PROCD=1
+
+UHTTPD_BIN="/usr/sbin/uhttpd"
+PX5G_BIN="/usr/sbin/px5g"
+
+append_arg() {
+ local cfg="$1"
+ local var="$2"
+ local opt="$3"
+ local def="$4"
+ local val
+
+ config_get val "$cfg" "$var"
+ [ -n "$val" -o -n "$def" ] && procd_append_param command "$opt" "${val:-$def}"
+}
+
+append_bool() {
+ local cfg="$1"
+ local var="$2"
+ local opt="$3"
+ local def="$4"
+ local val
+
+ config_get_bool val "$cfg" "$var" "$def"
+ [ "$val" = 1 ] && procd_append_param command "$opt"
+}
+
+generate_keys() {
+ local cfg="$1"
+ local key="$2"
+ local crt="$3"
+ local days bits country state location commonname
+
+ config_get days "$cfg" days
+ config_get bits "$cfg" bits
+ config_get country "$cfg" country
+ config_get state "$cfg" state
+ config_get location "$cfg" location
+ config_get commonname "$cfg" commonname
+
+ [ -x "$PX5G_BIN" ] && {
+ $PX5G_BIN selfsigned -der \
+ -days ${days:-730} -newkey rsa:${bits:-1024} -keyout "${UHTTPD_KEY}.new" -out "${UHTTPD_CERT}.new" \
+ -subj /C="${country:-DE}"/ST="${state:-Saxony}"/L="${location:-Leipzig}"/CN="${commonname:-OpenWrt}"
+ sync
+ mv "${UHTTPD_KEY}.new" "${UHTTPD_KEY}"
+ mv "${UHTTPD_CERT}.new" "${UHTTPD_CERT}"
+ }
+}
+
+start_instance()
+{
+ UHTTPD_CERT=""
+ UHTTPD_KEY=""
+
+ local cfg="$1"
+ local realm="$(uci_get system.@system[0].hostname)"
+ local listen http https interpreter indexes path handler
+
+ procd_open_instance
+ procd_set_param respawn
+ procd_set_param stderr 1
+ procd_set_param command "$UHTTPD_BIN" -f
+
+ append_arg "$cfg" home "-h"
+ append_arg "$cfg" realm "-r" "${realm:-OpenWrt}"
+ append_arg "$cfg" config "-c"
+ append_arg "$cfg" cgi_prefix "-x"
+ [ -f /usr/lib/uhttpd_lua.so ] && {
+ config_get handler "$cfg" lua_handler
+ [ -f "$handler" ] && append_arg "$cfg" lua_prefix "-l" && {
+ procd_append_param command "-L" "$handler"
+ }
+ }
+ [ -f /usr/lib/uhttpd_ubus.so ] && {
+ append_arg "$cfg" ubus_prefix "-u"
+ append_arg "$cfg" ubus_socket "-U"
+ }
+ append_arg "$cfg" script_timeout "-t"
+ append_arg "$cfg" network_timeout "-T"
+ append_arg "$cfg" http_keepalive "-k"
+ append_arg "$cfg" tcp_keepalive "-A"
+ append_arg "$cfg" error_page "-E"
+ append_arg "$cfg" max_requests "-n" 3
+ append_arg "$cfg" max_connections "-N"
+
+ append_bool "$cfg" no_ubusauth "-a" 0
+ append_bool "$cfg" no_symlinks "-S" 0
+ append_bool "$cfg" no_dirlists "-D" 0
+ append_bool "$cfg" rfc1918_filter "-R" 0
+
+ config_get alias_list "$cfg" alias
+ for alias in $alias_list; do
+ procd_append_param command -y "$alias"
+ done
+
+ config_get http "$cfg" listen_http
+ for listen in $http; do
+ procd_append_param command -p "$listen"
+ done
+
+ config_get interpreter "$cfg" interpreter
+ for path in $interpreter; do
+ procd_append_param command -i "$path"
+ done
+
+ config_get indexes "$cfg" index_page
+ for path in $indexes; do
+ procd_append_param command -I "$path"
+ done
+
+ config_get https "$cfg" listen_https
+ config_get UHTTPD_KEY "$cfg" key /etc/uhttpd.key
+ config_get UHTTPD_CERT "$cfg" cert /etc/uhttpd.crt
+
+ [ -f /lib/libustream-ssl.so ] && [ -n "$https" ] && {
+ [ -s "$UHTTPD_CERT" -a -s "$UHTTPD_KEY" ] || {
+ config_foreach generate_keys cert
+ }
+
+ [ -f "$UHTTPD_CERT" -a -f "$UHTTPD_KEY" ] && {
+ append_arg "$cfg" cert "-C"
+ append_arg "$cfg" key "-K"
+
+ for listen in $https; do
+ procd_append_param command -s "$listen"
+ done
+ }
+
+ append_bool "$cfg" redirect_https "-q" 0
+ }
+
+ procd_close_instance
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger "uhttpd"
+}
+
+start_service() {
+ config_load uhttpd
+ config_foreach start_instance uhttpd
+}
diff --git a/package/network/utils/arptables/Makefile b/package/network/utils/arptables/Makefile
new file mode 100644
index 0000000..62681dc
--- /dev/null
+++ b/package/network/utils/arptables/Makefile
@@ -0,0 +1,43 @@
+# Copyright (C) 2006-2010 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:=arptables
+PKG_VERSION:=0.0.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-v$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/ebtables
+PKG_MD5SUM:=c2e99c3aa9d78c9dfa30710ca3168182
+PKG_LICENSE:=GPL-2.0
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-v$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/arptables
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Firewall
+ TITLE:=ARP firewalling software
+ DEPENDS:=+kmod-arptables
+ URL:=http://ebtables.sourceforge.net
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(TARGET_CONFIGURE_OPTS) \
+ COPT_FLAGS="$(TARGET_CFLAGS)" \
+ KERNEL_DIR="./include/linux"
+endef
+
+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/arptables/patches/100-always_optimize.patch b/package/network/utils/arptables/patches/100-always_optimize.patch
new file mode 100644
index 0000000..b120eb7
--- /dev/null
+++ b/package/network/utils/arptables/patches/100-always_optimize.patch
@@ -0,0 +1,19 @@
+Index: arptables-v0.0.3-4/libarptc/libarptc_incl.c
+===================================================================
+--- arptables-v0.0.3-4.orig/libarptc/libarptc_incl.c 2010-03-08 16:49:28.000000000 +0100
++++ arptables-v0.0.3-4/libarptc/libarptc_incl.c 2012-08-14 12:10:29.527945144 +0200
+@@ -11,14 +11,6 @@
+ /* (C)1999 Paul ``Rusty'' Russell - Placed under the GNU GPL (See
+ COPYING for details). */
+
+-#ifndef __OPTIMIZE__
+-STRUCT_ENTRY_TARGET *
+-GET_TARGET(STRUCT_ENTRY *e)
+-{
+- return (void *)e + e->target_offset;
+-}
+-#endif
+-
+ static int sockfd = -1;
+ static void *arptc_fn = NULL;
+
diff --git a/package/network/utils/arptables/patches/200-musl_fixes.patch b/package/network/utils/arptables/patches/200-musl_fixes.patch
new file mode 100644
index 0000000..3a4ba3f
--- /dev/null
+++ b/package/network/utils/arptables/patches/200-musl_fixes.patch
@@ -0,0 +1,31 @@
+--- a/include/arptables.h
++++ b/include/arptables.h
+@@ -1,6 +1,7 @@
+ #ifndef _ARPTABLES_USER_H
+ #define _ARPTABLES_USER_H
+
++#include <sys/types.h>
+ #include "arptables_common.h"
+ #include "libarptc/libarptc.h"
+
+--- a/arptables.c
++++ b/arptables.c
+@@ -43,6 +43,7 @@
+ #include <arptables.h>
+ #include <fcntl.h>
+ #include <sys/wait.h>
++#include <net/ethernet.h>
+
+ #ifndef TRUE
+ #define TRUE 1
+--- a/include/libarptc/arpt_kernel_headers.h
++++ b/include/libarptc/arpt_kernel_headers.h
+@@ -5,7 +5,7 @@
+
+ #include <limits.h>
+
+-#if defined(__GLIBC__) && __GLIBC__ == 2
++#if 1
+ #include <netinet/ip.h>
+ #include <netinet/in.h>
+ #include <netinet/ip_icmp.h>
diff --git a/package/network/utils/comgt/Makefile b/package/network/utils/comgt/Makefile
new file mode 100644
index 0000000..ac19aad
--- /dev/null
+++ b/package/network/utils/comgt/Makefile
@@ -0,0 +1,103 @@
+#
+# 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:=27
+
+PKG_SOURCE:=$(PKG_NAME).$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=@SF/comgt
+PKG_MD5SUM:=db2452680c3d953631299e331daf49ef
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=GPL-2.0+
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME).$(PKG_VERSION)
+PKG_CHECK_FORMAT_SECURITY:=0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/comgt/Default
+ SECTION:=utils
+ CATEGORY:=Utilities
+endef
+
+define Package/comgt
+$(call Package/comgt/Default)
+ TITLE:=Option/Vodafone 3G/GPRS control tool
+ DEPENDS:=+chat
+ URL:=http://www.pharscape.org/comgt.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
+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_DIR) $(1)/etc/hotplug.d/tty
+ $(INSTALL_DATA) ./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_DATA) ./files/runcommand.gcom $(1)/etc/gcom/runcommand.gcom
+ $(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..b0cdae2
--- /dev/null
+++ b/package/network/utils/comgt/files/3g.sh
@@ -0,0 +1,110 @@
+#!/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 "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
+
+ [ -n "$dat_device" ] && device=$dat_device
+ [ -e "$device" ] || {
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ 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"
+ 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..ac8326b
--- /dev/null
+++ b/package/network/utils/comgt/files/3g.usb
@@ -0,0 +1,33 @@
+#!/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
+ available=1
+ else
+ available=0
+ fi
+ proto_set_available "$cfg" $available
+ fi
+}
+
+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..d828052
--- /dev/null
+++ b/package/network/utils/comgt/files/directip.sh
@@ -0,0 +1,111 @@
+#!/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_directip_setup() {
+ local interface="$1"
+ local chat devpath devname
+
+ local device apn pincode ifname auth username password
+ json_get_vars device apn pincode auth username password
+
+ [ -n "$ctl_device" ] && device=$ctl_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
+ }
+
+ cardinfo=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom)
+ [ -n $(echo "$cardinfo" | 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"
+ 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
+ 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..5c69a64
--- /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 "ATI^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..d1f8699
--- /dev/null
+++ b/package/network/utils/comgt/files/ncm.json
@@ -0,0 +1,67 @@
+{
+ "huawei": {
+ "initialize": [
+ "AT",
+ "ATZ",
+ "ATQ0",
+ "ATV1",
+ "ATE1",
+ "ATS0=0",
+ "AT+CGDCONT=1,\\\"${pdptype}\\\",\\\"${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=1,1,\\\"${apn}\\\"${username:+,\\\"$username\\\"}${password:+,\\\"$password\\\"}${auth:+,$auth}",
+ "disconnect": "AT^NDISDUP=1,0"
+ },
+ "samsung": {
+ "initialize": [
+ "AT",
+ "AT+CGREG=2",
+ "AT+CFUN=5",
+ "AT+MODESELECT=3",
+ "AT+CGDCONT=1,\\\"${pdptype}\\\",\\\"${apn}\\\""
+ ],
+ "modes": {
+ "umts": "AT+CHANGEALLPATH=1"
+ },
+ "connect": "AT+CGATT=1",
+ "disconnect": "AT+CGATT=0"
+ },
+ "sierra wireless, incorporated": {
+ "initialize": [
+ "AT+CFUN=1",
+ "AT+CGDCONT=1,\\\"${pdptype}\\\",\\\"${apn}\\\"",
+ "AT$QCPDPP=1${auth:+,$auth}${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,1",
+ "disconnect": "AT!SCACT=0,1"
+ },
+ "sony ericsson": {
+ "initialize": [
+ "AT+CFUN=1",
+ "AT+CGDCONT=1,\\\"${pdptype}\\\",\\\"${apn}\\\"",
+ "AT*EIAAUW=1,1,\\\"${username}\\\",\\\"${password}\\\",${auth:-00111}"
+ ],
+ "modes": {
+ "umts": "AT+CFUN=6",
+ "gsm": "AT+CFUN=5"
+ },
+ "connect": "AT*ENAP=1,1",
+ "disconnect": "AT*ENAP=0"
+ }
+}
diff --git a/package/network/utils/comgt/files/ncm.sh b/package/network/utils/comgt/files/ncm.sh
new file mode 100644
index 0000000..571cfaa
--- /dev/null
+++ b/package/network/utils/comgt/files/ncm.sh
@@ -0,0 +1,192 @@
+#!/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 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 ipv6
+}
+
+proto_ncm_setup() {
+ local interface="$1"
+
+ local manufacturer initialize setmode connect ifname devname devpath
+
+ local device apn auth username password pincode delay mode pdptype ipv6
+ json_get_vars device apn auth username password pincode delay mode pdptype ipv6
+
+ if [ "$ipv6" = 0 ]; then
+ ipv6=""
+ else
+ ipv6=1
+ fi
+
+ [ -z "$pdptype" ] && {
+ if [ -n "$ipv6" ]; then
+ pdptype="IPV4V6"
+ else
+ pdptype="IP"
+ fi
+ }
+
+ [ -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
+ }
+ [ -e "$device" ] || {
+ echo "Control device not valid"
+ proto_set_available "$interface" 0
+ return 1
+ }
+ [ -n "$apn" ] || {
+ echo "No APN specified"
+ proto_notify_error "$interface" NO_APN
+ return 1
+ }
+
+ devname="$(basename "$device")"
+ case "$devname" in
+ 'tty'*)
+ devpath="$(readlink -f /sys/class/tty/$devname/device)"
+ ifname="$( ls "$devpath"/../../*/net )"
+ ;;
+ *)
+ devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
+ ifname="$( ls "$devpath"/net )"
+ ;;
+ esac
+ [ -n "$ifname" ] || {
+ echo "The interface could not be found."
+ proto_notify_error "$interface" NO_IFACE
+ proto_set_available "$interface" 0
+ return 1
+ }
+
+ [ -n "$delay" ] && sleep "$delay"
+
+ manufacturer=`gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk '/Manufacturer/ { print tolower($2) }'`
+ [ $? -ne 0 ] && {
+ 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
+ }
+ }
+ [ -n "$mode" ] && {
+ json_select modes
+ json_get_var setmode "$mode"
+ 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 ..
+ }
+
+ json_get_vars connect
+ eval COMMAND="$connect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+ echo "Failed to connect"
+ proto_notify_error "$interface" CONNECT_FAILED
+ return 1
+ }
+
+ echo "Connected, starting DHCP on $ifname"
+
+ 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"
+ ubus call network add_dynamic "$(json_dump)"
+
+ [ -n "$ipv6" ] && {
+ json_init
+ json_add_string name "${interface}_6"
+ json_add_string ifname "@$interface"
+ json_add_string proto "dhcpv6"
+ json_add_string extendprefix 1
+ ubus call network add_dynamic "$(json_dump)"
+ }
+}
+
+proto_ncm_teardown() {
+ local interface="$1"
+
+ local manufacturer disconnect
+
+ local device
+ json_get_vars device
+
+ echo "Stopping network"
+
+ manufacturer=`gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk '/Manufacturer/ { print tolower($2) }'`
+ [ $? -ne 0 ] && {
+ echo "Failed to get modem information"
+ proto_notify_error "$interface" GETINFO_FAILED
+ return 1
+ }
+
+ 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
+ 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..e99b6f9
--- /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 15 "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..66350fe
--- /dev/null
+++ b/package/network/utils/comgt/files/setpin.gcom
@@ -0,0 +1,55 @@
+# 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+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/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/conntrack-tools/Makefile b/package/network/utils/conntrack-tools/Makefile
new file mode 100644
index 0000000..978467b
--- /dev/null
+++ b/package/network/utils/conntrack-tools/Makefile
@@ -0,0 +1,70 @@
+#
+# Copyright (C) 2009-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:=conntrack-tools
+PKG_VERSION:=1.4.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:= \
+ http://www.netfilter.org/projects/conntrack-tools/files \
+ ftp://ftp.netfilter.org/pub/conntrack-tools \
+ http://mirrors.evolva.ro/netfilter.org/conntrack-tools
+PKG_MD5SUM:=b1f9d006e7bf000a77395ff7cd3fac16
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+TAR_OPTIONS += --exclude='*.rej'
+
+PKG_BUILD_DEPENDS:=librpc
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/conntrack-tools
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=+libnetfilter-conntrack +libnetfilter-cttimeout +libnetfilter-cthelper +libnetfilter-queue
+ SUBMENU:=Firewall
+ TITLE:=Connection tracking userspace tools
+ URL:=http://conntrack-tools.netfilter.org/
+endef
+
+define Package/conntrack-tools/description
+ The conntrack-tools are a set of free software userspace tools for Linux
+ that allow system administrators interact with the Connection Tracking
+ System, which is the module that provides stateful packet inspection for
+ iptables. The conntrack-tools are the userspace daemon conntrackd and the
+ command line interface conntrack.
+endef
+
+define Package/conntrack-tools/conffiles
+/etc/conntrackd/conntrackd.conf
+endef
+
+TARGET_CFLAGS += -D_GNU_SOURCE=1
+
+define Package/conntrack-tools/install
+ $(INSTALL_DIR) $(1)/etc/conntrackd
+ $(INSTALL_CONF) \
+ $(PKG_BUILD_DIR)/doc/stats/conntrackd.conf \
+ $(1)/etc/conntrackd/
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) \
+ $(PKG_INSTALL_DIR)/usr/sbin/conntrack \
+ $(PKG_INSTALL_DIR)/usr/sbin/conntrackd \
+ $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/conntrackd.init $(1)/etc/init.d/conntrackd
+endef
+
+$(eval $(call BuildPackage,conntrack-tools))
diff --git a/package/network/utils/conntrack-tools/files/conntrackd.init b/package/network/utils/conntrack-tools/files/conntrackd.init
new file mode 100644
index 0000000..a51eb88
--- /dev/null
+++ b/package/network/utils/conntrack-tools/files/conntrackd.init
@@ -0,0 +1,17 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2015 OpenWrt.org
+
+START=21
+STOP=89
+
+USE_PROCD=1
+PROG="/usr/sbin/conntrackd"
+
+start_service() {
+ procd_open_instance
+
+ procd_set_param command $PROG -C /etc/conntrackd/conntrackd.conf
+ procd_set_param respawn
+
+ procd_close_instance
+}
diff --git a/package/network/utils/conntrack-tools/patches/100-missing_include.patch b/package/network/utils/conntrack-tools/patches/100-missing_include.patch
new file mode 100644
index 0000000..96941a8
--- /dev/null
+++ b/package/network/utils/conntrack-tools/patches/100-missing_include.patch
@@ -0,0 +1,40 @@
+--- a/include/mcast.h
++++ b/include/mcast.h
+@@ -4,6 +4,7 @@
+ #include <stdint.h>
+ #include <netinet/in.h>
+ #include <net/if.h>
++#include <sys/select.h>
+
+ struct mcast_conf {
+ int ipproto;
+--- a/include/tcp.h
++++ b/include/tcp.h
+@@ -3,6 +3,7 @@
+
+ #include <stdint.h>
+ #include <netinet/in.h>
++#include <sys/select.h>
+
+ struct tcp_conf {
+ int ipproto;
+--- a/include/udp.h
++++ b/include/udp.h
+@@ -3,6 +3,7 @@
+
+ #include <stdint.h>
+ #include <netinet/in.h>
++#include <sys/select.h>
+
+ struct udp_conf {
+ int ipproto;
+--- a/include/bitops.h
++++ b/include/bitops.h
+@@ -2,6 +2,7 @@
+ #define _BITOPS_H_
+
+ #include <stdlib.h>
++#include <sys/types.h>
+
+ static inline void set_bit_u32(int nr, u_int32_t *addr)
+ {
diff --git a/package/network/utils/curl/Config.in b/package/network/utils/curl/Config.in
new file mode 100644
index 0000000..11cfa39
--- /dev/null
+++ b/package/network/utils/curl/Config.in
@@ -0,0 +1,154 @@
+if PACKAGE_libcurl
+
+comment "SSL support"
+
+choice
+ prompt "Selected SSL library"
+ default LIBCURL_POLARSSL
+
+ config LIBCURL_POLARSSL
+ bool "PolarSSL"
+
+ config LIBCURL_CYASSL
+ bool "CyaSSL"
+
+ config LIBCURL_AXTLS
+ bool "axTLS"
+
+ config LIBCURL_OPENSSL
+ bool "OpenSSL"
+
+ config LIBCURL_GNUTLS
+ bool "GNUTLS"
+
+ config LIBCURL_NOSSL
+ bool "No SSL support"
+
+endchoice
+
+comment "Supported protocols"
+
+config LIBCURL_DICT
+ bool "DICT protocol"
+ default n
+
+config LIBCURL_FILE
+ bool "FILE protocol"
+ default y
+
+config LIBCURL_FTP
+ bool "FTP / FTPS protocol"
+ default y
+
+config LIBCURL_GOPHER
+ bool "Gopher protocol"
+ default n
+
+config LIBCURL_HTTP
+ bool "HTTP / HTTPS protocol"
+ default y
+
+config LIBCURL_COOKIES
+ bool "Enable Cookies support"
+ depends on LIBCURL_HTTP
+ default y
+
+config LIBCURL_IMAP
+ bool "IMAP / IMAPS protocol"
+ default n
+
+config LIBCURL_LDAP
+ bool "LDAP protocol"
+ default n
+
+config LIBCURL_LDAPS
+ bool "Enable LDAPS support"
+ depends on LIBCURL_LDAP && !LIBCURL_NOSSL
+ default y
+
+config LIBCURL_POP3
+ bool "POP3 / POP3S protocol"
+ default n
+
+config LIBCURL_RTSP
+ bool "RTSP protocol"
+ depends on LIBCURL_HTTP
+ default n
+config LIBCURL_NO_RTSP
+ string "RTSP require HTTP protocol"
+ depends on !LIBCURL_HTTP
+ default "!"
+
+config LIBCURL_SSH2
+ bool "SCP / SFTP protocol"
+ default n
+
+config LIBCURL_SMB
+ bool "SMB protocol (CIFS)"
+ depends on LIBCURL_CRYPTO_AUTH && (LIBCURL_GNUTLS || LIBCURL_OPENSSL)
+ default n
+config LIBCURL_NO_SMB
+ string "SMB require 'cryptographic authentication' and either 'GnuTLS' or 'OpenSSL'"
+ depends on !LIBCURL_CRYPTO_AUTH || (!LIBCURL_GNUTLS && !LIBCURL_OPENSSL)
+ default "!"
+
+config LIBCURL_SMTP
+ bool "SMTP / SMTPS protocol"
+ default n
+
+config LIBCURL_TELNET
+ bool "TELNET protocol"
+ default n
+
+config LIBCURL_TFTP
+ bool "TFTP protocol"
+ default n
+
+comment "Miscellaneous"
+
+config LIBCURL_PROXY
+ bool "Enable proxy support"
+ default y
+
+config LIBCURL_CRYPTO_AUTH
+ bool "Enable cryptographic authentication"
+ default n
+
+config LIBCURL_TLS_SRP
+ bool "Enable TLS-SRP authentication"
+ default n
+
+config LIBCURL_LIBIDN
+ bool "Enable IDN support"
+ default n
+
+config LIBCURL_THREADED_RESOLVER
+ bool "Enable threaded DNS resolver"
+ default n
+ help
+ Enable POSIX threaded asynchronous DNS resolution
+
+config LIBCURL_ZLIB
+ bool "Enable zlib support"
+ default n
+
+config LIBCURL_UNIX_SOCKETS
+ bool "Enable unix domain socket support"
+ default n
+ help
+ Enable HTTP over unix domain sockets.
+ To use this with the curl command line, you specify the socket path to the new --unix-domain option.
+ This feature is actually not limited to HTTP, you can do all the TCP-based protocols
+ except FTP over the unix domain socket, but it is only HTTP that is regularly used this way.
+ The reason FTP isn't supported is of course its use of two connections
+ which would be even weirder to do like this.
+
+config LIBCURL_LIBCURL_OPTION
+ bool "Enable generation of C code"
+ default n
+
+config LIBCURL_VERBOSE
+ bool "Enable verbose error strings"
+ default n
+
+endif
diff --git a/package/network/utils/curl/Makefile b/package/network/utils/curl/Makefile
new file mode 100644
index 0000000..82574cd
--- /dev/null
+++ b/package/network/utils/curl/Makefile
@@ -0,0 +1,178 @@
+#
+# Copyright (C) 2007-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:=curl
+PKG_VERSION:=7.43.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://curl.haxx.se/download/ \
+ http://www.mirrorspace.org/curl/ \
+ ftp://ftp.sunet.se/pub/www/utilities/curl/ \
+ ftp://ftp.planetmirror.com/pub/curl/ \
+ http://www.mirrormonster.com/curl/download/ \
+ http://curl.mirrors.cyberservers.net/download/
+PKG_MD5SUM:=11bddbb452a8b766b932f859aaeeed39
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+
+PKG_CONFIG_DEPENDS:= \
+ CONFIG_IPV6 \
+ \
+ CONFIG_LIBCURL_AXTLS \
+ CONFIG_LIBCURL_CYASSL \
+ CONFIG_LIBCURL_GNUTLS \
+ CONFIG_LIBCURL_OPENSSL \
+ CONFIG_LIBCURL_POLARSSL \
+ CONFIG_LIBCURL_NOSSL \
+ \
+ CONFIG_LIBCURL_LIBIDN \
+ CONFIG_LIBCURL_SSH2 \
+ CONFIG_LIBCURL_ZLIB \
+ \
+ CONFIG_LIBCURL_DICT \
+ CONFIG_LIBCURL_FILE \
+ CONFIG_LIBCURL_FTP \
+ CONFIG_LIBCURL_GOPHER \
+ CONFIG_LIBCURL_HTTP \
+ CONFIG_LIBCURL_IMAP \
+ CONFIG_LIBCURL_LDAP \
+ CONFIG_LIBCURL_LDAPS \
+ CONFIG_LIBCURL_POP3 \
+ CONFIG_LIBCURL_RTSP \
+ CONFIG_LIBCURL_NO_RTSP \
+ CONFIG_LIBCURL_SMB \
+ CONFIG_LIBCURL_NO_SMB \
+ CONFIG_LIBCURL_SMTP \
+ CONFIG_LIBCURL_TELNET \
+ CONFIG_LIBCURL_TFTP \
+ \
+ CONFIG_LIBCURL_COOKIES \
+ CONFIG_LIBCURL_CRYPTO_AUTH \
+ CONFIG_LIBCURL_LIBCURL_OPTION \
+ CONFIG_LIBCURL_PROXY \
+ CONFIG_LIBCURL_THREADED_RESOLVER \
+ CONFIG_LIBCURL_TLS_SRP \
+ CONFIG_LIBCURL_UNIX_SOCKETS \
+ CONFIG_LIBCURL_VERBOSE
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/curl/Default
+ SECTION:=net
+ CATEGORY:=Network
+ URL:=http://curl.haxx.se/
+ MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>
+endef
+
+define Package/curl
+ $(call Package/curl/Default)
+ SUBMENU:=File Transfer
+ DEPENDS:=+libcurl
+ TITLE:=A client-side URL transfer utility
+endef
+
+define Package/libcurl
+ $(call Package/curl/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=+LIBCURL_POLARSSL:libpolarssl +LIBCURL_CYASSL:libcyassl +LIBCURL_AXTLS:libaxtls +LIBCURL_OPENSSL:libopenssl +LIBCURL_GNUTLS:libgnutls
+ DEPENDS += +LIBCURL_ZLIB:zlib +LIBCURL_THREADED_RESOLVER:libpthread +LIBCURL_LDAP:libopenldap +LIBCURL_LIBIDN:libidn +LIBCURL_SSH2:libssh2
+ TITLE:=A client-side URL transfer library
+ MENU:=1
+endef
+
+
+define Package/libcurl/config
+ source "$(SOURCE)/Config.in"
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+ --disable-debug \
+ --disable-ares \
+ --enable-shared \
+ --enable-static \
+ --disable-manual \
+ --without-ca-bundle \
+ --without-nss \
+ --without-libmetalink \
+ --without-librtmp \
+ \
+ $(call autoconf_bool,CONFIG_IPV6,ipv6) \
+ \
+ $(if $(CONFIG_LIBCURL_AXTLS),--with-axtls="$(STAGING_DIR)/usr" --without-ca-path,--without-axtls) \
+ $(if $(CONFIG_LIBCURL_CYASSL),--with-cyassl="$(STAGING_DIR)/usr" --without-ca-path,--without-cyassl) \
+ $(if $(CONFIG_LIBCURL_GNUTLS),--with-gnutls="$(STAGING_DIR)/usr" --without-ca-path,--without-gnutls) \
+ $(if $(CONFIG_LIBCURL_OPENSSL),--with-ssl="$(STAGING_DIR)/usr" --with-ca-path=/etc/ssl/certs,--without-ssl) \
+ $(if $(CONFIG_LIBCURL_POLARSSL),--with-polarssl="$(STAGING_DIR)/usr" --with-ca-path=/etc/ssl/certs,--without-polarssl) \
+ \
+ $(if $(CONFIG_LIBCURL_LIBIDN),--with-libidn="$(STAGING_DIR)/usr",--without-libidn) \
+ $(if $(CONFIG_LIBCURL_SSH2),--with-libssh2="$(STAGING_DIR)/usr",--without-libssh2) \
+ $(if $(CONFIG_LIBCURL_ZLIB),--with-zlib="$(STAGING_DIR)/usr",--without-zlib) \
+ \
+ $(call autoconf_bool,CONFIG_LIBCURL_DICT,dict) \
+ $(call autoconf_bool,CONFIG_LIBCURL_FILE,file) \
+ $(call autoconf_bool,CONFIG_LIBCURL_FTP,ftp) \
+ $(call autoconf_bool,CONFIG_LIBCURL_GOPHER,gopher) \
+ $(call autoconf_bool,CONFIG_LIBCURL_HTTP,http) \
+ $(call autoconf_bool,CONFIG_LIBCURL_IMAP,imap) \
+ $(call autoconf_bool,CONFIG_LIBCURL_LDAP,ldap) \
+ $(call autoconf_bool,CONFIG_LIBCURL_LDAPS,ldaps) \
+ $(call autoconf_bool,CONFIG_LIBCURL_POP3,pop3) \
+ $(call autoconf_bool,CONFIG_LIBCURL_RTSP,rtsp) \
+ $(call autoconf_bool,CONFIG_LIBCURL_SMB,smb) \
+ $(call autoconf_bool,CONFIG_LIBCURL_SMTP,smtp) \
+ $(call autoconf_bool,CONFIG_LIBCURL_TELNET,telnet) \
+ $(call autoconf_bool,CONFIG_LIBCURL_TFTP,tftp) \
+ \
+ $(call autoconf_bool,CONFIG_LIBCURL_COOKIES,cookies) \
+ $(call autoconf_bool,CONFIG_LIBCURL_CRYPTO_AUTH,crypto-auth) \
+ $(call autoconf_bool,CONFIG_LIBCURL_LIBCURL_OPTION,libcurl-option) \
+ $(call autoconf_bool,CONFIG_LIBCURL_PROXY,proxy) \
+ $(call autoconf_bool,CONFIG_LIBCURL_THREADED_RESOLVER,threaded-resolver) \
+ $(call autoconf_bool,CONFIG_LIBCURL_TLS_SRP,tls-srp) \
+ $(call autoconf_bool,CONFIG_LIBCURL_UNIX_SOCKETS,unix-sockets) \
+ $(call autoconf_bool,CONFIG_LIBCURL_VERBOSE,verbose) \
+
+define Build/Compile
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+ DESTDIR="$(PKG_INSTALL_DIR)" \
+ CC="$(TARGET_CC)" \
+ install
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(2)/bin $(1)/usr/bin $(1)/usr/include $(1)/usr/lib $(1)/usr/lib/pkgconfig
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/curl-config $(1)/usr/bin/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/curl $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libcurl.{a,so*} $(1)/usr/lib/
+ $(CP) $(PKG_BUILD_DIR)/libcurl.pc $(1)/usr/lib/pkgconfig/
+ $(SED) 's,-L$$$${exec_prefix}/lib,,g' $(1)/usr/bin/curl-config
+ [ -n "$(TARGET_LDFLAGS)" ] && $(SED) 's#$(TARGET_LDFLAGS)##g' $(1)/usr/lib/pkgconfig/libcurl.pc || true
+ $(LN) $(STAGING_DIR)/usr/bin/curl-config $(2)/bin/
+endef
+
+define Package/curl/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/curl $(1)/usr/bin/
+endef
+
+define Package/libcurl/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libcurl.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,curl))
+$(eval $(call BuildPackage,libcurl))
diff --git a/package/network/utils/curl/patches/200-no_docs_tests.patch b/package/network/utils/curl/patches/200-no_docs_tests.patch
new file mode 100644
index 0000000..2845577
--- /dev/null
+++ b/package/network/utils/curl/patches/200-no_docs_tests.patch
@@ -0,0 +1,22 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -129,7 +129,7 @@ CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP)
+ bin_SCRIPTS = curl-config
+
+ SUBDIRS = lib src include
+-DIST_SUBDIRS = $(SUBDIRS) tests packages docs
++DIST_SUBDIRS = $(SUBDIRS) packages
+
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = libcurl.pc
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -577,7 +577,7 @@ CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP)
+
+ bin_SCRIPTS = curl-config
+ SUBDIRS = lib src include
+-DIST_SUBDIRS = $(SUBDIRS) tests packages docs
++DIST_SUBDIRS = $(SUBDIRS) packages
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = libcurl.pc
+ LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
diff --git a/package/network/utils/curl/patches/300-fix-disable-crypto-auth.patch b/package/network/utils/curl/patches/300-fix-disable-crypto-auth.patch
new file mode 100644
index 0000000..1cdb820
--- /dev/null
+++ b/package/network/utils/curl/patches/300-fix-disable-crypto-auth.patch
@@ -0,0 +1,25 @@
+--- a/lib/curl_ntlm_msgs.c
++++ b/lib/curl_ntlm_msgs.c
+@@ -569,7 +569,7 @@ CURLcode Curl_sasl_create_ntlm_type3_mes
+ else
+ #endif
+
+-#if USE_NTRESPONSES && USE_NTLM2SESSION
++#if USE_NTRESPONSES && USE_NTLM2SESSION && !defined(CURL_DISABLE_CRYPTO_AUTH)
+ /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
+ if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
+ unsigned char ntbuffer[0x18];
+--- a/lib/vtls/vtls.c
++++ b/lib/vtls/vtls.c
+@@ -852,9 +852,9 @@ CURLcode Curl_ssl_md5sum(unsigned char *
+ unsigned char *md5sum, /* output */
+ size_t md5len)
+ {
+-#ifdef curlssl_md5sum
++#if defined(curlssl_md5sum)
+ curlssl_md5sum(tmp, tmplen, md5sum, md5len);
+-#else
++#elif !defined(CURL_DISABLE_CRYPTO_AUTH)
+ MD5_context *MD5pw;
+
+ (void) md5len;
diff --git a/package/network/utils/curl/patches/310-polarssl-disable-runtime-version-check.patch b/package/network/utils/curl/patches/310-polarssl-disable-runtime-version-check.patch
new file mode 100644
index 0000000..1b5b63a
--- /dev/null
+++ b/package/network/utils/curl/patches/310-polarssl-disable-runtime-version-check.patch
@@ -0,0 +1,11 @@
+--- a/lib/vtls/polarssl.c
++++ b/lib/vtls/polarssl.c
+@@ -592,7 +592,7 @@ void Curl_polarssl_session_free(void *pt
+
+ size_t Curl_polarssl_version(char *buffer, size_t size)
+ {
+- unsigned int version = version_get_number();
++ unsigned int version = POLARSSL_VERSION_NUMBER;
+ return snprintf(buffer, size, "%s/%d.%d.%d",
+ version >= 0x01030A00?"mbedTLS":"PolarSSL",
+ version>>24, (version>>16)&0xff, (version>>8)&0xff);
diff --git a/package/network/utils/dante/Makefile b/package/network/utils/dante/Makefile
new file mode 100644
index 0000000..f10dd86
--- /dev/null
+++ b/package/network/utils/dante/Makefile
@@ -0,0 +1,117 @@
+#
+# Copyright (C) 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:=dante
+PKG_VERSION:=1.2.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.inet.no/dante/files/
+PKG_MD5SUM:=69b9d6234154d7d6a91fcbd98c68e62a
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=BSD-4-Clause
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+TARGET_CFLAGS += -D_GNU_SOURCE
+CONFIGURE_ARGS += \
+ --without-upnp \
+ --without-pam \
+ --disable-libwrap
+
+CONFIGURE_VARS += \
+ CC="$(TARGET_CC) $(TARGET_CFLAGS)"
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{a,so*,la} $(1)/usr/lib/
+endef
+
+
+define Package/dante/default
+ TITLE:=Dante SOCKS
+ URL:=http://www.inet.no/dante/
+endef
+
+define Package/dante/default/description
+Dante is a circuit-level firewall/proxy that can be used to provide convenient
+and secure network connectivity, requiring only that the server Dante runs on
+has external network connectivity. Dante is used daily by Fortune 100 companies
+and large international organizations, either as a standard SOCKS server or as
+a "reverse proxy".
+endef
+
+define Package/libsocks
+ $(call Package/dante/default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE+= Library
+endef
+
+define Package/libsocks/description
+$(call Package/dante/default/description)
+This package provides the shared libsocks library.
+endef
+
+define Package/libsocks/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsocks.so* $(1)/usr/lib/
+endef
+
+
+define Package/sockd
+ $(call Package/dante/default)
+ SUBMENU:=Web Servers/Proxies
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE+= Daemon
+endef
+
+define Package/sockd/description
+$(call Package/dante/default/description)
+This package provides the Dante sockd daemon.
+endef
+
+define Package/sockd/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/sockd $(1)/usr/sbin/
+endef
+
+
+define Package/socksify
+ $(call Package/dante/default)
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Web Servers/Proxies
+ TITLE+= Client
+endef
+
+define Package/socksify/description
+$(call Package/dante/default/description)
+This package provides the Dante socksify client.
+endef
+
+define Package/socksify/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(CP) $(PKG_INSTALL_DIR)/usr/bin/socksify $(1)/usr/bin/
+
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdsocks.so* $(1)/usr/lib/
+endef
+
+
+$(eval $(call BuildPackage,libsocks))
+$(eval $(call BuildPackage,sockd))
+$(eval $(call BuildPackage,socksify))
diff --git a/package/network/utils/dante/patches/001-automake-compat.patch b/package/network/utils/dante/patches/001-automake-compat.patch
new file mode 100644
index 0000000..4349a4b
--- /dev/null
+++ b/package/network/utils/dante/patches/001-automake-compat.patch
@@ -0,0 +1,482 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -16,7 +16,7 @@ echo "Configuring Dante ${version}${pren
+
+ AM_INIT_AUTOMAKE(dante, ${version}${prename})
+ AC_CONFIG_SRCDIR(include/common.h)
+-AM_CONFIG_HEADER(include/autoconf.h)
++AM_CONFIG_HEADER(autoconfig-is-soo-stupid.h include/autoconf.h)
+
+ AC_DEFINE(BAREFOOTD, 0, [we are Dante])
+
+@@ -38,17 +38,6 @@ AC_PROG_CPP
+
+ AM_CONDITIONAL(PRERELEASE, test x$prerelease != x)
+
+-#known keywords for --enable/disable-foo(=yes/no)?
+-LTINTERNAL="dlopen|dlopen_self|dlopen_self_static|fast_install|libtool_lock|win32_dll|shared_with_static_runtimes|shared_with_static_runtimes_CXX|shared_with_static_runtimes_F77"
+-KNOWN_KEYWORDS="$LTINTERNAL|shared|static|debug|warnings|diagnostic|profiling|linting|libwrap|preload|serverdl|clientdl|internal|pidfile|drt_fallback"
+-for keyword in `set | egrep '^enable_' | sed -e 's/^enable_\(.*\)=.*/\1/'`; do
+- echo $keyword | egrep "^(${KNOWN_KEYWORDS})$" > /dev/null
+- if test $? -ne 0; then
+- AC_MSG_WARN([unknown option '$keyword', ignoring ...])
+- sleep 10;
+- fi
+-done
+-
+ case $host in
+ *-*-osf*)
+ AC_MSG_WARN([OSF support might be removed in the near future.])
+@@ -175,31 +164,6 @@ case $host in
+ #XXX make sure compiling with compiler options works
+ esac
+
+-AC_MSG_CHECKING([for support for -pipe compiler flag])
+-oCFLAGS=$CFLAGS
+-CFLAGS="$CFLAGS -pipe"
+-AC_TRY_RUN([
+-int main()
+-{
+- return 0;
+-}], [AC_MSG_RESULT([yes])
+- comp_flags="${comp_flags} -pipe"],
+- AC_MSG_RESULT([no]))
+-CFLAGS="$oCFLAGS"
+-
+-AC_MSG_CHECKING([for support for -Wbounded compiler flag])
+-oCFLAGS=$CFLAGS
+-CFLAGS="$CFLAGS -Wbounded"
+-AC_TRY_RUN([
+-int main()
+-{
+- return 0;
+-}], [AC_MSG_RESULT([yes])
+- comp_flags="${comp_flags} -Wbounded"],
+- [AC_MSG_RESULT([no])
+- AC_DEFINE(__bounded__(a,b,c), , [empty __bounded__ macro])])
+-CFLAGS="$oCFLAGS"
+-
+ AC_MSG_CHECKING([for compilation with debugging])
+ AC_ARG_ENABLE(debug,
+ [ --enable-debug compile with debugging support],
+@@ -608,43 +572,6 @@ else
+ fi], [AC_MSG_RESULT(no)
+ AC_MSG_WARN([performance in the server might be degraded without support for the SO_SNDLOWAT socket option])])
+
+-AC_MSG_CHECKING([whether realloc with a NULL pointer calls malloc])
+-AC_TRY_RUN([
+-#include <stdlib.h>
+-#ifndef NULL
+-#define NULL (char *)0
+-#endif
+-
+-int main()
+-{
+- /* will assume this test doesn\'t fail because of lack of memory */
+- if (realloc(NULL, 1) == NULL)
+- return 1;
+- else
+- return 0;
+-}], [AC_MSG_RESULT(yes)],
+- [AC_DEFINE(HAVE_NOMALLOC_REALLOC, 1, [realloc never calls malloc])
+- AC_MSG_RESULT(no)])
+-
+-AC_MSG_CHECKING([whether free can be called with NULL])
+-AC_TRY_RUN([
+-#include <stdlib.h>
+-#ifndef NULL
+-#define NULL (char *)0
+-#endif
+-
+-int main()
+-{
+- /* will assume core dump/seg fault if it doesn\'t work */
+- free(NULL);
+- return 0;
+-}], [AC_MSG_RESULT(yes)],
+- [AC_DEFINE(HAVE_NONULL_FREE, 1, [free does not accept NULL parameter])
+- AC_MSG_RESULT(no)])
+-
+-#A good time to save the cache (preload code might fail)
+-AC_CACHE_SAVE
+-
+ m4_include(preload.m4)
+
+ #construct SUBDIRS variable
+@@ -722,31 +649,8 @@ case $host in
+ ;;
+ esac
+
+-AC_MSG_CHECKING([for CMSG_SPACE in sys/socket.h])
+-AC_TRY_RUN([
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-int main()
+-{
+- int d = CMSG_SPACE(4);
+- return 0;
+-}
+-], [AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_CMSG_SPACE, 1, CMSG_SPACE exists)],
+- [AC_MSG_RESULT(no)])
+-
+-AC_MSG_CHECKING([for CMSG_LEN in sys/socket.h])
+-AC_TRY_RUN([
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-
+-int main()
+-{
+- int d = CMSG_LEN(4);
+- return 0;
+-}], [AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_CMSG_LEN, 1, [CMSG_LEN exists])],
+- [AC_MSG_RESULT(no)])
++AC_DEFINE(HAVE_CMSG_SPACE, 1, [CMSG_SPACE exists])
++AC_DEFINE(HAVE_CMSG_LEN, 1, [CMSG_LEN exists])
+
+ AC_MSG_CHECKING([for sa_len in sockaddr])
+ AC_TRY_COMPILE([
+@@ -913,10 +817,6 @@ else
+ AC_MSG_RESULT([yes])
+ fi
+
+-dnl determine GSSAPI support
+-no_gssapi=t
+-m4_include(gssapi.m4)
+-
+ dnl compatibility library tests
+ m4_include(libscompat.m4)
+
+@@ -978,15 +878,6 @@ global:
+ fi
+ AC_SUBST(MAPOPT)
+
+-#expected select behaviour?
+-unset nb_select_err
+-L_UNCON_SELECT([],
+- [nb_select_err=t])
+-
+-if test x"${nb_select_err}" = xt; then
+- AC_MSG_WARN([operations on nonblocking sockets might fail on this platform])
+-fi
+-
+ AC_MSG_CHECKING([direct route fallback in client enabled])
+ with_drtfallback=t
+ AC_ARG_ENABLE(drt-fallback,
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -180,63 +180,7 @@ selectcheck(s)
+ [AC_MSG_RESULT(no)
+ [$2]])])
+
+-#can it really be this simple?
+-#nope, doesn't handle coff files which also have no underscore
+-AC_DEFUN([L_SYMBOL_UNDERSCORE],
+-[AC_MSG_CHECKING(for object file type)
+-AH_TEMPLATE([HAVE_NO_SYMBOL_UNDERSCORE], [platform symbol type])
+-AC_TRY_RUN([
+-/* look for ELF identification header at the start of argv[0] */
+-
+-#include <stdio.h>
+-#include <fcntl.h>
+-#include <string.h>
+-
+-/*
+- * ELF header, from ELF standard (Portable Formats Specification,
+- * Version 1.1).
+- */
+-char elfheader[] = { 0x7f, 'E', 'L', 'F' };
+-
+-int
+-main (argc, argv)
+- int argc;
+- char *argv[];
+-{
+- int fd;
+- int len = sizeof(elfheader);
+- char header[len];
+-
+- if ((fd = open(argv[0], O_RDONLY, 0)) == -1) {
+- perror("open");
+- exit(1);
+- }
+- if (read(fd, header, len) != len) {
+- perror("read");
+- exit(1);
+- }
+- if (memcmp(header, elfheader, len) == 0)
+- exit(0); /* pointy ears */
+- else
+- exit(1);
+-}
+-], [AC_MSG_RESULT(elf)
+- AC_DEFINE(HAVE_NO_SYMBOL_UNDERSCORE)],
+- [
+- #XXX exceptions for coff platforms, should be detected automatically
+- case $host in
+- alpha*-dec-osf*)
+- AC_DEFINE(HAVE_NO_SYMBOL_UNDERSCORE)
+- AC_MSG_RESULT(coff)
+- ;;
+- *-*-hpux*) #XXX apparently does not use underscore
+- AC_DEFINE(HAVE_NO_SYMBOL_UNDERSCORE)
+- AC_MSG_RESULT(a.out?)
+- ;;
+- *)
+- AC_MSG_RESULT(a.out)
+- ;;
+- esac])])
++AC_DEFUN([L_SYMBOL_UNDERSCORE], [AC_DEFINE(HAVE_NO_SYMBOL_UNDERSCORE, [1], [Automake sucks])])
+
+
+ dnl addproto - generate AC_DEFINE statements
+--- a/preload.m4
++++ b/preload.m4
+@@ -517,91 +517,6 @@ AC_DEFINE_UNQUOTED(LIBRARY_LIBC, "${LIBC
+
+ L_SYMBOL_UNDERSCORE()
+
+-AC_MSG_CHECKING([for working dlsym])
+-AC_TRY_RUN([
+-#include <dlfcn.h>
+-#include <stdio.h>
+-
+-#include "include/symbols.h"
+-
+-int main()
+-{
+- void *lib;
+- void *sym;
+-
+- if ((lib = dlopen(LIBRARY_CONNECT, DL_LAZY)) == NULL) {
+- fprintf(stderr, "dlopen: %s", dlerror());
+- return 1;
+- }
+- (void)dlerror();
+- if ((sym = dlsym(lib, SYMBOL_CONNECT)) == NULL) {
+- fprintf(stderr, "dlsym: %s", dlerror());
+- return 1;
+- }
+- return 0;
+-}], [AC_MSG_RESULT(yes)],
+- [AC_MSG_RESULT(no)
+- no_preload_client=t
+- no_preload_server=t
+- no_preload=t])
+-
+-AC_MSG_CHECKING([for working RTLD_NEXT])
+-AC_TRY_RUN([
+-#define _GNU_SOURCE
+-#include <dlfcn.h>
+-#include <stdio.h>
+-
+-#include "include/symbols.h"
+-
+-int main()
+-{
+- void *sym;
+-
+- if ((sym = dlsym(RTLD_NEXT, SYMBOL_READ)) == NULL) {
+- fprintf(stderr, "dlsym: %s", dlerror());
+- return 1;
+- }
+- return 0;
+-}], [AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_RTLD_NEXT, 1, [have working dlsym RTLD_NEXT])],
+- [AC_MSG_RESULT(no)
+- AC_DEFINE(HAVE_RTLD_NEXT, 0, [no working dlsym RTLD_NEXT])])
+-
+-#solaris might block preloading
+-AC_MSG_CHECKING([libc preload blocking])
+-AC_TRY_RUN([
+-#include <stdlib.h>
+-#include <string.h>
+-#include <unistd.h>
+-int
+-main(int argc, char *argv[])
+-{
+- char buf[1024];
+-
+- strcpy(buf, "lari -V ");
+- strcat(buf, argv[0]);
+- strcat(buf, " | grep read | grep protected > /dev/null");
+-
+- /*
+- * return error if 'protected'
+- * (ignore errors, not indicative of blocking) */
+- if (system(buf) == 0)
+- return 1;
+- else
+- return 0;
+-}
+-
+-ssize_t
+-read(d, buf, nbytes)
+- int d;
+- void *buf;
+- size_t nbytes;
+-{
+- return 0;
+-}
+-], [AC_MSG_RESULT(no)],
+- [AC_MSG_RESULT(yes)
+- AC_MSG_WARN([this platform blocks preloading of libraries])
+- blocked_preload=t])
++AC_DEFINE(HAVE_RTLD_NEXT, 1, [have working dlsym RTLD_NEXT])
+
+ AC_CONFIG_FILES(bin/socksify)
+--- a/libscompat.m4
++++ b/libscompat.m4
+@@ -1,70 +1,6 @@
+ dnl libscompat.m4 - tests related to replacement code in libscompat directory
+
+-AC_MSG_CHECKING([for __attribute__ support])
+-AC_TRY_RUN([
+-#include <stdlib.h>
+-
+-void errfunc(void) __attribute((noreturn));
+-
+-void errfunc(void)
+-{
+- exit(0);
+-}
+-
+-int main()
+-{
+- errfunc();
+-}], [AC_MSG_RESULT([yes])],
+- [AC_MSG_RESULT([no])
+- AC_DEFINE(__attribute__(a), , [empty __attribute__ macro])])
+-
+-AC_MSG_CHECKING([for __printf__ attribute support])
+-if test x"$have_suncc" = xt; then
+- AC_MSG_RESULT([disabled for sun cc])
+- AC_DEFINE(format(a,b,c), , [empty format attribute macro])
+-else
+- AC_TRY_RUN([
+-#include <stdlib.h>
+-
+-void func(const char *fmt, ...)
+- __attribute__((format(__printf__, 1, 2)));
+-
+-void func(const char *fmt, ...) {
+- (void)fmt;
+- return;
+-}
+-
+-int main()
+-{
+- func("foo");
+- return 0;
+-}], [AC_MSG_RESULT([yes])],
+- [AC_MSG_RESULT([no])
+- AC_DEFINE(format(a,b,c), , [empty format attribute macro])])
+-fi
+-
+-AC_MSG_CHECKING([for timer macros])
+-AC_TRY_RUN([
+-#include <sys/time.h>
+-
+-int main()
+-{
+- struct timeval tv, tv2, tv3;
+-
+- tv.tv_sec = 0;
+- tv.tv_usec = 0;
+- tv2.tv_sec = 0;
+- tv2.tv_usec = 0;
+- tv3.tv_sec = 0;
+- tv3.tv_usec = 0;
+-
+- timeradd(&tv, &tv2, &tv3);
+- timersub(&tv3, &tv2, &tv);
+-
+- return 0; }],
+-[AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_TIMER_MACROS, 1, [timeradd(), timersub etc. exist in sys/time.h])],
+-[AC_MSG_RESULT(no)])
++AC_DEFINE(HAVE_TIMER_MACROS, 1, [timeradd(), timersub etc. exist in sys/time.h])
+
+ AC_CHECK_FUNCS(daemon difftime getifaddrs freeifaddrs hstrerror inet_aton)
+ AC_CHECK_FUNCS(inet_pton issetugid memmove seteuid setegid)
+@@ -72,53 +8,7 @@ AC_CHECK_FUNCS(setproctitle sockatmark s
+ AC_CHECK_FUNCS(bzero)
+ #inet_ntoa - only checked for incorrect behavior
+
+-#try to detect gcc bug (irix 64 problem, affects among others inet_ntoa)
+-AC_MSG_CHECKING([for incorrect inet_ntoa behaviour])
+-AC_TRY_RUN([
+-#include <sys/types.h>
+-#include <netinet/in.h>
+-#include <arpa/inet.h>
+-#include <sys/socket.h>
+-int main(void)
+-{
+- struct sockaddr_in addr;
+- char *a, *b = "195.195.195.195";
+- addr.sin_addr.s_addr = inet_addr(b);
+- a = inet_ntoa(addr.sin_addr);
+- if (strcmp(a, b) == 0)
+- return 1;
+- else
+- return 0;
+-}
+-], [AC_DEFINE(HAVE_BROKEN_INET_NTOA, 1, [platform bug])
+- AC_MSG_RESULT(yes)
+- ac_cv_func_inet_ntoa=no],
+- AC_MSG_RESULT(no))
+-
+-if test x${ac_cv_func_sockatmark} = xyes; then
+- AC_MSG_CHECKING([for working sockatmark])
+- AC_TRY_RUN([
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-
+-int
+-main()
+-{
+- int s;
+- int r;
+-
+- if ((s = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
+- return 1;
+- if ((r = sockatmark(s)) == -1)
+- return 1;
+- if (r == 0)
+- return 0;
+- else
+- return 1; /* would likely indicate an error */
+-}], [AC_MSG_RESULT(yes)],
+- [AC_MSG_RESULT(no)
+- ac_cv_func_sockatmark=no])
+-fi
++ac_cv_func_sockatmark=no
+
+ #only compile files that are needed
+ unset LIBSCSRC
+@@ -139,24 +29,3 @@ AC_SUBST([LIBSCSRC])
+ if test x${ac_cv_func_bzero} = xno; then
+ AC_DEFINE(bzero(b, len), memset((b), 0, (len)), [bzero replacement])
+ fi
+-
+-#causes problems with packaging, allow test to be turned off
+-AC_ARG_WITH(glibc-secure,
+-[ --without-glibc-secure disable libc_enable_secure check @<:@default=detect@:>@],
+-[GLIBCSEC=$withval])
+-
+-if test "${GLIBCSEC}" != no; then
+- AC_MSG_CHECKING([for __libc_enable_secure])
+- AC_TRY_RUN([
+-extern int __libc_enable_secure;
+-
+-int main()
+-{
+- if (__libc_enable_secure == 0)
+- return 0;
+-
+- return 1;
+-}],[AC_MSG_RESULT([yes])
+- AC_DEFINE(HAVE_LIBC_ENABLE_SECURE, 1, [linux version of issetugid()])],
+- AC_MSG_RESULT([no]))
+-fi
diff --git a/package/network/utils/dante/patches/100-do-not-use-defdname.patch b/package/network/utils/dante/patches/100-do-not-use-defdname.patch
new file mode 100644
index 0000000..37b91a9
--- /dev/null
+++ b/package/network/utils/dante/patches/100-do-not-use-defdname.patch
@@ -0,0 +1,42 @@
+--- a/lib/addressmatch.c
++++ b/lib/addressmatch.c
+@@ -399,18 +399,6 @@ addrmatch(rule, address, protocol, alias
+ if (hostareeq(rule->addr.domain, hostent->h_name)
+ || hostisinlist(rule->addr.domain, (const char **)hostent->h_aliases))
+ matched = 1;
+-#if !HAVE_NO_RESOLVESTUFF
+- else if (strchr(hostent->h_name, '.') == NULL) {
+- /* if hostname we got is non-qualified, try to qualify it. */
+- char fqdn[MAXHOSTNAMELEN];
+-
+- snprintf(fqdn, sizeof(fqdn), "%s.%s",
+- hostent->h_name, _res.defdname);
+-
+- if (hostareeq(rule->addr.domain, fqdn))
+- matched = 1;
+- }
+-#endif /* !HAVE_NO_RESOLVESTUFF */
+ }
+
+ if (!matched && alias) {
+@@ -465,20 +453,6 @@ addrmatch(rule, address, protocol, alias
+ matched = 1;
+ break;
+ }
+-#if !HAVE_NO_RESOLVESTUFF
+- else if (strchr(ip->h_name, '.') == NULL) {
+- /* if hostname we got is non-qualified, try to qualify it. */
+- char fqdn[MAXHOSTNAMELEN];
+-
+- snprintf(fqdn, sizeof(fqdn), "%s.%s",
+- ip->h_name, _res.defdname);
+-
+- if (hostareeq(rule->addr.domain, fqdn)) {
+- matched = 1;
+- break;
+- }
+- }
+-#endif /* !HAVE_NO_RESOLVESTUFF */
+ }
+
+ hostentfree(host);
diff --git a/package/network/utils/dante/patches/200-fix-RTLD_NEXT.patch b/package/network/utils/dante/patches/200-fix-RTLD_NEXT.patch
new file mode 100644
index 0000000..7281ba6
--- /dev/null
+++ b/package/network/utils/dante/patches/200-fix-RTLD_NEXT.patch
@@ -0,0 +1,36 @@
+--- a/lib/address.c
++++ b/lib/address.c
+@@ -45,11 +45,12 @@
+
+ #include "interposition.h"
+
+-#ifndef __USE_GNU
+-#define __USE_GNU /* XXX for RTLD_NEXT on Linux */
+-#endif /* !__USE_GNU */
+ #include <dlfcn.h>
+
++#ifndef RTLD_NEXT
++#define RTLD_NEXT ((void *) -1l)
++#endif
++
+ static const char rcsid[] =
+ "$Id: address.c,v 1.177.2.2 2010/05/24 16:38:36 karls Exp $";
+
+--- a/dlib/interposition.c
++++ b/dlib/interposition.c
+@@ -66,11 +66,12 @@ sendto(HAVE_PROT_SENDTO_1, HAVE_PROT_SEN
+ HAVE_PROT_SENDTO_4, HAVE_PROT_SENDTO_5, HAVE_PROT_SENDTO_6);
+ #endif
+
+-#ifndef __USE_GNU
+-#define __USE_GNU /* XXX for RTLD_NEXT on Linux */
+-#endif /* !__USE_GNU */
+ #include <dlfcn.h>
+
++#ifndef RTLD_NEXT
++#define RTLD_NEXT ((void *) -1l)
++#endif
++
+ #undef accept
+ #undef bind
+ #undef bindresvport
diff --git a/package/network/utils/ebtables/Makefile b/package/network/utils/ebtables/Makefile
new file mode 100644
index 0000000..30bf426
--- /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_VERSION:=2.0.10-4
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)-v$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/ebtables
+PKG_MD5SUM:=506742a3d44b9925955425a659c1a8d0
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/ebtables-v$(PKG_VERSION)
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ebtables
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Firewall
+ DEPENDS:=+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/100-musl_fix.patch b/package/network/utils/ebtables/patches/100-musl_fix.patch
new file mode 100644
index 0000000..84aeb39
--- /dev/null
+++ b/package/network/utils/ebtables/patches/100-musl_fix.patch
@@ -0,0 +1,180 @@
+--- a/extensions/ebt_among.c
++++ b/extensions/ebt_among.c
+@@ -13,7 +13,6 @@
+ #include <ctype.h>
+ #include <unistd.h>
+ #include "../include/ebtables_u.h"
+-#include <netinet/ether.h>
+ #include "../include/ethernetdb.h"
+ #include <linux/if_ether.h>
+ #include <linux/netfilter_bridge/ebt_among.h>
+--- a/extensions/ebt_arpreply.c
++++ b/extensions/ebt_arpreply.c
+@@ -12,7 +12,6 @@
+ #include <string.h>
+ #include <getopt.h>
+ #include "../include/ebtables_u.h"
+-#include <netinet/ether.h>
+ #include <linux/netfilter_bridge/ebt_arpreply.h>
+
+ static int mac_supplied;
+--- a/extensions/ebt_nat.c
++++ b/extensions/ebt_nat.c
+@@ -11,7 +11,6 @@
+ #include <string.h>
+ #include <getopt.h>
+ #include "../include/ebtables_u.h"
+-#include <netinet/ether.h>
+ #include <linux/netfilter_bridge/ebt_nat.h>
+
+ static int to_source_supplied, to_dest_supplied;
+--- a/useful_functions.c
++++ b/useful_functions.c
+@@ -25,7 +25,6 @@
+ #include "include/ebtables_u.h"
+ #include "include/ethernetdb.h"
+ #include <stdio.h>
+-#include <netinet/ether.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <getopt.h>
+--- a/include/ebtables_u.h
++++ b/include/ebtables_u.h
+@@ -23,6 +23,8 @@
+
+ #ifndef EBTABLES_U_H
+ #define EBTABLES_U_H
++#include <sys/types.h>
++#include <netinet/ether.h>
+ #include <netinet/in.h>
+ #include <linux/netfilter_bridge/ebtables.h>
+ #include <linux/netfilter/x_tables.h>
+--- a/include/linux/if_ether.h
++++ /dev/null
+@@ -1,126 +0,0 @@
+-/*
+- * INET An implementation of the TCP/IP protocol suite for the LINUX
+- * operating system. INET is implemented using the BSD Socket
+- * interface as the means of communication with the user level.
+- *
+- * Global definitions for the Ethernet IEEE 802.3 interface.
+- *
+- * Version: @(#)if_ether.h 1.0.1a 02/08/94
+- *
+- * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+- * Donald Becker, <becker@super.org>
+- * Alan Cox, <alan@lxorguk.ukuu.org.uk>
+- * Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk>
+- *
+- * 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.
+- */
+-
+-#ifndef _LINUX_IF_ETHER_H
+-#define _LINUX_IF_ETHER_H
+-
+-#include <linux/types.h>
+-
+-/*
+- * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
+- * and FCS/CRC (frame check sequence).
+- */
+-
+-#define ETH_ALEN 6 /* Octets in one ethernet addr */
+-#define ETH_HLEN 14 /* Total octets in header. */
+-#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
+-#define ETH_DATA_LEN 1500 /* Max. octets in payload */
+-#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
+-#define ETH_FCS_LEN 4 /* Octets in the FCS */
+-
+-/*
+- * These are the defined Ethernet Protocol ID's.
+- */
+-
+-#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
+-#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
+-#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
+-#define ETH_P_IP 0x0800 /* Internet Protocol packet */
+-#define ETH_P_X25 0x0805 /* CCITT X.25 */
+-#define ETH_P_ARP 0x0806 /* Address Resolution packet */
+-#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
+-#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
+-#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */
+-#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
+-#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
+-#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
+-#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
+-#define ETH_P_LAT 0x6004 /* DEC LAT */
+-#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
+-#define ETH_P_CUST 0x6006 /* DEC Customer use */
+-#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
+-#define ETH_P_TEB 0x6558 /* Trans Ether Bridging */
+-#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
+-#define ETH_P_ATALK 0x809B /* Appletalk DDP */
+-#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
+-#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
+-#define ETH_P_IPX 0x8137 /* IPX over DIX */
+-#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
+-#define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */
+-#define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */
+-#define ETH_P_WCCP 0x883E /* Web-cache coordination protocol
+- * defined in draft-wilson-wrec-wccp-v2-00.txt */
+-#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
+-#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
+-#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */
+-#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */
+-#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
+-#define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */
+-#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
+- * over Ethernet
+- */
+-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+-#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
+-#define ETH_P_TIPC 0x88CA /* TIPC */
+-#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
+-#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
+-#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
+-#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
+-
+-/*
+- * Non DIX types. Won't clash for 1500 types.
+- */
+-
+-#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
+-#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
+-#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
+-#define ETH_P_802_2 0x0004 /* 802.2 frames */
+-#define ETH_P_SNAP 0x0005 /* Internal only */
+-#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
+-#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
+-#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
+-#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
+-#define ETH_P_CAN 0x000C /* Controller Area Network */
+-#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
+-#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
+-#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
+-#define ETH_P_CONTROL 0x0016 /* Card specific control frames */
+-#define ETH_P_IRDA 0x0017 /* Linux-IrDA */
+-#define ETH_P_ECONET 0x0018 /* Acorn Econet */
+-#define ETH_P_HDLC 0x0019 /* HDLC frames */
+-#define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */
+-#define ETH_P_DSA 0x001B /* Distributed Switch Arch. */
+-#define ETH_P_TRAILER 0x001C /* Trailer switch tagging */
+-#define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */
+-#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */
+-#define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */
+-
+-/*
+- * This is an Ethernet frame header.
+- */
+-
+-struct ethhdr {
+- unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
+- unsigned char h_source[ETH_ALEN]; /* source ether addr */
+- __be16 h_proto; /* packet type ID field */
+-} __attribute__((packed));
+-
+-
+-#endif /* _LINUX_IF_ETHER_H */
diff --git a/package/network/utils/iftop/Makefile b/package/network/utils/iftop/Makefile
new file mode 100644
index 0000000..037fb15
--- /dev/null
+++ b/package/network/utils/iftop/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2006 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:=iftop
+PKG_VERSION:=1.0pre2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.ex-parrot.com/~pdw/iftop/download
+PKG_MD5SUM:=fef521a49ec0122458d02c64212af3c5
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/iftop
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=+libpcap +libncurses +libpthread
+ TITLE:=display bandwith usage on an interface
+ URL:=http://www.ex-parrot.com/~pdw/iftop/
+endef
+
+define Package/iftop/description
+ iftop does for network usage what top(1) does for CPU usage. It
+ listens to network traffic on a named interface and displays a
+ table of current bandwidth usage by pairs of hosts. Handy for
+ answering the question 'why is our ADSL link so slow?'.
+endef
+
+define Package/iftop/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/iftop $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,iftop))
diff --git a/package/network/utils/iftop/patches/0001-force-ncurses.patch b/package/network/utils/iftop/patches/0001-force-ncurses.patch
new file mode 100644
index 0000000..bf23fb4
--- /dev/null
+++ b/package/network/utils/iftop/patches/0001-force-ncurses.patch
@@ -0,0 +1,12 @@
+diff -ru iftop-1.0pre2-old/configure iftop-1.0pre2/configure
+--- iftop-1.0pre2-old/configure 2011-10-04 13:30:30.000000000 -0700
++++ iftop-1.0pre2/configure 2012-09-09 22:26:05.000000000 -0700
+@@ -7568,7 +7568,7 @@
+ { $as_echo "$as_me:$LINENO: checking for a curses library containing mvchgat" >&5
+ $as_echo_n "checking for a curses library containing mvchgat... " >&6; }
+ oldLIBS=$LIBS
+-for curseslib in ncursesw curses ncurses ; do
++for curseslib in ncurses ; do
+ LIBS="$oldLIBS -l$curseslib"
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h. */
diff --git a/package/network/utils/iperf/Makefile b/package/network/utils/iperf/Makefile
new file mode 100644
index 0000000..414342d
--- /dev/null
+++ b/package/network/utils/iperf/Makefile
@@ -0,0 +1,88 @@
+#
+# Copyright (C) 2007-2010 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:=iperf
+PKG_VERSION:=2.0.5
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_MD5SUM:=44b5536b67719f4250faed632a3cd016
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=BSD-3-Clause
+
+PKG_BUILD_PARALLEL:=1
+PKG_CHECK_FORMAT_SECURITY:=0
+
+include $(INCLUDE_DIR)/uclibc++.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/iperf/Default
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:= $(CXX_DEPENDS)
+ TITLE:=Internet Protocol bandwidth measuring tool
+ URL:=http://sourceforge.net/projects/iperf/
+endef
+
+define Package/iperf/Default/description
+ Iperf is a modern alternative for measuring TCP and UDP bandwidth
+ performance, allowing the tuning of various parameters and
+ characteristics.
+endef
+
+define Package/iperf
+$(call Package/iperf/Default)
+ TITLE+= (with single thread support)
+ VARIANT:=single
+endef
+
+define Package/iperf/description
+$(call Package/iperf/Default/description)
+ This package is built with single thread support.
+endef
+
+define Package/iperf-mt
+$(call Package/iperf/Default)
+ DEPENDS+= +libpthread
+ TITLE+= (with multithread support)
+ VARIANT:=mt
+endef
+
+define Package/iperf-mt/description
+$(call Package/iperf/Default/description)
+ This package is built with multithread support.
+endef
+
+CONFIGURE_ARGS += --disable-multicast
+CONFIGURE_VARS += ac_cv_func_malloc_0_nonnull=yes
+
+ifeq ($(BUILD_VARIANT),single)
+ CONFIGURE_ARGS += --disable-threads
+else
+ CONFIGURE_ARGS += --enable-threads=posix
+ CONFIGURE_VARS += ac_cv_func_pthread_cancel=no
+endif
+
+CONFIGURE_VARS += CXXFLAGS="$$$$CXXFLAGS -fno-rtti"
+
+ifeq ($(BUILD_VARIANT),mt)
+ CONFIGURE_VARS += LIBS="-lpthread"
+endif
+
+define Package/iperf/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/iperf $(1)/usr/bin/iperf
+endef
+Package/iperf-mt/install = $(Package/iperf/install)
+
+$(eval $(call BuildPackage,iperf))
+$(eval $(call BuildPackage,iperf-mt))
diff --git a/package/network/utils/iperf/patches/001-set-report-next-time-in-single-thread-mode.patch b/package/network/utils/iperf/patches/001-set-report-next-time-in-single-thread-mode.patch
new file mode 100644
index 0000000..c61c754
--- /dev/null
+++ b/package/network/utils/iperf/patches/001-set-report-next-time-in-single-thread-mode.patch
@@ -0,0 +1,14 @@
+--- a/src/Reporter.c
++++ b/src/Reporter.c
+@@ -308,6 +308,11 @@ ReportHeader* InitReport( thread_Setting
+ #else
+ // set start time
+ gettimeofday( &(reporthdr->report.startTime), NULL );
++
++ // set next time
++ reporthdr->report.nextTime = reporthdr->report.startTime;
++ TimeAdd( reporthdr->report.nextTime, reporthdr->report.intervalTime );
++
+ /*
+ * Process the report in this thread
+ */
diff --git a/package/network/utils/iperf3/Makefile b/package/network/utils/iperf3/Makefile
new file mode 100644
index 0000000..da9c004
--- /dev/null
+++ b/package/network/utils/iperf3/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2007-2010 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:=iperf
+PKG_VERSION:=3.0.11
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://downloads.es.net/pub/iperf
+PKG_MD5SUM:=a3b2bed7961ba184566df3c3d47f96a6
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=BSD-3-Clause
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/iperf3
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Internet Protocol bandwidth measuring tool
+ URL:=https://github.com/esnet/iperf
+endef
+
+TARGET_CFLAGS += -D_GNU_SOURCE
+CONFIGURE_ARGS += --disable-shared
+
+MAKE_FLAGS += noinst_PROGRAMS=
+
+define Package/iperf3/description
+ Iperf is a modern alternative for measuring TCP and UDP bandwidth
+ performance, allowing the tuning of various parameters and
+ characteristics.
+endef
+
+define Package/iperf3/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,iperf3))
diff --git a/package/network/utils/iproute2/Makefile b/package/network/utils/iproute2/Makefile
new file mode 100644
index 0000000..e5015db
--- /dev/null
+++ b/package/network/utils/iproute2/Makefile
@@ -0,0 +1,140 @@
+#
+# 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:=4.0.0
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=http://kernel.org/pub/linux/utils/net/iproute2/
+PKG_MD5SUM:=3adc263ade4ee76c35032e8f50b54108
+PKG_BUILD_PARALLEL:=1
+PKG_LICENSE:=GPL-2.0
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/iproute2/Default
+ TITLE:=Routing control utility ($(2))
+ SECTION:=net
+ CATEGORY:=Network
+ URL:=http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
+ SUBMENU:=Routing and Redirection
+ MAINTAINER:=Russell Senior <russell@personaltelco.net>
+ DEPENDS:= +libnl-tiny
+ VARIANT:=$(1)
+endef
+
+define Package/ip
+$(call Package/iproute2/Default,tiny,Minimal)
+ CONFLICTS:=ip-full
+endef
+
+Package/ip-full=$(call Package/iproute2/Default,full,Full)
+
+define Package/ip-$(BUILD_VARIANT)/conffiles
+$(Package/ip/conffiles)
+endef
+
+define Package/tc
+$(call Package/iproute2/Default)
+ TITLE:=Traffic control utility
+ DEPENDS:=+kmod-sched-core
+endef
+
+define Package/genl
+$(call Package/iproute2/Default)
+ TITLE:=General netlink utility frontend
+endef
+
+define Package/ip-bridge
+$(call Package/iproute2/Default)
+ TITLE:=Bridge configuration utility from iproute2
+endef
+
+define Package/ss
+$(call Package/iproute2/Default)
+ TITLE:=Socket statistics utility
+endef
+
+ifeq ($(BUILD_VARIANT),tiny)
+ IP_CONFIG_TINY:=y
+endif
+
+define Build/Configure
+ $(SED) "s,-I/usr/include/db3,," $(PKG_BUILD_DIR)/Makefile
+ $(SED) "s,^KERNEL_INCLUDE.*,KERNEL_INCLUDE=$(LINUX_DIR)/include," \
+ $(PKG_BUILD_DIR)/Makefile
+ $(SED) "s,^LIBC_INCLUDE.*,LIBC_INCLUDE=$(STAGING_DIR)/include," \
+ $(PKG_BUILD_DIR)/Makefile
+ echo "static const char SNAPSHOT[] = \"$(PKG_VERSION)-$(PKG_RELEASE)-openwrt\";" \
+ > $(PKG_BUILD_DIR)/include/SNAPSHOT.h
+endef
+
+TARGET_CFLAGS += -DHAVE_SETNS
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+
+MAKE_FLAGS += \
+ EXTRA_CCOPTS="$(TARGET_CFLAGS) -I../include -I$(STAGING_DIR)/usr/include/libnl-tiny" \
+ KERNEL_INCLUDE="$(LINUX_DIR)/include" \
+ SHARED_LIBS="" \
+ LDFLAGS="$(TARGET_LDFLAGS) -Wl,--gc-sections" \
+ IP_CONFIG_TINY=$(IP_CONFIG_TINY) \
+ FPIC="$(FPIC)"
+
+define Build/Compile
+ +$(MAKE_VARS) $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(MAKE_FLAGS)
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_BUILD_DIR)/include/libnetlink.h $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/lib/libnetlink.a $(1)/usr/lib/
+endef
+
+define Package/ip/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ip/ip $(1)/usr/bin/
+endef
+
+define Package/ip-full/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ip/ip $(1)/usr/sbin/
+endef
+
+define Package/tc/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tc/tc $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+ $(INSTALL_BIN) ./files/15-teql $(1)/etc/hotplug.d/iface/
+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
+
+$(eval $(call BuildPackage,ip))
+$(eval $(call BuildPackage,ip-full))
+$(eval $(call BuildPackage,tc))
+$(eval $(call BuildPackage,genl))
+$(eval $(call BuildPackage,ip-bridge))
+$(eval $(call BuildPackage,ss))
diff --git a/package/network/utils/iproute2/files/15-teql b/package/network/utils/iproute2/files/15-teql
new file mode 100644
index 0000000..a0c0e50
--- /dev/null
+++ b/package/network/utils/iproute2/files/15-teql
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+. /lib/functions.sh
+
+if [ "$ACTION" != "ifup" ]; then
+ exit
+fi
+
+config_load network
+
+config_get teql $INTERFACE teql
+
+if [ "$teql" != "" ]; then
+ logger Adding device $DEVICE to TEQL master $teql
+ insmod sch_teql
+ tc qdisc add dev $DEVICE root $teql
+
+ # The kernel doesn't let us bring it up until it has at least one
+ # slave. So bring it up now, if it isn't already.
+ if ! cat /sys/class/net/$teql/carrier &>/dev/null; then
+ ifup $teql &
+ fi
+fi
diff --git a/package/network/utils/iproute2/patches/001-config.patch b/package/network/utils/iproute2/patches/001-config.patch
new file mode 100644
index 0000000..ece8652
--- /dev/null
+++ b/package/network/utils/iproute2/patches/001-config.patch
@@ -0,0 +1,7 @@
+--- /dev/null
++++ b/Config
+@@ -0,0 +1,4 @@
++# Fixed config to disable ATM support even if present on host system
++TC_CONFIG_ATM:=n
++TC_CONFIG_ACTION_GACT=y
++TC_CONFIG_ACTION_PROB=y
diff --git a/package/network/utils/iproute2/patches/004-darwin_fixes.patch b/package/network/utils/iproute2/patches/004-darwin_fixes.patch
new file mode 100644
index 0000000..e1a5e97
--- /dev/null
+++ b/package/network/utils/iproute2/patches/004-darwin_fixes.patch
@@ -0,0 +1,59 @@
+--- a/netem/maketable.c
++++ b/netem/maketable.c
+@@ -10,7 +10,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
+@@ -8,8 +8,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
+@@ -7,8 +7,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/006-no_sctp.patch b/package/network/utils/iproute2/patches/006-no_sctp.patch
new file mode 100644
index 0000000..4aa9884
--- /dev/null
+++ b/package/network/utils/iproute2/patches/006-no_sctp.patch
@@ -0,0 +1,18 @@
+--- a/ip/ipxfrm.c
++++ b/ip/ipxfrm.c
+@@ -467,7 +467,6 @@ void xfrm_selector_print(struct xfrm_sel
+ switch (sel->proto) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+- case IPPROTO_SCTP:
+ case IPPROTO_DCCP:
+ default: /* XXX */
+ if (sel->sport_mask)
+@@ -1337,7 +1336,6 @@ static int xfrm_selector_upspec_parse(st
+ switch (sel->proto) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+- case IPPROTO_SCTP:
+ case IPPROTO_DCCP:
+ break;
+ default:
diff --git a/package/network/utils/iproute2/patches/007-no_arpd.patch b/package/network/utils/iproute2/patches/007-no_arpd.patch
new file mode 100644
index 0000000..6a7e24e
--- /dev/null
+++ b/package/network/utils/iproute2/patches/007-no_arpd.patch
@@ -0,0 +1,11 @@
+--- a/misc/Makefile
++++ b/misc/Makefile
+@@ -1,7 +1,7 @@
+ SSOBJ=ss.o ssfilter.o
+ LNSTATOBJ=lnstat.o lnstat_util.o
+
+-TARGETS=ss nstat ifstat rtacct arpd lnstat
++TARGETS=ss nstat ifstat rtacct lnstat
+
+ include ../Config
+
diff --git a/package/network/utils/iproute2/patches/008-no_netem.patch b/package/network/utils/iproute2/patches/008-no_netem.patch
new file mode 100644
index 0000000..165ce0c
--- /dev/null
+++ b/package/network/utils/iproute2/patches/008-no_netem.patch
@@ -0,0 +1,11 @@
+--- a/Makefile
++++ b/Makefile
+@@ -36,7 +36,7 @@ WFLAGS += -Wmissing-declarations -Wold-s
+ CFLAGS = $(WFLAGS) $(CCOPTS) -I../include $(DEFINES)
+ YACCFLAGS = -d -t -v
+
+-SUBDIRS=lib ip tc bridge misc netem genl man
++SUBDIRS=lib ip tc bridge misc genl man
+
+ LIBNETLINK=../lib/libnetlink.a ../lib/libutil.a
+ LDLIBS += $(LIBNETLINK)
diff --git a/package/network/utils/iproute2/patches/010-type_fixes.patch b/package/network/utils/iproute2/patches/010-type_fixes.patch
new file mode 100644
index 0000000..e0055fc
--- /dev/null
+++ b/package/network/utils/iproute2/patches/010-type_fixes.patch
@@ -0,0 +1,396 @@
+--- a/include/iptables_common.h
++++ b/include/iptables_common.h
+@@ -2,6 +2,8 @@
+ #define _IPTABLES_COMMON_H
+ /* Shared definitions between ipv4 and ipv6. */
+
++#include <stdint.h>
++
+ enum exittype {
+ OTHER_PROBLEM = 1,
+ PARAMETER_PROBLEM,
+@@ -43,9 +45,9 @@ extern char *lib_dir;
+ extern void init_extensions(void);
+ #endif
+
+-#define __be32 u_int32_t
+-#define __le32 u_int32_t
+-#define __be16 u_int16_t
+-#define __le16 u_int16_t
++#define __be32 uint32_t
++#define __le32 uint32_t
++#define __be16 uint16_t
++#define __le16 uint16_t
+
+ #endif /*_IPTABLES_COMMON_H*/
+--- a/include/netinet/tcp.h
++++ /dev/null
+@@ -1,231 +0,0 @@
+-/*
+- * Copyright (c) 1982, 1986, 1993
+- * The Regents of the University of California. All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 4. Neither the name of the University nor the names of its contributors
+- * may be used to endorse or promote products derived from this software
+- * without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+- * SUCH DAMAGE.
+- *
+- * @(#)tcp.h 8.1 (Berkeley) 6/10/93
+- */
+-
+-#ifndef _NETINET_TCP_H
+-#define _NETINET_TCP_H 1
+-
+-#include <features.h>
+-
+-/*
+- * User-settable options (used with setsockopt).
+- */
+-#define TCP_NODELAY 1 /* Don't delay send to coalesce packets */
+-#define TCP_MAXSEG 2 /* Set maximum segment size */
+-#define TCP_CORK 3 /* Control sending of partial frames */
+-#define TCP_KEEPIDLE 4 /* Start keeplives after this period */
+-#define TCP_KEEPINTVL 5 /* Interval between keepalives */
+-#define TCP_KEEPCNT 6 /* Number of keepalives before death */
+-#define TCP_SYNCNT 7 /* Number of SYN retransmits */
+-#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
+-#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
+-#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
+-#define TCP_INFO 11 /* Information about this connection. */
+-#define TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */
+-#define TCP_CONGESTION 13 /* Congestion control algorithm. */
+-
+-#ifdef __USE_MISC
+-# include <sys/types.h>
+-
+-# ifdef __FAVOR_BSD
+-typedef u_int32_t tcp_seq;
+-/*
+- * TCP header.
+- * Per RFC 793, September, 1981.
+- */
+-struct tcphdr
+- {
+- u_int16_t th_sport; /* source port */
+- u_int16_t th_dport; /* destination port */
+- tcp_seq th_seq; /* sequence number */
+- tcp_seq th_ack; /* acknowledgement number */
+-# if __BYTE_ORDER == __LITTLE_ENDIAN
+- u_int8_t th_x2:4; /* (unused) */
+- u_int8_t th_off:4; /* data offset */
+-# endif
+-# if __BYTE_ORDER == __BIG_ENDIAN
+- u_int8_t th_off:4; /* data offset */
+- u_int8_t th_x2:4; /* (unused) */
+-# endif
+- u_int8_t th_flags;
+-# define TH_FIN 0x01
+-# define TH_SYN 0x02
+-# define TH_RST 0x04
+-# define TH_PUSH 0x08
+-# define TH_ACK 0x10
+-# define TH_URG 0x20
+- u_int16_t th_win; /* window */
+- u_int16_t th_sum; /* checksum */
+- u_int16_t th_urp; /* urgent pointer */
+-};
+-
+-# else /* !__FAVOR_BSD */
+-struct tcphdr
+- {
+- u_int16_t source;
+- u_int16_t dest;
+- u_int32_t seq;
+- u_int32_t ack_seq;
+-# if __BYTE_ORDER == __LITTLE_ENDIAN
+- u_int16_t res1:4;
+- u_int16_t doff:4;
+- u_int16_t fin:1;
+- u_int16_t syn:1;
+- u_int16_t rst:1;
+- u_int16_t psh:1;
+- u_int16_t ack:1;
+- u_int16_t urg:1;
+- u_int16_t res2:2;
+-# elif __BYTE_ORDER == __BIG_ENDIAN
+- u_int16_t doff:4;
+- u_int16_t res1:4;
+- u_int16_t res2:2;
+- u_int16_t urg:1;
+- u_int16_t ack:1;
+- u_int16_t psh:1;
+- u_int16_t rst:1;
+- u_int16_t syn:1;
+- u_int16_t fin:1;
+-# else
+-# error "Adjust your <bits/endian.h> defines"
+-# endif
+- u_int16_t window;
+- u_int16_t check;
+- u_int16_t urg_ptr;
+-};
+-# endif /* __FAVOR_BSD */
+-
+-enum
+-{
+- TCP_ESTABLISHED = 1,
+- TCP_SYN_SENT,
+- TCP_SYN_RECV,
+- TCP_FIN_WAIT1,
+- TCP_FIN_WAIT2,
+- TCP_TIME_WAIT,
+- TCP_CLOSE,
+- TCP_CLOSE_WAIT,
+- TCP_LAST_ACK,
+- TCP_LISTEN,
+- TCP_CLOSING /* now a valid state */
+-};
+-
+-# define TCPOPT_EOL 0
+-# define TCPOPT_NOP 1
+-# define TCPOPT_MAXSEG 2
+-# define TCPOLEN_MAXSEG 4
+-# define TCPOPT_WINDOW 3
+-# define TCPOLEN_WINDOW 3
+-# define TCPOPT_SACK_PERMITTED 4 /* Experimental */
+-# define TCPOLEN_SACK_PERMITTED 2
+-# define TCPOPT_SACK 5 /* Experimental */
+-# define TCPOPT_TIMESTAMP 8
+-# define TCPOLEN_TIMESTAMP 10
+-# define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
+-
+-# define TCPOPT_TSTAMP_HDR \
+- (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+-
+-/*
+- * Default maximum segment size for TCP.
+- * With an IP MSS of 576, this is 536,
+- * but 512 is probably more convenient.
+- * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
+- */
+-# define TCP_MSS 512
+-
+-# define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
+-
+-# define TCP_MAX_WINSHIFT 14 /* maximum window shift */
+-
+-# define SOL_TCP 6 /* TCP level */
+-
+-
+-# define TCPI_OPT_TIMESTAMPS 1
+-# define TCPI_OPT_SACK 2
+-# define TCPI_OPT_WSCALE 4
+-# define TCPI_OPT_ECN 8
+-# define TCPI_OPT_ECN_SEEN 16
+-
+-/* Values for tcpi_state. */
+-enum tcp_ca_state
+-{
+- TCP_CA_Open = 0,
+- TCP_CA_Disorder = 1,
+- TCP_CA_CWR = 2,
+- TCP_CA_Recovery = 3,
+- TCP_CA_Loss = 4
+-};
+-
+-struct tcp_info
+-{
+- u_int8_t tcpi_state;
+- u_int8_t tcpi_ca_state;
+- u_int8_t tcpi_retransmits;
+- u_int8_t tcpi_probes;
+- u_int8_t tcpi_backoff;
+- u_int8_t tcpi_options;
+- u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+-
+- u_int32_t tcpi_rto;
+- u_int32_t tcpi_ato;
+- u_int32_t tcpi_snd_mss;
+- u_int32_t tcpi_rcv_mss;
+-
+- u_int32_t tcpi_unacked;
+- u_int32_t tcpi_sacked;
+- u_int32_t tcpi_lost;
+- u_int32_t tcpi_retrans;
+- u_int32_t tcpi_fackets;
+-
+- /* Times. */
+- u_int32_t tcpi_last_data_sent;
+- u_int32_t tcpi_last_ack_sent; /* Not remembered, sorry. */
+- u_int32_t tcpi_last_data_recv;
+- u_int32_t tcpi_last_ack_recv;
+-
+- /* Metrics. */
+- u_int32_t tcpi_pmtu;
+- u_int32_t tcpi_rcv_ssthresh;
+- u_int32_t tcpi_rtt;
+- u_int32_t tcpi_rttvar;
+- u_int32_t tcpi_snd_ssthresh;
+- u_int32_t tcpi_snd_cwnd;
+- u_int32_t tcpi_advmss;
+- u_int32_t tcpi_reordering;
+- u_int32_t tcpi_rcv_rtt;
+- u_int32_t tcpi_rcv_space;
+- u_int32_t tcpi_total_retrans;
+-
+-};
+-
+-#endif /* Misc. */
+-
+-#endif /* netinet/tcp.h */
+--- a/include/iptables.h
++++ b/include/iptables.h
+@@ -20,7 +20,7 @@ struct ipt_get_revision
+ {
+ char name[IPT_FUNCTION_MAXNAMELEN-1];
+
+- u_int8_t revision;
++ uint8_t revision;
+ };
+ #endif /* IPT_SO_GET_REVISION_MATCH Old kernel source */
+
+@@ -39,7 +39,7 @@ struct iptables_match
+ ipt_chainlabel name;
+
+ /* Revision of match (0 by default). */
+- u_int8_t revision;
++ uint8_t revision;
+
+ const char *version;
+
+@@ -92,7 +92,7 @@ struct iptables_target
+ ipt_chainlabel name;
+
+ /* Revision of target (0 by default). */
+- u_int8_t revision;
++ uint8_t revision;
+
+ const char *version;
+
+@@ -153,7 +153,7 @@ extern char *mask_to_dotted(const struct
+
+ extern void parse_hostnetworkmask(const char *name, struct in_addr **addrpp,
+ struct in_addr *maskp, unsigned int *naddrs);
+-extern u_int16_t parse_protocol(const char *s);
++extern uint16_t parse_protocol(const char *s);
+
+ extern int do_command(int argc, char *argv[], char **table,
+ iptc_handle_t *handle);
+--- a/lib/dnet_ntop.c
++++ b/lib/dnet_ntop.c
+@@ -1,24 +1,25 @@
+ #include <errno.h>
+ #include <string.h>
++#include <stdint.h>
+ #include <sys/types.h>
+ #include <netinet/in.h>
+
+ #include "utils.h"
+
+-static __inline__ u_int16_t dn_ntohs(u_int16_t addr)
++static __inline__ uint16_t dn_ntohs(uint16_t addr)
+ {
+ union {
+- u_int8_t byte[2];
+- u_int16_t word;
++ uint8_t byte[2];
++ uint16_t word;
+ } u;
+
+ u.word = addr;
+- return ((u_int16_t)u.byte[0]) | (((u_int16_t)u.byte[1]) << 8);
++ return ((uint16_t)u.byte[0]) | (((uint16_t)u.byte[1]) << 8);
+ }
+
+-static __inline__ int do_digit(char *str, u_int16_t *addr, u_int16_t scale, size_t *pos, size_t len, int *started)
++static __inline__ int do_digit(char *str, uint16_t *addr, uint16_t scale, size_t *pos, size_t len, int *started)
+ {
+- u_int16_t tmp = *addr / scale;
++ uint16_t tmp = *addr / scale;
+
+ if (*pos == len)
+ return 1;
+@@ -36,7 +37,7 @@ static __inline__ int do_digit(char *str
+
+ static const char *dnet_ntop1(const struct dn_naddr *dna, char *str, size_t len)
+ {
+- u_int16_t addr, area;
++ uint16_t addr, area;
+ size_t pos = 0;
+ int started = 0;
+
+--- a/lib/dnet_pton.c
++++ b/lib/dnet_pton.c
+@@ -1,23 +1,24 @@
+ #include <errno.h>
+ #include <string.h>
++#include <stdint.h>
+ #include <sys/types.h>
+ #include <netinet/in.h>
+
+ #include "utils.h"
+
+-static __inline__ u_int16_t dn_htons(u_int16_t addr)
++static __inline__ uint16_t dn_htons(uint16_t addr)
+ {
+ union {
+- u_int8_t byte[2];
+- u_int16_t word;
++ uint8_t byte[2];
++ uint16_t word;
+ } u;
+
+ u.word = addr;
+- return ((u_int16_t)u.byte[0]) | (((u_int16_t)u.byte[1]) << 8);
++ return ((uint16_t)u.byte[0]) | (((uint16_t)u.byte[1]) << 8);
+ }
+
+
+-static int dnet_num(const char *src, u_int16_t * dst)
++static int dnet_num(const char *src, uint16_t * dst)
+ {
+ int rv = 0;
+ int tmp;
+@@ -38,9 +39,9 @@ static int dnet_num(const char *src, u_i
+
+ static int dnet_pton1(const char *src, struct dn_naddr *dna)
+ {
+- u_int16_t addr;
+- u_int16_t area = 0;
+- u_int16_t node = 0;
++ uint16_t addr;
++ uint16_t area = 0;
++ uint16_t node = 0;
+ int pos;
+
+ pos = dnet_num(src, &area);
+--- a/include/libiptc/ipt_kernel_headers.h
++++ b/include/libiptc/ipt_kernel_headers.h
+@@ -5,7 +5,7 @@
+
+ #include <limits.h>
+
+-#if defined(__GLIBC__) && __GLIBC__ == 2
++#if 1
+ #include <netinet/ip.h>
+ #include <netinet/in.h>
+ #include <netinet/ip_icmp.h>
diff --git a/package/network/utils/iproute2/patches/100-allow_pfifo_fast.patch b/package/network/utils/iproute2/patches/100-allow_pfifo_fast.patch
new file mode 100644
index 0000000..ce958a9
--- /dev/null
+++ b/package/network/utils/iproute2/patches/100-allow_pfifo_fast.patch
@@ -0,0 +1,9 @@
+--- a/tc/q_fifo.c
++++ b/tc/q_fifo.c
+@@ -98,5 +98,6 @@ struct qdisc_util pfifo_head_drop_qdisc_
+ extern int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
+ 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/110-extra-ccopts.patch b/package/network/utils/iproute2/patches/110-extra-ccopts.patch
new file mode 100644
index 0000000..0e36230
--- /dev/null
+++ b/package/network/utils/iproute2/patches/110-extra-ccopts.patch
@@ -0,0 +1,11 @@
+--- a/Makefile
++++ b/Makefile
+@@ -29,7 +29,7 @@ ADDLIB+=ipx_ntop.o ipx_pton.o
+ CC = gcc
+ HOSTCC = gcc
+ DEFINES += -D_GNU_SOURCE
+-CCOPTS = -O2
++CCOPTS = -O2 $(EXTRA_CCOPTS)
+ WFLAGS := -Wall -Wstrict-prototypes -Wmissing-prototypes
+ WFLAGS += -Wmissing-declarations -Wold-style-definition -Wformat=2
+
diff --git a/package/network/utils/iproute2/patches/120-libnetlink-pic.patch b/package/network/utils/iproute2/patches/120-libnetlink-pic.patch
new file mode 100644
index 0000000..19ccd1a
--- /dev/null
+++ b/package/network/utils/iproute2/patches/120-libnetlink-pic.patch
@@ -0,0 +1,11 @@
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -4,7 +4,7 @@ ifeq ($(IP_CONFIG_SETNS),y)
+ CFLAGS += -DHAVE_SETNS
+ endif
+
+-CFLAGS += -fPIC
++CFLAGS += $(FPIC)
+
+ UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o namespace.o \
+ names.o
diff --git a/package/network/utils/iproute2/patches/130-missing_include.patch b/package/network/utils/iproute2/patches/130-missing_include.patch
new file mode 100644
index 0000000..8856963
--- /dev/null
+++ b/package/network/utils/iproute2/patches/130-missing_include.patch
@@ -0,0 +1,10 @@
+--- a/lib/namespace.c
++++ b/lib/namespace.c
+@@ -9,6 +9,7 @@
+
+ #include <fcntl.h>
+ #include <dirent.h>
++#include <sys/param.h>
+
+ #include "utils.h"
+ #include "namespace.h"
diff --git a/package/network/utils/iproute2/patches/200-add-tc_esfq.patch b/package/network/utils/iproute2/patches/200-add-tc_esfq.patch
new file mode 100644
index 0000000..6c148ea
--- /dev/null
+++ b/package/network/utils/iproute2/patches/200-add-tc_esfq.patch
@@ -0,0 +1,249 @@
+--- a/tc/Makefile
++++ b/tc/Makefile
+@@ -13,6 +13,7 @@ SHARED_LIBS ?= y
+ TCMODULES :=
+ TCMODULES += q_fifo.o
+ TCMODULES += q_sfq.o
++TCMODULES += q_esfq.o
+ TCMODULES += q_red.o
+ TCMODULES += q_prio.o
+ TCMODULES += q_tbf.o
+--- a/include/linux/pkt_sched.h
++++ b/include/linux/pkt_sched.h
+@@ -226,6 +226,33 @@ struct tc_sfq_xstats {
+ __s32 allot;
+ };
+
++/* ESFQ section */
++
++enum
++{
++ /* traditional */
++ TCA_SFQ_HASH_CLASSIC,
++ TCA_SFQ_HASH_DST,
++ TCA_SFQ_HASH_SRC,
++ TCA_SFQ_HASH_FWMARK,
++ /* conntrack */
++ TCA_SFQ_HASH_CTORIGDST,
++ TCA_SFQ_HASH_CTORIGSRC,
++ TCA_SFQ_HASH_CTREPLDST,
++ TCA_SFQ_HASH_CTREPLSRC,
++ TCA_SFQ_HASH_CTNATCHG,
++};
++
++struct tc_esfq_qopt
++{
++ unsigned quantum; /* Bytes per round allocated to flow */
++ int perturb_period; /* Period of hash perturbation */
++ __u32 limit; /* Maximal packets in queue */
++ unsigned divisor; /* Hash divisor */
++ unsigned flows; /* Maximal number of flows */
++ unsigned hash_kind; /* Hash function to use for flow identification */
++};
++
+ /* RED section */
+
+ enum {
+--- /dev/null
++++ b/tc/q_esfq.c
+@@ -0,0 +1,200 @@
++/*
++ * q_esfq.c ESFQ.
++ *
++ * 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.
++ *
++ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
++ *
++ * Changes: Alexander Atanasov, <alex@ssi.bg>
++ * Alexander Clouter, <alex@digriz.org.uk>
++ * Corey Hickey, <bugfood-c@fatooh.org>
++ *
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <syslog.h>
++#include <fcntl.h>
++#include <math.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <string.h>
++
++#include "utils.h"
++#include "tc_util.h"
++
++static void explain(void)
++{
++ fprintf(stderr, "Usage: ... esfq [ perturb SECS ] [ quantum BYTES ] [ depth FLOWS ]\n\t[ divisor HASHBITS ] [ limit PKTS ] [ hash HASHTYPE]\n");
++ fprintf(stderr,"Where: \n");
++ fprintf(stderr,"HASHTYPE := { classic | src | dst | ctorigdst | ctorigsrc | ctrepldst | ctreplsrc | ctnatchg }\n");
++}
++
++#define usage() return(-1)
++
++static int esfq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
++{
++ int ok=0;
++ struct tc_esfq_qopt opt;
++
++ memset(&opt, 0, sizeof(opt));
++
++ opt.hash_kind= TCA_SFQ_HASH_CLASSIC;
++
++ while (argc > 0) {
++ if (strcmp(*argv, "quantum") == 0) {
++ NEXT_ARG();
++ if (get_size(&opt.quantum, *argv)) {
++ fprintf(stderr, "Illegal \"quantum\"\n");
++ return -1;
++ }
++ ok++;
++ } else if (strcmp(*argv, "perturb") == 0) {
++ NEXT_ARG();
++ if (get_integer(&opt.perturb_period, *argv, 0)) {
++ fprintf(stderr, "Illegal \"perturb\"\n");
++ return -1;
++ }
++ ok++;
++ } else if (strcmp(*argv, "depth") == 0) {
++ NEXT_ARG();
++ if (get_integer((int *) &opt.flows, *argv, 0)) {
++ fprintf(stderr, "Illegal \"depth\"\n");
++ return -1;
++ }
++ ok++;
++ } else if (strcmp(*argv, "divisor") == 0) {
++ NEXT_ARG();
++ if (get_integer((int *) &opt.divisor, *argv, 0)) {
++ fprintf(stderr, "Illegal \"divisor\"\n");
++ return -1;
++ }
++ if(opt.divisor >= 14) {
++ fprintf(stderr, "Illegal \"divisor\": must be < 14\n");
++ return -1;
++ }
++ opt.divisor=pow(2,opt.divisor);
++ ok++;
++ } else if (strcmp(*argv, "limit") == 0) {
++ NEXT_ARG();
++ if (get_integer((int *) &opt.limit, *argv, 0)) {
++ fprintf(stderr, "Illegal \"limit\"\n");
++ return -1;
++ }
++ ok++;
++ } else if (strcmp(*argv, "hash") == 0) {
++ NEXT_ARG();
++ if(strcmp(*argv, "classic") == 0) {
++ opt.hash_kind= TCA_SFQ_HASH_CLASSIC;
++ } else
++ if(strcmp(*argv, "dst") == 0) {
++ opt.hash_kind= TCA_SFQ_HASH_DST;
++ } else
++ if(strcmp(*argv, "src") == 0) {
++ opt.hash_kind= TCA_SFQ_HASH_SRC;
++ } else
++ if(strcmp(*argv, "ctorigsrc") == 0) {
++ opt.hash_kind= TCA_SFQ_HASH_CTORIGSRC;
++ } else
++ if(strcmp(*argv, "ctorigdst") == 0) {
++ opt.hash_kind= TCA_SFQ_HASH_CTORIGDST;
++ } else
++ if(strcmp(*argv, "ctreplsrc") == 0) {
++ opt.hash_kind= TCA_SFQ_HASH_CTREPLSRC;
++ } else
++ if(strcmp(*argv, "ctrepldst") == 0) {
++ opt.hash_kind= TCA_SFQ_HASH_CTREPLDST;
++ } else
++ if(strcmp(*argv, "ctnatchg") == 0) {
++ opt.hash_kind= TCA_SFQ_HASH_CTNATCHG;
++ } else {
++ fprintf(stderr, "Illegal \"hash\"\n");
++ explain();
++ return -1;
++ }
++ ok++;
++ } else if (strcmp(*argv, "help") == 0) {
++ explain();
++ return -1;
++ } else {
++ fprintf(stderr, "What is \"%s\"?\n", *argv);
++ explain();
++ return -1;
++ }
++ argc--; argv++;
++ }
++
++ if (ok)
++ addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
++ return 0;
++}
++
++static int esfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
++{
++ struct tc_esfq_qopt *qopt;
++ SPRINT_BUF(b1);
++
++ if (opt == NULL)
++ return 0;
++
++ if (RTA_PAYLOAD(opt) < sizeof(*qopt))
++ return -1;
++ qopt = RTA_DATA(opt);
++ fprintf(f, "quantum %s ", sprint_size(qopt->quantum, b1));
++ if (show_details) {
++ fprintf(f, "limit %up flows %u/%u ",
++ qopt->limit, qopt->flows, qopt->divisor);
++ }
++ if (qopt->perturb_period)
++ fprintf(f, "perturb %dsec ", qopt->perturb_period);
++
++ fprintf(f,"hash: ");
++ switch(qopt->hash_kind)
++ {
++ case TCA_SFQ_HASH_CLASSIC:
++ fprintf(f,"classic");
++ break;
++ case TCA_SFQ_HASH_DST:
++ fprintf(f,"dst");
++ break;
++ case TCA_SFQ_HASH_SRC:
++ fprintf(f,"src");
++ break;
++ case TCA_SFQ_HASH_CTORIGSRC:
++ fprintf(f,"ctorigsrc");
++ break;
++ case TCA_SFQ_HASH_CTORIGDST:
++ fprintf(f,"ctorigdst");
++ break;
++ case TCA_SFQ_HASH_CTREPLSRC:
++ fprintf(f,"ctreplsrc");
++ break;
++ case TCA_SFQ_HASH_CTREPLDST:
++ fprintf(f,"ctrepldst");
++ break;
++ case TCA_SFQ_HASH_CTNATCHG:
++ fprintf(f,"ctnatchg");
++ break;
++ default:
++ fprintf(f,"Unknown");
++ }
++ return 0;
++}
++
++static int esfq_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats)
++{
++ return 0;
++}
++
++
++struct qdisc_util esfq_qdisc_util = {
++ .id = "esfq",
++ .parse_qopt = esfq_parse_opt,
++ .print_qopt = esfq_print_opt,
++ .print_xstats = esfq_print_xstats,
++};
diff --git a/package/network/utils/iproute2/patches/210-add-act_connmark.patch b/package/network/utils/iproute2/patches/210-add-act_connmark.patch
new file mode 100644
index 0000000..10167ae
--- /dev/null
+++ b/package/network/utils/iproute2/patches/210-add-act_connmark.patch
@@ -0,0 +1,87 @@
+--- a/tc/Makefile
++++ b/tc/Makefile
+@@ -44,6 +44,7 @@ TCMODULES += m_mirred.o
+ TCMODULES += m_nat.o
+ TCMODULES += m_pedit.o
+ TCMODULES += m_skbedit.o
++TCMODULES += m_connmark.o
+ TCMODULES += m_csum.o
+ TCMODULES += m_simple.o
+ TCMODULES += m_vlan.o
+--- /dev/null
++++ b/tc/m_connmark.c
+@@ -0,0 +1,74 @@
++/*
++ * m_connmark.c Connection tracking marking import
++ *
++ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope 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.
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include "utils.h"
++#include "tc_util.h"
++
++static void
++explain(void)
++{
++ fprintf(stderr, "Usage: ... connmark\n");
++}
++
++static void
++usage(void)
++{
++ explain();
++ exit(-1);
++}
++
++static int
++parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
++ struct nlmsghdr *n)
++{
++ int argc = *argc_p;
++ char **argv = *argv_p;
++
++ if (matches(*argv, "connmark") != 0)
++ return -1;
++
++ NEXT_ARG();
++
++ if (matches(*argv, "help") == 0)
++ usage();
++
++ *argc_p = argc;
++ *argv_p = argv;
++ return 0;
++}
++
++static int print_connmark(struct action_util *au, FILE *f, struct rtattr *arg)
++{
++ if (arg == NULL)
++ return -1;
++
++ fprintf(f, " connmark");
++
++ return 0;
++}
++
++struct action_util connmark_action_util = {
++ .id = "connmark",
++ .parse_aopt = parse_connmark,
++ .print_aopt = print_connmark,
++};
diff --git a/package/network/utils/iproute2/patches/300-ip_tiny.patch b/package/network/utils/iproute2/patches/300-ip_tiny.patch
new file mode 100644
index 0000000..14518dc
--- /dev/null
+++ b/package/network/utils/iproute2/patches/300-ip_tiny.patch
@@ -0,0 +1,101 @@
+--- a/ip/Makefile
++++ b/ip/Makefile
+@@ -16,6 +16,13 @@ ifeq ($(IP_CONFIG_SETNS),y)
+ CFLAGS += -DHAVE_SETNS
+ endif
+
++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=ifcfg rtpr routel routef
+ TARGETS=ip rtmon
+@@ -43,7 +50,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
+@@ -71,30 +71,42 @@ 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 },
++#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 },
++#endif
+ { "mroute", do_multiroute },
+ { "mrule", do_multirule },
+ { "netns", do_netns },
++#ifndef IPROUTE2_TINY
+ { "netconf", do_ipnetconf },
++#endif
+ { "help", do_help },
+ { 0 }
+ };
+--- a/lib/utils.c
++++ b/lib/utils.c
+@@ -642,6 +642,7 @@ const char *rt_addr_n2a(int af, const vo
+ case AF_INET:
+ case AF_INET6:
+ return inet_ntop(af, addr, buf, buflen);
++#ifndef IPROUTE2_TINY
+ case AF_IPX:
+ return ipx_ntop(af, addr, buf, buflen);
+ case AF_DECnet:
+@@ -650,6 +651,7 @@ const char *rt_addr_n2a(int af, const vo
+ memcpy(dna.a_addr, addr, 2);
+ return dnet_ntop(af, &dna, buf, buflen);
+ }
++#endif
+ default:
+ return "???";
+ }
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -4,6 +4,10 @@ ifeq ($(IP_CONFIG_SETNS),y)
+ CFLAGS += -DHAVE_SETNS
+ endif
+
++ifeq ($(IP_CONFIG_TINY),y)
++ CFLAGS += -DIPROUTE2_TINY
++endif
++
+ CFLAGS += $(FPIC)
+
+ UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o namespace.o \
diff --git a/package/network/utils/iproute2/patches/900-drop_FAILED_POLICY.patch b/package/network/utils/iproute2/patches/900-drop_FAILED_POLICY.patch
new file mode 100644
index 0000000..f5d2dfe
--- /dev/null
+++ b/package/network/utils/iproute2/patches/900-drop_FAILED_POLICY.patch
@@ -0,0 +1,54 @@
+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/include/linux/fib_rules.h
++++ b/include/linux/fib_rules.h
+@@ -64,6 +64,10 @@ enum {
+ FR_ACT_BLACKHOLE, /* Drop without notification */
+ FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */
+ FR_ACT_PROHIBIT, /* Drop with EACCES */
++ FR_ACT_RES8,
++ FR_ACT_RES9,
++ FR_ACT_RES10,
++ FR_ACT_FAILED_POLICY, /* Drop with EPERM */
+ __FR_ACT_MAX,
+ };
+
+--- a/include/linux/rtnetlink.h
++++ b/include/linux/rtnetlink.h
+@@ -208,6 +208,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
+ };
+
+--- 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)
diff --git a/package/network/utils/iproute2/patches/910-sanitize_headers_for_musl.patch b/package/network/utils/iproute2/patches/910-sanitize_headers_for_musl.patch
new file mode 100644
index 0000000..ca1125d
--- /dev/null
+++ b/package/network/utils/iproute2/patches/910-sanitize_headers_for_musl.patch
@@ -0,0 +1,10 @@
+--- a/include/linux/if_bridge.h
++++ b/include/linux/if_bridge.h
+@@ -15,7 +15,6 @@
+
+ #include <linux/types.h>
+ #include <linux/if_ether.h>
+-#include <linux/in6.h>
+
+ #define SYSFS_BRIDGE_ATTR "bridge"
+ #define SYSFS_BRIDGE_FDB "brforward"
diff --git a/package/network/utils/ipset/Makefile b/package/network/utils/ipset/Makefile
new file mode 100644
index 0000000..f1c50a9
--- /dev/null
+++ b/package/network/utils/ipset/Makefile
@@ -0,0 +1,53 @@
+
+# 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:=6.24
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://ipset.netfilter.org
+PKG_MD5SUM:=8831b8f01458bf2abacc222884195a62
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ipset
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS+= +kmod-ipt-ipset +libmnl
+ TITLE:=IPset administration utility
+ URL:=http://ipset.netfilter.org/
+endef
+
+CONFIGURE_ARGS += \
+ --with-kbuild="$(LINUX_DIR)"
+
+MAKE_FLAGS += \
+ ARCH="$(LINUX_KARCH)" \
+ SHELL="$(BASH)"
+
+define Build/Compile
+ $(call Build/Compile/Default)
+endef
+
+define Package/ipset/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/ipset $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libipset*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,ipset))
diff --git a/package/network/utils/iptables/Makefile b/package/network/utils/iptables/Makefile
new file mode 100644
index 0000000..626b252
--- /dev/null
+++ b/package/network/utils/iptables/Makefile
@@ -0,0 +1,548 @@
+#
+# Copyright (C) 2006-2013 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.4.21
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://www.netfilter.org/projects/iptables/files \
+ ftp://ftp.be.netfilter.org/pub/netfilter/iptables/ \
+ ftp://ftp.de.netfilter.org/pub/netfilter/iptables/ \
+ ftp://ftp.no.netfilter.org/pub/netfilter/iptables/
+PKG_MD5SUM:=536d048c8e8eeebcd9757d0863ebb0c0
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_LICENSE:=GPL-2.0
+
+ifneq ($(CONFIG_EXTERNAL_KERNEL_TREE),"")
+PATCH_DIR:=
+endif
+
+include $(INCLUDE_DIR)/package.mk
+ifeq ($(DUMP),)
+ -include $(LINUX_DIR)/.config
+ include $(INCLUDE_DIR)/netfilter.mk
+ STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell $(SH_FUNC) grep 'NETFILTER' $(LINUX_DIR)/.config | md5s)
+endif
+
+
+define Package/iptables/Default
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Firewall
+ URL:=http://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+= +kmod-ipt-core +libip4tc +IPV6:libip6tc +libxtables
+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
+ - LOG
+ - MARK
+ - MASQUERADE
+ - REDIRECT
+ - SET
+ - SNAT
+ - TCPMSS
+
+ Tables:
+ - filter
+ - mangle
+ - nat
+ - raw
+
+endef
+
+define Package/iptables-mod-conntrack-extra
+$(call Package/iptables/Module, +kmod-ipt-conntrack-extra)
+ 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-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
+
+endef
+
+define Package/iptables-mod-ipopt
+$(call Package/iptables/Module, +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-ulog
+$(call Package/iptables/Module, +kmod-ipt-ulog)
+ TITLE:=user-space packet logging
+endef
+
+define Package/iptables-mod-ulog/description
+iptables extensions for user-space packet logging.
+
+ Targets:
+ - ULOG
+
+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-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-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
+ - physdev (if ebtables is enabled)
+ - pkttype
+ - quota
+
+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-tproxy
+$(call Package/iptables/Module, +kmod-ipt-tproxy)
+ TITLE:=Transparent proxy iptables extensions
+endef
+
+define Package/iptables-mod-tproxy/description
+Transparent proxy iptables extensions.
+
+ Matches:
+ - socket
+
+ 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/ip6tables
+$(call Package/iptables/Default)
+ DEPENDS:=@IPV6 +kmod-ip6tables +iptables
+ CATEGORY:=Network
+ TITLE:=IPv6 firewall administration tool
+ MENU:=1
+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/libiptc
+$(call Package/iptables/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=+libip4tc +libip6tc +libxtables
+ TITLE:=IPv4/IPv6 firewall - shared libiptc library (compatibility stub)
+endef
+
+define Package/libip4tc
+$(call Package/iptables/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=IPv4 firewall - shared libiptc library
+ DEPENDS:=+libxtables
+endef
+
+define Package/libip6tc
+$(call Package/iptables/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=IPv6 firewall - shared libiptc library
+ DEPENDS:=+libxtables
+endef
+
+define Package/libxtables
+ $(call Package/iptables/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=IPv4/IPv6 firewall - shared xtables library
+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-devel \
+ --with-kernel="$(LINUX_DIR)/user_headers" \
+ --with-xtlibdir=/usr/lib/iptables \
+ --enable-static \
+ $(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))))"
+
+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-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/ip6tables/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/ip6tables{,-restore,-save} $(1)/usr/sbin/
+endef
+
+define Package/libiptc/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libiptc.so* $(1)/usr/lib/
+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 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,iptables))
+$(eval $(call BuildPlugin,iptables-mod-conntrack-extra,$(IPT_CONNTRACK_EXTRA-m)))
+$(eval $(call BuildPlugin,iptables-mod-extra,$(IPT_EXTRA-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-ulog,$(IPT_ULOG-m)))
+$(eval $(call BuildPlugin,iptables-mod-hashlimit,$(IPT_HASHLIMIT-m)))
+$(eval $(call BuildPlugin,iptables-mod-led,$(IPT_LED-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-nfqueue,$(IPT_NFQUEUE-m)))
+$(eval $(call BuildPackage,ip6tables))
+$(eval $(call BuildPlugin,ip6tables-extra,$(IPT_IPV6_EXTRA-m)))
+$(eval $(call BuildPlugin,ip6tables-mod-nat,$(IPT_NAT6-m)))
+$(eval $(call BuildPackage,libiptc))
+$(eval $(call BuildPackage,libip4tc))
+$(eval $(call BuildPackage,libip6tc))
+$(eval $(call BuildPackage,libxtables))
diff --git a/package/network/utils/iptables/patches/020-iptables-disable-modprobe.patch b/package/network/utils/iptables/patches/020-iptables-disable-modprobe.patch
new file mode 100644
index 0000000..2b6c57e
--- /dev/null
+++ b/package/network/utils/iptables/patches/020-iptables-disable-modprobe.patch
@@ -0,0 +1,18 @@
+--- a/libxtables/xtables.c
++++ b/libxtables/xtables.c
+@@ -336,6 +336,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;
+@@ -380,6 +381,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/030-no-libnfnetlink.patch b/package/network/utils/iptables/patches/030-no-libnfnetlink.patch
new file mode 100644
index 0000000..50542ac
--- /dev/null
+++ b/package/network/utils/iptables/patches/030-no-libnfnetlink.patch
@@ -0,0 +1,94 @@
+--- a/configure
++++ b/configure
+@@ -12367,77 +12367,7 @@ fi
+ fi
+
+
+-pkg_failed=no
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libnfnetlink" >&5
+-$as_echo_n "checking for libnfnetlink... " >&6; }
+-
+-if test -n "$libnfnetlink_CFLAGS"; then
+- pkg_cv_libnfnetlink_CFLAGS="$libnfnetlink_CFLAGS"
+- elif test -n "$PKG_CONFIG"; then
+- if test -n "$PKG_CONFIG" && \
+- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnfnetlink >= 1.0\""; } >&5
+- ($PKG_CONFIG --exists --print-errors "libnfnetlink >= 1.0") 2>&5
+- ac_status=$?
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+- test $ac_status = 0; }; then
+- pkg_cv_libnfnetlink_CFLAGS=`$PKG_CONFIG --cflags "libnfnetlink >= 1.0" 2>/dev/null`
+- test "x$?" != "x0" && pkg_failed=yes
+-else
+- pkg_failed=yes
+-fi
+- else
+- pkg_failed=untried
+-fi
+-if test -n "$libnfnetlink_LIBS"; then
+- pkg_cv_libnfnetlink_LIBS="$libnfnetlink_LIBS"
+- elif test -n "$PKG_CONFIG"; then
+- if test -n "$PKG_CONFIG" && \
+- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnfnetlink >= 1.0\""; } >&5
+- ($PKG_CONFIG --exists --print-errors "libnfnetlink >= 1.0") 2>&5
+- ac_status=$?
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+- test $ac_status = 0; }; then
+- pkg_cv_libnfnetlink_LIBS=`$PKG_CONFIG --libs "libnfnetlink >= 1.0" 2>/dev/null`
+- test "x$?" != "x0" && pkg_failed=yes
+-else
+- pkg_failed=yes
+-fi
+- else
+- pkg_failed=untried
+-fi
+-
+-
+-
+-if test $pkg_failed = yes; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
+-
+-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+- _pkg_short_errors_supported=yes
+-else
+- _pkg_short_errors_supported=no
+-fi
+- if test $_pkg_short_errors_supported = yes; then
+- libnfnetlink_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnfnetlink >= 1.0" 2>&1`
+- else
+- libnfnetlink_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnfnetlink >= 1.0" 2>&1`
+- fi
+- # Put the nasty error message in config.log where it belongs
+- echo "$libnfnetlink_PKG_ERRORS" >&5
+-
+- nfnetlink=0
+-elif test $pkg_failed = untried; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
+- nfnetlink=0
+-else
+- libnfnetlink_CFLAGS=$pkg_cv_libnfnetlink_CFLAGS
+- libnfnetlink_LIBS=$pkg_cv_libnfnetlink_LIBS
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- nfnetlink=1
+-fi
+- if test "$nfnetlink" = 1; then
++if false; then
+ HAVE_LIBNFNETLINK_TRUE=
+ HAVE_LIBNFNETLINK_FALSE='#'
+ else
+--- a/configure.ac
++++ b/configure.ac
+@@ -111,9 +111,7 @@ if test "x$enable_bpfc" = "xyes" || test
+ AC_CHECK_LIB(pcap, pcap_compile,, AC_MSG_ERROR(missing libpcap library required by bpf compiler or nfsynproxy tool))
+ fi
+
+-PKG_CHECK_MODULES([libnfnetlink], [libnfnetlink >= 1.0],
+- [nfnetlink=1], [nfnetlink=0])
+-AM_CONDITIONAL([HAVE_LIBNFNETLINK], [test "$nfnetlink" = 1])
++AM_CONDITIONAL([HAVE_LIBNFNETLINK], [false])
+
+ regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
+ -Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \
diff --git a/package/network/utils/iptables/patches/050-optional-xml.patch b/package/network/utils/iptables/patches/050-optional-xml.patch
new file mode 100644
index 0000000..11311dd
--- /dev/null
+++ b/package/network/utils/iptables/patches/050-optional-xml.patch
@@ -0,0 +1,13 @@
+--- a/iptables/xtables-multi.c
++++ b/iptables/xtables-multi.c
+@@ -22,8 +22,10 @@ static const struct subcommand multi_sub
+ {"iptables-restore", iptables_restore_main},
+ {"restore4", iptables_restore_main},
+ #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/100-bash-location.patch b/package/network/utils/iptables/patches/100-bash-location.patch
new file mode 100644
index 0000000..02ee45b
--- /dev/null
+++ b/package/network/utils/iptables/patches/100-bash-location.patch
@@ -0,0 +1,8 @@
+--- a/iptables/iptables-apply
++++ b/iptables/iptables-apply
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/usr/bin/env bash
+ #
+ # iptables-apply -- a safer way to update iptables remotely
+ #
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..d35bc5a
--- /dev/null
+++ b/package/network/utils/iptables/patches/200-configurable_builtin.patch
@@ -0,0 +1,60 @@
+--- a/extensions/GNUmakefile.in
++++ b/extensions/GNUmakefile.in
+@@ -45,9 +45,24 @@ pfx_symlinks := NOTRACK state
+ pfx_build_mod := $(filter-out @blacklist_modules@,${pfx_build_mod})
+ pf4_build_mod := $(filter-out @blacklist_modules@,${pf4_build_mod})
+ pf6_build_mod := $(filter-out @blacklist_modules@,${pf6_build_mod})
+-pfx_objs := $(patsubst %,libxt_%.o,${pfx_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})
++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@ 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))
++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})
++pf4_objs := $(patsubst %,libipt_%.o,${pf4_build_static})
++pf6_objs := $(patsubst %,libip6t_%.o,${pf6_build_static})
+ pfx_solibs := $(patsubst %,libxt_%.so,${pfx_build_mod} ${pfx_symlinks})
+ pf4_solibs := $(patsubst %,libipt_%.so,${pf4_build_mod})
+ pf6_solibs := $(patsubst %,libip6t_%.so,${pf6_build_mod})
+@@ -58,11 +73,11 @@ pf6_solibs := $(patsubst %,libip6t_%.
+ #
+ targets := libext.a libext4.a libext6.a matches.man targets.man
+ targets_install :=
+-@ENABLE_STATIC_TRUE@ libext_objs := ${pfx_objs}
+-@ENABLE_STATIC_TRUE@ libext4_objs := ${pf4_objs}
+-@ENABLE_STATIC_TRUE@ libext6_objs := ${pf6_objs}
+-@ENABLE_STATIC_FALSE@ targets += ${pfx_solibs} ${pf4_solibs} ${pf6_solibs}
+-@ENABLE_STATIC_FALSE@ targets_install += ${pfx_solibs} ${pf4_solibs} ${pf6_solibs}
++libext_objs := ${pfx_objs}
++libext4_objs := ${pf4_objs}
++libext6_objs := ${pf6_objs}
++targets += ${pfx_solibs} ${pf4_solibs} ${pf6_solibs}
++targets_install := $(strip ${targets_install} ${pfx_solibs} ${pf4_solibs} ${pf6_solibs})
+
+ .SECONDARY:
+
+@@ -126,9 +141,9 @@ libext4.a: initext4.o ${libext4_objs}
+ libext6.a: initext6.o ${libext6_objs}
+ ${AM_VERBOSE_AR} ${AR} crs $@ $^;
+
+-initext_func := $(addprefix xt_,${pfx_build_mod})
+-initext4_func := $(addprefix ipt_,${pf4_build_mod})
+-initext6_func := $(addprefix ip6t_,${pf6_build_mod})
++initext_func := $(addprefix xt_,${pfx_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/300-musl_fixes.patch b/package/network/utils/iptables/patches/300-musl_fixes.patch
new file mode 100644
index 0000000..a78eda7
--- /dev/null
+++ b/package/network/utils/iptables/patches/300-musl_fixes.patch
@@ -0,0 +1,127 @@
+--- a/extensions/libip6t_ipv6header.c
++++ b/extensions/libip6t_ipv6header.c
+@@ -10,6 +10,9 @@ on whether they contain certain headers
+ #include <netdb.h>
+ #include <xtables.h>
+ #include <linux/netfilter_ipv6/ip6t_ipv6header.h>
++#ifndef IPPROTO_HOPOPTS
++# define IPPROTO_HOPOPTS 0
++#endif
+
+ enum {
+ O_HEADER = 0,
+--- a/extensions/libxt_TCPOPTSTRIP.c
++++ b/extensions/libxt_TCPOPTSTRIP.c
+@@ -12,6 +12,21 @@
+ #ifndef TCPOPT_MD5SIG
+ # define TCPOPT_MD5SIG 19
+ #endif
++#ifndef TCPOPT_MAXSEG
++# define TCPOPT_MAXSEG 2
++#endif
++#ifndef TCPOPT_WINDOW
++# define TCPOPT_WINDOW 3
++#endif
++#ifndef TCPOPT_SACK_PERMITTED
++# define TCPOPT_SACK_PERMITTED 4
++#endif
++#ifndef TCPOPT_SACK
++# define TCPOPT_SACK 5
++#endif
++#ifndef TCPOPT_TIMESTAMP
++# define TCPOPT_TIMESTAMP 8
++#endif
+
+ enum {
+ O_STRIP_OPTION = 0,
+--- a/include/libiptc/ipt_kernel_headers.h
++++ b/include/libiptc/ipt_kernel_headers.h
+@@ -5,7 +5,6 @@
+
+ #include <limits.h>
+
+-#if defined(__GLIBC__) && __GLIBC__ == 2
+ #include <netinet/ip.h>
+ #include <netinet/in.h>
+ #include <netinet/ip_icmp.h>
+@@ -13,15 +12,4 @@
+ #include <netinet/udp.h>
+ #include <net/if.h>
+ #include <sys/types.h>
+-#else /* libc5 */
+-#include <sys/socket.h>
+-#include <linux/ip.h>
+-#include <linux/in.h>
+-#include <linux/if.h>
+-#include <linux/icmp.h>
+-#include <linux/tcp.h>
+-#include <linux/udp.h>
+-#include <linux/types.h>
+-#include <linux/in6.h>
+-#endif
+ #endif
+--- a/include/linux/netfilter_ipv4/ip_tables.h
++++ b/include/linux/netfilter_ipv4/ip_tables.h
+@@ -16,6 +16,7 @@
+ #define _IPTABLES_H
+
+ #include <linux/types.h>
++#include <sys/types.h>
+
+ #include <linux/netfilter_ipv4.h>
+
+--- a/iptables/ip6tables-restore.c
++++ b/iptables/ip6tables-restore.c
+@@ -9,7 +9,7 @@
+ */
+
+ #include <getopt.h>
+-#include <sys/errno.h>
++#include <errno.h>
+ #include <stdbool.h>
+ #include <string.h>
+ #include <stdio.h>
+--- a/iptables/ip6tables-save.c
++++ b/iptables/ip6tables-save.c
+@@ -6,7 +6,7 @@
+ * This code is distributed under the terms of GNU GPL v2
+ */
+ #include <getopt.h>
+-#include <sys/errno.h>
++#include <errno.h>
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <stdlib.h>
+--- a/iptables/iptables-restore.c
++++ b/iptables/iptables-restore.c
+@@ -6,7 +6,7 @@
+ */
+
+ #include <getopt.h>
+-#include <sys/errno.h>
++#include <errno.h>
+ #include <stdbool.h>
+ #include <string.h>
+ #include <stdio.h>
+--- a/iptables/iptables-save.c
++++ b/iptables/iptables-save.c
+@@ -6,7 +6,7 @@
+ *
+ */
+ #include <getopt.h>
+-#include <sys/errno.h>
++#include <errno.h>
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <stdlib.h>
+--- a/iptables/iptables-xml.c
++++ b/iptables/iptables-xml.c
+@@ -7,7 +7,7 @@
+ */
+
+ #include <getopt.h>
+-#include <sys/errno.h>
++#include <errno.h>
+ #include <string.h>
+ #include <stdio.h>
+ #include <stdlib.h>
diff --git a/package/network/utils/iptables/patches/500-add-xt_id-match.patch b/package/network/utils/iptables/patches/500-add-xt_id-match.patch
new file mode 100644
index 0000000..94762f0
--- /dev/null
+++ b/package/network/utils/iptables/patches/500-add-xt_id-match.patch
@@ -0,0 +1,59 @@
+--- /dev/null
++++ b/extensions/libxt_id.c
+@@ -0,0 +1,45 @@
++/* Shared library add-on to iptables to add id match support. */
++
++#include <stdio.h>
++#include <xtables.h>
++#include <linux/netfilter/xt_id.h>
++
++enum {
++ O_ID = 0,
++};
++
++static const struct xt_option_entry id_opts[] = {
++ {
++ .name = "id",
++ .id = O_ID,
++ .type = XTTYPE_UINT32,
++ .flags = XTOPT_MAND | XTOPT_PUT,
++ XTOPT_POINTER(struct xt_id_info, id)
++ },
++ XTOPT_TABLEEND,
++};
++
++/* Saves the union ipt_matchinfo in parsable form to stdout. */
++static void
++id_save(const void *ip, const struct xt_entry_match *match)
++{
++ struct xt_id_info *idinfo = (void *)match->data;
++
++ printf(" --id %lu", idinfo->id);
++}
++
++static struct xtables_match id_match = {
++ .family = NFPROTO_UNSPEC,
++ .name = "id",
++ .version = XTABLES_VERSION,
++ .size = XT_ALIGN(sizeof(struct xt_id_info)),
++ .userspacesize = XT_ALIGN(sizeof(struct xt_id_info)),
++ .save = id_save,
++ .x6_parse = xtables_option_parse,
++ .x6_options = id_opts,
++};
++
++void _init(void)
++{
++ xtables_register_match(&id_match);
++}
+--- /dev/null
++++ b/include/linux/netfilter/xt_id.h
+@@ -0,0 +1,8 @@
++#ifndef _XT_ID_H
++#define _XT_ID_H
++
++struct xt_id_info {
++ __u32 id;
++};
++
++#endif /* XT_ID_H */
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..92f5485
--- /dev/null
+++ b/package/network/utils/iptables/patches/600-shared-libext.patch
@@ -0,0 +1,78 @@
+Index: iptables-1.4.21/extensions/GNUmakefile.in
+===================================================================
+--- iptables-1.4.21.orig/extensions/GNUmakefile.in
++++ iptables-1.4.21/extensions/GNUmakefile.in
+@@ -71,7 +71,7 @@ pf6_solibs := $(patsubst %,libip6t_%.
+ #
+ # Building blocks
+ #
+-targets := libext.a libext4.a libext6.a matches.man targets.man
++targets := libiptext.so libiptext4.so libiptext6.so matches.man targets.man
+ targets_install :=
+ libext_objs := ${pfx_objs}
+ libext4_objs := ${pf4_objs}
+@@ -96,7 +96,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
+
+@@ -130,16 +130,16 @@ xt_statistic_LIBADD = -lm
+ # 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 ${$*_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 ${$*_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 ${$*_LIBADD};
+
+ initext_func := $(addprefix xt_,${pfx_build_static})
+ initext4_func := $(addprefix ipt_,${pf4_build_static})
+Index: iptables-1.4.21/iptables/Makefile.am
+===================================================================
+--- iptables-1.4.21.orig/iptables/Makefile.am
++++ iptables-1.4.21/iptables/Makefile.am
+@@ -5,7 +5,8 @@ AM_CPPFLAGS = ${regular_CPPFLAGS} -
+
+ xtables_multi_SOURCES = xtables-multi.c iptables-xml.c
+ xtables_multi_CFLAGS = ${AM_CFLAGS}
+-xtables_multi_LDADD = ../extensions/libext.a
++xtables_multi_LDADD =
++xtables_multi_LDFLAGS = -L../extensions/ -liptext
+ if ENABLE_STATIC
+ xtables_multi_CFLAGS += -DALL_INCLUSIVE
+ endif
+@@ -13,13 +14,15 @@ if ENABLE_IPV4
+ xtables_multi_SOURCES += iptables-save.c iptables-restore.c \
+ iptables-standalone.c iptables.c
+ xtables_multi_CFLAGS += -DENABLE_IPV4
+-xtables_multi_LDADD += ../libiptc/libip4tc.la ../extensions/libext4.a
++xtables_multi_LDADD += ../libiptc/libip4tc.la
++xtables_multi_LDFLAGS += -liptext4
+ endif
+ if ENABLE_IPV6
+ xtables_multi_SOURCES += ip6tables-save.c ip6tables-restore.c \
+ ip6tables-standalone.c ip6tables.c
+ xtables_multi_CFLAGS += -DENABLE_IPV6
+-xtables_multi_LDADD += ../libiptc/libip6tc.la ../extensions/libext6.a
++xtables_multi_LDADD += ../libiptc/libip6tc.la
++xtables_multi_LDFLAGS += -liptext6
+ endif
+ xtables_multi_SOURCES += xshared.c
+ xtables_multi_LDADD += ../libxtables/libxtables.la -lm
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..342c3b0
--- /dev/null
+++ b/package/network/utils/iptables/patches/700-disable-legacy-revisions.patch
@@ -0,0 +1,108 @@
+Index: iptables-1.4.21/extensions/libxt_conntrack.c
+===================================================================
+--- iptables-1.4.21.orig/extensions/libxt_conntrack.c
++++ iptables-1.4.21/extensions/libxt_conntrack.c
+@@ -1157,6 +1157,7 @@ static void state_save(const void *ip, c
+ }
+
+ static struct xtables_match conntrack_mt_reg[] = {
++#ifndef NO_LEGACY
+ {
+ .version = XTABLES_VERSION,
+ .name = "conntrack",
+@@ -1232,6 +1233,7 @@ static struct xtables_match conntrack_mt
+ .alias = conntrack_print_name_alias,
+ .x6_options = conntrack2_mt_opts,
+ },
++#endif
+ {
+ .version = XTABLES_VERSION,
+ .name = "conntrack",
+@@ -1262,6 +1264,7 @@ static struct xtables_match conntrack_mt
+ .alias = conntrack_print_name_alias,
+ .x6_options = conntrack3_mt_opts,
+ },
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "state",
+@@ -1292,6 +1295,7 @@ static struct xtables_match conntrack_mt
+ .x6_parse = state_ct23_parse,
+ .x6_options = state_opts,
+ },
++#endif
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "state",
+@@ -1307,6 +1311,7 @@ static struct xtables_match conntrack_mt
+ .x6_parse = state_ct23_parse,
+ .x6_options = state_opts,
+ },
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "state",
+@@ -1320,6 +1325,7 @@ static struct xtables_match conntrack_mt
+ .x6_parse = state_parse,
+ .x6_options = state_opts,
+ },
++#endif
+ };
+
+ void _init(void)
+Index: iptables-1.4.21/extensions/libxt_CT.c
+===================================================================
+--- iptables-1.4.21.orig/extensions/libxt_CT.c
++++ iptables-1.4.21/extensions/libxt_CT.c
+@@ -290,6 +290,7 @@ static void notrack_ct2_tg_init(struct x
+ }
+
+ static struct xtables_target ct_target_reg[] = {
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "CT",
+@@ -315,6 +316,7 @@ static struct xtables_target ct_target_r
+ .x6_parse = ct_parse_v1,
+ .x6_options = ct_opts_v1,
+ },
++#endif
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "CT",
+@@ -329,6 +331,7 @@ static struct xtables_target ct_target_r
+ .x6_parse = ct_parse_v1,
+ .x6_options = ct_opts_v1,
+ },
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_UNSPEC,
+ .name = "NOTRACK",
+@@ -366,6 +369,7 @@ static struct xtables_target ct_target_r
+ .revision = 0,
+ .version = XTABLES_VERSION,
+ },
++#endif
+ };
+
+ void _init(void)
+Index: iptables-1.4.21/extensions/libxt_multiport.c
+===================================================================
+--- iptables-1.4.21.orig/extensions/libxt_multiport.c
++++ iptables-1.4.21/extensions/libxt_multiport.c
+@@ -469,6 +469,7 @@ static void multiport_save6_v1(const voi
+ }
+
+ static struct xtables_match multiport_mt_reg[] = {
++#ifndef NO_LEGACY
+ {
+ .family = NFPROTO_IPV4,
+ .name = "multiport",
+@@ -497,6 +498,7 @@ static struct xtables_match multiport_mt
+ .save = multiport_save6,
+ .x6_options = multiport_opts,
+ },
++#endif
+ {
+ .family = NFPROTO_IPV4,
+ .name = "multiport",
diff --git a/package/network/utils/iputils/Makefile b/package/network/utils/iputils/Makefile
new file mode 100644
index 0000000..6f75236
--- /dev/null
+++ b/package/network/utils/iputils/Makefile
@@ -0,0 +1,181 @@
+#
+# Copyright (C) 2006-2010 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:=iputils
+PKG_VERSION:=20101006
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-s$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://www.skbuff.net/iputils
+PKG_MD5SUM:=a36c25e9ec17e48be514dc0485e7376c
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=GPL-2.0+
+
+PKG_BUILD_DEPENDS:=sysfsutils
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-s$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define Package/iputils/Default
+ SECTION:=net
+ CATEGORY:=Network
+ URL:=http://www.skbuff.net/iputils
+endef
+
+
+define Package/iputils-arping
+$(call Package/iputils/Default)
+ TITLE:=iputils - arping
+ DEPENDS+= +libsysfs
+endef
+
+define Package/iputils-arping/description
+ Program arping from iputils.
+ Sends ARP REQUEST to a neighbour host.
+endef
+
+
+define Package/iputils-clockdiff
+$(call Package/iputils/Default)
+ TITLE:=iputils - clockdiff
+endef
+
+define Package/iputils-clockdiff/description
+ Program clockdiff from iputils.
+ Measures clock difference between hosts.
+endef
+
+
+define Package/iputils-ping
+$(call Package/iputils/Default)
+ TITLE:=iputils - ping
+endef
+
+define Package/iputils-ping/description
+ Program ping from iputils.
+ Sends ICMP ECHO_REQUEST to network hosts (IPv4).
+endef
+
+
+define Package/iputils-ping6
+$(call Package/iputils/Default)
+ TITLE:=iputils - ping6
+ DEPENDS+= @IPV6 +USE_GLIBC:libopenssl
+endef
+
+define Package/iputils-ping6/description
+ Program ping6 from iputils.
+ Sends ICMP ECHO_REQUEST to network hosts (IPv6).
+endef
+
+
+define Package/iputils-tftpd
+$(call Package/iputils/Default)
+ TITLE:=iputils - tftpd
+endef
+
+define Package/iputils-tftpd/description
+ Program tftpd from iputils
+ Trivial File Transfer Protocol server.
+endef
+
+
+define Package/iputils-tracepath
+$(call Package/iputils/Default)
+ TITLE:=iputils - tracepath
+endef
+
+define Package/iputils-tracepath/description
+ Program tracepath from iputils.
+ Traces path to a network host discovering MTU along this path (IPv4).
+endef
+
+
+define Package/iputils-tracepath6
+$(call Package/iputils/Default)
+ TITLE:=iputils - tracepath6
+ DEPENDS+= @IPV6
+endef
+
+define Package/iputils-tracepath6/description
+ Program tracepath6 from iputils.
+ Traces path to a network host discovering MTU along this path (IPv6).
+endef
+
+
+define Package/iputils-traceroute6
+$(call Package/iputils/Default)
+ TITLE:=iputils - traceroute6
+ DEPENDS+= @IPV6
+endef
+
+define Package/iputils-traceroute6/description
+ Program traceroute6 from iputils.
+ Traces path to a network host (IPv6).
+endef
+
+ifdef CONFIG_USE_MUSL
+ TARGET_CFLAGS += -D__UCLIBC__
+endif
+
+MAKE_FLAGS += \
+ CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) $(TARGET_LDFLAGS)" \
+ CONFIG_IPV6="$(CONFIG_IPV6)" \
+ CONFIG_USE_UCLIBC="$(CONFIG_USE_UCLIBC)$(CONFIG_USE_MUSL)" \
+
+define Package/iputils-arping/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/arping $(1)/usr/bin/
+endef
+
+define Package/iputils-clockdiff/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/clockdiff $(1)/usr/bin/
+endef
+
+define Package/iputils-ping/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ping $(1)/usr/bin/
+endef
+
+define Package/iputils-ping6/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ping6 $(1)/usr/bin/
+endef
+
+define Package/iputils-tftpd/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tftpd $(1)/usr/sbin/
+endef
+
+define Package/iputils-tracepath/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tracepath $(1)/usr/bin/
+endef
+
+define Package/iputils-tracepath6/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tracepath6 $(1)/usr/bin/
+endef
+
+define Package/iputils-traceroute6/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/traceroute6 $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,iputils-arping))
+$(eval $(call BuildPackage,iputils-clockdiff))
+$(eval $(call BuildPackage,iputils-ping))
+$(eval $(call BuildPackage,iputils-tftpd))
+$(eval $(call BuildPackage,iputils-tracepath))
+$(eval $(call BuildPackage,iputils-ping6))
+$(eval $(call BuildPackage,iputils-tracepath6))
+$(eval $(call BuildPackage,iputils-traceroute6))
diff --git a/package/network/utils/iputils/patches/001-iputils.patch b/package/network/utils/iputils/patches/001-iputils.patch
new file mode 100644
index 0000000..e57db13
--- /dev/null
+++ b/package/network/utils/iputils/patches/001-iputils.patch
@@ -0,0 +1,14 @@
+diff -ur a/Makefile b/Makefile
+--- a/Makefile 2002-09-20 18:23:55.000000000 +0000
++++ b/Makefile 2007-05-17 13:59:55.000000000 +0000
+@@ -16,8 +16,8 @@
+ CCOPT=-D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall -g
+ CFLAGS=$(CCOPT) $(GLIBCFIX) $(DEFINES)
+
+-IPV4_TARGETS=tracepath ping clockdiff rdisc arping tftpd rarpd
+-IPV6_TARGETS=tracepath6 traceroute6 ping6
++IPV4_TARGETS=tracepath ping clockdiff arping tftpd
++IPV6_TARGETS=tracepath6 traceroute6 ping6
+ TARGETS=$(IPV4_TARGETS) $(IPV6_TARGETS)
+
+ LASTTAG:=`git describe HEAD | sed -e 's/-.*//'`
diff --git a/package/network/utils/iputils/patches/002-fix-ipv6.patch b/package/network/utils/iputils/patches/002-fix-ipv6.patch
new file mode 100644
index 0000000..4411ca7
--- /dev/null
+++ b/package/network/utils/iputils/patches/002-fix-ipv6.patch
@@ -0,0 +1,14 @@
+--- a/Makefile
++++ b/Makefile
+@@ -18,7 +18,10 @@ CFLAGS=$(CCOPT) $(GLIBCFIX) $(DEFINES)
+
+ IPV4_TARGETS=tracepath ping clockdiff arping tftpd
+ IPV6_TARGETS=tracepath6 traceroute6 ping6
+-TARGETS=$(IPV4_TARGETS) $(IPV6_TARGETS)
++TARGETS=$(IPV4_TARGETS)
++ifeq ($(CONFIG_IPV6),y)
++ TARGETS=$(IPV4_TARGETS) $(IPV6_TARGETS)
++endif
+
+ LASTTAG:=`git describe HEAD | sed -e 's/-.*//'`
+ TAG:=`date +s%Y%m%d`
diff --git a/package/network/utils/iputils/patches/003-fix-makefile.patch b/package/network/utils/iputils/patches/003-fix-makefile.patch
new file mode 100644
index 0000000..926c685
--- /dev/null
+++ b/package/network/utils/iputils/patches/003-fix-makefile.patch
@@ -0,0 +1,18 @@
+--- a/Makefile
++++ b/Makefile
+@@ -30,9 +30,13 @@ all: $(TARGETS)
+
+
+ tftpd: tftpd.o tftpsubs.o
+-arping: arping.o -lsysfs
++arping: arping.o
++ $(CC) $(CFLAGS) -o $@ arping.o -lsysfs
+ ping: ping.o ping_common.o
+-ping6: ping6.o ping_common.o -lresolv -lcrypto
++ping6: ping6.o ping_common.o
++ifneq ($(CONFIG_USE_UCLIBC),y)
++ $(CC) $(CFLAGS) -o $@ ping6.o ping_common.o -lresolv -lcrypto
++endif
+ ping.o ping6.o ping_common.o: ping_common.h
+ tftpd.o tftpsubs.o: tftp.h
+
diff --git a/package/network/utils/iputils/patches/010-ping6_uclibc_resolv.patch b/package/network/utils/iputils/patches/010-ping6_uclibc_resolv.patch
new file mode 100644
index 0000000..6955803
--- /dev/null
+++ b/package/network/utils/iputils/patches/010-ping6_uclibc_resolv.patch
@@ -0,0 +1,200 @@
+diff --git a/ping6.c b/ping6.c
+index c5ff881..ef2243f 100644
+--- a/ping6.c
++++ b/ping6.c
+@@ -71,9 +71,11 @@ char copyright[] =
+ #include <linux/filter.h>
+ #include <netinet/ip6.h>
+ #include <netinet/icmp6.h>
++#ifndef __UCLIBC__
+ #include <resolv.h>
+
+ #include "ping6_niquery.h"
++#endif /* __UCLIBC__ */
+
+ #ifndef SOL_IPV6
+ #define SOL_IPV6 IPPROTO_IPV6
+@@ -154,6 +156,7 @@ int pmtudisc=-1;
+
+ static int icmp_sock;
+
++#ifndef __UCLIBC__
+ #include <openssl/md5.h>
+
+ /* Node Information query */
+@@ -165,6 +168,7 @@ int ni_subject_type = 0;
+ char *ni_group;
+
+ __u8 ni_nonce[8];
++#endif /* __UCLIBC__ */
+
+ static struct in6_addr in6_anyaddr;
+ static __inline__ int ipv6_addr_any(struct in6_addr *addr)
+@@ -223,6 +227,7 @@ unsigned int if_name2index(const char *ifname)
+ return i;
+ }
+
++#ifndef __UCLIBC__
+ struct niquery_option {
+ char *name;
+ int namelen;
+@@ -512,6 +517,7 @@ char *ni_groupaddr(const char *name)
+ strcat(nigroup_buf, q);
+ return nigroup_buf;
+ }
++#endif /* __UCLIBC__ */
+
+ int main(int argc, char *argv[])
+ {
+@@ -595,12 +601,14 @@ int main(int argc, char *argv[])
+ case 'V':
+ printf("ping6 utility, iputils-ss%s\n", SNAPSHOT);
+ exit(0);
++#ifndef __UCLIBC__
+ case 'N':
+ if (niquery_option_handler(optarg) < 0) {
+ usage();
+ break;
+ }
+ break;
++#endif /* __UCLIBC__ */
+ COMMON_OPTIONS
+ common_options(ch);
+ break;
+@@ -663,6 +671,7 @@ int main(int argc, char *argv[])
+ argc--;
+ }
+
++#ifndef __UCLIBC__
+ if (ni_query >= 0) {
+ int i;
+ for (i = 0; i < 8; i++)
+@@ -674,15 +683,20 @@ int main(int argc, char *argv[])
+ ni_subject_type = NI_SUBJ_IPV6;
+ }
+ }
++#endif /* __UCLIBC__ */
+
+ if (argc > 1)
+ usage();
+ else if (argc == 1) {
+ target = *argv;
+ } else {
++#ifndef __UCLIBC__
+ if (ni_query < 0 && ni_subject_type != NI_SUBJ_NAME)
++#endif /* __UCLIBC__ */
+ usage();
++#ifndef __UCLIBC__
+ target = ni_group;
++#endif /* __UCLIBC__ */
+ }
+
+ memset(&hints, 0, sizeof(hints));
+@@ -817,7 +831,11 @@ int main(int argc, char *argv[])
+ exit(2);
+ }
+
++#ifndef __UCLIBC__
+ if (datalen >= sizeof(struct timeval) && (ni_query < 0)) {
++#else
++ if (datalen >= sizeof(struct timeval)) {
++#endif /* __UCLIBC__ */
+ /* can we time transfer */
+ timing = 1;
+ }
+@@ -866,9 +884,11 @@ int main(int argc, char *argv[])
+ ICMP6_FILTER_SETPASS(ICMP6_PARAM_PROB, &filter);
+ }
+
++#ifndef __UCLIBC__
+ if (ni_query >= 0)
+ ICMP6_FILTER_SETPASS(ICMPV6_NI_REPLY, &filter);
+ else
++#endif /* __UCLIBC__ */
+ ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filter);
+
+ err = setsockopt(icmp_sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
+@@ -1100,6 +1120,7 @@ int build_echo(__u8 *_icmph)
+ return cc;
+ }
+
++#ifndef __UCLIBC__
+ int build_niquery(__u8 *_nih)
+ {
+ struct ni_hdr *nih;
+@@ -1125,6 +1146,7 @@ int build_niquery(__u8 *_nih)
+
+ return cc;
+ }
++#endif /* __UCLIBC__ */
+
+ int send_probe(void)
+ {
+@@ -1132,9 +1154,11 @@ int send_probe(void)
+
+ CLR((ntransmitted+1) % mx_dup_ck);
+
++#ifndef __UCLIBC__
+ if (ni_query >= 0)
+ len = build_niquery(outpack);
+ else
++#endif /* __UCLIBC__ */
+ len = build_echo(outpack);
+
+ if (cmsglen == 0) {
+@@ -1176,6 +1200,7 @@ static void putchar_safe(char c)
+ printf("\\%03o", c);
+ }
+
++#ifndef __UCLIBC__
+ void pr_niquery_reply_name(struct ni_hdr *nih, int len)
+ {
+ __u8 *h = (__u8 *)(nih + 1);
+@@ -1304,6 +1329,7 @@ void pr_niquery_reply(__u8 *_nih, int len)
+ }
+ putchar(';');
+ }
++#endif /* __UCLIBC__ */
+
+ /*
+ * parse_reply --
+@@ -1353,6 +1379,7 @@ parse_reply(struct msghdr *msg, int cc, void *addr, struct timeval *tv)
+ hops, 0, tv, pr_addr(&from->sin6_addr),
+ pr_echo_reply))
+ return 0;
++#ifndef __UCLIBC__
+ } else if (icmph->icmp6_type == ICMPV6_NI_REPLY) {
+ struct ni_hdr *nih = (struct ni_hdr *)icmph;
+ __u16 seq = ntohs(*(__u16 *)nih->ni_nonce);
+@@ -1363,6 +1390,7 @@ parse_reply(struct msghdr *msg, int cc, void *addr, struct timeval *tv)
+ hops, 0, tv, pr_addr(&from->sin6_addr),
+ pr_niquery_reply))
+ return 0;
++#endif /* __UCLIBC__ */
+ } else {
+ int nexthdr;
+ struct ip6_hdr *iph1 = (struct ip6_hdr*)(icmph+1);
+@@ -1557,7 +1585,9 @@ void usage(void)
+ "Usage: ping6 [-LUdfnqrvVaAD] [-c count] [-i interval] [-w deadline]\n"
+ " [-p pattern] [-s packetsize] [-t ttl] [-I interface]\n"
+ " [-M pmtudisc-hint] [-S sndbuf] [-F flowlabel] [-Q tclass]\n"
++#ifndef __UCLIBC__
+ " [[-N nodeinfo-option] ...]\n"
++#endif /* __UCLIBC__ */
+ " [hop1 ...] destination\n");
+ exit(2);
+ }
+diff --git a/ping6_niquery.h b/ping6_niquery.h
+index 61a5cfa..34c31f8 100644
+--- a/ping6_niquery.h
++++ b/ping6_niquery.h
+@@ -1,3 +1,4 @@
++#ifndef __UCLIBC__
+ #include <asm/byteorder.h>
+
+ /* Node Information Query */
+@@ -45,3 +46,4 @@ struct ni_hdr {
+ #define NI_IPV4ADDR_F_TRUNCATE NI_IPV6ADDR_F_TRUNCATE
+ #define NI_IPV4ADDR_F_ALL NI_IPV6ADDR_F_ALL
+
++#endif /* __UCLIBC__ */
diff --git a/package/network/utils/iputils/patches/011-ping6_use_gnu_source.patch b/package/network/utils/iputils/patches/011-ping6_use_gnu_source.patch
new file mode 100644
index 0000000..dc61b8c
--- /dev/null
+++ b/package/network/utils/iputils/patches/011-ping6_use_gnu_source.patch
@@ -0,0 +1,11 @@
+--- a/ping6.c
++++ b/ping6.c
+@@ -66,6 +66,8 @@ char copyright[] =
+ * More statistics could always be gathered.
+ * This program has to run SUID to ROOT to access the ICMP socket.
+ */
++
++#define _GNU_SOURCE
+ #include "ping_common.h"
+
+ #include <linux/filter.h>
diff --git a/package/network/utils/iputils/patches/020-include_fixes.patch b/package/network/utils/iputils/patches/020-include_fixes.patch
new file mode 100644
index 0000000..e982dab
--- /dev/null
+++ b/package/network/utils/iputils/patches/020-include_fixes.patch
@@ -0,0 +1,71 @@
+--- a/ping_common.h
++++ b/ping_common.h
+@@ -2,6 +2,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <time.h>
++#include <sys/types.h>
+ #include <sys/param.h>
+ #include <sys/socket.h>
+ #include <linux/sockios.h>
+@@ -11,7 +12,7 @@
+ #include <sys/ioctl.h>
+ #include <net/if.h>
+ #include <sys/uio.h>
+-#include <sys/poll.h>
++#include <poll.h>
+ #include <ctype.h>
+ #include <errno.h>
+ #include <string.h>
+@@ -24,6 +25,10 @@
+
+ #include "SNAPSHOT.h"
+
++#ifndef HZ
++#define HZ 100
++#endif
++
+ #define DEFDATALEN (64 - 8) /* default data length */
+
+ #define MAXWAIT 10 /* max seconds to wait for response */
+--- a/clockdiff.c
++++ b/clockdiff.c
+@@ -13,8 +13,6 @@
+ #include <netinet/in.h>
+ #include <netinet/ip.h>
+ #include <netinet/ip_icmp.h>
+-#define TSPTYPES
+-#include <protocols/timed.h>
+ #include <fcntl.h>
+ #include <netdb.h>
+ #include <arpa/inet.h>
+--- a/tracepath.c
++++ b/tracepath.c
+@@ -13,6 +13,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/socket.h>
++#include <sys/time.h>
+ #include <linux/types.h>
+ #include <linux/errqueue.h>
+ #include <errno.h>
+--- a/ping.c
++++ b/ping.c
+@@ -661,8 +661,15 @@ int send_probe()
+
+ do {
+ static struct iovec iov = {outpack, 0};
+- static struct msghdr m = { &whereto, sizeof(whereto),
+- &iov, 1, &cmsg, 0, 0 };
++ static struct msghdr m = {
++ .msg_name = &whereto,
++ .msg_namelen = sizeof(whereto),
++ .msg_iov = &iov,
++ .msg_iovlen = 1,
++ .msg_control = &cmsg,
++ .msg_controllen = 0,
++ .msg_flags = 0
++ };
+ m.msg_controllen = cmsg_len;
+ iov.iov_len = cc;
+
diff --git a/package/network/utils/iw/Makefile b/package/network/utils/iw/Makefile
new file mode 100644
index 0000000..53cfee3
--- /dev/null
+++ b/package/network/utils/iw/Makefile
@@ -0,0 +1,57 @@
+#
+# 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:=4.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://www.kernel.org/pub/software/network/iw
+PKG_MD5SUM:=3a292dd342bb88e30e74015ae6fe1e54
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+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
+endef
+
+define Build/Configure
+ echo "const char iw_version[] = \"$(PKG_VERSION)\";" > $(PKG_BUILD_DIR)/version.c
+ rm -f $(PKG_BUILD_DIR)/version.sh
+ touch $(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
+
+MAKE_FLAGS += \
+ CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -ffunction-sections -fdata-sections" \
+ LDFLAGS="$(TARGET_LDFLAGS) -Wl,--gc-sections" \
+ 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
+
+$(eval $(call BuildPackage,iw))
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..afa5506
--- /dev/null
+++ b/package/network/utils/iw/patches/001-nl80211_h_sync.patch
@@ -0,0 +1,100 @@
+--- a/nl80211.h
++++ b/nl80211.h
+@@ -1761,6 +1761,9 @@ enum nl80211_commands {
+ * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
+ * is operating in an indoor environment.
+ *
++ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
++ * transmit power to stay within regulatory limits. u32, dBi.
++ *
+ * @NUM_NL80211_ATTR: total number of nl80211_attrs available
+ * @NL80211_ATTR_MAX: highest attribute number currently defined
+ * @__NL80211_ATTR_AFTER_LAST: internal use
+@@ -2130,6 +2133,8 @@ enum nl80211_attrs {
+
+ NL80211_ATTR_REG_INDOOR,
+
++ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
++
+ /* add attributes here, update the policy in nl80211.c */
+
+ __NL80211_ATTR_AFTER_LAST,
+@@ -2620,16 +2625,17 @@ enum nl80211_band_attr {
+ * an indoor surroundings, i.e., it is connected to AC power (and not
+ * through portable DC inverters) or is under the control of a master
+ * that is acting as an AP and is connected to AC power.
+- * @NL80211_FREQUENCY_ATTR_GO_CONCURRENT: GO operation is allowed on this
++ * @NL80211_FREQUENCY_ATTR_IR_CONCURRENT: IR operation is allowed on this
+ * channel if it's connected concurrently to a BSS on the same channel on
+ * the 2 GHz band or to a channel in the same UNII band (on the 5 GHz
+- * band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO on a
+- * channel that has the GO_CONCURRENT attribute set can be done when there
+- * is a clear assessment that the device is operating under the guidance of
+- * an authorized master, i.e., setting up a GO while the device is also
+- * connected to an AP with DFS and radar detection on the UNII band (it is
+- * up to user-space, i.e., wpa_supplicant to perform the required
+- * verifications)
++ * band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO or TDLS
++ * off-channel on a channel that has the IR_CONCURRENT attribute set can be
++ * done when there is a clear assessment that the device is operating under
++ * the guidance of an authorized master, i.e., setting up a GO or TDLS
++ * off-channel while the device is also connected to an AP with DFS and
++ * radar detection on the UNII band (it is up to user-space, i.e.,
++ * wpa_supplicant to perform the required verifications). Using this
++ * attribute for IR is disallowed for master interfaces (IBSS, AP).
+ * @NL80211_FREQUENCY_ATTR_NO_20MHZ: 20 MHz operation is not allowed
+ * on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_10MHZ: 10 MHz operation is not allowed
+@@ -2641,7 +2647,7 @@ enum nl80211_band_attr {
+ * See https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122
+ * for more information on the FCC description of the relaxations allowed
+ * by NL80211_FREQUENCY_ATTR_INDOOR_ONLY and
+- * NL80211_FREQUENCY_ATTR_GO_CONCURRENT.
++ * NL80211_FREQUENCY_ATTR_IR_CONCURRENT.
+ */
+ enum nl80211_frequency_attr {
+ __NL80211_FREQUENCY_ATTR_INVALID,
+@@ -2659,7 +2665,7 @@ enum nl80211_frequency_attr {
+ NL80211_FREQUENCY_ATTR_NO_160MHZ,
+ NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
+ NL80211_FREQUENCY_ATTR_INDOOR_ONLY,
+- NL80211_FREQUENCY_ATTR_GO_CONCURRENT,
++ NL80211_FREQUENCY_ATTR_IR_CONCURRENT,
+ NL80211_FREQUENCY_ATTR_NO_20MHZ,
+ NL80211_FREQUENCY_ATTR_NO_10MHZ,
+
+@@ -2672,6 +2678,8 @@ enum nl80211_frequency_attr {
+ #define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR
+ #define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR
+ #define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR
++#define NL80211_FREQUENCY_ATTR_GO_CONCURRENT \
++ NL80211_FREQUENCY_ATTR_IR_CONCURRENT
+
+ /**
+ * enum nl80211_bitrate_attr - bitrate attributes
+@@ -2830,7 +2838,7 @@ enum nl80211_sched_scan_match_attr {
+ * @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.
+- * @NL80211_RRF_GO_CONCURRENT: See &NL80211_FREQUENCY_ATTR_GO_CONCURRENT
++ * @NL80211_RRF_IR_CONCURRENT: See &NL80211_FREQUENCY_ATTR_IR_CONCURRENT
+ * @NL80211_RRF_NO_HT40MINUS: channels can't be used in HT40- operation
+ * @NL80211_RRF_NO_HT40PLUS: channels can't be used in HT40+ operation
+ * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
+@@ -2847,7 +2855,7 @@ enum nl80211_reg_rule_flags {
+ NL80211_RRF_NO_IR = 1<<7,
+ __NL80211_RRF_NO_IBSS = 1<<8,
+ NL80211_RRF_AUTO_BW = 1<<11,
+- NL80211_RRF_GO_CONCURRENT = 1<<12,
++ NL80211_RRF_IR_CONCURRENT = 1<<12,
+ NL80211_RRF_NO_HT40MINUS = 1<<13,
+ NL80211_RRF_NO_HT40PLUS = 1<<14,
+ NL80211_RRF_NO_80MHZ = 1<<15,
+@@ -2859,6 +2867,7 @@ enum nl80211_reg_rule_flags {
+ #define NL80211_RRF_NO_IR NL80211_RRF_NO_IR
+ #define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS |\
+ NL80211_RRF_NO_HT40PLUS)
++#define NL80211_RRF_GO_CONCURRENT NL80211_RRF_IR_CONCURRENT
+
+ /* For backport compatibility with older userspace */
+ #define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
diff --git a/package/network/utils/iw/patches/120-antenna_gain.patch b/package/network/utils/iw/patches/120-antenna_gain.patch
new file mode 100644
index 0000000..8de3df2
--- /dev/null
+++ b/package/network/utils/iw/patches/120-antenna_gain.patch
@@ -0,0 +1,34 @@
+--- a/phy.c
++++ b/phy.c
+@@ -532,3 +532,31 @@ COMMAND(set, antenna, "<bitmap> | all |
+ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_antenna,
+ "Set a bitmap of allowed antennas to use for TX and RX.\n"
+ "The driver may reject antenna configurations it cannot support.");
++
++static int handle_antenna_gain(struct nl80211_state *state,
++ struct nl_cb *cb,
++ struct nl_msg *msg,
++ int argc, char **argv,
++ enum id_input id)
++{
++ char *endptr;
++ int dbm;
++
++ /* get the required args */
++ if (argc != 1)
++ return 1;
++
++ dbm = strtol(argv[0], &endptr, 10);
++ if (*endptr)
++ return 2;
++
++ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_GAIN, dbm);
++
++ return 0;
++
++ nla_put_failure:
++ return -ENOBUFS;
++}
++COMMAND(set, antenna_gain, "<antenna gain in dBm>",
++ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_antenna_gain,
++ "Specify antenna gain.");
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..3ba4730
--- /dev/null
+++ b/package/network/utils/iw/patches/200-reduce_size.patch
@@ -0,0 +1,255 @@
+--- a/Makefile
++++ b/Makefile
+@@ -15,8 +15,8 @@ CFLAGS += -Wall -Wundef -Wstrict-prototy
+ OBJS = iw.o genl.o event.o info.o phy.o \
+ interface.o ibss.o station.o survey.o util.o ocb.o \
+ mesh.o mpath.o mpp.o scan.o reg.o version.o \
+- reason.o status.o connect.o link.o offch.o ps.o cqm.o \
+- bitrate.o wowlan.o coalesce.o roc.o p2p.o vendor.o
++ reason.o status.o link.o offch.o ps.o cqm.o \
++ bitrate.o vendor.o
+ OBJS += sections.o
+
+ OBJS-$(HWSIM) += hwsim.o
+--- a/info.c
++++ b/info.c
+@@ -219,6 +219,7 @@ next:
+ }
+ }
+
++#if 0
+ 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) {
+@@ -235,6 +236,7 @@ next:
+ printf("\n");
+ }
+ }
++#endif
+ }
+ }
+
+@@ -291,6 +293,7 @@ next:
+ printf("\tCoverage class: %d (up to %dm)\n", coverage, 450 * coverage);
+ }
+
++#if 0
+ if (tb_msg[NL80211_ATTR_CIPHER_SUITES]) {
+ int num = nla_len(tb_msg[NL80211_ATTR_CIPHER_SUITES]) / sizeof(__u32);
+ int i;
+@@ -302,6 +305,7 @@ next:
+ cipher_name(ciphers[i]));
+ }
+ }
++#endif
+
+ if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX] &&
+ tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX])
+@@ -321,11 +325,13 @@ next:
+ printf("\t\t * %s\n", iftype_name(nla_type(nl_mode)));
+ }
+
++#if 0
+ if (tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES]) {
+ printf("\tsoftware interface modes (can always be added):\n");
+ nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES], rem_mode)
+ printf("\t\t * %s\n", iftype_name(nla_type(nl_mode)));
+ }
++#endif
+
+ if (tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS]) {
+ struct nlattr *nl_combi;
+@@ -422,6 +428,7 @@ broken_combination:
+ printf("\tinterface combinations are not supported\n");
+ }
+
++#if 0
+ 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)
+@@ -518,6 +525,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");
+@@ -554,6 +562,7 @@ broken_combination:
+ }
+ }
+
++#if 0
+ if (tb_msg[NL80211_ATTR_FEATURE_FLAGS]) {
+ unsigned int features = nla_get_u32(tb_msg[NL80211_ATTR_FEATURE_FLAGS]);
+
+@@ -612,6 +621,7 @@ broken_combination:
+ if (features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH)
+ printf("\tDevice supports TDLS channel switching\n");
+ }
++#endif
+
+ if (tb_msg[NL80211_ATTR_EXT_FEATURES]) {
+ struct nlattr *tb = tb_msg[NL80211_ATTR_EXT_FEATURES];
+@@ -669,6 +679,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);
+
++#if 0
+ static int handle_commands(struct nl80211_state *state,
+ struct nl_cb *cb, struct nl_msg *msg,
+ int argc, char **argv, enum id_input id)
+@@ -681,6 +692,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
+@@ -1080,6 +1080,7 @@ 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]);
++ return;
+ 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);
+@@ -1311,6 +1312,13 @@ 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), },
++ [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), },
++ [191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
++ [192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
++#if 0
+ [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), },
+@@ -1320,14 +1328,8 @@ static const struct ie_print ieprinters[
+ [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), },
+ [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), },
+ [113] = { "MESH Configuration", print_mesh_conf, 7, 7, BIT(PRINT_SCAN), },
+ [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
+@@ -1335,6 +1337,7 @@ static const struct ie_print ieprinters[
+ [107] = { "802.11u Interworking", print_interworking, 0, 255, BIT(PRINT_SCAN), },
+ [108] = { "802.11u Advertisement", print_11u_advert, 0, 255, BIT(PRINT_SCAN), },
+ [111] = { "802.11u Roaming Consortium", print_11u_rcon, 0, 255, BIT(PRINT_SCAN), },
++#endif
+ };
+
+ static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data)
+@@ -1766,6 +1769,7 @@ void print_ies(unsigned char *ie, int ie
+ ieprinters[ie[0]].name &&
+ ieprinters[ie[0]].flags & BIT(ptype)) {
+ print_ie(&ieprinters[ie[0]], ie[0], ie[1], ie + 2);
++#if 0
+ } else if (ie[0] == 221 /* vendor */) {
+ print_vendor(ie[1], ie + 2, unknown, ptype);
+ } else if (unknown) {
+@@ -1775,6 +1779,7 @@ void print_ies(unsigned char *ie, int ie
+ for (i=0; i<ie[1]; i++)
+ printf(" %.2x", ie[2+i]);
+ printf("\n");
++#endif
+ }
+ ielen -= ie[1] + 2;
+ ie += ie[1] + 2;
+@@ -1815,6 +1820,7 @@ static void print_capa_non_dmg(__u16 cap
+ printf(" ESS");
+ if (capa & WLAN_CAPABILITY_IBSS)
+ printf(" IBSS");
++#if 0
+ if (capa & WLAN_CAPABILITY_CF_POLLABLE)
+ printf(" CfPollable");
+ if (capa & WLAN_CAPABILITY_CF_POLL_REQUEST)
+@@ -1843,6 +1849,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)
+@@ -1921,8 +1928,10 @@ static int print_bss_handler(struct nl_m
+ if (bss[NL80211_BSS_FREQUENCY]) {
+ int freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
+ printf("\tfreq: %d\n", freq);
++#if 0
+ if (freq > 45000)
+ is_dmg = true;
++#endif
+ }
+ if (bss[NL80211_BSS_BEACON_INTERVAL])
+ printf("\tbeacon interval: %d TUs\n",
+--- a/util.c
++++ b/util.c
+@@ -264,6 +264,7 @@ static const char *commands[NL80211_CMD_
+
+ static char cmdbuf[100];
+
++#if 0
+ const char *command_name(enum nl80211_commands cmd)
+ {
+ if (cmd <= NL80211_CMD_MAX && commands[cmd])
+@@ -271,6 +272,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)
+ {
+--- a/event.c
++++ b/event.c
+@@ -334,6 +334,7 @@ static int print_event(struct nl_msg *ms
+ }
+
+ switch (gnlh->cmd) {
++#if 0
+ case NL80211_CMD_NEW_WIPHY:
+ printf("renamed to %s\n", nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]));
+ break;
+@@ -368,6 +369,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_REG_CHANGE:
+ printf("regulatory domain change: ");
+
+@@ -446,6 +448,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;
++#if 0
+ case NL80211_CMD_JOIN_IBSS:
+ mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC]));
+ printf("IBSS %s joined\n", macbuf);
+@@ -599,9 +602,9 @@ static int print_event(struct nl_msg *ms
+ }
+ printf("\n");
+ break;
++#endif
+ default:
+- printf("unknown event %d (%s)\n",
+- gnlh->cmd, command_name(gnlh->cmd));
++ printf("unknown event %d\n", gnlh->cmd);
+ break;
+ }
+
diff --git a/package/network/utils/iwcap/Makefile b/package/network/utils/iwcap/Makefile
new file mode 100644
index 0000000..d3f8847
--- /dev/null
+++ b/package/network/utils/iwcap/Makefile
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2012 Jo-Philipp Wich <jow@openwrt.org>
+#
+# 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 <jow@openwrt.org>
+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/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+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..d335e50
--- /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 <jow@openwrt.org>
+ *
+ * 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_stop)
+ {
+ msg("Shutting down ...\n");
+
+ if (promisc)
+ set_promisc(0);
+
+ if (ring)
+ ringbuf_free(ring);
+
+ return 0;
+ }
+ else 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;
+ }
+
+ 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..6de47e8
--- /dev/null
+++ b/package/network/utils/iwinfo/Makefile
@@ -0,0 +1,121 @@
+#
+# Copyright (C) 2010-2015 Jo-Philipp Wich <jow@openwrt.org>
+#
+# This is free software, licensed under the GPL 2 license.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libiwinfo
+PKG_VERSION:=2015-10-05
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=http://git.openwrt.org/project/iwinfo.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=813f61e48b9b1a76cb55f3b4a229bf98d3cd53a9
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+PKG_CONFIG_DEPENDS := \
+ CONFIG_PACKAGE_kmod-brcm-wl \
+ CONFIG_PACKAGE_kmod-brcm-wl-mini \
+ CONFIG_PACKAGE_kmod-brcm-wl-mimo \
+ CONFIG_PACKAGE_kmod-madwifi \
+ CONFIG_PACKAGE_kmod-cfg80211
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define Package/libiwinfo
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=Generalized Wireless Information Library (iwinfo)
+ DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny +libuci
+ ABI_VERSION:=$(PKG_RELEASE)
+endef
+
+define Package/libiwinfo/description
+ Wireless information library with consistent interface for proprietary Broadcom,
+ madwifi, 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/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
+
+IWINFO_BACKENDS := \
+ $(if $(CONFIG_PACKAGE_kmod-brcm-wl),wl) \
+ $(if $(CONFIG_PACKAGE_kmod-brcm-wl-mini),wl) \
+ $(if $(CONFIG_PACKAGE_kmod-brcm-wl-mimo),wl) \
+ $(if $(CONFIG_PACKAGE_kmod-madwifi),madwifi) \
+ $(if $(CONFIG_PACKAGE_kmod-cfg80211),nl80211)
+
+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="$(IWINFO_BACKENDS)"
+
+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
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/libiwinfo.so $(1)/usr/lib/libiwinfo.so
+ $(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 $(1)/usr/lib/libiwinfo.so
+ $(INSTALL_DIR) $(1)/usr/share/libiwinfo
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/hardware.txt $(1)/usr/share/libiwinfo/hardware.txt
+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/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,iwinfo))
diff --git a/package/network/utils/linux-atm/Makefile b/package/network/utils/linux-atm/Makefile
new file mode 100644
index 0000000..d9402c3
--- /dev/null
+++ b/package/network/utils/linux-atm/Makefile
@@ -0,0 +1,193 @@
+#
+# 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:=5
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_MD5SUM:=d49499368c3cf15f73a05d9bce8824a8
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_CHECK_FORMAT_SECURITY:=0
+PKG_LICENSE:=GPL-2.0+
+PKG_FIXUP:=autoreconf
+
+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))))
+
+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/
+ $(INSTALL_BIN) ./files/br2684ctl $(1)/etc/init.d/
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(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/br2684ctl b/package/network/utils/linux-atm/files/br2684ctl
new file mode 100755
index 0000000..30b1a44
--- /dev/null
+++ b/package/network/utils/linux-atm/files/br2684ctl
@@ -0,0 +1,89 @@
+#!/bin/sh /etc/rc.common
+
+START=50
+
+SERVICE_DAEMONIZE=1
+SERVICE_WRITE_PID=1
+
+start_daemon() {
+ . /lib/functions/network.sh
+
+ local cfg="$1"
+
+ local atmdev
+ config_get atmdev "$cfg" atmdev 0
+
+ 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
+
+ local circuit="$atmdev.$vpi.$vci"
+
+ network_defer_device "nas$unit"
+
+ SERVICE_PID_FILE="/var/run/br2684ctl-$circuit.pid" \
+ service_start /usr/sbin/br2684ctl \
+ -c "$unit" -e "$encaps" -p "$payload" \
+ -a "$circuit" ${qos:+-q "$qos"} ${sendsize:+-s "$sendsize"}
+ sleep 1
+
+ network_ready_device "nas$unit"
+}
+
+stop_daemon() {
+ local cfg="$1"
+
+ local atmdev
+ config_get atmdev "$cfg" atmdev 0
+
+ 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 circuit="$atmdev.$vpi.$vci"
+
+ SERVICE_PID_FILE="/var/run/br2684ctl-$circuit.pid" \
+ service_stop /usr/sbin/br2684ctl
+}
+
+start() {
+ config_load network
+ config_foreach start_daemon atm-bridge
+}
+
+stop() {
+ config_load network
+ config_foreach stop_daemon atm-bridge
+}
diff --git a/package/network/utils/linux-atm/patches/000-debian_16.patch b/package/network/utils/linux-atm/patches/000-debian_16.patch
new file mode 100644
index 0000000..4abaac0
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/000-debian_16.patch
@@ -0,0 +1,270 @@
+--- 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 */
+--- 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
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..462f57c
--- /dev/null
+++ b/package/network/utils/linux-atm/patches/400-portability_fixes.patch
@@ -0,0 +1,60 @@
+diff -urN linux-atm-2.5.2/src/ilmid/io.c linux-atm-2.5.2.new/src/ilmid/io.c
+--- linux-atm-2.5.2/src/ilmid/io.c 2008-01-01 01:14:50.000000000 +0100
++++ linux-atm-2.5.2.new/src/ilmid/io.c 2012-11-23 17:32:18.149268039 +0100
+@@ -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 */
+diff -urN linux-atm-2.5.2/src/mpoad/io.c linux-atm-2.5.2.new/src/mpoad/io.c
+--- linux-atm-2.5.2/src/mpoad/io.c 2008-01-01 01:14:51.000000000 +0100
++++ linux-atm-2.5.2.new/src/mpoad/io.c 2012-11-23 17:34:17.745271101 +0100
+@@ -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>
+diff -urN linux-atm-2.5.2/src/sigd/atmsigd.c linux-atm-2.5.2.new/src/sigd/atmsigd.c
+--- linux-atm-2.5.2/src/sigd/atmsigd.c 2008-01-01 01:14:52.000000000 +0100
++++ linux-atm-2.5.2.new/src/sigd/atmsigd.c 2012-11-23 17:30:38.689265492 +0100
+@@ -517,7 +517,7 @@
+ 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);
+diff -urN linux-atm-2.5.2/src/test/align.c linux-atm-2.5.2.new/src/test/align.c
+--- linux-atm-2.5.2/src/test/align.c 2001-10-10 00:33:08.000000000 +0200
++++ linux-atm-2.5.2.new/src/test/align.c 2012-11-23 17:25:15.077257206 +0100
+@@ -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/maccalc/Makefile b/package/network/utils/maccalc/Makefile
new file mode 100644
index 0000000..b4800d0
--- /dev/null
+++ b/package/network/utils/maccalc/Makefile
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 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:=maccalc
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/maccalc
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=MAC address calculation
+endef
+
+define Package/maccalc/description
+ This package contains a MAC address manipulation utility.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -Wall" \
+ LDFLAGS="$(TARGET_LDFLAGS)"
+endef
+
+define Package/maccalc/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/maccalc $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,maccalc))
diff --git a/package/network/utils/maccalc/src/Makefile b/package/network/utils/maccalc/src/Makefile
new file mode 100644
index 0000000..486badb
--- /dev/null
+++ b/package/network/utils/maccalc/src/Makefile
@@ -0,0 +1,14 @@
+CC = gcc
+CFLAGS = -Wall
+OBJS = main.o
+
+all: maccalc
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+maccalc: $(OBJS)
+ $(CC) -o $@ $(OBJS)
+
+clean:
+ rm -f maccalc *.o
diff --git a/package/network/utils/maccalc/src/main.c b/package/network/utils/maccalc/src/main.c
new file mode 100644
index 0000000..dcb5f55
--- /dev/null
+++ b/package/network/utils/maccalc/src/main.c
@@ -0,0 +1,256 @@
+/*
+ * MAC address manupulation utility
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#define MAC_ADDRESS_LEN 6
+
+#define ERR_INVALID 1
+#define ERR_IO 2
+
+static void usage(void);
+
+char *maccalc_name;
+
+static int parse_mac(const char *mac_str, unsigned char *buf)
+{
+ int t;
+
+ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+ &buf[0], &buf[1], &buf[2], &buf[3], &buf[4], &buf[5]);
+
+ if (t != MAC_ADDRESS_LEN)
+ return ERR_INVALID;
+
+ return 0;
+}
+
+static void print_mac(unsigned char *buf)
+{
+ printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+}
+
+static int maccalc_do_add(int argc, const char *argv[])
+{
+ unsigned char mac[MAC_ADDRESS_LEN];
+ uint32_t t;
+ int err;
+ int i;
+
+ if (argc != 2) {
+ usage();
+ return ERR_INVALID;
+ }
+
+ err = parse_mac(argv[0], mac);
+ if (err)
+ return err;
+
+ i = atoi(argv[1]);
+
+ t = (mac[3] << 16) | (mac[4] << 8) | mac[5];
+ t += i;
+ mac[3] = (t >> 16) & 0xff;
+ mac[4] = (t >> 8) & 0xff;
+ mac[5] = t & 0xff;
+
+ print_mac(mac);
+ return 0;
+}
+
+static int maccalc_do_logical(int argc, const char *argv[],
+ unsigned char (*op)(unsigned char n1,
+ unsigned char n2))
+{
+ unsigned char mac1[MAC_ADDRESS_LEN];
+ unsigned char mac2[MAC_ADDRESS_LEN];
+ int err;
+ int i;
+
+ if (argc != 2) {
+ usage();
+ return ERR_INVALID;
+ }
+
+ err = parse_mac(argv[0], mac1);
+ if (err)
+ return err;
+
+ err = parse_mac(argv[1], mac2);
+ if (err)
+ return err;
+
+ for (i = 0; i < MAC_ADDRESS_LEN; i++)
+ mac1[i] = op(mac1[i],mac2[i]);
+
+ print_mac(mac1);
+ return 0;
+}
+
+static int maccalc_do_mac2bin(int argc, const char *argv[])
+{
+ unsigned char mac[MAC_ADDRESS_LEN];
+ ssize_t c;
+ int err;
+
+ if (argc != 1) {
+ usage();
+ return ERR_INVALID;
+ }
+
+ err = parse_mac(argv[0], mac);
+ if (err)
+ return err;
+
+ c = write(STDOUT_FILENO, mac, sizeof(mac));
+ if (c != sizeof(mac)) {
+ fprintf(stderr, "failed to write to stdout\n");
+ return ERR_IO;
+ }
+
+ return 0;
+}
+
+static ssize_t read_safe(int fd, void *buf, size_t count)
+{
+ ssize_t total = 0;
+ ssize_t r;
+
+ while(count > 0) {
+ r = read(fd, buf, count);
+ if (r == 0)
+ /* EOF */
+ break;
+ if (r < 0) {
+ if (errno == EINTR)
+ /* interrupted by a signal, restart */
+ continue;
+ /* error */
+ total = -1;
+ break;
+ }
+
+ /* ok */
+ total += r;
+ count -= r;
+ buf += r;
+ }
+
+ return total;
+}
+
+static int maccalc_do_bin2mac(int argc, const char *argv[])
+{
+ unsigned char mac[MAC_ADDRESS_LEN];
+ ssize_t c;
+
+ if (argc != 0) {
+ usage();
+ return ERR_INVALID;
+ }
+
+ c = read_safe(STDIN_FILENO, mac, sizeof(mac));
+ if (c != sizeof(mac)) {
+ fprintf(stderr, "failed to read from stdin\n");
+ return ERR_IO;
+ }
+
+ print_mac(mac);
+ return 0;
+}
+
+static unsigned char op_or(unsigned char n1, unsigned char n2)
+{
+ return n1 | n2;
+}
+
+static int maccalc_do_or(int argc, const char *argv[])
+{
+ return maccalc_do_logical(argc, argv, op_or);
+}
+
+static unsigned char op_and(unsigned char n1, unsigned char n2)
+{
+ return n1 & n2;
+}
+
+static int maccalc_do_and(int argc, const char *argv[])
+{
+ return maccalc_do_logical(argc, argv, op_and);
+}
+
+static unsigned char op_xor(unsigned char n1, unsigned char n2)
+{
+ return n1 ^ n2;
+}
+
+static int maccalc_do_xor(int argc, const char *argv[])
+{
+ return maccalc_do_logical(argc, argv, op_xor);
+}
+
+static void usage(void)
+{
+ fprintf(stderr,
+ "Usage: %s <command>\n"
+ "valid commands:\n"
+ " add <mac> <number>\n"
+ " and|or|xor <mac1> <mac2>\n"
+ " mac2bin <mac>\n"
+ " bin2mac\n",
+ maccalc_name);
+}
+
+int main(int argc, const char *argv[])
+{
+ int (*op)(int argc, const char *argv[]);
+ int ret;
+
+ maccalc_name = (char *) argv[0];
+
+ if (argc < 2) {
+ usage();
+ return EXIT_FAILURE;
+ }
+
+ if (strcmp(argv[1], "add") == 0) {
+ op = maccalc_do_add;
+ } else if (strcmp(argv[1], "and") == 0) {
+ op = maccalc_do_and;
+ } else if (strcmp(argv[1], "or") == 0) {
+ op = maccalc_do_or;
+ } else if (strcmp(argv[1], "xor") == 0) {
+ op = maccalc_do_xor;
+ } else if (strcmp(argv[1], "mac2bin") == 0) {
+ op = maccalc_do_mac2bin;
+ } else if (strcmp(argv[1], "bin2mac") == 0) {
+ op = maccalc_do_bin2mac;
+ } else {
+ fprintf(stderr, "unknown command '%s'\n", argv[1]);
+ usage();
+ return EXIT_FAILURE;
+ }
+
+ argc -= 2;
+ argv += 2;
+
+ ret = op(argc, argv);
+ if (ret)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
diff --git a/package/network/utils/nftables/Makefile b/package/network/utils/nftables/Makefile
new file mode 100644
index 0000000..96db6ff
--- /dev/null
+++ b/package/network/utils/nftables/Makefile
@@ -0,0 +1,43 @@
+# Copyright (C) 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:=nftables
+PKG_VERSION:=0.4+2015-04-09
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=git://git.netfilter.org/nftables
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=3ed296118a065caff5600e60d4f7ef18e137f9a0
+PKG_MAINTAINER:=Steven Barth <steven@midlink.org>
+PKG_LICENSE:=GPL-2.0
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+CONFIGURE_ARGS += \
+ --with-mini-gmp \
+ --without-cli \
+
+define Package/nftables
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Firewall
+ TITLE:=nftables packet filtering userspace utility
+ DEPENDS:=+kmod-nft-core +kmod-nft-nat +libnftnl
+ URL:=http://netfilter.org/projects/nftables/
+endef
+
+define Package/nftables/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_BUILD_DIR)/src/nft $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,nftables))
diff --git a/package/network/utils/nftables/patches/100-disable-doc-generation.patch b/package/network/utils/nftables/patches/100-disable-doc-generation.patch
new file mode 100644
index 0000000..bcbffe2
--- /dev/null
+++ b/package/network/utils/nftables/patches/100-disable-doc-generation.patch
@@ -0,0 +1,8 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -2,5 +2,4 @@ ACLOCAL_AMFLAGS = -I m4
+
+ SUBDIRS = src \
+ include \
+- doc \
+ files
diff --git a/package/network/utils/owipcalc/Makefile b/package/network/utils/owipcalc/Makefile
new file mode 100644
index 0000000..9d6b397
--- /dev/null
+++ b/package/network/utils/owipcalc/Makefile
@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2012 Jo-Philipp Wich <jow@openwrt.org>
+#
+# This is free software, licensed under the Apache 2 license.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=owipcalc
+PKG_RELEASE:=3
+PKG_LICENSE:=Apache-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define Package/owipcalc
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Simple IPv4/IPv6 address calculator
+ MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+endef
+
+define Package/owipcalc/description
+ The owipcalc utility supports a number of calculations and tests to work
+ with ip-address ranges, this is useful for scripts that e.g. need to
+ partition ipv6-prefixes into small subnets or to calculate address ranges
+ for dhcp pools.
+endef
+
+
+define Build/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(TARGET_CC) $(TARGET_CFLAGS) \
+ -o $(PKG_BUILD_DIR)/owipcalc $(PKG_BUILD_DIR)/owipcalc.c
+endef
+
+
+define Package/owipcalc/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/owipcalc $(1)/usr/bin/owipcalc
+endef
+
+$(eval $(call BuildPackage,owipcalc))
diff --git a/package/network/utils/owipcalc/src/owipcalc.c b/package/network/utils/owipcalc/src/owipcalc.c
new file mode 100644
index 0000000..d22594b
--- /dev/null
+++ b/package/network/utils/owipcalc/src/owipcalc.c
@@ -0,0 +1,951 @@
+/*
+ * owipcalc - OpenWrt IP Calculator
+ *
+ * Copyright (C) 2012 Jo-Philipp Wich <jow@openwrt.org>
+ *
+ * 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 <stdbool.h>
+#include <stdlib.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+
+
+struct cidr {
+ uint8_t family;
+ uint32_t prefix;
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ } addr;
+ union {
+ char v4[sizeof("255.255.255.255/255.255.255.255 ")];
+ char v6[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/128 ")];
+ } buf;
+ struct cidr *next;
+};
+
+struct op {
+ const char *name;
+ const char *desc;
+ struct {
+ bool (*a1)(struct cidr *a);
+ bool (*a2)(struct cidr *a, struct cidr *b);
+ } f4;
+ struct {
+ bool (*a1)(struct cidr *a);
+ bool (*a2)(struct cidr *a, struct cidr *b);
+ } f6;
+};
+
+
+static bool quiet = false;
+static bool printed = false;
+
+static struct cidr *stack = NULL;
+
+#define qprintf(...) \
+ do { \
+ if (!quiet) printf(__VA_ARGS__); \
+ printed = true; \
+ } while(0)
+
+static void cidr_push(struct cidr *a)
+{
+ if (a)
+ {
+ a->next = stack;
+ stack = a;
+ }
+}
+
+static bool cidr_pop(struct cidr *a)
+{
+ struct cidr *old = stack;
+
+ if (old)
+ {
+ stack = stack->next;
+ free(old);
+
+ return true;
+ }
+
+ return false;
+}
+
+static struct cidr * cidr_clone(struct cidr *a)
+{
+ struct cidr *b = malloc(sizeof(*b));
+
+ if (!b)
+ {
+ fprintf(stderr, "out of memory\n");
+ exit(255);
+ }
+
+ memcpy(b, a, sizeof(*b));
+ cidr_push(b);
+
+ return b;
+}
+
+
+static struct cidr * cidr_parse4(const char *s)
+{
+ char *p = NULL, *r;
+ struct in_addr mask;
+ struct cidr *addr = malloc(sizeof(struct cidr));
+
+ if (!addr || (strlen(s) >= sizeof(addr->buf.v4)))
+ goto err;
+
+ snprintf(addr->buf.v4, sizeof(addr->buf.v4), "%s", s);
+
+ addr->family = AF_INET;
+
+ if ((p = strchr(addr->buf.v4, '/')) != NULL)
+ {
+ *p++ = 0;
+
+ if (strchr(p, '.') != NULL)
+ {
+ if (inet_pton(AF_INET, p, &mask) != 1)
+ goto err;
+
+ for (addr->prefix = 0; mask.s_addr; mask.s_addr >>= 1)
+ addr->prefix += (mask.s_addr & 1);
+ }
+ else
+ {
+ addr->prefix = strtoul(p, &r, 10);
+
+ if ((p == r) || (*r != 0) || (addr->prefix > 32))
+ goto err;
+ }
+ }
+ else
+ {
+ addr->prefix = 32;
+ }
+
+ if (p == addr->buf.v4+1)
+ memset(&addr->addr.v4, 0, sizeof(addr->addr.v4));
+ else if (inet_pton(AF_INET, addr->buf.v4, &addr->addr.v4) != 1)
+ goto err;
+
+ return addr;
+
+err:
+ if (addr)
+ free(addr);
+
+ return NULL;
+}
+
+static bool cidr_add4(struct cidr *a, struct cidr *b)
+{
+ uint32_t x = ntohl(a->addr.v4.s_addr);
+ uint32_t y = ntohl(b->addr.v4.s_addr);
+
+ struct cidr *n = cidr_clone(a);
+
+ if ((n->family != AF_INET) || (b->family != AF_INET))
+ return false;
+
+ if ((uint32_t)(x + y) < x)
+ {
+ fprintf(stderr, "overflow during 'add'\n");
+ return false;
+ }
+
+ n->addr.v4.s_addr = htonl(x + y);
+ return true;
+}
+
+static bool cidr_sub4(struct cidr *a, struct cidr *b)
+{
+ uint32_t x = ntohl(a->addr.v4.s_addr);
+ uint32_t y = ntohl(b->addr.v4.s_addr);
+
+ struct cidr *n = cidr_clone(a);
+
+ if ((n->family != AF_INET) || (b->family != AF_INET))
+ return false;
+
+ if ((uint32_t)(x - y) > x)
+ {
+ fprintf(stderr, "underflow during 'sub'\n");
+ return false;
+ }
+
+ n->addr.v4.s_addr = htonl(x - y);
+ return true;
+}
+
+static bool cidr_network4(struct cidr *a)
+{
+ struct cidr *n = cidr_clone(a);
+
+ n->addr.v4.s_addr &= htonl(~((1 << (32 - n->prefix)) - 1));
+ n->prefix = 32;
+
+ return true;
+}
+
+static bool cidr_broadcast4(struct cidr *a)
+{
+ struct cidr *n = cidr_clone(a);
+
+ n->addr.v4.s_addr |= htonl(((1 << (32 - n->prefix)) - 1));
+ n->prefix = 32;
+
+ return true;
+}
+
+static bool cidr_contains4(struct cidr *a, struct cidr *b)
+{
+ uint32_t net1 = a->addr.v4.s_addr & htonl(~((1 << (32 - a->prefix)) - 1));
+ uint32_t net2 = b->addr.v4.s_addr & htonl(~((1 << (32 - a->prefix)) - 1));
+
+ if (printed)
+ qprintf(" ");
+
+ if ((b->prefix >= a->prefix) && (net1 == net2))
+ {
+ qprintf("1");
+ return true;
+ }
+ else
+ {
+ qprintf("0");
+ return false;
+ }
+}
+
+static bool cidr_netmask4(struct cidr *a)
+{
+ struct cidr *n = cidr_clone(a);
+
+ n->addr.v4.s_addr = htonl(~((1 << (32 - n->prefix)) - 1));
+ n->prefix = 32;
+
+ return true;
+}
+
+static bool cidr_private4(struct cidr *a)
+{
+ uint32_t x = ntohl(a->addr.v4.s_addr);
+
+ if (printed)
+ qprintf(" ");
+
+ if (((x >= 0x0A000000) && (x <= 0x0AFFFFFF)) ||
+ ((x >= 0xAC100000) && (x <= 0xAC1FFFFF)) ||
+ ((x >= 0xC0A80000) && (x <= 0xC0A8FFFF)))
+ {
+ qprintf("1");
+ return true;
+ }
+ else
+ {
+ qprintf("0");
+ return false;
+ }
+}
+
+static bool cidr_linklocal4(struct cidr *a)
+{
+ uint32_t x = ntohl(a->addr.v4.s_addr);
+
+ if (printed)
+ qprintf(" ");
+
+ if ((x >= 0xA9FE0000) && (x <= 0xA9FEFFFF))
+ {
+ qprintf("1");
+ return true;
+ }
+ else
+ {
+ qprintf("0");
+ return false;
+ }
+}
+
+static bool cidr_prev4(struct cidr *a, struct cidr *b)
+{
+ struct cidr *n = cidr_clone(a);
+
+ n->prefix = b->prefix;
+ n->addr.v4.s_addr -= htonl(1 << (32 - b->prefix));
+
+ return true;
+}
+
+static bool cidr_next4(struct cidr *a, struct cidr *b)
+{
+ struct cidr *n = cidr_clone(a);
+
+ n->prefix = b->prefix;
+ n->addr.v4.s_addr += htonl(1 << (32 - b->prefix));
+
+ return true;
+}
+
+static bool cidr_6to4(struct cidr *a)
+{
+ struct cidr *n = cidr_clone(a);
+ uint32_t x = a->addr.v4.s_addr;
+
+ memset(&n->addr.v6.s6_addr, 0, sizeof(n->addr.v6.s6_addr));
+
+ n->family = AF_INET6;
+ n->prefix = 48;
+
+ n->addr.v6.s6_addr[0] = 0x20;
+ n->addr.v6.s6_addr[1] = 0x02;
+ n->addr.v6.s6_addr[2] = (x >> 24);
+ n->addr.v6.s6_addr[3] = (x >> 16) & 0xFF;
+ n->addr.v6.s6_addr[4] = (x >> 8) & 0xFF;
+ n->addr.v6.s6_addr[5] = x & 0xFF;
+
+ return true;
+}
+
+static bool cidr_print4(struct cidr *a)
+{
+ char *p;
+
+ if (!a || (a->family != AF_INET))
+ return false;
+
+ if (!(p = (char *)inet_ntop(AF_INET, &a->addr.v4, a->buf.v4, sizeof(a->buf.v4))))
+ return false;
+
+ if (printed)
+ qprintf(" ");
+
+ qprintf("%s", p);
+
+ if (a->prefix < 32)
+ qprintf("/%u", a->prefix);
+
+ cidr_pop(a);
+
+ return true;
+}
+
+
+static struct cidr * cidr_parse6(const char *s)
+{
+ char *p = NULL, *r;
+ struct cidr *addr = malloc(sizeof(struct cidr));
+
+ if (!addr || (strlen(s) >= sizeof(addr->buf.v6)))
+ goto err;
+
+ snprintf(addr->buf.v4, sizeof(addr->buf.v6), "%s", s);
+
+ addr->family = AF_INET6;
+
+ if ((p = strchr(addr->buf.v4, '/')) != NULL)
+ {
+ *p++ = 0;
+
+ addr->prefix = strtoul(p, &r, 10);
+
+ if ((p == r) || (*r != 0) || (addr->prefix > 128))
+ goto err;
+ }
+ else
+ {
+ addr->prefix = 128;
+ }
+
+ if (p == addr->buf.v4+1)
+ memset(&addr->addr.v6, 0, sizeof(addr->addr.v6));
+ else if (inet_pton(AF_INET6, addr->buf.v4, &addr->addr.v6) != 1)
+ goto err;
+
+ return addr;
+
+err:
+ if (addr)
+ free(addr);
+
+ return NULL;
+}
+
+static bool cidr_add6(struct cidr *a, struct cidr *b)
+{
+ uint8_t idx = 15, carry = 0, overflow = 0;
+
+ struct cidr *n = cidr_clone(a);
+ struct in6_addr *x = &n->addr.v6;
+ struct in6_addr *y = &b->addr.v6;
+
+ if ((a->family != AF_INET6) || (b->family != AF_INET6))
+ return false;
+
+ do {
+ overflow = !!((x->s6_addr[idx] + y->s6_addr[idx] + carry) >= 256);
+ x->s6_addr[idx] += y->s6_addr[idx] + carry;
+ carry = overflow;
+ }
+ while (idx-- > 0);
+
+ if (carry)
+ {
+ fprintf(stderr, "overflow during 'add'\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool cidr_sub6(struct cidr *a, struct cidr *b)
+{
+ uint8_t idx = 15, carry = 0, underflow = 0;
+
+ struct cidr *n = cidr_clone(a);
+ struct in6_addr *x = &n->addr.v6;
+ struct in6_addr *y = &b->addr.v6;
+
+ if ((n->family != AF_INET6) || (b->family != AF_INET6))
+ return false;
+
+ do {
+ underflow = !!((x->s6_addr[idx] - y->s6_addr[idx] - carry) < 0);
+ x->s6_addr[idx] -= y->s6_addr[idx] + carry;
+ carry = underflow;
+ }
+ while (idx-- > 0);
+
+ if (carry)
+ {
+ fprintf(stderr, "underflow during 'sub'\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool cidr_prev6(struct cidr *a, struct cidr *b)
+{
+ uint8_t idx, carry = 1, underflow = 0;
+ struct cidr *n = cidr_clone(a);
+ struct in6_addr *x = &n->addr.v6;
+
+ if (b->prefix == 0)
+ {
+ fprintf(stderr, "underflow during 'prev'\n");
+ return false;
+ }
+
+ idx = (b->prefix - 1) / 8;
+
+ do {
+ underflow = !!((x->s6_addr[idx] - carry) < 0);
+ x->s6_addr[idx] -= carry;
+ carry = underflow;
+ }
+ while (idx-- > 0);
+
+ if (carry)
+ {
+ fprintf(stderr, "underflow during 'prev'\n");
+ return false;
+ }
+
+ n->prefix = b->prefix;
+
+ return true;
+}
+
+static bool cidr_next6(struct cidr *a, struct cidr *b)
+{
+ uint8_t idx, carry = 1, overflow = 0;
+ struct cidr *n = cidr_clone(a);
+ struct in6_addr *x = &n->addr.v6;
+
+ if (b->prefix == 0)
+ {
+ fprintf(stderr, "overflow during 'next'\n");
+ return false;
+ }
+
+ idx = (b->prefix - 1) / 8;
+
+ do {
+ overflow = !!((x->s6_addr[idx] + carry) >= 256);
+ x->s6_addr[idx] += carry;
+ carry = overflow;
+ }
+ while (idx-- > 0);
+
+ if (carry)
+ {
+ fprintf(stderr, "overflow during 'next'\n");
+ return false;
+ }
+
+ n->prefix = b->prefix;
+
+ return true;
+}
+
+static bool cidr_network6(struct cidr *a)
+{
+ uint8_t i;
+ struct cidr *n = cidr_clone(a);
+
+ for (i = 0; i < (128 - n->prefix) / 8; i++)
+ n->addr.v6.s6_addr[15-i] = 0;
+
+ if ((128 - n->prefix) % 8)
+ n->addr.v6.s6_addr[15-i] &= ~((1 << ((128 - n->prefix) % 8)) - 1);
+
+ return true;
+}
+
+static bool cidr_contains6(struct cidr *a, struct cidr *b)
+{
+ struct cidr *n = cidr_clone(a);
+ struct in6_addr *x = &n->addr.v6;
+ struct in6_addr *y = &b->addr.v6;
+ uint8_t i = (128 - n->prefix) / 8;
+ uint8_t m = ~((1 << ((128 - n->prefix) % 8)) - 1);
+ uint8_t net1 = x->s6_addr[15-i] & m;
+ uint8_t net2 = y->s6_addr[15-i] & m;
+
+ if (printed)
+ qprintf(" ");
+
+ if ((b->prefix >= n->prefix) && (net1 == net2) &&
+ ((i == 15) || !memcmp(&x->s6_addr, &y->s6_addr, 15-i)))
+ {
+ qprintf("1");
+ return true;
+ }
+ else
+ {
+ qprintf("0");
+ return false;
+ }
+}
+
+static bool cidr_linklocal6(struct cidr *a)
+{
+ if (printed)
+ qprintf(" ");
+
+ if ((a->addr.v6.s6_addr[0] == 0xFE) &&
+ (a->addr.v6.s6_addr[1] >= 0x80) &&
+ (a->addr.v6.s6_addr[1] <= 0xBF))
+ {
+ qprintf("1");
+ return true;
+ }
+ else
+ {
+ qprintf("0");
+ return false;
+ }
+}
+
+static bool cidr_ula6(struct cidr *a)
+{
+ if (printed)
+ qprintf(" ");
+
+ if ((a->addr.v6.s6_addr[0] >= 0xFC) &&
+ (a->addr.v6.s6_addr[0] <= 0xFD))
+ {
+ qprintf("1");
+ return true;
+ }
+ else
+ {
+ qprintf("0");
+ return false;
+ }
+}
+
+static bool cidr_print6(struct cidr *a)
+{
+ char *p;
+
+ if (!a || (a->family != AF_INET6))
+ return NULL;
+
+ if (!(p = (char *)inet_ntop(AF_INET6, &a->addr.v6, a->buf.v6, sizeof(a->buf.v6))))
+ return false;
+
+ if (printed)
+ qprintf(" ");
+
+ qprintf("%s", p);
+
+ if (a->prefix < 128)
+ qprintf("/%u", a->prefix);
+
+ cidr_pop(a);
+
+ return true;
+}
+
+
+static struct cidr * cidr_parse(const char *op, const char *s, int af_hint)
+{
+ char *r;
+ struct cidr *a;
+
+ uint8_t i;
+ uint32_t sum = strtoul(s, &r, 0);
+
+ if ((r > s) && (*r == 0))
+ {
+ a = malloc(sizeof(struct cidr));
+
+ if (!a)
+ return NULL;
+
+ if (af_hint == AF_INET)
+ {
+ a->family = AF_INET;
+ a->prefix = sum;
+ a->addr.v4.s_addr = htonl(sum);
+ }
+ else
+ {
+ a->family = AF_INET6;
+ a->prefix = sum;
+
+ for (i = 0; i <= 15; i++)
+ {
+ a->addr.v6.s6_addr[15-i] = sum % 256;
+ sum >>= 8;
+ }
+ }
+
+ return a;
+ }
+
+ if (strchr(s, ':'))
+ a = cidr_parse6(s);
+ else
+ a = cidr_parse4(s);
+
+ if (!a)
+ return NULL;
+
+ if (a->family != af_hint)
+ {
+ fprintf(stderr, "attempt to '%s' %s with %s address\n",
+ op,
+ (af_hint == AF_INET) ? "ipv4" : "ipv6",
+ (af_hint != AF_INET) ? "ipv4" : "ipv6");
+ exit(4);
+ }
+
+ return a;
+}
+
+static bool cidr_howmany(struct cidr *a, struct cidr *b)
+{
+ if (printed)
+ qprintf(" ");
+
+ if (b->prefix < a->prefix)
+ qprintf("0");
+ else
+ qprintf("%u", 1 << (b->prefix - a->prefix));
+
+ return true;
+}
+
+static bool cidr_prefix(struct cidr *a, struct cidr *b)
+{
+ a->prefix = b->prefix;
+ return true;
+}
+
+static bool cidr_quiet(struct cidr *a)
+{
+ quiet = true;
+ return true;
+}
+
+
+struct op ops[] = {
+ { .name = "add",
+ .desc = "Add argument to base address",
+ .f4.a2 = cidr_add4,
+ .f6.a2 = cidr_add6 },
+
+ { .name = "sub",
+ .desc = "Substract argument from base address",
+ .f4.a2 = cidr_sub4,
+ .f6.a2 = cidr_sub6 },
+
+ { .name = "next",
+ .desc = "Advance base address to next prefix of given size",
+ .f4.a2 = cidr_next4,
+ .f6.a2 = cidr_next6 },
+
+ { .name = "prev",
+ .desc = "Lower base address to previous prefix of give size",
+ .f4.a2 = cidr_prev4,
+ .f6.a2 = cidr_prev6 },
+
+ { .name = "network",
+ .desc = "Turn base address into network address",
+ .f4.a1 = cidr_network4,
+ .f6.a1 = cidr_network6 },
+
+ { .name = "broadcast",
+ .desc = "Turn base address into broadcast address",
+ .f4.a1 = cidr_broadcast4 },
+
+ { .name = "prefix",
+ .desc = "Set the prefix of base address to argument",
+ .f4.a2 = cidr_prefix,
+ .f6.a2 = cidr_prefix },
+
+ { .name = "netmask",
+ .desc = "Calculate netmask of base address",
+ .f4.a1 = cidr_netmask4 },
+
+ { .name = "6to4",
+ .desc = "Calculate 6to4 prefix of given ipv4-address",
+ .f4.a1 = cidr_6to4 },
+
+ { .name = "howmany",
+ .desc = "Print amount of righ-hand prefixes that fit into base address",
+ .f4.a2 = cidr_howmany,
+ .f6.a2 = cidr_howmany },
+
+ { .name = "contains",
+ .desc = "Print '1' if argument fits into base address or '0' if not",
+ .f4.a2 = cidr_contains4,
+ .f6.a2 = cidr_contains6 },
+
+ { .name = "private",
+ .desc = "Print '1' if base address is in RFC1918 private space or '0' "
+ "if not",
+ .f4.a1 = cidr_private4 },
+
+ { .name = "linklocal",
+ .desc = "Print '1' if base address is in 169.254.0.0/16 or FE80::/10 "
+ "link local space or '0' if not",
+ .f4.a1 = cidr_linklocal4,
+ .f6.a1 = cidr_linklocal6 },
+
+ { .name = "ula",
+ .desc = "Print '1' if base address is in FC00::/7 unique local address "
+ "(ULA) space or '0' if not",
+ .f6.a1 = cidr_ula6 },
+
+ { .name = "quiet",
+ .desc = "Suppress output, useful for test operation where the result can "
+ "be inferred from the exit code",
+ .f4.a1 = cidr_quiet,
+ .f6.a1 = cidr_quiet },
+
+ { .name = "pop",
+ .desc = "Pop intermediate result from stack",
+ .f4.a1 = cidr_pop,
+ .f6.a1 = cidr_pop },
+
+ { .name = "print",
+ .desc = "Print intermediate result and pop it from stack, invoked "
+ "implicitely at the end of calculation if no intermediate prints "
+ "happened",
+ .f4.a1 = cidr_print4,
+ .f6.a1 = cidr_print6 },
+};
+
+static void usage(const char *prog)
+{
+ int i;
+
+ fprintf(stderr,
+ "\n"
+ "Usage:\n\n"
+ " %s {base address} operation [argument] "
+ "[operation [argument] ...]\n\n"
+ "Operations:\n\n",
+ prog);
+
+ for (i = 0; i < sizeof(ops) / sizeof(ops[0]); i++)
+ {
+ if (ops[i].f4.a2 || ops[i].f6.a2)
+ {
+ fprintf(stderr, " %s %s\n",
+ ops[i].name,
+ (ops[i].f4.a2 && ops[i].f6.a2) ? "{ipv4/ipv6/amount}" :
+ (ops[i].f6.a2 ? "{ipv6/amount}" : "{ipv4/amount}"));
+ }
+ else
+ {
+ fprintf(stderr, " %s\n", ops[i].name);
+ }
+
+ fprintf(stderr, " %s.\n", ops[i].desc);
+
+ if ((ops[i].f4.a1 && ops[i].f6.a1) || (ops[i].f4.a2 && ops[i].f6.a2))
+ fprintf(stderr, " Applicable to ipv4- and ipv6-addresses.\n\n");
+ else if (ops[i].f6.a2 || ops[i].f6.a1)
+ fprintf(stderr, " Only applicable to ipv6-addresses.\n\n");
+ else
+ fprintf(stderr, " Only applicable to ipv4-addresses.\n\n");
+ }
+
+ fprintf(stderr,
+ "Examples:\n\n"
+ " Calculate a DHCP range:\n\n"
+ " $ %s 192.168.1.1/255.255.255.0 network add 100 print add 150 print\n"
+ " 192.168.1.100\n"
+ " 192.168.1.250\n\n"
+ " Count number of prefixes:\n\n"
+ " $ %s 2001:0DB8:FDEF::/48 howmany ::/64\n"
+ " 65536\n\n",
+ prog, prog);
+
+ exit(1);
+}
+
+static bool runop(char ***arg, int *status)
+{
+ int i;
+ char *arg1 = **arg;
+ char *arg2 = *(*arg+1);
+ struct cidr *a = stack;
+ struct cidr *b = NULL;
+
+ if (!arg1)
+ return false;
+
+ for (i = 0; i < sizeof(ops) / sizeof(ops[0]); i++)
+ {
+ if (!strcmp(ops[i].name, arg1))
+ {
+ if (ops[i].f4.a2 || ops[i].f6.a2)
+ {
+ if (!arg2)
+ {
+ fprintf(stderr, "'%s' requires an argument\n",
+ ops[i].name);
+
+ *status = 2;
+ return false;
+ }
+
+ b = cidr_parse(ops[i].name, arg2, a->family);
+
+ if (!b)
+ {
+ fprintf(stderr, "invalid address argument for '%s'\n",
+ ops[i].name);
+
+ *status = 3;
+ return false;
+ }
+
+ *arg += 2;
+
+ if (((a->family == AF_INET) && !ops[i].f4.a2) ||
+ ((a->family == AF_INET6) && !ops[i].f6.a2))
+ {
+ fprintf(stderr, "'%s' not supported for %s addresses\n",
+ ops[i].name,
+ (a->family == AF_INET) ? "ipv4" : "ipv6");
+
+ *status = 5;
+ return false;
+ }
+
+ *status = !((a->family == AF_INET) ? ops[i].f4.a2(a, b)
+ : ops[i].f6.a2(a, b));
+
+ return true;
+ }
+ else
+ {
+ *arg += 1;
+
+ if (((a->family == AF_INET) && !ops[i].f4.a1) ||
+ ((a->family == AF_INET6) && !ops[i].f6.a1))
+ {
+ fprintf(stderr, "'%s' not supported for %s addresses\n",
+ ops[i].name,
+ (a->family == AF_INET) ? "ipv4" : "ipv6");
+
+ *status = 5;
+ return false;
+ }
+
+ *status = !((a->family == AF_INET) ? ops[i].f4.a1(a)
+ : ops[i].f6.a1(a));
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+int main(int argc, char **argv)
+{
+ int status = 0;
+ char **arg = argv+2;
+ struct cidr *a;
+
+ if (argc < 3)
+ usage(argv[0]);
+
+ a = strchr(argv[1], ':') ? cidr_parse6(argv[1]) : cidr_parse4(argv[1]);
+
+ if (!a)
+ usage(argv[0]);
+
+ cidr_push(a);
+
+ while (runop(&arg, &status));
+
+ if (*arg)
+ {
+ fprintf(stderr, "unknown operation '%s'\n", *arg);
+ exit(6);
+ }
+
+ if (!printed && (status < 2))
+ {
+ if (stack->family == AF_INET)
+ cidr_print4(stack);
+ else
+ cidr_print6(stack);
+ }
+
+ qprintf("\n");
+
+ exit(status);
+}
diff --git a/package/network/utils/resolveip/Makefile b/package/network/utils/resolveip/Makefile
new file mode 100644
index 0000000..3243a80
--- /dev/null
+++ b/package/network/utils/resolveip/Makefile
@@ -0,0 +1,46 @@
+#
+# 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 <jow@openwrt.org>
+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/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)
+ $(INSTALL_DATA) ./src/resolveip.c $(PKG_BUILD_DIR)/
+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..43c5ae7
--- /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 <jow@openwrt.org> 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..6ca4e32
--- /dev/null
+++ b/package/network/utils/rssileds/Makefile
@@ -0,0 +1,49 @@
+#
+# 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_VERSION:=0.2
+PKG_RELEASE:=1
+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
+ MAINTAINER:=Daniel Golle <dgolle@allnet.de>
+endef
+
+define Package/rssileds/description
+ A small process written in C to update the signal-strength indicator LEDs
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(TARGET_CC) $(TARGET_CFLAGS) -Wall -liwinfo \
+ -o $(PKG_BUILD_DIR)/rssileds $(PKG_BUILD_DIR)/rssileds.c
+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/
+endef
+
+$(eval $(call BuildPackage,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..b0d2627
--- /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=96
+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..8e33a2b
--- /dev/null
+++ b/package/network/utils/tcpdump/Makefile
@@ -0,0 +1,90 @@
+#
+# 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.5.1
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.tcpdump.org/release/ \
+ http://ftp.gwdg.de/pub/misc/tcpdump/ \
+ http://www.at.tcpdump.org/ \
+ http://www.br.tcpdump.org/
+PKG_MD5SUM:=973a2513d0076e34aa9da7e15ed98e1b
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_BUILD_PARALLEL:=1
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+PKG_LICENSE:=BSD-3-Clause
+
+PKG_INSTALL:=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-crypto
+
+ifeq ($(CONFIG_IPV6),y)
+CONFIGURE_ARGS += \
+ --enable-ipv6
+endif
+
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+CONFIGURE_VARS += \
+ BUILD_CC="$(TARGET_CC)" \
+ HOSTCC="$(HOSTCC)" \
+ td_cv_buggygetaddrinfo="no" \
+ ac_cv_linux_vers=$(LINUX_VERSION) \
+ ac_cv_header_rpc_rpcent_h=no \
+ ac_cv_lib_rpc_main=no \
+ ac_cv_path_PCAP_CONFIG=""
+
+MAKE_FLAGS :=
+
+ifeq ($(BUILD_VARIANT),mini)
+ TARGET_CFLAGS += -DTCPDUMP_MINI
+ CONFIGURE_ARGS += --disable-smb
+ MAKE_FLAGS += TCPDUMP_MINI=1
+endif
+
+MAKE_FLAGS += \
+ CCOPT="$(TARGET_CFLAGS)" INCLS="-I. $(TARGET_CPPFLAGS)"
+
+
+define Package/tcpdump/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/tcpdump $(1)/usr/sbin/
+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..d2c724d
--- /dev/null
+++ b/package/network/utils/tcpdump/patches/001-remove_pcap_debug.patch
@@ -0,0 +1,23 @@
+--- a/tcpdump.c
++++ b/tcpdump.c
+@@ -1095,20 +1095,6 @@ main(int argc, char **argv)
+ error("invalid data link type %s", gndo->ndo_dltname);
+ break;
+
+-#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG)
+- case 'Y':
+- {
+- /* Undocumented flag */
+-#ifdef HAVE_PCAP_DEBUG
+- extern int pcap_debug;
+- pcap_debug = 1;
+-#else
+- extern int yydebug;
+- yydebug = 1;
+-#endif
+- }
+- break;
+-#endif
+ case 'z':
+ if (optarg) {
+ zflag = strdup(optarg);
diff --git a/package/network/utils/tcpdump/patches/002-remove_static_libpcap_check.patch b/package/network/utils/tcpdump/patches/002-remove_static_libpcap_check.patch
new file mode 100644
index 0000000..c8bdf14
--- /dev/null
+++ b/package/network/utils/tcpdump/patches/002-remove_static_libpcap_check.patch
@@ -0,0 +1,73 @@
+--- a/configure
++++ b/configure
+@@ -5813,28 +5813,6 @@ $as_echo "Using $pfopen" >&6; }
+ LIBS="$LIBS $pfopen"
+ fi
+ fi
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local pcap library" >&5
+-$as_echo_n "checking for local pcap library... " >&6; }
+- libpcap=FAIL
+- lastdir=FAIL
+- places=`ls $srcdir/.. | sed -e 's,/$,,' -e "s,^,$srcdir/../," | \
+- egrep '/libpcap-[0-9]+\.[0-9]+(\.[0-9]*)?([ab][0-9]*|-PRE-GIT)?$'`
+- for dir in $places $srcdir/../libpcap $srcdir/libpcap ; do
+- basedir=`echo $dir | sed -e 's/[ab][0-9]*$//' | \
+- sed -e 's/-PRE-GIT$//' `
+- if test $lastdir = $basedir ; then
+- continue;
+- fi
+- lastdir=$dir
+- if test -r $dir/libpcap.a ; then
+- libpcap=$dir/libpcap.a
+- d=$dir
+- fi
+- done
+- if test $libpcap = FAIL ; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+-$as_echo "not found" >&6; }
+-
+ #
+ # Look for pcap-config.
+ #
+@@ -5989,41 +5967,6 @@ if test "x$ac_cv_lib_pcap_main" = xyes;
+ libpcap="-lpcap"
+ fi
+
+- if test $libpcap = FAIL ; then
+- as_fn_error $? "see the INSTALL doc for more info" "$LINENO" 5
+- fi
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for extraneous pcap header directories" >&5
+-$as_echo_n "checking for extraneous pcap header directories... " >&6; }
+- if test \( ! -r /usr/local/include/pcap.h \) -a \
+- \( ! -r /usr/include/pcap.h \); then
+- if test -r /usr/local/include/pcap/pcap.h; then
+- d="/usr/local/include/pcap"
+- elif test -r /usr/include/pcap/pcap.h; then
+- d="/usr/include/pcap"
+- fi
+- fi
+- if test -z "$d" ; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+-$as_echo "not found" >&6; }
+- else
+- V_INCLS="-I$d $V_INCLS"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: found -- -I$d added" >&5
+-$as_echo "found -- -I$d added" >&6; }
+- fi
+- fi
+- else
+- V_PCAPDEP=$libpcap
+- places=`ls $srcdir/.. | sed -e 's,/$,,' -e "s,^,$srcdir/../," | \
+- egrep '/libpcap-[0-9]*.[0-9]*(.[0-9]*)?([ab][0-9]*)?$'`
+- if test -r $d/pcap.h; then
+- V_INCLS="-I$d $V_INCLS"
+- elif test -r $places/pcap.h; then
+- V_INCLS="-I$places $V_INCLS"
+- else
+- as_fn_error see INSTALL "cannot find pcap.h" "$LINENO" 5
+- fi
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libpcap" >&5
+-$as_echo "$libpcap" >&6; }
+ # Extract the first word of "pcap-config", so it can be a program name with args.
+ set dummy pcap-config; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
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..8d07be6
--- /dev/null
+++ b/package/network/utils/tcpdump/patches/100-tcpdump_mini.patch
@@ -0,0 +1,844 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -71,6 +71,22 @@ DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
+ @rm -f $@
+ $(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
+
++ifdef TCPDUMP_MINI
++
++CSRC = addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c \
++ nlpid.c l2vpn.c machdep.c parsenfsfh.c in_cksum.c \
++ print-802_11.c print-aodv.c print-arp.c print-ascii.c \
++ print-bgp.c print-bootp.c print-cdp.c print-domain.c print-eap.c print-ether.c \
++ print-gre.c print-icmp.c print-igmp.c print-ip.c \
++ print-l2tp.c print-lldp.c print-llc.c \
++ print-nfs.c print-ntp.c print-null.c print-olsr.c print-ospf.c \
++ print-ppp.c print-pppoe.c print-pptp.c print-radius.c print-raw.c print-rsvp.c \
++ print-sctp.c print-sip.c print-sll.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 \
++ setsignal.c tcpdump.c util.c signature.c print-ipnet.c print-forces.c
++
++else
++
+ CSRC = addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c \
+ nlpid.c l2vpn.c machdep.c parsenfsfh.c in_cksum.c \
+ print-802_11.c print-802_15_4.c print-ap1394.c print-ah.c \
+@@ -103,6 +119,8 @@ LIBNETDISSECT_SRC=print-isakmp.c
+ LIBNETDISSECT_OBJ=$(LIBNETDISSECT_SRC:.c=.o)
+ LIBNETDISSECT=libnetdissect.a
+
++endif
++
+ LOCALSRC = @LOCALSRC@
+ GENSRC = version.c
+ LIBOBJS = @LIBOBJS@
+@@ -286,10 +304,12 @@ $(PROG): $(OBJ) @V_PCAPDEP@
+ @rm -f $@
+ $(CC) $(FULL_CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
+
++ifndef TCPDUMP_MINI
+ $(LIBNETDISSECT): $(LIBNETDISSECT_OBJ)
+ @rm -f $@
+ $(AR) cr $@ $(LIBNETDISSECT_OBJ)
+ $(RANLIB) $@
++endif
+
+ datalinks.o: $(srcdir)/missing/datalinks.c
+ $(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/datalinks.c
+--- a/addrtoname.c
++++ b/addrtoname.c
+@@ -556,10 +556,10 @@ linkaddr_string(const u_char *ep, const
+
+ if (type == LINKADDR_ETHER && len == ETHER_ADDR_LEN)
+ return (etheraddr_string(ep));
+-
++#ifndef TCPDUMP_MINI
+ if (type == LINKADDR_FRELAY)
+ return (q922_string(ep));
+-
++#endif
+ tp = lookup_bytestring(ep, len);
+ if (tp->e_name)
+ return (tp->e_name);
+@@ -1159,6 +1159,7 @@ init_addrtoname(u_int32_t localnet, u_in
+ init_ipxsaparray();
+ }
+
++#ifndef TCPDUMP_MINI
+ const char *
+ dnaddr_string(u_short dnaddr)
+ {
+@@ -1178,6 +1179,7 @@ dnaddr_string(u_short dnaddr)
+
+ 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
+@@ -342,6 +342,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);
+@@ -360,10 +361,13 @@ ethertype_print(netdissect_options *ndo,
+ ND_PRINT((ndo, "(NOV-ETHII) "));
+ ipx_print(/*ndo,*/p, length);
+ return (1);
++#endif
+
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_ISO:
+ isoclns_print(/*ndo,*/p+1, length-1, length-1);
+ return(1);
++#endif
+
+ case ETHERTYPE_PPPOED:
+ case ETHERTYPE_PPPOES:
+@@ -376,9 +380,11 @@ ethertype_print(netdissect_options *ndo,
+ eap_print(ndo, p, length);
+ return (1);
+
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_RRCP:
+ rrcp_print(ndo, p - 14 , length + 14);
+ return (1);
++#endif
+
+ case ETHERTYPE_PPP:
+ if (length) {
+@@ -387,6 +393,7 @@ ethertype_print(netdissect_options *ndo,
+ }
+ return (1);
+
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_MPCP:
+ mpcp_print(/*ndo,*/p, length);
+ return (1);
+@@ -399,7 +406,7 @@ 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);
+@@ -407,6 +414,7 @@ ethertype_print(netdissect_options *ndo,
+ case ETHERTYPE_LOOPBACK:
+ return (1);
+
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_MPLS:
+ case ETHERTYPE_MPLS_MULTI:
+ mpls_print(/*ndo,*/p, length);
+@@ -428,6 +436,7 @@ ethertype_print(netdissect_options *ndo,
+ case ETHERTYPE_CALM_FAST:
+ calm_fast_print(ndo, p-14, p, length);
+ return (1);
++#endif
+
+ case ETHERTYPE_LAT:
+ case ETHERTYPE_SCA:
+--- a/print-gre.c
++++ b/print-gre.c
+@@ -213,6 +213,7 @@ gre_print_0(const u_char *bp, u_int leng
+ ip6_print(gndo, bp, len);
+ break;
+ #endif
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_MPLS:
+ mpls_print(bp, len);
+ break;
+@@ -228,6 +229,7 @@ gre_print_0(const u_char *bp, u_int leng
+ case ETHERTYPE_TEB:
+ ether_print(gndo, bp, len, len, NULL, NULL);
+ break;
++#endif
+ default:
+ printf("gre-proto-0x%x", prot);
+ }
+--- a/print-igmp.c
++++ b/print-igmp.c
+@@ -309,6 +309,7 @@ igmp_print(register const u_char *bp, re
+ TCHECK2(bp[4], 4);
+ (void)printf("igmp leave %s", ipaddr_string(&bp[4]));
+ break;
++#ifndef TCPDUMP_MINI
+ case 0x13:
+ (void)printf("igmp dvmrp");
+ if (len < 8)
+@@ -320,6 +321,7 @@ igmp_print(register const u_char *bp, re
+ (void)printf("igmp pimv1");
+ pimv1_print(bp, len);
+ break;
++#endif
+ case 0x1e:
+ print_mresp(bp, len);
+ break;
+--- a/print-ip.c
++++ b/print-ip.c
+@@ -328,6 +328,7 @@ ip_print_demux(netdissect_options *ndo,
+ again:
+ switch (ipds->nh) {
+
++#ifndef TCPDUMP_MINI
+ case IPPROTO_AH:
+ ipds->nh = *ipds->cp;
+ ipds->advance = ah_print(ipds->cp);
+@@ -362,15 +363,15 @@ again:
+ ipds->nh = enh & 0xff;
+ goto again;
+ }
+-
++#endif
+ case IPPROTO_SCTP:
+ sctp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
+ break;
+-
++#ifndef TCPDUMP_MINI
+ case IPPROTO_DCCP:
+ dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
+ break;
+-
++#endif
+ case IPPROTO_TCP:
+ /* pass on the MF bit plus the offset to detect fragments */
+ tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
+@@ -388,7 +389,7 @@ again:
+ icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
+ ipds->off & (IP_MF|IP_OFFMASK));
+ break;
+-
++#ifndef TCPDUMP_MINI
+ case IPPROTO_PIGP:
+ /*
+ * XXX - the current IANA protocol number assignments
+@@ -409,15 +410,15 @@ again:
+ case IPPROTO_EIGRP:
+ eigrp_print(ipds->cp, ipds->len);
+ break;
+-
++#endif
+ case IPPROTO_ND:
+ ND_PRINT((ndo, " nd %d", ipds->len));
+ break;
+-
++#ifndef TCPDUMP_MINI
+ case IPPROTO_EGP:
+ egp_print(ipds->cp, ipds->len);
+ break;
+-
++#endif
+ case IPPROTO_OSPF:
+ ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
+ break;
+@@ -451,10 +452,10 @@ again:
+ gre_print(ipds->cp, ipds->len);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case IPPROTO_MOBILE:
+ mobile_print(ipds->cp, ipds->len);
+ break;
+-
+ case IPPROTO_PIM:
+ vec[0].ptr = ipds->cp;
+ vec[0].len = ipds->len;
+@@ -480,7 +481,7 @@ again:
+ case IPPROTO_PGM:
+ pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
+ break;
+-
++#endif
+ default:
+ if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL)
+ ND_PRINT((ndo, " %s", proto->p_name));
+--- a/print-ip6.c
++++ b/print-ip6.c
+@@ -192,9 +192,11 @@ ip6_print(netdissect_options *ndo, const
+ case IPPROTO_SCTP:
+ sctp_print(cp, (const u_char *)ip6, len);
+ return;
++#ifndef TCPDUMP_MINI
+ case IPPROTO_DCCP:
+ dccp_print(cp, (const u_char *)ip6, len);
+ return;
++#endif
+ case IPPROTO_TCP:
+ tcp_print(cp, len, (const u_char *)ip6, fragmented);
+ return;
+@@ -204,6 +206,7 @@ ip6_print(netdissect_options *ndo, const
+ case IPPROTO_ICMPV6:
+ icmp6_print(ndo, cp, len, (const u_char *)ip6, fragmented);
+ return;
++#ifndef TCPDUMP_MINI
+ case IPPROTO_AH:
+ advance = ah_print(cp);
+ nh = *cp;
+@@ -228,7 +231,7 @@ ip6_print(netdissect_options *ndo, const
+ pim_print(cp, len, nextproto6_cksum(ip6, cp, len,
+ IPPROTO_PIM));
+ return;
+-
++#endif
+ case IPPROTO_OSPF:
+ ospf6_print(cp, len);
+ return;
+@@ -240,11 +243,11 @@ ip6_print(netdissect_options *ndo, const
+ case IPPROTO_IPV4:
+ ip_print(ndo, cp, len);
+ return;
+-
++#ifndef TCPDUMP_MINI
+ case IPPROTO_PGM:
+ pgm_print(cp, len, (const u_char *)ip6);
+ return;
+-
++#endif
+ case IPPROTO_GRE:
+ gre_print(cp, len);
+ return;
+--- a/print-llc.c
++++ b/print-llc.c
+@@ -196,7 +196,7 @@ llc_print(const u_char *p, u_int length,
+ control = EXTRACT_LE_16BITS(p + 2);
+ is_u = 0;
+ }
+-
++#ifndef TCPDUMP_MINI
+ if (ssap_field == LLCSAP_GLOBAL && dsap_field == LLCSAP_GLOBAL) {
+ /*
+ * This is an Ethernet_802.3 IPX frame; it has an
+@@ -219,6 +219,7 @@ llc_print(const u_char *p, u_int length,
+ ipx_print(p, length);
+ return (1);
+ }
++#endif
+
+ dsap = dsap_field & ~LLC_IG;
+ ssap = ssap_field & ~LLC_GSAP;
+@@ -251,6 +252,7 @@ llc_print(const u_char *p, u_int length,
+ return (1);
+ }
+
++#ifndef TCPDUMP_MINI
+ if (ssap == LLCSAP_IPX && dsap == LLCSAP_IPX &&
+ control == LLC_UI) {
+ /*
+@@ -266,6 +268,7 @@ llc_print(const u_char *p, u_int length,
+ ipx_print(p+3, length-3);
+ return (1);
+ }
++#endif
+
+ #ifdef TCPDUMP_DO_SMB
+ if (ssap == LLCSAP_NETBEUI && dsap == LLCSAP_NETBEUI
+@@ -297,11 +300,13 @@ llc_print(const u_char *p, u_int length,
+ return (1);
+ }
+ #endif
++#ifndef TCPDUMP_MINI
+ if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
+ && control == LLC_UI) {
+ isoclns_print(p + 3, length - 3, caplen - 3);
+ return (1);
+ }
++#endif
+
+ if (ssap == LLCSAP_SNAP && dsap == LLCSAP_SNAP
+ && control == LLC_UI) {
+@@ -444,6 +449,7 @@ snap_print(const u_char *p, u_int length
+ case PID_CISCO_CDP:
+ cdp_print(p, length, caplen);
+ return (1);
++#ifndef TCPDUMP_MINI
+ case PID_CISCO_DTP:
+ dtp_print(p, length);
+ return (1);
+@@ -453,6 +459,7 @@ snap_print(const u_char *p, u_int length
+ case PID_CISCO_VTP:
+ vtp_print(p, length);
+ return (1);
++#endif
+ case PID_CISCO_PVST:
+ case PID_CISCO_VLANBRIDGE:
+ stp_print(p, length);
+@@ -484,6 +491,7 @@ snap_print(const u_char *p, u_int length
+ ether_print(gndo, p, length, caplen, NULL, NULL);
+ return (1);
+
++#ifndef TCPDUMP_MINI
+ case PID_RFC2684_802_5_FCS:
+ case PID_RFC2684_802_5_NOFCS:
+ /*
+@@ -525,6 +533,7 @@ snap_print(const u_char *p, u_int length
+ */
+ fddi_print(p, length, caplen);
+ return (1);
++#endif
+
+ case PID_RFC2684_BPDU:
+ stp_print(p, length);
+--- a/print-null.c
++++ b/print-null.c
+@@ -128,7 +128,7 @@ null_if_print(const struct pcap_pkthdr *
+ ip6_print(gndo, p, length);
+ break;
+ #endif
+-
++#ifndef TCPDUMP_MINI
+ case BSD_AFNUM_ISO:
+ isoclns_print(p, length, caplen);
+ break;
+@@ -140,7 +140,7 @@ null_if_print(const struct pcap_pkthdr *
+ case BSD_AFNUM_IPX:
+ ipx_print(p, length);
+ break;
+-
++#endif
+ default:
+ /* unknown AF_ value */
+ if (!eflag)
+--- a/print-ppp.c
++++ b/print-ppp.c
+@@ -1262,7 +1262,7 @@ trunc:
+ return 0;
+ }
+
+-
++#ifndef TCPDUMP_MINI
+ static void
+ ppp_hdlc(const u_char *p, int length)
+ {
+@@ -1327,17 +1327,19 @@ cleanup:
+ free(b);
+ return;
+ }
++#endif
+
+
+ /* PPP */
+ static void
+ handle_ppp(u_int proto, const u_char *p, int length)
+ {
++#ifndef TCPDUMP_MINI
+ if ((proto & 0xff00) == 0x7e00) {/* is this an escape code ? */
+ ppp_hdlc(p-1, length);
+ return;
+ }
+-
++#endif
+ switch (proto) {
+ case PPP_LCP: /* fall through */
+ case PPP_IPCP:
+@@ -1371,6 +1373,7 @@ handle_ppp(u_int proto, const u_char *p,
+ ip6_print(gndo, p, length);
+ break;
+ #endif
++#ifndef TCPDUMP_MINI
+ case ETHERTYPE_IPX: /*XXX*/
+ case PPP_IPX:
+ ipx_print(p, length);
+@@ -1382,6 +1385,7 @@ handle_ppp(u_int proto, const u_char *p,
+ case PPP_MPLS_MCAST:
+ mpls_print(p, length);
+ break;
++#endif
+ case PPP_COMP:
+ printf("compressed PPP data");
+ break;
+@@ -1520,6 +1524,7 @@ ppp_if_print(const struct pcap_pkthdr *h
+ return (0);
+ }
+
++#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,
+@@ -1747,7 +1752,7 @@ printx:
+ #endif /* __bsdi__ */
+ return (hdrlength);
+ }
+-
++#endif
+
+ /*
+ * Local Variables:
+--- a/print-tcp.c
++++ b/print-tcp.c
+@@ -573,14 +573,14 @@ tcp_print(register const u_char *bp, reg
+ utoval >>= 1;
+ (void)printf(" %u", utoval);
+ break;
+-
++#ifndef TCPDUMP_MINI
+ case TCPOPT_MPTCP:
+ datalen = len - 2;
+ LENCHECK(datalen);
+ if (!mptcp_print(cp-2, len, flags))
+ goto bad;
+ break;
+-
++#endif
+ case TCPOPT_EXPERIMENT2:
+ datalen = len - 2;
+ LENCHECK(datalen);
+@@ -659,8 +659,8 @@ tcp_print(register const u_char *bp, reg
+ if ((flags & TH_RST) && vflag) {
+ print_tcp_rst_data(bp, length);
+ return;
+- }
+-
++ }
++#ifndef TCPDUMP_MINI
+ if (packettype) {
+ switch (packettype) {
+ case PT_ZMTP1:
+@@ -669,7 +669,7 @@ tcp_print(register const u_char *bp, reg
+ }
+ return;
+ }
+-
++#endif
+ if (sport == TELNET_PORT || dport == TELNET_PORT) {
+ if (!qflag && vflag)
+ telnet_print(bp, length);
+@@ -683,10 +683,12 @@ tcp_print(register const u_char *bp, reg
+ else if (sport == SMB_PORT || dport == SMB_PORT)
+ smb_tcp_print(bp, length);
+ #endif
++#ifndef TCPDUMP_MINI
+ else if (sport == BEEP_PORT || dport == BEEP_PORT)
+ beep_print(bp, length);
+ else if (sport == OPENFLOW_PORT || dport == OPENFLOW_PORT)
+ openflow_print(bp, length);
++#endif
+ else if (length > 2 &&
+ (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT ||
+ sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) {
+@@ -695,6 +697,7 @@ tcp_print(register const u_char *bp, reg
+ * XXX packet could be unaligned, it can go strange
+ */
+ ns_print(bp + 2, length - 2, 0);
++#ifndef TCPDUMP_MINI
+ } else if (sport == MSDP_PORT || dport == MSDP_PORT) {
+ msdp_print(bp, length);
+ } else if (sport == RPKI_RTR_PORT || dport == RPKI_RTR_PORT) {
+@@ -702,6 +705,7 @@ tcp_print(register const u_char *bp, reg
+ }
+ else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) {
+ ldp_print(bp, length);
++#endif
+ }
+ else if ((sport == NFS_PORT || dport == NFS_PORT) &&
+ length >= 4 && TTEST2(*bp, 4)) {
+--- a/print-udp.c
++++ b/print-udp.c
+@@ -418,11 +418,12 @@ udp_print(register const u_char *bp, u_i
+ vat_print((void *)(up + 1), up);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case PT_WB:
+ udpipaddr_print(ip, sport, dport);
+ wb_print((void *)(up + 1), length);
+ break;
+-
++#endif
+ case PT_RPC:
+ rp = (struct sunrpc_msg *)(up + 1);
+ direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
+@@ -450,11 +451,12 @@ udp_print(register const u_char *bp, u_i
+ snmp_print((const u_char *)(up + 1), length);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case PT_CNFP:
+ udpipaddr_print(ip, sport, dport);
+ cnfp_print(cp, (const u_char *)ip);
+ break;
+-
++#endif
+ case PT_TFTP:
+ udpipaddr_print(ip, sport, dport);
+ tftp_print(cp, length);
+@@ -475,6 +477,7 @@ udp_print(register const u_char *bp, u_i
+ radius_print(cp, length);
+ break;
+
++#ifndef TCPDUMP_MINI
+ case PT_VXLAN:
+ udpipaddr_print(ip, sport, dport);
+ vxlan_print((const u_char *)(up + 1), length);
+@@ -489,6 +492,7 @@ udp_print(register const u_char *bp, u_i
+ udpipaddr_print(ip, sport, dport);
+ lmp_print(cp, length);
+ break;
++#endif
+ }
+ return;
+ }
+@@ -517,6 +521,7 @@ udp_print(register const u_char *bp, u_i
+ }
+ #endif
+ }
++#ifndef TCPDUMP_MINI
+ if (TTEST(((struct LAP *)cp)->type) &&
+ ((struct LAP *)cp)->type == lapDDP &&
+ (atalk_port(sport) || atalk_port(dport))) {
+@@ -525,6 +530,7 @@ udp_print(register const u_char *bp, u_i
+ llap_print(cp, length);
+ return;
+ }
++#endif
+ }
+ udpipaddr_print(ip, sport, dport);
+
+@@ -575,14 +581,18 @@ udp_print(register const u_char *bp, u_i
+ ns_print((const u_char *)(up + 1), length, 0);
+ else if (ISPORT(MULTICASTDNS_PORT))
+ ns_print((const u_char *)(up + 1), length, 1);
++#ifndef TCPDUMP_MINI
+ else if (ISPORT(TIMED_PORT))
+ timed_print((const u_char *)(up + 1));
++#endif
+ else if (ISPORT(TFTP_PORT))
+ tftp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS))
+ bootp_print((const u_char *)(up + 1), length);
++#ifndef TCPDUMP_MINI
+ else if (ISPORT(RIP_PORT))
+ rip_print((const u_char *)(up + 1), length);
++#endif
+ else if (ISPORT(AODV_PORT))
+ aodv_print((const u_char *)(up + 1), length,
+ #ifdef INET6
+@@ -590,6 +600,7 @@ udp_print(register const u_char *bp, u_i
+ #else
+ 0);
+ #endif
++#ifndef TCPDUMP_MINI
+ else if (ISPORT(ISAKMP_PORT))
+ isakmp_print(gndo, (const u_char *)(up + 1), length, bp2);
+ else if (ISPORT(ISAKMP_PORT_NATT))
+@@ -598,12 +609,15 @@ udp_print(register const u_char *bp, u_i
+ else if (ISPORT(ISAKMP_PORT_USER1) || ISPORT(ISAKMP_PORT_USER2))
+ isakmp_print(gndo, (const u_char *)(up + 1), length, bp2);
+ #endif
++#endif
+ else if (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT))
+ snmp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(NTP_PORT))
+ ntp_print((const u_char *)(up + 1), length);
++#ifndef TCPDUMP_MINI
+ else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT))
+ krb_print((const void *)(up + 1));
++#endif
+ else if (ISPORT(L2TP_PORT))
+ l2tp_print((const u_char *)(up + 1), length);
+ #ifdef TCPDUMP_DO_SMB
+@@ -614,6 +628,7 @@ udp_print(register const u_char *bp, u_i
+ #endif
+ else if (dport == VAT_PORT)
+ vat_print((const void *)(up + 1), up);
++#ifndef TCPDUMP_MINI
+ else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT))
+ zephyr_print((const void *)(up + 1), length);
+ /*
+@@ -624,6 +639,7 @@ udp_print(register const u_char *bp, u_i
+ (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH))
+ rx_print((const void *)(up + 1), length, sport, dport,
+ (u_char *) ip);
++#endif
+ #ifdef INET6
+ else if (ISPORT(RIPNG_PORT))
+ ripng_print((const u_char *)(up + 1), length);
+@@ -635,21 +651,25 @@ udp_print(register const u_char *bp, u_i
+ /*
+ * Kludge in test for whiteboard packets.
+ */
++#ifndef TCPDUMP_MINI
+ else if (dport == WB_PORT)
+ wb_print((const void *)(up + 1), length);
+ else if (ISPORT(CISCO_AUTORP_PORT))
+ cisco_autorp_print((const void *)(up + 1), length);
++#endif
+ else if (ISPORT(RADIUS_PORT) ||
+ ISPORT(RADIUS_NEW_PORT) ||
+ ISPORT(RADIUS_ACCOUNTING_PORT) ||
+ ISPORT(RADIUS_NEW_ACCOUNTING_PORT) )
+ radius_print((const u_char *)(up+1), length);
++#ifndef TCPDUMP_MINI
+ else if (dport == HSRP_PORT)
+ hsrp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(LWRES_PORT))
+ lwres_print((const u_char *)(up + 1), length);
+ else if (ISPORT(LDP_PORT))
+ ldp_print((const u_char *)(up + 1), length);
++#endif
+ else if (ISPORT(OLSR_PORT))
+ olsr_print((const u_char *)(up + 1), length,
+ #if INET6
+@@ -657,6 +677,7 @@ udp_print(register const u_char *bp, u_i
+ #else
+ 0);
+ #endif
++#ifndef TCPDUMP_MINI
+ else if (ISPORT(MPLS_LSP_PING_PORT))
+ lspping_print((const u_char *)(up + 1), length);
+ else if (dport == BFD_CONTROL_PORT ||
+@@ -674,14 +695,17 @@ udp_print(register const u_char *bp, u_i
+ lwapp_control_print((const u_char *)(up + 1), length, 0);
+ else if (ISPORT(LWAPP_DATA_PORT))
+ lwapp_data_print((const u_char *)(up + 1), length);
++#endif
+ else if (ISPORT(SIP_PORT))
+ sip_print((const u_char *)(up + 1), length);
+ else if (ISPORT(SYSLOG_PORT))
+ syslog_print((const u_char *)(up + 1), length);
++#ifndef TCPDUMP_MINI
+ else if (ISPORT(OTV_PORT))
+ otv_print((const u_char *)(up + 1), length);
+ else if (ISPORT(VXLAN_PORT))
+ vxlan_print((const u_char *)(up + 1), length);
++#endif
+ else
+ (void)printf("UDP, length %u",
+ (u_int32_t)(ulen - sizeof(*up)));
+--- a/tcpdump.c
++++ b/tcpdump.c
+@@ -161,6 +161,7 @@ struct ndo_printer {
+
+
+ static struct printer printers[] = {
++#ifndef TCPDUMP_MINI
+ { arcnet_if_print, DLT_ARCNET },
+ #ifdef DLT_ARCNET_LINUX
+ { arcnet_linux_if_print, DLT_ARCNET_LINUX },
+@@ -179,19 +180,23 @@ static struct printer printers[] = {
+ #ifdef DLT_SLIP_BSDOS
+ { sl_bsdos_if_print, DLT_SLIP_BSDOS },
+ #endif
++#endif
+ { ppp_if_print, DLT_PPP },
+ #ifdef DLT_PPP_WITHDIRECTION
+ { ppp_if_print, DLT_PPP_WITHDIRECTION },
+ #endif
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_PPP_BSDOS
+ { ppp_bsdos_if_print, DLT_PPP_BSDOS },
+ #endif
+ { fddi_if_print, DLT_FDDI },
++#endif
+ { null_if_print, DLT_NULL },
+ #ifdef DLT_LOOP
+ { null_if_print, DLT_LOOP },
+ #endif
+ { raw_if_print, DLT_RAW },
++#ifndef TCPDUMP_MINI
+ { atm_if_print, DLT_ATM_RFC1483 },
+ #ifdef DLT_C_HDLC
+ { chdlc_if_print, DLT_C_HDLC },
+@@ -202,6 +207,7 @@ static struct printer printers[] = {
+ #ifdef DLT_PPP_SERIAL
+ { ppp_hdlc_if_print, DLT_PPP_SERIAL },
+ #endif
++#endif
+ #ifdef DLT_PPP_ETHER
+ { pppoe_if_print, DLT_PPP_ETHER },
+ #endif
+@@ -211,6 +217,7 @@ static struct printer printers[] = {
+ #ifdef DLT_IEEE802_11
+ { ieee802_11_if_print, DLT_IEEE802_11},
+ #endif
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_LTALK
+ { ltalk_if_print, DLT_LTALK },
+ #endif
+@@ -229,12 +236,14 @@ static struct printer printers[] = {
+ #ifdef DLT_IP_OVER_FC
+ { ipfc_if_print, DLT_IP_OVER_FC },
+ #endif
++#endif
+ #ifdef DLT_PRISM_HEADER
+ { prism_if_print, DLT_PRISM_HEADER },
+ #endif
+ #ifdef DLT_IEEE802_11_RADIO
+ { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO },
+ #endif
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_ENC
+ { enc_if_print, DLT_ENC },
+ #endif
+@@ -244,9 +253,11 @@ static struct printer printers[] = {
+ #ifdef DLT_APPLE_IP_OVER_IEEE1394
+ { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 },
+ #endif
++#endif
+ #ifdef DLT_IEEE802_11_RADIO_AVS
+ { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS },
+ #endif
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_JUNIPER_ATM1
+ { juniper_atm1_print, DLT_JUNIPER_ATM1 },
+ #endif
+@@ -312,6 +323,7 @@ static struct printer printers[] = {
+ #ifdef DLT_IPV6
+ { raw_if_print, DLT_IPV6 },
+ #endif
++#endif
+ { NULL, 0 },
+ };
+
+@@ -320,6 +332,7 @@ static struct ndo_printer ndo_printers[]
+ #ifdef DLT_IPNET
+ { ipnet_if_print, DLT_IPNET },
+ #endif
++#ifndef TCPDUMP_MINI
+ #ifdef DLT_IEEE802_15_4
+ { ieee802_15_4_if_print, DLT_IEEE802_15_4 },
+ #endif
+@@ -329,15 +342,18 @@ static struct ndo_printer ndo_printers[]
+ #ifdef DLT_PPI
+ { ppi_if_print, DLT_PPI },
+ #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, 0 },
+ };
+
+--- a/print-sll.c
++++ b/print-sll.c
+@@ -154,14 +154,14 @@ recurse:
+ * Yes - what type is it?
+ */
+ switch (ether_type) {
+-
++#ifndef TCPDUMP_MINI
+ case LINUX_SLL_P_802_3:
+ /*
+ * Ethernet_802.3 IPX frame.
+ */
+ ipx_print(p, length);
+ break;
+-
++#endif
+ case LINUX_SLL_P_802_2:
+ /*
+ * 802.2.
diff --git a/package/network/utils/umbim/Makefile b/package/network/utils/umbim/Makefile
new file mode 100644
index 0000000..2ba6991
--- /dev/null
+++ b/package/network/utils/umbim/Makefile
@@ -0,0 +1,45 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=umbim
+PKG_VERSION:=2015-04-09
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://git.openwrt.org/project/umbim.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=af9c293c1f1d8a97fbd8adf9c6070ead4920ca84
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/umbim
+ SECTION:=net
+ CATEGORY:=Network
+ 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 -ffunction-sections -fdata-sections
+
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+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..f8b2c06
--- /dev/null
+++ b/package/network/utils/umbim/files/lib/netifd/proto/mbim.sh
@@ -0,0 +1,177 @@
+#!/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_string auth
+ proto_config_add_string username
+ proto_config_add_string password
+}
+
+_proto_mbim_setup() {
+ local interface="$1"
+ local tid=2
+ local ret
+
+ local device apn pincode delay
+ json_get_vars device apn pincode delay auth username password
+
+ [ -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"
+ 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"
+ 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 || {
+ echo "mbim[$$]" "PIN required"
+ 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"
+ proto_notify_error "$interface" NO_SUBSCRIBER
+ return 1
+ }
+ tid=$((tid + 1))
+
+ echo "mbim[$$]" "Register with network"
+ umbim $DBG -n -t $tid -d $device registration || {
+ echo "mbim[$$]" "Subscriber registration failed"
+ proto_notify_error "$interface" NO_REGISTRATION
+ return 1
+ }
+ tid=$((tid + 1))
+
+ echo "mbim[$$]" "Attach to network"
+ umbim $DBG -n -t $tid -d $device attach || {
+ echo "mbim[$$]" "Failed to attach to network"
+ proto_notify_error "$interface" ATTACH_FAILED
+ return 1
+ }
+ tid=$((tid + 1))
+
+ echo "mbim[$$]" "Connect to network"
+ while ! umbim $DBG -n -t $tid -d $device connect "$apn" "$auth" "$username" "$password"; do
+ tid=$((tid + 1))
+ sleep 1;
+ done
+ tid=$((tid + 1))
+
+ uci_set_state network $interface tid "$tid"
+
+ echo "mbim[$$]" "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"
+ json_close_object
+ 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
+ ubus call network add_dynamic "$(json_dump)"
+}
+
+proto_mbim_setup() {
+ local ret
+
+ _proto_mbim_setup $@
+ ret=$?
+
+ [ "$ret" = 0 ] || {
+ logger "mbim bringup failed, retry in 15s"
+ sleep 15
+ }
+
+ return $rt
+}
+
+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..7ccf549
--- /dev/null
+++ b/package/network/utils/uqmi/Makefile
@@ -0,0 +1,50 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=uqmi
+PKG_VERSION:=2015-09-17
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://nbd.name/uqmi.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=8a97586e9445a60e355dea13aa87885ab3dcb277
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_MAINTAINER:=Matti Laakso <malaakso@elisanet.fi>
+# PKG_MIRROR_MD5SUM:=
+# CMAKE_INSTALL:=1
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/uqmi
+ SECTION:=net
+ CATEGORY:=Network
+ 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 -ffunction-sections -fdata-sections
+
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+CMAKE_OPTIONS += \
+ -DDEBUG=1
+
+define Package/uqmi/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/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..48864be
--- /dev/null
+++ b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
@@ -0,0 +1,257 @@
+#!/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 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_boolean ipv6
+ proto_config_add_boolean dhcp
+}
+
+proto_qmi_setup() {
+ local interface="$1"
+
+ local device apn auth username password pincode delay modes ipv6 dhcp
+ local cid_4 pdh_4 cid_6 pdh_6 ipv4
+ local ip subnet gateway dns1 dns2 ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6
+ json_get_vars device apn auth username password pincode delay modes ipv6 dhcp
+
+ ipv4=1
+
+ if [ "$ipv6" = 0 ]; then
+ ipv6=""
+ else
+ ipv6=1
+ fi
+
+ [ -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
+ }
+ [ -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 "$delay" ] && sleep "$delay"
+
+ while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do
+ sleep 1;
+ done
+
+ [ -n "$pincode" ] && {
+ uqmi -s -d "$device" --verify-pin1 "$pincode" || {
+ echo "Unable to verify PIN"
+ proto_notify_error "$interface" PIN_FAILED
+ proto_block_restart "$interface"
+ return 1
+ }
+ }
+
+ [ -n "$apn" ] || {
+ echo "No APN specified"
+ proto_notify_error "$interface" NO_APN
+ return 1
+ }
+
+ uqmi -s -d "$device" --set-data-format 802.3
+ uqmi -s -d "$device" --wda-set-data-format 802.3
+
+ echo "Waiting for network registration"
+ while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do
+ sleep 5;
+ done
+
+ [ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes"
+
+ echo "Starting network $apn"
+
+ cid_4=`uqmi -s -d "$device" --get-client-id wds`
+ [ $? -ne 0 ] && {
+ echo "Unable to obtain client ID"
+ proto_notify_error "$interface" NO_CID
+ return 1
+ }
+
+ pdh_4=`uqmi -s -d "$device" --set-client-id wds,"$cid_4" \
+ --start-network "$apn" \
+ ${auth:+--auth-type $auth} \
+ ${username:+--username $username} \
+ ${password:+--password $password} \
+ --ip-family ipv4`
+ [ $? -ne 0 ] && {
+ echo "Unable to connect IPv4"
+ uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds
+ ipv4=""
+ }
+
+ [ -n "$ipv6" ] && {
+ cid_6=`uqmi -s -d "$device" --get-client-id wds`
+ if [ $? = 0 ]; then
+ pdh_6=`uqmi -s -d "$device" --set-client-id wds,"$cid_6" \
+ --start-network "$apn" \
+ ${auth:+--auth-type $auth} \
+ ${username:+--username $username} \
+ ${password:+--password $password} \
+ --ip-family ipv6`
+ [ $? -ne 0 ] && {
+ echo "Unable to connect IPv6"
+ uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds
+ ipv6=""
+ }
+ else
+ echo "Unable to connect IPv6"
+ ipv6=""
+ fi
+ }
+
+ [ -z "$ipv4" -a -z "$ipv6" ] && {
+ echo "Unable to connect"
+ proto_notify_error "$interface" CALL_FAILED
+ return 1
+ }
+
+ if [ -z "$dhcp" -o "$dhcp" = 0 ]; then
+ echo "Setting up $ifname"
+ [ -n "$ipv4" ] && {
+ json_load "$(uqmi -s -d $device --set-client-id wds,$cid_4 --get-current-settings)"
+ json_select ipv4
+ json_get_vars ip subnet gateway dns1 dns2
+
+ proto_init_update "$ifname" 1
+ proto_set_keep 1
+ proto_add_ipv4_address "$ip" "$subnet"
+ proto_add_dns_server "$dns1"
+ proto_add_dns_server "$dns2"
+ proto_add_ipv4_route "0.0.0.0" 0 "$gateway"
+ proto_add_data
+ json_add_string "cid_4" "$cid_4"
+ json_add_string "pdh_4" "$pdh_4"
+ proto_close_data
+ proto_send_update "$interface"
+ }
+
+ [ -n "$ipv6" ] && {
+ json_load "$(uqmi -s -d $device --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
+ # RFC 7278: Extend an IPv6 /64 Prefix to LAN
+ proto_add_ipv6_address "$ip_6" "128"
+ proto_add_ipv6_prefix "${ip_6}/${ip_prefix_length}"
+ proto_add_ipv6_route "$gateway_6" "128"
+ proto_add_ipv6_route "::0" 0 "$gateway_6" "" "" "${ip_6}/${ip_prefix_length}"
+ proto_add_dns_server "$dns1_6"
+ proto_add_dns_server "$dns2_6"
+ proto_add_data
+ json_add_string "cid_6" "$cid_6"
+ json_add_string "pdh_6" "$pdh_6"
+ proto_close_data
+ proto_send_update "$interface"
+ }
+ else
+ echo "Starting DHCP on $ifname"
+ proto_init_update "$ifname" 1
+ proto_add_data
+ [ -n "$ipv4" ] && {
+ json_add_string "cid_4" "$cid_4"
+ json_add_string "pdh_4" "$pdh_4"
+ }
+ [ -n "$ipv6" ] && {
+ json_add_string "cid_6" "$cid_6"
+ json_add_string "pdh_6" "$pdh_6"
+ }
+ proto_close_data
+ proto_send_update "$interface"
+
+ [ -n "$ipv4" ] && {
+ json_init
+ json_add_string name "${interface}_4"
+ json_add_string ifname "@$interface"
+ json_add_string proto "dhcp"
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ }
+
+ [ -n "$ipv6" ] && {
+ json_init
+ json_add_string name "${interface}_6"
+ json_add_string ifname "@$interface"
+ json_add_string proto "dhcpv6"
+ # RFC 7278: Extend an IPv6 /64 Prefix to LAN
+ json_add_string extendprefix 1
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ }
+ fi
+}
+
+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"
+
+ json_load "$(ubus call network.interface.$interface status)"
+ json_select data
+ json_get_vars cid_4 pdh_4 cid_6 pdh_6
+
+ [ -n "$cid_4" ] && {
+ [ -n "$pdh_4" ] && {
+ uqmi -s -d "$device" --set-client-id wds,"$cid_4" --stop-network "$pdh_4"
+ uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds
+ }
+ }
+ [ -n "$cid_6" ] && {
+ [ -n "$pdh_6" ] && {
+ uqmi -s -d "$device" --set-client-id wds,"$cid_6" --stop-network "$pdh_6"
+ uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds
+ }
+ }
+
+ proto_init_update "*" 0
+ proto_send_update "$interface"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol qmi
+}
diff --git a/package/network/utils/wireless-tools/Makefile b/package/network/utils/wireless-tools/Makefile
new file mode 100644
index 0000000..67986ba
--- /dev/null
+++ b/package/network/utils/wireless-tools/Makefile
@@ -0,0 +1,92 @@
+#
+# 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_VERSION:=29
+PKG_MINOR:=
+PKG_RELEASE:=5
+
+PKG_SOURCE:=wireless_tools.$(PKG_VERSION)$(PKG_MINOR).tar.gz
+PKG_SOURCE_URL:=http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux
+PKG_MD5SUM:=e06c222e186f7cc013fd272d023710cb
+TAR_OPTIONS += || true
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+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
+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,wireless-tools))
+$(eval $(call BuildPackage,libiw))
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..6c2559d
--- /dev/null
+++ b/package/network/utils/wpan-tools/Makefile
@@ -0,0 +1,36 @@
+#
+# Copyright (C) 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:=wpan-tools
+PKG_VERSION:=0.5
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://wpan.cakelab.org/releases/
+PKG_MD5SUM:=6226df405a98c13ec41bf4d1f0777d6b
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/wpan-tools
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=cfg802154 interface configuration utility
+ URL:=http://wpan.cakelab.org/
+ DEPENDS:= +libnl
+endef
+
+define Build/Configure
+ $(call Build/Configure/Default)
+endef
+
+define Package/wpan-tools/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/iwpan $(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..8d388dc
--- /dev/null
+++ b/package/network/utils/wwan/Makefile
@@ -0,0 +1,35 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=wwan
+PKG_VERSION:=2014-07-17
+PKG_RELEASE=1
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.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/
+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..1313401
--- /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..a9ad650
--- /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..a9ad650
--- /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..bc3e780
--- /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..52fbf58
--- /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..c1cb9f4
--- /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..f6674ba
--- /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..b637c34
--- /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..a95192b
--- /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..a95192b
--- /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..5fa7d49
--- /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..1a4a796
--- /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..ce288ed
--- /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..0b96160
--- /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..e8863b9
--- /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..6a72f4f
--- /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..b1da177
--- /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..cd1ecee
--- /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..84705b7
--- /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..06b2664
--- /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..20b18b7
--- /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..7e55a36
--- /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..5b4ea48
--- /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..84a9a9b
--- /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..84a9a9b
--- /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..2e82613
--- /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..2f725eb
--- /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..2f725eb
--- /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..d5ca787
--- /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..a2bee34
--- /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/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..3a68c20
--- /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..471d8a5
--- /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..840dc64
--- /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..ec94956
--- /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..df98b66
--- /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..4d22d4d
--- /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..5fa2a3a
--- /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..8cbe23d
--- /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..18bd074
--- /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..e028a4b
--- /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..a50654d
--- /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..02d7494
--- /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..4d6d4a9
--- /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..3482db4
--- /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..226c1b4
--- /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..dd089a3
--- /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..9c7e72b
--- /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..425d4cc
--- /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..002d6fb
--- /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..13998de
--- /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..af4824c
--- /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..34c896e
--- /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..083baee
--- /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..4d6d4a9
--- /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..02d7494
--- /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..3482db4
--- /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..a57e54a
--- /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..13fd7da
--- /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..d9bd29f
--- /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..c694fa3
--- /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..d9bd29f
--- /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..c694fa3
--- /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..d9bd29f
--- /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..d9bd29f
--- /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..f10c104
--- /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..f10c104
--- /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..f10c104
--- /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..ce52c8f
--- /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..3ebd0be
--- /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..35ee919
--- /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..0fcd10e
--- /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..0b9eadf
--- /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..0fcd10e
--- /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..0b9eadf
--- /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..0fcd10e
--- /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..02da610
--- /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..0f2a133
--- /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..1989d0a
--- /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..16d8ab4
--- /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..65be37b
--- /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..a8aee6d
--- /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..24eddc6
--- /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..415a80a
--- /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..075cc6b
--- /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..075cc6b
--- /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..e188c03
--- /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..6d2f892
--- /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..fa866e2
--- /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..99a2bd2
--- /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..16f4dfd
--- /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..7c5a9f2
--- /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/12d1:1035 b/package/network/utils/wwan/files/data/12d1:1035
new file mode 100644
index 0000000..ad7025a
--- /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..b1aa317
--- /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..cc99898
--- /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..e6fb6cc
--- /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..b1aa317
--- /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..c5d86cb
--- /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..7db8644
--- /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..500d775
--- /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..a704946
--- /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..1b5397c
--- /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..dbb20f7
--- /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..c1ae9a5
--- /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..50ea079
--- /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..50ea079
--- /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..e27a798
--- /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..b496a60
--- /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..18e1e1e
--- /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..65760e8
--- /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..e5eae2a
--- /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..3fc6b1b
--- /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..c561224
--- /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..cee7276
--- /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..4f6fb21
--- /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..50ea079
--- /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..50ea079
--- /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..d104347
--- /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..e2bda96
--- /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..ba48aea
--- /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..5cc96b6
--- /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..012f3ad
--- /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..d101677
--- /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..a0328cf
--- /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..701bf42
--- /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..7ab3c9d
--- /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..98006e2
--- /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..cd9f290
--- /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..4635063
--- /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..340666c
--- /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..260a289
--- /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..838a7fb
--- /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..a12716e
--- /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..a12716e
--- /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..fce8e9b
--- /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..d08c399
--- /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..079c7d5
--- /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..079c7d5
--- /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..0fc4029
--- /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..e1ba049
--- /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..03e8fcd
--- /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..0bb9cdb
--- /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..5e4fe34
--- /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..1ba8a50
--- /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..09207df
--- /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..4bdbf89
--- /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..5c108a2
--- /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..b1c4869
--- /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..bda356f
--- /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..185d257
--- /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..185d257
--- /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..2403381
--- /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..715878c
--- /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..bb8f87e
--- /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..44343d0
--- /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..406566b
--- /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..5b6a147
--- /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..07175f3
--- /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..c518ca7
--- /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..9b1c85f
--- /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..31ee3fd
--- /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..31ee3fd
--- /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..48c5fef
--- /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..76120d4
--- /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..7ed8ed1
--- /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..5ae34af
--- /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..e99314e
--- /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..8ee565d
--- /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..c80a51a
--- /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..7800746
--- /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..edb0efe
--- /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..c57d7ae
--- /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..0f9502f
--- /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..569a999
--- /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..ea4fcd9
--- /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..f25d77a
--- /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..4e429a6
--- /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..34a976e
--- /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..369d70f
--- /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..bfe9b5d
--- /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..8610bbf
--- /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..620eb90
--- /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..6d19e3e
--- /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..6885a9b
--- /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..20047be
--- /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..d7d6f97
--- /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..a7d0eb5
--- /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..a5eab00
--- /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..1b4c728
--- /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..1b4c728
--- /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..3d196af
--- /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..5ee7b2f
--- /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..4502531
--- /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..d8bc573
--- /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..0df58f0
--- /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..0df58f0
--- /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..d8bc573
--- /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..d8bc573
--- /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..d8bc573
--- /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..d8bc573
--- /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..7e4bbf7
--- /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..d8bc573
--- /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..d8bc573
--- /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..d8bc573
--- /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..4c926f0
--- /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..7a37c43
--- /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..6b46c73
--- /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..a625164
--- /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..a625164
--- /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..a625164
--- /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..a2a0880
--- /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..71d1050
--- /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..03a16bf
--- /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..57531e2
--- /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..4347f28
--- /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..4ff616a
--- /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..4ff616a
--- /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..4ff616a
--- /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..4e60049
--- /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..747fa23
--- /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..93388be
--- /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..93388be
--- /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..f013968
--- /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..82e4bf0
--- /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..1acb9ee
--- /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..67db2b4
--- /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..78f36ce
--- /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..0be73af
--- /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..3eecac0
--- /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..853c05c
--- /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..853c05c
--- /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..9eaffe6
--- /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..80d71fa
--- /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..6f77bb4
--- /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..6f77bb4
--- /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..39dcd77
--- /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..fd3f099
--- /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..c2992c1
--- /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..c2992c1
--- /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..40dcc76
--- /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..42da3ab
--- /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..bdb159d
--- /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..d1b2dda
--- /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..bdb159d
--- /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..93e0c3f
--- /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..ebc941d
--- /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/2001:7d00 b/package/network/utils/wwan/files/data/2001:7d00
new file mode 100644
index 0000000..b0cc479
--- /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..ab8fd9d
--- /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..ab8fd9d
--- /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..ab8fd9d
--- /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..06cdddc
--- /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/413c:8114 b/package/network/utils/wwan/files/data/413c:8114
new file mode 100644
index 0000000..a3cb2cd
--- /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..af27cbe
--- /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..31b79bf
--- /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..a3cb2cd
--- /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..b92d415
--- /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..a3cb2cd
--- /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..a3cb2cd
--- /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..4ae8402
--- /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..4ae8402
--- /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..4ae8402
--- /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..d2bf508
--- /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..d2bf508
--- /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..d2bf508
--- /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..f0b0638
--- /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..1ae4405
--- /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..1ae4405
--- /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..1ae4405
--- /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..e66c3fc
--- /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..6b33600
--- /dev/null
+++ b/package/network/utils/wwan/files/wwan.sh
@@ -0,0 +1,119 @@
+#!/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_wwan_setup() {
+ local driver usb devicename desc
+
+ 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
+
+ [ -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* | 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 wwan); do
+ [ -z "$ctl_device" ] || 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_ncm)
+ ctl_device=/dev/$(cd /sys/class/net/$net/; find ../../../ -name ttyUSB* |xargs 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_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_mbim_teardown $@ ;;
+ comgt) proto_3g_teardown $@ ;;
+ *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..507b002
--- /dev/null
+++ b/package/network/utils/wwan/files/wwan.usb
@@ -0,0 +1,18 @@
+[ "$ACTION" = add -a "$DEVTYPE" = usb_device ] || exit 0
+
+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..4079a7f
--- /dev/null
+++ b/package/network/utils/wwan/files/wwan.usbmisc
@@ -0,0 +1,27 @@
+#!/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
+ else
+ proto_set_available "$cfg" 0
+ fi
+ exit 0
+}
+
+config_load network
+config_foreach find_wwan_iface interface
diff --git a/package/network/utils/xtables-addons/Makefile b/package/network/utils/xtables-addons/Makefile
new file mode 100644
index 0000000..ff6466f
--- /dev/null
+++ b/package/network/utils/xtables-addons/Makefile
@@ -0,0 +1,152 @@
+#
+# Copyright (C) 2009-2013 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:=xtables-addons
+PKG_VERSION:=2.7
+PKG_RELEASE:=1
+PKG_MD5SUM:=81bd7ba82e5f7bfd1458fc97ddf72e1d
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@SF/xtables-addons
+PKG_BUILD_DEPENDS:=iptables
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_CHECK_FORMAT_SECURITY:=0
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/xtables-addons
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=Firewall
+ TITLE:=Extensions not distributed in the main Xtables
+ URL:=http://xtables-addons.sourceforge.net/
+endef
+
+# uses GNU configure
+
+CONFIGURE_ARGS+= \
+ --with-kbuild="$(LINUX_DIR)" \
+ --with-xtables="$(STAGING_DIR)/usr" \
+ --with-xtlibdir="/usr/lib/iptables" \
+
+define Build/Compile
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ DESTDIR="$(PKG_INSTALL_DIR)" \
+ DEPMOD="/bin/true" \
+ all
+endef
+
+define Build/Install
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ ARCH="$(LINUX_KARCH)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ DESTDIR="$(PKG_INSTALL_DIR)" \
+ DEPMOD="/bin/true" \
+ install
+endef
+
+# 1: extension/module suffix used in package name
+# 2: extension/module display name used in package title/description
+# 3: list of extensions to package
+# 4: list of modules to package
+# 5: module load priority
+# 6: module depends
+define BuildTemplate
+
+ ifneq ($(3),)
+ define Package/iptables-mod-$(1)
+ $$(call Package/xtables-addons)
+ CATEGORY:=Network
+ TITLE:=$(2) iptables extension
+ DEPENDS:=iptables $(if $(4),+kmod-ipt-$(1))
+ endef
+
+ define Package/iptables-mod-$(1)/install
+ $(INSTALL_DIR) $$(1)/usr/lib/iptables
+ for m in $(3); do \
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/lib/iptables/lib$$$$$$$${m}.so \
+ $$(1)/usr/lib/iptables/ ; \
+ done
+ endef
+
+ $$(eval $$(call BuildPackage,iptables-mod-$(1)))
+ endif
+
+ ifneq ($(4),)
+ define KernelPackage/ipt-$(1)
+ SUBMENU:=Netfilter Extensions
+ TITLE:=$(2) netfilter module
+ DEPENDS:=+kmod-ipt-core $(5)
+ KCONFIG:=$(6)
+ FILES:=$(foreach mod,$(4),$(PKG_BUILD_DIR)/extensions/$(mod).$(LINUX_KMOD_SUFFIX))
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(4)))
+ endef
+
+ $$(eval $$(call KernelPackage,ipt-$(1)))
+ endif
+
+endef
+
+
+define Package/iptaccount
+ $(call Package/xtables-addons)
+ CATEGORY:=Network
+ TITLE:=iptables-mod-account control utility
+ DEPENDS:=iptables +iptables-mod-account
+endef
+
+define Package/iptaccount/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/lib/libxt_ACCOUNT_cl.so* \
+ $(1)/usr/lib/
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/sbin/iptaccount \
+ $(1)/usr/sbin/
+endef
+
+
+#$(eval $(call BuildTemplate,SUFFIX,DESCRIPTION,EXTENSION,MODULE,PRIORITY,DEPENDS))
+
+$(eval $(call BuildTemplate,compat-xtables,API compatibilty layer,,compat_xtables,+IPV6:kmod-ip6tables,CONFIG_NF_CONNTRACK_MARK=y))
+$(eval $(call BuildTemplate,nathelper-rtsp,RTSP Conntrack and NAT,,rtsp/nf_conntrack_rtsp rtsp/nf_nat_rtsp,+kmod-ipt-conntrack-extra +kmod-ipt-nat))
+
+$(eval $(call BuildTemplate,account,ACCOUNT,xt_ACCOUNT,ACCOUNT/xt_ACCOUNT,+kmod-ipt-compat-xtables))
+$(eval $(call BuildTemplate,chaos,CHAOS,xt_CHAOS,xt_CHAOS,+kmod-ipt-compat-xtables +kmod-ipt-delude +kmod-ipt-tarpit))
+$(eval $(call BuildTemplate,condition,Condition,xt_condition,xt_condition,))
+$(eval $(call BuildTemplate,delude,DELUDE,xt_DELUDE,xt_DELUDE,+kmod-ipt-compat-xtables))
+$(eval $(call BuildTemplate,dhcpmac,DHCPMAC,xt_DHCPMAC,xt_DHCPMAC,+kmod-ipt-compat-xtables))
+$(eval $(call BuildTemplate,dnetmap,DNETMAP,xt_DNETMAP,xt_DNETMAP,+kmod-ipt-compat-xtables +kmod-ipt-nat))
+$(eval $(call BuildTemplate,fuzzy,fuzzy,xt_fuzzy,xt_fuzzy,))
+$(eval $(call BuildTemplate,geoip,geoip,xt_geoip,xt_geoip,))
+$(eval $(call BuildTemplate,iface,iface,xt_iface,xt_iface,))
+$(eval $(call BuildTemplate,ipmark,IPMARK,xt_IPMARK,xt_IPMARK,+kmod-ipt-compat-xtables))
+$(eval $(call BuildTemplate,ipp2p,IPP2P,xt_ipp2p,xt_ipp2p,+kmod-ipt-compat-xtables))
+$(eval $(call BuildTemplate,ipv4options,ipv4options,xt_ipv4options,xt_ipv4options,))
+$(eval $(call BuildTemplate,length2,length2,xt_length2,xt_length2,+kmod-ipt-compat-xtables))
+$(eval $(call BuildTemplate,logmark,LOGMARK,xt_LOGMARK,xt_LOGMARK,+kmod-ipt-compat-xtables))
+$(eval $(call BuildTemplate,lscan,lscan,xt_lscan,xt_lscan,))
+$(eval $(call BuildTemplate,lua,Lua PacketScript,xt_LUA,LUA/xt_LUA,+kmod-ipt-conntrack-extra))
+$(eval $(call BuildTemplate,psd,psd,xt_psd,xt_psd,))
+$(eval $(call BuildTemplate,quota2,quota2,xt_quota2,xt_quota2,))
+$(eval $(call BuildTemplate,sysrq,SYSRQ,xt_SYSRQ,xt_SYSRQ,+kmod-ipt-compat-xtables))
+$(eval $(call BuildTemplate,tarpit,TARPIT,xt_TARPIT,xt_TARPIT,+kmod-ipt-compat-xtables))
+
+$(eval $(call BuildPackage,iptaccount))
diff --git a/package/network/utils/xtables-addons/patches/002-fix-kernel-version-detection.patch b/package/network/utils/xtables-addons/patches/002-fix-kernel-version-detection.patch
new file mode 100644
index 0000000..e4101ad
--- /dev/null
+++ b/package/network/utils/xtables-addons/patches/002-fix-kernel-version-detection.patch
@@ -0,0 +1,11 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -44,7 +44,7 @@ regular_CFLAGS="-Wall -Waggregate-return
+
+ if test -n "$kbuilddir"; then
+ AC_MSG_CHECKING([kernel version that we will build against])
+- krel="$(make -sC "$kbuilddir" M=$PWD kernelrelease)";
++ krel="$(make -sC "$kbuilddir" M=$PWD kernelversion)";
+ kmajor="${krel%%[[^0-9]]*}";
+ kmajor="$(($kmajor+0))";
+ krel="${krel:${#kmajor}}";
diff --git a/package/network/utils/xtables-addons/patches/100-add-rtsp-conntrack.patch b/package/network/utils/xtables-addons/patches/100-add-rtsp-conntrack.patch
new file mode 100644
index 0000000..6c169ee
--- /dev/null
+++ b/package/network/utils/xtables-addons/patches/100-add-rtsp-conntrack.patch
@@ -0,0 +1,1526 @@
+--- /dev/null
++++ b/extensions/rtsp/Kbuild
+@@ -0,0 +1,4 @@
++# -*- Makefile -*-
++
++obj-m += nf_nat_rtsp.o
++obj-m += nf_conntrack_rtsp.o
+--- /dev/null
++++ b/extensions/rtsp/netfilter_helpers.h
+@@ -0,0 +1,133 @@
++/*
++ * Helpers for netfiler modules. This file provides implementations for basic
++ * functions such as strncasecmp(), etc.
++ *
++ * gcc will warn for defined but unused functions, so we only include the
++ * functions requested. The following macros are used:
++ * NF_NEED_STRNCASECMP nf_strncasecmp()
++ * NF_NEED_STRTOU16 nf_strtou16()
++ * NF_NEED_STRTOU32 nf_strtou32()
++ */
++#ifndef _NETFILTER_HELPERS_H
++#define _NETFILTER_HELPERS_H
++
++/* Only include these functions for kernel code. */
++#ifdef __KERNEL__
++
++#include <linux/ctype.h>
++#define iseol(c) ( (c) == '\r' || (c) == '\n' )
++
++/*
++ * The standard strncasecmp()
++ */
++#ifdef NF_NEED_STRNCASECMP
++static int
++nf_strncasecmp(const char* s1, const char* s2, u_int32_t len)
++{
++ if (s1 == NULL || s2 == NULL)
++ {
++ if (s1 == NULL && s2 == NULL)
++ {
++ return 0;
++ }
++ return (s1 == NULL) ? -1 : 1;
++ }
++ while (len > 0 && tolower(*s1) == tolower(*s2))
++ {
++ len--;
++ s1++;
++ s2++;
++ }
++ return ( (len == 0) ? 0 : (tolower(*s1) - tolower(*s2)) );
++}
++#endif /* NF_NEED_STRNCASECMP */
++
++/*
++ * Parse a string containing a 16-bit unsigned integer.
++ * Returns the number of chars used, or zero if no number is found.
++ */
++#ifdef NF_NEED_STRTOU16
++static int
++nf_strtou16(const char* pbuf, u_int16_t* pval)
++{
++ int n = 0;
++
++ *pval = 0;
++ while (isdigit(pbuf[n]))
++ {
++ *pval = (*pval * 10) + (pbuf[n] - '0');
++ n++;
++ }
++
++ return n;
++}
++#endif /* NF_NEED_STRTOU16 */
++
++/*
++ * Parse a string containing a 32-bit unsigned integer.
++ * Returns the number of chars used, or zero if no number is found.
++ */
++#ifdef NF_NEED_STRTOU32
++static int
++nf_strtou32(const char* pbuf, u_int32_t* pval)
++{
++ int n = 0;
++
++ *pval = 0;
++ while (pbuf[n] >= '0' && pbuf[n] <= '9')
++ {
++ *pval = (*pval * 10) + (pbuf[n] - '0');
++ n++;
++ }
++
++ return n;
++}
++#endif /* NF_NEED_STRTOU32 */
++
++/*
++ * Given a buffer and length, advance to the next line and mark the current
++ * line.
++ */
++#ifdef NF_NEED_NEXTLINE
++static int
++nf_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen)
++{
++ uint off = *poff;
++ uint physlen = 0;
++
++ if (off >= len)
++ {
++ return 0;
++ }
++
++ while (p[off] != '\n')
++ {
++ if (len-off <= 1)
++ {
++ return 0;
++ }
++
++ physlen++;
++ off++;
++ }
++
++ /* if we saw a crlf, physlen needs adjusted */
++ if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r')
++ {
++ physlen--;
++ }
++
++ /* advance past the newline */
++ off++;
++
++ *plineoff = *poff;
++ *plinelen = physlen;
++ *poff = off;
++
++ return 1;
++}
++#endif /* NF_NEED_NEXTLINE */
++
++#endif /* __KERNEL__ */
++
++#endif /* _NETFILTER_HELPERS_H */
+--- /dev/null
++++ b/extensions/rtsp/netfilter_mime.h
+@@ -0,0 +1,89 @@
++/*
++ * MIME functions for netfilter modules. This file provides implementations
++ * for basic MIME parsing. MIME headers are used in many protocols, such as
++ * HTTP, RTSP, SIP, etc.
++ *
++ * gcc will warn for defined but unused functions, so we only include the
++ * functions requested. The following macros are used:
++ * NF_NEED_MIME_NEXTLINE nf_mime_nextline()
++ */
++#ifndef _NETFILTER_MIME_H
++#define _NETFILTER_MIME_H
++
++/* Only include these functions for kernel code. */
++#ifdef __KERNEL__
++
++#include <linux/ctype.h>
++
++/*
++ * Given a buffer and length, advance to the next line and mark the current
++ * line. If the current line is empty, *plinelen will be set to zero. If
++ * not, it will be set to the actual line length (including CRLF).
++ *
++ * 'line' in this context means logical line (includes LWS continuations).
++ * Returns 1 on success, 0 on failure.
++ */
++#ifdef NF_NEED_MIME_NEXTLINE
++static int
++nf_mime_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen)
++{
++ uint off = *poff;
++ uint physlen = 0;
++ int is_first_line = 1;
++
++ if (off >= len)
++ {
++ return 0;
++ }
++
++ do
++ {
++ while (p[off] != '\n')
++ {
++ if (len-off <= 1)
++ {
++ return 0;
++ }
++
++ physlen++;
++ off++;
++ }
++
++ /* if we saw a crlf, physlen needs adjusted */
++ if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r')
++ {
++ physlen--;
++ }
++
++ /* advance past the newline */
++ off++;
++
++ /* check for an empty line */
++ if (physlen == 0)
++ {
++ break;
++ }
++
++ /* check for colon on the first physical line */
++ if (is_first_line)
++ {
++ is_first_line = 0;
++ if (memchr(p+(*poff), ':', physlen) == NULL)
++ {
++ return 0;
++ }
++ }
++ }
++ while (p[off] == ' ' || p[off] == '\t');
++
++ *plineoff = *poff;
++ *plinelen = (physlen == 0) ? 0 : (off - *poff);
++ *poff = off;
++
++ return 1;
++}
++#endif /* NF_NEED_MIME_NEXTLINE */
++
++#endif /* __KERNEL__ */
++
++#endif /* _NETFILTER_MIME_H */
+--- /dev/null
++++ b/extensions/rtsp/nf_conntrack_rtsp.c
+@@ -0,0 +1,576 @@
++/*
++ * RTSP extension for IP connection tracking
++ * (C) 2003 by Tom Marshall <tmarshall at real.com>
++ *
++ * 2005-02-13: Harald Welte <laforge at netfilter.org>
++ * - port to 2.6
++ * - update to recent post-2.6.11 api changes
++ * 2006-09-14: Steven Van Acker <deepstar at singularity.be>
++ * - removed calls to NAT code from conntrack helper: NAT no longer needed to use rtsp-conntrack
++ * 2007-04-18: Michael Guntsche <mike at it-loops.com>
++ * - Port to new NF API
++ * 2013-03-04: Il'inykh Sergey <sergeyi at inango-sw.com>. Inango Systems Ltd
++ * - fixed rtcp nat mapping and other port mapping fixes
++ * - simple TEARDOWN request handling
++ * - codestyle fixes and other less significant bug fixes
++ *
++ * based on ip_conntrack_irc.c
++ *
++ * 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.
++ *
++ * Module load syntax:
++ * insmod nf_conntrack_rtsp.o ports=port1,port2,...port<MAX_PORTS>
++ * max_outstanding=n setup_timeout=secs
++ *
++ * If no ports are specified, the default will be port 554.
++ *
++ * With max_outstanding you can define the maximum number of not yet
++ * answered SETUP requests per RTSP session (default 8).
++ * With setup_timeout you can specify how long the system waits for
++ * an expected data channel (default 300 seconds).
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/netfilter.h>
++#include <linux/ip.h>
++#include <linux/inet.h>
++#include <net/tcp.h>
++
++#include <net/netfilter/nf_conntrack.h>
++#include <net/netfilter/nf_conntrack_expect.h>
++#include <net/netfilter/nf_conntrack_helper.h>
++#include "nf_conntrack_rtsp.h"
++
++#define NF_NEED_STRNCASECMP
++#define NF_NEED_STRTOU16
++#define NF_NEED_STRTOU32
++#define NF_NEED_NEXTLINE
++#include "netfilter_helpers.h"
++#define NF_NEED_MIME_NEXTLINE
++#include "netfilter_mime.h"
++
++#include <linux/ctype.h>
++
++#define MAX_PORTS 8
++static int ports[MAX_PORTS];
++static int num_ports = 0;
++static int max_outstanding = 8;
++static unsigned int setup_timeout = 300;
++
++MODULE_AUTHOR("Tom Marshall <tmarshall at real.com>");
++MODULE_DESCRIPTION("RTSP connection tracking module");
++MODULE_LICENSE("GPL");
++module_param_array(ports, int, &num_ports, 0400);
++MODULE_PARM_DESC(ports, "port numbers of RTSP servers");
++module_param(max_outstanding, int, 0400);
++MODULE_PARM_DESC(max_outstanding, "max number of outstanding SETUP requests per RTSP session");
++module_param(setup_timeout, int, 0400);
++MODULE_PARM_DESC(setup_timeout, "timeout on for unestablished data channels");
++
++static char *rtsp_buffer;
++static DEFINE_SPINLOCK(rtsp_buffer_lock);
++
++static struct nf_conntrack_expect_policy rtsp_exp_policy;
++
++unsigned int (*nf_nat_rtsp_hook)(struct sk_buff *skb,
++ enum ip_conntrack_info ctinfo,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ unsigned int protoff,
++#endif
++ unsigned int matchoff, unsigned int matchlen,
++ struct ip_ct_rtsp_expect* prtspexp,
++ struct nf_conntrack_expect *rtp_exp,
++ struct nf_conntrack_expect *rtcp_exp);
++
++EXPORT_SYMBOL_GPL(nf_nat_rtsp_hook);
++
++/*
++ * Max mappings we will allow for one RTSP connection (for RTP, the number
++ * of allocated ports is twice this value). Note that SMIL burns a lot of
++ * ports so keep this reasonably high. If this is too low, you will see a
++ * lot of "no free client map entries" messages.
++ */
++#define MAX_PORT_MAPS 16
++
++/*** default port list was here in the masq code: 554, 3030, 4040 ***/
++
++#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; }
++
++/*
++ * Parse an RTSP packet.
++ *
++ * Returns zero if parsing failed.
++ *
++ * Parameters:
++ * IN ptcp tcp data pointer
++ * IN tcplen tcp data len
++ * IN/OUT ptcpoff points to current tcp offset
++ * OUT phdrsoff set to offset of rtsp headers
++ * OUT phdrslen set to length of rtsp headers
++ * OUT pcseqoff set to offset of CSeq header
++ * OUT pcseqlen set to length of CSeq header
++ */
++static int
++rtsp_parse_message(char* ptcp, uint tcplen, uint* ptcpoff,
++ uint* phdrsoff, uint* phdrslen,
++ uint* pcseqoff, uint* pcseqlen,
++ uint* transoff, uint* translen)
++{
++ uint entitylen = 0;
++ uint lineoff;
++ uint linelen;
++
++ if (!nf_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen))
++ return 0;
++
++ *phdrsoff = *ptcpoff;
++ while (nf_mime_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen)) {
++ if (linelen == 0) {
++ if (entitylen > 0)
++ *ptcpoff += min(entitylen, tcplen - *ptcpoff);
++ break;
++ }
++ if (lineoff+linelen > tcplen) {
++ pr_info("!! overrun !!\n");
++ break;
++ }
++
++ if (nf_strncasecmp(ptcp+lineoff, "CSeq:", 5) == 0) {
++ *pcseqoff = lineoff;
++ *pcseqlen = linelen;
++ }
++
++ if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0) {
++ *transoff = lineoff;
++ *translen = linelen;
++ }
++
++ if (nf_strncasecmp(ptcp+lineoff, "Content-Length:", 15) == 0) {
++ uint off = lineoff+15;
++ SKIP_WSPACE(ptcp+lineoff, linelen, off);
++ nf_strtou32(ptcp+off, &entitylen);
++ }
++ }
++ *phdrslen = (*ptcpoff) - (*phdrsoff);
++
++ return 1;
++}
++
++/*
++ * Find lo/hi client ports (if any) in transport header
++ * In:
++ * ptcp, tcplen = packet
++ * tranoff, tranlen = buffer to search
++ *
++ * Out:
++ * pport_lo, pport_hi = lo/hi ports (host endian)
++ *
++ * Returns nonzero if any client ports found
++ *
++ * Note: it is valid (and expected) for the client to request multiple
++ * transports, so we need to parse the entire line.
++ */
++static int
++rtsp_parse_transport(char* ptran, uint tranlen,
++ struct ip_ct_rtsp_expect* prtspexp)
++{
++ int rc = 0;
++ uint off = 0;
++
++ if (tranlen < 10 || !iseol(ptran[tranlen-1]) ||
++ nf_strncasecmp(ptran, "Transport:", 10) != 0) {
++ pr_info("sanity check failed\n");
++ return 0;
++ }
++
++ pr_debug("tran='%.*s'\n", (int)tranlen, ptran);
++ off += 10;
++ SKIP_WSPACE(ptran, tranlen, off);
++
++ /* Transport: tran;field;field=val,tran;field;field=val,... */
++ while (off < tranlen) {
++ const char* pparamend;
++ uint nextparamoff;
++
++ pparamend = memchr(ptran+off, ',', tranlen-off);
++ pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
++ nextparamoff = pparamend-ptran;
++
++ while (off < nextparamoff) {
++ const char* pfieldend;
++ uint nextfieldoff;
++
++ pfieldend = memchr(ptran+off, ';', nextparamoff-off);
++ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
++
++ if (strncmp(ptran+off, "client_port=", 12) == 0) {
++ u_int16_t port;
++ uint numlen;
++
++ off += 12;
++ numlen = nf_strtou16(ptran+off, &port);
++ off += numlen;
++ if (prtspexp->loport != 0 && prtspexp->loport != port)
++ pr_debug("multiple ports found, port %hu ignored\n", port);
++ else {
++ pr_debug("lo port found : %hu\n", port);
++ prtspexp->loport = prtspexp->hiport = port;
++ if (ptran[off] == '-') {
++ off++;
++ numlen = nf_strtou16(ptran+off, &port);
++ off += numlen;
++ prtspexp->pbtype = pb_range;
++ prtspexp->hiport = port;
++
++ // If we have a range, assume rtp:
++ // loport must be even, hiport must be loport+1
++ if ((prtspexp->loport & 0x0001) != 0 ||
++ prtspexp->hiport != prtspexp->loport+1) {
++ pr_debug("incorrect range: %hu-%hu, correcting\n",
++ prtspexp->loport, prtspexp->hiport);
++ prtspexp->loport &= 0xfffe;
++ prtspexp->hiport = prtspexp->loport+1;
++ }
++ } else if (ptran[off] == '/') {
++ off++;
++ numlen = nf_strtou16(ptran+off, &port);
++ off += numlen;
++ prtspexp->pbtype = pb_discon;
++ prtspexp->hiport = port;
++ }
++ rc = 1;
++ }
++ }
++
++ /*
++ * Note we don't look for the destination parameter here.
++ * If we are using NAT, the NAT module will handle it. If not,
++ * and the client is sending packets elsewhere, the expectation
++ * will quietly time out.
++ */
++
++ off = nextfieldoff;
++ }
++
++ off = nextparamoff;
++ }
++
++ return rc;
++}
++
++
++/*** conntrack functions ***/
++
++/* outbound packet: client->server */
++
++static inline int
++help_out(struct sk_buff *skb, unsigned char *rb_ptr, unsigned int datalen,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ struct nf_conn *ct, enum ip_conntrack_info ctinfo,
++ unsigned int protoff)
++#else
++ struct nf_conn *ct, enum ip_conntrack_info ctinfo)
++#endif
++{
++ struct ip_ct_rtsp_expect expinfo;
++
++ int dir = CTINFO2DIR(ctinfo); /* = IP_CT_DIR_ORIGINAL */
++ //struct tcphdr* tcph = (void*)iph + iph->ihl * 4;
++ //uint tcplen = pktlen - iph->ihl * 4;
++ char* pdata = rb_ptr;
++ //uint datalen = tcplen - tcph->doff * 4;
++ uint dataoff = 0;
++ int ret = NF_ACCEPT;
++
++ struct nf_conntrack_expect *rtp_exp;
++ struct nf_conntrack_expect *rtcp_exp = NULL;
++
++ __be16 be_loport;
++ __be16 be_hiport;
++
++ typeof(nf_nat_rtsp_hook) nf_nat_rtsp;
++
++ memset(&expinfo, 0, sizeof(expinfo));
++
++ while (dataoff < datalen) {
++ uint cmdoff = dataoff;
++ uint hdrsoff = 0;
++ uint hdrslen = 0;
++ uint cseqoff = 0;
++ uint cseqlen = 0;
++ uint transoff = 0;
++ uint translen = 0;
++ uint off;
++
++ if (!rtsp_parse_message(pdata, datalen, &dataoff,
++ &hdrsoff, &hdrslen,
++ &cseqoff, &cseqlen,
++ &transoff, &translen))
++ break; /* not a valid message */
++
++ if (strncmp(pdata+cmdoff, "TEARDOWN ", 9) == 0) {
++ pr_debug("teardown handled\n");
++ nf_ct_remove_expectations(ct); /* FIXME must be session id aware */
++ break;
++ }
++
++ if (strncmp(pdata+cmdoff, "SETUP ", 6) != 0)
++ continue; /* not a SETUP message */
++
++ pr_debug("found a setup message\n");
++
++ off = 0;
++ if(translen)
++ rtsp_parse_transport(pdata+transoff, translen, &expinfo);
++
++ if (expinfo.loport == 0) {
++ pr_debug("no udp transports found\n");
++ continue; /* no udp transports found */
++ }
++
++ pr_debug("udp transport found, ports=(%d,%hu,%hu)\n",
++ (int)expinfo.pbtype, expinfo.loport, expinfo.hiport);
++
++
++ be_loport = htons(expinfo.loport);
++
++ rtp_exp = nf_ct_expect_alloc(ct);
++ if (rtp_exp == NULL) {
++ ret = NF_DROP;
++ goto out;
++ }
++
++ nf_ct_expect_init(rtp_exp, NF_CT_EXPECT_CLASS_DEFAULT,
++ nf_ct_l3num(ct),
++ NULL, /* &ct->tuplehash[!dir].tuple.src.u3, */
++ &ct->tuplehash[!dir].tuple.dst.u3,
++ IPPROTO_UDP, NULL, &be_loport);
++
++ rtp_exp->flags = 0;
++
++ if (expinfo.pbtype == pb_range) {
++ pr_debug("setup expectation for rtcp\n");
++
++ be_hiport = htons(expinfo.hiport);
++ rtcp_exp = nf_ct_expect_alloc(ct);
++ if (rtcp_exp == NULL) {
++ ret = NF_DROP;
++ goto out1;
++ }
++
++ nf_ct_expect_init(rtcp_exp, NF_CT_EXPECT_CLASS_DEFAULT,
++ nf_ct_l3num(ct),
++ NULL, /* &ct->tuplehash[!dir].tuple.src.u3, */
++ &ct->tuplehash[!dir].tuple.dst.u3,
++ IPPROTO_UDP, NULL, &be_hiport);
++
++ rtcp_exp->flags = 0;
++
++ pr_debug("expect_related %pI4:%u-%u-%pI4:%u-%u\n",
++ &rtp_exp->tuple.src.u3.ip,
++ ntohs(rtp_exp->tuple.src.u.udp.port),
++ ntohs(rtcp_exp->tuple.src.u.udp.port),
++ &rtp_exp->tuple.dst.u3.ip,
++ ntohs(rtp_exp->tuple.dst.u.udp.port),
++ ntohs(rtcp_exp->tuple.dst.u.udp.port));
++ } else {
++ pr_debug("expect_related %pI4:%u-%pI4:%u\n",
++ &rtp_exp->tuple.src.u3.ip,
++ ntohs(rtp_exp->tuple.src.u.udp.port),
++ &rtp_exp->tuple.dst.u3.ip,
++ ntohs(rtp_exp->tuple.dst.u.udp.port));
++ }
++
++ nf_nat_rtsp = rcu_dereference(nf_nat_rtsp_hook);
++ if (nf_nat_rtsp && ct->status & IPS_NAT_MASK)
++ /* pass the request off to the nat helper */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ ret = nf_nat_rtsp(skb, ctinfo, protoff, hdrsoff, hdrslen,
++ &expinfo, rtp_exp, rtcp_exp);
++#else
++ ret = nf_nat_rtsp(skb, ctinfo, hdrsoff, hdrslen,
++ &expinfo, rtp_exp, rtcp_exp);
++#endif
++ else {
++ if (nf_ct_expect_related(rtp_exp) == 0) {
++ if (rtcp_exp && nf_ct_expect_related(rtcp_exp) != 0) {
++ nf_ct_unexpect_related(rtp_exp);
++ pr_info("nf_conntrack_expect_related failed for rtcp\n");
++ ret = NF_DROP;
++ }
++ } else {
++ pr_info("nf_conntrack_expect_related failed for rtp\n");
++ ret = NF_DROP;
++ }
++ }
++ if (rtcp_exp) {
++ nf_ct_expect_put(rtcp_exp);
++ }
++out1:
++ nf_ct_expect_put(rtp_exp);
++ goto out;
++ }
++out:
++
++ return ret;
++}
++
++
++static inline int
++help_in(struct sk_buff *skb, size_t pktlen,
++ struct nf_conn* ct, enum ip_conntrack_info ctinfo)
++{
++ return NF_ACCEPT;
++}
++
++static int help(struct sk_buff *skb, unsigned int protoff,
++ struct nf_conn *ct, enum ip_conntrack_info ctinfo)
++{
++ struct tcphdr _tcph, *th;
++ unsigned int dataoff, datalen;
++ char *rb_ptr;
++ int ret = NF_DROP;
++
++ /* Until there's been traffic both ways, don't look in packets. */
++ if (ctinfo != IP_CT_ESTABLISHED &&
++ ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
++ pr_debug("conntrackinfo = %u\n", ctinfo);
++ return NF_ACCEPT;
++ }
++
++ /* Not whole TCP header? */
++ th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
++
++ if (!th)
++ return NF_ACCEPT;
++
++ /* No data ? */
++ dataoff = protoff + th->doff*4;
++ datalen = skb->len - dataoff;
++ if (dataoff >= skb->len)
++ return NF_ACCEPT;
++
++ spin_lock_bh(&rtsp_buffer_lock);
++ rb_ptr = skb_header_pointer(skb, dataoff,
++ skb->len - dataoff, rtsp_buffer);
++ BUG_ON(rb_ptr == NULL);
++
++#if 0
++ /* Checksum invalid? Ignore. */
++ /* FIXME: Source route IP option packets --RR */
++ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
++ csum_partial((char*)tcph, tcplen, 0)))
++ {
++ DEBUGP("bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
++ tcph, tcplen, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
++ return NF_ACCEPT;
++ }
++#endif
++
++ switch (CTINFO2DIR(ctinfo)) {
++ case IP_CT_DIR_ORIGINAL:
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ ret = help_out(skb, rb_ptr, datalen, ct, ctinfo, protoff);
++#else
++ ret = help_out(skb, rb_ptr, datalen, ct, ctinfo);
++#endif
++ break;
++ case IP_CT_DIR_REPLY:
++ pr_debug("IP_CT_DIR_REPLY\n");
++ /* inbound packet: server->client */
++ ret = NF_ACCEPT;
++ break;
++ }
++
++ spin_unlock_bh(&rtsp_buffer_lock);
++
++ return ret;
++}
++
++static struct nf_conntrack_helper rtsp_helpers[MAX_PORTS];
++static char rtsp_names[MAX_PORTS][10];
++
++/* This function is intentionally _NOT_ defined as __exit */
++static void
++fini(void)
++{
++ int i;
++ for (i = 0; i < num_ports; i++) {
++ pr_debug("unregistering port %d\n", ports[i]);
++ nf_conntrack_helper_unregister(&rtsp_helpers[i]);
++ }
++ kfree(rtsp_buffer);
++}
++
++static int __init
++init(void)
++{
++ int i, ret;
++ struct nf_conntrack_helper *hlpr;
++ char *tmpname;
++
++ printk("nf_conntrack_rtsp v" IP_NF_RTSP_VERSION " loading\n");
++
++ if (max_outstanding < 1) {
++ printk("nf_conntrack_rtsp: max_outstanding must be a positive integer\n");
++ return -EBUSY;
++ }
++ if (setup_timeout < 0) {
++ printk("nf_conntrack_rtsp: setup_timeout must be a positive integer\n");
++ return -EBUSY;
++ }
++
++ rtsp_exp_policy.max_expected = max_outstanding;
++ rtsp_exp_policy.timeout = setup_timeout;
++
++ rtsp_buffer = kmalloc(65536, GFP_KERNEL);
++ if (!rtsp_buffer)
++ return -ENOMEM;
++
++ /* If no port given, default to standard rtsp port */
++ if (ports[0] == 0) {
++ ports[0] = RTSP_PORT;
++ num_ports = 1;
++ }
++
++ for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
++ hlpr = &rtsp_helpers[i];
++ memset(hlpr, 0, sizeof(struct nf_conntrack_helper));
++ hlpr->tuple.src.l3num = AF_INET;
++ hlpr->tuple.src.u.tcp.port = htons(ports[i]);
++ hlpr->tuple.dst.protonum = IPPROTO_TCP;
++ hlpr->expect_policy = &rtsp_exp_policy;
++ hlpr->me = THIS_MODULE;
++ hlpr->help = help;
++
++ tmpname = &rtsp_names[i][0];
++ if (ports[i] == RTSP_PORT) {
++ sprintf(tmpname, "rtsp");
++ } else {
++ sprintf(tmpname, "rtsp-%d", i);
++ }
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
++ strlcpy(hlpr->name, tmpname, sizeof(hlpr->name));
++#else
++ hlpr->name = tmpname;
++#endif
++ pr_debug("port #%d: %d\n", i, ports[i]);
++
++ ret = nf_conntrack_helper_register(hlpr);
++
++ if (ret) {
++ printk("nf_conntrack_rtsp: ERROR registering port %d\n", ports[i]);
++ fini();
++ return -EBUSY;
++ }
++ }
++ return 0;
++}
++
++module_init(init);
++module_exit(fini);
+--- /dev/null
++++ b/extensions/rtsp/nf_conntrack_rtsp.h
+@@ -0,0 +1,72 @@
++/*
++ * RTSP extension for IP connection tracking.
++ * (C) 2003 by Tom Marshall <tmarshall at real.com>
++ * based on ip_conntrack_irc.h
++ *
++ * 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.
++ *
++ * 2013-03-04: Il'inykh Sergey <sergeyi at inango-sw.com>. Inango Systems Ltd
++ * - conditional compilation for kernel 3.7
++ * - port mapping improvements
++*/
++#ifndef _IP_CONNTRACK_RTSP_H
++#define _IP_CONNTRACK_RTSP_H
++
++#include <linux/version.h>
++
++//#define IP_NF_RTSP_DEBUG 1
++#define IP_NF_RTSP_VERSION "0.7"
++
++#ifdef __KERNEL__
++/* port block types */
++typedef enum {
++ pb_single, /* client_port=x */
++ pb_range, /* client_port=x-y */
++ pb_discon /* client_port=x/y (rtspbis) */
++} portblock_t;
++
++/* We record seq number and length of rtsp headers here, all in host order. */
++
++/*
++ * This structure is per expected connection. It is a member of struct
++ * ip_conntrack_expect. The TCP SEQ for the conntrack expect is stored
++ * there and we are expected to only store the length of the data which
++ * needs replaced. If a packet contains multiple RTSP messages, we create
++ * one expected connection per message.
++ *
++ * We use these variables to mark the entire header block. This may seem
++ * like overkill, but the nature of RTSP requires it. A header may appear
++ * multiple times in a message. We must treat two Transport headers the
++ * same as one Transport header with two entries.
++ */
++struct ip_ct_rtsp_expect
++{
++ u_int32_t len; /* length of header block */
++ portblock_t pbtype; /* Type of port block that was requested */
++ u_int16_t loport; /* Port that was requested, low or first */
++ u_int16_t hiport; /* Port that was requested, high or second */
++#if 0
++ uint method; /* RTSP method */
++ uint cseq; /* CSeq from request */
++#endif
++};
++
++extern unsigned int (*nf_nat_rtsp_hook)(struct sk_buff *skb,
++ enum ip_conntrack_info ctinfo,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ unsigned int protoff,
++#endif
++ unsigned int matchoff,
++ unsigned int matchlen,
++ struct ip_ct_rtsp_expect *prtspexp,
++ struct nf_conntrack_expect *rtp_exp,
++ struct nf_conntrack_expect *rtcp_exp);
++
++#define RTSP_PORT 554
++
++#endif /* __KERNEL__ */
++
++#endif /* _IP_CONNTRACK_RTSP_H */
+--- /dev/null
++++ b/extensions/rtsp/nf_nat_rtsp.c
+@@ -0,0 +1,617 @@
++/*
++ * RTSP extension for TCP NAT alteration
++ * (C) 2003 by Tom Marshall <tmarshall at real.com>
++ *
++ * 2013-03-04: Il'inykh Sergey <sergeyi at inango-sw.com>. Inango Systems Ltd
++ * - fixed rtcp nat mapping and other port mapping fixes
++ * - fixed system hard lock because of bug in the parser
++ * - codestyle fixes and less significant fixes
++ *
++ * based on ip_nat_irc.c
++ *
++ * 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.
++ *
++ * Module load syntax:
++ * insmod nf_nat_rtsp.o ports=port1,port2,...port<MAX_PORTS>
++ * stunaddr=<address>
++ * destaction=[auto|strip|none]
++ *
++ * If no ports are specified, the default will be port 554 only.
++ *
++ * stunaddr specifies the address used to detect that a client is using STUN.
++ * If this address is seen in the destination parameter, it is assumed that
++ * the client has already punched a UDP hole in the firewall, so we don't
++ * mangle the client_port. If none is specified, it is autodetected. It
++ * only needs to be set if you have multiple levels of NAT. It should be
++ * set to the external address that the STUN clients detect. Note that in
++ * this case, it will not be possible for clients to use UDP with servers
++ * between the NATs.
++ *
++ * If no destaction is specified, auto is used.
++ * destaction=auto: strip destination parameter if it is not stunaddr.
++ * destaction=strip: always strip destination parameter (not recommended).
++ * destaction=none: do not touch destination parameter (not recommended).
++ */
++
++#include <linux/module.h>
++#include <linux/version.h>
++#include <net/tcp.h>
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++# include <net/netfilter/nf_nat.h>
++#else
++# include <net/netfilter/nf_nat_rule.h>
++#endif
++#include <net/netfilter/nf_nat_helper.h>
++#include "nf_conntrack_rtsp.h"
++#include <net/netfilter/nf_conntrack_expect.h>
++
++#include <linux/inet.h>
++#include <linux/ctype.h>
++#define NF_NEED_STRNCASECMP
++#define NF_NEED_STRTOU16
++#include "netfilter_helpers.h"
++#define NF_NEED_MIME_NEXTLINE
++#include "netfilter_mime.h"
++
++#define MAX_PORTS 8
++#define DSTACT_AUTO 0
++#define DSTACT_STRIP 1
++#define DSTACT_NONE 2
++
++static char* stunaddr = NULL;
++static char* destaction = NULL;
++
++static u_int32_t extip = 0;
++static int dstact = 0;
++
++static void nf_nat_rtsp_expected(struct nf_conn* ct, struct nf_conntrack_expect *exp);
++
++MODULE_AUTHOR("Tom Marshall <tmarshall at real.com>");
++MODULE_DESCRIPTION("RTSP network address translation module");
++MODULE_LICENSE("GPL");
++module_param(stunaddr, charp, 0644);
++MODULE_PARM_DESC(stunaddr, "Address for detecting STUN");
++module_param(destaction, charp, 0644);
++MODULE_PARM_DESC(destaction, "Action for destination parameter (auto/strip/none)");
++
++#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; }
++
++/*** helper functions ***/
++
++static void
++get_skb_tcpdata(struct sk_buff* skb, char** pptcpdata, uint* ptcpdatalen)
++{
++ struct iphdr* iph = ip_hdr(skb);
++ struct tcphdr* tcph = (void *)iph + ip_hdrlen(skb);
++
++ *pptcpdata = (char*)tcph + tcph->doff*4;
++ *ptcpdatalen = ((char*)skb_transport_header(skb) + skb->len) - *pptcpdata;
++}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++/* copy of sip_sprintf_addr */
++static int rtsp_sprintf_addr(const struct nf_conn *ct, char *buffer,
++ const union nf_inet_addr *addr, bool delim)
++{
++ if (nf_ct_l3num(ct) == NFPROTO_IPV4) {
++ return sprintf(buffer, "%pI4", &addr->ip);
++ } else {
++ if (delim)
++ return sprintf(buffer, "[%pI6c]", &addr->ip6);
++ else
++ return sprintf(buffer, "%pI6c", &addr->ip6);
++ }
++}
++#endif
++
++/*** nat functions ***/
++
++/*
++ * Mangle the "Transport:" header:
++ * - Replace all occurences of "client_port=<spec>"
++ * - Handle destination parameter
++ *
++ * In:
++ * ct, ctinfo = conntrack context
++ * skb = packet
++ * tranoff = Transport header offset from TCP data
++ * tranlen = Transport header length (incl. CRLF)
++ * rport_lo = replacement low port (host endian)
++ * rport_hi = replacement high port (host endian)
++ *
++ * Returns packet size difference.
++ *
++ * Assumes that a complete transport header is present, ending with CR or LF
++ */
++static int
++rtsp_mangle_tran(enum ip_conntrack_info ctinfo,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ unsigned int protoff,
++#endif
++ struct nf_conntrack_expect* rtp_exp,
++ struct nf_conntrack_expect* rtcp_exp,
++ struct ip_ct_rtsp_expect* prtspexp,
++ struct sk_buff* skb, uint tranoff, uint tranlen)
++{
++ char* ptcp;
++ uint tcplen;
++ char* ptran;
++ char rbuf1[16]; /* Replacement buffer (one port) */
++ uint rbuf1len; /* Replacement len (one port) */
++ char rbufa[16]; /* Replacement buffer (all ports) */
++ uint rbufalen; /* Replacement len (all ports) */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ union nf_inet_addr newip;
++#else
++ u_int32_t newip;
++#endif
++ u_int16_t loport, hiport;
++ uint off = 0;
++ uint diff; /* Number of bytes we removed */
++
++ struct nf_conn *ct = rtp_exp->master;
++ /* struct nf_conn *ct = nf_ct_get(skb, &ctinfo); */
++ struct nf_conntrack_tuple *rtp_t;
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ char szextaddr[INET6_ADDRSTRLEN];
++#else
++ char szextaddr[INET_ADDRSTRLEN];
++#endif
++ uint extaddrlen;
++ int is_stun;
++
++ get_skb_tcpdata(skb, &ptcp, &tcplen);
++ ptran = ptcp+tranoff;
++
++ if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen ||
++ tranlen < 10 || !iseol(ptran[tranlen-1]) ||
++ nf_strncasecmp(ptran, "Transport:", 10) != 0) {
++ pr_info("sanity check failed\n");
++ return 0;
++ }
++ off += 10;
++ SKIP_WSPACE(ptcp+tranoff, tranlen, off);
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3;
++ rtp_t = &rtp_exp->tuple;
++ rtp_t->dst.u3 = newip;
++ if (rtcp_exp) {
++ rtcp_exp->tuple.dst.u3 = newip;
++ }
++ extaddrlen = rtsp_sprintf_addr(ct, szextaddr, &newip, true); // FIXME handle extip
++ pr_debug("stunaddr=%s (auto)\n", szextaddr);
++#else
++ newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;
++ rtp_t = &rtp_exp->tuple;
++ rtp_t->dst.u3.ip = newip;
++ if (rtcp_exp) {
++ rtcp_exp->tuple.dst.u3.ip = newip;
++ }
++ extaddrlen = extip ? sprintf(szextaddr, "%pI4", &extip)
++ : sprintf(szextaddr, "%pI4", &newip);
++ pr_debug("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto"));
++#endif
++ hiport = 0;
++ rbuf1len = rbufalen = 0;
++ switch (prtspexp->pbtype) {
++ case pb_single:
++ for (loport = prtspexp->loport; loport != 0; loport++) { /* XXX: improper wrap? */
++ rtp_t->dst.u.udp.port = htons(loport);
++ if (nf_ct_expect_related(rtp_exp) == 0) {
++ pr_debug("using port %hu\n", loport);
++ break;
++ }
++ }
++ if (loport != 0) {
++ rbuf1len = sprintf(rbuf1, "%hu", loport);
++ rbufalen = sprintf(rbufa, "%hu", loport);
++ }
++ break;
++ case pb_range:
++ for (loport = prtspexp->loport; loport != 0; loport += 2) { /* XXX: improper wrap? */
++ rtp_t->dst.u.udp.port = htons(loport);
++ if (nf_ct_expect_related(rtp_exp) != 0) {
++ continue;
++ }
++ hiport = loport + 1;
++ rtcp_exp->tuple.dst.u.udp.port = htons(hiport);
++ if (nf_ct_expect_related(rtcp_exp) != 0) {
++ nf_ct_unexpect_related(rtp_exp);
++ continue;
++ }
++
++ /* FIXME: invalid print in case of ipv6 */
++ pr_debug("nat expect_related %pI4:%u-%u-%pI4:%u-%u\n",
++ &rtp_exp->tuple.src.u3.ip,
++ ntohs(rtp_exp->tuple.src.u.udp.port),
++ ntohs(rtcp_exp->tuple.src.u.udp.port),
++ &rtp_exp->tuple.dst.u3.ip,
++ ntohs(rtp_exp->tuple.dst.u.udp.port),
++ ntohs(rtcp_exp->tuple.dst.u.udp.port));
++ break;
++ }
++ if (loport != 0) {
++ rbuf1len = sprintf(rbuf1, "%hu", loport);
++ rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport);
++ }
++ break;
++ case pb_discon:
++ for (loport = prtspexp->loport; loport != 0; loport++) { /* XXX: improper wrap? */
++ rtp_t->dst.u.udp.port = htons(loport);
++ if (nf_ct_expect_related(rtp_exp) == 0) {
++ pr_debug("using port %hu (1 of 2)\n", loport);
++ break;
++ }
++ }
++ for (hiport = prtspexp->hiport; hiport != 0; hiport++) { /* XXX: improper wrap? */
++ rtp_t->dst.u.udp.port = htons(hiport);
++ if (nf_ct_expect_related(rtp_exp) == 0) {
++ pr_debug("using port %hu (2 of 2)\n", hiport);
++ break;
++ }
++ }
++ if (loport != 0 && hiport != 0) {
++ rbuf1len = sprintf(rbuf1, "%hu", loport);
++ rbufalen = sprintf(rbufa, hiport == loport+1 ?
++ "%hu-%hu":"%hu/%hu", loport, hiport);
++ }
++ break;
++ }
++
++ if (rbuf1len == 0)
++ return 0; /* cannot get replacement port(s) */
++
++ /* Transport: tran;field;field=val,tran;field;field=val,...
++ `off` is set to the start of Transport value from start of line
++ */
++ while (off < tranlen) {
++ uint saveoff;
++ const char* pparamend;
++ uint nextparamoff;
++
++ pparamend = memchr(ptran+off, ',', tranlen-off);
++ pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
++ nextparamoff = pparamend-ptran;
++
++ /*
++ * We pass over each param twice. On the first pass, we look for a
++ * destination= field. It is handled by the security policy. If it
++ * is present, allowed, and equal to our external address, we assume
++ * that STUN is being used and we leave the client_port= field alone.
++ */
++ is_stun = 0;
++ saveoff = off;
++ while (off < nextparamoff) {
++ const char* pfieldend;
++ uint nextfieldoff;
++
++ pfieldend = memchr(ptran+off, ';', nextparamoff-off);
++ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
++
++ if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0) {
++ if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0)
++ is_stun = 1;
++
++ if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun)) {
++ uint dstoff = (ptran-ptcp)+off;
++ uint dstlen = nextfieldoff-off;
++ char* pdstrep = NULL;
++ uint dstreplen = 0;
++ diff = dstlen;
++ if (dstact == DSTACT_AUTO && !is_stun) {
++ pr_debug("RTSP: replace dst addr\n");
++ dstoff += 12;
++ dstlen -= 13;
++ pdstrep = szextaddr;
++ dstreplen = extaddrlen;
++ diff = nextfieldoff-off-13-extaddrlen;
++ }
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff,
++ dstoff, dstlen, pdstrep, dstreplen)) {
++#else
++ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
++ dstoff, dstlen, pdstrep, dstreplen)) {
++#endif
++ /* mangle failed, all we can do is bail */
++ nf_ct_unexpect_related(rtp_exp);
++ if (rtcp_exp)
++ nf_ct_unexpect_related(rtcp_exp);
++ return 0;
++ }
++ get_skb_tcpdata(skb, &ptcp, &tcplen);
++ ptran = ptcp+tranoff;
++ tranlen -= diff;
++ nextparamoff -= diff;
++ nextfieldoff -= diff;
++ }
++ }
++
++ off = nextfieldoff;
++ }
++
++ if (is_stun)
++ continue;
++
++ off = saveoff;
++ while (off < nextparamoff) {
++ const char* pfieldend;
++ uint nextfieldoff;
++
++ pfieldend = memchr(ptran+off, ';', nextparamoff-off);
++ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
++
++ if (strncmp(ptran+off, "client_port=", 12) == 0) {
++ u_int16_t port;
++ uint numlen;
++ uint origoff;
++ uint origlen;
++ char* rbuf = rbuf1;
++ uint rbuflen = rbuf1len;
++
++ off += 12;
++ origoff = (ptran-ptcp)+off;
++ origlen = 0;
++ numlen = nf_strtou16(ptran+off, &port);
++ off += numlen;
++ origlen += numlen;
++ if (port != prtspexp->loport) {
++ pr_debug("multiple ports found, port %hu ignored\n", port);
++ } else {
++ if (ptran[off] == '-' || ptran[off] == '/') {
++ off++;
++ origlen++;
++ numlen = nf_strtou16(ptran+off, &port);
++ off += numlen;
++ origlen += numlen;
++ rbuf = rbufa;
++ rbuflen = rbufalen;
++ }
++
++ /*
++ * note we cannot just memcpy() if the sizes are the same.
++ * the mangle function does skb resizing, checks for a
++ * cloned skb, and updates the checksums.
++ *
++ * parameter 4 below is offset from start of tcp data.
++ */
++ diff = origlen-rbuflen;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff,
++ origoff, origlen, rbuf, rbuflen)) {
++#else
++ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
++ origoff, origlen, rbuf, rbuflen)) {
++#endif
++ /* mangle failed, all we can do is bail */
++ nf_ct_unexpect_related(rtp_exp);
++ if (rtcp_exp)
++ nf_ct_unexpect_related(rtcp_exp);
++ return 0;
++ }
++ get_skb_tcpdata(skb, &ptcp, &tcplen);
++ ptran = ptcp+tranoff;
++ tranlen -= diff;
++ nextparamoff -= diff;
++ nextfieldoff -= diff;
++ }
++ }
++
++ off = nextfieldoff;
++ }
++
++ off = nextparamoff;
++ }
++
++ return 1;
++}
++
++static uint
++help_out(struct sk_buff *skb, enum ip_conntrack_info ctinfo,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ unsigned int protoff,
++#endif
++ unsigned int matchoff, unsigned int matchlen,
++ struct ip_ct_rtsp_expect* prtspexp,
++ struct nf_conntrack_expect* rtp_exp,
++ struct nf_conntrack_expect* rtcp_exp)
++{
++ char* ptcp;
++ uint tcplen;
++ uint hdrsoff;
++ uint hdrslen;
++ uint lineoff;
++ uint linelen;
++ uint off;
++ int dir = CTINFO2DIR(ctinfo);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ union nf_inet_addr saddr = rtp_exp->master->tuplehash[dir].tuple.src.u3;
++#else
++ __be32 saddr = rtp_exp->master->tuplehash[dir].tuple.src.u3.ip;
++#endif
++
++ //struct iphdr* iph = (struct iphdr*)(*pskb)->nh.iph;
++ //struct tcphdr* tcph = (struct tcphdr*)((void*)iph + iph->ihl*4);
++
++ get_skb_tcpdata(skb, &ptcp, &tcplen);
++ hdrsoff = matchoff;//exp->seq - ntohl(tcph->seq);
++ hdrslen = matchlen;
++ off = hdrsoff;
++ pr_debug("NAT rtsp help_out\n");
++
++ while (nf_mime_nextline(ptcp, hdrsoff+hdrslen, &off, &lineoff, &linelen)) {
++ if (linelen == 0)
++ break;
++
++ if (off > hdrsoff+hdrslen) {
++ pr_info("!! overrun !!");
++ break;
++ }
++ pr_debug("hdr: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff);
++
++ if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0) {
++ uint oldtcplen = tcplen;
++ pr_debug("hdr: Transport\n");
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ if (!rtsp_mangle_tran(ctinfo, protoff, rtp_exp, rtcp_exp,
++ prtspexp, skb, lineoff, linelen)) {
++#else
++ if (!rtsp_mangle_tran(ctinfo, rtp_exp, rtcp_exp, prtspexp,
++ skb, lineoff, linelen)) {
++#endif
++ pr_debug("hdr: Transport mangle failed");
++ break;
++ }
++ rtp_exp->expectfn = nf_nat_rtsp_expected;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ rtp_exp->saved_addr = saddr;
++#else
++ rtp_exp->saved_ip = saddr;
++#endif
++ rtp_exp->saved_proto.udp.port = htons(prtspexp->loport);
++ rtp_exp->dir = !dir;
++ if (rtcp_exp) {
++ rtcp_exp->expectfn = nf_nat_rtsp_expected;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ rtcp_exp->saved_addr = saddr;
++#else
++ rtcp_exp->saved_ip = saddr;
++#endif
++ rtcp_exp->saved_proto.udp.port = htons(prtspexp->hiport);
++ rtcp_exp->dir = !dir;
++ }
++ get_skb_tcpdata(skb, &ptcp, &tcplen);
++ hdrslen -= (oldtcplen-tcplen);
++ off -= (oldtcplen-tcplen);
++ lineoff -= (oldtcplen-tcplen);
++ linelen -= (oldtcplen-tcplen);
++ pr_debug("rep: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff);
++ }
++ }
++
++ return NF_ACCEPT;
++}
++
++static unsigned int
++nf_nat_rtsp(struct sk_buff *skb, enum ip_conntrack_info ctinfo,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ unsigned int protoff,
++#endif
++ unsigned int matchoff, unsigned int matchlen,
++ struct ip_ct_rtsp_expect* prtspexp,
++ struct nf_conntrack_expect* rtp_exp,
++ struct nf_conntrack_expect* rtcp_exp)
++{
++ int dir = CTINFO2DIR(ctinfo);
++ int rc = NF_ACCEPT;
++
++ switch (dir) {
++ case IP_CT_DIR_ORIGINAL:
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ rc = help_out(skb, ctinfo, protoff, matchoff, matchlen, prtspexp,
++ rtp_exp, rtcp_exp);
++#else
++ rc = help_out(skb, ctinfo, matchoff, matchlen, prtspexp,
++ rtp_exp, rtcp_exp);
++#endif
++ break;
++ case IP_CT_DIR_REPLY:
++ pr_debug("unmangle ! %u\n", ctinfo);
++ /* XXX: unmangle */
++ rc = NF_ACCEPT;
++ break;
++ }
++ //UNLOCK_BH(&ip_rtsp_lock);
++
++ return rc;
++}
++
++static void nf_nat_rtsp_expected(struct nf_conn* ct, struct nf_conntrack_expect *exp)
++{
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ struct nf_nat_range range;
++#else
++ struct nf_nat_ipv4_range range;
++#endif
++
++ /* This must be a fresh one. */
++ BUG_ON(ct->status & IPS_NAT_DONE_MASK);
++
++ /* For DST manip, map port here to where it's expected. */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ range.min_proto = range.max_proto = exp->saved_proto;
++ range.min_addr = range.max_addr = exp->saved_addr;
++#else
++ range.min = range.max = exp->saved_proto;
++ range.min_ip = range.max_ip = exp->saved_ip;
++#endif
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
++ range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
++ nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
++#else
++ range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
++ nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
++#endif
++
++ /* Change src to where master sends to, but only if the connection
++ * actually came from the same source. */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
++ if (nf_inet_addr_cmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3,
++ &ct->master->tuplehash[exp->dir].tuple.src.u3)) {
++ range.min_addr = range.max_addr
++ = ct->master->tuplehash[!exp->dir].tuple.dst.u3;
++#else
++ if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip ==
++ ct->master->tuplehash[exp->dir].tuple.src.u3.ip) {
++ range.min_ip = range.max_ip
++ = ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip;
++#endif
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
++ range.flags = NF_NAT_RANGE_MAP_IPS;
++ nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
++#else
++ range.flags = IP_NAT_RANGE_MAP_IPS;
++ nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
++#endif
++ }
++}
++
++
++static void __exit fini(void)
++{
++ rcu_assign_pointer(nf_nat_rtsp_hook, NULL);
++ synchronize_net();
++}
++
++static int __init init(void)
++{
++ printk("nf_nat_rtsp v" IP_NF_RTSP_VERSION " loading\n");
++
++ BUG_ON(nf_nat_rtsp_hook);
++ rcu_assign_pointer(nf_nat_rtsp_hook, nf_nat_rtsp);
++
++ if (stunaddr != NULL)
++ extip = in_aton(stunaddr);
++
++ if (destaction != NULL) {
++ if (strcmp(destaction, "auto") == 0)
++ dstact = DSTACT_AUTO;
++
++ if (strcmp(destaction, "strip") == 0)
++ dstact = DSTACT_STRIP;
++
++ if (strcmp(destaction, "none") == 0)
++ dstact = DSTACT_NONE;
++ }
++
++ return 0;
++}
++
++module_init(init);
++module_exit(fini);
+--- a/extensions/Kbuild
++++ b/extensions/Kbuild
+@@ -28,6 +28,7 @@ obj-${build_lscan} += xt_lscan.o
+ obj-${build_pknock} += pknock/
+ obj-${build_psd} += xt_psd.o
+ obj-${build_quota2} += xt_quota2.o
++obj-${build_rtsp} += rtsp/
+
+ -include ${M}/*.Kbuild
+ -include ${M}/Kbuild.*
+--- a/mconfig
++++ b/mconfig
+@@ -22,3 +22,4 @@ build_lscan=m
+ build_pknock=m
+ build_psd=m
+ build_quota2=m
++build_rtsp=m
diff --git a/package/network/utils/xtables-addons/patches/200-add-lua-packetscript.patch b/package/network/utils/xtables-addons/patches/200-add-lua-packetscript.patch
new file mode 100644
index 0000000..8bc30a7
--- /dev/null
+++ b/package/network/utils/xtables-addons/patches/200-add-lua-packetscript.patch
@@ -0,0 +1,18158 @@
+--- /dev/null
++++ b/extensions/LUA/byte_array.c
+@@ -0,0 +1,145 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++#include "controller.h"
++
++/* Initialization helper function. This function should be used whenever
++ * a new byte array need to be initialized. Depending on the arguments it
++ * initializes the array in a different way. Have a look at the inline
++ * comments */
++lua_packet_segment * init_byte_array(lua_State *L, unsigned char * start, int length, int do_copy)
++{
++ lua_packet_segment *array;
++
++ if (length < 0)
++ luaL_error(L, "init_byte_array, requested size < 0");
++
++ if (start && do_copy) {
++ /* we have a start address where we copy from */
++ array = lua_newuserdata(L, sizeof(lua_packet_segment) + length);
++ array->start = (unsigned char *)array + sizeof(lua_packet_segment); /* aligning pointer */
++ memcpy(array->start, start, length);
++ }else if (start && !do_copy) {
++ /* just link the start pointer, in this case you have to free the memory yourself */
++ array = lua_newuserdata(L, sizeof(lua_packet_segment));
++ array->start = start;
++ }else{
++ /* create an empty array, fully managed by Lua */
++ array = lua_newuserdata(L, sizeof(lua_packet_segment) + length);
++ array->start = (unsigned char *)array + sizeof(lua_packet_segment); /* aligning pointer */
++ memset(array->start, 0, length);
++ }
++
++ array->length = length;
++ array->offset = 0;
++ array->changes = NULL;
++
++ luaL_getmetatable(L, LUA_BYTE_ARRAY);
++ lua_setmetatable(L, -2);
++
++ return array;
++}
++
++
++
++/* LUA_API: get one byte of the given byte array
++ * access-pattern: array[<index>] */
++static int32_t get_byte_array(lua_State *L)
++{
++ lua_packet_segment * array = checkbytearray(L, 1);
++ int32_t index = luaL_checkinteger(L, 2); /* array starts with index 0 (not 1 as usual in Lua) */
++
++ luaL_argcheck(L, 0 <= index && index < array->length, 1, "index out of range");
++ lua_pushinteger(L, (array->start + array->offset)[index]);
++
++ return 1;
++}
++
++/* LUA_API: set one byte of the given byte array
++ * access-pattern: array[<index>]= 0xFF */
++static int32_t set_byte_array(lua_State *L)
++{
++ lua_packet_segment * array = checkbytearray(L, 1);
++ uint8_t byte;
++ int32_t index = luaL_checkinteger(L, 2); /* array starts with index 0 (not 1 as usual in Lua) */
++ int32_t val = luaL_checkinteger(L, 3);
++ uint32_t nob = 1 << CHAR_BIT; /* we should use something like 1 << CHAR_BIT */
++
++ luaL_argcheck(L, 0 <= index && index < array->length, 1, "index out of range");
++ luaL_argcheck(L, 0 <= val && val < nob, 2, "cannot cast value to char");
++
++ byte = (uint8_t)val;
++
++ (array->start + array->offset)[index] = byte;
++
++ return 0;
++}
++
++/* LUA_API: get size of the given byte array
++ * access-pattern: #array (__length meta-method) */
++static int32_t get_byte_array_size(lua_State *L)
++{
++ lua_packet_segment * array = checkbytearray(L, 1);
++
++ lua_pushnumber(L, array->length);
++
++ return 1;
++}
++
++
++/* LUA_API: converts a given byte array to a string.
++ * access-pattern: implicit through functions calling the
++ * __to_string() metamethod , e.g. print32_t */
++static int32_t byte_array_to_string(lua_State *L)
++{
++ lua_packet_segment * array = checkbytearray(L, 1);
++ uint8_t buf[(array->length * 3) + 255];
++ uint8_t hexval[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
++ char res[255 + (array->length * 3)]; /* make sure the buffer is big enough*/
++ int32_t i, n;
++ uint8_t *ptr = array->start + array->offset;
++
++ for (i = 0; i < array->length; i++) {
++ buf[i * 3] = hexval[(ptr[i] >> 4) & 0xF];
++ buf[(i * 3) + 1] = hexval[ptr[i] & 0x0F];
++ buf[(i * 3) + 2] = ' '; /* seperator */
++ }
++
++ buf[array->length * 3] = '\0';
++ n = sprintf(res, "byte_array: length: %d value: %s", array->length, buf);
++
++ lua_pushlstring(L, res, n);
++
++ return 1;
++}
++
++static const struct luaL_Reg bytearray_lib_m [] = {
++ { "__len", get_byte_array_size },
++ { "__newindex", set_byte_array },
++ { "__index", get_byte_array },
++ { "__tostring", byte_array_to_string },
++ { NULL, NULL }
++};
++
++void luaopen_bytearraylib(lua_State *L)
++{
++ luaL_newmetatable(L, LUA_BYTE_ARRAY);
++ luaL_register(L, NULL, bytearray_lib_m);
++ lua_pop(L, 1);
++}
++
++
+--- /dev/null
++++ b/extensions/LUA/controller.c
+@@ -0,0 +1,604 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#if defined(__KERNEL__)
++ #include <linux/mm.h>
++#endif
++#include "controller.h"
++
++/* the array 'supported_protocols' holds all pointers to the
++ * static and dynamic protocol buffers. It is filled by the
++ * call to register_protbuf */
++static struct protocol_buf * supported_protocols[MAX_NR_OF_PROTOCOLS];
++
++/* C_API: the function 'get_protocol_buf' returns the pointer
++ * to the protocol buffer of a given protocol id. */
++struct protocol_buf * get_protocol_buf(uint32_t protocol_id)
++{
++ return (struct protocol_buf *)supported_protocols[protocol_id];
++}
++
++
++/* LUA_INT: the function 'gc_packet_segment' is triggered by the
++ * garbage collector whenever a userdata annotated with one of
++ * the protocol buffer metatable should be collected. */
++static int32_t gc_packet_segment(lua_State *L)
++{
++ lua_packet_segment * seg = (lua_packet_segment *)lua_touserdata(L, 1);
++ if (seg && seg->changes) {
++ seg->changes->ref_count--;
++ if (seg->changes->ref_count <= 0) {
++ kfree(seg->changes->field_length_changes);
++ kfree(seg->changes->field_offset_changes);
++ kfree(seg->changes);
++ seg->changes = NULL;
++ }
++ }
++ return 0;
++}
++
++
++/* LUA_API: the function 'set_raw' is used to set the bytes of a segment
++ * in 'raw' mode. The function is per default available in each protocol
++ * buffer until it gets overridden by a specific setter function inside
++ * a protocol buffer.
++ *
++ * Parameters:
++ * 1. lua_packet_segment (implicit)
++ * 2. int32_t byte_value
++ *
++ * Upvalues:
++ * 1. struct protocol_buf*
++ * 2. int32_t field index, not used in this function
++ *
++ * Return: void
++ */
++static int32_t set_raw(lua_State *L)
++{
++ int32_t i;
++ uint32_t nob;
++ uint8_t byte;
++ uint8_t *ptr;
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ int32_t val = luaL_checkinteger(L, 2);
++
++ nob = 1 << CHAR_BIT;
++
++ luaL_argcheck(L, 0 <= val && val < nob, 2, "cannot cast value to char");
++
++ byte = (uint8_t)val;
++ ptr = seg->start + seg->offset;
++
++ for (i = 0; i < seg->length; i++)
++ ptr[i] = byte;
++
++ return 0;
++}
++
++/* LUA_API: the function 'get_raw' is used to get the bytes of a segment
++ * in 'raw' mode. The function is per default available in each protocol
++ * buffer until it gets overridden by a specific getter function inside
++ * a protocol buffer.
++ *
++ * Parameters:
++ * 1. lua_packet_segment (implicit)
++ * 2. uint32_t offset
++ * 3. uint32_t length
++ *
++ * Upvalues:
++ * 1. struct protocol_buf*
++ * 2. int32_t field index, not used in this function
++ *
++ * Return:
++ * the byte array representing the given array
++ */
++static int32_t get_raw(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ init_byte_array(L, seg->start + seg->offset, seg->length, 1);
++
++ return 1;
++}
++/* LUA_API: The function 'get_segment' is used to get a new segment in 'raw' mode.
++ * Typically this function is applied on another raw segment in order
++ * to extract a part of the segment as new segment.
++ *
++ * Parameters:
++ * 1. lua_packet_segment, implicit through object oriented access seg:raw(..)
++ * 2. uint32_t offset, this indicates where to start the new segment, see e.g below.
++ * 3. uint32_t length, this indicates the size of the new segment
++ *
++ * Upvalues:
++ * 1. struct protocol_buf*
++ * 2. int32_t field index, not used in this function
++ *
++ * Return:
++ * 1. A lua_packet_segment annotated with the according metatable or False in
++ * case the input data is not valid
++ *
++ * Example:
++ *
++ * +------------------------+---------------------------------------+
++ * | function call | resulting lua_packet_segment |
++ * +========================+===+===+===+===+===+===+===+===+===+===+
++ * | seg = packet:raw(0,10) | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
++ * +------------------------+---+---+---+---+---+---+---+---+---+---+
++ * | 1st_half = seg:raw(0,5)| 0 | 1 | 2 | 3 | 4 | |
++ * +------------------------+---+---+---+---+---+---+---+---+---+---+
++ * | 2nd_half = seg:raw(5,5)| | 5 | 6 | 7 | 8 | 9 |
++ * +------------------------+-------------------+---+---+---+---+---+
++ */
++static int32_t get_segment(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++ uint32_t offset = luaL_checkinteger(L, 2);
++ uint32_t length = luaL_checkinteger(L, 3);
++ lua_packet_segment * new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
++
++ new->start = seg->start;
++ new->offset = seg->offset + offset;
++ new->changes = NULL;
++ /* we allow a seg->length == 0 , this enables processing packets where the packetsize is not fixed (0 = not fixed)*/
++ if (seg->length != 0 && length > seg->length) {
++ lua_pushboolean(L, 0);
++ return 1;
++ }
++
++ new->length = length;
++ luaL_getmetatable(L, prot_buf->name);
++ lua_setmetatable(L, -2);
++
++ return 1;
++}
++
++/* LUA_API: the function 'get_segment_size' is used to get the size of a segment.
++ *
++ * Parameters:
++ * 1. lua_packet_segment, implicit through object oriented access seg:raw(..)
++ *
++ * Upvalues:
++ * 1. struct protocol_buf*
++ * 2. int32_t field index, not used in this function
++ *
++ * Return:
++ * 1. Size as lua_Number
++ */
++static int32_t get_segment_size(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ lua_pushnumber(L, seg->length);
++ return 1;
++}
++
++/* LUA_API: the function 'get_segment_offset' is used to get the real offset
++ * of a segment. This function returns the offset of the segment to the start
++ * of the buffer. This means the following
++ * seg1 = packet:raw(2,10)
++ * seg2 = seg1:raw(3,5)
++ * offset = seg2:get_offset()
++ *
++ * will give an offset of 5, since the seg1 starts at offset 2, and seg2 starts
++ * at offset (seg1:get_offset() + 3).
++ *
++ * Parameters:
++ * 1. lua_packet_segment, implicit through object oriented access seg:raw(..)
++ *
++ * Upvalues:
++ * 1. struct protocol_buf*
++ * 2. int32_t field index, not used in this function
++ *
++ * Return:
++ * 1. Offset as lua_Number
++ */
++static int32_t get_segment_offset(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ lua_pushnumber(L, seg->offset);
++ return 1;
++}
++
++/* LUA_API: overwrites the __tostring function of a lua_packet_segment.
++ * this will print32_t a nicely formated string, including length,
++ * offset and name of the protocol buffer.
++ *
++ * Parameters:
++ * 1. lua_packet_segment (implicit)
++ *
++ * Returns:
++ * 1. the representing string
++ */
++static int32_t packet_segment_tostring(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++ int32_t n;
++ char buf[128];
++
++ n = sprintf(buf, "type: %s, offset: %d, length: %d", prot_buf->name, seg->offset, seg->length);
++ lua_pushlstring(L, buf, n);
++
++ return 1;
++}
++
++
++static const struct luaL_Reg seg_access_functions [] = {
++ { "set", set_raw },
++ { "get", get_raw },
++ { "raw", get_segment },
++ { "get_offset", get_segment_offset },
++ { "get_size", get_segment_size },
++ { "to_bytes", get_raw },
++ { "__tostring", packet_segment_tostring },
++ { "__gc", gc_packet_segment },
++ { NULL, NULL }
++};
++
++/* C_API: the function 'get_metatable_from_protocol_type' is a helper
++ * used in controller.c as well as it may find usage in the static
++ * protocol buffers and byte array implementation. */
++void get_metatable_from_protocol_type(lua_State *L, int32_t type)
++{
++ char * table;
++ lua_getglobal(L, SUPPORTED_PROTOCOL_TABLE);
++ lua_rawgeti(L, -1, type);
++ table = (char *)luaL_checkstring(L, -1);
++ lua_pop(L, 2); /* pop the table SUPPORTED_PROTOCOL_TABLE and the string pushed by lua_gettable */
++ luaL_getmetatable(L, table);
++ return;
++}
++
++/* C_INT: the function 'payload_contains_protocol' is used internally.
++ * Depending if static or dynamic protocol buffer it calls the right
++ * validation function. */
++static int32_t payload_contains_protocol(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment *seg, uint32_t prot_type)
++{
++ if (prot_buf->is_dynamic)
++ return has_protocol_dynamic(L, prot_buf, seg, prot_type);
++ else
++ return prot_buf->has_protocol(L, prot_buf, seg, prot_type);
++}
++
++/* C_INT: the function 'protocol_get_field_changes' is used interally.
++ * It requests the field_changes struct calling the protocol buffers
++ * 'get_field_changes' function. This funciton is called, whenever
++ * the payload field with a given protocol type is requested inside
++ * the function 'get_protocol_field' */
++static struct field_changes * protocol_get_field_changes(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment * seg)
++{
++ struct field_changes * changes = NULL;
++
++ if (prot_buf->get_field_changes) {
++ if (prot_buf->is_dynamic)
++ changes = get_field_changes_dynamic(L, prot_buf, seg);
++ else
++ changes = prot_buf->get_field_changes(L, seg);
++ /* is already 1 when set by helper 'get_allocated_field_changes,
++ * since not every prot_buf may use this function we enforce it. */
++ changes->ref_count = 1;
++ }
++ return changes;
++}
++
++/* C_INT: the function 'get_field_offset_in_bytes' wrapps the logic of
++ * calculating the new length with considering the optional field_changes. */
++static int32_t get_field_offset_in_bytes(struct protocol_field * field, lua_packet_segment * seg, int32_t field_index)
++{
++ uint32_t nr_of_bits, nr_of_bytes, field_offset;
++
++ field_offset = field->offset;
++ /* do we need to manipulate the default values stored inside the protocol buffer ?? */
++ if (seg->changes)
++ field_offset += seg->changes->field_offset_changes[field_index];
++ /* how many bits remain */
++ nr_of_bits = field_offset & (CHAR_BIT - 1);
++ /* assuming CHAR_BIT == 2 ^ 3 */
++ nr_of_bytes = (field_offset - nr_of_bits) >> 3;
++
++ return seg->offset + nr_of_bytes;
++}
++
++/* C_INT: the function 'get_field_length_in_bytes' wrapps the logic of
++ * calculating the new offset with considering the optional field_changes. */
++static int32_t get_field_length_in_bytes(struct protocol_field * field, lua_packet_segment * seg, int32_t field_index)
++{
++ uint32_t nr_of_bits, nr_of_bytes, field_length;
++
++ field_length = field->length;
++ /* if the field length is smaller than 1 byte, we take the size of one byte
++ * we treat the case where field_length == 0 in a special way ...*/
++ if (field_length < CHAR_BIT && field_length > 0)
++ field_length = CHAR_BIT;
++
++ /* do we need to manipulate the default values stored inside the protocol buffer ?? */
++ if (seg->changes)
++ field_length += seg->changes->field_length_changes[field_index];
++ /* how many bits remain */
++ nr_of_bits = field_length & (CHAR_BIT - 1);
++ /* assuming CHAR_BIT == 2 ^ 3 */
++ nr_of_bytes = (field_length - nr_of_bits) >> 3;
++ return nr_of_bytes;
++}
++
++/* C_INT: the function 'initialize_field_getter_and_setter' initializes
++ * the setter and getter function of the field, considering the optional
++ * field manipulator functions defined inside the protocol buffers. */
++static void initialize_field_getter_and_setter(lua_State *L, struct protocol_buf *prot_buf, int32_t field_index)
++{
++ /* lets check if there is a metatable on top of the stack */
++ struct protocol_field * f = (struct protocol_field *)&prot_buf->protocol_fields[field_index];
++
++ if (!lua_istable(L, -1)) luaL_error(L, "cannot initialize getter and setter for field %s->%s, "
++ "not a table on top of the stack, is '%s'", prot_buf->name, f->name, lua_typename(L, lua_type(L, -1)));
++
++ /* is there a 'getter' to initialize ? */
++ lua_pushlightuserdata(L, prot_buf); /* push upvalue 1 */
++ lua_pushinteger(L, field_index); /* push upvalue 2 */
++ if (f->get) {
++ if (prot_buf->is_dynamic)
++ lua_pushcclosure(L, field_dynamic_getter, 2);
++ else
++ lua_pushcclosure(L, f->get, 2);
++ }else
++ /* there is no specific getter defined - fall back to 'get_raw' */
++ lua_pushcclosure(L, get_raw, 2);
++ /* set the metatable field 'get' */
++ lua_setfield(L, -2, "get");
++
++ /* is there a 'setter' to initialize ? */
++ lua_pushlightuserdata(L, prot_buf); /* push upvalue 1 */
++ lua_pushinteger(L, field_index); /* push upvalue 2 */
++ if (f->set) {
++ if (prot_buf->is_dynamic)
++ lua_pushcclosure(L, field_dynamic_setter, 2);
++ else
++ lua_pushcclosure(L, f->set, 2);
++ }else
++ /* there is no specific setter defined - fall back to 'set_raw' */
++ lua_pushcclosure(L, set_raw, 2);
++ /* set the metatable field 'set' */
++ lua_setfield(L, -2, "set");
++}
++
++/* LUA_API: 'get_protocol_field' is used in Lua as a closure for each field of a protocol
++ * buffer. E.g a call to ip = packet:data(packet_ip) will go to this function,
++ * and trigger the conversion of the raw packet to a ip packet. Each call
++ * to a field function of an IP packet, like ip:daddr() uses this function
++ * to to return the right data. In each case you will end up either with a
++ * new packet segment (annotated with the proper metatable) or a boolean
++ * value (False) if something went wrong. In the case everything went fine,
++ * the newly created lua_packet_segment is annotated with the proper
++ * metatable where the fields get and set also contain the specific getter
++ * and setter functions given by the protocol buffer. E.g. the function call
++ * ip:daddr():get() or ip:daddr():set(...) will call the proper function
++ * defined inside the corresponding field definition.
++ *
++ * Parameters:
++ * 1. lua_packet_segment, implicit through object oriented access seg:raw(..)
++ * 2. type of the protocol buffer, optional, and only used if the accessed
++ * field is the payload field. If a type is provided for the access of the
++ * payload field, the function tries to convert the data pointed to by the
++ * payload field to the given type. To check if such a conversion is
++ * possible, it calls the function pointed to by the protocol buffer member
++ * has_protocol. If this function returns True, the conversion takes place.
++ *
++ * Upvalues:
++ * 1. struct protocol_buf*
++ * 2. int32_t field index
++ *
++ * Return:
++ * 1. A lua_packet_segment annotated with the according metatable or False in
++ * case the input data is not valid
++ */
++static int32_t get_protocol_field(lua_State *L)
++{
++ int32_t prot_type;
++ lua_packet_segment * seg, *new;
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ int32_t field_index = lua_tointeger(L, lua_upvalueindex(2));
++ struct protocol_field * field = &prot_buf->protocol_fields[field_index];
++
++ /* get the current packet segment */
++ seg = checkpacketseg(L, 1, prot_buf->name);
++
++ /* initialize the new packet segment */
++ new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
++ new->start = seg->start; /* the start is unchanged */
++ new->offset = get_field_offset_in_bytes(field, seg, field_index);
++ new->length = get_field_length_in_bytes(field, seg, field_index);
++
++ /* if new->length == 0 then no configuration was done, we guess the size by subtracting the
++ * new offset from the packet length. since the old length is getting initialized by the
++ * netfilter extension this assumption holds for the very last field of the protocol.
++ * this 'feature' should be used by protocol buffers containing a payload, whereas the
++ * payload field is the last field of the buffer. However, at compile-time unknown field
++ * sizes (and offsets) of fields not being placed at the end of the protocol should be
++ * initialized using the 'get_field_changes' hook system. */
++ if (new->length == 0)
++ new->length = (seg->length + seg->offset) - (new->offset);
++ /*
++ printf("%s->%s:: seg->offset %i, seg->length %i, new->offset %i, new->length %i\n",
++ prot_buf->name, field->name, seg->offset, seg->length, new->offset, new->length);
++ */
++ /* special care for packet payload requests */
++ if (prot_buf->payload_field != NULL && strcmp(prot_buf->payload_field, field->name) == 0) {
++ /* we know the payload field is requested */
++ /* the requested payload can be delivered either as a common segment or as
++ * an other packet type, such a conversion needs an extra protocol parameter
++ * ... so lets check */
++
++ if (lua_isnumber(L, 2)) {
++ /* we have an extra parameter, ... lets see if it is a valid protocol
++ * the parameter is the index of the 'supported_protocols'-array member */
++ prot_type = lua_tointeger(L, 2);
++ if (prot_type >= 0 && prot_type < PACKET_SENTINEL) {
++ /* we are sure the purpose of the request is to get the payload data,
++ * converted to the given protocol. lets check if the payload contains
++ * data of the given protocol */
++ if (payload_contains_protocol(L, prot_buf, seg, prot_type)) {
++ /* success, we can push the metatable for the given protocol */
++ get_metatable_from_protocol_type(L, prot_type);
++ if (!lua_isnil(L, -1)) /* check if the metatable was found */
++ /* perhaps the field offsets and lengths of the containing protocol
++ * are not set correctly. request the optional 'field_changes' structure
++ * holding the changes for lengths and offsets. */
++ new->changes = protocol_get_field_changes(L, get_protocol_buf(prot_type), new);
++ else{
++ /* failed, the requested protocol is not available
++ * we push false and return */
++ lua_pop(L, 1); /* pop the userdata */
++ lua_pushboolean(L, 0);
++ return 1;
++ }
++ }else{
++ /* payload does not carry the provided protocol */
++ /* we push false and return */
++ lua_pop(L, 1); /* pop the userdata */
++ lua_pushboolean(L, 0);
++ return 1;
++ }
++ }else{
++ /* unknown protocol */
++ lua_pop(L, 1); /* pop the userdata */
++ luaL_error(L, "provided protocol is unknown");
++ }
++ }
++ }
++
++ /* if there is still the 'new' userdata on the top, we push our own metatable */
++ if (lua_isuserdata(L, -1)) {
++ luaL_getmetatable(L, prot_buf->name);
++ new->changes = seg->changes;
++ if (seg->changes)
++ new->changes->ref_count++;
++ }
++
++ /* a new packet segment is at index -2 , and the proper metatable at index -1 of the stack
++ * lets set the propper setter and getter function for the requested field */
++ initialize_field_getter_and_setter(L, prot_buf, field_index);
++
++ lua_setmetatable(L, -2);
++ return 1;
++}
++
++/* C_API: 'register_protbuf' is only used internally. This function takes a
++ * pointer to a fully initialized protocol buffer struct and registers it
++ * inside the Lua state. Registering means:
++ *
++ * 1. it creates a new metatable with the name of the protocol buffer.
++ * 2. it registers the default functions which are stored in the luaL_Reg
++ * array seg_access_functions.
++ * 3. it loops over the protocol fields stored at prot_buf->protocol_fields
++ * and registers a new function (using the field name) inside the
++ * metatable. Each field points to the function 'get_protocol_field'
++ * which acts as a closure taking a pointer to the protocol buffer as
++ * well as the index of the field as upvalues.
++ * 4. The protocol index, serves as numerical identifier of this protocol
++ * buffer or even of the protocol itself. This index is stored as a
++ * global value inside the Lua state as well as inside the Lua table
++ * 'supported_protocols'. Assuming the name of a procotol buffer is
++ * "packet_ip" the following statements are true:
++ *
++ * supported_protocols[protocol_index] == "packet_ip"
++ * packet_ip == protocol_index
++ *
++ * This allows you to get all registered protocols from within Lua. This
++ * is especially usefull for the dynamic protocol buffers where you have
++ * to provide your own "has_protocol"-function, which probably needs the
++ * information on which protocols it is able to contain.
++ */
++void register_protbuf(lua_State *L, struct protocol_buf * prot_buf, uint32_t protocol_index)
++{
++ int32_t field_index;
++ luaL_Reg *reg = (struct luaL_Reg *)seg_access_functions;
++ struct protocol_field * field = prot_buf->protocol_fields;
++
++ luaL_newmetatable(L, prot_buf->name);
++
++ /* metatable.__index = metatable */
++ lua_pushvalue(L, -1); /* duplicates the metatable */
++ lua_setfield(L, -2, "__index");
++
++ /* pushing default functions */
++ for (; reg->name; reg++) {
++ lua_pushlightuserdata(L, (void *)prot_buf);
++ lua_pushcclosure(L, reg->func, 1);
++ lua_setfield(L, -2, reg->name);
++ }
++
++ /* pushing functions specific to the protocol buffer */
++ for (field_index = 0; field->name; field++, field_index++) {
++ lua_pushlightuserdata(L, (void *)prot_buf); /* upvalue: prot_buf */
++ lua_pushinteger(L, field_index); /* upvalue: index of protocol field */
++ lua_pushcclosure(L, get_protocol_field, 2);
++ lua_setfield(L, -2, field->name);
++ }
++ /* pop the metatable */
++ lua_pop(L, 1);
++
++ /* registering the array-index as the protocol_id*/
++ lua_getglobal(L, "_G");
++ lua_pushinteger(L, protocol_index);
++ lua_setfield(L, -2, prot_buf->name);
++ lua_pop(L, 1); /* pop _G */
++
++ lua_getglobal(L, SUPPORTED_PROTOCOL_TABLE);
++ lua_pushstring(L, prot_buf->name);
++ lua_rawseti(L, -2, protocol_index);
++
++ lua_pop(L, 1); /* pop SUPPORTED_PROTOCOL_TABLE */
++
++ supported_protocols[protocol_index] = prot_buf;
++}
++
++void luaopen_controller(lua_State *L)
++{
++ /* registering a table inside the _G with table[protocol_index] = prot_buf->name */
++ lua_getglobal(L, "_G");
++ lua_newtable(L);
++ lua_setfield(L, -2, SUPPORTED_PROTOCOL_TABLE);
++ lua_pop(L, 1); /* pop _G */
++
++ luaopen_protbuf_raw(L);
++ luaopen_protbuf_eth(L);
++ luaopen_protbuf_ip(L);
++ luaopen_protbuf_icmp(L);
++ luaopen_protbuf_tcp(L);
++ luaopen_protbuf_tcp_options(L);
++ luaopen_protbuf_udp(L);
++ luaopen_protbuf_tftp(L);
++ luaopen_protbuf_dynamic(L);
++ /* should follow all other static buffers */
++#if defined(__KERNEL__)
++ luaopen_nflib(L);
++#endif
++
++ luaopen_bytearraylib(L);
++}
++
++
++
++
+--- /dev/null
++++ b/extensions/LUA/controller.h
+@@ -0,0 +1,264 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#ifndef CONTROLLER_H_
++#define CONTROLLER_H_
++
++#include "stdlib.h" /* wrapper */
++#include "string.h" /* wrapper */
++#include "lua.h"
++#include "lualib.h"
++#include "lauxlib.h"
++
++#if defined(__KERNEL__)
++#include <linux/skbuff.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#endif
++
++
++/* to compile the stuff in userspace (for testing)*/
++#if !defined(__KERNEL__)
++#include <stdint.h>
++#define pr_debug printf;
++
++#define kmalloc(size, type) malloc(size)
++#define kfree(ptr) free(ptr)
++
++#endif
++
++
++/**********************************************************************/
++/* nf Lua configuration */
++/**********************************************************************/
++#define MAX_NR_OF_PROTOCOLS 16
++#define SUPPORTED_PROTOCOL_TABLE "supported_protocols"
++
++#define MAX_NR_OF_FIELDS_IN_DYN_PROT_BUF 32
++
++
++/**********************************************************************/
++/* Static Protocol Buffer configuration */
++/**********************************************************************/
++
++/* the definitions of the stringified expression of the prot_bufs...
++ * make sure all static prot_bufs are listed and are unique */
++#define LUA_PACKET_SEG_RAW "packet_raw"
++#define LUA_PACKET_SEG_ETH "packet_eth"
++#define LUA_PACKET_SEG_ICMP "packet_icmp"
++#define LUA_PACKET_SEG_IP "packet_ip"
++#define LUA_PACKET_SEG_TCP "packet_tcp"
++#define LUA_PACKET_SEG_TCP_OPT "packet_tcp_opt"
++#define LUA_PACKET_SEG_UDP "packet_udp"
++#define LUA_PACKET_SEG_TFTP "packet_tftp"
++
++/* the enum holding all static prot_bufs... make sure it contains all
++ * static prot_bufs */
++enum PROT_BUF {
++ PACKET_RAW,
++ PACKET_ETH,
++ PACKET_IP,
++ PACKET_ICMP,
++ PACKET_TCP,
++ PACKET_TCP_OPTIONS,
++ PACKET_UDP,
++ PACKET_TFTP,
++ PACKET_DYNAMIC,
++ PACKET_SENTINEL
++};
++
++/* the luaopen-function of the prot_bufs... make sure it is called
++ * inside luaopen_controller */
++void luaopen_protbuf_raw(lua_State *L);
++void luaopen_protbuf_eth(lua_State *L);
++void luaopen_protbuf_ip(lua_State *L);
++void luaopen_protbuf_icmp(lua_State *L);
++void luaopen_protbuf_tcp(lua_State *L);
++void luaopen_protbuf_tcp_options(lua_State *L);
++void luaopen_protbuf_udp(lua_State *L);
++void luaopen_protbuf_tftp(lua_State *L);
++void luaopen_protbuf_dynamic(lua_State *L);
++
++/**********************************************************************/
++/* field changes */
++/**********************************************************************/
++struct field_changes {
++ int ref_count;
++ int *field_length_changes;
++ int *field_offset_changes;
++};
++
++/**********************************************************************/
++/* lua packet segment */
++/* ------------------ */
++/* The struct lua_packet_segment is the integral part of a Lua packet.*/
++/* At the very beginning, when a new packet arrives in `lua_tg`_ such */
++/* a struct is initialized. The field start then points to the lowest */
++/* available header inside the sk_buff structure. During packet */
++/* processing the start pointer remains the same, only the offset and */
++/* length value change. */
++/**********************************************************************/
++#define checkpacketseg(L, i, seg_type) \
++ (lua_packet_segment *)luaL_checkudata(L, i, seg_type)
++
++typedef struct lua_packet_segment {
++ unsigned int offset;
++ unsigned int length;
++ struct field_changes * changes;
++ unsigned char * start; /* need to be at the end because of the memory alignment */
++} lua_packet_segment;
++
++/**********************************************************************/
++/* protocol field */
++/* -------------- */
++/* This structure is a container for the field definitions used by the*/
++/* protocol buffer. Each protocol field is expressed using this struct*/
++/* Have a look at the protocol buffers to see how the struct gets */
++/* initialized. */
++/* */
++/* name: */
++/* This member expresses the name of the field, ending */
++/* in its own Lua function to access the field. */
++/* offset / length: */
++/* These members do specify the position inside the protocol header */
++/* in bits (not bytes!). */
++/* get / set: */
++/* The get and set functions take a function pointer pointing to the*/
++/* specific getter and setter function for this field. */
++/**********************************************************************/
++struct protocol_field {
++ const char * name;
++ uint32_t offset;
++ uint32_t length;
++ lua_CFunction get;
++ lua_CFunction set;
++};
++#define PROT_FIELD_SENTINEL { NULL, 0, 0, NULL, NULL }
++
++
++/**********************************************************************/
++/* protocol_buf */
++/**********************************************************************/
++/* This structure is a container for all the information needed for a
++ * protocol buffer. It gets initialized in each protocol buffer header
++ * file or for the dynamic protocol buffers on runtime using the
++ * 'register_dynamic_protocol_buffer' function.
++ *
++ * name:
++ * This member is used throughout the system. It is also exported
++ * to Lua as a variable name holding the index of the 'supported_protocols'
++ * array. The name is also used as the name of the generated Lua
++ * metatable, that is why inside the macro checkpacketseg_ it
++ * is always the name of a protocol buffer that is passed as the
++ * second parameter.
++ * payload_field:
++ * This member holds the string of the field responsible for payload
++ * data. The payload field of a protocol has an extra property, since
++ * it can be used to invoke another protocol buffer that is applied to
++ * the payload content.
++ * has_protocol:
++ * This member is used together with the payload_field. Since we must
++ * be sure that the payload content does really contain a protocol
++ * of type X. The function pointed to by has_protocol checks if the
++ * protocol buffer X can be applied on the payload_data.
++ * protocol_fields:
++ * This member points to the array of 'protocol_field' structures
++ * get_field_changes:
++ * This member is optional. It is used to return a pointer to an initialized
++ * field_changes struct. The function is called, whenever the payload field
++ * is requested with a given protocol type. Usually this function will
++ * initialize the field_changes struct depending on the content of the
++ * payload data. e.g.
++ * tcp = ip:data(packet_tcp)
++ * such a request will call the 'get_field_changes' function of the tcp
++ * protocol buffer. This enables, that the tcp options field have the proper
++ * length as well as the tcp data start at the right offset.
++ */
++struct protocol_buf {
++ int is_dynamic;
++ const char * name;
++ char * payload_field;
++ int (*has_protocol)(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment * seg, int type);
++ struct protocol_field * protocol_fields;
++ struct field_changes * (*get_field_changes)(lua_State *L, lua_packet_segment * seg);
++};
++
++/**********************************************************************/
++/* lua byte array library */
++/**********************************************************************/
++#define LUA_BYTE_ARRAY "byte_array"
++#define checkbytearray(L, i) \
++ (lua_packet_segment *)luaL_checkudata(L, i, LUA_BYTE_ARRAY)
++lua_packet_segment * init_byte_array(lua_State *L, unsigned char * start, int length, int do_copy);
++void luaopen_bytearraylib(lua_State *L);
++
++
++/**********************************************************************/
++/* lua netfilter environment library */
++/**********************************************************************/
++#define NETFILTER_LIB "nf"
++#if defined(__KERNEL__)
++ struct lua_env {
++ lua_State *L;
++ /* perhaps more to come here (e.g. a state per CPU) */
++ };
++ #define LUA_ENV "lua_env"
++ #define checkluaenv(L, i) \
++ (struct lua_env *)luaL_checkudata(L, i, LUA_ENV)
++
++ void luaopen_nflib(lua_State *L);
++#endif
++
++void cleanup_dynamic_prot_bufs(void); /* freeing all dynamic prot bufs */
++/**********************************************************************/
++/* lua protbuf helpers */
++/**********************************************************************/
++int get_1_bit_generic(lua_State *L);
++int set_1_bit_generic(lua_State *L);
++int get_lower_4_bit_generic(lua_State *L);
++int set_lower_4_bit_generic(lua_State *L);
++int get_upper_4_bit_generic(lua_State *L);
++int set_upper_4_bit_generic(lua_State *L);
++int get_8_bit_generic(lua_State *L);
++int set_8_bit_generic(lua_State *L);
++int get_16_bit_generic(lua_State *L);
++int set_16_bit_generic(lua_State *L);
++int get_32_bit_generic(lua_State *L);
++int set_32_bit_generic(lua_State *L);
++int set_data_generic(lua_State *L);
++int get_string_generic(lua_State *L);
++int get_byte_generic_str(lua_State *L);
++struct field_changes * get_allocated_field_changes(lua_State *L, int nr_of_fields);
++
++/* only used by the dynamic prot buf subsystem */
++#define MAX_NR_OF_DYN_PROT_BUFS 16
++int field_dynamic_setter(lua_State *L);
++int field_dynamic_getter(lua_State *L);
++int has_protocol_dynamic(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int type);
++struct field_changes * get_field_changes_dynamic(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment * seg);
++
++/**********************************************************************/
++/* lua controller API */
++/**********************************************************************/
++void luaopen_controller(lua_State *L);
++struct protocol_buf * get_protocol_buf(unsigned int protocol_id);
++void get_metatable_from_protocol_type(lua_State *L, int type);
++void register_protbuf(lua_State *L, struct protocol_buf * prot_buf, unsigned int protocol_index);
++
++
++#endif /* CONTROLLER_H_ */
+--- /dev/null
++++ b/extensions/LUA/Kbuild
+@@ -0,0 +1,49 @@
++# -*- Makefile -*-
++
++# Adding debug options
++EXTRA_CFLAGS += -DDEBUG
++
++obj-m += xt_LUA.o
++
++EXTRA_CFLAGS += -I$(src)/prot_buf_new
++xt_LUA-y += xt_LUA_target.o \
++
++xt_LUA-y += nf_lua.o \
++ prot_buf_helpers.o \
++ byte_array.o \
++ controller.o \
++ prot_buf_ethernet.o \
++ prot_buf_icmp.o \
++ prot_buf_ip.o \
++ prot_buf_raw.o \
++ prot_buf_tcp.o \
++ prot_buf_udp.o \
++ prot_buf_tftp.o \
++ prot_buf_dynamic.o \
++
++
++# Adding Lua Support
++EXTRA_CFLAGS += -I$(src)/lua -I$(src)/lua/include
++xt_LUA-y += lua/lapi.o \
++ lua/lbaselib.o \
++ lua/lcode.o \
++ lua/ldebug.o \
++ lua/ldo.o \
++ lua/ldump.o \
++ lua/lfunc.o \
++ lua/lgc.o \
++ lua/llex.o \
++ lua/lmem.o \
++ lua/lobject.o \
++ lua/lopcodes.o \
++ lua/lparser.o \
++ lua/lstate.o \
++ lua/lstring.o \
++ lua/lstrlib.o \
++ lua/ltable.o \
++ lua/ltablib.o \
++ lua/ltm.o \
++ lua/lundump.o \
++ lua/lvm.o \
++ lua/lzio.o \
++ lua/lauxlib.o \
+--- /dev/null
++++ b/extensions/LUA/libxt_LUA.c
+@@ -0,0 +1,191 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <getopt.h>
++#include <stdio.h>
++#include <stdbool.h>
++#include <stdlib.h>
++#include <string.h>
++#include <xtables.h>
++#include <linux/netfilter.h>
++#include <linux/netfilter/x_tables.h>
++#include "xt_LUA.h"
++
++enum {
++ FLAG_SCRIPT = 1 << 0,
++ FLAG_STATE = 1 << 1,
++ FLAG_FUNCTION = 1 << 2,
++};
++
++static const struct option lua_tg_opts[] = {
++ { .name = "script", .has_arg = true, .val = 's' },
++ { .name = "state", .has_arg = true, .val = 'l' },
++ { .name = "function", .has_arg = true, .val = 'f' },
++ { NULL },
++};
++
++
++static void lua_tg_help(void)
++{
++ printf(
++ "LUA target options:\n"
++ " --script SCRIPT Process packet with the Lua script given by SCRIPT\n"
++ " \n"
++ " --state ID Process packet within the Lua state given by ID.\n"
++ " Omitting --state infers the ID 0, which can be\n"
++ " refered to the 'global' state.\n"
++ " \n"
++ " --function FUNCTION Name of the function that processes the Lua packet\n"
++ "\n");
++}
++
++static void
++lua_tg_init(struct xt_entry_target *target)
++{
++ struct xt_lua_tginfo *info = (void *)target->data;
++
++ info->state_id = 0;
++ strncpy(info->function, "process_packet\0", sizeof("process_packet\0"));
++}
++
++static int
++lua_tg_parse(int32_t c, char **argv, int32_t invert, uint32_t *flags,
++ const void *entry, struct xt_entry_target **target)
++{
++ struct xt_lua_tginfo *info = (void *)(*target)->data;
++ char buf[MAX_SCRIPT_SIZE];
++ long script_size;
++ uint32_t state_id;
++ FILE *file;
++
++ switch (c) {
++ case 's':
++ if (*flags & FLAG_SCRIPT)
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: Cannot specify --script more than once");
++
++ if (strlen(optarg) > sizeof(info->filename))
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: Maximum script length is %zu",
++ sizeof(info->filename));
++
++ if (strchr(optarg, '\n'))
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: Newlines not allowed in script name");
++ file = fopen(optarg, "rb");
++ if (file != NULL) {
++ fseek(file, 0, SEEK_END);
++ script_size = ftell(file);
++ if (script_size > MAX_SCRIPT_SIZE)
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: The size of the script is too big");
++
++ fseek(file, 0, SEEK_SET);
++ fread(buf, script_size, 1, file);
++ fclose(file);
++ } else
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: Cannot open script %s", optarg);
++
++ strncpy(info->filename, optarg, sizeof(info->filename));
++ strncpy(info->buf, buf, sizeof(info->buf));
++ info->script_size = script_size;
++
++ *flags |= FLAG_SCRIPT;
++ return true;
++
++ case 'l':
++ if (*flags & FLAG_STATE)
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: Cannot specify --state more than once");
++
++ if (!xtables_strtoui(optarg, NULL, &state_id, 0, 8))
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: Invalid --state %s", optarg);
++
++ info->state_id = state_id;
++ *flags |= FLAG_STATE;
++ return true;
++
++ case 'f':
++ if (*flags & FLAG_FUNCTION)
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: Cannot specify --function more than once");
++ if (strlen(optarg) > sizeof(info->function))
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: Maximum function length is %zu",
++ sizeof(info->function));
++
++ if (strchr(optarg, '\n'))
++ xtables_error(PARAMETER_PROBLEM,
++ "LUA: Newlines not allowed in function name");
++
++ strncpy(info->function, optarg, sizeof(info->function));
++
++ *flags |= FLAG_FUNCTION;
++ return true;
++ }
++
++ return false;
++}
++
++static void
++lua_tg_check(uint32_t flags)
++{
++ if (flags == 0)
++ xtables_error(PARAMETER_PROBLEM, "LUA: --script parameter required");
++}
++
++static void
++lua_tg_print(const void *entry, const struct xt_entry_target *target,
++ int32_t numeric)
++{
++ const struct xt_lua_tginfo *info = (const void *)target->data;
++
++ printf("LUA script: %s ", info->filename);
++}
++
++static void
++lua_tg_save(const void *entry, const struct xt_entry_target *target)
++{
++ const struct xt_lua_tginfo *info = (const void *)target->data;
++
++ printf("--script %s ", info->filename);
++}
++
++static struct xtables_target lua_tg_reg = {
++ .name = "LUA",
++ .version = XTABLES_VERSION,
++ .revision = 0,
++ .family = NFPROTO_UNSPEC,
++ .size = XT_ALIGN(sizeof(struct xt_lua_tginfo)),
++ .userspacesize = XT_ALIGN(sizeof(struct xt_lua_tginfo)),
++ .help = lua_tg_help,
++ .init = lua_tg_init,
++ .parse = lua_tg_parse,
++ .final_check = lua_tg_check,
++ .print = lua_tg_print,
++ .save = lua_tg_save,
++ .extra_opts = lua_tg_opts,
++};
++
++static __attribute__((constructor)) void lua_tg_ldr(void)
++{
++ xtables_register_target(&lua_tg_reg);
++}
++
+--- /dev/null
++++ b/extensions/LUA/libxt_LUA.man
+@@ -0,0 +1 @@
++Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+--- /dev/null
++++ b/extensions/LUA/lua/include/ctype.h
+@@ -0,0 +1,11 @@
++#include <linux/ctype.h>
++#undef isalnum
++#define isalnum(c) (((__ismask(c)&(_U|_L|_D)) != 0) && (c > 0))
++#undef isalpha
++#define isalpha(c) (((__ismask(c)&(_U|_L)) != 0) && (c > 0))
++#undef iscntrl
++#define iscntrl(c) (((__ismask(c)&(_C)) != 0) && (c > 0))
++#undef isdigit
++#define isdigit(c) (((__ismask(c)&(_D)) != 0) && (c > 0))
++#undef isspace
++#define isspace(c) (((__ismask(c)&(_S)) != 0) && (c > 0))
+--- /dev/null
++++ b/extensions/LUA/lua/include/errno.h
+@@ -0,0 +1 @@
++#include <linux/errno.h>
+--- /dev/null
++++ b/extensions/LUA/lua/include/locale.h
+@@ -0,0 +1,5 @@
++struct lconv {
++ char * decimal_point ;
++} ;
++
++#define localeconv() NULL
+--- /dev/null
++++ b/extensions/LUA/lua/include/setjmp.h
+@@ -0,0 +1,26 @@
++/*
++ * arch/um/include/sysdep-i386/archsetjmp.h
++ */
++
++#ifndef _KLIBC_ARCHSETJMP_H
++#define _KLIBC_ARCHSETJMP_H
++
++struct __jmp_buf {
++ unsigned int __ebx;
++ unsigned int __esp;
++ unsigned int __ebp;
++ unsigned int __esi;
++ unsigned int __edi;
++ unsigned int __eip;
++};
++
++typedef struct __jmp_buf jmp_buf[1];
++
++#define JB_IP __eip
++#define JB_SP __esp
++
++int setjmp(jmp_buf);
++void longjmp(jmp_buf, int);
++
++#endif /* _SETJMP_H */
++
+--- /dev/null
++++ b/extensions/LUA/lua/include/stdio.h
+@@ -0,0 +1 @@
++#include <linux/kernel.h>
+--- /dev/null
++++ b/extensions/LUA/lua/include/stdlib.h
+@@ -0,0 +1,7 @@
++#include <linux/kernel.h>
++
++#define exit(E) return
++#define strtoul simple_strtoul
++#define strcoll strcmp
++
++#define CHAR_BIT 8
+--- /dev/null
++++ b/extensions/LUA/lua/include/string.h
+@@ -0,0 +1 @@
++#include <linux/string.h>
+--- /dev/null
++++ b/extensions/LUA/lua/lapi.c
+@@ -0,0 +1,1086 @@
++/*
++** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
++** Lua API
++** See Copyright Notice in lua.h
++*/
++
++#include <stdarg.h>
++#include <math.h>
++#include <assert.h>
++#include <string.h>
++
++#define lapi_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "lapi.h"
++#include "ldebug.h"
++#include "ldo.h"
++#include "lfunc.h"
++#include "lgc.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "ltable.h"
++#include "ltm.h"
++#include "lundump.h"
++#include "lvm.h"
++
++
++
++const char lua_ident[] =
++ "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
++ "$Authors: " LUA_AUTHORS " $\n"
++ "$URL: www.lua.org $\n";
++
++
++
++#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
++
++#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)
++
++#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
++
++
++
++static TValue *index2adr (lua_State *L, int idx) {
++ if (idx > 0) {
++ TValue *o = L->base + (idx - 1);
++ api_check(L, idx <= L->ci->top - L->base);
++ if (o >= L->top) return cast(TValue *, luaO_nilobject);
++ else return o;
++ }
++ else if (idx > LUA_REGISTRYINDEX) {
++ api_check(L, idx != 0 && -idx <= L->top - L->base);
++ return L->top + idx;
++ }
++ else switch (idx) { /* pseudo-indices */
++ case LUA_REGISTRYINDEX: return registry(L);
++ case LUA_ENVIRONINDEX: {
++ Closure *func = curr_func(L);
++ sethvalue(L, &L->env, func->c.env);
++ return &L->env;
++ }
++ case LUA_GLOBALSINDEX: return gt(L);
++ default: {
++ Closure *func = curr_func(L);
++ idx = LUA_GLOBALSINDEX - idx;
++ return (idx <= func->c.nupvalues)
++ ? &func->c.upvalue[idx-1]
++ : cast(TValue *, luaO_nilobject);
++ }
++ }
++}
++
++
++static Table *getcurrenv (lua_State *L) {
++ if (L->ci == L->base_ci) /* no enclosing function? */
++ return hvalue(gt(L)); /* use global table as environment */
++ else {
++ Closure *func = curr_func(L);
++ return func->c.env;
++ }
++}
++
++
++void luaA_pushobject (lua_State *L, const TValue *o) {
++ setobj2s(L, L->top, o);
++ api_incr_top(L);
++}
++
++
++LUA_API int lua_checkstack (lua_State *L, int size) {
++ int res = 1;
++ lua_lock(L);
++ if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
++ res = 0; /* stack overflow */
++ else if (size > 0) {
++ luaD_checkstack(L, size);
++ if (L->ci->top < L->top + size)
++ L->ci->top = L->top + size;
++ }
++ lua_unlock(L);
++ return res;
++}
++
++
++LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
++ int i;
++ if (from == to) return;
++ lua_lock(to);
++ api_checknelems(from, n);
++ api_check(from, G(from) == G(to));
++ api_check(from, to->ci->top - to->top >= n);
++ from->top -= n;
++ for (i = 0; i < n; i++) {
++ setobj2s(to, to->top++, from->top + i);
++ }
++ lua_unlock(to);
++}
++
++
++LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
++ to->nCcalls = from->nCcalls;
++}
++
++
++LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
++ lua_CFunction old;
++ lua_lock(L);
++ old = G(L)->panic;
++ G(L)->panic = panicf;
++ lua_unlock(L);
++ return old;
++}
++
++
++LUA_API lua_State *lua_newthread (lua_State *L) {
++ lua_State *L1;
++ lua_lock(L);
++ luaC_checkGC(L);
++ L1 = luaE_newthread(L);
++ setthvalue(L, L->top, L1);
++ api_incr_top(L);
++ lua_unlock(L);
++ luai_userstatethread(L, L1);
++ return L1;
++}
++
++
++
++/*
++** basic stack manipulation
++*/
++
++
++LUA_API int lua_gettop (lua_State *L) {
++ return cast_int(L->top - L->base);
++}
++
++
++LUA_API void lua_settop (lua_State *L, int idx) {
++ lua_lock(L);
++ if (idx >= 0) {
++ api_check(L, idx <= L->stack_last - L->base);
++ while (L->top < L->base + idx)
++ setnilvalue(L->top++);
++ L->top = L->base + idx;
++ }
++ else {
++ api_check(L, -(idx+1) <= (L->top - L->base));
++ L->top += idx+1; /* `subtract' index (index is negative) */
++ }
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_remove (lua_State *L, int idx) {
++ StkId p;
++ lua_lock(L);
++ p = index2adr(L, idx);
++ api_checkvalidindex(L, p);
++ while (++p < L->top) setobjs2s(L, p-1, p);
++ L->top--;
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_insert (lua_State *L, int idx) {
++ StkId p;
++ StkId q;
++ lua_lock(L);
++ p = index2adr(L, idx);
++ api_checkvalidindex(L, p);
++ for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
++ setobjs2s(L, p, L->top);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_replace (lua_State *L, int idx) {
++ StkId o;
++ lua_lock(L);
++ /* explicit test for incompatible code */
++ if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
++ luaG_runerror(L, "no calling environment");
++ api_checknelems(L, 1);
++ o = index2adr(L, idx);
++ api_checkvalidindex(L, o);
++ if (idx == LUA_ENVIRONINDEX) {
++ Closure *func = curr_func(L);
++ api_check(L, ttistable(L->top - 1));
++ func->c.env = hvalue(L->top - 1);
++ luaC_barrier(L, func, L->top - 1);
++ }
++ else {
++ setobj(L, o, L->top - 1);
++ if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
++ luaC_barrier(L, curr_func(L), L->top - 1);
++ }
++ L->top--;
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_pushvalue (lua_State *L, int idx) {
++ lua_lock(L);
++ setobj2s(L, L->top, index2adr(L, idx));
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++
++/*
++** access functions (stack -> C)
++*/
++
++
++LUA_API int lua_type (lua_State *L, int idx) {
++ StkId o = index2adr(L, idx);
++ return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
++}
++
++
++LUA_API const char *lua_typename (lua_State *L, int t) {
++ UNUSED(L);
++ return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
++}
++
++
++LUA_API int lua_iscfunction (lua_State *L, int idx) {
++ StkId o = index2adr(L, idx);
++ return iscfunction(o);
++}
++
++
++LUA_API int lua_isnumber (lua_State *L, int idx) {
++ TValue n;
++ const TValue *o = index2adr(L, idx);
++ return tonumber(o, &n);
++}
++
++
++LUA_API int lua_isstring (lua_State *L, int idx) {
++ int t = lua_type(L, idx);
++ return (t == LUA_TSTRING || t == LUA_TNUMBER);
++}
++
++
++LUA_API int lua_isuserdata (lua_State *L, int idx) {
++ const TValue *o = index2adr(L, idx);
++ return (ttisuserdata(o) || ttislightuserdata(o));
++}
++
++
++LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
++ StkId o1 = index2adr(L, index1);
++ StkId o2 = index2adr(L, index2);
++ return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
++ : luaO_rawequalObj(o1, o2);
++}
++
++
++LUA_API int lua_equal (lua_State *L, int index1, int index2) {
++ StkId o1, o2;
++ int i;
++ lua_lock(L); /* may call tag method */
++ o1 = index2adr(L, index1);
++ o2 = index2adr(L, index2);
++ i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
++ lua_unlock(L);
++ return i;
++}
++
++
++LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
++ StkId o1, o2;
++ int i;
++ lua_lock(L); /* may call tag method */
++ o1 = index2adr(L, index1);
++ o2 = index2adr(L, index2);
++ i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
++ : luaV_lessthan(L, o1, o2);
++ lua_unlock(L);
++ return i;
++}
++
++
++
++LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
++ TValue n;
++ const TValue *o = index2adr(L, idx);
++ if (tonumber(o, &n))
++ return nvalue(o);
++ else
++ return 0;
++}
++
++
++LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
++ TValue n;
++ const TValue *o = index2adr(L, idx);
++ if (tonumber(o, &n)) {
++ lua_Integer res;
++ lua_Number num = nvalue(o);
++ lua_number2integer(res, num);
++ return res;
++ }
++ else
++ return 0;
++}
++
++
++LUA_API int lua_toboolean (lua_State *L, int idx) {
++ const TValue *o = index2adr(L, idx);
++ return !l_isfalse(o);
++}
++
++
++LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
++ StkId o = index2adr(L, idx);
++ if (!ttisstring(o)) {
++ lua_lock(L); /* `luaV_tostring' may create a new string */
++ if (!luaV_tostring(L, o)) { /* conversion failed? */
++ if (len != NULL) *len = 0;
++ lua_unlock(L);
++ return NULL;
++ }
++ luaC_checkGC(L);
++ o = index2adr(L, idx); /* previous call may reallocate the stack */
++ lua_unlock(L);
++ }
++ if (len != NULL) *len = tsvalue(o)->len;
++ return svalue(o);
++}
++
++
++LUA_API size_t lua_objlen (lua_State *L, int idx) {
++ StkId o = index2adr(L, idx);
++ switch (ttype(o)) {
++ case LUA_TSTRING: return tsvalue(o)->len;
++ case LUA_TUSERDATA: return uvalue(o)->len;
++ case LUA_TTABLE: return luaH_getn(hvalue(o));
++ case LUA_TNUMBER: {
++ size_t l;
++ lua_lock(L); /* `luaV_tostring' may create a new string */
++ l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
++ lua_unlock(L);
++ return l;
++ }
++ default: return 0;
++ }
++}
++
++
++LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
++ StkId o = index2adr(L, idx);
++ return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
++}
++
++
++LUA_API void *lua_touserdata (lua_State *L, int idx) {
++ StkId o = index2adr(L, idx);
++ switch (ttype(o)) {
++ case LUA_TUSERDATA: return (rawuvalue(o) + 1);
++ case LUA_TLIGHTUSERDATA: return pvalue(o);
++ default: return NULL;
++ }
++}
++
++
++LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
++ StkId o = index2adr(L, idx);
++ return (!ttisthread(o)) ? NULL : thvalue(o);
++}
++
++
++LUA_API const void *lua_topointer (lua_State *L, int idx) {
++ StkId o = index2adr(L, idx);
++ switch (ttype(o)) {
++ case LUA_TTABLE: return hvalue(o);
++ case LUA_TFUNCTION: return clvalue(o);
++ case LUA_TTHREAD: return thvalue(o);
++ case LUA_TUSERDATA:
++ case LUA_TLIGHTUSERDATA:
++ return lua_touserdata(L, idx);
++ default: return NULL;
++ }
++}
++
++
++
++/*
++** push functions (C -> stack)
++*/
++
++
++LUA_API void lua_pushnil (lua_State *L) {
++ lua_lock(L);
++ setnilvalue(L->top);
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
++ lua_lock(L);
++ setnvalue(L->top, n);
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
++ lua_lock(L);
++ setnvalue(L->top, cast_num(n));
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
++ lua_lock(L);
++ luaC_checkGC(L);
++ setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_pushstring (lua_State *L, const char *s) {
++ if (s == NULL)
++ lua_pushnil(L);
++ else
++ lua_pushlstring(L, s, strlen(s));
++}
++
++
++LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
++ va_list argp) {
++ const char *ret;
++ lua_lock(L);
++ luaC_checkGC(L);
++ ret = luaO_pushvfstring(L, fmt, argp);
++ lua_unlock(L);
++ return ret;
++}
++
++
++LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
++ const char *ret;
++ va_list argp;
++ lua_lock(L);
++ luaC_checkGC(L);
++ va_start(argp, fmt);
++ ret = luaO_pushvfstring(L, fmt, argp);
++ va_end(argp);
++ lua_unlock(L);
++ return ret;
++}
++
++
++LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
++ Closure *cl;
++ lua_lock(L);
++ luaC_checkGC(L);
++ api_checknelems(L, n);
++ cl = luaF_newCclosure(L, n, getcurrenv(L));
++ cl->c.f = fn;
++ L->top -= n;
++ while (n--)
++ setobj2n(L, &cl->c.upvalue[n], L->top+n);
++ setclvalue(L, L->top, cl);
++ lua_assert(iswhite(obj2gco(cl)));
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_pushboolean (lua_State *L, int b) {
++ lua_lock(L);
++ setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
++ lua_lock(L);
++ setpvalue(L->top, p);
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API int lua_pushthread (lua_State *L) {
++ lua_lock(L);
++ setthvalue(L, L->top, L);
++ api_incr_top(L);
++ lua_unlock(L);
++ return (G(L)->mainthread == L);
++}
++
++
++
++/*
++** get functions (Lua -> stack)
++*/
++
++
++LUA_API void lua_gettable (lua_State *L, int idx) {
++ StkId t;
++ lua_lock(L);
++ t = index2adr(L, idx);
++ api_checkvalidindex(L, t);
++ luaV_gettable(L, t, L->top - 1, L->top - 1);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
++ StkId t;
++ TValue key;
++ lua_lock(L);
++ t = index2adr(L, idx);
++ api_checkvalidindex(L, t);
++ setsvalue(L, &key, luaS_new(L, k));
++ luaV_gettable(L, t, &key, L->top);
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_rawget (lua_State *L, int idx) {
++ StkId t;
++ lua_lock(L);
++ t = index2adr(L, idx);
++ api_check(L, ttistable(t));
++ setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
++ StkId o;
++ lua_lock(L);
++ o = index2adr(L, idx);
++ api_check(L, ttistable(o));
++ setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
++ lua_lock(L);
++ luaC_checkGC(L);
++ sethvalue(L, L->top, luaH_new(L, narray, nrec));
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++LUA_API int lua_getmetatable (lua_State *L, int objindex) {
++ const TValue *obj;
++ Table *mt = NULL;
++ int res;
++ lua_lock(L);
++ obj = index2adr(L, objindex);
++ switch (ttype(obj)) {
++ case LUA_TTABLE:
++ mt = hvalue(obj)->metatable;
++ break;
++ case LUA_TUSERDATA:
++ mt = uvalue(obj)->metatable;
++ break;
++ default:
++ mt = G(L)->mt[ttype(obj)];
++ break;
++ }
++ if (mt == NULL)
++ res = 0;
++ else {
++ sethvalue(L, L->top, mt);
++ api_incr_top(L);
++ res = 1;
++ }
++ lua_unlock(L);
++ return res;
++}
++
++
++LUA_API void lua_getfenv (lua_State *L, int idx) {
++ StkId o;
++ lua_lock(L);
++ o = index2adr(L, idx);
++ api_checkvalidindex(L, o);
++ switch (ttype(o)) {
++ case LUA_TFUNCTION:
++ sethvalue(L, L->top, clvalue(o)->c.env);
++ break;
++ case LUA_TUSERDATA:
++ sethvalue(L, L->top, uvalue(o)->env);
++ break;
++ case LUA_TTHREAD:
++ setobj2s(L, L->top, gt(thvalue(o)));
++ break;
++ default:
++ setnilvalue(L->top);
++ break;
++ }
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++/*
++** set functions (stack -> Lua)
++*/
++
++
++LUA_API void lua_settable (lua_State *L, int idx) {
++ StkId t;
++ lua_lock(L);
++ api_checknelems(L, 2);
++ t = index2adr(L, idx);
++ api_checkvalidindex(L, t);
++ luaV_settable(L, t, L->top - 2, L->top - 1);
++ L->top -= 2; /* pop index and value */
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
++ StkId t;
++ TValue key;
++ lua_lock(L);
++ api_checknelems(L, 1);
++ t = index2adr(L, idx);
++ api_checkvalidindex(L, t);
++ setsvalue(L, &key, luaS_new(L, k));
++ luaV_settable(L, t, &key, L->top - 1);
++ L->top--; /* pop value */
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_rawset (lua_State *L, int idx) {
++ StkId t;
++ lua_lock(L);
++ api_checknelems(L, 2);
++ t = index2adr(L, idx);
++ api_check(L, ttistable(t));
++ setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
++ luaC_barriert(L, hvalue(t), L->top-1);
++ L->top -= 2;
++ lua_unlock(L);
++}
++
++
++LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
++ StkId o;
++ lua_lock(L);
++ api_checknelems(L, 1);
++ o = index2adr(L, idx);
++ api_check(L, ttistable(o));
++ setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
++ luaC_barriert(L, hvalue(o), L->top-1);
++ L->top--;
++ lua_unlock(L);
++}
++
++
++LUA_API int lua_setmetatable (lua_State *L, int objindex) {
++ TValue *obj;
++ Table *mt;
++ lua_lock(L);
++ api_checknelems(L, 1);
++ obj = index2adr(L, objindex);
++ api_checkvalidindex(L, obj);
++ if (ttisnil(L->top - 1))
++ mt = NULL;
++ else {
++ api_check(L, ttistable(L->top - 1));
++ mt = hvalue(L->top - 1);
++ }
++ switch (ttype(obj)) {
++ case LUA_TTABLE: {
++ hvalue(obj)->metatable = mt;
++ if (mt)
++ luaC_objbarriert(L, hvalue(obj), mt);
++ break;
++ }
++ case LUA_TUSERDATA: {
++ uvalue(obj)->metatable = mt;
++ if (mt)
++ luaC_objbarrier(L, rawuvalue(obj), mt);
++ break;
++ }
++ default: {
++ G(L)->mt[ttype(obj)] = mt;
++ break;
++ }
++ }
++ L->top--;
++ lua_unlock(L);
++ return 1;
++}
++
++
++LUA_API int lua_setfenv (lua_State *L, int idx) {
++ StkId o;
++ int res = 1;
++ lua_lock(L);
++ api_checknelems(L, 1);
++ o = index2adr(L, idx);
++ api_checkvalidindex(L, o);
++ api_check(L, ttistable(L->top - 1));
++ switch (ttype(o)) {
++ case LUA_TFUNCTION:
++ clvalue(o)->c.env = hvalue(L->top - 1);
++ break;
++ case LUA_TUSERDATA:
++ uvalue(o)->env = hvalue(L->top - 1);
++ break;
++ case LUA_TTHREAD:
++ sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
++ break;
++ default:
++ res = 0;
++ break;
++ }
++ if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
++ L->top--;
++ lua_unlock(L);
++ return res;
++}
++
++
++/*
++** `load' and `call' functions (run Lua code)
++*/
++
++
++#define adjustresults(L,nres) \
++ { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
++
++
++#define checkresults(L,na,nr) \
++ api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
++
++
++LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
++ StkId func;
++ lua_lock(L);
++ api_checknelems(L, nargs+1);
++ checkresults(L, nargs, nresults);
++ func = L->top - (nargs+1);
++ luaD_call(L, func, nresults);
++ adjustresults(L, nresults);
++ lua_unlock(L);
++}
++
++
++
++/*
++** Execute a protected call.
++*/
++struct CallS { /* data to `f_call' */
++ StkId func;
++ int nresults;
++};
++
++
++static void f_call (lua_State *L, void *ud) {
++ struct CallS *c = cast(struct CallS *, ud);
++ luaD_call(L, c->func, c->nresults);
++}
++
++
++
++LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
++ struct CallS c;
++ int status;
++ ptrdiff_t func;
++ lua_lock(L);
++ api_checknelems(L, nargs+1);
++ checkresults(L, nargs, nresults);
++ if (errfunc == 0)
++ func = 0;
++ else {
++ StkId o = index2adr(L, errfunc);
++ api_checkvalidindex(L, o);
++ func = savestack(L, o);
++ }
++ c.func = L->top - (nargs+1); /* function to be called */
++ c.nresults = nresults;
++ status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
++ adjustresults(L, nresults);
++ lua_unlock(L);
++ return status;
++}
++
++
++/*
++** Execute a protected C call.
++*/
++struct CCallS { /* data to `f_Ccall' */
++ lua_CFunction func;
++ void *ud;
++};
++
++
++static void f_Ccall (lua_State *L, void *ud) {
++ struct CCallS *c = cast(struct CCallS *, ud);
++ Closure *cl;
++ cl = luaF_newCclosure(L, 0, getcurrenv(L));
++ cl->c.f = c->func;
++ setclvalue(L, L->top, cl); /* push function */
++ api_incr_top(L);
++ setpvalue(L->top, c->ud); /* push only argument */
++ api_incr_top(L);
++ luaD_call(L, L->top - 2, 0);
++}
++
++
++LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
++ struct CCallS c;
++ int status;
++ lua_lock(L);
++ c.func = func;
++ c.ud = ud;
++ status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
++ lua_unlock(L);
++ return status;
++}
++
++
++LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
++ const char *chunkname) {
++ ZIO z;
++ int status;
++ lua_lock(L);
++ if (!chunkname) chunkname = "?";
++ luaZ_init(L, &z, reader, data);
++ status = luaD_protectedparser(L, &z, chunkname);
++ lua_unlock(L);
++ return status;
++}
++
++
++LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
++ int status;
++ TValue *o;
++ lua_lock(L);
++ api_checknelems(L, 1);
++ o = L->top - 1;
++ if (isLfunction(o))
++ status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
++ else
++ status = 1;
++ lua_unlock(L);
++ return status;
++}
++
++
++LUA_API int lua_status (lua_State *L) {
++ return L->status;
++}
++
++
++/*
++** Garbage-collection function
++*/
++
++LUA_API int lua_gc (lua_State *L, int what, int data) {
++ int res = 0;
++ global_State *g;
++ lua_lock(L);
++ g = G(L);
++ switch (what) {
++ case LUA_GCSTOP: {
++ g->GCthreshold = MAX_LUMEM;
++ break;
++ }
++ case LUA_GCRESTART: {
++ g->GCthreshold = g->totalbytes;
++ break;
++ }
++ case LUA_GCCOLLECT: {
++ luaC_fullgc(L);
++ break;
++ }
++ case LUA_GCCOUNT: {
++ /* GC values are expressed in Kbytes: #bytes/2^10 */
++ res = cast_int(g->totalbytes >> 10);
++ break;
++ }
++ case LUA_GCCOUNTB: {
++ res = cast_int(g->totalbytes & 0x3ff);
++ break;
++ }
++ case LUA_GCSTEP: {
++ lu_mem a = (cast(lu_mem, data) << 10);
++ if (a <= g->totalbytes)
++ g->GCthreshold = g->totalbytes - a;
++ else
++ g->GCthreshold = 0;
++ while (g->GCthreshold <= g->totalbytes) {
++ luaC_step(L);
++ if (g->gcstate == GCSpause) { /* end of cycle? */
++ res = 1; /* signal it */
++ break;
++ }
++ }
++ break;
++ }
++ case LUA_GCSETPAUSE: {
++ res = g->gcpause;
++ g->gcpause = data;
++ break;
++ }
++ case LUA_GCSETSTEPMUL: {
++ res = g->gcstepmul;
++ g->gcstepmul = data;
++ break;
++ }
++ default: res = -1; /* invalid option */
++ }
++ lua_unlock(L);
++ return res;
++}
++
++
++
++/*
++** miscellaneous functions
++*/
++
++
++LUA_API int lua_error (lua_State *L) {
++ lua_lock(L);
++ api_checknelems(L, 1);
++ luaG_errormsg(L);
++ lua_unlock(L);
++ return 0; /* to avoid warnings */
++}
++
++
++LUA_API int lua_next (lua_State *L, int idx) {
++ StkId t;
++ int more;
++ lua_lock(L);
++ t = index2adr(L, idx);
++ api_check(L, ttistable(t));
++ more = luaH_next(L, hvalue(t), L->top - 1);
++ if (more) {
++ api_incr_top(L);
++ }
++ else /* no more elements */
++ L->top -= 1; /* remove key */
++ lua_unlock(L);
++ return more;
++}
++
++
++LUA_API void lua_concat (lua_State *L, int n) {
++ lua_lock(L);
++ api_checknelems(L, n);
++ if (n >= 2) {
++ luaC_checkGC(L);
++ luaV_concat(L, n, cast_int(L->top - L->base) - 1);
++ L->top -= (n-1);
++ }
++ else if (n == 0) { /* push empty string */
++ setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
++ api_incr_top(L);
++ }
++ /* else n == 1; nothing to do */
++ lua_unlock(L);
++}
++
++
++LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
++ lua_Alloc f;
++ lua_lock(L);
++ if (ud) *ud = G(L)->ud;
++ f = G(L)->frealloc;
++ lua_unlock(L);
++ return f;
++}
++
++
++LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
++ lua_lock(L);
++ G(L)->ud = ud;
++ G(L)->frealloc = f;
++ lua_unlock(L);
++}
++
++
++LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
++ Udata *u;
++ lua_lock(L);
++ luaC_checkGC(L);
++ u = luaS_newudata(L, size, getcurrenv(L));
++ setuvalue(L, L->top, u);
++ api_incr_top(L);
++ lua_unlock(L);
++ return u + 1;
++}
++
++
++
++
++static const char *aux_upvalue (StkId fi, int n, TValue **val) {
++ Closure *f;
++ if (!ttisfunction(fi)) return NULL;
++ f = clvalue(fi);
++ if (f->c.isC) {
++ if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
++ *val = &f->c.upvalue[n-1];
++ return "";
++ }
++ else {
++ Proto *p = f->l.p;
++ if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
++ *val = f->l.upvals[n-1]->v;
++ return getstr(p->upvalues[n-1]);
++ }
++}
++
++
++LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
++ const char *name;
++ TValue *val;
++ lua_lock(L);
++ name = aux_upvalue(index2adr(L, funcindex), n, &val);
++ if (name) {
++ setobj2s(L, L->top, val);
++ api_incr_top(L);
++ }
++ lua_unlock(L);
++ return name;
++}
++
++
++LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
++ const char *name;
++ TValue *val;
++ StkId fi;
++ lua_lock(L);
++ fi = index2adr(L, funcindex);
++ api_checknelems(L, 1);
++ name = aux_upvalue(fi, n, &val);
++ if (name) {
++ L->top--;
++ setobj(L, val, L->top);
++ luaC_barrier(L, clvalue(fi), L->top);
++ }
++ lua_unlock(L);
++ return name;
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/lapi.h
+@@ -0,0 +1,16 @@
++/*
++** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $
++** Auxiliary functions from Lua API
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lapi_h
++#define lapi_h
++
++
++#include "lobject.h"
++
++
++LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lauxlib.c
+@@ -0,0 +1,674 @@
++/*
++** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $
++** Auxiliary functions for building Lua libraries
++** See Copyright Notice in lua.h
++*/
++
++#include <stdarg.h>
++
++#if !defined(__KERNEL__)
++#include <ctype.h>
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#else
++#include <linux/ctype.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#endif
++
++/* This file uses only the official API of Lua.
++** Any function declared here could be written as an application function.
++*/
++
++#define lauxlib_c
++#define LUA_LIB
++
++#include "lua.h"
++
++#include "lauxlib.h"
++
++
++#define FREELIST_REF 0 /* free list of references */
++
++
++/* convert a stack index to positive */
++#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
++ lua_gettop(L) + (i) + 1)
++
++
++/*
++** {======================================================
++** Error-report functions
++** =======================================================
++*/
++
++
++LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
++ lua_Debug ar;
++ if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
++ return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
++ lua_getinfo(L, "n", &ar);
++ if (strcmp(ar.namewhat, "method") == 0) {
++ narg--; /* do not count `self' */
++ if (narg == 0) /* error is in the self argument itself? */
++ return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
++ ar.name, extramsg);
++ }
++ if (ar.name == NULL)
++ ar.name = "?";
++ return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
++ narg, ar.name, extramsg);
++}
++
++
++LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
++ const char *msg = lua_pushfstring(L, "%s expected, got %s",
++ tname, luaL_typename(L, narg));
++ return luaL_argerror(L, narg, msg);
++}
++
++
++static void tag_error (lua_State *L, int narg, int tag) {
++ luaL_typerror(L, narg, lua_typename(L, tag));
++}
++
++
++LUALIB_API void luaL_where (lua_State *L, int level) {
++ lua_Debug ar;
++ if (lua_getstack(L, level, &ar)) { /* check function at level */
++ lua_getinfo(L, "Sl", &ar); /* get info about it */
++ if (ar.currentline > 0) { /* is there info? */
++ lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
++ return;
++ }
++ }
++ lua_pushliteral(L, ""); /* else, no information available... */
++}
++
++
++LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
++ va_list argp;
++ va_start(argp, fmt);
++ luaL_where(L, 1);
++ lua_pushvfstring(L, fmt, argp);
++ va_end(argp);
++ lua_concat(L, 2);
++ return lua_error(L);
++}
++
++/* }====================================================== */
++
++
++LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
++ const char *const lst[]) {
++ const char *name = (def) ? luaL_optstring(L, narg, def) :
++ luaL_checkstring(L, narg);
++ int i;
++ for (i=0; lst[i]; i++)
++ if (strcmp(lst[i], name) == 0)
++ return i;
++ return luaL_argerror(L, narg,
++ lua_pushfstring(L, "invalid option " LUA_QS, name));
++}
++
++
++LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
++ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
++ if (!lua_isnil(L, -1)) /* name already in use? */
++ return 0; /* leave previous value on top, but return 0 */
++ lua_pop(L, 1);
++ lua_newtable(L); /* create metatable */
++ lua_pushvalue(L, -1);
++ lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
++ return 1;
++}
++
++
++LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
++ void *p = lua_touserdata(L, ud);
++ if (p != NULL) { /* value is a userdata? */
++ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
++ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
++ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
++ lua_pop(L, 2); /* remove both metatables */
++ return p;
++ }
++ }
++ }
++ luaL_typerror(L, ud, tname); /* else error */
++ return NULL; /* to avoid warnings */
++}
++
++
++LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
++ if (!lua_checkstack(L, space))
++ luaL_error(L, "stack overflow (%s)", mes);
++}
++
++
++LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
++ if (lua_type(L, narg) != t)
++ tag_error(L, narg, t);
++}
++
++
++LUALIB_API void luaL_checkany (lua_State *L, int narg) {
++ if (lua_type(L, narg) == LUA_TNONE)
++ luaL_argerror(L, narg, "value expected");
++}
++
++
++LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
++ const char *s = lua_tolstring(L, narg, len);
++ if (!s) tag_error(L, narg, LUA_TSTRING);
++ return s;
++}
++
++
++LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
++ const char *def, size_t *len) {
++ if (lua_isnoneornil(L, narg)) {
++ if (len)
++ *len = (def ? strlen(def) : 0);
++ return def;
++ }
++ else return luaL_checklstring(L, narg, len);
++}
++
++
++LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
++ lua_Number d = lua_tonumber(L, narg);
++ if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
++ tag_error(L, narg, LUA_TNUMBER);
++ return d;
++}
++
++
++LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
++ return luaL_opt(L, luaL_checknumber, narg, def);
++}
++
++
++LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
++ lua_Integer d = lua_tointeger(L, narg);
++ if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
++ tag_error(L, narg, LUA_TNUMBER);
++ return d;
++}
++
++
++LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
++ lua_Integer def) {
++ return luaL_opt(L, luaL_checkinteger, narg, def);
++}
++
++
++LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
++ if (!lua_getmetatable(L, obj)) /* no metatable? */
++ return 0;
++ lua_pushstring(L, event);
++ lua_rawget(L, -2);
++ if (lua_isnil(L, -1)) {
++ lua_pop(L, 2); /* remove metatable and metafield */
++ return 0;
++ }
++ else {
++ lua_remove(L, -2); /* remove only metatable */
++ return 1;
++ }
++}
++
++
++LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
++ obj = abs_index(L, obj);
++ if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
++ return 0;
++ lua_pushvalue(L, obj);
++ lua_call(L, 1, 1);
++ return 1;
++}
++
++
++LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
++ const luaL_Reg *l) {
++ luaI_openlib(L, libname, l, 0);
++}
++
++
++static int libsize (const luaL_Reg *l) {
++ int size = 0;
++ for (; l->name; l++) size++;
++ return size;
++}
++
++
++LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
++ const luaL_Reg *l, int nup) {
++ if (libname) {
++ int size = libsize(l);
++ /* check whether lib already exists */
++ luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
++ lua_getfield(L, -1, libname); /* get _LOADED[libname] */
++ if (!lua_istable(L, -1)) { /* not found? */
++ lua_pop(L, 1); /* remove previous result */
++ /* try global variable (and create one if it does not exist) */
++ if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
++ luaL_error(L, "name conflict for module " LUA_QS, libname);
++ lua_pushvalue(L, -1);
++ lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
++ }
++ lua_remove(L, -2); /* remove _LOADED table */
++ lua_insert(L, -(nup+1)); /* move library table to below upvalues */
++ }
++ for (; l->name; l++) {
++ int i;
++ for (i=0; i<nup; i++) /* copy upvalues to the top */
++ lua_pushvalue(L, -nup);
++ lua_pushcclosure(L, l->func, nup);
++ lua_setfield(L, -(nup+2), l->name);
++ }
++ lua_pop(L, nup); /* remove upvalues */
++}
++
++
++
++/*
++** {======================================================
++** getn-setn: size for arrays
++** =======================================================
++*/
++
++#if defined(LUA_COMPAT_GETN)
++
++static int checkint (lua_State *L, int topop) {
++ int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
++ lua_pop(L, topop);
++ return n;
++}
++
++
++static void getsizes (lua_State *L) {
++ lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
++ if (lua_isnil(L, -1)) { /* no `size' table? */
++ lua_pop(L, 1); /* remove nil */
++ lua_newtable(L); /* create it */
++ lua_pushvalue(L, -1); /* `size' will be its own metatable */
++ lua_setmetatable(L, -2);
++ lua_pushliteral(L, "kv");
++ lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
++ lua_pushvalue(L, -1);
++ lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
++ }
++}
++
++
++LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
++ t = abs_index(L, t);
++ lua_pushliteral(L, "n");
++ lua_rawget(L, t);
++ if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
++ lua_pushliteral(L, "n"); /* use it */
++ lua_pushinteger(L, n);
++ lua_rawset(L, t);
++ }
++ else { /* use `sizes' */
++ getsizes(L);
++ lua_pushvalue(L, t);
++ lua_pushinteger(L, n);
++ lua_rawset(L, -3); /* sizes[t] = n */
++ lua_pop(L, 1); /* remove `sizes' */
++ }
++}
++
++
++LUALIB_API int luaL_getn (lua_State *L, int t) {
++ int n;
++ t = abs_index(L, t);
++ lua_pushliteral(L, "n"); /* try t.n */
++ lua_rawget(L, t);
++ if ((n = checkint(L, 1)) >= 0) return n;
++ getsizes(L); /* else try sizes[t] */
++ lua_pushvalue(L, t);
++ lua_rawget(L, -2);
++ if ((n = checkint(L, 2)) >= 0) return n;
++ return (int)lua_objlen(L, t);
++}
++
++#endif
++
++/* }====================================================== */
++
++
++
++LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
++ const char *r) {
++ const char *wild;
++ size_t l = strlen(p);
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "luaL_gsub: cannot allocate memory");
++ luaL_buffinit(L, b);
++ while ((wild = strstr(s, p)) != NULL) {
++ luaL_addlstring(b, s, wild - s); /* push prefix */
++ luaL_addstring(b, r); /* push replacement in place of pattern */
++ s = wild + l; /* continue after `p' */
++ }
++ luaL_addstring(b, s); /* push last suffix */
++ luaL_pushresult(b);
++ kfree(b);
++ return lua_tostring(L, -1);
++}
++
++
++LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
++ const char *fname, int szhint) {
++ const char *e;
++ lua_pushvalue(L, idx);
++ do {
++ e = strchr(fname, '.');
++ if (e == NULL) e = fname + strlen(fname);
++ lua_pushlstring(L, fname, e - fname);
++ lua_rawget(L, -2);
++ if (lua_isnil(L, -1)) { /* no such field? */
++ lua_pop(L, 1); /* remove this nil */
++ lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
++ lua_pushlstring(L, fname, e - fname);
++ lua_pushvalue(L, -2);
++ lua_settable(L, -4); /* set new table into field */
++ }
++ else if (!lua_istable(L, -1)) { /* field has a non-table value? */
++ lua_pop(L, 2); /* remove table and value */
++ return fname; /* return problematic part of the name */
++ }
++ lua_remove(L, -2); /* remove previous table */
++ fname = e + 1;
++ } while (*e == '.');
++ return NULL;
++}
++
++
++
++/*
++** {======================================================
++** Generic Buffer manipulation
++** =======================================================
++*/
++
++
++#define bufflen(B) ((B)->p - (B)->buffer)
++#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
++
++#define LIMIT (LUA_MINSTACK/2)
++
++
++static int emptybuffer (luaL_Buffer *B) {
++ size_t l = bufflen(B);
++ if (l == 0) return 0; /* put nothing on stack */
++ else {
++ lua_pushlstring(B->L, B->buffer, l);
++ B->p = B->buffer;
++ B->lvl++;
++ return 1;
++ }
++}
++
++
++static void adjuststack (luaL_Buffer *B) {
++ if (B->lvl > 1) {
++ lua_State *L = B->L;
++ int toget = 1; /* number of levels to concat */
++ size_t toplen = lua_strlen(L, -1);
++ do {
++ size_t l = lua_strlen(L, -(toget+1));
++ if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
++ toplen += l;
++ toget++;
++ }
++ else break;
++ } while (toget < B->lvl);
++ lua_concat(L, toget);
++ B->lvl = B->lvl - toget + 1;
++ }
++}
++
++
++LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
++ if (emptybuffer(B))
++ adjuststack(B);
++ return B->buffer;
++}
++
++
++LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
++ while (l--)
++ luaL_addchar(B, *s++);
++}
++
++
++LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
++ luaL_addlstring(B, s, strlen(s));
++}
++
++
++LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
++ emptybuffer(B);
++ lua_concat(B->L, B->lvl);
++ B->lvl = 1;
++}
++
++
++LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
++ lua_State *L = B->L;
++ size_t vl;
++ const char *s = lua_tolstring(L, -1, &vl);
++ if (vl <= bufffree(B)) { /* fit into buffer? */
++ memcpy(B->p, s, vl); /* put it there */
++ B->p += vl;
++ lua_pop(L, 1); /* remove from stack */
++ }
++ else {
++ if (emptybuffer(B))
++ lua_insert(L, -2); /* put buffer before new value */
++ B->lvl++; /* add new value into B stack */
++ adjuststack(B);
++ }
++}
++
++
++LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
++ B->L = L;
++ B->p = B->buffer;
++ B->lvl = 0;
++}
++
++/* }====================================================== */
++
++
++LUALIB_API int luaL_ref (lua_State *L, int t) {
++ int ref;
++ t = abs_index(L, t);
++ if (lua_isnil(L, -1)) {
++ lua_pop(L, 1); /* remove from stack */
++ return LUA_REFNIL; /* `nil' has a unique fixed reference */
++ }
++ lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
++ ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
++ lua_pop(L, 1); /* remove it from stack */
++ if (ref != 0) { /* any free element? */
++ lua_rawgeti(L, t, ref); /* remove it from list */
++ lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
++ }
++ else { /* no free elements */
++ ref = (int)lua_objlen(L, t);
++ ref++; /* create new reference */
++ }
++ lua_rawseti(L, t, ref);
++ return ref;
++}
++
++
++LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
++ if (ref >= 0) {
++ t = abs_index(L, t);
++ lua_rawgeti(L, t, FREELIST_REF);
++ lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
++ lua_pushinteger(L, ref);
++ lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
++ }
++}
++
++
++
++/*
++** {======================================================
++** Load functions
++** =======================================================
++*/
++
++#if !defined(__KERNEL__)
++typedef struct LoadF {
++ int extraline;
++ FILE *f;
++ char buff[LUAL_BUFFERSIZE];
++} LoadF;
++
++
++static const char *getF (lua_State *L, void *ud, size_t *size) {
++ LoadF *lf = (LoadF *)ud;
++ (void)L;
++ if (lf->extraline) {
++ lf->extraline = 0;
++ *size = 1;
++ return "\n";
++ }
++ if (feof(lf->f)) return NULL;
++ *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
++ return (*size > 0) ? lf->buff : NULL;
++}
++
++
++static int errfile (lua_State *L, const char *what, int fnameindex) {
++ const char *serr = strerror(errno);
++ const char *filename = lua_tostring(L, fnameindex) + 1;
++ lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
++ lua_remove(L, fnameindex);
++ return LUA_ERRFILE;
++}
++
++
++LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
++ LoadF lf;
++ int status, readstatus;
++ int c;
++ int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
++ lf.extraline = 0;
++ if (filename == NULL) {
++ lua_pushliteral(L, "=stdin");
++ lf.f = stdin;
++ }
++ else {
++ lua_pushfstring(L, "@%s", filename);
++ lf.f = fopen(filename, "r");
++ if (lf.f == NULL) return errfile(L, "open", fnameindex);
++ }
++ c = getc(lf.f);
++ if (c == '#') { /* Unix exec. file? */
++ lf.extraline = 1;
++ while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
++ if (c == '\n') c = getc(lf.f);
++ }
++ if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
++ lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
++ if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
++ /* skip eventual `#!...' */
++ while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
++ lf.extraline = 0;
++ }
++ ungetc(c, lf.f);
++ status = lua_load(L, getF, &lf, lua_tostring(L, -1));
++ readstatus = ferror(lf.f);
++ if (filename) fclose(lf.f); /* close file (even in case of errors) */
++ if (readstatus) {
++ lua_settop(L, fnameindex); /* ignore results from `lua_load' */
++ return errfile(L, "read", fnameindex);
++ }
++ lua_remove(L, fnameindex);
++ return status;
++}
++#endif
++
++typedef struct LoadS {
++ const char *s;
++ size_t size;
++} LoadS;
++
++
++static const char *getS (lua_State *L, void *ud, size_t *size) {
++ LoadS *ls = (LoadS *)ud;
++ (void)L;
++ if (ls->size == 0) return NULL;
++ *size = ls->size;
++ ls->size = 0;
++ return ls->s;
++}
++
++
++LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
++ const char *name) {
++ LoadS ls;
++ ls.s = buff;
++ ls.size = size;
++ return lua_load(L, getS, &ls, name);
++}
++
++
++LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
++ return luaL_loadbuffer(L, s, strlen(s), s);
++}
++
++
++
++/* }====================================================== */
++
++
++static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
++ (void)ud;
++ (void)osize;
++ if (nsize == 0) {
++#if !defined(__KERNEL__)
++ free(ptr);
++#else
++ kfree(ptr);
++#endif
++ return NULL;
++ }
++ else
++#if !defined(__KERNEL__)
++ return realloc(ptr, nsize);
++#else
++ return krealloc(ptr, nsize, GFP_ATOMIC);
++#endif
++}
++
++
++static int lpanic (lua_State *L) {
++ (void)L; /* to avoid warnings */
++#if !defined(__KERNEL__)
++ fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
++#else
++ printk( "PANIC: unprotected error in call to Lua API (%s)\n",
++#endif
++ lua_tostring(L, -1));
++ return 0;
++}
++
++
++LUALIB_API lua_State *luaL_newstate (void) {
++ lua_State *L = lua_newstate(l_alloc, NULL);
++ if (L) lua_atpanic(L, &lpanic);
++ return L;
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/lauxlib.h
+@@ -0,0 +1,184 @@
++/*
++** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
++** Auxiliary functions for building Lua libraries
++** See Copyright Notice in lua.h
++*/
++
++
++#ifndef lauxlib_h
++#define lauxlib_h
++
++
++#include <stddef.h>
++#include <linux/slab.h> /* for kmalloc and kfree when allocating luaL_Buffer */
++
++#if !defined(__KERNEL__)
++#include <stdio.h>
++#endif
++
++#include "lua.h"
++
++
++#if defined(LUA_COMPAT_GETN)
++LUALIB_API int (luaL_getn) (lua_State *L, int t);
++LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
++#else
++#define luaL_getn(L,i) ((int)lua_objlen(L, i))
++#define luaL_setn(L,i,j) ((void)0) /* no op! */
++#endif
++
++#if defined(LUA_COMPAT_OPENLIB)
++#define luaI_openlib luaL_openlib
++#endif
++
++
++/* extra error code for `luaL_load' */
++#define LUA_ERRFILE (LUA_ERRERR+1)
++
++
++typedef struct luaL_Reg {
++ const char *name;
++ lua_CFunction func;
++} luaL_Reg;
++
++
++
++LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
++ const luaL_Reg *l, int nup);
++LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
++ const luaL_Reg *l);
++LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
++LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
++LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
++LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
++LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
++ size_t *l);
++LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
++ const char *def, size_t *l);
++LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
++LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
++
++LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
++LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
++ lua_Integer def);
++
++LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
++LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
++LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
++
++LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
++LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
++
++LUALIB_API void (luaL_where) (lua_State *L, int lvl);
++LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
++
++LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
++ const char *const lst[]);
++
++LUALIB_API int (luaL_ref) (lua_State *L, int t);
++LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
++
++#if !defined(__KERNEL__)
++LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
++#endif
++
++LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
++ const char *name);
++LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
++
++LUALIB_API lua_State *(luaL_newstate) (void);
++
++
++LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
++ const char *r);
++
++LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
++ const char *fname, int szhint);
++
++
++
++
++/*
++** ===============================================================
++** some useful macros
++** ===============================================================
++*/
++
++#define luaL_argcheck(L, cond,numarg,extramsg) \
++ ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
++#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
++#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
++#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
++#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
++#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
++#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
++
++#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
++
++#if !defined(__KERNEL__)
++#define luaL_dofile(L, fn) \
++ (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
++#endif
++
++#define luaL_dostring(L, s) \
++ (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
++
++#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
++
++#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
++
++/*
++** {======================================================
++** Generic Buffer manipulation
++** =======================================================
++*/
++
++
++
++typedef struct luaL_Buffer {
++ char *p; /* current position in buffer */
++ int lvl; /* number of strings in the stack (level) */
++ lua_State *L;
++ char buffer[LUAL_BUFFERSIZE];
++} luaL_Buffer;
++
++#define luaL_addchar(B,c) \
++ ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
++ (*(B)->p++ = (char)(c)))
++
++/* compatibility only */
++#define luaL_putchar(B,c) luaL_addchar(B,c)
++
++#define luaL_addsize(B,n) ((B)->p += (n))
++
++
++LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
++LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
++LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
++LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
++LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
++LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
++
++
++/* }====================================================== */
++
++
++/* compatibility with ref system */
++
++/* pre-defined references */
++#define LUA_NOREF (-2)
++#define LUA_REFNIL (-1)
++
++#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
++ (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
++
++#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
++
++#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
++
++
++#define luaL_reg luaL_Reg
++
++#endif
++
++
+--- /dev/null
++++ b/extensions/LUA/lua/lbaselib.c
+@@ -0,0 +1,647 @@
++/*
++** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $
++** Basic library
++** See Copyright Notice in lua.h
++*/
++
++
++#include <linux/kernel.h>
++#include <linux/ctype.h>
++#include <linux/string.h>
++
++#define lbaselib_c
++#define LUA_LIB
++
++#include "lua.h"
++
++#include "lauxlib.h"
++#include "lualib.h"
++
++
++
++
++/*
++** If your system does not support `stdout', you can just remove this function.
++** If you need, you can define your own `print' function, following this
++** model but changing `fputs' to put the strings at a proper place
++** (a console window or a log file, for instance).
++*/
++static int luaB_print (lua_State *L) {
++ int n = lua_gettop(L); /* number of arguments */
++ int i;
++ lua_getglobal(L, "tostring");
++ for (i=1; i<=n; i++) {
++ const char *s;
++ lua_pushvalue(L, -1); /* function to be called */
++ lua_pushvalue(L, i); /* value to print */
++ lua_call(L, 1, 1);
++ s = lua_tostring(L, -1); /* get result */
++ if (s == NULL)
++ return luaL_error(L, LUA_QL("tostring") " must return a string to "
++ LUA_QL("print"));
++ printk(KERN_INFO "LUA[print]: %s", s);
++ lua_pop(L, 1); /* pop result */
++ }
++ return 0;
++}
++
++
++static int luaB_tonumber (lua_State *L) {
++ int base = luaL_optint(L, 2, 10);
++ if (base == 10) { /* standard conversion */
++ luaL_checkany(L, 1);
++ if (lua_isnumber(L, 1)) {
++ lua_pushnumber(L, lua_tonumber(L, 1));
++ return 1;
++ }
++ }
++ else {
++ const char *s1 = luaL_checkstring(L, 1);
++ char *s2;
++ unsigned long n;
++ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
++ n = simple_strtoul(s1, &s2, base);
++ if (s1 != s2) { /* at least one valid digit? */
++ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
++ if (*s2 == '\0') { /* no invalid trailing characters? */
++ lua_pushnumber(L, (lua_Number)n);
++ return 1;
++ }
++ }
++ }
++ lua_pushnil(L); /* else not a number */
++ return 1;
++}
++
++
++static int luaB_error (lua_State *L) {
++ int level = luaL_optint(L, 2, 1);
++ lua_settop(L, 1);
++ if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
++ luaL_where(L, level);
++ lua_pushvalue(L, 1);
++ lua_concat(L, 2);
++ }
++ return lua_error(L);
++}
++
++
++static int luaB_getmetatable (lua_State *L) {
++ luaL_checkany(L, 1);
++ if (!lua_getmetatable(L, 1)) {
++ lua_pushnil(L);
++ return 1; /* no metatable */
++ }
++ luaL_getmetafield(L, 1, "__metatable");
++ return 1; /* returns either __metatable field (if present) or metatable */
++}
++
++
++static int luaB_setmetatable (lua_State *L) {
++ int t = lua_type(L, 2);
++ luaL_checktype(L, 1, LUA_TTABLE);
++ luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
++ "nil or table expected");
++ if (luaL_getmetafield(L, 1, "__metatable"))
++ luaL_error(L, "cannot change a protected metatable");
++ lua_settop(L, 2);
++ lua_setmetatable(L, 1);
++ return 1;
++}
++
++
++static void getfunc (lua_State *L, int opt) {
++ if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
++ else {
++ lua_Debug ar;
++ int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
++ luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
++ if (lua_getstack(L, level, &ar) == 0)
++ luaL_argerror(L, 1, "invalid level");
++ lua_getinfo(L, "f", &ar);
++ if (lua_isnil(L, -1))
++ luaL_error(L, "no function environment for tail call at level %d",
++ level);
++ }
++}
++
++
++static int luaB_getfenv (lua_State *L) {
++ getfunc(L, 1);
++ if (lua_iscfunction(L, -1)) /* is a C function? */
++ lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
++ else
++ lua_getfenv(L, -1);
++ return 1;
++}
++
++
++static int luaB_setfenv (lua_State *L) {
++ luaL_checktype(L, 2, LUA_TTABLE);
++ getfunc(L, 0);
++ lua_pushvalue(L, 2);
++ if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
++ /* change environment of current thread */
++ lua_pushthread(L);
++ lua_insert(L, -2);
++ lua_setfenv(L, -2);
++ return 0;
++ }
++ else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
++ luaL_error(L,
++ LUA_QL("setfenv") " cannot change environment of given object");
++ return 1;
++}
++
++
++static int luaB_rawequal (lua_State *L) {
++ luaL_checkany(L, 1);
++ luaL_checkany(L, 2);
++ lua_pushboolean(L, lua_rawequal(L, 1, 2));
++ return 1;
++}
++
++
++static int luaB_rawget (lua_State *L) {
++ luaL_checktype(L, 1, LUA_TTABLE);
++ luaL_checkany(L, 2);
++ lua_settop(L, 2);
++ lua_rawget(L, 1);
++ return 1;
++}
++
++static int luaB_rawset (lua_State *L) {
++ luaL_checktype(L, 1, LUA_TTABLE);
++ luaL_checkany(L, 2);
++ luaL_checkany(L, 3);
++ lua_settop(L, 3);
++ lua_rawset(L, 1);
++ return 1;
++}
++
++
++static int luaB_gcinfo (lua_State *L) {
++ lua_pushinteger(L, lua_getgccount(L));
++ return 1;
++}
++
++static int luaB_collectgarbage (lua_State *L) {
++ static const char *const opts[] = {"stop", "restart", "collect",
++ "count", "step", "setpause", "setstepmul", NULL};
++ static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
++ LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
++ int o = luaL_checkoption(L, 1, "collect", opts);
++ int ex = luaL_optint(L, 2, 0);
++ int res = lua_gc(L, optsnum[o], ex);
++ switch (optsnum[o]) {
++ case LUA_GCCOUNT: {
++ int b = lua_gc(L, LUA_GCCOUNTB, 0);
++ lua_pushnumber(L, res + ((lua_Number)b/1024));
++ return 1;
++ }
++ case LUA_GCSTEP: {
++ lua_pushboolean(L, res);
++ return 1;
++ }
++ default: {
++ lua_pushnumber(L, res);
++ return 1;
++ }
++ }
++}
++
++
++static int luaB_type (lua_State *L) {
++ luaL_checkany(L, 1);
++ lua_pushstring(L, luaL_typename(L, 1));
++ return 1;
++}
++
++
++static int luaB_next (lua_State *L) {
++ luaL_checktype(L, 1, LUA_TTABLE);
++ lua_settop(L, 2); /* create a 2nd argument if there isn't one */
++ if (lua_next(L, 1))
++ return 2;
++ else {
++ lua_pushnil(L);
++ return 1;
++ }
++}
++
++
++static int luaB_pairs (lua_State *L) {
++ luaL_checktype(L, 1, LUA_TTABLE);
++ lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
++ lua_pushvalue(L, 1); /* state, */
++ lua_pushnil(L); /* and initial value */
++ return 3;
++}
++
++
++static int ipairsaux (lua_State *L) {
++ int i = luaL_checkint(L, 2);
++ luaL_checktype(L, 1, LUA_TTABLE);
++ i++; /* next value */
++ lua_pushinteger(L, i);
++ lua_rawgeti(L, 1, i);
++ return (lua_isnil(L, -1)) ? 0 : 2;
++}
++
++
++static int luaB_ipairs (lua_State *L) {
++ luaL_checktype(L, 1, LUA_TTABLE);
++ lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
++ lua_pushvalue(L, 1); /* state, */
++ lua_pushinteger(L, 0); /* and initial value */
++ return 3;
++}
++
++
++static int load_aux (lua_State *L, int status) {
++ if (status == 0) /* OK? */
++ return 1;
++ else {
++ lua_pushnil(L);
++ lua_insert(L, -2); /* put before error message */
++ return 2; /* return nil plus error message */
++ }
++}
++
++
++static int luaB_loadstring (lua_State *L) {
++ size_t l;
++ const char *s = luaL_checklstring(L, 1, &l);
++ const char *chunkname = luaL_optstring(L, 2, s);
++ return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
++}
++
++/*
++static int luaB_loadfile (lua_State *L) {
++ const char *fname = luaL_optstring(L, 1, NULL);
++ return load_aux(L, luaL_loadfile(L, fname));
++}
++*/
++
++/*
++** Reader for generic `load' function: `lua_load' uses the
++** stack for internal stuff, so the reader cannot change the
++** stack top. Instead, it keeps its resulting string in a
++** reserved slot inside the stack.
++*/
++static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
++ (void)ud; /* to avoid warnings */
++ luaL_checkstack(L, 2, "too many nested functions");
++ lua_pushvalue(L, 1); /* get function */
++ lua_call(L, 0, 1); /* call it */
++ if (lua_isnil(L, -1)) {
++ *size = 0;
++ return NULL;
++ }
++ else if (lua_isstring(L, -1)) {
++ lua_replace(L, 3); /* save string in a reserved stack slot */
++ return lua_tolstring(L, 3, size);
++ }
++ else luaL_error(L, "reader function must return a string");
++ return NULL; /* to avoid warnings */
++}
++
++
++static int luaB_load (lua_State *L) {
++ int status;
++ const char *cname = luaL_optstring(L, 2, "=(load)");
++ luaL_checktype(L, 1, LUA_TFUNCTION);
++ lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
++ status = lua_load(L, generic_reader, NULL, cname);
++ return load_aux(L, status);
++}
++
++/*
++static int luaB_dofile (lua_State *L) {
++ const char *fname = luaL_optstring(L, 1, NULL);
++ int n = lua_gettop(L);
++ if (luaL_loadfile(L, fname) != 0) lua_error(L);
++ lua_call(L, 0, LUA_MULTRET);
++ return lua_gettop(L) - n;
++}
++*/
++
++static int luaB_assert (lua_State *L) {
++ luaL_checkany(L, 1);
++ if (!lua_toboolean(L, 1))
++ return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
++ return lua_gettop(L);
++}
++
++
++static int luaB_unpack (lua_State *L) {
++ int i, e, n;
++ luaL_checktype(L, 1, LUA_TTABLE);
++ i = luaL_optint(L, 2, 1);
++ e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
++ if (i > e) return 0; /* empty range */
++ n = e - i + 1; /* number of elements */
++ if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
++ return luaL_error(L, "too many results to unpack");
++ lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
++ while (i++ < e) /* push arg[i + 1...e] */
++ lua_rawgeti(L, 1, i);
++ return n;
++}
++
++
++static int luaB_select (lua_State *L) {
++ int n = lua_gettop(L);
++ if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
++ lua_pushinteger(L, n-1);
++ return 1;
++ }
++ else {
++ int i = luaL_checkint(L, 1);
++ if (i < 0) i = n + i;
++ else if (i > n) i = n;
++ luaL_argcheck(L, 1 <= i, 1, "index out of range");
++ return n - i;
++ }
++}
++
++
++static int luaB_pcall (lua_State *L) {
++ int status;
++ luaL_checkany(L, 1);
++ status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
++ lua_pushboolean(L, (status == 0));
++ lua_insert(L, 1);
++ return lua_gettop(L); /* return status + all results */
++}
++
++
++static int luaB_xpcall (lua_State *L) {
++ int status;
++ luaL_checkany(L, 2);
++ lua_settop(L, 2);
++ lua_insert(L, 1); /* put error function under function to be called */
++ status = lua_pcall(L, 0, LUA_MULTRET, 1);
++ lua_pushboolean(L, (status == 0));
++ lua_replace(L, 1);
++ return lua_gettop(L); /* return status + all results */
++}
++
++
++static int luaB_tostring (lua_State *L) {
++ luaL_checkany(L, 1);
++ if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
++ return 1; /* use its value */
++ switch (lua_type(L, 1)) {
++ case LUA_TNUMBER:
++ lua_pushstring(L, lua_tostring(L, 1));
++ break;
++ case LUA_TSTRING:
++ lua_pushvalue(L, 1);
++ break;
++ case LUA_TBOOLEAN:
++ lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
++ break;
++ case LUA_TNIL:
++ lua_pushliteral(L, "nil");
++ break;
++ default:
++ lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
++ break;
++ }
++ return 1;
++}
++
++
++static int luaB_newproxy (lua_State *L) {
++ lua_settop(L, 1);
++ lua_newuserdata(L, 0); /* create proxy */
++ if (lua_toboolean(L, 1) == 0)
++ return 1; /* no metatable */
++ else if (lua_isboolean(L, 1)) {
++ lua_newtable(L); /* create a new metatable `m' ... */
++ lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
++ lua_pushboolean(L, 1);
++ lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
++ }
++ else {
++ int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
++ if (lua_getmetatable(L, 1)) {
++ lua_rawget(L, lua_upvalueindex(1));
++ validproxy = lua_toboolean(L, -1);
++ lua_pop(L, 1); /* remove value */
++ }
++ luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
++ lua_getmetatable(L, 1); /* metatable is valid; get it */
++ }
++ lua_setmetatable(L, 2);
++ return 1;
++}
++
++
++static const luaL_Reg base_funcs[] = {
++ {"assert", luaB_assert},
++ {"collectgarbage", luaB_collectgarbage},
++// {"dofile", luaB_dofile},
++ {"error", luaB_error},
++ {"gcinfo", luaB_gcinfo},
++ {"getfenv", luaB_getfenv},
++ {"getmetatable", luaB_getmetatable},
++// {"loadfile", luaB_loadfile},
++ {"load", luaB_load},
++ {"loadstring", luaB_loadstring},
++ {"next", luaB_next},
++ {"pcall", luaB_pcall},
++ {"print", luaB_print},
++ {"rawequal", luaB_rawequal},
++ {"rawget", luaB_rawget},
++ {"rawset", luaB_rawset},
++ {"select", luaB_select},
++ {"setfenv", luaB_setfenv},
++ {"setmetatable", luaB_setmetatable},
++ {"tonumber", luaB_tonumber},
++ {"tostring", luaB_tostring},
++ {"type", luaB_type},
++ {"unpack", luaB_unpack},
++ {"xpcall", luaB_xpcall},
++ {NULL, NULL}
++};
++
++
++/*
++** {======================================================
++** Coroutine library
++** =======================================================
++*/
++
++#define CO_RUN 0 /* running */
++#define CO_SUS 1 /* suspended */
++#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
++#define CO_DEAD 3
++
++static const char *const statnames[] =
++ {"running", "suspended", "normal", "dead"};
++
++static int costatus (lua_State *L, lua_State *co) {
++ if (L == co) return CO_RUN;
++ switch (lua_status(co)) {
++ case LUA_YIELD:
++ return CO_SUS;
++ case 0: {
++ lua_Debug ar;
++ if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
++ return CO_NOR; /* it is running */
++ else if (lua_gettop(co) == 0)
++ return CO_DEAD;
++ else
++ return CO_SUS; /* initial state */
++ }
++ default: /* some error occured */
++ return CO_DEAD;
++ }
++}
++
++
++static int luaB_costatus (lua_State *L) {
++ lua_State *co = lua_tothread(L, 1);
++ luaL_argcheck(L, co, 1, "coroutine expected");
++ lua_pushstring(L, statnames[costatus(L, co)]);
++ return 1;
++}
++
++
++static int auxresume (lua_State *L, lua_State *co, int narg) {
++ int status = costatus(L, co);
++ if (!lua_checkstack(co, narg))
++ luaL_error(L, "too many arguments to resume");
++ if (status != CO_SUS) {
++ lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
++ return -1; /* error flag */
++ }
++ lua_xmove(L, co, narg);
++ lua_setlevel(L, co);
++ status = lua_resume(co, narg);
++ if (status == 0 || status == LUA_YIELD) {
++ int nres = lua_gettop(co);
++ if (!lua_checkstack(L, nres + 1))
++ luaL_error(L, "too many results to resume");
++ lua_xmove(co, L, nres); /* move yielded values */
++ return nres;
++ }
++ else {
++ lua_xmove(co, L, 1); /* move error message */
++ return -1; /* error flag */
++ }
++}
++
++
++static int luaB_coresume (lua_State *L) {
++ lua_State *co = lua_tothread(L, 1);
++ int r;
++ luaL_argcheck(L, co, 1, "coroutine expected");
++ r = auxresume(L, co, lua_gettop(L) - 1);
++ if (r < 0) {
++ lua_pushboolean(L, 0);
++ lua_insert(L, -2);
++ return 2; /* return false + error message */
++ }
++ else {
++ lua_pushboolean(L, 1);
++ lua_insert(L, -(r + 1));
++ return r + 1; /* return true + `resume' returns */
++ }
++}
++
++
++static int luaB_auxwrap (lua_State *L) {
++ lua_State *co = lua_tothread(L, lua_upvalueindex(1));
++ int r = auxresume(L, co, lua_gettop(L));
++ if (r < 0) {
++ if (lua_isstring(L, -1)) { /* error object is a string? */
++ luaL_where(L, 1); /* add extra info */
++ lua_insert(L, -2);
++ lua_concat(L, 2);
++ }
++ lua_error(L); /* propagate error */
++ }
++ return r;
++}
++
++
++static int luaB_cocreate (lua_State *L) {
++ lua_State *NL = lua_newthread(L);
++ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
++ "Lua function expected");
++ lua_pushvalue(L, 1); /* move function to top */
++ lua_xmove(L, NL, 1); /* move function from L to NL */
++ return 1;
++}
++
++
++static int luaB_cowrap (lua_State *L) {
++ luaB_cocreate(L);
++ lua_pushcclosure(L, luaB_auxwrap, 1);
++ return 1;
++}
++
++
++static int luaB_yield (lua_State *L) {
++ return lua_yield(L, lua_gettop(L));
++}
++
++
++static int luaB_corunning (lua_State *L) {
++ if (lua_pushthread(L))
++ lua_pushnil(L); /* main thread is not a coroutine */
++ return 1;
++}
++
++
++static const luaL_Reg co_funcs[] = {
++ {"create", luaB_cocreate},
++ {"resume", luaB_coresume},
++ {"running", luaB_corunning},
++ {"status", luaB_costatus},
++ {"wrap", luaB_cowrap},
++ {"yield", luaB_yield},
++ {NULL, NULL}
++};
++
++/* }====================================================== */
++
++
++static void auxopen (lua_State *L, const char *name,
++ lua_CFunction f, lua_CFunction u) {
++ lua_pushcfunction(L, u);
++ lua_pushcclosure(L, f, 1);
++ lua_setfield(L, -2, name);
++}
++
++
++static void base_open (lua_State *L) {
++ /* set global _G */
++ lua_pushvalue(L, LUA_GLOBALSINDEX);
++ lua_setglobal(L, "_G");
++ /* open lib into global table */
++ luaL_register(L, "_G", base_funcs);
++ lua_pushliteral(L, LUA_VERSION);
++ lua_setglobal(L, "_VERSION"); /* set global _VERSION */
++ /* `ipairs' and `pairs' need auxliliary functions as upvalues */
++ auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
++ auxopen(L, "pairs", luaB_pairs, luaB_next);
++ /* `newproxy' needs a weaktable as upvalue */
++ lua_createtable(L, 0, 1); /* new table `w' */
++ lua_pushvalue(L, -1); /* `w' will be its own metatable */
++ lua_setmetatable(L, -2);
++ lua_pushliteral(L, "kv");
++ lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
++ lua_pushcclosure(L, luaB_newproxy, 1);
++ lua_setglobal(L, "newproxy"); /* set global `newproxy' */
++}
++
++
++LUALIB_API int luaopen_base (lua_State *L) {
++ base_open(L);
++ luaL_register(L, LUA_COLIBNAME, co_funcs);
++ return 2;
++}
+--- /dev/null
++++ b/extensions/LUA/lua/lcode.c
+@@ -0,0 +1,838 @@
++/*
++** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
++** Code generator for Lua
++** See Copyright Notice in lua.h
++*/
++
++#include <stdlib.h>
++
++#define lcode_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "lcode.h"
++#include "ldebug.h"
++#include "ldo.h"
++#include "lgc.h"
++#include "llex.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lopcodes.h"
++#include "lparser.h"
++#include "ltable.h"
++
++
++#define hasjumps(e) ((e)->t != (e)->f)
++
++
++static int isnumeral(expdesc *e) {
++ return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
++}
++
++
++void luaK_nil (FuncState *fs, int from, int n) {
++ Instruction *previous;
++ if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
++ if (fs->pc == 0) { /* function start? */
++ if (from >= fs->nactvar)
++ return; /* positions are already clean */
++ }
++ else {
++ previous = &fs->f->code[fs->pc-1];
++ if (GET_OPCODE(*previous) == OP_LOADNIL) {
++ int pfrom = GETARG_A(*previous);
++ int pto = GETARG_B(*previous);
++ if (pfrom <= from && from <= pto+1) { /* can connect both? */
++ if (from+n-1 > pto)
++ SETARG_B(*previous, from+n-1);
++ return;
++ }
++ }
++ }
++ }
++ luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
++}
++
++
++int luaK_jump (FuncState *fs) {
++ int jpc = fs->jpc; /* save list of jumps to here */
++ int j;
++ fs->jpc = NO_JUMP;
++ j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
++ luaK_concat(fs, &j, jpc); /* keep them on hold */
++ return j;
++}
++
++
++void luaK_ret (FuncState *fs, int first, int nret) {
++ luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
++}
++
++
++static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
++ luaK_codeABC(fs, op, A, B, C);
++ return luaK_jump(fs);
++}
++
++
++static void fixjump (FuncState *fs, int pc, int dest) {
++ Instruction *jmp = &fs->f->code[pc];
++ int offset = dest-(pc+1);
++ lua_assert(dest != NO_JUMP);
++ if (abs(offset) > MAXARG_sBx)
++ luaX_syntaxerror(fs->ls, "control structure too long");
++ SETARG_sBx(*jmp, offset);
++}
++
++
++/*
++** returns current `pc' and marks it as a jump target (to avoid wrong
++** optimizations with consecutive instructions not in the same basic block).
++*/
++int luaK_getlabel (FuncState *fs) {
++ fs->lasttarget = fs->pc;
++ return fs->pc;
++}
++
++
++static int getjump (FuncState *fs, int pc) {
++ int offset = GETARG_sBx(fs->f->code[pc]);
++ if (offset == NO_JUMP) /* point to itself represents end of list */
++ return NO_JUMP; /* end of list */
++ else
++ return (pc+1)+offset; /* turn offset into absolute position */
++}
++
++
++static Instruction *getjumpcontrol (FuncState *fs, int pc) {
++ Instruction *pi = &fs->f->code[pc];
++ if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
++ return pi-1;
++ else
++ return pi;
++}
++
++
++/*
++** check whether list has any jump that do not produce a value
++** (or produce an inverted value)
++*/
++static int need_value (FuncState *fs, int list) {
++ for (; list != NO_JUMP; list = getjump(fs, list)) {
++ Instruction i = *getjumpcontrol(fs, list);
++ if (GET_OPCODE(i) != OP_TESTSET) return 1;
++ }
++ return 0; /* not found */
++}
++
++
++static int patchtestreg (FuncState *fs, int node, int reg) {
++ Instruction *i = getjumpcontrol(fs, node);
++ if (GET_OPCODE(*i) != OP_TESTSET)
++ return 0; /* cannot patch other instructions */
++ if (reg != NO_REG && reg != GETARG_B(*i))
++ SETARG_A(*i, reg);
++ else /* no register to put value or register already has the value */
++ *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
++
++ return 1;
++}
++
++
++static void removevalues (FuncState *fs, int list) {
++ for (; list != NO_JUMP; list = getjump(fs, list))
++ patchtestreg(fs, list, NO_REG);
++}
++
++
++static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
++ int dtarget) {
++ while (list != NO_JUMP) {
++ int next = getjump(fs, list);
++ if (patchtestreg(fs, list, reg))
++ fixjump(fs, list, vtarget);
++ else
++ fixjump(fs, list, dtarget); /* jump to default target */
++ list = next;
++ }
++}
++
++
++static void dischargejpc (FuncState *fs) {
++ patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
++ fs->jpc = NO_JUMP;
++}
++
++
++void luaK_patchlist (FuncState *fs, int list, int target) {
++ if (target == fs->pc)
++ luaK_patchtohere(fs, list);
++ else {
++ lua_assert(target < fs->pc);
++ patchlistaux(fs, list, target, NO_REG, target);
++ }
++}
++
++
++void luaK_patchtohere (FuncState *fs, int list) {
++ luaK_getlabel(fs);
++ luaK_concat(fs, &fs->jpc, list);
++}
++
++
++void luaK_concat (FuncState *fs, int *l1, int l2) {
++ if (l2 == NO_JUMP) return;
++ else if (*l1 == NO_JUMP)
++ *l1 = l2;
++ else {
++ int list = *l1;
++ int next;
++ while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
++ list = next;
++ fixjump(fs, list, l2);
++ }
++}
++
++
++void luaK_checkstack (FuncState *fs, int n) {
++ int newstack = fs->freereg + n;
++ if (newstack > fs->f->maxstacksize) {
++ if (newstack >= MAXSTACK)
++ luaX_syntaxerror(fs->ls, "function or expression too complex");
++ fs->f->maxstacksize = cast_byte(newstack);
++ }
++}
++
++
++void luaK_reserveregs (FuncState *fs, int n) {
++ luaK_checkstack(fs, n);
++ fs->freereg += n;
++}
++
++
++static void freereg (FuncState *fs, int reg) {
++ if (!ISK(reg) && reg >= fs->nactvar) {
++ fs->freereg--;
++ lua_assert(reg == fs->freereg);
++ }
++}
++
++
++static void freeexp (FuncState *fs, expdesc *e) {
++ if (e->k == VNONRELOC)
++ freereg(fs, e->u.s.info);
++}
++
++
++static int addk (FuncState *fs, TValue *k, TValue *v) {
++ lua_State *L = fs->L;
++ TValue *idx = luaH_set(L, fs->h, k);
++ Proto *f = fs->f;
++ int oldsize = f->sizek;
++ if (ttisnumber(idx)) {
++ lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
++ return cast_int(nvalue(idx));
++ }
++ else { /* constant not found; create a new entry */
++ setnvalue(idx, cast_num(fs->nk));
++ luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
++ MAXARG_Bx, "constant table overflow");
++ while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
++ setobj(L, &f->k[fs->nk], v);
++ luaC_barrier(L, f, v);
++ return fs->nk++;
++ }
++}
++
++
++int luaK_stringK (FuncState *fs, TString *s) {
++ TValue o;
++ setsvalue(fs->L, &o, s);
++ return addk(fs, &o, &o);
++}
++
++
++int luaK_numberK (FuncState *fs, lua_Number r) {
++ TValue o;
++ setnvalue(&o, r);
++ return addk(fs, &o, &o);
++}
++
++
++static int boolK (FuncState *fs, int b) {
++ TValue o;
++ setbvalue(&o, b);
++ return addk(fs, &o, &o);
++}
++
++
++static int nilK (FuncState *fs) {
++ TValue k, v;
++ setnilvalue(&v);
++ /* cannot use nil as key; instead use table itself to represent nil */
++ sethvalue(fs->L, &k, fs->h);
++ return addk(fs, &k, &v);
++}
++
++
++void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
++ if (e->k == VCALL) { /* expression is an open function call? */
++ SETARG_C(getcode(fs, e), nresults+1);
++ }
++ else if (e->k == VVARARG) {
++ SETARG_B(getcode(fs, e), nresults+1);
++ SETARG_A(getcode(fs, e), fs->freereg);
++ luaK_reserveregs(fs, 1);
++ }
++}
++
++
++void luaK_setoneret (FuncState *fs, expdesc *e) {
++ if (e->k == VCALL) { /* expression is an open function call? */
++ e->k = VNONRELOC;
++ e->u.s.info = GETARG_A(getcode(fs, e));
++ }
++ else if (e->k == VVARARG) {
++ SETARG_B(getcode(fs, e), 2);
++ e->k = VRELOCABLE; /* can relocate its simple result */
++ }
++}
++
++
++void luaK_dischargevars (FuncState *fs, expdesc *e) {
++ switch (e->k) {
++ case VLOCAL: {
++ e->k = VNONRELOC;
++ break;
++ }
++ case VUPVAL: {
++ e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
++ e->k = VRELOCABLE;
++ break;
++ }
++ case VGLOBAL: {
++ e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
++ e->k = VRELOCABLE;
++ break;
++ }
++ case VINDEXED: {
++ freereg(fs, e->u.s.aux);
++ freereg(fs, e->u.s.info);
++ e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
++ e->k = VRELOCABLE;
++ break;
++ }
++ case VVARARG:
++ case VCALL: {
++ luaK_setoneret(fs, e);
++ break;
++ }
++ default: break; /* there is one value available (somewhere) */
++ }
++}
++
++
++static int code_label (FuncState *fs, int A, int b, int jump) {
++ luaK_getlabel(fs); /* those instructions may be jump targets */
++ return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
++}
++
++
++static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
++ luaK_dischargevars(fs, e);
++ switch (e->k) {
++ case VNIL: {
++ luaK_nil(fs, reg, 1);
++ break;
++ }
++ case VFALSE: case VTRUE: {
++ luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
++ break;
++ }
++ case VK: {
++ luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
++ break;
++ }
++ case VKNUM: {
++ luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
++ break;
++ }
++ case VRELOCABLE: {
++ Instruction *pc = &getcode(fs, e);
++ SETARG_A(*pc, reg);
++ break;
++ }
++ case VNONRELOC: {
++ if (reg != e->u.s.info)
++ luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
++ break;
++ }
++ default: {
++ lua_assert(e->k == VVOID || e->k == VJMP);
++ return; /* nothing to do... */
++ }
++ }
++ e->u.s.info = reg;
++ e->k = VNONRELOC;
++}
++
++
++static void discharge2anyreg (FuncState *fs, expdesc *e) {
++ if (e->k != VNONRELOC) {
++ luaK_reserveregs(fs, 1);
++ discharge2reg(fs, e, fs->freereg-1);
++ }
++}
++
++
++static void exp2reg (FuncState *fs, expdesc *e, int reg) {
++ discharge2reg(fs, e, reg);
++ if (e->k == VJMP)
++ luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
++ if (hasjumps(e)) {
++ int final; /* position after whole expression */
++ int p_f = NO_JUMP; /* position of an eventual LOAD false */
++ int p_t = NO_JUMP; /* position of an eventual LOAD true */
++ if (need_value(fs, e->t) || need_value(fs, e->f)) {
++ int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
++ p_f = code_label(fs, reg, 0, 1);
++ p_t = code_label(fs, reg, 1, 0);
++ luaK_patchtohere(fs, fj);
++ }
++ final = luaK_getlabel(fs);
++ patchlistaux(fs, e->f, final, reg, p_f);
++ patchlistaux(fs, e->t, final, reg, p_t);
++ }
++ e->f = e->t = NO_JUMP;
++ e->u.s.info = reg;
++ e->k = VNONRELOC;
++}
++
++
++void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
++ luaK_dischargevars(fs, e);
++ freeexp(fs, e);
++ luaK_reserveregs(fs, 1);
++ exp2reg(fs, e, fs->freereg - 1);
++}
++
++
++int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
++ luaK_dischargevars(fs, e);
++ if (e->k == VNONRELOC) {
++ if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
++ if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
++ exp2reg(fs, e, e->u.s.info); /* put value on it */
++ return e->u.s.info;
++ }
++ }
++ luaK_exp2nextreg(fs, e); /* default */
++ return e->u.s.info;
++}
++
++
++void luaK_exp2val (FuncState *fs, expdesc *e) {
++ if (hasjumps(e))
++ luaK_exp2anyreg(fs, e);
++ else
++ luaK_dischargevars(fs, e);
++}
++
++
++int luaK_exp2RK (FuncState *fs, expdesc *e) {
++ luaK_exp2val(fs, e);
++ switch (e->k) {
++ case VKNUM:
++ case VTRUE:
++ case VFALSE:
++ case VNIL: {
++ if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
++ e->u.s.info = (e->k == VNIL) ? nilK(fs) :
++ (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
++ boolK(fs, (e->k == VTRUE));
++ e->k = VK;
++ return RKASK(e->u.s.info);
++ }
++ else break;
++ }
++ case VK: {
++ if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
++ return RKASK(e->u.s.info);
++ else break;
++ }
++ default: break;
++ }
++ /* not a constant in the right range: put it in a register */
++ return luaK_exp2anyreg(fs, e);
++}
++
++
++void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
++ switch (var->k) {
++ case VLOCAL: {
++ freeexp(fs, ex);
++ exp2reg(fs, ex, var->u.s.info);
++ return;
++ }
++ case VUPVAL: {
++ int e = luaK_exp2anyreg(fs, ex);
++ luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
++ break;
++ }
++ case VGLOBAL: {
++ int e = luaK_exp2anyreg(fs, ex);
++ luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
++ break;
++ }
++ case VINDEXED: {
++ int e = luaK_exp2RK(fs, ex);
++ luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
++ break;
++ }
++ default: {
++ lua_assert(0); /* invalid var kind to store */
++ break;
++ }
++ }
++ freeexp(fs, ex);
++}
++
++
++void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
++ int func;
++ luaK_exp2anyreg(fs, e);
++ freeexp(fs, e);
++ func = fs->freereg;
++ luaK_reserveregs(fs, 2);
++ luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
++ freeexp(fs, key);
++ e->u.s.info = func;
++ e->k = VNONRELOC;
++}
++
++
++static void invertjump (FuncState *fs, expdesc *e) {
++ Instruction *pc = getjumpcontrol(fs, e->u.s.info);
++ lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
++ GET_OPCODE(*pc) != OP_TEST);
++ SETARG_A(*pc, !(GETARG_A(*pc)));
++}
++
++
++static int jumponcond (FuncState *fs, expdesc *e, int cond) {
++ if (e->k == VRELOCABLE) {
++ Instruction ie = getcode(fs, e);
++ if (GET_OPCODE(ie) == OP_NOT) {
++ fs->pc--; /* remove previous OP_NOT */
++ return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
++ }
++ /* else go through */
++ }
++ discharge2anyreg(fs, e);
++ freeexp(fs, e);
++ return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
++}
++
++
++void luaK_goiftrue (FuncState *fs, expdesc *e) {
++ int pc; /* pc of last jump */
++ luaK_dischargevars(fs, e);
++ switch (e->k) {
++ case VK: case VKNUM: case VTRUE: {
++ pc = NO_JUMP; /* always true; do nothing */
++ break;
++ }
++ case VFALSE: {
++ pc = luaK_jump(fs); /* always jump */
++ break;
++ }
++ case VJMP: {
++ invertjump(fs, e);
++ pc = e->u.s.info;
++ break;
++ }
++ default: {
++ pc = jumponcond(fs, e, 0);
++ break;
++ }
++ }
++ luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
++ luaK_patchtohere(fs, e->t);
++ e->t = NO_JUMP;
++}
++
++
++static void luaK_goiffalse (FuncState *fs, expdesc *e) {
++ int pc; /* pc of last jump */
++ luaK_dischargevars(fs, e);
++ switch (e->k) {
++ case VNIL: case VFALSE: {
++ pc = NO_JUMP; /* always false; do nothing */
++ break;
++ }
++ case VTRUE: {
++ pc = luaK_jump(fs); /* always jump */
++ break;
++ }
++ case VJMP: {
++ pc = e->u.s.info;
++ break;
++ }
++ default: {
++ pc = jumponcond(fs, e, 1);
++ break;
++ }
++ }
++ luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
++ luaK_patchtohere(fs, e->f);
++ e->f = NO_JUMP;
++}
++
++
++static void codenot (FuncState *fs, expdesc *e) {
++ luaK_dischargevars(fs, e);
++ switch (e->k) {
++ case VNIL: case VFALSE: {
++ e->k = VTRUE;
++ break;
++ }
++ case VK: case VKNUM: case VTRUE: {
++ e->k = VFALSE;
++ break;
++ }
++ case VJMP: {
++ invertjump(fs, e);
++ break;
++ }
++ case VRELOCABLE:
++ case VNONRELOC: {
++ discharge2anyreg(fs, e);
++ freeexp(fs, e);
++ e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
++ e->k = VRELOCABLE;
++ break;
++ }
++ default: {
++ lua_assert(0); /* cannot happen */
++ break;
++ }
++ }
++ /* interchange true and false lists */
++ { int temp = e->f; e->f = e->t; e->t = temp; }
++ removevalues(fs, e->f);
++ removevalues(fs, e->t);
++}
++
++
++void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
++ t->u.s.aux = luaK_exp2RK(fs, k);
++ t->k = VINDEXED;
++}
++
++
++static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
++ lua_Number v1, v2, r;
++ if (!isnumeral(e1) || !isnumeral(e2)) return 0;
++ v1 = e1->u.nval;
++ v2 = e2->u.nval;
++ switch (op) {
++ case OP_ADD: r = luai_numadd(v1, v2); break;
++ case OP_SUB: r = luai_numsub(v1, v2); break;
++ case OP_MUL: r = luai_nummul(v1, v2); break;
++ case OP_DIV:
++ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
++ r = luai_numdiv(v1, v2); break;
++ case OP_MOD:
++ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
++ r = luai_nummod(v1, v2); break;
++ case OP_POW: r = luai_numpow(v1, v2); break;
++ case OP_UNM: r = luai_numunm(v1); break;
++ case OP_LEN: return 0; /* no constant folding for 'len' */
++ default: lua_assert(0); r = 0; break;
++ }
++ if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
++ e1->u.nval = r;
++ return 1;
++}
++
++
++static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
++ if (constfolding(op, e1, e2))
++ return;
++ else {
++ int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
++ int o1 = luaK_exp2RK(fs, e1);
++ if (o1 > o2) {
++ freeexp(fs, e1);
++ freeexp(fs, e2);
++ }
++ else {
++ freeexp(fs, e2);
++ freeexp(fs, e1);
++ }
++ e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
++ e1->k = VRELOCABLE;
++ }
++}
++
++
++static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
++ expdesc *e2) {
++ int o1 = luaK_exp2RK(fs, e1);
++ int o2 = luaK_exp2RK(fs, e2);
++ freeexp(fs, e2);
++ freeexp(fs, e1);
++ if (cond == 0 && op != OP_EQ) {
++ int temp; /* exchange args to replace by `<' or `<=' */
++ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
++ cond = 1;
++ }
++ e1->u.s.info = condjump(fs, op, cond, o1, o2);
++ e1->k = VJMP;
++}
++
++
++void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
++ expdesc e2;
++ e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
++ switch (op) {
++ case OPR_MINUS: {
++ if (!isnumeral(e))
++ luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
++ codearith(fs, OP_UNM, e, &e2);
++ break;
++ }
++ case OPR_NOT: codenot(fs, e); break;
++ case OPR_LEN: {
++ luaK_exp2anyreg(fs, e); /* cannot operate on constants */
++ codearith(fs, OP_LEN, e, &e2);
++ break;
++ }
++ default: lua_assert(0);
++ }
++}
++
++
++void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
++ switch (op) {
++ case OPR_AND: {
++ luaK_goiftrue(fs, v);
++ break;
++ }
++ case OPR_OR: {
++ luaK_goiffalse(fs, v);
++ break;
++ }
++ case OPR_CONCAT: {
++ luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
++ break;
++ }
++ case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
++ case OPR_MOD: case OPR_POW: {
++ if (!isnumeral(v)) luaK_exp2RK(fs, v);
++ break;
++ }
++ default: {
++ luaK_exp2RK(fs, v);
++ break;
++ }
++ }
++}
++
++
++void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
++ switch (op) {
++ case OPR_AND: {
++ lua_assert(e1->t == NO_JUMP); /* list must be closed */
++ luaK_dischargevars(fs, e2);
++ luaK_concat(fs, &e2->f, e1->f);
++ *e1 = *e2;
++ break;
++ }
++ case OPR_OR: {
++ lua_assert(e1->f == NO_JUMP); /* list must be closed */
++ luaK_dischargevars(fs, e2);
++ luaK_concat(fs, &e2->t, e1->t);
++ *e1 = *e2;
++ break;
++ }
++ case OPR_CONCAT: {
++ luaK_exp2val(fs, e2);
++ if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
++ lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
++ freeexp(fs, e1);
++ SETARG_B(getcode(fs, e2), e1->u.s.info);
++ e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
++ }
++ else {
++ luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
++ codearith(fs, OP_CONCAT, e1, e2);
++ }
++ break;
++ }
++ case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
++ case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
++ case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
++ case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
++ case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
++ case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
++ case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
++ case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
++ case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
++ case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
++ case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
++ case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
++ default: lua_assert(0);
++ }
++}
++
++
++void luaK_fixline (FuncState *fs, int line) {
++ fs->f->lineinfo[fs->pc - 1] = line;
++}
++
++
++static int luaK_code (FuncState *fs, Instruction i, int line) {
++ Proto *f = fs->f;
++ dischargejpc(fs); /* `pc' will change */
++ /* put new instruction in code array */
++ luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
++ MAX_INT, "code size overflow");
++ f->code[fs->pc] = i;
++ /* save corresponding line information */
++ luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
++ MAX_INT, "code size overflow");
++ f->lineinfo[fs->pc] = line;
++ return fs->pc++;
++}
++
++
++int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
++ lua_assert(getOpMode(o) == iABC);
++ lua_assert(getBMode(o) != OpArgN || b == 0);
++ lua_assert(getCMode(o) != OpArgN || c == 0);
++ return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
++}
++
++
++int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
++ lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
++ lua_assert(getCMode(o) == OpArgN);
++ return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
++}
++
++
++void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
++ int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
++ int b = (tostore == LUA_MULTRET) ? 0 : tostore;
++ lua_assert(tostore != 0);
++ if (c <= MAXARG_C)
++ luaK_codeABC(fs, OP_SETLIST, base, b, c);
++ else {
++ luaK_codeABC(fs, OP_SETLIST, base, b, 0);
++ luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
++ }
++ fs->freereg = base + 1; /* free registers with list values */
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/lcode.h
+@@ -0,0 +1,76 @@
++/*
++** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $
++** Code generator for Lua
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lcode_h
++#define lcode_h
++
++#include "llex.h"
++#include "lobject.h"
++#include "lopcodes.h"
++#include "lparser.h"
++
++
++/*
++** Marks the end of a patch list. It is an invalid value both as an absolute
++** address, and as a list link (would link an element to itself).
++*/
++#define NO_JUMP (-1)
++
++
++/*
++** grep "ORDER OPR" if you change these enums
++*/
++typedef enum BinOpr {
++ OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
++ OPR_CONCAT,
++ OPR_NE, OPR_EQ,
++ OPR_LT, OPR_LE, OPR_GT, OPR_GE,
++ OPR_AND, OPR_OR,
++ OPR_NOBINOPR
++} BinOpr;
++
++
++typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
++
++
++#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info])
++
++#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
++
++#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
++
++LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
++LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
++LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
++LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
++LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
++LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
++LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
++LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
++LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
++LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
++LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
++LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
++LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
++LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
++LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
++LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
++LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
++LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
++LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
++LUAI_FUNC int luaK_jump (FuncState *fs);
++LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
++LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
++LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
++LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
++LUAI_FUNC int luaK_getlabel (FuncState *fs);
++LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
++LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
++LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
++LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/ldebug.c
+@@ -0,0 +1,637 @@
++/*
++** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $
++** Debug Interface
++** See Copyright Notice in lua.h
++*/
++
++
++#include <stdarg.h>
++#include <stddef.h>
++#include <string.h>
++
++#define ldebug_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "lapi.h"
++#include "lcode.h"
++#include "ldebug.h"
++#include "ldo.h"
++#include "lfunc.h"
++#include "lobject.h"
++#include "lopcodes.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "ltable.h"
++#include "ltm.h"
++#include "lvm.h"
++
++
++
++static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
++
++
++static int currentpc (lua_State *L, CallInfo *ci) {
++ if (!isLua(ci)) return -1; /* function is not a Lua function? */
++ if (ci == L->ci)
++ ci->savedpc = L->savedpc;
++ return pcRel(ci->savedpc, ci_func(ci)->l.p);
++}
++
++
++static int currentline (lua_State *L, CallInfo *ci) {
++ int pc = currentpc(L, ci);
++ if (pc < 0)
++ return -1; /* only active lua functions have current-line information */
++ else
++ return getline(ci_func(ci)->l.p, pc);
++}
++
++
++/*
++** this function can be called asynchronous (e.g. during a signal)
++*/
++LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
++ if (func == NULL || mask == 0) { /* turn off hooks? */
++ mask = 0;
++ func = NULL;
++ }
++ L->hook = func;
++ L->basehookcount = count;
++ resethookcount(L);
++ L->hookmask = cast_byte(mask);
++ return 1;
++}
++
++
++LUA_API lua_Hook lua_gethook (lua_State *L) {
++ return L->hook;
++}
++
++
++LUA_API int lua_gethookmask (lua_State *L) {
++ return L->hookmask;
++}
++
++
++LUA_API int lua_gethookcount (lua_State *L) {
++ return L->basehookcount;
++}
++
++
++LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
++ int status;
++ CallInfo *ci;
++ lua_lock(L);
++ for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
++ level--;
++ if (f_isLua(ci)) /* Lua function? */
++ level -= ci->tailcalls; /* skip lost tail calls */
++ }
++ if (level == 0 && ci > L->base_ci) { /* level found? */
++ status = 1;
++ ar->i_ci = cast_int(ci - L->base_ci);
++ }
++ else if (level < 0) { /* level is of a lost tail call? */
++ status = 1;
++ ar->i_ci = 0;
++ }
++ else status = 0; /* no such level */
++ lua_unlock(L);
++ return status;
++}
++
++
++static Proto *getluaproto (CallInfo *ci) {
++ return (isLua(ci) ? ci_func(ci)->l.p : NULL);
++}
++
++
++static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
++ const char *name;
++ Proto *fp = getluaproto(ci);
++ if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
++ return name; /* is a local variable in a Lua function */
++ else {
++ StkId limit = (ci == L->ci) ? L->top : (ci+1)->func;
++ if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
++ return "(*temporary)";
++ else
++ return NULL;
++ }
++}
++
++
++LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
++ CallInfo *ci = L->base_ci + ar->i_ci;
++ const char *name = findlocal(L, ci, n);
++ lua_lock(L);
++ if (name)
++ luaA_pushobject(L, ci->base + (n - 1));
++ lua_unlock(L);
++ return name;
++}
++
++
++LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
++ CallInfo *ci = L->base_ci + ar->i_ci;
++ const char *name = findlocal(L, ci, n);
++ lua_lock(L);
++ if (name)
++ setobjs2s(L, ci->base + (n - 1), L->top - 1);
++ L->top--; /* pop value */
++ lua_unlock(L);
++ return name;
++}
++
++
++static void funcinfo (lua_Debug *ar, Closure *cl) {
++ if (cl->c.isC) {
++ ar->source = "=[C]";
++ ar->linedefined = -1;
++ ar->lastlinedefined = -1;
++ ar->what = "C";
++ }
++ else {
++ ar->source = getstr(cl->l.p->source);
++ ar->linedefined = cl->l.p->linedefined;
++ ar->lastlinedefined = cl->l.p->lastlinedefined;
++ ar->what = (ar->linedefined == 0) ? "main" : "Lua";
++ }
++ luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
++}
++
++
++static void info_tailcall (lua_Debug *ar) {
++ ar->name = ar->namewhat = "";
++ ar->what = "tail";
++ ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
++ ar->source = "=(tail call)";
++ luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
++ ar->nups = 0;
++}
++
++
++static void collectvalidlines (lua_State *L, Closure *f) {
++ if (f == NULL || f->c.isC) {
++ setnilvalue(L->top);
++ }
++ else {
++ Table *t = luaH_new(L, 0, 0);
++ int *lineinfo = f->l.p->lineinfo;
++ int i;
++ for (i=0; i<f->l.p->sizelineinfo; i++)
++ setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
++ sethvalue(L, L->top, t);
++ }
++ incr_top(L);
++}
++
++
++static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
++ Closure *f, CallInfo *ci) {
++ int status = 1;
++ if (f == NULL) {
++ info_tailcall(ar);
++ return status;
++ }
++ for (; *what; what++) {
++ switch (*what) {
++ case 'S': {
++ funcinfo(ar, f);
++ break;
++ }
++ case 'l': {
++ ar->currentline = (ci) ? currentline(L, ci) : -1;
++ break;
++ }
++ case 'u': {
++ ar->nups = f->c.nupvalues;
++ break;
++ }
++ case 'n': {
++ ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
++ if (ar->namewhat == NULL) {
++ ar->namewhat = ""; /* not found */
++ ar->name = NULL;
++ }
++ break;
++ }
++ case 'L':
++ case 'f': /* handled by lua_getinfo */
++ break;
++ default: status = 0; /* invalid option */
++ }
++ }
++ return status;
++}
++
++
++LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
++ int status;
++ Closure *f = NULL;
++ CallInfo *ci = NULL;
++ lua_lock(L);
++ if (*what == '>') {
++ StkId func = L->top - 1;
++ luai_apicheck(L, ttisfunction(func));
++ what++; /* skip the '>' */
++ f = clvalue(func);
++ L->top--; /* pop function */
++ }
++ else if (ar->i_ci != 0) { /* no tail call? */
++ ci = L->base_ci + ar->i_ci;
++ lua_assert(ttisfunction(ci->func));
++ f = clvalue(ci->func);
++ }
++ status = auxgetinfo(L, what, ar, f, ci);
++ if (strchr(what, 'f')) {
++ if (f == NULL) setnilvalue(L->top);
++ else setclvalue(L, L->top, f);
++ incr_top(L);
++ }
++ if (strchr(what, 'L'))
++ collectvalidlines(L, f);
++ lua_unlock(L);
++ return status;
++}
++
++
++/*
++** {======================================================
++** Symbolic Execution and code checker
++** =======================================================
++*/
++
++#define check(x) if (!(x)) return 0;
++
++#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
++
++#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
++
++
++
++static int precheck (const Proto *pt) {
++ check(pt->maxstacksize <= MAXSTACK);
++ check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
++ check(!(pt->is_vararg & VARARG_NEEDSARG) ||
++ (pt->is_vararg & VARARG_HASARG));
++ check(pt->sizeupvalues <= pt->nups);
++ check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
++ check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
++ return 1;
++}
++
++
++#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
++
++int luaG_checkopenop (Instruction i) {
++ switch (GET_OPCODE(i)) {
++ case OP_CALL:
++ case OP_TAILCALL:
++ case OP_RETURN:
++ case OP_SETLIST: {
++ check(GETARG_B(i) == 0);
++ return 1;
++ }
++ default: return 0; /* invalid instruction after an open call */
++ }
++}
++
++
++static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
++ switch (mode) {
++ case OpArgN: check(r == 0); break;
++ case OpArgU: break;
++ case OpArgR: checkreg(pt, r); break;
++ case OpArgK:
++ check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
++ break;
++ }
++ return 1;
++}
++
++
++static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
++ int pc;
++ int last; /* stores position of last instruction that changed `reg' */
++ last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
++ check(precheck(pt));
++ for (pc = 0; pc < lastpc; pc++) {
++ Instruction i = pt->code[pc];
++ OpCode op = GET_OPCODE(i);
++ int a = GETARG_A(i);
++ int b = 0;
++ int c = 0;
++ check(op < NUM_OPCODES);
++ checkreg(pt, a);
++ switch (getOpMode(op)) {
++ case iABC: {
++ b = GETARG_B(i);
++ c = GETARG_C(i);
++ check(checkArgMode(pt, b, getBMode(op)));
++ check(checkArgMode(pt, c, getCMode(op)));
++ break;
++ }
++ case iABx: {
++ b = GETARG_Bx(i);
++ if (getBMode(op) == OpArgK) check(b < pt->sizek);
++ break;
++ }
++ case iAsBx: {
++ b = GETARG_sBx(i);
++ if (getBMode(op) == OpArgR) {
++ int dest = pc+1+b;
++ check(0 <= dest && dest < pt->sizecode);
++ if (dest > 0) {
++ int j;
++ /* check that it does not jump to a setlist count; this
++ is tricky, because the count from a previous setlist may
++ have the same value of an invalid setlist; so, we must
++ go all the way back to the first of them (if any) */
++ for (j = 0; j < dest; j++) {
++ Instruction d = pt->code[dest-1-j];
++ if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break;
++ }
++ /* if 'j' is even, previous value is not a setlist (even if
++ it looks like one) */
++ check((j&1) == 0);
++ }
++ }
++ break;
++ }
++ }
++ if (testAMode(op)) {
++ if (a == reg) last = pc; /* change register `a' */
++ }
++ if (testTMode(op)) {
++ check(pc+2 < pt->sizecode); /* check skip */
++ check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
++ }
++ switch (op) {
++ case OP_LOADBOOL: {
++ if (c == 1) { /* does it jump? */
++ check(pc+2 < pt->sizecode); /* check its jump */
++ check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST ||
++ GETARG_C(pt->code[pc+1]) != 0);
++ }
++ break;
++ }
++ case OP_LOADNIL: {
++ if (a <= reg && reg <= b)
++ last = pc; /* set registers from `a' to `b' */
++ break;
++ }
++ case OP_GETUPVAL:
++ case OP_SETUPVAL: {
++ check(b < pt->nups);
++ break;
++ }
++ case OP_GETGLOBAL:
++ case OP_SETGLOBAL: {
++ check(ttisstring(&pt->k[b]));
++ break;
++ }
++ case OP_SELF: {
++ checkreg(pt, a+1);
++ if (reg == a+1) last = pc;
++ break;
++ }
++ case OP_CONCAT: {
++ check(b < c); /* at least two operands */
++ break;
++ }
++ case OP_TFORLOOP: {
++ check(c >= 1); /* at least one result (control variable) */
++ checkreg(pt, a+2+c); /* space for results */
++ if (reg >= a+2) last = pc; /* affect all regs above its base */
++ break;
++ }
++ case OP_FORLOOP:
++ case OP_FORPREP:
++ checkreg(pt, a+3);
++ /* go through */
++ case OP_JMP: {
++ int dest = pc+1+b;
++ /* not full check and jump is forward and do not skip `lastpc'? */
++ if (reg != NO_REG && pc < dest && dest <= lastpc)
++ pc += b; /* do the jump */
++ break;
++ }
++ case OP_CALL:
++ case OP_TAILCALL: {
++ if (b != 0) {
++ checkreg(pt, a+b-1);
++ }
++ c--; /* c = num. returns */
++ if (c == LUA_MULTRET) {
++ check(checkopenop(pt, pc));
++ }
++ else if (c != 0)
++ checkreg(pt, a+c-1);
++ if (reg >= a) last = pc; /* affect all registers above base */
++ break;
++ }
++ case OP_RETURN: {
++ b--; /* b = num. returns */
++ if (b > 0) checkreg(pt, a+b-1);
++ break;
++ }
++ case OP_SETLIST: {
++ if (b > 0) checkreg(pt, a + b);
++ if (c == 0) {
++ pc++;
++ check(pc < pt->sizecode - 1);
++ }
++ break;
++ }
++ case OP_CLOSURE: {
++ int nup, j;
++ check(b < pt->sizep);
++ nup = pt->p[b]->nups;
++ check(pc + nup < pt->sizecode);
++ for (j = 1; j <= nup; j++) {
++ OpCode op1 = GET_OPCODE(pt->code[pc + j]);
++ check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
++ }
++ if (reg != NO_REG) /* tracing? */
++ pc += nup; /* do not 'execute' these pseudo-instructions */
++ break;
++ }
++ case OP_VARARG: {
++ check((pt->is_vararg & VARARG_ISVARARG) &&
++ !(pt->is_vararg & VARARG_NEEDSARG));
++ b--;
++ if (b == LUA_MULTRET) check(checkopenop(pt, pc));
++ checkreg(pt, a+b-1);
++ break;
++ }
++ default: break;
++ }
++ }
++ return pt->code[last];
++}
++
++#undef check
++#undef checkjump
++#undef checkreg
++
++/* }====================================================== */
++
++
++int luaG_checkcode (const Proto *pt) {
++ return (symbexec(pt, pt->sizecode, NO_REG) != 0);
++}
++
++
++static const char *kname (Proto *p, int c) {
++ if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
++ return svalue(&p->k[INDEXK(c)]);
++ else
++ return "?";
++}
++
++
++static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
++ const char **name) {
++ if (isLua(ci)) { /* a Lua function? */
++ Proto *p = ci_func(ci)->l.p;
++ int pc = currentpc(L, ci);
++ Instruction i;
++ *name = luaF_getlocalname(p, stackpos+1, pc);
++ if (*name) /* is a local? */
++ return "local";
++ i = symbexec(p, pc, stackpos); /* try symbolic execution */
++ lua_assert(pc != -1);
++ switch (GET_OPCODE(i)) {
++ case OP_GETGLOBAL: {
++ int g = GETARG_Bx(i); /* global index */
++ lua_assert(ttisstring(&p->k[g]));
++ *name = svalue(&p->k[g]);
++ return "global";
++ }
++ case OP_MOVE: {
++ int a = GETARG_A(i);
++ int b = GETARG_B(i); /* move from `b' to `a' */
++ if (b < a)
++ return getobjname(L, ci, b, name); /* get name for `b' */
++ break;
++ }
++ case OP_GETTABLE: {
++ int k = GETARG_C(i); /* key index */
++ *name = kname(p, k);
++ return "field";
++ }
++ case OP_GETUPVAL: {
++ int u = GETARG_B(i); /* upvalue index */
++ *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
++ return "upvalue";
++ }
++ case OP_SELF: {
++ int k = GETARG_C(i); /* key index */
++ *name = kname(p, k);
++ return "method";
++ }
++ default: break;
++ }
++ }
++ return NULL; /* no useful name found */
++}
++
++
++static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
++ Instruction i;
++ if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
++ return NULL; /* calling function is not Lua (or is unknown) */
++ ci--; /* calling function */
++ i = ci_func(ci)->l.p->code[currentpc(L, ci)];
++ if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
++ GET_OPCODE(i) == OP_TFORLOOP)
++ return getobjname(L, ci, GETARG_A(i), name);
++ else
++ return NULL; /* no useful name can be found */
++}
++
++
++/* only ANSI way to check whether a pointer points to an array */
++static int isinstack (CallInfo *ci, const TValue *o) {
++ StkId p;
++ for (p = ci->base; p < ci->top; p++)
++ if (o == p) return 1;
++ return 0;
++}
++
++
++void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
++ const char *name = NULL;
++ const char *t = luaT_typenames[ttype(o)];
++ const char *kind = (isinstack(L->ci, o)) ?
++ getobjname(L, L->ci, cast_int(o - L->base), &name) :
++ NULL;
++ if (kind)
++ luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
++ op, kind, name, t);
++ else
++ luaG_runerror(L, "attempt to %s a %s value", op, t);
++}
++
++
++void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
++ if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
++ lua_assert(!ttisstring(p1) && !ttisnumber(p1));
++ luaG_typeerror(L, p1, "concatenate");
++}
++
++
++void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
++ TValue temp;
++ if (luaV_tonumber(p1, &temp) == NULL)
++ p2 = p1; /* first operand is wrong */
++ luaG_typeerror(L, p2, "perform arithmetic on");
++}
++
++
++int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
++ const char *t1 = luaT_typenames[ttype(p1)];
++ const char *t2 = luaT_typenames[ttype(p2)];
++ if (t1[2] == t2[2])
++ luaG_runerror(L, "attempt to compare two %s values", t1);
++ else
++ luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
++ return 0;
++}
++
++
++static void addinfo (lua_State *L, const char *msg) {
++ CallInfo *ci = L->ci;
++ if (isLua(ci)) { /* is Lua code? */
++ char buff[LUA_IDSIZE]; /* add file:line information */
++ int line = currentline(L, ci);
++ luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
++ luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
++ }
++}
++
++
++void luaG_errormsg (lua_State *L) {
++ if (L->errfunc != 0) { /* is there an error handling function? */
++ StkId errfunc = restorestack(L, L->errfunc);
++ if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
++ setobjs2s(L, L->top, L->top - 1); /* move argument */
++ setobjs2s(L, L->top - 1, errfunc); /* push function */
++ incr_top(L);
++ luaD_call(L, L->top - 2, 1); /* call it */
++ }
++ luaD_throw(L, LUA_ERRRUN);
++}
++
++
++void luaG_runerror (lua_State *L, const char *fmt, ...) {
++ va_list argp;
++ va_start(argp, fmt);
++ addinfo(L, luaO_pushvfstring(L, fmt, argp));
++ va_end(argp);
++ luaG_errormsg(L);
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/ldebug.h
+@@ -0,0 +1,33 @@
++/*
++** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $
++** Auxiliary functions from Debug Interface module
++** See Copyright Notice in lua.h
++*/
++
++#ifndef ldebug_h
++#define ldebug_h
++
++
++#include "lstate.h"
++
++
++#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
++
++#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
++
++#define resethookcount(L) (L->hookcount = L->basehookcount)
++
++
++LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
++ const char *opname);
++LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
++LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
++ const TValue *p2);
++LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
++ const TValue *p2);
++LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
++LUAI_FUNC void luaG_errormsg (lua_State *L);
++LUAI_FUNC int luaG_checkcode (const Proto *pt);
++LUAI_FUNC int luaG_checkopenop (Instruction i);
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/ldo.c
+@@ -0,0 +1,515 @@
++/*
++** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $
++** Stack and Call structure of Lua
++** See Copyright Notice in lua.h
++*/
++
++#include <setjmp.h>
++#include <stdlib.h>
++#include <string.h>
++
++#define ldo_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "ldebug.h"
++#include "ldo.h"
++#include "lfunc.h"
++#include "lgc.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lopcodes.h"
++#include "lparser.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "ltable.h"
++#include "ltm.h"
++#include "lundump.h"
++#include "lvm.h"
++#include "lzio.h"
++
++
++
++/*
++** {======================================================
++** Error-recovery functions
++** =======================================================
++*/
++
++
++/* chain list of long jump buffers */
++struct lua_longjmp {
++ struct lua_longjmp *previous;
++ luai_jmpbuf b;
++ volatile int status; /* error code */
++};
++
++
++void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
++ switch (errcode) {
++ case LUA_ERRMEM: {
++ setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
++ break;
++ }
++ case LUA_ERRERR: {
++ setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
++ break;
++ }
++ case LUA_ERRSYNTAX:
++ case LUA_ERRRUN: {
++ setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
++ break;
++ }
++ }
++ L->top = oldtop + 1;
++}
++
++
++static void restore_stack_limit (lua_State *L) {
++ lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
++ if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
++ int inuse = cast_int(L->ci - L->base_ci);
++ if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
++ luaD_reallocCI(L, LUAI_MAXCALLS);
++ }
++}
++
++
++static void resetstack (lua_State *L, int status) {
++ L->ci = L->base_ci;
++ L->base = L->ci->base;
++ luaF_close(L, L->base); /* close eventual pending closures */
++ luaD_seterrorobj(L, status, L->base);
++ L->nCcalls = L->baseCcalls;
++ L->allowhook = 1;
++ restore_stack_limit(L);
++ L->errfunc = 0;
++ L->errorJmp = NULL;
++}
++
++
++void luaD_throw (lua_State *L, int errcode) {
++ if (L->errorJmp) {
++ L->errorJmp->status = errcode;
++ LUAI_THROW(L, L->errorJmp);
++ }
++ else {
++ L->status = cast_byte(errcode);
++ if (G(L)->panic) {
++ resetstack(L, errcode);
++ lua_unlock(L);
++ G(L)->panic(L);
++ }
++ exit(EXIT_FAILURE);
++ }
++}
++
++
++int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
++ struct lua_longjmp lj;
++ lj.status = 0;
++ lj.previous = L->errorJmp; /* chain new error handler */
++ L->errorJmp = &lj;
++ LUAI_TRY(L, &lj,
++ (*f)(L, ud);
++ );
++ L->errorJmp = lj.previous; /* restore old error handler */
++ return lj.status;
++}
++
++/* }====================================================== */
++
++
++static void correctstack (lua_State *L, TValue *oldstack) {
++ CallInfo *ci;
++ GCObject *up;
++ L->top = (L->top - oldstack) + L->stack;
++ for (up = L->openupval; up != NULL; up = up->gch.next)
++ gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
++ for (ci = L->base_ci; ci <= L->ci; ci++) {
++ ci->top = (ci->top - oldstack) + L->stack;
++ ci->base = (ci->base - oldstack) + L->stack;
++ ci->func = (ci->func - oldstack) + L->stack;
++ }
++ L->base = (L->base - oldstack) + L->stack;
++}
++
++
++void luaD_reallocstack (lua_State *L, int newsize) {
++ TValue *oldstack = L->stack;
++ int realsize = newsize + 1 + EXTRA_STACK;
++ lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
++ luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
++ L->stacksize = realsize;
++ L->stack_last = L->stack+newsize;
++ correctstack(L, oldstack);
++}
++
++
++void luaD_reallocCI (lua_State *L, int newsize) {
++ CallInfo *oldci = L->base_ci;
++ luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
++ L->size_ci = newsize;
++ L->ci = (L->ci - oldci) + L->base_ci;
++ L->end_ci = L->base_ci + L->size_ci - 1;
++}
++
++
++void luaD_growstack (lua_State *L, int n) {
++ if (n <= L->stacksize) /* double size is enough? */
++ luaD_reallocstack(L, 2*L->stacksize);
++ else
++ luaD_reallocstack(L, L->stacksize + n);
++}
++
++
++static CallInfo *growCI (lua_State *L) {
++ if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */
++ luaD_throw(L, LUA_ERRERR);
++ else {
++ luaD_reallocCI(L, 2*L->size_ci);
++ if (L->size_ci > LUAI_MAXCALLS)
++ luaG_runerror(L, "stack overflow");
++ }
++ return ++L->ci;
++}
++
++
++void luaD_callhook (lua_State *L, int event, int line) {
++ lua_Hook hook = L->hook;
++ if (hook && L->allowhook) {
++ ptrdiff_t top = savestack(L, L->top);
++ ptrdiff_t ci_top = savestack(L, L->ci->top);
++ lua_Debug ar;
++ ar.event = event;
++ ar.currentline = line;
++ if (event == LUA_HOOKTAILRET)
++ ar.i_ci = 0; /* tail call; no debug information about it */
++ else
++ ar.i_ci = cast_int(L->ci - L->base_ci);
++ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
++ L->ci->top = L->top + LUA_MINSTACK;
++ lua_assert(L->ci->top <= L->stack_last);
++ L->allowhook = 0; /* cannot call hooks inside a hook */
++ lua_unlock(L);
++ (*hook)(L, &ar);
++ lua_lock(L);
++ lua_assert(!L->allowhook);
++ L->allowhook = 1;
++ L->ci->top = restorestack(L, ci_top);
++ L->top = restorestack(L, top);
++ }
++}
++
++
++static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
++ int i;
++ int nfixargs = p->numparams;
++ Table *htab = NULL;
++ StkId base, fixed;
++ for (; actual < nfixargs; ++actual)
++ setnilvalue(L->top++);
++#if defined(LUA_COMPAT_VARARG)
++ if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
++ int nvar = actual - nfixargs; /* number of extra arguments */
++ lua_assert(p->is_vararg & VARARG_HASARG);
++ luaC_checkGC(L);
++ htab = luaH_new(L, nvar, 1); /* create `arg' table */
++ for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
++ setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
++ /* store counter in field `n' */
++ setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
++ }
++#endif
++ /* move fixed parameters to final position */
++ fixed = L->top - actual; /* first fixed argument */
++ base = L->top; /* final position of first argument */
++ for (i=0; i<nfixargs; i++) {
++ setobjs2s(L, L->top++, fixed+i);
++ setnilvalue(fixed+i);
++ }
++ /* add `arg' parameter */
++ if (htab) {
++ sethvalue(L, L->top++, htab);
++ lua_assert(iswhite(obj2gco(htab)));
++ }
++ return base;
++}
++
++
++static StkId tryfuncTM (lua_State *L, StkId func) {
++ const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
++ StkId p;
++ ptrdiff_t funcr = savestack(L, func);
++ if (!ttisfunction(tm))
++ luaG_typeerror(L, func, "call");
++ /* Open a hole inside the stack at `func' */
++ for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
++ incr_top(L);
++ func = restorestack(L, funcr); /* previous call may change stack */
++ setobj2s(L, func, tm); /* tag method is the new function to be called */
++ return func;
++}
++
++
++
++#define inc_ci(L) \
++ ((L->ci == L->end_ci) ? growCI(L) : \
++ (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
++
++
++int luaD_precall (lua_State *L, StkId func, int nresults) {
++ LClosure *cl;
++ ptrdiff_t funcr;
++ if (!ttisfunction(func)) /* `func' is not a function? */
++ func = tryfuncTM(L, func); /* check the `function' tag method */
++ funcr = savestack(L, func);
++ cl = &clvalue(func)->l;
++ L->ci->savedpc = L->savedpc;
++ if (!cl->isC) { /* Lua function? prepare its call */
++ CallInfo *ci;
++ StkId st, base;
++ Proto *p = cl->p;
++ luaD_checkstack(L, p->maxstacksize);
++ func = restorestack(L, funcr);
++ if (!p->is_vararg) { /* no varargs? */
++ base = func + 1;
++ if (L->top > base + p->numparams)
++ L->top = base + p->numparams;
++ }
++ else { /* vararg function */
++ int nargs = cast_int(L->top - func) - 1;
++ base = adjust_varargs(L, p, nargs);
++ func = restorestack(L, funcr); /* previous call may change the stack */
++ }
++ ci = inc_ci(L); /* now `enter' new function */
++ ci->func = func;
++ L->base = ci->base = base;
++ ci->top = L->base + p->maxstacksize;
++ lua_assert(ci->top <= L->stack_last);
++ L->savedpc = p->code; /* starting point */
++ ci->tailcalls = 0;
++ ci->nresults = nresults;
++ for (st = L->top; st < ci->top; st++)
++ setnilvalue(st);
++ L->top = ci->top;
++ if (L->hookmask & LUA_MASKCALL) {
++ L->savedpc++; /* hooks assume 'pc' is already incremented */
++ luaD_callhook(L, LUA_HOOKCALL, -1);
++ L->savedpc--; /* correct 'pc' */
++ }
++ return PCRLUA;
++ }
++ else { /* if is a C function, call it */
++ CallInfo *ci;
++ int n;
++ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
++ ci = inc_ci(L); /* now `enter' new function */
++ ci->func = restorestack(L, funcr);
++ L->base = ci->base = ci->func + 1;
++ ci->top = L->top + LUA_MINSTACK;
++ lua_assert(ci->top <= L->stack_last);
++ ci->nresults = nresults;
++ if (L->hookmask & LUA_MASKCALL)
++ luaD_callhook(L, LUA_HOOKCALL, -1);
++ lua_unlock(L);
++ n = (*curr_func(L)->c.f)(L); /* do the actual call */
++ lua_lock(L);
++ if (n < 0) /* yielding? */
++ return PCRYIELD;
++ else {
++ luaD_poscall(L, L->top - n);
++ return PCRC;
++ }
++ }
++}
++
++
++static StkId callrethooks (lua_State *L, StkId firstResult) {
++ ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
++ luaD_callhook(L, LUA_HOOKRET, -1);
++ if (f_isLua(L->ci)) { /* Lua function? */
++ while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */
++ luaD_callhook(L, LUA_HOOKTAILRET, -1);
++ }
++ return restorestack(L, fr);
++}
++
++
++int luaD_poscall (lua_State *L, StkId firstResult) {
++ StkId res;
++ int wanted, i;
++ CallInfo *ci;
++ if (L->hookmask & LUA_MASKRET)
++ firstResult = callrethooks(L, firstResult);
++ ci = L->ci--;
++ res = ci->func; /* res == final position of 1st result */
++ wanted = ci->nresults;
++ L->base = (ci - 1)->base; /* restore base */
++ L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
++ /* move results to correct place */
++ for (i = wanted; i != 0 && firstResult < L->top; i--)
++ setobjs2s(L, res++, firstResult++);
++ while (i-- > 0)
++ setnilvalue(res++);
++ L->top = res;
++ return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
++}
++
++
++/*
++** Call a function (C or Lua). The function to be called is at *func.
++** The arguments are on the stack, right after the function.
++** When returns, all the results are on the stack, starting at the original
++** function position.
++*/
++void luaD_call (lua_State *L, StkId func, int nResults) {
++ if (++L->nCcalls >= LUAI_MAXCCALLS) {
++ if (L->nCcalls == LUAI_MAXCCALLS)
++ luaG_runerror(L, "C stack overflow");
++ else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
++ luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
++ }
++ if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
++ luaV_execute(L, 1); /* call it */
++ L->nCcalls--;
++ luaC_checkGC(L);
++}
++
++
++static void resume (lua_State *L, void *ud) {
++ StkId firstArg = cast(StkId, ud);
++ CallInfo *ci = L->ci;
++ if (L->status == 0) { /* start coroutine? */
++ lua_assert(ci == L->base_ci && firstArg > L->base);
++ if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
++ return;
++ }
++ else { /* resuming from previous yield */
++ lua_assert(L->status == LUA_YIELD);
++ L->status = 0;
++ if (!f_isLua(ci)) { /* `common' yield? */
++ /* finish interrupted execution of `OP_CALL' */
++ lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
++ GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
++ if (luaD_poscall(L, firstArg)) /* complete it... */
++ L->top = L->ci->top; /* and correct top if not multiple results */
++ }
++ else /* yielded inside a hook: just continue its execution */
++ L->base = L->ci->base;
++ }
++ luaV_execute(L, cast_int(L->ci - L->base_ci));
++}
++
++
++static int resume_error (lua_State *L, const char *msg) {
++ L->top = L->ci->base;
++ setsvalue2s(L, L->top, luaS_new(L, msg));
++ incr_top(L);
++ lua_unlock(L);
++ return LUA_ERRRUN;
++}
++
++
++LUA_API int lua_resume (lua_State *L, int nargs) {
++ int status;
++ lua_lock(L);
++ if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci))
++ return resume_error(L, "cannot resume non-suspended coroutine");
++ if (L->nCcalls >= LUAI_MAXCCALLS)
++ return resume_error(L, "C stack overflow");
++ luai_userstateresume(L, nargs);
++ lua_assert(L->errfunc == 0);
++ L->baseCcalls = ++L->nCcalls;
++ status = luaD_rawrunprotected(L, resume, L->top - nargs);
++ if (status != 0) { /* error? */
++ L->status = cast_byte(status); /* mark thread as `dead' */
++ luaD_seterrorobj(L, status, L->top);
++ L->ci->top = L->top;
++ }
++ else {
++ lua_assert(L->nCcalls == L->baseCcalls);
++ status = L->status;
++ }
++ --L->nCcalls;
++ lua_unlock(L);
++ return status;
++}
++
++
++LUA_API int lua_yield (lua_State *L, int nresults) {
++ luai_userstateyield(L, nresults);
++ lua_lock(L);
++ if (L->nCcalls > L->baseCcalls)
++ luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
++ L->base = L->top - nresults; /* protect stack slots below */
++ L->status = LUA_YIELD;
++ lua_unlock(L);
++ return -1;
++}
++
++
++int luaD_pcall (lua_State *L, Pfunc func, void *u,
++ ptrdiff_t old_top, ptrdiff_t ef) {
++ int status;
++ unsigned short oldnCcalls = L->nCcalls;
++ ptrdiff_t old_ci = saveci(L, L->ci);
++ lu_byte old_allowhooks = L->allowhook;
++ ptrdiff_t old_errfunc = L->errfunc;
++ L->errfunc = ef;
++ status = luaD_rawrunprotected(L, func, u);
++ if (status != 0) { /* an error occurred? */
++ StkId oldtop = restorestack(L, old_top);
++ luaF_close(L, oldtop); /* close eventual pending closures */
++ luaD_seterrorobj(L, status, oldtop);
++ L->nCcalls = oldnCcalls;
++ L->ci = restoreci(L, old_ci);
++ L->base = L->ci->base;
++ L->savedpc = L->ci->savedpc;
++ L->allowhook = old_allowhooks;
++ restore_stack_limit(L);
++ }
++ L->errfunc = old_errfunc;
++ return status;
++}
++
++
++
++/*
++** Execute a protected parser.
++*/
++struct SParser { /* data to `f_parser' */
++ ZIO *z;
++ Mbuffer buff; /* buffer to be used by the scanner */
++ const char *name;
++};
++
++static void f_parser (lua_State *L, void *ud) {
++ int i;
++ Proto *tf;
++ Closure *cl;
++ struct SParser *p = cast(struct SParser *, ud);
++ int c = luaZ_lookahead(p->z);
++ luaC_checkGC(L);
++ tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
++ &p->buff, p->name);
++ cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
++ cl->l.p = tf;
++ for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
++ cl->l.upvals[i] = luaF_newupval(L);
++ setclvalue(L, L->top, cl);
++ incr_top(L);
++}
++
++
++int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
++ struct SParser p;
++ int status;
++ p.z = z; p.name = name;
++ luaZ_initbuffer(L, &p.buff);
++ status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
++ luaZ_freebuffer(L, &p.buff);
++ return status;
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/ldo.h
+@@ -0,0 +1,57 @@
++/*
++** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $
++** Stack and Call structure of Lua
++** See Copyright Notice in lua.h
++*/
++
++#ifndef ldo_h
++#define ldo_h
++
++
++#include "lobject.h"
++#include "lstate.h"
++#include "lzio.h"
++
++
++#define luaD_checkstack(L,n) \
++ if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
++ luaD_growstack(L, n); \
++ else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
++
++
++#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
++
++#define savestack(L,p) ((char *)(p) - (char *)L->stack)
++#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
++
++#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
++#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
++
++
++/* results from luaD_precall */
++#define PCRLUA 0 /* initiated a call to a Lua function */
++#define PCRC 1 /* did a call to a C function */
++#define PCRYIELD 2 /* C funtion yielded */
++
++
++/* type of protected functions, to be ran by `runprotected' */
++typedef void (*Pfunc) (lua_State *L, void *ud);
++
++LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
++LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line);
++LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
++LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
++LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
++ ptrdiff_t oldtop, ptrdiff_t ef);
++LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
++LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
++LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
++LUAI_FUNC void luaD_growstack (lua_State *L, int n);
++
++LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
++LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
++
++LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
++
++#endif
++
+--- /dev/null
++++ b/extensions/LUA/lua/ldump.c
+@@ -0,0 +1,164 @@
++/*
++** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
++** save precompiled Lua chunks
++** See Copyright Notice in lua.h
++*/
++
++#include <stddef.h>
++
++#define ldump_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "lobject.h"
++#include "lstate.h"
++#include "lundump.h"
++
++typedef struct {
++ lua_State* L;
++ lua_Writer writer;
++ void* data;
++ int strip;
++ int status;
++} DumpState;
++
++#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
++#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
++
++static void DumpBlock(const void* b, size_t size, DumpState* D)
++{
++ if (D->status==0)
++ {
++ lua_unlock(D->L);
++ D->status=(*D->writer)(D->L,b,size,D->data);
++ lua_lock(D->L);
++ }
++}
++
++static void DumpChar(int y, DumpState* D)
++{
++ char x=(char)y;
++ DumpVar(x,D);
++}
++
++static void DumpInt(int x, DumpState* D)
++{
++ DumpVar(x,D);
++}
++
++static void DumpNumber(lua_Number x, DumpState* D)
++{
++ DumpVar(x,D);
++}
++
++static void DumpVector(const void* b, int n, size_t size, DumpState* D)
++{
++ DumpInt(n,D);
++ DumpMem(b,n,size,D);
++}
++
++static void DumpString(const TString* s, DumpState* D)
++{
++ if (s==NULL || getstr(s)==NULL)
++ {
++ size_t size=0;
++ DumpVar(size,D);
++ }
++ else
++ {
++ size_t size=s->tsv.len+1; /* include trailing '\0' */
++ DumpVar(size,D);
++ DumpBlock(getstr(s),size,D);
++ }
++}
++
++#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
++
++static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
++
++static void DumpConstants(const Proto* f, DumpState* D)
++{
++ int i,n=f->sizek;
++ DumpInt(n,D);
++ for (i=0; i<n; i++)
++ {
++ const TValue* o=&f->k[i];
++ DumpChar(ttype(o),D);
++ switch (ttype(o))
++ {
++ case LUA_TNIL:
++ break;
++ case LUA_TBOOLEAN:
++ DumpChar(bvalue(o),D);
++ break;
++ case LUA_TNUMBER:
++ DumpNumber(nvalue(o),D);
++ break;
++ case LUA_TSTRING:
++ DumpString(rawtsvalue(o),D);
++ break;
++ default:
++ lua_assert(0); /* cannot happen */
++ break;
++ }
++ }
++ n=f->sizep;
++ DumpInt(n,D);
++ for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
++}
++
++static void DumpDebug(const Proto* f, DumpState* D)
++{
++ int i,n;
++ n= (D->strip) ? 0 : f->sizelineinfo;
++ DumpVector(f->lineinfo,n,sizeof(int),D);
++ n= (D->strip) ? 0 : f->sizelocvars;
++ DumpInt(n,D);
++ for (i=0; i<n; i++)
++ {
++ DumpString(f->locvars[i].varname,D);
++ DumpInt(f->locvars[i].startpc,D);
++ DumpInt(f->locvars[i].endpc,D);
++ }
++ n= (D->strip) ? 0 : f->sizeupvalues;
++ DumpInt(n,D);
++ for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
++}
++
++static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
++{
++ DumpString((f->source==p || D->strip) ? NULL : f->source,D);
++ DumpInt(f->linedefined,D);
++ DumpInt(f->lastlinedefined,D);
++ DumpChar(f->nups,D);
++ DumpChar(f->numparams,D);
++ DumpChar(f->is_vararg,D);
++ DumpChar(f->maxstacksize,D);
++ DumpCode(f,D);
++ DumpConstants(f,D);
++ DumpDebug(f,D);
++}
++
++static void DumpHeader(DumpState* D)
++{
++ char h[LUAC_HEADERSIZE];
++ luaU_header(h);
++ DumpBlock(h,LUAC_HEADERSIZE,D);
++}
++
++/*
++** dump Lua function as precompiled chunk
++*/
++int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
++{
++ DumpState D;
++ D.L=L;
++ D.writer=w;
++ D.data=data;
++ D.strip=strip;
++ D.status=0;
++ DumpHeader(&D);
++ DumpFunction(f,NULL,&D);
++ return D.status;
++}
+--- /dev/null
++++ b/extensions/LUA/lua/lfunc.c
+@@ -0,0 +1,174 @@
++/*
++** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $
++** Auxiliary functions to manipulate prototypes and closures
++** See Copyright Notice in lua.h
++*/
++
++
++#include <stddef.h>
++
++#define lfunc_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "lfunc.h"
++#include "lgc.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lstate.h"
++
++
++
++Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
++ Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
++ luaC_link(L, obj2gco(c), LUA_TFUNCTION);
++ c->c.isC = 1;
++ c->c.env = e;
++ c->c.nupvalues = cast_byte(nelems);
++ return c;
++}
++
++
++Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
++ Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
++ luaC_link(L, obj2gco(c), LUA_TFUNCTION);
++ c->l.isC = 0;
++ c->l.env = e;
++ c->l.nupvalues = cast_byte(nelems);
++ while (nelems--) c->l.upvals[nelems] = NULL;
++ return c;
++}
++
++
++UpVal *luaF_newupval (lua_State *L) {
++ UpVal *uv = luaM_new(L, UpVal);
++ luaC_link(L, obj2gco(uv), LUA_TUPVAL);
++ uv->v = &uv->u.value;
++ setnilvalue(uv->v);
++ return uv;
++}
++
++
++UpVal *luaF_findupval (lua_State *L, StkId level) {
++ global_State *g = G(L);
++ GCObject **pp = &L->openupval;
++ UpVal *p;
++ UpVal *uv;
++ while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) {
++ lua_assert(p->v != &p->u.value);
++ if (p->v == level) { /* found a corresponding upvalue? */
++ if (isdead(g, obj2gco(p))) /* is it dead? */
++ changewhite(obj2gco(p)); /* ressurect it */
++ return p;
++ }
++ pp = &p->next;
++ }
++ uv = luaM_new(L, UpVal); /* not found: create a new one */
++ uv->tt = LUA_TUPVAL;
++ uv->marked = luaC_white(g);
++ uv->v = level; /* current value lives in the stack */
++ uv->next = *pp; /* chain it in the proper position */
++ *pp = obj2gco(uv);
++ uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
++ uv->u.l.next = g->uvhead.u.l.next;
++ uv->u.l.next->u.l.prev = uv;
++ g->uvhead.u.l.next = uv;
++ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
++ return uv;
++}
++
++
++static void unlinkupval (UpVal *uv) {
++ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
++ uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
++ uv->u.l.prev->u.l.next = uv->u.l.next;
++}
++
++
++void luaF_freeupval (lua_State *L, UpVal *uv) {
++ if (uv->v != &uv->u.value) /* is it open? */
++ unlinkupval(uv); /* remove from open list */
++ luaM_free(L, uv); /* free upvalue */
++}
++
++
++void luaF_close (lua_State *L, StkId level) {
++ UpVal *uv;
++ global_State *g = G(L);
++ while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) {
++ GCObject *o = obj2gco(uv);
++ lua_assert(!isblack(o) && uv->v != &uv->u.value);
++ L->openupval = uv->next; /* remove from `open' list */
++ if (isdead(g, o))
++ luaF_freeupval(L, uv); /* free upvalue */
++ else {
++ unlinkupval(uv);
++ setobj(L, &uv->u.value, uv->v);
++ uv->v = &uv->u.value; /* now current value lives here */
++ luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
++ }
++ }
++}
++
++
++Proto *luaF_newproto (lua_State *L) {
++ Proto *f = luaM_new(L, Proto);
++ luaC_link(L, obj2gco(f), LUA_TPROTO);
++ f->k = NULL;
++ f->sizek = 0;
++ f->p = NULL;
++ f->sizep = 0;
++ f->code = NULL;
++ f->sizecode = 0;
++ f->sizelineinfo = 0;
++ f->sizeupvalues = 0;
++ f->nups = 0;
++ f->upvalues = NULL;
++ f->numparams = 0;
++ f->is_vararg = 0;
++ f->maxstacksize = 0;
++ f->lineinfo = NULL;
++ f->sizelocvars = 0;
++ f->locvars = NULL;
++ f->linedefined = 0;
++ f->lastlinedefined = 0;
++ f->source = NULL;
++ return f;
++}
++
++
++void luaF_freeproto (lua_State *L, Proto *f) {
++ luaM_freearray(L, f->code, f->sizecode, Instruction);
++ luaM_freearray(L, f->p, f->sizep, Proto *);
++ luaM_freearray(L, f->k, f->sizek, TValue);
++ luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
++ luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
++ luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
++ luaM_free(L, f);
++}
++
++
++void luaF_freeclosure (lua_State *L, Closure *c) {
++ int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
++ sizeLclosure(c->l.nupvalues);
++ luaM_freemem(L, c, size);
++}
++
++
++/*
++** Look for n-th local variable at line `line' in function `func'.
++** Returns NULL if not found.
++*/
++const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
++ int i;
++ for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
++ if (pc < f->locvars[i].endpc) { /* is variable active? */
++ local_number--;
++ if (local_number == 0)
++ return getstr(f->locvars[i].varname);
++ }
++ }
++ return NULL; /* not found */
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/lfunc.h
+@@ -0,0 +1,34 @@
++/*
++** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $
++** Auxiliary functions to manipulate prototypes and closures
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lfunc_h
++#define lfunc_h
++
++
++#include "lobject.h"
++
++
++#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
++ cast(int, sizeof(TValue)*((n)-1)))
++
++#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
++ cast(int, sizeof(TValue *)*((n)-1)))
++
++
++LUAI_FUNC Proto *luaF_newproto (lua_State *L);
++LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
++LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
++LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
++LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
++LUAI_FUNC void luaF_close (lua_State *L, StkId level);
++LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
++LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
++LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
++LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
++ int pc);
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lgc.c
+@@ -0,0 +1,711 @@
++/*
++** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $
++** Garbage Collector
++** See Copyright Notice in lua.h
++*/
++
++#include <string.h>
++
++#define lgc_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "ldebug.h"
++#include "ldo.h"
++#include "lfunc.h"
++#include "lgc.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "ltable.h"
++#include "ltm.h"
++
++
++#define GCSTEPSIZE 1024u
++#define GCSWEEPMAX 40
++#define GCSWEEPCOST 10
++#define GCFINALIZECOST 100
++
++
++#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
++
++#define makewhite(g,x) \
++ ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g)))
++
++#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
++#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
++
++#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
++
++
++#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
++#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
++
++
++#define KEYWEAK bitmask(KEYWEAKBIT)
++#define VALUEWEAK bitmask(VALUEWEAKBIT)
++
++
++
++#define markvalue(g,o) { checkconsistency(o); \
++ if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }
++
++#define markobject(g,t) { if (iswhite(obj2gco(t))) \
++ reallymarkobject(g, obj2gco(t)); }
++
++
++#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
++
++
++static void removeentry (Node *n) {
++ lua_assert(ttisnil(gval(n)));
++ if (iscollectable(gkey(n)))
++ setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
++}
++
++
++static void reallymarkobject (global_State *g, GCObject *o) {
++ lua_assert(iswhite(o) && !isdead(g, o));
++ white2gray(o);
++ switch (o->gch.tt) {
++ case LUA_TSTRING: {
++ return;
++ }
++ case LUA_TUSERDATA: {
++ Table *mt = gco2u(o)->metatable;
++ gray2black(o); /* udata are never gray */
++ if (mt) markobject(g, mt);
++ markobject(g, gco2u(o)->env);
++ return;
++ }
++ case LUA_TUPVAL: {
++ UpVal *uv = gco2uv(o);
++ markvalue(g, uv->v);
++ if (uv->v == &uv->u.value) /* closed? */
++ gray2black(o); /* open upvalues are never black */
++ return;
++ }
++ case LUA_TFUNCTION: {
++ gco2cl(o)->c.gclist = g->gray;
++ g->gray = o;
++ break;
++ }
++ case LUA_TTABLE: {
++ gco2h(o)->gclist = g->gray;
++ g->gray = o;
++ break;
++ }
++ case LUA_TTHREAD: {
++ gco2th(o)->gclist = g->gray;
++ g->gray = o;
++ break;
++ }
++ case LUA_TPROTO: {
++ gco2p(o)->gclist = g->gray;
++ g->gray = o;
++ break;
++ }
++ default: lua_assert(0);
++ }
++}
++
++
++static void marktmu (global_State *g) {
++ GCObject *u = g->tmudata;
++ if (u) {
++ do {
++ u = u->gch.next;
++ makewhite(g, u); /* may be marked, if left from previous GC */
++ reallymarkobject(g, u);
++ } while (u != g->tmudata);
++ }
++}
++
++
++/* move `dead' udata that need finalization to list `tmudata' */
++size_t luaC_separateudata (lua_State *L, int all) {
++ global_State *g = G(L);
++ size_t deadmem = 0;
++ GCObject **p = &g->mainthread->next;
++ GCObject *curr;
++ while ((curr = *p) != NULL) {
++ if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
++ p = &curr->gch.next; /* don't bother with them */
++ else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
++ markfinalized(gco2u(curr)); /* don't need finalization */
++ p = &curr->gch.next;
++ }
++ else { /* must call its gc method */
++ deadmem += sizeudata(gco2u(curr));
++ markfinalized(gco2u(curr));
++ *p = curr->gch.next;
++ /* link `curr' at the end of `tmudata' list */
++ if (g->tmudata == NULL) /* list is empty? */
++ g->tmudata = curr->gch.next = curr; /* creates a circular list */
++ else {
++ curr->gch.next = g->tmudata->gch.next;
++ g->tmudata->gch.next = curr;
++ g->tmudata = curr;
++ }
++ }
++ }
++ return deadmem;
++}
++
++
++static int traversetable (global_State *g, Table *h) {
++ int i;
++ int weakkey = 0;
++ int weakvalue = 0;
++ const TValue *mode;
++ if (h->metatable)
++ markobject(g, h->metatable);
++ mode = gfasttm(g, h->metatable, TM_MODE);
++ if (mode && ttisstring(mode)) { /* is there a weak mode? */
++ weakkey = (strchr(svalue(mode), 'k') != NULL);
++ weakvalue = (strchr(svalue(mode), 'v') != NULL);
++ if (weakkey || weakvalue) { /* is really weak? */
++ h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
++ h->marked |= cast_byte((weakkey << KEYWEAKBIT) |
++ (weakvalue << VALUEWEAKBIT));
++ h->gclist = g->weak; /* must be cleared after GC, ... */
++ g->weak = obj2gco(h); /* ... so put in the appropriate list */
++ }
++ }
++ if (weakkey && weakvalue) return 1;
++ if (!weakvalue) {
++ i = h->sizearray;
++ while (i--)
++ markvalue(g, &h->array[i]);
++ }
++ i = sizenode(h);
++ while (i--) {
++ Node *n = gnode(h, i);
++ lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
++ if (ttisnil(gval(n)))
++ removeentry(n); /* remove empty entries */
++ else {
++ lua_assert(!ttisnil(gkey(n)));
++ if (!weakkey) markvalue(g, gkey(n));
++ if (!weakvalue) markvalue(g, gval(n));
++ }
++ }
++ return weakkey || weakvalue;
++}
++
++
++/*
++** All marks are conditional because a GC may happen while the
++** prototype is still being created
++*/
++static void traverseproto (global_State *g, Proto *f) {
++ int i;
++ if (f->source) stringmark(f->source);
++ for (i=0; i<f->sizek; i++) /* mark literals */
++ markvalue(g, &f->k[i]);
++ for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
++ if (f->upvalues[i])
++ stringmark(f->upvalues[i]);
++ }
++ for (i=0; i<f->sizep; i++) { /* mark nested protos */
++ if (f->p[i])
++ markobject(g, f->p[i]);
++ }
++ for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
++ if (f->locvars[i].varname)
++ stringmark(f->locvars[i].varname);
++ }
++}
++
++
++
++static void traverseclosure (global_State *g, Closure *cl) {
++ markobject(g, cl->c.env);
++ if (cl->c.isC) {
++ int i;
++ for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
++ markvalue(g, &cl->c.upvalue[i]);
++ }
++ else {
++ int i;
++ lua_assert(cl->l.nupvalues == cl->l.p->nups);
++ markobject(g, cl->l.p);
++ for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
++ markobject(g, cl->l.upvals[i]);
++ }
++}
++
++
++static void checkstacksizes (lua_State *L, StkId max) {
++ int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */
++ int s_used = cast_int(max - L->stack); /* part of stack in use */
++ if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */
++ return; /* do not touch the stacks */
++ if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
++ luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
++ condhardstacktests(luaD_reallocCI(L, ci_used + 1));
++ if (4*s_used < L->stacksize &&
++ 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
++ luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
++ condhardstacktests(luaD_reallocstack(L, s_used));
++}
++
++
++static void traversestack (global_State *g, lua_State *l) {
++ StkId o, lim;
++ CallInfo *ci;
++ markvalue(g, gt(l));
++ lim = l->top;
++ for (ci = l->base_ci; ci <= l->ci; ci++) {
++ lua_assert(ci->top <= l->stack_last);
++ if (lim < ci->top) lim = ci->top;
++ }
++ for (o = l->stack; o < l->top; o++)
++ markvalue(g, o);
++ for (; o <= lim; o++)
++ setnilvalue(o);
++ checkstacksizes(l, lim);
++}
++
++
++/*
++** traverse one gray object, turning it to black.
++** Returns `quantity' traversed.
++*/
++static l_mem propagatemark (global_State *g) {
++ GCObject *o = g->gray;
++ lua_assert(isgray(o));
++ gray2black(o);
++ switch (o->gch.tt) {
++ case LUA_TTABLE: {
++ Table *h = gco2h(o);
++ g->gray = h->gclist;
++ if (traversetable(g, h)) /* table is weak? */
++ black2gray(o); /* keep it gray */
++ return sizeof(Table) + sizeof(TValue) * h->sizearray +
++ sizeof(Node) * sizenode(h);
++ }
++ case LUA_TFUNCTION: {
++ Closure *cl = gco2cl(o);
++ g->gray = cl->c.gclist;
++ traverseclosure(g, cl);
++ return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
++ sizeLclosure(cl->l.nupvalues);
++ }
++ case LUA_TTHREAD: {
++ lua_State *th = gco2th(o);
++ g->gray = th->gclist;
++ th->gclist = g->grayagain;
++ g->grayagain = o;
++ black2gray(o);
++ traversestack(g, th);
++ return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
++ sizeof(CallInfo) * th->size_ci;
++ }
++ case LUA_TPROTO: {
++ Proto *p = gco2p(o);
++ g->gray = p->gclist;
++ traverseproto(g, p);
++ return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
++ sizeof(Proto *) * p->sizep +
++ sizeof(TValue) * p->sizek +
++ sizeof(int) * p->sizelineinfo +
++ sizeof(LocVar) * p->sizelocvars +
++ sizeof(TString *) * p->sizeupvalues;
++ }
++ default: lua_assert(0); return 0;
++ }
++}
++
++
++static size_t propagateall (global_State *g) {
++ size_t m = 0;
++ while (g->gray) m += propagatemark(g);
++ return m;
++}
++
++
++/*
++** The next function tells whether a key or value can be cleared from
++** a weak table. Non-collectable objects are never removed from weak
++** tables. Strings behave as `values', so are never removed too. for
++** other objects: if really collected, cannot keep them; for userdata
++** being finalized, keep them in keys, but not in values
++*/
++static int iscleared (const TValue *o, int iskey) {
++ if (!iscollectable(o)) return 0;
++ if (ttisstring(o)) {
++ stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
++ return 0;
++ }
++ return iswhite(gcvalue(o)) ||
++ (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
++}
++
++
++/*
++** clear collected entries from weaktables
++*/
++static void cleartable (GCObject *l) {
++ while (l) {
++ Table *h = gco2h(l);
++ int i = h->sizearray;
++ lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
++ testbit(h->marked, KEYWEAKBIT));
++ if (testbit(h->marked, VALUEWEAKBIT)) {
++ while (i--) {
++ TValue *o = &h->array[i];
++ if (iscleared(o, 0)) /* value was collected? */
++ setnilvalue(o); /* remove value */
++ }
++ }
++ i = sizenode(h);
++ while (i--) {
++ Node *n = gnode(h, i);
++ if (!ttisnil(gval(n)) && /* non-empty entry? */
++ (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
++ setnilvalue(gval(n)); /* remove value ... */
++ removeentry(n); /* remove entry from table */
++ }
++ }
++ l = h->gclist;
++ }
++}
++
++
++static void freeobj (lua_State *L, GCObject *o) {
++ switch (o->gch.tt) {
++ case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
++ case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
++ case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
++ case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
++ case LUA_TTHREAD: {
++ lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
++ luaE_freethread(L, gco2th(o));
++ break;
++ }
++ case LUA_TSTRING: {
++ G(L)->strt.nuse--;
++ luaM_freemem(L, o, sizestring(gco2ts(o)));
++ break;
++ }
++ case LUA_TUSERDATA: {
++ luaM_freemem(L, o, sizeudata(gco2u(o)));
++ break;
++ }
++ default: lua_assert(0);
++ }
++}
++
++
++
++#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
++
++
++static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
++ GCObject *curr;
++ global_State *g = G(L);
++ int deadmask = otherwhite(g);
++ while ((curr = *p) != NULL && count-- > 0) {
++ if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
++ sweepwholelist(L, &gco2th(curr)->openupval);
++ if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
++ lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
++ makewhite(g, curr); /* make it white (for next cycle) */
++ p = &curr->gch.next;
++ }
++ else { /* must erase `curr' */
++ lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
++ *p = curr->gch.next;
++ if (curr == g->rootgc) /* is the first element of the list? */
++ g->rootgc = curr->gch.next; /* adjust first */
++ freeobj(L, curr);
++ }
++ }
++ return p;
++}
++
++
++static void checkSizes (lua_State *L) {
++ global_State *g = G(L);
++ /* check size of string hash */
++ if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
++ g->strt.size > MINSTRTABSIZE*2)
++ luaS_resize(L, g->strt.size/2); /* table is too big */
++ /* check size of buffer */
++ if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
++ size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
++ luaZ_resizebuffer(L, &g->buff, newsize);
++ }
++}
++
++
++static void GCTM (lua_State *L) {
++ global_State *g = G(L);
++ GCObject *o = g->tmudata->gch.next; /* get first element */
++ Udata *udata = rawgco2u(o);
++ const TValue *tm;
++ /* remove udata from `tmudata' */
++ if (o == g->tmudata) /* last element? */
++ g->tmudata = NULL;
++ else
++ g->tmudata->gch.next = udata->uv.next;
++ udata->uv.next = g->mainthread->next; /* return it to `root' list */
++ g->mainthread->next = o;
++ makewhite(g, o);
++ tm = fasttm(L, udata->uv.metatable, TM_GC);
++ if (tm != NULL) {
++ lu_byte oldah = L->allowhook;
++ lu_mem oldt = g->GCthreshold;
++ L->allowhook = 0; /* stop debug hooks during GC tag method */
++ g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */
++ setobj2s(L, L->top, tm);
++ setuvalue(L, L->top+1, udata);
++ L->top += 2;
++ luaD_call(L, L->top - 2, 0);
++ L->allowhook = oldah; /* restore hooks */
++ g->GCthreshold = oldt; /* restore threshold */
++ }
++}
++
++
++/*
++** Call all GC tag methods
++*/
++void luaC_callGCTM (lua_State *L) {
++ while (G(L)->tmudata)
++ GCTM(L);
++}
++
++
++void luaC_freeall (lua_State *L) {
++ global_State *g = G(L);
++ int i;
++ g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
++ sweepwholelist(L, &g->rootgc);
++ for (i = 0; i < g->strt.size; i++) /* free all string lists */
++ sweepwholelist(L, &g->strt.hash[i]);
++}
++
++
++static void markmt (global_State *g) {
++ int i;
++ for (i=0; i<NUM_TAGS; i++)
++ if (g->mt[i]) markobject(g, g->mt[i]);
++}
++
++
++/* mark root set */
++static void markroot (lua_State *L) {
++ global_State *g = G(L);
++ g->gray = NULL;
++ g->grayagain = NULL;
++ g->weak = NULL;
++ markobject(g, g->mainthread);
++ /* make global table be traversed before main stack */
++ markvalue(g, gt(g->mainthread));
++ markvalue(g, registry(L));
++ markmt(g);
++ g->gcstate = GCSpropagate;
++}
++
++
++static void remarkupvals (global_State *g) {
++ UpVal *uv;
++ for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
++ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
++ if (isgray(obj2gco(uv)))
++ markvalue(g, uv->v);
++ }
++}
++
++
++static void atomic (lua_State *L) {
++ global_State *g = G(L);
++ size_t udsize; /* total size of userdata to be finalized */
++ /* remark occasional upvalues of (maybe) dead threads */
++ remarkupvals(g);
++ /* traverse objects cautch by write barrier and by 'remarkupvals' */
++ propagateall(g);
++ /* remark weak tables */
++ g->gray = g->weak;
++ g->weak = NULL;
++ lua_assert(!iswhite(obj2gco(g->mainthread)));
++ markobject(g, L); /* mark running thread */
++ markmt(g); /* mark basic metatables (again) */
++ propagateall(g);
++ /* remark gray again */
++ g->gray = g->grayagain;
++ g->grayagain = NULL;
++ propagateall(g);
++ udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
++ marktmu(g); /* mark `preserved' userdata */
++ udsize += propagateall(g); /* remark, to propagate `preserveness' */
++ cleartable(g->weak); /* remove collected objects from weak tables */
++ /* flip current white */
++ g->currentwhite = cast_byte(otherwhite(g));
++ g->sweepstrgc = 0;
++ g->sweepgc = &g->rootgc;
++ g->gcstate = GCSsweepstring;
++ g->estimate = g->totalbytes - udsize; /* first estimate */
++}
++
++
++static l_mem singlestep (lua_State *L) {
++ global_State *g = G(L);
++ /*lua_checkmemory(L);*/
++ switch (g->gcstate) {
++ case GCSpause: {
++ markroot(L); /* start a new collection */
++ return 0;
++ }
++ case GCSpropagate: {
++ if (g->gray)
++ return propagatemark(g);
++ else { /* no more `gray' objects */
++ atomic(L); /* finish mark phase */
++ return 0;
++ }
++ }
++ case GCSsweepstring: {
++ lu_mem old = g->totalbytes;
++ sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
++ if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
++ g->gcstate = GCSsweep; /* end sweep-string phase */
++ lua_assert(old >= g->totalbytes);
++ g->estimate -= old - g->totalbytes;
++ return GCSWEEPCOST;
++ }
++ case GCSsweep: {
++ lu_mem old = g->totalbytes;
++ g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
++ if (*g->sweepgc == NULL) { /* nothing more to sweep? */
++ checkSizes(L);
++ g->gcstate = GCSfinalize; /* end sweep phase */
++ }
++ lua_assert(old >= g->totalbytes);
++ g->estimate -= old - g->totalbytes;
++ return GCSWEEPMAX*GCSWEEPCOST;
++ }
++ case GCSfinalize: {
++ if (g->tmudata) {
++ GCTM(L);
++ if (g->estimate > GCFINALIZECOST)
++ g->estimate -= GCFINALIZECOST;
++ return GCFINALIZECOST;
++ }
++ else {
++ g->gcstate = GCSpause; /* end collection */
++ g->gcdept = 0;
++ return 0;
++ }
++ }
++ default: lua_assert(0); return 0;
++ }
++}
++
++
++void luaC_step (lua_State *L) {
++ global_State *g = G(L);
++ l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
++ if (lim == 0)
++ lim = (MAX_LUMEM-1)/2; /* no limit */
++ g->gcdept += g->totalbytes - g->GCthreshold;
++ do {
++ lim -= singlestep(L);
++ if (g->gcstate == GCSpause)
++ break;
++ } while (lim > 0);
++ if (g->gcstate != GCSpause) {
++ if (g->gcdept < GCSTEPSIZE)
++ g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
++ else {
++ g->gcdept -= GCSTEPSIZE;
++ g->GCthreshold = g->totalbytes;
++ }
++ }
++ else {
++ lua_assert(g->totalbytes >= g->estimate);
++ setthreshold(g);
++ }
++}
++
++
++void luaC_fullgc (lua_State *L) {
++ global_State *g = G(L);
++ if (g->gcstate <= GCSpropagate) {
++ /* reset sweep marks to sweep all elements (returning them to white) */
++ g->sweepstrgc = 0;
++ g->sweepgc = &g->rootgc;
++ /* reset other collector lists */
++ g->gray = NULL;
++ g->grayagain = NULL;
++ g->weak = NULL;
++ g->gcstate = GCSsweepstring;
++ }
++ lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
++ /* finish any pending sweep phase */
++ while (g->gcstate != GCSfinalize) {
++ lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
++ singlestep(L);
++ }
++ markroot(L);
++ while (g->gcstate != GCSpause) {
++ singlestep(L);
++ }
++ setthreshold(g);
++}
++
++
++void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
++ global_State *g = G(L);
++ lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
++ lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
++ lua_assert(ttype(&o->gch) != LUA_TTABLE);
++ /* must keep invariant? */
++ if (g->gcstate == GCSpropagate)
++ reallymarkobject(g, v); /* restore invariant */
++ else /* don't mind */
++ makewhite(g, o); /* mark as white just to avoid other barriers */
++}
++
++
++void luaC_barrierback (lua_State *L, Table *t) {
++ global_State *g = G(L);
++ GCObject *o = obj2gco(t);
++ lua_assert(isblack(o) && !isdead(g, o));
++ lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
++ black2gray(o); /* make table gray (again) */
++ t->gclist = g->grayagain;
++ g->grayagain = o;
++}
++
++
++void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
++ global_State *g = G(L);
++ o->gch.next = g->rootgc;
++ g->rootgc = o;
++ o->gch.marked = luaC_white(g);
++ o->gch.tt = tt;
++}
++
++
++void luaC_linkupval (lua_State *L, UpVal *uv) {
++ global_State *g = G(L);
++ GCObject *o = obj2gco(uv);
++ o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
++ g->rootgc = o;
++ if (isgray(o)) {
++ if (g->gcstate == GCSpropagate) {
++ gray2black(o); /* closed upvalues need barrier */
++ luaC_barrier(L, uv, uv->v);
++ }
++ else { /* sweep phase: sweep it (turning it into white) */
++ makewhite(g, o);
++ lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
++ }
++ }
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/lgc.h
+@@ -0,0 +1,110 @@
++/*
++** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $
++** Garbage Collector
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lgc_h
++#define lgc_h
++
++
++#include "lobject.h"
++
++
++/*
++** Possible states of the Garbage Collector
++*/
++#define GCSpause 0
++#define GCSpropagate 1
++#define GCSsweepstring 2
++#define GCSsweep 3
++#define GCSfinalize 4
++
++
++/*
++** some userful bit tricks
++*/
++#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
++#define setbits(x,m) ((x) |= (m))
++#define testbits(x,m) ((x) & (m))
++#define bitmask(b) (1<<(b))
++#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
++#define l_setbit(x,b) setbits(x, bitmask(b))
++#define resetbit(x,b) resetbits(x, bitmask(b))
++#define testbit(x,b) testbits(x, bitmask(b))
++#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
++#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
++#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))
++
++
++
++/*
++** Layout for bit use in `marked' field:
++** bit 0 - object is white (type 0)
++** bit 1 - object is white (type 1)
++** bit 2 - object is black
++** bit 3 - for userdata: has been finalized
++** bit 3 - for tables: has weak keys
++** bit 4 - for tables: has weak values
++** bit 5 - object is fixed (should not be collected)
++** bit 6 - object is "super" fixed (only the main thread)
++*/
++
++
++#define WHITE0BIT 0
++#define WHITE1BIT 1
++#define BLACKBIT 2
++#define FINALIZEDBIT 3
++#define KEYWEAKBIT 3
++#define VALUEWEAKBIT 4
++#define FIXEDBIT 5
++#define SFIXEDBIT 6
++#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
++
++
++#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
++#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
++#define isgray(x) (!isblack(x) && !iswhite(x))
++
++#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
++#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
++
++#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
++#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
++
++#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
++
++#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
++
++
++#define luaC_checkGC(L) { \
++ condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
++ if (G(L)->totalbytes >= G(L)->GCthreshold) \
++ luaC_step(L); }
++
++
++#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
++ luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
++
++#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \
++ luaC_barrierback(L,t); }
++
++#define luaC_objbarrier(L,p,o) \
++ { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
++ luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
++
++#define luaC_objbarriert(L,t,o) \
++ { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); }
++
++LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
++LUAI_FUNC void luaC_callGCTM (lua_State *L);
++LUAI_FUNC void luaC_freeall (lua_State *L);
++LUAI_FUNC void luaC_step (lua_State *L);
++LUAI_FUNC void luaC_fullgc (lua_State *L);
++LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
++LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
++LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
++LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/llex.c
+@@ -0,0 +1,460 @@
++/*
++** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $
++** Lexical Analyzer
++** See Copyright Notice in lua.h
++*/
++
++#include <ctype.h>
++#include <locale.h>
++#include <string.h>
++
++#define llex_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "ldo.h"
++#include "llex.h"
++#include "lobject.h"
++#include "lparser.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "ltable.h"
++#include "lzio.h"
++
++
++
++#define next(ls) (ls->current = zgetc(ls->z))
++
++
++
++
++#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
++
++
++/* ORDER RESERVED */
++const char *const luaX_tokens [] = {
++ "and", "break", "do", "else", "elseif",
++ "end", "false", "for", "function", "if",
++ "in", "local", "nil", "not", "or", "repeat",
++ "return", "then", "true", "until", "while",
++ "..", "...", "==", ">=", "<=", "~=",
++ "<number>", "<name>", "<string>", "<eof>",
++ NULL
++};
++
++
++#define save_and_next(ls) (save(ls, ls->current), next(ls))
++
++
++static void save (LexState *ls, int c) {
++ Mbuffer *b = ls->buff;
++ if (b->n + 1 > b->buffsize) {
++ size_t newsize;
++ if (b->buffsize >= MAX_SIZET/2)
++ luaX_lexerror(ls, "lexical element too long", 0);
++ newsize = b->buffsize * 2;
++ luaZ_resizebuffer(ls->L, b, newsize);
++ }
++ b->buffer[b->n++] = cast(char, c);
++}
++
++
++void luaX_init (lua_State *L) {
++ int i;
++ for (i=0; i<NUM_RESERVED; i++) {
++ TString *ts = luaS_new(L, luaX_tokens[i]);
++ luaS_fix(ts); /* reserved words are never collected */
++ lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
++ ts->tsv.reserved = cast_byte(i+1); /* reserved word */
++ }
++}
++
++
++#define MAXSRC 80
++
++
++const char *luaX_token2str (LexState *ls, int token) {
++ if (token < FIRST_RESERVED) {
++ lua_assert(token == cast(unsigned char, token));
++ return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) :
++ luaO_pushfstring(ls->L, "%c", token);
++ }
++ else
++ return luaX_tokens[token-FIRST_RESERVED];
++}
++
++
++static const char *txtToken (LexState *ls, int token) {
++ switch (token) {
++ case TK_NAME:
++ case TK_STRING:
++ case TK_NUMBER:
++ save(ls, '\0');
++ return luaZ_buffer(ls->buff);
++ default:
++ return luaX_token2str(ls, token);
++ }
++}
++
++
++void luaX_lexerror (LexState *ls, const char *msg, int token) {
++ char buff[MAXSRC];
++ luaO_chunkid(buff, getstr(ls->source), MAXSRC);
++ msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
++ if (token)
++ luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token));
++ luaD_throw(ls->L, LUA_ERRSYNTAX);
++}
++
++
++void luaX_syntaxerror (LexState *ls, const char *msg) {
++ luaX_lexerror(ls, msg, ls->t.token);
++}
++
++
++TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
++ lua_State *L = ls->L;
++ TString *ts = luaS_newlstr(L, str, l);
++ TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */
++ if (ttisnil(o))
++ setbvalue(o, 1); /* make sure `str' will not be collected */
++ return ts;
++}
++
++
++static void inclinenumber (LexState *ls) {
++ int old = ls->current;
++ lua_assert(currIsNewline(ls));
++ next(ls); /* skip `\n' or `\r' */
++ if (currIsNewline(ls) && ls->current != old)
++ next(ls); /* skip `\n\r' or `\r\n' */
++ if (++ls->linenumber >= MAX_INT)
++ luaX_syntaxerror(ls, "chunk has too many lines");
++}
++
++
++void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
++ ls->decpoint = '.';
++ ls->L = L;
++ ls->lookahead.token = TK_EOS; /* no look-ahead token */
++ ls->z = z;
++ ls->fs = NULL;
++ ls->linenumber = 1;
++ ls->lastline = 1;
++ ls->source = source;
++ luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
++ next(ls); /* read first char */
++}
++
++
++
++/*
++** =======================================================
++** LEXICAL ANALYZER
++** =======================================================
++*/
++
++
++
++static int check_next (LexState *ls, const char *set) {
++ if (!strchr(set, ls->current))
++ return 0;
++ save_and_next(ls);
++ return 1;
++}
++
++
++static void buffreplace (LexState *ls, char from, char to) {
++ size_t n = luaZ_bufflen(ls->buff);
++ char *p = luaZ_buffer(ls->buff);
++ while (n--)
++ if (p[n] == from) p[n] = to;
++}
++
++
++static void trydecpoint (LexState *ls, SemInfo *seminfo) {
++ /* format error: try to update decimal point separator */
++ char old = ls->decpoint;
++ struct lconv *cv = localeconv();
++ ls->decpoint = (cv ? cv->decimal_point[0] : '.');
++ buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
++ if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
++ /* format error with correct decimal point: no more options */
++ buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
++ luaX_lexerror(ls, "malformed number", TK_NUMBER);
++ }
++}
++
++
++/* LUA_NUMBER */
++static void read_numeral (LexState *ls, SemInfo *seminfo) {
++ lua_assert(isdigit(ls->current));
++ do {
++ save_and_next(ls);
++ } while (isdigit(ls->current) || ls->current == '.');
++ if (check_next(ls, "Ee")) /* `E'? */
++ check_next(ls, "+-"); /* optional exponent sign */
++ while (isalnum(ls->current) || ls->current == '_')
++ save_and_next(ls);
++ save(ls, '\0');
++ buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
++ if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
++ trydecpoint(ls, seminfo); /* try to update decimal point separator */
++}
++
++
++static int skip_sep (LexState *ls) {
++ int count = 0;
++ int s = ls->current;
++ lua_assert(s == '[' || s == ']');
++ save_and_next(ls);
++ while (ls->current == '=') {
++ save_and_next(ls);
++ count++;
++ }
++ return (ls->current == s) ? count : (-count) - 1;
++}
++
++
++static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
++ int cont = 0;
++ (void)(cont); /* avoid warnings when `cont' is not used */
++ save_and_next(ls); /* skip 2nd `[' */
++ if (currIsNewline(ls)) /* string starts with a newline? */
++ inclinenumber(ls); /* skip it */
++ for (;;) {
++ switch (ls->current) {
++ case EOZ:
++ luaX_lexerror(ls, (seminfo) ? "unfinished long string" :
++ "unfinished long comment", TK_EOS);
++ break; /* to avoid warnings */
++#if defined(LUA_COMPAT_LSTR)
++ case '[': {
++ if (skip_sep(ls) == sep) {
++ save_and_next(ls); /* skip 2nd `[' */
++ cont++;
++#if LUA_COMPAT_LSTR == 1
++ if (sep == 0)
++ luaX_lexerror(ls, "nesting of [[...]] is deprecated", '[');
++#endif
++ }
++ break;
++ }
++#endif
++ case ']': {
++ if (skip_sep(ls) == sep) {
++ save_and_next(ls); /* skip 2nd `]' */
++#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2
++ cont--;
++ if (sep == 0 && cont >= 0) break;
++#endif
++ goto endloop;
++ }
++ break;
++ }
++ case '\n':
++ case '\r': {
++ save(ls, '\n');
++ inclinenumber(ls);
++ if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
++ break;
++ }
++ default: {
++ if (seminfo) save_and_next(ls);
++ else next(ls);
++ }
++ }
++ } endloop:
++ if (seminfo)
++ seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
++ luaZ_bufflen(ls->buff) - 2*(2 + sep));
++}
++
++
++static void read_string (LexState *ls, int del, SemInfo *seminfo) {
++ save_and_next(ls);
++ while (ls->current != del) {
++ switch (ls->current) {
++ case EOZ:
++ luaX_lexerror(ls, "unfinished string", TK_EOS);
++ continue; /* to avoid warnings */
++ case '\n':
++ case '\r':
++ luaX_lexerror(ls, "unfinished string", TK_STRING);
++ continue; /* to avoid warnings */
++ case '\\': {
++ int c;
++ next(ls); /* do not save the `\' */
++ switch (ls->current) {
++ case 'a': c = '\a'; break;
++ case 'b': c = '\b'; break;
++ case 'f': c = '\f'; break;
++ case 'n': c = '\n'; break;
++ case 'r': c = '\r'; break;
++ case 't': c = '\t'; break;
++ case 'v': c = '\v'; break;
++ case '\n': /* go through */
++ case '\r': save(ls, '\n'); inclinenumber(ls); continue;
++ case EOZ: continue; /* will raise an error next loop */
++ default: {
++ if (!isdigit(ls->current))
++ save_and_next(ls); /* handles \\, \", \', and \? */
++ else { /* \xxx */
++ int i = 0;
++ c = 0;
++ do {
++ c = 10*c + (ls->current-'0');
++ next(ls);
++ } while (++i<3 && isdigit(ls->current));
++ if (c > UCHAR_MAX)
++ luaX_lexerror(ls, "escape sequence too large", TK_STRING);
++ save(ls, c);
++ }
++ continue;
++ }
++ }
++ save(ls, c);
++ next(ls);
++ continue;
++ }
++ default:
++ save_and_next(ls);
++ }
++ }
++ save_and_next(ls); /* skip delimiter */
++ seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
++ luaZ_bufflen(ls->buff) - 2);
++}
++
++
++static int llex (LexState *ls, SemInfo *seminfo) {
++ luaZ_resetbuffer(ls->buff);
++ for (;;) {
++ switch (ls->current) {
++ case '\n':
++ case '\r': {
++ inclinenumber(ls);
++ continue;
++ }
++ case '-': {
++ next(ls);
++ if (ls->current != '-') return '-';
++ /* else is a comment */
++ next(ls);
++ if (ls->current == '[') {
++ int sep = skip_sep(ls);
++ luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
++ if (sep >= 0) {
++ read_long_string(ls, NULL, sep); /* long comment */
++ luaZ_resetbuffer(ls->buff);
++ continue;
++ }
++ }
++ /* else short comment */
++ while (!currIsNewline(ls) && ls->current != EOZ)
++ next(ls);
++ continue;
++ }
++ case '[': {
++ int sep = skip_sep(ls);
++ if (sep >= 0) {
++ read_long_string(ls, seminfo, sep);
++ return TK_STRING;
++ }
++ else if (sep == -1) return '[';
++ else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
++ }
++ case '=': {
++ next(ls);
++ if (ls->current != '=') return '=';
++ else { next(ls); return TK_EQ; }
++ }
++ case '<': {
++ next(ls);
++ if (ls->current != '=') return '<';
++ else { next(ls); return TK_LE; }
++ }
++ case '>': {
++ next(ls);
++ if (ls->current != '=') return '>';
++ else { next(ls); return TK_GE; }
++ }
++ case '~': {
++ next(ls);
++ if (ls->current != '=') return '~';
++ else { next(ls); return TK_NE; }
++ }
++ case '"':
++ case '\'': {
++ read_string(ls, ls->current, seminfo);
++ return TK_STRING;
++ }
++ case '.': {
++ save_and_next(ls);
++ if (check_next(ls, ".")) {
++ if (check_next(ls, "."))
++ return TK_DOTS; /* ... */
++ else return TK_CONCAT; /* .. */
++ }
++ else if (!isdigit(ls->current)) return '.';
++ else {
++ read_numeral(ls, seminfo);
++ return TK_NUMBER;
++ }
++ }
++ case EOZ: {
++ return TK_EOS;
++ }
++ default: {
++ if (isspace(ls->current)) {
++ lua_assert(!currIsNewline(ls));
++ next(ls);
++ continue;
++ }
++ else if (isdigit(ls->current)) {
++ read_numeral(ls, seminfo);
++ return TK_NUMBER;
++ }
++ else if (isalpha(ls->current) || ls->current == '_') {
++ /* identifier or reserved word */
++ TString *ts;
++ do {
++ save_and_next(ls);
++ } while (isalnum(ls->current) || ls->current == '_');
++ ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
++ luaZ_bufflen(ls->buff));
++ if (ts->tsv.reserved > 0) /* reserved word? */
++ return ts->tsv.reserved - 1 + FIRST_RESERVED;
++ else {
++ seminfo->ts = ts;
++ return TK_NAME;
++ }
++ }
++ else {
++ int c = ls->current;
++ next(ls);
++ return c; /* single-char tokens (+ - / ...) */
++ }
++ }
++ }
++ }
++}
++
++
++void luaX_next (LexState *ls) {
++ ls->lastline = ls->linenumber;
++ if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
++ ls->t = ls->lookahead; /* use this one */
++ ls->lookahead.token = TK_EOS; /* and discharge it */
++ }
++ else
++ ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
++}
++
++
++void luaX_lookahead (LexState *ls) {
++ lua_assert(ls->lookahead.token == TK_EOS);
++ ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/llex.h
+@@ -0,0 +1,81 @@
++/*
++** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $
++** Lexical Analyzer
++** See Copyright Notice in lua.h
++*/
++
++#ifndef llex_h
++#define llex_h
++
++#include "lobject.h"
++#include "lzio.h"
++
++
++#define FIRST_RESERVED 257
++
++/* maximum length of a reserved word */
++#define TOKEN_LEN (sizeof("function")/sizeof(char))
++
++
++/*
++* WARNING: if you change the order of this enumeration,
++* grep "ORDER RESERVED"
++*/
++enum RESERVED {
++ /* terminal symbols denoted by reserved words */
++ TK_AND = FIRST_RESERVED, TK_BREAK,
++ TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
++ TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
++ TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
++ /* other terminal symbols */
++ TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
++ TK_NAME, TK_STRING, TK_EOS
++};
++
++/* number of reserved words */
++#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
++
++
++/* array with token `names' */
++LUAI_DATA const char *const luaX_tokens [];
++
++
++typedef union {
++ lua_Number r;
++ TString *ts;
++} SemInfo; /* semantics information */
++
++
++typedef struct Token {
++ int token;
++ SemInfo seminfo;
++} Token;
++
++
++typedef struct LexState {
++ int current; /* current character (charint) */
++ int linenumber; /* input line counter */
++ int lastline; /* line of last token `consumed' */
++ Token t; /* current token */
++ Token lookahead; /* look ahead token */
++ struct FuncState *fs; /* `FuncState' is private to the parser */
++ struct lua_State *L;
++ ZIO *z; /* input stream */
++ Mbuffer *buff; /* buffer for tokens */
++ TString *source; /* current source name */
++ char decpoint; /* locale decimal point */
++} LexState;
++
++
++LUAI_FUNC void luaX_init (lua_State *L);
++LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
++ TString *source);
++LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
++LUAI_FUNC void luaX_next (LexState *ls);
++LUAI_FUNC void luaX_lookahead (LexState *ls);
++LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
++LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
++LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/llimits.h
+@@ -0,0 +1,125 @@
++/*
++** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $
++** Limits, basic types, and some other `installation-dependent' definitions
++** See Copyright Notice in lua.h
++*/
++
++#ifndef llimits_h
++#define llimits_h
++
++#include <stddef.h>
++#include <limits.h>
++
++#include "lua.h"
++
++typedef LUAI_UINT32 lu_int32;
++
++typedef LUAI_UMEM lu_mem;
++
++typedef LUAI_MEM l_mem;
++
++
++
++/* chars used as small naturals (so that `char' is reserved for characters) */
++typedef unsigned char lu_byte;
++
++
++#define MAX_SIZET ((size_t)(~(size_t)0)-2)
++
++#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
++
++
++#define MAX_INT (LUA_INT_MAX-2) /* maximum value of an int (-2 for safety) */
++
++/*
++** conversion of pointer to integer
++** this is for hashing only; there is no problem if the integer
++** cannot hold the whole pointer value
++*/
++#define IntPoint(p) ((unsigned int)(lu_mem)(p))
++
++
++
++/* type to ensure maximum alignment */
++typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
++
++
++/* result of a `usual argument conversion' over lua_Number */
++typedef LUAI_UACNUMBER l_uacNumber;
++
++
++/* internal assertions for in-house debugging */
++#ifdef lua_assert
++
++#define check_exp(c,e) (lua_assert(c), (e))
++#define api_check(l,e) lua_assert(e)
++
++#else
++
++#define lua_assert(c) ((void)0)
++#define check_exp(c,e) (e)
++#define api_check luai_apicheck
++
++#endif
++
++
++#ifndef UNUSED
++#define UNUSED(x) ((void)(x)) /* to avoid warnings */
++#endif
++
++
++#ifndef cast
++#define cast(t, exp) ((t)(exp))
++#endif
++
++#define cast_byte(i) cast(lu_byte, (i))
++#define cast_num(i) cast(lua_Number, (i))
++#define cast_int(i) cast(int, (i))
++
++
++
++/*
++** type for virtual-machine instructions
++** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
++*/
++typedef lu_int32 Instruction;
++
++
++
++/* maximum stack for a Lua function */
++#define MAXSTACK 250
++
++
++
++/* minimum size for the string table (must be power of 2) */
++#ifndef MINSTRTABSIZE
++#define MINSTRTABSIZE 32
++#endif
++
++
++/* minimum size for string buffer */
++#ifndef LUA_MINBUFFER
++#define LUA_MINBUFFER 32
++#endif
++
++
++#ifndef lua_lock
++#define lua_lock(L) ((void) 0)
++#define lua_unlock(L) ((void) 0)
++#endif
++
++#ifndef luai_threadyield
++#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
++#endif
++
++
++/*
++** macro to control inclusion of some hard tests on stack reallocation
++*/
++#ifndef HARDSTACKTESTS
++#define condhardstacktests(x) ((void)0)
++#else
++#define condhardstacktests(x) x
++#endif
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lmem.c
+@@ -0,0 +1,86 @@
++/*
++** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $
++** Interface to Memory Manager
++** See Copyright Notice in lua.h
++*/
++
++
++#include <stddef.h>
++
++#define lmem_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "ldebug.h"
++#include "ldo.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lstate.h"
++
++
++
++/*
++** About the realloc function:
++** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
++** (`osize' is the old size, `nsize' is the new size)
++**
++** Lua ensures that (ptr == NULL) iff (osize == 0).
++**
++** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
++**
++** * frealloc(ud, p, x, 0) frees the block `p'
++** (in this specific case, frealloc must return NULL).
++** particularly, frealloc(ud, NULL, 0, 0) does nothing
++** (which is equivalent to free(NULL) in ANSI C)
++**
++** frealloc returns NULL if it cannot create or reallocate the area
++** (any reallocation to an equal or smaller size cannot fail!)
++*/
++
++
++
++#define MINSIZEARRAY 4
++
++
++void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
++ int limit, const char *errormsg) {
++ void *newblock;
++ int newsize;
++ if (*size >= limit/2) { /* cannot double it? */
++ if (*size >= limit) /* cannot grow even a little? */
++ luaG_runerror(L, errormsg);
++ newsize = limit; /* still have at least one free place */
++ }
++ else {
++ newsize = (*size)*2;
++ if (newsize < MINSIZEARRAY)
++ newsize = MINSIZEARRAY; /* minimum size */
++ }
++ newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
++ *size = newsize; /* update only when everything else is OK */
++ return newblock;
++}
++
++
++void *luaM_toobig (lua_State *L) {
++ luaG_runerror(L, "memory allocation error: block too big");
++ return NULL; /* to avoid warnings */
++}
++
++
++
++/*
++** generic allocation routine.
++*/
++void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
++ global_State *g = G(L);
++ lua_assert((osize == 0) == (block == NULL));
++ block = (*g->frealloc)(g->ud, block, osize, nsize);
++ if (block == NULL && nsize > 0)
++ luaD_throw(L, LUA_ERRMEM);
++ lua_assert((nsize == 0) == (block == NULL));
++ g->totalbytes = (g->totalbytes - osize) + nsize;
++ return block;
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/lmem.h
+@@ -0,0 +1,49 @@
++/*
++** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
++** Interface to Memory Manager
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lmem_h
++#define lmem_h
++
++
++#include <stddef.h>
++
++#include "llimits.h"
++#include "lua.h"
++
++#define MEMERRMSG "not enough memory"
++
++
++#define luaM_reallocv(L,b,on,n,e) \
++ ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
++ luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
++ luaM_toobig(L))
++
++#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
++#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
++#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t))
++
++#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t))
++#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
++#define luaM_newvector(L,n,t) \
++ cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
++
++#define luaM_growvector(L,v,nelems,size,t,limit,e) \
++ if ((nelems)+1 > (size)) \
++ ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
++
++#define luaM_reallocvector(L, v,oldn,n,t) \
++ ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
++
++
++LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
++ size_t size);
++LUAI_FUNC void *luaM_toobig (lua_State *L);
++LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
++ size_t size_elem, int limit,
++ const char *errormsg);
++
++#endif
++
+--- /dev/null
++++ b/extensions/LUA/lua/lobject.c
+@@ -0,0 +1,215 @@
++/*
++** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
++** Some generic functions over Lua objects
++** See Copyright Notice in lua.h
++*/
++
++#include <stdarg.h>
++
++#include <ctype.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#define lobject_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "ldo.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "lvm.h"
++
++
++
++const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
++
++
++/*
++** converts an integer to a "floating point byte", represented as
++** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
++** eeeee != 0 and (xxx) otherwise.
++*/
++int luaO_int2fb (unsigned int x) {
++ int e = 0; /* expoent */
++ while (x >= 16) {
++ x = (x+1) >> 1;
++ e++;
++ }
++ if (x < 8) return x;
++ else return ((e+1) << 3) | (cast_int(x) - 8);
++}
++
++
++/* converts back */
++int luaO_fb2int (int x) {
++ int e = (x >> 3) & 31;
++ if (e == 0) return x;
++ else return ((x & 7)+8) << (e - 1);
++}
++
++
++int luaO_log2 (unsigned int x) {
++ static const lu_byte log_2[256] = {
++ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
++ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
++ };
++ int l = -1;
++ while (x >= 256) { l += 8; x >>= 8; }
++ return l + log_2[x];
++
++}
++
++
++int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
++ if (ttype(t1) != ttype(t2)) return 0;
++ else switch (ttype(t1)) {
++ case LUA_TNIL:
++ return 1;
++ case LUA_TNUMBER:
++ return luai_numeq(nvalue(t1), nvalue(t2));
++ case LUA_TBOOLEAN:
++ return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
++ case LUA_TLIGHTUSERDATA:
++ return pvalue(t1) == pvalue(t2);
++ default:
++ lua_assert(iscollectable(t1));
++ return gcvalue(t1) == gcvalue(t2);
++ }
++}
++
++
++int luaO_str2d (const char *s, lua_Number *result) {
++ char *endptr;
++ *result = lua_str2number(s, &endptr);
++ if (endptr == s) return 0; /* conversion failed */
++ if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
++ *result = cast_num(strtoul(s, &endptr, 16));
++ if (*endptr == '\0') return 1; /* most common case */
++ while (isspace(cast(unsigned char, *endptr))) endptr++;
++ if (*endptr != '\0') return 0; /* invalid trailing characters? */
++ return 1;
++}
++
++
++
++static void pushstr (lua_State *L, const char *str) {
++ setsvalue2s(L, L->top, luaS_new(L, str));
++ incr_top(L);
++}
++
++
++/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
++const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
++ int n = 1;
++ pushstr(L, "");
++ for (;;) {
++ const char *e = strchr(fmt, '%');
++ if (e == NULL) break;
++ setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
++ incr_top(L);
++ switch (*(e+1)) {
++ case 's': {
++ const char *s = va_arg(argp, char *);
++ if (s == NULL) s = "(null)";
++ pushstr(L, s);
++ break;
++ }
++ case 'c': {
++ char buff[2];
++ buff[0] = cast(char, va_arg(argp, int));
++ buff[1] = '\0';
++ pushstr(L, buff);
++ break;
++ }
++ case 'd': {
++ setnvalue(L->top, cast_num(va_arg(argp, int)));
++ incr_top(L);
++ break;
++ }
++ case 'f': {
++ setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
++ incr_top(L);
++ break;
++ }
++ case 'p': {
++ char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
++ sprintf(buff, "%p", va_arg(argp, void *));
++ pushstr(L, buff);
++ break;
++ }
++ case '%': {
++ pushstr(L, "%");
++ break;
++ }
++ default: {
++ char buff[3];
++ buff[0] = '%';
++ buff[1] = *(e+1);
++ buff[2] = '\0';
++ pushstr(L, buff);
++ break;
++ }
++ }
++ n += 2;
++ fmt = e+2;
++ }
++ pushstr(L, fmt);
++ luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
++ L->top -= n;
++ return svalue(L->top - 1);
++}
++
++
++const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
++ const char *msg;
++ va_list argp;
++ va_start(argp, fmt);
++ msg = luaO_pushvfstring(L, fmt, argp);
++ va_end(argp);
++ return msg;
++}
++
++
++void luaO_chunkid (char *out, const char *source, size_t bufflen) {
++ if (*source == '=') {
++ strncpy(out, source+1, bufflen); /* remove first char */
++ out[bufflen-1] = '\0'; /* ensures null termination */
++ }
++ else { /* out = "source", or "...source" */
++ if (*source == '@') {
++ size_t l;
++ source++; /* skip the `@' */
++ bufflen -= sizeof(" '...' ");
++ l = strlen(source);
++ strcpy(out, "");
++ if (l > bufflen) {
++ source += (l-bufflen); /* get last part of file name */
++ strcat(out, "...");
++ }
++ strcat(out, source);
++ }
++ else { /* out = [string "string"] */
++ size_t len = strcspn(source, "\n\r"); /* stop at first newline */
++ bufflen -= sizeof(" [string \"...\"] ");
++ if (len > bufflen) len = bufflen;
++ strcpy(out, "[string \"");
++ if (source[len] != '\0') { /* must truncate? */
++ strncat(out, source, len);
++ strcat(out, "...");
++ }
++ else
++ strcat(out, source);
++ strcat(out, "\"]");
++ }
++ }
++}
+--- /dev/null
++++ b/extensions/LUA/lua/lobject.h
+@@ -0,0 +1,381 @@
++/*
++** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $
++** Type definitions for Lua objects
++** See Copyright Notice in lua.h
++*/
++
++
++#ifndef lobject_h
++#define lobject_h
++
++
++#include <stdarg.h>
++
++
++#include "llimits.h"
++#include "lua.h"
++
++
++/* tags for values visible from Lua */
++#define LAST_TAG LUA_TTHREAD
++
++#define NUM_TAGS (LAST_TAG+1)
++
++
++/*
++** Extra tags for non-values
++*/
++#define LUA_TPROTO (LAST_TAG+1)
++#define LUA_TUPVAL (LAST_TAG+2)
++#define LUA_TDEADKEY (LAST_TAG+3)
++
++
++/*
++** Union of all collectable objects
++*/
++typedef union GCObject GCObject;
++
++
++/*
++** Common Header for all collectable objects (in macro form, to be
++** included in other objects)
++*/
++#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
++
++
++/*
++** Common header in struct form
++*/
++typedef struct GCheader {
++ CommonHeader;
++} GCheader;
++
++
++
++
++/*
++** Union of all Lua values
++*/
++typedef union {
++ GCObject *gc;
++ void *p;
++ lua_Number n;
++ int b;
++} Value;
++
++
++/*
++** Tagged Values
++*/
++
++#define TValuefields Value value; int tt
++
++typedef struct lua_TValue {
++ TValuefields;
++} TValue;
++
++
++/* Macros to test type */
++#define ttisnil(o) (ttype(o) == LUA_TNIL)
++#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
++#define ttisstring(o) (ttype(o) == LUA_TSTRING)
++#define ttistable(o) (ttype(o) == LUA_TTABLE)
++#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
++#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
++#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
++#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
++#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
++
++/* Macros to access values */
++#define ttype(o) ((o)->tt)
++#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
++#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
++#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
++#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
++#define tsvalue(o) (&rawtsvalue(o)->tsv)
++#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
++#define uvalue(o) (&rawuvalue(o)->uv)
++#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
++#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
++#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
++#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
++
++#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
++
++/*
++** for internal debug only
++*/
++#define checkconsistency(obj) \
++ lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
++
++#define checkliveness(g,obj) \
++ lua_assert(!iscollectable(obj) || \
++ ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
++
++
++/* Macros to set values */
++#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
++
++#define setnvalue(obj,x) \
++ { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
++
++#define setpvalue(obj,x) \
++ { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
++
++#define setbvalue(obj,x) \
++ { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
++
++#define setsvalue(L,obj,x) \
++ { TValue *i_o=(obj); \
++ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
++ checkliveness(G(L),i_o); }
++
++#define setuvalue(L,obj,x) \
++ { TValue *i_o=(obj); \
++ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
++ checkliveness(G(L),i_o); }
++
++#define setthvalue(L,obj,x) \
++ { TValue *i_o=(obj); \
++ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
++ checkliveness(G(L),i_o); }
++
++#define setclvalue(L,obj,x) \
++ { TValue *i_o=(obj); \
++ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
++ checkliveness(G(L),i_o); }
++
++#define sethvalue(L,obj,x) \
++ { TValue *i_o=(obj); \
++ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
++ checkliveness(G(L),i_o); }
++
++#define setptvalue(L,obj,x) \
++ { TValue *i_o=(obj); \
++ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
++ checkliveness(G(L),i_o); }
++
++
++
++
++#define setobj(L,obj1,obj2) \
++ { const TValue *o2=(obj2); TValue *o1=(obj1); \
++ o1->value = o2->value; o1->tt=o2->tt; \
++ checkliveness(G(L),o1); }
++
++
++/*
++** different types of sets, according to destination
++*/
++
++/* from stack to (same) stack */
++#define setobjs2s setobj
++/* to stack (not from same stack) */
++#define setobj2s setobj
++#define setsvalue2s setsvalue
++#define sethvalue2s sethvalue
++#define setptvalue2s setptvalue
++/* from table to same table */
++#define setobjt2t setobj
++/* to table */
++#define setobj2t setobj
++/* to new object */
++#define setobj2n setobj
++#define setsvalue2n setsvalue
++
++#define setttype(obj, tt) (ttype(obj) = (tt))
++
++
++#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
++
++
++
++typedef TValue *StkId; /* index to stack elements */
++
++
++/*
++** String headers for string table
++*/
++typedef union TString {
++ L_Umaxalign dummy; /* ensures maximum alignment for strings */
++ struct {
++ CommonHeader;
++ lu_byte reserved;
++ unsigned int hash;
++ size_t len;
++ } tsv;
++} TString;
++
++
++#define getstr(ts) cast(const char *, (ts) + 1)
++#define svalue(o) getstr(rawtsvalue(o))
++
++
++
++typedef union Udata {
++ L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
++ struct {
++ CommonHeader;
++ struct Table *metatable;
++ struct Table *env;
++ size_t len;
++ } uv;
++} Udata;
++
++
++
++
++/*
++** Function Prototypes
++*/
++typedef struct Proto {
++ CommonHeader;
++ TValue *k; /* constants used by the function */
++ Instruction *code;
++ struct Proto **p; /* functions defined inside the function */
++ int *lineinfo; /* map from opcodes to source lines */
++ struct LocVar *locvars; /* information about local variables */
++ TString **upvalues; /* upvalue names */
++ TString *source;
++ int sizeupvalues;
++ int sizek; /* size of `k' */
++ int sizecode;
++ int sizelineinfo;
++ int sizep; /* size of `p' */
++ int sizelocvars;
++ int linedefined;
++ int lastlinedefined;
++ GCObject *gclist;
++ lu_byte nups; /* number of upvalues */
++ lu_byte numparams;
++ lu_byte is_vararg;
++ lu_byte maxstacksize;
++} Proto;
++
++
++/* masks for new-style vararg */
++#define VARARG_HASARG 1
++#define VARARG_ISVARARG 2
++#define VARARG_NEEDSARG 4
++
++
++typedef struct LocVar {
++ TString *varname;
++ int startpc; /* first point where variable is active */
++ int endpc; /* first point where variable is dead */
++} LocVar;
++
++
++
++/*
++** Upvalues
++*/
++
++typedef struct UpVal {
++ CommonHeader;
++ TValue *v; /* points to stack or to its own value */
++ union {
++ TValue value; /* the value (when closed) */
++ struct { /* double linked list (when open) */
++ struct UpVal *prev;
++ struct UpVal *next;
++ } l;
++ } u;
++} UpVal;
++
++
++/*
++** Closures
++*/
++
++#define ClosureHeader \
++ CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
++ struct Table *env
++
++typedef struct CClosure {
++ ClosureHeader;
++ lua_CFunction f;
++ TValue upvalue[1];
++} CClosure;
++
++
++typedef struct LClosure {
++ ClosureHeader;
++ struct Proto *p;
++ UpVal *upvals[1];
++} LClosure;
++
++
++typedef union Closure {
++ CClosure c;
++ LClosure l;
++} Closure;
++
++
++#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
++#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
++
++
++/*
++** Tables
++*/
++
++typedef union TKey {
++ struct {
++ TValuefields;
++ struct Node *next; /* for chaining */
++ } nk;
++ TValue tvk;
++} TKey;
++
++
++typedef struct Node {
++ TValue i_val;
++ TKey i_key;
++} Node;
++
++
++typedef struct Table {
++ CommonHeader;
++ lu_byte flags; /* 1<<p means tagmethod(p) is not present */
++ lu_byte lsizenode; /* log2 of size of `node' array */
++ struct Table *metatable;
++ TValue *array; /* array part */
++ Node *node;
++ Node *lastfree; /* any free position is before this position */
++ GCObject *gclist;
++ int sizearray; /* size of `array' array */
++} Table;
++
++
++
++/*
++** `module' operation for hashing (size is always a power of 2)
++*/
++#define lmod(s,size) \
++ (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
++
++
++#define twoto(x) (1<<(x))
++#define sizenode(t) (twoto((t)->lsizenode))
++
++
++#define luaO_nilobject (&luaO_nilobject_)
++
++LUAI_DATA const TValue luaO_nilobject_;
++
++#define ceillog2(x) (luaO_log2((x)-1) + 1)
++
++LUAI_FUNC int luaO_log2 (unsigned int x);
++LUAI_FUNC int luaO_int2fb (unsigned int x);
++LUAI_FUNC int luaO_fb2int (int x);
++LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
++LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
++LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
++ va_list argp);
++LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
++LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
++
++
++#endif
++
+--- /dev/null
++++ b/extensions/LUA/lua/lopcodes.c
+@@ -0,0 +1,102 @@
++/*
++** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
++** See Copyright Notice in lua.h
++*/
++
++
++#define lopcodes_c
++#define LUA_CORE
++
++
++#include "lopcodes.h"
++
++
++/* ORDER OP */
++
++const char *const luaP_opnames[NUM_OPCODES+1] = {
++ "MOVE",
++ "LOADK",
++ "LOADBOOL",
++ "LOADNIL",
++ "GETUPVAL",
++ "GETGLOBAL",
++ "GETTABLE",
++ "SETGLOBAL",
++ "SETUPVAL",
++ "SETTABLE",
++ "NEWTABLE",
++ "SELF",
++ "ADD",
++ "SUB",
++ "MUL",
++ "DIV",
++ "MOD",
++ "POW",
++ "UNM",
++ "NOT",
++ "LEN",
++ "CONCAT",
++ "JMP",
++ "EQ",
++ "LT",
++ "LE",
++ "TEST",
++ "TESTSET",
++ "CALL",
++ "TAILCALL",
++ "RETURN",
++ "FORLOOP",
++ "FORPREP",
++ "TFORLOOP",
++ "SETLIST",
++ "CLOSE",
++ "CLOSURE",
++ "VARARG",
++ NULL
++};
++
++
++#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
++
++const lu_byte luaP_opmodes[NUM_OPCODES] = {
++/* T A B C mode opcode */
++ opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
++ ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
++ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
++ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
++ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
++ ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
++ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
++ ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
++ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
++ ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
++ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
++ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
++ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
++ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
++ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
++ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
++ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
++ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
++ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
++ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
++ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
++ ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
++ ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
++ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
++ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
++ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
++ ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
++ ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
++ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
++ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
++ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
++ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
++ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
++ ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
++ ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
++ ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
++ ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
++ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
++};
++
+--- /dev/null
++++ b/extensions/LUA/lua/lopcodes.h
+@@ -0,0 +1,268 @@
++/*
++** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
++** Opcodes for Lua virtual machine
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lopcodes_h
++#define lopcodes_h
++
++#include "llimits.h"
++
++
++/*===========================================================================
++ We assume that instructions are unsigned numbers.
++ All instructions have an opcode in the first 6 bits.
++ Instructions can have the following fields:
++ `A' : 8 bits
++ `B' : 9 bits
++ `C' : 9 bits
++ `Bx' : 18 bits (`B' and `C' together)
++ `sBx' : signed Bx
++
++ A signed argument is represented in excess K; that is, the number
++ value is the unsigned value minus K. K is exactly the maximum value
++ for that argument (so that -max is represented by 0, and +max is
++ represented by 2*max), which is half the maximum for the corresponding
++ unsigned argument.
++===========================================================================*/
++
++
++enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
++
++
++/*
++** size and position of opcode arguments.
++*/
++#define SIZE_C 9
++#define SIZE_B 9
++#define SIZE_Bx (SIZE_C + SIZE_B)
++#define SIZE_A 8
++
++#define SIZE_OP 6
++
++#define POS_OP 0
++#define POS_A (POS_OP + SIZE_OP)
++#define POS_C (POS_A + SIZE_A)
++#define POS_B (POS_C + SIZE_C)
++#define POS_Bx POS_C
++
++
++/*
++** limits for opcode arguments.
++** we use (signed) int to manipulate most arguments,
++** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
++*/
++#if SIZE_Bx < LUAI_BITSINT-1
++#define MAXARG_Bx ((1<<SIZE_Bx)-1)
++#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
++#else
++#define MAXARG_Bx MAX_INT
++#define MAXARG_sBx MAX_INT
++#endif
++
++
++#define MAXARG_A ((1<<SIZE_A)-1)
++#define MAXARG_B ((1<<SIZE_B)-1)
++#define MAXARG_C ((1<<SIZE_C)-1)
++
++
++/* creates a mask with `n' 1 bits at position `p' */
++#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
++
++/* creates a mask with `n' 0 bits at position `p' */
++#define MASK0(n,p) (~MASK1(n,p))
++
++/*
++** the following macros help to manipulate instructions
++*/
++
++#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
++#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
++ ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
++
++#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
++#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
++ ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
++
++#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
++#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
++ ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
++
++#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
++#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
++ ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
++
++#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
++#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
++ ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
++
++#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
++#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
++
++
++#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
++ | (cast(Instruction, a)<<POS_A) \
++ | (cast(Instruction, b)<<POS_B) \
++ | (cast(Instruction, c)<<POS_C))
++
++#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
++ | (cast(Instruction, a)<<POS_A) \
++ | (cast(Instruction, bc)<<POS_Bx))
++
++
++/*
++** Macros to operate RK indices
++*/
++
++/* this bit 1 means constant (0 means register) */
++#define BITRK (1 << (SIZE_B - 1))
++
++/* test whether value is a constant */
++#define ISK(x) ((x) & BITRK)
++
++/* gets the index of the constant */
++#define INDEXK(r) ((int)(r) & ~BITRK)
++
++#define MAXINDEXRK (BITRK - 1)
++
++/* code a constant index as a RK value */
++#define RKASK(x) ((x) | BITRK)
++
++
++/*
++** invalid register that fits in 8 bits
++*/
++#define NO_REG MAXARG_A
++
++
++/*
++** R(x) - register
++** Kst(x) - constant (in constant table)
++** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
++*/
++
++
++/*
++** grep "ORDER OP" if you change these enums
++*/
++
++typedef enum {
++/*----------------------------------------------------------------------
++name args description
++------------------------------------------------------------------------*/
++OP_MOVE,/* A B R(A) := R(B) */
++OP_LOADK,/* A Bx R(A) := Kst(Bx) */
++OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
++OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
++OP_GETUPVAL,/* A B R(A) := UpValue[B] */
++
++OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
++OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
++
++OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
++OP_SETUPVAL,/* A B UpValue[B] := R(A) */
++OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
++
++OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
++
++OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
++
++OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
++OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
++OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
++OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
++OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
++OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
++OP_UNM,/* A B R(A) := -R(B) */
++OP_NOT,/* A B R(A) := not R(B) */
++OP_LEN,/* A B R(A) := length of R(B) */
++
++OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
++
++OP_JMP,/* sBx pc+=sBx */
++
++OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
++OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
++OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
++
++OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
++OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
++
++OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
++OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
++OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
++
++OP_FORLOOP,/* A sBx R(A)+=R(A+2);
++ if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
++OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
++
++OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
++ if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
++OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
++
++OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
++OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
++
++OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
++} OpCode;
++
++
++#define NUM_OPCODES (cast(int, OP_VARARG) + 1)
++
++
++
++/*===========================================================================
++ Notes:
++ (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
++ and can be 0: OP_CALL then sets `top' to last_result+1, so
++ next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
++
++ (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
++ set top (like in OP_CALL with C == 0).
++
++ (*) In OP_RETURN, if (B == 0) then return up to `top'
++
++ (*) In OP_SETLIST, if (B == 0) then B = `top';
++ if (C == 0) then next `instruction' is real C
++
++ (*) For comparisons, A specifies what condition the test should accept
++ (true or false).
++
++ (*) All `skips' (pc++) assume that next instruction is a jump
++===========================================================================*/
++
++
++/*
++** masks for instruction properties. The format is:
++** bits 0-1: op mode
++** bits 2-3: C arg mode
++** bits 4-5: B arg mode
++** bit 6: instruction set register A
++** bit 7: operator is a test
++*/
++
++enum OpArgMask {
++ OpArgN, /* argument is not used */
++ OpArgU, /* argument is used */
++ OpArgR, /* argument is a register or a jump offset */
++ OpArgK /* argument is a constant or register/constant */
++};
++
++LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
++
++#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
++#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
++#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
++#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
++#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
++
++
++LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
++
++
++/* number of list items to accumulate before a SETLIST instruction */
++#define LFIELDS_PER_FLUSH 50
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lparser.c
+@@ -0,0 +1,1339 @@
++/*
++** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $
++** Lua Parser
++** See Copyright Notice in lua.h
++*/
++
++
++#include <string.h>
++
++#define lparser_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "lcode.h"
++#include "ldebug.h"
++#include "ldo.h"
++#include "lfunc.h"
++#include "llex.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lopcodes.h"
++#include "lparser.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "ltable.h"
++
++
++
++#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
++
++#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
++
++#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
++
++
++/*
++** nodes for block list (list of active blocks)
++*/
++typedef struct BlockCnt {
++ struct BlockCnt *previous; /* chain */
++ int breaklist; /* list of jumps out of this loop */
++ lu_byte nactvar; /* # active locals outside the breakable structure */
++ lu_byte upval; /* true if some variable in the block is an upvalue */
++ lu_byte isbreakable; /* true if `block' is a loop */
++} BlockCnt;
++
++
++
++/*
++** prototypes for recursive non-terminal functions
++*/
++static void chunk (LexState *ls);
++static void expr (LexState *ls, expdesc *v);
++
++
++static void anchor_token (LexState *ls) {
++ if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
++ TString *ts = ls->t.seminfo.ts;
++ luaX_newstring(ls, getstr(ts), ts->tsv.len);
++ }
++}
++
++
++static void error_expected (LexState *ls, int token) {
++ luaX_syntaxerror(ls,
++ luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
++}
++
++
++static void errorlimit (FuncState *fs, int limit, const char *what) {
++ const char *msg = (fs->f->linedefined == 0) ?
++ luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
++ luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
++ fs->f->linedefined, limit, what);
++ luaX_lexerror(fs->ls, msg, 0);
++}
++
++
++static int testnext (LexState *ls, int c) {
++ if (ls->t.token == c) {
++ luaX_next(ls);
++ return 1;
++ }
++ else return 0;
++}
++
++
++static void check (LexState *ls, int c) {
++ if (ls->t.token != c)
++ error_expected(ls, c);
++}
++
++static void checknext (LexState *ls, int c) {
++ check(ls, c);
++ luaX_next(ls);
++}
++
++
++#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
++
++
++
++static void check_match (LexState *ls, int what, int who, int where) {
++ if (!testnext(ls, what)) {
++ if (where == ls->linenumber)
++ error_expected(ls, what);
++ else {
++ luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
++ LUA_QS " expected (to close " LUA_QS " at line %d)",
++ luaX_token2str(ls, what), luaX_token2str(ls, who), where));
++ }
++ }
++}
++
++
++static TString *str_checkname (LexState *ls) {
++ TString *ts;
++ check(ls, TK_NAME);
++ ts = ls->t.seminfo.ts;
++ luaX_next(ls);
++ return ts;
++}
++
++
++static void init_exp (expdesc *e, expkind k, int i) {
++ e->f = e->t = NO_JUMP;
++ e->k = k;
++ e->u.s.info = i;
++}
++
++
++static void codestring (LexState *ls, expdesc *e, TString *s) {
++ init_exp(e, VK, luaK_stringK(ls->fs, s));
++}
++
++
++static void checkname(LexState *ls, expdesc *e) {
++ codestring(ls, e, str_checkname(ls));
++}
++
++
++static int registerlocalvar (LexState *ls, TString *varname) {
++ FuncState *fs = ls->fs;
++ Proto *f = fs->f;
++ int oldsize = f->sizelocvars;
++ luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
++ LocVar, SHRT_MAX, "too many local variables");
++ while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
++ f->locvars[fs->nlocvars].varname = varname;
++ luaC_objbarrier(ls->L, f, varname);
++ return fs->nlocvars++;
++}
++
++
++#define new_localvarliteral(ls,v,n) \
++ new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
++
++
++static void new_localvar (LexState *ls, TString *name, int n) {
++ FuncState *fs = ls->fs;
++ luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
++ fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
++}
++
++
++static void adjustlocalvars (LexState *ls, int nvars) {
++ FuncState *fs = ls->fs;
++ fs->nactvar = cast_byte(fs->nactvar + nvars);
++ for (; nvars; nvars--) {
++ getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
++ }
++}
++
++
++static void removevars (LexState *ls, int tolevel) {
++ FuncState *fs = ls->fs;
++ while (fs->nactvar > tolevel)
++ getlocvar(fs, --fs->nactvar).endpc = fs->pc;
++}
++
++
++static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
++ int i;
++ Proto *f = fs->f;
++ int oldsize = f->sizeupvalues;
++ for (i=0; i<f->nups; i++) {
++ if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
++ lua_assert(f->upvalues[i] == name);
++ return i;
++ }
++ }
++ /* new one */
++ luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
++ luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
++ TString *, MAX_INT, "");
++ while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
++ f->upvalues[f->nups] = name;
++ luaC_objbarrier(fs->L, f, name);
++ lua_assert(v->k == VLOCAL || v->k == VUPVAL);
++ fs->upvalues[f->nups].k = cast_byte(v->k);
++ fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
++ return f->nups++;
++}
++
++
++static int searchvar (FuncState *fs, TString *n) {
++ int i;
++ for (i=fs->nactvar-1; i >= 0; i--) {
++ if (n == getlocvar(fs, i).varname)
++ return i;
++ }
++ return -1; /* not found */
++}
++
++
++static void markupval (FuncState *fs, int level) {
++ BlockCnt *bl = fs->bl;
++ while (bl && bl->nactvar > level) bl = bl->previous;
++ if (bl) bl->upval = 1;
++}
++
++
++static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
++ if (fs == NULL) { /* no more levels? */
++ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
++ return VGLOBAL;
++ }
++ else {
++ int v = searchvar(fs, n); /* look up at current level */
++ if (v >= 0) {
++ init_exp(var, VLOCAL, v);
++ if (!base)
++ markupval(fs, v); /* local will be used as an upval */
++ return VLOCAL;
++ }
++ else { /* not found at current level; try upper one */
++ if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
++ return VGLOBAL;
++ var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
++ var->k = VUPVAL; /* upvalue in this level */
++ return VUPVAL;
++ }
++ }
++}
++
++
++static void singlevar (LexState *ls, expdesc *var) {
++ TString *varname = str_checkname(ls);
++ FuncState *fs = ls->fs;
++ if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
++ var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
++}
++
++
++static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
++ FuncState *fs = ls->fs;
++ int extra = nvars - nexps;
++ if (hasmultret(e->k)) {
++ extra++; /* includes call itself */
++ if (extra < 0) extra = 0;
++ luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
++ if (extra > 1) luaK_reserveregs(fs, extra-1);
++ }
++ else {
++ if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
++ if (extra > 0) {
++ int reg = fs->freereg;
++ luaK_reserveregs(fs, extra);
++ luaK_nil(fs, reg, extra);
++ }
++ }
++}
++
++
++static void enterlevel (LexState *ls) {
++ if (++ls->L->nCcalls > LUAI_MAXCCALLS)
++ luaX_lexerror(ls, "chunk has too many syntax levels", 0);
++}
++
++
++#define leavelevel(ls) ((ls)->L->nCcalls--)
++
++
++static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
++ bl->breaklist = NO_JUMP;
++ bl->isbreakable = isbreakable;
++ bl->nactvar = fs->nactvar;
++ bl->upval = 0;
++ bl->previous = fs->bl;
++ fs->bl = bl;
++ lua_assert(fs->freereg == fs->nactvar);
++}
++
++
++static void leaveblock (FuncState *fs) {
++ BlockCnt *bl = fs->bl;
++ fs->bl = bl->previous;
++ removevars(fs->ls, bl->nactvar);
++ if (bl->upval)
++ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
++ /* a block either controls scope or breaks (never both) */
++ lua_assert(!bl->isbreakable || !bl->upval);
++ lua_assert(bl->nactvar == fs->nactvar);
++ fs->freereg = fs->nactvar; /* free registers */
++ luaK_patchtohere(fs, bl->breaklist);
++}
++
++
++static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
++ FuncState *fs = ls->fs;
++ Proto *f = fs->f;
++ int oldsize = f->sizep;
++ int i;
++ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
++ MAXARG_Bx, "constant table overflow");
++ while (oldsize < f->sizep) f->p[oldsize++] = NULL;
++ f->p[fs->np++] = func->f;
++ luaC_objbarrier(ls->L, f, func->f);
++ init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
++ for (i=0; i<func->f->nups; i++) {
++ OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
++ luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
++ }
++}
++
++
++static void open_func (LexState *ls, FuncState *fs) {
++ lua_State *L = ls->L;
++ Proto *f = luaF_newproto(L);
++ fs->f = f;
++ fs->prev = ls->fs; /* linked list of funcstates */
++ fs->ls = ls;
++ fs->L = L;
++ ls->fs = fs;
++ fs->pc = 0;
++ fs->lasttarget = -1;
++ fs->jpc = NO_JUMP;
++ fs->freereg = 0;
++ fs->nk = 0;
++ fs->np = 0;
++ fs->nlocvars = 0;
++ fs->nactvar = 0;
++ fs->bl = NULL;
++ f->source = ls->source;
++ f->maxstacksize = 2; /* registers 0/1 are always valid */
++ fs->h = luaH_new(L, 0, 0);
++ /* anchor table of constants and prototype (to avoid being collected) */
++ sethvalue2s(L, L->top, fs->h);
++ incr_top(L);
++ setptvalue2s(L, L->top, f);
++ incr_top(L);
++}
++
++
++static void close_func (LexState *ls) {
++ lua_State *L = ls->L;
++ FuncState *fs = ls->fs;
++ Proto *f = fs->f;
++ removevars(ls, 0);
++ luaK_ret(fs, 0, 0); /* final return */
++ luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
++ f->sizecode = fs->pc;
++ luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
++ f->sizelineinfo = fs->pc;
++ luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
++ f->sizek = fs->nk;
++ luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
++ f->sizep = fs->np;
++ luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
++ f->sizelocvars = fs->nlocvars;
++ luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
++ f->sizeupvalues = f->nups;
++ lua_assert(luaG_checkcode(f));
++ lua_assert(fs->bl == NULL);
++ ls->fs = fs->prev;
++ L->top -= 2; /* remove table and prototype from the stack */
++ /* last token read was anchored in defunct function; must reanchor it */
++ if (fs) anchor_token(ls);
++}
++
++
++Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
++ struct LexState lexstate;
++ struct FuncState funcstate;
++ lexstate.buff = buff;
++ luaX_setinput(L, &lexstate, z, luaS_new(L, name));
++ open_func(&lexstate, &funcstate);
++ funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
++ luaX_next(&lexstate); /* read first token */
++ chunk(&lexstate);
++ check(&lexstate, TK_EOS);
++ close_func(&lexstate);
++ lua_assert(funcstate.prev == NULL);
++ lua_assert(funcstate.f->nups == 0);
++ lua_assert(lexstate.fs == NULL);
++ return funcstate.f;
++}
++
++
++
++/*============================================================*/
++/* GRAMMAR RULES */
++/*============================================================*/
++
++
++static void field (LexState *ls, expdesc *v) {
++ /* field -> ['.' | ':'] NAME */
++ FuncState *fs = ls->fs;
++ expdesc key;
++ luaK_exp2anyreg(fs, v);
++ luaX_next(ls); /* skip the dot or colon */
++ checkname(ls, &key);
++ luaK_indexed(fs, v, &key);
++}
++
++
++static void yindex (LexState *ls, expdesc *v) {
++ /* index -> '[' expr ']' */
++ luaX_next(ls); /* skip the '[' */
++ expr(ls, v);
++ luaK_exp2val(ls->fs, v);
++ checknext(ls, ']');
++}
++
++
++/*
++** {======================================================================
++** Rules for Constructors
++** =======================================================================
++*/
++
++
++struct ConsControl {
++ expdesc v; /* last list item read */
++ expdesc *t; /* table descriptor */
++ int nh; /* total number of `record' elements */
++ int na; /* total number of array elements */
++ int tostore; /* number of array elements pending to be stored */
++};
++
++
++static void recfield (LexState *ls, struct ConsControl *cc) {
++ /* recfield -> (NAME | `['exp1`]') = exp1 */
++ FuncState *fs = ls->fs;
++ int reg = ls->fs->freereg;
++ expdesc key, val;
++ int rkkey;
++ if (ls->t.token == TK_NAME) {
++ luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
++ checkname(ls, &key);
++ }
++ else /* ls->t.token == '[' */
++ yindex(ls, &key);
++ cc->nh++;
++ checknext(ls, '=');
++ rkkey = luaK_exp2RK(fs, &key);
++ expr(ls, &val);
++ luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
++ fs->freereg = reg; /* free registers */
++}
++
++
++static void closelistfield (FuncState *fs, struct ConsControl *cc) {
++ if (cc->v.k == VVOID) return; /* there is no list item */
++ luaK_exp2nextreg(fs, &cc->v);
++ cc->v.k = VVOID;
++ if (cc->tostore == LFIELDS_PER_FLUSH) {
++ luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
++ cc->tostore = 0; /* no more items pending */
++ }
++}
++
++
++static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
++ if (cc->tostore == 0) return;
++ if (hasmultret(cc->v.k)) {
++ luaK_setmultret(fs, &cc->v);
++ luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
++ cc->na--; /* do not count last expression (unknown number of elements) */
++ }
++ else {
++ if (cc->v.k != VVOID)
++ luaK_exp2nextreg(fs, &cc->v);
++ luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
++ }
++}
++
++
++static void listfield (LexState *ls, struct ConsControl *cc) {
++ expr(ls, &cc->v);
++ luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
++ cc->na++;
++ cc->tostore++;
++}
++
++
++static void constructor (LexState *ls, expdesc *t) {
++ /* constructor -> ?? */
++ FuncState *fs = ls->fs;
++ int line = ls->linenumber;
++ int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
++ struct ConsControl cc;
++ cc.na = cc.nh = cc.tostore = 0;
++ cc.t = t;
++ init_exp(t, VRELOCABLE, pc);
++ init_exp(&cc.v, VVOID, 0); /* no value (yet) */
++ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
++ checknext(ls, '{');
++ do {
++ lua_assert(cc.v.k == VVOID || cc.tostore > 0);
++ if (ls->t.token == '}') break;
++ closelistfield(fs, &cc);
++ switch(ls->t.token) {
++ case TK_NAME: { /* may be listfields or recfields */
++ luaX_lookahead(ls);
++ if (ls->lookahead.token != '=') /* expression? */
++ listfield(ls, &cc);
++ else
++ recfield(ls, &cc);
++ break;
++ }
++ case '[': { /* constructor_item -> recfield */
++ recfield(ls, &cc);
++ break;
++ }
++ default: { /* constructor_part -> listfield */
++ listfield(ls, &cc);
++ break;
++ }
++ }
++ } while (testnext(ls, ',') || testnext(ls, ';'));
++ check_match(ls, '}', '{', line);
++ lastlistfield(fs, &cc);
++ SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
++ SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
++}
++
++/* }====================================================================== */
++
++
++
++static void parlist (LexState *ls) {
++ /* parlist -> [ param { `,' param } ] */
++ FuncState *fs = ls->fs;
++ Proto *f = fs->f;
++ int nparams = 0;
++ f->is_vararg = 0;
++ if (ls->t.token != ')') { /* is `parlist' not empty? */
++ do {
++ switch (ls->t.token) {
++ case TK_NAME: { /* param -> NAME */
++ new_localvar(ls, str_checkname(ls), nparams++);
++ break;
++ }
++ case TK_DOTS: { /* param -> `...' */
++ luaX_next(ls);
++#if defined(LUA_COMPAT_VARARG)
++ /* use `arg' as default name */
++ new_localvarliteral(ls, "arg", nparams++);
++ f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
++#endif
++ f->is_vararg |= VARARG_ISVARARG;
++ break;
++ }
++ default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
++ }
++ } while (!f->is_vararg && testnext(ls, ','));
++ }
++ adjustlocalvars(ls, nparams);
++ f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
++ luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
++}
++
++
++static void body (LexState *ls, expdesc *e, int needself, int line) {
++ /* body -> `(' parlist `)' chunk END */
++ FuncState new_fs;
++ open_func(ls, &new_fs);
++ new_fs.f->linedefined = line;
++ checknext(ls, '(');
++ if (needself) {
++ new_localvarliteral(ls, "self", 0);
++ adjustlocalvars(ls, 1);
++ }
++ parlist(ls);
++ checknext(ls, ')');
++ chunk(ls);
++ new_fs.f->lastlinedefined = ls->linenumber;
++ check_match(ls, TK_END, TK_FUNCTION, line);
++ close_func(ls);
++ pushclosure(ls, &new_fs, e);
++}
++
++
++static int explist1 (LexState *ls, expdesc *v) {
++ /* explist1 -> expr { `,' expr } */
++ int n = 1; /* at least one expression */
++ expr(ls, v);
++ while (testnext(ls, ',')) {
++ luaK_exp2nextreg(ls->fs, v);
++ expr(ls, v);
++ n++;
++ }
++ return n;
++}
++
++
++static void funcargs (LexState *ls, expdesc *f) {
++ FuncState *fs = ls->fs;
++ expdesc args;
++ int base, nparams;
++ int line = ls->linenumber;
++ switch (ls->t.token) {
++ case '(': { /* funcargs -> `(' [ explist1 ] `)' */
++ if (line != ls->lastline)
++ luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
++ luaX_next(ls);
++ if (ls->t.token == ')') /* arg list is empty? */
++ args.k = VVOID;
++ else {
++ explist1(ls, &args);
++ luaK_setmultret(fs, &args);
++ }
++ check_match(ls, ')', '(', line);
++ break;
++ }
++ case '{': { /* funcargs -> constructor */
++ constructor(ls, &args);
++ break;
++ }
++ case TK_STRING: { /* funcargs -> STRING */
++ codestring(ls, &args, ls->t.seminfo.ts);
++ luaX_next(ls); /* must use `seminfo' before `next' */
++ break;
++ }
++ default: {
++ luaX_syntaxerror(ls, "function arguments expected");
++ return;
++ }
++ }
++ lua_assert(f->k == VNONRELOC);
++ base = f->u.s.info; /* base register for call */
++ if (hasmultret(args.k))
++ nparams = LUA_MULTRET; /* open call */
++ else {
++ if (args.k != VVOID)
++ luaK_exp2nextreg(fs, &args); /* close last argument */
++ nparams = fs->freereg - (base+1);
++ }
++ init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
++ luaK_fixline(fs, line);
++ fs->freereg = base+1; /* call remove function and arguments and leaves
++ (unless changed) one result */
++}
++
++
++
++
++/*
++** {======================================================================
++** Expression parsing
++** =======================================================================
++*/
++
++
++static void prefixexp (LexState *ls, expdesc *v) {
++ /* prefixexp -> NAME | '(' expr ')' */
++ switch (ls->t.token) {
++ case '(': {
++ int line = ls->linenumber;
++ luaX_next(ls);
++ expr(ls, v);
++ check_match(ls, ')', '(', line);
++ luaK_dischargevars(ls->fs, v);
++ return;
++ }
++ case TK_NAME: {
++ singlevar(ls, v);
++ return;
++ }
++ default: {
++ luaX_syntaxerror(ls, "unexpected symbol");
++ return;
++ }
++ }
++}
++
++
++static void primaryexp (LexState *ls, expdesc *v) {
++ /* primaryexp ->
++ prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
++ FuncState *fs = ls->fs;
++ prefixexp(ls, v);
++ for (;;) {
++ switch (ls->t.token) {
++ case '.': { /* field */
++ field(ls, v);
++ break;
++ }
++ case '[': { /* `[' exp1 `]' */
++ expdesc key;
++ luaK_exp2anyreg(fs, v);
++ yindex(ls, &key);
++ luaK_indexed(fs, v, &key);
++ break;
++ }
++ case ':': { /* `:' NAME funcargs */
++ expdesc key;
++ luaX_next(ls);
++ checkname(ls, &key);
++ luaK_self(fs, v, &key);
++ funcargs(ls, v);
++ break;
++ }
++ case '(': case TK_STRING: case '{': { /* funcargs */
++ luaK_exp2nextreg(fs, v);
++ funcargs(ls, v);
++ break;
++ }
++ default: return;
++ }
++ }
++}
++
++
++static void simpleexp (LexState *ls, expdesc *v) {
++ /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
++ constructor | FUNCTION body | primaryexp */
++ switch (ls->t.token) {
++ case TK_NUMBER: {
++ init_exp(v, VKNUM, 0);
++ v->u.nval = ls->t.seminfo.r;
++ break;
++ }
++ case TK_STRING: {
++ codestring(ls, v, ls->t.seminfo.ts);
++ break;
++ }
++ case TK_NIL: {
++ init_exp(v, VNIL, 0);
++ break;
++ }
++ case TK_TRUE: {
++ init_exp(v, VTRUE, 0);
++ break;
++ }
++ case TK_FALSE: {
++ init_exp(v, VFALSE, 0);
++ break;
++ }
++ case TK_DOTS: { /* vararg */
++ FuncState *fs = ls->fs;
++ check_condition(ls, fs->f->is_vararg,
++ "cannot use " LUA_QL("...") " outside a vararg function");
++ fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
++ init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
++ break;
++ }
++ case '{': { /* constructor */
++ constructor(ls, v);
++ return;
++ }
++ case TK_FUNCTION: {
++ luaX_next(ls);
++ body(ls, v, 0, ls->linenumber);
++ return;
++ }
++ default: {
++ primaryexp(ls, v);
++ return;
++ }
++ }
++ luaX_next(ls);
++}
++
++
++static UnOpr getunopr (int op) {
++ switch (op) {
++ case TK_NOT: return OPR_NOT;
++ case '-': return OPR_MINUS;
++ case '#': return OPR_LEN;
++ default: return OPR_NOUNOPR;
++ }
++}
++
++
++static BinOpr getbinopr (int op) {
++ switch (op) {
++ case '+': return OPR_ADD;
++ case '-': return OPR_SUB;
++ case '*': return OPR_MUL;
++ case '/': return OPR_DIV;
++ case '%': return OPR_MOD;
++ case '^': return OPR_POW;
++ case TK_CONCAT: return OPR_CONCAT;
++ case TK_NE: return OPR_NE;
++ case TK_EQ: return OPR_EQ;
++ case '<': return OPR_LT;
++ case TK_LE: return OPR_LE;
++ case '>': return OPR_GT;
++ case TK_GE: return OPR_GE;
++ case TK_AND: return OPR_AND;
++ case TK_OR: return OPR_OR;
++ default: return OPR_NOBINOPR;
++ }
++}
++
++
++static const struct {
++ lu_byte left; /* left priority for each binary operator */
++ lu_byte right; /* right priority */
++} priority[] = { /* ORDER OPR */
++ {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
++ {10, 9}, {5, 4}, /* power and concat (right associative) */
++ {3, 3}, {3, 3}, /* equality and inequality */
++ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
++ {2, 2}, {1, 1} /* logical (and/or) */
++};
++
++#define UNARY_PRIORITY 8 /* priority for unary operators */
++
++
++/*
++** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
++** where `binop' is any binary operator with a priority higher than `limit'
++*/
++static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
++ BinOpr op;
++ UnOpr uop;
++ enterlevel(ls);
++ uop = getunopr(ls->t.token);
++ if (uop != OPR_NOUNOPR) {
++ luaX_next(ls);
++ subexpr(ls, v, UNARY_PRIORITY);
++ luaK_prefix(ls->fs, uop, v);
++ }
++ else simpleexp(ls, v);
++ /* expand while operators have priorities higher than `limit' */
++ op = getbinopr(ls->t.token);
++ while (op != OPR_NOBINOPR && priority[op].left > limit) {
++ expdesc v2;
++ BinOpr nextop;
++ luaX_next(ls);
++ luaK_infix(ls->fs, op, v);
++ /* read sub-expression with higher priority */
++ nextop = subexpr(ls, &v2, priority[op].right);
++ luaK_posfix(ls->fs, op, v, &v2);
++ op = nextop;
++ }
++ leavelevel(ls);
++ return op; /* return first untreated operator */
++}
++
++
++static void expr (LexState *ls, expdesc *v) {
++ subexpr(ls, v, 0);
++}
++
++/* }==================================================================== */
++
++
++
++/*
++** {======================================================================
++** Rules for Statements
++** =======================================================================
++*/
++
++
++static int block_follow (int token) {
++ switch (token) {
++ case TK_ELSE: case TK_ELSEIF: case TK_END:
++ case TK_UNTIL: case TK_EOS:
++ return 1;
++ default: return 0;
++ }
++}
++
++
++static void block (LexState *ls) {
++ /* block -> chunk */
++ FuncState *fs = ls->fs;
++ BlockCnt bl;
++ enterblock(fs, &bl, 0);
++ chunk(ls);
++ lua_assert(bl.breaklist == NO_JUMP);
++ leaveblock(fs);
++}
++
++
++/*
++** structure to chain all variables in the left-hand side of an
++** assignment
++*/
++struct LHS_assign {
++ struct LHS_assign *prev;
++ expdesc v; /* variable (global, local, upvalue, or indexed) */
++};
++
++
++/*
++** check whether, in an assignment to a local variable, the local variable
++** is needed in a previous assignment (to a table). If so, save original
++** local value in a safe place and use this safe copy in the previous
++** assignment.
++*/
++static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
++ FuncState *fs = ls->fs;
++ int extra = fs->freereg; /* eventual position to save local variable */
++ int conflict = 0;
++ for (; lh; lh = lh->prev) {
++ if (lh->v.k == VINDEXED) {
++ if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
++ conflict = 1;
++ lh->v.u.s.info = extra; /* previous assignment will use safe copy */
++ }
++ if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
++ conflict = 1;
++ lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
++ }
++ }
++ }
++ if (conflict) {
++ luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
++ luaK_reserveregs(fs, 1);
++ }
++}
++
++
++static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
++ expdesc e;
++ check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
++ "syntax error");
++ if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
++ struct LHS_assign nv;
++ nv.prev = lh;
++ primaryexp(ls, &nv.v);
++ if (nv.v.k == VLOCAL)
++ check_conflict(ls, lh, &nv.v);
++ luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
++ "variables in assignment");
++ assignment(ls, &nv, nvars+1);
++ }
++ else { /* assignment -> `=' explist1 */
++ int nexps;
++ checknext(ls, '=');
++ nexps = explist1(ls, &e);
++ if (nexps != nvars) {
++ adjust_assign(ls, nvars, nexps, &e);
++ if (nexps > nvars)
++ ls->fs->freereg -= nexps - nvars; /* remove extra values */
++ }
++ else {
++ luaK_setoneret(ls->fs, &e); /* close last expression */
++ luaK_storevar(ls->fs, &lh->v, &e);
++ return; /* avoid default */
++ }
++ }
++ init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
++ luaK_storevar(ls->fs, &lh->v, &e);
++}
++
++
++static int cond (LexState *ls) {
++ /* cond -> exp */
++ expdesc v;
++ expr(ls, &v); /* read condition */
++ if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
++ luaK_goiftrue(ls->fs, &v);
++ return v.f;
++}
++
++
++static void breakstat (LexState *ls) {
++ FuncState *fs = ls->fs;
++ BlockCnt *bl = fs->bl;
++ int upval = 0;
++ while (bl && !bl->isbreakable) {
++ upval |= bl->upval;
++ bl = bl->previous;
++ }
++ if (!bl)
++ luaX_syntaxerror(ls, "no loop to break");
++ if (upval)
++ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
++ luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
++}
++
++
++static void whilestat (LexState *ls, int line) {
++ /* whilestat -> WHILE cond DO block END */
++ FuncState *fs = ls->fs;
++ int whileinit;
++ int condexit;
++ BlockCnt bl;
++ luaX_next(ls); /* skip WHILE */
++ whileinit = luaK_getlabel(fs);
++ condexit = cond(ls);
++ enterblock(fs, &bl, 1);
++ checknext(ls, TK_DO);
++ block(ls);
++ luaK_patchlist(fs, luaK_jump(fs), whileinit);
++ check_match(ls, TK_END, TK_WHILE, line);
++ leaveblock(fs);
++ luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
++}
++
++
++static void repeatstat (LexState *ls, int line) {
++ /* repeatstat -> REPEAT block UNTIL cond */
++ int condexit;
++ FuncState *fs = ls->fs;
++ int repeat_init = luaK_getlabel(fs);
++ BlockCnt bl1, bl2;
++ enterblock(fs, &bl1, 1); /* loop block */
++ enterblock(fs, &bl2, 0); /* scope block */
++ luaX_next(ls); /* skip REPEAT */
++ chunk(ls);
++ check_match(ls, TK_UNTIL, TK_REPEAT, line);
++ condexit = cond(ls); /* read condition (inside scope block) */
++ if (!bl2.upval) { /* no upvalues? */
++ leaveblock(fs); /* finish scope */
++ luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
++ }
++ else { /* complete semantics when there are upvalues */
++ breakstat(ls); /* if condition then break */
++ luaK_patchtohere(ls->fs, condexit); /* else... */
++ leaveblock(fs); /* finish scope... */
++ luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
++ }
++ leaveblock(fs); /* finish loop */
++}
++
++
++static int exp1 (LexState *ls) {
++ expdesc e;
++ int k;
++ expr(ls, &e);
++ k = e.k;
++ luaK_exp2nextreg(ls->fs, &e);
++ return k;
++}
++
++
++static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
++ /* forbody -> DO block */
++ BlockCnt bl;
++ FuncState *fs = ls->fs;
++ int prep, endfor;
++ adjustlocalvars(ls, 3); /* control variables */
++ checknext(ls, TK_DO);
++ prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
++ enterblock(fs, &bl, 0); /* scope for declared variables */
++ adjustlocalvars(ls, nvars);
++ luaK_reserveregs(fs, nvars);
++ block(ls);
++ leaveblock(fs); /* end of scope for declared variables */
++ luaK_patchtohere(fs, prep);
++ endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
++ luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
++ luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
++ luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
++}
++
++
++static void fornum (LexState *ls, TString *varname, int line) {
++ /* fornum -> NAME = exp1,exp1[,exp1] forbody */
++ FuncState *fs = ls->fs;
++ int base = fs->freereg;
++ new_localvarliteral(ls, "(for index)", 0);
++ new_localvarliteral(ls, "(for limit)", 1);
++ new_localvarliteral(ls, "(for step)", 2);
++ new_localvar(ls, varname, 3);
++ checknext(ls, '=');
++ exp1(ls); /* initial value */
++ checknext(ls, ',');
++ exp1(ls); /* limit */
++ if (testnext(ls, ','))
++ exp1(ls); /* optional step */
++ else { /* default step = 1 */
++ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
++ luaK_reserveregs(fs, 1);
++ }
++ forbody(ls, base, line, 1, 1);
++}
++
++
++static void forlist (LexState *ls, TString *indexname) {
++ /* forlist -> NAME {,NAME} IN explist1 forbody */
++ FuncState *fs = ls->fs;
++ expdesc e;
++ int nvars = 0;
++ int line;
++ int base = fs->freereg;
++ /* create control variables */
++ new_localvarliteral(ls, "(for generator)", nvars++);
++ new_localvarliteral(ls, "(for state)", nvars++);
++ new_localvarliteral(ls, "(for control)", nvars++);
++ /* create declared variables */
++ new_localvar(ls, indexname, nvars++);
++ while (testnext(ls, ','))
++ new_localvar(ls, str_checkname(ls), nvars++);
++ checknext(ls, TK_IN);
++ line = ls->linenumber;
++ adjust_assign(ls, 3, explist1(ls, &e), &e);
++ luaK_checkstack(fs, 3); /* extra space to call generator */
++ forbody(ls, base, line, nvars - 3, 0);
++}
++
++
++static void forstat (LexState *ls, int line) {
++ /* forstat -> FOR (fornum | forlist) END */
++ FuncState *fs = ls->fs;
++ TString *varname;
++ BlockCnt bl;
++ enterblock(fs, &bl, 1); /* scope for loop and control variables */
++ luaX_next(ls); /* skip `for' */
++ varname = str_checkname(ls); /* first variable name */
++ switch (ls->t.token) {
++ case '=': fornum(ls, varname, line); break;
++ case ',': case TK_IN: forlist(ls, varname); break;
++ default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
++ }
++ check_match(ls, TK_END, TK_FOR, line);
++ leaveblock(fs); /* loop scope (`break' jumps to this point) */
++}
++
++
++static int test_then_block (LexState *ls) {
++ /* test_then_block -> [IF | ELSEIF] cond THEN block */
++ int condexit;
++ luaX_next(ls); /* skip IF or ELSEIF */
++ condexit = cond(ls);
++ checknext(ls, TK_THEN);
++ block(ls); /* `then' part */
++ return condexit;
++}
++
++
++static void ifstat (LexState *ls, int line) {
++ /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
++ FuncState *fs = ls->fs;
++ int flist;
++ int escapelist = NO_JUMP;
++ flist = test_then_block(ls); /* IF cond THEN block */
++ while (ls->t.token == TK_ELSEIF) {
++ luaK_concat(fs, &escapelist, luaK_jump(fs));
++ luaK_patchtohere(fs, flist);
++ flist = test_then_block(ls); /* ELSEIF cond THEN block */
++ }
++ if (ls->t.token == TK_ELSE) {
++ luaK_concat(fs, &escapelist, luaK_jump(fs));
++ luaK_patchtohere(fs, flist);
++ luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
++ block(ls); /* `else' part */
++ }
++ else
++ luaK_concat(fs, &escapelist, flist);
++ luaK_patchtohere(fs, escapelist);
++ check_match(ls, TK_END, TK_IF, line);
++}
++
++
++static void localfunc (LexState *ls) {
++ expdesc v, b;
++ FuncState *fs = ls->fs;
++ new_localvar(ls, str_checkname(ls), 0);
++ init_exp(&v, VLOCAL, fs->freereg);
++ luaK_reserveregs(fs, 1);
++ adjustlocalvars(ls, 1);
++ body(ls, &b, 0, ls->linenumber);
++ luaK_storevar(fs, &v, &b);
++ /* debug information will only see the variable after this point! */
++ getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
++}
++
++
++static void localstat (LexState *ls) {
++ /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
++ int nvars = 0;
++ int nexps;
++ expdesc e;
++ do {
++ new_localvar(ls, str_checkname(ls), nvars++);
++ } while (testnext(ls, ','));
++ if (testnext(ls, '='))
++ nexps = explist1(ls, &e);
++ else {
++ e.k = VVOID;
++ nexps = 0;
++ }
++ adjust_assign(ls, nvars, nexps, &e);
++ adjustlocalvars(ls, nvars);
++}
++
++
++static int funcname (LexState *ls, expdesc *v) {
++ /* funcname -> NAME {field} [`:' NAME] */
++ int needself = 0;
++ singlevar(ls, v);
++ while (ls->t.token == '.')
++ field(ls, v);
++ if (ls->t.token == ':') {
++ needself = 1;
++ field(ls, v);
++ }
++ return needself;
++}
++
++
++static void funcstat (LexState *ls, int line) {
++ /* funcstat -> FUNCTION funcname body */
++ int needself;
++ expdesc v, b;
++ luaX_next(ls); /* skip FUNCTION */
++ needself = funcname(ls, &v);
++ body(ls, &b, needself, line);
++ luaK_storevar(ls->fs, &v, &b);
++ luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
++}
++
++
++static void exprstat (LexState *ls) {
++ /* stat -> func | assignment */
++ FuncState *fs = ls->fs;
++ struct LHS_assign v;
++ primaryexp(ls, &v.v);
++ if (v.v.k == VCALL) /* stat -> func */
++ SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
++ else { /* stat -> assignment */
++ v.prev = NULL;
++ assignment(ls, &v, 1);
++ }
++}
++
++
++static void retstat (LexState *ls) {
++ /* stat -> RETURN explist */
++ FuncState *fs = ls->fs;
++ expdesc e;
++ int first, nret; /* registers with returned values */
++ luaX_next(ls); /* skip RETURN */
++ if (block_follow(ls->t.token) || ls->t.token == ';')
++ first = nret = 0; /* return no values */
++ else {
++ nret = explist1(ls, &e); /* optional return values */
++ if (hasmultret(e.k)) {
++ luaK_setmultret(fs, &e);
++ if (e.k == VCALL && nret == 1) { /* tail call? */
++ SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
++ lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
++ }
++ first = fs->nactvar;
++ nret = LUA_MULTRET; /* return all values */
++ }
++ else {
++ if (nret == 1) /* only one single value? */
++ first = luaK_exp2anyreg(fs, &e);
++ else {
++ luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
++ first = fs->nactvar; /* return all `active' values */
++ lua_assert(nret == fs->freereg - first);
++ }
++ }
++ }
++ luaK_ret(fs, first, nret);
++}
++
++
++static int statement (LexState *ls) {
++ int line = ls->linenumber; /* may be needed for error messages */
++ switch (ls->t.token) {
++ case TK_IF: { /* stat -> ifstat */
++ ifstat(ls, line);
++ return 0;
++ }
++ case TK_WHILE: { /* stat -> whilestat */
++ whilestat(ls, line);
++ return 0;
++ }
++ case TK_DO: { /* stat -> DO block END */
++ luaX_next(ls); /* skip DO */
++ block(ls);
++ check_match(ls, TK_END, TK_DO, line);
++ return 0;
++ }
++ case TK_FOR: { /* stat -> forstat */
++ forstat(ls, line);
++ return 0;
++ }
++ case TK_REPEAT: { /* stat -> repeatstat */
++ repeatstat(ls, line);
++ return 0;
++ }
++ case TK_FUNCTION: {
++ funcstat(ls, line); /* stat -> funcstat */
++ return 0;
++ }
++ case TK_LOCAL: { /* stat -> localstat */
++ luaX_next(ls); /* skip LOCAL */
++ if (testnext(ls, TK_FUNCTION)) /* local function? */
++ localfunc(ls);
++ else
++ localstat(ls);
++ return 0;
++ }
++ case TK_RETURN: { /* stat -> retstat */
++ retstat(ls);
++ return 1; /* must be last statement */
++ }
++ case TK_BREAK: { /* stat -> breakstat */
++ luaX_next(ls); /* skip BREAK */
++ breakstat(ls);
++ return 1; /* must be last statement */
++ }
++ default: {
++ exprstat(ls);
++ return 0; /* to avoid warnings */
++ }
++ }
++}
++
++
++static void chunk (LexState *ls) {
++ /* chunk -> { stat [`;'] } */
++ int islast = 0;
++ enterlevel(ls);
++ while (!islast && !block_follow(ls->t.token)) {
++ islast = statement(ls);
++ testnext(ls, ';');
++ lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
++ ls->fs->freereg >= ls->fs->nactvar);
++ ls->fs->freereg = ls->fs->nactvar; /* free registers */
++ }
++ leavelevel(ls);
++}
++
++/* }====================================================================== */
+--- /dev/null
++++ b/extensions/LUA/lua/lparser.h
+@@ -0,0 +1,82 @@
++/*
++** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $
++** Lua Parser
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lparser_h
++#define lparser_h
++
++#include "llimits.h"
++#include "lobject.h"
++#include "lzio.h"
++
++
++/*
++** Expression descriptor
++*/
++
++typedef enum {
++ VVOID, /* no value */
++ VNIL,
++ VTRUE,
++ VFALSE,
++ VK, /* info = index of constant in `k' */
++ VKNUM, /* nval = numerical value */
++ VLOCAL, /* info = local register */
++ VUPVAL, /* info = index of upvalue in `upvalues' */
++ VGLOBAL, /* info = index of table; aux = index of global name in `k' */
++ VINDEXED, /* info = table register; aux = index register (or `k') */
++ VJMP, /* info = instruction pc */
++ VRELOCABLE, /* info = instruction pc */
++ VNONRELOC, /* info = result register */
++ VCALL, /* info = instruction pc */
++ VVARARG /* info = instruction pc */
++} expkind;
++
++typedef struct expdesc {
++ expkind k;
++ union {
++ struct { int info, aux; } s;
++ lua_Number nval;
++ } u;
++ int t; /* patch list of `exit when true' */
++ int f; /* patch list of `exit when false' */
++} expdesc;
++
++
++typedef struct upvaldesc {
++ lu_byte k;
++ lu_byte info;
++} upvaldesc;
++
++
++struct BlockCnt; /* defined in lparser.c */
++
++
++/* state needed to generate code for a given function */
++typedef struct FuncState {
++ Proto *f; /* current function header */
++ Table *h; /* table to find (and reuse) elements in `k' */
++ struct FuncState *prev; /* enclosing function */
++ struct LexState *ls; /* lexical state */
++ struct lua_State *L; /* copy of the Lua state */
++ struct BlockCnt *bl; /* chain of current blocks */
++ int pc; /* next position to code (equivalent to `ncode') */
++ int lasttarget; /* `pc' of last `jump target' */
++ int jpc; /* list of pending jumps to `pc' */
++ int freereg; /* first free register */
++ int nk; /* number of elements in `k' */
++ int np; /* number of elements in `p' */
++ short nlocvars; /* number of elements in `locvars' */
++ lu_byte nactvar; /* number of active local variables */
++ upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
++ unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
++} FuncState;
++
++
++LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
++ const char *name);
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lstate.c
+@@ -0,0 +1,214 @@
++/*
++** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $
++** Global State
++** See Copyright Notice in lua.h
++*/
++
++
++#include <stddef.h>
++
++#define lstate_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "ldebug.h"
++#include "ldo.h"
++#include "lfunc.h"
++#include "lgc.h"
++#include "llex.h"
++#include "lmem.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "ltable.h"
++#include "ltm.h"
++
++
++#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
++#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
++#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
++
++
++/*
++** Main thread combines a thread state and the global state
++*/
++typedef struct LG {
++ lua_State l;
++ global_State g;
++} LG;
++
++
++
++static void stack_init (lua_State *L1, lua_State *L) {
++ /* initialize CallInfo array */
++ L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
++ L1->ci = L1->base_ci;
++ L1->size_ci = BASIC_CI_SIZE;
++ L1->end_ci = L1->base_ci + L1->size_ci - 1;
++ /* initialize stack array */
++ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
++ L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
++ L1->top = L1->stack;
++ L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
++ /* initialize first ci */
++ L1->ci->func = L1->top;
++ setnilvalue(L1->top++); /* `function' entry for this `ci' */
++ L1->base = L1->ci->base = L1->top;
++ L1->ci->top = L1->top + LUA_MINSTACK;
++}
++
++
++static void freestack (lua_State *L, lua_State *L1) {
++ luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
++ luaM_freearray(L, L1->stack, L1->stacksize, TValue);
++}
++
++
++/*
++** open parts that may cause memory-allocation errors
++*/
++static void f_luaopen (lua_State *L, void *ud) {
++ global_State *g = G(L);
++ UNUSED(ud);
++ stack_init(L, L); /* init stack */
++ sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
++ sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
++ luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
++ luaT_init(L);
++ luaX_init(L);
++ luaS_fix(luaS_newliteral(L, MEMERRMSG));
++ g->GCthreshold = 4*g->totalbytes;
++}
++
++
++static void preinit_state (lua_State *L, global_State *g) {
++ G(L) = g;
++ L->stack = NULL;
++ L->stacksize = 0;
++ L->errorJmp = NULL;
++ L->hook = NULL;
++ L->hookmask = 0;
++ L->basehookcount = 0;
++ L->allowhook = 1;
++ resethookcount(L);
++ L->openupval = NULL;
++ L->size_ci = 0;
++ L->nCcalls = L->baseCcalls = 0;
++ L->status = 0;
++ L->base_ci = L->ci = NULL;
++ L->savedpc = NULL;
++ L->errfunc = 0;
++ setnilvalue(gt(L));
++}
++
++
++static void close_state (lua_State *L) {
++ global_State *g = G(L);
++ luaF_close(L, L->stack); /* close all upvalues for this thread */
++ luaC_freeall(L); /* collect all objects */
++ lua_assert(g->rootgc == obj2gco(L));
++ lua_assert(g->strt.nuse == 0);
++ luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
++ luaZ_freebuffer(L, &g->buff);
++ freestack(L, L);
++ lua_assert(g->totalbytes == sizeof(LG));
++ (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
++}
++
++
++lua_State *luaE_newthread (lua_State *L) {
++ lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
++ luaC_link(L, obj2gco(L1), LUA_TTHREAD);
++ preinit_state(L1, G(L));
++ stack_init(L1, L); /* init stack */
++ setobj2n(L, gt(L1), gt(L)); /* share table of globals */
++ L1->hookmask = L->hookmask;
++ L1->basehookcount = L->basehookcount;
++ L1->hook = L->hook;
++ resethookcount(L1);
++ lua_assert(iswhite(obj2gco(L1)));
++ return L1;
++}
++
++
++void luaE_freethread (lua_State *L, lua_State *L1) {
++ luaF_close(L1, L1->stack); /* close all upvalues for this thread */
++ lua_assert(L1->openupval == NULL);
++ luai_userstatefree(L1);
++ freestack(L, L1);
++ luaM_freemem(L, fromstate(L1), state_size(lua_State));
++}
++
++
++LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
++ int i;
++ lua_State *L;
++ global_State *g;
++ void *l = (*f)(ud, NULL, 0, state_size(LG));
++ if (l == NULL) return NULL;
++ L = tostate(l);
++ g = &((LG *)L)->g;
++ L->next = NULL;
++ L->tt = LUA_TTHREAD;
++ g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
++ L->marked = luaC_white(g);
++ set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
++ preinit_state(L, g);
++ g->frealloc = f;
++ g->ud = ud;
++ g->mainthread = L;
++ g->uvhead.u.l.prev = &g->uvhead;
++ g->uvhead.u.l.next = &g->uvhead;
++ g->GCthreshold = 0; /* mark it as unfinished state */
++ g->strt.size = 0;
++ g->strt.nuse = 0;
++ g->strt.hash = NULL;
++ setnilvalue(registry(L));
++ luaZ_initbuffer(L, &g->buff);
++ g->panic = NULL;
++ g->gcstate = GCSpause;
++ g->rootgc = obj2gco(L);
++ g->sweepstrgc = 0;
++ g->sweepgc = &g->rootgc;
++ g->gray = NULL;
++ g->grayagain = NULL;
++ g->weak = NULL;
++ g->tmudata = NULL;
++ g->totalbytes = sizeof(LG);
++ g->gcpause = LUAI_GCPAUSE;
++ g->gcstepmul = LUAI_GCMUL;
++ g->gcdept = 0;
++ for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
++ if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
++ /* memory allocation error: free partial state */
++ close_state(L);
++ L = NULL;
++ }
++ else
++ luai_userstateopen(L);
++ return L;
++}
++
++
++static void callallgcTM (lua_State *L, void *ud) {
++ UNUSED(ud);
++ luaC_callGCTM(L); /* call GC metamethods for all udata */
++}
++
++
++LUA_API void lua_close (lua_State *L) {
++ L = G(L)->mainthread; /* only the main thread can be closed */
++ lua_lock(L);
++ luaF_close(L, L->stack); /* close all upvalues for this thread */
++ luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
++ L->errfunc = 0; /* no error function during GC metamethods */
++ do { /* repeat until no more errors */
++ L->ci = L->base_ci;
++ L->base = L->top = L->ci->base;
++ L->nCcalls = L->baseCcalls = 0;
++ } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
++ lua_assert(G(L)->tmudata == NULL);
++ luai_userstateclose(L);
++ close_state(L);
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/lstate.h
+@@ -0,0 +1,169 @@
++/*
++** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $
++** Global State
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lstate_h
++#define lstate_h
++
++#include "lua.h"
++
++#include "lobject.h"
++#include "ltm.h"
++#include "lzio.h"
++
++
++
++struct lua_longjmp; /* defined in ldo.c */
++
++
++/* table of globals */
++#define gt(L) (&L->l_gt)
++
++/* registry */
++#define registry(L) (&G(L)->l_registry)
++
++
++/* extra stack space to handle TM calls and some other extras */
++#define EXTRA_STACK 5
++
++
++#define BASIC_CI_SIZE 8
++
++#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
++
++
++
++typedef struct stringtable {
++ GCObject **hash;
++ lu_int32 nuse; /* number of elements */
++ int size;
++} stringtable;
++
++
++/*
++** informations about a call
++*/
++typedef struct CallInfo {
++ StkId base; /* base for this function */
++ StkId func; /* function index in the stack */
++ StkId top; /* top for this function */
++ const Instruction *savedpc;
++ int nresults; /* expected number of results from this function */
++ int tailcalls; /* number of tail calls lost under this entry */
++} CallInfo;
++
++
++
++#define curr_func(L) (clvalue(L->ci->func))
++#define ci_func(ci) (clvalue((ci)->func))
++#define f_isLua(ci) (!ci_func(ci)->c.isC)
++#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
++
++
++/*
++** `global state', shared by all threads of this state
++*/
++typedef struct global_State {
++ stringtable strt; /* hash table for strings */
++ lua_Alloc frealloc; /* function to reallocate memory */
++ void *ud; /* auxiliary data to `frealloc' */
++ lu_byte currentwhite;
++ lu_byte gcstate; /* state of garbage collector */
++ int sweepstrgc; /* position of sweep in `strt' */
++ GCObject *rootgc; /* list of all collectable objects */
++ GCObject **sweepgc; /* position of sweep in `rootgc' */
++ GCObject *gray; /* list of gray objects */
++ GCObject *grayagain; /* list of objects to be traversed atomically */
++ GCObject *weak; /* list of weak tables (to be cleared) */
++ GCObject *tmudata; /* last element of list of userdata to be GC */
++ Mbuffer buff; /* temporary buffer for string concatentation */
++ lu_mem GCthreshold;
++ lu_mem totalbytes; /* number of bytes currently allocated */
++ lu_mem estimate; /* an estimate of number of bytes actually in use */
++ lu_mem gcdept; /* how much GC is `behind schedule' */
++ int gcpause; /* size of pause between successive GCs */
++ int gcstepmul; /* GC `granularity' */
++ lua_CFunction panic; /* to be called in unprotected errors */
++ TValue l_registry;
++ struct lua_State *mainthread;
++ UpVal uvhead; /* head of double-linked list of all open upvalues */
++ struct Table *mt[NUM_TAGS]; /* metatables for basic types */
++ TString *tmname[TM_N]; /* array with tag-method names */
++} global_State;
++
++
++/*
++** `per thread' state
++*/
++struct lua_State {
++ CommonHeader;
++ lu_byte status;
++ StkId top; /* first free slot in the stack */
++ StkId base; /* base of current function */
++ global_State *l_G;
++ CallInfo *ci; /* call info for current function */
++ const Instruction *savedpc; /* `savedpc' of current function */
++ StkId stack_last; /* last free slot in the stack */
++ StkId stack; /* stack base */
++ CallInfo *end_ci; /* points after end of ci array*/
++ CallInfo *base_ci; /* array of CallInfo's */
++ int stacksize;
++ int size_ci; /* size of array `base_ci' */
++ unsigned short nCcalls; /* number of nested C calls */
++ unsigned short baseCcalls; /* nested C calls when resuming coroutine */
++ lu_byte hookmask;
++ lu_byte allowhook;
++ int basehookcount;
++ int hookcount;
++ lua_Hook hook;
++ TValue l_gt; /* table of globals */
++ TValue env; /* temporary place for environments */
++ GCObject *openupval; /* list of open upvalues in this stack */
++ GCObject *gclist;
++ struct lua_longjmp *errorJmp; /* current error recover point */
++ ptrdiff_t errfunc; /* current error handling function (stack index) */
++};
++
++
++#define G(L) (L->l_G)
++
++
++/*
++** Union of all collectable objects
++*/
++union GCObject {
++ GCheader gch;
++ union TString ts;
++ union Udata u;
++ union Closure cl;
++ struct Table h;
++ struct Proto p;
++ struct UpVal uv;
++ struct lua_State th; /* thread */
++};
++
++
++/* macros to convert a GCObject into a specific value */
++#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
++#define gco2ts(o) (&rawgco2ts(o)->tsv)
++#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
++#define gco2u(o) (&rawgco2u(o)->uv)
++#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
++#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
++#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
++#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
++#define ngcotouv(o) \
++ check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
++#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
++
++/* macro to convert any Lua object into a GCObject */
++#define obj2gco(v) (cast(GCObject *, (v)))
++
++
++LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
++LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
++
++#endif
++
+--- /dev/null
++++ b/extensions/LUA/lua/lstring.c
+@@ -0,0 +1,110 @@
++/*
++** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
++** String table (keeps all strings handled by Lua)
++** See Copyright Notice in lua.h
++*/
++
++#include <string.h>
++
++#define lstring_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "lmem.h"
++#include "lobject.h"
++#include "lstate.h"
++#include "lstring.h"
++
++
++
++void luaS_resize (lua_State *L, int newsize) {
++ GCObject **newhash;
++ stringtable *tb;
++ int i;
++ if (G(L)->gcstate == GCSsweepstring)
++ return; /* cannot resize during GC traverse */
++ newhash = luaM_newvector(L, newsize, GCObject *);
++ tb = &G(L)->strt;
++ for (i=0; i<newsize; i++) newhash[i] = NULL;
++ /* rehash */
++ for (i=0; i<tb->size; i++) {
++ GCObject *p = tb->hash[i];
++ while (p) { /* for each node in the list */
++ GCObject *next = p->gch.next; /* save next */
++ unsigned int h = gco2ts(p)->hash;
++ int h1 = lmod(h, newsize); /* new position */
++ lua_assert(cast_int(h%newsize) == lmod(h, newsize));
++ p->gch.next = newhash[h1]; /* chain it */
++ newhash[h1] = p;
++ p = next;
++ }
++ }
++ luaM_freearray(L, tb->hash, tb->size, TString *);
++ tb->size = newsize;
++ tb->hash = newhash;
++}
++
++
++static TString *newlstr (lua_State *L, const char *str, size_t l,
++ unsigned int h) {
++ TString *ts;
++ stringtable *tb;
++ if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
++ luaM_toobig(L);
++ ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
++ ts->tsv.len = l;
++ ts->tsv.hash = h;
++ ts->tsv.marked = luaC_white(G(L));
++ ts->tsv.tt = LUA_TSTRING;
++ ts->tsv.reserved = 0;
++ memcpy(ts+1, str, l*sizeof(char));
++ ((char *)(ts+1))[l] = '\0'; /* ending 0 */
++ tb = &G(L)->strt;
++ h = lmod(h, tb->size);
++ ts->tsv.next = tb->hash[h]; /* chain new entry */
++ tb->hash[h] = obj2gco(ts);
++ tb->nuse++;
++ if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
++ luaS_resize(L, tb->size*2); /* too crowded */
++ return ts;
++}
++
++
++TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
++ GCObject *o;
++ unsigned int h = cast(unsigned int, l); /* seed */
++ size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
++ size_t l1;
++ for (l1=l; l1>=step; l1-=step) /* compute hash */
++ h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
++ for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
++ o != NULL;
++ o = o->gch.next) {
++ TString *ts = rawgco2ts(o);
++ if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
++ /* string may be dead */
++ if (isdead(G(L), o)) changewhite(o);
++ return ts;
++ }
++ }
++ return newlstr(L, str, l, h); /* not found */
++}
++
++
++Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
++ Udata *u;
++ if (s > MAX_SIZET - sizeof(Udata))
++ luaM_toobig(L);
++ u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
++ u->uv.marked = luaC_white(G(L)); /* is not finalized */
++ u->uv.tt = LUA_TUSERDATA;
++ u->uv.len = s;
++ u->uv.metatable = NULL;
++ u->uv.env = e;
++ /* chain it on udata list (after main thread) */
++ u->uv.next = G(L)->mainthread->next;
++ G(L)->mainthread->next = obj2gco(u);
++ return u;
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/lstring.h
+@@ -0,0 +1,31 @@
++/*
++** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $
++** String table (keep all strings handled by Lua)
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lstring_h
++#define lstring_h
++
++
++#include "lgc.h"
++#include "lobject.h"
++#include "lstate.h"
++
++
++#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
++
++#define sizeudata(u) (sizeof(union Udata)+(u)->len)
++
++#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
++#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
++ (sizeof(s)/sizeof(char))-1))
++
++#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
++
++LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
++LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
++LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lstrlib.c
+@@ -0,0 +1,883 @@
++/*
++** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $
++** Standard library for string operations and pattern-matching
++** See Copyright Notice in lua.h
++*/
++
++
++#include <ctype.h>
++#include <stddef.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#define lstrlib_c
++#define LUA_LIB
++
++#include "lua.h"
++
++#include "lauxlib.h"
++#include "lualib.h"
++
++
++/* macro to `unsign' a character */
++#define uchar(c) ((unsigned char)(c))
++
++
++
++static int str_len (lua_State *L) {
++ size_t l;
++ luaL_checklstring(L, 1, &l);
++ lua_pushinteger(L, l);
++ return 1;
++}
++
++
++static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
++ /* relative string position: negative means back from end */
++ if (pos < 0) pos += (ptrdiff_t)len + 1;
++ return (pos >= 0) ? pos : 0;
++}
++
++
++static int str_sub (lua_State *L) {
++ size_t l;
++ const char *s = luaL_checklstring(L, 1, &l);
++ ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
++ ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
++ if (start < 1) start = 1;
++ if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
++ if (start <= end)
++ lua_pushlstring(L, s+start-1, end-start+1);
++ else lua_pushliteral(L, "");
++ return 1;
++}
++
++
++static int str_reverse (lua_State *L) {
++ size_t l;
++ const char *s = luaL_checklstring(L, 1, &l);
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "str_reverse: cannot allocate memory");
++ luaL_buffinit(L, b);
++ while (l--) luaL_addchar(b, s[l]);
++ luaL_pushresult(b);
++ kfree(b);
++ return 1;
++}
++
++
++static int str_lower (lua_State *L) {
++ size_t l;
++ size_t i;
++ const char *s = luaL_checklstring(L, 1, &l);
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "str_lower: cannot allocate memory");
++ luaL_buffinit(L, b);
++ for (i=0; i<l; i++)
++ luaL_addchar(b, tolower(uchar(s[i])));
++ luaL_pushresult(b);
++ kfree(b);
++ return 1;
++}
++
++
++static int str_upper (lua_State *L) {
++ size_t l;
++ size_t i;
++ const char *s = luaL_checklstring(L, 1, &l);
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "str_upper: cannot allocate memory");
++ luaL_buffinit(L, b);
++ for (i=0; i<l; i++)
++ luaL_addchar(b, toupper(uchar(s[i])));
++ luaL_pushresult(b);
++ kfree(b);
++ return 1;
++}
++
++static int str_rep (lua_State *L) {
++ size_t l;
++ const char *s = luaL_checklstring(L, 1, &l);
++ int n = luaL_checkint(L, 2);
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "str_rep: cannot allocate memory");
++ luaL_buffinit(L, b);
++ while (n-- > 0)
++ luaL_addlstring(b, s, l);
++ luaL_pushresult(b);
++ kfree(b);
++ return 1;
++}
++
++
++static int str_byte (lua_State *L) {
++ size_t l;
++ const char *s = luaL_checklstring(L, 1, &l);
++ ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
++ ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
++ int n, i;
++ if (posi <= 0) posi = 1;
++ if ((size_t)pose > l) pose = l;
++ if (posi > pose) return 0; /* empty interval; return no values */
++ n = (int)(pose - posi + 1);
++ if (posi + n <= pose) /* overflow? */
++ luaL_error(L, "string slice too long");
++ luaL_checkstack(L, n, "string slice too long");
++ for (i=0; i<n; i++)
++ lua_pushinteger(L, uchar(s[posi+i-1]));
++ return n;
++}
++
++
++static int str_char (lua_State *L) {
++ int n = lua_gettop(L); /* number of arguments */
++ int i;
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "str_char: cannot allocate memory");
++ luaL_buffinit(L, b);
++ for (i=1; i<=n; i++) {
++ int c = luaL_checkint(L, i);
++ luaL_argcheck(L, uchar(c) == c, i, "invalid value");
++ luaL_addchar(b, uchar(c));
++ }
++ luaL_pushresult(b);
++ kfree(b);
++ return 1;
++}
++
++
++static int writer (lua_State *L, const void* b, size_t size, void* B) {
++ (void)L;
++ luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
++ return 0;
++}
++
++
++static int str_dump (lua_State *L) {
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "str_dump: cannot allocate memory");
++ luaL_checktype(L, 1, LUA_TFUNCTION);
++ lua_settop(L, 1);
++ luaL_buffinit(L,b);
++ if (lua_dump(L, writer, b) != 0){
++ kfree(b);
++ luaL_error(L, "unable to dump given function");
++ }
++
++ luaL_pushresult(b);
++ kfree(b);
++ return 1;
++}
++
++
++
++/*
++** {======================================================
++** PATTERN MATCHING
++** =======================================================
++*/
++
++
++#define CAP_UNFINISHED (-1)
++#define CAP_POSITION (-2)
++
++typedef struct MatchState {
++ const char *src_init; /* init of source string */
++ const char *src_end; /* end (`\0') of source string */
++ lua_State *L;
++ int level; /* total number of captures (finished or unfinished) */
++ struct {
++ const char *init;
++ ptrdiff_t len;
++ } capture[LUA_MAXCAPTURES];
++} MatchState;
++
++
++#define L_ESC '%'
++#define SPECIALS "^$*+?.([%-"
++
++
++static int check_capture (MatchState *ms, int l) {
++ l -= '1';
++ if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
++ return luaL_error(ms->L, "invalid capture index");
++ return l;
++}
++
++
++static int capture_to_close (MatchState *ms) {
++ int level = ms->level;
++ for (level--; level>=0; level--)
++ if (ms->capture[level].len == CAP_UNFINISHED) return level;
++ return luaL_error(ms->L, "invalid pattern capture");
++}
++
++
++static const char *classend (MatchState *ms, const char *p) {
++ switch (*p++) {
++ case L_ESC: {
++ if (*p == '\0')
++ luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
++ return p+1;
++ }
++ case '[': {
++ if (*p == '^') p++;
++ do { /* look for a `]' */
++ if (*p == '\0')
++ luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
++ if (*(p++) == L_ESC && *p != '\0')
++ p++; /* skip escapes (e.g. `%]') */
++ } while (*p != ']');
++ return p+1;
++ }
++ default: {
++ return p;
++ }
++ }
++}
++
++
++static int match_class (int c, int cl) {
++ int res;
++ switch (tolower(cl)) {
++ case 'a' : res = isalpha(c); break;
++ case 'c' : res = iscntrl(c); break;
++ case 'd' : res = isdigit(c); break;
++ case 'l' : res = islower(c); break;
++ case 'p' : res = ispunct(c); break;
++ case 's' : res = isspace(c); break;
++ case 'u' : res = isupper(c); break;
++ case 'w' : res = isalnum(c); break;
++ case 'x' : res = isxdigit(c); break;
++ case 'z' : res = (c == 0); break;
++ default: return (cl == c);
++ }
++ return (islower(cl) ? res : !res);
++}
++
++
++static int matchbracketclass (int c, const char *p, const char *ec) {
++ int sig = 1;
++ if (*(p+1) == '^') {
++ sig = 0;
++ p++; /* skip the `^' */
++ }
++ while (++p < ec) {
++ if (*p == L_ESC) {
++ p++;
++ if (match_class(c, uchar(*p)))
++ return sig;
++ }
++ else if ((*(p+1) == '-') && (p+2 < ec)) {
++ p+=2;
++ if (uchar(*(p-2)) <= c && c <= uchar(*p))
++ return sig;
++ }
++ else if (uchar(*p) == c) return sig;
++ }
++ return !sig;
++}
++
++
++static int singlematch (int c, const char *p, const char *ep) {
++ switch (*p) {
++ case '.': return 1; /* matches any char */
++ case L_ESC: return match_class(c, uchar(*(p+1)));
++ case '[': return matchbracketclass(c, p, ep-1);
++ default: return (uchar(*p) == c);
++ }
++}
++
++
++static const char *match (MatchState *ms, const char *s, const char *p);
++
++
++static const char *matchbalance (MatchState *ms, const char *s,
++ const char *p) {
++ if (*p == 0 || *(p+1) == 0)
++ luaL_error(ms->L, "unbalanced pattern");
++ if (*s != *p) return NULL;
++ else {
++ int b = *p;
++ int e = *(p+1);
++ int cont = 1;
++ while (++s < ms->src_end) {
++ if (*s == e) {
++ if (--cont == 0) return s+1;
++ }
++ else if (*s == b) cont++;
++ }
++ }
++ return NULL; /* string ends out of balance */
++}
++
++
++static const char *max_expand (MatchState *ms, const char *s,
++ const char *p, const char *ep) {
++ ptrdiff_t i = 0; /* counts maximum expand for item */
++ while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
++ i++;
++ /* keeps trying to match with the maximum repetitions */
++ while (i>=0) {
++ const char *res = match(ms, (s+i), ep+1);
++ if (res) return res;
++ i--; /* else didn't match; reduce 1 repetition to try again */
++ }
++ return NULL;
++}
++
++
++static const char *min_expand (MatchState *ms, const char *s,
++ const char *p, const char *ep) {
++ for (;;) {
++ const char *res = match(ms, s, ep+1);
++ if (res != NULL)
++ return res;
++ else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
++ s++; /* try with one more repetition */
++ else return NULL;
++ }
++}
++
++
++static const char *start_capture (MatchState *ms, const char *s,
++ const char *p, int what) {
++ const char *res;
++ int level = ms->level;
++ if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
++ ms->capture[level].init = s;
++ ms->capture[level].len = what;
++ ms->level = level+1;
++ if ((res=match(ms, s, p)) == NULL) /* match failed? */
++ ms->level--; /* undo capture */
++ return res;
++}
++
++
++static const char *end_capture (MatchState *ms, const char *s,
++ const char *p) {
++ int l = capture_to_close(ms);
++ const char *res;
++ ms->capture[l].len = s - ms->capture[l].init; /* close capture */
++ if ((res = match(ms, s, p)) == NULL) /* match failed? */
++ ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
++ return res;
++}
++
++
++static const char *match_capture (MatchState *ms, const char *s, int l) {
++ size_t len;
++ l = check_capture(ms, l);
++ len = ms->capture[l].len;
++ if ((size_t)(ms->src_end-s) >= len &&
++ memcmp(ms->capture[l].init, s, len) == 0)
++ return s+len;
++ else return NULL;
++}
++
++
++static const char *match (MatchState *ms, const char *s, const char *p) {
++ init: /* using goto's to optimize tail recursion */
++ switch (*p) {
++ case '(': { /* start capture */
++ if (*(p+1) == ')') /* position capture? */
++ return start_capture(ms, s, p+2, CAP_POSITION);
++ else
++ return start_capture(ms, s, p+1, CAP_UNFINISHED);
++ }
++ case ')': { /* end capture */
++ return end_capture(ms, s, p+1);
++ }
++ case L_ESC: {
++ switch (*(p+1)) {
++ case 'b': { /* balanced string? */
++ s = matchbalance(ms, s, p+2);
++ if (s == NULL) return NULL;
++ p+=4; goto init; /* else return match(ms, s, p+4); */
++ }
++ case 'f': { /* frontier? */
++ const char *ep; char previous;
++ p += 2;
++ if (*p != '[')
++ luaL_error(ms->L, "missing " LUA_QL("[") " after "
++ LUA_QL("%%f") " in pattern");
++ ep = classend(ms, p); /* points to what is next */
++ previous = (s == ms->src_init) ? '\0' : *(s-1);
++ if (matchbracketclass(uchar(previous), p, ep-1) ||
++ !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
++ p=ep; goto init; /* else return match(ms, s, ep); */
++ }
++ default: {
++ if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
++ s = match_capture(ms, s, uchar(*(p+1)));
++ if (s == NULL) return NULL;
++ p+=2; goto init; /* else return match(ms, s, p+2) */
++ }
++ goto dflt; /* case default */
++ }
++ }
++ }
++ case '\0': { /* end of pattern */
++ return s; /* match succeeded */
++ }
++ case '$': {
++ if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
++ return (s == ms->src_end) ? s : NULL; /* check end of string */
++ else goto dflt;
++ }
++ default: dflt: { /* it is a pattern item */
++ const char *ep = classend(ms, p); /* points to what is next */
++ int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
++ switch (*ep) {
++ case '?': { /* optional */
++ const char *res;
++ if (m && ((res=match(ms, s+1, ep+1)) != NULL))
++ return res;
++ p=ep+1; goto init; /* else return match(ms, s, ep+1); */
++ }
++ case '*': { /* 0 or more repetitions */
++ return max_expand(ms, s, p, ep);
++ }
++ case '+': { /* 1 or more repetitions */
++ return (m ? max_expand(ms, s+1, p, ep) : NULL);
++ }
++ case '-': { /* 0 or more repetitions (minimum) */
++ return min_expand(ms, s, p, ep);
++ }
++ default: {
++ if (!m) return NULL;
++ s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
++ }
++ }
++ }
++ }
++}
++
++
++
++static const char *lmemfind (const char *s1, size_t l1,
++ const char *s2, size_t l2) {
++ if (l2 == 0) return s1; /* empty strings are everywhere */
++ else if (l2 > l1) return NULL; /* avoids a negative `l1' */
++ else {
++ const char *init; /* to search for a `*s2' inside `s1' */
++ l2--; /* 1st char will be checked by `memchr' */
++ l1 = l1-l2; /* `s2' cannot be found after that */
++ while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
++ init++; /* 1st char is already checked */
++ if (memcmp(init, s2+1, l2) == 0)
++ return init-1;
++ else { /* correct `l1' and `s1' to try again */
++ l1 -= init-s1;
++ s1 = init;
++ }
++ }
++ return NULL; /* not found */
++ }
++}
++
++
++static void push_onecapture (MatchState *ms, int i, const char *s,
++ const char *e) {
++ if (i >= ms->level) {
++ if (i == 0) /* ms->level == 0, too */
++ lua_pushlstring(ms->L, s, e - s); /* add whole match */
++ else
++ luaL_error(ms->L, "invalid capture index");
++ }
++ else {
++ ptrdiff_t l = ms->capture[i].len;
++ if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
++ if (l == CAP_POSITION)
++ lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
++ else
++ lua_pushlstring(ms->L, ms->capture[i].init, l);
++ }
++}
++
++
++static int push_captures (MatchState *ms, const char *s, const char *e) {
++ int i;
++ int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
++ luaL_checkstack(ms->L, nlevels, "too many captures");
++ for (i = 0; i < nlevels; i++)
++ push_onecapture(ms, i, s, e);
++ return nlevels; /* number of strings pushed */
++}
++
++
++static int str_find_aux (lua_State *L, int find) {
++ size_t l1, l2;
++ const char *s = luaL_checklstring(L, 1, &l1);
++ const char *p = luaL_checklstring(L, 2, &l2);
++ ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
++ if (init < 0) init = 0;
++ else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
++ if (find && (lua_toboolean(L, 4) || /* explicit request? */
++ strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
++ /* do a plain search */
++ const char *s2 = lmemfind(s+init, l1-init, p, l2);
++ if (s2) {
++ lua_pushinteger(L, s2-s+1);
++ lua_pushinteger(L, s2-s+l2);
++ return 2;
++ }
++ }
++ else {
++ MatchState ms;
++ int anchor = (*p == '^') ? (p++, 1) : 0;
++ const char *s1=s+init;
++ ms.L = L;
++ ms.src_init = s;
++ ms.src_end = s+l1;
++ do {
++ const char *res;
++ ms.level = 0;
++ if ((res=match(&ms, s1, p)) != NULL) {
++ if (find) {
++ lua_pushinteger(L, s1-s+1); /* start */
++ lua_pushinteger(L, res-s); /* end */
++ return push_captures(&ms, NULL, 0) + 2;
++ }
++ else
++ return push_captures(&ms, s1, res);
++ }
++ } while (s1++ < ms.src_end && !anchor);
++ }
++ lua_pushnil(L); /* not found */
++ return 1;
++}
++
++
++static int str_find (lua_State *L) {
++ return str_find_aux(L, 1);
++}
++
++
++static int str_match (lua_State *L) {
++ return str_find_aux(L, 0);
++}
++
++
++static int gmatch_aux (lua_State *L) {
++ MatchState ms;
++ size_t ls;
++ const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
++ const char *p = lua_tostring(L, lua_upvalueindex(2));
++ const char *src;
++ ms.L = L;
++ ms.src_init = s;
++ ms.src_end = s+ls;
++ for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
++ src <= ms.src_end;
++ src++) {
++ const char *e;
++ ms.level = 0;
++ if ((e = match(&ms, src, p)) != NULL) {
++ lua_Integer newstart = e-s;
++ if (e == src) newstart++; /* empty match? go at least one position */
++ lua_pushinteger(L, newstart);
++ lua_replace(L, lua_upvalueindex(3));
++ return push_captures(&ms, src, e);
++ }
++ }
++ return 0; /* not found */
++}
++
++
++static int gmatch (lua_State *L) {
++ luaL_checkstring(L, 1);
++ luaL_checkstring(L, 2);
++ lua_settop(L, 2);
++ lua_pushinteger(L, 0);
++ lua_pushcclosure(L, gmatch_aux, 3);
++ return 1;
++}
++
++
++static int gfind_nodef (lua_State *L) {
++ return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
++ LUA_QL("string.gmatch"));
++}
++
++
++static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
++ const char *e) {
++ size_t l, i;
++ const char *news = lua_tolstring(ms->L, 3, &l);
++ for (i = 0; i < l; i++) {
++ if (news[i] != L_ESC)
++ luaL_addchar(b, news[i]);
++ else {
++ i++; /* skip ESC */
++ if (!isdigit(uchar(news[i])))
++ luaL_addchar(b, news[i]);
++ else if (news[i] == '0')
++ luaL_addlstring(b, s, e - s);
++ else {
++ push_onecapture(ms, news[i] - '1', s, e);
++ luaL_addvalue(b); /* add capture to accumulated result */
++ }
++ }
++ }
++}
++
++
++static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
++ const char *e) {
++ lua_State *L = ms->L;
++ switch (lua_type(L, 3)) {
++ case LUA_TNUMBER:
++ case LUA_TSTRING: {
++ add_s(ms, b, s, e);
++ return;
++ }
++ case LUA_TFUNCTION: {
++ int n;
++ lua_pushvalue(L, 3);
++ n = push_captures(ms, s, e);
++ lua_call(L, n, 1);
++ break;
++ }
++ case LUA_TTABLE: {
++ push_onecapture(ms, 0, s, e);
++ lua_gettable(L, 3);
++ break;
++ }
++ }
++ if (!lua_toboolean(L, -1)) { /* nil or false? */
++ lua_pop(L, 1);
++ lua_pushlstring(L, s, e - s); /* keep original text */
++ }
++ else if (!lua_isstring(L, -1))
++ luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
++ luaL_addvalue(b); /* add result to accumulator */
++}
++
++
++static int str_gsub (lua_State *L) {
++ size_t srcl;
++ const char *src = luaL_checklstring(L, 1, &srcl);
++ const char *p = luaL_checkstring(L, 2);
++ int tr = lua_type(L, 3);
++ int max_s = luaL_optint(L, 4, srcl+1);
++ int anchor = (*p == '^') ? (p++, 1) : 0;
++ int n = 0;
++ MatchState ms;
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "str_gsub: cannot allocate memory");
++ luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
++ tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
++ "string/function/table expected");
++ luaL_buffinit(L, b);
++ ms.L = L;
++ ms.src_init = src;
++ ms.src_end = src+srcl;
++ while (n < max_s) {
++ const char *e;
++ ms.level = 0;
++ e = match(&ms, src, p);
++ if (e) {
++ n++;
++ add_value(&ms, b, src, e);
++ }
++ if (e && e>src) /* non empty match? */
++ src = e; /* skip it */
++ else if (src < ms.src_end)
++ luaL_addchar(b, *src++);
++ else break;
++ if (anchor) break;
++ }
++ luaL_addlstring(b, src, ms.src_end-src);
++ luaL_pushresult(b);
++ lua_pushinteger(L, n); /* number of substitutions */
++ kfree(b);
++ return 2;
++}
++
++/* }====================================================== */
++
++
++/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
++#define MAX_ITEM 512
++/* valid flags in a format specification */
++#define FLAGS "-+ #0"
++/*
++** maximum size of each format specification (such as '%-099.99d')
++** (+10 accounts for %99.99x plus margin of error)
++*/
++#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
++
++
++static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
++ size_t l;
++ const char *s = luaL_checklstring(L, arg, &l);
++ luaL_addchar(b, '"');
++ while (l--) {
++ switch (*s) {
++ case '"': case '\\': case '\n': {
++ luaL_addchar(b, '\\');
++ luaL_addchar(b, *s);
++ break;
++ }
++ case '\r': {
++ luaL_addlstring(b, "\\r", 2);
++ break;
++ }
++ case '\0': {
++ luaL_addlstring(b, "\\000", 4);
++ break;
++ }
++ default: {
++ luaL_addchar(b, *s);
++ break;
++ }
++ }
++ s++;
++ }
++ luaL_addchar(b, '"');
++}
++
++static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
++ const char *p = strfrmt;
++ while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
++ if ((size_t)(p - strfrmt) >= sizeof(FLAGS))
++ luaL_error(L, "invalid format (repeated flags)");
++ if (isdigit(uchar(*p))) p++; /* skip width */
++ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
++ if (*p == '.') {
++ p++;
++ if (isdigit(uchar(*p))) p++; /* skip precision */
++ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
++ }
++ if (isdigit(uchar(*p)))
++ luaL_error(L, "invalid format (width or precision too long)");
++ *(form++) = '%';
++ strncpy(form, strfrmt, p - strfrmt + 1);
++ form += p - strfrmt + 1;
++ *form = '\0';
++ return p;
++}
++
++
++static void addintlen (char *form) {
++ size_t l = strlen(form);
++ char spec = form[l - 1];
++ strcpy(form + l - 1, LUA_INTFRMLEN);
++ form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
++ form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
++}
++
++
++static int str_format (lua_State *L) {
++ int arg = 1;
++ size_t sfl;
++ const char *strfrmt = luaL_checklstring(L, arg, &sfl);
++ const char *strfrmt_end = strfrmt+sfl;
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "str_format: cannot allocate memory");
++ luaL_buffinit(L, b);
++ while (strfrmt < strfrmt_end) {
++ if (*strfrmt != L_ESC)
++ luaL_addchar(b, *strfrmt++);
++ else if (*++strfrmt == L_ESC)
++ luaL_addchar(b, *strfrmt++); /* %% */
++ else { /* format item */
++ char form[MAX_FORMAT]; /* to store the format (`%...') */
++ char buff[MAX_ITEM]; /* to store the formatted item */
++ arg++;
++ strfrmt = scanformat(L, strfrmt, form);
++ switch (*strfrmt++) {
++ case 'c': {
++ sprintf(buff, form, (int)luaL_checknumber(L, arg));
++ break;
++ }
++ case 'd': case 'i': {
++ addintlen(form);
++ sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
++ break;
++ }
++ case 'o': case 'u': case 'x': case 'X': {
++ addintlen(form);
++ sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
++ break;
++ }
++ case 'q': {
++ addquoted(L, b, arg);
++ continue; /* skip the 'addsize' at the end */
++ }
++ case 's': {
++ size_t l;
++ const char *s = luaL_checklstring(L, arg, &l);
++ if (!strchr(form, '.') && l >= 100) {
++ /* no precision and string is too long to be formatted;
++ keep original string */
++ lua_pushvalue(L, arg);
++ luaL_addvalue(b);
++ continue; /* skip the `addsize' at the end */
++ }
++ else {
++ sprintf(buff, form, s);
++ break;
++ }
++ }
++ default: { /* also treat cases `pnLlh' */
++ kfree(b);
++ return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
++ LUA_QL("format"), *(strfrmt - 1));
++ }
++ }
++ luaL_addlstring(b, buff, strlen(buff));
++ }
++ }
++ luaL_pushresult(b);
++ kfree(b);
++ return 1;
++}
++
++
++static const luaL_Reg strlib[] = {
++ {"byte", str_byte},
++ {"char", str_char},
++ {"dump", str_dump},
++ {"find", str_find},
++ {"format", str_format},
++ {"gfind", gfind_nodef},
++ {"gmatch", gmatch},
++ {"gsub", str_gsub},
++ {"len", str_len},
++ {"lower", str_lower},
++ {"match", str_match},
++ {"rep", str_rep},
++ {"reverse", str_reverse},
++ {"sub", str_sub},
++ {"upper", str_upper},
++ {NULL, NULL}
++};
++
++
++static void createmetatable (lua_State *L) {
++ lua_createtable(L, 0, 1); /* create metatable for strings */
++ lua_pushliteral(L, ""); /* dummy string */
++ lua_pushvalue(L, -2);
++ lua_setmetatable(L, -2); /* set string metatable */
++ lua_pop(L, 1); /* pop dummy string */
++ lua_pushvalue(L, -2); /* string library... */
++ lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
++ lua_pop(L, 1); /* pop metatable */
++}
++
++
++/*
++** Open string library
++*/
++LUALIB_API int luaopen_string (lua_State *L) {
++ luaL_register(L, LUA_STRLIBNAME, strlib);
++#if defined(LUA_COMPAT_GFIND)
++ lua_getfield(L, -1, "gmatch");
++ lua_setfield(L, -2, "gfind");
++#endif
++ createmetatable(L);
++ return 1;
++}
+--- /dev/null
++++ b/extensions/LUA/lua/ltable.c
+@@ -0,0 +1,588 @@
++/*
++** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $
++** Lua tables (hash)
++** See Copyright Notice in lua.h
++*/
++
++
++/*
++** Implementation of tables (aka arrays, objects, or hash tables).
++** Tables keep its elements in two parts: an array part and a hash part.
++** Non-negative integer keys are all candidates to be kept in the array
++** part. The actual size of the array is the largest `n' such that at
++** least half the slots between 0 and n are in use.
++** Hash uses a mix of chained scatter table with Brent's variation.
++** A main invariant of these tables is that, if an element is not
++** in its main position (i.e. the `original' position that its hash gives
++** to it), then the colliding element is in its own main position.
++** Hence even when the load factor reaches 100%, performance remains good.
++*/
++
++#include <math.h>
++#include <string.h>
++
++#define ltable_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "ldebug.h"
++#include "ldo.h"
++#include "lgc.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lstate.h"
++#include "ltable.h"
++
++
++/*
++** max size of array part is 2^MAXBITS
++*/
++#if LUAI_BITSINT > 26
++#define MAXBITS 26
++#else
++#define MAXBITS (LUAI_BITSINT-2)
++#endif
++
++#define MAXASIZE (1 << MAXBITS)
++
++
++#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
++
++#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
++#define hashboolean(t,p) hashpow2(t, p)
++
++
++/*
++** for some types, it is better to avoid modulus by power of 2, as
++** they tend to have many 2 factors.
++*/
++#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
++
++
++#define hashpointer(t,p) hashmod(t, IntPoint(p))
++
++
++/*
++** number of ints inside a lua_Number
++*/
++#define numints cast_int(sizeof(lua_Number)/sizeof(int))
++
++
++
++#define dummynode (&dummynode_)
++
++static const Node dummynode_ = {
++ {{NULL}, LUA_TNIL}, /* value */
++ {{{NULL}, LUA_TNIL, NULL}} /* key */
++};
++
++
++/*
++** hash for lua_Numbers
++*/
++static Node *hashnum (const Table *t, lua_Number n) {
++ unsigned int a[numints];
++ int i;
++ if (luai_numeq(n, 0)) /* avoid problems with -0 */
++ return gnode(t, 0);
++ memcpy(a, &n, sizeof(a));
++ for (i = 1; i < numints; i++) a[0] += a[i];
++ return hashmod(t, a[0]);
++}
++
++
++
++/*
++** returns the `main' position of an element in a table (that is, the index
++** of its hash value)
++*/
++static Node *mainposition (const Table *t, const TValue *key) {
++ switch (ttype(key)) {
++ case LUA_TNUMBER:
++ return hashnum(t, nvalue(key));
++ case LUA_TSTRING:
++ return hashstr(t, rawtsvalue(key));
++ case LUA_TBOOLEAN:
++ return hashboolean(t, bvalue(key));
++ case LUA_TLIGHTUSERDATA:
++ return hashpointer(t, pvalue(key));
++ default:
++ return hashpointer(t, gcvalue(key));
++ }
++}
++
++
++/*
++** returns the index for `key' if `key' is an appropriate key to live in
++** the array part of the table, -1 otherwise.
++*/
++static int arrayindex (const TValue *key) {
++ if (ttisnumber(key)) {
++ lua_Number n = nvalue(key);
++ int k;
++ lua_number2int(k, n);
++ if (luai_numeq(cast_num(k), n))
++ return k;
++ }
++ return -1; /* `key' did not match some condition */
++}
++
++
++/*
++** returns the index of a `key' for table traversals. First goes all
++** elements in the array part, then elements in the hash part. The
++** beginning of a traversal is signalled by -1.
++*/
++static int findindex (lua_State *L, Table *t, StkId key) {
++ int i;
++ if (ttisnil(key)) return -1; /* first iteration */
++ i = arrayindex(key);
++ if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
++ return i-1; /* yes; that's the index (corrected to C) */
++ else {
++ Node *n = mainposition(t, key);
++ do { /* check whether `key' is somewhere in the chain */
++ /* key may be dead already, but it is ok to use it in `next' */
++ if (luaO_rawequalObj(key2tval(n), key) ||
++ (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
++ gcvalue(gkey(n)) == gcvalue(key))) {
++ i = cast_int(n - gnode(t, 0)); /* key index in hash table */
++ /* hash elements are numbered after array ones */
++ return i + t->sizearray;
++ }
++ else n = gnext(n);
++ } while (n);
++ luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
++ return 0; /* to avoid warnings */
++ }
++}
++
++
++int luaH_next (lua_State *L, Table *t, StkId key) {
++ int i = findindex(L, t, key); /* find original element */
++ for (i++; i < t->sizearray; i++) { /* try first array part */
++ if (!ttisnil(&t->array[i])) { /* a non-nil value? */
++ setnvalue(key, cast_num(i+1));
++ setobj2s(L, key+1, &t->array[i]);
++ return 1;
++ }
++ }
++ for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
++ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
++ setobj2s(L, key, key2tval(gnode(t, i)));
++ setobj2s(L, key+1, gval(gnode(t, i)));
++ return 1;
++ }
++ }
++ return 0; /* no more elements */
++}
++
++
++/*
++** {=============================================================
++** Rehash
++** ==============================================================
++*/
++
++
++static int computesizes (int nums[], int *narray) {
++ int i;
++ int twotoi; /* 2^i */
++ int a = 0; /* number of elements smaller than 2^i */
++ int na = 0; /* number of elements to go to array part */
++ int n = 0; /* optimal size for array part */
++ for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
++ if (nums[i] > 0) {
++ a += nums[i];
++ if (a > twotoi/2) { /* more than half elements present? */
++ n = twotoi; /* optimal size (till now) */
++ na = a; /* all elements smaller than n will go to array part */
++ }
++ }
++ if (a == *narray) break; /* all elements already counted */
++ }
++ *narray = n;
++ lua_assert(*narray/2 <= na && na <= *narray);
++ return na;
++}
++
++
++static int countint (const TValue *key, int *nums) {
++ int k = arrayindex(key);
++ if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
++ nums[ceillog2(k)]++; /* count as such */
++ return 1;
++ }
++ else
++ return 0;
++}
++
++
++static int numusearray (const Table *t, int *nums) {
++ int lg;
++ int ttlg; /* 2^lg */
++ int ause = 0; /* summation of `nums' */
++ int i = 1; /* count to traverse all array keys */
++ for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
++ int lc = 0; /* counter */
++ int lim = ttlg;
++ if (lim > t->sizearray) {
++ lim = t->sizearray; /* adjust upper limit */
++ if (i > lim)
++ break; /* no more elements to count */
++ }
++ /* count elements in range (2^(lg-1), 2^lg] */
++ for (; i <= lim; i++) {
++ if (!ttisnil(&t->array[i-1]))
++ lc++;
++ }
++ nums[lg] += lc;
++ ause += lc;
++ }
++ return ause;
++}
++
++
++static int numusehash (const Table *t, int *nums, int *pnasize) {
++ int totaluse = 0; /* total number of elements */
++ int ause = 0; /* summation of `nums' */
++ int i = sizenode(t);
++ while (i--) {
++ Node *n = &t->node[i];
++ if (!ttisnil(gval(n))) {
++ ause += countint(key2tval(n), nums);
++ totaluse++;
++ }
++ }
++ *pnasize += ause;
++ return totaluse;
++}
++
++
++static void setarrayvector (lua_State *L, Table *t, int size) {
++ int i;
++ luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
++ for (i=t->sizearray; i<size; i++)
++ setnilvalue(&t->array[i]);
++ t->sizearray = size;
++}
++
++
++static void setnodevector (lua_State *L, Table *t, int size) {
++ int lsize;
++ if (size == 0) { /* no elements to hash part? */
++ t->node = cast(Node *, dummynode); /* use common `dummynode' */
++ lsize = 0;
++ }
++ else {
++ int i;
++ lsize = ceillog2(size);
++ if (lsize > MAXBITS)
++ luaG_runerror(L, "table overflow");
++ size = twoto(lsize);
++ t->node = luaM_newvector(L, size, Node);
++ for (i=0; i<size; i++) {
++ Node *n = gnode(t, i);
++ gnext(n) = NULL;
++ setnilvalue(gkey(n));
++ setnilvalue(gval(n));
++ }
++ }
++ t->lsizenode = cast_byte(lsize);
++ t->lastfree = gnode(t, size); /* all positions are free */
++}
++
++
++static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
++ int i;
++ int oldasize = t->sizearray;
++ int oldhsize = t->lsizenode;
++ Node *nold = t->node; /* save old hash ... */
++ if (nasize > oldasize) /* array part must grow? */
++ setarrayvector(L, t, nasize);
++ /* create new hash part with appropriate size */
++ setnodevector(L, t, nhsize);
++ if (nasize < oldasize) { /* array part must shrink? */
++ t->sizearray = nasize;
++ /* re-insert elements from vanishing slice */
++ for (i=nasize; i<oldasize; i++) {
++ if (!ttisnil(&t->array[i]))
++ setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
++ }
++ /* shrink array */
++ luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
++ }
++ /* re-insert elements from hash part */
++ for (i = twoto(oldhsize) - 1; i >= 0; i--) {
++ Node *old = nold+i;
++ if (!ttisnil(gval(old)))
++ setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
++ }
++ if (nold != dummynode)
++ luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
++}
++
++
++void luaH_resizearray (lua_State *L, Table *t, int nasize) {
++ int nsize = (t->node == dummynode) ? 0 : sizenode(t);
++ resize(L, t, nasize, nsize);
++}
++
++
++static void rehash (lua_State *L, Table *t, const TValue *ek) {
++ int nasize, na;
++ int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
++ int i;
++ int totaluse;
++ for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
++ nasize = numusearray(t, nums); /* count keys in array part */
++ totaluse = nasize; /* all those keys are integer keys */
++ totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
++ /* count extra key */
++ nasize += countint(ek, nums);
++ totaluse++;
++ /* compute new size for array part */
++ na = computesizes(nums, &nasize);
++ /* resize the table to new computed sizes */
++ resize(L, t, nasize, totaluse - na);
++}
++
++
++
++/*
++** }=============================================================
++*/
++
++
++Table *luaH_new (lua_State *L, int narray, int nhash) {
++ Table *t = luaM_new(L, Table);
++ luaC_link(L, obj2gco(t), LUA_TTABLE);
++ t->metatable = NULL;
++ t->flags = cast_byte(~0);
++ /* temporary values (kept only if some malloc fails) */
++ t->array = NULL;
++ t->sizearray = 0;
++ t->lsizenode = 0;
++ t->node = cast(Node *, dummynode);
++ setarrayvector(L, t, narray);
++ setnodevector(L, t, nhash);
++ return t;
++}
++
++
++void luaH_free (lua_State *L, Table *t) {
++ if (t->node != dummynode)
++ luaM_freearray(L, t->node, sizenode(t), Node);
++ luaM_freearray(L, t->array, t->sizearray, TValue);
++ luaM_free(L, t);
++}
++
++
++static Node *getfreepos (Table *t) {
++ while (t->lastfree-- > t->node) {
++ if (ttisnil(gkey(t->lastfree)))
++ return t->lastfree;
++ }
++ return NULL; /* could not find a free place */
++}
++
++
++
++/*
++** inserts a new key into a hash table; first, check whether key's main
++** position is free. If not, check whether colliding node is in its main
++** position or not: if it is not, move colliding node to an empty place and
++** put new key in its main position; otherwise (colliding node is in its main
++** position), new key goes to an empty position.
++*/
++static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
++ Node *mp = mainposition(t, key);
++ if (!ttisnil(gval(mp)) || mp == dummynode) {
++ Node *othern;
++ Node *n = getfreepos(t); /* get a free place */
++ if (n == NULL) { /* cannot find a free place? */
++ rehash(L, t, key); /* grow table */
++ return luaH_set(L, t, key); /* re-insert key into grown table */
++ }
++ lua_assert(n != dummynode);
++ othern = mainposition(t, key2tval(mp));
++ if (othern != mp) { /* is colliding node out of its main position? */
++ /* yes; move colliding node into free position */
++ while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
++ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
++ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
++ gnext(mp) = NULL; /* now `mp' is free */
++ setnilvalue(gval(mp));
++ }
++ else { /* colliding node is in its own main position */
++ /* new node will go into free position */
++ gnext(n) = gnext(mp); /* chain new position */
++ gnext(mp) = n;
++ mp = n;
++ }
++ }
++ gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
++ luaC_barriert(L, t, key);
++ lua_assert(ttisnil(gval(mp)));
++ return gval(mp);
++}
++
++
++/*
++** search function for integers
++*/
++const TValue *luaH_getnum (Table *t, int key) {
++ /* (1 <= key && key <= t->sizearray) */
++ if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
++ return &t->array[key-1];
++ else {
++ lua_Number nk = cast_num(key);
++ Node *n = hashnum(t, nk);
++ do { /* check whether `key' is somewhere in the chain */
++ if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
++ return gval(n); /* that's it */
++ else n = gnext(n);
++ } while (n);
++ return luaO_nilobject;
++ }
++}
++
++
++/*
++** search function for strings
++*/
++const TValue *luaH_getstr (Table *t, TString *key) {
++ Node *n = hashstr(t, key);
++ do { /* check whether `key' is somewhere in the chain */
++ if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
++ return gval(n); /* that's it */
++ else n = gnext(n);
++ } while (n);
++ return luaO_nilobject;
++}
++
++
++/*
++** main search function
++*/
++const TValue *luaH_get (Table *t, const TValue *key) {
++ switch (ttype(key)) {
++ case LUA_TNIL: return luaO_nilobject;
++ case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
++ case LUA_TNUMBER: {
++ int k;
++ lua_Number n = nvalue(key);
++ lua_number2int(k, n);
++ if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
++ return luaH_getnum(t, k); /* use specialized version */
++ /* else go through */
++ }
++ default: {
++ Node *n = mainposition(t, key);
++ do { /* check whether `key' is somewhere in the chain */
++ if (luaO_rawequalObj(key2tval(n), key))
++ return gval(n); /* that's it */
++ else n = gnext(n);
++ } while (n);
++ return luaO_nilobject;
++ }
++ }
++}
++
++
++TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
++ const TValue *p = luaH_get(t, key);
++ t->flags = 0;
++ if (p != luaO_nilobject)
++ return cast(TValue *, p);
++ else {
++ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
++ else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
++ luaG_runerror(L, "table index is NaN");
++ return newkey(L, t, key);
++ }
++}
++
++
++TValue *luaH_setnum (lua_State *L, Table *t, int key) {
++ const TValue *p = luaH_getnum(t, key);
++ if (p != luaO_nilobject)
++ return cast(TValue *, p);
++ else {
++ TValue k;
++ setnvalue(&k, cast_num(key));
++ return newkey(L, t, &k);
++ }
++}
++
++
++TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
++ const TValue *p = luaH_getstr(t, key);
++ if (p != luaO_nilobject)
++ return cast(TValue *, p);
++ else {
++ TValue k;
++ setsvalue(L, &k, key);
++ return newkey(L, t, &k);
++ }
++}
++
++
++static int unbound_search (Table *t, unsigned int j) {
++ unsigned int i = j; /* i is zero or a present index */
++ j++;
++ /* find `i' and `j' such that i is present and j is not */
++ while (!ttisnil(luaH_getnum(t, j))) {
++ i = j;
++ j *= 2;
++ if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
++ /* table was built with bad purposes: resort to linear search */
++ i = 1;
++ while (!ttisnil(luaH_getnum(t, i))) i++;
++ return i - 1;
++ }
++ }
++ /* now do a binary search between them */
++ while (j - i > 1) {
++ unsigned int m = (i+j)/2;
++ if (ttisnil(luaH_getnum(t, m))) j = m;
++ else i = m;
++ }
++ return i;
++}
++
++
++/*
++** Try to find a boundary in table `t'. A `boundary' is an integer index
++** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
++*/
++int luaH_getn (Table *t) {
++ unsigned int j = t->sizearray;
++ if (j > 0 && ttisnil(&t->array[j - 1])) {
++ /* there is a boundary in the array part: (binary) search for it */
++ unsigned int i = 0;
++ while (j - i > 1) {
++ unsigned int m = (i+j)/2;
++ if (ttisnil(&t->array[m - 1])) j = m;
++ else i = m;
++ }
++ return i;
++ }
++ /* else must find a boundary in hash part */
++ else if (t->node == dummynode) /* hash part is empty? */
++ return j; /* that is easy... */
++ else return unbound_search(t, j);
++}
++
++
++
++#if defined(LUA_DEBUG)
++
++Node *luaH_mainposition (const Table *t, const TValue *key) {
++ return mainposition(t, key);
++}
++
++int luaH_isdummy (Node *n) { return n == dummynode; }
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/ltable.h
+@@ -0,0 +1,40 @@
++/*
++** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $
++** Lua tables (hash)
++** See Copyright Notice in lua.h
++*/
++
++#ifndef ltable_h
++#define ltable_h
++
++#include "lobject.h"
++
++
++#define gnode(t,i) (&(t)->node[i])
++#define gkey(n) (&(n)->i_key.nk)
++#define gval(n) (&(n)->i_val)
++#define gnext(n) ((n)->i_key.nk.next)
++
++#define key2tval(n) (&(n)->i_key.tvk)
++
++
++LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
++LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
++LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
++LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
++LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
++LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
++LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
++LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
++LUAI_FUNC void luaH_free (lua_State *L, Table *t);
++LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
++LUAI_FUNC int luaH_getn (Table *t);
++
++
++#if defined(LUA_DEBUG)
++LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
++LUAI_FUNC int luaH_isdummy (Node *n);
++#endif
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/ltablib.c
+@@ -0,0 +1,288 @@
++/*
++** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $
++** Library for Table Manipulation
++** See Copyright Notice in lua.h
++*/
++
++
++#include <stddef.h>
++
++#define ltablib_c
++#define LUA_LIB
++
++#include "lua.h"
++
++#include "lauxlib.h"
++#include "lualib.h"
++
++
++#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
++
++
++static int foreachi (lua_State *L) {
++ int i;
++ int n = aux_getn(L, 1);
++ luaL_checktype(L, 2, LUA_TFUNCTION);
++ for (i=1; i <= n; i++) {
++ lua_pushvalue(L, 2); /* function */
++ lua_pushinteger(L, i); /* 1st argument */
++ lua_rawgeti(L, 1, i); /* 2nd argument */
++ lua_call(L, 2, 1);
++ if (!lua_isnil(L, -1))
++ return 1;
++ lua_pop(L, 1); /* remove nil result */
++ }
++ return 0;
++}
++
++
++static int foreach (lua_State *L) {
++ luaL_checktype(L, 1, LUA_TTABLE);
++ luaL_checktype(L, 2, LUA_TFUNCTION);
++ lua_pushnil(L); /* first key */
++ while (lua_next(L, 1)) {
++ lua_pushvalue(L, 2); /* function */
++ lua_pushvalue(L, -3); /* key */
++ lua_pushvalue(L, -3); /* value */
++ lua_call(L, 2, 1);
++ if (!lua_isnil(L, -1))
++ return 1;
++ lua_pop(L, 2); /* remove value and result */
++ }
++ return 0;
++}
++
++
++static int maxn (lua_State *L) {
++ lua_Number max = 0;
++ luaL_checktype(L, 1, LUA_TTABLE);
++ lua_pushnil(L); /* first key */
++ while (lua_next(L, 1)) {
++ lua_pop(L, 1); /* remove value */
++ if (lua_type(L, -1) == LUA_TNUMBER) {
++ lua_Number v = lua_tonumber(L, -1);
++ if (v > max) max = v;
++ }
++ }
++ lua_pushnumber(L, max);
++ return 1;
++}
++
++
++static int getn (lua_State *L) {
++ lua_pushinteger(L, aux_getn(L, 1));
++ return 1;
++}
++
++
++static int setn (lua_State *L) {
++ luaL_checktype(L, 1, LUA_TTABLE);
++#ifndef luaL_setn
++ luaL_setn(L, 1, luaL_checkint(L, 2));
++#else
++ luaL_error(L, LUA_QL("setn") " is obsolete");
++#endif
++ lua_pushvalue(L, 1);
++ return 1;
++}
++
++
++static int tinsert (lua_State *L) {
++ int e = aux_getn(L, 1) + 1; /* first empty element */
++ int pos; /* where to insert new element */
++ switch (lua_gettop(L)) {
++ case 2: { /* called with only 2 arguments */
++ pos = e; /* insert new element at the end */
++ break;
++ }
++ case 3: {
++ int i;
++ pos = luaL_checkint(L, 2); /* 2nd argument is the position */
++ if (pos > e) e = pos; /* `grow' array if necessary */
++ for (i = e; i > pos; i--) { /* move up elements */
++ lua_rawgeti(L, 1, i-1);
++ lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
++ }
++ break;
++ }
++ default: {
++ return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
++ }
++ }
++ luaL_setn(L, 1, e); /* new size */
++ lua_rawseti(L, 1, pos); /* t[pos] = v */
++ return 0;
++}
++
++
++static int tremove (lua_State *L) {
++ int e = aux_getn(L, 1);
++ int pos = luaL_optint(L, 2, e);
++ if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
++ return 0; /* nothing to remove */
++ luaL_setn(L, 1, e - 1); /* t.n = n-1 */
++ lua_rawgeti(L, 1, pos); /* result = t[pos] */
++ for ( ;pos<e; pos++) {
++ lua_rawgeti(L, 1, pos+1);
++ lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
++ }
++ lua_pushnil(L);
++ lua_rawseti(L, 1, e); /* t[e] = nil */
++ return 1;
++}
++
++
++static void addfield (lua_State *L, luaL_Buffer *b, int i) {
++ lua_rawgeti(L, 1, i);
++ if (!lua_isstring(L, -1))
++ luaL_error(L, "invalid value (%s) at index %d in table for "
++ LUA_QL("concat"), luaL_typename(L, -1), i);
++ luaL_addvalue(b);
++}
++
++
++static int tconcat (lua_State *L) {
++ size_t lsep;
++ int i, last;
++ const char *sep = luaL_optlstring(L, 2, "", &lsep);
++ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
++ if(!b) luaL_error(L, "tconcat: cannot allocate memory");
++ luaL_checktype(L, 1, LUA_TTABLE);
++ i = luaL_optint(L, 3, 1);
++ last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1));
++ luaL_buffinit(L, b);
++ for (; i < last; i++) {
++ addfield(L, b, i);
++ luaL_addlstring(b, sep, lsep);
++ }
++ if (i == last) /* add last value (if interval was not empty) */
++ addfield(L, b, i);
++ luaL_pushresult(b);
++ kfree(b);
++ return 1;
++}
++
++
++
++/*
++** {======================================================
++** Quicksort
++** (based on `Algorithms in MODULA-3', Robert Sedgewick;
++** Addison-Wesley, 1993.)
++*/
++
++
++static void set2 (lua_State *L, int i, int j) {
++ lua_rawseti(L, 1, i);
++ lua_rawseti(L, 1, j);
++}
++
++static int sort_comp (lua_State *L, int a, int b) {
++ if (!lua_isnil(L, 2)) { /* function? */
++ int res;
++ lua_pushvalue(L, 2);
++ lua_pushvalue(L, a-1); /* -1 to compensate function */
++ lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
++ lua_call(L, 2, 1);
++ res = lua_toboolean(L, -1);
++ lua_pop(L, 1);
++ return res;
++ }
++ else /* a < b? */
++ return lua_lessthan(L, a, b);
++}
++
++static void auxsort (lua_State *L, int l, int u) {
++ while (l < u) { /* for tail recursion */
++ int i, j;
++ /* sort elements a[l], a[(l+u)/2] and a[u] */
++ lua_rawgeti(L, 1, l);
++ lua_rawgeti(L, 1, u);
++ if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
++ set2(L, l, u); /* swap a[l] - a[u] */
++ else
++ lua_pop(L, 2);
++ if (u-l == 1) break; /* only 2 elements */
++ i = (l+u)/2;
++ lua_rawgeti(L, 1, i);
++ lua_rawgeti(L, 1, l);
++ if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
++ set2(L, i, l);
++ else {
++ lua_pop(L, 1); /* remove a[l] */
++ lua_rawgeti(L, 1, u);
++ if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
++ set2(L, i, u);
++ else
++ lua_pop(L, 2);
++ }
++ if (u-l == 2) break; /* only 3 elements */
++ lua_rawgeti(L, 1, i); /* Pivot */
++ lua_pushvalue(L, -1);
++ lua_rawgeti(L, 1, u-1);
++ set2(L, i, u-1);
++ /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
++ i = l; j = u-1;
++ for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
++ /* repeat ++i until a[i] >= P */
++ while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
++ if (i>u) luaL_error(L, "invalid order function for sorting");
++ lua_pop(L, 1); /* remove a[i] */
++ }
++ /* repeat --j until a[j] <= P */
++ while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
++ if (j<l) luaL_error(L, "invalid order function for sorting");
++ lua_pop(L, 1); /* remove a[j] */
++ }
++ if (j<i) {
++ lua_pop(L, 3); /* pop pivot, a[i], a[j] */
++ break;
++ }
++ set2(L, i, j);
++ }
++ lua_rawgeti(L, 1, u-1);
++ lua_rawgeti(L, 1, i);
++ set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
++ /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
++ /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
++ if (i-l < u-i) {
++ j=l; i=i-1; l=i+2;
++ }
++ else {
++ j=i+1; i=u; u=j-2;
++ }
++ auxsort(L, j, i); /* call recursively the smaller one */
++ } /* repeat the routine for the larger one */
++}
++
++static int sort (lua_State *L) {
++ int n = aux_getn(L, 1);
++ luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
++ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
++ luaL_checktype(L, 2, LUA_TFUNCTION);
++ lua_settop(L, 2); /* make sure there is two arguments */
++ auxsort(L, 1, n);
++ return 0;
++}
++
++/* }====================================================== */
++
++
++static const luaL_Reg tab_funcs[] = {
++ {"concat", tconcat},
++ {"foreach", foreach},
++ {"foreachi", foreachi},
++ {"getn", getn},
++ {"maxn", maxn},
++ {"insert", tinsert},
++ {"remove", tremove},
++ {"setn", setn},
++ {"sort", sort},
++ {NULL, NULL}
++};
++
++
++LUALIB_API int luaopen_table (lua_State *L) {
++ luaL_register(L, LUA_TABLIBNAME, tab_funcs);
++ return 1;
++}
+--- /dev/null
++++ b/extensions/LUA/lua/ltm.c
+@@ -0,0 +1,74 @@
++/*
++** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
++** Tag methods
++** See Copyright Notice in lua.h
++*/
++
++#include <string.h>
++
++#define ltm_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "lobject.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "ltable.h"
++#include "ltm.h"
++
++
++
++const char *const luaT_typenames[] = {
++ "nil", "boolean", "userdata", "number",
++ "string", "table", "function", "userdata", "thread",
++ "proto", "upval"
++};
++
++
++void luaT_init (lua_State *L) {
++ static const char *const luaT_eventname[] = { /* ORDER TM */
++ "__index", "__newindex",
++ "__gc", "__mode", "__eq",
++ "__add", "__sub", "__mul", "__div", "__mod",
++ "__pow", "__unm", "__len", "__lt", "__le",
++ "__concat", "__call"
++ };
++ int i;
++ for (i=0; i<TM_N; i++) {
++ G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
++ luaS_fix(G(L)->tmname[i]); /* never collect these names */
++ }
++}
++
++
++/*
++** function to be used with macro "fasttm": optimized for absence of
++** tag methods
++*/
++const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
++ const TValue *tm = luaH_getstr(events, ename);
++ lua_assert(event <= TM_EQ);
++ if (ttisnil(tm)) { /* no tag method? */
++ events->flags |= cast_byte(1u<<event); /* cache this fact */
++ return NULL;
++ }
++ else return tm;
++}
++
++
++const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
++ Table *mt;
++ switch (ttype(o)) {
++ case LUA_TTABLE:
++ mt = hvalue(o)->metatable;
++ break;
++ case LUA_TUSERDATA:
++ mt = uvalue(o)->metatable;
++ break;
++ default:
++ mt = G(L)->mt[ttype(o)];
++ }
++ return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/ltm.h
+@@ -0,0 +1,54 @@
++/*
++** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $
++** Tag methods
++** See Copyright Notice in lua.h
++*/
++
++#ifndef ltm_h
++#define ltm_h
++
++
++#include "lobject.h"
++
++
++/*
++* WARNING: if you change the order of this enumeration,
++* grep "ORDER TM"
++*/
++typedef enum {
++ TM_INDEX,
++ TM_NEWINDEX,
++ TM_GC,
++ TM_MODE,
++ TM_EQ, /* last tag method with `fast' access */
++ TM_ADD,
++ TM_SUB,
++ TM_MUL,
++ TM_DIV,
++ TM_MOD,
++ TM_POW,
++ TM_UNM,
++ TM_LEN,
++ TM_LT,
++ TM_LE,
++ TM_CONCAT,
++ TM_CALL,
++ TM_N /* number of elements in the enum */
++} TMS;
++
++
++
++#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
++ ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
++
++#define fasttm(l,et,e) gfasttm(G(l), et, e)
++
++LUAI_DATA const char *const luaT_typenames[];
++
++
++LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
++LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
++ TMS event);
++LUAI_FUNC void luaT_init (lua_State *L);
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/luaconf.h
+@@ -0,0 +1,797 @@
++/*
++** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $
++** Configuration file for Lua
++** See Copyright Notice in lua.h
++*/
++
++
++#ifndef lconfig_h
++#define lconfig_h
++
++#include <stddef.h>
++
++#if !defined(__KERNEL__)
++#include <limits.h>
++#else
++#define UCHAR_MAX 255
++#define SHRT_MAX 32767
++#define BUFSIZ 8192
++#define NO_FPU
++#endif
++
++/*
++** ==================================================================
++** Search for "@@" to find all configurable definitions.
++** ===================================================================
++*/
++
++
++/*
++@@ LUA_ANSI controls the use of non-ansi features.
++** CHANGE it (define it) if you want Lua to avoid the use of any
++** non-ansi feature or library.
++*/
++#if defined(__STRICT_ANSI__)
++#define LUA_ANSI
++#endif
++
++
++#if !defined(LUA_ANSI) && defined(_WIN32)
++#define LUA_WIN
++#endif
++
++#if defined(LUA_USE_LINUX)
++#define LUA_USE_POSIX
++#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
++#define LUA_USE_READLINE /* needs some extra libraries */
++#endif
++
++#if defined(LUA_USE_MACOSX)
++#define LUA_USE_POSIX
++#define LUA_DL_DYLD /* does not need extra library */
++#endif
++
++
++
++/*
++@@ LUA_USE_POSIX includes all functionallity listed as X/Open System
++@* Interfaces Extension (XSI).
++** CHANGE it (define it) if your system is XSI compatible.
++*/
++#if defined(LUA_USE_POSIX)
++#define LUA_USE_MKSTEMP
++#define LUA_USE_ISATTY
++#define LUA_USE_POPEN
++#define LUA_USE_ULONGJMP
++#endif
++
++
++/*
++@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
++@* Lua check to set its paths.
++@@ LUA_INIT is the name of the environment variable that Lua
++@* checks for initialization code.
++** CHANGE them if you want different names.
++*/
++#define LUA_PATH "LUA_PATH"
++#define LUA_CPATH "LUA_CPATH"
++#define LUA_INIT "LUA_INIT"
++
++
++/*
++@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
++@* Lua libraries.
++@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
++@* C libraries.
++** CHANGE them if your machine has a non-conventional directory
++** hierarchy or if you want to install your libraries in
++** non-conventional directories.
++*/
++#if defined(_WIN32)
++/*
++** In Windows, any exclamation mark ('!') in the path is replaced by the
++** path of the directory of the executable file of the current process.
++*/
++#define LUA_LDIR "!\\lua\\"
++#define LUA_CDIR "!\\"
++#define LUA_PATH_DEFAULT \
++ ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
++ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
++#define LUA_CPATH_DEFAULT \
++ ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
++
++#else
++#define LUA_ROOT "/usr/local/"
++#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
++#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
++#define LUA_PATH_DEFAULT \
++ "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
++ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
++#define LUA_CPATH_DEFAULT \
++ "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
++#endif
++
++
++/*
++@@ LUA_DIRSEP is the directory separator (for submodules).
++** CHANGE it if your machine does not use "/" as the directory separator
++** and is not Windows. (On Windows Lua automatically uses "\".)
++*/
++#if defined(_WIN32)
++#define LUA_DIRSEP "\\"
++#else
++#define LUA_DIRSEP "/"
++#endif
++
++
++/*
++@@ LUA_PATHSEP is the character that separates templates in a path.
++@@ LUA_PATH_MARK is the string that marks the substitution points in a
++@* template.
++@@ LUA_EXECDIR in a Windows path is replaced by the executable's
++@* directory.
++@@ LUA_IGMARK is a mark to ignore all before it when bulding the
++@* luaopen_ function name.
++** CHANGE them if for some reason your system cannot use those
++** characters. (E.g., if one of those characters is a common character
++** in file/directory names.) Probably you do not need to change them.
++*/
++#define LUA_PATHSEP ";"
++#define LUA_PATH_MARK "?"
++#define LUA_EXECDIR "!"
++#define LUA_IGMARK "-"
++
++
++/*
++@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
++** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
++** machines, ptrdiff_t gives a good choice between int or long.)
++*/
++#define LUA_INTEGER ptrdiff_t
++
++
++/*
++@@ LUA_API is a mark for all core API functions.
++@@ LUALIB_API is a mark for all standard library functions.
++** CHANGE them if you need to define those functions in some special way.
++** For instance, if you want to create one Windows DLL with the core and
++** the libraries, you may want to use the following definition (define
++** LUA_BUILD_AS_DLL to get it).
++*/
++#if defined(LUA_BUILD_AS_DLL)
++
++#if defined(LUA_CORE) || defined(LUA_LIB)
++#define LUA_API __declspec(dllexport)
++#else
++#define LUA_API __declspec(dllimport)
++#endif
++
++#else
++
++#define LUA_API extern
++
++#endif
++
++/* more often than not the libs go together with the core */
++#define LUALIB_API LUA_API
++
++
++/*
++@@ LUAI_FUNC is a mark for all extern functions that are not to be
++@* exported to outside modules.
++@@ LUAI_DATA is a mark for all extern (const) variables that are not to
++@* be exported to outside modules.
++** CHANGE them if you need to mark them in some special way. Elf/gcc
++** (versions 3.2 and later) mark them as "hidden" to optimize access
++** when Lua is compiled as a shared library.
++*/
++#if defined(luaall_c)
++#define LUAI_FUNC static
++#define LUAI_DATA /* empty */
++
++#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
++ defined(__ELF__)
++#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
++#define LUAI_DATA LUAI_FUNC
++
++#else
++#define LUAI_FUNC extern
++#define LUAI_DATA extern
++#endif
++
++
++
++/*
++@@ LUA_QL describes how error messages quote program elements.
++** CHANGE it if you want a different appearance.
++*/
++#define LUA_QL(x) "'" x "'"
++#define LUA_QS LUA_QL("%s")
++
++
++/*
++@@ LUA_IDSIZE gives the maximum size for the description of the source
++@* of a function in debug information.
++** CHANGE it if you want a different size.
++*/
++#define LUA_IDSIZE 60
++
++
++/*
++** {==================================================================
++** Stand-alone configuration
++** ===================================================================
++*/
++
++#if defined(lua_c) || defined(luaall_c)
++
++/*
++@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
++@* is, whether we're running lua interactively).
++** CHANGE it if you have a better definition for non-POSIX/non-Windows
++** systems.
++*/
++#if defined(LUA_USE_ISATTY)
++#include <unistd.h>
++#define lua_stdin_is_tty() isatty(0)
++#elif defined(LUA_WIN)
++#include <io.h>
++#include <stdio.h>
++#define lua_stdin_is_tty() _isatty(_fileno(stdin))
++#else
++#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
++#endif
++
++
++/*
++@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
++@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
++** CHANGE them if you want different prompts. (You can also change the
++** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
++*/
++#define LUA_PROMPT "> "
++#define LUA_PROMPT2 ">> "
++
++
++/*
++@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
++** CHANGE it if your stand-alone interpreter has a different name and
++** your system is not able to detect that name automatically.
++*/
++#define LUA_PROGNAME "lua"
++
++
++/*
++@@ LUA_MAXINPUT is the maximum length for an input line in the
++@* stand-alone interpreter.
++** CHANGE it if you need longer lines.
++*/
++#define LUA_MAXINPUT 512
++
++
++/*
++@@ lua_readline defines how to show a prompt and then read a line from
++@* the standard input.
++@@ lua_saveline defines how to "save" a read line in a "history".
++@@ lua_freeline defines how to free a line read by lua_readline.
++** CHANGE them if you want to improve this functionality (e.g., by using
++** GNU readline and history facilities).
++*/
++#if defined(LUA_USE_READLINE)
++#include <stdio.h>
++#include <readline/readline.h>
++#include <readline/history.h>
++#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
++#define lua_saveline(L,idx) \
++ if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
++ add_history(lua_tostring(L, idx)); /* add it to history */
++#define lua_freeline(L,b) ((void)L, free(b))
++#else
++#define lua_readline(L,b,p) \
++ ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
++ fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
++#define lua_saveline(L,idx) { (void)L; (void)idx; }
++#define lua_freeline(L,b) { (void)L; (void)b; }
++#endif
++
++#endif
++
++/* }================================================================== */
++
++
++/*
++@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
++@* as a percentage.
++** CHANGE it if you want the GC to run faster or slower (higher values
++** mean larger pauses which mean slower collection.) You can also change
++** this value dynamically.
++*/
++#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
++
++
++/*
++@@ LUAI_GCMUL defines the default speed of garbage collection relative to
++@* memory allocation as a percentage.
++** CHANGE it if you want to change the granularity of the garbage
++** collection. (Higher values mean coarser collections. 0 represents
++** infinity, where each step performs a full collection.) You can also
++** change this value dynamically.
++*/
++#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
++
++
++
++/*
++@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
++** CHANGE it (define it) if you want exact compatibility with the
++** behavior of setn/getn in Lua 5.0.
++*/
++#undef LUA_COMPAT_GETN
++
++/*
++@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
++** CHANGE it to undefined as soon as you do not need a global 'loadlib'
++** function (the function is still available as 'package.loadlib').
++*/
++#undef LUA_COMPAT_LOADLIB
++
++/*
++@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
++** CHANGE it to undefined as soon as your programs use only '...' to
++** access vararg parameters (instead of the old 'arg' table).
++*/
++#define LUA_COMPAT_VARARG
++
++/*
++@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
++** CHANGE it to undefined as soon as your programs use 'math.fmod' or
++** the new '%' operator instead of 'math.mod'.
++*/
++#define LUA_COMPAT_MOD
++
++/*
++@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
++@* facility.
++** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
++** off the advisory error when nesting [[...]].
++*/
++#define LUA_COMPAT_LSTR 1
++
++/*
++@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
++** CHANGE it to undefined as soon as you rename 'string.gfind' to
++** 'string.gmatch'.
++*/
++#define LUA_COMPAT_GFIND
++
++/*
++@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
++@* behavior.
++** CHANGE it to undefined as soon as you replace to 'luaL_register'
++** your uses of 'luaL_openlib'
++*/
++#define LUA_COMPAT_OPENLIB
++
++
++
++/*
++@@ luai_apicheck is the assert macro used by the Lua-C API.
++** CHANGE luai_apicheck if you want Lua to perform some checks in the
++** parameters it gets from API calls. This may slow down the interpreter
++** a bit, but may be quite useful when debugging C code that interfaces
++** with Lua. A useful redefinition is to use assert.h.
++*/
++#if defined(LUA_USE_APICHECK)
++#include <assert.h>
++#define luai_apicheck(L,o) { (void)L; assert(o); }
++#else
++#define luai_apicheck(L,o) { (void)L; }
++#endif
++
++
++/*
++@@ LUAI_BITSINT defines the number of bits in an int.
++** CHANGE here if Lua cannot automatically detect the number of bits of
++** your machine. Probably you do not need to change this.
++*/
++/* avoid overflows in comparison */
++#if !defined(__KERNEL__)
++#include <limits.h>
++#define LUA_INT_MAX INT_MAX
++#else
++#define LUA_INT_MAX (~0U>>1)
++#endif
++
++#if LUA_INT_MAX-20 < 32760
++#define LUAI_BITSINT 16
++#elif LUA_INT_MAX > 2147483640L
++/* int has at least 32 bits */
++#define LUAI_BITSINT 32
++#else
++#error "you must define LUA_BITSINT with number of bits in an integer"
++#endif
++
++
++/*
++@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
++@@ LUAI_INT32 is an signed integer with at least 32 bits.
++@@ LUAI_UMEM is an unsigned integer big enough to count the total
++@* memory used by Lua.
++@@ LUAI_MEM is a signed integer big enough to count the total memory
++@* used by Lua.
++** CHANGE here if for some weird reason the default definitions are not
++** good enough for your machine. (The definitions in the 'else'
++** part always works, but may waste space on machines with 64-bit
++** longs.) Probably you do not need to change this.
++*/
++#if LUAI_BITSINT >= 32
++#define LUAI_UINT32 unsigned int
++#define LUAI_INT32 int
++#define LUAI_MAXINT32 INT_MAX
++#define LUAI_UMEM size_t
++#define LUAI_MEM ptrdiff_t
++#else
++/* 16-bit ints */
++#define LUAI_UINT32 unsigned long
++#define LUAI_INT32 long
++#define LUAI_MAXINT32 LONG_MAX
++#define LUAI_UMEM unsigned long
++#define LUAI_MEM long
++#endif
++
++
++/*
++@@ LUAI_MAXCALLS limits the number of nested calls.
++** CHANGE it if you need really deep recursive calls. This limit is
++** arbitrary; its only purpose is to stop infinite recursion before
++** exhausting memory.
++*/
++#define LUAI_MAXCALLS 20000
++
++
++/*
++@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
++@* can use.
++** CHANGE it if you need lots of (Lua) stack space for your C
++** functions. This limit is arbitrary; its only purpose is to stop C
++** functions to consume unlimited stack space. (must be smaller than
++** -LUA_REGISTRYINDEX)
++*/
++#define LUAI_MAXCSTACK 8000
++
++
++
++/*
++** {==================================================================
++** CHANGE (to smaller values) the following definitions if your system
++** has a small C stack. (Or you may want to change them to larger
++** values if your system has a large C stack and these limits are
++** too rigid for you.) Some of these constants control the size of
++** stack-allocated arrays used by the compiler or the interpreter, while
++** others limit the maximum number of recursive calls that the compiler
++** or the interpreter can perform. Values too large may cause a C stack
++** overflow for some forms of deep constructs.
++** ===================================================================
++*/
++
++
++/*
++@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
++@* syntactical nested non-terminals in a program.
++*/
++#define LUAI_MAXCCALLS 200
++
++
++/*
++@@ LUAI_MAXVARS is the maximum number of local variables per function
++@* (must be smaller than 250).
++*/
++#define LUAI_MAXVARS 200
++
++
++/*
++@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
++@* (must be smaller than 250).
++*/
++#define LUAI_MAXUPVALUES 60
++
++
++/*
++@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
++*/
++#define LUAL_BUFFERSIZE BUFSIZ
++
++/* }================================================================== */
++
++
++
++
++/*
++** {==================================================================
++@@ LUA_NUMBER is the type of numbers in Lua.
++** CHANGE the following definitions only if you want to build Lua
++** with a number type different from double. You may also need to
++** change lua_number2int & lua_number2integer.
++** ===================================================================
++*/
++#if !defined(NO_FPU)
++#define LUA_NUMBER_DOUBLE
++#define LUA_NUMBER double
++#else
++#define LUA_NUMBER long
++#endif
++
++/*
++@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
++@* over a number.
++*/
++#define LUAI_UACNUMBER LUA_NUMBER
++
++
++/*
++@@ LUA_NUMBER_SCAN is the format for reading numbers.
++@@ LUA_NUMBER_FMT is the format for writing numbers.
++@@ lua_number2str converts a number to a string.
++@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
++@@ lua_str2number converts a string to a number.
++*/
++#if !defined(NO_FPU)
++#define LUA_NUMBER_SCAN "%lf"
++#define LUA_NUMBER_FMT "%.14g"
++#define lua_str2number(s,p) strtod((s), (p))
++#else
++#define LUA_NUMBER_SCAN "%ld"
++#define LUA_NUMBER_FMT "%ld"
++#if !defined(__KERNEL__)
++#define lua_str2number(s,p) strtol((s), (p), 10)
++#else
++#define lua_str2number(s,p) simple_strtol((s), (p), 10)
++#endif
++#endif
++
++#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
++#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
++
++/*
++@@ The luai_num* macros define the primitive operations over numbers.
++*/
++#if defined(LUA_CORE)
++#define luai_numadd(a,b) ((a)+(b))
++#define luai_numsub(a,b) ((a)-(b))
++#define luai_nummul(a,b) ((a)*(b))
++#define luai_numdiv(a,b) ((a)/(b))
++#define luai_numunm(a) (-(a))
++#define luai_numeq(a,b) ((a)==(b))
++#define luai_numlt(a,b) ((a)<(b))
++#define luai_numle(a,b) ((a)<=(b))
++#define luai_numisnan(a) (!luai_numeq((a), (a)))
++#if !defined(NO_FPU)
++#include <math.h>
++#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
++#define luai_numpow(a,b) (pow(a,b))
++#else
++#define luai_nummod(a,b) ((a)%(b))
++#define luai_numpow(a,b) luai_nummul(a,b)
++#endif
++#endif
++
++
++/*
++@@ lua_number2int is a macro to convert lua_Number to int.
++@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
++** CHANGE them if you know a faster way to convert a lua_Number to
++** int (with any rounding method and without throwing errors) in your
++** system. In Pentium machines, a naive typecast from double to int
++** in C is extremely slow, so any alternative is worth trying.
++*/
++
++/* On a Pentium, resort to a trick */
++#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
++ (defined(__i386) || defined (_M_IX86) || defined(__i386__))
++
++/* On a Microsoft compiler, use assembler */
++#if defined(_MSC_VER)
++
++#define lua_number2int(i,d) __asm fld d __asm fistp i
++#define lua_number2integer(i,n) lua_number2int(i, n)
++
++/* the next trick should work on any Pentium, but sometimes clashes
++ with a DirectX idiosyncrasy */
++#else
++
++union luai_Cast { double l_d; long l_l; };
++#define lua_number2int(i,d) \
++ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
++#define lua_number2integer(i,n) lua_number2int(i, n)
++
++#endif
++
++
++/* this option always works, but may be slow */
++#else
++#define lua_number2int(i,d) ((i)=(int)(d))
++#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
++
++#endif
++
++/* }================================================================== */
++
++
++/*
++@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
++** CHANGE it if your system requires alignments larger than double. (For
++** instance, if your system supports long doubles and they must be
++** aligned in 16-byte boundaries, then you should add long double in the
++** union.) Probably you do not need to change this.
++*/
++#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
++
++
++/*
++@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
++** CHANGE them if you prefer to use longjmp/setjmp even with C++
++** or if want/don't to use _longjmp/_setjmp instead of regular
++** longjmp/setjmp. By default, Lua handles errors with exceptions when
++** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
++** and with longjmp/setjmp otherwise.
++*/
++#if defined(__KERNEL__)
++#undef LUA_USE_ULONGJMP
++#endif
++
++#if defined(__cplusplus)
++/* C++ exceptions */
++#define LUAI_THROW(L,c) throw(c)
++#define LUAI_TRY(L,c,a) try { a } catch(...) \
++ { if ((c)->status == 0) (c)->status = -1; }
++#define luai_jmpbuf int /* dummy variable */
++
++#elif defined(LUA_USE_ULONGJMP)
++/* in Unix, try _longjmp/_setjmp (more efficient) */
++#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
++#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
++#define luai_jmpbuf jmp_buf
++
++#else
++/* default handling with long jumps */
++#define LUAI_THROW(L,c) longjmp((c)->b, 1)
++#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
++#define luai_jmpbuf jmp_buf
++
++#endif
++
++
++/*
++@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
++@* can do during pattern-matching.
++** CHANGE it if you need more captures. This limit is arbitrary.
++*/
++#define LUA_MAXCAPTURES 32
++
++
++/*
++@@ lua_tmpnam is the function that the OS library uses to create a
++@* temporary name.
++@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
++** CHANGE them if you have an alternative to tmpnam (which is considered
++** insecure) or if you want the original tmpnam anyway. By default, Lua
++** uses tmpnam except when POSIX is available, where it uses mkstemp.
++*/
++#if defined(loslib_c) || defined(luaall_c)
++
++#if defined(LUA_USE_MKSTEMP)
++#include <unistd.h>
++#define LUA_TMPNAMBUFSIZE 32
++#define lua_tmpnam(b,e) { \
++ strcpy(b, "/tmp/lua_XXXXXX"); \
++ e = mkstemp(b); \
++ if (e != -1) close(e); \
++ e = (e == -1); }
++
++#else
++#define LUA_TMPNAMBUFSIZE L_tmpnam
++#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
++#endif
++
++#endif
++
++
++/*
++@@ lua_popen spawns a new process connected to the current one through
++@* the file streams.
++** CHANGE it if you have a way to implement it in your system.
++*/
++#if defined(LUA_USE_POPEN)
++
++#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
++#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
++
++#elif defined(LUA_WIN)
++
++#define lua_popen(L,c,m) ((void)L, _popen(c,m))
++#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
++
++#else
++
++#define lua_popen(L,c,m) ((void)((void)c, m), \
++ luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
++#define lua_pclose(L,file) ((void)((void)L, file), 0)
++
++#endif
++
++/*
++@@ LUA_DL_* define which dynamic-library system Lua should use.
++** CHANGE here if Lua has problems choosing the appropriate
++** dynamic-library system for your platform (either Windows' DLL, Mac's
++** dyld, or Unix's dlopen). If your system is some kind of Unix, there
++** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
++** it. To use dlopen you also need to adapt the src/Makefile (probably
++** adding -ldl to the linker options), so Lua does not select it
++** automatically. (When you change the makefile to add -ldl, you must
++** also add -DLUA_USE_DLOPEN.)
++** If you do not want any kind of dynamic library, undefine all these
++** options.
++** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
++*/
++#if defined(LUA_USE_DLOPEN)
++#define LUA_DL_DLOPEN
++#endif
++
++#if defined(LUA_WIN)
++#define LUA_DL_DLL
++#endif
++
++
++/*
++@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
++@* (the data goes just *before* the lua_State pointer).
++** CHANGE (define) this if you really need that. This value must be
++** a multiple of the maximum alignment required for your machine.
++*/
++#define LUAI_EXTRASPACE 0
++
++
++/*
++@@ luai_userstate* allow user-specific actions on threads.
++** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
++** extra when a thread is created/deleted/resumed/yielded.
++*/
++#define luai_userstateopen(L) ((void)L)
++#define luai_userstateclose(L) ((void)L)
++#define luai_userstatethread(L,L1) ((void)L)
++#define luai_userstatefree(L) ((void)L)
++#define luai_userstateresume(L,n) ((void)L)
++#define luai_userstateyield(L,n) ((void)L)
++
++
++/*
++@@ LUA_INTFRMLEN is the length modifier for integer conversions
++@* in 'string.format'.
++@@ LUA_INTFRM_T is the integer type correspoding to the previous length
++@* modifier.
++** CHANGE them if your system supports long long or does not support long.
++*/
++
++#if defined(LUA_USELONGLONG)
++
++#define LUA_INTFRMLEN "ll"
++#define LUA_INTFRM_T long long
++
++#else
++
++#define LUA_INTFRMLEN "l"
++#define LUA_INTFRM_T long
++
++#endif
++
++/* =================================================================== */
++
++/*
++** Local configuration. You can use this space to add your redefinitions
++** without modifying the main part of the file.
++*/
++
++
++
++#endif
++
+--- /dev/null
++++ b/extensions/LUA/lua/lua.h
+@@ -0,0 +1,387 @@
++/*
++** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
++** Lua - An Extensible Extension Language
++** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
++** See Copyright Notice at the end of this file
++*/
++
++
++#ifndef lua_h
++#define lua_h
++
++#include <stdarg.h>
++#include <stddef.h>
++
++#include "luaconf.h"
++
++
++#define LUA_VERSION "Lua 5.1"
++#define LUA_RELEASE "Lua 5.1.4"
++#define LUA_VERSION_NUM 501
++#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
++#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
++
++
++/* mark for precompiled code (`<esc>Lua') */
++#define LUA_SIGNATURE "\033Lua"
++
++/* option for multiple returns in `lua_pcall' and `lua_call' */
++#define LUA_MULTRET (-1)
++
++
++/*
++** pseudo-indices
++*/
++#define LUA_REGISTRYINDEX (-10000)
++#define LUA_ENVIRONINDEX (-10001)
++#define LUA_GLOBALSINDEX (-10002)
++#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
++
++
++/* thread status; 0 is OK */
++#define LUA_YIELD 1
++#define LUA_ERRRUN 2
++#define LUA_ERRSYNTAX 3
++#define LUA_ERRMEM 4
++#define LUA_ERRERR 5
++
++
++typedef struct lua_State lua_State;
++
++typedef int (*lua_CFunction) (lua_State *L);
++
++
++/*
++** functions that read/write blocks when loading/dumping Lua chunks
++*/
++typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
++
++typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
++
++
++/*
++** prototype for memory-allocation functions
++*/
++typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
++
++
++/*
++** basic types
++*/
++#define LUA_TNONE (-1)
++
++#define LUA_TNIL 0
++#define LUA_TBOOLEAN 1
++#define LUA_TLIGHTUSERDATA 2
++#define LUA_TNUMBER 3
++#define LUA_TSTRING 4
++#define LUA_TTABLE 5
++#define LUA_TFUNCTION 6
++#define LUA_TUSERDATA 7
++#define LUA_TTHREAD 8
++
++
++
++/* minimum Lua stack available to a C function */
++#define LUA_MINSTACK 20
++
++
++/*
++** generic extra include file
++*/
++#if defined(LUA_USER_H)
++#include LUA_USER_H
++#endif
++
++
++/* type of numbers in Lua */
++typedef LUA_NUMBER lua_Number;
++
++
++/* type for integer functions */
++typedef LUA_INTEGER lua_Integer;
++
++
++
++/*
++** state manipulation
++*/
++LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
++LUA_API void (lua_close) (lua_State *L);
++LUA_API lua_State *(lua_newthread) (lua_State *L);
++
++LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
++
++
++/*
++** basic stack manipulation
++*/
++LUA_API int (lua_gettop) (lua_State *L);
++LUA_API void (lua_settop) (lua_State *L, int idx);
++LUA_API void (lua_pushvalue) (lua_State *L, int idx);
++LUA_API void (lua_remove) (lua_State *L, int idx);
++LUA_API void (lua_insert) (lua_State *L, int idx);
++LUA_API void (lua_replace) (lua_State *L, int idx);
++LUA_API int (lua_checkstack) (lua_State *L, int sz);
++
++LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
++
++
++/*
++** access functions (stack -> C)
++*/
++
++LUA_API int (lua_isnumber) (lua_State *L, int idx);
++LUA_API int (lua_isstring) (lua_State *L, int idx);
++LUA_API int (lua_iscfunction) (lua_State *L, int idx);
++LUA_API int (lua_isuserdata) (lua_State *L, int idx);
++LUA_API int (lua_type) (lua_State *L, int idx);
++LUA_API const char *(lua_typename) (lua_State *L, int tp);
++
++LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
++LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
++LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
++
++LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
++LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
++LUA_API int (lua_toboolean) (lua_State *L, int idx);
++LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
++LUA_API size_t (lua_objlen) (lua_State *L, int idx);
++LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
++LUA_API void *(lua_touserdata) (lua_State *L, int idx);
++LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
++LUA_API const void *(lua_topointer) (lua_State *L, int idx);
++
++
++/*
++** push functions (C -> stack)
++*/
++LUA_API void (lua_pushnil) (lua_State *L);
++LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
++LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
++LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
++LUA_API void (lua_pushstring) (lua_State *L, const char *s);
++LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
++ va_list argp);
++LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
++LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
++LUA_API void (lua_pushboolean) (lua_State *L, int b);
++LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
++LUA_API int (lua_pushthread) (lua_State *L);
++
++
++/*
++** get functions (Lua -> stack)
++*/
++LUA_API void (lua_gettable) (lua_State *L, int idx);
++LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
++LUA_API void (lua_rawget) (lua_State *L, int idx);
++LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
++LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
++LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
++LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
++LUA_API void (lua_getfenv) (lua_State *L, int idx);
++
++
++/*
++** set functions (stack -> Lua)
++*/
++LUA_API void (lua_settable) (lua_State *L, int idx);
++LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
++LUA_API void (lua_rawset) (lua_State *L, int idx);
++LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
++LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
++LUA_API int (lua_setfenv) (lua_State *L, int idx);
++
++
++/*
++** `load' and `call' functions (load and run Lua code)
++*/
++LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
++LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
++LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
++LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
++ const char *chunkname);
++
++LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
++
++
++/*
++** coroutine functions
++*/
++LUA_API int (lua_yield) (lua_State *L, int nresults);
++LUA_API int (lua_resume) (lua_State *L, int narg);
++LUA_API int (lua_status) (lua_State *L);
++
++/*
++** garbage-collection function and options
++*/
++
++#define LUA_GCSTOP 0
++#define LUA_GCRESTART 1
++#define LUA_GCCOLLECT 2
++#define LUA_GCCOUNT 3
++#define LUA_GCCOUNTB 4
++#define LUA_GCSTEP 5
++#define LUA_GCSETPAUSE 6
++#define LUA_GCSETSTEPMUL 7
++
++LUA_API int (lua_gc) (lua_State *L, int what, int data);
++
++
++/*
++** miscellaneous functions
++*/
++
++LUA_API int (lua_error) (lua_State *L);
++
++LUA_API int (lua_next) (lua_State *L, int idx);
++
++LUA_API void (lua_concat) (lua_State *L, int n);
++
++LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
++LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
++
++
++
++/*
++** ===============================================================
++** some useful macros
++** ===============================================================
++*/
++
++#define lua_pop(L,n) lua_settop(L, -(n)-1)
++
++#define lua_newtable(L) lua_createtable(L, 0, 0)
++
++#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
++
++#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
++
++#define lua_strlen(L,i) lua_objlen(L, (i))
++
++#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
++#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
++#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
++#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
++#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
++#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
++#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
++#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
++
++#define lua_pushliteral(L, s) \
++ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
++
++#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
++#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
++
++#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
++
++
++
++/*
++** compatibility macros and functions
++*/
++
++#define lua_open() luaL_newstate()
++
++#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
++
++#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
++
++#define lua_Chunkreader lua_Reader
++#define lua_Chunkwriter lua_Writer
++
++
++/* hack */
++LUA_API void lua_setlevel (lua_State *from, lua_State *to);
++
++
++/*
++** {======================================================================
++** Debug API
++** =======================================================================
++*/
++
++
++/*
++** Event codes
++*/
++#define LUA_HOOKCALL 0
++#define LUA_HOOKRET 1
++#define LUA_HOOKLINE 2
++#define LUA_HOOKCOUNT 3
++#define LUA_HOOKTAILRET 4
++
++
++/*
++** Event masks
++*/
++#define LUA_MASKCALL (1 << LUA_HOOKCALL)
++#define LUA_MASKRET (1 << LUA_HOOKRET)
++#define LUA_MASKLINE (1 << LUA_HOOKLINE)
++#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
++
++typedef struct lua_Debug lua_Debug; /* activation record */
++
++
++/* Functions to be called by the debuger in specific events */
++typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
++
++
++LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
++LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
++LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
++LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
++LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
++LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
++
++LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
++LUA_API lua_Hook lua_gethook (lua_State *L);
++LUA_API int lua_gethookmask (lua_State *L);
++LUA_API int lua_gethookcount (lua_State *L);
++
++
++struct lua_Debug {
++ int event;
++ const char *name; /* (n) */
++ const char *namewhat; /* (n) `global', `local', `field', `method' */
++ const char *what; /* (S) `Lua', `C', `main', `tail' */
++ const char *source; /* (S) */
++ int currentline; /* (l) */
++ int nups; /* (u) number of upvalues */
++ int linedefined; /* (S) */
++ int lastlinedefined; /* (S) */
++ char short_src[LUA_IDSIZE]; /* (S) */
++ /* private part */
++ int i_ci; /* active function */
++};
++
++/* }====================================================================== */
++
++
++/******************************************************************************
++* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
++*
++* Permission is hereby granted, free of charge, to any person obtaining
++* a copy of this software and associated documentation files (the
++* "Software"), to deal in the Software without restriction, including
++* without limitation the rights to use, copy, modify, merge, publish,
++* distribute, sublicense, and/or sell copies of the Software, and to
++* permit persons to whom the Software is furnished to do so, subject to
++* the following conditions:
++*
++* The above copyright notice and this permission notice shall be
++* included in all copies or substantial portions of the Software.
++*
++* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++******************************************************************************/
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lualib.h
+@@ -0,0 +1,55 @@
++/*
++** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $
++** Lua standard libraries
++** See Copyright Notice in lua.h
++*/
++
++
++#ifndef lualib_h
++#define lualib_h
++
++#include "lua.h"
++
++
++/* Key to file-handle type */
++#define LUA_FILEHANDLE "FILE*"
++
++
++#define LUA_COLIBNAME "coroutine"
++LUALIB_API int (luaopen_base) (lua_State *L);
++
++#define LUA_TABLIBNAME "table"
++LUALIB_API int (luaopen_table) (lua_State *L);
++/*
++#define LUA_IOLIBNAME "io"
++LUALIB_API int (luaopen_io) (lua_State *L);
++
++#define LUA_OSLIBNAME "os"
++LUALIB_API int (luaopen_os) (lua_State *L);
++*/
++
++#define LUA_STRLIBNAME "string"
++LUALIB_API int (luaopen_string) (lua_State *L);
++
++/*
++#define LUA_MATHLIBNAME "math"
++LUALIB_API int (luaopen_math) (lua_State *L);
++
++#define LUA_DBLIBNAME "debug"
++LUALIB_API int (luaopen_debug) (lua_State *L);
++
++#define LUA_LOADLIBNAME "package"
++LUALIB_API int (luaopen_package) (lua_State *L);
++*/
++
++/* open all previous libraries */
++LUALIB_API void (luaL_openlibs) (lua_State *L);
++
++
++
++#ifndef lua_assert
++#define lua_assert(x) ((void)0)
++#endif
++
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lundump.c
+@@ -0,0 +1,227 @@
++/*
++** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
++** load precompiled Lua chunks
++** See Copyright Notice in lua.h
++*/
++
++#include <string.h>
++
++#define lundump_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "ldebug.h"
++#include "ldo.h"
++#include "lfunc.h"
++#include "lmem.h"
++#include "lobject.h"
++#include "lstring.h"
++#include "lundump.h"
++#include "lzio.h"
++
++typedef struct {
++ lua_State* L;
++ ZIO* Z;
++ Mbuffer* b;
++ const char* name;
++} LoadState;
++
++#ifdef LUAC_TRUST_BINARIES
++#define IF(c,s)
++#define error(S,s)
++#else
++#define IF(c,s) if (c) error(S,s)
++
++static void error(LoadState* S, const char* why)
++{
++ luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
++ luaD_throw(S->L,LUA_ERRSYNTAX);
++}
++#endif
++
++#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
++#define LoadByte(S) (lu_byte)LoadChar(S)
++#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
++#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
++
++static void LoadBlock(LoadState* S, void* b, size_t size)
++{
++ size_t r=luaZ_read(S->Z,b,size);
++ IF (r!=0, "unexpected end");
++}
++
++static int LoadChar(LoadState* S)
++{
++ char x;
++ LoadVar(S,x);
++ return x;
++}
++
++static int LoadInt(LoadState* S)
++{
++ int x;
++ LoadVar(S,x);
++ IF (x<0, "bad integer");
++ return x;
++}
++
++static lua_Number LoadNumber(LoadState* S)
++{
++ lua_Number x;
++ LoadVar(S,x);
++ return x;
++}
++
++static TString* LoadString(LoadState* S)
++{
++ size_t size;
++ LoadVar(S,size);
++ if (size==0)
++ return NULL;
++ else
++ {
++ char* s=luaZ_openspace(S->L,S->b,size);
++ LoadBlock(S,s,size);
++ return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
++ }
++}
++
++static void LoadCode(LoadState* S, Proto* f)
++{
++ int n=LoadInt(S);
++ f->code=luaM_newvector(S->L,n,Instruction);
++ f->sizecode=n;
++ LoadVector(S,f->code,n,sizeof(Instruction));
++}
++
++static Proto* LoadFunction(LoadState* S, TString* p);
++
++static void LoadConstants(LoadState* S, Proto* f)
++{
++ int i,n;
++ n=LoadInt(S);
++ f->k=luaM_newvector(S->L,n,TValue);
++ f->sizek=n;
++ for (i=0; i<n; i++) setnilvalue(&f->k[i]);
++ for (i=0; i<n; i++)
++ {
++ TValue* o=&f->k[i];
++ int t=LoadChar(S);
++ switch (t)
++ {
++ case LUA_TNIL:
++ setnilvalue(o);
++ break;
++ case LUA_TBOOLEAN:
++ setbvalue(o,LoadChar(S)!=0);
++ break;
++ case LUA_TNUMBER:
++ setnvalue(o,LoadNumber(S));
++ break;
++ case LUA_TSTRING:
++ setsvalue2n(S->L,o,LoadString(S));
++ break;
++ default:
++ error(S,"bad constant");
++ break;
++ }
++ }
++ n=LoadInt(S);
++ f->p=luaM_newvector(S->L,n,Proto*);
++ f->sizep=n;
++ for (i=0; i<n; i++) f->p[i]=NULL;
++ for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
++}
++
++static void LoadDebug(LoadState* S, Proto* f)
++{
++ int i,n;
++ n=LoadInt(S);
++ f->lineinfo=luaM_newvector(S->L,n,int);
++ f->sizelineinfo=n;
++ LoadVector(S,f->lineinfo,n,sizeof(int));
++ n=LoadInt(S);
++ f->locvars=luaM_newvector(S->L,n,LocVar);
++ f->sizelocvars=n;
++ for (i=0; i<n; i++) f->locvars[i].varname=NULL;
++ for (i=0; i<n; i++)
++ {
++ f->locvars[i].varname=LoadString(S);
++ f->locvars[i].startpc=LoadInt(S);
++ f->locvars[i].endpc=LoadInt(S);
++ }
++ n=LoadInt(S);
++ f->upvalues=luaM_newvector(S->L,n,TString*);
++ f->sizeupvalues=n;
++ for (i=0; i<n; i++) f->upvalues[i]=NULL;
++ for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
++}
++
++static Proto* LoadFunction(LoadState* S, TString* p)
++{
++ Proto* f;
++ if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
++ f=luaF_newproto(S->L);
++ setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
++ f->source=LoadString(S); if (f->source==NULL) f->source=p;
++ f->linedefined=LoadInt(S);
++ f->lastlinedefined=LoadInt(S);
++ f->nups=LoadByte(S);
++ f->numparams=LoadByte(S);
++ f->is_vararg=LoadByte(S);
++ f->maxstacksize=LoadByte(S);
++ LoadCode(S,f);
++ LoadConstants(S,f);
++ LoadDebug(S,f);
++ IF (!luaG_checkcode(f), "bad code");
++ S->L->top--;
++ S->L->nCcalls--;
++ return f;
++}
++
++static void LoadHeader(LoadState* S)
++{
++ char h[LUAC_HEADERSIZE];
++ char s[LUAC_HEADERSIZE];
++ luaU_header(h);
++ LoadBlock(S,s,LUAC_HEADERSIZE);
++ IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
++}
++
++/*
++** load precompiled chunk
++*/
++Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
++{
++ LoadState S;
++ if (*name=='@' || *name=='=')
++ S.name=name+1;
++ else if (*name==LUA_SIGNATURE[0])
++ S.name="binary string";
++ else
++ S.name=name;
++ S.L=L;
++ S.Z=Z;
++ S.b=buff;
++ LoadHeader(&S);
++ return LoadFunction(&S,luaS_newliteral(L,"=?"));
++}
++
++/*
++* make header
++*/
++void luaU_header (char* h)
++{
++ int x=1;
++ memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
++ h+=sizeof(LUA_SIGNATURE)-1;
++ *h++=(char)LUAC_VERSION;
++ *h++=(char)LUAC_FORMAT;
++ *h++=(char)*(char*)&x; /* endianness */
++ *h++=(char)sizeof(int);
++ *h++=(char)sizeof(size_t);
++ *h++=(char)sizeof(Instruction);
++ *h++=(char)sizeof(lua_Number);
++ *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
++}
+--- /dev/null
++++ b/extensions/LUA/lua/lundump.h
+@@ -0,0 +1,36 @@
++/*
++** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
++** load precompiled Lua chunks
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lundump_h
++#define lundump_h
++
++#include "lobject.h"
++#include "lzio.h"
++
++/* load one chunk; from lundump.c */
++LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
++
++/* make header; from lundump.c */
++LUAI_FUNC void luaU_header (char* h);
++
++/* dump one chunk; from ldump.c */
++LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
++
++#ifdef luac_c
++/* print one chunk; from print.c */
++LUAI_FUNC void luaU_print (const Proto* f, int full);
++#endif
++
++/* for header of binary files -- this is Lua 5.1 */
++#define LUAC_VERSION 0x51
++
++/* for header of binary files -- this is the official format */
++#define LUAC_FORMAT 0
++
++/* size of header of binary files */
++#define LUAC_HEADERSIZE 12
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lvm.c
+@@ -0,0 +1,762 @@
++/*
++** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $
++** Lua virtual machine
++** See Copyright Notice in lua.h
++*/
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#define lvm_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "ldebug.h"
++#include "ldo.h"
++#include "lfunc.h"
++#include "lgc.h"
++#include "lobject.h"
++#include "lopcodes.h"
++#include "lstate.h"
++#include "lstring.h"
++#include "ltable.h"
++#include "ltm.h"
++#include "lvm.h"
++
++
++
++/* limit for table tag-method chains (to avoid loops) */
++#define MAXTAGLOOP 100
++
++
++const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
++ lua_Number num;
++ if (ttisnumber(obj)) return obj;
++ if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
++ setnvalue(n, num);
++ return n;
++ }
++ else
++ return NULL;
++}
++
++
++int luaV_tostring (lua_State *L, StkId obj) {
++ if (!ttisnumber(obj))
++ return 0;
++ else {
++ char s[LUAI_MAXNUMBER2STR];
++ lua_Number n = nvalue(obj);
++ lua_number2str(s, n);
++ setsvalue2s(L, obj, luaS_new(L, s));
++ return 1;
++ }
++}
++
++
++static void traceexec (lua_State *L, const Instruction *pc) {
++ lu_byte mask = L->hookmask;
++ const Instruction *oldpc = L->savedpc;
++ L->savedpc = pc;
++ if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
++ resethookcount(L);
++ luaD_callhook(L, LUA_HOOKCOUNT, -1);
++ }
++ if (mask & LUA_MASKLINE) {
++ Proto *p = ci_func(L->ci)->l.p;
++ int npc = pcRel(pc, p);
++ int newline = getline(p, npc);
++ /* call linehook when enter a new function, when jump back (loop),
++ or when enter a new line */
++ if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
++ luaD_callhook(L, LUA_HOOKLINE, newline);
++ }
++}
++
++
++static void callTMres (lua_State *L, StkId res, const TValue *f,
++ const TValue *p1, const TValue *p2) {
++ ptrdiff_t result = savestack(L, res);
++ setobj2s(L, L->top, f); /* push function */
++ setobj2s(L, L->top+1, p1); /* 1st argument */
++ setobj2s(L, L->top+2, p2); /* 2nd argument */
++ luaD_checkstack(L, 3);
++ L->top += 3;
++ luaD_call(L, L->top - 3, 1);
++ res = restorestack(L, result);
++ L->top--;
++ setobjs2s(L, res, L->top);
++}
++
++
++
++static void callTM (lua_State *L, const TValue *f, const TValue *p1,
++ const TValue *p2, const TValue *p3) {
++ setobj2s(L, L->top, f); /* push function */
++ setobj2s(L, L->top+1, p1); /* 1st argument */
++ setobj2s(L, L->top+2, p2); /* 2nd argument */
++ setobj2s(L, L->top+3, p3); /* 3th argument */
++ luaD_checkstack(L, 4);
++ L->top += 4;
++ luaD_call(L, L->top - 4, 0);
++}
++
++
++void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
++ int loop;
++ for (loop = 0; loop < MAXTAGLOOP; loop++) {
++ const TValue *tm;
++ if (ttistable(t)) { /* `t' is a table? */
++ Table *h = hvalue(t);
++ const TValue *res = luaH_get(h, key); /* do a primitive get */
++ if (!ttisnil(res) || /* result is no nil? */
++ (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
++ setobj2s(L, val, res);
++ return;
++ }
++ /* else will try the tag method */
++ }
++ else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
++ luaG_typeerror(L, t, "index");
++ if (ttisfunction(tm)) {
++ callTMres(L, val, tm, t, key);
++ return;
++ }
++ t = tm; /* else repeat with `tm' */
++ }
++ luaG_runerror(L, "loop in gettable");
++}
++
++
++void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
++ int loop;
++ for (loop = 0; loop < MAXTAGLOOP; loop++) {
++ const TValue *tm;
++ if (ttistable(t)) { /* `t' is a table? */
++ Table *h = hvalue(t);
++ TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
++ if (!ttisnil(oldval) || /* result is no nil? */
++ (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
++ setobj2t(L, oldval, val);
++ luaC_barriert(L, h, val);
++ return;
++ }
++ /* else will try the tag method */
++ }
++ else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
++ luaG_typeerror(L, t, "index");
++ if (ttisfunction(tm)) {
++ callTM(L, tm, t, key, val);
++ return;
++ }
++ t = tm; /* else repeat with `tm' */
++ }
++ luaG_runerror(L, "loop in settable");
++}
++
++
++static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
++ StkId res, TMS event) {
++ const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
++ if (ttisnil(tm))
++ tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
++ if (ttisnil(tm)) return 0;
++ callTMres(L, res, tm, p1, p2);
++ return 1;
++}
++
++
++static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
++ TMS event) {
++ const TValue *tm1 = fasttm(L, mt1, event);
++ const TValue *tm2;
++ if (tm1 == NULL) return NULL; /* no metamethod */
++ if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
++ tm2 = fasttm(L, mt2, event);
++ if (tm2 == NULL) return NULL; /* no metamethod */
++ if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
++ return tm1;
++ return NULL;
++}
++
++
++static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
++ TMS event) {
++ const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
++ const TValue *tm2;
++ if (ttisnil(tm1)) return -1; /* no metamethod? */
++ tm2 = luaT_gettmbyobj(L, p2, event);
++ if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
++ return -1;
++ callTMres(L, L->top, tm1, p1, p2);
++ return !l_isfalse(L->top);
++}
++
++
++static int l_strcmp (const TString *ls, const TString *rs) {
++ const char *l = getstr(ls);
++ size_t ll = ls->tsv.len;
++ const char *r = getstr(rs);
++ size_t lr = rs->tsv.len;
++ for (;;) {
++ int temp = strcoll(l, r);
++ if (temp != 0) return temp;
++ else { /* strings are equal up to a `\0' */
++ size_t len = strlen(l); /* index of first `\0' in both strings */
++ if (len == lr) /* r is finished? */
++ return (len == ll) ? 0 : 1;
++ else if (len == ll) /* l is finished? */
++ return -1; /* l is smaller than r (because r is not finished) */
++ /* both strings longer than `len'; go on comparing (after the `\0') */
++ len++;
++ l += len; ll -= len; r += len; lr -= len;
++ }
++ }
++}
++
++
++int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
++ int res;
++ if (ttype(l) != ttype(r))
++ return luaG_ordererror(L, l, r);
++ else if (ttisnumber(l))
++ return luai_numlt(nvalue(l), nvalue(r));
++ else if (ttisstring(l))
++ return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
++ else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
++ return res;
++ return luaG_ordererror(L, l, r);
++}
++
++
++static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
++ int res;
++ if (ttype(l) != ttype(r))
++ return luaG_ordererror(L, l, r);
++ else if (ttisnumber(l))
++ return luai_numle(nvalue(l), nvalue(r));
++ else if (ttisstring(l))
++ return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
++ else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
++ return res;
++ else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
++ return !res;
++ return luaG_ordererror(L, l, r);
++}
++
++
++int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
++ const TValue *tm;
++ lua_assert(ttype(t1) == ttype(t2));
++ switch (ttype(t1)) {
++ case LUA_TNIL: return 1;
++ case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
++ case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
++ case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
++ case LUA_TUSERDATA: {
++ if (uvalue(t1) == uvalue(t2)) return 1;
++ tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
++ TM_EQ);
++ break; /* will try TM */
++ }
++ case LUA_TTABLE: {
++ if (hvalue(t1) == hvalue(t2)) return 1;
++ tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
++ break; /* will try TM */
++ }
++ default: return gcvalue(t1) == gcvalue(t2);
++ }
++ if (tm == NULL) return 0; /* no TM? */
++ callTMres(L, L->top, tm, t1, t2); /* call TM */
++ return !l_isfalse(L->top);
++}
++
++
++void luaV_concat (lua_State *L, int total, int last) {
++ do {
++ StkId top = L->base + last + 1;
++ int n = 2; /* number of elements handled in this pass (at least 2) */
++ if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
++ if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
++ luaG_concaterror(L, top-2, top-1);
++ } else if (tsvalue(top-1)->len == 0) /* second op is empty? */
++ (void)tostring(L, top - 2); /* result is first op (as string) */
++ else {
++ /* at least two string values; get as many as possible */
++ size_t tl = tsvalue(top-1)->len;
++ char *buffer;
++ int i;
++ /* collect total length */
++ for (n = 1; n < total && tostring(L, top-n-1); n++) {
++ size_t l = tsvalue(top-n-1)->len;
++ if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
++ tl += l;
++ }
++ buffer = luaZ_openspace(L, &G(L)->buff, tl);
++ tl = 0;
++ for (i=n; i>0; i--) { /* concat all strings */
++ size_t l = tsvalue(top-i)->len;
++ memcpy(buffer+tl, svalue(top-i), l);
++ tl += l;
++ }
++ setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
++ }
++ total -= n-1; /* got `n' strings to create 1 new */
++ last -= n-1;
++ } while (total > 1); /* repeat until only 1 result left */
++}
++
++
++static void Arith (lua_State *L, StkId ra, const TValue *rb,
++ const TValue *rc, TMS op) {
++ TValue tempb, tempc;
++ const TValue *b, *c;
++ if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
++ (c = luaV_tonumber(rc, &tempc)) != NULL) {
++ lua_Number nb = nvalue(b), nc = nvalue(c);
++ switch (op) {
++ case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
++ case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
++ case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
++ case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
++ case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
++ case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
++ case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
++ default: lua_assert(0); break;
++ }
++ }
++ else if (!call_binTM(L, rb, rc, ra, op))
++ luaG_aritherror(L, rb, rc);
++}
++
++
++
++/*
++** some macros for common tasks in `luaV_execute'
++*/
++
++#define runtime_check(L, c) { if (!(c)) break; }
++
++#define RA(i) (base+GETARG_A(i))
++/* to be used after possible stack reallocation */
++#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
++#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
++#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
++ ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
++#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
++ ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
++#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
++
++
++#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
++
++
++#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
++
++
++#define arith_op(op,tm) { \
++ TValue *rb = RKB(i); \
++ TValue *rc = RKC(i); \
++ if (ttisnumber(rb) && ttisnumber(rc)) { \
++ lua_Number nb = nvalue(rb), nc = nvalue(rc); \
++ setnvalue(ra, op(nb, nc)); \
++ } \
++ else \
++ Protect(Arith(L, ra, rb, rc, tm)); \
++ }
++
++
++
++void luaV_execute (lua_State *L, int nexeccalls) {
++ LClosure *cl;
++ StkId base;
++ TValue *k;
++ const Instruction *pc;
++ reentry: /* entry point */
++ lua_assert(isLua(L->ci));
++ pc = L->savedpc;
++ cl = &clvalue(L->ci->func)->l;
++ base = L->base;
++ k = cl->p->k;
++ /* main loop of interpreter */
++ for (;;) {
++ const Instruction i = *pc++;
++ StkId ra;
++ if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
++ (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
++ traceexec(L, pc);
++ if (L->status == LUA_YIELD) { /* did hook yield? */
++ L->savedpc = pc - 1;
++ return;
++ }
++ base = L->base;
++ }
++ /* warning!! several calls may realloc the stack and invalidate `ra' */
++ ra = RA(i);
++ lua_assert(base == L->base && L->base == L->ci->base);
++ lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
++ lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
++ switch (GET_OPCODE(i)) {
++ case OP_MOVE: {
++ setobjs2s(L, ra, RB(i));
++ continue;
++ }
++ case OP_LOADK: {
++ setobj2s(L, ra, KBx(i));
++ continue;
++ }
++ case OP_LOADBOOL: {
++ setbvalue(ra, GETARG_B(i));
++ if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
++ continue;
++ }
++ case OP_LOADNIL: {
++ TValue *rb = RB(i);
++ do {
++ setnilvalue(rb--);
++ } while (rb >= ra);
++ continue;
++ }
++ case OP_GETUPVAL: {
++ int b = GETARG_B(i);
++ setobj2s(L, ra, cl->upvals[b]->v);
++ continue;
++ }
++ case OP_GETGLOBAL: {
++ TValue g;
++ TValue *rb = KBx(i);
++ sethvalue(L, &g, cl->env);
++ lua_assert(ttisstring(rb));
++ Protect(luaV_gettable(L, &g, rb, ra));
++ continue;
++ }
++ case OP_GETTABLE: {
++ Protect(luaV_gettable(L, RB(i), RKC(i), ra));
++ continue;
++ }
++ case OP_SETGLOBAL: {
++ TValue g;
++ sethvalue(L, &g, cl->env);
++ lua_assert(ttisstring(KBx(i)));
++ Protect(luaV_settable(L, &g, KBx(i), ra));
++ continue;
++ }
++ case OP_SETUPVAL: {
++ UpVal *uv = cl->upvals[GETARG_B(i)];
++ setobj(L, uv->v, ra);
++ luaC_barrier(L, uv, ra);
++ continue;
++ }
++ case OP_SETTABLE: {
++ Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
++ continue;
++ }
++ case OP_NEWTABLE: {
++ int b = GETARG_B(i);
++ int c = GETARG_C(i);
++ sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
++ Protect(luaC_checkGC(L));
++ continue;
++ }
++ case OP_SELF: {
++ StkId rb = RB(i);
++ setobjs2s(L, ra+1, rb);
++ Protect(luaV_gettable(L, rb, RKC(i), ra));
++ continue;
++ }
++ case OP_ADD: {
++ arith_op(luai_numadd, TM_ADD);
++ continue;
++ }
++ case OP_SUB: {
++ arith_op(luai_numsub, TM_SUB);
++ continue;
++ }
++ case OP_MUL: {
++ arith_op(luai_nummul, TM_MUL);
++ continue;
++ }
++ case OP_DIV: {
++ arith_op(luai_numdiv, TM_DIV);
++ continue;
++ }
++ case OP_MOD: {
++ arith_op(luai_nummod, TM_MOD);
++ continue;
++ }
++ case OP_POW: {
++ arith_op(luai_numpow, TM_POW);
++ continue;
++ }
++ case OP_UNM: {
++ TValue *rb = RB(i);
++ if (ttisnumber(rb)) {
++ lua_Number nb = nvalue(rb);
++ setnvalue(ra, luai_numunm(nb));
++ }
++ else {
++ Protect(Arith(L, ra, rb, rb, TM_UNM));
++ }
++ continue;
++ }
++ case OP_NOT: {
++ int res = l_isfalse(RB(i)); /* next assignment may change this value */
++ setbvalue(ra, res);
++ continue;
++ }
++ case OP_LEN: {
++ const TValue *rb = RB(i);
++ switch (ttype(rb)) {
++ case LUA_TTABLE: {
++ setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
++ break;
++ }
++ case LUA_TSTRING: {
++ setnvalue(ra, cast_num(tsvalue(rb)->len));
++ break;
++ }
++ default: { /* try metamethod */
++ Protect(
++ if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
++ luaG_typeerror(L, rb, "get length of");
++ )
++ }
++ }
++ continue;
++ }
++ case OP_CONCAT: {
++ int b = GETARG_B(i);
++ int c = GETARG_C(i);
++ Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
++ setobjs2s(L, RA(i), base+b);
++ continue;
++ }
++ case OP_JMP: {
++ dojump(L, pc, GETARG_sBx(i));
++ continue;
++ }
++ case OP_EQ: {
++ TValue *rb = RKB(i);
++ TValue *rc = RKC(i);
++ Protect(
++ if (equalobj(L, rb, rc) == GETARG_A(i))
++ dojump(L, pc, GETARG_sBx(*pc));
++ )
++ pc++;
++ continue;
++ }
++ case OP_LT: {
++ Protect(
++ if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
++ dojump(L, pc, GETARG_sBx(*pc));
++ )
++ pc++;
++ continue;
++ }
++ case OP_LE: {
++ Protect(
++ if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
++ dojump(L, pc, GETARG_sBx(*pc));
++ )
++ pc++;
++ continue;
++ }
++ case OP_TEST: {
++ if (l_isfalse(ra) != GETARG_C(i))
++ dojump(L, pc, GETARG_sBx(*pc));
++ pc++;
++ continue;
++ }
++ case OP_TESTSET: {
++ TValue *rb = RB(i);
++ if (l_isfalse(rb) != GETARG_C(i)) {
++ setobjs2s(L, ra, rb);
++ dojump(L, pc, GETARG_sBx(*pc));
++ }
++ pc++;
++ continue;
++ }
++ case OP_CALL: {
++ int b = GETARG_B(i);
++ int nresults = GETARG_C(i) - 1;
++ if (b != 0) L->top = ra+b; /* else previous instruction set top */
++ L->savedpc = pc;
++ switch (luaD_precall(L, ra, nresults)) {
++ case PCRLUA: {
++ nexeccalls++;
++ goto reentry; /* restart luaV_execute over new Lua function */
++ }
++ case PCRC: {
++ /* it was a C function (`precall' called it); adjust results */
++ if (nresults >= 0) L->top = L->ci->top;
++ base = L->base;
++ continue;
++ }
++ default: {
++ return; /* yield */
++ }
++ }
++ }
++ case OP_TAILCALL: {
++ int b = GETARG_B(i);
++ if (b != 0) L->top = ra+b; /* else previous instruction set top */
++ L->savedpc = pc;
++ lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
++ switch (luaD_precall(L, ra, LUA_MULTRET)) {
++ case PCRLUA: {
++ /* tail call: put new frame in place of previous one */
++ CallInfo *ci = L->ci - 1; /* previous frame */
++ int aux;
++ StkId func = ci->func;
++ StkId pfunc = (ci+1)->func; /* previous function index */
++ if (L->openupval) luaF_close(L, ci->base);
++ L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
++ for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
++ setobjs2s(L, func+aux, pfunc+aux);
++ ci->top = L->top = func+aux; /* correct top */
++ lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
++ ci->savedpc = L->savedpc;
++ ci->tailcalls++; /* one more call lost */
++ L->ci--; /* remove new frame */
++ goto reentry;
++ }
++ case PCRC: { /* it was a C function (`precall' called it) */
++ base = L->base;
++ continue;
++ }
++ default: {
++ return; /* yield */
++ }
++ }
++ }
++ case OP_RETURN: {
++ int b = GETARG_B(i);
++ if (b != 0) L->top = ra+b-1;
++ if (L->openupval) luaF_close(L, base);
++ L->savedpc = pc;
++ b = luaD_poscall(L, ra);
++ if (--nexeccalls == 0) /* was previous function running `here'? */
++ return; /* no: return */
++ else { /* yes: continue its execution */
++ if (b) L->top = L->ci->top;
++ lua_assert(isLua(L->ci));
++ lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
++ goto reentry;
++ }
++ }
++ case OP_FORLOOP: {
++ lua_Number step = nvalue(ra+2);
++ lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
++ lua_Number limit = nvalue(ra+1);
++ if (luai_numlt(0, step) ? luai_numle(idx, limit)
++ : luai_numle(limit, idx)) {
++ dojump(L, pc, GETARG_sBx(i)); /* jump back */
++ setnvalue(ra, idx); /* update internal index... */
++ setnvalue(ra+3, idx); /* ...and external index */
++ }
++ continue;
++ }
++ case OP_FORPREP: {
++ const TValue *init = ra;
++ const TValue *plimit = ra+1;
++ const TValue *pstep = ra+2;
++ L->savedpc = pc; /* next steps may throw errors */
++ if (!tonumber(init, ra))
++ luaG_runerror(L, LUA_QL("for") " initial value must be a number");
++ else if (!tonumber(plimit, ra+1))
++ luaG_runerror(L, LUA_QL("for") " limit must be a number");
++ else if (!tonumber(pstep, ra+2))
++ luaG_runerror(L, LUA_QL("for") " step must be a number");
++ setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
++ dojump(L, pc, GETARG_sBx(i));
++ continue;
++ }
++ case OP_TFORLOOP: {
++ StkId cb = ra + 3; /* call base */
++ setobjs2s(L, cb+2, ra+2);
++ setobjs2s(L, cb+1, ra+1);
++ setobjs2s(L, cb, ra);
++ L->top = cb+3; /* func. + 2 args (state and index) */
++ Protect(luaD_call(L, cb, GETARG_C(i)));
++ L->top = L->ci->top;
++ cb = RA(i) + 3; /* previous call may change the stack */
++ if (!ttisnil(cb)) { /* continue loop? */
++ setobjs2s(L, cb-1, cb); /* save control variable */
++ dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
++ }
++ pc++;
++ continue;
++ }
++ case OP_SETLIST: {
++ int n = GETARG_B(i);
++ int c = GETARG_C(i);
++ int last;
++ Table *h;
++ if (n == 0) {
++ n = cast_int(L->top - ra) - 1;
++ L->top = L->ci->top;
++ }
++ if (c == 0) c = cast_int(*pc++);
++ runtime_check(L, ttistable(ra));
++ h = hvalue(ra);
++ last = ((c-1)*LFIELDS_PER_FLUSH) + n;
++ if (last > h->sizearray) /* needs more space? */
++ luaH_resizearray(L, h, last); /* pre-alloc it at once */
++ for (; n > 0; n--) {
++ TValue *val = ra+n;
++ setobj2t(L, luaH_setnum(L, h, last--), val);
++ luaC_barriert(L, h, val);
++ }
++ continue;
++ }
++ case OP_CLOSE: {
++ luaF_close(L, ra);
++ continue;
++ }
++ case OP_CLOSURE: {
++ Proto *p;
++ Closure *ncl;
++ int nup, j;
++ p = cl->p->p[GETARG_Bx(i)];
++ nup = p->nups;
++ ncl = luaF_newLclosure(L, nup, cl->env);
++ ncl->l.p = p;
++ for (j=0; j<nup; j++, pc++) {
++ if (GET_OPCODE(*pc) == OP_GETUPVAL)
++ ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
++ else {
++ lua_assert(GET_OPCODE(*pc) == OP_MOVE);
++ ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
++ }
++ }
++ setclvalue(L, ra, ncl);
++ Protect(luaC_checkGC(L));
++ continue;
++ }
++ case OP_VARARG: {
++ int b = GETARG_B(i) - 1;
++ int j;
++ CallInfo *ci = L->ci;
++ int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
++ if (b == LUA_MULTRET) {
++ Protect(luaD_checkstack(L, n));
++ ra = RA(i); /* previous call may change the stack */
++ b = n;
++ L->top = ra + n;
++ }
++ for (j = 0; j < b; j++) {
++ if (j < n) {
++ setobjs2s(L, ra + j, ci->base - n + j);
++ }
++ else {
++ setnilvalue(ra + j);
++ }
++ }
++ continue;
++ }
++ }
++ }
++}
++
+--- /dev/null
++++ b/extensions/LUA/lua/lvm.h
+@@ -0,0 +1,36 @@
++/*
++** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $
++** Lua virtual machine
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lvm_h
++#define lvm_h
++
++
++#include "ldo.h"
++#include "lobject.h"
++#include "ltm.h"
++
++
++#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
++
++#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
++ (((o) = luaV_tonumber(o,n)) != NULL))
++
++#define equalobj(L,o1,o2) \
++ (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
++
++
++LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
++LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
++LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
++LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
++LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
++ StkId val);
++LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
++ StkId val);
++LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
++LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/lua/lzio.c
+@@ -0,0 +1,81 @@
++/*
++** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
++** a generic input stream interface
++** See Copyright Notice in lua.h
++*/
++
++#include <string.h>
++
++#define lzio_c
++#define LUA_CORE
++
++#include "lua.h"
++
++#include "llimits.h"
++#include "lmem.h"
++#include "lstate.h"
++#include "lzio.h"
++
++
++int luaZ_fill (ZIO *z) {
++ size_t size;
++ lua_State *L = z->L;
++ const char *buff;
++ lua_unlock(L);
++ buff = z->reader(L, z->data, &size);
++ lua_lock(L);
++ if (buff == NULL || size == 0) return EOZ;
++ z->n = size - 1;
++ z->p = buff;
++ return char2int(*(z->p++));
++}
++
++
++int luaZ_lookahead (ZIO *z) {
++ if (z->n == 0) {
++ if (luaZ_fill(z) == EOZ)
++ return EOZ;
++ else {
++ z->n++; /* luaZ_fill removed first byte; put back it */
++ z->p--;
++ }
++ }
++ return char2int(*z->p);
++}
++
++
++void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
++ z->L = L;
++ z->reader = reader;
++ z->data = data;
++ z->n = 0;
++ z->p = NULL;
++}
++
++
++/* --------------------------------------------------------------- read --- */
++size_t luaZ_read (ZIO *z, void *b, size_t n) {
++ while (n) {
++ size_t m;
++ if (luaZ_lookahead(z) == EOZ)
++ return n; /* return number of missing bytes */
++ m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
++ memcpy(b, z->p, m);
++ z->n -= m;
++ z->p += m;
++ b = (char *)b + m;
++ n -= m;
++ }
++ return 0;
++}
++
++/* ------------------------------------------------------------------------ */
++char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
++ if (n > buff->buffsize) {
++ if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
++ luaZ_resizebuffer(L, buff, n);
++ }
++ return buff->buffer;
++}
++
++
+--- /dev/null
++++ b/extensions/LUA/lua/lzio.h
+@@ -0,0 +1,67 @@
++/*
++** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $
++** Buffered streams
++** See Copyright Notice in lua.h
++*/
++
++
++#ifndef lzio_h
++#define lzio_h
++
++#include "lua.h"
++
++#include "lmem.h"
++
++
++#define EOZ (-1) /* end of stream */
++
++typedef struct Zio ZIO;
++
++#define char2int(c) cast(int, cast(unsigned char, (c)))
++
++#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
++
++typedef struct Mbuffer {
++ char *buffer;
++ size_t n;
++ size_t buffsize;
++} Mbuffer;
++
++#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
++
++#define luaZ_buffer(buff) ((buff)->buffer)
++#define luaZ_sizebuffer(buff) ((buff)->buffsize)
++#define luaZ_bufflen(buff) ((buff)->n)
++
++#define luaZ_resetbuffer(buff) ((buff)->n = 0)
++
++
++#define luaZ_resizebuffer(L, buff, size) \
++ (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
++ (buff)->buffsize = size)
++
++#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
++
++
++LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
++LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
++ void *data);
++LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
++LUAI_FUNC int luaZ_lookahead (ZIO *z);
++
++
++
++/* --------- Private Part ------------------ */
++
++struct Zio {
++ size_t n; /* bytes still unread */
++ const char *p; /* current position in buffer */
++ lua_Reader reader;
++ void* data; /* additional data */
++ lua_State *L; /* Lua state (for reader) */
++};
++
++
++LUAI_FUNC int luaZ_fill (ZIO *z);
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/Makefile
+@@ -0,0 +1,389 @@
++# Makefile.in generated by automake 1.11.1 from Makefile.am.
++# extensions/LUA/Makefile. Generated from Makefile.in by configure.
++
++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
++# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
++# Inc.
++# This Makefile.in is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++# PARTICULAR PURPOSE.
++
++
++
++# -*- Makefile -*-
++# AUTOMAKE
++
++pkgdatadir = $(datadir)/xtables-addons
++pkgincludedir = $(includedir)/xtables-addons
++pkglibdir = $(libdir)/xtables-addons
++pkglibexecdir = $(libexecdir)/xtables-addons
++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
++install_sh_DATA = $(install_sh) -c -m 644
++install_sh_PROGRAM = $(install_sh) -c
++install_sh_SCRIPT = $(install_sh) -c
++INSTALL_HEADER = $(INSTALL_DATA)
++transform = $(program_transform_name)
++NORMAL_INSTALL = :
++PRE_INSTALL = :
++POST_INSTALL = :
++NORMAL_UNINSTALL = :
++PRE_UNINSTALL = :
++POST_UNINSTALL = :
++build_triplet = i686-pc-linux-gnu
++host_triplet = i686-pc-linux-gnu
++DIST_COMMON = $(srcdir)/../../Makefile.extra $(srcdir)/Makefile.am \
++ $(srcdir)/Makefile.in
++subdir = extensions/LUA
++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
++am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
++ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
++ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
++ $(top_srcdir)/configure.ac
++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
++ $(ACLOCAL_M4)
++mkinstalldirs = $(install_sh) -d
++CONFIG_HEADER = $(top_builddir)/config.h
++CONFIG_CLEAN_FILES =
++CONFIG_CLEAN_VPATH_FILES =
++SOURCES =
++DIST_SOURCES =
++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
++ACLOCAL = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run aclocal-1.11
++AMTAR = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run tar
++AR = ar
++AUTOCONF = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run autoconf
++AUTOHEADER = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run autoheader
++AUTOMAKE = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run automake-1.11
++AWK = mawk
++CC = gcc
++CCDEPMODE = depmode=gcc3
++CFLAGS = -g -O2
++CPP = gcc -E
++CPPFLAGS =
++CYGPATH_W = echo
++DEFS = -DHAVE_CONFIG_H
++DEPDIR = .deps
++DSYMUTIL =
++DUMPBIN =
++ECHO_C =
++ECHO_N = -n
++ECHO_T =
++EGREP = /bin/grep -E
++EXEEXT =
++FGREP = /bin/grep -F
++GREP = /bin/grep
++INSTALL = /usr/bin/install -c
++INSTALL_DATA = ${INSTALL} -m 644
++INSTALL_PROGRAM = ${INSTALL}
++INSTALL_SCRIPT = ${INSTALL}
++INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
++LD = /usr/bin/ld
++LDFLAGS =
++LIBOBJS =
++LIBS =
++LIBTOOL = $(SHELL) $(top_builddir)/libtool
++LIPO =
++LN_S = ln -s
++LTLIBOBJS =
++MAKEINFO = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run makeinfo
++MKDIR_P = /bin/mkdir -p
++NM = /usr/bin/nm -B
++NMEDIT =
++OBJDUMP = objdump
++OBJEXT = o
++OTOOL =
++OTOOL64 =
++PACKAGE = xtables-addons
++PACKAGE_BUGREPORT =
++PACKAGE_NAME = xtables-addons
++PACKAGE_STRING = xtables-addons 1.21
++PACKAGE_TARNAME = xtables-addons
++PACKAGE_URL =
++PACKAGE_VERSION = 1.21
++PATH_SEPARATOR = :
++PKG_CONFIG = /usr/bin/pkg-config
++RANLIB = ranlib
++SED = /bin/sed
++SET_MAKE =
++SHELL = /bin/bash
++STRIP = strip
++VERSION = 1.21
++abs_builddir = /home/andre/Dropbox/xtables-addons/extensions/LUA
++abs_srcdir = /home/andre/Dropbox/xtables-addons/extensions/LUA
++abs_top_builddir = /home/andre/Dropbox/xtables-addons
++abs_top_srcdir = /home/andre/Dropbox/xtables-addons
++ac_ct_CC = gcc
++ac_ct_DUMPBIN =
++am__include = include
++am__leading_dot = .
++am__quote =
++am__tar = ${AMTAR} chof - "$$tardir"
++am__untar = ${AMTAR} xf -
++bindir = ${exec_prefix}/bin
++build = i686-pc-linux-gnu
++build_alias =
++build_cpu = i686
++build_os = linux-gnu
++build_vendor = pc
++builddir = .
++datadir = ${datarootdir}
++datarootdir = ${prefix}/share
++docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
++dvidir = ${docdir}
++exec_prefix = ${prefix}
++host = i686-pc-linux-gnu
++host_alias =
++host_cpu = i686
++host_os = linux-gnu
++host_vendor = pc
++htmldir = ${docdir}
++includedir = ${prefix}/include
++infodir = ${datarootdir}/info
++install_sh = ${SHELL} /home/andre/Dropbox/xtables-addons/install-sh
++kbuilddir = /lib/modules/2.6.33-020633-generic/build
++kinclude_CFLAGS = -I /lib/modules/2.6.33-020633-generic/build/include
++ksourcedir =
++libdir = ${exec_prefix}/lib
++libexecdir = ${exec_prefix}/libexec
++libxtables_CFLAGS =
++libxtables_LIBS = -L/lib -lxtables
++localedir = ${datarootdir}/locale
++localstatedir = ${prefix}/var
++lt_ECHO = echo
++mandir = ${datarootdir}/man
++mkdir_p = /bin/mkdir -p
++oldincludedir = /usr/include
++pdfdir = ${docdir}
++prefix = /usr/local
++program_transform_name = s,x,x,
++psdir = ${docdir}
++regular_CFLAGS = -D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes -Winline -pipe -DXTABLES_LIBDIR=\"${xtlibdir}\"
++sbindir = ${exec_prefix}/sbin
++sharedstatedir = ${prefix}/com
++srcdir = .
++sysconfdir = ${prefix}/etc
++target_alias =
++top_build_prefix = ../../
++top_builddir = ../..
++top_srcdir = ../..
++xtlibdir = ${libexecdir}/xtables
++XA_SRCDIR = ${srcdir}
++XA_TOPSRCDIR = ${top_srcdir}
++XA_ABSTOPSRCDIR = ${abs_top_srcdir}
++_mcall = -f ${top_builddir}/Makefile.iptrules
++all: all-am
++
++.SUFFIXES:
++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/../../Makefile.extra $(am__configure_deps)
++ @for dep in $?; do \
++ case '$(am__configure_deps)' in \
++ *$$dep*) \
++ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
++ && { if test -f $@; then exit 0; else break; fi; }; \
++ exit 1;; \
++ esac; \
++ done; \
++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/LUA/Makefile'; \
++ $(am__cd) $(top_srcdir) && \
++ $(AUTOMAKE) --foreign extensions/LUA/Makefile
++.PRECIOUS: Makefile
++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
++ @case '$?' in \
++ *config.status*) \
++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
++ *) \
++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
++ esac;
++
++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++
++$(top_srcdir)/configure: $(am__configure_deps)
++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(ACLOCAL_M4): $(am__aclocal_m4_deps)
++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(am__aclocal_m4_deps):
++
++mostlyclean-libtool:
++ -rm -f *.lo
++
++clean-libtool:
++ -rm -rf .libs _libs
++tags: TAGS
++TAGS:
++
++ctags: CTAGS
++CTAGS:
++
++
++distdir: $(DISTFILES)
++ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++ list='$(DISTFILES)'; \
++ dist_files=`for file in $$list; do echo $$file; done | \
++ sed -e "s|^$$srcdirstrip/||;t" \
++ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
++ case $$dist_files in \
++ */*) $(MKDIR_P) `echo "$$dist_files" | \
++ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
++ sort -u` ;; \
++ esac; \
++ for file in $$dist_files; do \
++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
++ if test -d $$d/$$file; then \
++ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
++ if test -d "$(distdir)/$$file"; then \
++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++ fi; \
++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
++ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++ fi; \
++ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
++ else \
++ test -f "$(distdir)/$$file" \
++ || cp -p $$d/$$file "$(distdir)/$$file" \
++ || exit 1; \
++ fi; \
++ done
++check-am: all-am
++check: check-am
++all-am: Makefile all-local
++installdirs:
++install: install-am
++install-exec: install-exec-am
++install-data: install-data-am
++uninstall: uninstall-am
++
++install-am: all-am
++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
++
++installcheck: installcheck-am
++install-strip:
++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++ `test -z '$(STRIP)' || \
++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
++mostlyclean-generic:
++
++clean-generic:
++
++distclean-generic:
++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
++ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
++
++maintainer-clean-generic:
++ @echo "This command is intended for maintainers to use"
++ @echo "it deletes files that may require special tools to rebuild."
++clean: clean-am
++
++clean-am: clean-generic clean-libtool clean-local mostlyclean-am
++
++distclean: distclean-am
++ -rm -f Makefile
++distclean-am: clean-am distclean-generic
++
++dvi: dvi-am
++
++dvi-am:
++
++html: html-am
++
++html-am:
++
++info: info-am
++
++info-am:
++
++install-data-am:
++
++install-dvi: install-dvi-am
++
++install-dvi-am:
++
++install-exec-am: install-exec-local
++
++install-html: install-html-am
++
++install-html-am:
++
++install-info: install-info-am
++
++install-info-am:
++
++install-man:
++
++install-pdf: install-pdf-am
++
++install-pdf-am:
++
++install-ps: install-ps-am
++
++install-ps-am:
++
++installcheck-am:
++
++maintainer-clean: maintainer-clean-am
++ -rm -f Makefile
++maintainer-clean-am: distclean-am maintainer-clean-generic
++
++mostlyclean: mostlyclean-am
++
++mostlyclean-am: mostlyclean-generic mostlyclean-libtool
++
++pdf: pdf-am
++
++pdf-am:
++
++ps: ps-am
++
++ps-am:
++
++uninstall-am:
++
++.MAKE: install-am install-strip
++
++.PHONY: all all-am all-local check check-am clean clean-generic \
++ clean-libtool clean-local distclean distclean-generic \
++ distclean-libtool distdir dvi dvi-am html html-am info info-am \
++ install install-am install-data install-data-am install-dvi \
++ install-dvi-am install-exec install-exec-am install-exec-local \
++ install-html install-html-am install-info install-info-am \
++ install-man install-pdf install-pdf-am install-ps \
++ install-ps-am install-strip installcheck installcheck-am \
++ installdirs maintainer-clean maintainer-clean-generic \
++ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
++ ps ps-am uninstall uninstall-am
++
++export XA_SRCDIR
++export XA_TOPSRCDIR
++export XA_ABSTOPSRCDIR
++
++all-local: user-all-local
++
++install-exec-local: user-install-local
++
++clean-local: user-clean-local
++
++user-all-local:
++ ${MAKE} ${_mcall} all;
++
++# Have no user-install-data-local ATM
++user-install-local: user-install-exec-local
++
++user-install-exec-local:
++ ${MAKE} ${_mcall} install;
++
++user-clean-local:
++ ${MAKE} ${_mcall} clean;
++
++# Tell versions [3.59,3.63) of GNU make to not export all variables.
++# Otherwise a system limit (for SysV at least) may be exceeded.
++.NOEXPORT:
++
+--- /dev/null
++++ b/extensions/LUA/Makefile.am
+@@ -0,0 +1 @@
++include ../../Makefile.extra
+--- /dev/null
++++ b/extensions/LUA/Makefile.in
+@@ -0,0 +1,389 @@
++# Makefile.in generated by automake 1.11.1 from Makefile.am.
++# @configure_input@
++
++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
++# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
++# Inc.
++# This Makefile.in is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++# PARTICULAR PURPOSE.
++
++@SET_MAKE@
++
++# -*- Makefile -*-
++# AUTOMAKE
++VPATH = @srcdir@
++pkgdatadir = $(datadir)/@PACKAGE@
++pkgincludedir = $(includedir)/@PACKAGE@
++pkglibdir = $(libdir)/@PACKAGE@
++pkglibexecdir = $(libexecdir)/@PACKAGE@
++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
++install_sh_DATA = $(install_sh) -c -m 644
++install_sh_PROGRAM = $(install_sh) -c
++install_sh_SCRIPT = $(install_sh) -c
++INSTALL_HEADER = $(INSTALL_DATA)
++transform = $(program_transform_name)
++NORMAL_INSTALL = :
++PRE_INSTALL = :
++POST_INSTALL = :
++NORMAL_UNINSTALL = :
++PRE_UNINSTALL = :
++POST_UNINSTALL = :
++build_triplet = @build@
++host_triplet = @host@
++DIST_COMMON = $(srcdir)/../../Makefile.extra $(srcdir)/Makefile.am \
++ $(srcdir)/Makefile.in
++subdir = extensions/LUA
++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
++am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
++ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
++ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
++ $(top_srcdir)/configure.ac
++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
++ $(ACLOCAL_M4)
++mkinstalldirs = $(install_sh) -d
++CONFIG_HEADER = $(top_builddir)/config.h
++CONFIG_CLEAN_FILES =
++CONFIG_CLEAN_VPATH_FILES =
++SOURCES =
++DIST_SOURCES =
++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
++ACLOCAL = @ACLOCAL@
++AMTAR = @AMTAR@
++AR = @AR@
++AUTOCONF = @AUTOCONF@
++AUTOHEADER = @AUTOHEADER@
++AUTOMAKE = @AUTOMAKE@
++AWK = @AWK@
++CC = @CC@
++CCDEPMODE = @CCDEPMODE@
++CFLAGS = @CFLAGS@
++CPP = @CPP@
++CPPFLAGS = @CPPFLAGS@
++CYGPATH_W = @CYGPATH_W@
++DEFS = @DEFS@
++DEPDIR = @DEPDIR@
++DSYMUTIL = @DSYMUTIL@
++DUMPBIN = @DUMPBIN@
++ECHO_C = @ECHO_C@
++ECHO_N = @ECHO_N@
++ECHO_T = @ECHO_T@
++EGREP = @EGREP@
++EXEEXT = @EXEEXT@
++FGREP = @FGREP@
++GREP = @GREP@
++INSTALL = @INSTALL@
++INSTALL_DATA = @INSTALL_DATA@
++INSTALL_PROGRAM = @INSTALL_PROGRAM@
++INSTALL_SCRIPT = @INSTALL_SCRIPT@
++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
++LD = @LD@
++LDFLAGS = @LDFLAGS@
++LIBOBJS = @LIBOBJS@
++LIBS = @LIBS@
++LIBTOOL = @LIBTOOL@
++LIPO = @LIPO@
++LN_S = @LN_S@
++LTLIBOBJS = @LTLIBOBJS@
++MAKEINFO = @MAKEINFO@
++MKDIR_P = @MKDIR_P@
++NM = @NM@
++NMEDIT = @NMEDIT@
++OBJDUMP = @OBJDUMP@
++OBJEXT = @OBJEXT@
++OTOOL = @OTOOL@
++OTOOL64 = @OTOOL64@
++PACKAGE = @PACKAGE@
++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
++PACKAGE_NAME = @PACKAGE_NAME@
++PACKAGE_STRING = @PACKAGE_STRING@
++PACKAGE_TARNAME = @PACKAGE_TARNAME@
++PACKAGE_URL = @PACKAGE_URL@
++PACKAGE_VERSION = @PACKAGE_VERSION@
++PATH_SEPARATOR = @PATH_SEPARATOR@
++PKG_CONFIG = @PKG_CONFIG@
++RANLIB = @RANLIB@
++SED = @SED@
++SET_MAKE = @SET_MAKE@
++SHELL = @SHELL@
++STRIP = @STRIP@
++VERSION = @VERSION@
++abs_builddir = @abs_builddir@
++abs_srcdir = @abs_srcdir@
++abs_top_builddir = @abs_top_builddir@
++abs_top_srcdir = @abs_top_srcdir@
++ac_ct_CC = @ac_ct_CC@
++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
++am__include = @am__include@
++am__leading_dot = @am__leading_dot@
++am__quote = @am__quote@
++am__tar = @am__tar@
++am__untar = @am__untar@
++bindir = @bindir@
++build = @build@
++build_alias = @build_alias@
++build_cpu = @build_cpu@
++build_os = @build_os@
++build_vendor = @build_vendor@
++builddir = @builddir@
++datadir = @datadir@
++datarootdir = @datarootdir@
++docdir = @docdir@
++dvidir = @dvidir@
++exec_prefix = @exec_prefix@
++host = @host@
++host_alias = @host_alias@
++host_cpu = @host_cpu@
++host_os = @host_os@
++host_vendor = @host_vendor@
++htmldir = @htmldir@
++includedir = @includedir@
++infodir = @infodir@
++install_sh = @install_sh@
++kbuilddir = @kbuilddir@
++kinclude_CFLAGS = @kinclude_CFLAGS@
++ksourcedir = @ksourcedir@
++libdir = @libdir@
++libexecdir = @libexecdir@
++libxtables_CFLAGS = @libxtables_CFLAGS@
++libxtables_LIBS = @libxtables_LIBS@
++localedir = @localedir@
++localstatedir = @localstatedir@
++lt_ECHO = @lt_ECHO@
++mandir = @mandir@
++mkdir_p = @mkdir_p@
++oldincludedir = @oldincludedir@
++pdfdir = @pdfdir@
++prefix = @prefix@
++program_transform_name = @program_transform_name@
++psdir = @psdir@
++regular_CFLAGS = @regular_CFLAGS@
++sbindir = @sbindir@
++sharedstatedir = @sharedstatedir@
++srcdir = @srcdir@
++sysconfdir = @sysconfdir@
++target_alias = @target_alias@
++top_build_prefix = @top_build_prefix@
++top_builddir = @top_builddir@
++top_srcdir = @top_srcdir@
++xtlibdir = @xtlibdir@
++XA_SRCDIR = ${srcdir}
++XA_TOPSRCDIR = ${top_srcdir}
++XA_ABSTOPSRCDIR = ${abs_top_srcdir}
++_mcall = -f ${top_builddir}/Makefile.iptrules
++all: all-am
++
++.SUFFIXES:
++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/../../Makefile.extra $(am__configure_deps)
++ @for dep in $?; do \
++ case '$(am__configure_deps)' in \
++ *$$dep*) \
++ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
++ && { if test -f $@; then exit 0; else break; fi; }; \
++ exit 1;; \
++ esac; \
++ done; \
++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/LUA/Makefile'; \
++ $(am__cd) $(top_srcdir) && \
++ $(AUTOMAKE) --foreign extensions/LUA/Makefile
++.PRECIOUS: Makefile
++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
++ @case '$?' in \
++ *config.status*) \
++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
++ *) \
++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
++ esac;
++
++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++
++$(top_srcdir)/configure: $(am__configure_deps)
++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(ACLOCAL_M4): $(am__aclocal_m4_deps)
++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
++$(am__aclocal_m4_deps):
++
++mostlyclean-libtool:
++ -rm -f *.lo
++
++clean-libtool:
++ -rm -rf .libs _libs
++tags: TAGS
++TAGS:
++
++ctags: CTAGS
++CTAGS:
++
++
++distdir: $(DISTFILES)
++ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
++ list='$(DISTFILES)'; \
++ dist_files=`for file in $$list; do echo $$file; done | \
++ sed -e "s|^$$srcdirstrip/||;t" \
++ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
++ case $$dist_files in \
++ */*) $(MKDIR_P) `echo "$$dist_files" | \
++ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
++ sort -u` ;; \
++ esac; \
++ for file in $$dist_files; do \
++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
++ if test -d $$d/$$file; then \
++ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
++ if test -d "$(distdir)/$$file"; then \
++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++ fi; \
++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
++ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
++ fi; \
++ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
++ else \
++ test -f "$(distdir)/$$file" \
++ || cp -p $$d/$$file "$(distdir)/$$file" \
++ || exit 1; \
++ fi; \
++ done
++check-am: all-am
++check: check-am
++all-am: Makefile all-local
++installdirs:
++install: install-am
++install-exec: install-exec-am
++install-data: install-data-am
++uninstall: uninstall-am
++
++install-am: all-am
++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
++
++installcheck: installcheck-am
++install-strip:
++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
++ `test -z '$(STRIP)' || \
++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
++mostlyclean-generic:
++
++clean-generic:
++
++distclean-generic:
++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
++ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
++
++maintainer-clean-generic:
++ @echo "This command is intended for maintainers to use"
++ @echo "it deletes files that may require special tools to rebuild."
++clean: clean-am
++
++clean-am: clean-generic clean-libtool clean-local mostlyclean-am
++
++distclean: distclean-am
++ -rm -f Makefile
++distclean-am: clean-am distclean-generic
++
++dvi: dvi-am
++
++dvi-am:
++
++html: html-am
++
++html-am:
++
++info: info-am
++
++info-am:
++
++install-data-am:
++
++install-dvi: install-dvi-am
++
++install-dvi-am:
++
++install-exec-am: install-exec-local
++
++install-html: install-html-am
++
++install-html-am:
++
++install-info: install-info-am
++
++install-info-am:
++
++install-man:
++
++install-pdf: install-pdf-am
++
++install-pdf-am:
++
++install-ps: install-ps-am
++
++install-ps-am:
++
++installcheck-am:
++
++maintainer-clean: maintainer-clean-am
++ -rm -f Makefile
++maintainer-clean-am: distclean-am maintainer-clean-generic
++
++mostlyclean: mostlyclean-am
++
++mostlyclean-am: mostlyclean-generic mostlyclean-libtool
++
++pdf: pdf-am
++
++pdf-am:
++
++ps: ps-am
++
++ps-am:
++
++uninstall-am:
++
++.MAKE: install-am install-strip
++
++.PHONY: all all-am all-local check check-am clean clean-generic \
++ clean-libtool clean-local distclean distclean-generic \
++ distclean-libtool distdir dvi dvi-am html html-am info info-am \
++ install install-am install-data install-data-am install-dvi \
++ install-dvi-am install-exec install-exec-am install-exec-local \
++ install-html install-html-am install-info install-info-am \
++ install-man install-pdf install-pdf-am install-ps \
++ install-ps-am install-strip installcheck installcheck-am \
++ installdirs maintainer-clean maintainer-clean-generic \
++ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
++ ps ps-am uninstall uninstall-am
++
++export XA_SRCDIR
++export XA_TOPSRCDIR
++export XA_ABSTOPSRCDIR
++
++all-local: user-all-local
++
++install-exec-local: user-install-local
++
++clean-local: user-clean-local
++
++user-all-local:
++ ${MAKE} ${_mcall} all;
++
++# Have no user-install-data-local ATM
++user-install-local: user-install-exec-local
++
++user-install-exec-local:
++ ${MAKE} ${_mcall} install;
++
++user-clean-local:
++ ${MAKE} ${_mcall} clean;
++
++# Tell versions [3.59,3.63) of GNU make to not export all variables.
++# Otherwise a system limit (for SysV at least) may be exceeded.
++.NOEXPORT:
++
+--- /dev/null
++++ b/extensions/LUA/Mbuild
+@@ -0,0 +1,3 @@
++# -*- Makefile -*-
++
++obj-${build_LUA} += libxt_LUA.so
+--- /dev/null
++++ b/extensions/LUA/nf_lua.c
+@@ -0,0 +1,64 @@
++#if defined(__KERNEL__)
++
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/timer.h>
++#include <linux/random.h>
++#include <linux/netfilter/x_tables.h>
++
++#endif
++
++#include "lua.h"
++#include "lobject.h" /*sizeof(udata) */
++#include "lauxlib.h"
++#include "controller.h"
++
++#if defined(__KERNEL__) /* reachs until luaopen_nflib */
++
++
++static int32_t nf_get_random(lua_State *L)
++{
++ uint32_t rand = 0;
++
++ get_random_bytes(&rand, sizeof(uint32_t ));
++ lua_pushnumber(L, rand);
++ return 1;
++}
++
++static int32_t nf_get_time(lua_State *L)
++{
++ lua_pushnumber(L, jiffies_to_msecs(jiffies_64));
++ return 1;
++}
++
++static const struct luaL_Reg nf_lua_lib_f [] = {
++ { "get_random", nf_get_random },
++ { "get_time", nf_get_time },
++ { NULL, NULL }
++};
++
++void luaopen_nflib(lua_State *L)
++{
++ int32_t top;
++
++ luaL_register(L, NETFILTER_LIB, nf_lua_lib_f);
++ lua_pop(L, 1);
++
++ /* registering verdicts inside the _G */
++ lua_getglobal(L, "_G");
++ top = lua_gettop(L);
++
++ lua_pushinteger(L, XT_CONTINUE);
++ lua_setfield(L, top, "XT_CONTINUE"); /* continiue with next rule */
++
++ lua_pushinteger(L, NF_DROP);
++ lua_setfield(L, top, "NF_DROP"); /* stop traversal in the current table hook and drop packet */
++
++ lua_pushinteger(L, NF_ACCEPT);
++ lua_setfield(L, top, "NF_ACCEPT"); /* stop traversal in the current table hook and accept packet */
++
++ lua_pop(L, 1); /* pop _G */
++}
++
++#endif
+--- /dev/null
++++ b/extensions/LUA/prot_buf_dynamic.c
+@@ -0,0 +1,486 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "controller.h"
++
++
++
++struct protocol_buf * dyn_prot_buf_array[MAX_NR_OF_DYN_PROT_BUFS] = { NULL };
++
++
++/* LUA_API: the function 'field_dynamic_setter' acts as a wrapper around
++ * a given Lua field setter function of a dynamic protocol buffer. The
++ * string containing the lua function name was piggybacked in the 'set'
++ * member of the protocol_field. We call this function passing the actual
++ * segment as byte array and the set value.
++ *
++ * Paramters:
++ * 1. lua_packet_segment (implicit)
++ * 2. some lua value
++ *
++ * Upvalues:
++ * 1. pointer to the protocol buffer
++ * 2. field index
++ *
++ * Returns:
++ * 1. true or false if the 'set' was successful
++ */
++int32_t field_dynamic_setter(lua_State *L)
++{
++ size_t nbytes;
++ lua_packet_segment * array;
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ int32_t field_index = lua_tointeger(L, lua_upvalueindex(2));
++
++ /* the function name is piggybacked as a string */
++ lua_getglobal(L, (char *)prot_buf->protocol_fields[field_index].set);
++ if (!lua_isfunction(L, -1)) {
++ lua_pushboolean(L, 0);
++ return 1;
++ }
++
++ nbytes = sizeof(lua_packet_segment) + seg->length * sizeof(uint8_t);
++ array = (lua_packet_segment *)lua_newuserdata(L, nbytes);
++ array->length = seg->length;
++ array->start = seg->start + seg->offset;
++ array->changes = NULL;
++
++ luaL_getmetatable(L, LUA_BYTE_ARRAY);
++ lua_setmetatable(L, -2);
++ lua_pushvalue(L, 2); /* push value to set */
++ if (lua_pcall(L, 2, 1, 0) != 0) {
++ pr_debug("Error: %s \n", lua_tostring(L, -1));
++ lua_pop(L, 1);
++ lua_pushboolean(L, 0);
++ }
++ return 1;
++}
++
++/* LUA_API: the function 'field_dynamic_getter' acts as a wrapper around
++ * a given Lua field getter function of a dynamic protocol buffer. The
++ * string containing the lua function name was piggybacked in the 'get'
++ * member of the protocol_field. We call this function passing the actual
++ * segment as byte array.
++ *
++ * Paramters:
++ * 1. lua_packet_segment (implicit)
++ *
++ * Upvalues:
++ * 1. pointer to the protocol buffer
++ * 2. field index
++ *
++ * Returns:
++ * 1. true or false if the 'get' was successful
++ */
++int32_t field_dynamic_getter(lua_State *L)
++{
++ size_t nbytes;
++ lua_packet_segment * array;
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ int32_t field_index = lua_tointeger(L, lua_upvalueindex(2));
++
++ /* the function name is piggybacked as a string */
++ lua_getglobal(L, (char *)prot_buf->protocol_fields[field_index].get);
++ if (!lua_isfunction(L, -1)) {
++ lua_pushboolean(L, 0);
++ return 1;
++ }
++
++ nbytes = sizeof(lua_packet_segment) + seg->length * sizeof(uint8_t);
++ array = (lua_packet_segment *)lua_newuserdata(L, nbytes);
++ array->length = seg->length;
++ array->start = seg->start + seg->offset;
++ array->changes = NULL;
++
++ luaL_getmetatable(L, LUA_BYTE_ARRAY);
++ lua_setmetatable(L, -2);
++ if (lua_pcall(L, 1, 1, 0) != 0) {
++ pr_debug("Error: %s \n", luaL_checkstring(L, -1));
++ lua_pop(L, 1);
++ lua_pushboolean(L, 0);
++ }
++ return 1;
++}
++
++/* LUA_API: the function 'has_protocol_dynamic' acts as a wrapper around
++ * a given lua has_protocol function of a dynamic protocol buffer. The
++ * string containing the lua function name was piggybacked in the 'has_protocol'
++ * member of the protocol_buffer. We call this function passing the actual
++ * segment.
++ *
++ * Paramters:
++ * 1. lua_packet_segment
++ * 2. protocol type
++ *
++ * Returns:
++ * 1. true or false if the payload field contains the given protocol
++ */
++int32_t has_protocol_dynamic(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t type)
++{
++ lua_packet_segment *seg_new;
++ int32_t res = 0;
++
++ /* the function name is piggybacked as a string */
++ lua_getglobal(L, (char *)prot_buf->has_protocol);
++ seg_new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
++ seg_new->start = seg->start;
++ seg_new->offset = seg->offset;
++ seg_new->length = seg->length;
++ seg_new->changes = NULL;
++ luaL_getmetatable(L, prot_buf->name);
++ lua_setmetatable(L, -2);
++ lua_pushinteger(L, type); /* push the protocol type */
++ if (lua_pcall(L, 2, 1, 0) != 0) {
++ pr_debug("Error: %s \n", luaL_checkstring(L, -1));
++ lua_pop(L, 1);
++ return 0;
++ }
++ res = lua_toboolean(L, -1);
++ lua_pop(L, 1);
++
++ return res;
++}
++
++/* LUA_API: the function 'get_field_changes_dynamic' acts as a wrapper around
++ * a given lua get_field_changes function of a dynamic protocol buffer. The
++ * string containing the lua function name was piggybacked in the 'get_field_changes'
++ * member of the protocol_buffer. We call this function passing the actual
++ * segment. The lua function must return two lua table containing the offset
++ * and length changes (in bits).
++ *
++ * Paramters:
++ * 1. lua_packet_segment
++ *
++ * Returns:
++ * 1. new allocated field_changes struct
++ */
++struct field_changes * get_field_changes_dynamic(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment * seg)
++{
++ lua_packet_segment *seg_new;
++ struct field_changes * changes;
++ int32_t nr_of_changes, i;
++
++ lua_getglobal(L, (char *)prot_buf->get_field_changes);
++
++ seg_new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
++ seg_new->start = seg->start;
++ seg_new->offset = seg->offset;
++ seg_new->length = seg->length;
++ seg_new->changes = NULL;
++ luaL_getmetatable(L, prot_buf->name);
++ lua_setmetatable(L, -2);
++
++ if (lua_pcall(L, 1, 2, 0) != 0)
++ luaL_error(L, "inside get_field_changes_dynamic. %s\n", lua_tostring(L, -1));
++
++ /* the function call must return a table containing length changes */
++ luaL_checktype(L, -1, LUA_TTABLE);
++ /* the function call must return a table containing offset changes */
++ luaL_checktype(L, -2, LUA_TTABLE);
++ /* both tables have to be of same size */
++ if (lua_objlen(L, -1) != lua_objlen(L, -2))
++ luaL_error(L, "the provided tables are not of equal size");
++
++ nr_of_changes = lua_objlen(L, -1);
++ changes = get_allocated_field_changes(L, nr_of_changes);
++
++ /* loop over the tables */
++ for (i = 1; i < nr_of_changes; i++) {
++ lua_rawgeti(L, -1, i); /* push length value of field at index i */
++ changes->field_length_changes[i - 1] = luaL_checkinteger(L, -1);
++ lua_pop(L, 1); /* pop offset value */
++
++ lua_rawgeti(L, -2, i); /* push offset value of field at index i */
++ changes->field_offset_changes[i - 1] = luaL_checkinteger(L, -1);
++ lua_pop(L, 1); /* pop length value */
++ }
++
++ /* pop both tables */
++ lua_pop(L, 2);
++
++ return changes;
++}
++
++/* C_INT: 'get_free_protocol_index' is only used internally. This function
++ * gets a free slot inside the array holding all the protocol buffers.
++ * There are several ways to get to this information. In this case I take
++ * the way over the reflected array SUPPORTED_PROTOCOL_TABLE inside the
++ * Lua state. Since this function is called at laodtime, we do not have
++ * to care about performance.
++ */
++static int32_t get_free_protocol_index(lua_State *L)
++{
++ int32_t protocol_index;
++
++ lua_getglobal(L, SUPPORTED_PROTOCOL_TABLE);
++ protocol_index = lua_objlen(L, -1) + 1;
++ lua_pop(L, 1);
++ return protocol_index;
++}
++
++/* C_API: 'free_dynamic_prot_buf' frees the allocated memory of a given
++ * dynamic protocol buffer. this function is normally called inside a
++ * cleanup routine. Be aware, before running this function you must be
++ * sure that no references to the dynamic protocol buffers were available.
++ * It's recomended to close the Lua state before calling the function. */
++void free_dynamic_prot_buf(struct protocol_buf * prot_buf)
++{
++ struct protocol_field * field = prot_buf->protocol_fields;
++
++ for (; field->name != NULL; field++) {
++ if (field->get) kfree(field->get);
++ if (field->set) kfree(field->set);
++ if (field->name) kfree((char *)field->name);
++ }
++
++ if (prot_buf->payload_field) kfree(prot_buf->payload_field);
++ if (prot_buf->has_protocol) kfree(prot_buf->has_protocol);
++
++ if (prot_buf->get_field_changes) kfree(prot_buf->get_field_changes);
++ kfree((char *)prot_buf->name);
++ kfree(prot_buf);
++ return;
++}
++
++void cleanup_dynamic_prot_bufs(void)
++{
++ int32_t i;
++
++ for (i = 0; i < MAX_NR_OF_DYN_PROT_BUFS; i++) {
++ if (dyn_prot_buf_array[i]) {
++ free_dynamic_prot_buf(dyn_prot_buf_array[i]);
++ dyn_prot_buf_array[i] = NULL;
++ }
++ }
++ return;
++}
++
++
++/* C_INT: 'free_protocol_fields' is used internally as a helper function for
++ * 'register_dynamic_protbuf'. It is used when durin registration an error
++ * occurs and the afore allocated fields needed to be freed. */
++static inline void free_protocol_fields(struct protocol_field * prot_fields, int32_t i)
++{
++ struct protocol_field * f;
++
++ while (i >= 0) {
++ f = &prot_fields[i];
++ if (f->name) kfree((void *)f->name);
++ if (f->get) kfree((void *)f->get);
++ if (f->set) kfree((void *)f->set);
++ kfree((void *)f);
++ i--;
++ }
++}
++
++/* LUA_API: 'register_dynamic_protbuf' is called from within the Lua script.
++ * it takes a Lua table representing the dynamic protocol buffer as parameter.
++ * e.g.:
++ * eth_prot_buf = {
++ * name = "packet_eth_dyn",
++ * payload_field = "data",
++ * protocol_fields = {
++ * {"dmac", 0, 48, nil, nil },
++ * {"smac", 48, 48, nil, nil },
++ * {"type", 96, 16, nil, nil },
++ * {"data", 112, 0, nil, nil },
++ * },
++ * has_protocol = "eth_dyn_has_protocol",
++ * get_field_changes = "eth_dyn_get_field_changes"
++ * }
++ * register_dynamic_protbuf(eth_prot_buf)
++ *
++ * the table gets parsed and a new protocol_buf struct is allocated and
++ * initialized using 'register_protbuf', which is also used for the static
++ * protocol buffers. This enables an identical behavior like the static
++ * protocol buffers. The dynamic protocol buffers are not garbage collected,
++ * use 'free_dynamic_protbuf' to free them after closing the Lua state.
++ */
++static int32_t register_dynamic_protbuf(lua_State *L)
++{
++ struct protocol_buf *prot_buf;
++ struct protocol_field *field, sentinel = PROT_FIELD_SENTINEL;
++ int32_t nr_of_fields, i;
++
++ prot_buf = (struct protocol_buf *)kmalloc(sizeof(struct protocol_buf), GFP_KERNEL);
++ prot_buf->is_dynamic = 1;
++
++ /* check if parameter is a table */
++ luaL_checktype(L, 1, LUA_TTABLE);
++
++ /* initialize prot_buf.name */
++ lua_getfield(L, 1, "name");
++ prot_buf->name = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
++ strcpy((char *)prot_buf->name, luaL_checkstring(L, -1));
++ lua_pop(L, 1); /* pop res from lua_getfield */
++
++ /* check if protocol buffer is already registered */
++ lua_getglobal(L, prot_buf->name);
++ if (!lua_isnil(L, -1)) {
++ lua_pop(L, 1); /* pop res from lua_getglobal */
++ pr_debug("protocol_buf '%s' already registered.\n", prot_buf->name);
++ goto free_prot_buf;
++ }
++ lua_pop(L, 1); /* pop res from lua_getglobal */
++
++ /* initialize payload field */
++ lua_getfield(L, 1, "payload_field");
++ if (lua_isstring(L, -1)) {
++ prot_buf->payload_field = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
++ strcpy(prot_buf->payload_field, lua_tostring(L, -1));
++ }else
++ prot_buf->payload_field = NULL;
++ lua_pop(L, 1); /* pop res from lua_getfield */
++
++ /* initialize protocol_fields field*/
++ lua_getfield(L, 1, "protocol_fields");
++ if (!lua_istable(L, -1)) {
++ pr_debug("invalid protocol_fields table.\n");
++ goto err2;
++
++ }
++
++ nr_of_fields = lua_objlen(L, -1);
++ prot_buf->protocol_fields = (struct protocol_field *)kmalloc((nr_of_fields + 1) * sizeof(struct protocol_field), GFP_KERNEL);
++
++ for (i = 1; i <= nr_of_fields; i++) {
++ field = &prot_buf->protocol_fields[i - 1];
++ /* initialize protocol field */
++ lua_rawgeti(L, -1, i); /* push field-table */
++ if (!lua_istable(L, -1)) {
++ free_protocol_fields(prot_buf->protocol_fields, i);
++ pr_debug("invalid protocol_field at %i.\n", i);
++ goto err;
++ }
++
++ /* initialize protocol field name */
++ lua_rawgeti(L, -1, 1);
++ if (!lua_isstring(L, -1)) {
++ free_protocol_fields(prot_buf->protocol_fields, i);
++ pr_debug("invalid protocol_field name at %i.\n", i);
++ goto err;
++ }
++
++ field->name = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
++ strcpy((char*)field->name, lua_tostring(L, -1));
++ lua_pop(L, 1); /* pop field name */
++
++ /* initialize protocol field offset */
++ lua_rawgeti(L, -1, 2);
++ if (!lua_isnumber(L, -1)) {
++ free_protocol_fields(prot_buf->protocol_fields, i);
++ pr_debug("invalid protocol_field offset at %i.\n", i);
++ goto err;
++ }
++ field->offset = lua_tointeger(L, -1);
++ lua_pop(L, 1); /* pop field offset */
++
++ /* initialize protocol field length */
++ lua_rawgeti(L, -1, 3);
++ if (!lua_isnumber(L, -1)) {
++ free_protocol_fields(prot_buf->protocol_fields, i);
++ pr_debug("invalid protocol_field length at %i.\n", i);
++ goto err;
++ }
++ field->length = lua_tointeger(L, -1);
++ lua_pop(L, 1); /* pop field length */
++
++ /* initialize protocol field getter */
++ lua_rawgeti(L, -1, 4);
++ if (lua_isstring(L, -1)) {
++ field->get = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
++ strcpy((char *)field->get, lua_tostring(L, -1)); /* the get-wrapper knows about the piggybacked string */
++ }else
++ field->get = NULL;
++ lua_pop(L, 1); /* pop field getter */
++
++ /* initialize protocol field setter */
++ lua_rawgeti(L, -1, 5);
++ if (lua_isstring(L, -1)) {
++ field->set = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
++ strcpy((char *)field->set, lua_tostring(L, -1)); /* the set-wrapper knows about the piggybacked string */
++ }else
++ field->set = NULL;
++ lua_pop(L, 1); /* pop field setter */
++
++ /* field initialization completed */
++ lua_pop(L, 1); /* pop field-table */
++ }
++
++ /* put sentinel at the end of protocol_fields */
++ memcpy(&prot_buf->protocol_fields[nr_of_fields], &sentinel, sizeof(sentinel));
++ lua_pop(L, 1); /* pop protocol-fields-table */
++
++ /* initialize has_protocol field */
++ lua_getfield(L, 1, "has_protocol");
++ if (lua_isstring(L, -1)) {
++ prot_buf->has_protocol = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
++ strcpy((char *)prot_buf->has_protocol, lua_tostring(L, -1)); /* the has_protocol-wrapper knows about the piggybacked string */
++ }else
++ prot_buf->has_protocol = NULL;
++ lua_pop(L, 1); /* pop has_protocol */
++
++ /* initialize get_field_changes field */
++ lua_getfield(L, 1, "get_field_changes");
++ if (lua_isstring(L, -1)) {
++ prot_buf->get_field_changes = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
++ strcpy((char *)prot_buf->get_field_changes, lua_tostring(L, -1)); /* the get_field_changes-wrapper knows about the piggybacked string */
++ }else
++ prot_buf->get_field_changes = NULL;
++ lua_pop(L, 1); /* pop get_field_changes */
++
++ /* Storing the pointer to the DYNAMIC protbuf within dyn_prot_buf_array, in order to free it at cleanup */
++ for (i = 0; i < MAX_NR_OF_DYN_PROT_BUFS; i++) {
++ if (!dyn_prot_buf_array[i]) {
++ dyn_prot_buf_array[i] = prot_buf;
++ break;
++ }else
++ goto err;
++ }
++
++ /* call the "common" register_protbuf */
++ register_protbuf(L, prot_buf, get_free_protocol_index(L)); /* register prot_buf as it is done with the static ones */
++
++ return 0;
++
++err:
++ kfree(prot_buf->protocol_fields);
++err2:
++ if (prot_buf->payload_field) kfree(prot_buf->payload_field);
++free_prot_buf:
++ kfree((void *)prot_buf->name);
++ kfree(prot_buf);
++
++ luaL_error(L, "one or more error happend while registering a dynamic protocol buffer, please consult the debug log");
++
++ return 0;
++
++}
++
++void luaopen_protbuf_dynamic(lua_State *L)
++{
++ lua_getglobal(L, "_G");
++ lua_pushcclosure(L, register_dynamic_protbuf, 0);
++ lua_setfield(L, -2, "register_dynamic_protbuf");
++ lua_pop(L, 1); /* pop _G */
++ return;
++}
+--- /dev/null
++++ b/extensions/LUA/prot_buf_ethernet.c
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "controller.h"
++
++
++static int32_t eth_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
++{
++ uint8_t *embedded_protocol = seg->start + seg->offset + 12 /*bytes*/;
++ unsigned short res = (unsigned short)((embedded_protocol[1] << CHAR_BIT) | (embedded_protocol[0] << CHAR_BIT));
++
++ switch (res) {
++ case 0x0800: /* 1: Internet Protocol (IP) */
++ if (protocol_type == PACKET_IP) return 1;
++ break;
++ default:
++ return 0;
++ }
++
++ return 0;
++}
++
++static const struct protocol_field eth_protocol_fields[] = {
++ /* field name offset length getter setter */
++ { "dmac", 0, 48, NULL, NULL },
++ { "smac", 48, 48, NULL, NULL },
++ { "type", 96, 16, NULL, NULL },
++ { "data", 112, 0, NULL, NULL },
++ PROT_FIELD_SENTINEL,
++};
++
++static const struct protocol_buf eth_protocol_buf = {
++ .is_dynamic = 0,
++ .name = LUA_PACKET_SEG_ETH,
++ .payload_field = "data",
++ .protocol_fields = (struct protocol_field *)&eth_protocol_fields,
++ .has_protocol = &eth_has_protocol,
++ .get_field_changes = NULL,
++};
++
++
++void luaopen_protbuf_eth(lua_State *L)
++{
++ register_protbuf(L, (struct protocol_buf *)&eth_protocol_buf, PACKET_ETH);
++}
+--- /dev/null
++++ b/extensions/LUA/prot_buf_helpers.c
+@@ -0,0 +1,216 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#if defined(__KERNEL__)
++#include <linux/netfilter_ipv4.h>
++#include <linux/slab.h> /* kmalloc */
++#endif
++
++#include "controller.h"
++
++int32_t get_header_size(struct protocol_buf * prot_buf)
++{
++ int32_t bit_counter = 0;
++ struct protocol_field * field = prot_buf->protocol_fields;
++
++ for (; field->name; field++)
++ bit_counter += field->length;
++
++ return bit_counter >> 3;
++}
++
++
++int32_t set_32_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ *(uint32_t *)(seg->start + seg->offset) = (uint32_t )htonl(luaL_checkinteger(L, 2));
++ return 0;
++}
++int32_t get_32_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ lua_pushinteger(L, ntohl(*((uint32_t *)(seg->start + seg->offset))));
++ return 1;
++}
++
++int32_t set_16_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ *(uint16_t *)(seg->start + seg->offset) = (uint16_t)htons(luaL_checkinteger(L, 2));
++ return 0;
++}
++int32_t get_16_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ lua_pushinteger(L, ntohs(*((uint16_t *)(seg->start + seg->offset))));
++ return 1;
++}
++
++int32_t set_lower_4_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++ uint8_t b = (uint8_t)luaL_checkinteger(L, 2) << 4;
++ uint8_t * pos = (uint8_t *)(seg->start + seg->offset);
++
++ *pos &= 0x0F; /* reset lower 4 bits*/
++ *pos |= b;
++
++ return 0;
++}
++
++int32_t get_lower_4_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ lua_pushinteger(L, (*(uint8_t *)(seg->start + seg->offset)) >> 4);
++ return 1;
++}
++
++int32_t set_upper_4_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++ uint8_t b = (uint8_t)luaL_checkinteger(L, 2) << 4;
++ uint8_t * pos = (uint8_t *)(seg->start + seg->offset);
++
++ *pos &= 0xF0; /* reset upper 4 bits*/
++ *pos |= (b >> 4);
++
++ return 0;
++}
++
++int32_t get_upper_4_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ lua_pushinteger(L, (*(uint8_t *)(seg->start + seg->offset)) & 0x0F);
++ return 1;
++}
++
++
++int32_t set_8_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ *(uint8_t *)(seg->start + seg->offset) = (uint8_t)luaL_checkinteger(L, 2);
++ return 0;
++}
++
++int32_t get_8_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ lua_pushinteger(L, *(uint8_t *)(seg->start + seg->offset));
++ return 1;
++}
++
++int32_t set_1_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++ unsigned long l = 0;
++
++ memcpy(&l, (seg->start + seg->offset), seg->length);
++ l |= (1 << ((CHAR_BIT * seg->length) - luaL_checkinteger(L, 2)));
++ memcpy((seg->start + seg->offset), &l, seg->length);
++
++ return 0;
++}
++
++int32_t get_1_bit_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++ unsigned long l = 0;
++ uint32_t bit = 0;
++
++ memcpy(&l, (seg->start + seg->offset), seg->length);
++ bit = l & (1 << ((CHAR_BIT * seg->length) - luaL_checkinteger(L, 2)));
++
++ lua_pushboolean(L, bit);
++ return 1;
++}
++
++int32_t get_string_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++ /* Warning we cast from uchar to char */
++ lua_pushlstring(L, (char *)seg->start + seg->offset, seg->length);
++ return 1;
++}
++
++int32_t set_data_generic(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++ lua_packet_segment * data = checkbytearray(L, 2);
++
++ pr_debug("seg->length %u, data->length %u\n", seg->length, data->length);
++
++ if (seg->length >= data->length)
++ memcpy((seg->start + seg->offset), data->start, data->length);
++ else
++ luaL_error(L, "provided byte array too big for given packet segment");
++ return 0;
++}
++
++struct field_changes * get_allocated_field_changes(lua_State *L, int32_t nr_of_fields)
++{
++ struct field_changes * changes;
++
++ changes = kmalloc(sizeof(struct field_changes), GFP_ATOMIC);
++
++ if (!changes)
++ goto failure;
++
++ changes->field_length_changes = kmalloc(nr_of_fields * sizeof(int), GFP_ATOMIC);
++ if (!changes->field_length_changes)
++ goto free1;
++
++ changes->field_offset_changes = kmalloc(nr_of_fields * sizeof(int), GFP_ATOMIC);
++ if (!changes->field_offset_changes)
++ goto free2;
++
++ memset(changes->field_length_changes, 0, nr_of_fields * sizeof(int));
++ memset(changes->field_offset_changes, 0, nr_of_fields * sizeof(int));
++
++ changes->ref_count = 1;
++
++ return changes;
++
++free2: kfree(changes->field_length_changes);
++free1: kfree(changes);
++failure:
++ if (!changes) luaL_error(L, "couldnt allocate memory inside 'get_allocated_field_changes'");
++ return NULL; /* only to omit warnings */
++}
+\ No newline at end of file
+--- /dev/null
++++ b/extensions/LUA/prot_buf_icmp.c
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "controller.h"
++
++static int32_t icmp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
++{
++ return 0;
++}
++
++static const struct protocol_field icmp_protocol_fields[] = {
++ /* field name offset length getter setter */
++ { "type", 0, 8, NULL, NULL },
++ { "code", 8, 8, NULL, NULL },
++ { "checksum", 16, 16, NULL, NULL },
++ { "id", 32, 16, NULL, NULL },
++ { "sequence", 48, 16, NULL, NULL },
++ PROT_FIELD_SENTINEL,
++};
++
++static const struct protocol_buf icmp_protocol_buf = {
++ .is_dynamic = 0,
++ .name = LUA_PACKET_SEG_ICMP,
++ .payload_field = NULL,
++ .protocol_fields = (struct protocol_field *)&icmp_protocol_fields,
++ .has_protocol = &icmp_has_protocol,
++ .get_field_changes = NULL,
++};
++
++void luaopen_protbuf_icmp(lua_State *L)
++{
++ register_protbuf(L, (struct protocol_buf *)&icmp_protocol_buf, PACKET_ICMP);
++}
++
+--- /dev/null
++++ b/extensions/LUA/prot_buf_ip.c
+@@ -0,0 +1,209 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#if defined(__KERNEL__)
++ #include <net/checksum.h>
++ #include <net/tcp.h>
++#endif
++
++#include "controller.h"
++
++
++#define IP_FMT "%u.%u.%u.%u"
++#define IP_ACC(buf) buf[0], buf[1], buf[2], buf[3]
++
++
++static int32_t ip_version_set(lua_State *L)
++{
++ uint8_t version_checked;
++ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
++ uint8_t *version_seg = seg->start + seg->offset;
++ int32_t version = luaL_checkinteger(L, 2);
++
++ luaL_argcheck(L, version >= 0 && version <= 15, 1, "version number invalid");
++
++ version_checked = (uint8_t)version;
++
++ version_seg[0] &= (uint8_t)0x0F; /* reset version bits */
++ version_seg[0] |= version_checked << 4;
++
++ return 0;
++}
++static int32_t ip_version_get(lua_State *L)
++{
++ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
++ uint8_t *version_seg = seg->start + seg->offset;
++ uint8_t v = version_seg[0] & 0xF0;
++
++ v >>= 4;
++
++ lua_pushinteger(L, v);
++ return 1;
++}
++
++static int32_t ip_ihl_set(lua_State *L)
++{
++ uint8_t ihl_checked;
++ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
++ uint8_t *ihl_seg = seg->start + seg->offset;
++ int32_t ihl = luaL_checkinteger(L, 2);
++
++ luaL_argcheck(L, ihl >= 5 && ihl <= 15, 1, "ip header length invalid"); // RFC 791 5x32 = 160 bits
++
++ ihl_checked = (uint8_t)ihl;
++
++ ihl_seg[0] &= (uint8_t)0xF0; /* reset ihl bits */
++ ihl_seg[0] |= ihl_checked;
++
++ return 0;
++}
++static int32_t ip_ihl_get(lua_State *L)
++{
++ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
++ uint8_t *ihl_seg = seg->start + seg->offset;
++ uint8_t v = ihl_seg[0] & 0x0F;
++
++ lua_pushinteger(L, v);
++ return 1;
++}
++
++static int32_t ip_addr_set(lua_State *L)
++{
++ int32_t field_id = lua_tointeger(L, lua_upvalueindex(2));
++ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
++ uint8_t *addr_seg = seg->start + seg->offset;
++ uint32_t old_addr;
++ char *ip = (char *)luaL_checkstring(L, 2);
++ uint32_t a, b, c, d;
++ struct sk_buff * skb = (struct sk_buff *)lua_touserdata(L, 3);
++
++ /* for tcp / udp checksumming*/
++ uint32_t prot_offset;
++ uint8_t *check, *protocol_seg;
++
++ /* end */
++
++ sscanf(ip, IP_FMT, &a, &b, &c, &d);
++
++ luaL_argcheck(L, a < 256 && b < 256 && c < 256 && d < 256, 1, "invalid ip addr");
++
++ old_addr = *((uint32_t *)addr_seg);
++ addr_seg[0] = (uint8_t)a;
++ addr_seg[1] = (uint8_t)b;
++ addr_seg[2] = (uint8_t)c;
++ addr_seg[3] = (uint8_t)d;
++
++#if defined(__KERNEL__)
++ if (old_addr != *(uint32_t *)addr_seg) {
++ int32_t offset = (field_id == 10) ? -2 : -6; /* offset from saddr or daddr */
++
++ csum_replace4((uint16_t *)(addr_seg + offset), old_addr, *(uint32_t *)addr_seg);
++
++ prot_offset = (field_id == 10) ? -3 : -7; /* offset from saddr or daddr */
++ protocol_seg = seg->start + seg->offset + prot_offset;
++
++ if (skb && (protocol_seg[0] == 0x06 || protocol_seg[0] == 0x11)) { /* is payload TCP or UDP ? */
++
++ check = seg->start + seg->offset; /* tmp res */
++ check += (field_id == 10) ? 8 : 16; /* the start of the payload, depending saddr or daddr */
++ check += (protocol_seg[0] == 0x06) ? 16 : 6; /* the start of the checksum, depending on TCP or UDP */
++
++ inet_proto_csum_replace4((__sum16 *)check, skb, old_addr, *(uint32_t *)addr_seg, 1);
++
++ lua_pop(L, 1);
++ }
++ }
++#endif
++ return 0;
++}
++
++
++
++
++
++static int32_t ip_addr_get(lua_State *L)
++{
++ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
++ uint8_t *addr_seg = seg->start + seg->offset;
++
++ char buf[16]; /*max: 255.255.255.255\0 --> 16 chars */
++
++ sprintf(buf, IP_FMT, IP_ACC(addr_seg));
++ lua_pushstring(L, buf);
++ return 1;
++}
++
++static int32_t ip_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
++{
++ uint8_t * embedded_protocol = seg->start + seg->offset + 9 /*bytes*/;
++
++ switch (embedded_protocol[0]) {
++ case 0x01: /* 1: Internet Control Message Protocol (ICMP) */
++ if (protocol_type == PACKET_ICMP) return 1;
++ break;
++ case 0x02: /* 2: Internet Group Management Protocol (IGMP) */
++ break;
++ case 0x06: /* 6: Transmission Control Protocol (TCP) */
++ if (protocol_type == PACKET_TCP) return 1;
++ break;
++ case 0x11: /* 17: User Datagram Protocol (UDP) */
++ if (protocol_type == PACKET_UDP) return 1;
++ break;
++ case 0x59: /* 89: Open Shortest Path First (OSPF) */
++ break;
++ case 0x84: /* 132: Stream Control Transmission Protocol (SCTP) */
++ break;
++ default:
++ break;
++ }
++
++ return 0;
++}
++
++static const struct protocol_field ip_protocol_fields[] = {
++ /* field name offset length getter setter */
++ { "version", 0, 4, ip_version_get, ip_version_set },
++ { "ihl", 4, 4, ip_ihl_get, ip_ihl_set },
++ { "tos", 8, 8, get_8_bit_generic, set_8_bit_generic },
++ { "tot_len", 16, 16, get_16_bit_generic, set_16_bit_generic },
++ { "id", 32, 16, get_16_bit_generic, set_16_bit_generic },
++ { "flags", 48, 3, get_1_bit_generic, set_1_bit_generic },
++ { "frag_off", 51, 13, NULL, NULL },
++ { "ttl", 64, 8, get_8_bit_generic, set_8_bit_generic },
++ { "protocol", 72, 8, get_8_bit_generic, set_8_bit_generic },
++ { "check", 80, 16, get_16_bit_generic, set_16_bit_generic },
++ { "saddr", 96, 32, ip_addr_get, ip_addr_set },
++ { "daddr", 128, 32, ip_addr_get, ip_addr_set },
++ { "data", 160, 0, NULL, set_data_generic },
++ PROT_FIELD_SENTINEL,
++};
++
++static const struct protocol_buf ip_protocol_buf = {
++ .is_dynamic = 0,
++ .name = LUA_PACKET_SEG_IP,
++ .payload_field = "data",
++ .protocol_fields = (struct protocol_field *)&ip_protocol_fields,
++ .has_protocol = &ip_has_protocol,
++ .get_field_changes = NULL,
++};
++
++void luaopen_protbuf_ip(lua_State *L)
++{
++ register_protbuf(L, (struct protocol_buf *)&ip_protocol_buf, PACKET_IP);
++}
++
+--- /dev/null
++++ b/extensions/LUA/prot_buf_raw.c
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "controller.h"
++static int32_t raw_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
++{
++ return 1;
++}
++
++static const struct protocol_field raw_protocol_fields[] = {
++ /* field name offset length getter setter */
++ { "data", 0, 0, NULL, NULL },
++ PROT_FIELD_SENTINEL,
++};
++
++static const struct protocol_buf raw_protocol_buf = {
++ .is_dynamic = 0,
++ .name = LUA_PACKET_SEG_RAW,
++ .payload_field = "data",
++ .protocol_fields = (struct protocol_field *)&raw_protocol_fields,
++ .has_protocol = &raw_has_protocol,
++ .get_field_changes = NULL,
++};
++
++void luaopen_protbuf_raw(lua_State *L)
++{
++ register_protbuf(L, (struct protocol_buf *)&raw_protocol_buf, PACKET_RAW);
++}
+--- /dev/null
++++ b/extensions/LUA/prot_buf_tcp.c
+@@ -0,0 +1,188 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#if defined(__KERNEL__)
++ #include <net/checksum.h>
++ #include <net/tcp.h>
++#endif
++#include "controller.h"
++
++
++static int32_t tcp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
++{
++ return 1;
++}
++
++static int32_t tcp_set_checksum(lua_State *L)
++{
++ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
++ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
++
++#if defined(__KERNEL__)
++ uint8_t * check_seg = seg->start + seg->offset;
++ uint8_t * tcp_hdr = check_seg - 16;
++ uint8_t * saddr = tcp_hdr - 8;
++ uint8_t * daddr = saddr + 4;
++ uint32_t len = 20 + (seg->changes->field_length_changes[11] / 8) + (seg->changes->field_length_changes[10] / 8);
++ unsigned short checksum = tcp_v4_check(len, *(uint32_t *)saddr, *(uint32_t *)daddr,
++ csum_partial(tcp_hdr, len, 0));
++
++ memcpy(check_seg, &checksum, sizeof(unsigned short));
++#endif
++ return 0;
++}
++
++
++static const struct protocol_field tcp_protocol_fields[] = {
++ /* field name offset length getter setter */
++ { "sport", 0, 16, get_16_bit_generic, set_16_bit_generic },
++ { "dport", 16, 16, get_16_bit_generic, set_16_bit_generic },
++ { "seq", 32, 32, get_32_bit_generic, set_32_bit_generic },
++ { "ack", 64, 32, get_32_bit_generic, set_32_bit_generic },
++ { "data_off", 96, 4, get_lower_4_bit_generic, set_lower_4_bit_generic },
++ { "reserved", 100, 4, get_upper_4_bit_generic, set_upper_4_bit_generic },
++ { "flags", 104, 8, get_1_bit_generic, set_1_bit_generic },
++ { "window_size", 112, 16, get_16_bit_generic, set_16_bit_generic },
++ { "check", 128, 16, get_16_bit_generic, tcp_set_checksum },
++ { "urgent", 144, 16, NULL, NULL },
++ { "options", 160, 0, NULL, set_data_generic },
++ { "data", 160, 0, NULL, set_data_generic }, /* begin of data depends on options */
++ PROT_FIELD_SENTINEL,
++};
++
++
++static const struct protocol_field tcp_options_and_data[] = {
++ /* field name offset length getter setter */
++ { "MSS", 0, 16, get_16_bit_generic, set_16_bit_generic },
++ { "WS", 0, 8, get_8_bit_generic, set_8_bit_generic },
++ { "SACK", 0, 16, get_16_bit_generic, set_16_bit_generic },
++ { "TSVAL", 0, 32, get_32_bit_generic, set_32_bit_generic },
++ { "TSER", 0, 32, get_32_bit_generic, set_32_bit_generic },
++ PROT_FIELD_SENTINEL,
++};
++
++
++static struct field_changes * tcp_get_field_changes(lua_State *L, lua_packet_segment * seg);
++
++static const struct protocol_buf tcp_protocol_buf = {
++ .is_dynamic = 0,
++ .name = LUA_PACKET_SEG_TCP,
++ .payload_field = "data",
++ .protocol_fields = (struct protocol_field *)&tcp_protocol_fields,
++ .has_protocol = &tcp_has_protocol,
++ .get_field_changes = &tcp_get_field_changes,
++};
++
++
++static struct field_changes * tcp_options_get_field_changes(lua_State *L, lua_packet_segment * seg);
++
++static const struct protocol_buf tcp_options_and_data_buf = {
++ .is_dynamic = 0,
++ .name = LUA_PACKET_SEG_TCP_OPT,
++ .payload_field = NULL,
++ .protocol_fields = (struct protocol_field *)&tcp_options_and_data,
++ .has_protocol = NULL,
++ .get_field_changes = &tcp_options_get_field_changes,
++};
++
++struct field_changes * tcp_get_field_changes(lua_State *L, lua_packet_segment * seg)
++{
++ /* depending on the value stored inside the 'data_off'-field, the length of
++ * the 'options' field has to be changed, as well as the length and offset
++ * of the 'data' field */
++ uint8_t *tcp_hdr = seg->start + seg->offset;
++
++ /* get the pointer to the 'data_off' field */
++ uint8_t * data_off_field = tcp_hdr + 12; /* 12 bytes offset */
++ /* extract the stored header length in bits */
++ uint32_t tcp_hdr_len = ((*(uint8_t *)data_off_field) >> 4) * 32;
++
++ /* get an allocated 'field_changes' structure */
++ struct field_changes * changes = get_allocated_field_changes(L, 12);
++
++ /* depending on the tcp header length, change the length of the options*/
++ changes->field_length_changes[10] = tcp_hdr_len - 160;
++ /* depending on the options length, change the offset of the data */
++ changes->field_offset_changes[11] = changes->field_length_changes[10];
++ changes->field_length_changes[11] = (seg->length * 8) - tcp_hdr_len;
++
++ return changes;
++
++}
++
++struct field_changes * tcp_options_get_field_changes(lua_State *L, lua_packet_segment * seg)
++{
++ /* depending on the value stored inside the 'data_off'-field, the length of
++ * the 'options' field has to be changed, as well as the length and offset
++ * of the 'data' field */
++ uint8_t *tcp_opt_hdr = seg->start + seg->offset;
++
++ /* get an allocated 'field_changes' structure */
++ struct field_changes * changes = get_allocated_field_changes(L, 5);
++
++ int32_t MSS = 0, WS = 0, SACK = 0, TS = 0, i;
++
++ uint8_t b1, b2;
++
++ for (i = 0; i < seg->length; i++) {
++ b1 = tcp_opt_hdr[i];
++ b2 = tcp_opt_hdr[i + 1];
++
++ if (b1 == 0x00)
++ break;
++
++ /* test for MSS */
++ if (!MSS && (b1 == 0x02 && b2 == 0x04)) {
++ changes->field_offset_changes[0] = (i + 2) * CHAR_BIT;
++ MSS = 1;
++ }
++
++ /* test for WS --- yet buggy somehow */
++ if (!WS && (b1 == 0x03 && b2 == 0x03)) {
++ changes->field_offset_changes[1] = (i + 2) * CHAR_BIT;
++ WS = 1;
++ }
++
++ /* test for SACK*/
++ if (!SACK && (b1 == 0x04 && b2 == 0x02)) {
++ changes->field_offset_changes[2] = i * CHAR_BIT; /* has no value */
++ SACK = 1;
++ }
++
++ /* test for TS */
++ if (!TS && (b1 == 0x08 && b2 == 0x0A)) {
++ changes->field_offset_changes[3] = (i + 2) * CHAR_BIT;
++ changes->field_offset_changes[4] = (i + 2 + 4) * CHAR_BIT;
++ TS = 1;
++ }
++ }
++
++ return changes;
++
++}
++
++void luaopen_protbuf_tcp(lua_State *L)
++{
++ register_protbuf(L, (struct protocol_buf *)&tcp_protocol_buf, PACKET_TCP);
++}
++void luaopen_protbuf_tcp_options(lua_State *L)
++{
++ register_protbuf(L, (struct protocol_buf *)&tcp_options_and_data_buf, PACKET_TCP_OPTIONS);
++}
++
++
+--- /dev/null
++++ b/extensions/LUA/prot_buf_tftp.c
+@@ -0,0 +1,87 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++#include "controller.h"
++
++static const struct protocol_field tftp_protocol_fields[] = {
++ /* field name offset length getter setter */
++ { "opcode", 0, 16, get_16_bit_generic, NULL},
++ { "filename", 0, 0, get_string_generic, NULL},
++ { "mode", 0, 0, get_string_generic, NULL},
++ { "block_nr", 0, 16, get_16_bit_generic, NULL},
++ { "data", 0, 0, NULL, NULL},
++ PROT_FIELD_SENTINEL,
++};
++
++struct field_changes * tftp_get_field_changes(lua_State *L, lua_packet_segment * seg)
++{
++ /* depending on the value stored inside the 'opcode'-field we have to change
++ * offsets and lengths */
++ uint8_t *tftp_hdr = seg->start + seg->offset;
++ short opcode = ntohs(*((uint16_t *)tftp_hdr));
++ /* get an allocated 'field_changes' structure */
++ struct field_changes * changes = get_allocated_field_changes(L, 5);
++ switch (opcode) {
++ case 1: /* Read Request (RRQ) */
++ /* setting offset and length of field 'filename' */
++ changes->field_offset_changes[1] = sizeof(unsigned short) << 3;
++ changes->field_length_changes[1] = strlen((char *)tftp_hdr + sizeof(unsigned short)) << 3;
++ /* setting offset and length of field 'mode' */
++ changes->field_offset_changes[2] = changes->field_offset_changes[1] + changes->field_length_changes[1];
++ changes->field_length_changes[2] = strlen((char *)tftp_hdr + (changes->field_offset_changes[2] >> 3));
++ break;
++ case 2: /* Write Request (WRQ) */
++ /* setting offset and length of field 'filename' */
++ changes->field_offset_changes[1] = sizeof(unsigned short) << 3;
++ changes->field_length_changes[1] = strlen((char *)tftp_hdr + sizeof(unsigned short)) << 3;
++ /* setting offset and length of field 'mode' */
++ changes->field_offset_changes[2] = changes->field_offset_changes[1] + changes->field_length_changes[1];
++ changes->field_length_changes[2] = strlen((char *)tftp_hdr + (changes->field_offset_changes[2] >> 3));
++ break;
++ case 3: /* Data (DATA) */
++ /* setting offset of field 'block_nr' */
++ changes->field_offset_changes[3] = sizeof(unsigned short) << 3;
++ /* setting offset of field 'data' */
++ changes->field_offset_changes[4] = changes->field_offset_changes[3] + (sizeof(unsigned short) << 3);
++ break;
++ case 4: /* Acknowledgment (ACK) */
++ /* setting offset of field 'block_nr' */
++ changes->field_offset_changes[3] = sizeof(unsigned short) << 3;
++ break;
++ case 5: /* Error (ERROR) */
++ /* we don't care ... yet */
++ break;
++ default:
++ break;
++ }
++
++ return changes;
++}
++
++static const struct protocol_buf tftp_protocol_buf = {
++ .is_dynamic = 0,
++ .name = LUA_PACKET_SEG_TFTP,
++ .payload_field = NULL,
++ .protocol_fields = (struct protocol_field *)&tftp_protocol_fields,
++ .has_protocol = NULL, /* we don't need it, since we don't provide a payload field */
++ .get_field_changes = tftp_get_field_changes,
++};
++
++void luaopen_protbuf_tftp(lua_State *L)
++{
++ register_protbuf(L, (struct protocol_buf *)&tftp_protocol_buf, PACKET_TFTP);
++}
+--- /dev/null
++++ b/extensions/LUA/prot_buf_udp.c
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#if defined(__KERNEL__)
++ #include <net/checksum.h>
++#endif
++
++#include "controller.h"
++
++
++static int32_t udp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
++{
++ return 1;
++}
++
++static const struct protocol_field udp_protocol_fields[] = {
++ /* field name offset length getter setter */
++ { "sport", 0, 16, get_16_bit_generic, set_16_bit_generic },
++ { "dport", 16, 16, get_16_bit_generic, set_16_bit_generic },
++ { "length", 32, 16, get_16_bit_generic, set_16_bit_generic },
++ { "check", 48, 16, get_16_bit_generic, set_16_bit_generic },
++ { "data", 64, 0, NULL, NULL },
++ PROT_FIELD_SENTINEL,
++};
++
++static const struct protocol_buf udp_protocol_buf = {
++ .is_dynamic = 0,
++ .name = LUA_PACKET_SEG_UDP,
++ .payload_field = "data",
++ .protocol_fields = (struct protocol_field *)&udp_protocol_fields,
++ .has_protocol = &udp_has_protocol,
++ .get_field_changes = NULL,
++};
++
++void luaopen_protbuf_udp(lua_State *L)
++{
++ register_protbuf(L, (struct protocol_buf *)&udp_protocol_buf, PACKET_UDP);
++}
+--- /dev/null
++++ b/extensions/LUA/xt_LUA.h
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre.graf@stud.unibas.ch>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#ifndef XT_LUA_H_
++#define XT_LUA_H_
++
++#define MAX_FILENAME_SIZE 256
++#define MAX_FUNCTION_SIZE 256
++#define MAX_SCRIPT_SIZE 32768
++#define LUA_STATE_ARRAY_SIZE 128
++
++/* the targetsize is stored in a u16, so max size of the xt_lua_tginfo cannot exceed 64K*/
++struct xt_lua_tginfo {
++ char buf[MAX_SCRIPT_SIZE];
++ char filename[MAX_FILENAME_SIZE];
++ char function[MAX_FUNCTION_SIZE];
++ __u64 script_size;
++ __u32 state_id;
++};
++
++#endif /* XT_LUA_H_ */
+--- /dev/null
++++ b/extensions/LUA/xt_LUA_target.c
+@@ -0,0 +1,286 @@
++/*
++ * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
++ * by Andre Graf <andre@dergraf.org>
++ *
++ * 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, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <asm/uaccess.h>
++#include <net/ip.h>
++#include <linux/netfilter/x_tables.h>
++#include "xt_LUA.h"
++
++#include "controller.h"
++
++/*::*
++ * lua_envs
++ * ----------
++ * This array holds a defined number of `lua_envs`_ structures.
++ * The used array index is also used as the Lua state identifier.
++ * The size of the array is defined in `LUA_STATE_ARRAY_SIZE`_.
++ */
++struct lua_env * lua_envs[LUA_STATE_ARRAY_SIZE];
++
++/*::*
++ * lua_state_refs
++ * --------------
++ * This array holds the reference counts of the several `lua_nf_state`_s
++ * which are stored inside the array `lua_states`_.
++ */
++uint32_t lua_state_refs[LUA_STATE_ARRAY_SIZE] = { 0 };
++
++/*::*
++ * lua_tg
++ * ------
++ * This function is called whenever a packet matches all matching conditions
++ * inside a rule. It is the target. It extracts the state identifier comming
++ * inside the *xt_target_param* structure and uses it to access the proper
++ * Lua state inside the `lua_states`_ array.
++ *
++ * It then constructs a new Lua userdata of type *lua_packet_segment* and
++ * initializes it with the lowest network header available. This userdata
++ * is annotated with the Lua metatable `LUA_PACKET_SEG_RAW`_ which converts
++ * the userdata to a raw lua packet having all raw functions available.
++ * This raw packet is the single parameter to the Lua function *process_packet*
++ * which must be defined inside the Lua script provided by the user. So far
++ * hardcoded, may be later configured by Lua - subject to change.
++ *
++ * The process_packet function must return an integer value, the verdict. For
++ * convenience reasons xt_LUA exports the verdicts NF_ACCEPT, NF_DROP and
++ * XT_CONTINUE inside the *register_lua_packet_lib* function.
++ */
++
++spinlock_t lock = SPIN_LOCK_UNLOCKED;
++
++static uint32_t
++lua_tg(struct sk_buff *pskb, const struct xt_target_param *par)
++{
++ uint32_t verdict;
++ lua_packet_segment *p;
++ const struct xt_lua_tginfo *info = par->targinfo;
++ lua_State * L;
++
++ /* START critical section on SMP, PacketScript is on the sequential trail at the moment TODO*/
++ spin_lock_irq(&lock);
++
++ L = lua_envs[info->state_id]->L;
++
++ if (!skb_make_writable(pskb, pskb->len))
++ return NF_DROP;
++
++ /* call the function provided by --function parameter or the default 'process_packet' defined in Lua */
++ lua_getglobal(L, info->function);
++
++ /* push the lua_packet_segment as a parameter */
++ p = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
++ if (pskb->mac_header)
++ p->start = pskb->mac_header;
++ else if (pskb->network_header)
++ p->start = pskb->network_header;
++ else if (pskb->transport_header)
++ p->start = pskb->transport_header;
++ p->offset = 0;
++ p->length = (unsigned long)pskb->tail - (unsigned long)p->start;
++ p->changes = NULL;
++
++ /* marking userdata 'lua_packet_seg' with the corresponding metatable */
++ luaL_getmetatable(L, LUA_PACKET_SEG_RAW);
++ lua_setmetatable(L, -2);
++
++ /* push a reference to the skb as a parameter, needed at the moment for calculating TCP checksum, but I am not happy with it*/
++ lua_pushlightuserdata(L, (void *)skb_get(pskb));
++
++ /* do the function call (2 argument, 1 result) */
++ if (lua_pcall(L, 2, 1, 0) != 0) {
++ printk(KERN_ERR "LUA [%d]: pcall '%s' failed: %s\n", info->state_id, info->function, lua_tostring(L, -1));
++ lua_pop(L, 1);
++ return NF_DROP;
++ }
++
++ if (!lua_isnumber(L, -1)) {
++ printk(KERN_ERR "LUA [%d]: function '%s' must return a verdict\n", info->state_id, info->function);
++ lua_pop(L, 1);
++ return NF_DROP;
++ }
++
++ verdict = lua_tonumber(L, -1);
++ lua_pop(L, 1);
++
++ kfree_skb(pskb);
++
++ /* END critical section on SMP */
++ spin_unlock_irq(&lock);
++
++
++ return verdict;
++
++}
++/* Helper for checkentry */
++static bool load_script_into_state(uint32_t state_id, unsigned long script_size, char *script_buf)
++{
++ char *buf = kmalloc(script_size, GFP_KERNEL);
++ int32_t ret;
++ struct lua_env * env = kmalloc(sizeof(struct lua_env), GFP_KERNEL);
++
++ if (!script_size > 0) {
++ pr_debug("LUA [%d]: script_size %lu < 0\n", state_id, script_size);
++ return false;
++ }
++
++ env->L = lua_open();
++ luaopen_base(env->L);
++ luaopen_controller(env->L);
++
++ lua_getglobal(env->L, "_G");
++ lua_pushinteger(env->L, state_id);
++ lua_setfield(env->L, -2, "STATE_ID");
++ lua_pop(env->L, 1); /* pop _G */
++
++ strncpy(buf, script_buf, script_size);
++ ret = luaL_loadbuffer(env->L, buf, script_size, "PacketScript, loadbuffer") ||
++ lua_pcall(env->L, 0, 1, 0);
++
++ if (ret != 0) {
++ printk(KERN_ERR "LUA [%d]: failure loading script, error %s \n", state_id, lua_tostring(env->L, -1));
++ lua_pop(env->L, 1);
++ kfree(buf);
++ kfree(env);
++ return false;
++ }
++
++ lua_envs[state_id] = env;
++
++ kfree(buf);
++
++ return true;
++}
++/*::*
++ * lua_tg_checkentry
++ * -----------------
++ * This function is used as a kernel-side sanity check of the data comming
++ * from the iptables userspace program. Since this is the function which is
++ * called everytime a new rule (with -j xt_LUA) is injected, this function
++ * is used to do the bookkeeping work, such as counting the reference of
++ * several Lua states and the initialization of new states if needed. As an
++ * extra initialization step it loads the provided Lua script into the Lua
++ * state.
++ *
++ * Lua state initialization
++ * ~~~~~~~~~~~~~~~~~~~~~~~~
++ * 1. If a new rule is inserted and there is no existing state for the given
++ * state identifier (default state identifier is 0) a new Lua state is
++ * initialized using *lua_open*.
++ * 2. The Lua base library is registered inside the newly initialized state.
++ * Have a look at *lua/lbaselib.c* to see what functions of the Lua base
++ * library are available inside Lua.
++ * 3. The Lua packet library is registered inside the Lua state using the
++ * function *register_lua_packet_lib*. So far this function only registers
++ * the Netfilter verdicts NF_ACCEPT, NF_DROP and XT_CONTINUE inside the
++ * global environment of the given Lua state.
++ * 4. All the protocol Buffers, and the functions for accessing the bytes are
++ * registered using *register_protocols*.
++ *
++ * Lua state reference counting
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ * Bookkeeping of the Lua states inside the *lua_state_refs* array. The
++ * state identifier is mapped to the array index, which holds an integer
++ * counting the several initialized states.
++ *
++ * Loading the Lua script
++ * ~~~~~~~~~~~~~~~~~~~~~~
++ * Copying the buffer which was initialized by the userspace program to a
++ * buffer with the proper size. The script is then loaded by the function
++ * xt_LUA_loadcode, which wrapps the *luaL_loadbuffer* function and does
++ * some workqueue initialization. So far this is done each time this function
++ * is called, subject to change.
++ */
++static bool
++lua_tg_checkentry(const struct xt_tgchk_param *par)
++{
++ const struct xt_lua_tginfo *info = par->targinfo;
++
++ if (load_script_into_state(info->state_id, info->script_size, (char *)info->buf)) {
++ lua_state_refs[info->state_id]++;
++ return true;
++ }
++ return false;
++}
++
++/*::*
++ * lua_tg_destroy
++ * --------------
++ * This function is the counterpart of the `lua_tg_checkentry`_ function. It is
++ * responsible to free all the resources alocated inside the checkentry process.
++ * To be more specific it frees the Lua state using *lua_close* and kfree on all
++ * the dynamically allocated pointers to the registered dynamic protocol buffers.
++ *
++ * Additionally the function cares about decrementing the reference counters
++ * inside the array `lua_states`_.
++ */
++static void
++lua_tg_destroy(const struct xt_tgdtor_param *par)
++{
++ const struct xt_lua_tginfo *info = par->targinfo;
++ struct lua_env * env = lua_envs[info->state_id];
++
++ if (lua_state_refs[info->state_id] == 1) {
++ lua_close(env->L);
++ cleanup_dynamic_prot_bufs(); /* clean memory allocated by protocols defined in Lua */
++ kfree(env);
++ pr_debug("LUA [%d]: Rule removed, close Lua state\n", info->state_id);
++ } else
++ pr_debug("LUA [%d]: Rule removed, Lua state stays open, referenced %d time(s)\n",
++ info->state_id, lua_state_refs[info->state_id] - 1);
++
++ lua_state_refs[info->state_id]--;
++}
++
++static struct xt_target lua_tg_reg __read_mostly = {
++ .name = "LUA",
++ .revision = 0,
++ .family = NFPROTO_UNSPEC,
++ .targetsize = XT_ALIGN(sizeof(struct xt_lua_tginfo)),
++ .target = lua_tg,
++ .checkentry = lua_tg_checkentry,
++ .destroy = lua_tg_destroy,
++ .me = THIS_MODULE,
++};
++
++
++static int32_t lua_tg_init(void)
++{
++ return xt_register_target(&lua_tg_reg);
++}
++
++static void lua_tg_exit(void)
++{
++ xt_unregister_target(&lua_tg_reg);
++}
++
++module_init(lua_tg_init);
++module_exit(lua_tg_exit);
++
++MODULE_AUTHOR("Andre Graf <andre@dergraf.org>");
++MODULE_DESCRIPTION("Xtables: Processing of matched packets using the Lua scripting environment");
++MODULE_ALIAS("ipt_LUA");
++MODULE_ALIAS("ipt6t_LUA");
++MODULE_ALIAS("arpt_LUA");
++MODULE_ALIAS("ebt_LUA");
++MODULE_LICENSE("GPL");
++
++
++
+--- a/extensions/Kbuild
++++ b/extensions/Kbuild
+@@ -29,6 +29,7 @@ obj-${build_pknock} += pknock/
+ obj-${build_psd} += xt_psd.o
+ obj-${build_quota2} += xt_quota2.o
+ obj-${build_rtsp} += rtsp/
++obj-${build_LUA} += LUA/
+
+ -include ${M}/*.Kbuild
+ -include ${M}/Kbuild.*
+--- a/extensions/Mbuild
++++ b/extensions/Mbuild
+@@ -22,3 +22,4 @@ obj-${build_pknock} += pknock/
+ obj-${build_psd} += libxt_psd.so
+ obj-${build_quota2} += libxt_quota2.so
+ obj-${build_gradm} += libxt_gradm.so
++obj-${build_LUA} += LUA/
+--- a/mconfig
++++ b/mconfig
+@@ -23,3 +23,4 @@ build_pknock=m
+ build_psd=m
+ build_quota2=m
+ build_rtsp=m
++build_LUA=m
diff --git a/package/network/utils/xtables-addons/patches/201-fix-lua-packetscript.patch b/package/network/utils/xtables-addons/patches/201-fix-lua-packetscript.patch
new file mode 100644
index 0000000..966d29d
--- /dev/null
+++ b/package/network/utils/xtables-addons/patches/201-fix-lua-packetscript.patch
@@ -0,0 +1,89 @@
+--- a/extensions/LUA/xt_LUA_target.c
++++ b/extensions/LUA/xt_LUA_target.c
+@@ -64,10 +64,10 @@ uint32_t lua_state_refs[LUA_STATE_ARRAY
+ * XT_CONTINUE inside the *register_lua_packet_lib* function.
+ */
+
+-spinlock_t lock = SPIN_LOCK_UNLOCKED;
++DEFINE_SPINLOCK(lock);
+
+ static uint32_t
+-lua_tg(struct sk_buff *pskb, const struct xt_target_param *par)
++lua_tg(struct sk_buff *pskb, const struct xt_action_param *par)
+ {
+ uint32_t verdict;
+ lua_packet_segment *p;
+@@ -208,16 +208,16 @@ static bool load_script_into_state(uint3
+ * some workqueue initialization. So far this is done each time this function
+ * is called, subject to change.
+ */
+-static bool
++static int
+ lua_tg_checkentry(const struct xt_tgchk_param *par)
+ {
+ const struct xt_lua_tginfo *info = par->targinfo;
+
+ if (load_script_into_state(info->state_id, info->script_size, (char *)info->buf)) {
+ lua_state_refs[info->state_id]++;
+- return true;
++ return 0;
+ }
+- return false;
++ return -EINVAL;
+ }
+
+ /*::*
+--- a/extensions/LUA/lua/llimits.h
++++ b/extensions/LUA/lua/llimits.h
+@@ -8,7 +8,6 @@
+ #define llimits_h
+
+ #include <stddef.h>
+-#include <limits.h>
+
+ #include "lua.h"
+
+--- a/extensions/LUA/lua/lapi.c
++++ b/extensions/LUA/lua/lapi.c
+@@ -4,9 +4,6 @@
+ ** See Copyright Notice in lua.h
+ */
+
+-#include <stdarg.h>
+-#include <math.h>
+-#include <assert.h>
+ #include <string.h>
+
+ #define lapi_c
+--- a/extensions/LUA/lua/ltable.c
++++ b/extensions/LUA/lua/ltable.c
+@@ -18,7 +18,6 @@
+ ** Hence even when the load factor reaches 100%, performance remains good.
+ */
+
+-#include <math.h>
+ #include <string.h>
+
+ #define ltable_c
+--- a/extensions/LUA/lua/luaconf.h
++++ b/extensions/LUA/lua/luaconf.h
+@@ -13,6 +13,10 @@
+ #if !defined(__KERNEL__)
+ #include <limits.h>
+ #else
++#undef UCHAR_MAX
++#undef SHRT_MAX
++#undef BUFSIZ
++#undef NO_FPU
+ #define UCHAR_MAX 255
+ #define SHRT_MAX 32767
+ #define BUFSIZ 8192
+@@ -637,6 +641,8 @@ union luai_Cast { double l_d; long l_l;
+ */
+ #if defined(__KERNEL__)
+ #undef LUA_USE_ULONGJMP
++#define setjmp __builtin_setjmp
++#define longjmp __builtin_longjmp
+ #endif
+
+ #if defined(__cplusplus)
diff --git a/package/network/utils/xtables-addons/patches/300-geoip-endian-detection.patch b/package/network/utils/xtables-addons/patches/300-geoip-endian-detection.patch
new file mode 100644
index 0000000..842e7af
--- /dev/null
+++ b/package/network/utils/xtables-addons/patches/300-geoip-endian-detection.patch
@@ -0,0 +1,18 @@
+--- a/extensions/libxt_geoip.c
++++ b/extensions/libxt_geoip.c
+@@ -59,13 +59,13 @@ geoip_get_subnets(const char *code, uint
+
+ /* Use simple integer vector files */
+ if (nfproto == NFPROTO_IPV6) {
+-#if __BYTE_ORDER == _BIG_ENDIAN
++#if BYTE_ORDER == BIG_ENDIAN
+ snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv6", code);
+ #else
+ snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv6", code);
+ #endif
+ } else {
+-#if __BYTE_ORDER == _BIG_ENDIAN
++#if BYTE_ORDER == BIG_ENDIAN
+ snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv4", code);
+ #else
+ snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv4", code);