Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Кто знает, как проверить IP?  [new]
lightspeed
Member

Откуда:
Сообщений: 143
Привет All,

В общем, такая проблема.
Есть таблица, в которой содержатся адрес хоста/сети и маска подсети. Т.е.
create table gates (
id NUMBER NOT NULL,
user_id NUMBER NOT NULL,
ipaddr VARCHAR2(15) DEFAULT '127.0.0.1' NOT NULL,
mask VARCHAR2(15) DEFAULT '255.255.255.255' NOT NULL
) tablespace users_s;

Авторизация гейта по IP.
Раньше использовались только адреса хостов, но, теперь понадобилось что-бы проходила авторизация хоста из пула адрес/маска.

Т.е. если ранее было все просто:
SELECT u.id, u.cash, g.id FROM gates g, users u WHERE g.ipaddr = ? AND u.id = g.user_id

То что делать теперь?!!!
Не возьму в толк, как быть...
:-(

Best regards,
lightspeed
16 дек 04, 19:05    [1187087]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
Elic
Member

Откуда:
Сообщений: 29984
Вот что значит выбрать неподходящий тип данных :)
Надо написать функцию вроде inet_aton (перевод строки ip-адреса в int). Тогда
... and bitand(inet_aton(:ip), inet_aton(mask)) = inet_aton(ipaddr) ...
16 дек 04, 19:50    [1187158]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
lightspeed
Member

Откуда:
Сообщений: 143
Elic
Вот что значит выбрать неподходящий тип данных :)


Elic, спасибо.

Толькотут вижу заковыку - как упаковать массив из 4х десятичныхв int/bin, в PL/SQL??

Best regards,
lightspeed
16 дек 04, 20:15    [1187181]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
Elic
Member

Откуда:
Сообщений: 29984
lightspeed
как упаковать массив из 4х десятичныхв int/bin, в PL/SQL??
Распарсить 'a.b.c.d' и return (a*256**3+b*256**2+c*256+d) не должно составить "заковыки" :)
16 дек 04, 20:28    [1187197]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
lightspeed
Member

Откуда:
Сообщений: 143
Elic,

В общем, с божъей помощью написал inet_aton.
:-)
Но, получил еще одну проблему именно в Oracle8i, теперь проблема с bitand.
Преверяю inet_aton - работает:
select inet_aton(:ip),inet_aton(:mask),inet_aton(:ipaddr)
from DUAL
Все показывается, все складывается вручную кк надо.
Но, как только:
bitand(inet_aton(:ip),inet_aton(:mask)) то
этот bitand != inet_aton(:ipaddr)!
Не могу понять в чем дело.

И еще, так можно писать:
select bitand(inet_aton(:ipaddr)) from dual;
А то у меня Oracle8i сразу dump на 500Kb вываливает.
Говорит что (29) not explicitly supported...

Best regards,
lightspeed
17 дек 04, 03:48    [1187552]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
Вячеслав Любомудров
Member

Откуда: Владивосток
Сообщений: 18484
Подобная проблема
17 дек 04, 04:18    [1187558]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
lightspeed
Member

Откуда:
Сообщений: 143
Вячеслав,

проблему с inet_aton я решил, как раз через умножение.
Вопрос в другом,
использую bitand(ipnum,masknum) для вычисления адреса сети и его дальнейшего сравнения.
Так вот, он мне выдает просто адрес хоста.
Вот пример запроса:
select to_number(bitand(to_number(inet_aton(:ipaddr)),to_number(inet_aton(:mask))) from DUAL;
Запрос выдает только :ipaddr, но никак не :netaddr.
Не могу понять, почему.

Best regards,
lightspeed
17 дек 04, 05:15    [1187582]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
Вячеслав Любомудров
Member

Откуда: Владивосток
Сообщений: 18484
Проблема скорее всего с переполнением и
SY из топика по предыдущей ссылке
...Because any value > 2**32-1 will cause overflow which means all bits will be set to 1...
И как вариант
fbsd> declare
  2  ipaddr number := 1370528731;  -- 81.176.155.219
  3  netmask number := 4294967040; -- 255.255.255.0
  4  begin
  5  dbms_output.put_line(bitand(ipaddr, netmask));
  6  end;
  7  /
declare
*
ERROR at line 1:
ORA-01426: numeric overflow
ORA-06512: at line 5


fbsd> declare
  2  ipaddr number := 1370528731;  -- 81.176.155.219
  3  netmask number := 4294967040; -- 255.255.255.0
  4  begin
  5  dbms_output.put_line(bitand(trunc(ipaddr/65536), trunc(netmask/65536))*65536+
  6                       bitand(mod(ipaddr, 65536), mod(netmask, 65536)) );
  7  end;
  8  /
1370528512  -- 81.176.155.0

PL/SQL procedure successfully completed.

17 дек 04, 06:22    [1187614]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
lightspeed
Member

Откуда:
Сообщений: 143
Да, Вячеслав. Вы оказались правы, дело именно в переполнении bitand.
Ладно, все хорошо, что хорошо кончается. А в общем, запрос заработал, теперь надо его оптимизировать...
Кстати, хорошая мысль хранить все IP в числовом виде, да вот только NAS их присылает в текстовом, вот и приходится выбирать. А так как кол-во запросов к IP с маской .255 превышает кол-во запросов к subnet, то в общем выбор ясен.

Спасибо, большое всем!

Best regards,
lightspeed
17 дек 04, 15:02    [1189474]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10046
lightspeed
Кстати, хорошая мысль хранить все IP в числовом виде, да вот только NAS их присылает в текстовом, вот и приходится выбирать.


Just add 4 derived columns and a trigger:

SQL> create table gates(ipaddr varchar2(20),ipaddr_part1 number,
  2  ipaddr_part2 number,ipaddr_part3 number,ipaddr_part4 number);

Table created.

SQL> CREATE OR REPLACE
  2    TRIGGER GATES_BIUR
  3      BEFORE INSERT
  4          OR
  5             UPDATE
  6      ON GATES
  7      FOR EACH ROW
  8      BEGIN
  9          EXECUTE IMMEDIATE 'SELECT ' || REPLACE(:NEW.IPADDR,'.',',') || ' FROM DUAL'
 10            INTO :NEW.IPADDR_PART1,
 11                 :NEW.IPADDR_PART2,
 12                 :NEW.IPADDR_PART3,
 13                 :NEW.IPADDR_PART4;
 14  END;
 15  /

Trigger created.

SQL> insert into gates(ipaddr) values('127.0.0.1');

1 row created.

SQL> select * from gates;

IPADDR               IPADDR_PART1 IPADDR_PART2 IPADDR_PART3 IPADDR_PART4
-------------------- ------------ ------------ ------------ ------------
127.0.0.1                     127            0            0            1

SQL> 

SY.
17 дек 04, 16:46    [1189911]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
lightspeed
Member

Откуда:
Сообщений: 143
To SY,
So, dunno.
I think in your case the better way to store the range between the first and the last of IP addresses than to store numbers.
So, you know, you wrong.

Best regards,
lightspeed
18 дек 04, 04:28    [1190728]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Кто знает, как проверить IP?  [new]
valensy
Member

Откуда:
Сообщений: 55
lightspeed, не поделитесь полезной вещью? :)
мне как раз нужно перевести порядка 20 тыс. айпи адресов в целочисленные значения.. :(
буду очень благодарна :)
11 мар 09, 13:56    [6910860]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
test_2008
Member

Откуда: Москва
Сообщений: 1209
valensy
lightspeed, не поделитесь полезной вещью? :)
мне как раз нужно перевести порядка 20 тыс. айпи адресов в целочисленные значения.. :(
буду очень благодарна :)


Как они хранятся ? В таблице ?
что мешает написать inet_ntoa и применить построчно ?

COMMIT;
11 мар 09, 15:12    [6911570]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
valensy
Member

Откуда:
Сообщений: 55
test_2008,

хранятся в таблице.. 2 колонки в каждой по 10 тыс адресов
inet_aton эьл ж для mysql..?
а мне нужно для оракла..
11 мар 09, 15:49    [6911945]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
test_2008
Member

Откуда: Москва
Сообщений: 1209
create or replace function inet_aton(a_IpStr in varchar2) return number
as
    l_IpNum     number          := 0;
    l_IpStr     varchar2(255)   := a_IpStr;
begin
    if l_IpStr is not null then
        while length(l_IpStr) > 0 loop
            if instr(l_IPStr,'.') > 0 then
                l_IpNum := l_IpNum * 256 +
                                     to_number(substr(l_IpStr,1,instr(l_IPStr,'.') - 1));
                l_IpStr := substr(l_IpStr,instr(l_IpStr,'.') + 1);
            else
                l_IpNum := l_IpNum * 256 + to_number(l_IpStr);
                l_IpStr := '';
            end if;
        end loop;
    end if;
    return l_IpNum;
end;
/

COMMIT;
11 мар 09, 15:56    [6911996]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
valensy
Member

Откуда:
Сообщений: 55
test_2008,

спасибо огромное.. ща буду экспериментировать
11 мар 09, 15:59    [6912022]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
test_2008
Member

Откуда: Москва
Сообщений: 1209
valensy
test_2008,

спасибо огромное.. ща буду экспериментировать


You are welcome

COMMIT;
11 мар 09, 16:05    [6912060]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
inet_aton
Guest
test_2008,

я бы добавил еще кляузу детерминистик навсяк случай...
11 мар 09, 17:23    [6912772]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
test_2008
Member

Откуда: Москва
Сообщений: 1209
inet_aton
я бы добавил еще кляузу детерминистик навсяк случай...


разумно

но думаю у девушки все айпишники разные
11 мар 09, 17:36    [6912852]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
valensy
Member

Откуда:
Сообщений: 55
есть и повторяющиеся ай пи..

все работает, спасибо огромное
скажите пожалуйста, а обратной функции у вас случайно нет (аналог inet_ntoa)? :)
очень пригодилась бы...

заранее благодарю
14 мар 09, 16:50    [6927172]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
utopiya
Member

Откуда:
Сообщений: 37
Хороший вопрос про inet_ntoa! присоединяюсь..
в поиске на эту тему ничего не обнаружено :(
14 мар 09, 18:31    [6927343]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10046
utopiya
Хороший вопрос про inet_ntoa! присоединяюсь..
в поиске на эту тему ничего не обнаружено :(


??? Right under your nose. Needs just a small adjustment.

SY.

Сообщение было отредактировано: 14 мар 09, 18:45
14 мар 09, 18:43    [6927357]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
utopiya
Member

Откуда:
Сообщений: 37
нашлось кое-что.. просто я запрашивал в поиске inet_ntoa, а нужно было ip адрес..
спасибо!
14 мар 09, 18:53    [6927370]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
valensy
Member

Откуда:
Сообщений: 55
и правда :)
спасибо!
разобралась :)
14 мар 09, 19:02    [6927381]     Ответить | Цитировать Сообщить модератору
 Re: Кто знает, как проверить IP?  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10046
Or much simpler:

declare
    ipaddr number := 1370528731;  -- 81.176.155.219
    hex varchar2(8);
begin
    hex := to_char(ipaddr,'FMXXXXXXXXXX');
    dbms_output.put_line(to_number(substr(hex,1,2),'XX') || '.' || to_number(substr(hex,3,2),'XX') || '.' ||
                         to_number(substr(hex,5,2),'XX') || '.' || to_number(substr(hex,7,2),'XX')) ;
end;
/

81.176.155.219

PL/SQL procedure successfully completed.

SQL> 

SY.
14 мар 09, 19:06    [6927388]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить