/* Copyright (c) 2000 RIPE NCC All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ------------------------------------------------------------------------------- Module Header Filename : common.c Purpose : Common functions used by all scripts of the application Author : Manuel Valente Date : 20000510 Revised : 20021210 Florian Frotzler: added IPv6 compatibility Description : Language Version : gcc version 2.95.2 OSs Tested : Solaris 2.6 Command Line : Input Files : Output Files : External Programs : mysqld Problems : To Do : Comments : ------------------------------------------------------------------------------- */ static char const rcsid[] = "$Id: common.c,v 1.6 2004/03/10 18:04:33 wilhelm Exp $"; #include #include #include #include #include #include #include #include "common.h" #include "read_line.h" /* ------------------------------------------------------------------------------- Purpose : Open MySQL connection Params : mysql handler Returns : 0 Comments : Only works with the correct user ADMIN */ int open_admin_connection (MYSQL *mysql, char *mysql_host) { /* Only the ADMIN login can use this function */ if (getuid() != ADMIN_UID) { fprintf (stderr, "This program can only be run by ttraffic.\n"); exit (1); }; /* Initialize handler */ mysql_init(mysql); /* Open connection */ if (!mysql_real_connect(mysql,mysql_host,ADMIN_NAME_v4,ADMIN_PWD_v4,MYSQL_DB_v4,0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n",mysql_error(mysql)); exit (1); }; return (0); }; /* ------------------------------------------------------------------------------- Purpose : Open MySQL connection Params : mysql handler Returns : 0 Comments : Only works with the correct user TTMV6ADM connects to IPv6 TTM database */ int open_admin_connection_ip6 (MYSQL *mysql, char *mysql_host) { /* Only the ADMIN login can use this function */ if (getuid() != ADMIN_UID) { fprintf (stderr, "This program can only be run by ttraffic.\n"); exit (1); }; /* Initialize handler */ mysql_init(mysql); /* Open connection */ if (!mysql_real_connect(mysql,mysql_host,ADMIN_NAME_v6,ADMIN_PWD_v6,MYSQL_DB_v6,0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n",mysql_error(mysql)); exit (1); }; return (0); }; /* ------------------------------------------------------------------------------- Purpose : Open MySQL connection Params : mysql handler Returns : 0 Comments : */ int open_user_connection (MYSQL *mysql, char *mysql_host) { /* Initialize handler */ mysql_init(mysql); /* Open connection */ if (!mysql_real_connect(mysql,mysql_host,USER_NAME,USER_PWD,MYSQL_DB_v4,0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n",mysql_error(mysql)); exit (1); }; return (0); } /* ------------------------------------------------------------------------------- Purpose : Open MySQL connection Params : mysql handler Returns : 0 Comments : IPv6 counterpart to open_user_connection() */ int open_user_connection_ip6 (MYSQL *mysql, char *mysql_host) { /* Initialize handler */ mysql_init(mysql); /* Open connection */ if (!mysql_real_connect(mysql,mysql_host,USER_NAME,USER_PWD,MYSQL_DB_v6,0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n",mysql_error(mysql)); exit (1); }; return (0); } /* ------------------------------------------------------------------------------- Purpose : Fill a hash with a Routes like table from the DB Params : mysql handle, routes hash, table name Returns : 0 Comments : Routes and ASpath table have similar layout this routine can be used for both */ int get_table (MYSQL *mysql, GHashTable *hash, char* table) { struct routestruct* rn; char query [1024]; MYSQL_RES *result; MYSQL_ROW row; /* Select all routes from the DB */ sprintf (query,"SELECT id,len,crc from %s",table); if (mysql_query(mysql,query)) { fprintf(stderr, "Error: %s\n", mysql_error(mysql)); exit (1); }; if (!(result = mysql_use_result(mysql))) { fprintf(stderr, "Error: %s\n", mysql_error(mysql)); exit (1); }; /* For each route */ while ((row = mysql_fetch_row(result))) { /* Allocate memory to store the route */ rn = malloc(sizeof(struct routestruct)); /* Fill route with data from DB */ rn->id = atoi(row[0]); rn->len = atoi(row[1]); strcpy (rn->crc,row[2]); /* Store route in hash */ g_hash_table_insert (hash,&rn->crc,rn); }; mysql_free_result(result); return (0); }; /* ------------------------------------------------------------------------------- Purpose : Fill a hash with the "Ranges" from TTM config this hash will match IP addresses with Testbox IDs Params : ranges hash, path to LIST_OF_BOXES file, IP specific flag Returns : 0 Comments : key = ip / value = id ip6flag = 0: make hash with IPv4 testbox addresses ip6flag = 1: make hash with IPv6 testbox addresses */ int get_ranges (GHashTable *ranges, char *path_boxes, int ip6flag) { char *p; int id; char boxname [50]; char cip [50]; unsigned int ip; FILE *fd; int *key; int *val; char *ip6key; char buf [1024]; /* Open LIST_OF_BOXES file */ if((fd = fopen(path_boxes,"rb")) == NULL) { fprintf(stderr, "Cannot open %s: %s\n", path_boxes, strerror(errno)); exit (1); }; /* Read file */ while (!feof(fd)) { if(fgets(buf, sizeof(buf), fd) == NULL) continue; buf[strlen(buf)-1] = '\0'; /* Split the line in 3 tokens: id boxname ip */ p = strtok (buf,"\t"); id = atoi (p); p = strtok (NULL,"\t"); strcpy (boxname,p); p = strtok (NULL,"\t"); val = malloc (sizeof(int)); *val = id; if ((strstr(p,":") != NULL) && (ip6flag)) { struct in6_addr v6addr; ip6key = (char * ) malloc (MAX_IP6_SIZE); /* shake forth and back, to arrive at standard ascii representation, protect against mismatches due to human vs. inet_ntop presentation */ inet_pton(AF_INET6, p, &v6addr); inet_ntop(AF_INET6, &v6addr, ip6key, MAX_IP6_SIZE); g_hash_table_insert (ranges,ip6key,val); } else if ((strstr(p,":") == NULL) && (!ip6flag)) { strcpy (cip,p); ip = rv_iptoint(cip); key = malloc (sizeof(int)); /* Store the data in a hash */ *key = ip; g_hash_table_insert (ranges,key,val); } }; fclose (fd); return (0); }; /* ------------------------------------------------------------------------------- Purpose : Fill a hash with the "Ranges" from TTM config this hash will match Testbox names with Testbox IDs Params : ranges hash, path to LIST_OF_BOXES file Returns : 0 Comments : key = boxname / value = id */ int get_ranges_by_boxname (GHashTable *ranges,char *path_boxes) { char *p; int id; char boxname [256]; /* some domain names are looooong */ FILE *fd; char* key; int *val; char buf [1024]; /* Open LIST_OF_BOXES file */ if((fd = fopen(path_boxes,"rb")) == NULL) { fprintf(stderr, "Cannot open %s: %s\n", path_boxes, strerror(errno)); exit (1); }; /* Read file */ while (!feof(fd)) { if(fgets(buf, sizeof(buf), fd) == NULL) continue; buf[strlen(buf)-1] = '\0'; /* Split the line in 3 tokens: id boxname ip */ p = strtok (buf,"\t"); id = atoi (p); p = strtok (NULL,"\t"); strcpy (boxname,p); p = strtok (NULL,"\t"); /* Store the data in a hash */ val = malloc (sizeof(int)); key = strdup(boxname); *val = id; g_hash_table_insert (ranges,key,val); }; fclose (fd); return (0); }; /* ------------------------------------------------------------------------------- Purpose : Return all the files that need to be processed Params : Path to read, files array Returns : Number of files Comments : Works on a list of directories */ int get_filenames_recursive (char *path, char **files) { unsigned int i; char inpath[256]; char filename[256]; char buf[256]; DIR *dir; struct dirent *dirhdl; DIR *indir; struct dirent *indirhdl; i = 0; /* Open directory */ if (!(dir = opendir (path))) { printf ("Cannot open %s : %s\n",path,strerror(errno)); exit(1); }; /* Read Dir contents */ while ((dirhdl = readdir (dir))) { /* Skip '.' and '..' */ if ((strcmp (".",dirhdl->d_name)==0)||(strcmp("..",dirhdl->d_name)==0)) { continue; }; sprintf (inpath,"%s%s/",path,dirhdl->d_name); /* Open subdir */ if (!(indir = opendir (inpath))) { printf ("Cannot open %s : %s\n",inpath,strerror(errno)); exit(1); } /* Read subdir contents */ while ((indirhdl = readdir (indir))) { /* Skip '.' and '..' */ if ((strcmp (".",indirhdl->d_name)==0)||(strcmp("..",indirhdl->d_name)==0)) {continue; }; /* Skip if file does not start with RVEC */ strncpy (buf,indirhdl->d_name,4); buf[4]='\0'; if (!(strcmp ("RVEC",buf)==0)) { continue; }; /* Store filename in files[] */ sprintf (filename,"%s%s",inpath,indirhdl->d_name); files[i++] = strdup (filename); }; closedir (indir); }; closedir (dir); return (i); }; /* ------------------------------------------------------------------------------- Purpose : Return all the files that need to be processed Params : Filename to read, files array Returns : Number of files Comments : gets either RVEC or RVEC6 files, depends on ip6flag */ int get_filenames (char *path, char **files, int ip6flag) { FILE *fd; char buf[512]; int i; i = 0; /* Open file */ if((fd = fopen(path,"rb")) == NULL) { fprintf(stderr, "Cannot open %s: %s\n", path, strerror(errno)); exit (1); }; while (!feof(fd)) { if(fgets(buf, sizeof(buf), fd) == NULL) continue; buf[strlen(buf)-1] = '\0'; /* Push filename in files[] */ if ( (!ip6flag && (strstr(buf,"RVEC.") != NULL)) || (ip6flag && (strstr(buf,"RVEC6") != NULL)) ) { files[i++] = strdup (buf); } }; fclose (fd); return (i); }; /* ------------------------------------------------------------------------------- Purpose : Transform an IP quads route into integer route Params : IP quads route Returns : Integer route Comments : Returns " " if route is NULL */ char* route_ip_to_int (const char *route) { char route_buffer [1024]; char buffer [1024]; unsigned int b; char *p; char str [30]; char *lasts; if (strlen(route)==0) { return (" "); }; strcpy (route_buffer,route); p = strtok_r (route_buffer," ",&lasts); strcpy (str,p); b = rv_iptoint(str); sprintf(buffer,"%u ",b); while ((p = strtok_r (NULL," ",&lasts))) { strcpy(str,p); b = rv_iptoint(str); sprintf (str,"%u ",b); strcat (buffer,str); }; buffer[strlen(buffer)-1] = '\0'; return strdup(buffer); }; /* ------------------------------------------------------------------------------- Purpose : Transform an IP integer route into quads route Params : Integer route Returns : IP quads route Comments : Returns " " if route is NULL */ char* route_int_to_ip (const char *route) { char route_buffer [1024]; char buffer [1024]; char *p; char str [30]; char ip [30]; char *lasts; if (strlen(route)==0) { return (" "); }; strcpy (route_buffer,route); p = strtok_r (route_buffer," ",&lasts); strcpy (str,p); rv_inttoip((unsigned int) ATOUI(str),ip); sprintf(buffer,"%s ",ip); while ((p = strtok_r (NULL," ",&lasts))) { strcpy(str,p); rv_inttoip(ATOUI(str),ip); sprintf (str,"%s ",ip); strcat (buffer,str); }; buffer[strlen(buffer)-1] = '\0'; return strdup(buffer); };