summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormiau <miaukatzemiau@priveasy.de>2011-06-05 12:14:34 (GMT)
committermiau <miaukatzemiau@priveasy.de>2011-06-05 12:14:34 (GMT)
commit2ff4666452ee56f4d6c51b7050dbe77456110d2f (patch)
treee5d4d3a17b3bc84902d9a8bed22b42b25d05df67
parentff98567423ed50673ea42404b6c5a32f011850af (diff)
add receiver loop, service multiplexing, common.h
* Service multiplexing Broadcaster call signature is changed to broadcaster host service [message] to acommodate multiple sevices listening on the same port for broadcast information. * Receiver Loop Listener now loops infinitely instead of returning after the first packet. For each packet with the content service[,message] the programm service [message] will be executed. Upward directory traversal is prohibited (and detected). To prevent DoS only one service program runs concurrently. * Common.h Port numbers and maximum message sizes are now stored in common.h. Broascaster respects max. message size.
-rw-r--r--broadcaster.c22
-rw-r--r--common.h8
-rw-r--r--listener.c42
3 files changed, 54 insertions, 18 deletions
diff --git a/broadcaster.c b/broadcaster.c
index 0e4eef5..4160b93 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,7 +64,7 @@ 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);
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
diff --git a/listener.c b/listener.c
index fa9f0c1..2fa6666 100644
--- a/listener.c
+++ b/listener.c
@@ -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;
}
@@ -74,16 +72,34 @@ int main(void)
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] = {buf, (strlen(task)<numbytes) ? (buf+strlen(task)+1) : NULL, NULL };
+
+ if (buf[0] == '/' || strstr(buf, "..")) {
+ fprintf(stderr, "payload tried directory traversal\n");
+ continue;
+ }
+
+ switch (fork()) {
+ case 0:
+ // TODO: clean file descriptors
+ 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);
-
+ perror("recvfrom");
close(sockfd);
- return 0;
+ return -1;
}
contact: Jan Huwald // Impressum