Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Найти сеть которой принадлежит IP (перебрав все вложеные) / 5 сообщений из 5, страница 1 из 1
22.06.2016, 10:11
    #39260158
DeeZ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти сеть которой принадлежит IP (перебрав все вложеные)
Есть список сетей, в тч разбитые на более мелкие сети:
10.0.82.0/24
10.0.83.0/24 разбитая на две сети /25, одна из кторых разбита еще на две /26. В таблице все лежит так:
idipmaskINET_ATON(ip)1501677931522410.0.82.01511677934082510.0.83.01521677935362510.0.83.1281531677935362610.0.83.1281541677936042610.0.83.1961931677934082410.0.83.0

Есть, например IP 10.0.83.1 который принадлежит и сети с ID=151 и сети с ID=193. Но сеть 10.0.83.0/25 вложена в 10.0.83.0/24. по этому IP должен принадлежать именно 10.0.83.0/25 но не 10.0.83.0/24.
Есть более сложные варианты, когда, например нужно найти куда принадлежит 10.0.83.197:
10.0.83.0/24 -> 10.0.83.128/25 -> 10.0.83.196/26 ->10.0.83.197

Написал процедуру, по определению принадлежит ли IP сети.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Delimiter $$
Create Procedure isip(IN ipadd VARCHAR(50),IN ipanet VARCHAR(50),IN ipmask INT)
Begin
  Declare vid int;
  Declare var INT;
  SELECT (-1 << (32 - ipmask)) & INET_ATON(ipadd) = INET_ATON(ipanet) into vid;
  if vid then
      select ipadd, 'belong';	
  else
     select ipadd, 'not belong';	
  end if;
end;
$$


Никак не могу придумать как теперь сделать перебор всех сетей, и выбор той, к оторой самое больше значение ipmask.
...
Рейтинг: 0 / 0
22.06.2016, 10:49
    #39260171
DeeZ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти сеть которой принадлежит IP (перебрав все вложеные)
отвечу на первую часть вопроса сам.
переписал первую функцию:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Delimiter $$
Create Procedure useip(IN ipadd VARCHAR(50),IN ipanet VARCHAR(50),IN ipmask INT,IN iid INT)
Begin
  Declare vid int;
  Declare var INT;
  SELECT (-1 << (32 - ipmask)) & INET_ATON(ipadd) = INET_ATON(ipanet) into vid;
  if vid then
      select iid,ipanet, ipmask;	
  end if;
end;
$$


Вторая - занимается перебором:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Delimiter $$
Create Procedure findnet(IN ipadd VARCHAR(50))
Begin
  DECLARE done INT DEFAULT FALSE;
  DECLARE iid, isub, imask INT;
  DECLARE cur CURSOR FOR SELECT id,subnet,mask FROM subnets where mask < 33 ;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;    
Open cur;
WHILE not done  DO 
  FETCH cur INTO iid, isub, imask;
  /*select ipadd,iid,isub, imask;*/
  call useip(ipadd,INET_ATON(isub),imask,iid);
END WHILE;
Close cur; 
END;
$$


Осталось придумать как выбрать ту строку, у которой ipmask самая большая
...
Рейтинг: 0 / 0
22.06.2016, 12:26
    #39260280
DeeZ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти сеть которой принадлежит IP (перебрав все вложеные)
решил сам :)
Ищем сеть, и добавляем. если новая находка дает маску больше - обновляем ID подсети:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Delimiter $$
Create Procedure findnet(IN ipadd VARCHAR(50))
Begin
  DECLARE done INT DEFAULT FALSE;
  DECLARE iid, isub, imask INT;
  DECLARE cur CURSOR FOR SELECT id,subnet,mask FROM subnets;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;    
Open cur;
WHILE not done  DO 
  FETCH cur INTO iid, isub, imask;
  call useip(ipadd,INET_ATON(isub),imask,iid);
END WHILE;
Close cur; 
END;
$$



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Delimiter $$
Create Procedure useip(IN ipadd VARCHAR(50),IN ipanet VARCHAR(50),IN ipmask INT,IN idd INT)
Begin
  Declare vid int;
  Declare var INT;
  SELECT (-1 << (32 - ipmask)) & INET_ATON(ipadd) = INET_ATON(ipanet) into vid;
  if vid then
      SELECT mask into var FROM ipaddresses join subnets on subnets.id=ipaddresses.subnetId where ip_addr=INET_ATON(ipadd);
      if var then      
        if ipmask >  var then      
          /*UPDATE ipaddresses SET subnetId=iid WHERE ip_addr = INET_ATON('ipadd') limit 1;*/
          select 'update', idd, ipadd, hostname;
        end if; 
      else
        select 'insert', idd, ipadd, hostname; 
       /*INSERT INTO ipaddresses (subnetId,ip_addr,dns_name) VALUES(iid,INET_ATON('ipadd'),hostname);*/
      end if;
  end if;
end;
$$




ЗЫЖ мучаю phpipam
...
Рейтинг: 0 / 0
22.06.2016, 13:06
    #39260312
DeeZ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти сеть которой принадлежит IP (перебрав все вложеные)
А теперь без ошибок и правда работающий:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
Delimiter $$
Create Procedure useip(IN ipadd VARCHAR(50),IN ipanet VARCHAR(50),IN ipmask INT,IN idd INT, IN hostname VARCHAR(50))
Begin
  Declare vid int;
  Declare var INT;
  SELECT (-1 << (32 - ipmask)) & INET_ATON(ipadd) = INET_ATON(ipanet) into vid;
  if vid then
      SELECT mask into var FROM ipaddresses join subnets on subnets.id=ipaddresses.subnetId where ip_addr=INET_ATON(ipadd);
      if var then      
        if (ipmask >  var) then      
          UPDATE ipaddresses SET subnetId=idd WHERE ip_addr = INET_ATON(ipadd) limit 1;
        end if; 
      else
	   INSERT INTO ipaddresses (subnetId,ip_addr,dns_name) VALUES(idd,INET_ATON(ipadd),hostname);
      end if;
  end if;
end;
$$
...
Рейтинг: 0 / 0
22.06.2016, 14:29
    #39260384
netwind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти сеть которой принадлежит IP (перебрав все вложеные)
DeeZ, никогда не задумывались почему GeoIP хранит только непересекающиеся сети в предвычисленных отрезках ?
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Найти сеть которой принадлежит IP (перебрав все вложеные) / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]