2 * Copyright (c) 2013, Petar Alilovic,
3 * Faculty of Electrical Engineering and Computing, University of Zagreb
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 #include <netdissect-stdinc.h>
34 #include "netdissect.h"
36 #if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H)
37 #include <pcap/nflog.h>
39 static const struct tok nflog_values
[] = {
48 nflog_hdr_print(netdissect_options
*ndo
, const nflog_hdr_t
*hdr
, u_int length
)
50 ND_PRINT((ndo
, "version %d, resource ID %d", hdr
->nflog_version
, ntohs(hdr
->nflog_rid
)));
52 if (!ndo
->ndo_qflag
) {
53 ND_PRINT((ndo
,", family %s (%d)",
54 tok2str(nflog_values
, "Unknown",
60 "Unknown NFLOG (0x%02x)",
64 ND_PRINT((ndo
, ", length %u: ", length
));
67 static char *hook_names
[] = { "PRE","IN","FWD","OUT","POST" };
69 static const char *hook2txt(int hook
) {
70 if(hook
>= sizeof(hook_names
)/sizeof(hook_names
[0])) return "UNK";
71 return hook_names
[hook
];
75 nflog_if_print(netdissect_options
*ndo
,
76 const struct pcap_pkthdr
*h
, const u_char
*p
)
78 const nflog_hdr_t
*hdr
= (const nflog_hdr_t
*)p
;
79 const nflog_tlv_t
*tlv
;
81 uint16_t hw_hdrlen
= 0;
82 uint16_t hw_addrlen
= 0;
83 uint16_t h_size
= sizeof(nflog_hdr_t
);
84 u_int caplen
= h
->caplen
;
85 u_int length
= h
->len
;
87 if (caplen
< (int) sizeof(nflog_hdr_t
) || length
< (int) sizeof(nflog_hdr_t
)) {
88 ND_PRINT((ndo
, "[|nflog]"));
92 if (!(hdr
->nflog_version
) == 0) {
93 ND_PRINT((ndo
, "version %u (unknown)", hdr
->nflog_version
));
98 nflog_hdr_print(ndo
, hdr
, length
);
100 p
+= sizeof(nflog_hdr_t
);
101 length
-= sizeof(nflog_hdr_t
);
102 caplen
-= sizeof(nflog_hdr_t
);
105 /* We have some data. Do we have enough for the TLV header? */
106 if (caplen
< sizeof(nflog_tlv_t
) || length
< sizeof(nflog_tlv_t
)) {
108 ND_PRINT((ndo
, "[|nflog]"));
112 tlv
= (const nflog_tlv_t
*) p
;
113 size
= tlv
->tlv_length
;
115 size
+= 4 - size
% 4;
117 /* Is the TLV's length less than the minimum? */
118 if (size
< sizeof(nflog_tlv_t
)) {
119 /* Yes. Give up now. */
120 ND_PRINT((ndo
, "[|nflog]"));
124 /* Do we have enough data for the full TLV? */
125 if (caplen
< size
|| length
< size
) {
127 ND_PRINT((ndo
, "[|nflog]"));
131 if (tlv
->tlv_type
== NFULA_PAYLOAD
) {
133 * This TLV's data is the packet payload.
134 * Skip past the TLV header, and break out
135 * of the loop so we print the packet data.
137 p
+= sizeof(nflog_tlv_t
);
138 h_size
+= sizeof(nflog_tlv_t
);
139 length
-= sizeof(nflog_tlv_t
);
140 caplen
-= sizeof(nflog_tlv_t
);
144 const u_char
*adata
= p
+sizeof(nflog_tlv_t
);
145 switch(tlv
->tlv_type
) {
146 case NFULA_TIMESTAMP
:
149 case NFULA_PACKET_HDR
:
151 ND_PRINT((ndo
, "HOOK:%s ",
152 hook2txt(((nflog_packet_hdr_t
*)adata
)->hook
)));
155 ND_PRINT((ndo
, "MARK:0x%x ",
156 htonl(*(u_int32_t
*)adata
)));
160 ND_PRINT((ndo
, "UID:%u ",
161 htonl(*(u_int32_t
*)adata
)));
165 ND_PRINT((ndo
, "GID:%u ",
166 htonl(*(u_int32_t
*)adata
)));
169 if(p
[sizeof(nflog_tlv_t
)])
170 ND_PRINT((ndo
, "Prefix:%.*s ",
171 size
-sizeof(nflog_tlv_t
), adata
));
173 case NFULA_IFINDEX_INDEV
:
174 if(ndo
->ndo_vflag
> 1)
175 ND_PRINT((ndo
, "iif:%u ",
176 htonl(*(u_int32_t
*)adata
)));
178 case NFULA_IFINDEX_OUTDEV
:
179 if(ndo
->ndo_vflag
> 1)
180 ND_PRINT((ndo
, "oif:%u ",
181 htonl(*(u_int32_t
*)adata
)));
183 case NFULA_IFINDEX_PHYSINDEV
:
184 if(ndo
->ndo_vflag
> 1)
185 ND_PRINT((ndo
, "phyiif:%u ",
186 htonl(*(u_int32_t
*)adata
)));
188 case NFULA_IFINDEX_PHYSOUTDEV
:
189 if(ndo
->ndo_vflag
> 1)
190 ND_PRINT((ndo
, "phyoif:%u ",
191 htonl(*(u_int32_t
*)adata
)));
194 hw_addrlen
= htons(((nflog_hwaddr_t
*)adata
)->hw_addrlen
);
197 hw_hdrlen
= htons((*(u_int16_t
*)adata
));
200 if (!hw_hdrlen
|| ndo
->ndo_vflag
< 2) break;
204 memset(attr_buf
,0,sizeof(attr_buf
));
205 for(n
=0,l
=0; n
< hw_hdrlen
&& l
< sizeof(attr_buf
)-3; n
++) {
207 (n
== hw_addrlen
|| n
== hw_addrlen
*2))
209 l
+= snprintf(&attr_buf
[l
],3,"%02x",adata
[n
]);
211 ND_PRINT((ndo
, "HWHDR=%s ",attr_buf
));
215 if (ndo
->ndo_vflag
< 3) break;
216 ND_PRINT((ndo
, "ATTR%d/%d ",tlv
->tlv_type
,size
));
226 switch (hdr
->nflog_family
) {
229 ip_print(ndo
, p
, length
);
234 ip6_print(ndo
, p
, length
);
236 #endif /* AF_INET6 */
240 nflog_hdr_print(ndo
, hdr
,
241 length
+ sizeof(nflog_hdr_t
));
243 if (!ndo
->ndo_suppress_default_print
)
244 ND_DEFAULTPRINT(p
, caplen
);
251 #endif /* defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H) */