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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
|
/*
* Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
* nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __PCAP_RPCAP_H__
#define __PCAP_RPCAP_H__
#include "pcap.h"
#include "sockutils.h" /* Needed for some structures (like SOCKET, sockaddr_in) which are used here */
/*
* \file pcap-pcap.h
*
* This file keeps all the new definitions and typedefs that are exported to the user and
* that are needed for the RPCAP protocol.
*
* \warning All the RPCAP functions that are allowed to return a buffer containing
* the error description can return max PCAP_ERRBUF_SIZE characters.
* However there is no guarantees that the string will be zero-terminated.
* Best practice is to define the errbuf variable as a char of size 'PCAP_ERRBUF_SIZE+1'
* and to insert manually the termination char at the end of the buffer. This will
* guarantee that no buffer overflows occur even if we use the printf() to show
* the error on the screen.
*
* \warning This file declares some typedefs that MUST be of a specific size.
* These definitions (i.e. typedefs) could need to be changed on other platforms than
* Intel IA32.
*
* \warning This file defines some structures that are used to transfer data on the network.
* Be careful that you compiler MUST not insert padding into these structures
* for better alignment.
* These structures have been created in order to be correctly aligned to a 32 bits
* boundary, but be careful in any case.
*/
/*********************************************************
* *
* General definitions / typedefs for the RPCAP protocol *
* *
*********************************************************/
/* All the following structures and typedef belongs to the Private Documentation */
/*
* \addtogroup remote_pri_struct
* \{
*/
#define RPCAP_DEFAULT_NETPORT "2002" /* Default port on which the RPCAP daemon is waiting for connections. */
/* Default port on which the client workstation is waiting for connections in case of active mode. */
#define RPCAP_DEFAULT_NETPORT_ACTIVE "2003"
#define RPCAP_DEFAULT_NETADDR "" /* Default network address on which the RPCAP daemon binds to. */
#define RPCAP_VERSION 0 /* Present version of the RPCAP protocol (0 = Experimental). */
#define RPCAP_TIMEOUT_INIT 90 /* Initial timeout for RPCAP connections (default: 90 sec) */
#define RPCAP_TIMEOUT_RUNTIME 180 /* Run-time timeout for RPCAP connections (default: 3 min) */
#define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
#define RPCAP_SUSPEND_WRONGAUTH 1 /* If the authentication is wrong, stops 1 sec before accepting a new auth message */
/*
* \brief Buffer used by socket functions to send-receive packets.
* In case you plan to have messages larger than this value, you have to increase it.
*/
#define RPCAP_NETBUF_SIZE 64000
/*
* \brief Separators used for the host list.
*
* It is used:
* - by the rpcapd daemon, when you types a list of allowed connecting hosts
* - by the rpcap in active mode, when the client waits for incoming connections from other hosts
*/
#define RPCAP_HOSTLIST_SEP " ,;\n\r"
/* WARNING: These could need to be changed on other platforms */
typedef unsigned char uint8; /* Provides an 8-bits unsigned integer */
typedef unsigned short uint16; /* Provides a 16-bits unsigned integer */
typedef unsigned int uint32; /* Provides a 32-bits unsigned integer */
typedef int int32; /* Provides a 32-bits integer */
/*
* \brief Keeps a list of all the opened connections in the active mode.
*
* This structure defines a linked list of items that are needed to keep the info required to
* manage the active mode.
* In other words, when a new connection in active mode starts, this structure is updated so that
* it reflects the list of active mode connections currently opened.
* This structure is required by findalldevs() and open_remote() to see if they have to open a new
* control connection toward the host, or they already have a control connection in place.
*/
struct activehosts
{
struct sockaddr_storage host;
SOCKET sockctrl;
struct activehosts *next;
};
/*********************************************************
* *
* Protocol messages formats *
* *
*********************************************************/
/* WARNING Take care you compiler does not insert padding for better alignments into these structs */
/* Common header for all the RPCAP messages */
struct rpcap_header
{
uint8 ver; /* RPCAP version number */
uint8 type; /* RPCAP message type (error, findalldevs, ...) */
uint16 value; /* Message-dependent value (not always used) */
uint32 plen; /* Length of the payload of this RPCAP message */
};
/* Format of the message for the interface description (findalldevs command) */
struct rpcap_findalldevs_if
{
uint16 namelen; /* Length of the interface name */
uint16 desclen; /* Length of the interface description */
uint32 flags; /* Interface flags */
uint16 naddr; /* Number of addresses */
uint16 dummy; /* Must be zero */
};
/* Format of the message for the address listing (findalldevs command) */
struct rpcap_findalldevs_ifaddr
{
struct sockaddr_storage addr; /* Network address */
struct sockaddr_storage netmask; /* Netmask for that address */
struct sockaddr_storage broadaddr; /* Broadcast address for that address */
struct sockaddr_storage dstaddr; /* P2P destination address for that address */
};
/*
* \brief Format of the message of the connection opening reply (open command).
*
* This structure transfers over the network some of the values useful on the client side.
*/
struct rpcap_openreply
{
int32 linktype; /* Link type */
int32 tzoff; /* Timezone offset */
};
/* Format of the message that starts a remote capture (startcap command) */
struct rpcap_startcapreq
{
uint32 snaplen; /* Length of the snapshot (number of bytes to capture for each packet) */
uint32 read_timeout; /* Read timeout in milliseconds */
uint16 flags; /* Flags (see RPCAP_STARTCAPREQ_FLAG_xxx) */
uint16 portdata; /* Network port on which the client is waiting at (if 'serveropen') */
};
/* Format of the reply message that devoted to start a remote capture (startcap reply command) */
struct rpcap_startcapreply
{
int32 bufsize; /* Size of the user buffer allocated by WinPcap; it can be different from the one we chose */
uint16 portdata; /* Network port on which the server is waiting at (passive mode only) */
uint16 dummy; /* Must be zero */
};
/*
* \brief Format of the header which encapsulates captured packets when transmitted on the network.
*
* This message requires the general header as well, since we want to be able to exchange
* more information across the network in the future (for example statistics, and kind like that).
*/
struct rpcap_pkthdr
{
uint32 timestamp_sec; /* 'struct timeval' compatible, it represents the 'tv_sec' field */
uint32 timestamp_usec; /* 'struct timeval' compatible, it represents the 'tv_usec' field */
uint32 caplen; /* Length of portion present in the capture */
uint32 len; /* Real length this packet (off wire) */
uint32 npkt; /* Ordinal number of the packet (i.e. the first one captured has '1', the second one '2', etc) */
};
/* General header used for the pcap_setfilter() command; keeps just the number of BPF instructions */
struct rpcap_filter
{
uint16 filtertype; /* type of the filter transferred (BPF instructions, ...) */
uint16 dummy; /* Must be zero */
uint32 nitems; /* Number of items contained into the filter (e.g. BPF instructions for BPF filters) */
};
/* Structure that keeps a single BPF instuction; it is repeated 'ninsn' times according to the 'rpcap_filterbpf' header */
struct rpcap_filterbpf_insn
{
uint16 code; /* opcode of the instruction */
uint8 jt; /* relative offset to jump to in case of 'true' */
uint8 jf; /* relative offset to jump to in case of 'false' */
int32 k; /* instruction-dependent value */
};
/* Structure that keeps the data required for the authentication on the remote host */
struct rpcap_auth
{
uint16 type; /* Authentication type */
uint16 dummy; /* Must be zero */
uint16 slen1; /* Length of the first authentication item (e.g. username) */
uint16 slen2; /* Length of the second authentication item (e.g. password) */
};
/* Structure that keeps the statistics about the number of packets captured, dropped, etc. */
struct rpcap_stats
{
uint32 ifrecv; /* Packets received by the kernel filter (i.e. pcap_stats.ps_recv) */
uint32 ifdrop; /* Packets dropped by the network interface (e.g. not enough buffers) (i.e. pcap_stats.ps_ifdrop) */
uint32 krnldrop; /* Packets dropped by the kernel filter (i.e. pcap_stats.ps_drop) */
uint32 svrcapt; /* Packets captured by the RPCAP daemon and sent on the network */
};
/* Structure that is needed to set sampling parameters */
struct rpcap_sampling
{
uint8 method; /* Sampling method */
uint8 dummy1; /* Must be zero */
uint16 dummy2; /* Must be zero */
uint32 value; /* Parameter related to the sampling method */
};
/*
* Private data for doing a live capture.
*/
struct pcap_md {
struct pcap_stat stat;
/* XXX */
int use_bpf; /* using kernel filter */
u_long TotPkts; /* can't overflow for 79 hrs on ether */
u_long TotAccepted; /* count accepted by filter */
u_long TotDrops; /* count of dropped packets */
long TotMissed; /* missed by i/f during this run */
long OrigMissed; /* missed by i/f before this run */
char *device; /* device name */
int timeout; /* timeout for buffering */
int must_clear; /* stuff we must clear when we close */
struct pcap *next; /* list of open pcaps that need stuff cleared on close */
#ifdef linux
int sock_packet; /* using Linux 2.0 compatible interface */
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
int ifindex; /* interface index of device we're bound to */
int lo_ifindex; /* interface index of the loopback device */
u_int packets_read; /* count of packets read with recvfrom() */
bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
u_int tp_version; /* version of tpacket_hdr for mmaped ring */
u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */
#endif /* linux */
#ifdef HAVE_DAG_API
#ifdef HAVE_DAG_STREAMS_API
u_char *dag_mem_bottom;/* DAG card current memory bottom pointer */
u_char *dag_mem_top; /* DAG card current memory top pointer */
#else /* HAVE_DAG_STREAMS_API */
void *dag_mem_base; /* DAG card memory base address */
u_int dag_mem_bottom; /* DAG card current memory bottom offset */
u_int dag_mem_top; /* DAG card current memory top offset */
#endif /* HAVE_DAG_STREAMS_API */
int dag_fcs_bits; /* Number of checksum bits from link layer */
int dag_offset_flags; /* Flags to pass to dag_offset(). */
int dag_stream; /* DAG stream number */
int dag_timeout; /* timeout specified to pcap_open_live.
* Same as in linux above, introduce
* generally?
*/
#endif /* HAVE_DAG_API */
#ifdef HAVE_ZEROCOPY_BPF
/*
* Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will
* alternative between these two actual mmap'd buffers as required.
* As there is a header on the front size of the mmap'd buffer, only
* some of the buffer is exposed to libpcap as a whole via bufsize;
* zbufsize is the true size. zbuffer tracks the current zbuf
* associated with buffer so that it can be used to decide which the
* next buffer to read will be.
*/
u_char *zbuf1, *zbuf2, *zbuffer;
u_int zbufsize;
u_int zerocopy;
u_int interrupted;
struct timespec firstsel;
/*
* If there's currently a buffer being actively processed, then it is
* referenced here; 'buffer' is also pointed at it, but offset by the
* size of the header.
*/
struct bpf_zbuf_header *bzh;
#endif /* HAVE_ZEROCOPY_BPF */
#ifdef HAVE_REMOTE
/*
* There is really a mess with previous variables, and it seems to me that they are not used
* (they are used in pcap_pf.c only). I think we have to start using them.
* The meaning is the following:
*
* - TotPkts: the amount of packets received by the bpf filter, *before* applying the filter
* - TotAccepted: the amount of packets that satisfies the filter
* - TotDrops: the amount of packet that were dropped into the kernel buffer because of lack of space
* - TotMissed: the amount of packets that were dropped by the physical interface; it is basically
* the value of the hardware counter into the card. This number is never put to zero, so this number
* takes into account the *total* number of interface drops starting from the interface power-on.
* - OrigMissed: the amount of packets that were dropped by the interface *when the capture begins*.
* This value is used to detect the number of packets dropped by the interface *during the present
* capture*, so that (ps_ifdrops= TotMissed - OrigMissed).
*/
unsigned int TotNetDrops; /* keeps the number of packets that have been dropped by the network */
/*
* \brief It keeps the number of packets that have been received by the application.
*
* Packets dropped by the kernel buffer are not counted in this variable. The variable is always
* equal to (TotAccepted - TotDrops), except for the case of remote capture, in which we have also
* packets in flight, i.e. that have been transmitted by the remote host, but that have not been
* received (yet) from the client. In this case, (TotAccepted - TotDrops - TotNetDrops) gives a
* wrong result, since this number does not corresponds always to the number of packet received by
* the application. For this reason, in the remote capture we need another variable that takes
* into account of the number of packets actually received by the application.
*/
unsigned int TotCapt;
/*! \brief '1' if we're the network client; needed by several functions (like pcap_setfilter() ) to know if
they have to use the socket or they have to open the local adapter. */
int rmt_clientside;
SOCKET rmt_sockctrl; //!< socket ID of the socket used for the control connection
SOCKET rmt_sockdata; //!< socket ID of the socket used for the data connection
int rmt_flags; //!< we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture()
int rmt_capstarted; //!< 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture()
struct pcap_samp rmt_samp; //!< Keeps the parameters related to the sampling process.
char *currentfilter; //!< Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is turned on.
#endif /* HAVE_REMOTE */
};
/* Messages field coding */
#define RPCAP_MSG_ERROR 1 /* Message that keeps an error notification */
#define RPCAP_MSG_FINDALLIF_REQ 2 /* Request to list all the remote interfaces */
#define RPCAP_MSG_OPEN_REQ 3 /* Request to open a remote device */
#define RPCAP_MSG_STARTCAP_REQ 4 /* Request to start a capture on a remote device */
#define RPCAP_MSG_UPDATEFILTER_REQ 5 /* Send a compiled filter into the remote device */
#define RPCAP_MSG_CLOSE 6 /* Close the connection with the remote peer */
#define RPCAP_MSG_PACKET 7 /* This is a 'data' message, which carries a network packet */
#define RPCAP_MSG_AUTH_REQ 8 /* Message that keeps the authentication parameters */
#define RPCAP_MSG_STATS_REQ 9 /* It requires to have network statistics */
#define RPCAP_MSG_ENDCAP_REQ 10 /* Stops the current capture, keeping the device open */
#define RPCAP_MSG_SETSAMPLING_REQ 11 /* Set sampling parameters */
#define RPCAP_MSG_FINDALLIF_REPLY (128+RPCAP_MSG_FINDALLIF_REQ) /* Keeps the list of all the remote interfaces */
#define RPCAP_MSG_OPEN_REPLY (128+RPCAP_MSG_OPEN_REQ) /* The remote device has been opened correctly */
#define RPCAP_MSG_STARTCAP_REPLY (128+RPCAP_MSG_STARTCAP_REQ) /* The capture is starting correctly */
#define RPCAP_MSG_UPDATEFILTER_REPLY (128+RPCAP_MSG_UPDATEFILTER_REQ) /* The filter has been applied correctly on the remote device */
#define RPCAP_MSG_AUTH_REPLY (128+RPCAP_MSG_AUTH_REQ) /* Sends a message that says 'ok, authorization successful' */
#define RPCAP_MSG_STATS_REPLY (128+RPCAP_MSG_STATS_REQ) /* Message that keeps the network statistics */
#define RPCAP_MSG_ENDCAP_REPLY (128+RPCAP_MSG_ENDCAP_REQ) /* Confirms that the capture stopped successfully */
#define RPCAP_MSG_SETSAMPLING_REPLY (128+RPCAP_MSG_SETSAMPLING_REQ) /* Confirms that the capture stopped successfully */
#define RPCAP_STARTCAPREQ_FLAG_PROMISC 1 /* Enables promiscuous mode (default: disabled) */
#define RPCAP_STARTCAPREQ_FLAG_DGRAM 2 /* Use a datagram (i.e. UDP) connection for the data stream (default: use TCP)*/
#define RPCAP_STARTCAPREQ_FLAG_SERVEROPEN 4 /* The server has to open the data connection toward the client */
#define RPCAP_STARTCAPREQ_FLAG_INBOUND 8 /* Capture only inbound packets (take care: the flag has no effects with promiscuous enabled) */
#define RPCAP_STARTCAPREQ_FLAG_OUTBOUND 16 /* Capture only outbound packets (take care: the flag has no effects with promiscuous enabled) */
#define RPCAP_UPDATEFILTER_BPF 1 /* This code tells us that the filter is encoded with the BPF/NPF syntax */
/* Network error codes */
#define PCAP_ERR_NETW 1 /* Network error */
#define PCAP_ERR_INITTIMEOUT 2 /* The RPCAP initial timeout has expired */
#define PCAP_ERR_AUTH 3 /* Generic authentication error */
#define PCAP_ERR_FINDALLIF 4 /* Generic findalldevs error */
#define PCAP_ERR_NOREMOTEIF 5 /* The findalldevs was ok, but the remote end had no interfaces to list */
#define PCAP_ERR_OPEN 6 /* Generic pcap_open error */
#define PCAP_ERR_UPDATEFILTER 7 /* Generic updatefilter error */
#define PCAP_ERR_GETSTATS 8 /* Generic pcap_stats error */
#define PCAP_ERR_READEX 9 /* Generic pcap_next_ex error */
#define PCAP_ERR_HOSTNOAUTH 10 /* The host is not authorized to connect to this server */
#define PCAP_ERR_REMOTEACCEPT 11 /* Generic pcap_remoteaccept error */
#define PCAP_ERR_STARTCAPTURE 12 /* Generic pcap_startcapture error */
#define PCAP_ERR_ENDCAPTURE 13 /* Generic pcap_endcapture error */
#define PCAP_ERR_RUNTIMETIMEOUT 14 /* The RPCAP run-time timeout has expired */
#define PCAP_ERR_SETSAMPLING 15 /* Error during the settings of sampling parameters */
#define PCAP_ERR_WRONGMSG 16 /* The other end endpoint sent a message which has not been recognized */
#define PCAP_ERR_WRONGVER 17 /* The other end endpoint has a version number that is not compatible with our */
/*
* \}
* // end of private documentation
*/
/*********************************************************
* *
* Exported function prototypes *
* *
*********************************************************/
int pcap_opensource_remote(pcap_t *p, struct pcap_rmtauth *auth);
int pcap_startcapture_remote(pcap_t *fp);
void rpcap_createhdr(struct rpcap_header *header, uint8 type, uint16 value, uint32 length);
int rpcap_deseraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage **sockaddrout, char *errbuf);
int rpcap_checkmsg(char *errbuf, SOCKET sock, struct rpcap_header *header, uint8 first, ...);
int rpcap_senderror(SOCKET sock, char *error, unsigned short errcode, char *errbuf);
int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf);
SOCKET rpcap_remoteact_getsock(const char *host, int *isactive, char *errbuf);
#endif
|