/* * Copyright (C) 2003 Luca Deri * Andreas Pfaller * * http://www.ntop.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* ************************************************************************* */ #include #include #include #include #include #include #include "p2clib.h" /* Note: Setting DO_FREES to 0 skips free() calls for performance reasons. Since the program exits anyway after the run the leak does not really matter. */ #define DO_FREES 0 #define VERSION "2.0" extern double log2(double); typedef struct IPNode { struct IPNode *b[2]; char cc[8]; int fnum; } IPNode; IPNode *Head; int OptVerbose=0; int OptReportDuplicateMappings=0; int OptReportConflictingMappings=0; int OptEmitConflictingMappings=0; int OptOnlyTest=0; /* ************************************************************************* */ int imaxblock(u_int32_t ip, int prefix) { while (prefix>0) { if ((ip & PREFIX2MASK(prefix-1)) != ip) break; prefix--; } return prefix; } /* ************************************************************************* */ void recursiveDump(FILE *fp, IPNode *p, u_int32_t ip, int prefix) { int i; static char ips[32]; if (p->cc[0]!=0 && prefix!=0) fprintf(fp, "%s:%s/%d\n", p->cc, xntoa(ip, ips, sizeof(ips)), prefix); for (i=0; i<2; i++) if (p->b[i]) recursiveDump(fp, p->b[i], ip | (i<<(31-prefix)), prefix+1); } /* ************************************************************************* */ void printInfo(char *msg, char *country, u_int32_t ip, int prefix) { char ips[32]; fprintf(stderr, "%s: %3s:%s/%d\n", msg, country, xntoa(ip, ips, sizeof(ips)), prefix); } /* ************************************************************************* */ IPNode *consolidateTree(IPNode *p, char *country) { int i; char *cc=country; if (strcmp(p->cc, country)==0) p->cc[0]=0; if (p->cc[0]!=0) cc=p->cc; for (i=0; i<2; i++) if (p->b[i]) p->b[i]=consolidateTree(p->b[i], cc); if (p->b[0]==NULL && p->b[1]==NULL && (p->cc[0]==0 || strcmp(country, p->cc)==0)) { #if DO_FREES free(p); #endif return NULL; } if (p->b[0]!=NULL && p->b[1]!=NULL && p->b[0]->cc[0]!=0 && p->b[1]->cc[0]!=0 && strcmp(p->b[0]->cc, p->b[1]->cc)==0) { strcpy(p->cc, p->b[0]->cc); for (i=0; i<2; i++) { p->b[i]->cc[0]=0; if (p->b[i]->b[0]==NULL && p->b[i]->b[1]==NULL) { #if DO_FREES free(p->b[i]); #endif p->b[i]=NULL; } } } return p; } /* ************************************************************************* */ void addNodeInternal(u_int32_t ip, int prefix, char *country, int fnum) { IPNode *p1=Head; IPNode *p2; int i, b; for (i=0; i>(31-i)) & 0x1; if (!p1->b[b]) { if (!(p2=malloc(sizeof(IPNode)))) exit(EXIT_FAILURE); memset(p2, 0, sizeof(IPNode)); p1->b[b]=p2; } else p2=p1->b[b]; p1=p2; } if (p2->cc[0]==0) { strcpy(p2->cc, country); p2->fnum=fnum; } else if (OptReportConflictingMappings || OptEmitConflictingMappings) { /* Note: the strstr test is a little too simple but works ok */ if (strcmp(p2->cc, "LOC")!=0) { if (strstr(p2->cc, country)==NULL) { if (OptReportConflictingMappings) { fprintf(stderr, "%2d-%2d %3s ", p2->fnum, fnum, p2->cc); printInfo("CONFLICT", country, ip, prefix); } if (OptEmitConflictingMappings) { i=strlen(p2->cc); if (strlen(p2->cc)+strlen(country)+1 < sizeof(p2->cc)) { strcat(p2->cc, "+"); strcat(p2->cc, country); } else { fprintf(stderr, "%2d-%2d %s ", p2->fnum, fnum, p2->cc); printInfo("Too many conflicts", country, ip, prefix); } } } else if (OptReportDuplicateMappings) { fprintf(stderr, "%2d-%2d %3s ", p2->fnum, fnum, p2->cc); printInfo("DUPLICATE", country, ip, prefix); } } } } /* ************************************************************************* */ void addNode(u_int32_t ip, int range, char *country, int fnum) { u_int32_t ip1, ip2; int maxsize, maxdiff; if (range<1) return; if (!ip) return; ip1=ip; ip2=ip1+range-1; while (ip2>=ip1 && ip1!=0) { maxsize=imaxblock(ip1, 32); maxdiff=32 - (int) log2(ip2-ip1+1); if (maxsizecc, "***"); Head->b[0]=NULL; Head->b[1]=NULL; addNode(QUAD2IP(10,0,0,0), 256*256*256, "LOC", 0); addNode(QUAD2IP(127,0,0,0), 256*256*256, "LOC", 0); addNode(QUAD2IP(172,16,0,0), 16*256*256, "LOC", 0); addNode(QUAD2IP(192,168,0,0), 256*256, "LOC", 0); for (i=0; i