@@ -34,49 +34,29 @@ I make full userdata out of one or both of them, thats what it has to be. Don't
34
34
confuse them, or you will segfault!
35
35
*/
36
36
37
-
38
- #include "lua.h"
39
- #include "lauxlib.h"
40
- #include "lualib.h"
41
-
42
- #include <assert.h>
43
- #include <errno.h>
44
- #include <stdio.h>
45
- #include <stdlib.h>
46
- #include <string.h>
47
- #include <unistd.h>
48
-
49
- #include <netinet/in.h>
50
- #include <netinet/ip.h>
51
- #include <netinet/tcp.h>
52
- #include <netinet/udp.h>
53
-
54
- #include <linux/netfilter.h>
55
- #include <linux/types.h>
37
+ #include "nflua.h"
56
38
57
39
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
58
40
59
- #include "nflua.h"
60
-
61
41
#define NFCT_REGID "wt.nfct"
62
42
63
43
64
- static struct nf_conntrack * check_ct (lua_State * L )
44
+ static struct nfct_handle * check_cthandle (lua_State * L )
65
45
{
66
- struct nf_conntrack * ct = lua_touserdata (L , 1 );
46
+ struct nfct_handle * cth = lua_touserdata (L , 1 );
67
47
68
- luaL_argcheck (L , ct , 1 , "conntrack not provided" );
48
+ luaL_argcheck (L , cth , 1 , "conntrack handle not provided" );
69
49
70
- return ct ;
50
+ return cth ;
71
51
}
72
52
73
- static struct nfct_handle * check_cthandle (lua_State * L )
53
+ static struct nf_conntrack * check_ct (lua_State * L )
74
54
{
75
- struct nfct_handle * cth = lua_touserdata (L , 1 );
55
+ struct nf_conntrack * ct = lua_touserdata (L , 1 );
76
56
77
- luaL_argcheck (L , cth , 1 , "conntrack handle not provided" );
57
+ luaL_argcheck (L , ct , 1 , "conntrack not provided" );
78
58
79
- return cth ;
59
+ return ct ;
80
60
}
81
61
82
62
static const char * ctmsg_type_string (enum nf_conntrack_msg_type type )
@@ -104,7 +84,7 @@ Returns a conntrack handle on success, or nil,emsg,errno on failure.
104
84
There is no garbage collection, nfct.fini() must be called on the handle to
105
85
release it's resources.
106
86
*/
107
- static int open (lua_State * L )
87
+ static int hopen (lua_State * L )
108
88
{
109
89
static const char * subsys_opts [] = {
110
90
"track" , "expect" , NULL
@@ -145,7 +125,7 @@ static int open(lua_State *L)
145
125
assert (subsys_opt == 0 || subsys_opt == 1 );
146
126
147
127
for (narg = 2 ; narg <= lua_gettop (L ); narg ++ ) {
148
- int subscription_opt = luaL_checkoption (L , 1 , "none" , subscription_opts );
128
+ int subscription_opt = luaL_checkoption (L , narg , "none" , subscription_opts );
149
129
subscription_val |= subscription_vals [subsys_opt ][subscription_opt ];
150
130
}
151
131
@@ -186,6 +166,18 @@ static int fd(lua_State* L)
186
166
return 1 ;
187
167
}
188
168
169
+ /*-
170
+ -- cthandle = nfct.setblocking(cthandle, [blocking])
171
+
172
+ blocking is true to set blocking, and false to set non-blocking (default is false)
173
+
174
+ Return is cthandle on success, or nil,emsg,errno on failure.
175
+ */
176
+ static int setblocking (lua_State * L )
177
+ {
178
+ return nfsetblocking (L , nfct_fd (check_cthandle (L )));
179
+ }
180
+
189
181
static int cb (
190
182
enum nf_conntrack_msg_type type ,
191
183
struct nf_conntrack * ct ,
@@ -559,10 +551,20 @@ static enum nf_conntrack_attr check_attr(lua_State* L)
559
551
return attr_val ;
560
552
}
561
553
554
+ /*
555
+ TODO
556
+ get_attr_ip() -- ip in presentation format
557
+ get_attr_port() -- port as a number (cvt to host byte order)
558
+ get_attr_l3proto() -- protocol as string (or number if unrecognized)
559
+ get_attr_l4proto() -- "" ""
560
+ */
562
561
/*-
563
562
-- value = nfct.get_attr_u8(ct, attr)
564
563
-- value = nfct.get_attr_u16(ct, attr)
565
564
-- value = nfct.get_attr_u32(ct, attr)
565
+ -- value = nfct.get_attr_n16(ct, attr)
566
+ -- value = nfct.get_attr_n32(ct, attr)
567
+ -- value = nfct.get_attr_port(ct, attr)
566
568
567
569
No error checking is done, values of zero will be returned for
568
570
attributes that aren't present, and undefined values will be returned
@@ -571,6 +573,11 @@ the attribute value may be in network byte order.
571
573
572
574
ct is a conntrack context (NOT a conntrack handle, do not mix the two).
573
575
576
+ get_attr_n#() is like the "u" version, but it converts the number from network
577
+ to host byte order.
578
+
579
+ get_attr_port() is an alias for get_attr_n16(), since TCP and UDP ports are n16.
580
+
574
581
attr is one of:
575
582
"orig-ipv4-src", -- u32 bits
576
583
"orig-ipv4-dst", -- u32 bits
@@ -634,24 +641,45 @@ attr is one of:
634
641
635
642
See enum nf_conntrack_attr (the aliases are not supported)
636
643
*/
637
- /* TODO this could have a much better API, but I've no time for this now. */
638
-
644
+ /* FIXME - I really need the aliases back in, they aren't just for backwards
645
+ * compatibility, they are the best names to use, usually.
646
+ */
639
647
/*-
640
648
-- ct = nfct.set_attr_u8(ct, attr, value)
641
649
-- ct = nfct.set_attr_u16(ct, attr, value)
642
650
-- ct = nfct.set_attr_u32(ct, attr, value)
651
+ -- ct = nfct.set_attr_n16(ct, attr, value)
652
+ -- ct = nfct.set_attr_n32(ct, attr, value)
643
653
644
654
No error checking is done, value will be cast to the necessary type, and who
645
655
knows what will happen for values that aren't actually of the correct type for
646
656
the attribute. The attribute value may need to be in network byte order.
647
657
648
658
ct is a conntrack context (NOT a conntrack handle, do not mix the two).
649
659
650
- See nfct.get_attr_*() for the supported attr names.
660
+ See nfct.get_attr_*() for the supported attr names and types .
651
661
652
662
Returns the conntrack conntext, so calls can be chained.
653
663
*/
654
664
665
+ /* Pretent nfct implements these, so I can construct setters/getters using my macro. */
666
+ static u_int16_t nfct_get_attr_n16 (struct nf_conntrack * ct , enum nf_conntrack_attr attr )
667
+ {
668
+ return ntohs (nfct_get_attr_u16 (ct , attr ));
669
+ }
670
+ static u_int32_t nfct_get_attr_n32 (struct nf_conntrack * ct , enum nf_conntrack_attr attr )
671
+ {
672
+ return ntohl (nfct_get_attr_u32 (ct , attr ));
673
+ }
674
+ static void nfct_set_attr_n16 (struct nf_conntrack * ct , enum nf_conntrack_attr attr , u_int16_t value )
675
+ {
676
+ nfct_set_attr_u16 (ct , attr , htons (value ));
677
+ }
678
+ static void nfct_set_attr_n32 (struct nf_conntrack * ct , enum nf_conntrack_attr attr , u_int32_t value )
679
+ {
680
+ nfct_set_attr_u32 (ct , attr , htonl (value ));
681
+ }
682
+
655
683
/*
656
684
static int get_attr_u8(lua_State* L)
657
685
{
@@ -664,11 +692,79 @@ static int get_attr_u8(lua_State* L)
664
692
static int get_attr_##ux(lua_State* L) \
665
693
{ lua_pushinteger(L, nfct_get_attr_##ux(check_ct(L), check_attr(L))); return 1; } \
666
694
static int set_attr_##ux(lua_State* L) \
667
- { nfct_set_attr_##ux(check_ct(L), check_attr(L), luaL_checklong(L,3)); return 1; }
695
+ { nfct_set_attr_##ux(check_ct(L), check_attr(L), luaL_checklong(L,3)); lua_settop(L, 1); return 1; }
696
+
697
+ /* should I add checks for existence of the attribute? I doubt performance is
698
+ * an issue, so why not return
699
+ * nil and emsg when attr isn't present
700
+ */
668
701
669
702
ATTR_UX (u8 )
670
703
ATTR_UX (u16 )
671
704
ATTR_UX (u32 )
705
+ ATTR_UX (n16 )
706
+ ATTR_UX (n32 )
707
+
708
+ /*-
709
+ -- value = nfct.get_attr_ipv4(ct, attr)
710
+ -- value = nfct.get_attr_ipv6(ct, attr)
711
+ -- ct = nfct.set_attr_ipv4(ct, attr, value)
712
+
713
+ Get an attribute as a string, the internet address in presentation format.
714
+
715
+ See inet_ntop(3) for more information.
716
+
717
+ Return is the presentation address, or nil,emsg,errno on failure.
718
+ */
719
+ static int get_attr_ipvx (lua_State * L , int af , const void * src )
720
+ {
721
+ char dst [INET6_ADDRSTRLEN ];
722
+ const char * p = inet_ntop (af , src , dst , sizeof (dst ));
723
+ if (!p ) {
724
+ return push_error (L );
725
+ }
726
+ lua_pushstring (L , p );
727
+ return 1 ;
728
+ }
729
+
730
+ static int get_attr_ipv4 (lua_State * L )
731
+ {
732
+ return get_attr_ipvx (L ,
733
+ AF_INET ,
734
+ nfct_get_attr (check_ct (L ), check_attr (L )));
735
+ }
736
+
737
+ static int get_attr_ipv6 (lua_State * L )
738
+ {
739
+ return get_attr_ipvx (L ,
740
+ AF_INET6 ,
741
+ nfct_get_attr (check_ct (L ), check_attr (L )));
742
+ }
743
+
744
+ static int set_attr_ipvx (lua_State * L , int af )
745
+ {
746
+ unsigned char buf [sizeof (struct in6_addr )];
747
+
748
+ if (!inet_pton (af , luaL_checkstring (L , 3 ), buf )) {
749
+ return push_error (L );
750
+ }
751
+
752
+ nfct_set_attr (check_ct (L ), check_attr (L ), buf );
753
+
754
+ lua_settop (L , 1 );
755
+
756
+ return 1 ;
757
+ }
758
+
759
+ static int set_attr_ipv4 (lua_State * L )
760
+ {
761
+ return set_attr_ipvx (L , AF_INET );
762
+ }
763
+
764
+ static int set_attr_ipv6 (lua_State * L )
765
+ {
766
+ return set_attr_ipvx (L , AF_INET6 );
767
+ }
672
768
673
769
/*-
674
770
-- h = nfct.ntohs(n)
@@ -692,9 +788,10 @@ static int cthtons(lua_State* L)
692
788
static const luaL_reg nfct [] =
693
789
{
694
790
/* return or operate on cthandle */
695
- {"open" , open },
791
+ {"open" , hopen },
696
792
{"close" , gc },
697
793
{"fd" , fd },
794
+ {"setblocking" , setblocking },
698
795
{"callback_register" , callback_register },
699
796
{"catch" , catch },
700
797
{"loop" , loop },
@@ -706,9 +803,19 @@ static const luaL_reg nfct[] =
706
803
{"get_attr_u8" , get_attr_u8 },
707
804
{"get_attr_u16" , get_attr_u16 },
708
805
{"get_attr_u32" , get_attr_u32 },
806
+ {"get_attr_n16" , get_attr_n16 },
807
+ {"get_attr_n32" , get_attr_n32 },
808
+ {"get_attr_ipv4" , get_attr_ipv4 },
809
+ {"get_attr_ipv6" , get_attr_ipv6 },
810
+ {"get_attr_port" , get_attr_n16 },
709
811
{"set_attr_u8" , set_attr_u8 },
710
812
{"set_attr_u16" , set_attr_u16 },
711
813
{"set_attr_u32" , set_attr_u32 },
814
+ {"set_attr_n16" , set_attr_n16 },
815
+ {"set_attr_n32" , set_attr_n32 },
816
+ {"set_attr_ipv4" , set_attr_ipv4 },
817
+ {"set_attr_ipv6" , set_attr_ipv6 },
818
+ {"set_attr_port" , set_attr_n16 },
712
819
713
820
/* attr value conversion */
714
821
{"ntohs" , ctntohs },
0 commit comments