Skip to content

Instantly share code, notes, and snippets.

@nanpuyue
Last active March 19, 2018 04:26
Show Gist options
  • Save nanpuyue/9fd0a0a51eda91fdf61939fcd8166061 to your computer and use it in GitHub Desktop.
Save nanpuyue/9fd0a0a51eda91fdf61939fcd8166061 to your computer and use it in GitHub Desktop.
iptables -A OUTPUT -s 192.168.1.100/32 -m limit --limit 200/sec --limit-burst 10 -j ACCEPT
/*
* file: iptc_test.c
* date: 2018-03-19
* license: GPLv3 https://www.gnu.org/licenses/gpl-3.0.txt
* author: nanpuyue <[email protected]> https://blog.nanpuyue.com
* compile: gcc -lip4tc iptc_test.c -o iptc_test
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <libiptc/libiptc.h>
#include <linux/netfilter/xt_limit.h>
int main()
{
struct xtc_handle *h = iptc_init("filter");
if (!h)
{
fprintf(stderr, "iptc_init() err: %s\n", strerror(errno));
return -1;
}
struct ipt_entry *e = NULL;
struct ipt_entry_match *em = NULL;
struct xt_rateinfo *limit = NULL;
struct ipt_standard_target *st = NULL;
struct ipt_entry_target *et = NULL;
int ret = 0;
size_t target_size, match_size, entry_size;
match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + XT_ALIGN(sizeof(struct xt_rateinfo));
target_size = XT_ALIGN(sizeof(struct ipt_standard_target));
entry_size = sizeof(*e) + match_size + target_size;
e = (struct ipt_entry *)calloc(1, entry_size);
if (!e)
{
fprintf(stderr, "calloc() err: %s\n", strerror(errno));
ret = -1;
goto do_return;
}
e->ip.src.s_addr = inet_addr("192.168.1.100");
e->ip.smsk.s_addr = inet_addr("255.255.255.255");
e->ip.proto = IPPROTO_IP;
e->target_offset = sizeof(*e) + match_size;
e->next_offset = (__u16)entry_size;
em = (struct ipt_entry_match *)e->elems;
em->u.user.match_size = (__u16)match_size;
strcpy(em->u.user.name, "limit");
limit = (struct xt_rateinfo *)em->data;
limit->avg = 50;
limit->burst = 10;
st = (struct ipt_standard_target *)(e->elems + match_size);
et = &st->target;
et->u.user.target_size = (__u16)target_size;
strcpy(et->u.user.name, "ACCEPT");
if (iptc_append_entry("OUTPUT", e, h) == 0)
{
fprintf(stderr, "iptc_append_entry() err: %s\n", iptc_strerror(errno));
ret = -1;
goto do_return;
}
if (iptc_commit(h) == 0)
{
fprintf(stderr, "iptc_commit() err: %s\n", iptc_strerror(errno));
ret = -1;
goto do_return;
}
do_return:
if (e)
{
free(e);
}
if (h)
{
free(h);
}
return ret;
}
@sbwtw
Copy link

sbwtw commented Mar 16, 2018

cr -2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment