freedombone-mesh-batman 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. #!/bin/bash
  2. # _____ _ _
  3. # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
  4. # | __| _| -_| -_| . | . | | . | . | | -_|
  5. # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
  6. #
  7. # Freedom in the Cloud
  8. #
  9. # Used to enable or disable batman mesh protocol on a given interface
  10. #
  11. # License
  12. # =======
  13. #
  14. # Copyright (C) 2015-2018 Bob Mottram <bob@freedombone.net>
  15. #
  16. # This program is free software: you can redistribute it and/or modify
  17. # it under the terms of the GNU Affero General Public License as published by
  18. # the Free Software Foundation, either version 3 of the License, or
  19. # (at your option) any later version.
  20. #
  21. # This program is distributed in the hope that it will be useful,
  22. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. # GNU Affero General Public License for more details.
  25. #
  26. # You should have received a copy of the GNU Affero General Public License
  27. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  28. PROJECT_NAME='freedombone'
  29. COMPLETION_FILE="/root/${PROJECT_NAME}-completed.txt"
  30. # hotspot passphrase must be 5 characters or longer
  31. HOTSPOT_PASSPHRASE="${PROJECT_NAME}"
  32. # The type of interface which the mesh will run on
  33. MESH_INTERFACE_TYPE='wlan'
  34. source /usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-wifi
  35. source /usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-mesh
  36. function status {
  37. batctl o
  38. if grep -q "bmx6" "$MESH_CURRENT_PROTOCOL"; then
  39. bmx6 -c show=originators
  40. fi
  41. if grep -q "bmx7" "$MESH_CURRENT_PROTOCOL"; then
  42. bmx7 -c show=originators
  43. fi
  44. }
  45. function stop {
  46. if [ ! -f "$MESH_CURRENT_PROTOCOL" ]; then
  47. return
  48. fi
  49. if [ -z "$IFACE" ]; then
  50. echo 'error: unable to find wifi interface, not enabling batman-adv mesh'
  51. return
  52. fi
  53. systemctl stop bmx6
  54. if [ -d /etc/bmx7 ]; then
  55. systemctl stop bmx7
  56. fi
  57. systemctl stop olsr2
  58. systemctl stop babel
  59. systemctl disable bmx6
  60. systemctl disable bmx7
  61. systemctl disable olsr2
  62. systemctl disable babel
  63. systemctl stop dnsmasq
  64. systemctl disable dnsmasq
  65. # shellcheck disable=SC2153
  66. if [ "$EIFACE" ]; then
  67. if [[ "$EIFACE" != "$IFACE" ]] ; then
  68. brctl delif "$BRIDGE" bat0
  69. ifconfig "$BRIDGE" down || true
  70. ethernet_connected=$(cat "/sys/class/net/$EIFACE/carrier")
  71. if [[ "$ethernet_connected" != "0" ]]; then
  72. systemctl stop hostapd
  73. brctl delif "$BRIDGE" "$EIFACE"
  74. ifconfig "$EIFACE" down -promisc
  75. fi
  76. brctl delbr "$BRIDGE"
  77. fi
  78. fi
  79. ifconfig bat0 down -promisc
  80. batctl if del "$IFACE"
  81. ifconfig "$IFACE" mtu 1500
  82. ifconfig "$IFACE" down
  83. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  84. iwconfig "$IFACE" mode managed
  85. fi
  86. if [ "$IFACE_SECONDARY" ]; then
  87. systemctl stop hostapd
  88. systemctl disable hostapd
  89. batctl if del "$IFACE_SECONDARY"
  90. ifconfig "$IFACE_SECONDARY" mtu 1500
  91. ifconfig "$IFACE_SECONDARY" down
  92. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  93. iwconfig "$IFACE_SECONDARY" mode managed
  94. fi
  95. fi
  96. rmmod batman-adv
  97. disable_mesh_firewall
  98. systemctl restart network-manager
  99. if [ -f "$MESH_CURRENT_PROTOCOL" ]; then
  100. rm "$MESH_CURRENT_PROTOCOL"
  101. fi
  102. }
  103. function verify {
  104. tempfile="$(mktemp)"
  105. batctl o > "$tempfile"
  106. if grep -q "disabled" "$tempfile"; then
  107. echo $'B.A.T.M.A.N. not enabled'
  108. rm "$tempfile"
  109. stop
  110. exit 726835
  111. fi
  112. echo $'B.A.T.M.A.N. is running'
  113. rm "$tempfile"
  114. }
  115. function add_wifi_interface {
  116. ifname=$1
  117. ifssid=$WIFI_SSID
  118. if [ "$2" ]; then
  119. ifssid=$2
  120. fi
  121. ifmode=ad-hoc
  122. if [ "$3" ]; then
  123. ifmode=$3
  124. fi
  125. ifchannel=$CHANNEL
  126. if [ "$4" ]; then
  127. ifchannel=$4
  128. fi
  129. ifconfig "$ifname" down
  130. ifconfig "$ifname" mtu 1532
  131. peermac=$(assign_peer_address)
  132. if [ ! "$peermac" ]; then
  133. echo $"Unable to obtain MAC address for $peermac on $ifname"
  134. return
  135. fi
  136. ifconfig "$ifname" hw ether "$peermac"
  137. echo $"$ifname assigned MAC address $peermac"
  138. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  139. iwconfig "$ifname" enc off
  140. iwconfig "$ifname" mode "$ifmode" essid "$ifssid" channel "$ifchannel"
  141. fi
  142. batctl if add "$ifname"
  143. ifconfig "$ifname" up
  144. }
  145. # shellcheck disable=SC2120
  146. function start {
  147. update_wifi_adaptors "${MESH_INTERFACE_TYPE}"
  148. if [ -z "$IFACE" ] ; then
  149. echo 'error: unable to find wifi interface, not enabling batman-adv mesh'
  150. exit 723657
  151. fi
  152. echo "info: enabling batman-adv mesh network $WIFI_SSID on $IFACE"
  153. stop
  154. systemctl stop network-manager
  155. sleep 5
  156. systemctl stop dnsmasq
  157. systemctl disable dnsmasq
  158. # remove an avahi service which isn't used
  159. if [ -f /etc/avahi/services/udisks.service ]; then
  160. sudo rm /etc/avahi/services/udisks.service
  161. fi
  162. global_rate_limit
  163. # Might have to re-enable wifi
  164. rfkill unblock "$(rfkill list|awk -F: "/phy/ {print $1}")" || true
  165. secondary_wifi_available=
  166. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  167. if [ "$IFACE_SECONDARY" ]; then
  168. if [[ "$IFACE" != "$IFACE_SECONDARY" ]]; then
  169. if [ -d /etc/hostapd ]; then
  170. if [ ${#HOTSPOT_PASSPHRASE} -gt 4 ]; then
  171. secondary_wifi_available=1
  172. else
  173. echo $'Hotspot passphrase is too short'
  174. fi
  175. fi
  176. fi
  177. fi
  178. fi
  179. modprobe batman-adv
  180. # avahi on ipv6
  181. sed -i 's|use-ipv4=.*|use-ipv4=no|g' /etc/avahi/avahi-daemon.conf
  182. sed -i 's|use-ipv6=.*|use-ipv6=yes|g' /etc/avahi/avahi-daemon.conf
  183. sed -i "s|ExecStart=.*|ExecStart=/usr/sbin/bmx6 dev=${IFACE}|g" /etc/systemd/system/bmx6.service
  184. sed -i "s|ExecStart=.*|ExecStart=/usr/sbin/bmx7 dev=${IFACE}|g" /etc/systemd/system/bmx7.service
  185. sed -i "s|ExecStart=.*|ExecStart=/usr/local/sbin/olsrd2_static ${IFACE}|g" /etc/systemd/system/olsr2.service
  186. sed -i "s|ExecStart=.*|ExecStart=/usr/local/bin/babeld ${IFACE}|g" /etc/systemd/system/babel.service
  187. systemctl daemon-reload
  188. add_wifi_interface "$IFACE" "$WIFI_SSID" ad-hoc "$CHANNEL"
  189. # NOTE: Don't connect the secondary wifi device. hostapd will handle that by itself
  190. ifconfig bat0 up promisc
  191. brctl addbr "$BRIDGE"
  192. brctl addif "$BRIDGE" bat0
  193. ifconfig bat0 0.0.0.0
  194. ethernet_connected='0'
  195. if [ "$EIFACE" ] ; then
  196. if [[ "$EIFACE" != "$IFACE" ]] ; then
  197. ethernet_connected=$(cat "/sys/class/net/$EIFACE/carrier")
  198. if [[ "$ethernet_connected" != "0" ]]; then
  199. echo $'Trying ethernet bridge to the internet'
  200. brctl addif "$BRIDGE" "$EIFACE"
  201. ifconfig "$EIFACE" 0.0.0.0
  202. ifconfig "$EIFACE" up promisc
  203. echo $'End of internet bridge'
  204. sed -i "s|ExecStart=.*|ExecStart=/usr/sbin/bmx6 dev=${IFACE} dev=${EIFACE}|g" /etc/systemd/system/bmx6.service
  205. sed -i "s|ExecStart=.*|ExecStart=/usr/sbin/bmx7 dev=${IFACE} dev=${EIFACE}|g" /etc/systemd/system/bmx7.service
  206. sed -i "s|ExecStart=.*|ExecStart=/usr/local/sbin/olsrd2_static ${IFACE} ${EIFACE}|g" /etc/systemd/system/olsr2.service
  207. sed -i "s|ExecStart=.*|ExecStart=/usr/local/bin/babeld ${IFACE} ${EIFACE}|g" /etc/systemd/system/babel.service
  208. systemctl daemon-reload
  209. else
  210. echo $"$EIFACE is not connected"
  211. fi
  212. fi
  213. fi
  214. ifconfig "$BRIDGE" up
  215. dhclient "$BRIDGE"
  216. enable_mesh_seconary_wifi
  217. enable_mesh_firewall
  218. enable_mesh_scuttlebot
  219. enable_mesh_tor
  220. sed -i "s|server_name .*|server_name ${HOSTNAME}.local;|g" /etc/nginx/sites-available/git_ssb
  221. systemctl restart nginx
  222. if [ ! -f "$MESH_DEFAULT_PROTOCOL" ]; then
  223. echo 'bmx6' > "$MESH_DEFAULT_PROTOCOL"
  224. fi
  225. if grep -q "bmx6" "$MESH_DEFAULT_PROTOCOL"; then
  226. systemctl enable bmx6
  227. systemctl restart bmx6
  228. sed -i 's|<type>.*|<type>_bmx6._tcp</type>|g' /etc/avahi/services/routing.service
  229. fi
  230. if grep -q "bmx7" "$MESH_DEFAULT_PROTOCOL"; then
  231. systemctl enable bmx7
  232. systemctl restart bmx7
  233. sed -i 's|<type>.*|<type>_bmx7._tcp</type>|g' /etc/avahi/services/routing.service
  234. fi
  235. if grep -q "olsr" "$MESH_DEFAULT_PROTOCOL"; then
  236. IFACE=$(grep ExecStart "/etc/systemd/system/olsr2.service" | awk -F ' ' '{print $2}')
  237. mesh_generate_ipv6_address "$IFACE"
  238. systemctl enable olsr2
  239. systemctl restart olsr2
  240. sed -i 's|<type>.*|<type>_olsr2._tcp</type>|g' /etc/avahi/services/routing.service
  241. fi
  242. if grep -q "babel" "$MESH_DEFAULT_PROTOCOL"; then
  243. IFACE=$(grep ExecStart /etc/systemd/system/babel.service | awk -F ' ' '{print $2}')
  244. mesh_generate_ipv6_address "$IFACE"
  245. systemctl enable babel
  246. systemctl restart babel
  247. sed -i 's|<type>.*|<type>_babel._tcp</type>|g' /etc/avahi/services/routing.service
  248. fi
  249. systemctl restart avahi-daemon
  250. verify
  251. cat "$MESH_DEFAULT_PROTOCOL" > "$MESH_CURRENT_PROTOCOL"
  252. }
  253. function monitor {
  254. if [[ "$MESH_INTERFACE_TYPE" != 'wlan'* ]]; then
  255. return
  256. fi
  257. if [ -z "$IFACE" ] ; then
  258. echo 'error: unable to find wifi interface, not enabling batman-adv mesh'
  259. exit 723657
  260. fi
  261. clear
  262. echo ''
  263. echo $'*** Stopping network ***'
  264. echo ''
  265. stop
  266. echo "info: monitoring mesh network $WIFI_SSID on $IFACE"
  267. systemctl stop network-manager
  268. sleep 5
  269. clear
  270. echo ''
  271. echo $'*** Setting firewall rate limit ***'
  272. echo ''
  273. global_rate_limit
  274. clear
  275. echo ''
  276. echo $'*** Enabling wifi adaptor in monitor mode ***'
  277. echo ''
  278. # Might have to re-enable wifi
  279. rfkill unblock "$(rfkill list|awk -F: "/phy/ {print $1}")" || true
  280. ifconfig "$IFACE" down
  281. ifconfig "$IFACE" mtu 1532
  282. ifconfig "$IFACE" hw ether "$(assign_peer_address)"
  283. iwconfig "$IFACE" enc off
  284. iwconfig "$IFACE" mode monitor channel "$CHANNEL"
  285. sleep 1
  286. iwconfig "$IFACE" ap "$CELLID"
  287. modprobe batman-adv
  288. batctl if add "$IFACE"
  289. ifconfig "$IFACE" up
  290. horst -i "$IFACE"
  291. clear
  292. echo ''
  293. echo $'*** Restarting the network daemon. This may take a while. ***'
  294. echo ''
  295. # shellcheck disable=SC2119
  296. start
  297. }
  298. # optionally a file can contain the mesh interface type
  299. mesh_interface_type_file=/root/.mesh_interface_type
  300. if [ -f "$mesh_interface_type_file" ]; then
  301. MESH_INTERFACE_TYPE=$(head -n 1 < "$mesh_interface_type_file")
  302. if [[ "$MESH_INTERFACE_TYPE" == 'wlan'* ]]; then
  303. MESH_INTERFACE_TYPE='wlan'
  304. fi
  305. if [[ "$MESH_INTERFACE_TYPE" == 'eth'* ]]; then
  306. MESH_INTERFACE_TYPE='eth'
  307. fi
  308. fi
  309. mesh_protocol_init
  310. if [[ "$MESH_INTERFACE_TYPE" == 'eth'* ]]; then
  311. MESH_INTERFACE_TYPE='eth'
  312. fi
  313. update_wifi_adaptors "${MESH_INTERFACE_TYPE}"
  314. if [ ! "$IFACE" ]; then
  315. echo $'No wlan adaptor'
  316. exit 0
  317. fi
  318. if [ -e /etc/default/batctl ]; then
  319. # shellcheck disable=SC1091
  320. . /etc/default/batctl
  321. fi
  322. if ! grep -q "$IFACE" /proc/net/dev; then
  323. echo "Interface \$IFACE was not found"
  324. stop
  325. exit 1
  326. fi
  327. case "$1" in
  328. start|stop|status|monitor)
  329. $1
  330. ;;
  331. restart)
  332. clear
  333. echo ''
  334. echo $'*** Stopping mesh network connection ***'
  335. echo ''
  336. stop
  337. sleep 10
  338. clear
  339. echo ''
  340. echo $'*** Starting mesh network connection ***'
  341. echo ''
  342. # shellcheck disable=SC2119
  343. start
  344. ;;
  345. ping)
  346. batctl ping "$2"
  347. ;;
  348. data)
  349. watch -n1 "batctl s | grep mgmt | grep bytes"
  350. ;;
  351. ls|list)
  352. avahi-browse -atl
  353. ;;
  354. *)
  355. echo "error: invalid parameter $1"
  356. echo "usage: \$0 {start|stop|restart|status|ping|ls|list}"
  357. exit 2
  358. ;;
  359. esac
  360. exit 0