diff options
-rw-r--r-- | broadcaster.c | 27 | ||||
-rw-r--r-- | common.h | 8 | ||||
-rw-r--r-- | listener.c | 45 |
3 files changed, 55 insertions, 25 deletions
diff --git a/broadcaster.c b/broadcaster.c index 0e4eef5..9c02f79 100644 --- a/broadcaster.c +++ b/broadcaster.c @@ -14,7 +14,7 @@ #include <arpa/inet.h> #include <netdb.h> -#define SERVERPORT 4950 // the port users will be connecting to +#include "common.h" int main(int argc, char *argv[]) { @@ -23,12 +23,24 @@ int main(int argc, char *argv[]) struct hostent *he; int numbytes; int broadcast = 1; - //char broadcast = '1'; // if that doesn't work, try this - if (argc != 3) { - fprintf(stderr,"usage: broadcaster hostname message\n"); + // assemble packet + if (argc < 3 || argc > 4) { + fprintf(stderr,"usage: broadcaster hostname task [message]\n"); exit(1); } + char buf[MAXBUFLEN], + *task = argv[2], + *message = (argc == 4) ? argv[3] : NULL; + int task_len = strlen(task), + total_len = task_len + 1 + strlen(message); + if (total_len > MAXBUFLEN) { + fprintf(stderr,"payload to long: max %d bytes, was %d\n", MAXBUFLEN, total_len); + exit(1); + } + strcpy(buf, task); + buf[task_len] = 0; + strcpy(buf + 1 + task_len, message); if ((he=gethostbyname(argv[1])) == NULL) { // get the host info perror("gethostbyname"); @@ -52,16 +64,11 @@ int main(int argc, char *argv[]) their_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero); - if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0, + if ((numbytes=sendto(sockfd, buf, total_len, 0, (struct sockaddr *)&their_addr, sizeof their_addr)) == -1) { perror("sendto"); exit(1); } - printf("sent %d bytes to %s\n", numbytes, - inet_ntoa(their_addr.sin_addr)); - - close(sockfd); - return 0; } diff --git a/common.h b/common.h new file mode 100644 index 0000000..c64c764 --- /dev/null +++ b/common.h @@ -0,0 +1,8 @@ +#ifndef UDP_BROADCAST_COMMON +#define UDP_BROADCAST_COMMON + +#define SERVERPORT 4950 // the port users will be connecting to +#define SERVERPORT_S "4950" +#define MAXBUFLEN 100 + +#endif // UDP_BROADCAST_COMMON @@ -13,9 +13,7 @@ #include <arpa/inet.h> #include <netdb.h> -#define MYPORT "4950" // the port users will be connecting to - -#define MAXBUFLEN 100 +#include "common.h" // get sockaddr, IPv4 or IPv6: void *get_in_addr(struct sockaddr *sa) @@ -27,7 +25,7 @@ void *get_in_addr(struct sockaddr *sa) return &(((struct sockaddr_in6*)sa)->sin6_addr); } -int main(void) +int main(int argc, char *argv[], char *envp[]) { int sockfd; struct addrinfo hints, *servinfo, *p; @@ -43,7 +41,7 @@ int main(void) hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; // use my IP - if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) { + if ((rv = getaddrinfo(NULL, SERVERPORT_S, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } @@ -72,18 +70,35 @@ int main(void) freeaddrinfo(servinfo); - + // receive loop addr_len = sizeof their_addr; - if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, - (struct sockaddr *)&their_addr, &addr_len)) == -1) { - perror("recvfrom"); - exit(1); + while ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, + (struct sockaddr *)&their_addr, &addr_len)) != -1) { + // decode packet & launch handler + buf[numbytes] = '\0'; + char *task = buf, + *cl_argv[3] = {task, (strlen(task)<numbytes) ? (buf+strlen(task)+1) : NULL, NULL }; + + if (task[0] == '/' || strstr(task, "..")) { + fprintf(stderr, "payload tried directory traversal\n"); + continue; + } + + switch (fork()) { + case 0: + close(sockfd); // close socket handler, leave std io + execve(task, cl_argv, envp); + perror("exec"); + exit(-1); + case -1: + perror("fork (serious!)"); + exit(-1); + default: + wait(); + } } - buf[numbytes] = '\0'; - printf("%s\n", buf); - - close(sockfd); + perror("recvfrom"); - return 0; + return -1; } |