2009-02-25 21 views
10

Netfilter kancasını kaydeden bir çekirdek modülü yazıyorum. Sk_buff-> saddr üyesini kullanarak arayanın ip adresini almaya çalışıyorum. IP'yi insan tarafından okunabilir, yani x.x.x.x biçiminde elde etmenin bir yolu var mı?IP Adresi sk_buff dan

inet_ntop() işlevini buldum ancak çekirdek başlıklarında bulunmuyor gibi görünüyor. \ XC0 \ xA8 \ x00 \ x01 'i 192.168.0.1 sürümüne nasıl dönüştürebilirim?

+0

inet_ntop() ve onun kardeşi inet_pton() aslında arpa/inet.h içinde, şimdi çekirdek uygulamalarını arıyorum. –

+0

ummm, netfilter'in günlük hedefi bunu yapmalı ... Oraya bakarım. – derobert

+0

& Rohit: Dürüst olmak gerekirse, baytların böyle bir dizede nasıl biçimlendirileceğini bilmiyorsanız, muhtemelen bir çekirdek modülü yazmamalısınız. İlk önce bazı kullanıcı alanı öğelerini deneyin. –

cevap

12

tanımlanan iki makro iPv6 adresleri için IPv4 adres ve NIP6 için/linux/kernel.h

NIPQUAD gibi komplikasyonlar görülebilir.

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

insan tarafından okunabilir formatta ip adreslerini yazdırmak için bu faydalanmak çekirdek kaynaklarda yeterli örneği vardır. Örneğin:

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

Bu yardımcı olur umarım.

+9

çekirdeğini çöktü. Buna rastlamak için başkalarının yararına, 'NIPQUAD' 2.6.38 sonra ellimated edildi. Bunun yerine '% pI4' yerine – pratikm

+0

kullanın. Şu anda 'in4_pton()' in /net/core/utils.c dosyasında – BonBon

+0

@ BeBon: 'in4_pton()' tersini yapar. –

0

Her parçayı tamsayı formuna dönüştürmek için strtol kullanabilirsiniz.

+0

Neredeyse bunu yapan bir makro var neredeyse pozitif, ben sadece ATM bulamıyorum. –

2

Basit. "X.x.x.x" biçimindeki IP adresi bir sebepten dolayı noktalı dörtlü olarak adlandırılır. Her numara, adresinizde toplam 4 baytlık bir bayt temsil eder.

Bu nedenle, 4 bayt adresiyle, her baytın ondalık değerini yazdırabilirsiniz.

Hızlı ve kirli örnek (seçtiğiniz çıkış fonksiyonu ile printf değiştirin):

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

Bu, şimdi – Rohit

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

IP Adresi [0] .a [1] .a [2] .a elde edilebilir [3]

11

Sen printk tarafından sağlanan% PI4 genişletilmiş biçim belirteçlerini() kullanmalısınız:

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

printk doğrudan bu işleyebilir:

IPv4 adres:

%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 adresleri:

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

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