OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / lib / atoasr.c
1 /*
2  * convert from ASCII form of address/subnet/range 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: atoasr.c,v 1.5 1999/12/07 05:00:51 henry Exp $
16  */
17 #include "internal.h"
18 #include "freeswan.h"
19
20 /*
21  - atoasr - convert ASCII to address, subnet, or range
22  */
23 const char *                    /* NULL for success, else string literal */
24 atoasr(src, srclen, typep, addrsp)
25 const char *src;
26 size_t srclen;                  /* 0 means "apply strlen" */
27 char *typep;                    /* return type code:  'a', 's', 'r' */
28 struct in_addr addrsp[2];
29 {
30         const char *punct;
31         const char *stop;
32         const char *oops;
33
34         if (srclen == 0)
35                 srclen = strlen(src);
36         if (srclen == 0)
37                 return "empty string";
38
39         /* subnet is easy to spot */
40         punct = memchr(src, '/', srclen);
41         if (punct != NULL) {
42                 *typep = 's';
43                 return atosubnet(src, srclen, &addrsp[0], &addrsp[1]);
44         }
45
46         /* try for a range */
47         stop = src + srclen;
48         for (punct = src; (punct = memchr(punct, '.', stop - punct)) != NULL;
49                                                                         punct++)
50                 if (stop - punct > 3 && *(punct+1) == '.' && *(punct+2) == '.')
51                         break;                  /* NOTE BREAK OUT */
52         if (punct == NULL) {
53                 /* didn't find the range delimiter, must be plain address */
54                 *typep = 'a';
55                 return atoaddr(src, srclen, &addrsp[0]);
56         }
57
58         /* looks like a range */
59         *typep = 'r';
60         if (stop - punct > 4 && *(punct+3) == '.')
61                 punct++;                /* first dot is trailing dot of name */
62         oops = atoaddr(src, punct - src, &addrsp[0]);
63         if (oops != NULL)
64                 return oops;
65         oops = atoaddr(punct+3, stop - (punct+3), &addrsp[1]);
66         if (oops != NULL)
67                 return oops;
68         if (ntohl(addrsp[0].s_addr) > ntohl(addrsp[1].s_addr))
69                 return "invalid range, begin > end";
70         return NULL;
71 }
72
73
74
75 #ifdef ATOASR_MAIN
76
77 #include <stdio.h>
78
79 void regress();
80
81 int
82 main(argc, argv)
83 int argc;
84 char *argv[];
85 {
86         struct in_addr a[2];
87         char buf[100];
88         const char *oops;
89         size_t n;
90         char type;
91
92         if (argc < 2) {
93                 fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
94                                                                 argv[0]);
95                 exit(2);
96         }
97
98         if (strcmp(argv[1], "-r") == 0) {
99                 regress();
100                 fprintf(stderr, "regress() returned?!?\n");
101                 exit(1);
102         }
103
104         oops = atoasr(argv[1], 0, &type, a);
105         if (oops != NULL) {
106                 fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
107                 exit(1);
108         }
109         switch (type) {
110         case 'a':
111                 n = addrtoa(a[0], 0, buf, sizeof(buf));
112                 break;
113         case 's':
114                 n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
115                 break;
116         case 'r':
117                 n = rangetoa(a, 0, buf, sizeof(buf));
118                 break;
119         default:
120                 fprintf(stderr, "%s: unknown type '%c'\n", argv[0], type);
121                 exit(1);
122                 break;
123         }
124         if (n > sizeof(buf)) {
125                 fprintf(stderr, "%s: reverse conversion of ", argv[0]);
126                 fprintf(stderr, "%s ", inet_ntoa(a[0]));
127                 fprintf(stderr, "%s", inet_ntoa(a[1]));
128                 fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
129                                                 (long)n, (long)sizeof(buf));
130                 exit(1);
131         }
132         printf("%s\n", buf);
133
134         exit(0);
135 }
136
137 struct rtab {
138         char *input;
139         char *output;                   /* NULL means error expected */
140 } rtab[] = {
141         "1.2.3.0",                      "1.2.3.0",
142         "1.2.3.0/255.255.255.0",        "1.2.3.0/24",
143         "1.2.3.0...1.2.3.5",            "1.2.3.0...1.2.3.5",
144         "1.2.3.4.5",                    NULL,
145         "1.2.3.4/",                     NULL,
146         "1.2.3.4...",                   NULL,
147         "1.2.3.4....",                  NULL,
148         "localhost./32",                "127.0.0.1/32",
149         "localhost....127.0.0.3",       "127.0.0.1...127.0.0.3",
150         "127.0.0.0...localhost.",       "127.0.0.0...127.0.0.1",
151         "127.0.0.3...localhost.",       NULL,
152         NULL,                           NULL
153 };
154
155 void
156 regress()
157 {
158         struct rtab *r;
159         int status = 0;
160         struct in_addr a[2];
161         struct in_addr m;
162         char in[100];
163         char buf[100];
164         const char *oops;
165         size_t n;
166         char type;
167
168         for (r = rtab; r->input != NULL; r++) {
169                 strcpy(in, r->input);
170                 oops = atoasr(in, 0, &type, a);
171                 if (oops != NULL && r->output == NULL)
172                         {}              /* okay, error expected */
173                 else if (oops != NULL) {
174                         printf("`%s' atoasr failed: %s\n", r->input, oops);
175                         status = 1;
176                 } else if (r->output == NULL) {
177                         printf("`%s' atoasr succeeded unexpectedly '%c'\n",
178                                                         r->input, type);
179                         status = 1;
180                 } else {
181                         switch (type) {
182                         case 'a':
183                                 n = addrtoa(a[0], 0, buf, sizeof(buf));
184                                 break;
185                         case 's':
186                                 n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
187                                 break;
188                         case 'r':
189                                 n = rangetoa(a, 0, buf, sizeof(buf));
190                                 break;
191                         default:
192                                 fprintf(stderr, "`%s' unknown type '%c'\n",
193                                                         r->input, type);
194                                 n = 0;
195                                 status = 1;
196                                 break;
197                         }
198                         if (n > sizeof(buf)) {
199                                 printf("`%s' '%c' reverse failed:  need %ld\n",
200                                                 r->input, type, (long)n);
201                                 status = 1;
202                         } else if (n > 0 && strcmp(r->output, buf) != 0) {
203                                 printf("`%s' '%c' gave `%s', expected `%s'\n",
204                                         r->input, type, buf, r->output);
205                                 status = 1;
206                         }
207                 }
208         }
209         exit(status);
210 }
211
212 #endif /* ATOASR_MAIN */