📄 waitpacket.c
字号:
/* waitpacket.c -- handle and print the incoming packet * Copyright(C) 1999-2001 Salvatore Sanfilippo * Under GPL, see the COPYING file for more information about * the license. */ /* * Revised for Windows: Rob Turpin <rgturpin@epop3.com> * 7/03/2004 */#include <stdio.h>#include <string.h>#include <sys/types.h>#include <errno.h>#include <time.h>#include <ctype.h>#ifndef WIN32#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#else#include <winsock2.h>#include <io.h>#endif#include "hping2.h"#include "globals.h"static int icmp_unreach_rtt(void *quoted_ip, int size, int *seqp, float *ms_delay);static void print_tcp_timestamp(void *tcp, int tcpsize);static int recv_icmp(void *packet, size_t size);static int recv_udp(void *packet, size_t size);static int recv_tcp(void *packet, size_t size);static void hex_dump(void *packet, int size);static void human_dump(void *packet, int size);static void handle_hcmp(char *packet, int size);static struct myiphdr ip;static int ip_size;static struct in_addr src, dst;void wait_packet(void){ int match = 0; int size, iphdr_size, enc_size;#ifndef WIN32 char packet [IP_MAX_SIZE+linkhdr_size];#endif char *ip_packet, *enc_packet;#ifdef WIN32 char *packet; packet = malloc(sizeof(char) * (IP_MAX_SIZE + linkhdr_size)); if (packet == NULL) { fprintf(stderr, "[malloc] failed: %d\n", GetLastError()); exit(1); }#endif size = read_packet(packet, IP_MAX_SIZE+linkhdr_size); switch(size) { case 0: return; case -1: exit(1); } /* Check if the packet is shorter than the link header size */ if (size < linkhdr_size) { if (opt_debug) printf("DEBUG: WARNING: packet size < linkhdr_size\n"); return; } /* IP packet pointer and len */ ip_packet = packet + linkhdr_size; ip_size = size - linkhdr_size; /* Truncated IP header? */ if (ip_size < IPHDR_SIZE) { if (opt_debug) printf("[|ip fix]\n"); return; } memcpy(&ip, packet + linkhdr_size, sizeof(ip)); iphdr_size = ip.ihl * 4;#ifdef WIN32 free(packet); packet = NULL;#endif /* Bad IP header len? */ if (iphdr_size > ip_size) { if (opt_debug) printf("[|iphdr size]\n"); return; } /* Handle the HCMP for almost safe file transfer with hping */ if (opt_sign) handle_hcmp(ip_packet, ip_size); /* Check if the dest IP address is the one of our interface */ if (memcmp(&ip.daddr, &local.sin_addr, sizeof(ip.daddr))) return; /* If the packet isn't an ICMP error it should come from * our target IP addresss. We accepts packets from all the * source if the random destination option is active */ if (ip.protocol != IPPROTO_ICMP && !opt_rand_dest) { if (memcmp(&ip.saddr, &remote.sin_addr, sizeof(ip.saddr))) return; } /* Get the encapsulated protocol offset and size */ enc_packet = ip_packet + iphdr_size; enc_size = ip_size - iphdr_size; /* Put the IP source and dest addresses in a struct in_addr */ memcpy(&src, &(ip.saddr), sizeof(struct in_addr)); memcpy(&dst, &(ip.daddr), sizeof(struct in_addr)); switch(ip.protocol) { case IPPROTO_ICMP: match = recv_icmp(enc_packet, enc_size); break; case IPPROTO_UDP: match = recv_udp(enc_packet, enc_size); break; case IPPROTO_TCP: match = recv_tcp(enc_packet, enc_size); break; default: return; } if (match) recv_pkt++; /* Dump the packet in hex */ if (opt_hexdump && match && !opt_quiet) hex_dump(ip_packet, ip_size); /* Dump printable characters inside the packet */ if (opt_contdump && match && !opt_quiet) human_dump(ip_packet, ip_size); /* Display IP options */ if (match && opt_rroute && !opt_quiet) display_ipopt(ip_packet); /* --stop-tr stops hping in traceroute mode when the * first not ICMP time exceeded packet is received */ if (opt_traceroute && opt_tr_stop && match) { struct myicmphdr icmp; if (ip.protocol != IPPROTO_ICMP)#ifndef WIN32 print_statistics(0);#else win_print_statistics(0);#endif if (enc_size >= ICMPHDR_SIZE) { memcpy(&icmp, enc_packet, sizeof(icmp)); if (icmp.type != 11)#ifndef WIN32 print_statistics(0);#else win_print_statistics(0);#endif } } /* if the count was reached exit now */ if (count != -1 && count == recv_pkt)#ifndef WIN32 print_statistics(0);#else win_print_statistics(0);#endif}void log_ip(int status, int sequence){ int rel_id, ip_id; /* get ip->id */ if (opt_winid_order) ip_id = ip.id; else ip_id = htons(ip.id); if (status == S_RECV) printf("DUP! "); if (opt_relid) rel_id = relativize_id(sequence, &ip_id); else rel_id = 0; printf("len=%d ip=%s ttl=%d %sid%s%d ", ip_size, inet_ntoa(src), ip.ttl, (ntohs(ip.frag_off) ? "DF " : ""), (rel_id ? "=+" : "="), ip_id); if (opt_verbose && !opt_quiet) printf("tos=%x iplen=%u\n", ip.tos, htons(ip.tot_len));}void log_icmp_ts(void *ts){ struct icmp_tstamp_data icmp_tstamp; memcpy(&icmp_tstamp, ts, sizeof(icmp_tstamp)); printf("ICMP timestamp: Originate=%u Receive=%u Transmit=%u\n", (unsigned int) ntohl(icmp_tstamp.orig), (unsigned int) ntohl(icmp_tstamp.recv), (unsigned int) ntohl(icmp_tstamp.tran)); printf("ICMP timestamp RTT tsrtt=%lu\n\n", ((long unsigned int)get_midnight_ut_ms() - ntohl(icmp_tstamp.orig)));}void log_icmp_addr(void *addrptr){ unsigned char *addr = addrptr; printf("ICMP address mask: icmpam=%u.%u.%u.%u\n\n", addr[0], addr[1], addr[2], addr[3]);}#ifndef WIN32void log_traceroute(void *packet, int size, int icmp_code)#elsevoid log_traceroute(void *packet2, int size, int icmp_code)#endif{ static unsigned char old_src_addr[4] = { 0, 0, 0, 0 }; int sequence = 0, retval; float rtt;#ifdef WIN32 char *packet = (char *)packet2;#endif if (!opt_tr_keep_ttl && !memcmp(&ip.saddr, old_src_addr, 4)) return; retval = icmp_unreach_rtt(packet+ICMPHDR_SIZE, size-ICMPHDR_SIZE, &sequence, &rtt); memcpy(old_src_addr, &ip.saddr, sizeof(ip.saddr)); printf("hop=%d ", src_ttl); fflush(stdout); log_icmp_timeexc(inet_ntoa(src), icmp_code); if (retval != -1) printf("hop=%d hoprtt=%.1f ms\n", src_ttl, rtt); if (!opt_tr_keep_ttl) src_ttl++;}#ifndef WIN32int recv_icmp(void *packet, size_t size)#elseint recv_icmp(void *packet2, size_t size)#endif{ struct myicmphdr icmp; struct myiphdr quoted_ip;#ifdef WIN32 char *packet = (char *)packet2;#endif /* Check if the packet can contain the ICMP header */ if (size < ICMPHDR_SIZE) { printf("[|icmp]\n"); return 0; } memcpy(&icmp, packet, sizeof(icmp)); /* --------------------------- * * ICMP ECHO/TIMESTAMP/ADDRESS * * --------------------------- */ if ((icmp.type == ICMP_ECHOREPLY || icmp.type == ICMP_TIMESTAMPREPLY || icmp.type == ICMP_ADDRESSREPLY) && icmp.un.echo.id == (getpid() & 0xffff)) { int icmp_seq = icmp.un.echo.sequence; int status; float ms_delay; /* obtain round trip time */ status = rtt(&icmp_seq, 0, &ms_delay); log_ip(status, icmp_seq); printf("icmp_seq=%d rtt=%.1f ms\n", icmp_seq, ms_delay); if (icmp.type == ICMP_TIMESTAMPREPLY) { if ((size - ICMPHDR_SIZE) >= 12) log_icmp_ts(packet+ICMPHDR_SIZE); else printf("[|icmp timestamp]\n"); } else if (icmp.type == ICMP_ADDRESSREPLY) { if ((size - ICMPHDR_SIZE) >= 4) log_icmp_addr(packet+ICMPHDR_SIZE); else printf("[|icmp subnet address]\n"); } return 1; } /* ------------------------------------ * * ICMP DEST UNREACHABLE, TIME EXCEEDED * * ------------------------------------ */ else if (icmp.type == 3 || icmp.type == 11) { if ((size - ICMPHDR_SIZE) < sizeof(struct myiphdr)) { printf("[|icmp quoted ip]\n"); return 0; } memcpy("ed_ip, packet+ICMPHDR_SIZE, sizeof(quoted_ip)); if (memcmp("ed_ip.daddr, &remote.sin_addr, sizeof(quoted_ip.daddr)) || memcmp(&ip.daddr, &local.sin_addr, sizeof(ip.daddr))) return 0; /* addresses don't match */ /* Now we can handle the specific type */ switch(icmp.type) { case 3: if (!opt_quiet) log_icmp_unreach(inet_ntoa(src), icmp.code); return 1; case 11: if (opt_traceroute) log_traceroute(packet, size, icmp.code); else log_icmp_timeexc(inet_ntoa(src), icmp.code); return 1; } } return 0; /* don't match */}int recv_udp(void *packet, size_t size){ struct myudphdr udp; int sequence = 0, status; float ms_delay; if (size < UDPHDR_SIZE) { printf("[|udp]\n"); return 0; } memcpy(&udp, packet, sizeof(udp)); /* check if the packet matches */ if ((ntohs(udp.uh_sport) == dst_port) || (opt_force_incdport && (ntohs(udp.uh_sport) >= base_dst_port && ntohs(udp.uh_sport) <= dst_port)))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -