2 * Copyright (C) 1993-2001 by Darren Reed.
4 * See the IPFILTER.LICENCE file for details on licencing.
6 #if defined(__sgi) && (IRIX > 602)
7 # include <sys/ptimers.h>
12 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <netinet/in_systm.h>
17 #include <netinet/ip.h>
19 #include <netinet/ip_var.h>
21 #include <netinet/tcp.h>
23 #include <arpa/inet.h>
24 #include "ip_compat.h"
25 #include <netinet/tcpip.h>
30 static const char sccsid
[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-2000 Darren Reed";
31 static const char rcsid
[] = "@(#)$Id: opt.c,v 2.2.2.3 2002/12/06 11:40:27 darrenr Exp $";
36 struct ipopt_names ionames
[] ={
37 { IPOPT_NOP
, 0x000001, 1, "nop" },
38 { IPOPT_RR
, 0x000002, 7, "rr" }, /* 1 route */
39 { IPOPT_ZSU
, 0x000004, 3, "zsu" },
40 { IPOPT_MTUP
, 0x000008, 3, "mtup" },
41 { IPOPT_MTUR
, 0x000010, 3, "mtur" },
42 { IPOPT_ENCODE
, 0x000020, 3, "encode" },
43 { IPOPT_TS
, 0x000040, 8, "ts" }, /* 1 TS */
44 { IPOPT_TR
, 0x000080, 3, "tr" },
45 { IPOPT_SECURITY
,0x000100, 11, "sec" },
46 { IPOPT_SECURITY
,0x000100, 11, "sec-class" },
47 { IPOPT_LSRR
, 0x000200, 7, "lsrr" }, /* 1 route */
48 { IPOPT_E_SEC
, 0x000400, 3, "e-sec" },
49 { IPOPT_CIPSO
, 0x000800, 3, "cipso" },
50 { IPOPT_SATID
, 0x001000, 4, "satid" },
51 { IPOPT_SSRR
, 0x002000, 7, "ssrr" }, /* 1 route */
52 { IPOPT_ADDEXT
, 0x004000, 3, "addext" },
53 { IPOPT_VISA
, 0x008000, 3, "visa" },
54 { IPOPT_IMITD
, 0x010000, 3, "imitd" },
55 { IPOPT_EIP
, 0x020000, 3, "eip" },
56 { IPOPT_FINN
, 0x040000, 3, "finn" },
57 { 0, 0, 0, (char *)NULL
} /* must be last */
60 struct ipopt_names secclass
[] = {
61 { IPSO_CLASS_RES4
, 0x01, 0, "reserv-4" },
62 { IPSO_CLASS_TOPS
, 0x02, 0, "topsecret" },
63 { IPSO_CLASS_SECR
, 0x04, 0, "secret" },
64 { IPSO_CLASS_RES3
, 0x08, 0, "reserv-3" },
65 { IPSO_CLASS_CONF
, 0x10, 0, "confid" },
66 { IPSO_CLASS_UNCL
, 0x20, 0, "unclass" },
67 { IPSO_CLASS_RES2
, 0x40, 0, "reserv-2" },
68 { IPSO_CLASS_RES1
, 0x80, 0, "reserv-1" },
69 { 0, 0, 0, NULL
} /* must be last */
73 static u_char seclevel
__P((char *));
74 int addipopt
__P((char *, struct ipopt_names
*, int, char *));
76 static u_char
seclevel(slevel
)
79 struct ipopt_names
*so
;
81 for (so
= secclass
; so
->on_name
; so
++)
82 if (!strcasecmp(slevel
, so
->on_name
))
86 fprintf(stderr
, "no such security level: %s\n", slevel
);
89 return (u_char
)so
->on_value
;
93 int addipopt(op
, io
, len
, class)
95 struct ipopt_names
*io
;
100 struct in_addr ipadr
;
105 if ((len
+ io
->on_siz
) > 48) {
106 fprintf(stderr
, "options too long\n");
110 *op
++ = io
->on_value
;
111 if (io
->on_siz
> 1) {
114 *op
++ = IPOPT_MINOFF
;
117 switch (io
->on_value
)
119 case IPOPT_SECURITY
:
120 lvl
= seclevel(class);
125 ipadr
.s_addr
= inet_addr(class);
126 s
[IPOPT_OLEN
] = IPOPT_MINOFF
- 1 + 4;
127 bcopy((char *)&ipadr
, op
, sizeof(ipadr
));
131 bcopy((char *)&val
, op
, 2);
136 op
+= io
->on_siz
- 3;
142 if (opts
& OPT_DEBUG
)
143 fprintf(stderr
, "bo: %s %d %#x: %d\n",
144 io
->on_name
, io
->on_value
, io
->on_bit
, len
);
149 u_32_t
buildopts(cp
, op
, len
)
153 struct ipopt_names
*io
;
158 for (s
= strtok(cp
, ","); s
; s
= strtok(NULL
, ",")) {
159 if ((t
= strchr(s
, '=')))
161 for (io
= ionames
; io
->on_name
; io
++) {
162 if (strcasecmp(s
, io
->on_name
) || (msk
& io
->on_bit
))
164 if ((inc
= addipopt(op
, io
, len
, t
))) {
172 fprintf(stderr
, "unknown IP option name %s\n", s
);