... | ... |
@@ -507,6 +507,89 @@ static void print_con_info(conn_t *conn, const char *fmt, ...) |
507 | 507 |
va_end(ap); |
508 | 508 |
} |
509 | 509 |
|
510 |
+char *get_ip(const char *ip) |
|
511 |
+{ |
|
512 |
+ char *dupip, *p1; |
|
513 |
+ |
|
514 |
+ /* |
|
515 |
+ * Expected format of ip: |
|
516 |
+ * 1) IPv4:Port |
|
517 |
+ * 2) [IPv6]:Port |
|
518 |
+ * |
|
519 |
+ * Use of IPv6:Port is incorrect. An IPv6 address must be enclosed in brackets. |
|
520 |
+ */ |
|
521 |
+ |
|
522 |
+ dupip = strdup(ip); |
|
523 |
+ if (!(dupip)) |
|
524 |
+ return NULL; |
|
525 |
+ |
|
526 |
+ if (dupip[0] == '[') { |
|
527 |
+ /* IPv6 */ |
|
528 |
+ p1 = strchr(dupip, ']'); |
|
529 |
+ if (!(p1)) { |
|
530 |
+ free(dupip); |
|
531 |
+ return NULL; |
|
532 |
+ } |
|
533 |
+ |
|
534 |
+ *p1 = '\0'; |
|
535 |
+ |
|
536 |
+ return (dupip+1); |
|
537 |
+ } |
|
538 |
+ |
|
539 |
+ p1 = strchr(dupip, ':'); |
|
540 |
+ if (!(p1)) { |
|
541 |
+ /* Port number is required */ |
|
542 |
+ free(dupip); |
|
543 |
+ return NULL; |
|
544 |
+ } |
|
545 |
+ |
|
546 |
+ *p1++ = '\0'; |
|
547 |
+ |
|
548 |
+ /* Extra sanity checking. If we have another colon, then we're IPv6. */ |
|
549 |
+ p1 = strchr(p1, ':'); |
|
550 |
+ if ((p1)) { |
|
551 |
+ free(dupip); |
|
552 |
+ return NULL; |
|
553 |
+ } |
|
554 |
+ |
|
555 |
+ return dupip; |
|
556 |
+} |
|
557 |
+ |
|
558 |
+char *get_port(const char *ip) |
|
559 |
+{ |
|
560 |
+ char *dupip, *p; |
|
561 |
+ |
|
562 |
+ dupip = get_ip(ip); |
|
563 |
+ if (!(dupip)) |
|
564 |
+ return NULL; |
|
565 |
+ |
|
566 |
+ p = dupip + strlen(dupip) + 1; |
|
567 |
+ if (*p == ':') |
|
568 |
+ return p+1; |
|
569 |
+ |
|
570 |
+ return p; |
|
571 |
+} |
|
572 |
+ |
|
573 |
+char *make_ip(const char *host, const char *port) |
|
574 |
+{ |
|
575 |
+ char *ip; |
|
576 |
+ size_t len; |
|
577 |
+ int ipv6; |
|
578 |
+ |
|
579 |
+ len = strlen(host) + strlen(port); |
|
580 |
+ |
|
581 |
+ ipv6 = (strchr(host, ':') != NULL); |
|
582 |
+ |
|
583 |
+ len += (ipv6 ? 3 : 2); |
|
584 |
+ |
|
585 |
+ ip = calloc(1, len); |
|
586 |
+ if (!(ip)) |
|
587 |
+ return NULL; |
|
588 |
+ |
|
589 |
+ snprintf(ip, len, "%s%s%s:%s", ipv6 ? "[" : "", host, ipv6 ? "]" : "", port); |
|
590 |
+ |
|
591 |
+ return ip; |
|
592 |
+} |
|
510 | 593 |
|
511 | 594 |
static int make_connection_real(const char *soname, conn_t *conn) |
512 | 595 |
{ |
... | ... |
@@ -516,6 +599,7 @@ static int make_connection_real(const char *soname, conn_t *conn) |
516 | 516 |
char *name, *pt = strdup(soname); |
517 | 517 |
const char *host = pt; |
518 | 518 |
struct addrinfo hints, *res=NULL, *p; |
519 |
+ int err; |
|
519 | 520 |
|
520 | 521 |
conn->tcp = 0; |
521 | 522 |
|
... | ... |
@@ -550,18 +634,19 @@ static int make_connection_real(const char *soname, conn_t *conn) |
550 | 550 |
hints.ai_socktype = SOCK_STREAM; |
551 | 551 |
hints.ai_flags = AI_PASSIVE; |
552 | 552 |
|
553 |
+ host = get_ip(soname); |
|
554 |
+ if (!(host)) |
|
555 |
+ return -1; |
|
556 |
+ |
|
557 |
+ port = get_port(soname); |
|
558 |
+ |
|
553 | 559 |
conn->tcp=1; |
554 |
- name = strchr(pt, '/'); |
|
555 |
- if(name) { |
|
556 |
- *name = '\0'; |
|
557 |
- port = name+1; |
|
558 |
- } else { |
|
559 |
- port = NULL; |
|
560 |
- } |
|
561 | 560 |
|
562 |
- print_con_info(conn, "Looking up: %s\n", host); |
|
563 |
- if (getaddrinfo(host, (port != NULL) ? port : "3310", &hints, &res)) |
|
561 |
+ print_con_info(conn, "Looking up: %s:%s\n", host, port ? port : "3310"); |
|
562 |
+ if ((err = getaddrinfo(host, (port != NULL) ? port : "3310", &hints, &res))) { |
|
563 |
+ print_con_info(conn, "Could not look up %s:%s, getaddrinfo returned: %s\n", host, port ? port : "3310", gai_strerror(err)); |
|
564 | 564 |
return -1; |
565 |
+ } |
|
565 | 566 |
|
566 | 567 |
for (p = res; p != NULL; p = p->ai_next) { |
567 | 568 |
if ((s = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) { |
... | ... |
@@ -569,7 +654,7 @@ static int make_connection_real(const char *soname, conn_t *conn) |
569 | 569 |
continue; |
570 | 570 |
} |
571 | 571 |
|
572 |
- print_con_info(conn, "Connecting to: %s:%s\n", host, port); |
|
572 |
+ print_con_info(conn, "Connecting to: %s\n", soname); |
|
573 | 573 |
if (connect(s, p->ai_addr, p->ai_addrlen)) { |
574 | 574 |
perror("connect"); |
575 | 575 |
close(s); |
... | ... |
@@ -593,7 +678,7 @@ end: |
593 | 593 |
if (conn->remote) |
594 | 594 |
free(conn->remote); |
595 | 595 |
|
596 |
- conn->remote = strdup(soname); |
|
596 |
+ conn->remote = make_ip(host, (port != NULL) ? port : "3310"); |
|
597 | 597 |
} |
598 | 598 |
conn->sd = s; |
599 | 599 |
gettimeofday(&conn->tv_conn, NULL); |
... | ... |
@@ -1132,7 +1217,7 @@ static void help(void) |
1132 | 1132 |
printf(" --version -V Show version\n"); |
1133 | 1133 |
printf(" --config-file=FILE -c FILE Read clamd's configuration files from FILE\n"); |
1134 | 1134 |
printf(" --defaultcolors -d Use default terminal colors\n"); |
1135 |
- printf(" host[/port] Connect to clamd on host at port (default 3310)\n"); |
|
1135 |
+ printf(" host[:port] Connect to clamd on host at port (default 3310)\n"); |
|
1136 | 1136 |
printf(" /path/to/clamd.socket Connect to clamd over a local socket\n"); |
1137 | 1137 |
printf("\n"); |
1138 | 1138 |
return; |
... | ... |
@@ -1192,8 +1277,8 @@ static void setup_connections(int argc, char *argv[]) |
1192 | 1192 |
if ((opt_addr = optget(clamd_opts, "TCPAddr"))->enabled) { |
1193 | 1193 |
host = opt_addr->strarg; |
1194 | 1194 |
} |
1195 |
- snprintf(buf, sizeof(buf), "%s/%llu", host, opt->numarg); |
|
1196 |
- conn = strdup(buf); |
|
1195 |
+ snprintf(buf, sizeof(buf), "%lld", opt->numarg); |
|
1196 |
+ conn = make_ip(host, buf); |
|
1197 | 1197 |
} else { |
1198 | 1198 |
fprintf(stderr, "Can't find how to connect to clamd\n"); |
1199 | 1199 |
EXIT_PROGRAM(FAIL_INITIAL_CONN); |