diff --git a/.gitignore b/.gitignore index 6f0b426..cb3a15a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ INSTALL # build *.o wrapsix-dnsproxy +wrapsix-wrapper # debug core diff --git a/src/Makefile.am b/src/Makefile.am index c36c11e..722fb1d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,2 +1,3 @@ -sbin_PROGRAMS = wrapsix-dnsproxy +sbin_PROGRAMS = wrapsix-dnsproxy wrapsix-wrapper wrapsix_dnsproxy_SOURCES = dnsproxy.c +wrapsix_wrapper_SOURCES = wrapper.c wrapper.h diff --git a/src/wrapper.c b/src/wrapper.c new file mode 100644 index 0000000..fd6aa96 --- /dev/null +++ b/src/wrapper.c @@ -0,0 +1,119 @@ +/* + * WrapSix + * Copyright (C) 2008-2010 Michal Zima + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include /* inet_pton */ +#include /* ETH_P_ALL */ +#include /* struct ifreq */ +#include /* struct packet_mreq, struct sockaddr_ll */ +#include /* htons */ +#include /* ETHERTYPE_* */ +#include +#include /* strncpy */ +#include /* ioctl, SIOCGIFINDEX */ +#include /* close */ + +#include "wrapper.h" + +#define INTERFACE "eth0" +#define BUFFER_SIZE 65536 + +int process(char *packet); + +int main(int argc, char **argv) +{ + struct ifreq interface; + struct packet_mreq pmr; + + struct sockaddr_ll addr; + size_t addr_size; + + int sniff_sock; + int length; + char buffer[BUFFER_SIZE]; + + /* initialize the socket for sniffing */ + if ((sniff_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) { + fprintf(stderr, "[Error] Unable to create listening socket\n"); + return 1; + } + + /* get the interface */ + strncpy(interface.ifr_name, INTERFACE, IFNAMSIZ); + if (ioctl(sniff_sock, SIOCGIFINDEX, &interface) == -1) { + fprintf(stderr, "[Error] Unable to get the interface\n"); + return 1; + } + + /* set the promiscuous mode */ + memset(&pmr, 0x0, sizeof(pmr)); + pmr.mr_ifindex = interface.ifr_ifindex; + pmr.mr_type = PACKET_MR_PROMISC; + if (setsockopt(sniff_sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, (char *) &pmr, sizeof(pmr)) == -1) { + fprintf(stderr, "[Error] Unable to set the promiscuous mode on the interface\n"); + return 1; + } + + /* sniff! :c) */ + for (;;) { + addr_size = sizeof(addr); + if ((length = recv(sniff_sock, buffer, BUFFER_SIZE, 0)) == -1) { + fprintf(stderr, "[Error] Unable to retrieve data from socket\n"); + return 1; + } + + process((char *) &buffer); + } + + /* clean-up */ + /* unset the promiscuous mode */ + if (setsockopt(sniff_sock, SOL_PACKET, PACKET_DROP_MEMBERSHIP, (char *) &pmr, sizeof(pmr)) == -1) { + fprintf(stderr, "[Error] Unable to unset the promiscuous mode on the interface\n"); + /* do not call `return` here as we want to close the socket too */ + } + + /* close the socket */ + close(sniff_sock); + + return 0; +} + +int process(char *packet) +{ + struct s_ethernet *eth; /* the ethernet header */ + char *payload; /* the IP header + packet payload */ + + /* parse ethernet header */ + eth = (struct s_ethernet *) (packet); + payload = packet + sizeof(struct s_ethernet); + + switch (htons(eth->type)) { + case ETHERTYPE_IP: + printf("[Debug] HW Protocol: IPv4\n"); + return -1; + case ETHERTYPE_IPV6: + printf("[Debug] HW Protocol: IPv6\n"); + return -1; + case ETHERTYPE_ARP: + printf("[Debug] HW Protocol: ARP\n"); + return -1; + default: + printf("[Debug] HW Protocol: unknown [%d/0x%04x]\n", + htons(eth->type), htons(eth->type)); + return 1; + } +} diff --git a/src/wrapper.h b/src/wrapper.h new file mode 100644 index 0000000..983a8f7 --- /dev/null +++ b/src/wrapper.h @@ -0,0 +1,39 @@ +/* + * WrapSix + * Copyright (C) 2008-2010 Michal Zima + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef WRAPPER_H +#define WRAPPER_H + +/* MAC address structure */ +struct s_mac_addr { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; +} __attribute__ ((__packed__)); + +/* Ethernet header structure */ +struct s_ethernet { + struct s_mac_addr dest; /* 48 b; destination host (MAC) address */ + struct s_mac_addr src; /* 48 b; source host (MAC) address */ + unsigned short type; /* 16 b; IP/ARP/RARP/... */ +} __attribute__ ((__packed__)); + +#endif /* WRAPPER_H */