File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / pool / pool_attributes.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:45 2020 UTC (4 years, 2 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    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: }

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