OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / lib / atosa.c
1 /*
2  * convert from ASCII form of SA ID to binary
3  * Copyright (C) 1998, 1999  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: atosa.c,v 1.11 2000/09/17 18:55:37 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         { NULL,         0,      0,      }
30 };
31
32 /*
33  - atosa - convert ASCII "ah507@10.0.0.1" to SA identifier
34  */
35 const char *                    /* NULL for success, else string literal */
36 atosa(src, srclen, sa)
37 const char *src;
38 size_t srclen;                  /* 0 means "apply strlen" */
39 struct sa_id *sa;
40 {
41         const char *at;
42         const char *addr;
43         const char *spi = NULL;
44         struct satype *sat;
45         unsigned long ul;
46         const char *oops;
47 #       define  MINLEN  5       /* ah0@0 is as short as it can get */
48         static char ptname[] = PASSTHROUGHNAME;
49 #       define  PTNLEN  (sizeof(ptname)-1)      /* -1 for NUL */
50
51         if (srclen == 0)
52                 srclen = strlen(src);
53         if (srclen == 0)
54                 return "empty string";
55         if (srclen < MINLEN)
56                 return "string too short to be SA specifier";
57         if (srclen == PTNLEN && memcmp(src, ptname, PTNLEN) == 0) {
58                 src = PASSTHROUGHIS;
59                 srclen = strlen(src);
60         }
61
62         at = memchr(src, '@', srclen);
63         if (at == NULL)
64                 return "no @ in SA specifier";
65
66         for (sat = satypes; sat->prefix != NULL; sat++)
67                 if (sat->prelen < srclen &&
68                                 strncmp(src, sat->prefix, sat->prelen) == 0) {
69                         sa->proto = sat->proto;
70                         spi = src + sat->prelen;
71                         break;                  /* NOTE BREAK OUT */
72                 }
73         if (sat->prefix == NULL)
74                 return "SA specifier lacks valid protocol prefix";
75
76         if (spi >= at)
77                 return "no SPI in SA specifier";
78         oops = atoul(spi, at - spi, 13, &ul);
79         if (oops != NULL)
80                 return oops;
81         sa->spi = htonl(ul);
82
83         addr = at + 1;
84         oops = atoaddr(addr, srclen - (addr - src), &sa->dst);
85         if (oops != NULL)
86                 return oops;
87
88         return NULL;
89 }
90
91
92
93 #ifdef ATOSA_MAIN
94
95 #include <stdio.h>
96
97 void regress();
98
99 int
100 main(argc, argv)
101 int argc;
102 char *argv[];
103 {
104         struct sa_id sa;
105         char buf[100];
106         const char *oops;
107         size_t n;
108
109         if (argc < 2) {
110                 fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
111                 exit(2);
112         }
113
114         if (strcmp(argv[1], "-r") == 0) {
115                 regress();
116                 fprintf(stderr, "regress() returned?!?\n");
117                 exit(1);
118         }
119
120         oops = atosa(argv[1], 0, &sa);
121         if (oops != NULL) {
122                 fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
123                 exit(1);
124         }
125         n = satoa(sa, 0, buf, sizeof(buf));
126         if (n > sizeof(buf)) {
127                 fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto);
128                 fprintf(stderr, "%lu@", sa.spi);
129                 fprintf(stderr, "%s", inet_ntoa(sa.dst));
130                 fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
131                                                 (long)n, (long)sizeof(buf));
132                 exit(1);
133         }
134         printf("%s\n", buf);
135
136         exit(0);
137 }
138
139 struct rtab {
140         char *input;
141         char *output;                   /* NULL means error expected */
142 } rtab[] = {
143         "esp257@1.2.3.0",               "esp257@1.2.3.0",
144         "ah0x20@1.2.3.4",               "ah32@1.2.3.4",
145         "tun011@111.2.3.99",            "tun11@111.2.3.99",
146         "",                             NULL,
147         "_",                            NULL,
148         "ah2.2",                        NULL,
149         "goo2@1.2.3.4",                 NULL,
150         "esp9@1.2.3.4",                 "esp9@1.2.3.4",
151         "espp9@1.2.3.4",                NULL,
152         "es9@1.2.3.4",                  NULL,
153         "ah@1.2.3.4",                   NULL,
154         "esp7x7@1.2.3.4",               NULL,
155         "esp77@1.0x2.3.4",              NULL,
156         PASSTHROUGHNAME,                PASSTHROUGHNAME,
157         NULL,                           NULL
158 };
159
160 void
161 regress()
162 {
163         struct rtab *r;
164         int status = 0;
165         struct sa_id sa;
166         char in[100];
167         char buf[100];
168         const char *oops;
169         size_t n;
170
171         for (r = rtab; r->input != NULL; r++) {
172                 strcpy(in, r->input);
173                 oops = atosa(in, 0, &sa);
174                 if (oops != NULL && r->output == NULL)
175                         {}              /* okay, error expected */
176                 else if (oops != NULL) {
177                         printf("`%s' atosa failed: %s\n", r->input, oops);
178                         status = 1;
179                 } else if (r->output == NULL) {
180                         printf("`%s' atosa succeeded unexpectedly\n",
181                                                                 r->input);
182                         status = 1;
183                 } else {
184                         n = satoa(sa, 'd', buf, sizeof(buf));
185                         if (n > sizeof(buf)) {
186                                 printf("`%s' satoa failed:  need %ld\n",
187                                                         r->input, (long)n);
188                                 status = 1;
189                         } else if (strcmp(r->output, buf) != 0) {
190                                 printf("`%s' gave `%s', expected `%s'\n",
191                                                 r->input, buf, r->output);
192                                 status = 1;
193                         }
194                 }
195         }
196         exit(status);
197 }
198
199 #endif /* ATOSA_MAIN */