IP-адрес от sk_buff - PullRequest
       53

IP-адрес от sk_buff

12 голосов
/ 25 февраля 2009

Я пишу модуль ядра, который регистрирует ловушку netfilter. Я пытаюсь получить IP-адрес вызывающего абонента, используя элемент sk_buff->saddr. Есть ли способ, которым я могу получить IP в удобочитаемом формате, то есть формате x.x.x.x?

Я нашел функцию inet_ntop(), но она не доступна в заголовках ядра. Как преобразовать \ xC0 \ xA8 \ x00 \ x01 в 192.168.0.1?

Ответы [ 6 ]

16 голосов
/ 16 ноября 2012

Вы должны использовать спецификаторы расширенного формата% pI4, предоставляемые printk ():

printk(KERN_DEBUG "IP addres = %pI4\n", &local_ip);
13 голосов
/ 02 апреля 2009

В include / linux / kernel.h

определены два макроса

NIPQUAD для адресов ipv4 и NIP6 для адресов ipv6.

#define NIPQUAD(addr) \
    ((unsigned char *)&addr)[0], \
    ((unsigned char *)&addr)[1], \
    ((unsigned char *)&addr)[2], \
    ((unsigned char *)&addr)[3]

#define NIP6(addr) \
    ntohs((addr).s6_addr16[0]), \
    ntohs((addr).s6_addr16[1]), \
    ntohs((addr).s6_addr16[2]), \
    ntohs((addr).s6_addr16[3]), \
    ntohs((addr).s6_addr16[4]), \
    ntohs((addr).s6_addr16[5]), \
    ntohs((addr).s6_addr16[6]), \
    ntohs((addr).s6_addr16[7])

В источниках ядра имеется достаточно примеров, которые используют их для печати IP-адресов в удобочитаемом формате. Например:

printk(KERN_DEBUG "Received packet from source address: %d.%d.%d.%d!\n",NIPQUAD(iph->saddr));

Надеюсь, это поможет.

3 голосов
/ 12 июня 2015

printk может справиться с этим напрямую:

IPv4-адреса:

%pI4    1.2.3.4
%pi4    001.002.003.004
%p[Ii]4[hnbl]

For printing IPv4 dot-separated decimal addresses. The 'I4' and 'i4'
specifiers result in a printed address with ('i4') or without ('I4')
leading zeros.

The additional 'h', 'n', 'b', and 'l' specifiers are used to specify
host, network, big or little endian order addresses respectively. Where
no specifier is provided the default network/big endian order is used.

Passed by reference.

IPv6-адреса:

%pI6    0001:0002:0003:0004:0005:0006:0007:0008
%pi6    00010002000300040005000600070008
%pI6c   1:2:3:4:5:6:7:8

For printing IPv6 network-order 16-bit hex addresses. The 'I6' and 'i6'
specifiers result in a printed address with ('I6') or without ('i6')
colon-separators. Leading zeros are always used.

The additional 'c' specifier can be used with the 'I' specifier to
print a compressed IPv6 address as described by
http://tools.ietf.org/html/rfc5952

Passed by reference.

Ссылка: https://www.kernel.org/doc/Documentation/printk-formats.txt

2 голосов
/ 25 февраля 2009

Simple. IP-адрес в формате «x.x.x.x» называется dotted-quad по причине. Каждое число представляет байт, всего 4 байта в вашем адресе.

Итак, с 4-байтовым адресом вы просто напечатаете десятичное значение каждого байта.

Быстрый и грязный пример (замените printf на выбранную вами функцию вывода):

unsigned char *addr = (unsigned char*)sk_buff->addr;
printf("%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
0 голосов
/ 27 февраля 2009
/* Convinience union to __be32 to ip address  */
union ip_address {
    u8 a[4];
    __be32 saddr;
};

IP-адрес может быть получен [0] .a [1] .a [2] .a [3]

0 голосов
/ 25 февраля 2009

Вы можете использовать strtol для преобразования каждого куска в целочисленную форму.

...