2 * convert from text form of SA ID to binary
3 * Copyright (C) 2000, 2001 Henry Spencer.
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>.
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.
15 * RCSID $Id: ttosa.c,v 1.10 2002/03/12 02:24:53 henry Exp $
20 static struct satype {
22 size_t prelen; /* strlen(prefix) */
27 { "tun", 3, SA_IPIP },
28 { "comp", 4, SA_COMP },
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" },
50 - ttosa - convert text "ah507@10.0.0.1" to SA identifier
52 err_t /* NULL for success, else string literal */
53 ttosa(src, srclen, sa)
55 size_t srclen; /* 0 means "apply strlen" */
61 const char *spi = NULL;
67 # define MINLEN 5 /* ah0@0 is as short as it can get */
74 return "empty string";
76 return "string too short to be SA identifier";
78 for (mp = magic; mp->name != NULL; mp++) {
79 nlen = strlen(mp->name);
80 if (srclen == nlen && memcmp(src, mp->name, nlen) == 0)
84 return "unknown % keyword";
89 at = memchr(src, '@', srclen);
91 return "no @ in SA specifier";
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 */
100 if (sat->prefix == NULL)
101 return "SA specifier lacks valid protocol prefix";
104 return "no SPI in SA specifier";
117 af = AF_UNSPEC; /* not known yet */
122 return "no SPI found in SA specifier";
123 oops = ttoul(spi, at - spi, base, &ul);
129 alen = srclen - (addr - src);
131 af = (memchr(addr, ':', alen) != NULL) ? AF_INET6 : AF_INET;
132 oops = ttoaddr(addr, alen, af, &sa->dst);
159 fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
163 if (strcmp(argv[1], "-r") == 0) {
165 fprintf(stderr, "regress() returned?!?\n");
169 oops = ttosa(argv[1], 0, &sa);
171 fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
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));
191 # define FUDGE 0x1000
193 char *output; /* NULL means error expected */
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,
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,
225 0, "int256@0.0.0.0", "%pass",
227 0, "int257@0.0.0.0", "%drop",
228 0, "%reject", "%reject",
229 0, "int258@0.0.0.0", "%reject",
231 0, "int259@0.0.0.0", "%hold",
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",
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);
260 } else if (r->output == NULL) {
261 printf("`%s' ttosa succeeded unexpectedly\n",
267 n = satot(&sa, (char)r->format, buf, sizeof(buf));
268 if (n > sizeof(buf)) {
269 printf("`%s' satot failed: need %ld\n",
272 } else if (strcmp(r->output, buf) != 0) {
273 printf("`%s' gave `%s', expected `%s'\n",
274 r->input, buf, r->output);
282 #endif /* TTOSA_MAIN */