2 * Copyright (C) 1995-1998 by Darren Reed.
4 * See the IPFILTER.LICENCE file for details on licencing.
6 #if defined(__sgi) && (IRIX > 602)
7 # include <sys/ptimers.h>
13 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <netinet/in_systm.h>
18 #include <netinet/ip.h>
20 #include <netinet/ip_var.h>
22 #include <netinet/tcp.h>
23 #include <arpa/inet.h>
27 static const char sccsid
[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
28 static const char rcsid
[] = "@(#)$Id: ipsopt.c,v 2.1.4.5 2004/04/10 11:50:52 darrenr Exp $";
32 struct ipopt_names ionames
[] = {
33 { IPOPT_EOL
, 0x01, 1, "eol" },
34 { IPOPT_NOP
, 0x02, 1, "nop" },
35 { IPOPT_RR
, 0x04, 3, "rr" }, /* 1 route */
36 { IPOPT_TS
, 0x08, 8, "ts" }, /* 1 TS */
37 { IPOPT_SECURITY
, 0x08, 11, "sec-level" },
38 { IPOPT_LSRR
, 0x10, 7, "lsrr" }, /* 1 route */
39 { IPOPT_SATID
, 0x20, 4, "satid" },
40 { IPOPT_SSRR
, 0x40, 7, "ssrr" }, /* 1 route */
41 { 0, 0, 0, NULL
} /* must be last */
44 struct ipopt_names secnames
[] = {
45 { IPOPT_SECUR_UNCLASS
, 0x0100, 0, "unclass" },
46 { IPOPT_SECUR_CONFID
, 0x0200, 0, "confid" },
47 { IPOPT_SECUR_EFTO
, 0x0400, 0, "efto" },
48 { IPOPT_SECUR_MMMM
, 0x0800, 0, "mmmm" },
49 { IPOPT_SECUR_RESTR
, 0x1000, 0, "restr" },
50 { IPOPT_SECUR_SECRET
, 0x2000, 0, "secret" },
51 { IPOPT_SECUR_TOPSECRET
, 0x4000,0, "topsecret" },
52 { 0, 0, 0, NULL
} /* must be last */
56 u_short
seclevel(slevel
)
59 struct ipopt_names
*so
;
61 for (so
= secnames
; so
->on_name
; so
++)
62 if (!strcasecmp(slevel
, so
->on_name
))
66 fprintf(stderr
, "no such security level: %s\n", slevel
);
73 int addipopt(op
, io
, len
, class)
75 struct ipopt_names
*io
;
80 int olen
= len
, srr
= 0;
85 if ((len
+ io
->on_siz
) > 48) {
86 fprintf(stderr
, "options too long\n");
93 * Allow option to specify RR buffer length in bytes.
95 if (io
->on_value
== IPOPT_RR
) {
96 val
= (class && *class) ? atoi(class) : 4;
97 *op
++ = val
+ io
->on_siz
;
101 if (io
->on_value
== IPOPT_TS
)
102 *op
++ = IPOPT_MINOFF
+ 1;
104 *op
++ = IPOPT_MINOFF
;
106 while (class && *class) {
108 switch (io
->on_value
)
110 case IPOPT_SECURITY
:
111 lvl
= seclevel(class);
116 if ((t
= strchr(class, ',')))
118 ipadr
.s_addr
= inet_addr(class);
120 bcopy((char *)&ipadr
, op
, sizeof(ipadr
));
125 bcopy((char *)&val
, op
, 2);
134 s
[IPOPT_OLEN
] = IPOPT_MINOFF
- 1 + 4 * srr
;
135 if (io
->on_value
== IPOPT_RR
)
138 op
+= io
->on_siz
- 3;
144 u_32_t
buildopts(cp
, op
, len
)
148 struct ipopt_names
*io
;
151 int inc
, lastop
= -1;
153 for (s
= strtok(cp
, ","); s
; s
= strtok(NULL
, ",")) {
154 if ((t
= strchr(s
, '=')))
156 for (io
= ionames
; io
->on_name
; io
++) {
157 if (strcasecmp(s
, io
->on_name
) || (msk
& io
->on_bit
))
159 lastop
= io
->on_value
;
160 if ((inc
= addipopt(op
, io
, len
, t
))) {
168 fprintf(stderr
, "unknown IP option name %s\n", s
);
175 *op
++ = ((len
& 3) == 3) ? IPOPT_EOL
: IPOPT_NOP
;
179 if (lastop
!= IPOPT_EOL
) {
180 if (lastop
== IPOPT_NOP
)
181 *(op
- 1) = IPOPT_EOL
;