1#!/bin/bash 2# 3# Copyright (c) 2017, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29#---------------------------------------- 30# Purpose: 31# To understand the purpose of this script see: print_big_ugly_warning() below. 32#---------------------------------------- 33# 34 35# remember the name of this script 36SCRIPT_NAME=$0 37 38CWD=$(pwd) 39DATE=$(date) 40 41# shellcheck source=script/_initrc 42. "$(dirname "$0")"/_initrc 43 44ETH0_IPV6_BASE_PREFIX=fd11:33 45 46debug_echo() 47{ 48 if [ "${_DEBUG_IPV6}" == "true" ]; then 49 echo "${@}" 50 fi 51} 52 53determine_eth0_name() 54{ 55 ETH0_NAME='' 56 57 # 58 # this gives us a sorted list of network interface names 59 for devname in $( 60 cd /sys/class/net || exit 61 ls 62 ); do 63 # We want the physical device 64 # Not things like "usb0" or "wpan0" 65 # And we assume the first one is what we want 66 debug_echo "Consider: ${devname}" 67 ignore=false 68 case ${devname} in 69 usb* | can* | wpan* | br* | wlan* | lo) 70 # by name we can ignore USB-gadget, CANbus, Thread, wireless and loopback 71 ignore=true 72 ;; 73 *) 74 ignore=false 75 ;; 76 esac 77 78 if $ignore; then 79 debug_echo "Ignore ${devname} by name" 80 continue 81 fi 82 83 debug_echo "Consider: ${devname}" 84 if [ ! -L /sys/class/net/"${devname}"/device ]; then 85 debug_echo "Not a DEVICE ${devname}" 86 continue 87 fi 88 89 type=$(cat /sys/class/net/"${devname}"/type) 90 # Type1 = ARPHRD_ETHER 91 if [ "$type" -ne 1 ]; then 92 debug_echo "Not ARPHRD_ETHER" 93 continue 94 fi 95 # We assume the first thing we find is our device 96 ETH0_NAME=${devname} 97 break 98 done 99 100 if [ -z "${ETH0_NAME}" ]; then 101 echo "Cannot determine ETH0 name...." 102 exit 1 103 fi 104 echo "Assuming: Primary ETHERNET name is $ETH0_NAME" 105} 106 107install_radvd() 108{ 109 echo "Fetching RADVD..." 110 echo "apt-get install --no-install-recommends radvd" 111 sudo apt-get install --no-install-recommends radvd 112} 113 114choose_random_eth0_address() 115{ 116 # steps below are 117 # Using "od" see http://man7.org/linux/man-pages/man1/od.1.html 118 # read from /dev/urandom 119 # 120 # We use /dev/urandom not /dev/random for these reasons: 121 # 1) This is for private (not public) test purposes 122 # 2) urandom might stall ... and not give us bytes 123 # 124 # We want data in 16bit hex, hence: --format=x2 125 # We want only 4 bytes, hence --read-bytes=4 126 # 127 # The output looks like: 128 # 0000000 1234 5678 129 # 0000008 130 # 131 # head gives us the first line 132 # cut gives us the items 2 and 3 on the line 133 # tr converts the space into a ':' 134 # 135 RANDOM_32BIT_VALUE=$(od --read-bytes=4 --format=x2 /dev/urandom \ 136 | head -1 \ 137 | cut -d' ' -f2,3 \ 138 | tr ' ' ':') 139 140 # thus, "RANDOM_32BIT_VALUE=1234:5678" 141 142 # We'll use this for the radvd config 143 ETH0_IPV6_PREFIX=${ETH0_IPV6_BASE_PREFIX}:${RANDOM_32BIT_VALUE} 144 145 # and this for the static network address 146 ETH0_IPV6_STATIC_ADDRESS=${ETH0_IPV6_PREFIX}::1 147} 148 149configure_radvd() 150{ 151 # this creates a configuration file for radvd 152 CFG_FILE=/etc/radvd.conf 153 if [ -f $CFG_FILE ]; then 154 echo "radvd config file exists: $CFG_FILE" 155 echo "SKIPPING radvd configuration" 156 else 157 sudo tee -a /etc/radvd.conf <<__EOF__ 158# 159# This RADVD configuration file was created 160# by the OpenThread configuration script $SCRIPT_NAME 161# Executed in the directory ${CWD} on ${DATE} 162# 163# The purpose is to configure IPV6 in an issolated and 164# standalone network configuration for the purpose of test only 165# 166# This is by no means a complete IPv6 configuration 167# it is sufficent to allow coap transactions 168# with thread devices on the thread mesh network 169# attched to this boarder router 170# 171interface ${ETH0_NAME} { 172 # We want to send router adverts 173 AdvSendAdvert on; 174 175 # This is not a proper IPv6 router 176 # it is only for openthread 177 AdvDefaultPreference low; 178 179 # We should advertize this prefix 180 prefix ${ETH0_IPV6_PREFIX}::/64 { 181 # we want this "on link" 182 AdvOnLink on; 183 # devices should self-assign addresses with this prefix 184 AdvAutonomous on; 185 AdvRouterAddr on; 186 }; 187}; 188__EOF__ 189 fi 190} 191 192assign_eth0_static_ipv6() 193{ 194 195 # this creates a static IPv6 address for Eth0 196 sudo tee -a /etc/network/interfaces <<__EOF__ 197 198# This configuration was created by 199# the openthread ${SCRIPT_NAME} 200# executing in the directory ${CWD} 201# and executed on ${DATE} 202# 203# for the purposes of testing ipv6 addresses 204# in an issolated network configuration 205 206# ensure ETH0 is configured at boot 207auto ${ETH0_NAME} 208 209# Configure the IPv6 address static 210# Note: IPv4 is not effected by this 211iface ${ETH0_NAME} inet6 static 212 address ${ETH0_IPV6_STATIC_ADDRESS} 213 netmask 64 214__EOF__ 215 216} 217 218# on BBB we do this. 219# other platforms might do something simular 220bbb_main() 221{ 222 install_radvd 223 determine_eth0_name 224 choose_random_eth0_address 225 configure_radvd 226 assign_eth0_static_ipv6 227 228 echo "You should now reboot your Device" 229} 230 231print_big_ugly_warning() 232{ 233 # Scare our victim. 234 235 cat <<_EOF_ 236 237Please understand the purpose of this script. 238 239This script is not intended to be an complete and proper IPv6 240configuration script. 241 242This is only hack that turns on just enough IPv6 to perform simple 243CoAP requests on or across an issolated test network to the Thread 244network. 245 246The example issolated test network consists of these parts: 247 2481) A thread RF radio network. 249 2502) The OpenThread Border router attached to the Thread network 251 2523) The Openthread Border router would typically be connected 253 to a residential home network in some way (wifi, or wired) 254 255 In this case, it is connected to a router that is not 256 connected to an upstream provider - it is issolated. 257 2584) In order to test & develop applications other things on the 259 "home/test network" need to talk to the various Thread end nodes 260 via IPv6 261 262 Examples include: 263 264 * Laptop, or desktop machine 265 * Android/Apple Phone or Tablet 266 * other network devices 267 268To test/develop your applications a means for these other devices on 269your test network to talk to devices on the Thread Network must exist. 270 271The problem: 272 273 274 Most home network routers provide only IPv4 services. They most 275 typically assume the upstream ISP network provider will provide 276 IPv6 addresses and configuration. A test network is often issolated 277 and not connected to the large world wide web, it is completely an 278 island. The upstream ISP provider does not exist. 279 280 In the end something needs to provide a minimal IPv6 configuration. 281 282========================================================= 283The above is the purpose of this ipv6 standalone hack script 284 285Never consider this script a proper IPv6 configuration. 286========================================================= 287 288It is only a quick hack that enables enough IPv6 to work such that: 289 2901) Your local test laptop/cellphone has an IPv6 address and 2912) can perform CoAP transfers between a node on thread network 292 293Now that you have read and understood the above, execute this script 294again like this: 295 296 ${SCRIPT_NAME} enable_ipv6_hack 297 298_EOF_ 299 300} 301 302# ensure user/victim has read the ugly warning. 303if [ "${1}" != "enable_ipv6_hack" ]; then 304 print_big_ugly_warning 305 exit 1 306fi 307 308# platforms specifc 309case ${PLATFORM} in 310 "beagleboneblack") 311 bbb_main 312 ;; 313 *) 314 die "Unsupported/unknown platform ${PLATFORM}" 315 ;; 316esac 317