Return to pool_attributes.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / pool |
1.1 ! misho 1: /* ! 2: * Copyright (C) 2009-2010 Andreas Steffen ! 3: * HSR Hochschule fuer Technik Rapperswil ! 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: #define _GNU_SOURCE ! 17: #include <string.h> ! 18: ! 19: #include <library.h> ! 20: #include <networking/host.h> ! 21: ! 22: #include "pool_attributes.h" ! 23: #include "pool_usage.h" ! 24: ! 25: /** ! 26: * global database handle ! 27: */ ! 28: extern database_t *db; ! 29: ! 30: #define UNITY_NETWORK_LEN 14 ! 31: ! 32: ENUM(value_type_names, VALUE_HEX, VALUE_SUBNET, ! 33: "hex", ! 34: "string", ! 35: "addr", ! 36: "subnet" ! 37: ); ! 38: ! 39: typedef struct attr_info_t attr_info_t; ! 40: ! 41: struct attr_info_t { ! 42: char* keyword; ! 43: value_type_t value_type; ! 44: configuration_attribute_type_t type; ! 45: configuration_attribute_type_t type_ip6; ! 46: }; ! 47: ! 48: static const attr_info_t attr_info[] = { ! 49: { "internal_ip4_netmask", VALUE_ADDR, INTERNAL_IP4_NETMASK, 0 }, ! 50: { "internal_ip6_netmask", VALUE_ADDR, INTERNAL_IP6_NETMASK, 0 }, ! 51: { "netmask", VALUE_ADDR, INTERNAL_IP4_NETMASK, ! 52: INTERNAL_IP6_NETMASK }, ! 53: { "internal_ip4_dns", VALUE_ADDR, INTERNAL_IP4_DNS, 0 }, ! 54: { "internal_ip6_dns", VALUE_ADDR, INTERNAL_IP6_DNS, 0 }, ! 55: { "dns", VALUE_ADDR, INTERNAL_IP4_DNS, ! 56: INTERNAL_IP6_DNS }, ! 57: { "internal_ip4_nbns", VALUE_ADDR, INTERNAL_IP4_NBNS, 0 }, ! 58: { "internal_ip6_nbns", VALUE_ADDR, INTERNAL_IP6_NBNS, 0 }, ! 59: { "nbns", VALUE_ADDR, INTERNAL_IP4_NBNS, ! 60: INTERNAL_IP6_NBNS }, ! 61: { "wins", VALUE_ADDR, INTERNAL_IP4_NBNS, ! 62: INTERNAL_IP6_NBNS }, ! 63: { "internal_ip4_dhcp", VALUE_ADDR, INTERNAL_IP4_DHCP, 0 }, ! 64: { "internal_ip6_dhcp", VALUE_ADDR, INTERNAL_IP6_DHCP, 0 }, ! 65: { "dhcp", VALUE_ADDR, INTERNAL_IP4_DHCP, ! 66: INTERNAL_IP6_DHCP }, ! 67: { "internal_ip4_server", VALUE_ADDR, INTERNAL_IP4_SERVER, 0 }, ! 68: { "internal_ip6_server", VALUE_ADDR, INTERNAL_IP6_SERVER, 0 }, ! 69: { "server", VALUE_ADDR, INTERNAL_IP4_SERVER, ! 70: INTERNAL_IP6_SERVER }, ! 71: { "application_version", VALUE_STRING, APPLICATION_VERSION, 0 }, ! 72: { "version", VALUE_STRING, APPLICATION_VERSION, 0 }, ! 73: { "unity_banner", VALUE_STRING, UNITY_BANNER, 0 }, ! 74: { "banner", VALUE_STRING, UNITY_BANNER, 0 }, ! 75: { "unity_def_domain", VALUE_STRING, UNITY_DEF_DOMAIN, 0 }, ! 76: { "unity_splitdns_name", VALUE_STRING, UNITY_SPLITDNS_NAME, 0 }, ! 77: { "unity_split_include", VALUE_SUBNET, UNITY_SPLIT_INCLUDE, 0 }, ! 78: { "unity_split_exclude", VALUE_SUBNET, UNITY_LOCAL_LAN, 0 }, ! 79: { "unity_local_lan", VALUE_SUBNET, UNITY_LOCAL_LAN, 0 }, ! 80: }; ! 81: ! 82: /** ! 83: * Determine the type of the attribute and its value ! 84: */ ! 85: static bool parse_attributes(char *name, char *value, value_type_t *value_type, ! 86: configuration_attribute_type_t *type, ! 87: configuration_attribute_type_t *type_ip6, ! 88: chunk_t *blob) ! 89: { ! 90: host_t *addr = NULL, *mask = NULL; ! 91: chunk_t addr_chunk, mask_chunk, blob_next; ! 92: char *text = "", *pos_addr, *pos_mask, *pos_next, *endptr; ! 93: int i; ! 94: ! 95: switch (*value_type) ! 96: { ! 97: case VALUE_STRING: ! 98: *blob = chunk_create(value, strlen(value)); ! 99: *blob = chunk_clone(*blob); ! 100: break; ! 101: case VALUE_HEX: ! 102: *blob = chunk_from_hex(chunk_create(value, strlen(value)), NULL); ! 103: break; ! 104: case VALUE_ADDR: ! 105: addr = host_create_from_string(value, 0); ! 106: if (addr == NULL) ! 107: { ! 108: fprintf(stderr, "invalid IP address: '%s'.\n", value); ! 109: return FALSE; ! 110: } ! 111: addr_chunk = addr->get_address(addr); ! 112: *blob = chunk_clone(addr_chunk); ! 113: break; ! 114: case VALUE_SUBNET: ! 115: *blob = chunk_empty; ! 116: pos_next = value; ! 117: ! 118: do ! 119: { ! 120: pos_addr = pos_next; ! 121: pos_next = strchr(pos_next, ','); ! 122: if (pos_next) ! 123: { ! 124: *pos_next = '\0'; ! 125: pos_next += 1; ! 126: } ! 127: pos_mask = strchr(pos_addr, '/'); ! 128: if (pos_mask == NULL) ! 129: { ! 130: fprintf(stderr, "invalid IPv4 subnet: '%s'.\n", pos_addr); ! 131: free(blob->ptr); ! 132: return FALSE; ! 133: } ! 134: *pos_mask = '\0'; ! 135: pos_mask += 1; ! 136: addr = host_create_from_string(pos_addr, 0); ! 137: mask = host_create_from_string(pos_mask, 0); ! 138: if (addr == NULL || addr->get_family(addr) != AF_INET || ! 139: mask == NULL || mask->get_family(addr) != AF_INET) ! 140: { ! 141: fprintf(stderr, "invalid IPv4 subnet: '%s/%s'.\n", ! 142: pos_addr, pos_mask); ! 143: DESTROY_IF(addr); ! 144: DESTROY_IF(mask); ! 145: free(blob->ptr); ! 146: return FALSE; ! 147: } ! 148: addr_chunk = addr->get_address(addr); ! 149: mask_chunk = mask->get_address(mask); ! 150: blob_next = chunk_alloc(blob->len + UNITY_NETWORK_LEN); ! 151: memcpy(blob_next.ptr, blob->ptr, blob->len); ! 152: pos_addr = blob_next.ptr + blob->len; ! 153: memset(pos_addr, 0x00, UNITY_NETWORK_LEN); ! 154: memcpy(pos_addr, addr_chunk.ptr, 4); ! 155: memcpy(pos_addr + 4, mask_chunk.ptr, 4); ! 156: addr->destroy(addr); ! 157: addr = NULL; ! 158: mask->destroy(mask); ! 159: chunk_free(blob); ! 160: *blob = blob_next; ! 161: } ! 162: while (pos_next); ! 163: break; ! 164: case VALUE_NONE: ! 165: *blob = chunk_empty; ! 166: break; ! 167: } ! 168: ! 169: /* init the attribute type */ ! 170: *type = 0; ! 171: *type_ip6 = 0; ! 172: ! 173: for (i = 0; i < countof(attr_info); i++) ! 174: { ! 175: if (strcaseeq(name, attr_info[i].keyword)) ! 176: { ! 177: *type = attr_info[i].type; ! 178: *type_ip6 = attr_info[i].type_ip6; ! 179: ! 180: if (*value_type == VALUE_NONE) ! 181: { ! 182: *value_type = attr_info[i].value_type; ! 183: return TRUE; ! 184: } ! 185: ! 186: if (*value_type != attr_info[i].value_type && ! 187: *value_type != VALUE_HEX) ! 188: { ! 189: switch (attr_info[i].value_type) ! 190: { ! 191: case VALUE_STRING: ! 192: text = "a string"; ! 193: break; ! 194: case VALUE_HEX: ! 195: text = "a hex"; ! 196: break; ! 197: case VALUE_ADDR: ! 198: text = "an IP address"; ! 199: break; ! 200: case VALUE_SUBNET: ! 201: text = "a subnet"; ! 202: break; ! 203: case VALUE_NONE: ! 204: text = "no"; ! 205: break; ! 206: } ! 207: fprintf(stderr, "the %s attribute requires %s value.\n", ! 208: name, text); ! 209: DESTROY_IF(addr); ! 210: free(blob->ptr); ! 211: return FALSE; ! 212: } ! 213: ! 214: if (*value_type == VALUE_ADDR) ! 215: { ! 216: *type = (addr->get_family(addr) == AF_INET) ? ! 217: attr_info[i].type : attr_info[i].type_ip6; ! 218: addr->destroy(addr); ! 219: } ! 220: else if (*value_type == VALUE_HEX) ! 221: { ! 222: *value_type = attr_info[i].value_type; ! 223: ! 224: if (*value_type == VALUE_ADDR) ! 225: { ! 226: if (blob->len == 16) ! 227: { ! 228: *type = attr_info[i].type_ip6; ! 229: } ! 230: else if (blob->len != 4) ! 231: { ! 232: fprintf(stderr, "the %s attribute requires " ! 233: "a valid IP address.\n", name); ! 234: free(blob->ptr); ! 235: return FALSE; ! 236: } ! 237: } ! 238: } ! 239: return TRUE; ! 240: } ! 241: } ! 242: ! 243: /* clean up */ ! 244: DESTROY_IF(addr); ! 245: ! 246: /* is the attribute type numeric? */ ! 247: *type = strtol(name, &endptr, 10); ! 248: ! 249: if (*endptr != '\0') ! 250: { ! 251: fprintf(stderr, "the %s attribute is not recognized.\n", name); ! 252: free(blob->ptr); ! 253: return FALSE; ! 254: } ! 255: if (*type < 1 || *type > 32767) ! 256: { ! 257: fprintf(stderr, "the attribute type must lie in the range 1..32767.\n"); ! 258: free(blob->ptr); ! 259: return FALSE; ! 260: } ! 261: if (*value_type == VALUE_NONE) ! 262: { ! 263: *value_type = VALUE_HEX; ! 264: } ! 265: return TRUE; ! 266: } ! 267: ! 268: /** ! 269: * Lookup/insert an attribute pool by name ! 270: */ ! 271: static u_int get_attr_pool(char *name) ! 272: { ! 273: enumerator_t *e; ! 274: u_int row = 0; ! 275: ! 276: /* look for an existing attribute pool in the table */ ! 277: e = db->query(db, "SELECT id FROM attribute_pools WHERE name = ?", ! 278: DB_TEXT, name, DB_UINT); ! 279: if (e && e->enumerate(e, &row)) ! 280: { ! 281: e->destroy(e); ! 282: return row; ! 283: } ! 284: DESTROY_IF(e); ! 285: /* not found, insert new one */ ! 286: if (db->execute(db, &row, "INSERT INTO attribute_pools (name) VALUES (?)", ! 287: DB_TEXT, name) != 1) ! 288: { ! 289: fprintf(stderr, "creating attribute pool '%s' failed.\n", name); ! 290: return 0; ! 291: } ! 292: return row; ! 293: } ! 294: ! 295: /** ! 296: * Lookup/insert an identity ! 297: */ ! 298: u_int get_identity(identification_t *id) ! 299: { ! 300: enumerator_t *e; ! 301: u_int row; ! 302: ! 303: /* look for peer identity in the identities table */ ! 304: e = db->query(db, "SELECT id FROM identities WHERE type = ? AND data = ?", ! 305: DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id), DB_UINT); ! 306: if (e && e->enumerate(e, &row)) ! 307: { ! 308: e->destroy(e); ! 309: return row; ! 310: } ! 311: DESTROY_IF(e); ! 312: /* not found, insert new one */ ! 313: if (db->execute(db, &row, "INSERT INTO identities (type,data) VALUES (?,?)", ! 314: DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id)) != 1) ! 315: { ! 316: fprintf(stderr, "creating id '%Y' failed.\n", id); ! 317: return 0; ! 318: } ! 319: return row; ! 320: } ! 321: ! 322: /** ! 323: * ipsec pool --addattr <type> - add attribute entry ! 324: */ ! 325: void add_attr(char *name, char *pool, char *identity, ! 326: char *value, value_type_t value_type) ! 327: { ! 328: configuration_attribute_type_t type, type_ip6; ! 329: u_int pool_id = 0, identity_id = 0; ! 330: char id_pool_str[128] = ""; ! 331: chunk_t blob; ! 332: bool success; ! 333: ! 334: if (pool) ! 335: { ! 336: pool_id = get_attr_pool(pool); ! 337: if (pool_id == 0) ! 338: { ! 339: exit(EXIT_FAILURE); ! 340: } ! 341: ! 342: if (identity) ! 343: { ! 344: identification_t *id; ! 345: ! 346: id = identification_create_from_string(identity); ! 347: identity_id = get_identity(id); ! 348: id->destroy(id); ! 349: if (identity_id == 0) ! 350: { ! 351: exit(EXIT_FAILURE); ! 352: } ! 353: snprintf(id_pool_str, sizeof(id_pool_str), ! 354: " for '%s' in pool '%s'", identity, pool); ! 355: } ! 356: else ! 357: { ! 358: snprintf(id_pool_str, sizeof(id_pool_str), " in pool '%s'", pool); ! 359: } ! 360: } ! 361: ! 362: if (value_type == VALUE_NONE) ! 363: { ! 364: fprintf(stderr, "the value of the %s attribute is missing.\n", name); ! 365: usage(); ! 366: } ! 367: if (!parse_attributes(name, value, &value_type, &type, &type_ip6, &blob)) ! 368: { ! 369: exit(EXIT_FAILURE); ! 370: } ! 371: ! 372: success = db->execute(db, NULL, ! 373: "INSERT INTO attributes (identity, pool, type, value) " ! 374: "VALUES (?, ?, ?, ?)", DB_UINT, identity_id, DB_UINT, pool_id, ! 375: DB_INT, type, DB_BLOB, blob) == 1; ! 376: free(blob.ptr); ! 377: ! 378: if (success) ! 379: { ! 380: printf("added %s attribute (%N)%s.\n", name, ! 381: configuration_attribute_type_names, type, id_pool_str); ! 382: } ! 383: else ! 384: { ! 385: fprintf(stderr, "adding %s attribute (%N)%s failed.\n", name, ! 386: configuration_attribute_type_names, type, id_pool_str); ! 387: } ! 388: } ! 389: ! 390: /** ! 391: * ipsec pool --delattr <type> - delete attribute entry ! 392: */ ! 393: void del_attr(char *name, char *pool, char *identity, ! 394: char *value, value_type_t value_type) ! 395: { ! 396: configuration_attribute_type_t type, type_ip6, type_db; ! 397: u_int pool_id = 0, identity_id = 0; ! 398: char id_pool_str[128] = ""; ! 399: chunk_t blob, blob_db; ! 400: u_int id; ! 401: enumerator_t *query; ! 402: bool found = FALSE; ! 403: ! 404: if (pool) ! 405: { ! 406: pool_id = get_attr_pool(pool); ! 407: if (pool_id == 0) ! 408: { ! 409: exit(EXIT_FAILURE); ! 410: } ! 411: ! 412: if (identity) ! 413: { ! 414: identification_t *id; ! 415: ! 416: id = identification_create_from_string(identity); ! 417: identity_id = get_identity(id); ! 418: id->destroy(id); ! 419: if (identity_id == 0) ! 420: { ! 421: exit(EXIT_FAILURE); ! 422: } ! 423: snprintf(id_pool_str, sizeof(id_pool_str), ! 424: " for '%s' in pool '%s'", identity, pool); ! 425: } ! 426: else ! 427: { ! 428: snprintf(id_pool_str, sizeof(id_pool_str), " in pool '%s'", pool); ! 429: } ! 430: } ! 431: ! 432: if (!parse_attributes(name, value, &value_type, &type, &type_ip6, &blob)) ! 433: { ! 434: exit(EXIT_FAILURE); ! 435: } ! 436: ! 437: if (blob.len > 0) ! 438: { ! 439: query = db->query(db, ! 440: "SELECT id, type, value FROM attributes " ! 441: "WHERE identity = ? AND pool = ? AND type = ? AND value = ?", ! 442: DB_UINT, identity_id, DB_UINT, pool_id, DB_INT, type, ! 443: DB_BLOB, blob, DB_UINT, DB_INT, DB_BLOB); ! 444: } ! 445: else if (type_ip6 == 0) ! 446: { ! 447: query = db->query(db, ! 448: "SELECT id, type, value FROM attributes " ! 449: "WHERE identity = ? AND pool = ? AND type = ?", ! 450: DB_UINT, identity_id, DB_UINT, pool_id, DB_INT, type, ! 451: DB_UINT, DB_INT, DB_BLOB); ! 452: } ! 453: else ! 454: { ! 455: query = db->query(db, ! 456: "SELECT id, type, value FROM attributes " ! 457: "WHERE identity = ? AND pool = ? AND (type = ? OR type = ?)", ! 458: DB_UINT, identity_id, DB_UINT, pool_id, DB_INT, type, ! 459: DB_INT, type_ip6, DB_UINT, DB_INT, DB_BLOB); ! 460: } ! 461: ! 462: if (!query) ! 463: { ! 464: fprintf(stderr, "deleting '%s' attribute (%N)%s failed.\n", ! 465: name, configuration_attribute_type_names, type, id_pool_str); ! 466: free(blob.ptr); ! 467: exit(EXIT_FAILURE); ! 468: } ! 469: ! 470: while (query->enumerate(query, &id, &type_db, &blob_db)) ! 471: { ! 472: host_t *server = NULL; ! 473: ! 474: found = TRUE; ! 475: ! 476: if (value_type == VALUE_ADDR) ! 477: { ! 478: int family = (type_db == type_ip6) ? AF_INET6 : AF_INET; ! 479: ! 480: server = host_create_from_chunk(family, blob_db, 0); ! 481: } ! 482: ! 483: if (db->execute(db, NULL, ! 484: "DELETE FROM attributes WHERE id = ?", ! 485: DB_UINT, id) != 1) ! 486: { ! 487: if (server) ! 488: { ! 489: fprintf(stderr, "deleting %s server %H%s failed\n", ! 490: name, server, id_pool_str); ! 491: server->destroy(server); ! 492: } ! 493: else if (value_type == VALUE_STRING) ! 494: { ! 495: fprintf(stderr, "deleting %s attribute (%N) with value '%.*s'%s failed.\n", ! 496: name, configuration_attribute_type_names, type, ! 497: (int)blob_db.len, blob_db.ptr, id_pool_str); ! 498: } ! 499: ! 500: else ! 501: { ! 502: fprintf(stderr, "deleting %s attribute (%N) with value %#B%s failed.\n", ! 503: name, configuration_attribute_type_names, type, ! 504: &blob_db, id_pool_str); ! 505: } ! 506: query->destroy(query); ! 507: free(blob.ptr); ! 508: exit(EXIT_FAILURE); ! 509: } ! 510: if (server) ! 511: { ! 512: printf("deleted %s server %H%s\n", name, server, id_pool_str); ! 513: server->destroy(server); ! 514: } ! 515: else if (value_type == VALUE_STRING) ! 516: { ! 517: printf("deleted %s attribute (%N) with value '%.*s'%s.\n", ! 518: name, configuration_attribute_type_names, type, ! 519: (int)blob_db.len, blob_db.ptr, id_pool_str); ! 520: } ! 521: else ! 522: { ! 523: printf("deleted %s attribute (%N) with value %#B%s.\n", ! 524: name, configuration_attribute_type_names, type, ! 525: &blob_db, id_pool_str); ! 526: } ! 527: } ! 528: query->destroy(query); ! 529: ! 530: if (!found) ! 531: { ! 532: if (blob.len == 0) ! 533: { ! 534: if (type_ip6 == 0) ! 535: { ! 536: fprintf(stderr, "no %s attribute (%N) was found%s.\n", name, ! 537: configuration_attribute_type_names, type, id_pool_str); ! 538: } ! 539: else ! 540: { ! 541: fprintf(stderr, "no %s attribute%s was found.\n", ! 542: name, id_pool_str); ! 543: } ! 544: } ! 545: else ! 546: { ! 547: if (value_type == VALUE_ADDR) ! 548: { ! 549: host_t *server = host_create_from_chunk(AF_UNSPEC, blob, 0); ! 550: ! 551: fprintf(stderr, "the %s server %H%s was not found.\n", name, ! 552: server, id_pool_str); ! 553: server->destroy(server); ! 554: } ! 555: else ! 556: { ! 557: fprintf(stderr, "the %s attribute (%N) with value '%.*s'%s " ! 558: "was not found.\n", name, ! 559: configuration_attribute_type_names, type, ! 560: (int)blob.len, blob.ptr, id_pool_str); ! 561: } ! 562: } ! 563: } ! 564: free(blob.ptr); ! 565: } ! 566: ! 567: /** ! 568: * ipsec pool --statusattr - show all attribute entries ! 569: */ ! 570: void status_attr(bool hexout) ! 571: { ! 572: configuration_attribute_type_t type; ! 573: value_type_t value_type; ! 574: chunk_t value, addr_chunk, mask_chunk, identity_chunk; ! 575: identification_t *identity; ! 576: enumerator_t *enumerator; ! 577: host_t *addr, *mask; ! 578: char type_name[30]; ! 579: bool first = TRUE; ! 580: int i, identity_type; ! 581: char *pool_name; ! 582: ! 583: /* enumerate over all attributes */ ! 584: enumerator = db->query(db, ! 585: "SELECT attributes.type, attribute_pools.name, " ! 586: "identities.type, identities.data, attributes.value " ! 587: "FROM attributes " ! 588: "LEFT OUTER JOIN identities " ! 589: "ON attributes.identity = identities.id " ! 590: "LEFT OUTER JOIN attribute_pools " ! 591: "ON attributes.pool = attribute_pools.id " ! 592: "ORDER BY attributes.type, attribute_pools.name, " ! 593: "identities.type, identities.data, attributes.value", ! 594: DB_INT, DB_TEXT, DB_INT, DB_BLOB, DB_BLOB); ! 595: if (enumerator) ! 596: { ! 597: while (enumerator->enumerate(enumerator, &type,&pool_name, ! 598: &identity_type, &identity_chunk, &value)) ! 599: { ! 600: if (first) ! 601: { ! 602: printf(" type description pool " ! 603: " identity value\n"); ! 604: first = FALSE; ! 605: } ! 606: snprintf(type_name, sizeof(type_name), "%N", ! 607: configuration_attribute_type_names, type); ! 608: if (type_name[0] == '(') ! 609: { ! 610: type_name[0] = '\0'; ! 611: } ! 612: printf("%5d %-20s ",type, type_name); ! 613: ! 614: printf(" %-10s ", (pool_name ? pool_name : "")); ! 615: ! 616: if (identity_type) ! 617: { ! 618: identity = identification_create_from_encoding(identity_type, identity_chunk); ! 619: printf(" %-20.20Y ", identity); ! 620: identity->destroy(identity); ! 621: } ! 622: else ! 623: { ! 624: printf(" "); ! 625: } ! 626: ! 627: value_type = VALUE_HEX; ! 628: if (!hexout) ! 629: { ! 630: for (i = 0; i < countof(attr_info); i++) ! 631: { ! 632: if (type == attr_info[i].type) ! 633: { ! 634: value_type = attr_info[i].value_type; ! 635: break; ! 636: } ! 637: } ! 638: } ! 639: switch (value_type) ! 640: { ! 641: case VALUE_ADDR: ! 642: addr = host_create_from_chunk(AF_UNSPEC, value, 0); ! 643: if (addr) ! 644: { ! 645: printf(" %H\n", addr); ! 646: addr->destroy(addr); ! 647: } ! 648: else ! 649: { ! 650: /* value cannot be represented as an IP address */ ! 651: printf(" %#B\n", &value); ! 652: } ! 653: break; ! 654: case VALUE_SUBNET: ! 655: if (value.len % UNITY_NETWORK_LEN == 0) ! 656: { ! 657: for (i = 0; i < value.len / UNITY_NETWORK_LEN; i++) ! 658: { ! 659: addr_chunk = chunk_create(value.ptr + i*UNITY_NETWORK_LEN, 4); ! 660: addr = host_create_from_chunk(AF_INET, addr_chunk, 0); ! 661: mask_chunk = chunk_create(addr_chunk.ptr + 4, 4); ! 662: mask = host_create_from_chunk(AF_INET, mask_chunk, 0); ! 663: printf("%s%H/%H", (i > 0) ? "," : " ", addr, mask); ! 664: addr->destroy(addr); ! 665: mask->destroy(mask); ! 666: } ! 667: printf("\n"); ! 668: } ! 669: else ! 670: { ! 671: /* value cannot be represented as a list of subnets */ ! 672: printf(" %#B\n", &value); ! 673: } ! 674: break; ! 675: case VALUE_STRING: ! 676: printf("\"%.*s\"\n", (int)value.len, value.ptr); ! 677: break; ! 678: case VALUE_HEX: ! 679: default: ! 680: printf(" %#B\n", &value); ! 681: } ! 682: } ! 683: enumerator->destroy(enumerator); ! 684: } ! 685: } ! 686: ! 687: /** ! 688: * ipsec pool --showattr - show all supported attribute keywords ! 689: */ ! 690: void show_attr(void) ! 691: { ! 692: int i; ! 693: ! 694: for (i = 0; i < countof(attr_info); i++) ! 695: { ! 696: char value_name[10]; ! 697: ! 698: ! 699: snprintf(value_name, sizeof(value_name), "%N", ! 700: value_type_names, attr_info[i].value_type); ! 701: ! 702: printf("%-20s --%-6s (%N", ! 703: attr_info[i].keyword, value_name, ! 704: configuration_attribute_type_names, attr_info[i].type); ! 705: ! 706: if (attr_info[i].type_ip6) ! 707: { ! 708: printf(", %N)\n", ! 709: configuration_attribute_type_names, attr_info[i].type_ip6); ! 710: } ! 711: else ! 712: { ! 713: printf(")\n"); ! 714: } ! 715: } ! 716: }