mirror of
https://codeberg.org/scip/udpxd.git
synced 2025-12-16 19:40:58 +01:00
forgot
This commit is contained in:
2
Makefile
2
Makefile
@@ -21,7 +21,7 @@
|
||||
# warning: do not set -O to 2, see TODO
|
||||
CFLAGS = -Wall -Wextra -Werror -O1 -g
|
||||
LDFLAGS=
|
||||
OBJS = client.o net.o udpxd.o
|
||||
OBJS = host.o client.o net.o udpxd.o
|
||||
DST = udpxd
|
||||
PREFIX = /usr/local
|
||||
UID = root
|
||||
|
||||
10
client.c
10
client.c
@@ -35,10 +35,10 @@ client_t *client_find_fd(int fd) {
|
||||
return client; /* maybe NULL! */
|
||||
}
|
||||
|
||||
client_t *client_find_src(struct sockaddr_in *src) {
|
||||
client_t *client_find_src(host_t *src) {
|
||||
client_t *current = NULL;
|
||||
client_iter(clients, current) {
|
||||
if (current->src == src)
|
||||
if(strcmp(current->src->ip, src->ip) == 0 && current->src->port == src->port)
|
||||
return current;
|
||||
}
|
||||
return NULL;
|
||||
@@ -48,7 +48,7 @@ void client_seen(client_t *client) {
|
||||
client->lastseen = (long)time(0);
|
||||
}
|
||||
|
||||
client_t *client_new(int fd, struct sockaddr_in *src, struct sockaddr_in *dst) {
|
||||
client_t *client_new(int fd, host_t *src, host_t *dst) {
|
||||
client_t *client = malloc(sizeof(client_t));
|
||||
client->socket = fd;
|
||||
client->src = src;
|
||||
@@ -73,10 +73,8 @@ void client_clean() {
|
||||
diff = now - current->lastseen;
|
||||
if(diff >= MAXAGE) {
|
||||
if(VERBOSE) {
|
||||
char *srcip = inet_ntoa(current->src->sin_addr);
|
||||
char *bindip = inet_ntoa(current->dst->sin_addr);
|
||||
fprintf(stderr, "closing socket %s:%d for client %s:%d (aged out after %d seconds)\n",
|
||||
srcip, ntohs(current->src->sin_port), bindip, ntohs(current->dst->sin_port), MAXAGE);
|
||||
current->src->ip, current->src->port, current->dst->ip, current->dst->port, MAXAGE);
|
||||
}
|
||||
client_close(current);
|
||||
}
|
||||
|
||||
10
client.h
10
client.h
@@ -39,14 +39,16 @@ typedef uint8_t byte;
|
||||
#endif
|
||||
|
||||
#include "uthash.h"
|
||||
#include "host.h"
|
||||
|
||||
#define MAXAGE 3600 /* seconds after which to close outgoing sockets and forget client src */
|
||||
|
||||
struct _client_t {
|
||||
int socket; /* bind socket for outgoing traffic */
|
||||
struct sockaddr_in *src; /* client src (ip+port) from incoming socket */
|
||||
struct sockaddr_in *dst; /* client dst (ip+port) to outgoing socket */
|
||||
host_t *src; /* client src (ip+port) from incoming socket */
|
||||
host_t *dst; /* client dst (ip+port) to outgoing socket */
|
||||
uint64_t lastseen; /* when did we recv last time from it */
|
||||
size_t size; /* sockaddr size */
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
typedef struct _client_t client_t;
|
||||
@@ -78,8 +80,8 @@ void client_close(client_t *client);
|
||||
void client_clean();
|
||||
|
||||
client_t *client_find_fd(int fd);
|
||||
client_t *client_find_src(struct sockaddr_in *src);
|
||||
client_t *client_new(int fd, struct sockaddr_in *src, struct sockaddr_in *dst);
|
||||
client_t *client_find_src(host_t *src);
|
||||
client_t *client_new(int fd, host_t *src, host_t *dst);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
184
net.c
184
net.c
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "net.h"
|
||||
#include "client.h"
|
||||
#include "host.h"
|
||||
|
||||
|
||||
|
||||
char *ntoa(struct sockaddr_in *src) {
|
||||
@@ -29,6 +31,7 @@ char *ntoa(struct sockaddr_in *src) {
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
/* called each time when the loop restarts to feed select() correctly */
|
||||
int fill_set(fd_set *fds) {
|
||||
int max = 0;
|
||||
@@ -58,57 +61,106 @@ int get_sender(fd_set *fds) {
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/* bind to a socket, either for listen() or for outgoing src ip binding */
|
||||
int bindsocket( char* ip, int port ) {
|
||||
int bindsocket( host_t *sock_h) {
|
||||
int fd;
|
||||
struct sockaddr_in addr;
|
||||
int err = 0;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr( ip );
|
||||
addr.sin_port = htons( port );
|
||||
if(sock_h->is_v6) {
|
||||
fd = socket( PF_INET6, SOCK_DGRAM, IPPROTO_UDP );
|
||||
}
|
||||
else {
|
||||
fd = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
|
||||
}
|
||||
|
||||
fd = socket( PF_INET, SOCK_DGRAM, IPPROTO_IP );
|
||||
if( -1 == bind( fd, (struct sockaddr*)&addr, sizeof( addr ) ) ) {
|
||||
fprintf( stderr, "Cannot bind address (%s:%d)\n", ip, port );
|
||||
exit( 1 );
|
||||
if( -1 == bind( fd, (struct sockaddr*)sock_h->sock, sock_h->size ) ) {
|
||||
err = 1;
|
||||
}
|
||||
|
||||
if(err) {
|
||||
fprintf( stderr, "Cannot bind address ([%s]:%d)\n", sock_h->ip, sock_h->port );
|
||||
perror(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* handle new or known incoming requests */
|
||||
void handle_inside(int inside, char *bindip, struct sockaddr_in *dst) {
|
||||
int len;
|
||||
unsigned char buffer[MAX_BUFFER_SIZE];
|
||||
struct sockaddr_in *src;
|
||||
client_t *client;
|
||||
int output;
|
||||
char *srcip;
|
||||
char *dstip = ntoa(dst);
|
||||
size_t size = sizeof(struct sockaddr_in);
|
||||
src = malloc(size);
|
||||
int start_listener (char *inip, char *inpt, char *srcip, char *dstip, char *dstpt) {
|
||||
host_t *listen_h = get_host(inip, atoi(inpt), NULL, NULL);
|
||||
host_t *dst_h = get_host(dstip, atoi(dstpt), NULL, NULL);
|
||||
host_t *bind_h = NULL;
|
||||
|
||||
len = recvfrom( inside, buffer, sizeof( buffer ), 0, (struct sockaddr*)src, (socklen_t *)&size );
|
||||
srcip = ntoa(src);
|
||||
if(srcip != NULL) {
|
||||
bind_h = get_host(srcip, 0, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
if(dst_h->is_v6)
|
||||
bind_h = get_host("::0", 0, NULL, NULL);
|
||||
else
|
||||
bind_h = get_host("0.0.0.0", 0, NULL, NULL);
|
||||
}
|
||||
|
||||
int listen = bindsocket(listen_h);
|
||||
|
||||
if(listen == -1)
|
||||
return 1;
|
||||
|
||||
if(VERBOSE) {
|
||||
fprintf(stderr, "Listening on %s:%s, forwarding to %s:%s",
|
||||
inip, inpt, dstip, dstpt);
|
||||
if(srcip != NULL)
|
||||
fprintf(stderr, ", binding to %s\n", srcip);
|
||||
else
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
main_loop(listen, listen_h, bind_h, dst_h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* handle new or known incoming requests
|
||||
FIXME: check client handling:
|
||||
http://long.ccaba.upc.es/long/045Guidelines/eva/ipv6.html#daytimeServer6
|
||||
*/
|
||||
void handle_inside(int inside, host_t *listen_h, host_t *bind_h, host_t *dst_h) {
|
||||
int len;
|
||||
unsigned char buffer[MAX_BUFFER_SIZE];
|
||||
void *src;
|
||||
client_t *client;
|
||||
host_t *src_h;
|
||||
int output;
|
||||
size_t size = listen_h->size;
|
||||
|
||||
src = malloc(size);
|
||||
|
||||
len = recvfrom( inside, buffer, sizeof( buffer ), 0,
|
||||
(struct sockaddr*)src, (socklen_t *)&size );
|
||||
|
||||
if(listen_h->is_v6)
|
||||
src_h = get_host(NULL, 0, NULL, (struct sockaddr_in6 *)src);
|
||||
else
|
||||
src_h = get_host(NULL, 0, (struct sockaddr_in *)src, NULL);
|
||||
|
||||
if(VERBOSE) {
|
||||
char *srcip = ntoa(src);
|
||||
fprintf(stderr, "New incomming request from %s:%d with %d bytes\n",
|
||||
srcip, ntohs(src->sin_port), len);
|
||||
src_h->ip, src_h->port, len);
|
||||
}
|
||||
|
||||
if(len > 0) {
|
||||
/* do we know it ? */
|
||||
client = client_find_src(src);
|
||||
client = client_find_src(src_h);
|
||||
if(client != NULL) {
|
||||
/* yes, we know it, send req out via existing bind socket */
|
||||
if(VERBOSE) {
|
||||
fprintf(stderr, "Client %s:%d is known, forwarding data to %s:%d\n",
|
||||
srcip, ntohs(src->sin_port), dstip, ntohs(dst->sin_port));
|
||||
src_h->ip, src_h->port, dst_h->ip, dst_h->port);
|
||||
|
||||
}
|
||||
if(sendto(client->socket, buffer, len, 0, (struct sockaddr*)dst, size) < 0) {
|
||||
fprintf(stderr, "unable to forward to %s:%d\n", dstip, ntohs(dst->sin_port));
|
||||
if(sendto(client->socket, buffer, len, 0, (struct sockaddr*)dst_h->sock, dst_h->size) < 0) {
|
||||
fprintf(stderr, "unable to forward to %s:%d\n", dst_h->ip, dst_h->port);
|
||||
perror(NULL);
|
||||
}
|
||||
else {
|
||||
@@ -119,29 +171,38 @@ void handle_inside(int inside, char *bindip, struct sockaddr_in *dst) {
|
||||
/* unknown client, open new out socket */
|
||||
if(VERBOSE) {
|
||||
fprintf(stderr, "Client %s:%d is unknown, forwarding data to %s:%d ",
|
||||
srcip, ntohs(src->sin_port), dstip, ntohs(dst->sin_port));
|
||||
src_h->ip, src_h->port, dst_h->ip, dst_h->port);
|
||||
|
||||
}
|
||||
|
||||
if(bindip == NULL)
|
||||
output = bindsocket("0.0.0.0", 0);
|
||||
else
|
||||
output = bindsocket(bindip, 0);
|
||||
output = bindsocket(bind_h);
|
||||
|
||||
/* send req out */
|
||||
if(sendto(output, buffer, len, 0, (struct sockaddr*)dst, size) < 0) {
|
||||
fprintf(stderr, "unable to forward to %s:%d\n", dstip, ntohs(dst->sin_port));
|
||||
if(sendto(output, buffer, len, 0, (struct sockaddr*)dst_h->sock, dst_h->size) < 0) {
|
||||
fprintf(stderr, "unable to forward to %s:%d\n", dst_h->ip, dst_h->port);
|
||||
perror(NULL);
|
||||
}
|
||||
else {
|
||||
struct sockaddr_in *ret = malloc(size);
|
||||
getsockname(output, (struct sockaddr*)ret, (socklen_t *)&size);
|
||||
client = client_new(output, src, ret);
|
||||
size = listen_h->size;
|
||||
host_t *ret_h;
|
||||
if(listen_h->is_v6) {
|
||||
struct sockaddr_in6 *ret = malloc(size);
|
||||
getsockname(output, (struct sockaddr*)ret, (socklen_t *)&size);
|
||||
ret_h = get_host(NULL, 0, NULL, ret);
|
||||
client = client_new(output, src_h, ret_h);
|
||||
}
|
||||
else {
|
||||
struct sockaddr_in *ret = malloc(size);
|
||||
getsockname(output, (struct sockaddr*)ret, (socklen_t *)&size);
|
||||
ret_h = get_host(NULL, 0, ret, NULL);
|
||||
client = client_new(output, src_h, ret_h);
|
||||
}
|
||||
|
||||
client_add(client);
|
||||
|
||||
if(VERBOSE) {
|
||||
if(bindip != NULL) {
|
||||
char *bindip = ntoa(ret);
|
||||
fprintf(stderr, "from %s:%d\n", bindip, ntohs(ret->sin_port));
|
||||
if(strcmp(bind_h->ip, "0.0.0.0") != 0 || strcmp(bind_h->ip, "::0") != 0) {
|
||||
fprintf(stderr, "from %s:%d\n", ret_h->ip, ret_h->port);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "\n");
|
||||
@@ -151,18 +212,17 @@ void handle_inside(int inside, char *bindip, struct sockaddr_in *dst) {
|
||||
}
|
||||
}
|
||||
|
||||
free(dstip);
|
||||
free(srcip);
|
||||
/* FIXME: free? */
|
||||
}
|
||||
|
||||
/* handle answer from the outside */
|
||||
void handle_outside(int inside, int outside) {
|
||||
void handle_outside(int inside, int outside, host_t *outside_h) {
|
||||
int len;
|
||||
unsigned char buffer[MAX_BUFFER_SIZE];
|
||||
struct sockaddr_in *src;
|
||||
void *src;
|
||||
client_t *client;
|
||||
|
||||
size_t size = sizeof(struct sockaddr_in);
|
||||
size_t size = outside_h->size;
|
||||
src = malloc(size);
|
||||
|
||||
len = recvfrom( outside, buffer, sizeof( buffer ), 0, (struct sockaddr*)src, (socklen_t *)&size );
|
||||
@@ -172,7 +232,7 @@ void handle_outside(int inside, int outside) {
|
||||
client = client_find_fd(outside);
|
||||
if(client != NULL) {
|
||||
/* yes, we know it */
|
||||
if(sendto(inside, buffer, len, 0, (struct sockaddr*)client->src, size) < 0) {
|
||||
if(sendto(inside, buffer, len, 0, (struct sockaddr*)client->src, client->size) < 0) {
|
||||
perror("unable to send back to client"); /* FIXME: add src+port */
|
||||
client_close(client);
|
||||
}
|
||||
@@ -180,3 +240,33 @@ void handle_outside(int inside, int outside) {
|
||||
}
|
||||
}
|
||||
|
||||
/* runs forever, handles incoming requests on the inside and answers on the outside */
|
||||
int main_loop(int listensocket, host_t *listen_h, host_t *bind_h, host_t *dst_h) {
|
||||
int max, sender;
|
||||
fd_set fds;
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&fds);
|
||||
max = fill_set(&fds);
|
||||
|
||||
FD_SET(listensocket, &fds);
|
||||
if (listensocket > max)
|
||||
max = listensocket;
|
||||
|
||||
select(max + 1, &fds, NULL, NULL, NULL);
|
||||
|
||||
if (FD_ISSET(listensocket, &fds)) {
|
||||
/* incoming client on the inside, get src, bind output fd, add to list
|
||||
if known, otherwise just handle it */
|
||||
handle_inside(listensocket, listen_h, bind_h, dst_h);
|
||||
}
|
||||
else {
|
||||
/* remote answer came in on an output fd, proxy back to the inside */
|
||||
sender = get_sender(&fds);
|
||||
handle_outside(listensocket, sender, dst_h);
|
||||
}
|
||||
|
||||
/* close old outputs, if any */
|
||||
client_clean();
|
||||
}
|
||||
}
|
||||
|
||||
17
net.h
17
net.h
@@ -35,6 +35,7 @@
|
||||
#include <sys/fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#include "client.h"
|
||||
|
||||
#define MAX_BUFFER_SIZE 65535
|
||||
@@ -42,10 +43,20 @@
|
||||
extern client_t *clients;
|
||||
extern int VERBOSE;
|
||||
|
||||
|
||||
|
||||
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, char *dstpt);
|
||||
|
||||
int fill_set(fd_set *fds);
|
||||
int get_sender(fd_set *fds);
|
||||
int bindsocket( char* ip, int port );
|
||||
void handle_inside(int inside, char *bindip, struct sockaddr_in *dst);
|
||||
void handle_outside(int inside, int outside);
|
||||
int bindsocket( host_t *sock_h);
|
||||
|
||||
|
||||
|
||||
#define _IS_LINK_LOCAL(a) do { IN6_IS_ADDR_LINKLOCAL(a); } while(0)
|
||||
|
||||
#endif
|
||||
|
||||
168
udpxd.c
168
udpxd.c
@@ -27,43 +27,70 @@
|
||||
client_t *clients = NULL;
|
||||
int VERBOSE = 0;
|
||||
|
||||
/* runs forever, handles incoming requests on the inside and answers on the outside */
|
||||
int main_loop(int listensocket, char *bindip, struct sockaddr_in *dst) {
|
||||
int max, sender;
|
||||
fd_set fds;
|
||||
/* parse ip:port */
|
||||
int parse_ip(char *src, char *ip, char *pt) {
|
||||
char *ptr = NULL;
|
||||
|
||||
for(;;) {
|
||||
FD_ZERO(&fds);
|
||||
max = fill_set(&fds);
|
||||
if (strchr(optarg, '[')) {
|
||||
/* v6 */
|
||||
ptr = strtok(&src[1], "]");
|
||||
|
||||
FD_SET(listensocket, &fds);
|
||||
if (listensocket > max)
|
||||
max = listensocket;
|
||||
|
||||
select(max + 1, &fds, NULL, NULL, NULL);
|
||||
|
||||
if (FD_ISSET(listensocket, &fds)) {
|
||||
/* incoming client on the inside, get src, bind output fd, add to list
|
||||
if known, otherwise just handle it */
|
||||
handle_inside(listensocket, bindip, dst);
|
||||
}
|
||||
else {
|
||||
/* remote answer came in on an output fd, proxy back to the inside */
|
||||
sender = get_sender(&fds);
|
||||
handle_outside(listensocket, sender);
|
||||
}
|
||||
|
||||
/* close old outputs, if any */
|
||||
client_clean();
|
||||
if(strlen(ptr) > INET6_ADDRSTRLEN) {
|
||||
fprintf(stderr, "ip v6 address is too long!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
strncpy(ip, ptr, strlen(ptr)+1);
|
||||
ptr = strtok(NULL, "]");
|
||||
if(ptr)
|
||||
ptr = &ptr[1]; /* remove : */
|
||||
}
|
||||
else if(strchr(optarg, ':')) {
|
||||
/* v4 */
|
||||
ptr = strtok(src, ":");
|
||||
|
||||
if(strlen(ptr) > INET_ADDRSTRLEN) {
|
||||
fprintf(stderr, "ip v4 address is too long!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
strncpy(ip, ptr, strlen(ptr)+1);
|
||||
ptr = strtok(NULL, ":");
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Invalid ip/port specification!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(ptr != NULL) {
|
||||
/* got a port */
|
||||
if(strlen(ptr) > 5) {
|
||||
fprintf(stderr, "port is too long!\n");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
if(atoi(ptr) > 65535) {
|
||||
fprintf(stderr, "maximum port number possible: 65535!\n");
|
||||
return 1;
|
||||
}
|
||||
strncpy(pt, ptr, strlen(ptr)+1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Port is missing!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main ( int argc, char* argv[] ) {
|
||||
int listen, opt;
|
||||
int opt, err;
|
||||
char *inip, *inpt, *srcip, *dstip, *dstpt;
|
||||
struct sockaddr_in *dst;
|
||||
char colon[] = ":";
|
||||
err = 0;
|
||||
|
||||
static struct option longopts[] = {
|
||||
{ "listen", required_argument, NULL, 'l' },
|
||||
@@ -96,49 +123,27 @@ int main ( int argc, char* argv[] ) {
|
||||
VERBOSE = 1;
|
||||
break;
|
||||
case 'l':
|
||||
if(strchr(optarg, ':')) {
|
||||
char *ptr = NULL;
|
||||
ptr = strtok(optarg, colon);
|
||||
inip = malloc( strlen(ptr)+1);
|
||||
strncpy(inip, ptr, strlen(ptr)+1);
|
||||
ptr = strtok(NULL, colon);
|
||||
if(ptr != NULL) {
|
||||
inpt = malloc( strlen(ptr)+1);
|
||||
strncpy(inpt, ptr, strlen(ptr)+1);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Listen port for parameter -l is missing!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
inip = malloc(INET6_ADDRSTRLEN+1);
|
||||
inpt = malloc(6);
|
||||
if (parse_ip(optarg, inip, inpt) != 0) {
|
||||
fprintf(stderr, "Parameter -l has the format <ip-address:port>!\n");
|
||||
return 0;
|
||||
err = 1;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if(strchr(optarg, ':')) {
|
||||
char *ptr = NULL;
|
||||
ptr = strtok(optarg, colon);
|
||||
dstip = malloc( strlen(ptr)+1);
|
||||
strncpy(dstip, ptr, strlen(ptr)+1);
|
||||
ptr = strtok(NULL, colon);
|
||||
if(ptr != NULL) {
|
||||
dstpt = malloc( strlen(ptr)+1);
|
||||
strncpy(dstpt, ptr, strlen(ptr)+1);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Destination port for parameter -d is missing!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dstip = malloc(INET6_ADDRSTRLEN+1);
|
||||
dstpt = malloc(6);
|
||||
if (parse_ip(optarg, dstip, dstpt) != 0) {
|
||||
fprintf(stderr, "Parameter -d has the format <ip-address:port>!\n");
|
||||
return 0;
|
||||
err = 1;
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
srcip = malloc(strlen(optarg));
|
||||
if(strlen(optarg) > INET6_ADDRSTRLEN) {
|
||||
fprintf(stderr, "Bind ip address is too long!\n");
|
||||
err = 1;
|
||||
}
|
||||
srcip = malloc(INET6_ADDRSTRLEN+1);
|
||||
strncpy(srcip, optarg, strlen(optarg));
|
||||
break;
|
||||
default:
|
||||
@@ -151,36 +156,33 @@ int main ( int argc, char* argv[] ) {
|
||||
if(inip == NULL) {
|
||||
fprintf(stderr, "-l parameter is required!\n");
|
||||
usage();
|
||||
return 1;
|
||||
err = 1;
|
||||
}
|
||||
|
||||
if(dstip == NULL) {
|
||||
fprintf(stderr, "-d parameter is required!\n");
|
||||
usage();
|
||||
return 1;
|
||||
err = 1;
|
||||
}
|
||||
|
||||
listen = bindsocket(inip, atoi(inpt));
|
||||
|
||||
dst = malloc(sizeof(struct sockaddr_in));
|
||||
dst->sin_family = AF_INET;
|
||||
dst->sin_addr.s_addr = inet_addr( dstip );
|
||||
dst->sin_port = htons( atoi( dstpt ) );
|
||||
|
||||
if(VERBOSE) {
|
||||
fprintf(stderr, "Listening on %s:%s, forwarding to %s:%s",
|
||||
inip, inpt, dstip, dstpt);
|
||||
if(srcip != NULL)
|
||||
fprintf(stderr, ", binding to %s\n", srcip);
|
||||
else
|
||||
fprintf(stderr, "\n");
|
||||
if(! err) {
|
||||
err = start_listener (inip, inpt, srcip, dstip, dstpt);
|
||||
}
|
||||
|
||||
main_loop(listen, srcip, dst);
|
||||
/* FIXME: add sighandler */
|
||||
|
||||
/* FIXME: add sighandler, clean up mem */
|
||||
if(srcip != NULL)
|
||||
free(srcip);
|
||||
if(dstip != NULL)
|
||||
free(dstip);
|
||||
if(inip != NULL)
|
||||
free(inip);
|
||||
if(inpt != NULL)
|
||||
free(inpt);
|
||||
if(dstpt != NULL)
|
||||
free(dstpt);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
void usage() {
|
||||
|
||||
Reference in New Issue
Block a user