Mercurial > hg > nginx
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) { |