From e09d7e4f69639c09d55e73e6ea6b3500c7cd92ec Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 31 May 2015 16:16:12 +0200 Subject: [PATCH] added some more sniffer stuff --- session5/sniff/Makefile | 2 +- session5/sniff/sniff.c | 113 ++++++++++++++++++++++++++++------------ 2 files changed, 82 insertions(+), 33 deletions(-) diff --git a/session5/sniff/Makefile b/session5/sniff/Makefile index 45a324c..8621158 100644 --- a/session5/sniff/Makefile +++ b/session5/sniff/Makefile @@ -1,7 +1,7 @@ TARGETS = sniff CC = gcc -CFLAGS = -g +CFLAGS = -g -std=c99 all: $(TARGETS) Makefile clean: diff --git a/session5/sniff/sniff.c b/session5/sniff/sniff.c index 1c2bd1a..b16fb58 100644 --- a/session5/sniff/sniff.c +++ b/session5/sniff/sniff.c @@ -1,12 +1,20 @@ +#define _BSD_SOURCE + #include #include #include #include +#include +#include #include +#include +#include #include -#include +#include + +#include #include #include @@ -15,11 +23,12 @@ #include #include -#define SNAPLEN 1024 +#define SNAPLEN 65536 +#define INTERFACE "eth1" -const char* icmp_type_str = { +const char* icmp_type_str[] = { [ 0 ] = "Echo Reply", - [ 1..2 ] = NULL, + [ 1 ... 2 ] = NULL, [ 3 ] = "Destination Unreachable", [ 4 ] = "Source Quench", [ 5 ] = "Redirect", @@ -36,7 +45,7 @@ const char* icmp_type_str = { [ 16 ] = "Information Reply", [ 17 ] = "Address Mask Request", [ 18 ] = "Address Mask Reply" -} +}; int hexdump(void *buf, size_t len) { @@ -54,58 +63,98 @@ int hexdump(void *buf, size_t len) int parse_packet(uint8_t *data, size_t len) { /* Parse Ethertype */ - struct ether_header *ehdr = data; + struct ethhdr *eth = (struct ethhdr*) data; - printf("ether_src: %s ", ether_ntoa(ehdr->ether_shost)); - printf("ether_dst: %s ", ether_ntoa(ehdr->ether_dhost)); - printf("ether_type: %#04x ", ehdr->ether_type); + printf("ether_src: %s ", ether_ntoa((const struct ether_addr*) eth->h_source)); + printf("ether_dst: %s ", ether_ntoa((const struct ether_addr*) eth->h_dest)); + printf("ether_type: %#04x ", eth->h_proto); - if (ehdr->ether_type == ETHERTYPE_IP) { + if (eth->h_proto == ETH_P_IP) { /* Parse IP protocol */ - struct ip *iphdr = (char *) ehdr + sizeof(*ehdr) + struct iphdr *ip = (struct iphdr*) (eth+1); - printf("ip_version: %u ", iphdr->ip_v); - printf("ip_ihl: %u ", iphdr->ip_hl); - printf("ip_ttl: %u ", iphdr->ip_ttl); - printf("ip_protocol: %u ", iphdr->ip_p); - printf("ip_src: %u ", iphdr->ip_p); - printf("ip_dst: %u ", iphdr->ip_p); + printf("ip_version: %u ", ip->version); + printf("ip_ihl: %u ", ip->ihl); + printf("ip_ttl: %u ", ip->ttl); + printf("ip_protocol: %u ", ip->protocol); + printf("ip_src: %u ", *((struct in_addr*) &ip->saddr)); + printf("ip_dst: %u ", *((struct in_addr*) &ip->daddr)); - if (iphdr->p == IPPROTO_ICMP) { + if (ip->protocol == IPPROTO_ICMP) { /* Parse ICMP */ - struct icmphdr *icmphdr = (char *) iphdr + iphdr->ip_hl * 4; + struct icmphdr *icmp = (struct icmphdr*) ((char*) ip + ip->ihl * 4); printf("icmp_type: %u (%s) "); - printf("icmp_code: %u ") + printf("icmp_code: %u "); } - else if (iphdr->p == IPPROTO_UDP) { + else if (ip->protocol == IPPROTO_UDP) { /* Parse UDP */ - struct udphdr *udphdr = (char *) udphdr + iphdr->ip_hl * 4; - - } - else if (iphdr->p == IPPROTO_TCP) { - /* Parse TCP */ - struct udphdr *udphdr = (char *) udphdr + iphdr->ip_hl * 4; + struct udphdr *udp = (struct udphdr*) ((char*) ip + ip->ihl * 4); + printf("udp_port: %u "); + } + else if (ip->protocol == IPPROTO_TCP) { + /* Parse TCP */ + struct tcphdr *tcp = (struct tcphdr*) ((char*) ip + ip->ihl * 4); + + printf("tcp_port: %u "); } } + + printf("\n"); } int main (int argc, char *argv[]) { uint8_t packet[SNAPLEN]; + int val, sd, ifindex; + struct ifreq ifr; + struct sockaddr_ll sll; - int sd = socket(AF_INET, SOCK_RAW, htons(ETH_P_ALL)); + sd = socket(AF_INET, SOCK_RAW, htons(ETH_P_ALL)); if (sd < 0) error(-1, errno, "Failed to create socket"); + + val = 1; + if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))) + error(-1, errno, "Failed to set socket option: SO_REUSEADDR"); + + /* Get interface flags */ + strncpy(ifr.ifr_name, INTERFACE, IFNAMSIZ); + if (ioctl(sd, SIOCGIFFLAGS, &ifr)) + error(-1, errno, "Failed to get interface flags"); - + /* Enable promiscious flag for interface */ + ifr.ifr_flags |= IFF_PROMISC; + if (ioctl(sd, SIOCSIFFLAGS, &ifr)) + error(-1, errno, "Failed to enable promiscuous mode"); + + /* Get interface index */ + if (ioctl(sd, SIOCGIFINDEX, &ifr)) + error(-1, errno, "Failed to get interface index"); + + /* Bind socket to interface */ + memset(&sll, 0, sizeof(sll)); + sll.sll_protocol = htons(ETH_P_ALL); + sll.sll_ifindex = ifr.ifr_ifindex; + + if (bind(sd, (struct sockaddr*) &sll, sizeof(sll))) + error(-1, errno, "Failed to bind socket to interface"); + + printf("Successfully put interface %s (%u) into promiscuous mode!\n", + ifr.ifr_name, ifr.ifr_ifindex); + printf("The socket is now bound/listening on interface %s", ifr.ifr_name); + while (1) { - if (recv(sd, packet, sizeof(packet), 0) > 0) - parse_packet(packet, sizeof(packet)); + ssize_t bytes = recv(sd, packet, sizeof(packet), 0); + if (bytes == -1) + error(-1, errno, "Failed to recv"); + + printf("Received %u bytes\n", bytes); + parse_packet(packet, sizeof(packet)); } close(sd); return 0; -} \ No newline at end of file +}