xref: /freebsd/sbin/ipf/libipf/addipopt.c (revision 963f5dc7a30624e95d72fb7f87b8892651164e46)
1 /*	$FreeBSD$	*/
2 
3 /*
4  * Copyright (C) 2012 by Darren Reed.
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  *
8  * $Id$
9  */
10 
11 #include "ipf.h"
12 
13 
14 int addipopt(op, io, len, class)
15 	char *op;
16 	struct ipopt_names *io;
17 	int len;
18 	char *class;
19 {
20 	int olen = len;
21 	struct in_addr ipadr;
22 	u_short val;
23 	u_char lvl;
24 	char *s;
25 
26 	if ((len + io->on_siz) > 48) {
27 		fprintf(stderr, "options too long\n");
28 		return 0;
29 	}
30 	len += io->on_siz;
31 	*op++ = io->on_value;
32 	if (io->on_siz > 1) {
33 		s = op;
34 		*op++ = io->on_siz;
35 		*op++ = IPOPT_MINOFF;
36 
37 		if (class) {
38 			switch (io->on_value)
39 			{
40 			case IPOPT_SECURITY :
41 				lvl = seclevel(class);
42 				*(op - 1) = lvl;
43 				break;
44 			case IPOPT_RR :
45 			case IPOPT_TS :
46 				s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4;
47 				break;
48 			case IPOPT_LSRR :
49 			case IPOPT_SSRR :
50 				ipadr.s_addr = inet_addr(class);
51 				s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4;
52 				bcopy((char *)&ipadr, op, sizeof(ipadr));
53 				break;
54 			case IPOPT_SATID :
55 				val = atoi(class);
56 				bcopy((char *)&val, op, 2);
57 				break;
58 			}
59 		}
60 	}
61 	if (opts & OPT_DEBUG)
62 		fprintf(stderr, "bo: %s %d %#x: %d\n",
63 			io->on_name, io->on_value, io->on_bit, len);
64 	return len - olen;
65 }
66