]> git.saurik.com Git - apple/network_cmds.git/blob - traceroute.tproj/as.c
network_cmds-325.tar.gz
[apple/network_cmds.git] / traceroute.tproj / as.c
1 /* $FreeBSD: src/contrib/traceroute/as.c,v 1.1 2008/02/20 23:29:52 rpaulo Exp $ */
2 /* $NetBSD: as.c,v 1.1 2001/11/04 23:14:36 atatat Exp $ */
3
4 /*
5 * Copyright (c) 2001 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Andrew Brown.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #include <sys/cdefs.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 #include <netdb.h>
46 #include <unistd.h>
47 #include <string.h>
48 #include <stdlib.h>
49 #include <errno.h>
50 #include <err.h>
51 #include <stdio.h>
52
53 #include "as.h"
54
55 #define DEFAULT_AS_SERVER "whois.radb.net"
56 #undef AS_DEBUG_FILE
57
58 struct aslookup {
59 FILE *as_f;
60 #ifdef AS_DEBUG_FILE
61 FILE *as_debug;
62 #endif /* AS_DEBUG_FILE */
63 };
64
65 void *
66 as_setup(server)
67 char *server;
68 {
69 struct aslookup *asn;
70 struct hostent *he = NULL;
71 struct servent *se;
72 struct sockaddr_in in;
73 FILE *f;
74 int s;
75
76 if (server == NULL)
77 server = DEFAULT_AS_SERVER;
78
79 (void)memset(&in, 0, sizeof(in));
80 in.sin_family = AF_INET;
81 in.sin_len = sizeof(in);
82 if ((se = getservbyname("whois", "tcp")) == NULL) {
83 warnx("warning: whois/tcp service not found");
84 in.sin_port = ntohs(43);
85 } else
86 in.sin_port = se->s_port;
87
88 if (inet_aton(server, &in.sin_addr) == 0 &&
89 ((he = gethostbyname(server)) == NULL ||
90 he->h_addr == NULL)) {
91 warnx("%s: %s", server, hstrerror(h_errno));
92 return (NULL);
93 }
94
95 if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
96 warn("socket");
97 return (NULL);
98 }
99
100 do {
101 if (he != NULL) {
102 memcpy(&in.sin_addr, he->h_addr, he->h_length);
103 he->h_addr_list++;
104 }
105 if (connect(s, (struct sockaddr *)&in, sizeof(in)) == 0)
106 break;
107 if (he == NULL || he->h_addr == NULL) {
108 close(s);
109 s = -1;
110 break;
111 }
112 } while (1);
113
114 if (s == -1) {
115 warn("connect");
116 return (NULL);
117 }
118
119 f = fdopen(s, "r+");
120 (void)fprintf(f, "!!\n");
121 (void)fflush(f);
122
123 asn = malloc(sizeof(struct aslookup));
124 if (asn == NULL)
125 (void)fclose(f);
126 else
127 asn->as_f = f;
128
129 #ifdef AS_DEBUG_FILE
130 asn->as_debug = fopen(AS_DEBUG_FILE, "w");
131 if (asn->as_debug) {
132 (void)fprintf(asn->as_debug, ">> !!\n");
133 (void)fflush(asn->as_debug);
134 }
135 #endif /* AS_DEBUG_FILE */
136
137 return (asn);
138 }
139
140 int
141 as_lookup(_asn, addr)
142 void *_asn;
143 struct in_addr *addr;
144 {
145 struct aslookup *asn = _asn;
146 char buf[1024];
147 int as, rc, dlen;
148
149 as = rc = dlen = 0;
150 (void)fprintf(asn->as_f, "!r%s/32,l\n", inet_ntoa(*addr));
151 (void)fflush(asn->as_f);
152
153 #ifdef AS_DEBUG_FILE
154 if (asn->as_debug) {
155 (void)fprintf(asn->as_debug, ">> !r%s/32,l\n",
156 inet_ntoa(*addr));
157 (void)fflush(asn->as_debug);
158 }
159 #endif /* AS_DEBUG_FILE */
160
161 while (fgets(buf, sizeof(buf), asn->as_f) != NULL) {
162 buf[sizeof(buf) - 1] = '\0';
163
164 #ifdef AS_DEBUG_FILE
165 if (asn->as_debug) {
166 (void)fprintf(asn->as_debug, "<< %s", buf);
167 (void)fflush(asn->as_debug);
168 }
169 #endif /* AS_DEBUG_FILE */
170
171 if (rc == 0) {
172 rc = buf[0];
173 switch (rc) {
174 case 'A':
175 /* A - followed by # bytes of answer */
176 sscanf(buf, "A%d\n", &dlen);
177 #ifdef AS_DEBUG_FILE
178 if (asn->as_debug) {
179 (void)fprintf(asn->as_debug,
180 "dlen: %d\n", dlen);
181 (void)fflush(asn->as_debug);
182 }
183 #endif /* AS_DEBUG_FILE */
184 break;
185 case 'C':
186 case 'D':
187 case 'E':
188 case 'F':
189 /* C - no data returned */
190 /* D - key not found */
191 /* E - multiple copies of key */
192 /* F - some other error */
193 break;
194 }
195 if (rc == 'A')
196 /* skip to next input line */
197 continue;
198 }
199
200 if (dlen == 0)
201 /* out of data, next char read is end code */
202 rc = buf[0];
203 if (rc != 'A')
204 /* either an error off the bat, or a done code */
205 break;
206
207 /* data received, thank you */
208 dlen -= strlen(buf);
209
210 /* origin line is the interesting bit */
211 if (as == 0 && strncasecmp(buf, "origin:", 7) == 0) {
212 sscanf(buf + 7, " AS%d", &as);
213 #ifdef AS_DEBUG_FILE
214 if (asn->as_debug) {
215 (void)fprintf(asn->as_debug, "as: %d\n", as);
216 (void)fflush(asn->as_debug);
217 }
218 #endif /* AS_DEBUG_FILE */
219 }
220 }
221
222 return (as);
223 }
224
225 void
226 as_shutdown(_asn)
227 void *_asn;
228 {
229 struct aslookup *asn = _asn;
230
231 (void)fprintf(asn->as_f, "!q\n");
232 (void)fclose(asn->as_f);
233
234 #ifdef AS_DEBUG_FILE
235 if (asn->as_debug) {
236 (void)fprintf(asn->as_debug, ">> !q\n");
237 (void)fclose(asn->as_debug);
238 }
239 #endif /* AS_DEBUG_FILE */
240
241 free(asn);
242 }