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