문제

나는 netfilter 후크를 등록하는 커널 모듈을 작성 중입니다.나는 다음을 사용하여 발신자의 IP 주소를 얻으려고합니다. sk_buff->saddr 회원.사람이 읽을 수 있는 IP를 얻을 수 있는 방법이 있습니까?x.x.x.x 형식인가요?

기능을 찾았어요 inet_ntop() 하지만 커널 헤더에서는 사용할 수 없는 것 같습니다.\xC0\xA8\x00\x01 을 192.168.0.1 로 어떻게 변환합니까?

도움이 되었습니까?

해결책

포함/linux/kernel.h에 정의 된 두 개의 매크로가 있습니다.

IPv4 주소의 NIPQUAD 및 IPv6 주소의 경우 NIP6.

#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));

도움이 되었기를 바랍니다.

다른 팁

printk ()에서 제공하는 %pi4 확장 형식 지정자를 사용해야합니다.

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

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

단순한. "xxxx"형식의 IP 주소를 이유는 점선 쿼드라고합니다. 각 숫자는 주소에서 총 4 바이트에 대해 바이트를 나타냅니다.

따라서 4 바이트 주소를 사용하면 각 바이트의 소수점 값을 인쇄합니다.

빠르고 더러운 예제 (선택한 출력 함수로 printf를 대체) :

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

당신이 사용할 수있는 strtol 각 조각을 정수 형태로 변환합니다.

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

IP 주소는 [0] .a [1] .a [2] .a [3]를 얻을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top