#!/bin/bash # Usage: ./init_adhoc.sh # Example: ./init_adhoc.sh phy0 wlan0 adhocnet 36 1000 -95 0 1 2 3 set -e ### === INPUT ARGUMENTS === PHYNAME=$1 DEVNAME=$2 SSID=$3 CHANNEL=$4 TXPOWER=$5 NOISEFLOOR=$6 shift 6 NODES=($@) source /opt/scripts/mesh/node_addresses.sh # Check whether node is part of the network HOSTNAME=$(uname -n | cut -d. -f1) NODE_ID=$(echo "$HOSTNAME" | sed -E 's/[^0-9]*([0-9]+)$/\1/') NODE_ID=$((10#$NODE_ID)) NODE_INDEX=-1 for idx in "${!NODES[@]}"; do [[ ${NODES[$idx]} -eq $NODE_ID ]] && NODE_INDEX=$idx && break done if [[ $NODE_INDEX -lt 0 ]]; then echo "[!] Node ID $NODE_ID not found in list." exit 1 fi # Extract device number dev_number=$(echo "$DEVNAME" | grep -o '[0-9]\+$') ### === PATHS === devPath="/sys/class/net/" phyPath="/sys/kernel/debug/ieee80211/" ### === SYSTEM TUNING === echo "[*] Applying system optimizations..." sysctl -w net.core.rmem_max=8388608 sysctl -w net.core.wmem_max=8388608 sysctl -w net.core.rmem_default=8388608 sysctl -w net.core.wmem_default=8388608 sysctl -w net.core.optmem_max=8388608 sysctl -w net.ipv4.tcp_mem="8388608 8388608 8388608" sysctl -w net.ipv4.tcp_rmem="4096 87380 8388608" sysctl -w net.ipv4.tcp_wmem="4096 65536 8388608" sysctl -w net.ipv4.udp_mem="8388608 8388608 8388608" sysctl -w net.ipv4.udp_rmem_min=4096 sysctl -w net.ipv4.udp_wmem_min=4096 sysctl -w net.core.netdev_max_backlog=5000 sysctl -w net.ipv4.tcp_max_syn_backlog=5000 sysctl -w net.ipv4.tcp_syn_retries=9 sysctl -w net.ipv4.tcp_synack_retries=9 sysctl -w net.ipv4.tcp_no_metrics_save=1 sysctl -w net.ipv4.route.flush=1 echo 0 > /sys/module/tcp_cubic/parameters/hystart echo 0 > /sys/module/tcp_cubic/parameters/hystart_detect sysctl -w net.ipv4.neigh.default.base_reachable_time_ms=1200000 sysctl -w net.ipv4.neigh.default.mcast_solicit=25 sysctl -w net.ipv4.neigh.default.ucast_solicit=25 ### === CLEAN INTERFACES === if ip link show dev $DEVNAME &>/dev/null; then ip addr flush dev $DEVNAME ip link set $DEVNAME down || true iw dev $DEVNAME del || true fi phy_index=${PHYNAME//[!0-9]/} current_dev_on_phy=$(iw dev | awk -v phy="$phy_index" '$0 ~ "phy#"phy {getline; while ($1 == "Interface") {print $2; getline}}') if [[ ! -z "$current_dev_on_phy" ]]; then ip link set $current_dev_on_phy down || true iw dev $current_dev_on_phy del || true fi ### === INTERFACE CONFIG === echo "[*] Creating IBSS interface $DEVNAME on $PHYNAME..." iw phy $PHYNAME interface add $DEVNAME type ibss || { echo "[!] Failed to create interface. Ensure PHY is up." exit 1 } ip addr flush dev $DEVNAME ### === FREQUENCY SETUP === source /opt/scripts/mesh/freq.sh FREQ=${chan[$CHANNEL]} if [[ -z "$FREQ" ]]; then echo "[!] Channel $CHANNEL not found in freq.sh mapping" exit 1 fi ### === PHY PARAMS BEFORE IFACE UP === iw dev $DEVNAME set type ibss # These must be done *before* bringing interface up: iw phy $PHYNAME set antenna 3 3 iw phy $PHYNAME set retry short 7 long 4 iw phy $PHYNAME set rts off iw dev $DEVNAME set power_save off ### === BRING IFACE UP === ip link set $DEVNAME up sleep 1 # Optional: ARP suppression after iface is up sysctl -w net.ipv4.conf.$DEVNAME.arp_ignore=1 sysctl -w net.ipv4.conf.$DEVNAME.arp_announce=2 ### === JOIN IBSS === BSSID="02:11:87:7B:5E:01" echo "[*] Joining IBSS: SSID=$SSID FREQ=$FREQ MHz..." # iw dev $DEVNAME ibss leave || true sleep 1 # iw dev $DEVNAME ibss join $SSID $FREQ HT40 fixed-freq $BSSID || { # echo "Failed to join IBSS." # exit 1 # } iw dev $DEVNAME ibss join "$SSID" "$FREQ" HT40+ beacon-interval 1000 basic-rates 54 mcast-rate 54 || { echo "[!] Failed to join IBSS with basic/mcast rates." exit 1 } ### === SET TX POWER === iw dev $DEVNAME set txpower fixed $TXPOWER ### === ASSIGN IP === if [[ $dev_number -eq 0 ]]; then IP_ADDR=${phy0IP[$HOSTNAME]} BROADCAST_IP=${phy0IP["broadcast"]} elif [[ $dev_number -eq 1 ]]; then IP_ADDR=${phy1IP[$HOSTNAME]} BROADCAST_IP=${phy1IP["broadcast"]} fi if [[ -z "$IP_ADDR" ]]; then echo "[!] IP not found for $HOSTNAME" exit 1 fi ip addr add ${IP_ADDR}/24 broadcast $BROADCAST_IP dev $DEVNAME ### === ENABLE IP FORWARDING === if (( NODE_INDEX > 0 && NODE_INDEX < ${#NODES[@]} - 1 )); then echo "Enabling IP forwarding..." sysctl -w net.ipv4.ip_forward=1 fi ### === ADD ROUTES === for target_idx in "${!NODES[@]}"; do target_node=${NODES[$target_idx]} [[ $target_node -eq $NODE_ID ]] && continue if (( target_idx < NODE_INDEX )); then next_hop=${NODES[$((NODE_INDEX - 1))]} else next_hop=${NODES[$((NODE_INDEX + 1))]} fi target_ip=${phy0IP["apu$(printf "%02d" $target_node)"]} next_ip=${phy0IP["apu$(printf "%02d" $next_hop)"]} [[ -n "$target_ip" && -n "$next_ip" ]] && ip route add "$target_ip/32" via "$next_ip" dev "$DEVNAME" 2>/dev/null || true done ### === NOISE FLOOR === echo 0 > /sys/kernel/debug/ieee80211/${PHYNAME}/ath9k/ani echo ${NOISEFLOOR} > /sys/kernel/debug/ieee80211/${PHYNAME}/ath9k/nf_override ### === FIXED RATE (Optional) === echo 198 > /sys/kernel/debug/ieee80211/${PHYNAME}/rc/fixed_rate_idx echo "IBSS initialization complete for $DEVNAME ($IP_ADDR)"