char *devtun = "tun://tun0:1440";
char *loctun = "tun://10.2.0.1";
char *remtun = "tun://10.2.1.0";
-char *locudp = "udp://10.1.0.1:1234";
-char *remudp = "udp://10.1.0.2:1235";
+char *locudprx = "udp://10.1.0.1:1234";
+char *locudptx = NULL;
+char *remudprx = "udp://10.1.0.2:1235";
+char *remudptx = NULL;
char *cmlocblack = "lo://00:00:00:00:00:00/0829";
char *cmremblack = "lo://00:00:00:00:00:00/0839";
char *cmlocred = "lo://00:00:00:00:00:00/0809";
void usage (void)
{
- printf ("usage: %s [-d devtun] [-h] [-l loctun] [-n mod] [-r remtun] [-t locudp] [-u remudp] [-v int] [-x url url] [-y url url] [-w]\n", progname);
+ printf ("usage: %s [-d devtun] [-h] [-l loctun] [-n mod] [-r remtun] [-t[r|t] locudp] [-u[r|t] remudp] [-v int] [-x url url] [-y url url] [-w]\n", progname);
printf (" -d: dev tun (%s)\n", devtun);
printf (" -h: help message\n");
printf (" -l: local tun (%s)\n", loctun);
printf (" -n: desactivate module (tun,udp,red,black)\n");
printf (" -r: remote tun (%s)\n", remtun);
- printf (" -t: local udp (%s)\n", locudp);
- printf (" -u: remote udp (%s)\n", remudp);
+ if (locudprx != locudptx) {
+ printf (" -t[r|t]: local udp [rx|tx] (%s|%s)\n", locudprx, locudptx);
+ } else {
+ printf (" -t[r|t]: local udp [rx|tx] (%s)\n", locudprx);
+ }
+ if (remudprx != remudptx) {
+ printf (" -u[r|t]: remote udp [rx|tx] (%s|%s)\n", remudprx, remudptx);
+ } else {
+ printf (" -u[r|t]: remote udp [rx|tx] (%s)\n", remudprx);
+ }
printf (" -v: program verbose level [%d..%d] (%d)\n", ERROR, TRACE, GET_VERBOSE_LEVEL (ulvpn));
printf (" -V: library verbose level [%d..%d] (%d)\n", ERROR, TRACE, GET_VERBOSE_LEVEL (mapec));
printf (" -x: black CM service (%s|%s)\n", cmlocblack, cmremblack);
int main (int argc, char **argv)
{
+ locudptx = locudprx;
+ remudptx = remudprx;
/* get basename */
char *ptr = progname = argv[0];
return 1;
}
char c = arg[1];
+ int way = 0;
switch (c) {
case 'd':
arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
loctun = NULL;
remtun = NULL;
} else if (strcmp (arg, "udp") == 0) {
- locudp = NULL;
- remudp = NULL;
+ locudprx = locudptx = NULL;
+ remudprx = remudptx = NULL;
} else if (strcmp (arg, "black") == 0) {
cmlocblack = NULL;
cmremblack = NULL;
remtun = arg;
break;
case 't':
- arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
+ way = (arg[2] == 'r') ? 1 : (arg[2] == 't') ? -1 : 0;
+ arg = (--argc > 0) ? *(++argv) : NULL;
if (arg == NULL) {
VERBOSE (ulvpn, ERROR, PRINTF ("%s: local udp not specified\n", progname));
return 1;
}
- locudp = arg;
+ switch (way) {
+ case 1: locudprx = arg; break;
+ case -1: locudptx = arg; break;
+ default: locudprx = locudptx = arg; break;
+ }
break;
case 'u':
- arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
+ way = (arg[2] == 'r') ? 1 : (arg[2] == 't') ? -1 : 0;
+ arg = (--argc > 0) ? *(++argv) : NULL;
if (arg == NULL) {
VERBOSE (ulvpn, ERROR, PRINTF ("%s: remote udp not specified\n", progname));
return 1;
}
- remudp = arg;
+ switch (way) {
+ case 1: remudprx = arg; break;
+ case -1: remudptx = arg; break;
+ default: remudprx = remudptx = arg; break;
+ }
break;
case 'v':
arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s %s\n", devtun, loctun, remtun));
return -1;
}
- int udp_fd = -1;
- if (((locudp) && (remudp)) && ((udp_fd = MAPEC_Connect (locudp, remudp, NULL)) < 0)) {
- VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s\n", locudp, remudp));
+ int udprx_fd = -1;
+ if (((locudprx) && (remudprx)) && ((udprx_fd = MAPEC_Connect (locudprx, remudprx, NULL)) < 0)) {
+ VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s %s\n", locudprx, remudprx, (locudprx == locudptx) ? "RX/TX" : "RX"));
return -1;
}
+ int udptx_fd = -1;
+ if (locudprx == locudptx) {
+ udptx_fd = udprx_fd;
+ } else {
+ if (((locudptx) && (remudptx)) && ((udptx_fd = MAPEC_Connect (locudptx, remudptx, NULL)) < 0)) {
+ VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s TX\n", locudptx, remudptx));
+ return -1;
+ }
+ }
/* init crypto module communication channels */
int rxblack_fd = (cmlocblack) ? MOREP_Connect (cmlocblack) : -1;
return -1;
}
- VERBOSE (ulvpn, INFO, PRINTF ("fids: %d %d %d %d %d %d\n", tun_fd, udp_fd, rxblack_fd, txblack_fd, rxred_fd, txred_fd));
+ VERBOSE (ulvpn, INFO, PRINTF ("fids: %d %d %d %d %d %d %d\n", tun_fd, udprx_fd, udptx_fd, rxblack_fd, txblack_fd, rxred_fd, txred_fd));
/* signals */
sigset_t mask;
max_fd = tun_fd;
}
}
- if (udp_fd >= 0) {
- FD_SET (udp_fd, &readset);
- if (max_fd < udp_fd) {
- max_fd = udp_fd;
+ if (udprx_fd >= 0) {
+ FD_SET (udprx_fd, &readset);
+ if (max_fd < udprx_fd) {
+ max_fd = udprx_fd;
}
}
if (rxblack_fd >= 0) {
VERBOSE (ulvpn, DEBUG, PRINTF ("send %d bytes to CM red\n", txlen));
}
}
- } else if (udp_fd >= 0) {
- int txlen = MAPEC_Send (udp_fd, buffer, rxlen);
+ } else if (udptx_fd >= 0) {
+ int txlen = MAPEC_Send (udptx_fd, buffer, rxlen);
stat_udp_fd.tx++;
if (txlen <= 0) {
VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to udp\n"));
}
}
- } else if (FD_ISSET (udp_fd, &readset)) {
+ } else if (FD_ISSET (udprx_fd, &readset)) {
uint8_t buffer[MAXPAYLOAD] = {0};
- int rxlen = MAPEC_Receive (udp_fd, buffer, sizeof (buffer));
+ int rxlen = MAPEC_Receive (udprx_fd, buffer, sizeof (buffer));
stat_udp_fd.rx++;
if (rxlen < 0) {
VERBOSE (ulvpn, WARNING, PRINTF ("error when receiving from udp\n"));
}
if (msgtype == 0x01) {
- if (udp_fd >= 0) {
+ if (udptx_fd >= 0) {
int txlen = depack_encrypted_data (buffer, rxlen, sizeof (buffer));
if (txlen <= 0) {
VERBOSE (ulvpn, WARNING, PRINTF ("error when depacking encrypted data\n"));
} else {
VERBOSE (ulvpn, DEBUG, PRINTF ("depacking %d bytes\n", txlen));
- txlen = MAPEC_Send (udp_fd, buffer, txlen);
+ txlen = MAPEC_Send (udptx_fd, buffer, txlen);
stat_udp_fd.tx++;
if (txlen <= 0) {
VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to udp\n"));
/* cleaning */
close (tun_fd);
- close (udp_fd);
+ close (udprx_fd);
+ if (udprx_fd != udptx_fd) {
+ close (udptx_fd);
+ }
return rc;
}
/* test: ulvpn.exe -n 2>&1 | grep 'module not specified' */
/* test: ulvpn.exe -n foo 2>&1 | grep 'unknown module' */
/* test: ulvpn.exe -n tun -h | grep 'dev tun ((null))' */
-/* test: ulvpn.exe -n udp -h | grep 'local udp ((null))' */
+/* test: ulvpn.exe -n udp -h | fgrep 'local udp [rx|tx] ((null))' */
/* test: ulvpn.exe -n black -h | grep 'black CM service ((null)|(null))' */
/* test: ulvpn.exe -n red -h | grep 'red CM service ((null)|(null))' */
/* test: ulvpn.exe -v 5 -n black -n red -t udp://\*:1234 -u udp://localhost:1235 > ulvpn.log & pid=$!; sleep 1; echo TEST | nc -Nuq0 10.2.1.1 3000; kill -TRAP $pid; sleep 1; kill -HUP $pid; sleep 1; echo TEST | nc -Nuq0 10.2.1.1 3000; kill -TRAP $pid; sleep 1; kill -TERM $pid; grep 'tun: RX' ulvpn.log | wc -l | xargs test 2 -eq */
+/* test: ulvpn.exe -v 5 -n black -n red -tr udp://localhost:1234 -ur udp://localhost:1235 -tt udp://localhost:1236 -ut udp://localhost:1237 & pid1=$!; sleep 1; nc -ul 1237 > pcap & pid2=$!; sleep 1; echo | nc -Nuq0 10.2.1.1 3000; echo TEST | nc -Nuq0 10.2.1.1 3000; sleep 1; kill -TERM $pid1 $pid2; strings pcap | grep -q TEST */
+/* test: ulvpn.exe -v 5 -n black -n red -l tun://10.2.1.1 -r tun://10.2.0.0 -tr udp://localhost:1234 -ur udp://localhost:1235 -tt udp://localhost:1236 -ut udp://localhost:1237 & pid1=$!; sleep 1; nc -ul 3000 > text & pid2=$!; sleep 1; cat pcap | nc -4Nuq0 -p 1235 localhost 1234; sleep 1; kill -TERM $pid1 $pid2; test "$(cat text)" = TEST */
+/* test: rm -f pcap text */
+
/* vim: set ts=4 sw=4 si et: */