URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 2481
[ Назад ]

Исходное сообщение
"Не пойму"

Отправлено dooman , 20-Янв-04 01:32 
Поскажите пожалуйста почему не работает эта маленькая функция???!!!:
int  inet_pton_loose(const char *addr,int af)
{

struct in_addr k;
int  dst;


if(af==AF_INET){

        if( inet_pton(AF_INET,addr,&dst) ==0)
        {
                return(inet_aton(addr,&k));

        }
                }

if(af==AF_INET6){
        if( inet_pton(AF_INET6,addr,&dst) ==0)
        {
                return(inet_aton(addr,&k));

        }
                }

        return(inet_pton(af,addr,&dst));

}


Содержание

Сообщения в этом обсуждении
"Не пойму"
Отправлено asso , 20-Янв-04 18:24 
Она не работает потому что ты man inet_pton не прочитал.  Помимо того что эта функция в таком виде не имеет смысла, у тебя еще переполнение буфера есть.

В случае ошибки inet_pton возвращает 0.  В случае неправильно заданного протокола - отрицательное число.  В случае успеха - положительное число. В зависимости от протокола параметром dst должен быть указатель на структуру struct in_addr или struct in6_addr.  Подробности читай в мане.


"Не пойму"
Отправлено dooman , 20-Янв-04 20:04 
>Она не работает потому что ты man inet_pton не прочитал.  Помимо
>того что эта функция в таком виде не имеет смысла, у
>тебя еще переполнение буфера есть.
>
>В случае ошибки inet_pton возвращает 0.  В случае неправильно заданного протокола
>- отрицательное число.  В случае успеха - положительное число. В
>зависимости от протокола параметром dst должен быть указатель на структуру struct
>in_addr или struct in6_addr.  Подробности читай в мане.
Ой блин...видимо я просто пересидел, если честно то только проснулся, но dst не обязательно должен быть указатель на структуру например return(dst) и потом вывод его приводят к корректному результату а вот inet_aton там да там только указатель на саму структуру


"Не пойму"
Отправлено asso , 21-Янв-04 05:51 
>Ой блин...видимо я просто пересидел, если честно то только проснулся, но dst
>не обязательно должен быть указатель на структуру например return(dst) и потом
>вывод его приводят к корректному результату а вот inet_aton там да
>там только указатель на саму структуру

В функции inet_pton параметр dst - указатель на структуру.  Обязательно.  Прочитай man inet_pton раз мне не веришь.


"Не пойму"
Отправлено dooman , 21-Янв-04 17:26 
>>Ой блин...видимо я просто пересидел, если честно то только проснулся, но dst
>>не обязательно должен быть указатель на структуру например return(dst) и потом
>>вывод его приводят к корректному результату а вот inet_aton там да
>>там только указатель на саму структуру
>
>В функции inet_pton параметр dst - указатель на структуру.  Обязательно.  
>Прочитай man inet_pton раз мне не веришь.
inet_pton(3)               Linux Programmer's Manual              inet_pton(3)

NAME
       inet_pton - Create a network address structure

SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>
       #include <arpa/inet.h>

       int inet_pton(int af, const char *src, void *dst);

У меня в мане так... вроде указатель на переменну пустого типа


"Не пойму"
Отправлено asso , 21-Янв-04 19:04 
man надо читать до конца.  Читай дальше, там через два абзаца про параметр dst написано.  Еще ниже написано про то что возвращает эта функция.  Первые два абзаца то же прочитать не забудь.  На раздел BUGS обрати внимание.  По ссылкам в SEE ALSO походи для общего развития.  Короче, прочитай его целиком и убедись что все именно так как я описал с самого начала.

"Не пойму"
Отправлено dooman , 21-Янв-04 20:15 
>man надо читать до конца.  Читай дальше, там через два абзаца
>про параметр dst написано.  Еще ниже написано про то что
>возвращает эта функция.  Первые два абзаца то же прочитать не
>забудь.  На раздел BUGS обрати внимание.  По ссылкам в
>SEE ALSO походи для общего развития.  Короче, прочитай его целиком
>и убедись что все именно так как я описал с самого
>начала.
Cорри, может я английский и не очень хорошо знаю(так и не понял приводит он его к вду структуры и копирует в dst или как по дугому) но вот этот код работает вполне корректно:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>

int  inet_pton_loose(const char *addr,int af)
{

struct in_addr *k;
int  dst;


if(af==AF_INET){

        if( inet_pton(AF_INET,addr,&dst) ==0)
        {
                printf("inet_pton==0\n");
                inet_aton(addr,k);
                return(k->s_addr);

        }
                }

if(af==AF_INET6){
        if( inet_pton(AF_INET6,addr,&dst) ==0)
        {
                printf("inet_pton==0\n");
                inet_aton(addr,k);
                return(k->s_addr);
        }
                }

        return(dst);

}

int main(int argc,char *argv[])
{
        if(argc<1){
                printf("No arguments\n");
                exit(1);
                }

        //if(argv[2]=="AF_INET")
        //      printf("%i\n",inet_pton_loose(argv[1],AF_INET));
        //if(argv[2]=="AF_INET6")
        //      printf("%i\n",inet_pton_loose(argv[1],AF_INET6));

        printf("%i\n",inet_pton_loose(argv[1],AF_INET));
return 0;
}

Правда  2 if'a закоментированых не работает


"Не пойму"
Отправлено asso , 22-Янв-04 07:36 
Учи английский, потому что без английского невозможно быть программистом.

Да, это _иногда_ работает, но только потому что sizeof(int) == sizeof(struct in_addr).  Если ввести адрес с ошибкой, то в зависимости от внешних условий программа может выпасть в кору.  Если inet_pton вернул 0 то в случае AF_INET функция inet_aton то же всегда вернет 0.  В случае AF_INET6 inet_aton может сработать если адрес был IPv4.  Помимо этого у тебя происходит запись в случайную область памяти и переполнение буфера.  В случае IPv6 твоя функция в любом случае вернет бессмысслицу, потому что в IPv6 адрес в int не влезет.  Кроме того, адрес - это беззнаковое целое а ты его используешь как знаковое, из-за чего могут быть проблемы позже.

Если тебе надо преобразовать адрес IPv4 то пиши так:

u_int32_t inet_pton_loose(const char *addr)
{
    struct in_addr k;
    if (inet_pton(AF_INET, addr, &k) > 0)
        return k.s_addr;
    else
        return 0;
}

Для IPv6 аналогично только структура будет in6_addr.  И не забывай что в IPv6 адрес занимает 16 байт.

Сравнение строк в Си делается при помощи функции strcmp.  Читай man strcmp.


"Не пойму"
Отправлено dooman , 22-Янв-04 16:54 
>Учи английский, потому что без английского невозможно быть программистом.
>
>Да, это _иногда_ работает, но только потому что sizeof(int) == sizeof(struct in_addr).
> Если ввести адрес с ошибкой, то в зависимости от внешних
>условий программа может выпасть в кору.  Если inet_pton вернул 0
>то в случае AF_INET функция inet_aton то же всегда вернет 0.
> В случае AF_INET6 inet_aton может сработать если адрес был IPv4.
> Помимо этого у тебя происходит запись в случайную область памяти
>и переполнение буфера.  В случае IPv6 твоя функция в любом
>случае вернет бессмысслицу, потому что в IPv6 адрес в int не
>влезет.  Кроме того, адрес - это беззнаковое целое а ты
>его используешь как знаковое, из-за чего могут быть проблемы позже.
>
>Если тебе надо преобразовать адрес IPv4 то пиши так:
>
>u_int32_t inet_pton_loose(const char *addr)
>{
>    struct in_addr k;
>    if (inet_pton(AF_INET, addr, &k) > 0)
>        return k.s_addr;
>    else
>        return 0;
>}
>
>Для IPv6 аналогично только структура будет in6_addr.  И не забывай что
>в IPv6 адрес занимает 16 байт.
>
>Сравнение строк в Си делается при помощи функции strcmp.  Читай man
>strcmp.


ааааа...спасибо. Да про строки я чё то забыл а inet_aton мне нужен был чтобы обабатывать неправильные адреса(например 123.5) которые inet_pton не
может. Только inet_aton работает только с IPv4 как я понял а как преобразовать адрес IPv4 k IPv6 я так и не понял ну и хрен с ним.
Спасибо за всё!!!