Возникла задача найти все живые устройства в сети. Эта задача легко решается с помощью пинга по всем адресам локальной сети и последующей печатью Arp-таблицы хоста. Проблема была лишь в том, что на Bash я ее еще не решал (в отличие от Python/Powershell)…
Чатжпт, по коням, у нас скрипт, возможно, на баше.
Ответ от нейросети я буду приводить в сокращенном виде.
1) Could you please provide me with bash script that:
– takes local network subnet from provided nic interface by parameter or subnet by parameter;
– makes icmp request (ping ip) for each ip in the provided subnet;
– prints all ip/mac pairs for IPv4 related to the provided network.
Let’s think step by step, do not hurry
# Step 2: Generate a list of IP addresses within the subnet
IFS=‘/’ read -ra SUBNET_ARRAY <<< “$SUBNET“ NETWORK=“${SUBNET_ARRAY[0]}“ PREFIXLEN=“${SUBNET_ARRAY[1]}“
IP_LIST=()
for (( i=1; i <= 254; i++ )); do IP=“$NETWORK.$i“ IP_LIST+=(“$IP“) done
2) Погоди, но сеть может быть с Netmask отличной от 24…
NUM_HOSTS=$((2**(32 – PREFIXLEN) – 2))
for (( i=1; i <= NUM_HOSTS; i++ )); do IP=“$NETWORK.$i“ IP_LIST+=(“$IP“) done
3) Тут я предположил, что неонка просто считает последнюю цифру нулем, почему и образовывает IP путем простого склеивания с адресом подсети, и попросил исправить это.
NETWORK_BASE=“${NETWORK_OCTETS[0]}.${NETWORK_OCTETS[1]}.${NETWORK_OCTETS[2]}.$((NETWORK_OCTETS[3] & ~(2**(32 – PREFIXLEN) – 1)))”
4) В целом уже было круто, но нейросеть тупила с формированием списка IP, по прежнему считая адреса вида 192.168.10.64.12 вполне легитимными.
Ок, чатик, подскажи как сложить в баше два числа
# Define your values a and b a=5 b=3
# Perform the addition
result=$((a + b))
5) В конструкции
SUBNET=$(ip addr show $NIC_INTERFACE | grep -oP ‘inet \K[^/]+’)
ты получаешь не адрес ПК с сетевой маской, а просто адрес пк.
To obtain the subnet (including the CIDR notation)
SUBNET=$(ip -o -f inet addr show dev “$NIC_INTERFACE“ | awk ‘{print $4}’)
Конечно, тут отсутствует защита от дурака.
Но все равно ВАУ! Полчаса трудов и результат готов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#!/bin/bash # Step 1: Get the local network subnet from a provided NIC interface or subnet parameter if [[ $# -eq 0 ]]; then echo "Usage: $0 <NIC_INTERFACE or SUBNET>" exit 1 fi if [[ -d /sys/class/net/$1 ]]; then NIC_INTERFACE="$1" SUBNET=$(ip -o -f inet addr show dev $NIC_INTERFACE | awk '{print $4}') else SUBNET="$1" fi # Step 2: Generate a list of IP addresses within the subnet IFS='/' read -ra SUBNET_ARRAY <<< "$SUBNET" NETWORK="${SUBNET_ARRAY[0]}" PREFIXLEN="${SUBNET_ARRAY[1]}" IP_LIST=() # Calculate the number of possible hosts in the subnet based on the prefix length NUM_HOSTS=$((2**(32 - PREFIXLEN) - 2)) # -2 to exclude network and broadcast addresses # Extract the octets from the network address IFS='.' read -ra NETWORK_OCTETS <<< "$NETWORK" for (( i=1; i <= NUM_HOSTS; i++ )); do LAST=$(($((NETWORK_OCTETS[3] & ~(2**(32 - PREFIXLEN) - 1))) + i )) IP="${NETWORK_OCTETS[0]}.${NETWORK_OCTETS[1]}.${NETWORK_OCTETS[2]}.${LAST}" IP_LIST+=("$IP") done # Step 3: Send ICMP requests (ping) to each IP address in the subnet for IP in "${IP_LIST[@]}"; do if ping -c 1 -W 1 "$IP" &> /dev/null; then # Step 4: Print the IP/MAC pairs for IPv4 addresses on the local network MAC=$(ip neighbour | grep -i "$IP" | awk '{print $5}') if [[ ! -z "$MAC" ]]; then echo "IP: $IP, MAC: $MAC" fi fi done |
nmap $SUBNET
ip ne
Слишком лехко )
Ну и результатом будут вообще все соседи, а не наша подсеть ))