xref: /aosp_15_r20/external/ot-br-posix/script/standalone_ipv6 (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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