Home | History | Annotate | Download | only in libxtables
      1 /*
      2  *	Argument parser
      3  *	Copyright  Jan Engelhardt, 2011
      4  *
      5  *	This program is free software; you can redistribute it and/or
      6  *	modify it under the terms of the GNU General Public License as
      7  *	published by the Free Software Foundation; either version 2 of
      8  *	the License, or (at your option) any later version.
      9  */
     10 #include <ctype.h>
     11 #include <errno.h>
     12 #include <getopt.h>
     13 #include <limits.h>
     14 #include <netdb.h>
     15 #include <stdbool.h>
     16 #include <stdint.h>
     17 #include <stdio.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 #include <syslog.h>
     21 #include <arpa/inet.h>
     22 #include <netinet/ip.h>
     23 #include "xtables.h"
     24 #include "xshared.h"
     25 #ifndef IPTOS_NORMALSVC
     26 #	define IPTOS_NORMALSVC 0
     27 #endif
     28 
     29 #define XTOPT_MKPTR(cb) \
     30 	((void *)((char *)(cb)->data + (cb)->entry->ptroff))
     31 
     32 /**
     33  * Simple key-value pairs for syslog levels
     34  */
     35 struct syslog_level {
     36 	char name[8];
     37 	uint8_t level;
     38 };
     39 
     40 struct tos_value_mask {
     41 	uint8_t value, mask;
     42 };
     43 
     44 static const size_t xtopt_psize[] = {
     45 	/*
     46 	 * All types not listed here, and thus essentially being initialized to
     47 	 * zero have zero on purpose.
     48 	 */
     49 	[XTTYPE_UINT8]       = sizeof(uint8_t),
     50 	[XTTYPE_UINT16]      = sizeof(uint16_t),
     51 	[XTTYPE_UINT32]      = sizeof(uint32_t),
     52 	[XTTYPE_UINT64]      = sizeof(uint64_t),
     53 	[XTTYPE_UINT8RC]     = sizeof(uint8_t[2]),
     54 	[XTTYPE_UINT16RC]    = sizeof(uint16_t[2]),
     55 	[XTTYPE_UINT32RC]    = sizeof(uint32_t[2]),
     56 	[XTTYPE_UINT64RC]    = sizeof(uint64_t[2]),
     57 	[XTTYPE_DOUBLE]      = sizeof(double),
     58 	[XTTYPE_STRING]      = -1,
     59 	[XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t),
     60 	[XTTYPE_HOST]        = sizeof(union nf_inet_addr),
     61 	[XTTYPE_HOSTMASK]    = sizeof(union nf_inet_addr),
     62 	[XTTYPE_PROTOCOL]    = sizeof(uint8_t),
     63 	[XTTYPE_PORT]        = sizeof(uint16_t),
     64 	[XTTYPE_PORTRC]      = sizeof(uint16_t[2]),
     65 	[XTTYPE_PLENMASK]    = sizeof(union nf_inet_addr),
     66 	[XTTYPE_ETHERMAC]    = sizeof(uint8_t[6]),
     67 };
     68 
     69 /**
     70  * Creates getopt options from the x6-style option map, and assigns each a
     71  * getopt id.
     72  */
     73 struct option *
     74 xtables_options_xfrm(struct option *orig_opts, struct option *oldopts,
     75 		     const struct xt_option_entry *entry, unsigned int *offset)
     76 {
     77 	unsigned int num_orig, num_old = 0, num_new, i;
     78 	struct option *merge, *mp;
     79 
     80 	if (entry == NULL)
     81 		return oldopts;
     82 	for (num_orig = 0; orig_opts[num_orig].name != NULL; ++num_orig)
     83 		;
     84 	if (oldopts != NULL)
     85 		for (num_old = 0; oldopts[num_old].name != NULL; ++num_old)
     86 			;
     87 	for (num_new = 0; entry[num_new].name != NULL; ++num_new)
     88 		;
     89 
     90 	/*
     91 	 * Since @oldopts also has @orig_opts already (and does so at the
     92 	 * start), skip these entries.
     93 	 */
     94 	oldopts += num_orig;
     95 	num_old -= num_orig;
     96 
     97 	merge = malloc(sizeof(*mp) * (num_orig + num_old + num_new + 1));
     98 	if (merge == NULL)
     99 		return NULL;
    100 
    101 	/* Let the base options -[ADI...] have precedence over everything */
    102 	memcpy(merge, orig_opts, sizeof(*mp) * num_orig);
    103 	mp = merge + num_orig;
    104 
    105 	/* Second, the new options */
    106 	xt_params->option_offset += XT_OPTION_OFFSET_SCALE;
    107 	*offset = xt_params->option_offset;
    108 
    109 	for (i = 0; i < num_new; ++i, ++mp, ++entry) {
    110 		mp->name         = entry->name;
    111 		mp->has_arg      = entry->type != XTTYPE_NONE;
    112 		mp->flag         = NULL;
    113 		mp->val          = entry->id + *offset;
    114 	}
    115 
    116 	/* Third, the old options */
    117 	memcpy(mp, oldopts, sizeof(*mp) * num_old);
    118 	mp += num_old;
    119 	xtables_free_opts(0);
    120 
    121 	/* Clear trailing entry */
    122 	memset(mp, 0, sizeof(*mp));
    123 	return merge;
    124 }
    125 
    126 /**
    127  * Give the upper limit for a certain type.
    128  */
    129 static uintmax_t xtopt_max_by_type(enum xt_option_type type)
    130 {
    131 	switch (type) {
    132 	case XTTYPE_UINT8:
    133 	case XTTYPE_UINT8RC:
    134 		return UINT8_MAX;
    135 	case XTTYPE_UINT16:
    136 	case XTTYPE_UINT16RC:
    137 		return UINT16_MAX;
    138 	case XTTYPE_UINT32:
    139 	case XTTYPE_UINT32RC:
    140 		return UINT32_MAX;
    141 	case XTTYPE_UINT64:
    142 	case XTTYPE_UINT64RC:
    143 		return UINT64_MAX;
    144 	default:
    145 		return 0;
    146 	}
    147 }
    148 
    149 /**
    150  * Return the size of a single entity based upon a type - predominantly an
    151  * XTTYPE_UINT*RC type.
    152  */
    153 static size_t xtopt_esize_by_type(enum xt_option_type type)
    154 {
    155 	switch (type) {
    156 	case XTTYPE_UINT8RC:
    157 		return xtopt_psize[XTTYPE_UINT8];
    158 	case XTTYPE_UINT16RC:
    159 		return xtopt_psize[XTTYPE_UINT16];
    160 	case XTTYPE_UINT32RC:
    161 		return xtopt_psize[XTTYPE_UINT32];
    162 	case XTTYPE_UINT64RC:
    163 		return xtopt_psize[XTTYPE_UINT64];
    164 	default:
    165 		return xtopt_psize[type];
    166 	}
    167 }
    168 
    169 /**
    170  * Require a simple integer.
    171  */
    172 static void xtopt_parse_int(struct xt_option_call *cb)
    173 {
    174 	const struct xt_option_entry *entry = cb->entry;
    175 	uintmax_t lmin = 0, lmax = xtopt_max_by_type(entry->type);
    176 	uintmax_t value;
    177 
    178 	if (cb->entry->min != 0)
    179 		lmin = cb->entry->min;
    180 	if (cb->entry->max != 0)
    181 		lmax = cb->entry->max;
    182 
    183 	if (!xtables_strtoul(cb->arg, NULL, &value, lmin, lmax))
    184 		xt_params->exit_err(PARAMETER_PROBLEM,
    185 			"%s: bad value for option \"--%s\", "
    186 			"or out of range (%ju-%ju).\n",
    187 			cb->ext_name, entry->name, lmin, lmax);
    188 
    189 	if (entry->type == XTTYPE_UINT8) {
    190 		cb->val.u8 = value;
    191 		if (entry->flags & XTOPT_PUT)
    192 			*(uint8_t *)XTOPT_MKPTR(cb) = cb->val.u8;
    193 	} else if (entry->type == XTTYPE_UINT16) {
    194 		cb->val.u16 = value;
    195 		if (entry->flags & XTOPT_PUT)
    196 			*(uint16_t *)XTOPT_MKPTR(cb) = cb->val.u16;
    197 	} else if (entry->type == XTTYPE_UINT32) {
    198 		cb->val.u32 = value;
    199 		if (entry->flags & XTOPT_PUT)
    200 			*(uint32_t *)XTOPT_MKPTR(cb) = cb->val.u32;
    201 	} else if (entry->type == XTTYPE_UINT64) {
    202 		cb->val.u64 = value;
    203 		if (entry->flags & XTOPT_PUT)
    204 			*(uint64_t *)XTOPT_MKPTR(cb) = cb->val.u64;
    205 	}
    206 }
    207 
    208 /**
    209  * Require a simple floating point number.
    210  */
    211 static void xtopt_parse_float(struct xt_option_call *cb)
    212 {
    213 	const struct xt_option_entry *entry = cb->entry;
    214 	double value;
    215 	char *end;
    216 
    217 	value = strtod(cb->arg, &end);
    218 	if (end == cb->arg || *end != '\0' ||
    219 	    (entry->min != entry->max &&
    220 	    (value < entry->min || value > entry->max)))
    221 		xt_params->exit_err(PARAMETER_PROBLEM,
    222 			"%s: bad value for option \"--%s\", "
    223 			"or out of range (%u-%u).\n",
    224 			cb->ext_name, entry->name, entry->min, entry->max);
    225 
    226 	cb->val.dbl = value;
    227 	if (entry->flags & XTOPT_PUT)
    228 		*(double *)XTOPT_MKPTR(cb) = cb->val.dbl;
    229 }
    230 
    231 /**
    232  * Copy the parsed value to the appropriate entry in cb->val.
    233  */
    234 static void xtopt_mint_value_to_cb(struct xt_option_call *cb, uintmax_t value)
    235 {
    236 	const struct xt_option_entry *entry = cb->entry;
    237 
    238 	if (cb->nvals >= ARRAY_SIZE(cb->val.u32_range))
    239 		return;
    240 	if (entry->type == XTTYPE_UINT8RC)
    241 		cb->val.u8_range[cb->nvals] = value;
    242 	else if (entry->type == XTTYPE_UINT16RC)
    243 		cb->val.u16_range[cb->nvals] = value;
    244 	else if (entry->type == XTTYPE_UINT32RC)
    245 		cb->val.u32_range[cb->nvals] = value;
    246 	else if (entry->type == XTTYPE_UINT64RC)
    247 		cb->val.u64_range[cb->nvals] = value;
    248 }
    249 
    250 /**
    251  * Copy the parsed value to the data area, using appropriate type access.
    252  */
    253 static void xtopt_mint_value_to_ptr(struct xt_option_call *cb, void **datap,
    254 				    uintmax_t value)
    255 {
    256 	const struct xt_option_entry *entry = cb->entry;
    257 	void *data = *datap;
    258 
    259 	if (!(entry->flags & XTOPT_PUT))
    260 		return;
    261 	if (entry->type == XTTYPE_UINT8RC)
    262 		*(uint8_t *)data = value;
    263 	else if (entry->type == XTTYPE_UINT16RC)
    264 		*(uint16_t *)data = value;
    265 	else if (entry->type == XTTYPE_UINT32RC)
    266 		*(uint32_t *)data = value;
    267 	else if (entry->type == XTTYPE_UINT64RC)
    268 		*(uint64_t *)data = value;
    269 	data += xtopt_esize_by_type(entry->type);
    270 	*datap = data;
    271 }
    272 
    273 /**
    274  * Multiple integer parse routine.
    275  *
    276  * This function is capable of parsing any number of fields. Only the first
    277  * two values from the string will be put into @cb however (and as such,
    278  * @cb->val.uXX_range is just that large) to cater for the few extensions that
    279  * do not have a range[2] field, but {min, max}, and which cannot use
    280  * XTOPT_POINTER.
    281  */
    282 static void xtopt_parse_mint(struct xt_option_call *cb)
    283 {
    284 	const struct xt_option_entry *entry = cb->entry;
    285 	const char *arg = cb->arg;
    286 	size_t esize = xtopt_esize_by_type(entry->type);
    287 	const uintmax_t lmax = xtopt_max_by_type(entry->type);
    288 	void *put = XTOPT_MKPTR(cb);
    289 	unsigned int maxiter;
    290 	uintmax_t value;
    291 	char *end = "";
    292 	char sep = ':';
    293 
    294 	maxiter = entry->size / esize;
    295 	if (maxiter == 0)
    296 		maxiter = ARRAY_SIZE(cb->val.u32_range);
    297 	if (entry->size % esize != 0)
    298 		xt_params->exit_err(OTHER_PROBLEM, "%s: memory block does "
    299 			"not have proper size\n", __func__);
    300 
    301 	cb->nvals = 0;
    302 	for (arg = cb->arg, end = (char *)arg; ; arg = end + 1) {
    303 		if (cb->nvals == maxiter)
    304 			xt_params->exit_err(PARAMETER_PROBLEM, "%s: Too many "
    305 				"components for option \"--%s\" (max: %u)\n",
    306 				cb->ext_name, entry->name, maxiter);
    307 		if (*arg == '\0' || *arg == sep) {
    308 			/* Default range components when field not spec'd. */
    309 			end = (char *)arg;
    310 			value = (cb->nvals == 1) ? lmax : 0;
    311 		} else {
    312 			if (!xtables_strtoul(arg, &end, &value, 0, lmax))
    313 				xt_params->exit_err(PARAMETER_PROBLEM,
    314 					"%s: bad value for option \"--%s\" near "
    315 					"\"%s\", or out of range (0-%ju).\n",
    316 					cb->ext_name, entry->name, arg, lmax);
    317 			if (*end != '\0' && *end != sep)
    318 				xt_params->exit_err(PARAMETER_PROBLEM,
    319 					"%s: Argument to \"--%s\" has "
    320 					"unexpected characters near \"%s\".\n",
    321 					cb->ext_name, entry->name, end);
    322 		}
    323 		xtopt_mint_value_to_cb(cb, value);
    324 		++cb->nvals;
    325 		xtopt_mint_value_to_ptr(cb, &put, value);
    326 		if (*end == '\0')
    327 			break;
    328 	}
    329 }
    330 
    331 static void xtopt_parse_string(struct xt_option_call *cb)
    332 {
    333 	const struct xt_option_entry *entry = cb->entry;
    334 	size_t z = strlen(cb->arg);
    335 	char *p;
    336 
    337 	if (entry->min != 0 && z < entry->min)
    338 		xt_params->exit_err(PARAMETER_PROBLEM,
    339 			"Argument must have a minimum length of "
    340 			"%u characters\n", entry->min);
    341 	if (entry->max != 0 && z > entry->max)
    342 		xt_params->exit_err(PARAMETER_PROBLEM,
    343 			"Argument must have a maximum length of "
    344 			"%u characters\n", entry->max);
    345 	if (!(entry->flags & XTOPT_PUT))
    346 		return;
    347 	if (z >= entry->size)
    348 		z = entry->size - 1;
    349 	p = XTOPT_MKPTR(cb);
    350 	strncpy(p, cb->arg, z);
    351 	p[z] = '\0';
    352 }
    353 
    354 static const struct tos_symbol_info {
    355 	unsigned char value;
    356 	const char *name;
    357 } tos_symbol_names[] = {
    358 	{IPTOS_LOWDELAY,    "Minimize-Delay"},
    359 	{IPTOS_THROUGHPUT,  "Maximize-Throughput"},
    360 	{IPTOS_RELIABILITY, "Maximize-Reliability"},
    361 	{IPTOS_MINCOST,     "Minimize-Cost"},
    362 	{IPTOS_NORMALSVC,   "Normal-Service"},
    363 	{},
    364 };
    365 
    366 /*
    367  * tos_parse_numeric - parse a string like "15/255"
    368  *
    369  * @str:	input string
    370  * @tvm:	(value/mask) tuple
    371  * @max:	maximum allowed value (must be pow(2,some_int)-1)
    372  */
    373 static bool tos_parse_numeric(const char *str, struct xt_option_call *cb,
    374                               unsigned int max)
    375 {
    376 	unsigned int value;
    377 	char *end;
    378 
    379 	xtables_strtoui(str, &end, &value, 0, max);
    380 	cb->val.tos_value = value;
    381 	cb->val.tos_mask  = max;
    382 
    383 	if (*end == '/') {
    384 		const char *p = end + 1;
    385 
    386 		if (!xtables_strtoui(p, &end, &value, 0, max))
    387 			xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"",
    388 			           str);
    389 		cb->val.tos_mask = value;
    390 	}
    391 
    392 	if (*end != '\0')
    393 		xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", str);
    394 	return true;
    395 }
    396 
    397 /**
    398  * @str:	input string
    399  * @tvm:	(value/mask) tuple
    400  * @def_mask:	mask to force when a symbolic name is used
    401  */
    402 static void xtopt_parse_tosmask(struct xt_option_call *cb)
    403 {
    404 	const struct tos_symbol_info *symbol;
    405 	char *tmp;
    406 
    407 	if (xtables_strtoui(cb->arg, &tmp, NULL, 0, UINT8_MAX)) {
    408 		tos_parse_numeric(cb->arg, cb, UINT8_MAX);
    409 		return;
    410 	}
    411 	/*
    412 	 * This is our way we deal with different defaults
    413 	 * for different revisions.
    414 	 */
    415 	cb->val.tos_mask = cb->entry->max;
    416 	for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
    417 		if (strcasecmp(cb->arg, symbol->name) == 0) {
    418 			cb->val.tos_value = symbol->value;
    419 			return;
    420 		}
    421 
    422 	xtables_error(PARAMETER_PROBLEM, "Symbolic name \"%s\" is unknown",
    423 		      cb->arg);
    424 }
    425 
    426 /**
    427  * Validate the input for being conformant to "mark[/mask]".
    428  */
    429 static void xtopt_parse_markmask(struct xt_option_call *cb)
    430 {
    431 	unsigned int mark = 0, mask = ~0U;
    432 	char *end;
    433 
    434 	if (!xtables_strtoui(cb->arg, &end, &mark, 0, UINT32_MAX))
    435 		xt_params->exit_err(PARAMETER_PROBLEM,
    436 			"%s: bad mark value for option \"--%s\", "
    437 			"or out of range.\n",
    438 			cb->ext_name, cb->entry->name);
    439 	if (*end == '/' &&
    440 	    !xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
    441 		xt_params->exit_err(PARAMETER_PROBLEM,
    442 			"%s: bad mask value for option \"--%s\", "
    443 			"or out of range.\n",
    444 			cb->ext_name, cb->entry->name);
    445 	if (*end != '\0')
    446 		xt_params->exit_err(PARAMETER_PROBLEM,
    447 			"%s: trailing garbage after value "
    448 			"for option \"--%s\".\n",
    449 			cb->ext_name, cb->entry->name);
    450 	cb->val.mark = mark;
    451 	cb->val.mask = mask;
    452 }
    453 
    454 static int xtopt_sysloglvl_compare(const void *a, const void *b)
    455 {
    456 	const char *name = a;
    457 	const struct syslog_level *entry = b;
    458 
    459 	return strcmp(name, entry->name);
    460 }
    461 
    462 static void xtopt_parse_sysloglevel(struct xt_option_call *cb)
    463 {
    464 	static const struct syslog_level log_names[] = { /* must be sorted */
    465 		{"alert",   LOG_ALERT},
    466 		{"crit",    LOG_CRIT},
    467 		{"debug",   LOG_DEBUG},
    468 		{"emerg",   LOG_EMERG},
    469 		{"error",   LOG_ERR}, /* deprecated */
    470 		{"info",    LOG_INFO},
    471 		{"notice",  LOG_NOTICE},
    472 		{"panic",   LOG_EMERG}, /* deprecated */
    473 		{"warning", LOG_WARNING},
    474 	};
    475 	const struct syslog_level *e;
    476 	unsigned int num = 0;
    477 
    478 	if (!xtables_strtoui(cb->arg, NULL, &num, 0, 7)) {
    479 		e = bsearch(cb->arg, log_names, ARRAY_SIZE(log_names),
    480 			    sizeof(*log_names), xtopt_sysloglvl_compare);
    481 		if (e == NULL)
    482 			xt_params->exit_err(PARAMETER_PROBLEM,
    483 				"log level \"%s\" unknown\n", cb->arg);
    484 		num = e->level;
    485 	}
    486 	cb->val.syslog_level = num;
    487 	if (cb->entry->flags & XTOPT_PUT)
    488 		*(uint8_t *)XTOPT_MKPTR(cb) = num;
    489 }
    490 
    491 static void *xtables_sa_host(const void *sa, unsigned int afproto)
    492 {
    493 	if (afproto == AF_INET6)
    494 		return &((struct sockaddr_in6 *)sa)->sin6_addr;
    495 	else if (afproto == AF_INET)
    496 		return &((struct sockaddr_in *)sa)->sin_addr;
    497 	return (void *)sa;
    498 }
    499 
    500 static socklen_t xtables_sa_hostlen(unsigned int afproto)
    501 {
    502 	if (afproto == AF_INET6)
    503 		return sizeof(struct in6_addr);
    504 	else if (afproto == AF_INET)
    505 		return sizeof(struct in_addr);
    506 	return 0;
    507 }
    508 
    509 /**
    510  * Accepts: a hostname (DNS), or a single inetaddr - without any mask. The
    511  * result is stored in @cb->val.haddr. Additionally, @cb->val.hmask and
    512  * @cb->val.hlen are set for completeness to the appropriate values.
    513  */
    514 static void xtopt_parse_host(struct xt_option_call *cb)
    515 {
    516 	struct addrinfo hints = {.ai_family = afinfo->family};
    517 	unsigned int adcount = 0;
    518 	struct addrinfo *res, *p;
    519 	int ret;
    520 
    521 	ret = getaddrinfo(cb->arg, NULL, &hints, &res);
    522 	if (ret != 0)
    523 		xt_params->exit_err(PARAMETER_PROBLEM,
    524 			"getaddrinfo: %s\n", gai_strerror(ret));
    525 
    526 	memset(&cb->val.hmask, 0xFF, sizeof(cb->val.hmask));
    527 	cb->val.hlen = (afinfo->family == NFPROTO_IPV4) ? 32 : 128;
    528 
    529 	for (p = res; p != NULL; p = p->ai_next) {
    530 		if (adcount == 0) {
    531 			memset(&cb->val.haddr, 0, sizeof(cb->val.haddr));
    532 			memcpy(&cb->val.haddr,
    533 			       xtables_sa_host(p->ai_addr, p->ai_family),
    534 			       xtables_sa_hostlen(p->ai_family));
    535 			++adcount;
    536 			continue;
    537 		}
    538 		if (memcmp(&cb->val.haddr,
    539 		    xtables_sa_host(p->ai_addr, p->ai_family),
    540 		    xtables_sa_hostlen(p->ai_family)) != 0)
    541 			xt_params->exit_err(PARAMETER_PROBLEM,
    542 				"%s resolves to more than one address\n",
    543 				cb->arg);
    544 	}
    545 
    546 	freeaddrinfo(res);
    547 	if (cb->entry->flags & XTOPT_PUT)
    548 		/* Validation in xtables_option_metavalidate */
    549 		memcpy(XTOPT_MKPTR(cb), &cb->val.haddr,
    550 		       sizeof(cb->val.haddr));
    551 }
    552 
    553 /**
    554  * @name:	port name, or number as a string (e.g. "http" or "80")
    555  *
    556  * Resolve a port name to a number. Returns the port number in integral
    557  * form on success, or <0 on error. (errno will not be set.)
    558  */
    559 static int xtables_getportbyname(const char *name)
    560 {
    561 	struct addrinfo *res = NULL, *p;
    562 	int ret;
    563 
    564 	ret = getaddrinfo(NULL, name, NULL, &res);
    565 	if (ret != 0)
    566 		return -1;
    567 	ret = -1;
    568 	for (p = res; p != NULL; p = p->ai_next) {
    569 		if (p->ai_family == AF_INET6) {
    570 			ret = ((struct sockaddr_in6 *)p->ai_addr)->sin6_port;
    571 			break;
    572 		} else if (p->ai_family == AF_INET) {
    573 			ret = ((struct sockaddr_in *)p->ai_addr)->sin_port;
    574 			break;
    575 		}
    576 	}
    577 	freeaddrinfo(res);
    578 	if (ret < 0)
    579 		return ret;
    580 	return ntohs(ret);
    581 }
    582 
    583 /**
    584  * Validate and parse a protocol specification (number or name) by use of
    585  * /etc/protocols and put the result into @cb->val.protocol.
    586  */
    587 static void xtopt_parse_protocol(struct xt_option_call *cb)
    588 {
    589 	cb->val.protocol = xtables_parse_protocol(cb->arg);
    590 	if (cb->entry->flags & XTOPT_PUT)
    591 		*(uint8_t *)XTOPT_MKPTR(cb) = cb->val.protocol;
    592 }
    593 
    594 /**
    595  * Validate and parse a port specification and put the result into
    596  * @cb->val.port.
    597  */
    598 static void xtopt_parse_port(struct xt_option_call *cb)
    599 {
    600 	const struct xt_option_entry *entry = cb->entry;
    601 	int ret;
    602 
    603 	ret = xtables_getportbyname(cb->arg);
    604 	if (ret < 0)
    605 		xt_params->exit_err(PARAMETER_PROBLEM,
    606 			"Port \"%s\" does not resolve to anything.\n",
    607 			cb->arg);
    608 	if (entry->flags & XTOPT_NBO)
    609 		ret = htons(ret);
    610 	cb->val.port = ret;
    611 	if (entry->flags & XTOPT_PUT)
    612 		*(uint16_t *)XTOPT_MKPTR(cb) = cb->val.port;
    613 }
    614 
    615 static void xtopt_parse_mport(struct xt_option_call *cb)
    616 {
    617 	static const size_t esize = sizeof(uint16_t);
    618 	const struct xt_option_entry *entry = cb->entry;
    619 	char *lo_arg, *wp_arg, *arg;
    620 	unsigned int maxiter;
    621 	int value;
    622 
    623 	wp_arg = lo_arg = strdup(cb->arg);
    624 	if (lo_arg == NULL)
    625 		xt_params->exit_err(RESOURCE_PROBLEM, "strdup");
    626 
    627 	maxiter = entry->size / esize;
    628 	if (maxiter == 0)
    629 		maxiter = 2; /* ARRAY_SIZE(cb->val.port_range) */
    630 	if (entry->size % esize != 0)
    631 		xt_params->exit_err(OTHER_PROBLEM, "%s: memory block does "
    632 			"not have proper size\n", __func__);
    633 
    634 	cb->val.port_range[0] = 0;
    635 	cb->val.port_range[1] = UINT16_MAX;
    636 	cb->nvals = 0;
    637 
    638 	while ((arg = strsep(&wp_arg, ":")) != NULL) {
    639 		if (cb->nvals == maxiter)
    640 			xt_params->exit_err(PARAMETER_PROBLEM, "%s: Too many "
    641 				"components for option \"--%s\" (max: %u)\n",
    642 				cb->ext_name, entry->name, maxiter);
    643 		if (*arg == '\0') {
    644 			++cb->nvals;
    645 			continue;
    646 		}
    647 
    648 		value = xtables_getportbyname(arg);
    649 		if (value < 0)
    650 			xt_params->exit_err(PARAMETER_PROBLEM,
    651 				"Port \"%s\" does not resolve to "
    652 				"anything.\n", arg);
    653 		if (entry->flags & XTOPT_NBO)
    654 			value = htons(value);
    655 		if (cb->nvals < ARRAY_SIZE(cb->val.port_range))
    656 			cb->val.port_range[cb->nvals] = value;
    657 		++cb->nvals;
    658 	}
    659 
    660 	if (cb->nvals == 1) {
    661 		cb->val.port_range[1] = cb->val.port_range[0];
    662 		++cb->nvals;
    663 	}
    664 	if (entry->flags & XTOPT_PUT)
    665 		memcpy(XTOPT_MKPTR(cb), cb->val.port_range, sizeof(uint16_t) *
    666 		       (cb->nvals <= maxiter ? cb->nvals : maxiter));
    667 	free(lo_arg);
    668 }
    669 
    670 static int xtopt_parse_mask(struct xt_option_call *cb)
    671 {
    672 	struct addrinfo hints = {.ai_family = afinfo->family,
    673 				 .ai_flags = AI_NUMERICHOST };
    674 	struct addrinfo *res;
    675 	int ret;
    676 
    677 	ret = getaddrinfo(cb->arg, NULL, &hints, &res);
    678 	if (ret != 0)
    679 		return 0;
    680 
    681 	memcpy(&cb->val.hmask, xtables_sa_host(res->ai_addr, res->ai_family),
    682 	       xtables_sa_hostlen(res->ai_family));
    683 
    684 	switch(afinfo->family) {
    685 	case AF_INET:
    686 		cb->val.hlen = xtables_ipmask_to_cidr(&cb->val.hmask.in);
    687 		break;
    688 	case AF_INET6:
    689 		cb->val.hlen = xtables_ip6mask_to_cidr(&cb->val.hmask.in6);
    690 		break;
    691 	}
    692 
    693 	freeaddrinfo(res);
    694 	return 1;
    695 }
    696 
    697 /**
    698  * Parse an integer and ensure it is within the address family's prefix length
    699  * limits. The result is stored in @cb->val.hlen.
    700  */
    701 static void xtopt_parse_plen(struct xt_option_call *cb)
    702 {
    703 	const struct xt_option_entry *entry = cb->entry;
    704 	unsigned int prefix_len = 128; /* happiness is a warm gcc */
    705 
    706 	cb->val.hlen = (afinfo->family == NFPROTO_IPV4) ? 32 : 128;
    707 	if (!xtables_strtoui(cb->arg, NULL, &prefix_len, 0, cb->val.hlen)) {
    708 		/* Is this mask expressed in full format? e.g. 255.255.255.0 */
    709 		if (xtopt_parse_mask(cb))
    710 			return;
    711 
    712 		xt_params->exit_err(PARAMETER_PROBLEM,
    713 			"%s: bad value for option \"--%s\", "
    714 			"neither a valid network mask "
    715 			"nor valid CIDR (%u-%u).\n",
    716 			cb->ext_name, entry->name, 0, cb->val.hlen);
    717 	}
    718 	cb->val.hlen = prefix_len;
    719 }
    720 
    721 /**
    722  * Reuse xtopt_parse_plen for testing the integer. Afterwards convert this to
    723  * a bitmask, and make it available through @cb->val.hmask (hlen remains
    724  * valid). If %XTOPT_PUT is used, hmask will be copied to the target area.
    725  */
    726 static void xtopt_parse_plenmask(struct xt_option_call *cb)
    727 {
    728 	const struct xt_option_entry *entry = cb->entry;
    729 	uint32_t *mask = cb->val.hmask.all;
    730 
    731 	xtopt_parse_plen(cb);
    732 
    733 	memset(mask, 0xFF, sizeof(union nf_inet_addr));
    734 	/* This shifting is AF-independent. */
    735 	if (cb->val.hlen == 0) {
    736 		mask[0] = mask[1] = mask[2] = mask[3] = 0;
    737 	} else if (cb->val.hlen <= 32) {
    738 		mask[0] <<= 32 - cb->val.hlen;
    739 		mask[1] = mask[2] = mask[3] = 0;
    740 	} else if (cb->val.hlen <= 64) {
    741 		mask[1] <<= 32 - (cb->val.hlen - 32);
    742 		mask[2] = mask[3] = 0;
    743 	} else if (cb->val.hlen <= 96) {
    744 		mask[2] <<= 32 - (cb->val.hlen - 64);
    745 		mask[3] = 0;
    746 	} else if (cb->val.hlen <= 128) {
    747 		mask[3] <<= 32 - (cb->val.hlen - 96);
    748 	}
    749 	mask[0] = htonl(mask[0]);
    750 	mask[1] = htonl(mask[1]);
    751 	mask[2] = htonl(mask[2]);
    752 	mask[3] = htonl(mask[3]);
    753 	if (entry->flags & XTOPT_PUT)
    754 		memcpy(XTOPT_MKPTR(cb), mask, sizeof(union nf_inet_addr));
    755 }
    756 
    757 static void xtopt_parse_hostmask(struct xt_option_call *cb)
    758 {
    759 	const char *orig_arg = cb->arg;
    760 	char *work, *p;
    761 
    762 	if (strchr(cb->arg, '/') == NULL) {
    763 		xtopt_parse_host(cb);
    764 		return;
    765 	}
    766 	work = strdup(orig_arg);
    767 	if (work == NULL)
    768 		xt_params->exit_err(PARAMETER_PROBLEM, "strdup");
    769 	p = strchr(work, '/'); /* by def this can't be NULL now */
    770 	*p++ = '\0';
    771 	/*
    772 	 * Because xtopt_parse_host and xtopt_parse_plenmask would store
    773 	 * different things in the same target area, XTTYPE_HOSTMASK must
    774 	 * disallow XTOPT_PUT, which it does by forcing its absence,
    775 	 * cf. not being listed in xtopt_psize.
    776 	 */
    777 	cb->arg = work;
    778 	xtopt_parse_host(cb);
    779 	cb->arg = p;
    780 	xtopt_parse_plenmask(cb);
    781 	cb->arg = orig_arg;
    782 }
    783 
    784 static void xtopt_parse_ethermac(struct xt_option_call *cb)
    785 {
    786 	const char *arg = cb->arg;
    787 	unsigned int i;
    788 	char *end;
    789 
    790 	for (i = 0; i < ARRAY_SIZE(cb->val.ethermac) - 1; ++i) {
    791 		cb->val.ethermac[i] = strtoul(arg, &end, 16);
    792 		if (*end != ':' || end - arg > 2)
    793 			goto out;
    794 		arg = end + 1;
    795 	}
    796 	i = ARRAY_SIZE(cb->val.ethermac) - 1;
    797 	cb->val.ethermac[i] = strtoul(arg, &end, 16);
    798 	if (*end != '\0' || end - arg > 2)
    799 		goto out;
    800 	if (cb->entry->flags & XTOPT_PUT)
    801 		memcpy(XTOPT_MKPTR(cb), cb->val.ethermac,
    802 		       sizeof(cb->val.ethermac));
    803 	return;
    804  out:
    805 	xt_params->exit_err(PARAMETER_PROBLEM, "Invalid MAC address specified.");
    806 }
    807 
    808 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
    809 	[XTTYPE_UINT8]       = xtopt_parse_int,
    810 	[XTTYPE_UINT16]      = xtopt_parse_int,
    811 	[XTTYPE_UINT32]      = xtopt_parse_int,
    812 	[XTTYPE_UINT64]      = xtopt_parse_int,
    813 	[XTTYPE_UINT8RC]     = xtopt_parse_mint,
    814 	[XTTYPE_UINT16RC]    = xtopt_parse_mint,
    815 	[XTTYPE_UINT32RC]    = xtopt_parse_mint,
    816 	[XTTYPE_UINT64RC]    = xtopt_parse_mint,
    817 	[XTTYPE_DOUBLE]      = xtopt_parse_float,
    818 	[XTTYPE_STRING]      = xtopt_parse_string,
    819 	[XTTYPE_TOSMASK]     = xtopt_parse_tosmask,
    820 	[XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
    821 	[XTTYPE_SYSLOGLEVEL] = xtopt_parse_sysloglevel,
    822 	[XTTYPE_HOST]        = xtopt_parse_host,
    823 	[XTTYPE_HOSTMASK]    = xtopt_parse_hostmask,
    824 	[XTTYPE_PROTOCOL]    = xtopt_parse_protocol,
    825 	[XTTYPE_PORT]        = xtopt_parse_port,
    826 	[XTTYPE_PORTRC]      = xtopt_parse_mport,
    827 	[XTTYPE_PLEN]        = xtopt_parse_plen,
    828 	[XTTYPE_PLENMASK]    = xtopt_parse_plenmask,
    829 	[XTTYPE_ETHERMAC]    = xtopt_parse_ethermac,
    830 };
    831 
    832 /**
    833  * The master option parsing routine. May be used for the ".x6_parse"
    834  * function pointer in extensions if fully automatic parsing is desired.
    835  * It may be also called manually from a custom x6_parse function.
    836  */
    837 void xtables_option_parse(struct xt_option_call *cb)
    838 {
    839 	const struct xt_option_entry *entry = cb->entry;
    840 	unsigned int eflag = 1 << cb->entry->id;
    841 
    842 	/*
    843 	 * With {.id = P_FOO, .excl = P_FOO} we can have simple double-use
    844 	 * prevention. Though it turned out that this is too much typing (most
    845 	 * of the options are one-time use only), so now we also have
    846 	 * %XTOPT_MULTI.
    847 	 */
    848 	if ((!(entry->flags & XTOPT_MULTI) || (entry->excl & eflag)) &&
    849 	    cb->xflags & eflag)
    850 		xt_params->exit_err(PARAMETER_PROBLEM,
    851 			"%s: option \"--%s\" can only be used once.\n",
    852 			cb->ext_name, cb->entry->name);
    853 	if (cb->invert && !(entry->flags & XTOPT_INVERT))
    854 		xt_params->exit_err(PARAMETER_PROBLEM,
    855 			"%s: option \"--%s\" cannot be inverted.\n",
    856 			cb->ext_name, entry->name);
    857 	if (entry->type != XTTYPE_NONE && optarg == NULL)
    858 		xt_params->exit_err(PARAMETER_PROBLEM,
    859 			"%s: option \"--%s\" requires an argument.\n",
    860 			cb->ext_name, entry->name);
    861 	/*
    862 	 * Fill in fallback value for "nvals", in case an extension (as it
    863 	 * happened with libxt_conntrack.2) tries to read it, despite not using
    864 	 * a *RC option type.
    865 	 */
    866 	cb->nvals = 1;
    867 	if (entry->type <= ARRAY_SIZE(xtopt_subparse) &&
    868 	    xtopt_subparse[entry->type] != NULL)
    869 		xtopt_subparse[entry->type](cb);
    870 	/* Exclusion with other flags tested later in finalize. */
    871 	cb->xflags |= 1 << entry->id;
    872 }
    873 
    874 /**
    875  * Verifies that an extension's option map descriptor is valid, and ought to
    876  * be called right after the extension has been loaded, and before option
    877  * merging/xfrm.
    878  */
    879 void xtables_option_metavalidate(const char *name,
    880 				 const struct xt_option_entry *entry)
    881 {
    882 	for (; entry->name != NULL; ++entry) {
    883 		if (entry->id >= CHAR_BIT * sizeof(unsigned int) ||
    884 		    entry->id >= XT_OPTION_OFFSET_SCALE)
    885 			xt_params->exit_err(OTHER_PROBLEM,
    886 				"Extension %s uses invalid ID %u\n",
    887 				name, entry->id);
    888 		if (!(entry->flags & XTOPT_PUT)) {
    889 			if (entry->ptroff != 0)
    890 				xt_params->exit_err(OTHER_PROBLEM,
    891 					"%s: ptroff for \"--%s\" is non-"
    892 					"zero but no XTOPT_PUT is specified. "
    893 					"Oversight?", name, entry->name);
    894 			continue;
    895 		}
    896 		if (entry->type >= ARRAY_SIZE(xtopt_psize) ||
    897 		    xtopt_psize[entry->type] == 0)
    898 			xt_params->exit_err(OTHER_PROBLEM,
    899 				"%s: entry type of option \"--%s\" cannot be "
    900 				"combined with XTOPT_PUT\n",
    901 				name, entry->name);
    902 		if (xtopt_psize[entry->type] != -1 &&
    903 		    xtopt_psize[entry->type] != entry->size)
    904 			xt_params->exit_err(OTHER_PROBLEM,
    905 				"%s: option \"--%s\" points to a memory block "
    906 				"of wrong size (expected %zu, got %zu)\n",
    907 				name, entry->name,
    908 				xtopt_psize[entry->type], entry->size);
    909 	}
    910 }
    911 
    912 /**
    913  * Find an option entry by its id.
    914  */
    915 static const struct xt_option_entry *
    916 xtables_option_lookup(const struct xt_option_entry *entry, unsigned int id)
    917 {
    918 	for (; entry->name != NULL; ++entry)
    919 		if (entry->id == id)
    920 			return entry;
    921 	return NULL;
    922 }
    923 
    924 /**
    925  * @c:		getopt id (i.e. with offset)
    926  * @fw:		struct ipt_entry or ip6t_entry
    927  *
    928  * Dispatch arguments to the appropriate parse function, based upon the
    929  * extension's choice of API.
    930  */
    931 void xtables_option_tpcall(unsigned int c, char **argv, bool invert,
    932 			   struct xtables_target *t, void *fw)
    933 {
    934 	struct xt_option_call cb;
    935 
    936 	if (t->x6_parse == NULL) {
    937 		if (t->parse != NULL)
    938 			t->parse(c - t->option_offset, argv, invert,
    939 				 &t->tflags, fw, &t->t);
    940 		return;
    941 	}
    942 
    943 	c -= t->option_offset;
    944 	cb.entry = xtables_option_lookup(t->x6_options, c);
    945 	if (cb.entry == NULL)
    946 		xtables_error(OTHER_PROBLEM,
    947 			"Extension does not know id %u\n", c);
    948 	cb.arg      = optarg;
    949 	cb.invert   = invert;
    950 	cb.ext_name = t->name;
    951 	cb.data     = t->t->data;
    952 	cb.xflags   = t->tflags;
    953 	cb.target   = &t->t;
    954 	cb.xt_entry = fw;
    955 	cb.udata    = t->udata;
    956 	t->x6_parse(&cb);
    957 	t->tflags = cb.xflags;
    958 }
    959 
    960 /**
    961  * @c:		getopt id (i.e. with offset)
    962  * @fw:		struct ipt_entry or ip6t_entry
    963  *
    964  * Dispatch arguments to the appropriate parse function, based upon the
    965  * extension's choice of API.
    966  */
    967 void xtables_option_mpcall(unsigned int c, char **argv, bool invert,
    968 			   struct xtables_match *m, void *fw)
    969 {
    970 	struct xt_option_call cb;
    971 
    972 	if (m->x6_parse == NULL) {
    973 		if (m->parse != NULL)
    974 			m->parse(c - m->option_offset, argv, invert,
    975 				 &m->mflags, fw, &m->m);
    976 		return;
    977 	}
    978 
    979 	c -= m->option_offset;
    980 	cb.entry = xtables_option_lookup(m->x6_options, c);
    981 	if (cb.entry == NULL)
    982 		xtables_error(OTHER_PROBLEM,
    983 			"Extension does not know id %u\n", c);
    984 	cb.arg      = optarg;
    985 	cb.invert   = invert;
    986 	cb.ext_name = m->name;
    987 	cb.data     = m->m->data;
    988 	cb.xflags   = m->mflags;
    989 	cb.match    = &m->m;
    990 	cb.xt_entry = fw;
    991 	cb.udata    = m->udata;
    992 	m->x6_parse(&cb);
    993 	m->mflags = cb.xflags;
    994 }
    995 
    996 /**
    997  * @name:	name of extension
    998  * @entry:	current option (from all ext's entries) being validated
    999  * @xflags:	flags the extension has collected
   1000  * @i:		conflicting option (id) to test for
   1001  */
   1002 static void
   1003 xtables_option_fcheck2(const char *name, const struct xt_option_entry *entry,
   1004 		       const struct xt_option_entry *other,
   1005 		       unsigned int xflags)
   1006 {
   1007 	unsigned int ef = 1 << entry->id, of = 1 << other->id;
   1008 
   1009 	if (entry->also & of && !(xflags & of))
   1010 		xt_params->exit_err(PARAMETER_PROBLEM,
   1011 			"%s: option \"--%s\" also requires \"--%s\".\n",
   1012 			name, entry->name, other->name);
   1013 
   1014 	if (!(entry->excl & of))
   1015 		/* Use of entry does not collide with other option, good. */
   1016 		return;
   1017 	if ((xflags & (ef | of)) != (ef | of))
   1018 		/* Conflicting options were not used. */
   1019 		return;
   1020 
   1021 	xt_params->exit_err(PARAMETER_PROBLEM,
   1022 		"%s: option \"--%s\" cannot be used together with \"--%s\".\n",
   1023 		name, entry->name, other->name);
   1024 }
   1025 
   1026 /**
   1027  * @name:	name of extension
   1028  * @xflags:	accumulated flags
   1029  * @entry:	extension's option table
   1030  *
   1031  * Check that all option constraints have been met. This effectively replaces
   1032  * ->final_check of the older API.
   1033  */
   1034 void xtables_options_fcheck(const char *name, unsigned int xflags,
   1035 			    const struct xt_option_entry *table)
   1036 {
   1037 	const struct xt_option_entry *entry, *other;
   1038 	unsigned int i;
   1039 
   1040 	for (entry = table; entry->name != NULL; ++entry) {
   1041 		if (entry->flags & XTOPT_MAND &&
   1042 		    !(xflags & (1 << entry->id)))
   1043 			xt_params->exit_err(PARAMETER_PROBLEM,
   1044 				"%s: option \"--%s\" must be specified\n",
   1045 				name, entry->name);
   1046 		if (!(xflags & (1 << entry->id)))
   1047 			/* Not required, not specified, thus skip. */
   1048 			continue;
   1049 
   1050 		for (i = 0; i < CHAR_BIT * sizeof(entry->id); ++i) {
   1051 			if (entry->id == i)
   1052 				/*
   1053 				 * Avoid conflict with self. Multi-use check
   1054 				 * was done earlier in xtables_option_parse.
   1055 				 */
   1056 				continue;
   1057 			other = xtables_option_lookup(table, i);
   1058 			if (other == NULL)
   1059 				continue;
   1060 			xtables_option_fcheck2(name, entry, other, xflags);
   1061 		}
   1062 	}
   1063 }
   1064 
   1065 /**
   1066  * Dispatch arguments to the appropriate final_check function, based upon the
   1067  * extension's choice of API.
   1068  */
   1069 void xtables_option_tfcall(struct xtables_target *t)
   1070 {
   1071 	if (t->x6_fcheck != NULL) {
   1072 		struct xt_fcheck_call cb;
   1073 
   1074 		cb.ext_name = t->name;
   1075 		cb.data     = t->t->data;
   1076 		cb.xflags   = t->tflags;
   1077 		cb.udata    = t->udata;
   1078 		t->x6_fcheck(&cb);
   1079 	} else if (t->final_check != NULL) {
   1080 		t->final_check(t->tflags);
   1081 	}
   1082 	if (t->x6_options != NULL)
   1083 		xtables_options_fcheck(t->name, t->tflags, t->x6_options);
   1084 }
   1085 
   1086 /**
   1087  * Dispatch arguments to the appropriate final_check function, based upon the
   1088  * extension's choice of API.
   1089  */
   1090 void xtables_option_mfcall(struct xtables_match *m)
   1091 {
   1092 	if (m->x6_fcheck != NULL) {
   1093 		struct xt_fcheck_call cb;
   1094 
   1095 		cb.ext_name = m->name;
   1096 		cb.data     = m->m->data;
   1097 		cb.xflags   = m->mflags;
   1098 		cb.udata    = m->udata;
   1099 		m->x6_fcheck(&cb);
   1100 	} else if (m->final_check != NULL) {
   1101 		m->final_check(m->mflags);
   1102 	}
   1103 	if (m->x6_options != NULL)
   1104 		xtables_options_fcheck(m->name, m->mflags, m->x6_options);
   1105 }
   1106 
   1107 struct xtables_lmap *xtables_lmap_init(const char *file)
   1108 {
   1109 	struct xtables_lmap *lmap_head = NULL, *lmap_prev = NULL, *lmap_this;
   1110 	char buf[512];
   1111 	FILE *fp;
   1112 	char *cur, *nxt;
   1113 	int id;
   1114 
   1115 	fp = fopen(file, "re");
   1116 	if (fp == NULL)
   1117 		return NULL;
   1118 
   1119 	while (fgets(buf, sizeof(buf), fp) != NULL) {
   1120 		cur = buf;
   1121 		while (isspace(*cur))
   1122 			++cur;
   1123 		if (*cur == '#' || *cur == '\n' || *cur == '\0')
   1124 			continue;
   1125 
   1126 		/* iproute2 allows hex and dec format */
   1127 		errno = 0;
   1128 		id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) == 0 ? 16 : 10);
   1129 		if (nxt == cur || errno != 0)
   1130 			continue;
   1131 
   1132 		/* same boundaries as in iproute2 */
   1133 		if (id < 0 || id > 255)
   1134 			continue;
   1135 		cur = nxt;
   1136 
   1137 		if (!isspace(*cur))
   1138 			continue;
   1139 		while (isspace(*cur))
   1140 			++cur;
   1141 		if (*cur == '#' || *cur == '\n' || *cur == '\0')
   1142 			continue;
   1143 		nxt = cur;
   1144 		while (*nxt != '\0' && !isspace(*nxt))
   1145 			++nxt;
   1146 		if (nxt == cur)
   1147 			continue;
   1148 		*nxt = '\0';
   1149 
   1150 		/* found valid data */
   1151 		lmap_this = malloc(sizeof(*lmap_this));
   1152 		if (lmap_this == NULL) {
   1153 			perror("malloc");
   1154 			goto out;
   1155 		}
   1156 		lmap_this->id   = id;
   1157 		lmap_this->name = strdup(cur);
   1158 		if (lmap_this->name == NULL) {
   1159 			free(lmap_this);
   1160 			goto out;
   1161 		}
   1162 		lmap_this->next = NULL;
   1163 
   1164 		if (lmap_prev != NULL)
   1165 			lmap_prev->next = lmap_this;
   1166 		else
   1167 			lmap_head = lmap_this;
   1168 		lmap_prev = lmap_this;
   1169 	}
   1170 
   1171 	fclose(fp);
   1172 	return lmap_head;
   1173  out:
   1174 	fclose(fp);
   1175 	xtables_lmap_free(lmap_head);
   1176 	return NULL;
   1177 }
   1178 
   1179 void xtables_lmap_free(struct xtables_lmap *head)
   1180 {
   1181 	struct xtables_lmap *next;
   1182 
   1183 	for (; head != NULL; head = next) {
   1184 		next = head->next;
   1185 		free(head->name);
   1186 		free(head);
   1187 	}
   1188 }
   1189 
   1190 int xtables_lmap_name2id(const struct xtables_lmap *head, const char *name)
   1191 {
   1192 	for (; head != NULL; head = head->next)
   1193 		if (strcmp(head->name, name) == 0)
   1194 			return head->id;
   1195 	return -1;
   1196 }
   1197 
   1198 const char *xtables_lmap_id2name(const struct xtables_lmap *head, int id)
   1199 {
   1200 	for (; head != NULL; head = head->next)
   1201 		if (head->id == id)
   1202 			return head->name;
   1203 	return NULL;
   1204 }
   1205