The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Как перечислить подряд все IP из подсети?"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"Как перечислить подряд все IP из подсети?"  +/
Сообщение от Collins on 09-Окт-09, 21:33 
Есть подсеть, например, 192.168.0.0/30 или шире 10.0.0.0/16.
Как в shell скрипте получить список всех IP адресов от первого "нулевого" до последнего широковещательного?
Список в столбик ли, в строчку ли через разделитель - не важно.

Ниже пример, стесняюсь показать, наваял. Как сделать более элегантно и более быстро?
Поскольку скрипт для других целей использует Postgresql, то мне в примере было допустимо использовать Postgresql, иначе конечно было бы лучше :) без такой монструозности.

Пример:


#!/bin/bash

# PostgreSQL shell
PSQL_PSQL=psql

# any valid database
PSQL_DB_NAME="postgres"

PSQL_USER="root"

# network id
LAN_ID=192.168.0.0/30

ip_first=`${PSQL_PSQL} -qtA -c "SELECT host('${LAN_ID}');" ${PSQL_DB_NAME} ${PSQL_USER}`
ip_last=`${PSQL_PSQL} -qtA -c "SELECT host(broadcast('${LAN_ID}'));" ${PSQL_DB_NAME} ${PSQL_USER}`

i=0 ; j=0
while [ $j == 0 ] ; do
   insertion_str="SELECT inet '${ip_first}' + ${i}"
   ip_middle="$( ${PSQL_PSQL} -qtA -c "${insertion_str}" ${PSQL_DB_NAME} ${PSQL_USER} )"

   echo "${ip_middle}"
   i=$(($i+1))

   insertion_str="SELECT 'stop_here' AS stop_here WHERE inet '${ip_middle}' = inet '${ip_last}'"
   feedback="$( ${PSQL_PSQL} -qtA -c "${insertion_str}" ${PSQL_DB_NAME} ${PSQL_USER} )"
   [ "${feedback}" == "stop_here" ] && j=1
done


Результат:

192.168.0.0
192.168.0.1
192.168.0.2
192.168.0.3

Высказать мнение | Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Как перечислить подряд все IP из подсети?"  +/
Сообщение от Vitaly_loki (ok) on 09-Окт-09, 23:08 
>[оверквотинг удален]
>   [ "${feedback}" == "stop_here" ] && j=1
>done
>
>Результат:
>
 
>192.168.0.0
>192.168.0.1
>192.168.0.2
>192.168.0.3
>

#!/bin/sh

for i in `seq 1 254`; #подставь свой диапазон
do echo 192.168.0.$i; #подставь свою подсеть
done

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Как перечислить подряд все IP из подсети?"  +/
Сообщение от Collins on 09-Окт-09, 23:44 
>for i in `seq 1 254`; #подставь свой диапазон
>do echo 192.168.0.$i; #подставь свою подсеть
>done

А если 10.20.16.0/20 (шир.веш. 10.20.31.255), то код серьёзно сложнее. Подсети могут произвольно меняться.

Возможно путь должен быть:


4 octet ip decimal -> ip binary -> ip decimal
while true ; do
  ip decimal -> ip binary -> 4 octet ip binary -> 4 octet ip decimal
  echo "4 octet ip decimal"
  ip decimal ++
done

Или использовать готовую, но неизвестную мне утилиту...
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Как перечислить подряд все IP из подсети?"  +/
Сообщение от Collins on 10-Окт-09, 00:33 
По прежнему интересно: кто что более эффективное придумал и сделал.

Вычисление ш.в. адреса я не пока не сделал.
Кроме вычисления ш.в. адреса, только shell командами, вот:


#!/bin/bash

function dec2bin () # converter for a $1 number from decimal number system binary with $2 bits width
{
   value=$1
   base=2
   number_plates=$(($2-1))
   result=""

   i=0
   [ $value -eq 0 ] && result="0"
   while [ $value -gt 0 ]
   do
      reminder=$((${value}%${base}))
      value=$((${value}/${base}))
      result="$reminder$result"
      i=$(($i+1))
   done
   for i in $(seq 0 $number_plates) ; do
      [ -z ${result:$i:1} ] && result="0$result"  
   done
   echo -n "$result"
}

function ip2dec () # $1 is IPv4, output is the ip decimal value
{
   arg_ip=$1
   # split to octets; octet1 is left, octet4 is right
   octet1="${arg_ip%%.*}" ; arg_ip="${arg_ip#*.}"
   octet2="${arg_ip%%.*}" ; arg_ip="${arg_ip#*.}"
   octet3="${arg_ip%%.*}" ; arg_ip="${arg_ip#*.}"
   octet4="${arg_ip%%.*}"

   # get single number decimal ip; catenate binary value into single binary number; BASh arithmetic is decimal... value will be auto-converted
   (( arg_ip=2#$( dec2bin ${octet1} 8 )$( dec2bin ${octet2} 8 )$( dec2bin ${octet3} 8 )$( dec2bin ${octet4} 8 ) ))

   echo -n "${arg_ip}"
}

ip_first="192.168.0.0"
ip_last="192.168.0.3"

# get single number decimal ip
the_ip=$( ip2dec ${ip_first} )
ip_last=$(( $( ip2dec ${ip_last} ) + 1 ))

while [ "${the_ip}" != "${ip_last}" ] ; do
   #echo -e "\nDecimal:\t${the_ip}"
   #echo -e "Binary:\t\t$( dec2bin ${octet1} 8 )$( dec2bin ${octet2} 8 )$( dec2bin ${octet3} 8 )$( dec2bin ${octet4} 8 )"

   ip_to_print=$( dec2bin ${the_ip} 32 )

   (( octet1=2#${ip_to_print:0:8} ))
   (( octet2=2#${ip_to_print:8:8} ))
   (( octet3=2#${ip_to_print:16:8} ))
   (( octet4=2#${ip_to_print:24:8} ))

   echo -e "4 octet:\t${octet1}.${octet2}.${octet3}.${octet4}"
   ((the_ip++))
done


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Как перечислить подряд все IP из подсети?"  +/
Сообщение от Vitaly_loki (ok) on 10-Окт-09, 01:07 
>[оверквотинг удален]
>
>   (( octet1=2#${ip_to_print:0:8} ))
>   (( octet2=2#${ip_to_print:8:8} ))
>   (( octet3=2#${ip_to_print:16:8} ))
>   (( octet4=2#${ip_to_print:24:8} ))
>
>   echo -e "4 octet:\t${octet1}.${octet2}.${octet3}.${octet4}"
>   ((the_ip++))
>done
>

Сорри, видимо я вас неправильно понял сначала (думал вам надо было просто заполнить много IP-адрес автоматически), на Перле модуль есть, к-й уммет делать то, что вам надо... К сожалению, в названии не уверен, вроде Net::IP хотя не уверен точно..

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "Как перечислить подряд все IP из подсети?"  +/
Сообщение от temny email(??) on 10-Окт-09, 08:56 
Классная задачка - сразу захотелось решить. Вот что у меня получилось:

a='10.20.16.0/20';
ip=${a/\/*};mask=${a/*\/};ip_array=(${ip//./ });for((i=0,b=0;i<4;i++));do b=$((b<<8));
b=$((b+ip_array[i]));done;f=$((b&(4294967295<<(32-mask))));l=$((b|(4294967295>>mask)));
while [ $f -le $l ];do for i in 24 16 8 0;do echo -n $(((f&(255<<i))>>i));
[ $i -ne 0 ] && echo -n . || echo;done;f=$((f+1));done

Результат:


10.20.16.0
10.20.16.1
10.20.16.2
10.20.16.3
10.20.16.4
10.20.16.5
10.20.16.6
10.20.16.7
10.20.16.8
10.20.16.9
...
10.20.31.246
10.20.31.247
10.20.31.248
10.20.31.249
10.20.31.250
10.20.31.251
10.20.31.252
10.20.31.253
10.20.31.254
10.20.31.255

PS На всякий - у меня bash-4.0.33

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Как перечислить подряд все IP из подсети?"  +/
Сообщение от pavel_simple (ok) on 10-Окт-09, 01:10 
>[оверквотинг удален]
>Возможно путь должен быть:
>
 
>4 octet ip decimal -> ip binary -> ip decimal
>while true ; do
>  ip decimal -> ip binary -> 4 octet ip binary -> 4 octet ip decimal
>  echo "4 octet ip decimal"
>  ip decimal ++
>done
>

>Или использовать готовую, но неизвестную мне утилиту...

утилита эта назыывется ipcalc

а в остальном.... в остальном ... PostgreSQL обладает большим кол-вом функций работы с ip диапазонами

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Как перечислить подряд все IP из подсети?"  +/
Сообщение от pavel_simple (ok) on 10-Окт-09, 01:10 
>[оверквотинг удален]
>>  echo "4 octet ip decimal"
>>  ip decimal ++
>>done
>>
>>Или использовать готовую, но неизвестную мне утилиту...
>
>утилита эта назыывется ipcalc
>
>а в остальном.... в остальном ... PostgreSQL обладает большим кол-вом функций работы
>с ip диапазонами

P.S. бОльшим

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "Как перечислить подряд все IP из подсети?"  +/
Сообщение от jd (??) on 10-Окт-09, 08:44 
Будет работать с башем не меньше 3-й версии.
#!/bin/bash

read NET WIDTH <<< `tr / ' ' <<< "$1"`
read IP1 IP2 IP3 IP4 <<< `tr . ' ' <<< "$NET"`

MASK=$(( (0xffffffff << $((32 - WIDTH))) & 0xffffffff ))
MINADDR=$(( ((IP1 << 24) | (IP2 << 16) | (IP3 << 8) | IP4) & MASK ))
MAXADDR=$(( MINADDR | (0xffffffff ^ MASK) ))

printip()
{ echo $(( ($1>>24) )).$(( ($1>>16)&0xff )).$(( ($1>>8)&0xff )).$(($1&0xff)); }

while (( MINADDR <= MAXADDR )); do
  printip $MINADDR
  MINADDR=$((MINADDR+1))
done

Вызов:

$ ./ip-list.sh 10.0.0.96/29
10.0.0.96
10.0.0.97
10.0.0.98
10.0.0.99
10.0.0.100
10.0.0.101
10.0.0.102
10.0.0.103

Развлекайтесь.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "Как перечислить подряд все IP из подсети?"  +/
Сообщение от temny email(??) on 10-Окт-09, 09:42 
Классное кунг-фу :)
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру