Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
iproute2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
iproute2
Commits
1ffd7fd2
Commit
1ffd7fd2
authored
Jan 17, 2005
by
net[shemminger]!shemminger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import patch iproute2.110
(Logical change 1.112)
parent
3e1d2ea6
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1379 additions
and
0 deletions
+1379
-0
ChangeLog
ChangeLog
+5
-0
include/ip6tables.h
include/ip6tables.h
+141
-0
include/iptables.h
include/iptables.h
+155
-0
include/iptables_common.h
include/iptables_common.h
+37
-0
include/libiptc/ipt_kernel_headers.h
include/libiptc/ipt_kernel_headers.h
+27
-0
include/libiptc/libip6tc.h
include/libiptc/libip6tc.h
+154
-0
include/libiptc/libiptc.h
include/libiptc/libiptc.h
+166
-0
include/linux/tc_act/tc_ipt.h
include/linux/tc_act/tc_ipt.h
+21
-0
tc/Makefile
tc/Makefile
+1
-0
tc/m_ipt.c
tc/m_ipt.c
+672
-0
No files found.
ChangeLog
View file @
1ffd7fd2
2005-01-12 Jamal Hadi Salim <hadi@znyx.com>
* Add iptables tc support. This meant borrowing headers
from iptables *ugh*
2004-12-08 Jamal Hadi Salim <hadi@znyx.com>
* Add mirror and redirect actions
...
...
include/ip6tables.h
View file @
1ffd7fd2
#ifndef _IP6TABLES_USER_H
#define _IP6TABLES_USER_H
#include "iptables_common.h"
#include "libiptc/libip6tc.h"
struct
ip6tables_rule_match
{
struct
ip6tables_rule_match
*
next
;
struct
ip6tables_match
*
match
;
};
/* Include file for additions: new matches and targets. */
struct
ip6tables_match
{
struct
ip6tables_match
*
next
;
ip6t_chainlabel
name
;
const
char
*
version
;
/* Size of match data. */
size_t
size
;
/* Size of match data relevent for userspace comparison purposes */
size_t
userspacesize
;
/* Function which prints out usage message. */
void
(
*
help
)(
void
);
/* Initialize the match. */
void
(
*
init
)(
struct
ip6t_entry_match
*
m
,
unsigned
int
*
nfcache
);
/* Function which parses command options; returns true if it
ate an option */
int
(
*
parse
)(
int
c
,
char
**
argv
,
int
invert
,
unsigned
int
*
flags
,
const
struct
ip6t_entry
*
entry
,
unsigned
int
*
nfcache
,
struct
ip6t_entry_match
**
match
);
/* Final check; exit if not ok. */
void
(
*
final_check
)(
unsigned
int
flags
);
/* Prints out the match iff non-NULL: put space at end */
void
(
*
print
)(
const
struct
ip6t_ip6
*
ip
,
const
struct
ip6t_entry_match
*
match
,
int
numeric
);
/* Saves the union ipt_matchinfo in parsable form to stdout. */
void
(
*
save
)(
const
struct
ip6t_ip6
*
ip
,
const
struct
ip6t_entry_match
*
match
);
/* Pointer to list of extra command-line options */
const
struct
option
*
extra_opts
;
/* Ignore these men behind the curtain: */
unsigned
int
option_offset
;
struct
ip6t_entry_match
*
m
;
unsigned
int
mflags
;
#ifdef NO_SHARED_LIBS
unsigned
int
loaded
;
/* simulate loading so options are merged properly */
#endif
};
struct
ip6tables_target
{
struct
ip6tables_target
*
next
;
ip6t_chainlabel
name
;
const
char
*
version
;
/* Size of target data. */
size_t
size
;
/* Size of target data relevent for userspace comparison purposes */
size_t
userspacesize
;
/* Function which prints out usage message. */
void
(
*
help
)(
void
);
/* Initialize the target. */
void
(
*
init
)(
struct
ip6t_entry_target
*
t
,
unsigned
int
*
nfcache
);
/* Function which parses command options; returns true if it
ate an option */
int
(
*
parse
)(
int
c
,
char
**
argv
,
int
invert
,
unsigned
int
*
flags
,
const
struct
ip6t_entry
*
entry
,
struct
ip6t_entry_target
**
target
);
/* Final check; exit if not ok. */
void
(
*
final_check
)(
unsigned
int
flags
);
/* Prints out the target iff non-NULL: put space at end */
void
(
*
print
)(
const
struct
ip6t_ip6
*
ip
,
const
struct
ip6t_entry_target
*
target
,
int
numeric
);
/* Saves the targinfo in parsable form to stdout. */
void
(
*
save
)(
const
struct
ip6t_ip6
*
ip
,
const
struct
ip6t_entry_target
*
target
);
/* Pointer to list of extra command-line options */
struct
option
*
extra_opts
;
/* Ignore these men behind the curtain: */
unsigned
int
option_offset
;
struct
ip6t_entry_target
*
t
;
unsigned
int
tflags
;
unsigned
int
used
;
#ifdef NO_SHARED_LIBS
unsigned
int
loaded
;
/* simulate loading so options are merged properly */
#endif
};
extern
int
line
;
/* Your shared library should call one of these. */
extern
void
register_match6
(
struct
ip6tables_match
*
me
);
extern
void
register_target6
(
struct
ip6tables_target
*
me
);
extern
int
do_command6
(
int
argc
,
char
*
argv
[],
char
**
table
,
ip6tc_handle_t
*
handle
);
/* Keeping track of external matches and targets: linked lists. */
extern
struct
ip6tables_match
*
ip6tables_matches
;
extern
struct
ip6tables_target
*
ip6tables_targets
;
enum
ip6t_tryload
{
DONT_LOAD
,
TRY_LOAD
,
LOAD_MUST_SUCCEED
};
extern
struct
ip6tables_target
*
find_target
(
const
char
*
name
,
enum
ip6t_tryload
);
extern
struct
ip6tables_match
*
find_match
(
const
char
*
name
,
enum
ip6t_tryload
,
struct
ip6tables_rule_match
**
match
);
extern
int
for_each_chain
(
int
(
*
fn
)(
const
ip6t_chainlabel
,
int
,
ip6tc_handle_t
*
),
int
verbose
,
int
builtinstoo
,
ip6tc_handle_t
*
handle
);
extern
int
flush_entries
(
const
ip6t_chainlabel
chain
,
int
verbose
,
ip6tc_handle_t
*
handle
);
extern
int
delete_chain
(
const
ip6t_chainlabel
chain
,
int
verbose
,
ip6tc_handle_t
*
handle
);
extern
int
ip6tables_insmod
(
const
char
*
modname
,
const
char
*
modprobe
);
#endif
/*_IP6TABLES_USER_H*/
include/iptables.h
View file @
1ffd7fd2
#ifndef _IPTABLES_USER_H
#define _IPTABLES_USER_H
#include "iptables_common.h"
#include "libiptc/libiptc.h"
#ifndef IPPROTO_SCTP
#define IPPROTO_SCTP 132
#endif
struct
iptables_rule_match
{
struct
iptables_rule_match
*
next
;
struct
iptables_match
*
match
;
};
/* Include file for additions: new matches and targets. */
struct
iptables_match
{
struct
iptables_match
*
next
;
ipt_chainlabel
name
;
const
char
*
version
;
/* Size of match data. */
size_t
size
;
/* Size of match data relevent for userspace comparison purposes */
size_t
userspacesize
;
/* Function which prints out usage message. */
void
(
*
help
)(
void
);
/* Initialize the match. */
void
(
*
init
)(
struct
ipt_entry_match
*
m
,
unsigned
int
*
nfcache
);
/* Function which parses command options; returns true if it
ate an option */
int
(
*
parse
)(
int
c
,
char
**
argv
,
int
invert
,
unsigned
int
*
flags
,
const
struct
ipt_entry
*
entry
,
unsigned
int
*
nfcache
,
struct
ipt_entry_match
**
match
);
/* Final check; exit if not ok. */
void
(
*
final_check
)(
unsigned
int
flags
);
/* Prints out the match iff non-NULL: put space at end */
void
(
*
print
)(
const
struct
ipt_ip
*
ip
,
const
struct
ipt_entry_match
*
match
,
int
numeric
);
/* Saves the match info in parsable form to stdout. */
void
(
*
save
)(
const
struct
ipt_ip
*
ip
,
const
struct
ipt_entry_match
*
match
);
/* Pointer to list of extra command-line options */
const
struct
option
*
extra_opts
;
/* Ignore these men behind the curtain: */
unsigned
int
option_offset
;
struct
ipt_entry_match
*
m
;
unsigned
int
mflags
;
#ifdef NO_SHARED_LIBS
unsigned
int
loaded
;
/* simulate loading so options are merged properly */
#endif
};
struct
iptables_target
{
struct
iptables_target
*
next
;
ipt_chainlabel
name
;
const
char
*
version
;
/* Size of target data. */
size_t
size
;
/* Size of target data relevent for userspace comparison purposes */
size_t
userspacesize
;
/* Function which prints out usage message. */
void
(
*
help
)(
void
);
/* Initialize the target. */
void
(
*
init
)(
struct
ipt_entry_target
*
t
,
unsigned
int
*
nfcache
);
/* Function which parses command options; returns true if it
ate an option */
int
(
*
parse
)(
int
c
,
char
**
argv
,
int
invert
,
unsigned
int
*
flags
,
const
struct
ipt_entry
*
entry
,
struct
ipt_entry_target
**
target
);
/* Final check; exit if not ok. */
void
(
*
final_check
)(
unsigned
int
flags
);
/* Prints out the target iff non-NULL: put space at end */
void
(
*
print
)(
const
struct
ipt_ip
*
ip
,
const
struct
ipt_entry_target
*
target
,
int
numeric
);
/* Saves the targinfo in parsable form to stdout. */
void
(
*
save
)(
const
struct
ipt_ip
*
ip
,
const
struct
ipt_entry_target
*
target
);
/* Pointer to list of extra command-line options */
struct
option
*
extra_opts
;
/* Ignore these men behind the curtain: */
unsigned
int
option_offset
;
struct
ipt_entry_target
*
t
;
unsigned
int
tflags
;
unsigned
int
used
;
#ifdef NO_SHARED_LIBS
unsigned
int
loaded
;
/* simulate loading so options are merged properly */
#endif
};
extern
int
line
;
/* Your shared library should call one of these. */
extern
void
register_match
(
struct
iptables_match
*
me
);
extern
void
register_target
(
struct
iptables_target
*
me
);
extern
struct
in_addr
*
dotted_to_addr
(
const
char
*
dotted
);
extern
char
*
addr_to_dotted
(
const
struct
in_addr
*
addrp
);
extern
char
*
addr_to_anyname
(
const
struct
in_addr
*
addr
);
extern
char
*
mask_to_dotted
(
const
struct
in_addr
*
mask
);
extern
void
parse_hostnetworkmask
(
const
char
*
name
,
struct
in_addr
**
addrpp
,
struct
in_addr
*
maskp
,
unsigned
int
*
naddrs
);
extern
u_int16_t
parse_protocol
(
const
char
*
s
);
extern
int
do_command
(
int
argc
,
char
*
argv
[],
char
**
table
,
iptc_handle_t
*
handle
);
/* Keeping track of external matches and targets: linked lists. */
extern
struct
iptables_match
*
iptables_matches
;
extern
struct
iptables_target
*
iptables_targets
;
enum
ipt_tryload
{
DONT_LOAD
,
TRY_LOAD
,
LOAD_MUST_SUCCEED
};
extern
struct
iptables_target
*
find_target
(
const
char
*
name
,
enum
ipt_tryload
);
extern
struct
iptables_match
*
find_match
(
const
char
*
name
,
enum
ipt_tryload
,
struct
iptables_rule_match
**
match
);
extern
int
delete_chain
(
const
ipt_chainlabel
chain
,
int
verbose
,
iptc_handle_t
*
handle
);
extern
int
flush_entries
(
const
ipt_chainlabel
chain
,
int
verbose
,
iptc_handle_t
*
handle
);
extern
int
for_each_chain
(
int
(
*
fn
)(
const
ipt_chainlabel
,
int
,
iptc_handle_t
*
),
int
verbose
,
int
builtinstoo
,
iptc_handle_t
*
handle
);
#endif
/*_IPTABLES_USER_H*/
include/iptables_common.h
View file @
1ffd7fd2
#ifndef _IPTABLES_COMMON_H
#define _IPTABLES_COMMON_H
/* Shared definitions between ipv4 and ipv6. */
enum
exittype
{
OTHER_PROBLEM
=
1
,
PARAMETER_PROBLEM
,
VERSION_PROBLEM
};
extern
void
exit_printhelp
(
void
)
__attribute__
((
noreturn
));
extern
void
exit_tryhelp
(
int
)
__attribute__
((
noreturn
));
int
check_inverse
(
const
char
option
[],
int
*
invert
,
int
*
optind
,
int
argc
);
extern
int
string_to_number
(
const
char
*
,
unsigned
int
,
unsigned
int
,
unsigned
int
*
);
extern
int
string_to_number_l
(
const
char
*
,
unsigned
long
int
,
unsigned
long
int
,
unsigned
long
*
);
extern
int
string_to_number_ll
(
const
char
*
,
unsigned
long
long
int
,
unsigned
long
long
int
,
unsigned
long
long
*
);
extern
int
iptables_insmod
(
const
char
*
modname
,
const
char
*
modprobe
);
void
exit_error
(
enum
exittype
,
char
*
,
...)
__attribute__
((
noreturn
,
format
(
printf
,
2
,
3
)));
extern
const
char
*
program_name
,
*
program_version
;
#ifdef NO_SHARED_LIBS
# ifdef _INIT
# define _init _INIT
# endif
extern
void
init_extensions
(
void
);
#endif
#endif
/*_IPTABLES_COMMON_H*/
include/libiptc/ipt_kernel_headers.h
View file @
1ffd7fd2
/* This is the userspace/kernel interface for Generic IP Chains,
required for libc6. */
#ifndef _FWCHAINS_KERNEL_HEADERS_H
#define _FWCHAINS_KERNEL_HEADERS_H
#include <limits.h>
#if defined(__GLIBC__) && __GLIBC__ == 2
#include <netinet/ip.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <net/if.h>
#include <sys/types.h>
#else
/* libc5 */
#include <sys/socket.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/if.h>
#include <linux/icmp.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/types.h>
#include <linux/in6.h>
#endif
#endif
include/libiptc/libip6tc.h
View file @
1ffd7fd2
#ifndef _LIBIP6TC_H
#define _LIBIP6TC_H
/* Library which manipulates firewall rules. Version 0.2. */
#include <libiptc/ipt_kernel_headers.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#ifndef IP6T_MIN_ALIGN
#define IP6T_MIN_ALIGN (__alignof__(struct ip6t_entry))
#endif
#define IP6T_ALIGN(s) (((s) + (IP6T_MIN_ALIGN-1)) & ~(IP6T_MIN_ALIGN-1))
typedef
char
ip6t_chainlabel
[
32
];
#define IP6TC_LABEL_ACCEPT "ACCEPT"
#define IP6TC_LABEL_DROP "DROP"
#define IP6TC_LABEL_QUEUE "QUEUE"
#define IP6TC_LABEL_RETURN "RETURN"
/* Transparent handle type. */
typedef
struct
ip6tc_handle
*
ip6tc_handle_t
;
/* Does this chain exist? */
int
ip6tc_is_chain
(
const
char
*
chain
,
const
ip6tc_handle_t
handle
);
/* Take a snapshot of the rules. Returns NULL on error. */
ip6tc_handle_t
ip6tc_init
(
const
char
*
tablename
);
/* Cleanup after ip6tc_init(). */
void
ip6tc_free
(
ip6tc_handle_t
*
h
);
/* Iterator functions to run through the chains. Returns NULL at end. */
const
char
*
ip6tc_first_chain
(
ip6tc_handle_t
*
handle
);
const
char
*
ip6tc_next_chain
(
ip6tc_handle_t
*
handle
);
/* Get first rule in the given chain: NULL for empty chain. */
const
struct
ip6t_entry
*
ip6tc_first_rule
(
const
char
*
chain
,
ip6tc_handle_t
*
handle
);
/* Returns NULL when rules run out. */
const
struct
ip6t_entry
*
ip6tc_next_rule
(
const
struct
ip6t_entry
*
prev
,
ip6tc_handle_t
*
handle
);
/* Returns a pointer to the target name of this position. */
const
char
*
ip6tc_get_target
(
const
struct
ip6t_entry
*
e
,
ip6tc_handle_t
*
handle
);
/* Is this a built-in chain? */
int
ip6tc_builtin
(
const
char
*
chain
,
const
ip6tc_handle_t
handle
);
/* Get the policy of a given built-in chain */
const
char
*
ip6tc_get_policy
(
const
char
*
chain
,
struct
ip6t_counters
*
counters
,
ip6tc_handle_t
*
handle
);
/* These functions return TRUE for OK or 0 and set errno. If errno ==
0, it means there was a version error (ie. upgrade libiptc). */
/* Rule numbers start at 1 for the first rule. */
/* Insert the entry `fw' in chain `chain' into position `rulenum'. */
int
ip6tc_insert_entry
(
const
ip6t_chainlabel
chain
,
const
struct
ip6t_entry
*
e
,
unsigned
int
rulenum
,
ip6tc_handle_t
*
handle
);
/* Atomically replace rule `rulenum' in `chain' with `fw'. */
int
ip6tc_replace_entry
(
const
ip6t_chainlabel
chain
,
const
struct
ip6t_entry
*
e
,
unsigned
int
rulenum
,
ip6tc_handle_t
*
handle
);
/* Append entry `fw' to chain `chain'. Equivalent to insert with
rulenum = length of chain. */
int
ip6tc_append_entry
(
const
ip6t_chainlabel
chain
,
const
struct
ip6t_entry
*
e
,
ip6tc_handle_t
*
handle
);
/* Delete the first rule in `chain' which matches `fw'. */
int
ip6tc_delete_entry
(
const
ip6t_chainlabel
chain
,
const
struct
ip6t_entry
*
origfw
,
unsigned
char
*
matchmask
,
ip6tc_handle_t
*
handle
);
/* Delete the rule in position `rulenum' in `chain'. */
int
ip6tc_delete_num_entry
(
const
ip6t_chainlabel
chain
,
unsigned
int
rulenum
,
ip6tc_handle_t
*
handle
);
/* Check the packet `fw' on chain `chain'. Returns the verdict, or
NULL and sets errno. */
const
char
*
ip6tc_check_packet
(
const
ip6t_chainlabel
chain
,
struct
ip6t_entry
*
,
ip6tc_handle_t
*
handle
);
/* Flushes the entries in the given chain (ie. empties chain). */
int
ip6tc_flush_entries
(
const
ip6t_chainlabel
chain
,
ip6tc_handle_t
*
handle
);
/* Zeroes the counters in a chain. */
int
ip6tc_zero_entries
(
const
ip6t_chainlabel
chain
,
ip6tc_handle_t
*
handle
);
/* Creates a new chain. */
int
ip6tc_create_chain
(
const
ip6t_chainlabel
chain
,
ip6tc_handle_t
*
handle
);
/* Deletes a chain. */
int
ip6tc_delete_chain
(
const
ip6t_chainlabel
chain
,
ip6tc_handle_t
*
handle
);
/* Renames a chain. */
int
ip6tc_rename_chain
(
const
ip6t_chainlabel
oldname
,
const
ip6t_chainlabel
newname
,
ip6tc_handle_t
*
handle
);
/* Sets the policy on a built-in chain. */
int
ip6tc_set_policy
(
const
ip6t_chainlabel
chain
,
const
ip6t_chainlabel
policy
,
struct
ip6t_counters
*
counters
,
ip6tc_handle_t
*
handle
);
/* Get the number of references to this chain */
int
ip6tc_get_references
(
unsigned
int
*
ref
,
const
ip6t_chainlabel
chain
,
ip6tc_handle_t
*
handle
);
/* read packet and byte counters for a specific rule */
struct
ip6t_counters
*
ip6tc_read_counter
(
const
ip6t_chainlabel
chain
,
unsigned
int
rulenum
,
ip6tc_handle_t
*
handle
);
/* zero packet and byte counters for a specific rule */
int
ip6tc_zero_counter
(
const
ip6t_chainlabel
chain
,
unsigned
int
rulenum
,
ip6tc_handle_t
*
handle
);
/* set packet and byte counters for a specific rule */
int
ip6tc_set_counter
(
const
ip6t_chainlabel
chain
,
unsigned
int
rulenum
,
struct
ip6t_counters
*
counters
,
ip6tc_handle_t
*
handle
);
/* Makes the actual changes. */
int
ip6tc_commit
(
ip6tc_handle_t
*
handle
);
/* Get raw socket. */
int
ip6tc_get_raw_socket
();
/* Translates errno numbers into more human-readable form than strerror. */
const
char
*
ip6tc_strerror
(
int
err
);
/* Return prefix length, or -1 if not contiguous */
int
ipv6_prefix_length
(
const
struct
in6_addr
*
a
);
#endif
/* _LIBIP6TC_H */
include/libiptc/libiptc.h
View file @
1ffd7fd2
#ifndef _LIBIPTC_H
#define _LIBIPTC_H
/* Library which manipulates filtering rules. */
#include <libiptc/ipt_kernel_headers.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#ifdef __cplusplus
extern
"C"
{
#endif
#ifndef IPT_MIN_ALIGN
/* ipt_entry has pointers and u_int64_t's in it, so if you align to
it, you'll also align to any crazy matches and targets someone
might write */
#define IPT_MIN_ALIGN (__alignof__(struct ipt_entry))
#endif
#define IPT_ALIGN(s) (((s) + ((IPT_MIN_ALIGN)-1)) & ~((IPT_MIN_ALIGN)-1))
typedef
char
ipt_chainlabel
[
32
];
#define IPTC_LABEL_ACCEPT "ACCEPT"
#define IPTC_LABEL_DROP "DROP"
#define IPTC_LABEL_QUEUE "QUEUE"
#define IPTC_LABEL_RETURN "RETURN"
/* Transparent handle type. */
typedef
struct
iptc_handle
*
iptc_handle_t
;
/* Does this chain exist? */
int
iptc_is_chain
(
const
char
*
chain
,
const
iptc_handle_t
handle
);
/* Take a snapshot of the rules. Returns NULL on error. */
iptc_handle_t
iptc_init
(
const
char
*
tablename
);
/* Cleanup after iptc_init(). */
void
iptc_free
(
iptc_handle_t
*
h
);
/* Iterator functions to run through the chains. Returns NULL at end. */
const
char
*
iptc_first_chain
(
iptc_handle_t
*
handle
);
const
char
*
iptc_next_chain
(
iptc_handle_t
*
handle
);
/* Get first rule in the given chain: NULL for empty chain. */
const
struct
ipt_entry
*
iptc_first_rule
(
const
char
*
chain
,
iptc_handle_t
*
handle
);
/* Returns NULL when rules run out. */
const
struct
ipt_entry
*
iptc_next_rule
(
const
struct
ipt_entry
*
prev
,
iptc_handle_t
*
handle
);
/* Returns a pointer to the target name of this entry. */
const
char
*
iptc_get_target
(
const
struct
ipt_entry
*
e
,
iptc_handle_t
*
handle
);
/* Is this a built-in chain? */
int
iptc_builtin
(
const
char
*
chain
,
const
iptc_handle_t
handle
);
/* Get the policy of a given built-in chain */
const
char
*
iptc_get_policy
(
const
char
*
chain
,
struct
ipt_counters
*
counter
,
iptc_handle_t
*
handle
);
/* These functions return TRUE for OK or 0 and set errno. If errno ==
0, it means there was a version error (ie. upgrade libiptc). */
/* Rule numbers start at 1 for the first rule. */
/* Insert the entry `e' in chain `chain' into position `rulenum'. */
int
iptc_insert_entry
(
const
ipt_chainlabel
chain
,
const
struct
ipt_entry
*
e
,
unsigned
int
rulenum
,
iptc_handle_t
*
handle
);
/* Atomically replace rule `rulenum' in `chain' with `e'. */
int
iptc_replace_entry
(
const
ipt_chainlabel
chain
,
const
struct
ipt_entry
*
e
,
unsigned
int
rulenum
,
iptc_handle_t
*
handle
);
/* Append entry `e' to chain `chain'. Equivalent to insert with
rulenum = length of chain. */
int
iptc_append_entry
(
const
ipt_chainlabel
chain
,
const
struct
ipt_entry
*
e
,
iptc_handle_t
*
handle
);
/* Delete the first rule in `chain' which matches `e', subject to
matchmask (array of length == origfw) */
int
iptc_delete_entry
(
const
ipt_chainlabel
chain
,
const
struct
ipt_entry
*
origfw
,
unsigned
char
*
matchmask
,
iptc_handle_t
*
handle
);
/* Delete the rule in position `rulenum' in `chain'. */
int
iptc_delete_num_entry
(
const
ipt_chainlabel
chain
,
unsigned
int
rulenum
,
iptc_handle_t
*
handle
);
/* Check the packet `e' on chain `chain'. Returns the verdict, or
NULL and sets errno. */
const
char
*
iptc_check_packet
(
const
ipt_chainlabel
chain
,
struct
ipt_entry
*
entry
,
iptc_handle_t
*
handle
);
/* Flushes the entries in the given chain (ie. empties chain). */
int
iptc_flush_entries
(
const
ipt_chainlabel
chain
,
iptc_handle_t
*
handle
);
/* Zeroes the counters in a chain. */
int
iptc_zero_entries
(
const
ipt_chainlabel
chain
,
iptc_handle_t
*
handle
);
/* Creates a new chain. */
int
iptc_create_chain
(
const
ipt_chainlabel
chain
,
iptc_handle_t
*
handle
);
/* Deletes a chain. */
int
iptc_delete_chain
(
const
ipt_chainlabel
chain
,
iptc_handle_t
*
handle
);
/* Renames a chain. */
int
iptc_rename_chain
(
const
ipt_chainlabel
oldname
,
const
ipt_chainlabel
newname
,
iptc_handle_t
*
handle
);
/* Sets the policy on a built-in chain. */
int
iptc_set_policy
(
const
ipt_chainlabel
chain
,
const
ipt_chainlabel
policy
,
struct
ipt_counters
*
counters
,
iptc_handle_t
*
handle
);
/* Get the number of references to this chain */
int
iptc_get_references
(
unsigned
int
*
ref
,
const
ipt_chainlabel
chain
,
iptc_handle_t
*
handle
);
/* read packet and byte counters for a specific rule */
struct
ipt_counters
*
iptc_read_counter
(
const
ipt_chainlabel
chain
,
unsigned
int
rulenum
,
iptc_handle_t
*
handle
);
/* zero packet and byte counters for a specific rule */
int
iptc_zero_counter
(
const
ipt_chainlabel
chain
,
unsigned
int
rulenum
,
iptc_handle_t
*
handle
);
/* set packet and byte counters for a specific rule */
int
iptc_set_counter
(
const
ipt_chainlabel
chain
,
unsigned
int
rulenum
,
struct
ipt_counters
*
counters
,
iptc_handle_t
*
handle
);
/* Makes the actual changes. */
int
iptc_commit
(
iptc_handle_t
*
handle
);
/* Get raw socket. */
int
iptc_get_raw_socket
(
void
);
/* Translates errno numbers into more human-readable form than strerror. */
const
char
*
iptc_strerror
(
int
err
);
#ifdef __cplusplus
}
#endif
#endif
/* _LIBIPTC_H */
include/linux/tc_act/tc_ipt.h
View file @
1ffd7fd2
#ifndef __LINUX_TC_IPT_H
#define __LINUX_TC_IPT_H
#include <linux/pkt_cls.h>
#define TCA_ACT_IPT 6
enum
{
TCA_IPT_UNSPEC
,
TCA_IPT_TABLE
,
TCA_IPT_HOOK
,
TCA_IPT_INDEX
,
TCA_IPT_CNT
,
TCA_IPT_TM
,
TCA_IPT_TARG
,
__TCA_IPT_MAX
};
#define TCA_IPT_MAX (__TCA_IPT_MAX - 1)
#endif
tc/Makefile
View file @
1ffd7fd2
...
...
@@ -22,6 +22,7 @@ TCMODULES += q_hfsc.o
TCMODULES
+=
q_htb.o
TCMODULES
+=
m_gact.o
TCMODULES
+=
m_mirred.o
TCMODULES
+=
m_ipt.o
TCOBJ
+=
$(TCMODULES)
...
...
tc/m_ipt.c
View file @
1ffd7fd2
/*
* m_ipt.c iptables based targets
* utilities mostly ripped from iptables <duh, its the linux way>
*
* This program is free software; you can distribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: J Hadi Salim (hadi@cyberus.ca)
*
* TODO: bad bad hardcoding IPT_LIB_DIR and PROC_SYS_MODPROBE
*
*/
#include <syslog.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iptables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include "utils.h"
#include "tc_util.h"
#include <linux/tc_act/tc_ipt.h>
#include <stdio.h>
#include <dlfcn.h>
#include <getopt.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
const
char
*
pname
=
"tc-ipt"
;
const
char
*
tname
=
"mangle"
;
const
char
*
pversion
=
"0.1"
;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef IPT_LIB_DIR
#define IPT_LIB_DIR "/usr/local/lib/iptables"
#endif
#ifndef PROC_SYS_MODPROBE
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
#endif
static
const
char
*
ipthooks
[]
=
{
"NF_IP_PRE_ROUTING"
,
"NF_IP_LOCAL_IN"
,
"NF_IP_FORWARD"
,
"NF_IP_LOCAL_OUT"
,
"NF_IP_POST_ROUTING"
,
};
static
struct
option
original_opts
[]
=
{
{
"jump"
,
1
,
0
,
'j'
},
{
0
,
0
,
0
,
0
}
};
static
struct
iptables_target
*
t_list
=
NULL
;
static
unsigned
int
global_option_offset
=
0
;
#define OPTION_OFFSET 256
#if 0
/* no clue why register match is within targets
figure out later. Talk to Harald -- JHS
*/
void
register_match(struct iptables_match *me)
{
/* fprintf(stderr, "\nDummy register_match\n"); */
}
void
register_target(struct iptables_target *me)
{
/* fprintf(stderr, "\nDummy register_target %s \n", me->name);
*/
me->next = t_list;
t_list = me;
}
#endif
void
exit_tryhelp
(
int
status
)
{
fprintf
(
stderr
,
"Try `%s -h' or '%s --help' for more information.
\n
"
,
pname
,
pname
);
exit
(
status
);
}
void
exit_error
(
enum
exittype
status
,
char
*
msg
,
...)
{
va_list
args
;
va_start
(
args
,
msg
);
fprintf
(
stderr
,
"%s v%s: "
,
pname
,
pversion
);
vfprintf
(
stderr
,
msg
,
args
);
va_end
(
args
);
fprintf
(
stderr
,
"
\n
"
);
if
(
status
==
PARAMETER_PROBLEM
)
exit_tryhelp
(
status
);
if
(
status
==
VERSION_PROBLEM
)
fprintf
(
stderr
,
"Perhaps iptables or your kernel needs to be upgraded.
\n
"
);
exit
(
status
);
}
/* stolen from iptables 1.2.11
They should really have them as a library so i can link to them
Email them next time i remember
*/
char
*
addr_to_dotted
(
const
struct
in_addr
*
addrp
)
{
static
char
buf
[
20
];
const
unsigned
char
*
bytep
;
bytep
=
(
const
unsigned
char
*
)
&
(
addrp
->
s_addr
);
sprintf
(
buf
,
"%d.%d.%d.%d"
,
bytep
[
0
],
bytep
[
1
],
bytep
[
2
],
bytep
[
3
]);
return
buf
;
}
int
string_to_number_ll
(
const
char
*
s
,
unsigned
long
long
min
,
unsigned
long
long
max
,
unsigned
long
long
*
ret
)
{
unsigned
long
long
number
;
char
*
end
;
/* Handle hex, octal, etc. */
errno
=
0
;
number
=
strtoull
(
s
,
&
end
,
0
);
if
(
*
end
==
'\0'
&&
end
!=
s
)
{
/* we parsed a number, let's see if we want this */
if
(
errno
!=
ERANGE
&&
min
<=
number
&&
(
!
max
||
number
<=
max
))
{
*
ret
=
number
;
return
0
;
}
}
return
-
1
;
}
int
string_to_number_l
(
const
char
*
s
,
unsigned
long
min
,
unsigned
long
max
,
unsigned
long
*
ret
)
{
int
result
;
unsigned
long
long
number
;
result
=
string_to_number_ll
(
s
,
min
,
max
,
&
number
);
*
ret
=
(
unsigned
long
)
number
;
return
result
;
}
int
string_to_number
(
const
char
*
s
,
unsigned
int
min
,
unsigned
int
max
,
unsigned
int
*
ret
)
{
int
result
;
unsigned
long
number
;
result
=
string_to_number_l
(
s
,
min
,
max
,
&
number
);
*
ret
=
(
unsigned
int
)
number
;
return
result
;
}
#if 0
static int
string_to_number(const char *s, unsigned int min, unsigned int max,
unsigned int *ret)
{
long number;
char *end;
/* Handle hex, octal, etc. */
errno = 0;
number = strtol(s, &end, 0);
if (*end == '\0' && end != s) {
/* we parsed a number, let's see if we want this */
if (errno != ERANGE && min <= number && number <= max) {
*ret = number;
return 0;
}
}
return -1;
}
#endif
static
struct
option
*
copy_options
(
struct
option
*
oldopts
)
{
struct
option
*
merge
;
unsigned
int
num_old
;
for
(
num_old
=
0
;
oldopts
[
num_old
].
name
;
num_old
++
)
;
merge
=
malloc
(
sizeof
(
struct
option
)
*
(
num_old
+
1
));
if
(
NULL
==
merge
)
return
NULL
;
memcpy
(
merge
,
oldopts
,
num_old
*
sizeof
(
struct
option
));
memset
(
merge
+
num_old
,
0
,
sizeof
(
struct
option
));
return
merge
;
}
static
struct
option
*
merge_options
(
struct
option
*
oldopts
,
const
struct
option
*
newopts
,
unsigned
int
*
option_offset
)
{
struct
option
*
merge
;
unsigned
int
num_old
,
num_new
,
i
;
for
(
num_old
=
0
;
oldopts
[
num_old
].
name
;
num_old
++
)
;
for
(
num_new
=
0
;
newopts
[
num_new
].
name
;
num_new
++
)
;
*
option_offset
=
global_option_offset
+
OPTION_OFFSET
;
merge
=
malloc
(
sizeof
(
struct
option
)
*
(
num_new
+
num_old
+
1
));
memcpy
(
merge
,
oldopts
,
num_old
*
sizeof
(
struct
option
));
for
(
i
=
0
;
i
<
num_new
;
i
++
)
{
merge
[
num_old
+
i
]
=
newopts
[
i
];
merge
[
num_old
+
i
].
val
+=
*
option_offset
;
}
memset
(
merge
+
num_old
+
num_new
,
0
,
sizeof
(
struct
option
));
return
merge
;
}
static
void
*
fw_calloc
(
size_t
count
,
size_t
size
)
{
void
*
p
;
if
((
p
=
(
void
*
)
calloc
(
count
,
size
))
==
NULL
)
{
perror
(
"iptables: calloc failed"
);
exit
(
1
);
}
return
p
;
}
#if 0
static void *
fw_malloc(size_t size)
{
void *p;
if ((p = (void *) malloc(size)) == NULL) {
perror("iptables: malloc failed");
exit(1);
}
return p;
}
static int
check_inverse(const char option[], int *invert)
{
if (option && strcmp(option, "!") == 0) {
if (*invert)
exit_error(PARAMETER_PROBLEM,
"Multiple `!' flags not allowed");
*invert = TRUE;
return TRUE;
}
return FALSE;
}
#endif
static
struct
iptables_target
*
find_t
(
char
*
name
)
{
struct
iptables_target
*
m
;
for
(
m
=
t_list
;
m
;
m
=
m
->
next
)
{
if
(
strcmp
(
m
->
name
,
name
)
==
0
)
return
m
;
}
return
NULL
;
}
static
struct
iptables_target
*
get_target_name
(
char
*
name
)
{
void
*
handle
;
char
*
error
;
char
*
new_name
,
*
lname
;
struct
iptables_target
*
m
;
char
path
[
sizeof
(
IPT_LIB_DIR
)
+
sizeof
(
"/libipt_.so"
)
+
strlen
(
name
)];
new_name
=
malloc
(
strlen
(
name
)
+
1
);
lname
=
malloc
(
strlen
(
name
)
+
1
);
if
(
new_name
)
memset
(
new_name
,
'\0'
,
strlen
(
name
)
+
1
);
else
exit_error
(
PARAMETER_PROBLEM
,
"get_target_name"
);
if
(
lname
)
memset
(
lname
,
'\0'
,
strlen
(
name
)
+
1
);
else
exit_error
(
PARAMETER_PROBLEM
,
"get_target_name"
);
strcpy
(
new_name
,
name
);
strcpy
(
lname
,
name
);
if
(
isupper
(
lname
[
0
]))
{
int
i
;
for
(
i
=
0
;
i
<
strlen
(
name
);
i
++
)
{
lname
[
i
]
=
tolower
(
lname
[
i
]);
}
}
if
(
islower
(
new_name
[
0
]))
{
int
i
;
for
(
i
=
0
;
i
<
strlen
(
new_name
);
i
++
)
{
new_name
[
i
]
=
toupper
(
new_name
[
i
]);
}
}
sprintf
(
path
,
IPT_LIB_DIR
"/libipt_%s.so"
,
new_name
);
handle
=
dlopen
(
path
,
RTLD_LAZY
);
if
(
!
handle
)
{
sprintf
(
path
,
IPT_LIB_DIR
"/libipt_%s.so"
,
lname
);
handle
=
dlopen
(
path
,
RTLD_LAZY
);
if
(
!
handle
)
{
fputs
(
dlerror
(),
stderr
);
printf
(
"
\n
"
);
return
NULL
;
}
}
m
=
dlsym
(
handle
,
new_name
);
if
((
error
=
dlerror
())
!=
NULL
)
{
m
=
(
struct
iptables_target
*
)
dlsym
(
handle
,
lname
);
if
((
error
=
dlerror
())
!=
NULL
)
{
m
=
find_t
(
new_name
);
if
(
NULL
==
m
)
{
m
=
find_t
(
lname
);
if
(
NULL
==
m
)
{
fputs
(
error
,
stderr
);
fprintf
(
stderr
,
"
\n
"
);
dlclose
(
handle
);
return
NULL
;
}
}
}
}
return
m
;
}
#if 0
static char *
addr_to_dotted(const struct in_addr *addrp)
{
static char buf[20];
const unsigned char *bytep;
bytep = (const unsigned char *) &(addrp->s_addr);
sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
return buf;
}
#endif
struct
in_addr
*
dotted_to_addr
(
const
char
*
dotted
)
{
static
struct
in_addr
addr
;
unsigned
char
*
addrp
;
char
*
p
,
*
q
;
unsigned
int
onebyte
;
int
i
;
char
buf
[
20
];
/* copy dotted string, because we need to modify it */
strncpy
(
buf
,
dotted
,
sizeof
(
buf
)
-
1
);
addrp
=
(
unsigned
char
*
)
&
(
addr
.
s_addr
);
p
=
buf
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
if
((
q
=
strchr
(
p
,
'.'
))
==
NULL
)
return
(
struct
in_addr
*
)
NULL
;
*
q
=
'\0'
;
if
(
string_to_number
(
p
,
0
,
255
,
&
onebyte
)
==
-
1
)
return
(
struct
in_addr
*
)
NULL
;
addrp
[
i
]
=
(
unsigned
char
)
onebyte
;
p
=
q
+
1
;
}
/* we've checked 3 bytes, now we check the last one */
if
(
string_to_number
(
p
,
0
,
255
,
&
onebyte
)
==
-
1
)
return
(
struct
in_addr
*
)
NULL
;
addrp
[
3
]
=
(
unsigned
char
)
onebyte
;
return
&
addr
;
}
int
build_st
(
struct
iptables_target
*
target
,
struct
ipt_entry_target
*
t
)
{
unsigned
int
nfcache
=
0
;
if
(
target
)
{
size_t
size
;
size
=
IPT_ALIGN
(
sizeof
(
struct
ipt_entry_target
))
+
target
->
size
;
if
(
NULL
==
t
)
{
target
->
t
=
fw_calloc
(
1
,
size
);
target
->
init
(
target
->
t
,
&
nfcache
);
target
->
t
->
u
.
target_size
=
size
;
}
else
{
target
->
t
=
t
;
}
strcpy
(
target
->
t
->
u
.
user
.
name
,
target
->
name
);
return
0
;
}
return
-
1
;
}
static
int
parse_ipt
(
struct
action_util
*
a
,
int
*
argc_p
,
char
***
argv_p
,
int
tca_id
,
struct
nlmsghdr
*
n
)
{
struct
iptables_target
*
m
=
NULL
;
struct
ipt_entry
fw
;
struct
rtattr
*
tail
;
int
c
;
int
rargc
=
*
argc_p
;
char
**
argv
=
*
argv_p
;
struct
option
*
opts
;
int
argc
=
0
,
iargc
=
0
;
char
k
[
16
];
int
res
=
-
1
;
int
size
=
0
;
int
iok
=
0
,
ok
=
0
;
__u32
hook
=
0
,
index
=
0
;
res
=
0
;
{
int
i
;
for
(
i
=
0
;
i
<
rargc
;
i
++
)
{
if
(
NULL
==
argv
[
i
]
||
0
==
strcmp
(
argv
[
i
],
"action"
))
{
break
;
}
}
iargc
=
argc
=
i
;
}
if
(
argc
<=
2
)
{
fprintf
(
stderr
,
"bad arguements to ipt %d vs %d
\n
"
,
argc
,
rargc
);
return
-
1
;
}
opts
=
copy_options
(
original_opts
);
if
(
NULL
==
opts
)
return
-
1
;
while
(
1
)
{
c
=
getopt_long
(
argc
,
argv
,
"j:"
,
opts
,
NULL
);
if
(
c
==
-
1
)
break
;
switch
(
c
)
{
case
'j'
:
m
=
get_target_name
(
optarg
);
if
(
NULL
!=
m
)
{
if
(
0
>
build_st
(
m
,
NULL
))
{
printf
(
" %s error
\n
"
,
m
->
name
);
return
-
1
;
}
opts
=
merge_options
(
opts
,
m
->
extra_opts
,
&
m
->
option_offset
);
}
else
{
fprintf
(
stderr
,
" failed to find target %s
\n\n
"
,
optarg
);
return
-
1
;
}
ok
++
;
break
;
default:
memset
(
&
fw
,
0
,
sizeof
(
fw
));
if
(
m
)
{
unsigned
int
fake_flags
=
0
;
m
->
parse
(
c
-
m
->
option_offset
,
argv
,
0
,
&
fake_flags
,
NULL
,
&
m
->
t
);
}
else
{
fprintf
(
stderr
,
" failed to find target %s
\n\n
"
,
optarg
);
return
-
1
;
}
ok
++
;
/*m->final_check(m->t); -- Is this necessary?
** useful when theres depencies
** eg ipt_TCPMSS.c has have the TCP match loaded
** before this can be used;
** also seems the ECN target needs it
*/
break
;
}
}
if
(
iargc
>
optind
)
{
if
(
matches
(
argv
[
optind
],
"index"
)
==
0
)
{
if
(
get_u32
(
&
index
,
argv
[
optind
+
1
],
10
))
{
fprintf
(
stderr
,
"Illegal
\"
index
\"\n
"
);
return
-
1
;
}
iok
++
;
optind
+=
2
;
}
}
if
(
!
ok
&&
!
iok
)
{
fprintf
(
stderr
,
" ipt Parser BAD!! (%s)
\n
"
,
*
argv
);
return
-
1
;
}
{
struct
tcmsg
*
t
=
NLMSG_DATA
(
n
);
if
(
t
->
tcm_parent
!=
TC_H_ROOT
&&
t
->
tcm_parent
==
TC_H_MAJ
(
TC_H_INGRESS
))
{
hook
=
NF_IP_PRE_ROUTING
;
}
else
{
hook
=
NF_IP_POST_ROUTING
;
}
}
tail
=
(
struct
rtattr
*
)
(((
void
*
)
n
)
+
NLMSG_ALIGN
(
n
->
nlmsg_len
));
addattr_l
(
n
,
MAX_MSG
,
tca_id
,
NULL
,
0
);
fprintf
(
stdout
,
"tablename: %s hook: %s
\n
"
,
tname
,
ipthooks
[
hook
]);
fprintf
(
stdout
,
"
\t
target: "
);
if
(
m
)
m
->
print
(
NULL
,
m
->
t
,
0
);
fprintf
(
stdout
,
" index %d
\n
"
,
index
);
if
(
strlen
(
tname
)
>
16
)
{
size
=
16
;
k
[
15
]
=
0
;
}
else
{
size
=
1
+
strlen
(
tname
);
}
strncpy
(
k
,
tname
,
size
);
addattr_l
(
n
,
MAX_MSG
,
TCA_IPT_TABLE
,
k
,
size
);
addattr_l
(
n
,
MAX_MSG
,
TCA_IPT_HOOK
,
&
hook
,
4
);
addattr_l
(
n
,
MAX_MSG
,
TCA_IPT_INDEX
,
&
index
,
4
);
if
(
m
)
addattr_l
(
n
,
MAX_MSG
,
TCA_IPT_TARG
,
m
->
t
,
m
->
t
->
u
.
target_size
);
tail
->
rta_len
=
(((
void
*
)
n
)
+
NLMSG_ALIGN
(
n
->
nlmsg_len
))
-
(
void
*
)
tail
;
argc
-=
optind
;
argv
+=
optind
;
*
argc_p
=
rargc
-
iargc
;
*
argv_p
=
argv
;
optind
=
1
;
return
0
;
}
static
int
print_ipt
(
struct
action_util
*
au
,
FILE
*
f
,
struct
rtattr
*
arg
)
{
struct
rtattr
*
tb
[
TCA_IPT_MAX
+
1
];
struct
ipt_entry_target
*
t
=
NULL
;
struct
option
*
opts
;
if
(
arg
==
NULL
)
return
-
1
;
opts
=
copy_options
(
original_opts
);
if
(
NULL
==
opts
)
return
-
1
;
memset
(
tb
,
0
,
sizeof
(
tb
));
parse_rtattr
(
tb
,
TCA_IPT_MAX
,
RTA_DATA
(
arg
),
RTA_PAYLOAD
(
arg
));
if
(
tb
[
TCA_IPT_TABLE
]
==
NULL
)
{
fprintf
(
f
,
"[NULL ipt table name ] assuming mangle "
);
}
else
{
fprintf
(
f
,
"tablename: %s "
,
(
char
*
)
RTA_DATA
(
tb
[
TCA_IPT_TABLE
]));
}
if
(
tb
[
TCA_IPT_HOOK
]
==
NULL
)
{
fprintf
(
f
,
"[NULL ipt hook name ]
\n
"
);
return
-
1
;
}
else
{
__u32
hook
;
hook
=
*
(
__u32
*
)
RTA_DATA
(
tb
[
TCA_IPT_HOOK
]);
fprintf
(
f
,
" hook: %s
\n
"
,
ipthooks
[
hook
]);
}
if
(
tb
[
TCA_IPT_TARG
]
==
NULL
)
{
fprintf
(
f
,
"
\t
[NULL ipt target parameters ]
\n
"
);
return
-
1
;
}
else
{
struct
iptables_target
*
m
=
NULL
;
t
=
RTA_DATA
(
tb
[
TCA_IPT_TARG
]);
m
=
get_target_name
(
t
->
u
.
user
.
name
);
if
(
NULL
!=
m
)
{
if
(
0
>
build_st
(
m
,
t
))
{
fprintf
(
stderr
,
" %s error
\n
"
,
m
->
name
);
return
-
1
;
}
opts
=
merge_options
(
opts
,
m
->
extra_opts
,
&
m
->
option_offset
);
}
else
{
fprintf
(
stderr
,
" failed to find target %s
\n\n
"
,
t
->
u
.
user
.
name
);
return
-
1
;
}
fprintf
(
f
,
"
\t
target "
);
m
->
print
(
NULL
,
m
->
t
,
0
);
if
(
tb
[
TCA_IPT_INDEX
]
==
NULL
)
{
fprintf
(
f
,
" [NULL ipt target index ]
\n
"
);
}
else
{
__u32
index
;
index
=
*
(
__u32
*
)
RTA_DATA
(
tb
[
TCA_IPT_INDEX
]);
fprintf
(
f
,
"
\n\t
index %d"
,
index
);
}
if
(
tb
[
TCA_IPT_CNT
])
{
struct
tc_cnt
*
c
=
RTA_DATA
(
tb
[
TCA_IPT_CNT
]);;
fprintf
(
f
,
" ref %d bind %d"
,
c
->
refcnt
,
c
->
bindcnt
);
}
if
(
show_stats
)
{
if
(
tb
[
TCA_IPT_TM
])
{
struct
tcf_t
*
tm
=
RTA_DATA
(
tb
[
TCA_IPT_TM
]);
print_tm
(
f
,
tm
);
}
}
fprintf
(
f
,
"
\n
"
);
}
return
0
;
}
struct
action_util
ipt_action_util
=
{
.
id
=
"ipt"
,
.
parse_aopt
=
parse_ipt
,
.
print_aopt
=
print_ipt
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment