tutorial ejemplos comandos arch linux-kernel netfilter

linux kernel - ejemplos - Dirección IP de sk_buff



netfilter arch linux (6)

Estoy escribiendo un módulo kernel que registra un gancho netfilter. Estoy tratando de obtener la dirección IP de la persona que llama usando el miembro sk_buff-> saddr. ¿Hay alguna forma de obtener el IP en formato iexxxx legible para humanos?

Encontré la función inet_ntop () pero no parece estar disponible en los encabezados del kernel. ¿Cómo convierto / xC0 / xA8 / x00 / x01 a 192.168.0.1?


Debe usar los especificadores de formato extendido% pI4 proporcionados por printk ():

printk(KERN_DEBUG "IP addres = %pI4/n", &local_ip);


Hay dos macros definidas en include / linux / kernel.h

NIPQUAD para direcciones IPv4 y NIP6 para direcciones 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])

Hay numerosos ejemplos en las fuentes del núcleo que hacen uso de estos para imprimir direcciones IP en formato legible para humanos. Por ejemplo:

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

Espero que esto ayude.


Puedes usar strtol para convertir cada pieza a su forma entera.


Sencillo. La dirección IP en formato "xxxx" se llama quad punteado por una razón. Cada número representa un byte, para un total de 4 bytes en su dirección.

Entonces, con la dirección de 4 bytes, simplemente imprimiría el valor decimal de cada byte.

Ejemplo rápido y sucio (reemplace printf con su función de salida preferida):

unsigned char *addr = (unsigned char*)sk_buff->addr; printf("%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);


printk puede manejar esto directamente:

Direcciones 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.

Direcciones 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.

Referencia: https://www.kernel.org/doc/Documentation/printk-formats.txt


/* Convinience union to __be32 to ip address */ union ip_address { u8 a[4]; __be32 saddr; };

Dirección IP se puede obtener a [0] .a [1] .a [2] .a [3]