OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / lib / ttosa.c
1 /*
2  * convert from text form of SA ID to binary
3  * Copyright (C) 2000, 2001  Henry Spencer.
4  * 
5  * This library is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Library General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9  * 
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13  * License for more details.
14  *
15  * RCSID $Id: ttosa.c,v 1.10 2002/03/12 02:24:53 henry Exp $
16  */
17 #include "internal.h"
18 #include "freeswan.h"
19
20 static struct satype {
21         char *prefix;
22         size_t prelen;          /* strlen(prefix) */
23         int proto;
24 } satypes[] = {
25         { "ah",         2,      SA_AH   },
26         { "esp",        3,      SA_ESP  },
27         { "tun",        3,      SA_IPIP },
28         { "comp",       4,      SA_COMP },
29         { "int",        3,      SA_INT  },
30         { NULL,         0,      0,      }
31 };
32
33 static struct magic {
34         char *name;
35         char *really;
36 } magic[] = {
37         { PASSTHROUGHNAME,      PASSTHROUGH4IS          },
38         { PASSTHROUGH4NAME,     PASSTHROUGH4IS          },
39         { PASSTHROUGH6NAME,     PASSTHROUGH6IS          },
40         { "%pass",              "int256@0.0.0.0"        },
41         { "%drop",              "int257@0.0.0.0"        },
42         { "%reject",            "int258@0.0.0.0"        },
43         { "%hold",              "int259@0.0.0.0"        },
44         { "%trap",              "int260@0.0.0.0"        },
45         { "%trapsubnet",        "int261@0.0.0.0"        },
46         { NULL,                 NULL                    }
47 };
48
49 /*
50  - ttosa - convert text "ah507@10.0.0.1" to SA identifier
51  */
52 err_t                           /* NULL for success, else string literal */
53 ttosa(src, srclen, sa)
54 const char *src;
55 size_t srclen;                  /* 0 means "apply strlen" */
56 ip_said *sa;
57 {
58         const char *at;
59         const char *addr;
60         size_t alen;
61         const char *spi = NULL;
62         struct satype *sat;
63         unsigned long ul;
64         const char *oops;
65         struct magic *mp;
66         size_t nlen;
67 #       define  MINLEN  5       /* ah0@0 is as short as it can get */
68         int af;
69         int base;
70
71         if (srclen == 0)
72                 srclen = strlen(src);
73         if (srclen == 0)
74                 return "empty string";
75         if (srclen < MINLEN)
76                 return "string too short to be SA identifier";
77         if (*src == '%') {
78                 for (mp = magic; mp->name != NULL; mp++) {
79                         nlen = strlen(mp->name);
80                         if (srclen == nlen && memcmp(src, mp->name, nlen) == 0)
81                                 break;
82                 }
83                 if (mp->name == NULL)
84                         return "unknown % keyword";
85                 src = mp->really;
86                 srclen = strlen(src);
87         }
88
89         at = memchr(src, '@', srclen);
90         if (at == NULL)
91                 return "no @ in SA specifier";
92
93         for (sat = satypes; sat->prefix != NULL; sat++)
94                 if (sat->prelen < srclen &&
95                                 strncmp(src, sat->prefix, sat->prelen) == 0) {
96                         sa->proto = sat->proto;
97                         spi = src + sat->prelen;
98                         break;                  /* NOTE BREAK OUT */
99                 }
100         if (sat->prefix == NULL)
101                 return "SA specifier lacks valid protocol prefix";
102
103         if (spi >= at)
104                 return "no SPI in SA specifier";
105         switch (*spi) {
106         case '.':
107                 af = AF_INET;
108                 spi++;
109                 base = 16;
110                 break;
111         case ':':
112                 af = AF_INET6;
113                 spi++;
114                 base = 16;
115                 break;
116         default:
117                 af = AF_UNSPEC;         /* not known yet */
118                 base = 0;
119                 break;
120         }
121         if (spi >= at)
122                 return "no SPI found in SA specifier";
123         oops = ttoul(spi, at - spi, base, &ul);
124         if (oops != NULL)
125                 return oops;
126         sa->spi = htonl(ul);
127
128         addr = at + 1;
129         alen = srclen - (addr - src);
130         if (af == AF_UNSPEC)
131                 af = (memchr(addr, ':', alen) != NULL) ? AF_INET6 : AF_INET;
132         oops = ttoaddr(addr, alen, af, &sa->dst);
133         if (oops != NULL)
134                 return oops;
135
136         return NULL;
137 }
138
139
140
141 #ifdef TTOSA_MAIN
142
143 #include <stdio.h>
144
145 void regress();
146
147 int
148 main(argc, argv)
149 int argc;
150 char *argv[];
151 {
152         ip_said sa;
153         char buf[100];
154         char buf2[100];
155         const char *oops;
156         size_t n;
157
158         if (argc < 2) {
159                 fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
160                 exit(2);
161         }
162
163         if (strcmp(argv[1], "-r") == 0) {
164                 regress();
165                 fprintf(stderr, "regress() returned?!?\n");
166                 exit(1);
167         }
168
169         oops = ttosa(argv[1], 0, &sa);
170         if (oops != NULL) {
171                 fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
172                 exit(1);
173         }
174         n = satot(&sa, 0, buf, sizeof(buf));
175         if (n > sizeof(buf)) {
176                 fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto);
177                 fprintf(stderr, "%lx@", sa.spi);
178                 (void) addrtot(&sa.dst, 0, buf2, sizeof(buf2));
179                 fprintf(stderr, "%s", buf2);
180                 fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
181                                                 (long)n, (long)sizeof(buf));
182                 exit(1);
183         }
184         printf("%s\n", buf);
185
186         exit(0);
187 }
188
189 struct rtab {
190         int format;
191 #               define  FUDGE   0x1000
192         char *input;
193         char *output;                   /* NULL means error expected */
194 } rtab[] = {
195         0, "esp257@1.2.3.0",            "esp.101@1.2.3.0",
196         0, "ah0x20@1.2.3.4",            "ah.20@1.2.3.4",
197         0, "tun20@1.2.3.4",             "tun.14@1.2.3.4",
198         0, "comp20@1.2.3.4",            "comp.14@1.2.3.4",
199         0, "esp257@::1",                "esp:101@::1",
200         0, "esp257@0bc:12de::1",        "esp:101@bc:12de::1",
201         0, "esp78@1049:1::8007:2040",   "esp:4e@1049:1::8007:2040",
202         0, "esp0x78@1049:1::8007:2040", "esp:78@1049:1::8007:2040",
203         0, "ah78@1049:1::8007:2040",    "ah:4e@1049:1::8007:2040",
204         0, "ah0x78@1049:1::8007:2040",  "ah:78@1049:1::8007:2040",
205         0, "tun78@1049:1::8007:2040",   "tun:4e@1049:1::8007:2040",
206         0, "tun0x78@1049:1::8007:2040", "tun:78@1049:1::8007:2040",
207         0, "duk99@3ffe:370:400:ff::9001:3001",  NULL,
208         0, "esp78x@1049:1::8007:2040",  NULL,
209         0, "esp0x78@1049:1:0xfff::8007:2040",   NULL,
210         0, "es78@1049:1::8007:2040",    NULL,
211         0, "",                          NULL,
212         0, "_",                         NULL,
213         0, "ah2.2",                     NULL,
214         0, "goo2@1.2.3.4",              NULL,
215         0, "esp9@1.2.3.4",              "esp.9@1.2.3.4",
216         'f', "esp0xa9@1.2.3.4",         "esp.000000a9@1.2.3.4",
217         0, "espp9@1.2.3.4",             NULL,
218         0, "es9@1.2.3.4",               NULL,
219         0, "ah@1.2.3.4",                NULL,
220         0, "esp7x7@1.2.3.4",            NULL,
221         0, "esp77@1.0x2.3.4",           NULL,
222         0, PASSTHROUGHNAME,             PASSTHROUGH4NAME,
223         0, PASSTHROUGH6NAME,            PASSTHROUGH6NAME,
224         0, "%pass",                     "%pass",
225         0, "int256@0.0.0.0",            "%pass",
226         0, "%drop",                     "%drop",
227         0, "int257@0.0.0.0",            "%drop",
228         0, "%reject",                   "%reject",
229         0, "int258@0.0.0.0",            "%reject",
230         0, "%hold",                     "%hold",
231         0, "int259@0.0.0.0",            "%hold",
232         0, "%trap",                     "%trap",
233         0, "int260@0.0.0.0",            "%trap",
234         0, "%trapsubnet",               "%trapsubnet",
235         0, "int261@0.0.0.0",            "%trapsubnet",
236         0, "int262@0.0.0.0",            "int.106@0.0.0.0",
237         FUDGE, "esp9@1.2.3.4",          "unk77.9@1.2.3.4",
238         0, NULL,                        NULL
239 };
240
241 void
242 regress()
243 {
244         struct rtab *r;
245         int status = 0;
246         ip_said sa;
247         char in[100];
248         char buf[100];
249         const char *oops;
250         size_t n;
251
252         for (r = rtab; r->input != NULL; r++) {
253                 strcpy(in, r->input);
254                 oops = ttosa(in, 0, &sa);
255                 if (oops != NULL && r->output == NULL)
256                         {}              /* okay, error expected */
257                 else if (oops != NULL) {
258                         printf("`%s' ttosa failed: %s\n", r->input, oops);
259                         status = 1;
260                 } else if (r->output == NULL) {
261                         printf("`%s' ttosa succeeded unexpectedly\n",
262                                                                 r->input);
263                         status = 1;
264                 } else {
265                         if (r->format&FUDGE)
266                                 sa.proto = 77;
267                         n = satot(&sa, (char)r->format, buf, sizeof(buf));
268                         if (n > sizeof(buf)) {
269                                 printf("`%s' satot failed:  need %ld\n",
270                                                         r->input, (long)n);
271                                 status = 1;
272                         } else if (strcmp(r->output, buf) != 0) {
273                                 printf("`%s' gave `%s', expected `%s'\n",
274                                                 r->input, buf, r->output);
275                                 status = 1;
276                         }
277                 }
278         }
279         exit(status);
280 }
281
282 #endif /* TTOSA_MAIN */