summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/checksum.h5
-rw-r--r--src/client.c22
-rw-r--r--src/client.h7
-rw-r--r--src/common.h14
-rw-r--r--src/server.c12
-rw-r--r--src/server.h9
-rw-r--r--src/udpastcp.c82
-rwxr-xr-xtest.sh4
8 files changed, 123 insertions, 32 deletions
diff --git a/src/checksum.h b/src/checksum.h
index 74fe69f..192d538 100644
--- a/src/checksum.h
+++ b/src/checksum.h
@@ -1,3 +1,6 @@
+#ifndef CHECKSUM_H
+#define CHECKSUM_H
+
#include <stdint.h>
struct sockaddr;
@@ -14,3 +17,5 @@ uint16_t csum_partial(const void *buff, int len, uint16_t wsum);
* otherwise identical to csum_partial.
*/
uint16_t csum_sockaddr_partial(const struct sockaddr *addr, int incl_port, uint16_t wsum);
+
+#endif
diff --git a/src/client.c b/src/client.c
index 733ffa0..1517481 100644
--- a/src/client.c
+++ b/src/client.c
@@ -23,8 +23,7 @@
#define PORTS_IN_INT (sizeof(int) * CHAR_BIT)
struct c_data {
- const char *r_host;
- const char *r_port;
+ const struct common_data *common_data;
struct o_c_sock *o_socks_by_caddr;
struct o_c_rsock *o_rsocks;
struct sockaddr_storage pkt_addr;
@@ -410,9 +409,9 @@ static inline struct o_c_sock * c_sock_init(EV_P_ struct c_data *c_data) {
struct o_c_sock *sock = NULL;
struct addrinfo *res;
- DBG("looking up [%s]:%s", c_data->r_host, c_data->r_port);
+ DBG("looking up [%s]:%s", c_data->common_data->remote_host, c_data->common_data->remote_port);
// TODO: make this asynchronous
- int r = getaddrinfo(c_data->r_host, c_data->r_port, NULL, &res);
+ int r = getaddrinfo(c_data->common_data->remote_host, c_data->common_data->remote_port, NULL, &res);
if (r) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(r));
goto err;
@@ -565,18 +564,17 @@ static void c_finish(EV_P_ ev_signal *w __attribute__((unused)), int revents __a
ev_break(EV_A_ EVBREAK_ALL);
}
-int start_client(const char *s_host, const char *s_port, const char *r_host, const char *r_port) {
+int start_client(const struct common_data *common_data) {
struct addrinfo *res;
- int r = getaddrinfo(s_host, s_port, NULL, &res);
+ int r = getaddrinfo(common_data->listen_host, common_data->listen_port, NULL, &res);
if (r) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(r));
return 3;
}
struct c_data c_data = {
- .s_addrlen = res->ai_addrlen,
- .r_host = r_host,
- .r_port = r_port
+ .common_data = common_data,
+ .s_addrlen = res->ai_addrlen
};
c_data.s_sock = socket(res->ai_family, SOCK_DGRAM, 0);
@@ -597,13 +595,13 @@ int start_client(const char *s_host, const char *s_port, const char *r_host, con
return 4;
}
- global_c_data = &c_data;
- atexit(c_cleanup);
-
struct ev_loop *loop = EV_DEFAULT;
ev_io s_watcher;
ev_signal iwatcher, twatcher;
+ global_c_data = &c_data;
+ atexit(c_cleanup);
+
s_watcher.data = &c_data;
ev_io_init(&s_watcher, cs_cb, c_data.s_sock, EV_READ);
diff --git a/src/client.h b/src/client.h
index 69d4c7d..72c86fb 100644
--- a/src/client.h
+++ b/src/client.h
@@ -1 +1,6 @@
-int start_client(const char *s_host, const char *s_port, const char *r_host, const char *r_port);
+#ifndef CLIENT_H
+#define CLIENT_H
+#include "common.h"
+
+int start_client(const struct common_data *);
+#endif
diff --git a/src/common.h b/src/common.h
index fea0db7..9dd7318 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,3 +1,6 @@
+#ifndef COMMON_H
+#define COMMON_H
+
#ifdef DEBUG
#define DBG(...) do { fprintf(stderr, __VA_ARGS__); putc('\n', stderr); } while (0)
#else
@@ -7,3 +10,14 @@
#define IN_ADDR_PORT(addr) (((struct sockaddr_in *)addr)->sin_port)
extern int free_mem_on_exit;
+extern void *libpcap;
+
+struct common_data {
+ const char *listen_host;
+ const char *listen_port;
+ const char *remote_host;
+ const char *remote_port;
+ const char *device;
+};
+
+#endif
diff --git a/src/server.c b/src/server.c
index 382e675..b9c2783 100644
--- a/src/server.c
+++ b/src/server.c
@@ -20,10 +20,9 @@
#include "uthash.h"
struct s_data {
+ const struct common_data *common_data;
struct sockaddr *s_addr;
struct sockaddr_storage pkt_addr;
- const char *r_host;
- const char *r_port;
struct o_s_sock *o_socks_by_caddr;
int s_sock;
socklen_t s_addrlen;
@@ -299,7 +298,7 @@ static void ss_cb(EV_P_ ev_io *w, int revents __attribute__((unused))) {
sock->status = TCP_ESTABLISHED;
struct addrinfo *res;
- r = getaddrinfo(s_data->r_host, s_data->r_port, NULL, &res);
+ r = getaddrinfo(s_data->common_data->remote_host, s_data->common_data->remote_port, NULL, &res);
if (r) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(r));
ev_break(EV_A_ EVBREAK_ONE);
@@ -375,9 +374,9 @@ static void s_finish(EV_P_ ev_signal *w __attribute__((unused)), int revents __a
ev_break(EV_A_ EVBREAK_ALL);
}
-int start_server(const char *s_host, const char *s_port, const char *r_host, const char *r_port) {
+int start_server(const struct common_data *common_data) {
struct addrinfo *res;
- int r = getaddrinfo(s_host, s_port, NULL, &res);
+ int r = getaddrinfo(common_data->listen_host, common_data->listen_port, NULL, &res);
if (r) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(r));
return 1;
@@ -386,10 +385,9 @@ int start_server(const char *s_host, const char *s_port, const char *r_host, con
char proto[] = { 0, IPPROTO_TCP };
struct s_data s_data = {
+ .common_data = common_data,
.s_addr = res->ai_addr,
.s_addrlen = res->ai_addrlen,
- .r_host = r_host,
- .r_port = r_port,
.csum_p = csum_sockaddr_partial(res->ai_addr, 1,
csum_partial(&proto, sizeof(proto), 0))
};
diff --git a/src/server.h b/src/server.h
index 3157173..80fb26b 100644
--- a/src/server.h
+++ b/src/server.h
@@ -1 +1,8 @@
-int start_server(const char *s_addr, const char *s_port, const char *r_addr, const char *r_port);
+#ifndef SERVER_H
+#define SERVER_H
+
+#include "common.h"
+
+int start_server(const struct common_data *);
+
+#endif
diff --git a/src/udpastcp.c b/src/udpastcp.c
index fa8fea2..31d2d50 100644
--- a/src/udpastcp.c
+++ b/src/udpastcp.c
@@ -1,17 +1,78 @@
+#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
+#include <unistd.h>
#include "common.h"
#include "server.h"
#include "client.h"
int free_mem_on_exit = 0;
+void *libpcap = NULL;
+
+void usage() {
+ puts("usage: udpintcp [OPTION]...\n"
+ "Make UDP look like TCP.\n"
+ "\n"
+ " -m MODE Client/server mode.\n"
+ " -h LISTEN_HOST -p LISTEN_PORT Listen on the specified host/port. Port is required.\n"
+ " -H REMOTE_HOST -P REMOTE_PORT Connect to the specified host/port. Always required.\n"
+ " -d DEVICE Use libpcap and listen on the specified interface.\n");
+}
int main(int argc, char *argv[]) {
- if (argc < 6) {
- puts("usage: udpintcp client|server LISTEN_HOST LISTEN_PORT REMOTE_HOST REMOTE_PORT");
- return !(argc == 2 && !strcmp(argv[1], "--help"));
+ char ch;
+ struct common_data common_data = {
+ .listen_host = "::"
+ };
+ const char *mode = NULL;
+ while ((ch = getopt(argc, argv, "m:h:p:H:P:d:")) != -1) {
+ switch (ch) {
+ case 'm':
+ mode = optarg;
+ break;
+ case 'h':
+ common_data.listen_host = optarg;
+ break;
+ case 'p':
+ common_data.listen_port = optarg;
+ break;
+ case 'H':
+ common_data.remote_host = optarg;
+ break;
+ case 'P':
+ common_data.remote_port = optarg;
+ break;
+ case 'd':
+ common_data.device = optarg;
+ break;
+ case '?':
+ usage();
+ break;
+ default:
+ abort();
+ }
+ if (optind > argc) {
+ fputs("extra arguments on command line\n", stderr);
+ exit(EXIT_FAILURE);
+ }
+ }
+ if (!mode) {
+ fputs("missing required argument: mode", stderr);
+ exit(EXIT_FAILURE);
+ }
+ if (!common_data.listen_port) {
+ fputs("missing required argument: listen port", stderr);
+ exit(EXIT_FAILURE);
+ }
+ if (!common_data.remote_host) {
+ fputs("missing required argument: remote host", stderr);
+ exit(EXIT_FAILURE);
+ }
+ if (!common_data.remote_port) {
+ fputs("missing required argument: remote port", stderr);
+ exit(EXIT_FAILURE);
}
srandom((unsigned int)time(NULL));
@@ -21,14 +82,17 @@ int main(int argc, char *argv[]) {
free_mem_on_exit = 1;
}
- if (!strcmp(argv[1], "client")) {
- DBG("starting client listening on [%s]:%s connecting to [%s]:%s", argv[2], argv[3], argv[4], argv[5]);
- return start_client(argv[2], argv[3], argv[4], argv[5]) == 0;
- } else if (!strcmp(argv[1], "server")) {
- DBG("starting server listening on [%s]:%s connecting to [%s]:%s", argv[2], argv[3], argv[4], argv[5]);
- return start_server(argv[2], argv[3], argv[4], argv[5]) == 0;
+ int (*startf)(struct common_data *);
+
+ if (!strcmp(mode, "client")) {
+ startf = start_client;
+ } else if (!strcmp(mode, "server")) {
+ startf = start_server;
} else {
fputs("invalid mode\n", stderr);
return 1;
}
+
+ DBG("starting %s listening on [%s]:%s connecting to [%s]:%s", mode, common_data.listen_host, common_data.listen_port, common_data.remote_host, common_data.remote_port);
+ return startf(&common_data);
}
diff --git a/test.sh b/test.sh
index a82020a..62f3b93 100755
--- a/test.sh
+++ b/test.sh
@@ -7,9 +7,9 @@ test_bidi() {
(
pids=
trap 'kill $pids' INT TERM EXIT
- $UDPASTCP client "$1" 36563 "$1" 64109 &
+ $UDPASTCP -m client -h "$1" -p 36563 -H "$1" -P 64109 &
pids="$!"
- $UDPASTCP server "$1" 64109 "$1" 41465 &
+ $UDPASTCP -m server -h "$1" -p 64109 -H "$1" -P 41465 &
pids="$pids $!"
( ( sleep 0.5; echo BBBBBBBB; ) | socat "udp-listen:41465,pf=${2}" - ) &
pids="$pids $!"