xref: /freebsd/sbin/ipf/libipf/addipopt.c (revision 3c4ba5f55438f7afd4f4b0b56f88f2bb505fd6a6)
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
15 addipopt(char *op, struct ipopt_names *io, int len, char *class)
16 {
17 	int olen = len;
18 	struct in_addr ipadr;
19 	u_short val;
20 	u_char lvl;
21 	char *s;
22 
23 	if ((len + io->on_siz) > 48) {
24 		fprintf(stderr, "options too long\n");
25 		return (0);
26 	}
27 	len += io->on_siz;
28 	*op++ = io->on_value;
29 	if (io->on_siz > 1) {
30 		s = op;
31 		*op++ = io->on_siz;
32 		*op++ = IPOPT_MINOFF;
33 
34 		if (class) {
35 			switch (io->on_value)
36 			{
37 			case IPOPT_SECURITY :
38 				lvl = seclevel(class);
39 				*(op - 1) = lvl;
40 				break;
41 			case IPOPT_RR :
42 			case IPOPT_TS :
43 				s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4;
44 				break;
45 			case IPOPT_LSRR :
46 			case IPOPT_SSRR :
47 				ipadr.s_addr = inet_addr(class);
48 				s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4;
49 				bcopy((char *)&ipadr, op, sizeof(ipadr));
50 				break;
51 			case IPOPT_SATID :
52 				val = atoi(class);
53 				bcopy((char *)&val, op, 2);
54 				break;
55 			}
56 		}
57 	}
58 	if (opts & OPT_DEBUG)
59 		fprintf(stderr, "bo: %s %d %#x: %d\n",
60 			io->on_name, io->on_value, io->on_bit, len);
61 	return (len - olen);
62 }
63