8
8
// 3) run it as root:
9
9
// sudo ../target/debug/examples/nflog
10
10
11
- use std:: time:: Duration ;
11
+ use std:: { net :: Ipv4Addr , time:: Duration } ;
12
12
13
+ use byteorder:: { ByteOrder , NetworkEndian } ;
13
14
use netlink_packet_netfilter:: {
14
15
constants:: * ,
15
- message:: NetfilterMessage ,
16
+ message:: { NetfilterMessage , NetfilterMessageInner } ,
16
17
nflog:: {
17
18
self ,
18
19
config:: { ConfigCmd , ConfigFlags , ConfigMode , Timeout } ,
20
+ packet:: PacketNla ,
21
+ NfLogMessage ,
19
22
} ,
20
23
NetlinkMessage ,
21
24
NetlinkPayload ,
22
25
} ;
23
26
use netlink_sys:: { constants:: NETLINK_NETFILTER , Socket } ;
24
27
28
+ fn get_packet_nlas ( message : & NetlinkMessage < NetfilterMessage > ) -> & [ PacketNla ] {
29
+ if let NetlinkPayload :: InnerMessage ( NetfilterMessage {
30
+ inner : NetfilterMessageInner :: NfLog ( NfLogMessage :: Packet ( nlas) ) ,
31
+ ..
32
+ } ) = & message. payload
33
+ {
34
+ nlas
35
+ } else {
36
+ & [ ]
37
+ }
38
+ }
39
+
25
40
fn main ( ) {
26
41
let mut receive_buffer = vec ! [ 0 ; 4096 ] ;
27
42
@@ -51,7 +66,7 @@ fn main() {
51
66
vec ! [
52
67
ConfigCmd :: Bind . into( ) ,
53
68
ConfigFlags :: SEQ_GLOBAL . into( ) ,
54
- ConfigMode :: new_packet ( 16 ) . into( ) ,
69
+ ConfigMode :: PACKET_MAX . into( ) ,
55
70
timeout. into( ) ,
56
71
] ,
57
72
) ;
@@ -67,23 +82,32 @@ fn main() {
67
82
assert ! ( matches!( rx_packet. payload, NetlinkPayload :: Ack ( _) ) ) ;
68
83
69
84
// And now we can receive the packets
85
+ loop {
86
+ match socket. recv ( & mut & mut receive_buffer[ ..] , 0 ) {
87
+ Ok ( size) => {
88
+ let mut offset = 0 ;
89
+ loop {
90
+ let bytes = & receive_buffer[ offset..] ;
70
91
71
- let mut offset = 0 ;
72
- while let Ok ( size) = socket. recv ( & mut & mut receive_buffer[ ..] , 0 ) {
73
- loop {
74
- let bytes = & receive_buffer[ offset..] ;
92
+ let rx_packet = <NetlinkMessage < NetfilterMessage > >:: deserialize ( bytes) . unwrap ( ) ;
75
93
76
- let rx_packet = <NetlinkMessage < NetfilterMessage > >:: deserialize ( bytes) . unwrap ( ) ;
77
- println ! ( "<<< {:?}" , rx_packet) ;
94
+ for nla in get_packet_nlas ( & rx_packet) {
95
+ if let nflog:: packet:: PacketNla :: Payload ( payload) = nla {
96
+ let src = Ipv4Addr :: from ( NetworkEndian :: read_u32 ( & payload[ 12 ..] ) ) ;
97
+ let dst = Ipv4Addr :: from ( NetworkEndian :: read_u32 ( & payload[ 16 ..] ) ) ;
98
+ println ! ( "Packet from {} to {}" , src, dst) ;
99
+ break ;
100
+ }
101
+ }
78
102
79
- match rx_packet. payload {
80
- NetlinkPayload :: Error ( _) | NetlinkPayload :: Overrun ( _) => return ,
81
- _ => ( ) ,
103
+ offset += rx_packet. header . length as usize ;
104
+ if offset == size || rx_packet. header . length == 0 {
105
+ break ;
106
+ }
107
+ }
82
108
}
83
-
84
- offset += rx_packet. header . length as usize ;
85
- if offset == size || rx_packet. header . length == 0 {
86
- offset = 0 ;
109
+ Err ( e) => {
110
+ println ! ( "error while receiving packets: {:?}" , e) ;
87
111
break ;
88
112
}
89
113
}
0 commit comments