X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet.c;h=bd991e905689ea910fdfa0101467718eeb3c062a;hp=e62bb8dc122b519097a0d1cac913fff312d31aec;hb=d38772ebc42f5ad1d946ee89d955f5d43bb2fe8c;hpb=cea3d8f3056d3c6aaaef473443240b8470c8ea2d diff --git a/src/net.c b/src/net.c index e62bb8dc..bd991e90 100644 --- a/src/net.c +++ b/src/net.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: net.c,v 1.35.4.54 2000/10/29 10:39:06 guus Exp $ + $Id: net.c,v 1.35.4.62 2000/11/04 14:16:46 zarq Exp $ */ #include "config.h" @@ -51,11 +51,11 @@ #include #include "conf.h" +#include "connlist.h" +#include "meta.h" #include "net.h" #include "netutl.h" #include "protocol.h" -#include "meta.h" -#include "connlist.h" #include "subnet.h" #include "system.h" @@ -74,33 +74,47 @@ int keylifetime = 0; int keyexpires = 0; char *unknown = NULL; +char *interface_name = NULL; /* Contains the name of the interface */ subnet_t mymac; /* - strip off the MAC adresses of an ethernet frame + Execute the given script. + This function doesn't really belong here. */ -void strip_mac_addresses(vpn_packet_t *p) +int execute_script(const char* name) { -cp - memmove(p->data, p->data + 12, p->len -= 12); -cp -} + char *scriptname; + pid_t pid; + char *s; -/* - reassemble MAC addresses -*/ -void add_mac_addresses(vpn_packet_t *p) -{ -cp - memcpy(p->data + 12, p->data, p->len); - p->len += 12; - p->data[0] = p->data[6] = 0xfe; - p->data[1] = p->data[7] = 0xfd; - /* Really evil pointer stuff just below! */ - *((ip_t*)(&p->data[2])) = (ip_t)(htonl(myself->address)); - *((ip_t*)(&p->data[8])) = *((ip_t*)(&p->data[26])); -cp + asprintf(&scriptname, "%s/%s", confbase, name); + + if((pid = fork()) < 0) + { + syslog(LOG_ERR, _("System call `%s' failed: %m"), + "fork"); + return -1; + } + + if(pid) + { + free(scriptname); + return 0; + } + + /* Child here */ + + asprintf(&s, "IFNAME=%s", interface_name); + putenv(s); + execl(scriptname, NULL); + /* No return on success */ + + if(errno != ENOENT) /* Ignore if the file does not exist */ + syslog(LOG_WARNING, _("Error executing `%s': %m"), scriptname); + + /* No need to free things */ + exit(0); } int xsend(conn_list_t *cl, vpn_packet_t *inpkt) @@ -111,7 +125,9 @@ int xsend(conn_list_t *cl, vpn_packet_t *inpkt) cp outpkt.len = inpkt->len; - EVP_EncryptInit(&ctx, cl->cipher_pkttype, cl->cipher_pktkey, cl->cipher_pktkey); + /* Encrypt the packet */ + + EVP_EncryptInit(&ctx, cl->cipher_pkttype, cl->cipher_pktkey, cl->cipher_pktkey + cl->cipher_pkttype->key_len); EVP_EncryptUpdate(&ctx, outpkt.data, &outlen, inpkt->data, inpkt->len); EVP_EncryptFinal(&ctx, outpkt.data + outlen, &outpad); outlen += outpad + 2; @@ -146,8 +162,11 @@ int xrecv(vpn_packet_t *inpkt) EVP_CIPHER_CTX ctx; cp outpkt.len = inpkt->len; - EVP_DecryptInit(&ctx, myself->cipher_pkttype, myself->cipher_pktkey, NULL); - EVP_DecryptUpdate(&ctx, outpkt.data, &outlen, inpkt->data, inpkt->len); + + /* Decrypt the packet */ + + EVP_DecryptInit(&ctx, myself->cipher_pkttype, myself->cipher_pktkey, myself->cipher_pktkey + myself->cipher_pkttype->key_len); + EVP_DecryptUpdate(&ctx, outpkt.data, &outlen, inpkt->data, inpkt->len + 8); EVP_DecryptFinal(&ctx, outpkt.data + outlen, &outpad); outlen += outpad; @@ -156,6 +175,10 @@ cp memcpy(&outpkt, inpkt, outlen); */ + if(debug_lvl >= DEBUG_TRAFFIC) + syslog(LOG_ERR, _("Writing packet of %d bytes to tap device"), + outpkt.len, outlen); + /* Fix mac address */ memcpy(outpkt.data, mymac.net.mac.address.x, 6); @@ -371,7 +394,6 @@ int setup_tap_fd(void) int nfd; const char *tapfname; config_t const *cfg; - char *envvar; struct ifreq ifr; cp @@ -421,9 +443,8 @@ cp /* Add name of network interface to environment (for scripts) */ ioctl(tap_fd, SIOCGIFNAME, (void *) &ifr); - asprintf(&envvar, "IFNAME=%s", ifr.ifr_name); - putenv(envvar); - free(envvar); + interface_name = xmalloc(strlen(ifr.ifr_name)); + strcpy(interface_name, ifr.ifr_name); cp return 0; @@ -448,20 +469,23 @@ cp if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { - syslog(LOG_ERR, _("setsockopt: %m")); + syslog(LOG_ERR, _("System call `%s' failed: %m"), + "setsockopt"); return -1; } if(setsockopt(nfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one))) { - syslog(LOG_ERR, _("setsockopt: %m")); + syslog(LOG_ERR, _("System call `%s' failed: %m"), + "setsockopt"); return -1; } flags = fcntl(nfd, F_GETFL); if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) { - syslog(LOG_ERR, _("fcntl: %m")); + syslog(LOG_ERR, _("System call `%s' failed: %m"), + "fcntl"); return -1; } @@ -491,7 +515,8 @@ cp if(listen(nfd, 3)) { - syslog(LOG_ERR, _("listen: %m")); + syslog(LOG_ERR, _("System call `%s' failed: %m"), + "listen"); return -1; } cp @@ -516,14 +541,16 @@ cp if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { - syslog(LOG_ERR, _("setsockopt: %m")); + syslog(LOG_ERR, _("System call `%s' failed: %m"), + "setsockopt"); return -1; } flags = fcntl(nfd, F_GETFL); if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) { - syslog(LOG_ERR, _("fcntl: %m")); + syslog(LOG_ERR, _("System call `%s' failed: %m"), + "fcntl"); return -1; } @@ -604,7 +631,7 @@ int setup_outgoing_connection(char *name) { conn_list_t *ncn; struct hostent *h; - config_t *cfg; + config_t const *cfg; cp if(check_id(name)) { @@ -770,10 +797,12 @@ cp /* Generate packet encryption key */ - myself->cipher_pkttype = EVP_bf_cbc(); + myself->cipher_pkttype = EVP_bf_cfb(); - myself->cipher_pktkey = (char *)xmalloc(64); - RAND_bytes(myself->cipher_pktkey, 64); + myself->cipher_pktkeylength = myself->cipher_pkttype->key_len + myself->cipher_pkttype->iv_len; + + myself->cipher_pktkey = (char *)xmalloc(myself->cipher_pktkeylength); + RAND_bytes(myself->cipher_pktkey, myself->cipher_pktkeylength); if(!(cfg = get_config_val(config, keyexpire))) keylifetime = 3600; @@ -830,7 +859,6 @@ cp int setup_network_connections(void) { config_t const *cfg; - char *scriptname; cp if((cfg = get_config_val(config, pingtimeout)) == NULL) timeout = 5; @@ -844,22 +872,8 @@ cp return -1; /* Run tinc-up script to further initialize the tap interface */ - - asprintf(&scriptname, "%s/tinc-up", confbase); - - if(!fork()) - { - - execl(scriptname, NULL); - - if(errno != ENOENT) - syslog(LOG_WARNING, _("Error while executing %s: %m"), scriptname); - - exit(0); - } - - free(scriptname); - + execute_script("tinc-up"); + if(!(cfg = get_config_val(config, connectto))) /* No upstream IP given, we're listen only. */ return 0; @@ -887,7 +901,6 @@ cp void close_network_connections(void) { conn_list_t *p; - char *scriptname; cp for(p = conn_list; p != NULL; p = p->next) { @@ -904,23 +917,11 @@ cp myself = NULL; } - /* Execute tinc-down script right before shutting down the interface */ - - asprintf(&scriptname, "%s/tinc-down", confbase); - - if(!fork()) - { - execl(scriptname, NULL); - - if(errno != ENOENT) - syslog(LOG_WARNING, _("Error while executing %s: %m"), scriptname); + close(tap_fd); - exit(0); - } - - free(scriptname); + /* Execute tinc-down script right after shutting down the interface */ + execute_script("tinc-down"); - close(tap_fd); destroy_conn_list(); syslog(LOG_NOTICE, _("Terminating")); @@ -985,7 +986,8 @@ cp if(getpeername(sfd, &ci, &len) < 0) { - syslog(LOG_ERR, _("Error: getpeername: %m")); + syslog(LOG_ERR, _("System call `%s' failed: %m"), + "getpeername"); return NULL; } @@ -1041,6 +1043,7 @@ int handle_incoming_vpn_data() vpn_packet_t pkt; int x, l = sizeof(x); struct sockaddr from; + int lenin; socklen_t fromlen = sizeof(from); cp if(getsockopt(myself->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0) @@ -1055,18 +1058,17 @@ cp return -1; } - if(recvfrom(myself->socket, (char *) &(pkt.len), MTU, 0, &from, &fromlen) <= 0) + if((lenin = recvfrom(myself->socket, (char *) &(pkt.len), MTU, 0, &from, &fromlen)) <= 0) { syslog(LOG_ERR, _("Receiving packet failed: %m")); return -1; } -/* + if(debug_lvl >= DEBUG_TRAFFIC) { - syslog(LOG_DEBUG, _("Received packet of %d bytes from %d.%d.%d.%d"), pkt.len, - from.sa_addr[0], from.sa_addr[1], from.sa_addr[2], from.sa_addr[3]); + syslog(LOG_DEBUG, _("Received packet of %d bytes"), lenin); } -*/ + cp return xrecv(&pkt); } @@ -1362,7 +1364,7 @@ cp if(debug_lvl >= DEBUG_STATUS) syslog(LOG_INFO, _("Regenerating symmetric key")); - RAND_bytes(myself->cipher_pktkey, 64); + RAND_bytes(myself->cipher_pktkey, myself->cipher_pktkeylength); send_key_changed(myself, NULL); keyexpires = time(NULL) + keylifetime; }