00001 #include "num_list.h"
00002 #include <string.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <netinet/in.h>
00006 #include <arpa/inet.h>
00007 #include "hlbr.h"
00008
00009
00010
00011 extern GlobalVars Globals;
00012
00013
00014
00015
00016 NumList* InitNumList(int ListType){
00017 NumList* n;
00018
00019 DEBUGPATH;
00020
00021 n=calloc(sizeof(NumList),1);
00022
00023 n->ListType=ListType;
00024 n->Items=calloc(sizeof(NumItem*),LIST_INITIAL_SIZE);
00025 n->AllocCount=LIST_INITIAL_SIZE;
00026
00027 return n;
00028 }
00029
00030
00031
00032
00033 int ClearNumList(NumList* n){
00034 int i;
00035
00036 DEBUGPATH;
00037
00038 for (i=0;i<n->NumEntries;i++){
00039 if (n->Items[i]){
00040 free(n->Items[i]);
00041 n->Items[i]=NULL;
00042 }
00043 }
00044
00045 n->NumEntries=0;
00046
00047 free(n->Items);
00048 n->Items=calloc(sizeof(NumItem*),LIST_INITIAL_SIZE);
00049 n->AllocCount=LIST_INITIAL_SIZE;
00050
00051 return TRUE;
00052 }
00053
00054
00055
00056
00057 void DestroyNumList(NumList* n){
00058 DEBUGPATH;
00059
00060 ClearNumList(n);
00061 if (n->Items){
00062 free(n->Items);
00063 n->Items=NULL;
00064 }
00065 free(n);
00066 }
00067
00068
00069
00070
00071
00072 int AddRangeTime(NumList* n, unsigned int Lower, unsigned int Upper, int Time){
00073 NumItem* i;
00074 NumItem** new_items;
00075
00076 DEBUGPATH;
00077
00078 i=calloc(sizeof(NumItem),1);
00079 i->Lower=Lower;
00080 i->Upper=Upper;
00081 i->Time=Time;
00082
00083 if (n->NumEntries==n->AllocCount){
00084 #ifdef DEBUG
00085 printf("List is full, allocating more slots\n");
00086 #endif
00087 new_items=calloc(sizeof(NumItem*), n->AllocCount+LIST_GROW_SIZE);
00088 memcpy(new_items, n->Items, sizeof(NumItem*)*n->AllocCount);
00089 n->AllocCount+=LIST_GROW_SIZE;
00090 free(n->Items);
00091 n->Items=new_items;
00092 }
00093
00094 n->Items[n->NumEntries]=i;
00095 n->NumEntries++;
00096
00097 return TRUE;
00098 }
00099
00100
00101
00102
00103 int AddRange(NumList* n, unsigned int Lower, unsigned int Upper){
00104 DEBUGPATH;
00105
00106 return AddRangeTime(n,Lower, Upper, -1);
00107 }
00108
00109
00110
00111
00112 int AddSubList(NumList* n, NumList* SubList){
00113 NumItem* i;
00114 NumItem** new_items;
00115
00116 DEBUGPATH;
00117
00118 i=calloc(sizeof(NumItem),1);
00119 i->Time=-1;
00120 i->SubList=SubList;
00121
00122 if (n->NumEntries==n->AllocCount){
00123 #ifdef DEBUG
00124 printf("2List is full, allocating more slots\n");
00125 #endif
00126 new_items=calloc(sizeof(NumItem*), n->AllocCount+LIST_GROW_SIZE);
00127 memcpy(new_items, n->Items, sizeof(NumItem*)*n->AllocCount);
00128 n->AllocCount+=LIST_GROW_SIZE;
00129 free(n->Items);
00130 n->Items=new_items;
00131 }
00132
00133 n->Items[n->NumEntries]=i;
00134 n->NumEntries++;
00135
00136 return TRUE;
00137 }
00138
00139
00140
00141
00142 int IsInList(NumList* n, unsigned int Number){
00143 NumItem* i;
00144 int j;
00145
00146 DEBUGPATH;
00147
00148 for (j=0;j<n->NumEntries;j++){
00149 i=n->Items[j];
00150 #ifdef DEBUG
00151 printf("Checking for %u in %u-%u\n",Number, i->Lower, i->Upper);
00152 #endif
00153 if (i->SubList){
00154 if (IsInList(i->SubList, Number)) return TRUE;
00155 }else if ( (i->Lower<=Number) && (i->Upper>=Number) ){
00156 return TRUE;
00157 }
00158 }
00159
00160 return FALSE;
00161 }
00162
00163
00164
00165
00166
00167 int IsInListTime(NumList* n, unsigned int Number, int Now){
00168 NumItem* i;
00169 int j;
00170
00171 DEBUGPATH;
00172
00173 if ((n->ListType!=LIST_TYPE_TIME) && (n->ListType!=LIST_TYPE_AGE)) return FALSE;
00174
00175 for (j=0;j<n->NumEntries;j++){
00176 i=n->Items[j];
00177
00178
00179 if (i->Time!=-1){
00180 if (n->ListType==LIST_TYPE_TIME){
00181 if (i->Time < Now){
00182 #ifdef DEBUG
00183 printf("Timing out item\n");
00184 #endif
00185 free(n->Items[j]);
00186 n->Items[j]=NULL;
00187 memmove(&n->Items[j],&n->Items[j+1], sizeof(NumItem*)*(n->NumEntries-j));
00188 n->Items[n->NumEntries]=NULL;
00189 n->NumEntries--;
00190 j--;
00191 continue;
00192 }
00193 }else if (n->ListType==LIST_TYPE_AGE){
00194 if (i->Time < (Now+n->Timeout)){
00195 #ifdef DEBUG
00196 printf("2Timing out item\n");
00197 #endif
00198 free(n->Items[j]);
00199 n->Items[j]=NULL;
00200 memmove(&n->Items[j],&n->Items[j+1], sizeof(NumItem*)*(n->NumEntries-j));
00201 n->Items[n->NumEntries]=NULL;
00202 n->NumEntries--;
00203 j--;
00204 continue;
00205 }
00206 }
00207 }
00208
00209 #ifdef DEBUG
00210 printf("Checking for %u in %u-%u\n",Number, i->Lower, i->Upper);
00211 #endif
00212 if (i->SubList){
00213 if (IsInListTime(i->SubList, Number, Now)) return TRUE;
00214 }else if ( (i->Lower<=Number) && (i->Upper>=Number) ){
00215 return TRUE;
00216 }
00217 }
00218
00219 return FALSE;
00220 }
00221
00222
00223
00224
00225
00226 int ReplaceAliases(char* s1, int s1len, char* s2, int s2len, NumAlias* a, int NumAliases){
00227 int i;
00228 char TempBuff[65536];
00229 char* pos;
00230
00231 DEBUGPATH;
00232
00233 if (s1len>65536) return FALSE;
00234 if (NumAliases==0){
00235 snprintf(s2, s2len, "%s", s1);
00236 return TRUE;
00237 }
00238
00239 snprintf(TempBuff, 65535, "%s",s1);
00240
00241 for (i=0;i<NumAliases;i++){
00242 pos=TempBuff;
00243 while ( (pos=strstr(pos, a[i].Alias)) ){
00244 memcpy(TempBuff, TempBuff, pos-TempBuff);
00245 TempBuff[pos-TempBuff]=0;
00246 sprintf(TempBuff+strlen(TempBuff),"%u",a[i].Num);
00247 sprintf(TempBuff+strlen(TempBuff), "%s", pos+strlen(a[i].Alias));
00248 pos=TempBuff;
00249 }
00250 }
00251
00252 snprintf(s2, s2len, "%s", TempBuff);
00253 return TRUE;
00254 }
00255
00256
00257
00258
00259 int AddRangesString(NumList* n, char* RawRanges, NumAlias* Aliases, int NumAliases){
00260 int i;
00261 char ThisNum[64];
00262 int ThisNumCount;
00263 unsigned int LowNum;
00264 unsigned int HighNum;
00265 int IsRange;
00266 char* Ranges;
00267
00268 DEBUGPATH;
00269
00270 if (!n) return FALSE;
00271
00272 Ranges=calloc(strlen(RawRanges)*2,sizeof(char));
00273 if (!ReplaceAliases(RawRanges, strlen(RawRanges), Ranges, strlen(RawRanges)*2, Aliases, NumAliases)){
00274 printf("Couldn't apply alias list\n");
00275 free(Ranges);
00276 return FALSE;
00277 }
00278
00279 ThisNumCount=0;
00280 IsRange=FALSE;
00281 for (i=0;i<strlen(Ranges);i++){
00282 switch(Ranges[i]){
00283 case '1':
00284 case '2':
00285 case '3':
00286 case '4':
00287 case '5':
00288 case '6':
00289 case '7':
00290 case '8':
00291 case '9':
00292 case '0':
00293
00294 ThisNum[ThisNumCount]=Ranges[i];
00295 ThisNumCount++;
00296 break;
00297 case ',':
00298
00299 ThisNum[ThisNumCount]=0x00;
00300 if (!IsRange){
00301 LowNum=strtoul(ThisNum,NULL,10);
00302 AddRange(n, LowNum, LowNum);
00303 #ifdef DEBUG
00304 printf("2Added Number %u-%u\n",LowNum, LowNum);
00305 #endif
00306 }else{
00307 HighNum=strtoul(ThisNum, NULL, 10);
00308 AddRange(n, LowNum, HighNum);
00309 #ifdef DEBUG
00310 printf("Added Range %u-%u\n",LowNum, HighNum);
00311 #endif
00312 }
00313 ThisNumCount=0;
00314 IsRange=FALSE;
00315 break;
00316 case ' ':
00317
00318 break;
00319 case '-':
00320
00321 ThisNum[ThisNumCount]=0x00;
00322 LowNum=strtoul(ThisNum, NULL, 10);
00323 #ifdef DEBUG
00324 printf("Low part of the range is %u\n",LowNum);
00325 #endif
00326 IsRange=TRUE;
00327 ThisNumCount=0;
00328 break;
00329 default:
00330 printf("Invalid character \"%c\"\n", Ranges[i]);
00331 printf("I don't understand %s\n",Ranges);
00332 free(Ranges);
00333 return FALSE;
00334 }
00335 }
00336
00337
00338 ThisNum[ThisNumCount]=0x00;
00339 if (!IsRange){
00340 LowNum=strtoul(ThisNum,NULL,10);
00341 AddRange(n, LowNum, LowNum);
00342 #ifdef DEBUG
00343 printf("3Added Number %u-%u\n",LowNum, LowNum);
00344 #endif
00345 }else{
00346 HighNum=strtoul(ThisNum, NULL, 10);
00347 AddRange(n, LowNum, HighNum);
00348 #ifdef DEBUG
00349 printf("Added Range %u-%u\n",LowNum, HighNum);
00350 #endif
00351 }
00352
00353 free(Ranges);
00354 return TRUE;
00355 }
00356
00357
00358
00359
00360 int AddIPRanges(NumList* n, char* Ranges){
00361 int i;
00362 char ThisNum[64];
00363 int ThisNumCount;
00364 unsigned int LowNum;
00365 unsigned int HighNum;
00366 unsigned int Mask;
00367 int SubListID;
00368 int IsDashed=FALSE;
00369
00370 DEBUGPATH;
00371
00372 if (!n) return FALSE;
00373
00374 #ifdef DEBUG
00375 printf("Ranges is %s\n",Ranges);
00376 #endif
00377
00378 if ( (SubListID=GetListByName(Ranges))!=LIST_NONE){
00379 if (!AddSubList(n,Globals.Lists[SubListID].List)){
00380 printf("Failed to add ip list \"%s\" \n",Ranges);
00381 return FALSE;
00382 }
00383 return TRUE;
00384 }
00385
00386 ThisNumCount=0;
00387 LowNum=0;
00388 for (i=0;i<=strlen(Ranges);i++){
00389 switch(Ranges[i]){
00390 case '1':
00391 case '2':
00392 case '3':
00393 case '4':
00394 case '5':
00395 case '6':
00396 case '7':
00397 case '8':
00398 case '9':
00399 case '0':
00400 case '.':
00401
00402 ThisNum[ThisNumCount]=Ranges[i];
00403 ThisNumCount++;
00404 break;
00405 case '-':
00406
00407
00408 ThisNum[ThisNumCount]=0x00;
00409 LowNum=ntohl(inet_addr(ThisNum));
00410 #ifdef DEBUG
00411 printf("Setting Low Range to %u\n",LowNum);
00412 #endif
00413 ThisNumCount=0;
00414 IsDashed=TRUE;
00415 break;
00416 case 0x00:
00417 case ',':
00418
00419 ThisNum[ThisNumCount]=0x00;
00420 HighNum=ntohl(inet_addr(ThisNum));
00421 if (LowNum==0) LowNum=HighNum;
00422 if (IsDashed){
00423 AddRange(n, LowNum, HighNum);
00424 #ifdef DEBUG
00425 printf("1Added Number %u-%u\n",LowNum, HighNum);
00426 #endif
00427 }else{
00428
00429
00430 AddRange(n, LowNum, LowNum);
00431 #ifdef DEBUG
00432 printf("5Added Number %u-%u\n", LowNum, LowNum);
00433 #endif
00434 }
00435 ThisNumCount=0;
00436 IsDashed=FALSE;
00437 LowNum=0;
00438 break;
00439 case ' ':
00440
00441 break;
00442 case '/':
00443
00444 ThisNum[ThisNumCount]=0x00;
00445 LowNum=ntohl(inet_addr(ThisNum));
00446 i++;
00447 Mask=atoi(&Ranges[i]);
00448 HighNum=LowNum;
00449 switch (Mask){
00450 case 0:
00451 LowNum&=0x00000000;
00452 HighNum|=0xFFFFFFFF;
00453 AddRange(n, LowNum, HighNum);
00454 break;
00455 case 1:
00456 LowNum&=0x10000000;
00457 HighNum|=0x7FFFFFFF;
00458 AddRange(n, LowNum, HighNum);
00459 break;
00460 case 2:
00461 LowNum&=0x30000000;
00462 HighNum|=0x3FFFFFFF;
00463 AddRange(n, LowNum, HighNum);
00464 break;
00465 case 3:
00466 LowNum&=0x70000000;
00467 HighNum|=0x1FFFFFFF;
00468 AddRange(n, LowNum, HighNum);
00469 break;
00470 case 4:
00471 LowNum&=0xF0000000;
00472 HighNum|=0x0FFFFFFF;
00473 AddRange(n, LowNum, HighNum);
00474 break;
00475 case 5:
00476 LowNum&=0xF1000000;
00477 HighNum|=0x07FFFFFF;
00478 AddRange(n, LowNum, HighNum);
00479 break;
00480 case 6:
00481 LowNum&=0xF3000000;
00482 HighNum|=0x03FFFFFF;
00483 AddRange(n, LowNum, HighNum);
00484 break;
00485 case 7:
00486 LowNum&=0xF7000000;
00487 HighNum|=0x01FFFFFF;
00488 AddRange(n, LowNum, HighNum);
00489 break;
00490 case 8:
00491 LowNum&=0xFF000000;
00492 HighNum|=0x00FFFFFF;
00493 AddRange(n, LowNum, HighNum);
00494 break;
00495 case 9:
00496 LowNum&=0xFF100000;
00497 HighNum|=0x007FFFFF;
00498 AddRange(n, LowNum, HighNum);
00499 break;
00500 case 10:
00501 LowNum&=0xFF300000;
00502 HighNum|=0x003FFFFF;
00503 AddRange(n, LowNum, HighNum);
00504 break;
00505 case 11:
00506 LowNum&=0xFF700000;
00507 HighNum|=0x001FFFFF;
00508 AddRange(n, LowNum, HighNum);
00509 break;
00510 case 12:
00511 LowNum&=0xFFF00000;
00512 HighNum|=0x000FFFFF;
00513 AddRange(n, LowNum, HighNum);
00514 break;
00515 case 13:
00516 LowNum&=0xFFF10000;
00517 HighNum|=0x0007FFFF;
00518 AddRange(n, LowNum, HighNum);
00519 break;
00520 case 14:
00521 LowNum&=0xFFF30000;
00522 HighNum|=0x0003FFFF;
00523 AddRange(n, LowNum, HighNum);
00524 break;
00525 case 15:
00526 LowNum&=0xFFF70000;
00527 HighNum|=0x0001FFFF;
00528 AddRange(n, LowNum, HighNum);
00529 break;
00530 case 16:
00531 LowNum&=0xFFFF0000;
00532 HighNum|=0x0000FFFF;
00533 AddRange(n, LowNum, HighNum);
00534 break;
00535 case 17:
00536 LowNum&=0xFFFF1000;
00537 HighNum|=0x00007FFF;
00538 AddRange(n, LowNum, HighNum);
00539 break;
00540 case 18:
00541 LowNum&=0xFFFF3000;
00542 HighNum|=0x00003FFF;
00543 AddRange(n, LowNum, HighNum);
00544 break;
00545 case 19:
00546 LowNum&=0xFFFF7000;
00547 HighNum|=0x00001FFF;
00548 AddRange(n, LowNum, HighNum);
00549 break;
00550 case 20:
00551 LowNum&=0xFFFF000;
00552 HighNum|=0x00000FFF;
00553 AddRange(n, LowNum, HighNum);
00554 break;
00555 case 21:
00556 LowNum&=0xFFFFF100;
00557 HighNum|=0x000007FF;
00558 AddRange(n, LowNum, HighNum);
00559 break;
00560 case 22:
00561 LowNum&=0xFFFFF300;
00562 HighNum|=0x000003FF;
00563 AddRange(n, LowNum, HighNum);
00564 break;
00565 case 23:
00566 LowNum&=0xFFFFF700;
00567 HighNum|=0x000001FF;
00568 AddRange(n, LowNum, HighNum);
00569 break;
00570 case 24:
00571 LowNum&=0xFFFFFF00;
00572 HighNum|=0x000000FF;
00573 AddRange(n, LowNum, HighNum);
00574 break;
00575 case 25:
00576 LowNum&=0xFFFFFF10;
00577 HighNum|=0x0000007F;
00578 AddRange(n, LowNum, HighNum);
00579 break;
00580 case 26:
00581 LowNum&=0xFFFFFF30;
00582 HighNum|=0x0000003F;
00583 AddRange(n, LowNum, HighNum);
00584 break;
00585 case 27:
00586 LowNum&=0xFFFFFF70;
00587 HighNum|=0x0000001F;
00588 AddRange(n, LowNum, HighNum);
00589 break;
00590 case 28:
00591 LowNum&=0xFFFFFFF0;
00592 HighNum|=0x0000000F;
00593 AddRange(n, LowNum, HighNum);
00594 break;
00595 case 29:
00596 LowNum&=0xFFFFFFF1;
00597 HighNum|=0x00000007;
00598 AddRange(n, LowNum, HighNum);
00599 break;
00600 case 30:
00601 LowNum&=0xFFFFFFF3;
00602 HighNum|=0x00000003;
00603 AddRange(n, LowNum, HighNum);
00604 break;
00605 case 31:
00606 LowNum&=0xFFFFFFF7;
00607 HighNum|=0x00000001;
00608 AddRange(n, LowNum, HighNum);
00609 break;
00610 case 32:
00611 LowNum&=0xFFFFFFFF;
00612 HighNum|=0x00000000;
00613 AddRange(n, LowNum, HighNum);
00614 break;
00615 default:
00616 printf("Invalid CIDR Notation /%u\n",Mask);
00617 return FALSE;
00618 }
00619
00620 #ifdef DEBUG
00621 printf("1Added Range %u-%u\n",LowNum, HighNum);
00622 #endif
00623
00624
00625 while ((Ranges[i]>='0') && (Ranges[i]<='9')) i++;
00626 ThisNumCount=0;
00627 IsDashed=FALSE;
00628
00629 break;
00630 default:
00631 printf("Invalid character \"%c\"\n", Ranges[i]);
00632 printf("I don't understand %s\n",Ranges);
00633 return FALSE;
00634 }
00635 }
00636
00637 return TRUE;
00638 }
00639
00640
00641
00642
00643 int RemoveFromList(NumList* n, unsigned int Number){
00644 NumItem* i;
00645 int j;
00646
00647 DEBUGPATH;
00648
00649 if (!n->NumEntries) return FALSE;
00650
00651 for (j=0;j<n->NumEntries;j++){
00652 i=n->Items[j];
00653 #ifdef DEBUG
00654 printf("Checking for %u in %u-%u\n",Number, i->Lower, i->Upper);
00655 #endif
00656 if (i->SubList){
00657 if (RemoveFromList(i->SubList, Number)) return TRUE;
00658 }else if ( (i->Lower<=Number) && (i->Upper>=Number) ){
00659 free(n->Items[j]);
00660 n->Items[j]=NULL;
00661 memmove(&n->Items[j], &n->Items[j+1], sizeof(NumItem*)*(n->NumEntries-j));
00662 n->Items[n->NumEntries]=NULL;
00663 n->NumEntries--;
00664 return TRUE;
00665 }
00666 }
00667
00668 return FALSE;
00669 }
00670
00671
00672
00673
00674
00675 int NumListCompare(NumList* n1, NumList* n2){
00676 NumItem* t1;
00677 NumItem* t2;
00678 int i;
00679
00680 DEBUGPATH;
00681
00682 if (n1->NumEntries != n2->NumEntries){
00683 #ifdef DEBUG
00684 printf("Two lists don't have same number of entries\n");
00685 #endif
00686 return FALSE;
00687 }
00688
00689 for (i=0;i<n1->NumEntries;i++){
00690 t1=n1->Items[i];
00691 t2=n2->Items[i];
00692
00693 if (
00694 (t1->SubList != t2->SubList) ||
00695 (t1->Lower != t2->Lower) ||
00696 (t1->Upper != t2->Upper)
00697 ){
00698 #ifdef DEBUG
00699 printf("They don't match\n");
00700 #endif
00701 return FALSE;
00702 }
00703 }
00704
00705 return TRUE;
00706 }