2013-05-13 4 views
1

나는 들어오는 패킷을 검사 할 리눅스 커널 모듈을 만들려고한다. 현재로서는 패킷의 TCP 헤더를 추출하고 원본 및 대상 포트를 읽는 중입니다. 그러나 잘못된 값이 표시됩니다. 나는 텔넷 포트 21 (가 듣고 내가하지)하려고 할 때, 이제C - 리눅스 - 커널 모듈 - TCP 헤더

unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, 
         const struct net_device *in, 
         const struct net_device *out, 
         int (*okfn)(struct sk_buff *)) 
{ 
    struct iphdr *ipp = (struct iphdr *)skb_network_header(skb); 
    struct tcphdr *hdr; 
    /* Using this to filter data from another machine */ 
    unsigned long ok_ip = 2396891328; 

    /* Some problem, empty network packet. Stop it now. */ 
    if (!skb) 
     return NF_ACCEPT; 

    /* Just to track only packets coming from 1 IP */ 
    if (ipp->saddr != ok_ip) 
     return NF_ACCEPT; 

    /* Incomming packet is TCP */ 
    if (ipp->protocol == IPPROTO_TCP) { 
     hdr = (struct tcphdr *) skb_transport_header(skb); 
     printk(" TCP ports: source: %d, dest: %d .\n", ntohs(hdr->source), 
                 ntohs(hdr->dest)); 
    } 
} 

: 나는 후크 기능이

[ 4252.961912] TCP ports: source: 17664, dest: 52 . 
[ 4253.453978] TCP ports: source: 17664, dest: 52 . 
[ 4253.953204] TCP ports: source: 17664, dest: 48 . 

그리고 포트 22 텔넷 때 - SSH 데몬을 듣고 이 : 문제가 오는 곳

나는 매우 이상한 결과를 얻고 출력에서 ​​볼 수로서
[ 4299.239940] TCP ports: source: 17664, dest: 52 . 
[ 4299.240527] TCP ports: source: 17664, dest: 40 . 
[ 4299.552566] TCP ports: source: 17664, dest: 40 . 

, 사람이 생각이있다 에서? 모듈을 컴파일 할 때 오류/경고가 없습니다. 커널 버전 (헤더) : 3.7.10. SELinux 또는 유사하지 않습니다.

+0

NAT 리디렉션과 관련 될 수 있습니다. 패킷이 포트 21과 22에 남겨지기는하지만 라우터는이를 동적 포트로 변환 한 다음 서버가 실제로이 포트에서 요청을 받고 있습니다. 돌아 오는 길에 서버의 헤더에 표시되며 라우터가 전달합니다. 헤더가 실제로 헤더에 들어가서 바뀌 었다고 생각하기 때문에 헤더가 실제로 변경 (또는 캡슐화)되지는 않는다고 생각합니다. – Magn3s1um

+0

나가는 패킷도 시도해보아야합니다. 라우터가 올바른 포트를 표시하면 라우터가이 값을 변경합니다. – Magn3s1um

+0

NAT가 없습니다. 두 시스템 모두 ESX 서버에 있으며 VLAN은 없습니다. 기계는 IP를 가지고 있습니다 : 192.168.221.141/24와 192.168.221.142/24 그래서 어떤 방법으로 패킷을 수정할 수있는 가능성은 없습니다. 또한 iptables 규칙이 없으며 모두 수용하도록 설정됩니다. – LukasH

답변

7

네트워킹 클래스에 작은 방화벽을 작성하는 것과 같은 문제가있었습니다. 제가 가지고 있었던 문제를 발견했습니다. 내가 잘못 tcp 헤더를 캐스팅했다. tcp로 변환 한 다음 포트에 액세스하십시오. 여기

는 기능 ip_hdr(skb)tcp_hdr(skb)을 적용, 소켓 버퍼 ( skb)에서 IP 헤더 또는 TCP 헤더를 얻으려면

struct iphdr *ip_header;  // ip header struct 
struct tcphdr *tcp_header;  // tcp header struct 
struct udphdr *udp_header;  // udp header struct 
struct sk_buff *sock_buff; 

unsigned int sport , 
      dport; 


sock_buff = skb; 

if (!sock_buff) 
    return NF_ACCEPT; 

ip_header = (struct iphdr *)skb_network_header(sock_buff); 
if (!ip_header) 
    return NF_ACCEPT; 


//if TCP PACKET 
if(ip_header->protocol==IPPROTO_TCP) 
{ 
    //tcp_header = (struct tcphdr *)skb_transport_header(sock_buff); //doing the cast this way gave me the same problem 

    tcp_header= (struct tcphdr *)((__u32 *)ip_header+ ip_header->ihl); //this fixed the problem 

    sport = htons((unsigned short int) tcp_header->source); //sport now has the source port 
    dport = htons((unsigned short int) tcp_header->dest); //dport now has the dest port 
} 
+0

고맙습니다, tcp_header = (struct tcphdr *) ((__ u32 *) ip_header + ip_header-> ihl); ' 내 문제가 해결되었습니다. – LukasH

+2

이 두 함수를 사용하여 IP 헤더와 TCP 헤더'ip_hdr (sock_buff)'와'tcp_hdr (sock_buff)'를 얻을 수도 있습니다. – IoT

1

작업 그것의 코드입니다.

관련 문제