我遇到了一个令人尴尬的问题:我有一个带有两个全局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保持为零! 任何帮助将不胜感激:)。
此致
莱纳斯
答案 0 :(得分:3)
好的,我做了一个正确的答案。
为什么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->seq)) - ntohl((uint32_t)(tcp->seq))
,始终为0.
你必须反转行
seq_offset = ntohl((uint32_t)(tcp->seq)) - last_seq;
last_seq = ntohl((uint32_t)(tcp->seq));
这样,last_seq包含最后一个值。
答案 1 :(得分:0)
tristopia在评论中指出了答案,我担心这是相当尴尬的。我通过切换两个赋值语句来修复它
last_seq = ntohl((uint32_t)(tcp->seq));
seq_offset = ntohl((uint32_t)(tcp->seq)) - last_seq;
谢谢!