1 /* Copyright (C) 2000,2001 Salvatore Sanfilippo <antirez@invece.org>
2  * See the LICENSE file for more information. */
3 
4 /* $Id: ars.h,v 1.4 2004/06/04 07:22:38 antirez Exp $ */
5 
6 #ifndef _ARS_H
7 #define _ARS_H
8 
9 /* define before including sys/socket.h */
10 #if defined(__APPLE__) && !defined(_BSD_SOCKLEN_T_)
11 #define _BSD_SOCKLEN_T_ int
12 #endif
13 
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <string.h>
17 #include <errno.h>
18 #include "systype.h"
19 #include "in.h"
20 #include "bytesex.h"
21 #include "adbuf.h"
22 #include "fixtypes.h"
23 
24 #ifndef TRUE
25 #define TRUE	1
26 #define FALSE	0
27 #endif
28 
29 
30 #ifndef MIN
31 #define MIN(x,y)	((x)<(y)?(x):(y))
32 #endif
33 
34 #ifndef MAX
35 #define MAX(x,y)	((x)>(y)?(x):(y))
36 #endif
37 
38 #ifdef DEBUG
39 #define __D(x) x
40 #else
41 #define __D(x) do { } while (0);
42 #endif
43 
44 #ifndef __u8
45 #define __u8	u_int8_t
46 #define __u16	u_int16_t
47 #define __u32	u_int32_t
48 #endif
49 
50 /* error codes */
51 #define ARS_OK          0
52 #define ARS_ERROR	1
53 #define ARS_NOSPACE     2
54 #define ARS_NOMEM       3
55 #define ARS_INVALID	4
56 
57 /* Headers size */
58 #define ARS_ICMPHDR_SIZE	sizeof(struct ars_icmphdr)
59 #define ARS_UDPHDR_SIZE		sizeof(struct ars_udphdr)
60 #define ARS_TCPHDR_SIZE		sizeof(struct ars_tcphdr)
61 #define ARS_IPHDR_SIZE		sizeof(struct ars_iphdr)
62 #define ARS_PSEUDOHDR_SIZE	sizeof(struct pseudohdr)
63 #define ARS_IGRPHDR_SIZE	sizeof(struct ars_igrphdr)
64 #define ARS_IGRPENTRY_SIZE	sizeof(struct ars_igrpentry)
65 
66 /* IP defines */
67 #define ARS_MAX_IP_SIZE		65535
68 
69 #define ARS_IP_MF ((unsigned short)0x2000)	/* more fragments */
70 #define ARS_IP_DF ((unsigned short)0x4000)	/* dont fragment */
71 #define ARS_IP_RF ((unsigned short)0x8000)	/* reserved fragment flag */
72 
73 #define ARS_IPOPT_COPY		0x80
74 #define ARS_IPOPT_CLASS_MASK	0x60
75 #define ARS_IPOPT_NUMBER_MASK	0x1f
76 
77 #define	ARS_IPOPT_COPIED(o)		((o)&ARS_IPOPT_COPY)
78 #define	ARS_IPOPT_CLASS(o)		((o)&ARS_IPOPT_CLASS_MASK)
79 #define	ARS_IPOPT_NUMBER(o)		((o)&ARS_IPOPT_NUMBER_MASK)
80 
81 #define	ARS_IPOPT_CONTROL		0x00
82 #define	ARS_IPOPT_RESERVED1		0x20
83 #define	ARS_IPOPT_MEASUREMENT		0x40
84 #define	ARS_IPOPT_RESERVED2		0x60
85 
86 #define ARS_IPOPT_END		(0 |ARS_IPOPT_CONTROL)
87 #define ARS_IPOPT_NOOP		(1 |ARS_IPOPT_CONTROL)
88 #define ARS_IPOPT_SEC		(2 |ARS_IPOPT_CONTROL|ARS_IPOPT_COPY)
89 #define ARS_IPOPT_LSRR		(3 |ARS_IPOPT_CONTROL|ARS_IPOPT_COPY)
90 #define ARS_IPOPT_TIMESTAMP	(4 |ARS_IPOPT_MEASUREMENT)
91 #define ARS_IPOPT_RR		(7 |ARS_IPOPT_CONTROL)
92 #define ARS_IPOPT_SID		(8 |ARS_IPOPT_CONTROL|ARS_IPOPT_COPY)
93 #define ARS_IPOPT_SSRR		(9 |ARS_IPOPT_CONTROL|ARS_IPOPT_COPY)
94 #define ARS_IPOPT_RA		(20|ARS_IPOPT_CONTROL|ARS_IPOPT_COPY)
95 
96 #define ARS_IPOPT_OPTVAL 0
97 #define ARS_IPOPT_OLEN   1
98 #define ARS_IPOPT_OFFSET 2
99 #define ARS_IPOPT_MINOFF 4
100 #define ARS_MAX_IPOPTLEN 40
101 #define ARS_IPOPT_NOP ARS_IPOPT_NOOP
102 #define ARS_IPOPT_EOL ARS_IPOPT_END
103 #define ARS_IPOPT_TS  ARS_IPOPT_TIMESTAMP
104 
105 #define	ARS_IPOPT_TS_TSONLY	0		/* timestamps only */
106 #define	ARS_IPOPT_TS_TSANDADDR	1		/* timestamps and addresses */
107 #define	ARS_IPOPT_TS_PRESPEC	3		/* specified modules only */
108 
109 /* IPV4 and IPV6 string rappresentation len */
110 #define ARS_INET_ADDRSTRLEN	16
111 #define ARS_INET6_ADDRSTRLEN	46
112 
113 /* TCP */
114 #define ARS_TCPOPT_EOL		0
115 #define ARS_TCPOPT_NOP		1
116 #define ARS_TCPOPT_MAXSEG	2
117 #define ARS_TCPOPT_WINDOW	3
118 #define ARS_TCPOPT_SACK_PERM	4
119 #define ARS_TCPOPT_SACK		5
120 #define ARS_TCPOPT_ECHOREQUEST	6
121 #define ARS_TCPOPT_ECHOREPLY	7
122 #define ARS_TCPOPT_TIMESTAMP	8
123 
124 #define ARS_TCP_TH_FIN	0x01
125 #define ARS_TCP_TH_SYN	0x02
126 #define ARS_TCP_TH_RST	0x04
127 #define ARS_TCP_TH_PUSH	0x08
128 #define ARS_TCP_TH_ACK	0x10
129 #define ARS_TCP_TH_URG	0x20
130 #define	ARS_TCP_TH_X 	0x40	/* X tcp flag */
131 #define ARS_TCP_TH_Y 	0x80	/* Y tcp flag */
132 
133 /* ICMP TYPE */
134 #define ARS_ICMP_ECHOREPLY          0       /* Echo Reply                   */
135 #define ARS_ICMP_DEST_UNREACH       3       /* Destination Unreachable      */
136 #define ARS_ICMP_SOURCE_QUENCH      4       /* Source Quench                */
137 #define ARS_ICMP_REDIRECT           5       /* Redirect (change route)      */
138 #define ARS_ICMP_ECHO               8       /* Echo Request                 */
139 #define ARS_ICMP_TIME_EXCEEDED      11      /* Time Exceeded                */
140 #define ARS_ICMP_PARAMETERPROB      12      /* Parameter Problem            */
141 #define ARS_ICMP_TIMESTAMP          13      /* Timestamp Request            */
142 #define ARS_ICMP_TIMESTAMPREPLY     14      /* Timestamp Reply              */
143 #define ARS_ICMP_INFO_REQUEST       15      /* Information Request          */
144 #define ARS_ICMP_INFO_REPLY         16      /* Information Reply            */
145 #define ARS_ICMP_ADDRESS            17      /* Address Mask Request         */
146 #define ARS_ICMP_ADDRESSREPLY       18      /* Address Mask Reply           */
147 
148 /* Codes for UNREACHABLE */
149 #define ARS_ICMP_UNR_NET		0       /* Network Unreachable */
150 #define ARS_ICMP_UNR_HOST		1       /* Host Unreachable */
151 #define ARS_ICMP_UNR_PROT		2       /* Protocol Unreachable */
152 #define ARS_ICMP_UNR_PORT		3       /* Port Unreachable */
153 #define ARS_ICMP_UNR_FRAG_NEEDED	4       /* Fragmentation Needed,DF set*/
154 #define ARS_ICMP_UNR_SR_FAILED          5       /* Source Route failed */
155 #define ARS_ICMP_UNR_UNK_NET		6
156 #define ARS_ICMP_UNR_UNK_HOST		7
157 #define ARS_ICMP_UNR_ISOLATED_HOST	8
158 #define ARS_ICMP_UNR_NET_ANO		9
159 #define ARS_ICMP_UNR_HOST_ANO		10
160 #define ARS_ICMP_UNR_NET_UNR_TOS	11
161 #define ARS_ICMP_UNR_HOST_UNR_TOS	12
162 #define ARS_ICMP_UNR_PKT_FILTERED	13      /* Packet filtered */
163 #define ARS_ICMP_UNR_PREC_VIOLATION	14      /* Precedence violation */
164 #define ARS_ICMP_UNR_PREC_CUTOFF	15      /* Precedence cut off */
165 #define ARS_NR_ICMP_UNREACH 15	/* Instead of hardcoded immediate value */
166 
167 /* Codes for REDIRECT */
168 #define ARS_ICMP_REDIR_NET		0       /* Redirect Net */
169 #define ARS_ICMP_REDIR_HOST		1       /* Redirect Host */
170 #define ARS_ICMP_REDIR_NETTOS		2       /* Redirect Net for TOS */
171 #define ARS_ICMP_REDIR_HOSTTOS		3       /* Redirect Host for TOS */
172 
173 /* Codes for TIME_EXCEEDED */
174 #define ARS_ICMP_EXC_TTL		0       /* TTL count exceeded */
175 #define ARS_ICMP_EXC_FRAGTIME		1       /* TTL exceeded reassembling */
176 
177 /* IGRP defines */
178 #define ARS_IGRP_OPCODE_UPDATE		1
179 #define ARS_IGRP_OPCODE_REQUEST		2
180 
181 /* The IP header structure */
182 struct ars_iphdr {
183 #if defined(BYTE_ORDER_LITTLE_ENDIAN)
184         __u8    ihl:4,
185                 version:4;
186 #elif defined (BYTE_ORDER_BIG_ENDIAN)
187         __u8    version:4,
188                 ihl:4;
189 #else
190 #error  "Please, edit Makefile and add -DBYTE_ORDER_(BIG|LITTLE)_ENDIAN"
191 #endif
192         __u8    tos;
193         __u16   tot_len;
194         __u16   id;
195         __u16   frag_off;
196         __u8    ttl;
197         __u8    protocol;
198         __u16   check;
199         __u32   saddr;
200         __u32   daddr;
201 };
202 
203 /* The IP options structure */
204 struct ars_ipopt {
205 	u_int8_t kind;
206 	u_int8_t len;
207 	union {
208 		struct {
209 			u_int16_t s;
210 			u_int16_t c;
211 			u_int16_t h;
212 			u_int8_t tcc[3];
213 		} sec;		/* security */
214 		struct {
215 			u_int8_t ptr;
216 			u_int8_t data[37];
217 		} src;		/* loose and strict source routing */
218 		struct {
219 			u_int8_t ptr;
220 			u_int8_t data[37];
221 		} rr;		/* record route */
222 		struct {
223 			u_int16_t id;
224 		} sid;		/* stream id */
225 		struct {
226 			u_int8_t ptr;
227 			u_int8_t flags;
228 			u_int8_t data[36];
229 		} ts;		/* timestamp */
230 	} un;
231 };
232 
233 /* The UDP header structure */
234 struct ars_udphdr {
235 	__u16 uh_sport;     /* source port */
236 	__u16 uh_dport;     /* destination port */
237 	__u16 uh_ulen;      /* udp length */
238 	__u16 uh_sum;       /* udp checksum */
239 };
240 
241 /* The TCP header structure */
242 struct ars_tcphdr {
243 	__u16	th_sport;               /* source port */
244 	__u16	th_dport;               /* destination port */
245 	__u32	th_seq;                 /* sequence number */
246 	__u32	th_ack;                 /* acknowledgement number */
247 #if defined (BYTE_ORDER_LITTLE_ENDIAN)
248 	__u8    th_x2:4,                /* (unused) */
249 		th_off:4;               /* data offset */
250 #elif defined (BYTE_ORDER_BIG_ENDIAN)
251 	__u8    th_off:4,               /* data offset */
252 		th_x2:4;                /* (unused) */
253 #else
254 #error  "Please, edit Makefile and add -DBYTE_ORDER_(BIG|LITTLE)_ENDIAN"
255 #endif
256 	__u8    th_flags;
257 	__u16   th_win;                 /* window */
258 	__u16   th_sum;                 /* checksum */
259 	__u16   th_urp;                 /* urgent pointer */
260 };
261 
262 /* The TCP options structure */
263 struct ars_tcpopt {
264 	u_int8_t kind;
265 	u_int8_t len;
266 	union {
267 		struct {
268 			u_int16_t size;
269 		} mss;
270 		struct {
271 			u_int8_t shift;
272 		} win;
273 		struct {
274 			u_int8_t origin[4];
275 			u_int8_t size[4];
276 		} sack[4]; /* max 4 SACK blocks in 40 bytes of space */
277 		struct {
278 			u_int8_t info[4];
279 		} echo;
280 		struct {
281 			u_int8_t tsval[4];
282 			u_int8_t tsecr[4];
283 		} timestamp;
284 	} un;
285 };
286 
287 /* The ICMP header structure */
288 struct ars_icmphdr
289 {
290 	__u8          type;
291 	__u8          code;
292 	__u16         checksum;
293 	union
294 	{
295 		struct
296 		{
297 			__u16   id;
298 			__u16   sequence;
299 		} echo; /* called echo since it's the most used */
300 		__u32   gateway;
301 	} un;
302 };
303 
304 /* TCP/UDP pseudo header used to compute the checksum */
305 struct ars_pseudohdr
306 {
307 	__u32 saddr;
308 	__u32 daddr;
309 	__u8  zero;
310 	__u8  protocol;
311 	__u16 lenght;
312 };
313 
314 /* The IGRP header structure */
315 struct ars_igrphdr {
316 #if defined(BYTE_ORDER_LITTLE_ENDIAN)
317         __u8    opcode:4,
318                 version:4;
319 #elif defined (BYTE_ORDER_BIG_ENDIAN)
320         __u8    version:4,
321                 opcode:4;
322 #else
323 #error  "Please, edit Makefile and add -DBYTE_ORDER_(BIG|LITTLE)_ENDIAN"
324 #endif
325 	__u8	edition;
326 	__u16	autosys;
327 	__u16	interior;
328 	__u16	system;
329 	__u16	exterior;
330 	__u16	checksum;
331 };
332 
333 /* The IGRP entry */
334 struct ars_igrpentry {
335 	__u8	destination[3];
336 	__u8	delay[3];
337 	__u8	bandwidth[3];
338 	__u8	mtu[2];
339 	__u8	reliability;
340 	__u8	load;
341 	__u8	hopcount;
342 };
343 
344 struct ars_packet; /* forward declaration */
345 
346 /* ARS layer */
347 struct ars_layer {
348 	int l_type;
349 	int l_size;
350 	int l_flags;
351 	void *l_data;
352 	struct ars_packet *l_packet;
353 };
354 
355 #define ARS_MAX_LAYER	256
356 #define ARS_ERR_BUFSZ	1024
357 
358 /* Types */
359 #define ARS_TYPE_SIZE		32
360 #define ARS_TYPE_NULL		0
361 #define ARS_TYPE_IP		1
362 #define ARS_TYPE_IPOPT		2
363 #define ARS_TYPE_ICMP		3
364 #define ARS_TYPE_UDP		4
365 #define ARS_TYPE_TCP		5
366 #define ARS_TYPE_TCPOPT		6
367 #define ARS_TYPE_IGRP		7
368 #define ARS_TYPE_IGRPENTRY	8
369 #define ARS_TYPE_DATA		31
370 
371 /* ARS packet context */
372 struct ars_packet {
373 	char *p_error;
374 	int p_layer_nr;
375 	struct ars_layer p_layer[ARS_MAX_LAYER];
376 	void *p_default[ARS_TYPE_SIZE];
377 	int p_options;
378 	int aux; /* Auxiliar variable for data exchange between functions */
379 	int aux_ipproto; /* This hold the ip->proto field seen in the last
380 			  IP datagram so that when the IP options processing
381 			  is done, the split-machine can continue with
382 			  the right state. */
383 };
384 
385 /* Facility to check for flags */
386 #define ARS_TAKE(f,x)		(f & x)
387 #define ARS_DONTTAKE(f, x)	(!(f & x))
388 #define ARS_TAKE_NONE		0
389 
390 /* IP layer flags */
391 #define ARS_TAKE_IP_VERSION	(1 << 0)
392 #define ARS_TAKE_IP_HDRLEN	(1 << 1)
393 #define ARS_TAKE_IP_TOTLEN	(1 << 2)
394 #define ARS_TAKE_IP_PROTOCOL	(1 << 3)
395 #define ARS_TAKE_IP_CKSUM	(1 << 4)
396 
397 /* IP options layers flags */
398 #define ARS_TAKE_IPOPT_PTR	(1 << 0) /* for RR, LSRR, SSRR */
399 
400 /* ICMP layer flags */
401 #define ARS_TAKE_ICMP_CKSUM	(1 << 0)
402 
403 /* UDP layer flags */
404 #define ARS_TAKE_UDP_CKSUM	(1 << 0)
405 #define ARS_TAKE_UDP_LEN	(1 << 1)
406 
407 /* TCP layer flags */
408 #define ARS_TAKE_TCP_HDRLEN	(1 << 0)
409 #define ARS_TAKE_TCP_CKSUM	(1 << 1)
410 
411 /* IGRP layer flags */
412 #define ARS_TAKE_IGRP_CKSUM	(1 << 0)
413 
414 /* Some function that acts on layer switch to the last layer with this */
415 #define ARS_LAST_LAYER		-1
416 
417 /* Structure and defines needed to calculate the internet-like checksum
418  * when the data is splitted in more not adjacent buffers */
419 #define ARS_MC_INIT     0
420 #define ARS_MC_UPDATE   1
421 #define ARS_MC_FINAL    2
422 
423 struct mc_context {
424 	u_int32_t oddbyte_flag;
425 	u_int32_t old;
426 	u_int8_t oddbyte;
427 	u_int8_t pad;
428 };
429 
430 /* ARS layer info structure */
431 struct ars_layer_info {
432 	char *li_name; /* NULL = unused slot */
433 	int (*li_compiler) (struct ars_packet *pkt, int layer); /* NULL = NOP */
434 	int (*li_rapd) (struct adbuf *dest, struct ars_packet *pkt, int layer);
435 	int layer_id;
436 };
437 
438 /* ARS layer info table */
439 extern struct ars_layer_info ars_linfo[ARS_TYPE_SIZE];
440 
441 /* ARS interface managment structure and defines */
442 #define ARS_IF_UP	(1 << 0)
443 #define ARS_IF_LOOP	(1 << 1)
444 #define ARS_IF_IPV4	(1 << 2)
445 #define ARS_IF_IPV6 	(1 << 3)
446 #define ARS_IF_MISCONF	(1 << 4)
447 
448 #define ARS_IF_MAX_IFACE	16
449 #define ARS_IF_NAME_SIZE	32
450 
451 /* iface type are obtained using libpcap to avoid efforts duplication */
452 struct ars_iface {
453 	char if_name[ARS_IF_NAME_SIZE];
454 	int if_mtu;
455 	int if_flags;
456 	char if_ipv4addr[ARS_INET_ADDRSTRLEN];
457 	char if_ipv6addr[ARS_INET6_ADDRSTRLEN];
458 };
459 
460 /* Flags for packet splitting */
461 #define ARS_SPLIT_FTRUNC        (1 << 0)
462 #define ARS_SPLIT_FBADCKSUM     (1 << 1)
463 
464 /* Ars packet options */
465 #define ARS_OPT_RAPD_HEXDATA	(1 << 0) /* Use hex format for RAPD data */
466 
467 /* More macros */
468 #define ars_atou(x) strtoul(x, (char **) NULL, 0)
469 #define ars_set_option(pkt,opt) do { (pkt)->p_options |= (opt); } while(0)
470 #define ars_clear_option(pkt,opt) do { (pkt)->p_options &= ~(opt); } while(0)
471 #define ars_test_option(pkt,opt) ((pkt)->p_options & (opt))
472 
473 /* Prototypes */
474 int ars_init(struct ars_packet *pkt);
475 int ars_destroy(struct ars_packet *pkt);
476 int ars_nospace(struct ars_packet *pkt);
477 int ars_add_generic(struct ars_packet *pkt, size_t size, int type);
478 void *ars_add_iphdr(struct ars_packet *pkt, int unused);
479 void *ars_add_ipopt(struct ars_packet *pkt, int option);
480 void *ars_add_udphdr(struct ars_packet *pkt, int unused);
481 void *ars_add_tcphdr(struct ars_packet *pkt, int unused);
482 void *ars_add_tcpopt(struct ars_packet *pkt, int option);
483 void *ars_add_icmphdr(struct ars_packet *pkt, int unused);
484 void *ars_add_igrphdr(struct ars_packet *pkt, int unused);
485 void *ars_add_igrpentry(struct ars_packet *pkt, int unused);
486 void *ars_add_data(struct ars_packet *pkt, int size);
487 size_t ars_relative_size(struct ars_packet *pkt, int layer_nr);
488 size_t ars_packet_size(struct ars_packet *pkt);
489 u_int16_t ars_cksum(void *vbuf, size_t nbytes);
490 u_int16_t ars_multi_cksum(struct mc_context *c, int op, void *vbuf, size_t nbytes);
491 int ars_compile(struct ars_packet *pkt);
492 int ars_udptcp_cksum(struct ars_packet *pkt, int layer, u_int16_t *sum);
493 int ars_open_rawsocket(struct ars_packet *pkt);
494 int ars_build_packet(struct ars_packet *pkt, unsigned char **packet, size_t *size);
495 int ars_bsd_fix(struct ars_packet *pkt, unsigned char *packet, size_t size);
496 int ars_set_flags(struct ars_packet *pkt, int layer, int flags);
497 int ars_send(int s, struct ars_packet *pkt, struct sockaddr *sa, socklen_t slen);
498 int ars_resolve(struct ars_packet *pkt, u_int32_t *dest, char *hostname);
499 int ars_set_error(struct ars_packet *pkt, const char *fmt, ...);
500 int ars_d_build(struct ars_packet *pkt, char *t);
501 int ars_valid_layer(int layer);
502 int ars_get_iface_list(struct ars_iface *iface, size_t *isize);
503 int ars_get_iface(char *name, struct ars_iface *i);
504 int ars_valid_layer(int layer);
505 int ars_remove_layer(struct ars_packet *pkt, int layer);
506 
507 /* split.c prototypes */
508 int ars_seems_ip(struct ars_iphdr *ip, size_t size);
509 int ars_guess_ipoff(void *packet, size_t size, int *lhs);
510 int ars_check_ip_cksum(struct ars_iphdr *ip);
511 int ars_check_icmp_cksum(struct ars_icmphdr *icmp, size_t size);
512 int ars_split_packet(void *packet, size_t size, int ipoff, struct ars_packet *pkt);
513 
514 /* reverse apd */
515 int ars_d_from_ars(char *dest, size_t len, struct ars_packet *pkt);
516 int ars_rapd_ip(struct adbuf *dest, struct ars_packet *pkt, int layer);
517 int ars_rapd_ipopt(struct adbuf *dest, struct ars_packet *pkt, int layer);
518 int ars_rapd_icmp(struct adbuf *dest, struct ars_packet *pkt, int layer);
519 int ars_rapd_udp(struct adbuf *dest, struct ars_packet *pkt, int layer);
520 int ars_rapd_tcp(struct adbuf *dest, struct ars_packet *pkt, int layer);
521 int ars_rapd_tcpopt(struct adbuf *dest, struct ars_packet *pkt, int layer);
522 int ars_rapd_igrp(struct adbuf *dest, struct ars_packet *pkt, int layer);
523 int ars_rapd_igrpentry(struct adbuf *dest, struct ars_packet *pkt, int layer);
524 int ars_rapd_data(struct adbuf *dest, struct ars_packet *pkt, int layer);
525 
526 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \
527     !defined(__bsdi__) && !defined(__APPLE__)
528 size_t strlcpy(char *dst, const char *src, size_t siz);
529 #endif
530 
531 #endif /* _ARS_H */
532