libip6t_hbh.c revision ae31bb6bac68f800a1e4b30cf2548dacaaf76102
12ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó/* Shared library add-on to ip6tables to add Hop-by-Hop and Dst headers support. */
22ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <stdio.h>
32ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <netdb.h>
42ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <string.h>
52ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <stdlib.h>
62ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <getopt.h>
72ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <errno.h>
82ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <ip6tables.h>
92ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó/*#include <linux/in6.h>*/
102ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <linux/netfilter_ipv6/ip6t_opts.h>
112ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <sys/types.h>
122ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <sys/socket.h>
132ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#include <arpa/inet.h>
142ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
152ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#define DEBUG		0
162ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#define HOPBYHOP	1
172ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#define UNAME		(HOPBYHOP ? "HBH" : "DST")
182ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#define LNAME		(HOPBYHOP ? "hbh" : "dst")
192ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
202ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó/* Function which prints out usage message. */
212ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic void
222ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóhelp(void)
232ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
242ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	printf(
252ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó"%s v%s options:\n"
262ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó" --%s-len [!] length           total length of this header\n"
272ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó" --%s-opts TYPE[:LEN][,TYPE[:LEN]...] \n"
282ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó"                               Options and its length (list, max: %d)\n",
2980fe35d6339b53a12ddaec41885613e4e37ed031Harald WelteUNAME , IPTABLES_VERSION, LNAME, LNAME, IP6T_OPTS_OPTSNR);
302ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
312ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
322ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#if HOPBYHOP
332ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic struct option opts[] = {
342ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	{ "hbh-len", 1, 0, '1' },
352ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	{ "hbh-opts", 1, 0, '2' },
362ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	{ "hbh-not-strict", 1, 0, '3' },
372ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	{0}
382ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó};
392ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#else
402ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic struct option opts[] = {
412ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	{ "dst-len", 1, 0, '1' },
422ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	{ "dst-opts", 1, 0, '2' },
432ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	{ "dst-not-strict", 1, 0, '3' },
442ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	{0}
452ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó};
462ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#endif
472ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
482ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic u_int32_t
492ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóparse_opts_num(const char *idstr, const char *typestr)
502ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
512ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	unsigned long int id;
522ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	char* ep;
532ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
542ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	id =  strtoul(idstr,&ep,0) ;
552ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
562ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if ( idstr == ep ) {
572ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		exit_error(PARAMETER_PROBLEM,
582ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			   "%s no valid digits in %s `%s'", UNAME, typestr, idstr);
592ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	}
602ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if ( id == ULONG_MAX  && errno == ERANGE ) {
612ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		exit_error(PARAMETER_PROBLEM,
622ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			   "%s `%s' specified too big: would overflow",
632ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			   typestr, idstr);
642ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	}
652ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if ( *idstr != '\0'  && *ep != '\0' ) {
662ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		exit_error(PARAMETER_PROBLEM,
672ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			   "%s error parsing %s `%s'", UNAME, typestr, idstr);
682ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	}
692ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	return (u_int32_t) id;
702ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
712ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
722ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic int
732ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóparse_options(const char *optsstr, u_int16_t *opts)
742ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
752ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó        char *buffer, *cp, *next, *range;
762ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó        unsigned int i;
772ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
782ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	buffer = strdup(optsstr);
792ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó        if (!buffer) exit_error(OTHER_PROBLEM, "strdup failed");
802ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
812ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó        for (cp=buffer, i=0; cp && i<IP6T_OPTS_OPTSNR; cp=next,i++)
822ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó        {
832ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                next=strchr(cp, ',');
842ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                if (next) *next++='\0';
852ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                range = strchr(cp, ':');
862ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                if (range) {
872ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                        if (i == IP6T_OPTS_OPTSNR-1)
882ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                                exit_error(PARAMETER_PROBLEM,
892ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                                           "too many ports specified");
902ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                        *range++ = '\0';
912ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                }
922ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                opts[i] = (u_int16_t)((parse_opts_num(cp,"opt") & 0x000000FF)<<8);
932ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                if (range) {
942ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			if (opts[i] == 0)
952ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó        			exit_error(PARAMETER_PROBLEM, "PAD0 hasn't got length");
962ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                        opts[i] |= (u_int16_t)(parse_opts_num(range,"length") &
972ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó					0x000000FF);
982ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                } else {
992ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                        opts[i] |= (0x00FF);
1002ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		}
1012ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1022ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#if DEBUG
1032ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf("opts str: %s %s\n", cp, range);
1042ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf("opts opt: %04X\n", opts[i]);
1052ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#endif
1062ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	}
1072ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó        if (cp) exit_error(PARAMETER_PROBLEM, "too many addresses specified");
1082ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1092ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	free(buffer);
1102ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1112ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#if DEBUG
1122ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	printf("addr nr: %d\n", i);
1132ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#endif
1142ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1152ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	return i;
1162ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
1172ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1182ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó/* Initialize the match. */
1192ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic void
1202ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóinit(struct ip6t_entry_match *m, unsigned int *nfcache)
1212ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
1222ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	struct ip6t_opts *optinfo = (struct ip6t_opts *)m->data;
1232ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1242ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	optinfo->hdrlen = 0;
1252ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	optinfo->flags = 0;
1262ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	optinfo->invflags = 0;
1272ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	optinfo->optsnr = 0;
1282ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
1292ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1302ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó/* Function which parses command options; returns true if it
1312ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó   ate an option */
1322ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic int
1332ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóparse(int c, char **argv, int invert, unsigned int *flags,
1342ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó      const struct ip6t_entry *entry,
1352ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó      unsigned int *nfcache,
1362ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó      struct ip6t_entry_match **match)
1372ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
1382ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	struct ip6t_opts *optinfo = (struct ip6t_opts *)(*match)->data;
1392ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1402ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	switch (c) {
1412ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	case '1':
1422ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		if (*flags & IP6T_OPTS_LEN)
1432ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			exit_error(PARAMETER_PROBLEM,
1442ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó				   "Only one `--%s-len' allowed", LNAME);
1452ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		check_inverse(optarg, &invert, &optind, 0);
1462ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		optinfo->hdrlen = parse_opts_num(argv[optind-1], "length");
1472ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		if (invert)
1482ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			optinfo->invflags |= IP6T_OPTS_INV_LEN;
1492ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		optinfo->flags |= IP6T_OPTS_LEN;
1502ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		*flags |= IP6T_OPTS_LEN;
1512ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		break;
1522ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	case '2':
1532ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		if (*flags & IP6T_OPTS_OPTS)
1542ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			exit_error(PARAMETER_PROBLEM,
1552ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó				   "Only one `--%s-opts' allowed", LNAME);
1562ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                check_inverse(optarg, &invert, &optind, 0);
1572ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                if (invert)
1582ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó                        exit_error(PARAMETER_PROBLEM,
1592ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó				" '!' not allowed with `--%s-opts'", LNAME);
1602ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		optinfo->optsnr = parse_options(argv[optind-1], optinfo->opts);
1612ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		optinfo->flags |= IP6T_OPTS_OPTS;
1622ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		*flags |= IP6T_OPTS_OPTS;
1632ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		break;
1642ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	case '3':
1652ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		if (*flags & IP6T_OPTS_NSTRICT)
1662ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			exit_error(PARAMETER_PROBLEM,
1672ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó				   "Only one `--%s-not-strict' allowed", LNAME);
1682ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		if ( !(*flags & IP6T_OPTS_OPTS) )
1692ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			exit_error(PARAMETER_PROBLEM,
1702ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó				   "`--%s-opts ...' required before `--%s-not-strict'", LNAME, LNAME);
1712ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		optinfo->flags |= IP6T_OPTS_NSTRICT;
1722ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		*flags |= IP6T_OPTS_NSTRICT;
1732ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		break;
1742ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	default:
1752ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		return 0;
1762ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	}
1772ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1782ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	return 1;
1792ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
1802ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1812ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó/* Final check; we don't care. */
1822ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic void
1832ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabófinal_check(unsigned int flags)
1842ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
1852ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
1862ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1872ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic void
1882ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóprint_options(int optsnr, u_int16_t *optsp)
1892ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
1902ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	unsigned int i;
1912ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
1922ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	for(i=0; i<optsnr; i++){
1932ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf("%d", (optsp[i] & 0xFF00)>>8);
1942ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		if ((optsp[i] & 0x00FF) != 0x00FF){
1952ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			printf(":%d", (optsp[i] & 0x00FF));
1962ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		}
1972ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf("%c", (i!=optsnr-1)?',':' ');
1982ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	}
1992ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
2002ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
2012ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó/* Prints out the union ip6t_matchinfo. */
2022ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic void
2032ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóprint(const struct ip6t_ip6 *ip,
2042ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó      const struct ip6t_entry_match *match, int numeric)
2052ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
2062ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	const struct ip6t_opts *optinfo = (struct ip6t_opts *)match->data;
2072ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
2082ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	printf("%s ", LNAME);
2092ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if (optinfo->flags & IP6T_OPTS_LEN) {
2102ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf("length");
2112ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf(":%s", optinfo->invflags & IP6T_OPTS_INV_LEN ? "!" : "");
2122ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf("%u", optinfo->hdrlen);
2132ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf(" ");
2142ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	}
2152ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if (optinfo->flags & IP6T_OPTS_OPTS) printf("opts ");
216ae31bb6bac68f800a1e4b30cf2548dacaaf76102Fabrice MARIE	print_options(optinfo->optsnr, (u_int16_t *)optinfo->opts);
2172ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if (optinfo->flags & IP6T_OPTS_NSTRICT) printf("not-strict ");
2182ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if (optinfo->invflags & ~IP6T_OPTS_INV_MASK)
2192ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf("Unknown invflags: 0x%X ",
2202ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		       optinfo->invflags & ~IP6T_OPTS_INV_MASK);
2212ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
2222ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
2232ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó/* Saves the union ip6t_matchinfo in parsable form to stdout. */
2242ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
2252ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
2262ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	const struct ip6t_opts *optinfo = (struct ip6t_opts *)match->data;
2272ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
2282ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if (optinfo->flags & IP6T_OPTS_LEN) {
2292ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó		printf("--%s-len %s%u ", LNAME,
2302ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			(optinfo->invflags & IP6T_OPTS_INV_LEN) ? "! " : "",
2312ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó			optinfo->hdrlen);
2322ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	}
2332ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
2342ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if (optinfo->flags & IP6T_OPTS_OPTS) printf("--%s-opts ", LNAME);
235ae31bb6bac68f800a1e4b30cf2548dacaaf76102Fabrice MARIE	print_options(optinfo->optsnr, (u_int16_t *)optinfo->opts);
2362ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	if (optinfo->flags & IP6T_OPTS_NSTRICT) printf("--%s-not-strict ", LNAME);
2372ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
2382ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
2392ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
2402ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstatic
2412ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóstruct ip6tables_match optstruct
2422ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó= { NULL,
2432ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#if HOPBYHOP
2442ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    "hbh",
2452ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#else
2462ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    "dst",
2472ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó#endif
24880fe35d6339b53a12ddaec41885613e4e37ed031Harald Welte    IPTABLES_VERSION,
2492ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    IP6T_ALIGN(sizeof(struct ip6t_opts)),
2502ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    IP6T_ALIGN(sizeof(struct ip6t_opts)),
2512ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    &help,
2522ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    &init,
2532ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    &parse,
2542ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    &final_check,
2552ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    &print,
2562ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    &save,
2572ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó    opts
2582ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó};
2592ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó
2602ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabóvoid
2612ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó_init(void)
2622ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó{
2632ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó	register_match6(&optstruct);
2642ea56498b07506c00a511ddee39cb1c4bd85457dAndrás Kis-Szabó}
265