Annotation of embedaddon/strongswan/src/libcharon/plugins/kernel_wfp/ipsecdump.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2013 Martin Willi
                      3:  * Copyright (C) 2013 revosec AG
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: /* Windows 7, for some fwpmu.h functionality */
                     17: #define _WIN32_WINNT 0x0601
                     18: 
                     19: #include "kernel_wfp_compat.h"
                     20: 
                     21: #include <library.h>
                     22: 
                     23: ENUM(auth_type_names, IPSEC_AUTH_MD5, IPSEC_AUTH_AES_256,
                     24:        "MD5",
                     25:        "SHA1",
                     26:        "SHA256",
                     27:        "AES128",
                     28:        "AES192",
                     29:        "AES256",
                     30: );
                     31: 
                     32: ENUM(auth_config_names, 0, 5,
                     33:        "HMAC96",
                     34:        "HMAC96",
                     35:        "HMAC128",
                     36:        "GMAC",
                     37:        "GMAC",
                     38:        "GMAC",
                     39: );
                     40: 
                     41: ENUM(cipher_type_names, IPSEC_CIPHER_TYPE_DES, IPSEC_CIPHER_TYPE_AES_256,
                     42:        "DES",
                     43:        "3DES",
                     44:        "AES128",
                     45:        "AES192",
                     46:        "AES256",
                     47: );
                     48: 
                     49: ENUM(cipher_config_names, 1, 8,
                     50:        "CBC",
                     51:        "CBC",
                     52:        "CBC",
                     53:        "CBC",
                     54:        "CBC",
                     55:        "GCM",
                     56:        "GCM",
                     57:        "GCM",
                     58: );
                     59: 
                     60: ENUM(match_type_names, FWP_MATCH_EQUAL, FWP_MATCH_NOT_EQUAL,
                     61:        "equals",
                     62:        "greater",
                     63:        "less than",
                     64:        "greater or equal than",
                     65:        "less or equal than",
                     66:        "in range",
                     67:        "has all flags set",
                     68:        "has any flags set",
                     69:        "has none flags set",
                     70:        "equals case insensitive",
                     71:        "not equal",
                     72: );
                     73: 
                     74: ENUM(traffic_type_names, IPSEC_TRAFFIC_TYPE_TRANSPORT, IPSEC_TRAFFIC_TYPE_TUNNEL,
                     75:        "Transport",
                     76:        "Tunnel",
                     77: );
                     78: 
                     79: /**
                     80:  * Print a GUID to a static buffer
                     81:  */
                     82: static char *guid2string(GUID *guid)
                     83: {
                     84:        static char buf[64];
                     85: 
                     86:        snprintf(buf, sizeof(buf),
                     87:                "%08x,%04x,%04x%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x",
                     88:                guid->Data1, guid->Data2, guid->Data3,
                     89:                guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
                     90:                guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
                     91: 
                     92:        return buf;
                     93: }
                     94: 
                     95: /**
                     96:  * Convert filter condition key GUID to some known strings
                     97:  */
                     98: static char* cond2name(GUID *guid, bool *address)
                     99: {
                    100:        struct {
                    101:                GUID guid;
                    102:                char *name;
                    103:                bool address;
                    104:        } map[] = {
                    105:                { FWPM_CONDITION_IP_LOCAL_ADDRESS, "local address", TRUE},
                    106:                { FWPM_CONDITION_IP_REMOTE_ADDRESS, "remote address", TRUE},
                    107:                { FWPM_CONDITION_IP_SOURCE_ADDRESS, "source address", TRUE},
                    108:                { FWPM_CONDITION_IP_DESTINATION_ADDRESS, "destination address", TRUE},
                    109:                { FWPM_CONDITION_IP_LOCAL_PORT, "local port", FALSE},
                    110:                { FWPM_CONDITION_IP_REMOTE_PORT, "remote port", FALSE},
                    111:                { FWPM_CONDITION_IP_PROTOCOL, "protocol", FALSE},
                    112:                { FWPM_CONDITION_ICMP_CODE, "icmp code", FALSE},
                    113:                { FWPM_CONDITION_ICMP_TYPE, "icmp type", FALSE},
                    114:        };
                    115:        int i;
                    116: 
                    117:        for (i = 0; i < countof(map); i++)
                    118:        {
                    119:                if (memeq(&map[i].guid, guid, sizeof(GUID)))
                    120:                {
                    121:                        *address = map[i].address;
                    122:                        return map[i].name;
                    123:                }
                    124:        }
                    125:        *address = FALSE;
                    126:        return guid2string(guid);
                    127: }
                    128: 
                    129: /**
                    130:  * Print a host from raw data and IP version
                    131:  */
                    132: static void print_host(FWP_IP_VERSION version, void *data)
                    133: {
                    134:        host_t *host = NULL;
                    135:        UINT32 ints[4];
                    136: 
                    137:        switch (version)
                    138:        {
                    139:                case FWP_IP_VERSION_V4:
                    140:                        ints[0] = untoh32(data);
                    141:                        host = host_create_from_chunk(AF_INET, chunk_from_thing(ints[0]), 0);
                    142:                        break;
                    143:                case FWP_IP_VERSION_V6:
                    144:                        ints[3] = untoh32(data);
                    145:                        ints[2] = untoh32(data + 4);
                    146:                        ints[1] = untoh32(data + 8);
                    147:                        ints[0] = untoh32(data + 12);
                    148:                        host = host_create_from_chunk(AF_INET6, chunk_from_thing(ints), 0);
                    149:                        break;
                    150:                default:
                    151:                        break;
                    152:        }
                    153:        if (host)
                    154:        {
                    155:                printf("%H", host);
                    156:                host->destroy(host);
                    157:        }
                    158: }
                    159: 
                    160: /**
                    161:  * Print IPSEC_SA_AUTH_INFORMATION0
                    162:  */
                    163: static void print_auth(IPSEC_SA_AUTH_INFORMATION0 *a)
                    164: {
                    165:        printf("%N-%N",
                    166:                auth_type_names, a->authTransform.authTransformId.authType,
                    167:                auth_config_names, a->authTransform.authTransformId.authConfig);
                    168: }
                    169: 
                    170: /**
                    171:  * Print IPSEC_SA_CIPHER_INFORMATION0
                    172:  */
                    173: static void print_cipher(IPSEC_SA_CIPHER_INFORMATION0 *c)
                    174: {
                    175:        printf("%N-%N",
                    176:                cipher_type_names, c->cipherTransform.cipherTransformId.cipherType,
                    177:                cipher_config_names, c->cipherTransform.cipherTransformId.cipherConfig);
                    178: }
                    179: 
                    180: /**
                    181:  * Print IPsec SA transform
                    182:  */
                    183: static void list_sa(HANDLE engine, IPSEC_SA0 *sa)
                    184: {
                    185:        printf("    SPI 0x%08x\n", sa->spi);
                    186:        switch (sa->saTransformType)
                    187:        {
                    188:                case IPSEC_TRANSFORM_AH:
                    189:                        printf("      AH: ");
                    190:                        print_auth(sa->ahInformation);
                    191:                        break;
                    192:                case IPSEC_TRANSFORM_ESP_AUTH:
                    193:                        printf("      ESP: ");
                    194:                        print_auth(sa->espAuthInformation);
                    195:                        break;
                    196:                case IPSEC_TRANSFORM_ESP_CIPHER:
                    197:                        printf("      ESP: ");
                    198:                        print_cipher(sa->espCipherInformation);
                    199:                        break;
                    200:                case IPSEC_TRANSFORM_ESP_AUTH_AND_CIPHER:
                    201:                        printf("      ESP: ");
                    202:                        print_auth(&sa->espAuthAndCipherInformation->saAuthInformation);
                    203:                        printf(", ");
                    204:                        print_cipher(&sa->espAuthAndCipherInformation->saCipherInformation);
                    205:                        break;
                    206:                default:
                    207:                        printf("      (Transform %d)", sa->saTransformType);
                    208:                        break;
                    209:        }
                    210:        printf("\n");
                    211: }
                    212: 
                    213: /**
                    214:  * List a filter condition value, optionally as IP address
                    215:  */
                    216: static void print_value(FWP_CONDITION_VALUE0 *value, bool address)
                    217: {
                    218:        chunk_t chunk;
                    219: 
                    220:        switch (value->type)
                    221:        {
                    222:                case FWP_EMPTY:
                    223:                        printf("empty");
                    224:                        break;
                    225:                case FWP_UINT8:
                    226:                        printf("%u", value->uint8);
                    227:                        break;
                    228:                case FWP_UINT16:
                    229:                        printf("%u", value->uint16);
                    230:                        break;
                    231:                case FWP_UINT32:
                    232:                        if (address)
                    233:                        {
                    234:                                print_host(FWP_IP_VERSION_V4, &value->uint32);
                    235:                        }
                    236:                        else
                    237:                        {
                    238:                                printf("%u", value->uint32);
                    239:                        }
                    240:                        break;
                    241:                case FWP_UINT64:
                    242:                        printf("%llu", value->uint64);
                    243:                        break;
                    244:                case FWP_INT8:
                    245:                        printf("%d", value->int8);
                    246:                        break;
                    247:                case FWP_INT16:
                    248:                        printf("%d", value->int16);
                    249:                        break;
                    250:                case FWP_INT32:
                    251:                        printf("%d", value->int32);
                    252:                        break;
                    253:                case FWP_INT64:
                    254:                        printf("%lld", value->int64);
                    255:                        break;
                    256:                case FWP_FLOAT:
                    257:                        printf("%f", value->float32);
                    258:                        break;
                    259:                case FWP_DOUBLE:
                    260:                        printf("%lf", value->double64);
                    261:                        break;
                    262:                case FWP_BYTE_ARRAY16_TYPE:
                    263:                        if (address)
                    264:                        {
                    265:                                print_host(FWP_IP_VERSION_V6, value->byteArray16);
                    266:                        }
                    267:                        else
                    268:                        {
                    269:                                chunk = chunk_create((u_char*)value->byteArray16, 16);
                    270:                                printf("%#B", &chunk);
                    271:                        }
                    272:                        break;
                    273:                case FWP_BYTE_BLOB_TYPE:
                    274:                        chunk = chunk_create(value->byteBlob->data, value->byteBlob->size);
                    275:                        printf("%#B", &chunk);
                    276:                        break;
                    277:                case FWP_V4_ADDR_MASK:
                    278:                        print_host(FWP_IP_VERSION_V4, &value->v4AddrMask->addr);
                    279:                        printf("/");
                    280:                        print_host(FWP_IP_VERSION_V4, &value->v4AddrMask->mask);
                    281:                        break;
                    282:                case FWP_V6_ADDR_MASK:
                    283:                        print_host(FWP_IP_VERSION_V6, &value->v6AddrMask->addr);
                    284:                        printf("/%u", &value->v6AddrMask->prefixLength);
                    285:                        break;
                    286:                case FWP_RANGE_TYPE:
                    287:                        print_value((FWP_CONDITION_VALUE0*)&value->rangeValue->valueLow,
                    288:                                                address);
                    289:                        printf(" - ");
                    290:                        print_value((FWP_CONDITION_VALUE0*)&value->rangeValue->valueHigh,
                    291:                                                address);
                    292:                        break;
                    293:                default:
                    294:                        printf("(unsupported)");
                    295:                        break;
                    296:        }
                    297: }
                    298: 
                    299: /**
                    300:  * List a filter condition
                    301:  */
                    302: static void list_cond(HANDLE engine, FWPM_FILTER_CONDITION0 *cond)
                    303: {
                    304:        bool address;
                    305: 
                    306:        printf("      '%s' %N '", cond2name(&cond->fieldKey, &address),
                    307:                match_type_names, cond->matchType);
                    308:        print_value(&cond->conditionValue, address);
                    309:        printf("'\n");
                    310: }
                    311: 
                    312: /**
                    313:  * Print IPsec SA details
                    314:  */
                    315: static void list_details(HANDLE engine, IPSEC_SA_DETAILS1 *details)
                    316: {
                    317:        int i;
                    318: 
                    319:        printf("  %sbound SA: ",
                    320:                details->saDirection == FWP_DIRECTION_INBOUND ? "In" : "Out");
                    321:        print_host(details->traffic.ipVersion, &details->traffic.localV4Address);
                    322:        printf(" %s ", details->saDirection == FWP_DIRECTION_INBOUND ? "<-" : "->");
                    323:        print_host(details->traffic.ipVersion, &details->traffic.remoteV4Address);
                    324:        printf("\n    %N, flags: 0x%06x, lifetime: %us\n",
                    325:                  traffic_type_names, details->traffic.trafficType,
                    326:                  details->saBundle.flags, details->saBundle.lifetime.lifetimeSeconds);
                    327:        if (details->udpEncapsulation)
                    328:        {
                    329:                printf("    UDP encap ports %u - %u\n",
                    330:                        details->udpEncapsulation->localUdpEncapPort,
                    331:                        details->udpEncapsulation->remoteUdpEncapPort);
                    332:        }
                    333:        for (i = 0; i < details->saBundle.numSAs; i++)
                    334:        {
                    335:                list_sa(engine, &details->saBundle.saList[i]);
                    336:        }
                    337:        printf("    Filter ID %llu\n", details->transportFilter->filterId);
                    338:        for (i = 0; i < details->transportFilter->numFilterConditions; i++)
                    339:        {
                    340:                list_cond(engine, &details->transportFilter->filterCondition[i]);
                    341:        }
                    342: }
                    343: 
                    344: /**
                    345:  * List installed SA contexts
                    346:  */
                    347: static bool list_contexts(HANDLE engine)
                    348: {
                    349:        HANDLE handle;
                    350:        UINT32 returned;
                    351:        DWORD res;
                    352:        IPSEC_SA_CONTEXT1 **entries;
                    353: 
                    354:        res = IPsecSaContextCreateEnumHandle0(engine, NULL, &handle);
                    355:        if (res != ERROR_SUCCESS)
                    356:        {
                    357:                fprintf(stderr, "IPsecSaContextCreateEnumHandle0(): 0x%08x\n", res);
                    358:                return FALSE;
                    359:        }
                    360: 
                    361:        while (TRUE)
                    362:        {
                    363:                res = IPsecSaContextEnum1(engine, handle, 1, &entries, &returned);
                    364:                if (res != ERROR_SUCCESS)
                    365:                {
                    366:                        fprintf(stderr, "IPsecSaContextEnum1(): 0x%08x\n", res);
                    367:                        IPsecSaContextDestroyEnumHandle0(engine, handle);
                    368:                        return FALSE;
                    369:                }
                    370:                if (returned == 0)
                    371:                {
                    372:                        break;
                    373:                }
                    374: 
                    375:                printf("SA context %llu:\n", entries[0]->saContextId);
                    376:                list_details(engine, entries[0]->inboundSa);
                    377:                list_details(engine, entries[0]->outboundSa);
                    378: 
                    379:                FwpmFreeMemory0((void**)&entries);
                    380:        }
                    381:        IPsecSaContextDestroyEnumHandle0(engine, handle);
                    382:        return TRUE;
                    383: }
                    384: 
                    385: const GUID FWPM_LAYER_IPSEC_KM_DEMUX_V4 = {
                    386:        0xf02b1526, 0xa459, 0x4a51, { 0xb9, 0xe3, 0x75, 0x9d, 0xe5, 0x2b, 0x9d, 0x2c }
                    387: };
                    388: const GUID FWPM_LAYER_IPSEC_KM_DEMUX_V6 = {
                    389:        0x2f755cf6, 0x2fd4, 0x4e88, { 0xb3, 0xe4, 0xa9, 0x1b, 0xca, 0x49, 0x52, 0x35 }
                    390: };
                    391: const GUID FWPM_LAYER_IPSEC_V4 = {
                    392:        0xeda65c74, 0x610d, 0x4bc5, { 0x94, 0x8f, 0x3c, 0x4f, 0x89, 0x55, 0x68, 0x67 }
                    393: };
                    394: const GUID FWPM_LAYER_IPSEC_V6 = {
                    395:        0x13c48442, 0x8d87, 0x4261, { 0x9a, 0x29, 0x59, 0xd2, 0xab, 0xc3, 0x48, 0xb4 }
                    396: };
                    397: const GUID FWPM_LAYER_IKEEXT_V4 = {
                    398:        0xb14b7bdb, 0xdbbd, 0x473e, { 0xbe, 0xd4, 0x8b, 0x47, 0x08, 0xd4, 0xf2, 0x70 }
                    399: };
                    400: const GUID FWPM_LAYER_IKEEXT_V6 = {
                    401:        0xb64786b3, 0xf687, 0x4eb9, { 0x89, 0xd2, 0x8e, 0xf3, 0x2a, 0xcd, 0xab, 0xe2 }
                    402: };
                    403: const GUID FWPM_LAYER_INBOUND_IPPACKET_V4 = {
                    404:        0xc86fd1bf, 0x21cd, 0x497e, { 0xa0, 0xbb, 0x17, 0x42, 0x5c, 0x88, 0x5c, 0x58 }
                    405: };
                    406: const GUID FWPM_LAYER_INBOUND_IPPACKET_V4_DISCARD = {
                    407:        0xb5a230d0, 0xa8c0, 0x44f2, { 0x91, 0x6e, 0x99, 0x1b, 0x53, 0xde, 0xd1, 0xf7 }
                    408: };
                    409: const GUID FWPM_LAYER_INBOUND_IPPACKET_V6 = {
                    410:        0xf52032cb, 0x991c, 0x46e7, { 0x97, 0x1d, 0x26, 0x01, 0x45, 0x9a, 0x91, 0xca }
                    411: };
                    412: const GUID FWPM_LAYER_INBOUND_IPPACKET_V6_DISCARD = {
                    413:        0xbb24c279, 0x93b4, 0x47a2, { 0x83, 0xad, 0xae, 0x16, 0x98, 0xb5, 0x08, 0x85 }
                    414: };
                    415: const GUID FWPM_LAYER_OUTBOUND_IPPACKET_V4 = {
                    416:        0x1e5c9fae, 0x8a84, 0x4135, { 0xa3, 0x31, 0x95, 0x0b, 0x54, 0x22, 0x9e, 0xcd }
                    417: };
                    418: const GUID FWPM_LAYER_OUTBOUND_IPPACKET_V4_DISCARD = {
                    419:        0x08e4bcb5, 0xb647, 0x48f3, { 0x95, 0x3c, 0xe5, 0xdd, 0xbd, 0x03, 0x93, 0x7e }
                    420: };
                    421: const GUID FWPM_LAYER_OUTBOUND_IPPACKET_V6 = {
                    422:        0xa3b3ab6b, 0x3564, 0x488c, { 0x91, 0x17, 0xf3, 0x4e, 0x82, 0x14, 0x27, 0x63 }
                    423: };
                    424: const GUID FWPM_LAYER_OUTBOUND_IPPACKET_V6_DISCARD = {
                    425:        0x9513d7c4, 0xa934, 0x49dc, { 0x91, 0xa7, 0x6c, 0xcb, 0x80, 0xcc, 0x02, 0xe3 }
                    426: };
                    427: const GUID FWPM_LAYER_IPFORWARD_V4_DISCARD = {
                    428:        0x9e9ea773, 0x2fae, 0x4210, { 0x8f, 0x17, 0x34, 0x12, 0x9e, 0xf3, 0x69, 0xeb }
                    429: };
                    430: const GUID FWPM_LAYER_IPFORWARD_V6_DISCARD = {
                    431:        0x31524a5d, 0x1dfe, 0x472f, { 0xbb, 0x93, 0x51, 0x8e, 0xe9, 0x45, 0xd8, 0xa2 }
                    432: };
                    433: const GUID FWPM_LAYER_INBOUND_TRANSPORT_V4_DISCARD = {
                    434:        0xac4a9833, 0xf69d, 0x4648, { 0xb2, 0x61, 0x6d, 0xc8, 0x48, 0x35, 0xef, 0x39 }
                    435: };
                    436: const GUID FWPM_LAYER_INBOUND_TRANSPORT_V6_DISCARD = {
                    437:        0x2a6ff955, 0x3b2b, 0x49d2, { 0x98, 0x48, 0xad, 0x9d, 0x72, 0xdc, 0xaa, 0xb7 }
                    438: };
                    439: const GUID FWPM_LAYER_OUTBOUND_TRANSPORT_V4_DISCARD = {
                    440:        0xc5f10551, 0xbdb0, 0x43d7, { 0xa3, 0x13, 0x50, 0xe2, 0x11, 0xf4, 0xd6, 0x8a }
                    441: };
                    442: const GUID FWPM_LAYER_OUTBOUND_TRANSPORT_V6_DISCARD = {
                    443:        0xf433df69, 0xccbd, 0x482e, { 0xb9, 0xb2, 0x57, 0x16, 0x56, 0x58, 0xc3, 0xb3 }
                    444: };
                    445: 
                    446: /**
                    447:  * Convert filter layer GUID to name
                    448:  */
                    449: static char* layer2name(GUID *guid)
                    450: {
                    451:        struct {
                    452:                GUID guid;
                    453:                char *name;
                    454:        } map[] = {
                    455:                { FWPM_LAYER_IPSEC_KM_DEMUX_V4, "IPsec KM demux v4" },
                    456:                { FWPM_LAYER_IPSEC_KM_DEMUX_V6, "IPsec KM demux v6" },
                    457:                { FWPM_LAYER_IPSEC_V4, "IPsec v4" },
                    458:                { FWPM_LAYER_IPSEC_V6, "IPsec v6" },
                    459:                { FWPM_LAYER_IKEEXT_V4, "IKE ext v4" },
                    460:                { FWPM_LAYER_IKEEXT_V6, "IKE ext v6" },
                    461:                { FWPM_LAYER_INBOUND_IPPACKET_V4, "inbound v4" },
                    462:                { FWPM_LAYER_INBOUND_IPPACKET_V4_DISCARD, "inbound v4 dsc" },
                    463:                { FWPM_LAYER_INBOUND_IPPACKET_V6, "inbound v6" },
                    464:                { FWPM_LAYER_INBOUND_IPPACKET_V6_DISCARD, "inbound v6 dsc" },
                    465:                { FWPM_LAYER_OUTBOUND_IPPACKET_V4, "outbound v4" },
                    466:                { FWPM_LAYER_OUTBOUND_IPPACKET_V4_DISCARD, "outbound v4 dsc" },
                    467:                { FWPM_LAYER_OUTBOUND_IPPACKET_V6, "outbound v6" },
                    468:                { FWPM_LAYER_OUTBOUND_IPPACKET_V6_DISCARD, "outbound v6 dsc" },
                    469:                { FWPM_LAYER_IPFORWARD_V4, "forward v4" },
                    470:                { FWPM_LAYER_IPFORWARD_V4_DISCARD, "forward v4 dsc" },
                    471:                { FWPM_LAYER_IPFORWARD_V6, "forward v6" },
                    472:                { FWPM_LAYER_IPFORWARD_V6_DISCARD, "forward v6 discard" },
                    473:                { FWPM_LAYER_INBOUND_TRANSPORT_V4, "inbound transport v4" },
                    474:                { FWPM_LAYER_INBOUND_TRANSPORT_V4_DISCARD, "inbound transport v4 dsc" },
                    475:                { FWPM_LAYER_INBOUND_TRANSPORT_V6, "inbound transport v6" },
                    476:                { FWPM_LAYER_INBOUND_TRANSPORT_V6_DISCARD, "inbound v6 transport dsc" },
                    477:                { FWPM_LAYER_OUTBOUND_TRANSPORT_V4, "outbound transport v4" },
                    478:                { FWPM_LAYER_OUTBOUND_TRANSPORT_V4_DISCARD, "outbound transport v4 dsc" },
                    479:                { FWPM_LAYER_OUTBOUND_TRANSPORT_V6, "outbound transport v6" },
                    480:                { FWPM_LAYER_OUTBOUND_TRANSPORT_V6_DISCARD, "outbound transport v6 dsc" },
                    481:        };
                    482:        int i;
                    483: 
                    484:        for (i = 0; i < countof(map); i++)
                    485:        {
                    486:                if (memeq(&map[i].guid, guid, sizeof(GUID)))
                    487:                {
                    488:                        return map[i].name;
                    489:                }
                    490:        }
                    491:        return NULL;
                    492: }
                    493: 
                    494: /**
                    495:  * Convert filter callout GUID to name
                    496:  */
                    497: static char* callout2name(GUID *guid)
                    498: {
                    499:        struct {
                    500:                GUID guid;
                    501:                char *name;
                    502:        } map[] = {
                    503:                { FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4, "inbound transport v4" },
                    504:                { FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V6, "inbound transport v6" },
                    505:                { FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V4, "outbound transport v4" },
                    506:                { FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V6, "outbound transport v6" },
                    507:                { FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V4, "inbound tunnel v4" },
                    508:                { FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V6, "inbound tunnel v6" },
                    509:                { FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V4, "outbound tunnel v4" },
                    510:                { FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V6, "outbound tunnel v6" },
                    511:                { FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4, "forward in tunnel v4" },
                    512:                { FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6, "forward in tunnel v6" },
                    513:                { FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4, "forward out tunnel v4" },
                    514:                { FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6, "forward out tunnel v6" },
                    515:        };
                    516:        int i;
                    517: 
                    518:        for (i = 0; i < countof(map); i++)
                    519:        {
                    520:                if (memeq(&map[i].guid, guid, sizeof(GUID)))
                    521:                {
                    522:                        return map[i].name;
                    523:                }
                    524:        }
                    525:        return guid2string(guid);
                    526: }
                    527: 
                    528: /**
                    529:  * Print display data with description
                    530:  */
                    531: static void print_display_data(FWPM_DISPLAY_DATA0 *data)
                    532: {
                    533:        char buf[128];
                    534: 
                    535:        buf[0] = '\0';
                    536:        if (data->name)
                    537:        {
                    538:                wcstombs(buf, data->name, sizeof(buf));
                    539:        }
                    540:        printf("%s", buf);
                    541:        if (data->description)
                    542:        {
                    543:                buf[0] = '\0';
                    544:                wcstombs(buf, data->description, sizeof(buf));
                    545:                if (strlen(buf))
                    546:                {
                    547:                        printf(" (%s)", buf);
                    548:                }
                    549:        }
                    550: }
                    551: 
                    552: /**
                    553:  * List installed firewall filters
                    554:  */
                    555: static bool list_filters(HANDLE engine)
                    556: {
                    557:        HANDLE handle;
                    558:        UINT32 returned;
                    559:        DWORD res;
                    560:        FWPM_FILTER0 **entries;
                    561:        char *layer;
                    562:        int i;
                    563: 
                    564:        res = FwpmFilterCreateEnumHandle0(engine, NULL, &handle);
                    565:        if (res != ERROR_SUCCESS)
                    566:        {
                    567:                fprintf(stderr, "FwpmFilterCreateEnumHandle0(): 0x%08x\n", res);
                    568:                return FALSE;
                    569:        }
                    570: 
                    571:        while (TRUE)
                    572:        {
                    573:                res = FwpmFilterEnum0(engine, handle, 1, &entries, &returned);
                    574:                if (res != ERROR_SUCCESS)
                    575:                {
                    576:                        fprintf(stderr, "FwpmFilterEnum0(): 0x%08x\n", res);
                    577:                        FwpmFilterDestroyEnumHandle0(engine, handle);
                    578:                        return FALSE;
                    579:                }
                    580:                if (returned == 0)
                    581:                {
                    582:                        break;
                    583:                }
                    584: 
                    585:                layer = layer2name(&entries[0]->layerKey);
                    586:                if (layer)
                    587:                {
                    588:                        printf("Filter ID %llu, '", entries[0]->filterId);
                    589:                        print_display_data(&entries[0]->displayData);
                    590:                        printf("'\n");
                    591:                        printf("  %s, ", layer);
                    592:                        if (entries[0]->effectiveWeight.type == FWP_UINT64)
                    593:                        {
                    594:                                printf("weight %016llx, ", *entries[0]->effectiveWeight.uint64);
                    595:                        }
                    596: 
                    597:                        switch (entries[0]->action.type)
                    598:                        {
                    599:                                case FWP_ACTION_BLOCK:
                    600:                                        printf("block\n");
                    601:                                        break;
                    602:                                case FWP_ACTION_PERMIT:
                    603:                                        printf("permit\n");
                    604:                                        break;
                    605:                                case FWP_ACTION_CALLOUT_TERMINATING:
                    606:                                        printf("callout terminating: %s\n",
                    607:                                                callout2name(&entries[0]->action.calloutKey));
                    608:                                        break;
                    609:                                case FWP_ACTION_CALLOUT_INSPECTION:
                    610:                                        printf("callout inspection: %s\n",
                    611:                                                callout2name(&entries[0]->action.calloutKey));
                    612:                                        break;
                    613:                                case FWP_ACTION_CALLOUT_UNKNOWN:
                    614:                                        printf("callout unknown: %s\n",
                    615:                                                callout2name(&entries[0]->action.calloutKey));
                    616:                                        break;
                    617:                                default:
                    618:                                        printf("(unknown action)\n");
                    619:                                        break;
                    620:                        }
                    621:                        for (i = 0; i < entries[0]->numFilterConditions; i++)
                    622:                        {
                    623:                                list_cond(engine, &entries[0]->filterCondition[i]);
                    624:                        }
                    625:                }
                    626:                FwpmFreeMemory0((void**)&entries);
                    627:        }
                    628:        FwpmFilterDestroyEnumHandle0(engine, handle);
                    629:        return TRUE;
                    630: }
                    631: 
                    632: /**
                    633:  * ipsecdump main()
                    634:  */
                    635: int main(int argc, char *argv[])
                    636: {
                    637:        FWPM_SESSION0 session = {
                    638:                .displayData = {
                    639:                        .name = L"ipsecdump",
                    640:                        .description = L"strongSwan SAD/SPD dumper",
                    641:                },
                    642:        };
                    643:        HANDLE engine;
                    644:        DWORD res;
                    645:        int code;
                    646: 
                    647:        library_init(NULL, "ipsecdump");
                    648:        atexit(library_deinit);
                    649: 
                    650:        res = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engine);
                    651:        if (res != ERROR_SUCCESS)
                    652:        {
                    653:                fprintf(stderr, "FwpmEngineOpen(): 0x%08x\n", res);
                    654:                return 2;
                    655:        }
                    656:        if (argc > 1 && streq(argv[1], "filters"))
                    657:        {
                    658:                code = list_filters(engine) ? 0 : 1;
                    659:        }
                    660:        else
                    661:        {
                    662:                code = list_contexts(engine) ? 0 : 1;
                    663:        }
                    664:        FwpmEngineClose0(engine);
                    665:        return code;
                    666: }

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