summaryrefslogtreecommitdiffstats
path: root/libiptc/libiptc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libiptc/libiptc.c')
-rw-r--r--libiptc/libiptc.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
index 74f56f4f..a71ecad1 100644
--- a/libiptc/libiptc.c
+++ b/libiptc/libiptc.c
@@ -1,4 +1,4 @@
-/* Library which manipulates firewall rules. Version $Revision: 1.51 $ */
+/* Library which manipulates firewall rules. Version $Revision: 1.52 $ */
/* Architecture of firewall rules is as follows:
*
@@ -1245,7 +1245,8 @@ TC_INSERT_ENTRY(const IPT_CHAINLABEL chain,
TC_HANDLE_T *handle)
{
struct chain_head *c;
- struct rule_head *r, *prev;
+ struct rule_head *r;
+ struct list_head *prev;
iptc_fn = TC_INSERT_ENTRY;
@@ -1254,12 +1255,21 @@ TC_INSERT_ENTRY(const IPT_CHAINLABEL chain,
return 0;
}
- prev = iptcc_get_rule_num(c, rulenum);
- if (!prev) {
+ /* first rulenum index = 0
+ first c->num_rules index = 1 */
+ if (rulenum > c->num_rules) {
errno = E2BIG;
return 0;
}
+ /* Try to get the rule we want to insert after.
+ In case of no rules, insert after chain head. */
+ r = iptcc_get_rule_num(c, rulenum + 1);
+ if (r)
+ prev = &r->list;
+ else
+ prev = &c->rules;
+
if (!(r = iptcc_alloc_rule(c, e->next_offset))) {
errno = ENOMEM;
return 0;
@@ -1273,7 +1283,7 @@ TC_INSERT_ENTRY(const IPT_CHAINLABEL chain,
return 0;
}
- list_add_tail(&r->list, &prev->list);
+ list_add_tail(&r->list, prev);
c->num_rules++;
set_changed(*handle);