git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1416 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2005/03/21 10:27:50... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Mon Mar 21 02:24:33 CET 2005 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * freshclam: add LocalIPAddress/--local-address (patch by Thomas Lamy) |
|
4 |
+ |
|
1 | 5 |
Mon Mar 21 01:13:41 CET 2005 (tk) |
2 | 6 |
--------------------------------- |
3 | 7 |
* libclamav/pe.c: add W32.Magistr.A/B detection |
... | ... |
@@ -55,6 +55,9 @@ Check #n times per day for a new database. #n must be between 1 and 50. |
55 | 55 |
\fB\-\-daemon\-notify=/path/to/clamd.conf\fR |
56 | 56 |
Notify the daemon about the new database. By default it reads a hardcoded config file but you can use an another one. Both local and TCP sockets are supported. |
57 | 57 |
.TP |
58 |
+\fB\-a IP, \-\-local-address=IP\fR |
|
59 |
+Use (local) IP for HTTP downloads. Useful for multi-homed systems. If binding fails for whatever reason, a warning is issued and freshclam behaves like without this flag. |
|
60 |
+.TP |
|
58 | 61 |
\fB\-\-on\-error\-execute=COMMAND\fR |
59 | 62 |
Execute COMMAND if error occured. Remeber, that virus database freshness is the most important thing in anti\-virus system. With this option freshclam can alert you (eg. send SMS) when something is going wrong. |
60 | 63 |
.TP |
... | ... |
@@ -92,6 +92,11 @@ Proxy usage is authenticated through given username and password. |
92 | 92 |
.br . |
93 | 93 |
Default: no proxy authentication |
94 | 94 |
.TP |
95 |
+\fBLocalIPAddress IP\fR |
|
96 |
+Use \fBIP\fR as client address for downloading databases. Useful for multi homed systems. |
|
97 |
+.br . |
|
98 |
+Default: Use OS\'es default outgoing IP address. |
|
99 |
+.TP |
|
95 | 100 |
\fBNotifyClamd \[STRING\]\fR |
96 | 101 |
Notify a running clamd(8) to reload it\'s database after a download has occured. Optionally a clamd.conf(5) file location may be given to tell freshclam(1) how to communicate with clamd(8). |
97 | 102 |
.br . |
... | ... |
@@ -75,6 +75,11 @@ DatabaseMirror database.clamav.net |
75 | 75 |
#HTTPProxyUsername myusername |
76 | 76 |
#HTTPProxyPassword mypass |
77 | 77 |
|
78 |
+# Use aaa.bbb.ccc.ddd as client address for downloading databases. Useful for multi- |
|
79 |
+# homed systems. |
|
80 |
+# Default: Use OS'es default outgoing IP address. |
|
81 |
+#LocalIPAddress aaa.bbb.ccc.ddd |
|
82 |
+ |
|
78 | 83 |
# Send the RELOAD command to clamd. |
79 | 84 |
# Default: disabled |
80 | 85 |
#NotifyClamd |
... | ... |
@@ -445,6 +445,7 @@ void help(void) |
445 | 445 |
#ifdef BUILD_CLAMD |
446 | 446 |
mprintf(" --daemon-notify[=/path/clamd.conf] send RELOAD command to clamd\n"); |
447 | 447 |
#endif |
448 |
+ mprintf(" --local-address=IP -a IP bind to IP for HTTP downloads\n"); |
|
448 | 449 |
mprintf(" --on-update-execute=COMMAND execute COMMAND after successful update\n"); |
449 | 450 |
mprintf(" --on-error-execute=COMMAND execute COMMAND if errors occured\n"); |
450 | 451 |
|
... | ... |
@@ -38,6 +38,7 @@ |
38 | 38 |
#include <fcntl.h> |
39 | 39 |
#include <sys/stat.h> |
40 | 40 |
#include <clamav.h> |
41 |
+#include <errno.h> |
|
41 | 42 |
|
42 | 43 |
#include "options.h" |
43 | 44 |
#include "defaults.h" |
... | ... |
@@ -56,6 +57,7 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c |
56 | 56 |
int ret, updated = 0, signo = 0, ttl = -1; |
57 | 57 |
char ipaddr[16], *dnsreply = NULL, *pt; |
58 | 58 |
struct cfgstruct *cpt; |
59 |
+ char *localip = NULL; |
|
59 | 60 |
#ifdef HAVE_RESOLV_H |
60 | 61 |
const char *dnsdbinfo; |
61 | 62 |
#endif |
... | ... |
@@ -131,9 +133,15 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c |
131 | 131 |
} |
132 | 132 |
#endif /* HAVE_RESOLV_H */ |
133 | 133 |
|
134 |
+ if(optl(opt, "localip")) { |
|
135 |
+ localip = getargl(opt, "localip"); |
|
136 |
+ } else if((cpt = cfgopt(copt, "LocalIPAddress"))) { |
|
137 |
+ localip = cpt->strarg; |
|
138 |
+ } |
|
139 |
+ |
|
134 | 140 |
memset(ipaddr, 0, sizeof(ipaddr)); |
135 | 141 |
|
136 |
- if((ret = downloaddb(DB1NAME, "main.cvd", hostname, ipaddr, &signo, copt, dnsreply)) > 50) { |
|
142 |
+ if((ret = downloaddb(DB1NAME, "main.cvd", hostname, ipaddr, &signo, copt, dnsreply, localip)) > 50) { |
|
137 | 143 |
if(dnsreply) |
138 | 144 |
free(dnsreply); |
139 | 145 |
|
... | ... |
@@ -143,7 +151,7 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c |
143 | 143 |
updated = 1; |
144 | 144 |
|
145 | 145 |
/* if ipaddr[0] != 0 it will use it to connect to the web host */ |
146 |
- if((ret = downloaddb(DB2NAME, "daily.cvd", hostname, ipaddr, &signo, copt, dnsreply)) > 50) { |
|
146 |
+ if((ret = downloaddb(DB2NAME, "daily.cvd", hostname, ipaddr, &signo, copt, dnsreply, localip)) > 50) { |
|
147 | 147 |
if(dnsreply) |
148 | 148 |
free(dnsreply); |
149 | 149 |
|
... | ... |
@@ -202,7 +210,7 @@ static int isnumb(const char *str) |
202 | 202 |
return 1; |
203 | 203 |
} |
204 | 204 |
|
205 |
-int downloaddb(const char *localname, const char *remotename, const char *hostname, char *ip, int *signo, const struct cfgstruct *copt, const char *dnsreply) |
|
205 |
+int downloaddb(const char *localname, const char *remotename, const char *hostname, char *ip, int *signo, const struct cfgstruct *copt, const char *dnsreply, char *localip) |
|
206 | 206 |
{ |
207 | 207 |
struct cl_cvd *current, *remote; |
208 | 208 |
struct cfgstruct *cpt; |
... | ... |
@@ -271,9 +279,9 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna |
271 | 271 |
|
272 | 272 |
if(!nodb && dbver == -1) { |
273 | 273 |
if(ip[0]) /* use ip to connect */ |
274 |
- hostfd = wwwconnect(ip, proxy, port, ipaddr); |
|
274 |
+ hostfd = wwwconnect(ip, proxy, port, ipaddr, localip); |
|
275 | 275 |
else |
276 |
- hostfd = wwwconnect(hostname, proxy, port, ipaddr); |
|
276 |
+ hostfd = wwwconnect(hostname, proxy, port, ipaddr, localip); |
|
277 | 277 |
|
278 | 278 |
if(hostfd < 0) { |
279 | 279 |
mprintf("@No servers could be reached. Giving up\n"); |
... | ... |
@@ -335,9 +343,9 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna |
335 | 335 |
|
336 | 336 |
if(ipaddr[0]) { |
337 | 337 |
/* use ipaddr in order to connect to the same mirror */ |
338 |
- hostfd = wwwconnect(ipaddr, proxy, port, NULL); |
|
338 |
+ hostfd = wwwconnect(ipaddr, proxy, port, NULL, localip); |
|
339 | 339 |
} else { |
340 |
- hostfd = wwwconnect(hostname, proxy, port, ipaddr); |
|
340 |
+ hostfd = wwwconnect(hostname, proxy, port, ipaddr, localip); |
|
341 | 341 |
if(!ip[0]) |
342 | 342 |
strcpy(ip, ipaddr); |
343 | 343 |
} |
... | ... |
@@ -418,7 +426,7 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna |
418 | 418 |
|
419 | 419 |
/* this function returns socket descriptor */ |
420 | 420 |
/* proxy support finshed by njh@bandsman.co.uk */ |
421 |
-int wwwconnect(const char *server, const char *proxy, int pport, char *ip) |
|
421 |
+int wwwconnect(const char *server, const char *proxy, int pport, char *ip, char *localip) |
|
422 | 422 |
{ |
423 | 423 |
int socketfd = -1, port, i; |
424 | 424 |
struct sockaddr_in name; |
... | ... |
@@ -426,13 +434,54 @@ int wwwconnect(const char *server, const char *proxy, int pport, char *ip) |
426 | 426 |
char ipaddr[16]; |
427 | 427 |
unsigned char *ia; |
428 | 428 |
const char *hostpt; |
429 |
- |
|
429 |
+ struct hostent *he = NULL; |
|
430 | 430 |
|
431 | 431 |
if(ip) |
432 | 432 |
strcpy(ip, "???"); |
433 | 433 |
|
434 | 434 |
name.sin_family = AF_INET; |
435 | 435 |
|
436 |
+ if (localip) { |
|
437 |
+ if ((he = gethostbyname(localip)) == NULL) { |
|
438 |
+ char *herr; |
|
439 |
+ switch(h_errno) { |
|
440 |
+ case HOST_NOT_FOUND: |
|
441 |
+ herr = "Host not found"; |
|
442 |
+ break; |
|
443 |
+ |
|
444 |
+ case NO_DATA: |
|
445 |
+ herr = "No IP address"; |
|
446 |
+ break; |
|
447 |
+ |
|
448 |
+ case NO_RECOVERY: |
|
449 |
+ herr = "Unrecoverable DNS error"; |
|
450 |
+ break; |
|
451 |
+ |
|
452 |
+ case TRY_AGAIN: |
|
453 |
+ herr = "Temporary DNS error"; |
|
454 |
+ break; |
|
455 |
+ |
|
456 |
+ default: |
|
457 |
+ herr = "Unknown error"; |
|
458 |
+ break; |
|
459 |
+ } |
|
460 |
+ mprintf("!Could not resolve local ip address '%s': %s\n", localip, herr); |
|
461 |
+ mprintf("^Using standard local ip address and port for fetching.\n"); |
|
462 |
+ } else { |
|
463 |
+ struct sockaddr_in client; |
|
464 |
+ memset ((char *) &client, 0, sizeof(struct sockaddr_in)); |
|
465 |
+ client.sin_family = AF_INET; |
|
466 |
+ client.sin_addr = *(struct in_addr *) he->h_addr_list[0]; |
|
467 |
+ if (bind(socketfd, (struct sockaddr *) &client, sizeof(struct sockaddr_in)) != 0) { |
|
468 |
+ mprintf("!Could not bind to local ip address '%s': %s\n", localip, strerror(errno)); |
|
469 |
+ mprintf("^Using default client ip.\n"); |
|
470 |
+ } else { |
|
471 |
+ ia = (unsigned char *) he->h_addr_list[0]; |
|
472 |
+ sprintf(ipaddr, "%u.%u.%u.%u", ia[0], ia[1], ia[2], ia[3]); |
|
473 |
+ mprintf("*Using ip '%s' for fetching.\n", ipaddr); |
|
474 |
+ } |
|
475 |
+ } |
|
476 |
+ } |
|
436 | 477 |
if(proxy) { |
437 | 478 |
hostpt = proxy; |
438 | 479 |
|
... | ... |
@@ -457,7 +506,29 @@ int wwwconnect(const char *server, const char *proxy, int pport, char *ip) |
457 | 457 |
} |
458 | 458 |
|
459 | 459 |
if((host = gethostbyname(hostpt)) == NULL) { |
460 |
- mprintf("@Can't get information about %s host.\n", hostpt); |
|
460 |
+ char *herr; |
|
461 |
+ switch(h_errno) { |
|
462 |
+ case HOST_NOT_FOUND: |
|
463 |
+ herr = "Host not found"; |
|
464 |
+ break; |
|
465 |
+ |
|
466 |
+ case NO_DATA: |
|
467 |
+ herr = "No IP address"; |
|
468 |
+ break; |
|
469 |
+ |
|
470 |
+ case NO_RECOVERY: |
|
471 |
+ herr = "Unrecoverable DNS error"; |
|
472 |
+ break; |
|
473 |
+ |
|
474 |
+ case TRY_AGAIN: |
|
475 |
+ herr = "Temporary DNS error"; |
|
476 |
+ break; |
|
477 |
+ |
|
478 |
+ default: |
|
479 |
+ herr = "Unknown error"; |
|
480 |
+ break; |
|
481 |
+ } |
|
482 |
+ mprintf("@Can't get information about %s: %s\n", hostpt, herr); |
|
461 | 483 |
return -1; |
462 | 484 |
} |
463 | 485 |
|
... | ... |
@@ -24,9 +24,9 @@ |
24 | 24 |
|
25 | 25 |
int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, const char *hostname); |
26 | 26 |
|
27 |
-int downloaddb(const char *localname, const char *remotename, const char *hostname, char *ip, int *signo, const struct cfgstruct *copt, const char *dnsreply); |
|
27 |
+int downloaddb(const char *localname, const char *remotename, const char *hostname, char *ip, int *signo, const struct cfgstruct *copt, const char *dnsreply, char *localip); |
|
28 | 28 |
|
29 |
-int wwwconnect(const char *server, const char *proxy, int pport, char *ip); |
|
29 |
+int wwwconnect(const char *server, const char *proxy, int pport, char *remoteip, char *localip); |
|
30 | 30 |
|
31 | 31 |
struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostname, const char *proxy, const char *user, const char *pass, int *ims); |
32 | 32 |
|
... | ... |
@@ -38,7 +38,7 @@ int main(int argc, char **argv) |
38 | 38 |
int ret, opt_index, i, len; |
39 | 39 |
struct optstruct *opt; |
40 | 40 |
|
41 |
- const char *getopt_parameters = "hvdp:Vl:c:u:"; |
|
41 |
+ const char *getopt_parameters = "hvdp:Vl:c:u:a:"; |
|
42 | 42 |
|
43 | 43 |
static struct option long_options[] = { |
44 | 44 |
/* |
... | ... |
@@ -61,6 +61,7 @@ int main(int argc, char **argv) |
61 | 61 |
{"no-dns", 0, 0, 0}, |
62 | 62 |
{"checks", 1, 0, 'c'}, |
63 | 63 |
{"http-proxy", 1, 0, 0}, |
64 |
+ {"client-address", 1, 0, 'a'}, |
|
64 | 65 |
{"proxy-user", 1, 0, 0}, |
65 | 66 |
{"daemon-notify", 2, 0, 0}, |
66 | 67 |
{"on-update-execute", 1, 0, 0}, |
... | ... |
@@ -123,6 +123,7 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages) |
123 | 123 |
{"NotifyClamd", OPT_OPTARG}, /* freshclam */ |
124 | 124 |
{"OnUpdateExecute", OPT_FULLSTR}, /* freshclam */ |
125 | 125 |
{"OnErrorExecute", OPT_FULLSTR}, /* freshclam */ |
126 |
+ {"LocalIPAddress", OPT_STR}, /* freshclam */ |
|
126 | 127 |
{0, 0} |
127 | 128 |
}; |
128 | 129 |
|