52
#define FMT_NUMERIC 0x0001
53
#define FMT_NOCOUNTS 0x0002
54
#define FMT_KILOMEGAGIGA 0x0004
55
#define FMT_OPTIONS 0x0008
56
#define FMT_NOTABLE 0x0010
57
#define FMT_NOTARGET 0x0020
58
#define FMT_VIA 0x0040
59
#define FMT_NONEWLINE 0x0080
60
#define FMT_LINENUMBERS 0x0100
62
#define FMT_PRINT_RULE (FMT_NOCOUNTS | FMT_OPTIONS | FMT_VIA \
63
| FMT_NUMERIC | FMT_NOTABLE)
64
#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
67
51
#define CMD_NONE 0x0000U
68
52
#define CMD_INSERT 0x0001U
69
53
#define CMD_DELETE 0x0002U
82
66
#define CMD_CHECK 0x4000U
83
67
#define NUMBER_OF_CMD 16
84
68
static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
85
'Z', 'N', 'X', 'P', 'E', 'S', 'C' };
69
'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
87
71
#define OPT_FRAGMENT 0x00800U
88
72
#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
187
171
#define prog_name iptables_globals.program_name
188
172
#define prog_vers iptables_globals.program_version
192
/* Primitive headers... */
193
/* defined in netinet/in.h */
196
#define IPPROTO_ESP 50
199
#define IPPROTO_AH 51
208
174
static void __attribute__((noreturn))
209
175
exit_tryhelp(int status)
451
print_num(uint64_t number, unsigned int format)
453
if (format & FMT_KILOMEGAGIGA) {
454
if (number > 99999) {
455
number = (number + 500) / 1000;
457
number = (number + 500) / 1000;
459
number = (number + 500) / 1000;
461
number = (number + 500) / 1000;
462
printf(FMT("%4lluT ","%lluT "), (unsigned long long)number);
464
else printf(FMT("%4lluG ","%lluG "), (unsigned long long)number);
466
else printf(FMT("%4lluM ","%lluM "), (unsigned long long)number);
468
printf(FMT("%4lluK ","%lluK "), (unsigned long long)number);
470
printf(FMT("%5llu ","%llu "), (unsigned long long)number);
472
printf(FMT("%8llu ","%llu "), (unsigned long long)number);
477
print_header(unsigned int format, const char *chain, struct iptc_handle *handle)
479
struct ipt_counters counters;
417
print_header(unsigned int format, const char *chain, struct xtc_handle *handle)
419
struct xt_counters counters;
480
420
const char *pol = iptc_get_policy(chain, &counters, handle);
481
421
printf("Chain %s", chain);
483
423
printf(" (policy %s", pol);
484
424
if (!(format & FMT_NOCOUNTS)) {
485
425
fputc(' ', stdout);
486
print_num(counters.pcnt, (format|FMT_NOTABLE));
426
xtables_print_num(counters.pcnt, (format|FMT_NOTABLE));
487
427
fputs("packets, ", stdout);
488
print_num(counters.bcnt, (format|FMT_NOTABLE));
428
xtables_print_num(counters.bcnt, (format|FMT_NOTABLE));
489
429
fputs("bytes", stdout);
550
490
const char *targname,
551
491
unsigned int num,
552
492
unsigned int format,
553
struct iptc_handle *const handle)
493
struct xtc_handle *const handle)
555
495
const struct xtables_target *target = NULL;
556
const struct ipt_entry_target *t;
496
const struct xt_entry_target *t;
558
498
char buf[BUFSIZ];
560
500
if (!iptc_is_chain(targname, handle))
561
501
target = xtables_find_target(targname, XTF_TRY_LOAD);
563
target = xtables_find_target(IPT_STANDARD_TARGET,
503
target = xtables_find_target(XT_STANDARD_TARGET,
564
504
XTF_LOAD_MUST_SUCCEED);
566
506
t = ipt_get_target((struct ipt_entry *)fw);
570
510
printf(FMT("%-4u ", "%u "), num);
572
512
if (!(format & FMT_NOCOUNTS)) {
573
print_num(fw->counters.pcnt, format);
574
print_num(fw->counters.bcnt, format);
513
xtables_print_num(fw->counters.pcnt, format);
514
xtables_print_num(fw->counters.bcnt, format);
577
517
if (!(format & FMT_NOTARGET))
578
518
printf(FMT("%-9s ", "%s "), targname);
580
fputc(fw->ip.invflags & IPT_INV_PROTO ? '!' : ' ', stdout);
520
fputc(fw->ip.invflags & XT_INV_PROTO ? '!' : ' ', stdout);
582
522
const char *pname = proto_to_name(fw->ip.proto, format&FMT_NUMERIC);
674
614
print_firewall_line(const struct ipt_entry *fw,
675
struct iptc_handle *const h)
615
struct xtc_handle *const h)
677
struct ipt_entry_target *t;
617
struct xt_entry_target *t;
679
619
t = ipt_get_target((struct ipt_entry *)fw);
680
620
print_firewall(fw, t->u.user.name, 0, FMT_PRINT_RULE, h);
684
append_entry(const ipt_chainlabel chain,
624
append_entry(const xt_chainlabel chain,
685
625
struct ipt_entry *fw,
686
626
unsigned int nsaddrs,
687
627
const struct in_addr saddrs[],
690
630
const struct in_addr daddrs[],
691
631
const struct in_addr dmasks[],
693
struct iptc_handle *handle)
633
struct xtc_handle *handle)
695
635
unsigned int i, j;
714
replace_entry(const ipt_chainlabel chain,
654
replace_entry(const xt_chainlabel chain,
715
655
struct ipt_entry *fw,
716
656
unsigned int rulenum,
717
657
const struct in_addr *saddr, const struct in_addr *smask,
718
658
const struct in_addr *daddr, const struct in_addr *dmask,
720
struct iptc_handle *handle)
660
struct xtc_handle *handle)
722
662
fw->ip.src.s_addr = saddr->s_addr;
723
663
fw->ip.dst.s_addr = daddr->s_addr;
740
680
const struct in_addr daddrs[],
741
681
const struct in_addr dmasks[],
743
struct iptc_handle *handle)
683
struct xtc_handle *handle)
745
685
unsigned int i, j;
772
712
size = sizeof(struct ipt_entry);
773
713
for (matchp = matches; matchp; matchp = matchp->next)
774
size += XT_ALIGN(sizeof(struct ipt_entry_match)) + matchp->match->size;
714
size += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
776
716
mask = xtables_calloc(1, size
777
+ XT_ALIGN(sizeof(struct ipt_entry_target))
717
+ XT_ALIGN(sizeof(struct xt_entry_target))
780
720
memset(mask, 0xFF, sizeof(struct ipt_entry));
783
723
for (matchp = matches; matchp; matchp = matchp->next) {
784
724
memset(mptr, 0xFF,
785
XT_ALIGN(sizeof(struct ipt_entry_match))
725
XT_ALIGN(sizeof(struct xt_entry_match))
786
726
+ matchp->match->userspacesize);
787
mptr += XT_ALIGN(sizeof(struct ipt_entry_match)) + matchp->match->size;
727
mptr += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
790
730
memset(mptr, 0xFF,
791
XT_ALIGN(sizeof(struct ipt_entry_target))
731
XT_ALIGN(sizeof(struct xt_entry_target))
792
732
+ target->userspacesize);
798
delete_entry(const ipt_chainlabel chain,
738
delete_entry(const xt_chainlabel chain,
799
739
struct ipt_entry *fw,
800
740
unsigned int nsaddrs,
801
741
const struct in_addr saddrs[],
804
744
const struct in_addr daddrs[],
805
745
const struct in_addr dmasks[],
807
struct iptc_handle *handle,
747
struct xtc_handle *handle,
808
748
struct xtables_rule_match *matches,
809
749
const struct xtables_target *target)
833
check_entry(const ipt_chainlabel chain, struct ipt_entry *fw,
773
check_entry(const xt_chainlabel chain, struct ipt_entry *fw,
834
774
unsigned int nsaddrs, const struct in_addr *saddrs,
835
775
const struct in_addr *smasks, unsigned int ndaddrs,
836
776
const struct in_addr *daddrs, const struct in_addr *dmasks,
837
bool verbose, struct iptc_handle *handle,
777
bool verbose, struct xtc_handle *handle,
838
778
struct xtables_rule_match *matches,
839
779
const struct xtables_target *target)
863
for_each_chain4(int (*fn)(const ipt_chainlabel, int, struct iptc_handle *),
864
int verbose, int builtinstoo, struct iptc_handle *handle)
803
for_each_chain4(int (*fn)(const xt_chainlabel, int, struct xtc_handle *),
804
int verbose, int builtinstoo, struct xtc_handle *handle)
867
807
const char *chain;
874
814
chain = iptc_next_chain(handle);
877
chains = xtables_malloc(sizeof(ipt_chainlabel) * chaincount);
817
chains = xtables_malloc(sizeof(xt_chainlabel) * chaincount);
879
819
chain = iptc_first_chain(handle);
881
strcpy(chains + i*sizeof(ipt_chainlabel), chain);
821
strcpy(chains + i*sizeof(xt_chainlabel), chain);
883
823
chain = iptc_next_chain(handle);
886
826
for (i = 0; i < chaincount; i++) {
888
&& iptc_builtin(chains + i*sizeof(ipt_chainlabel),
828
&& iptc_builtin(chains + i*sizeof(xt_chainlabel),
891
ret &= fn(chains + i*sizeof(ipt_chainlabel), verbose, handle);
831
ret &= fn(chains + i*sizeof(xt_chainlabel), verbose, handle);
899
flush_entries4(const ipt_chainlabel chain, int verbose,
900
struct iptc_handle *handle)
839
flush_entries4(const xt_chainlabel chain, int verbose,
840
struct xtc_handle *handle)
903
843
return for_each_chain4(flush_entries4, verbose, 1, handle);
911
zero_entries(const ipt_chainlabel chain, int verbose,
912
struct iptc_handle *handle)
851
zero_entries(const xt_chainlabel chain, int verbose,
852
struct xtc_handle *handle)
915
855
return for_each_chain4(zero_entries, verbose, 1, handle);
923
delete_chain4(const ipt_chainlabel chain, int verbose,
924
struct iptc_handle *handle)
863
delete_chain4(const xt_chainlabel chain, int verbose,
864
struct xtc_handle *handle)
927
867
return for_each_chain4(delete_chain4, verbose, 0, handle);
935
list_entries(const ipt_chainlabel chain, int rulenum, int verbose, int numeric,
936
int expanded, int linenumbers, struct iptc_handle *handle)
875
list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric,
876
int expanded, int linenumbers, struct xtc_handle *handle)
939
879
unsigned int format;
1047
static int print_match_save(const struct ipt_entry_match *e,
987
static int print_match_save(const struct xt_entry_match *e,
1048
988
const struct ipt_ip *ip)
1050
990
const struct xtables_match *match =
1051
991
xtables_find_match(e->u.user.name, XTF_TRY_LOAD, NULL);
1054
printf(" -m %s", e->u.user.name);
995
match->alias ? match->alias(e) : e->u.user.name);
1056
997
/* some matches don't provide a save function */
1057
998
if (match->save)
1100
1041
/* We want this to be readable, so only print out neccessary fields.
1101
1042
* Because that's the kind of world I want to live in. */
1102
1043
void print_rule4(const struct ipt_entry *e,
1103
struct iptc_handle *h, const char *chain, int counters)
1044
struct xtc_handle *h, const char *chain, int counters)
1105
const struct ipt_entry_target *t;
1046
const struct xt_entry_target *t;
1106
1047
const char *target_name;
1108
1049
/* print counters for iptables-save */
1125
1066
print_iface('o', e->ip.outiface, e->ip.outiface_mask,
1126
1067
e->ip.invflags & IPT_INV_VIA_OUT);
1128
print_proto(e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
1069
print_proto(e->ip.proto, e->ip.invflags & XT_INV_PROTO);
1130
1071
if (e->ip.flags & IPT_F_FRAG)
1131
1072
printf("%s -f",
1140
1081
if (counters < 0)
1141
1082
printf(" -c %llu %llu", (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt);
1143
/* Print target name */
1084
/* Print target name and targinfo part */
1144
1085
target_name = iptc_get_target(e, h);
1145
if (target_name && (*target_name != '\0'))
1147
printf(" -%c %s", e->ip.flags & IPT_F_GOTO ? 'g' : 'j', target_name);
1149
printf(" -j %s", target_name);
1152
/* Print targinfo part */
1153
1086
t = ipt_get_target((struct ipt_entry *)e);
1154
1087
if (t->u.user.name[0]) {
1155
1088
const struct xtables_target *target =
1097
printf(" -j %s", target->alias ? target->alias(t) : target_name);
1164
1098
if (target->save)
1165
1099
target->save(&e->ip, t);
1167
/* If the target size is greater than ipt_entry_target
1101
/* If the target size is greater than xt_entry_target
1168
1102
* there is something to be saved, we just don't know
1169
1103
* how to print it */
1170
1104
if (t->u.target_size !=
1171
sizeof(struct ipt_entry_target)) {
1105
sizeof(struct xt_entry_target)) {
1172
1106
fprintf(stderr, "Target `%s' is missing "
1173
1107
"save function\n",
1174
1108
t->u.user.name);
1112
} else if (target_name && (*target_name != '\0'))
1114
printf(" -%c %s", e->ip.flags & IPT_F_GOTO ? 'g' : 'j', target_name);
1116
printf(" -j %s", target_name);
1183
list_rules(const ipt_chainlabel chain, int rulenum, int counters,
1184
struct iptc_handle *handle)
1123
list_rules(const xt_chainlabel chain, int rulenum, int counters,
1124
struct xtc_handle *handle)
1186
1126
const char *this = NULL;
1200
1140
if (iptc_builtin(this, handle)) {
1201
struct ipt_counters count;
1141
struct xt_counters count;
1202
1142
printf("-P %s %s", this, iptc_get_policy(this, &count, handle));
1204
1144
printf(" -c %llu %llu", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
1235
1175
static struct ipt_entry *
1236
1176
generate_entry(const struct ipt_entry *fw,
1237
1177
struct xtables_rule_match *matches,
1238
struct ipt_entry_target *target)
1178
struct xt_entry_target *target)
1240
1180
unsigned int size;
1241
1181
struct xtables_rule_match *matchp;
1263
static void clear_rule_matches(struct xtables_rule_match **matches)
1265
struct xtables_rule_match *matchp, *tmp;
1267
for (matchp = *matches; matchp;) {
1269
if (matchp->match->m) {
1270
free(matchp->match->m);
1271
matchp->match->m = NULL;
1273
if (matchp->match == matchp->match->next) {
1274
free(matchp->match);
1275
matchp->match = NULL;
1285
get_kernel_version(void) {
1286
static struct utsname uts;
1287
int x = 0, y = 0, z = 0;
1289
if (uname(&uts) == -1) {
1290
fprintf(stderr, "Unable to retrieve kernel version.\n");
1291
xtables_free_opts(1);
1295
sscanf(uts.release, "%d.%d.%d", &x, &y, &z);
1296
kernel_version = LINUX_VERSION(x, y, z);
1299
1203
static void command_jump(struct iptables_command_state *cs)
1308
1212
if (cs->target == NULL)
1311
size = XT_ALIGN(sizeof(struct ipt_entry_target))
1215
size = XT_ALIGN(sizeof(struct xt_entry_target))
1312
1216
+ cs->target->size;
1314
1218
cs->target->t = xtables_calloc(1, size);
1315
1219
cs->target->t->u.target_size = size;
1316
strcpy(cs->target->t->u.user.name, cs->jumpto);
1220
if (cs->target->real_name == NULL) {
1221
strcpy(cs->target->t->u.user.name, cs->jumpto);
1223
/* Alias support for userspace side */
1224
strcpy(cs->target->t->u.user.name, cs->target->real_name);
1225
if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
1226
fprintf(stderr, "Notice: The %s target is converted into %s target "
1227
"in rule listing and saving.\n",
1228
cs->jumpto, cs->target->real_name);
1317
1230
cs->target->t->u.user.revision = cs->target->revision;
1318
1232
xs_init_target(cs->target);
1320
1234
if (cs->target->x6_options != NULL)
1339
1253
"unexpected ! flag before --match");
1341
1255
m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
1342
size = XT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
1256
size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
1343
1257
m->m = xtables_calloc(1, size);
1344
1258
m->m->u.match_size = size;
1345
strcpy(m->m->u.user.name, m->name);
1259
if (m->real_name == NULL) {
1260
strcpy(m->m->u.user.name, m->name);
1262
strcpy(m->m->u.user.name, m->real_name);
1263
if (!(m->ext_flags & XTABLES_EXT_ALIAS))
1264
fprintf(stderr, "Notice: the %s match is converted into %s match "
1265
"in rule listing and saving.\n", m->name, m->real_name);
1346
1267
m->m->u.user.revision = m->revision;
1347
1269
xs_init_match(m);
1348
1270
if (m == m->next)
1358
1280
xtables_error(OTHER_PROBLEM, "can't alloc memory!");
1361
int do_command4(int argc, char *argv[], char **table, struct iptc_handle **handle)
1283
int do_command4(int argc, char *argv[], char **table, struct xtc_handle **handle)
1363
1285
struct iptables_command_state cs;
1364
1286
struct ipt_entry *e = NULL;
1577
1499
cs.fw.ip.proto = xtables_parse_protocol(cs.protocol);
1579
1501
if (cs.fw.ip.proto == 0
1580
&& (cs.fw.ip.invflags & IPT_INV_PROTO))
1502
&& (cs.fw.ip.invflags & XT_INV_PROTO))
1581
1503
xtables_error(PARAMETER_PROBLEM,
1582
1504
"rule would never match protocol");
1855
1777
|| iptc_is_chain(cs.jumpto, *handle))) {
1858
cs.target = xtables_find_target(IPT_STANDARD_TARGET,
1780
cs.target = xtables_find_target(XT_STANDARD_TARGET,
1859
1781
XTF_LOAD_MUST_SUCCEED);
1861
size = sizeof(struct ipt_entry_target)
1783
size = sizeof(struct xt_entry_target)
1862
1784
+ cs.target->size;
1863
1785
cs.target->t = xtables_calloc(1, size);
1864
1786
cs.target->t->u.target_size = size;