Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.os.linux.development.system > #722

Usage libiptc to add new rule, error with function iptc_commit(): Invalid argument

Newsgroups comp.os.linux.development.system
Date 2014-10-12 05:11 -0700
Message-ID <67a83df0-a662-4e80-8a50-ce9e69bf96d7@googlegroups.com> (permalink)
Subject Usage libiptc to add new rule, error with function iptc_commit(): Invalid argument
From aplekaev@gmail.com

Show all headers | View raw


I am trying to write some code to add this iptables rule:

iptables -t nat -A PREROUTING -s 192.168.213.2 -d 186.23.1.128 -i eth1 -p tcp --sport 34533 --dport 443 -j REDIRECT --to-ports 8443

When I call iptc_commit() procedure in this code, I get the error invalid argument. I think the problem lies in completing the structure of ipt_entry_target.

Does anyone know what could be wrong with my sample code here?

#include "linux/netfilter/xt_limit.h"
#include "linux/netfilter/xt_physdev.h"
#include "linux/netfilter_ipv4/ip_tables.h"

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define __must_be_array(a) \
    BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
#define LIST_POISON2  ((void *) 0x00200200 )
#include <linux/netfilter_ipv4/nf_nat.h>
#define ip_nat_multi_range  nf_nat_multi_range
#define ip_nat_range        nf_nat_range
#define IPTC_HANDLE     struct iptc_handle *

#ifndef IPT_ALIGN
#define IPT_ALIGN XT_ALIGN
#endif

#define IP_PARTS_NATIVE(n)      \
(unsigned int)((n)>>24)&0xFF,   \
(unsigned int)((n)>>16)&0xFF,   \
(unsigned int)((n)>>8)&0xFF,    \
(unsigned int)((n)&0xFF)

#define IP_PARTS(n) IP_PARTS_NATIVE(ntohl(n))

struct pprot {
  char *name;
  u_int8_t num;
};

static const struct pprot chain_protos[] = {
  { "tcp", IPPROTO_TCP },
  { "udp", IPPROTO_UDP },
  { "icmp", IPPROTO_ICMP },
  { "esp", IPPROTO_ESP },
  { "ah", IPPROTO_AH },
};

int main(int argc, char *argv[])
{
    int ret = 0;
    struct ipt_entry *entry = NULL;
    struct ipt_entry_match *match = NULL;
    struct ipt_entry_target *target = NULL;
    IPTC_HANDLE iptcHandle_ = iptc_init(nat);
         if (!IPTC_HANDLE)
        exit(1);
    entry = static_cast<struct ipt_entry *>(calloc(1, sizeof (struct ipt_entry)));
    if  (entry == NULL)
        exit(1);
    entry->ip.proto = IPPROTO_TCP;
    match = getTcpMatch(443, 34533);
    entry->nfcache = NFC_IP_DST_PT;
    target = getRedirectTarget(_redirectPort);
        entry->nfcache |= NFC_UNKNOWN;
        entry = static_cast<struct ipt_entry *>(realloc(entry, sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size));
        memcpy(entry->elems, match, match->u.match_size);
        memcpy(entry->elems + match->u.match_size, target, target->u.target_size);
        entry->target_offset = sizeof(struct ipt_entry)
                       + match->u.match_size;
        entry->next_offset = sizeof(struct ipt_entry)
                     + match->u.match_size
                     + target->u.target_size;
        entry->ip.src.s_addr = inet_addr('192.168.213.2');
        entry->ip.smsk.s_addr = 0xFFFFFFFF;
        strcpy(entry->ip.iniface, 'eth1');
        entry->ip.dst.s_addr = inet_addr('189.222.1.128');
        entry->ip.dmsk.s_addr = 0xFFFFFFFF;
        if(!iptc_append_entry("PREROUTING", entry, iptcHandle_))
                exit(1);
    if(!iptc_commit(iptcHandle_))
                exit(1);
} //int main(int argc, char *argv[])

struct ipt_entry_match *getTcpMatch(unsigned short _dport, unsigned short _sport)
{
    struct ipt_entry_match *match;
    struct ipt_tcp * tcpinfo;
    size_t size;
    size =   IPT_ALIGN(sizeof(struct ipt_entry_match))
           + IPT_ALIGN(sizeof(struct ipt_tcp));
    match = static_cast<ipt_entry_match *>(calloc(1, size));
    match->u.match_size = size;
    strncpy(match->u.user.name, "tcp", sizeof(match->u.user.name));
    tcpinfo = (struct ipt_tcp *)match->data;
    if (_sport == 0)
    {
        tcpinfo->spts[0] = 0;       /* all source ports */
        tcpinfo->spts[1] = 0xFFFF;
    } //if (sport == 0)
    else
    {
        tcpinfo->spts[0] = _sport;     /* specified source port */
        tcpinfo->spts[1] = _sport;
    } //else /if (sport == 0)
    if (_dport == 0)
    {
        tcpinfo->dpts[0] = 0;      /* all destination ports */
        tcpinfo->dpts[1] = 0xFFFF;
    } //if (dport == 0)
    else
    {
        tcpinfo->dpts[0] = _dport;  /* specified destination port */
        tcpinfo->dpts[1] = _dport;
    } //else /if (dport == 0)
    return match;
} //struct ipt_entry_match *getTcpMatch(unsigned short _dport, unsigned short _sport)

struct ipt_entry_target *getRedirectTarget(unsigned short _redirectPort)
{
    struct ipt_entry_target * target;
    //!!! I doubt the use of this structure
    struct ip_nat_range * range;
    size_t size;

    size =   IPT_ALIGN(sizeof(struct ipt_entry_target))
           + IPT_ALIGN(sizeof(struct ip_nat_range));
    target = static_cast<ipt_entry_target *>(calloc(1, size));
    target->u.target_size = size;
    strncpy(target->u.user.name, "REDIRECT", sizeof(target->u.user.name));
    /* one ip_nat_range already included in ip_nat_multi_range */
    range = (struct ip_nat_range *)&target->data[0];
    //range->min_ip = range->max_ip = inet_addr(daddr);
    //range->flags |= IP_NAT_RANGE_MAP_IPS;
    range->min.all = range->max.all = htons(_redirectPort);
    range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
    return target;
} //static struct ipt_entry_target *getRedirectTarget(unsigned short _redirectPort)

Back to comp.os.linux.development.system | Previous | Next | Find similar


Thread

Usage libiptc to add new rule, error with function iptc_commit(): Invalid argument aplekaev@gmail.com - 2014-10-12 05:11 -0700

csiph-web