forked from netsniff-ng/netsniff-ng
-
Notifications
You must be signed in to change notification settings - Fork 1
/
dissector.h
168 lines (148 loc) · 4.32 KB
/
dissector.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
* netsniff-ng - the packet sniffing beast
* Copyright 2009 - 2013 Daniel Borkmann.
* Subject to the GPL, version 2.
*/
#ifndef DISSECTOR_H
#define DISSECTOR_H
#include <stdlib.h>
#include <stdint.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/netlink.h>
#include <linux/if_packet.h>
#include "ring.h"
#include "tprintf.h"
#include "linktype.h"
#include "vlan.h"
#ifdef HAVE_PF_RING
#include "pfring.h"
#endif
#define PRINT_NORM 0
#define PRINT_LESS 1
#define PRINT_HEX 2
#define PRINT_ASCII 3
#define PRINT_HEX_ASCII 4
#define PRINT_NONE 5
extern char *if_indextoname(unsigned ifindex, char *ifname);
static const char * const packet_types[256] = {
[PACKET_HOST] = "<", /* Incoming */
[PACKET_BROADCAST] = "B", /* Broadcast */
[PACKET_MULTICAST] = "M", /* Multicast */
[PACKET_OTHERHOST] = "P", /* Promisc */
[PACKET_OUTGOING] = ">", /* Outgoing */
[PACKET_USER] = "K->U", /* To Userspace */
[PACKET_KERNEL] = "U->K", /* To Kernelspace */
};
static inline const char *__show_ts_source(uint32_t status)
{
if (status & TP_STATUS_TS_RAW_HARDWARE)
return "(raw hw ts)";
else if (status & TP_STATUS_TS_SYS_HARDWARE)
return "(sys hw ts)";
else if (status & TP_STATUS_TS_SOFTWARE)
return "(sw ts)";
else
return "";
}
static inline void __show_frame_hdr(uint8_t *packet, size_t len, int linktype,
struct sockaddr_ll *s_ll, void *raw_hdr,
int mode, bool v3, unsigned long count)
{
char tmp[IFNAMSIZ];
union tpacket_uhdr hdr;
uint8_t pkttype = s_ll->sll_pkttype;
bool is_nl;
if (mode == PRINT_NONE)
return;
/*
* If we're capturing on nlmon0, all packets will have sll_pkttype set
* to PACKET_OUTGOING, but we actually want PACKET_USER/PACKET_KERNEL as
* it originally was set in the kernel. Thus, use nlmsghdr->nlmsg_pid to
* restore the type.
*/
is_nl = (linktype == LINKTYPE_NETLINK && len >= sizeof(struct nlmsghdr));
if (is_nl && pkttype == PACKET_OUTGOING) {
struct nlmsghdr *hdr = (struct nlmsghdr *) packet;
pkttype = hdr->nlmsg_pid == 0 ? PACKET_KERNEL : PACKET_USER;
}
hdr.raw = raw_hdr;
switch (mode) {
case PRINT_LESS:
tprintf("%s %s %u #%lu",
packet_types[pkttype] ? : "?",
if_indextoname(s_ll->sll_ifindex, tmp) ? : "?",
tpacket_uhdr(hdr, tp_len, v3),
count);
break;
default:
tprintf("%s %s %u %us.%uns #%lu %s\n",
packet_types[pkttype] ? : "?",
if_indextoname(s_ll->sll_ifindex, tmp) ? : "?",
tpacket_uhdr(hdr, tp_len, v3),
tpacket_uhdr(hdr, tp_sec, v3),
tpacket_uhdr(hdr, tp_nsec, v3),
count,
v3 ? "" : __show_ts_source(hdr.h2->tp_status));
if (tpacket_has_vlan_info(&hdr)) {
uint16_t tci = tpacket_uhdr_vlan_tci(&hdr, v3);
tprintf(" [ tpacketv3 VLAN ");
tprintf("Prio (%u), ", vlan_tci2prio(tci));
tprintf("CFI (%u), ", vlan_tci2cfi(tci));
tprintf("ID (%u), ", vlan_tci2vid(tci));
tprintf("Proto (0x%.4x)", tpacket_uhdr_vlan_proto(&hdr, v3));
tprintf(" ]\n");
}
break;
}
}
static inline void show_frame_hdr(uint8_t *packet, size_t len, int linktype,
struct frame_map *hdr, int mode,
unsigned long count)
{
__show_frame_hdr(packet, len, linktype, &hdr->s_ll, &hdr->tp_h, mode,
false, count);
}
#ifdef HAVE_PF_RING
static inline void show_frame_hdr_pfring(uint8_t *packet, size_t len, int linktype,
struct sockaddr_ll *s_ll, struct pfring_pkthdr *hdr,
int mode, unsigned long count)
{
char tmp[IFNAMSIZ];
uint8_t pkttype = s_ll->sll_pkttype;
uint32_t sec, nsec;
if (mode == PRINT_NONE)
return;
switch (mode) {
case PRINT_LESS:
tprintf("%s %s %u #%lu",
packet_types[pkttype] ? : "?",
if_indextoname(s_ll->sll_ifindex, tmp) ? : "?",
hdr->len,
count);
break;
default:
if (hdr->extended_hdr.timestamp_ns) {
sec = hdr->extended_hdr.timestamp_ns / 1000000000;
nsec = hdr->extended_hdr.timestamp_ns % 1000000000;
} else {
sec = hdr->ts.tv_sec;
nsec = hdr->ts.tv_usec*1000;
}
tprintf("%s %s %u %us.%uns #%lu %s\n",
packet_types[pkttype] ? : "?",
if_indextoname(s_ll->sll_ifindex, tmp) ? : "?",
hdr->len,
sec, nsec,
count,
"");
break;
}
}
#endif
extern void dissector_init_all(int fnttype);
extern void dissector_entry_point(uint8_t *packet, size_t len, int linktype,
int mode, struct sockaddr_ll *sll);
extern void dissector_cleanup_all(void);
extern int dissector_set_print_type(void *ptr, int type);
#endif /* DISSECTOR_H */