Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
365 / 124 / 22
Регистрация: 08.01.2015
Сообщений: 1,418
Записей в блоге: 2

Некорректно работает функция inet_ntoa

26.07.2017, 20:56. Показов 3959. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть код:
C
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <net/if.h>
#include <stdio.h>
#include <string.h>
#include <linux/socket.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <inttypes.h>
#include <netdb.h>
 
struct ifparam {
    __u32 ip;   // IP адрес
    __u32 mask; // маска подсети
} ifp;
 
 
int getifconf(__u8 *intf, struct ifparam *ifp)
{
    int fd;
    struct sockaddr_in s;
    struct ifreq ifr; // см. <linux/if.h>
 
    memset((void *)&ifr, 0, sizeof(struct ifreq));
    if((fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) return (-1);
 
    sprintf(ifr.ifr_name,"%s",intf);
 
/*
 * Определяем IP адрес сетевого интерфейса
 */
    if(ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
    perror("ioctl SIOCGIFADDR");
    return -1;
    }
    memset((void *)&s, 0, sizeof(struct sockaddr_in));
    memcpy((void *)&s, (void *)&ifr.ifr_addr, sizeof(struct sockaddr));
    memcpy((void *)&ifp->ip, (void *)&s.sin_addr.s_addr, sizeof(__u32));
 
    return 0;
}
 
 
int main()
{
/*
 * Получаем параметры сетевого интерфейса eth0 
 */
    if(getifconf("eth0", &ifp) < 0) {
    perror("getifconf");
    return -1;
    }
 
   char *ac = "localhost";
   struct hostent *hosten= gethostbyname(ac);
   char * ip1=(hosten->h_addr_list[0]);
   printf("IP-адрес для localhost: %s\n", ip1);
 
/*
 * Отобразим полученные параметры сетевого интерфейса
 */
 
  printf("IP адрес (__U32): %"PRIi32"\n",ifp.ip);
  printf("IP адрес (char):  %d\n", inet_ntoa(ifp.ip));
  printf("Маска подсети (char): %d\n",inet_ntoa(ifp.mask));
 
    return 0;
}
Типичный результат его работы:
IP-адрес для localhost: 
IP адрес (__U32): -2104383296
IP адрес (char): 369350424
Маска подсети (char): 369350424

Добавлено через 5 минут
Возникли вопросы:
1) Почему функция inet_ntoa возвращает в данном случае целое значение (если сделать при выводе %s, то будет warning и вывод не сработает), а не char?
2) Почему некоторые результаты (например, в данном случае - IP адрес (__U32) ) могут быть отрицательными?
3) Почему поля структуры в некоторых случаях получаются как -> а в других случаях как .
4) Почему адрес для localhost выводится в виде иероглифа?

Добавлено через 46 секунд
5) Почему IP-адрес и маска сети всегда совпадают?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.07.2017, 20:56
Ответы с готовыми решениями:

Написать пример, показывающий нерентерабельность функции inet_ntoa()
Привет, друзья. Подскажите какой-нибудь код, чтобы показать нерентабельность этой функции, мол, у неё буфер портиться. Не могу сам...

Функция некорректно работает
Функция компилируется, но постоянно один и тот же ответ. y=0000... Где допущена ошибка? #include &lt;stdio.h&gt; #include...

Функция работает некорректно
Добрый день! Сделал функцию, которая должна удалить определённый символ в определённом тексте. Принцип работы: функция конкатенирует всё,...

12
191 / 151 / 61
Регистрация: 08.04.2010
Сообщений: 1,032
26.07.2017, 23:19
В linux для вызова функций прямого доступа к железу нужны права администратора.
0
365 / 124 / 22
Регистрация: 08.01.2015
Сообщений: 1,418
Записей в блоге: 2
27.07.2017, 00:58  [ТС]
Вопрос 1 снимается. Оказывается, нужно делать преобразование типа
C
1
u_long IpAddr=ntohl(*((u_long *)(hosten -> h_addr_list[i])));
и затем, преобразовывая в целые части, по отдельности

Добавлено через 6 минут
вычленять каждую из 4-х составных частей IP-адреса. Остается только сказать "мда". Ну, неужели об этом сложно было сказать в документации.
Остальные вопросы остаются.

Добавлено через 3 минуты
Цитата Сообщение от Dovgon Посмотреть сообщение
нужны права администратора
Для той программы - да, я ее запускаю через sudo (потому, что там идет обращение к сетевой карте через пакетные сокеты). А эта, вроде, не обращается к железу.

Добавлено через 2 минуты
Вот как вычленение происходит (на примере второй слева части IP-адреса):
C
1
Ip2=(int)( IpAddr>>16 ) & 0xff;
Вместо 0xff можно писать 255 в десятичном виде - результат не меняется.

Добавлено через 19 минут
Странно. однако. Выводя
C
1
2
3
4
  printf("IpAddr: %lu\n", IpAddr);
  printf("IP адрес (__U32): %"PRIi32"\n",ifp.ip);
     printf("IP адрес (char):  %d\n", inet_ntoa(ifp.ip));
     printf("IP адрес1 (inet_ntoa(IpAddr)):  %d\n", inet_ntoa(IpAddr));
получается типичный результат:
IpAddr: 2130706433
IP адрес (__U32): -2104383296
IP адрес (char): 932112152
IP адрес1 (inet_ntoa(IpAddr)): 932112152

Т.е. IP-адреса, определенные через inet_ntoa, совпадают. Но, при этом аргументы этой функции - НЕ совпадают. Т.е.
IpAddr НЕ РАВНО ifp.ip
Почему?
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
27.07.2017, 14:52
Цитата Сообщение от Dovgon Посмотреть сообщение
В linux для вызова функций прямого доступа к железу нужны права администратора.
Причем тут прямой доступ к железу? Это вызов POSIX функции.

Цитата Сообщение от Htext Посмотреть сообщение
printf("IP адрес (char): %d\n", inet_ntoa(ifp.ip));
Это что за магия? Каким образом оно должно рабоать (%d != %s)

char *inet_ntoa(struct in_addr in);
https://linux.die.net/man/3/inet_ntoa

Пересмотрите свой код. И маны. И поправьте так что-бы оно хоть теоретически было правильно.

Добавлено через 17 минут
C++
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
44
#include <sys/ioctl.h>
 
#include <net/if.h>
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#include <arpa/inet.h>
 
int get_addr(const char *intf, struct in_addr *addr)
{
    int fd;
    if((fd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
    {
        return -1;
    }
 
    struct ifreq ifr = {};
    strncpy(ifr.ifr_name, intf, IFNAMSIZ);
 
    if(ioctl(fd, SIOCGIFADDR, &ifr) < 0)
    {
        perror("ioctl SIOCGIFADDR");
        return -1;
    }
 
    *addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
    return 0;
}
 
int main()
{
    struct in_addr addr;
    if (get_addr("enp5s0", &addr) < 0)
    {
        perror("get_addr");
        return -1;
    }
 
    printf("IP адрес (char):  %s\n", inet_ntoa(addr));
 
    return 0;
}
1
365 / 124 / 22
Регистрация: 08.01.2015
Сообщений: 1,418
Записей в блоге: 2
27.07.2017, 21:28  [ТС]
Цитата Сообщение от stima Посмотреть сообщение
Каким образом оно должно рабоать (%d != %s)
Я уже писал, что если применить %s, то компилятор выдает Warning и программа не работает.
Именно потому и задал я вопрос, что эта функция почему-то возвращает ЦЕЛОЕ значение.

Добавлено через 8 минут
Цитата Сообщение от stima Посмотреть сообщение
enp5s0
А это что такое?

Добавлено через 6 минут
Хотя, в Вашем коде эта функция выдает значение типа char, однако... Т.е. работает, как и должно быть. Но, почему же в моем коде она выдает целое значение? И, несмотря на это - путем указанных мной манипуляций - она все же выдает IP-адреса ресурса, к которому обращается программа.
Кто может объяснить такие странности?...

Добавлено через 39 минут
Цитата Сообщение от stima Посмотреть сообщение
IFNAMSIZ
Что это такое? Что-то не могу найти.
0
191 / 151 / 61
Регистрация: 08.04.2010
Сообщений: 1,032
28.07.2017, 01:04
ioctl - используются для выполнения над устройством управляющих действий, которые не обеспечиваются регулярными POSIX вызовами (read(), write(), lseek()).
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
28.07.2017, 11:36
Цитата Сообщение от Htext Посмотреть сообщение
А это что такое?
Это имя моего интерфейса.

Цитата Сообщение от Htext Посмотреть сообщение
Хотя, в Вашем коде эта функция выдает значение типа char, однако... Т.е. работает, как и должно быть. Но, почему же в моем коде она выдает целое значение? И, несмотря на это - путем указанных мной манипуляций - она все же выдает IP-адреса ресурса, к которому обращается программа.
Кто может объяснить такие странности?...
Подключите <arpa/inet.h>

Цитата Сообщение от Htext Посмотреть сообщение
Что это такое? Что-то не могу найти.
https://www.gnu.org/software/l... aming.html

Цитата Сообщение от Dovgon Посмотреть сообщение
ioctl - используются для выполнения над устройством управляющих действий, которые не обеспечиваются регулярными POSIX вызовами (read(), write(), lseek()).
Ну ок, ioctl там не POSIX. Но все равно для него не нужны, конкретно в этом случае, рут права.
1
365 / 124 / 22
Регистрация: 08.01.2015
Сообщений: 1,418
Записей в блоге: 2
30.07.2017, 20:49  [ТС]
stima
Если указать интерфейс eth0, то программа выдает некий Ip-адрес, который явно не мой. По крайней мере, на сайте 2ip.ru показывает совсем другой адрес, близко не тот. В частности, выдается 192.168.145.130. Это что за адрес?
А мой код:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char *ac = "localhost";
   struct hostent *hosten= gethostbyname(ac);
 
int cnt;
u_long IpAddr;
for( cnt=0 ; hosten->h_addr_list[cnt] != NULL ; cnt++ ) {
     int Ip1,Ip2,Ip3,Ip4;
       IpAddr=ntohl(*((u_long *)(hosten -> h_addr_list[cnt])));
     Ip1=(int)( IpAddr>>24 ) & 0xff;
     Ip2=(int)( IpAddr>>16 ) & 0xff;
     Ip3=(int)( IpAddr>>8 ) & 0xff;
     Ip4=(int)( IpAddr&0xff );
     printf("Entry \%d = \%d.\%d.\%d.\%d\n",cnt,Ip1,Ip2,Ip3,Ip4);
 
  }
выдает 127.0.0.1 (т.е. локальный адрес).
Если вместо localhost ввести имя какого-нибудь сайта- то выдается его IP-адрес (совпадает с результатом на 2ip.ru).
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
30.07.2017, 21:02
Это внешний адрес - тот который дает Вам провайдер для выхода в мир. http://ip-address.ru/
0
365 / 124 / 22
Регистрация: 08.01.2015
Сообщений: 1,418
Записей в блоге: 2
31.07.2017, 09:41  [ТС]
Цитата Сообщение от stima Посмотреть сообщение
Это внешний адрес - тот который дает Вам провайдер для выхода в мир.
Я тоже так вначале подумал, но, ни по Вашей ссылке, ни по 2ip.ru - этот адрес близко не совпадает. Т.е. даже нет ни одного аналогичного числа (из четырех).

Добавлено через 12 минут
Может, вместо eth0 надо какое другое имя указать? Что-то я уже вообще запутался.
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
31.07.2017, 11:26
eth0 [N] это имя интерфейса. Вы можете посмотреть конфигурацию Вашей сети с помощью
Bash
1
ip a
Цитата Сообщение от Htext Посмотреть сообщение
Я тоже так вначале подумал, но, ни по Вашей ссылке, ни по 2ip.ru - этот адрес близко не совпадает. Т.е. даже нет ни одного аналогичного числа (из четырех).
Не совпадает с чем?
0
365 / 124 / 22
Регистрация: 08.01.2015
Сообщений: 1,418
Записей в блоге: 2
31.07.2017, 21:25  [ТС]
Цитата Сообщение от stima Посмотреть сообщение
Не совпадает с чем?
Не совпадает с IР-адресом, который выдает приведенный Вами код.

Добавлено через 11 минут
Сейчас посмотрел конфигурацию сети (ip a) - как ни странно, показывает ТОТ САМЫЙ адрес, что и Ваш код... А почему же тогда интернет-сервисы (ip-address.ru, 2ip.ru) определяют его иначе? Не связано ли это с тем, что у меня Linux в виртуальной машине запущен?
0
365 / 124 / 22
Регистрация: 08.01.2015
Сообщений: 1,418
Записей в блоге: 2
03.08.2017, 21:03  [ТС]
Цитата Сообщение от Htext Посмотреть сообщение
Не связано ли это с тем, что у меня Linux в виртуальной машине запущен?
Да, оказывается, именно с этим и связано: https://www.cyberforum.ru/c-li... st10662842
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.08.2017, 21:03
Помогаю со студенческими работами здесь

Функция работает некорректно
Здравствуйте! Задача, написать функцию myfuc по заданному вызову ее int main(int argc, char *argv) { char *s = NULL; ...

Некорректно работает функция
Функция Small_S должна находить короткое слово в строке str, а она почему-то выводит первое слово! Помогите решить проблему, буду очень...

Функция работает некорректно
#include &lt;iostream&gt; using namespace std; short fill(double*, short); const short size = 5; int main() { double array;...

Функция работает некорректно
написал функцию,возвращающий нажатую клавишу: char func2(){ if(_kbhit()){ char c; c=_getch(); return c; } return 0; ...

Некорректно работает функция Delete
Слепил прожку. Которая должна записать в файл информацию о стране. А потом функция Делит должна по названию страны удалить всю информацию о...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru