diff --git a/net.c b/net.c index 4c61ffe..bd39283 100644 --- a/net.c +++ b/net.c @@ -185,7 +185,7 @@ int drop_privileges(char *user, char *chrootdir) { return 0; } -int start_listener (char *inip, char *inpt, char *srcip, char *dstip, +int start_listener (char *inip, char *inpt, char *srcip, char *srcpt, char *dstip, char *dstpt, char *pidfile, char *chrootdir, char *user) { host_t *listen_h, *dst_h, *bind_h; @@ -208,7 +208,7 @@ int start_listener (char *inip, char *inpt, char *srcip, char *dstip, bind_h = NULL; if(srcip != NULL) { - bind_h = get_host(srcip, 0, NULL, NULL); + bind_h = get_host(srcip, atoi(srcpt), NULL, NULL); } else { if(dst_h->is_v6) @@ -298,6 +298,8 @@ void handle_inside(int inside, host_t *listen_h, host_t *bind_h, host_t *dst_h) src_h->ip, src_h->port, len, dst_h->ip, dst_h->port); verb_prbind(bind_h); + if (bind_h->port) + client_clean(1); output = bindsocket(bind_h); if (output >= 0) { /* send req out */ diff --git a/net.h b/net.h index 25156f7..6a7d615 100644 --- a/net.h +++ b/net.h @@ -56,7 +56,7 @@ void handle_inside(int inside, host_t *listen_h, host_t *bind_h, host_t *dst_h); void handle_outside(int inside, int outside, host_t *outside_h); int main_loop(int listensocket, host_t *listen_h, host_t *bind_h, host_t *dst_h); -int start_listener (char *inip, char *inpt, char *srcip, char *dstip, +int start_listener (char *inip, char *inpt, char *srcip, char *srcpt, char *dstip, char *dstpt, char *pidfile, char *chrootdir, char *user); int daemonize(char *pidfile); int drop_privileges(char *user, char *chrootdir); diff --git a/udpxd.c b/udpxd.c index 5f36f35..00ad44b 100644 --- a/udpxd.c +++ b/udpxd.c @@ -92,7 +92,8 @@ void usage() { "Usage: udpxd [-lbdfpvhV]\n\n" "Options:\n" "--listen -l listen for incoming requests\n" - "--bind -b bind ip used for outgoing requests\n" + "--bind -b bind ip used for outgoing requests\n" + " specify port for promiscuous mode\n" "--to -t destination to forward requests to\n" "--daemon -d daemon mode, fork into background\n" "--pidfile -p pidfile, default: /var/run/udpxd.pid\n" @@ -110,7 +111,7 @@ void usage() { int main ( int argc, char* argv[] ) { int opt, err; - char *inip, *inpt, *srcip, *dstip, *dstpt; + char *inip, *inpt, *srcip, *srcpt, *dstip, *dstpt; char pidfile[MAX_BUFFER_SIZE]; char user[128]; char chroot[MAX_BUFFER_SIZE]; @@ -135,7 +136,7 @@ int main ( int argc, char* argv[] ) { return 1; } - srcip = dstip = inip = dstpt = inpt = NULL; + srcip = srcpt = dstip = inip = dstpt = inpt = NULL; /* set defaults */ strncpy(pidfile, "/var/run/udpxd.pid", 19); @@ -171,19 +172,23 @@ int main ( int argc, char* argv[] ) { dstip = malloc(INET6_ADDRSTRLEN+1); dstpt = malloc(6); if (parse_ip(optarg, dstip, dstpt) != 0) { - fprintf(stderr, "Parameter -d has the format !\n"); + fprintf(stderr, "Parameter -t has the format !\n"); err = 1; } break; case 'b': - srcip = malloc(INET6_ADDRSTRLEN+1); - if(strlen(optarg) > INET6_ADDRSTRLEN) { + srcip = malloc(INET6_ADDRSTRLEN+1+5); // +5 is for port + srcpt = malloc(6); + if(strlen(optarg) > INET6_ADDRSTRLEN+5) { fprintf(stderr, "Bind ip address is too long!\n"); err = 1; } else { - strncpy(srcip, optarg, INET6_ADDRSTRLEN); - srcip[INET6_ADDRSTRLEN-1] = '\0'; + if (strchr(optarg, ':') == NULL || parse_ip(optarg, srcip, srcpt) != 0) { + strncpy(srcip, optarg, INET6_ADDRSTRLEN+5); + srcip[INET6_ADDRSTRLEN+5-1] = '\0'; + strncpy(srcpt, "0", 2); + } } break; case 'p': @@ -225,11 +230,13 @@ int main ( int argc, char* argv[] ) { } if(! err) { - err = start_listener (inip, inpt, srcip, dstip, dstpt, pidfile, chroot, user); + err = start_listener (inip, inpt, srcip, srcpt, dstip, dstpt, pidfile, chroot, user); } if(srcip != NULL) free(srcip); + if(srcpt != NULL) + free(srcpt); if(dstip != NULL) free(dstip); if(inip != NULL)