1 /* Copyright (C) 2000,2001 Salvatore Sanfilippo <antirez@invece.org>
2  * See the LICENSE file for more information.
3  *
4  * ARS Packet Description System.
5  *
6  * Please, prefix all the function with ars_d_ */
7 
8 /* $Id: apd.c,v 1.3 2003/09/07 11:21:18 antirez Exp $ */
9 
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <sys/types.h>
14 #include <netinet/in.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <ctype.h>
19 #include "ars.h"
20 #include "hstring.h"
21 #include "hex.h"
22 
23 /* FIXME: parsing should use dynamic buffers to use less memory.
24  * For now we support MTU up to 3000 */
25 #define ARS_MAX_TSIZE	(3000*4)
ars_d_parser(char * t,char * next,size_t size)26 char *ars_d_parser(char *t, char *next, size_t size)
27 {
28 	int i = 0;
29 
30 	if (size == 0 || next == NULL || *t == '\0')
31 		return NULL;
32 	size--; /* space for nul term */
33 	while (1) {
34 		/* no space for the next char */
35 		if (i == size) {
36 			next[i] = '\0';
37 			return t;
38 		}
39 		switch(*t) {
40 		case '\0':
41 		case '(':
42 		case ')':
43 		case ',':
44 		case '=':
45 		case '+':
46 			if (i == 0) {
47 				next[i] = *t;
48 				next[i+1] = '\0';
49 				return t+1;
50 			} else {
51 				next[i] = '\0';
52 				return t;
53 			}
54 		default:
55 			next[i++] = *t++;
56 			break;
57 		}
58 	}
59 	return NULL; /* unreached */
60 }
61 
62 /* states */
63 #define ARS_G_LAYER		0
64 #define ARS_G_FIELD_OR_CBRACE	1
65 #define ARS_G_VALUE		2
66 #define ARS_G_OBRACE_OR_PLUS	3
67 #define ARS_G_CBRACE		4
68 #define ARS_G_COMMA_OR_CBRACE	5
69 #define ARS_G_LEN_OR_PLUS	6
70 #define ARS_G_PLUS		7
71 #define ARS_G_EQUAL		8
72 
73 struct ars_d_keyword_info {
74 	char *ki_keyword;
75 	int ki_opt;
76 	void *(*ki_add) (struct ars_packet *pkt, int opt);
77 	int (*ki_set) (struct ars_packet *pkt, int layer, char *f, char *v);
78 };
79 
80 #define ARS_DKINFO_SIZE		64
81 
82 /* If the user specify a layer number of -1 with *set functions, the
83  * last layer is selected */
84 #define ARS_DEF_LAYER \
85 do { \
86 	if (layer == ARS_LAST_LAYER) \
87 		layer = pkt->p_layer_nr - 1; \
88 	if (ars_valid_layer(layer) != -ARS_OK) \
89 		return -ARS_INVALID; \
90 } while(0)
91 
92 #define BOGUS_SET_F(x) \
93   int (x)(struct ars_packet *pkt, int layer, char *f, char *v) { return 0; }
94 
95 int ars_d_set_ip(struct ars_packet *pkt, int layer, char *f, char *v);
96 int ars_d_set_udp(struct ars_packet *pkt, int layer, char *f, char *v);
97 int ars_d_set_tcp(struct ars_packet *pkt, int layer, char *f, char *v);
98 int ars_d_set_icmp(struct ars_packet *pkt, int layer, char *f, char *v);
99 int ars_d_set_data(struct ars_packet *pkt, int layer, char *f, char *v);
100 int ars_d_set_ipopt_rr(struct ars_packet *pkt, int layer, char *f, char *v);
101 int ars_d_set_ipopt_ts(struct ars_packet *pkt, int layer, char *f, char *v);
102 int ars_d_set_ipopt_sid(struct ars_packet *pkt, int layer, char *f, char *v);
103 int ars_d_set_ipopt_sec(struct ars_packet *pkt, int layer, char *f, char *v);
104 int ars_d_set_ipopt_dumb(struct ars_packet *pkt, int layer, char *f, char *v);
105 int ars_d_set_tcpopt_mss(struct ars_packet *pkt, int layer, char *f, char *v);
106 int ars_d_set_tcpopt_wscale(struct ars_packet *pkt, int layer, char *f, char *v);
107 int ars_d_set_tcpopt_sack(struct ars_packet *pkt, int layer, char *f, char *v);
108 int ars_d_set_tcpopt_echo(struct ars_packet *pkt, int layer, char *f, char *v);
109 int ars_d_set_tcpopt_dumb(struct ars_packet *pkt, int layer, char *f, char *v);
110 int ars_d_set_igrp(struct ars_packet *pkt, int layer, char *f, char *v);
111 int ars_d_set_igrpentry(struct ars_packet *pkt, int layer, char *f, char *v);
112 BOGUS_SET_F(ars_d_set_tcpopt_ts)
113 
114 struct ars_d_keyword_info ars_dkinfo[ARS_DKINFO_SIZE] = {
115 	/* KEYWORD	OPT		ADD function	SET function *
116 	 * --------------------------------------------------------- */
117 	{"ip",		0,		ars_add_iphdr,	ars_d_set_ip},
118 	{"ip.eol",	ARS_IPOPT_EOL,	ars_add_ipopt,	ars_d_set_ipopt_dumb},
119 	{"ip.nop",	ARS_IPOPT_NOP,	ars_add_ipopt,	ars_d_set_ipopt_dumb},
120 	{"ip.sec",	ARS_IPOPT_SEC,	ars_add_ipopt,	ars_d_set_ipopt_sec},
121 	{"ip.sid",	ARS_IPOPT_SID,	ars_add_ipopt,	ars_d_set_ipopt_sid},
122 	{"ip.lsrr",	ARS_IPOPT_LSRR,	ars_add_ipopt,	ars_d_set_ipopt_rr},
123 	{"ip.ssrr",	ARS_IPOPT_SSRR,	ars_add_ipopt,	ars_d_set_ipopt_rr},
124 	{"ip.rr",	ARS_IPOPT_RR,	ars_add_ipopt,	ars_d_set_ipopt_rr},
125 	{"ip.ts",	ARS_IPOPT_TIMESTAMP, ars_add_ipopt, ars_d_set_ipopt_ts},
126 	{"udp",		0,		ars_add_udphdr,	ars_d_set_udp},
127 	{"tcp",		0,		ars_add_tcphdr,	ars_d_set_tcp},
128 	{"tcp.eol",	ARS_TCPOPT_EOL,	ars_add_tcpopt,	ars_d_set_tcpopt_dumb},
129 	{"tcp.nop",	ARS_TCPOPT_NOP,	ars_add_tcpopt,	ars_d_set_tcpopt_dumb},
130 	{"tcp.mss",	ARS_TCPOPT_MAXSEG, ars_add_tcpopt, ars_d_set_tcpopt_mss},
131 	{"tcp.wscale", ARS_TCPOPT_WINDOW, ars_add_tcpopt, ars_d_set_tcpopt_wscale},
132 	{"tcp.sackperm", ARS_TCPOPT_SACK_PERM, ars_add_tcpopt, ars_d_set_tcpopt_dumb},
133 	{"tcp.sack", ARS_TCPOPT_SACK, ars_add_tcpopt, ars_d_set_tcpopt_sack},
134 	{"tcp.echo", ARS_TCPOPT_ECHOREQUEST, ars_add_tcpopt, ars_d_set_tcpopt_echo},
135 	{"tcp.echoreply", ARS_TCPOPT_ECHOREPLY, ars_add_tcpopt, ars_d_set_tcpopt_echo},
136 	{"tcp.ts",	ARS_TCPOPT_TIMESTAMP, ars_add_tcpopt, ars_d_set_tcpopt_ts},
137 	{"icmp",	0,		ars_add_icmphdr, ars_d_set_icmp},
138 	{"igrp",	0,		ars_add_igrphdr, ars_d_set_igrp},
139 	{"igrp.entry",	0,		ars_add_igrpentry, ars_d_set_igrpentry},
140 	{"data",	0,		ars_add_data,	ars_d_set_data},
141 	{NULL, 0, NULL, NULL} /* nul term */
142 };
143 
ars_get_keyword_by_name(char * name)144 struct ars_d_keyword_info *ars_get_keyword_by_name(char *name)
145 {
146 	struct ars_d_keyword_info *k = ars_dkinfo;
147 
148 	while (k->ki_keyword) {
149 		if (strcasecmp(k->ki_keyword, name) == 0)
150 			return k;
151 		k++;
152 	}
153 	return NULL;
154 }
155 
ars_d_setlayer_size(struct ars_packet * pkt,int layer,char * size)156 int ars_d_setlayer_size(struct ars_packet *pkt, int layer, char *size)
157 {
158 	size_t newsize;
159 
160 	ARS_DEF_LAYER;
161 	newsize = ars_atou(size);
162 	if (newsize < 1 || newsize > pkt->p_layer[layer].l_size) {
163 		ars_set_error(pkt, "Invalid layer size in description");
164 		return -ARS_INVALID;
165 	}
166 	pkt->p_layer[layer].l_size = newsize;
167 
168 	__D(printf("Setting the layer to size %s\n", size);)
169 	return -ARS_OK;
170 }
171 
ars_d_set_ip(struct ars_packet * pkt,int layer,char * f,char * v)172 int ars_d_set_ip(struct ars_packet *pkt, int layer, char *f, char *v)
173 {
174 	struct ars_iphdr *ip;
175 
176 	ARS_DEF_LAYER;
177 	ip = pkt->p_layer[layer].l_data;
178 
179 	if (strcasecmp(f, "saddr") == 0) {
180 		return ars_resolve(pkt, &ip->saddr, v);
181 	} else if (strcasecmp(f, "daddr") == 0) {
182 		return ars_resolve(pkt, &ip->daddr, v);
183 	} else if (strcasecmp(f, "ihl") == 0) {
184 		ip->ihl = ars_atou(v);
185 		pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_HDRLEN;
186 	} else if (strcasecmp(f, "ver") == 0) {
187 		ip->version = ars_atou(v);
188 		pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_VERSION;
189 	} else if (strcasecmp(f, "tos") == 0) {
190 		ip->tos = ars_atou(v);
191 	} else if (strcasecmp(f, "totlen") == 0) {
192 		ip->tot_len = htons(ars_atou(v));
193 		pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_TOTLEN;
194 	} else if (strcasecmp(f, "id") == 0) {
195 		ip->id = htons(ars_atou(v));
196 	} else if (strcasecmp(f, "fragoff") == 0) {
197 		ip->frag_off = ip->frag_off & 0xE000;
198 		ip->frag_off |= htons(ars_atou(v) >> 3);
199 	} else if (strcasecmp(f, "mf") == 0) {
200 		if (ars_atou(v) == 0)
201 			ip->frag_off &= htons(~ARS_IP_MF);
202 		else
203 			ip->frag_off |= htons(ARS_IP_MF);
204 	} else if (strcasecmp(f, "df") == 0) {
205 		if (ars_atou(v) == 0)
206 			ip->frag_off &= htons(~ARS_IP_DF);
207 		else
208 			ip->frag_off |= htons(ARS_IP_DF);
209 	} else if (strcasecmp(f, "rf") == 0) {
210 		if (ars_atou(v) == 0)
211 			ip->frag_off &= htons((u_int16_t)~ARS_IP_RF);
212 		else
213 			ip->frag_off |= htons(ARS_IP_RF);
214 	} else if (strcasecmp(f, "ttl") == 0) {
215 		ip->ttl = ars_atou(v);
216 	} else if (strcasecmp(f, "proto") == 0) {
217 		if (!strcasecmp(v, "icmp")) {
218 			ip->protocol = ARS_IPPROTO_ICMP;
219 		} else if (!strcasecmp(v, "udp")) {
220 			ip->protocol = ARS_IPPROTO_UDP;
221 		} else if (!strcasecmp(v, "tcp")) {
222 			ip->protocol = ARS_IPPROTO_TCP;
223 		} else {
224 			ip->protocol = ars_atou(v);
225 		}
226 		pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_PROTOCOL;
227 	} else if (strcasecmp(f, "cksum") == 0) {
228 		ip->check = htons(ars_atou(v));
229 		pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_CKSUM;
230 	} else {
231 		ars_set_error(pkt, "Invalid field for IP layer: '%s'", f);
232 		return -ARS_INVALID;
233 	}
234 	return -ARS_OK;
235 }
236 
237 /* Note: for all the variable-length ip options the allocated layer data
238  * length is always as big as possible (40 bytes), so set_ipopt_rr() and
239  * other similar functions don't need to check if there is enough room.
240  * Of course functions shoult still check to not overflow over the 40
241  * bytes, but this makes very little sense. */
242 #define IPOPTRR_MAX_ENTRIES 9
ars_d_set_ipopt_rr(struct ars_packet * pkt,int layer,char * f,char * v)243 int ars_d_set_ipopt_rr(struct ars_packet *pkt, int layer, char *f, char *v)
244 {
245 	struct ars_ipopt *ipopt;
246 
247 	ARS_DEF_LAYER;
248 	ipopt = pkt->p_layer[layer].l_data;
249 
250 	if (strcasecmp(f, "optlen") == 0) {
251 		ipopt->len = ars_atou(v);
252 	} else if (strcasecmp(f, "ptr") == 0) {
253 		ipopt->un.rr.ptr = ars_atou(v);
254 		pkt->p_layer[layer].l_flags |= ARS_TAKE_IPOPT_PTR;
255 	} else if (strcasecmp(f, "data") == 0) {
256 		char *addrv[IPOPTRR_MAX_ENTRIES];
257 		int vlen = strlen(v), num, i;
258 		char *vcopy = alloca(vlen+1);
259 		unsigned char *data = pkt->p_layer[layer].l_data;
260 
261 		memcpy(vcopy, v, vlen+1);
262 		num = strftok("/", vcopy, addrv, IPOPTRR_MAX_ENTRIES);
263 		for (i = 0; i < num; i++) {
264 			__u32 addr;
265 			int err;
266 
267 			err = ars_resolve(pkt, &addr, addrv[i]);
268 			if (err != -ARS_OK)
269 				return err;
270 			memcpy(data+3+(i*4), &addr, 4);
271 		}
272 		if (ARS_DONTTAKE(pkt->p_layer[layer].l_flags,
273 					ARS_TAKE_IPOPT_PTR))
274 		{
275 			/* For the record route option the default ptr
276 			 * is at the end of the specified entries */
277 			if (ipopt->kind == ARS_IPOPT_RR) {
278 				ipopt->un.rr.ptr = 4+(num*4);
279 			} else {
280 			/* For SSRR and LSRR is set at the start
281 			 * if not otherwise specified. */
282 				ipopt->un.rr.ptr = 4;
283 			}
284 		}
285 	} else {
286 		ars_set_error(pkt, "Invalid field for IP.RR layer: '%s'", f);
287 		return -ARS_INVALID;
288 	}
289 
290 	return -ARS_OK;
291 }
292 
293 #define IPOPTTS_MAX_ENTRIES 9
ars_d_set_ipopt_ts(struct ars_packet * pkt,int layer,char * f,char * v)294 int ars_d_set_ipopt_ts(struct ars_packet *pkt, int layer, char *f, char *v)
295 {
296 	struct ars_ipopt *ipopt;
297 	int flags, overflow;
298 
299 	ARS_DEF_LAYER;
300 	ipopt = pkt->p_layer[layer].l_data;
301 	overflow = (ipopt->un.ts.flags & 0xF0) >> 4;
302 	flags = ipopt->un.ts.flags & 0xF;
303 
304 	if (strcasecmp(f, "optlen") == 0) {
305 		ipopt->len = ars_atou(v);
306 	} else if (strcasecmp(f, "ptr") == 0) {
307 		ipopt->un.rr.ptr = ars_atou(v);
308 		pkt->p_layer[layer].l_flags |= ARS_TAKE_IPOPT_PTR;
309 	} else if (strcasecmp(f, "flags") == 0) {
310 		if (strisnum(v)) {
311 			flags = ars_atou(v) & 0xF;
312 		} else {
313 			if (!strcasecmp(v, "tsonly"))
314 				flags = ARS_IPOPT_TS_TSONLY;
315 			else if (!strcasecmp(v, "tsandaddr"))
316 				flags = ARS_IPOPT_TS_TSANDADDR;
317 			else if (!strcasecmp(v, "prespec"))
318 				flags = ARS_IPOPT_TS_PRESPEC;
319 			else {
320 				ars_set_error(pkt, "Invalid symbol for ip.ts flags: '%s' (use: tsonly, tsandaddr, prespec or a numerical value)", v);
321 				return -ARS_INVALID;
322 			}
323 		}
324 		ipopt->un.ts.flags = ((overflow&0xF)<<4)|(flags&0xF);
325 	} else if (strcasecmp(f, "overflow") == 0) {
326 		overflow = ars_atou(v) & 0xF;
327 		ipopt->un.ts.flags = ((overflow&0xF)<<4)|(flags&0xF);
328 	} else if (strcasecmp(f, "data") == 0) {
329 		char *addrv[IPOPTTS_MAX_ENTRIES];
330 		int vlen = strlen(v), num, i;
331 		char *vcopy = alloca(vlen+1);
332 		unsigned char *data = pkt->p_layer[layer].l_data;
333 
334 		memcpy(vcopy, v, vlen+1);
335 		num = strftok("/", vcopy, addrv, IPOPTTS_MAX_ENTRIES);
336 		for (i = 0; i < num; i++) {
337 			__u32 addr, ts;
338 			int err;
339 			char *p;
340 
341 			p = strchr(addrv[i], '@');
342 			if (p) {
343 				if (flags == ARS_IPOPT_TS_TSONLY) {
344 					ars_set_error(pkt, "Gateway specified but ip.ts flags set to 'tsonly'. (Try flags=tsandaddr,data=...)");
345 					return -ARS_INVALID;
346 				}
347 				*p = '\0';
348 				p++;
349 				err = ars_resolve(pkt, &addr, p);
350 				if (err != -ARS_OK)
351 					return err;
352 				ts = ars_atou(addrv[i]);
353 				ts = htonl(ts);
354 				if (i < 4) {
355 					memcpy(data+4+(i*8), &addr, 4);
356 					memcpy(data+8+(i*8), &ts, 4);
357 				};
358 			} else {
359 				if (flags == ARS_IPOPT_TS_TSANDADDR ||
360 				    flags == ARS_IPOPT_TS_PRESPEC) {
361 					ars_set_error(pkt, "Gateway not specified in data for ip.ts, but flags set to 'tsandaddr' or 'prespec'. (Try flags=tsonly)");
362 					return -ARS_INVALID;
363 				}
364 				ts = ars_atou(addrv[i]);
365 				ts = htonl(ts);
366 				memcpy(data+4+(i*4), &ts, 4);
367 			}
368 		}
369 		if (ARS_DONTTAKE(pkt->p_layer[layer].l_flags,
370 					ARS_TAKE_IPOPT_PTR))
371 		{
372 			if (flags == ARS_IPOPT_TS_TSANDADDR ||
373 			    flags == ARS_IPOPT_TS_PRESPEC) {
374 				ipopt->un.rr.ptr = 5+(num*8);
375 			} else {
376 				ipopt->un.rr.ptr = 5+(num*4);
377 			}
378 		}
379 	} else {
380 		ars_set_error(pkt, "Invalid field for IP.TS layer: '%s'", f);
381 		return -ARS_INVALID;
382 	}
383 
384 	return -ARS_OK;
385 }
386 
ars_d_set_ipopt_sid(struct ars_packet * pkt,int layer,char * f,char * v)387 int ars_d_set_ipopt_sid(struct ars_packet *pkt, int layer, char *f, char *v)
388 {
389 	struct ars_ipopt *ipopt;
390 
391 	ARS_DEF_LAYER;
392 	ipopt = pkt->p_layer[layer].l_data;
393 	if (strcasecmp(f, "optlen") == 0) {
394 		ipopt->len = ars_atou(v);
395 	} else if (strcasecmp(f, "sid") == 0) {
396 		ipopt->un.sid.id = ars_atou(v);
397 	} else {
398 		ars_set_error(pkt, "Invalid field for IP.SID layer: '%s'", f);
399 		return -ARS_INVALID;
400 	}
401 	return -ARS_OK;
402 }
403 
ars_d_set_ipopt_sec(struct ars_packet * pkt,int layer,char * f,char * v)404 int ars_d_set_ipopt_sec(struct ars_packet *pkt, int layer, char *f, char *v)
405 {
406 	struct ars_ipopt *ipopt;
407 
408 	ARS_DEF_LAYER;
409 	ipopt = pkt->p_layer[layer].l_data;
410 	if (strcasecmp(f, "optlen") == 0) {
411 		ipopt->len = ars_atou(v);
412 	} else if (strcasecmp(f, "seclev") == 0) {
413 		ipopt->un.sec.s = ars_atou(v);
414 	} else if (strcasecmp(f, "comp") == 0) {
415 		ipopt->un.sec.c = ars_atou(v);
416 	} else if (strcasecmp(f, "hrest") == 0) {
417 		if (strlen(v) != 4) {
418 			ars_set_error(pkt, "Invalid ip.sec hrest field value of '%s'(should be four hex digits, like this: ...,hrest=252A,...)", v);
419 			return -ARS_INVALID;
420 		}
421 		if (hextobin(&ipopt->un.sec.h, v, 4)) {
422 			ars_set_error(pkt, "Invalid hex value for ip.sec hex: '%s'", v);
423 			return -ARS_INVALID;
424 		}
425 	} else if (strcasecmp(f, "tcc") == 0) {
426 		if (strlen(v) != 6) {
427 			ars_set_error(pkt, "Invalid ip.sec tcc field value of '%s'(should be six hex digits, like this: ...,tcc=252A27,...)", v);
428 			return -ARS_INVALID;
429 		}
430 		if (hextobin(&ipopt->un.sec.h, v, 6)) {
431 			ars_set_error(pkt, "Invalid hex value for ip.sec hex: '%s'", v);
432 			return -ARS_INVALID;
433 		}
434 	} else {
435 		ars_set_error(pkt, "Invalid field for IP.SEC layer: '%s'", f);
436 		return -ARS_INVALID;
437 	}
438 
439 	return -ARS_OK;
440 }
441 
ars_d_set_ipopt_dumb(struct ars_packet * pkt,int layer,char * f,char * v)442 int ars_d_set_ipopt_dumb(struct ars_packet *pkt, int layer, char *f, char *v)
443 {
444 	struct ars_ipopt *ipopt;
445 
446 	ARS_DEF_LAYER;
447 	ipopt = pkt->p_layer[layer].l_data;
448 	if (strcasecmp(f, "optlen") == 0) {
449 		ipopt->len = ars_atou(v);
450 	} else {
451 		ars_set_error(pkt, "Invalid field for IP.? layer: '%s'", f);
452 		return -ARS_INVALID;
453 	}
454 	return -ARS_OK;
455 }
456 
ars_d_set_udp(struct ars_packet * pkt,int layer,char * f,char * v)457 int ars_d_set_udp(struct ars_packet *pkt, int layer, char *f, char *v)
458 {
459 	struct ars_udphdr *udp;
460 
461 	ARS_DEF_LAYER;
462 	udp = pkt->p_layer[layer].l_data;
463 
464 	if (strcasecmp(f, "sport") == 0) {
465 		udp->uh_sport = htons(ars_atou(v));
466 	} else if (strcasecmp(f, "dport") == 0) {
467 		udp->uh_dport = htons(ars_atou(v));
468 	} else if (strcasecmp(f, "len") == 0) {
469 		udp->uh_ulen = htons(ars_atou(v));
470 		pkt->p_layer[layer].l_flags |= ARS_TAKE_UDP_LEN;
471 	} else if (strcasecmp(f, "cksum") == 0) {
472 		udp->uh_sum = htons(ars_atou(v));
473 		pkt->p_layer[layer].l_flags |= ARS_TAKE_UDP_CKSUM;
474 	} else {
475 		ars_set_error(pkt, "Invalid field for UDP layer: '%s'", f);
476 		return -ARS_INVALID;
477 	}
478 	return -ARS_OK;
479 }
480 
ars_d_set_tcp(struct ars_packet * pkt,int layer,char * f,char * v)481 int ars_d_set_tcp(struct ars_packet *pkt, int layer, char *f, char *v)
482 {
483 	struct ars_tcphdr *tcp;
484 
485 	ARS_DEF_LAYER;
486 	tcp = pkt->p_layer[layer].l_data;
487 
488 	if (strcasecmp(f, "sport") == 0) {
489 		tcp->th_sport = htons(ars_atou(v));
490 	} else if (strcasecmp(f, "dport") == 0) {
491 		tcp->th_dport = htons(ars_atou(v));
492 	} else if (strcasecmp(f, "seq") == 0) {
493 		tcp->th_seq = htonl(ars_atou(v));
494 	} else if (strcasecmp(f, "ack") == 0) {
495 		tcp->th_ack = htonl(ars_atou(v));
496 	} else if (strcasecmp(f, "x2") == 0) {
497 		tcp->th_x2 = ars_atou(v);
498 	} else if (strcasecmp(f, "off") == 0) {
499 		tcp->th_off = ars_atou(v);
500 		pkt->p_layer[layer].l_flags |= ARS_TAKE_TCP_HDRLEN;
501 	} else if (strcasecmp(f, "flags") == 0) {
502 		tcp->th_flags = 0;
503 		if (strchr(v, 'f') || strchr(v, 'F'))
504 			tcp->th_flags |= ARS_TCP_TH_FIN;
505 		if (strchr(v, 's') || strchr(v, 'S'))
506 			tcp->th_flags |= ARS_TCP_TH_SYN;
507 		if (strchr(v, 'r') || strchr(v, 'R'))
508 			tcp->th_flags |= ARS_TCP_TH_RST;
509 		if (strchr(v, 'p') || strchr(v, 'P'))
510 			tcp->th_flags |= ARS_TCP_TH_PUSH;
511 		if (strchr(v, 'a') || strchr(v, 'A'))
512 			tcp->th_flags |= ARS_TCP_TH_ACK;
513 		if (strchr(v, 'u') || strchr(v, 'U'))
514 			tcp->th_flags |= ARS_TCP_TH_URG;
515 		if (strchr(v, 'x') || strchr(v, 'X'))
516 			tcp->th_flags |= ARS_TCP_TH_X;
517 		if (strchr(v, 'y') || strchr(v, 'Y'))
518 			tcp->th_flags |= ARS_TCP_TH_Y;
519 	} else if (strcasecmp(f, "win") == 0) {
520 		tcp->th_win = htons(ars_atou(v));
521 	} else if (strcasecmp(f, "cksum") == 0) {
522 		tcp->th_sum = htons(ars_atou(v));
523 		pkt->p_layer[layer].l_flags |= ARS_TAKE_TCP_CKSUM;
524 	} else if (strcasecmp(f, "urp") == 0) {
525 		tcp->th_urp = htons(ars_atou(v));
526 	} else {
527 		ars_set_error(pkt, "Invalid field for TCP layer: '%s'", f);
528 		return -ARS_INVALID;
529 	}
530 	return -ARS_OK;
531 }
532 
ars_d_set_tcpopt_mss(struct ars_packet * pkt,int layer,char * f,char * v)533 int ars_d_set_tcpopt_mss(struct ars_packet *pkt, int layer, char *f, char *v)
534 {
535 	struct ars_tcpopt *tcpopt;
536 
537 	ARS_DEF_LAYER;
538 	tcpopt = pkt->p_layer[layer].l_data;
539 	if (strcasecmp(f, "optlen") == 0) {
540 		tcpopt->len = ars_atou(v);
541 	} else if (strcasecmp(f, "size") == 0) {
542 		tcpopt->un.mss.size = htons(ars_atou(v));
543 	} else {
544 		ars_set_error(pkt, "Invalid field for TCP.MSS layer: '%s'", f);
545 		return -ARS_INVALID;
546 	}
547 	return -ARS_OK;
548 }
549 
ars_d_set_tcpopt_wscale(struct ars_packet * pkt,int layer,char * f,char * v)550 int ars_d_set_tcpopt_wscale(struct ars_packet *pkt, int layer, char *f, char *v)
551 {
552 	struct ars_tcpopt *tcpopt;
553 
554 	ARS_DEF_LAYER;
555 	tcpopt = pkt->p_layer[layer].l_data;
556 	if (strcasecmp(f, "optlen") == 0) {
557 		tcpopt->len = ars_atou(v);
558 	} else if (strcasecmp(f, "shift") == 0) {
559 		tcpopt->un.win.shift = htons(ars_atou(v));
560 	} else {
561 		ars_set_error(pkt, "Invalid field for TCP.WSCALE layer: '%s'", f);
562 		return -ARS_INVALID;
563 	}
564 	return -ARS_OK;
565 }
566 
567 #define TCPOPTSACK_MAX_ENTRIES 4
ars_d_set_tcpopt_sack(struct ars_packet * pkt,int layer,char * f,char * v)568 int ars_d_set_tcpopt_sack(struct ars_packet *pkt, int layer, char *f, char *v)
569 {
570 	struct ars_tcpopt *tcpopt;
571 
572 	ARS_DEF_LAYER;
573 	tcpopt = pkt->p_layer[layer].l_data;
574 	if (strcasecmp(f, "optlen") == 0) {
575 		tcpopt->len = ars_atou(v);
576 	} else if (strcasecmp(f, "blocks") == 0) {
577 		char *bv[TCPOPTSACK_MAX_ENTRIES];
578 		int vlen = strlen(v), num, i;
579 		char *vcopy = alloca(vlen+1);
580 		unsigned char *data = pkt->p_layer[layer].l_data;
581 
582 		memcpy(vcopy, v, vlen+1);
583 		num = strftok("/", vcopy, bv, TCPOPTSACK_MAX_ENTRIES);
584 		for (i = 0; i < num; i++) {
585 			char *p;
586 			__u32 s_origin, s_len;
587 
588 			p = strchr(bv[i], '-');
589 			if (!p) {
590 				ars_set_error(pkt, "Invalid syntax for tcp.sack blocks: '%s' (try ...tcp.sack(blocks=123342-10/12653-50/0-0/0-0)... )");
591 				return -ARS_INVALID;
592 			}
593 			*p = '\0';
594 			p++;
595 			s_origin = htonl(ars_atou(bv[i]));
596 			s_len = htonl(ars_atou(p));
597 			memcpy(data+2+(i*8), &s_origin, 4);
598 			memcpy(data+6+(i*8), &s_len, 4);
599 		}
600 	} else {
601 		ars_set_error(pkt, "Invalid field for TCP.SACK layer: '%s'", f);
602 		return -ARS_INVALID;
603 	}
604 	return -ARS_OK;
605 }
606 
ars_d_set_tcpopt_dumb(struct ars_packet * pkt,int layer,char * f,char * v)607 int ars_d_set_tcpopt_dumb(struct ars_packet *pkt, int layer, char *f, char *v)
608 {
609 	struct ars_tcpopt *tcpopt;
610 
611 	ARS_DEF_LAYER;
612 	tcpopt = pkt->p_layer[layer].l_data;
613 	if (strcasecmp(f, "optlen") == 0) {
614 		tcpopt->len = ars_atou(v);
615 	} else {
616 		ars_set_error(pkt, "Invalid field for TCP.? layer: '%s'", f);
617 		return -ARS_INVALID;
618 	}
619 	return -ARS_OK;
620 }
621 
ars_d_set_tcpopt_echo(struct ars_packet * pkt,int layer,char * f,char * v)622 int ars_d_set_tcpopt_echo(struct ars_packet *pkt, int layer, char *f, char *v)
623 {
624 	struct ars_tcpopt *tcpopt;
625 
626 	ARS_DEF_LAYER;
627 	tcpopt = pkt->p_layer[layer].l_data;
628 	if (strcasecmp(f, "optlen") == 0) {
629 		tcpopt->len = ars_atou(v);
630 	} else if (strcasecmp(f, "info") == 0) {
631 		u_int32_t info = htonl(ars_atou(v));
632 		memcpy(tcpopt->un.echo.info, &info, 4);
633 	} else {
634 		ars_set_error(pkt, "Invalid field for TCP.ECHO layer: '%s'", f);
635 		return -ARS_INVALID;
636 	}
637 	return -ARS_OK;
638 }
639 
ars_d_set_icmp(struct ars_packet * pkt,int layer,char * f,char * v)640 int ars_d_set_icmp(struct ars_packet *pkt, int layer, char *f, char *v)
641 {
642 	struct ars_icmphdr *icmp;
643 
644 	ARS_DEF_LAYER;
645 	icmp = pkt->p_layer[layer].l_data;
646 
647 	if (strcasecmp(f, "type") == 0) {
648 		icmp->type = ars_atou(v);
649 	} else if (strcasecmp(f, "code") == 0) {
650 		icmp->code = ars_atou(v);
651 	} else if (strcasecmp(f, "cksum") == 0) {
652 		icmp->checksum = htons(ars_atou(v));
653 		pkt->p_layer[layer].l_flags |= ARS_TAKE_ICMP_CKSUM;
654 	} else if (strcasecmp(f, "id") == 0) {
655 		icmp->un.echo.id = htons(ars_atou(v));
656 	} else if (strcasecmp(f, "seq") == 0) {
657 		icmp->un.echo.sequence = htons(ars_atou(v));
658 	} else if (strcasecmp(f, "gw") == 0) {
659 		return ars_resolve(pkt, &icmp->un.gateway, v);
660 	} else if (strcasecmp(f, "unused") == 0) {
661 		icmp->un.gateway = htonl(ars_atou(v));
662 	} else {
663 		ars_set_error(pkt, "Invalid field for ICMP layer: '%s'", f);
664 		return -ARS_INVALID;
665 	}
666 	return -ARS_OK;
667 }
668 
ars_d_set_igrp(struct ars_packet * pkt,int layer,char * f,char * v)669 int ars_d_set_igrp(struct ars_packet *pkt, int layer, char *f, char *v)
670 {
671 	struct ars_igrphdr *igrp;
672 
673 	ARS_DEF_LAYER;
674 	igrp = pkt->p_layer[layer].l_data;
675 
676 	if (strcasecmp(f, "version") == 0) {
677 		igrp->version = ars_atou(v);
678 	} else if (strcasecmp(f, "opcode") == 0) {
679 		if (strcasecmp(v, "update") == 0)
680 			igrp->opcode = ARS_IGRP_OPCODE_UPDATE;
681 		else if (strcasecmp(v, "request") == 0)
682 			igrp->opcode = ARS_IGRP_OPCODE_REQUEST;
683 		else
684 			igrp->opcode = ars_atou(v);
685 	} else if (strcasecmp(f, "cksum") == 0) {
686 		igrp->checksum = htons(ars_atou(v));
687 		pkt->p_layer[layer].l_flags |= ARS_TAKE_IGRP_CKSUM;
688 	} else if (strcasecmp(f, "edition") == 0) {
689 		igrp->edition = ars_atou(v);
690 	} else if (strcasecmp(f, "autosys") == 0) {
691 		igrp->autosys = htons(ars_atou(v));
692 	} else if (strcasecmp(f, "interior") == 0) {
693 		igrp->interior = htons(ars_atou(v));
694 	} else if (strcasecmp(f, "system") == 0) {
695 		igrp->system= htons(ars_atou(v));
696 	} else if (strcasecmp(f, "exterior") == 0) {
697 		igrp->exterior = htons(ars_atou(v));
698 	} else {
699 		ars_set_error(pkt, "Invalid field for IGRP layer: '%s'", f);
700 		return -ARS_INVALID;
701 	}
702 	return -ARS_OK;
703 }
704 
igrp_set_dest(unsigned char * d,char * v)705 static int igrp_set_dest(unsigned char *d, char *v)
706 {
707 	int l = strlen(v);
708 	char *vcopy = alloca(l+1);
709 	char *f0, *f1, *f2;
710 
711 	memcpy(vcopy, v, l+1);
712 	f0 = vcopy;
713 	if ((f1 = strchr(f0, '.')) == NULL)
714 		return 1;
715 	*f1++ = '\0';
716 	if ((f2 = strchr(f1, '.')) == NULL)
717 		return 1;
718 	*f2++ = '\0';
719 	if (!strisnum(f0) || !strisnum(f1) || !strisnum(f2))
720 		return 1;
721 	d[0] = ars_atou(f0);
722 	d[1] = ars_atou(f1);
723 	d[2] = ars_atou(f2);
724 	return 0;
725 }
726 
igrp_set_uint24(void * d,char * v)727 static void igrp_set_uint24(void *d, char *v)
728 {
729 	__u32 t;
730 	unsigned char *x;
731 
732 	t = htonl(ars_atou(v));
733 	x = (unsigned char*) &t;
734 	memcpy(d, x+1, 3);
735 }
736 
ars_d_set_igrpentry(struct ars_packet * pkt,int layer,char * f,char * v)737 int ars_d_set_igrpentry(struct ars_packet *pkt, int layer, char *f, char *v)
738 {
739 	struct ars_igrpentry *entry;
740 
741 	ARS_DEF_LAYER;
742 	entry = pkt->p_layer[layer].l_data;
743 
744 	if (strcasecmp(f, "dest") == 0) {
745 		if (igrp_set_dest(entry->destination, v)) {
746 			ars_set_error(pkt, "Invalid IGRP entry 'dest' field value: '%s'\n", v);
747 			return -ARS_INVALID;
748 		}
749 	} else if (strcasecmp(f, "delay") == 0) {
750 		igrp_set_uint24(entry->delay, v);
751 	} else if (strcasecmp(f, "bandwidth") == 0) {
752 		igrp_set_uint24(entry->bandwidth, v);
753 	} else if (strcasecmp(f, "mtu") == 0) {
754 		__u16 mtu = htons(ars_atou(v));
755 		memcpy(entry->mtu, &mtu, 2);
756 	} else if (strcasecmp(f, "reliability") == 0) {
757 		entry->reliability = ars_atou(v);
758 	} else if (strcasecmp(f, "load") == 0) {
759 		entry->load = ars_atou(v);
760 	} else if (strcasecmp(f, "hopcount") == 0) {
761 		entry->hopcount = ars_atou(v);
762 	} else {
763 		ars_set_error(pkt, "Invalid field for IGRP.ENTRY layer: '%s'", f);
764 		return -ARS_INVALID;
765 	}
766 	return -ARS_OK;
767 }
768 
ars_push_data(struct ars_packet * pkt,int layer,void * data,size_t size)769 int ars_push_data(struct ars_packet *pkt, int layer, void *data, size_t size)
770 {
771 	char *p;
772 	int old_size;
773 
774 	ARS_DEF_LAYER;
775 	old_size = pkt->p_layer[layer].l_size;
776 	p = realloc(pkt->p_layer[layer].l_data, old_size + size);
777 	if (p == NULL)
778 		return -ARS_NOMEM;
779 	memcpy(p+old_size, data, size);
780 	pkt->p_layer[layer].l_data = p;
781 	pkt->p_layer[layer].l_size += size;
782 	return ARS_OK;
783 }
784 
785 static int hextab[256];
786 static int hextab_initialized = 0;
787 static char *hexdig = "0123456789abcdef";
788 
ars_decode_hex(struct ars_packet * pkt,char * s,int * blen)789 static char *ars_decode_hex(struct ars_packet *pkt, char *s, int *blen)
790 {
791 	int len = strlen(s), i;
792 	unsigned char *d, *saved;
793 
794 	if (len%2) {
795 		ars_set_error(pkt, "Odd length of 'hex' data");
796 		return NULL;
797 	}
798 	*blen = len/2;
799 	if (!hextab_initialized) {
800 		memset(hextab, 255, 255);
801 		for (i = 0; i < 16; i++)
802 			hextab[(int)hexdig[i]] = i;
803 	}
804 	if ((d = malloc(*blen)) == NULL) {
805 		ars_set_error(pkt, "Out of memory decoding 'hex' data");
806 		return NULL;
807 	}
808 	saved = d;
809 	while(*s) {
810 		int x0, x1;
811 
812 		x0 = hextab[tolower(*s)];
813 		x1 = hextab[tolower(*(s+1))];
814 		if (x0 == 255 || x1 == 255) {
815 			ars_set_error(pkt, "Wrong byte for 'hex' data: '%c%c'",
816 					*s, *(s+1));
817 			free(saved);
818 			return NULL;
819 		}
820 		*d++ = (x0 << 4) | x1;
821 		s += 2;
822 	}
823 	return saved;
824 }
825 
ars_decode_string(struct ars_packet * pkt,char * s,int * blen)826 static char *ars_decode_string(struct ars_packet *pkt, char *s, int *blen)
827 {
828 	int l = strlen(s), i;
829 	int bl = 0;
830 	unsigned char *d, *saved;
831 
832 	if (!hextab_initialized) {
833 		memset(hextab, -1, 255);
834 		for (i = 0; i < 16; i++)
835 			hextab[(int)hexdig[i]] = i;
836 	}
837 	if ((d = malloc(l)) == NULL) {
838 		ars_set_error(pkt, "Out of memory decoding 'str' data");
839 		return NULL;
840 	}
841 	saved = d;
842 	while(*s) {
843 		if (*s == '\\' && *(s+1) && *(s+2)) {
844 			*d++ = (hextab[(int)*(s+1)] << 4) + hextab[(int)*(s+2)];
845 			s += 3;
846 		} else {
847 			*d++ = *s++;
848 		}
849 		bl++;
850 	}
851 	*blen = bl;
852 	return saved;
853 }
854 
855 #define ARS_DATA_BUF_SIZE 4096
ars_d_set_data(struct ars_packet * pkt,int layer,char * f,char * v)856 int ars_d_set_data(struct ars_packet *pkt, int layer, char *f, char *v)
857 {
858 	ARS_DEF_LAYER;
859 	if (strcasecmp(f, "file") == 0) {
860 		int fd, n_read;
861 		unsigned char buffer[ARS_DATA_BUF_SIZE];
862 
863 		if ((fd = open(v, O_RDONLY)) == -1) {
864 			ars_set_error(pkt, "Can't open the DATA file '%s': %s",
865 					v, strerror(errno));
866 			return -ARS_ERROR;
867 		}
868 		if ((n_read = read(fd, buffer, ARS_DATA_BUF_SIZE)) == -1) {
869 			close(fd);
870 			ars_set_error(pkt, "Can't read DATA from file: %s", strerror(errno));
871 			return -ARS_ERROR;
872 		}
873 		close(fd);
874 		if (n_read == 0)
875 			return -ARS_OK;
876 		return ars_push_data(pkt, layer, buffer, n_read);
877 	} else if (strcasecmp(f, "str") == 0) {
878 		char *binary;
879 		int err, blen;
880 
881 		binary = ars_decode_string(pkt, v, &blen);
882 		if (binary == NULL)
883 			return -ARS_ERROR;
884 		err = ars_push_data(pkt, layer, binary, blen);
885 		free(binary);
886 		return err;
887 	} else if (strcasecmp(f, "hex") == 0) {
888 		char *binary;
889 		int err, blen;
890 
891 		binary = ars_decode_hex(pkt, v, &blen);
892 		if (binary == NULL)
893 			return -ARS_ERROR;
894 		err = ars_push_data(pkt, layer, binary, blen);
895 		free(binary);
896 	} else if (strcasecmp(f, "uint32") == 0) {
897 		int err;
898 		__u32 t, nt;
899 		t = ars_atou(v);
900 		nt = htonl(t);
901 		err = ars_push_data(pkt, layer, (char*)&nt, 4);
902 		return err;
903 	} else if (strcasecmp(f, "uint24") == 0) {
904 		int err;
905 		__u32 t, nt;
906 		unsigned char *x = (unsigned char*) &nt;
907 		t = ars_atou(v);
908 		nt = htonl(t);
909 		err = ars_push_data(pkt, layer, x+1, 3);
910 		return err;
911 	} else if (strcasecmp(f, "uint16") == 0) {
912 		int err;
913 		__u16 t, nt;
914 		t = ars_atou(v);
915 		nt = htons(t);
916 		err = ars_push_data(pkt, layer, (char*)&nt, 2);
917 		return err;
918 	} else if (strcasecmp(f, "uint8") == 0) {
919 		int err;
920 		__u8 t;
921 		t = ars_atou(v);
922 		err = ars_push_data(pkt, layer, (char*)&t, 1);
923 		return err;
924 	} else {
925 		ars_set_error(pkt, "Invalid field for DATA layer: '%s'", f);
926 		return -ARS_INVALID;
927 	}
928 	return -ARS_OK;
929 }
930 
931 /* A Finite state machine to build the packet using the description */
ars_d_build(struct ars_packet * pkt,char * t)932 int ars_d_build(struct ars_packet *pkt, char *t)
933 {
934 	struct ars_d_keyword_info *k = NULL;
935 	char next[ARS_MAX_TSIZE];
936 	char field[ARS_MAX_TSIZE];
937 	int state = ARS_G_LAYER;
938 	int error;
939 	void *p;
940 
941 	while ((t = ars_d_parser(t, next, ARS_MAX_TSIZE)) != NULL) {
942 		switch(state) {
943 		case ARS_G_LAYER:
944 			k = ars_get_keyword_by_name(next);
945 			if (k == NULL) {
946 				ars_set_error(pkt, "Unknown keyword: '%s'", next);
947 				return -ARS_INVALID;
948 			}
949 			__D(printf("Adding a new layer (%s)\n", next);)
950 			p = k->ki_add(pkt, k->ki_opt);
951 			if (p == NULL)
952 				return -ARS_INVALID;
953 			state = ARS_G_OBRACE_OR_PLUS;
954 			break;
955 		case ARS_G_FIELD_OR_CBRACE:
956 			if (next[0] == ')' && next[1] == '\0') {
957 				state = ARS_G_LEN_OR_PLUS;
958 			} else {
959 				strncpy(field, next, ARS_MAX_TSIZE);
960 				state = ARS_G_EQUAL;
961 			}
962 			break;
963 		case ARS_G_VALUE:
964 			if (k->ki_set == NULL) {
965 				ars_set_error(pkt, "Field specified for"
966 					"a layer that doesn't support fields");
967 				return -ARS_INVALID;
968 			}
969 			error = k->ki_set(pkt, ARS_LAST_LAYER, field, next);
970 			if (error != -ARS_OK)
971 				return error;
972 			state = ARS_G_COMMA_OR_CBRACE;
973 			break;
974 		case ARS_G_OBRACE_OR_PLUS:
975 			if (next[0] == '(' && next[1] == '\0') {
976 				state = ARS_G_FIELD_OR_CBRACE;
977 				break;
978 			} else if (next[0] == '+' && next[1] == '\0') {
979 				state = ARS_G_LAYER;
980 				break;
981 			} else {
982 				ars_set_error(pkt, "Missing brace or plus");
983 				return -ARS_INVALID;
984 			}
985 			break;
986 		case ARS_G_CBRACE:
987 			if (next[0] != ')' || next[1] != '\0') {
988 				ars_set_error(pkt, "Missing closed brace");
989 				return -ARS_INVALID;
990 			}
991 			state = ARS_G_LEN_OR_PLUS;
992 			break;
993 		case ARS_G_COMMA_OR_CBRACE:
994 			if (next[0] == ')' && next[1] == '\0') {
995 				state = ARS_G_LEN_OR_PLUS;
996 				break;
997 			} else if (next[0] == ',' && next[1] == '\0') {
998 				state = ARS_G_FIELD_OR_CBRACE;
999 				break;
1000 			} else {
1001 				ars_set_error(pkt, "Missing brace or comma");
1002 				return -ARS_INVALID;
1003 			}
1004 			break;
1005 		case ARS_G_LEN_OR_PLUS:
1006 			if (next[0] == '+' && next[1] == '\0') {
1007 				state = ARS_G_LAYER;
1008 				break;
1009 			}
1010 			error = ars_d_setlayer_size(pkt, ARS_LAST_LAYER, next);
1011 			if (error != -ARS_OK)
1012 				return error;
1013 			state = ARS_G_PLUS;
1014 			break;
1015 		case ARS_G_PLUS:
1016 			if (next[0] != '+' || next[1] != '\0') {
1017 				ars_set_error(pkt, "Missing plus");
1018 				return -ARS_INVALID;
1019 			}
1020 			state = ARS_G_LAYER;
1021 			break;
1022 		case ARS_G_EQUAL:
1023 			if (next[0] != '=' || next[1] != '\0') {
1024 				ars_set_error(pkt, "Missing equal");
1025 				return -ARS_INVALID;
1026 			}
1027 			state = ARS_G_VALUE;
1028 			break;
1029 		}
1030 	}
1031 	if (state != ARS_G_LEN_OR_PLUS && state != ARS_G_PLUS &&
1032 	    state != ARS_G_OBRACE_OR_PLUS) {
1033 		ars_set_error(pkt, "Packet description truncated");
1034 		return -ARS_INVALID;
1035 	}
1036 	return -ARS_OK;
1037 }
1038