comparison src/core/ngx_inet.c @ 3277:f8ec17eeeaa6

ngx_ptocidr() supports IPv6
author Igor Sysoev <igor@sysoev.ru>
date Tue, 03 Nov 2009 13:42:25 +0000
parents beaf94f2f265
children 8de152fbb49d
comparison
equal deleted inserted replaced
3276:beaf94f2f265 3277:f8ec17eeeaa6
352 } 352 }
353 353
354 #endif 354 #endif
355 355
356 356
357 /* AF_INET only */
358
359 ngx_int_t 357 ngx_int_t
360 ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr) 358 ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr)
361 { 359 {
362 u_char *addr, *mask, *last; 360 u_char *addr, *mask, *last;
363 ngx_int_t shift; 361 size_t len;
362 ngx_int_t shift;
363 #if (NGX_HAVE_INET6)
364 ngx_int_t rc;
365 ngx_uint_t s, i;
366 #endif
364 367
365 addr = text->data; 368 addr = text->data;
366 last = addr + text->len; 369 last = addr + text->len;
367 370
368 mask = ngx_strlchr(addr, last, '/'); 371 mask = ngx_strlchr(addr, last, '/');
369 372 len = (mask ? mask : last) - addr;
370 cidr->u.in.addr = ngx_inet_addr(addr, (mask ? mask : last) - addr); 373
371 374 cidr->u.in.addr = ngx_inet_addr(addr, len);
372 if (cidr->u.in.addr == INADDR_NONE) { 375
373 return NGX_ERROR; 376 if (cidr->u.in.addr != INADDR_NONE) {
374 }
375
376 if (mask == NULL) {
377 cidr->family = AF_INET; 377 cidr->family = AF_INET;
378 cidr->u.in.mask = 0xffffffff; 378
379 return NGX_OK; 379 if (mask == NULL) {
380 cidr->u.in.mask = 0xffffffff;
381 return NGX_OK;
382 }
383
384 #if (NGX_HAVE_INET6)
385 } else if (ngx_inet6_addr(addr, len, cidr->u.in6.addr.s6_addr) == NGX_OK) {
386 cidr->family = AF_INET6;
387
388 if (mask == NULL) {
389 ngx_memset(cidr->u.in6.mask.s6_addr, 0xff, 16);
390 return NGX_OK;
391 }
392
393 #endif
394 } else {
395 return NGX_ERROR;
380 } 396 }
381 397
382 mask++; 398 mask++;
383 399
384 shift = ngx_atoi(mask, last - mask); 400 shift = ngx_atoi(mask, last - mask);
385 if (shift == NGX_ERROR) { 401 if (shift == NGX_ERROR) {
386 return NGX_ERROR; 402 return NGX_ERROR;
387 } 403 }
388 404
389 cidr->family = AF_INET; 405 switch (cidr->family) {
390 406
391 if (shift == 0) { 407 #if (NGX_HAVE_INET6)
392 408 case AF_INET6:
393 /* the x86 compilers use the shl instruction that shifts by modulo 32 */ 409 addr = cidr->u.in6.addr.s6_addr;
394 410 mask = cidr->u.in6.mask.s6_addr;
395 cidr->u.in.mask = 0; 411 rc = NGX_OK;
396 412
397 if (cidr->u.in.addr == 0) { 413 for (i = 0; i < 16; i++) {
414
415 s = (shift > 8) ? 8 : shift;
416 shift -= s;
417
418 mask[i] = (u_char) (0 - (1 << (8 - s)));
419
420 if (addr[i] != (addr[i] & mask[i])) {
421 rc = NGX_DONE;
422 addr[i] &= mask[i];
423 }
424 }
425
426 return rc;
427 #endif
428
429 default: /* AF_INET */
430
431 if (shift) {
432 cidr->u.in.mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
433
434 } else {
435 /* x86 compilers use a shl instruction that shifts by modulo 32 */
436 cidr->u.in.mask = 0;
437 }
438
439 if (cidr->u.in.addr == (cidr->u.in.addr & cidr->u.in.mask)) {
398 return NGX_OK; 440 return NGX_OK;
399 } 441 }
400 442
443 cidr->u.in.addr &= cidr->u.in.mask;
444
401 return NGX_DONE; 445 return NGX_DONE;
402 } 446 }
403
404 cidr->u.in.mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
405
406 if (cidr->u.in.addr == (cidr->u.in.addr & cidr->u.in.mask)) {
407 return NGX_OK;
408 }
409
410 cidr->u.in.addr &= cidr->u.in.mask;
411
412 return NGX_DONE;
413 } 447 }
414 448
415 449
416 ngx_int_t 450 ngx_int_t
417 ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len) 451 ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len)
420 ngx_uint_t family; 454 ngx_uint_t family;
421 struct sockaddr_in *sin; 455 struct sockaddr_in *sin;
422 #if (NGX_HAVE_INET6) 456 #if (NGX_HAVE_INET6)
423 struct in6_addr inaddr6; 457 struct in6_addr inaddr6;
424 struct sockaddr_in6 *sin6; 458 struct sockaddr_in6 *sin6;
459
460 /*
461 * prevent MSVC8 waring:
462 * potentially uninitialized local variable 'inaddr6' used
463 */
464 ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr));
425 #endif 465 #endif
426 466
427 inaddr = ngx_inet_addr(text, len); 467 inaddr = ngx_inet_addr(text, len);
428 468
429 if (inaddr != INADDR_NONE) { 469 if (inaddr != INADDR_NONE) {