From 716ca530e1c4515d8683c9d5be3d56b301758b66 Mon Sep 17 00:00:00 2001 From: James <> Date: Wed, 4 Nov 2015 11:49:21 +0000 Subject: trunk-47381 --- package/network/ipv6/6in4/Makefile | 43 +++ package/network/ipv6/6in4/files/6in4.sh | 156 ++++++++ package/network/ipv6/6rd/Makefile | 54 +++ package/network/ipv6/6rd/files/6rd.sh | 102 +++++ package/network/ipv6/6rd/src/6rdcalc.c | 126 +++++++ package/network/ipv6/6rd/src/Makefile | 7 + package/network/ipv6/6to4/Makefile | 43 +++ package/network/ipv6/6to4/files/6to4.sh | 98 +++++ package/network/ipv6/ds-lite/Makefile | 43 +++ package/network/ipv6/ds-lite/files/dslite.sh | 102 +++++ package/network/ipv6/map/Makefile | 45 +++ package/network/ipv6/map/files/map.sh | 221 +++++++++++ package/network/ipv6/map/src/CMakeLists.txt | 26 ++ package/network/ipv6/map/src/mapcalc.c | 412 +++++++++++++++++++++ package/network/ipv6/odhcp6c/Makefile | 51 +++ package/network/ipv6/odhcp6c/files/dhcpv6.script | 219 +++++++++++ package/network/ipv6/odhcp6c/files/dhcpv6.sh | 103 ++++++ package/network/ipv6/thc-ipv6/Makefile | 61 +++ .../network/ipv6/thc-ipv6/patches/100-no-ssl.patch | 9 + 19 files changed, 1921 insertions(+) create mode 100644 package/network/ipv6/6in4/Makefile create mode 100755 package/network/ipv6/6in4/files/6in4.sh create mode 100644 package/network/ipv6/6rd/Makefile create mode 100644 package/network/ipv6/6rd/files/6rd.sh create mode 100644 package/network/ipv6/6rd/src/6rdcalc.c create mode 100644 package/network/ipv6/6rd/src/Makefile create mode 100644 package/network/ipv6/6to4/Makefile create mode 100755 package/network/ipv6/6to4/files/6to4.sh create mode 100644 package/network/ipv6/ds-lite/Makefile create mode 100755 package/network/ipv6/ds-lite/files/dslite.sh create mode 100644 package/network/ipv6/map/Makefile create mode 100755 package/network/ipv6/map/files/map.sh create mode 100644 package/network/ipv6/map/src/CMakeLists.txt create mode 100644 package/network/ipv6/map/src/mapcalc.c create mode 100644 package/network/ipv6/odhcp6c/Makefile create mode 100755 package/network/ipv6/odhcp6c/files/dhcpv6.script create mode 100755 package/network/ipv6/odhcp6c/files/dhcpv6.sh create mode 100644 package/network/ipv6/thc-ipv6/Makefile create mode 100644 package/network/ipv6/thc-ipv6/patches/100-no-ssl.patch (limited to 'package/network/ipv6') 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 + 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 + 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 + * + * 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 +#include +#include +#include +#include +#include + +#define INET_PREFIXSTRLEN (INET_ADDRSTRLEN+3) +#define INET6_PREFIXSTRLEN (INET6_ADDRSTRLEN+4) + +static void print_usage() +{ + fprintf(stderr, "Usage: 6rdcalc / /\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 + 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 + 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 +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 +# 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 ") +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 + * Copyright (c) 2014-2015 cisco Systems, Inc. + * Copyright (c) 2015 Steven Barth + * + * 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 +#include +#include +#include +#include +#include + + +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 [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 +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 + +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 -- cgit v1.2.3