summaryrefslogtreecommitdiff
path: root/dissector.h
blob: 52f341b1bc3ad4f262629016e1f8723add572ee4 (plain)
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
/*
 * 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_packet.h>
#include <linux/if.h>
#include <netlink/msg.h>

#include "ring.h"
#include "tprintf.h"
#include "linktype.h"
#include "vlan.h"

#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);
}

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 */
2.898802] [<ffffff80083a20dc>] __pci_register_driver+0x3c/0x48 [ 2.898809] [<ffffff8008468eb4>] drm_pci_init+0xf4/0x120 [ 2.898818] [<ffffff8008c56fc0>] nouveau_drm_init+0x21c/0x230 [ 2.898825] [<ffffff80080829d4>] do_one_initcall+0x8c/0x190 [ 2.898832] [<ffffff8008c31af4>] kernel_init_freeable+0x14c/0x1f0 [ 2.898839] [<ffffff80088a0c20>] kernel_init+0x10/0x100 [ 2.898845] [<ffffff8008085e10>] ret_from_fork+0x10/0x40 [ 2.898853] Code: a88120c7 a8c12027 a88120c7 a8c12027 (a88120c7) [ 2.898871] ---[ end trace d5713dcad023ee04 ]--- [ 2.898888] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b In a toss-up between the GPU seeing stale data artefacts on some systems vs. catastrophic kernel crashes on other systems, the latter would seem to take precedence, so revert this change until the real underlying problem can be fixed. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Acked-by: Alexandre Courbot <acourbot@nvidia.com> [acourbot@nvidia.com: port to Nouveau tree, remove bits in lib/] Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Cc: stable@vger.kernel.org
Diffstat