2013-04-22 3 views
-2

약간 당황한 문제가 있습니다. 두 개의 전역 uint32_t 변수와 값을 할당하는 함수가 있습니다. 그러나 나중에이 값을 인쇄/액세스하려고하면 다른 값은 여전히 ​​0이지만 올바른 값을 제공합니다! 나는 매우 혼란 스럽다. 다음은 코드입니다.C 전역 변수 값이 함수 외부에 보관되지 않습니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <libnet.h> 
#include <stdint.h> 
#include <pcap.h> 
#include <time.h> 
#include <string.h> 
#include <arpa/inet.h> 

static uint32_t last_seq; 
static uint32_t seq_offset; 


void packet_handler(u_char* user, const struct pcap_pkthdr *header, const u_char * packet){ 
    struct tcphdr *tcp = (struct tcphdr *) (packet + LIBNET_IPV4_H + LIBNET_ETH_H); 

    printf("current seq = %u\n", ntohl((uint32_t)(tcp->seq))); 
    printf("last seq = %u\n", last_seq); 
    printf("difference in seq = %u\n", ntohl((uint32_t)(tcp->seq)) - last_seq); 
    last_seq = ntohl((uint32_t)(tcp->seq)); 

    seq_offset = ntohl((uint32_t)(tcp->seq)) - last_seq; 
} 

void seqno_probe(){ 
    libnet_t *l; 
    u_int32_t dst_addr; 
    u_int32_t src_addr; 
    char *device = "eth0"; 
    char errbuf[LIBNET_ERRBUF_SIZE]; 
    libnet_ptag_t tcp = 0; 
    libnet_ptag_t ip4 = 0; 
    char *filter = "(tcp[13] == 0x14) || (tcp[13] == 0x12)"; 
    pcap_t *handle; 
    char libpcap_errbuf[PCAP_ERRBUF_SIZE]; 
    struct bpf_program fp; 
    bpf_u_int32 netp, maskp; 
    int answer, i; 
    time_t tv; 

    l = libnet_init(LIBNET_RAW4, device , errbuf); 
    if(l == NULL){ 
    fprintf(stderr, "libnet_init() failed: %s\n", errbuf); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 


    /* IP address */ 

    dst_addr = libnet_name2addr4(l, "172.16.54.5", LIBNET_DONT_RESOLVE); 

    if(dst_addr == -1){ 
    fprintf(stderr, "Error converting IP address.\n"); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 

    src_addr = libnet_name2addr4(l, "172.16.54.3", LIBNET_DONT_RESOLVE); 
if(src_addr == -1){ 
    fprintf(stderr, "Couldn't get own IP address: %s\n", libnet_geterror(l)); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 

    handle = pcap_open_live(device, 1500, 0, 2000, libpcap_errbuf); 
    if(handle == NULL){ 
    fprintf(stderr, "Error opening pcap handle: %s\n", libpcap_errbuf); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 

    if((pcap_setnonblock(handle, 1, libpcap_errbuf)) == -1){ 
    fprintf(stderr, "Error setting nonblock: %s\n", libpcap_errbuf); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 

    if(pcap_lookupnet(device, &netp, &maskp, libpcap_errbuf) == -1){ 
    fprintf(stderr, "Net lookup error: %s\n", libpcap_errbuf); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 

    if(pcap_compile(handle, &fp, filter, 0, maskp) == -1){ 
    fprintf(stderr, "BPF error: %s\n", libpcap_errbuf); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 
if(pcap_setfilter(handle, &fp) == -1){ 
    fprintf(stderr, "Error setting BPF: %s\n", libpcap_errbuf); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 

    pcap_freecode(&fp); 

    tcp = libnet_build_tcp(
     libnet_get_prand(LIBNET_PRu16), /*source port*/ 
     514,       /*destination port */ 
     libnet_get_prand(LIBNET_PRu16),/*sequence number */ 
     0,        /*ack*/ 
     TH_SYN,       /*control flag*/ 
     7,        /*window*/ 
     0,        /*checksum*/ 
     0,        /*urgent*/ 
     LIBNET_TCP_H,     /*header length*/ 
     NULL,       /*payload*/ 
     0,        /*payload length*/ 
     l,        /*libnet context*/ 
     tcp        /*protocol tag*/ 
     ); 

    if(tcp == -1){ 
    fprintf(stderr,"Error building TCP header: %s\n", libnet_geterror(l)); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 


    ip4 = libnet_build_ipv4(
     LIBNET_TCP_H + LIBNET_IPV4_H,  /*length*/ 
     0,        /*TOS*/ 
     libnet_get_prand(LIBNET_PRu16), /*IP ID*/ 
     0,        /*frag offset*/ 
     127,        /*TTL*/ 
     IPPROTO_TCP,      /*upper layer protocol*/ 
     0,        /*checksum*/ 
     src_addr,       /*src ip address*/ 
     dst_addr,       /*dest ip address*/ 
     NULL,        /*payload*/ 
     0,        /*payload length*/ 
     l,        /*libnet context*/ 
     ip4        /*protocol tag*/ 
    ); 

    if(ip4 == -1){ 
    fprintf(stderr, "Error building IP4 header: %s\n", libnet_geterror(l)); 
    libnet_destroy(l); 
    exit(EXIT_FAILURE); 
    } 

    for(i=0;i<2;i++){ 
    if(libnet_write(l) == -1){ 
     fprintf(stderr, "Unable to send packet: %s\n", libnet_geterror(l)); 
     libnet_destroy(l); 
     exit(EXIT_FAILURE); 
    } 
answer = 1; 
    tv  = time(NULL); 

    while(answer){ 
     pcap_dispatch(handle, -1, packet_handler, NULL); 
     if((time(NULL) - tv) > 2){ 
     answer = 0; 
     } 
    } 
    } 
    libnet_destroy(l); 
} 


int main(){ 
    seqno_probe(); 
    printf("last_seq = %u\n seq_offset = %u\n", last_seq, seq_offset); 
    return 0; 
} 

이 스크립트를 실행하면 last_seq의 결과는 정확하지만 seq_offset은 0으로 유지됩니다! 도움을 주시면 감사하겠습니다. :).

감사합니다,

리누스

+0

그럼 뭐가 궁금한가요? – djechlin

+0

음, seq_offset = ntohl ((uint32_t) (tcp-> seq) 할 때 seq_offset이 변경되지 않는 이유는 무엇입니까?) - last_seq; last_seq는 무엇이며, 어떻게 행동하게합니까? – Linus

+0

[SSCCE] (http://sscce.org)를 게시하십시오. 너무 많은 코드가 있습니다. – djechlin

답변

3

좋아, 나는 적절한 대답을합니다.

왜 seq_offset이 변경됩니까? 기본적으로 모든 호출에 0을 지정합니다. 항상 0

seq_offset = ntohl((uint32_t)(tcp->seq)) - ntohl((uint32_t)(tcp->seq))

last_seq = ntohl((uint32_t)(tcp->seq)); 
seq_offset = ntohl((uint32_t)(tcp->seq)) - last_seq; 

당신은

seq_offset = ntohl((uint32_t)(tcp->seq)) - last_seq; 
last_seq = ntohl((uint32_t)(tcp->seq)); 

이 방법은, last_seq는 마지막 값을 포함하는 라인 반전이 계산됩니다.

0

tristopia가 의견에서 대답을 지적했으며, 내가 두려워하는 것처럼 오히려 난처했다. 두 개의 할당 문을 전환하여 문제를 해결했습니다.

last_seq = ntohl((uint32_t)(tcp->seq)); 
seq_offset = ntohl((uint32_t)(tcp->seq)) - last_seq; 

고마워요!