This file is indexed.

/usr/src/xtables-addons-1.40/libxt_iface.c is in xtables-addons-dkms 1.40-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*
 * Shared library add-on to iptables to add interface state matching
 * support.
 *
 * (C) 2008 Gáspár Lajos <gaspar.lajos@glsys.eu>
 *
 * This program is released under the terms of GNU GPL version 2.
 */

#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <xtables.h>
#include "xt_iface.h"
#include "compat_user.h"

enum {
	XT_IFACE_IFACE = 1 << 16,
};

static const struct option iface_mt_opts[] = {
	{.name = "iface",        .has_arg = true,  .val = 'i'},
	{.name = "dev-in",       .has_arg = false, .val = 'I'},
	{.name = "dev-out",      .has_arg = false, .val = 'O'},
	{.name = "up",           .has_arg = false, .val = 'u'},
	{.name = "down",         .has_arg = false, .val = 'U'}, /* not up */
	{.name = "broadcast",    .has_arg = false, .val = 'b'},
	{.name = "loopback",     .has_arg = false, .val = 'l'},
	{.name = "pointopoint",  .has_arg = false, .val = 'p'},
	{.name = "pointtopoint", .has_arg = false, .val = 'p'}, /* eq pointopoint */
	{.name = "running",      .has_arg = false, .val = 'r'},
	{.name = "noarp",        .has_arg = false, .val = 'n'},
	{.name = "arp",          .has_arg = false, .val = 'N'}, /* not noarp */
	{.name = "promisc",      .has_arg = false, .val = 'o'},
	{.name = "multicast",    .has_arg = false, .val = 'm'},
	{.name = "dynamic",      .has_arg = false, .val = 'd'},
	{.name = "lower-up",     .has_arg = false, .val = 'w'},
	{.name = "dormant",      .has_arg = false, .val = 'a'},
	{NULL},
};

static void iface_print_opt(const struct xt_iface_mtinfo *info,
    const unsigned int option, const char *command)
{
	if (info->flags & option)
		printf(" %s%s", (info->invflags & option) ? "! " : "", command);
}

static void iface_setflag(struct xt_iface_mtinfo *info,
    unsigned int *flags, int invert, u_int16_t flag, const char *command)
{
	if (*flags & flag)
		xtables_error(PARAMETER_PROBLEM,
			"iface: \"--%s\" flag already specified", command);
	info->flags |= flag;
	if (invert)
		info->invflags |= flag;
	*flags |= flag;
}

static bool iface_valid_name(const char *name)
{
	static const char invalid_chars[] = ".+!*";

	return strlen(name) < IFNAMSIZ && strpbrk(name, invalid_chars) == NULL;
}

static void iface_mt_help(void)
{
	printf(
	"iface match options:\n"
	"    --iface interface     Name of interface\n"
	"    --dev-in / --dev-out  Use incoming/outgoing interface instead\n"
	"[!] --up / --down         match if UP flag (not) set\n"
	"[!] --broadcast           match if BROADCAST flag (not) set\n"
	"[!] --loopback            match if LOOPBACK flag (not) set\n"
	"[!] --pointopoint\n"
	"[!] --pointtopoint        match if POINTOPOINT flag (not) set\n"
	"[!] --running             match if RUNNING flag (not) set\n"
	"[!] --noarp / --arp       match if NOARP flag (not) set\n"
	"[!] --promisc             match if PROMISC flag (not) set\n"
	"[!] --multicast           match if MULTICAST flag (not) set\n"
	"[!] --dynamic             match if DYNAMIC flag (not) set\n"
	"[!] --lower-up            match if LOWER_UP flag (not) set\n"
	"[!] --dormant             match if DORMANT flag (not) set\n");
}

static int iface_mt_parse(int c, char **argv, int invert, unsigned int *flags,
    const void *entry, struct xt_entry_match **match)
{
	struct xt_iface_mtinfo *info = (void *)(*match)->data;

	switch (c) {
	case 'U':
		c = 'u';
		invert = !invert;
		break;
	case 'N':
		c = 'n';
		invert = !invert;
		break;
	}

	switch (c) {
	case 'i': /* interface name */
		if (*flags & XT_IFACE_IFACE)
			xtables_error(PARAMETER_PROBLEM,
				"iface: Interface name already specified");
		if (!iface_valid_name(optarg))
			xtables_error(PARAMETER_PROBLEM,
				"iface: Invalid interface name!");
		strcpy(info->ifname, optarg);
		*flags |= XT_IFACE_IFACE;
		return true;
	case 'I': /* --dev-in */
		xtables_param_act(XTF_ONLY_ONCE, "iface", "--dev-in",
			*flags & XT_IFACE_IFACE);
		*flags |= XT_IFACE_IFACE;
		iface_setflag(info, flags, invert, XT_IFACE_DEV_IN, "dev-in");
		return true;
	case 'O': /* --dev-out */
		xtables_param_act(XTF_ONLY_ONCE, "iface", "--dev-out",
			*flags & XT_IFACE_IFACE);
		*flags |= XT_IFACE_IFACE;
		iface_setflag(info, flags, invert, XT_IFACE_DEV_OUT, "dev-out");
		return true;
	case 'u': /* UP */
		iface_setflag(info, flags, invert, XT_IFACE_UP, "up");
		return true;
	case 'b': /* BROADCAST */
		iface_setflag(info, flags, invert, XT_IFACE_BROADCAST, "broadcast");
		return true;
	case 'l': /* LOOPBACK */
		iface_setflag(info, flags, invert, XT_IFACE_LOOPBACK, "loopback");
		return true;
	case 'p': /* POINTOPOINT */
		iface_setflag(info, flags, invert, XT_IFACE_POINTOPOINT, "pointopoint");
		return true;
	case 'r': /* RUNNING */
		iface_setflag(info, flags, invert, XT_IFACE_RUNNING, "running");
		return true;
	case 'n': /* NOARP */
		iface_setflag(info, flags, invert, XT_IFACE_NOARP, "noarp");
		return true;
	case 'o': /* PROMISC */
		iface_setflag(info, flags, invert, XT_IFACE_PROMISC, "promisc");
		return true;
	case 'm': /* MULTICAST */
		iface_setflag(info, flags, invert, XT_IFACE_MULTICAST, "multicast");
		return true;
	case 'd': /* DYNAMIC */
		iface_setflag(info, flags, invert, XT_IFACE_DYNAMIC, "dynamic");
		return true;
	case 'w': /* LOWER_UP */
		iface_setflag(info, flags, invert, XT_IFACE_LOWER_UP, "lower_up");
		return true;
	case 'a': /* DORMANT */
		iface_setflag(info, flags, invert, XT_IFACE_DORMANT, "dormant");
		return true;
	}
	return false;
}

static void iface_mt_check(unsigned int flags)
{
	if (!(flags & XT_IFACE_IFACE))
		xtables_error(PARAMETER_PROBLEM,
			"iface: You must specify an interface");
	if ((flags & ~(XT_IFACE_IFACE | XT_IFACE_DEV_IN |
	    XT_IFACE_DEV_OUT)) == 0)
		xtables_error(PARAMETER_PROBLEM,
			"iface: You must specify at least one option");
}

static void iface_mt_print(const void *ip, const struct xt_entry_match *match,
    int numeric)
{
	const struct xt_iface_mtinfo *info = (const void *)match->data;

	printf(" iface: ");
	if (info->flags & XT_IFACE_DEV_IN)
		printf("(in)");
	else if (info->flags & XT_IFACE_DEV_OUT)
		printf("(out)");
	else
		printf("%s", info->ifname);
	printf(" [state:");
	iface_print_opt(info, XT_IFACE_UP,          "up");
	iface_print_opt(info, XT_IFACE_BROADCAST,   "broadcast");
	iface_print_opt(info, XT_IFACE_LOOPBACK,    "loopback");
	iface_print_opt(info, XT_IFACE_POINTOPOINT, "pointopoint");
	iface_print_opt(info, XT_IFACE_RUNNING,     "running");
	iface_print_opt(info, XT_IFACE_NOARP,       "noarp");
	iface_print_opt(info, XT_IFACE_PROMISC,     "promisc");
	iface_print_opt(info, XT_IFACE_MULTICAST,   "multicast");
	iface_print_opt(info, XT_IFACE_DYNAMIC,     "dynamic");
	iface_print_opt(info, XT_IFACE_LOWER_UP,    "lower_up");
	iface_print_opt(info, XT_IFACE_DORMANT,     "dormant");
	printf("] ");
}

static void iface_mt_save(const void *ip, const struct xt_entry_match *match)
{
	const struct xt_iface_mtinfo *info = (const void *)match->data;

	if (info->flags & XT_IFACE_DEV_IN)
		printf(" --dev-in");
	else if (info->flags & XT_IFACE_DEV_OUT)
		printf(" --dev-out");
	else
		printf(" --iface %s", info->ifname);
	iface_print_opt(info, XT_IFACE_UP,          "--up");
	iface_print_opt(info, XT_IFACE_BROADCAST,   "--broadcast");
	iface_print_opt(info, XT_IFACE_LOOPBACK,    "--loopback");
	iface_print_opt(info, XT_IFACE_POINTOPOINT, "--pointopoint");
	iface_print_opt(info, XT_IFACE_RUNNING,     "--running");
	iface_print_opt(info, XT_IFACE_NOARP,       "--noarp");
	iface_print_opt(info, XT_IFACE_PROMISC,     "--promisc");
	iface_print_opt(info, XT_IFACE_MULTICAST,   "--multicast");
	iface_print_opt(info, XT_IFACE_DYNAMIC,     "--dynamic");
	iface_print_opt(info, XT_IFACE_LOWER_UP,    "--lower_up");
	iface_print_opt(info, XT_IFACE_DORMANT,     "--dormant");
	printf(" ");
}

static struct xtables_match iface_mt_reg = {
	.version	= XTABLES_VERSION,
	.name		= "iface",
	.revision	= 0,
	.family		= NFPROTO_UNSPEC,
	.size		= XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
	.help		= iface_mt_help,
	.parse		= iface_mt_parse,
	.final_check	= iface_mt_check,
	.print		= iface_mt_print,
	.save		= iface_mt_save,
	.extra_opts	= iface_mt_opts,
};

static void _init(void)
{
	xtables_register_match(&iface_mt_reg);
}