--- BAK_ssmtp.c 2006-08-17 03:00:37.306324793 +0800 +++ ssmtp.c 2006-08-17 04:55:21.367377527 +0800 @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_SSL #include #include @@ -60,6 +61,7 @@ char *mail_domain = (char)NULL; char *from = (char)NULL; /* Use this as the From: address */ char hostname[MAXHOSTNAMELEN] = "localhost"; +char *srchost = (char)NULL; char *mailhost = "mailhub"; char *minus_f = (char)NULL; char *minus_F = (char)NULL; @@ -828,6 +830,15 @@ log_event(LOG_INFO, "Set RemotePort=\"%d\"\n", port); } } + else if(strcasecmp(p, "SrcHost") == 0) { + if((srchost = strdup(q)) == (char *)NULL) { + die("parse_config() -- strdup() failed"); + } + + if (log_level > 0) { + log_event(LOG_INFO, "Set SrcHost=\"%s\"\n", srchost); + } + } else if(strcasecmp(p, "HostName") == 0) { if(strncpy(hostname, q, MAXHOSTNAMELEN) == NULL) { die("parse_config() -- strncpy() failed"); @@ -984,8 +995,8 @@ char servname[NI_MAXSERV]; int s; #else - struct sockaddr_in name; - struct hostent *hent; + struct sockaddr_in name, srcname; + struct hostent *hent, *srchent; int s, namelen; #endif @@ -1080,9 +1091,29 @@ name.sin_family = hent->h_addrtype; name.sin_port = htons(port); + /* Bind to specific source address, if provided in conf file */ + if (srchost != (char *)NULL) { + if ((srchent = gethostbyname(srchost)) == (struct hostent *)NULL) { + log_event(LOG_ERR, "Unable to locate source host %s", srchost); + return(-1); + } + + if (srchent->h_length > sizeof(srchent->h_addr)) { + log_event(LOG_ERR, "Buffer overflow in gethostbyname() for source address"); + return(-1); + } + + srcname.sin_addr.s_addr = ((struct in_addr *)(srchent->h_addr))->s_addr; + srcname.sin_family = srchent->h_addrtype; + if (bind(s, (struct sockaddr *)&srcname, sizeof(struct sockaddr_in)) < 0) { + log_event(LOG_ERR, "Unable to bind to %s (%s / %d)", srchost, strerror(errno), errno); + return(-1); + } + } + namelen = sizeof(struct sockaddr_in); if(connect(s, (struct sockaddr *)&name, namelen) < 0) { - log_event(LOG_ERR, "Unable to connect to %s:%d", host, port); + log_event(LOG_ERR, "Unable to connect to %s:%d (%s / %d)", host, port, strerror(errno), errno); return(-1); } #endif