first commit of hack
This commit is contained in:
commit
36b3db1556
252
hftsniff.c
Normal file
252
hftsniff.c
Normal file
@ -0,0 +1,252 @@
|
||||
/******
|
||||
* HFTSniff simple sniffer using pcap
|
||||
* xorg62@gmail.com
|
||||
******/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <pcap.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user