aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/btlib.h
blob: cc8b52b65c70c602d6d623db03966074ab25ec7d (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
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
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
 * btlib.h
 *
 * Copyright (C) 2011-15 - ntop.org
 *               Contributed by Vitaly Lavrov <vel21ripn@gmail.com>
 *
 * This file is part of nDPI, an open source deep packet inspection
 * library based on the OpenDPI and PACE technology by ipoque GmbH
 *
 * nDPI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * nDPI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with nDPI.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#define BDEC_MAXDEPT 8

#ifdef WIN32
#include "ndpi_win32.h"
#endif

typedef struct b_elem_s {
	const u_int8_t *s;
	size_t   l;
} b_elem_s_t;

#ifdef WIN32
// enable 1 byte packing on Windows
#include <pshpack1.h>
#endif

struct
#ifndef WIN32
	__attribute__((__packed__))
#endif
	bt_nodes_data {
	u_int8_t  id[20];
	u_int32_t ip;
	u_int16_t port;
};

struct
#ifndef WIN32
	__attribute__((__packed__))
#endif
	bt_ipv4p {
	u_int32_t ip;
	u_int16_t port;
};

struct
#ifndef WIN32
	__attribute__((__packed__))
#endif
	bt_ipv4p2 {
	struct bt_ipv4p d;
	u_int8_t	pad[2];
};

struct
#ifndef WIN32
	__attribute__((__packed__))
#endif
	bt_nodes6_data {
	u_int8_t  id[20];
	u_int32_t ip[4];
	u_int16_t port;
};

struct
#ifndef WIN32
	__attribute__((__packed__))
#endif
	bt_ipv6p {
	u_int32_t ip[4];
	u_int16_t port;
};

struct
#ifndef WIN32
	__attribute__((__packed__))
#endif
	bt_ipv6p2 {
	struct bt_ipv6p d;
	u_int8_t	pad[3];
};

#ifdef WIN32
// disable 1 byte packing
#include <poppack.h>
#endif

/*
 
  a.id S		r.id S
  a.info_hash S		r.ip ipv4
  a.name S		r.nodes x(id,ipv4,port)
 -a.noseed 0|1		r.n S        name of file
  a.port N		r.p          port
 -a.scrape 0|1		r.token S
 -a.seed 0|1		r.values x(ipv4,port)
  a.target S
  a.token S		-a.vote N
 -a.want n4|n6
 
  q announce_peer	q find_node
  q get_peers		q ping
 -q vote
 
  ip ipv4+port		interval N
  min interval N	peers x(ipv4,port)
  t 2/4/8b		v 4/6b
 
  e S			y e	y r	y q
 
  */

struct bt_parse_protocol {
	u_int16_t y_e:1, y_r:1, y_q:1,
		  q_a_peer:1,q_f_node:1,
		  q_g_peers:1,q_ping:1,
		  h_int:1,h_mint:1,h_ip:1;
	struct {
		const u_int8_t	*id,		// 20
			 	*info_hash,	// 20
			 	*target,	// 20
				*token,		// 20|8
			 	*name;		// varlen
		u_int16_t name_len;
		u_int16_t port;
		u_int16_t	t_len;
	} a;
	struct {
		const u_int8_t 	*id,		// 20
			 	*token,		// 20|8
				*values,	// (6+2)*x
				*values6,	// (18_3)*x
			 	*name;		// varlen
		struct bt_ipv4p	*ip;
		struct bt_nodes_data *nodes;
		struct bt_nodes6_data *nodes6;
		u_int16_t	name_len;
		u_int16_t	nn;		// nodes num
		u_int16_t	nv;		// values num
		u_int16_t	nn6;		// nodes6 num
		u_int16_t	nv6;		// values6 num
		u_int16_t	port;
		u_int16_t	t_len;
	} r;
	int			interval,min_interval;
	struct bt_ipv4p		*peers;
	int			n_peers;
	struct bt_ipv4p		*ip;
	const u_int8_t		*e_msg;
	u_int16_t		e_len;
	u_int64_t		t,v;
};

typedef struct bt_parse_data_cb {
	struct bt_parse_protocol p;
	char	buf[64];
	int	level;
	int	t;
	union {
		int64_t i;
		b_elem_s_t s;
	} v;
} bt_parse_data_cb_t;

extern int bt_parse_debug;
void dump_bt_proto_struct(struct bt_parse_protocol *p);
const u_int8_t *bt_decode(const u_int8_t *b, size_t *l, int *ret, bt_parse_data_cb_t *cbd);