00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <ctype.h>
00036 #include <string.h>
00037 #ifdef _WIN32
00038 # include <winsock2.h>
00039 #endif
00040 #include <stdio.h>
00041
00042 #include "match.h"
00043 #include "win_sock.h"
00044
00045 #include "params.h"
00046
00047
00048 #define INET6
00049
00050 #ifdef __alpha
00051 typedef unsigned int uint32;
00052 #else
00053 typedef unsigned long uint32;
00054 #endif
00055
00056 unsigned char tolowertab[] =
00057 { 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
00058 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
00059 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
00060 0x1e, 0x1f,
00061 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
00062 '*', '+', ',', '-', '.', '/',
00063 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
00064 ':', ';', '<', '=', '>', '?',
00065 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
00066 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
00067 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
00068 '_',
00069 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
00070 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
00071 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
00072 0x7f,
00073 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
00074 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
00075 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
00076 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
00077 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
00078 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
00079 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
00080 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
00081 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
00082 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
00083 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
00084 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
00085 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
00086 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
00087 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
00088 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
00089
00090 unsigned char touppertab[] =
00091 { 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
00092 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
00093 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
00094 0x1e, 0x1f,
00095 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
00096 '*', '+', ',', '-', '.', '/',
00097 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
00098 ':', ';', '<', '=', '>', '?',
00099 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
00100 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
00101 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
00102 0x5f,
00103 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
00104 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
00105 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
00106 0x7f,
00107 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
00108 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
00109 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
00110 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
00111 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
00112 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
00113 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
00114 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
00115 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
00116 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
00117 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
00118 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
00119 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
00120 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
00121 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
00122 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
00123
00124
00125
00126
00127 #if defined(IN6_IS_ADDR_V4MAPPED)
00128 # undef IN6_IS_ADDR_V4MAPPED
00129 #endif
00130
00131
00132 # define MYDUMMY_SIZE 128
00133 # define bcopy(a,b,c) memmove((b),(a),(c))
00134 #define IN6_IS_ADDR_V4MAPPED(a) \
00135 ((((u_int32_t*)(a))[0] == 0) \
00136 && (((u_int32_t*)(a))[1] == 0) \
00137 && (((u_int32_t*)(a))[2] == htonl(0xffff)))
00138
00139 #define u_int32_t uint32
00140 #define u_char unsigned char
00141 #define IN6ADDRSZ 16
00142 #define INADDRSZ 4
00143 #define INT16SZ 2
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 const char* ipv6_decompress(char* src)
00154 {
00155 static char res[1024];
00156 if(strstr(src,":")==NULL)
00157 return src;
00158 if(strstr(src,"::")==NULL)
00159 return src;
00160
00161 int expected_num_frags=8;
00162 if(strstr(src,".")!=NULL)
00163 expected_num_frags=7;
00164 int num_frags=0;
00165 int num_size=0;
00166 bool got=false;
00167 unsigned int i1;
00168 for(i1=0; i1<strlen(src)+1; i1++) {
00169 if(src[i1]==':' || src[i1]==0) {
00170 if( num_frags>expected_num_frags)
00171 return src;
00172 num_size=0;
00173 if(i1>0 && src[i1-1]==':')
00174 got=true;
00175 else
00176 if((i1>0 && src[i1-1]!=':') && i1>0)
00177 num_frags++;
00178 } else {
00179 num_size++;
00180 }
00181 }
00182 if(!got)
00183 return src;
00184 if(num_frags>8)
00185 return src;
00186 bool need_colon=false;
00187 int i2=0;
00188 for(i1=0; i1<strlen(src); i1++) {
00189 if(i2>sizeof(res)-8)
00190 return src;
00191 if(src[i1]==':' && i1>0 && src[i1-1]==':') {
00192 for(int i3=0; i3<expected_num_frags-num_frags; i3++) {
00193 if(i2>sizeof(res)-8)
00194 return src;
00195 if(i2>0 && res[i2-1]!=':')
00196 res[i2++]=':';
00197 res[i2++]='0';
00198 need_colon=true;
00199 }
00200 } else {
00201 if(!(i1==0 && src[i1]==':')) {
00202 if(need_colon)
00203 res[i2++]=':';
00204 if(!need_colon)
00205 res[i2++]=src[i1];
00206 if(need_colon && src[i1]!=':')
00207 res[i2++]=src[i1];
00208 }
00209 need_colon=false;
00210 }
00211 }
00212 res[i2++]=0;
00213 return res;
00214 }
00215
00216 static const char *inet_ntop4 (const u_char *src, char *dst, size_t size)
00217 {
00218 char tmp [sizeof("255.255.255.255")];
00219
00220 if ((size_t)sprintf(tmp,"%u.%u.%u.%u",src[0],src[1],src[2],src[3]) > size)
00221 {
00222
00223 return (NULL);
00224 }
00225 return strcpy (dst, tmp);
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 #ifdef SPRINTF_CHAR
00316 # define SPRINTF(x) strlen(sprintfx)
00317 #else
00318 # define SPRINTF(x) ((size_t)sprintf x)
00319 #endif
00320
00321
00322
00323
00324
00325
00326
00327
00328 const char * inet_ntop6(const u_char *src, char *dst, size_t size)
00329 {
00330
00331
00332
00333
00334
00335
00336
00337 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
00338 struct { int base, len; } best, cur;
00339 u_int words[IN6ADDRSZ / INT16SZ];
00340 int i;
00341
00342
00343
00344
00345
00346
00347
00348 memset(words, '\0', sizeof words);
00349 for (i = 0; i < IN6ADDRSZ; i++)
00350 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
00351 best.base = -1;
00352 cur.base = -1;
00353 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
00354 if (words[i] == 0) {
00355 if (cur.base == -1)
00356 cur.base = i, cur.len = 1;
00357 else
00358 cur.len++;
00359 } else {
00360 if (cur.base != -1) {
00361 if (best.base == -1 || cur.len > best.len)
00362 best = cur;
00363 cur.base = -1;
00364 }
00365 }
00366 }
00367 if (cur.base != -1) {
00368 if (best.base == -1 || cur.len > best.len)
00369 best = cur;
00370 }
00371 if (best.base != -1 && best.len < 2)
00372 best.base = -1;
00373
00374
00375
00376
00377 tp = tmp;
00378 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
00379
00380 if (best.base != -1 && i >= best.base &&
00381 i < (best.base + best.len)) {
00382 if (i == best.base)
00383 *tp++ = ':';
00384 continue;
00385 }
00386
00387
00388 if (i != 0)
00389 *tp++ = ':';
00390
00391 if (i == 6 && best.base == 0 &&
00392 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
00393 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
00394 return (NULL);
00395 tp += strlen(tp);
00396 break;
00397 }
00398 tp += SPRINTF((tp, "%x", words[i]));
00399 }
00400
00401 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
00402 *tp++ = ':';
00403 *tp++ = '\0';
00404
00405
00406
00407
00408 if ((size_t)(tp - tmp) > size) {
00409
00410 return (NULL);
00411 }
00412 strcpy(dst, tmp);
00413 return (dst);
00414 }
00415
00416
00417 const char * inet_ntop (int af, const void *src, char *dst, size_t size)
00418 {
00419 switch (af)
00420 {
00421 case AF_INET:
00422 return inet_ntop4 ((const u_char*)src, dst, size);
00423 case AF_INET6:
00424 return inet_ntop6 ((const u_char*)src, dst, size);
00425 default:
00426 return (NULL);
00427 }
00428 }
00429
00430
00431
00432
00433
00434
00435 char *inetntop(int af, const void *in, char *out, size_t the_size)
00436 {
00437 static char local_dummy[MYDUMMY_SIZE];
00438
00439 if (the_size > sizeof(local_dummy))
00440 {
00441 the_size = sizeof(local_dummy);
00442 }
00443
00444 if (!inet_ntop(af, in, local_dummy, the_size))
00445 {
00446
00447
00448 return NULL;
00449 }
00450
00451
00452 if (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED((const struct in_addr6_ *)in))
00453 {
00454 char *p;
00455
00456 if (!(p = strstr(local_dummy, ":ffff:")) &&
00457 !(p = strstr(local_dummy, ":FFFF:")))
00458 {
00459 return NULL;
00460 }
00461 strcpy(out, p + 6);
00462 return out;
00463 }
00464 if (strstr(local_dummy, "::"))
00465 {
00466 char cnt = 0, *cp = local_dummy, *op = out;
00467
00468 while (*cp)
00469 {
00470 if (*cp == ':')
00471 cnt += 1;
00472 if (*cp++ == '.')
00473 {
00474 cnt += 1;
00475 break;
00476 }
00477 }
00478 cp = local_dummy;
00479 while (*cp)
00480 {
00481 *op++ = *cp++;
00482 if (*(cp-1) == ':' && *cp == ':')
00483 {
00484 if ((cp-1) == local_dummy)
00485 {
00486 op--;
00487 *op++ = '0';
00488 *op++ = ':';
00489 }
00490
00491 *op++ = '0';
00492 while (cnt++ < 7)
00493 {
00494 *op++ = ':';
00495 *op++ = '0';
00496 }
00497 }
00498 }
00499 if (*(op-1)==':') *op++ = '0';
00500 *op = '\0';
00501
00502
00503
00504
00505 }
00506 else
00507 bcopy(local_dummy, out, the_size);
00508
00509 return out;
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 int
00524 inet_pton4(const char *src, u_char *dst, int pton)
00525 {
00526 u_int val;
00527 u_int digit;
00528 int base, n;
00529 unsigned char c;
00530 u_int parts[4];
00531 register u_int *pp = parts;
00532
00533 c = *src;
00534 for (;;) {
00535
00536
00537
00538
00539
00540 if (!isdigit(c))
00541 return (0);
00542 val = 0; base = 10;
00543 if (c == '0') {
00544 c = *++src;
00545 if (c == 'x' || c == 'X')
00546 base = 16, c = *++src;
00547 else if (isdigit(c) && c != '9')
00548 base = 8;
00549 }
00550
00551 if (pton && base != 10)
00552 return (0);
00553 for (;;) {
00554 if (isdigit(c)) {
00555 digit = c - '0';
00556 if (digit >= base)
00557 break;
00558 val = (val * base) + digit;
00559 c = *++src;
00560 } else if (base == 16 && isxdigit(c)) {
00561 digit = c + 10 - (islower(c) ? 'a' : 'A');
00562 if (digit >= 16)
00563 break;
00564 val = (val << 4) | digit;
00565 c = *++src;
00566 } else
00567 break;
00568 }
00569 if (c == '.') {
00570
00571
00572
00573
00574
00575
00576
00577 if (pp >= parts + 3)
00578 return (0);
00579 *pp++ = val;
00580 c = *++src;
00581 } else
00582 break;
00583 }
00584
00585
00586
00587 if (c != '\0' && !isspace(c))
00588 return (0);
00589
00590
00591
00592
00593 n = pp - parts + 1;
00594
00595 if (pton && n != 4)
00596 return (0);
00597 switch (n) {
00598
00599 case 0:
00600 return (0);
00601
00602 case 1:
00603 break;
00604
00605 case 2:
00606 if (parts[0] > 0xff || val > 0xffffff)
00607 return (0);
00608 val |= parts[0] << 24;
00609 break;
00610
00611 case 3:
00612 if ((parts[0] | parts[1]) > 0xff || val > 0xffff)
00613 return (0);
00614 val |= (parts[0] << 24) | (parts[1] << 16);
00615 break;
00616
00617 case 4:
00618 if ((parts[0] | parts[1] | parts[2] | val) > 0xff)
00619 return (0);
00620 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
00621 break;
00622 }
00623 if (dst) {
00624 val = htonl(val);
00625 memcpy(dst, &val, INADDRSZ);
00626 }
00627 return (1);
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 int
00645 inet_pton6(const char *src, u_char *dst)
00646 {
00647 if(src) {
00648 src=ipv6_decompress((char*)src);
00649 }
00650
00651 static const char xdigits_l[] = "0123456789abcdef",
00652 xdigits_u[] = "0123456789ABCDEF";
00653 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
00654 const char *xdigits, *curtok;
00655 int ch, saw_xdigit;
00656 u_int val;
00657
00658 memset((tp = tmp), '\0', IN6ADDRSZ);
00659 endp = tp + IN6ADDRSZ;
00660 colonp = NULL;
00661
00662 if (*src == ':')
00663 if (*++src != ':')
00664 return (0);
00665 curtok = src;
00666 saw_xdigit = 0;
00667 val = 0;
00668 while ((ch = *src++) != '\0') {
00669 const char *pch;
00670
00671 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
00672 pch = strchr((xdigits = xdigits_u), ch);
00673 if (pch != NULL) {
00674 val <<= 4;
00675 val |= (pch - xdigits);
00676 if (val > 0xffff)
00677 return (0);
00678 saw_xdigit = 1;
00679 continue;
00680 }
00681 if (ch == ':') {
00682 curtok = src;
00683 if (!saw_xdigit) {
00684 if (colonp)
00685 return (0);
00686 colonp = tp;
00687 continue;
00688 } else if (*src == '\0')
00689 return (0);
00690 if (tp + INT16SZ > endp)
00691 return (0);
00692 *tp++ = (u_char) (val >> 8) & 0xff;
00693 *tp++ = (u_char) val & 0xff;
00694 saw_xdigit = 0;
00695 val = 0;
00696 continue;
00697 }
00698 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
00699 inet_pton4(curtok, tp, 1) > 0) {
00700 tp += INADDRSZ;
00701 saw_xdigit = 0;
00702 break;
00703 }
00704 return (0);
00705 }
00706 if (saw_xdigit) {
00707 if (tp + INT16SZ > endp)
00708 return (0);
00709 *tp++ = (u_char) (val >> 8) & 0xff;
00710 *tp++ = (u_char) val & 0xff;
00711 }
00712 if (colonp != NULL) {
00713
00714
00715
00716
00717 const int n = tp - colonp;
00718 int i;
00719
00720 if (tp == endp)
00721 return (0);
00722 for (i = 1; i <= n; i++) {
00723 endp[- i] = colonp[n - i];
00724 colonp[n - i] = 0;
00725 }
00726 tp = endp;
00727 }
00728 if (tp != endp)
00729 return (0);
00730 memcpy(dst, tmp, IN6ADDRSZ);
00731 return (1);
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 int
00746 inet_pton(int af, const char *src, void *dst)
00747 {
00748
00749 switch (af) {
00750 case AF_INET:
00751 return (inet_pton4(src, (unsigned char*)dst, 1));
00752 case AF_INET6:
00753 return (inet_pton6(src, (unsigned char*)dst));
00754 default:
00755
00756 return (-1);
00757 }
00758
00759 }
00760
00761
00762
00763
00764
00765
00766 int inetpton(int af, const char *src, void *dst)
00767 {
00768 int i;
00769
00770
00771 if (af == AF_INET6 && *src && !strchr(src, ':'))
00772 {
00773 i = inet_pton(AF_INET, src, dst);
00774
00775
00776 memcpy((char *)dst + 12, dst, 4);
00777 memset(dst, 0, 10);
00778 memset((char *)dst + 10, 0xff, 2);
00779 return i;
00780 }
00781 return inet_pton(af, src, dst);
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 #define Reg register
00805 #define u_char unsigned char
00806
00807 #define MAX_ITERATIONS 512
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 int match(char *mask, char *name)
00825 {
00826 Reg u_char *m = (u_char *)mask, *n = (u_char *)name;
00827 char *ma = mask, *na = name;
00828 int wild = 0, q = 0, calls = 0;
00829
00830 if (!*mask)
00831 return 1;
00832
00833 if (mask[0]=='*' && mask[1]=='\0')
00834 return 0;
00835
00836 while (1)
00837 {
00838 #ifdef MAX_ITERATIONS
00839 if (calls++ > MAX_ITERATIONS)
00840 break;
00841 #endif
00842
00843 if (*m == '*')
00844 {
00845 while (*m == '*')
00846 m++;
00847 wild = 1;
00848 ma = (char *)m;
00849 na = (char *)n;
00850 }
00851
00852 if (!*m)
00853 {
00854 if (!*n)
00855 return 0;
00856 for (m--; (m > (u_char *)mask) && (*m == '?'); m--)
00857 ;
00858 if ((m > (u_char *)mask) && (*m == '*') &&
00859 (m[-1] != '\\'))
00860 return 0;
00861 if (!wild)
00862 return 1;
00863 m = (u_char *)ma;
00864 n = (u_char *)++na;
00865 }
00866 else if (!*n)
00867 return 1;
00868 if ((*m == '\\') &&
00869 ((m[1] == '*') || (m[1] == '?') || (m[1] == '#')))
00870 {
00871 m++;
00872 q = 1;
00873 }
00874 else
00875 q = 0;
00876
00877 if ((tolower(*m) == tolower(*n))
00878 || (*m == '?' && !q)
00879 || (*m == '#' && !q && isdigit(*n)))
00880 {
00881 if (*m)
00882 m++;
00883 if (*n)
00884 n++;
00885 }
00886 else
00887 {
00888 if (!wild)
00889 return 1;
00890 m = (u_char *)ma;
00891 n = (u_char *)++na;
00892 }
00893 }
00894
00895 return 1;
00896 }
00897
00898
00899 #define u_long unsigned long
00900
00901 char* index(char* str, char sub)
00902 {
00903 char tmp[2];
00904 tmp[0]=sub;
00905 tmp[1]=0;
00906 return strstr(str,tmp);
00907 }
00908
00909
00910 #define strncpyzt(x, y, N) do{(void)strncpy(x,y,N);x[N-1]='\0';}while(0)
00911
00912
00913
00914
00915
00916
00917
00918
00919 int match_ipmask(char *mask, char* username, in_addr6_ u_addr, int maskwithusername)
00920
00921 {
00922 int m;
00923 char *p;
00924
00925
00926 struct in_addr6_ addr;
00927
00928 char dummy[128];
00929 char *omask;
00930 u_long lmask;
00931 #ifdef INET6
00932 int j;
00933 #endif
00934
00935 omask = mask;
00936 strncpyzt(dummy, mask, sizeof(dummy));
00937 mask = dummy;
00938 if (maskwithusername && (p = index(mask, '@')))
00939 {
00940 *p = '\0';
00941
00942
00943 if (match(mask, username))
00944
00945 return 1;
00946 mask = p + 1;
00947 }
00948 if (!(p = index(mask, '/')))
00949 goto badmask;
00950 *p = '\0';
00951
00952 if (sscanf(p + 1, "%d", &m) != 1)
00953 {
00954 goto badmask;
00955 }
00956 if (!m)
00957 return 0;
00958 #ifndef INET6
00959 if (m < 0 || m > 32)
00960 goto badmask;
00961 lmask = htonl((u_long)0xffffffffL << (32 - m));
00962
00963
00964
00965 addr.s_addr=inet_addr(mask);
00966 return ((addr.s_addr ^ u_addr) & lmask) ? 1 : 0;
00967
00968 #else
00969 if (m < 0 || m > 128)
00970 goto badmask;
00971 if (inet_pton(AF_INET6, mask, (void *)addr.bytes) != 1)
00972 {
00973 return -1;
00974 }
00975
00976
00977 if (IN6_IS_ADDR_V4MAPPED(&addr) && m < 96)
00978 {
00979 m += 96;
00980 }
00981
00982 j = m & 0x1F;
00983 m >>= 5;
00984
00985 if (m && memcmp((void *)(addr.bytes),
00986 (void *)(&(u_addr.bytes)), m << 2))
00987 return 1;
00988
00989 if (j)
00990 {
00991 lmask = htonl((u_long)0xffffffffL << (32 - j));
00992 if ((((u_int32_t *)(addr.bytes))[m] ^
00993 ((u_int32_t *)(&(u_addr.bytes)))[m]) & lmask)
00994 return 1;
00995 }
00996
00997 return 0;
00998 #endif
00999 badmask:
01000
01001
01002
01003
01004 return -1;
01005 }
01006
01007