diff options
| author | David M. Syzdek <david.syzdek@acsalaska.com> | 2020-01-30 18:11:28 -0900 |
|---|---|---|
| committer | David M. Syzdek <david.syzdek@acsalaska.com> | 2020-01-30 18:11:28 -0900 |
| commit | c8f036a79d152f4c6d993d2df503363dee5f194d (patch) | |
| tree | f8fc841f0d5ff1beddeb8bdfe315ae1a5c7b24b0 | |
| parent | 3429a757b8049d7e57d7d990a6193fa848bc9936 (diff) | |
| download | akcom-udpecho-c8f036a79d152f4c6d993d2df503363dee5f194d.tar.gz akcom-udpecho-c8f036a79d152f4c6d993d2df503363dee5f194d.tar.bz2 akcom-udpecho-c8f036a79d152f4c6d993d2df503363dee5f194d.tar.xz akcom-udpecho-c8f036a79d152f4c6d993d2df503363dee5f194d.zip | |
adding option to specify listening address
| -rw-r--r-- | src/akcom-udpechod.c | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/src/akcom-udpechod.c b/src/akcom-udpechod.c index 190b8b5..aa6ce10 100644 --- a/src/akcom-udpechod.c +++ b/src/akcom-udpechod.c | |||
| @@ -151,6 +151,7 @@ struct | |||
| 151 | int32_t verbose; // runtime verbosity | 151 | int32_t verbose; // runtime verbosity |
| 152 | int facility; // syslog facility | 152 | int facility; // syslog facility |
| 153 | int dont_fork; | 153 | int dont_fork; |
| 154 | const char * listen; // IP address to listen for requests | ||
| 154 | } | 155 | } |
| 155 | cnf = | 156 | cnf = |
| 156 | { | 157 | { |
| @@ -163,6 +164,7 @@ cnf = | |||
| 163 | .verbose = 0, | 164 | .verbose = 0, |
| 164 | .facility = LOG_DAEMON, | 165 | .facility = LOG_DAEMON, |
| 165 | .dont_fork = 0, | 166 | .dont_fork = 0, |
| 167 | .listen = NULL, | ||
| 166 | }; | 168 | }; |
| 167 | 169 | ||
| 168 | 170 | ||
| @@ -217,13 +219,14 @@ int main(int argc, char * argv[]) | |||
| 217 | int opt_index; | 219 | int opt_index; |
| 218 | 220 | ||
| 219 | // getopt options | 221 | // getopt options |
| 220 | static char short_opt[] = "d:D:ehnp:P:rvV"; | 222 | static char short_opt[] = "d:D:ehl:np:P:rvV"; |
| 221 | static struct option long_opt[] = | 223 | static struct option long_opt[] = |
| 222 | { | 224 | { |
| 223 | {"drop", required_argument, 0, 'd'}, | 225 | {"drop", required_argument, 0, 'd'}, |
| 224 | {"delay", required_argument, 0, 'D'}, | 226 | {"delay", required_argument, 0, 'D'}, |
| 225 | {"echoplus", no_argument, 0, 'e'}, | 227 | {"echoplus", no_argument, 0, 'e'}, |
| 226 | {"help", no_argument, 0, 'h'}, | 228 | {"help", no_argument, 0, 'h'}, |
| 229 | {"listen", required_argument, 0, 'l'}, | ||
| 227 | {"foreground", no_argument, 0, 'n'}, | 230 | {"foreground", no_argument, 0, 'n'}, |
| 228 | {"port", required_argument, 0, 'p'}, | 231 | {"port", required_argument, 0, 'p'}, |
| 229 | {"pidfile", required_argument, 0, 'P'}, | 232 | {"pidfile", required_argument, 0, 'P'}, |
| @@ -294,6 +297,10 @@ int main(int argc, char * argv[]) | |||
| 294 | my_usage(); | 297 | my_usage(); |
| 295 | return(0); | 298 | return(0); |
| 296 | 299 | ||
| 300 | case 'l': | ||
| 301 | cnf.listen = optarg; | ||
| 302 | break; | ||
| 303 | |||
| 297 | case 'n': | 304 | case 'n': |
| 298 | cnf.dont_fork = 1; | 305 | cnf.dont_fork = 1; |
| 299 | break; | 306 | break; |
| @@ -468,9 +475,41 @@ int my_daemonize(void) | |||
| 468 | unlink(pidfile); | 475 | unlink(pidfile); |
| 469 | syslog(LOG_DEBUG, "pidfile: %s", cnf.pidfile); | 476 | syslog(LOG_DEBUG, "pidfile: %s", cnf.pidfile); |
| 470 | 477 | ||
| 478 | // determines interface on which to listen | ||
| 479 | bzero(&sa, sizeof(sa)); | ||
| 480 | if (!(cnf.listen)) | ||
| 481 | { | ||
| 482 | sa.sin6.sin6_family = AF_INET6; | ||
| 483 | sa.sin6.sin6_addr = in6addr_any; | ||
| 484 | sa.sin6.sin6_port = htons(cnf.port); | ||
| 485 | socklen = sizeof(struct sockaddr_in6); | ||
| 486 | } else | ||
| 487 | { | ||
| 488 | if ((rc = inet_pton(AF_INET, cnf.listen, &sa.sin.sin_addr)) == 1) | ||
| 489 | { | ||
| 490 | sa.sin.sin_family = AF_INET; | ||
| 491 | sa.sin.sin_port = htons(cnf.port); | ||
| 492 | socklen = sizeof(struct sockaddr_in); | ||
| 493 | } else if ((rc = inet_pton(AF_INET6, cnf.listen, &sa.sin6.sin6_addr)) == 1) | ||
| 494 | { | ||
| 495 | sa.sin6.sin6_family = AF_INET6; | ||
| 496 | sa.sin6.sin6_port = htons(cnf.port); | ||
| 497 | socklen = sizeof(struct sockaddr_in6); | ||
| 498 | } else | ||
| 499 | { | ||
| 500 | if (rc == -1) | ||
| 501 | syslog(LOG_ERR, "error: inet_pton(): %s", strerror(errno)); | ||
| 502 | else | ||
| 503 | syslog(LOG_ERR, "error: invalid address specified with `-l'"); | ||
| 504 | close(fd); | ||
| 505 | unlink(cnf.pidfile); | ||
| 506 | return(-1); | ||
| 507 | }; | ||
| 508 | }; | ||
| 509 | |||
| 471 | // creates socket | 510 | // creates socket |
| 472 | syslog(LOG_DEBUG, "creating UDP socket"); | 511 | syslog(LOG_DEBUG, "creating UDP socket"); |
| 473 | if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) == -1) | 512 | if ((s = socket(sa.sa.sa_family, SOCK_DGRAM, 0)) == -1) |
| 474 | { | 513 | { |
| 475 | syslog(LOG_ERR, "socket error: %s", strerror(errno)); | 514 | syslog(LOG_ERR, "socket error: %s", strerror(errno)); |
| 476 | close(fd); | 515 | close(fd); |
| @@ -492,11 +531,6 @@ int my_daemonize(void) | |||
| 492 | 531 | ||
| 493 | // bind socket to interface | 532 | // bind socket to interface |
| 494 | syslog(LOG_DEBUG, "binding socket"); | 533 | syslog(LOG_DEBUG, "binding socket"); |
| 495 | bzero(&sa, sizeof(sa)); | ||
| 496 | sa.sin6.sin6_family = AF_INET6; | ||
| 497 | sa.sin6.sin6_addr = in6addr_any; | ||
| 498 | sa.sin6.sin6_port = htons(cnf.port); | ||
| 499 | socklen = sizeof(struct sockaddr_in6); | ||
| 500 | if ((rc = bind(s, &sa.sa, socklen)) == -1) | 534 | if ((rc = bind(s, &sa.sa, socklen)) == -1) |
| 501 | { | 535 | { |
| 502 | syslog(LOG_ERR, "error: bind(): %s", strerror(errno)); | 536 | syslog(LOG_ERR, "error: bind(): %s", strerror(errno)); |
| @@ -507,7 +541,7 @@ int my_daemonize(void) | |||
| 507 | }; | 541 | }; |
| 508 | 542 | ||
| 509 | // log socket address | 543 | // log socket address |
| 510 | socklen = sizeof(struct sockaddr_in6); | 544 | socklen = sizeof(struct sockaddr_storage); |
| 511 | if ((rc = getsockname(s, &sa.sa, &socklen)) == -1) | 545 | if ((rc = getsockname(s, &sa.sa, &socklen)) == -1) |
| 512 | { | 546 | { |
| 513 | syslog(LOG_ERR, "error: getsockname(): %s", strerror(errno)); | 547 | syslog(LOG_ERR, "error: getsockname(): %s", strerror(errno)); |
| @@ -759,13 +793,13 @@ void my_sighandler(int signum) | |||
| 759 | // display program usage | 793 | // display program usage |
| 760 | void my_usage(void) | 794 | void my_usage(void) |
| 761 | { | 795 | { |
| 762 | |||
| 763 | printf("Usage: %s [options]\n", cnf.prog_name); | 796 | printf("Usage: %s [options]\n", cnf.prog_name); |
| 764 | printf("OPTIONS:\n"); | 797 | printf("OPTIONS:\n"); |
| 765 | printf(" -d num, --drop=num set packet drop probability [0-99] (default: %u)\n", cnf.drop_perct); | 798 | printf(" -d num, --drop=num set packet drop probability [0-99] (default: %u)\n", cnf.drop_perct); |
| 766 | printf(" -D ms, --delay=ms set echo delay range to microseconds (default: %u)\n", cnf.delay); | 799 | printf(" -D ms, --delay=ms set echo delay range to microseconds (default: %u)\n", cnf.delay); |
| 767 | printf(" -e, --echoplus enable echo plus, not RFC compliant%s\n", ((cnf.echoplus)) ? " (default)" : ""); | 800 | printf(" -e, --echoplus enable echo plus, not RFC compliant%s\n", ((cnf.echoplus)) ? " (default)" : ""); |
| 768 | printf(" -h, --help print this help and exit\n"); | 801 | printf(" -h, --help print this help and exit\n"); |
| 802 | printf(" -l addr, --listen=addr bind to IP address (default: all)\n"); | ||
| 769 | printf(" -n, --foreground do not fork\n"); | 803 | printf(" -n, --foreground do not fork\n"); |
| 770 | printf(" -p port, --port=port list on port number (default: %u)\n", cnf.port); | 804 | printf(" -p port, --port=port list on port number (default: %u)\n", cnf.port); |
| 771 | printf(" -P file, --pidfile=file PID file (default: %s)\n", cnf.pidfile); | 805 | printf(" -P file, --pidfile=file PID file (default: %s)\n", cnf.pidfile); |
