Deleted Added
full compact
ipsopt.c (24583) ipsopt.c (31183)
1/*
1/*
2 * (C)opyright 1995 by Darren Reed.
2 * Copyright (C) 1995-1997 by Darren Reed.
3 *
3 *
4 * This code may be freely distributed as long as it retains this notice
5 * and is not changed in any way. The author accepts no responsibility
6 * for the use of this software. I hate legaleese, don't you ?
4 * Redistribution and use in source and binary forms are permitted
5 * provided that this notice is preserved and due credit is given
6 * to the original author and the contributors.
7 */
7 */
8#if !defined(lint) && defined(LIBC_SCCS)
9static char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
8#if !defined(lint)
9static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
10static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.0.2.10 1997/09/28 07:13:28 darrenr Exp $";
10#endif
11#include <stdio.h>
12#include <string.h>
11#endif
12#include <stdio.h>
13#include <string.h>
14#include <stdlib.h>
13#include <sys/types.h>
14#include <sys/time.h>
15#include <sys/socket.h>
16#include <netinet/in.h>
17#include <netinet/in_systm.h>
18#include <netinet/ip.h>
15#include <sys/types.h>
16#include <sys/time.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <netinet/in_systm.h>
20#include <netinet/ip.h>
19#include "ip_compat.h"
21#ifndef linux
22#include <netinet/ip_var.h>
23#endif
24#include <netinet/tcp.h>
25#include <arpa/inet.h>
26#include "ipsend.h"
20
21
22#ifndef __P
23# ifdef __STDC__
24# define __P(x) x
25# else
26# define __P(x) ()
27# endif
28#endif
29
30
27
28
29#ifndef __P
30# ifdef __STDC__
31# define __P(x) x
32# else
33# define __P(x) ()
34# endif
35#endif
36
37
31struct ipopt_names {
32 int on_value;
33 int on_bit;
34 int on_siz;
35 char *on_name;
36};
37
38struct ipopt_names ionames[] = {
39 { IPOPT_EOL, 0x01, 1, "eol" },
40 { IPOPT_NOP, 0x02, 1, "nop" },
38struct ipopt_names ionames[] = {
39 { IPOPT_EOL, 0x01, 1, "eol" },
40 { IPOPT_NOP, 0x02, 1, "nop" },
41 { IPOPT_RR, 0x04, 7, "rr" }, /* 1 route */
41 { IPOPT_RR, 0x04, 3, "rr" }, /* 1 route */
42 { IPOPT_TS, 0x08, 8, "ts" }, /* 1 TS */
43 { IPOPT_SECURITY, 0x08, 11, "sec-level" },
44 { IPOPT_LSRR, 0x10, 7, "lsrr" }, /* 1 route */
45 { IPOPT_SATID, 0x20, 4, "satid" },
46 { IPOPT_SSRR, 0x40, 7, "ssrr" }, /* 1 route */
47 { 0, 0, 0, NULL } /* must be last */
48};
49

--- 4 unchanged lines hidden (view full) ---

54 { IPOPT_SECUR_MMMM, 0x0800, 0, "mmmm" },
55 { IPOPT_SECUR_RESTR, 0x1000, 0, "restr" },
56 { IPOPT_SECUR_SECRET, 0x2000, 0, "secret" },
57 { IPOPT_SECUR_TOPSECRET, 0x4000,0, "topsecret" },
58 { 0, 0, 0, NULL } /* must be last */
59};
60
61
42 { IPOPT_TS, 0x08, 8, "ts" }, /* 1 TS */
43 { IPOPT_SECURITY, 0x08, 11, "sec-level" },
44 { IPOPT_LSRR, 0x10, 7, "lsrr" }, /* 1 route */
45 { IPOPT_SATID, 0x20, 4, "satid" },
46 { IPOPT_SSRR, 0x40, 7, "ssrr" }, /* 1 route */
47 { 0, 0, 0, NULL } /* must be last */
48};
49

--- 4 unchanged lines hidden (view full) ---

54 { IPOPT_SECUR_MMMM, 0x0800, 0, "mmmm" },
55 { IPOPT_SECUR_RESTR, 0x1000, 0, "restr" },
56 { IPOPT_SECUR_SECRET, 0x2000, 0, "secret" },
57 { IPOPT_SECUR_TOPSECRET, 0x4000,0, "topsecret" },
58 { 0, 0, 0, NULL } /* must be last */
59};
60
61
62u_short seclevel __P((char *));
63u_long optname __P((char *, char *));
64
65
66u_short seclevel(slevel)
67char *slevel;
68{
69 struct ipopt_names *so;
70
71 for (so = secnames; so->on_name; so++)
72 if (!strcasecmp(slevel, so->on_name))
73 break;
74
75 if (!so->on_name) {
76 fprintf(stderr, "no such security level: %s\n", slevel);
77 return 0;
78 }
79 return so->on_value;
80}
81
82
62u_short seclevel(slevel)
63char *slevel;
64{
65 struct ipopt_names *so;
66
67 for (so = secnames; so->on_name; so++)
68 if (!strcasecmp(slevel, so->on_name))
69 break;
70
71 if (!so->on_name) {
72 fprintf(stderr, "no such security level: %s\n", slevel);
73 return 0;
74 }
75 return so->on_value;
76}
77
78
83u_long optname(cp, op)
79int addipopt(op, io, len, class)
80char *op;
81struct ipopt_names *io;
82int len;
83char *class;
84{
85 struct in_addr ipadr;
86 int olen = len, srr = 0;
87 u_short val;
88 u_char lvl;
89 char *s = op, *t;
90
91 if ((len + io->on_siz) > 48) {
92 fprintf(stderr, "options too long\n");
93 return 0;
94 }
95 len += io->on_siz;
96 *op++ = io->on_value;
97 if (io->on_siz > 1) {
98 /*
99 * Allow option to specify RR buffer length in bytes.
100 */
101 if (io->on_value == IPOPT_RR) {
102 val = (class && *class) ? atoi(class) : 4;
103 *op++ = val + io->on_siz;
104 len += val;
105 } else
106 *op++ = io->on_siz;
107 *op++ = IPOPT_MINOFF;
108
109 while (class && *class) {
110 t = NULL;
111 switch (io->on_value)
112 {
113 case IPOPT_SECURITY :
114 lvl = seclevel(class);
115 *(op - 1) = lvl;
116 break;
117 case IPOPT_LSRR :
118 case IPOPT_SSRR :
119 if ((t = strchr(class, ',')))
120 *t = '\0';
121 ipadr.s_addr = inet_addr(class);
122 srr++;
123 bcopy((char *)&ipadr, op, sizeof(ipadr));
124 op += sizeof(ipadr);
125 break;
126 case IPOPT_SATID :
127 val = atoi(class);
128 bcopy((char *)&val, op, 2);
129 break;
130 }
131
132 if (t)
133 *t++ = ',';
134 class = t;
135 }
136 if (srr)
137 s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4 * srr;
138 if (io->on_value == IPOPT_RR)
139 op += val;
140 else
141 op += io->on_siz - 3;
142 }
143 return len - olen;
144}
145
146
147u_32_t buildopts(cp, op, len)
84char *cp, *op;
148char *cp, *op;
149int len;
85{
86 struct ipopt_names *io;
150{
151 struct ipopt_names *io;
87 u_short lvl;
88 u_long msk = 0;
152 u_32_t msk = 0;
89 char *s, *t;
153 char *s, *t;
90 int len = 0;
154 int inc, lastop = -1;
91
92 for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) {
93 if ((t = strchr(s, '=')))
94 *t++ = '\0';
95 for (io = ionames; io->on_name; io++) {
96 if (strcasecmp(s, io->on_name) || (msk & io->on_bit))
97 continue;
155
156 for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) {
157 if ((t = strchr(s, '=')))
158 *t++ = '\0';
159 for (io = ionames; io->on_name; io++) {
160 if (strcasecmp(s, io->on_name) || (msk & io->on_bit))
161 continue;
98 if ((len + io->on_siz) > 48) {
99 fprintf(stderr, "options too long\n");
100 return 0;
162 lastop = io->on_value;
163 if ((inc = addipopt(op, io, len, t))) {
164 op += inc;
165 len += inc;
101 }
166 }
102 len += io->on_siz;
103 *op++ = io->on_value;
104 if (io->on_siz > 1) {
105 *op++ = io->on_siz;
106 *op++ = IPOPT_MINOFF;
107
108 if (t && !strcasecmp(s, "sec-level")) {
109 lvl = seclevel(t);
110 bcopy(&lvl, op, sizeof(lvl));
111 }
112 op += io->on_siz - 3;
113 }
114 msk |= io->on_bit;
115 break;
116 }
117 if (!io->on_name) {
118 fprintf(stderr, "unknown IP option name %s\n", s);
119 return 0;
120 }
121 }
167 msk |= io->on_bit;
168 break;
169 }
170 if (!io->on_name) {
171 fprintf(stderr, "unknown IP option name %s\n", s);
172 return 0;
173 }
174 }
122 *op++ = IPOPT_EOL;
123 len++;
175
176 if (len & 3) {
177 while (len & 3) {
178 *op++ = ((len & 3) == 3) ? IPOPT_EOL : IPOPT_NOP;
179 len++;
180 }
181 } else {
182 if (lastop != IPOPT_EOL) {
183 if (lastop == IPOPT_NOP)
184 *(op - 1) = IPOPT_EOL;
185 else {
186 *op++ = IPOPT_NOP;
187 *op++ = IPOPT_NOP;
188 *op++ = IPOPT_NOP;
189 *op = IPOPT_EOL;
190 len += 4;
191 }
192 }
193 }
124 return len;
125}
194 return len;
195}