Return to ipsecdump.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / kernel_wfp |
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: }