【问题标题】:C global variable value is not kept outside of functionC全局变量值不保留在函数之外
【发布时间】:2013-04-22 16:52:41
【问题描述】:

我遇到了一个有点尴尬的问题:我有一个程序,其中包含两个全局 uint32_t 变量,以及一个我为它们赋值的函数。但是,当我稍后尝试打印/访问这些值时,一个给了我正确的值,而另一个仍然为零!我很困惑。这是代码:

#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 仍然为零! 任何帮助将不胜感激:)。

问候,

莱纳斯

【问题讨论】:

  • 那么你的问题是什么?
  • 好吧,为什么当我做 seq_offset = ntohl((uint32_t)(tcp->seq)) - last_seq 时 seq_offset 没有改变而 last_seq 是,我如何让他们表现得一样?
  • 请发帖SSCCE。这里的代码太多了。
  • 这已经是我完整程序的精简版。我不知道哪些部分会影响全局变量,因为琐碎的测试代码会按预期执行,这就是为什么我留下了这么多可能无用的代码。
  • 为什么seq_offset 会改变?您基本上在每次通话时都将其分配为 0。 a = x; b = x - a;

标签: c static global-variables uint32-t


【解决方案1】:

好的,我做出正确的回答。

为什么 seq_offset 会改变?您基本上在每次通话时都将其分配为 0。

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

将计算为seq_offset = ntohl((uint32_t)(tcp-&gt;seq)) - ntohl((uint32_t)(tcp-&gt;seq)),始终为 0。

你必须反转线条

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

这样,last_seq 包含最后一个值。

【讨论】:

    【解决方案2】:

    tristopia 已经在 cmets 中指出了答案,我担心这相当尴尬。我已经通过切换两个赋值语句来修复它

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

    谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-15
      • 2021-09-14
      • 2019-06-01
      相关资源
      最近更新 更多