Annotation of embedaddon/strongswan/src/libstrongswan/networking/host.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2006-2014 Tobias Brunner
                      3:  * Copyright (C) 2006 Daniel Roethlisberger
                      4:  * Copyright (C) 2005-2006 Martin Willi
                      5:  * Copyright (C) 2005 Jan Hutter
                      6:  * HSR Hochschule fuer Technik Rapperswil
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or modify it
                      9:  * under the terms of the GNU General Public License as published by the
                     10:  * Free Software Foundation; either version 2 of the License, or (at your
                     11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful, but
                     14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     16:  * for more details.
                     17:  */
                     18: 
                     19: #include "host.h"
                     20: 
                     21: #include <utils/debug.h>
                     22: #include <library.h>
                     23: 
                     24: #define IPV4_LEN        4
                     25: #define IPV6_LEN       16
                     26: 
                     27: typedef struct private_host_t private_host_t;
                     28: 
                     29: /**
                     30:  * Private Data of a host object.
                     31:  */
                     32: struct private_host_t {
                     33:        /**
                     34:         * Public data
                     35:         */
                     36:        host_t public;
                     37: 
                     38:        /**
                     39:         * low-lewel structure, which stores the address
                     40:         */
                     41:        union {
                     42:                /** generic type */
                     43:                struct sockaddr address;
                     44:                /** maximum sockaddr size */
                     45:                struct sockaddr_storage address_max;
                     46:                /** IPv4 address */
                     47:                struct sockaddr_in address4;
                     48:                /** IPv6 address */
                     49:                struct sockaddr_in6 address6;
                     50:        };
                     51:        /**
                     52:         * length of address structure
                     53:         */
                     54:        socklen_t socklen;
                     55: };
                     56: 
                     57: /**
                     58:  * Update the sockaddr internal sa_len option, if available
                     59:  */
                     60: static inline void update_sa_len(private_host_t *this)
                     61: {
                     62: #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
                     63:        this->address.sa_len = this->socklen;
                     64: #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
                     65: }
                     66: 
                     67: METHOD(host_t, get_sockaddr, sockaddr_t*,
                     68:        private_host_t *this)
                     69: {
                     70:        return &(this->address);
                     71: }
                     72: 
                     73: METHOD(host_t, get_sockaddr_len, socklen_t*,
                     74:        private_host_t *this)
                     75: {
                     76:        return &(this->socklen);
                     77: }
                     78: 
                     79: METHOD(host_t, is_anyaddr, bool,
                     80:        private_host_t *this)
                     81: {
                     82:        static const uint8_t zeroes[IPV6_LEN];
                     83: 
                     84:        switch (this->address.sa_family)
                     85:        {
                     86:                case AF_INET:
                     87:                {
                     88:                        return memeq(zeroes, &(this->address4.sin_addr.s_addr), IPV4_LEN);
                     89:                }
                     90:                case AF_INET6:
                     91:                {
                     92:                        return memeq(zeroes, &(this->address6.sin6_addr.s6_addr), IPV6_LEN);
                     93:                }
                     94:                default:
                     95:                {
                     96:                        return FALSE;
                     97:                }
                     98:        }
                     99: }
                    100: 
                    101: /**
                    102:  * Described in header.
                    103:  */
                    104: int host_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
                    105:                                         const void *const *args)
                    106: {
                    107:        private_host_t *this = *((private_host_t**)(args[0]));
                    108:        char buffer[INET6_ADDRSTRLEN + 16];
                    109: 
                    110:        if (this == NULL)
                    111:        {
                    112:                snprintf(buffer, sizeof(buffer), "(null)");
                    113:        }
                    114:        else if (is_anyaddr(this) && !spec->plus && !spec->hash)
                    115:        {
                    116:                snprintf(buffer, sizeof(buffer), "%%any%s",
                    117:                                 this->address.sa_family == AF_INET6 ? "6" : "");
                    118:        }
                    119:        else
                    120:        {
                    121:                void *address;
                    122:                uint16_t port;
                    123:                int len;
                    124: 
                    125:                address = &this->address6.sin6_addr;
                    126:                port = this->address6.sin6_port;
                    127: 
                    128:                switch (this->address.sa_family)
                    129:                {
                    130:                        case AF_INET:
                    131:                                address = &this->address4.sin_addr;
                    132:                                port = this->address4.sin_port;
                    133:                                /* fall */
                    134:                        case AF_INET6:
                    135: 
                    136:                                if (inet_ntop(this->address.sa_family, address,
                    137:                                                          buffer, sizeof(buffer)) == NULL)
                    138:                                {
                    139:                                        snprintf(buffer, sizeof(buffer),
                    140:                                                         "(address conversion failed)");
                    141:                                }
                    142:                                else if (spec->hash && port)
                    143:                                {
                    144:                                        len = strlen(buffer);
                    145:                                        snprintf(buffer + len, sizeof(buffer) - len,
                    146:                                                         "[%d]", ntohs(port));
                    147:                                }
                    148:                                break;
                    149:                        default:
                    150:                                snprintf(buffer, sizeof(buffer), "(family not supported)");
                    151:                                break;
                    152:                }
                    153:        }
                    154:        if (spec->minus)
                    155:        {
                    156:                return print_in_hook(data, "%-*s", spec->width, buffer);
                    157:        }
                    158:        return print_in_hook(data, "%*s", spec->width, buffer);
                    159: }
                    160: 
                    161: METHOD(host_t, get_address, chunk_t,
                    162:        private_host_t *this)
                    163: {
                    164:        chunk_t address = chunk_empty;
                    165: 
                    166:        switch (this->address.sa_family)
                    167:        {
                    168:                case AF_INET:
                    169:                {
                    170:                        address.ptr = (char*)&(this->address4.sin_addr.s_addr);
                    171:                        address.len = IPV4_LEN;
                    172:                        return address;
                    173:                }
                    174:                case AF_INET6:
                    175:                {
                    176:                        address.ptr = (char*)&(this->address6.sin6_addr.s6_addr);
                    177:                        address.len = IPV6_LEN;
                    178:                        return address;
                    179:                }
                    180:                default:
                    181:                {
                    182:                        /* return empty chunk */
                    183:                        return address;
                    184:                }
                    185:        }
                    186: }
                    187: 
                    188: METHOD(host_t, get_family, int,
                    189:        private_host_t *this)
                    190: {
                    191:        return this->address.sa_family;
                    192: }
                    193: 
                    194: METHOD(host_t, get_port, uint16_t,
                    195:        private_host_t *this)
                    196: {
                    197:        switch (this->address.sa_family)
                    198:        {
                    199:                case AF_INET:
                    200:                {
                    201:                        return ntohs(this->address4.sin_port);
                    202:                }
                    203:                case AF_INET6:
                    204:                {
                    205:                        return ntohs(this->address6.sin6_port);
                    206:                }
                    207:                default:
                    208:                {
                    209:                        return 0;
                    210:                }
                    211:        }
                    212: }
                    213: 
                    214: METHOD(host_t, set_port, void,
                    215:        private_host_t *this, uint16_t port)
                    216: {
                    217:        switch (this->address.sa_family)
                    218:        {
                    219:                case AF_INET:
                    220:                {
                    221:                        this->address4.sin_port = htons(port);
                    222:                        break;
                    223:                }
                    224:                case AF_INET6:
                    225:                {
                    226:                        this->address6.sin6_port = htons(port);
                    227:                        break;
                    228:                }
                    229:                default:
                    230:                {
                    231:                        break;
                    232:                }
                    233:        }
                    234: }
                    235: 
                    236: METHOD(host_t, clone_, host_t*,
                    237:        private_host_t *this)
                    238: {
                    239:        private_host_t *new;
                    240: 
                    241:        new = malloc_thing(private_host_t);
                    242:        memcpy(new, this, sizeof(private_host_t));
                    243: 
                    244:        return &new->public;
                    245: }
                    246: 
                    247: /**
                    248:  * Implements host_t.ip_equals
                    249:  */
                    250: static bool ip_equals(private_host_t *this, private_host_t *other)
                    251: {
                    252:        if (this->address.sa_family != other->address.sa_family)
                    253:        {
                    254:                /* 0.0.0.0 and 0::0 are equal */
                    255:                return (is_anyaddr(this) && is_anyaddr(other));
                    256:        }
                    257: 
                    258:        switch (this->address.sa_family)
                    259:        {
                    260:                case AF_INET:
                    261:                {
                    262:                        return memeq(&this->address4.sin_addr, &other->address4.sin_addr,
                    263:                                                 sizeof(this->address4.sin_addr));
                    264:                }
                    265:                case AF_INET6:
                    266:                {
                    267:                        return memeq(&this->address6.sin6_addr, &other->address6.sin6_addr,
                    268:                                                 sizeof(this->address6.sin6_addr));
                    269:                }
                    270:                default:
                    271:                        break;
                    272:        }
                    273:        return FALSE;
                    274: }
                    275: 
                    276: /**
                    277:  * Implements host_t.equals
                    278:  */
                    279: static bool equals(private_host_t *this, private_host_t *other)
                    280: {
                    281:        if (!ip_equals(this, other))
                    282:        {
                    283:                return FALSE;
                    284:        }
                    285: 
                    286:        switch (this->address.sa_family)
                    287:        {
                    288:                case AF_INET:
                    289:                {
                    290:                        return (this->address4.sin_port == other->address4.sin_port);
                    291:                }
                    292:                case AF_INET6:
                    293:                {
                    294:                        return (this->address6.sin6_port == other->address6.sin6_port);
                    295:                }
                    296:                default:
                    297:                        break;
                    298:        }
                    299:        return FALSE;
                    300: }
                    301: 
                    302: METHOD(host_t, destroy, void,
                    303:        private_host_t *this)
                    304: {
                    305:        free(this);
                    306: }
                    307: 
                    308: /**
                    309:  * Creates an empty host_t object
                    310:  */
                    311: static private_host_t *host_create_empty(void)
                    312: {
                    313:        private_host_t *this;
                    314: 
                    315:        INIT(this,
                    316:                .public = {
                    317:                        .get_sockaddr = _get_sockaddr,
                    318:                        .get_sockaddr_len = _get_sockaddr_len,
                    319:                        .clone = _clone_,
                    320:                        .get_family = _get_family,
                    321:                        .get_address = _get_address,
                    322:                        .get_port = _get_port,
                    323:                        .set_port = _set_port,
                    324:                        .ip_equals = (bool (*)(host_t *,host_t *))ip_equals,
                    325:                        .equals = (bool (*)(host_t *,host_t *)) equals,
                    326:                        .is_anyaddr = _is_anyaddr,
                    327:                        .destroy = _destroy,
                    328:                },
                    329:        );
                    330: 
                    331:        return this;
                    332: }
                    333: 
                    334: /*
                    335:  * Create a %any host with port
                    336:  */
                    337: static host_t *host_create_any_port(int family, uint16_t port)
                    338: {
                    339:        host_t *this;
                    340: 
                    341:        this = host_create_any(family);
                    342:        this->set_port(this, port);
                    343:        return this;
                    344: }
                    345: 
                    346: /*
                    347:  * Described in header.
                    348:  */
                    349: host_t *host_create_from_string_and_family(char *string, int family,
                    350:                                                                                   uint16_t port)
                    351: {
                    352:        union {
                    353:                struct sockaddr_in v4;
                    354:                struct sockaddr_in6 v6;
                    355:        } addr;
                    356: 
                    357:        if (!string)
                    358:        {
                    359:                return NULL;
                    360:        }
                    361:        if (streq(string, "%any"))
                    362:        {
                    363:                return host_create_any_port(family ? family : AF_INET, port);
                    364:        }
                    365:        if (family == AF_UNSPEC || family == AF_INET)
                    366:        {
                    367:                if (streq(string, "%any4") || streq(string, "0.0.0.0"))
                    368:                {
                    369:                        return host_create_any_port(AF_INET, port);
                    370:                }
                    371:        }
                    372:        if (family == AF_UNSPEC || family == AF_INET6)
                    373:        {
                    374:                if (streq(string, "%any6") || streq(string, "::"))
                    375:                {
                    376:                        return host_create_any_port(AF_INET6, port);
                    377:                }
                    378:        }
                    379:        switch (family)
                    380:        {
                    381:                case AF_UNSPEC:
                    382:                        if (strchr(string, '.'))
                    383:                        {
                    384:                                goto af_inet;
                    385:                        }
                    386:                        /* FALL */
                    387:                case AF_INET6:
                    388:                        memset(&addr.v6, 0, sizeof(addr.v6));
                    389:                        if (inet_pton(AF_INET6, string, &addr.v6.sin6_addr) != 1)
                    390:                        {
                    391:                                return NULL;
                    392:                        }
                    393:                        addr.v6.sin6_port = htons(port);
                    394:                        addr.v6.sin6_family = AF_INET6;
                    395:                        return host_create_from_sockaddr((sockaddr_t*)&addr);
                    396:                case AF_INET:
                    397:                        if (strchr(string, ':'))
                    398:                        {       /* do not try to convert v6 addresses for v4 family */
                    399:                                return NULL;
                    400:                        }
                    401:                af_inet:
                    402:                        memset(&addr.v4, 0, sizeof(addr.v4));
                    403:                        if (inet_pton(AF_INET, string, &addr.v4.sin_addr) != 1)
                    404:                        {
                    405:                                return NULL;
                    406:                        }
                    407:                        addr.v4.sin_port = htons(port);
                    408:                        addr.v4.sin_family = AF_INET;
                    409:                        return host_create_from_sockaddr((sockaddr_t*)&addr);
                    410:                default:
                    411:                        return NULL;
                    412:        }
                    413: }
                    414: 
                    415: /*
                    416:  * Described in header.
                    417:  */
                    418: host_t *host_create_from_string(char *string, uint16_t port)
                    419: {
                    420:        return host_create_from_string_and_family(string, AF_UNSPEC, port);
                    421: }
                    422: 
                    423: /*
                    424:  * Described in header.
                    425:  */
                    426: host_t *host_create_from_sockaddr(sockaddr_t *sockaddr)
                    427: {
                    428:        private_host_t *this = host_create_empty();
                    429: 
                    430:        switch (sockaddr->sa_family)
                    431:        {
                    432:                case AF_INET:
                    433:                {
                    434:                        memcpy(&this->address4, (struct sockaddr_in*)sockaddr,
                    435:                                   sizeof(struct sockaddr_in));
                    436:                        this->socklen = sizeof(struct sockaddr_in);
                    437:                        update_sa_len(this);
                    438:                        return &this->public;
                    439:                }
                    440:                case AF_INET6:
                    441:                {
                    442:                        memcpy(&this->address6, (struct sockaddr_in6*)sockaddr,
                    443:                                   sizeof(struct sockaddr_in6));
                    444:                        this->socklen = sizeof(struct sockaddr_in6);
                    445:                        update_sa_len(this);
                    446:                        return &this->public;
                    447:                }
                    448:                default:
                    449:                        break;
                    450:        }
                    451:        free(this);
                    452:        return NULL;
                    453: }
                    454: 
                    455: /*
                    456:  * Described in header.
                    457:  */
                    458: host_t *host_create_from_dns(char *string, int af, uint16_t port)
                    459: {
                    460:        host_t *this;
                    461: 
                    462:        this = host_create_from_string_and_family(string, af, port);
                    463:        if (!this)
                    464:        {
                    465:                this = lib->hosts->resolve(lib->hosts, string, af);
                    466:        }
                    467:        if (this)
                    468:        {
                    469:                this->set_port(this, port);
                    470:        }
                    471:        return this;
                    472: }
                    473: 
                    474: /*
                    475:  * Described in header.
                    476:  */
                    477: host_t *host_create_from_chunk(int family, chunk_t address, uint16_t port)
                    478: {
                    479:        private_host_t *this;
                    480: 
                    481:        switch (family)
                    482:        {
                    483:                case AF_INET:
                    484:                        if (address.len < IPV4_LEN)
                    485:                        {
                    486:                                return NULL;
                    487:                        }
                    488:                        address.len = IPV4_LEN;
                    489:                        break;
                    490:                case AF_INET6:
                    491:                        if (address.len < IPV6_LEN)
                    492:                        {
                    493:                                return NULL;
                    494:                        }
                    495:                        address.len = IPV6_LEN;
                    496:                        break;
                    497:                case AF_UNSPEC:
                    498:                        switch (address.len)
                    499:                        {
                    500:                                case IPV4_LEN:
                    501:                                        family = AF_INET;
                    502:                                        break;
                    503:                                case IPV6_LEN:
                    504:                                        family = AF_INET6;
                    505:                                        break;
                    506:                                default:
                    507:                                        return NULL;
                    508:                        }
                    509:                        break;
                    510:                default:
                    511:                        return NULL;
                    512:        }
                    513:        this = host_create_empty();
                    514:        this->address.sa_family = family;
                    515:        switch (family)
                    516:        {
                    517:                case AF_INET:
                    518:                        memcpy(&this->address4.sin_addr.s_addr, address.ptr, address.len);
                    519:                        this->address4.sin_port = htons(port);
                    520:                        this->socklen = sizeof(struct sockaddr_in);
                    521:                        break;
                    522:                case AF_INET6:
                    523:                        memcpy(&this->address6.sin6_addr.s6_addr, address.ptr, address.len);
                    524:                        this->address6.sin6_port = htons(port);
                    525:                        this->socklen = sizeof(struct sockaddr_in6);
                    526:                        break;
                    527:        }
                    528:        update_sa_len(this);
                    529:        return &this->public;
                    530: }
                    531: 
                    532: /*
                    533:  * Described in header.
                    534:  */
                    535: bool host_create_from_range(char *string, host_t **from, host_t **to)
                    536: {
                    537:        char *sep, *pos;
                    538: 
                    539:        sep = strchr(string, '-');
                    540:        if (!sep)
                    541:        {
                    542:                return FALSE;
                    543:        }
                    544:        for (pos = sep+1; *pos && *pos == ' '; pos++)
                    545:        {
                    546:                /* trim spaces before to address*/
                    547:        }
                    548:        *to = host_create_from_string(pos, 0);
                    549:        if (!*to)
                    550:        {
                    551:                return FALSE;
                    552:        }
                    553:        for (pos = sep-1; pos > string && *pos == ' '; pos--)
                    554:        {
                    555:                /* trim spaces behind from address */
                    556:        }
                    557:        pos = strndup(string, pos - string + 1);
                    558:        *from = host_create_from_string_and_family(pos, (*to)->get_family(*to), 0);
                    559:        free(pos);
                    560:        if (!*from)
                    561:        {
                    562:                (*to)->destroy(*to);
                    563:                return FALSE;
                    564:        }
                    565:        return TRUE;
                    566: }
                    567: 
                    568: /*
                    569:  * Described in header.
                    570:  */
                    571: host_t *host_create_from_subnet(char *string, int *bits)
                    572: {
                    573:        char *pos, buf[64];
                    574:        host_t *net;
                    575: 
                    576:        pos = strchr(string, '/');
                    577:        if (pos)
                    578:        {
                    579:                if (pos - string >= sizeof(buf))
                    580:                {
                    581:                        return NULL;
                    582:                }
                    583:                strncpy(buf, string, pos - string);
                    584:                buf[pos - string] = '\0';
                    585:                *bits = atoi(pos + 1);
                    586:                return host_create_from_string(buf, 0);
                    587:        }
                    588:        net = host_create_from_string(string, 0);
                    589:        if (net)
                    590:        {
                    591:                if (net->get_family(net) == AF_INET)
                    592:                {
                    593:                        *bits = 32;
                    594:                }
                    595:                else
                    596:                {
                    597:                        *bits = 128;
                    598:                }
                    599:        }
                    600:        return net;
                    601: }
                    602: 
                    603: /*
                    604:  * See header.
                    605:  */
                    606: host_t *host_create_netmask(int family, int netbits)
                    607: {
                    608:        private_host_t *this;
                    609:        int bits, bytes, len = 0;
                    610:        char *target;
                    611: 
                    612:        switch (family)
                    613:        {
                    614:                case AF_INET:
                    615:                        if (netbits < 0 || netbits > 32)
                    616:                        {
                    617:                                return NULL;
                    618:                        }
                    619:                        this = host_create_empty();
                    620:                        this->socklen = sizeof(struct sockaddr_in);
                    621:                        target = (char*)&this->address4.sin_addr;
                    622:                        len = 4;
                    623:                        break;
                    624:                case AF_INET6:
                    625:                        if (netbits < 0 || netbits > 128)
                    626:                        {
                    627:                                return NULL;
                    628:                        }
                    629:                        this = host_create_empty();
                    630:                        this->socklen = sizeof(struct sockaddr_in6);
                    631:                        target = (char*)&this->address6.sin6_addr;
                    632:                        len = 16;
                    633:                        break;
                    634:                default:
                    635:                        return NULL;
                    636:        }
                    637: 
                    638:        memset(&this->address_max, 0, sizeof(struct sockaddr_storage));
                    639:        this->address.sa_family = family;
                    640:        update_sa_len(this);
                    641: 
                    642:        bytes = netbits / 8;
                    643:        bits = 8 - (netbits & 0x07);
                    644: 
                    645:        memset(target, 0xff, bytes);
                    646:        if (bytes < len)
                    647:        {
                    648:                memset(target + bytes, 0x00, len - bytes);
                    649:                target[bytes] = (uint8_t)(0xff << bits);
                    650:        }
                    651:        return &this->public;
                    652: }
                    653: 
                    654: /*
                    655:  * Described in header.
                    656:  */
                    657: host_t *host_create_any(int family)
                    658: {
                    659:        private_host_t *this = host_create_empty();
                    660: 
                    661:        memset(&this->address_max, 0, sizeof(struct sockaddr_storage));
                    662:        this->address.sa_family = family;
                    663: 
                    664:        switch (family)
                    665:        {
                    666:                case AF_INET:
                    667:                {
                    668:                        this->socklen = sizeof(struct sockaddr_in);
                    669:                        update_sa_len(this);
                    670:                        return &(this->public);
                    671:                }
                    672:                case AF_INET6:
                    673:                {
                    674:                        this->socklen = sizeof(struct sockaddr_in6);
                    675:                        update_sa_len(this);
                    676:                        return &this->public;
                    677:                }
                    678:                default:
                    679:                        break;
                    680:        }
                    681:        free(this);
                    682:        return NULL;
                    683: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>