From 36b3db155644c137987586f3345c895bc710b844 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Wed, 22 Jun 2011 18:11:49 +0200 Subject: [PATCH] first commit of hack --- README | 1 + hftsniff.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 README create mode 100644 hftsniff.c diff --git a/README b/README new file mode 100644 index 0000000..888a4a9 --- /dev/null +++ b/README @@ -0,0 +1 @@ +Some usefull hacks of any k1nd diff --git a/hftsniff.c b/hftsniff.c new file mode 100644 index 0000000..ae86324 --- /dev/null +++ b/hftsniff.c @@ -0,0 +1,252 @@ +/****** + * HFTSniff simple sniffer using pcap + * xorg62@gmail.com + ******/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Macros */ +#define LEN(x) (sizeof(x) / sizeof(*x)) + +/* Using ANSI escape codes to use bold in simple text mode */ +#define IP_SRCDEST(src, psrc, dest, pdest) \ + do { \ + printf("%s:\e[1m%d\e[0m ==> %s:\e[1m%d\e[0m\n", \ + src, psrc, dest, pdest); \ + } while(/* CONSTCOND */ 0); + +#define DISP_PROTO(s) \ + do { \ + printf("( \e[1m%s\e[0m ) ", s); \ + } while(/* CONSTCOND */ 0); + +#define BYE(s, er) \ + do { \ + fprintf(stderr, s": (%s)\n", er); \ + exit(EXIT_FAILURE); \ + } while(/* CONSTCOND */ 0); + +#define PKT_ERROR(r, s, a) \ + do { \ + fprintf(stderr, " PKT_ERROR: %s (%u)\n", s, a); \ + return r; \ + } while(/* CONSTCOND */ 0); \ + +/* Option const */ +#define FILTER "ip" +#define TIMEOUT (10) +#define SNAPLEN (SHRT_MAX) + +/* + * Ethernet packet format + */ +#define ETHERNET_SIZE (14) +#define ETHERNET_ALEN (6) + +struct ethernet_header +{ + unsigned char ether_dhost[ETHERNET_ALEN]; /* Destination ethernet address */ + unsigned char ether_shost[ETHERNET_ALEN]; /* Source ethernet adress */ + unsigned short ether_type; /* Packet type, id field */ +}; + +/* + * Ip packet format (tcpdump way) + */ +#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4) +#define IP_HL(ip) ((ip)->ip_vhl & 0x0f) + +#define IP_DF (0x4000) /* Dont fragment flag */ +#define IP_MF (0x2000) /* More fragments flag */ +#define IP_OFFMASK (0x1fff) /* Mask for fragmenting bits */ + +struct ip_header +{ + unsigned char ip_vhl; /* Header length, version */ + unsigned char ip_tos; /* Type of service */ + unsigned short ip_len; /* Total length */ + unsigned short ip_id; /* Identification */ + unsigned short ip_off; /* Fragment offset field */ + unsigned char ip_ttl; /* Time to live */ + unsigned char ip_p; /* Protocol */ + unsigned short ip_sum; /* Checksum */ + struct in_addr ip_src, ip_dst; /* Source and dest address */ +}; + +/* + * TCP packet format + */ +#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) + +#define TH_FIN (0x01) +#define TH_SYN (0x02) +#define TH_RST (0x04) +#define TH_PUSH (0x08) +#define TH_ACK (0x10) +#define TH_URG (0x20) +#define TH_ECE (0x40) +#define TH_CWR (0x80) +#define TH_FLAGS (0xf7) /* TH_* */ + +struct tcp_header +{ + unsigned short th_sport; /* Source port */ + unsigned short th_dport; /* Destination port */ + unsigned int th_seq; /* Sequence number */ + unsigned int th_ack; /* Acknowledgement number */ + unsigned char th_offx2; /* Data offset, rsvd */ + unsigned char th_flags; /* Flags bitfield */ + unsigned short th_win; /* Window */ + unsigned short th_sum; /* Checksum */ + unsigned short th_urp; /* Urgent pointer */ +}; + +/* Function protos */ +int pkt_tcp_handle(void *, void *); + + +/* Usefull things */ +const struct +{ + unsigned int p; + int (*f)(void *, void*); + char name[32]; +} protos[] = +{ + { IPPROTO_IP, NULL, "IP" }, /* _IP 0 */ + { IPPROTO_ICMP, NULL, "ICMP" }, /* _ICMP 1 */ + { IPPROTO_TCP, pkt_tcp_handle, "TCP" }, /* _TCP 6 */ + { IPPROTO_UDP, NULL, "UDP" }, /* _UDP 17 */ + { -1, NULL, ""} +}; + + +/* As defined in man: */ +char errbuf[PCAP_ERRBUF_SIZE]; + +/* + * Handle TCP packets + */ +int +pkt_tcp_handle(void *pkt, void *prev_pkt) +{ + const struct tcp_header *tcp; + const struct ip_header *ip; + int len; + + ip = (struct ip_header*)prev_pkt; + tcp = (struct tcp_header*)(pkt + ETHERNET_SIZE + (IP_HL(ip) << 2)); + + if((len = TH_OFF(tcp) << 2) < 20) + PKT_ERROR(0, "Invalid IP header length:", len); + + IP_SRCDEST(inet_ntoa(ip->ip_src), ntohs(tcp->th_sport), /* src */ + inet_ntoa(ip->ip_dst), ntohs(tcp->th_dport)); /* dest */ + + return len; +} + +/* + * Handle every packet, point it to corresponding pkt_proto_handle + */ +void +pkt_handle(unsigned char *args, const struct pcap_pkthdr *header, const unsigned char *packet) +{ + struct ethernet_header *eth; + struct ip_header *ip; + int len, plen, i = 0; + bool pfound = false; + + /* Translate ethernet pkt */ + eth = (struct ethernet_header*)packet; + + /* Translate ip pkt */ + ip = (struct ip_header*)(packet + ETHERNET_SIZE); + + /* Check ipv4 */ + if((len = IP_HL(ip) << 2) < 20) + PKT_ERROR(, "Invalid IP header length:", len); + + /* Protocol */ + for(; i < LEN(protos); ++i) + if(ip->ip_p == protos[i].p) + { + DISP_PROTO(protos[i].name); + + if(protos[i].f) + plen = protos[i].f((void*)packet, (void*)ip); + + pfound = true; + break; + } + + /* Unknown protocol */ + if(!pfound) + { + DISP_PROTO("unknown"); + IP_SRCDEST(inet_ntoa(ip->ip_src), -1, /* src */ + inet_ntoa(ip->ip_dst), -1); /* dest */ + + } + + puts("\n"); + + return; +} + +int +main(int argc, char **argv) +{ + char *dev; + bpf_u_int32 mask; + bpf_u_int32 netip; + pcap_t *descr; + struct bpf_program bpf; + + /* Find device */ + if(!(dev = pcap_lookupdev(errbuf))) + BYE("Can't find device", errbuf); + + printf("Device ( %s )\n", dev); + + /* Find adress & mask */ + if(pcap_lookupnet(dev, &netip, &mask, errbuf) < 0) + { + fprintf(stderr, "Can't find Adress or Mask: (%s)", errbuf); + netip = mask = 0; + } + + /* Open device and reaaad */ + if(!(descr = pcap_open_live(dev, SNAPLEN, true, TIMEOUT, errbuf))) + BYE("Fail at opening and reading device", errbuf); + + /* Check if packet is from ethernet device */ + if(pcap_datalink(descr) != DLT_EN10MB) + BYE("Device is not an Ethernet", dev); + + /* Parse & set pcap with option expression */ + if(pcap_compile(descr, &bpf, FILTER, 0, netip) < 0) + BYE("Option parse error", pcap_geterr(descr)); + + if(pcap_setfilter(descr, &bpf) < 0) + BYE("Can't use option", pcap_geterr(descr)); + + pcap_loop(descr, 10, pkt_handle, NULL); + + pcap_freecode(&bpf); + pcap_close(descr); + + return 0; +} +