27 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
28 |
*/ |
*/ |
29 |
|
|
30 |
#ifndef lint |
#if 0 |
31 |
static char sccsid[] = "@(#)commands.c 8.4 (Berkeley) 5/30/95"; |
static char sccsid[] = "@(#)commands.c 8.4 (Berkeley) 5/30/95"; |
32 |
#endif /* not lint */ |
#endif |
33 |
|
|
34 |
#ifdef HAVE_CONFIG_H |
#ifdef HAVE_CONFIG_H |
35 |
#include <config.h> |
#include <config.h> |
72 |
#include <malloc.h> |
#include <malloc.h> |
73 |
#endif |
#endif |
74 |
|
|
75 |
|
#include <arpa/inet.h> |
76 |
#include <arpa/telnet.h> |
#include <arpa/telnet.h> |
77 |
|
|
78 |
#include "general.h" |
#include "general.h" |
96 |
#include <netinet/ip.h> |
#include <netinet/ip.h> |
97 |
#endif |
#endif |
98 |
|
|
99 |
#if defined(IPPROTO_IP) && defined(IP_TOS) |
char *hostname = 0; |
|
int tos = -1; |
|
|
#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ |
|
|
|
|
|
char *hostname; |
|
|
static char *_hostname = 0; |
|
100 |
|
|
101 |
extern char *getenv __P((const char *)); |
extern char *getenv __P((const char *)); |
102 |
|
|
2195 |
} |
} |
2196 |
#endif |
#endif |
2197 |
|
|
|
unsigned long inet_addr(); |
|
|
|
|
2198 |
int |
int |
2199 |
tn(int argc, char *argv[]) |
tn(int argc, char *argv[]) |
2200 |
{ |
{ |
2201 |
register struct hostent *host = 0; |
#ifdef IPV6 |
2202 |
struct sockaddr_in sin; |
struct addrinfo *result, *aip, hints; |
2203 |
struct servent *sp = 0; |
#else |
2204 |
unsigned long temp; |
struct hostent *host = 0; |
2205 |
extern char *inet_ntoa(); |
struct sockaddr_in sin; |
2206 |
#if defined(IP_OPTIONS) && defined(IPPROTO_IP) |
struct servent *sp = 0; |
2207 |
char *srp = 0; |
in_addr_t temp; |
2208 |
#ifndef strrchr |
#endif |
2209 |
char *strrchr(); |
const int on = 1; |
2210 |
#endif |
int err; |
2211 |
unsigned long sourceroute(), srlen; |
char *cmd, *hostp = 0, *portp = 0, *user = 0; |
|
#endif |
|
|
char *cmd, *hostp = 0, *portp = 0, *user = 0; |
|
|
|
|
|
/* clear the socket address prior to use */ |
|
|
memset((char *)&sin, 0, sizeof(sin)); |
|
2212 |
|
|
2213 |
if (connected) { |
#ifdef IPV6 |
2214 |
printf("?Already connected to %s\n", hostname); |
memset (&hints, 0, sizeof (hints)); |
2215 |
setuid(getuid()); |
#else |
2216 |
return 0; |
/* clear the socket address prior to use */ |
2217 |
} |
memset ((char *)&sin, 0, sizeof(sin)); |
2218 |
if (argc < 2) { |
#endif |
2219 |
(void) strcpy(line, "open "); |
|
2220 |
printf("(to) "); |
if (connected) |
2221 |
(void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); |
{ |
2222 |
makeargv(); |
printf("?Already connected to %s\n", hostname); |
2223 |
argc = margc; |
return 0; |
|
argv = margv; |
|
2224 |
} |
} |
2225 |
cmd = *argv; |
if (argc < 2) |
2226 |
--argc; ++argv; |
{ |
2227 |
while (argc) { |
(void) strcpy(line, "open "); |
2228 |
if (strcmp(*argv, "help") == 0 || isprefix(*argv, "?")) |
printf("(to) "); |
2229 |
|
(void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); |
2230 |
|
makeargv(); |
2231 |
|
argc = margc; |
2232 |
|
argv = margv; |
2233 |
|
} |
2234 |
|
cmd = *argv; |
2235 |
|
--argc; ++argv; |
2236 |
|
while (argc) |
2237 |
|
{ |
2238 |
|
if (strcmp(*argv, "help") == 0 || isprefix(*argv, "?")) |
2239 |
|
goto usage; |
2240 |
|
if (strcmp(*argv, "-l") == 0) |
2241 |
|
{ |
2242 |
|
--argc; ++argv; |
2243 |
|
if (argc == 0) |
2244 |
goto usage; |
goto usage; |
2245 |
if (strcmp(*argv, "-l") == 0) { |
user = *argv++; |
2246 |
--argc; ++argv; |
--argc; |
2247 |
if (argc == 0) |
continue; |
|
goto usage; |
|
|
user = *argv++; |
|
|
--argc; |
|
|
continue; |
|
2248 |
} |
} |
2249 |
if (strcmp(*argv, "-a") == 0) { |
if (strcmp(*argv, "-a") == 0) |
2250 |
--argc; ++argv; |
{ |
2251 |
autologin = 1; |
--argc; ++argv; |
2252 |
continue; |
autologin = 1; |
2253 |
|
continue; |
2254 |
} |
} |
2255 |
if (hostp == 0) { |
if (strcmp(*argv, "-6") == 0) |
2256 |
hostp = *argv++; |
{ |
2257 |
--argc; |
--argc; ++argv; |
2258 |
continue; |
#ifdef IPV6 |
2259 |
|
hints.ai_family = AF_INET6; |
2260 |
|
#else |
2261 |
|
puts ("IPv6 isn't supported"); |
2262 |
|
#endif |
2263 |
|
continue; |
2264 |
} |
} |
2265 |
if (portp == 0) { |
if (strcmp(*argv, "-4") == 0) |
2266 |
portp = *argv++; |
{ |
2267 |
--argc; |
--argc; ++argv; |
2268 |
continue; |
#ifdef IPV6 |
2269 |
|
hints.ai_family = AF_INET; |
2270 |
|
#endif |
2271 |
|
continue; |
2272 |
|
} |
2273 |
|
if (hostp == 0) |
2274 |
|
{ |
2275 |
|
hostp = *argv++; |
2276 |
|
--argc; |
2277 |
|
continue; |
2278 |
|
} |
2279 |
|
if (portp == 0) |
2280 |
|
{ |
2281 |
|
portp = *argv++; |
2282 |
|
--argc; |
2283 |
|
continue; |
2284 |
} |
} |
2285 |
usage: |
usage: |
2286 |
printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); |
printf("usage: %s [-4] [-6] [-l user] [-a] host-name [port]\n", cmd); |
2287 |
setuid(getuid()); |
return 0; |
|
return 0; |
|
2288 |
} |
} |
2289 |
if (hostp == 0) |
if (hostp == 0) |
2290 |
goto usage; |
goto usage; |
2291 |
|
|
2292 |
#if defined(IP_OPTIONS) && defined(IPPROTO_IP) |
if (!portp) |
2293 |
if (hostp[0] == '@' || hostp[0] == '!') { |
{ |
2294 |
if ((hostname = strrchr(hostp, ':')) == NULL) |
portp = "telnet"; |
2295 |
hostname = strrchr(hostp, '@'); |
telnetport = 1; |
2296 |
hostname++; |
} |
2297 |
srp = 0; |
else |
2298 |
temp = sourceroute(hostp, &srp, &srlen); |
{ |
2299 |
if (temp == 0) { |
if (*portp == '-') |
2300 |
herror(srp); |
{ |
2301 |
setuid(getuid()); |
portp++; |
2302 |
return 0; |
telnetport = 1; |
|
} else if (temp == -1) { |
|
|
printf("Bad source route option: %s\n", hostp); |
|
|
setuid(getuid()); |
|
|
return 0; |
|
|
} else { |
|
|
sin.sin_addr.s_addr = temp; |
|
|
sin.sin_family = AF_INET; |
|
2303 |
} |
} |
2304 |
} else { |
else |
2305 |
|
telnetport = 0; |
2306 |
|
} |
2307 |
|
|
2308 |
|
if (hostname) |
2309 |
|
free (hostname); |
2310 |
|
hostname = malloc (strlen (hostp) + 1); |
2311 |
|
if (hostname) |
2312 |
|
strcpy (hostname, hostp); |
2313 |
|
else |
2314 |
|
{ |
2315 |
|
printf ("Can't allocate memory to copy hostname\n"); |
2316 |
|
return 0; |
2317 |
|
} |
2318 |
|
|
2319 |
|
#ifdef IPV6 |
2320 |
|
#ifdef AI_ADDRCONFIG |
2321 |
|
hints.ai_flags = AI_ADDRCONFIG; |
2322 |
#endif |
#endif |
2323 |
temp = inet_addr(hostp); |
hints.ai_socktype = SOCK_STREAM; |
|
if (temp != (unsigned long) -1) { |
|
|
sin.sin_addr.s_addr = temp; |
|
|
sin.sin_family = AF_INET; |
|
2324 |
|
|
2325 |
} else { |
err = getaddrinfo (hostp, portp, &hints, &result); |
2326 |
host = gethostbyname(hostp); |
if (err) |
2327 |
if (host) { |
{ |
2328 |
sin.sin_family = host->h_addrtype; |
const char *errmsg; |
2329 |
#if defined(h_addr) /* In 4.3, this is a #define */ |
|
2330 |
memmove((caddr_t)&sin.sin_addr, |
if (err == EAI_SYSTEM) |
2331 |
host->h_addr_list[0], host->h_length); |
errmsg = strerror (errno); |
2332 |
#else /* defined(h_addr) */ |
else |
2333 |
memmove((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); |
errmsg = gai_strerror (err); |
2334 |
#endif /* defined(h_addr) */ |
|
2335 |
|
printf ("%s/%s: lookup failure: %s\n", hostp, portp, errmsg); |
2336 |
|
return 0; |
2337 |
|
} |
2338 |
|
|
2339 |
|
aip = result; |
2340 |
|
|
2341 |
|
do |
2342 |
|
{ |
2343 |
|
char buf[256]; |
2344 |
|
|
2345 |
|
err = getnameinfo (aip->ai_addr, aip->ai_addrlen, buf, sizeof (buf), |
2346 |
|
NULL, 0, NI_NUMERICHOST); |
2347 |
|
if (err) |
2348 |
|
{ |
2349 |
|
/* I don't know how thing can happen, but we just handle it. */ |
2350 |
|
const char *errmsg; |
2351 |
|
|
2352 |
|
if (err == EAI_SYSTEM) |
2353 |
|
errmsg = strerror (errno); |
2354 |
|
else |
2355 |
|
errmsg = gai_strerror (err); |
2356 |
|
|
2357 |
|
printf ("getnameinfo error: %s\n", errmsg); |
2358 |
|
return 0; |
2359 |
|
} |
2360 |
|
|
2361 |
|
printf ("Trying %s...\n", buf); |
2362 |
|
|
2363 |
|
net = socket (aip->ai_family, SOCK_STREAM, 0); |
2364 |
|
if (net < 0) |
2365 |
|
{ |
2366 |
|
perror("telnet: socket"); |
2367 |
|
return 0; |
2368 |
|
} |
2369 |
|
|
2370 |
|
if (debug) |
2371 |
|
{ |
2372 |
|
err = setsockopt (net, SOL_SOCKET, SO_DEBUG, &on, sizeof(on)); |
2373 |
|
if (err < 0) |
2374 |
|
perror("setsockopt (SO_DEBUG)"); |
2375 |
|
} |
2376 |
|
|
2377 |
|
err = connect (net, (struct sockaddr *)aip->ai_addr, aip->ai_addrlen); |
2378 |
|
if (err < 0) |
2379 |
|
{ |
2380 |
|
if (aip->ai_next) |
2381 |
|
{ |
2382 |
|
perror ("Connection failed"); |
2383 |
|
aip = aip->ai_next; |
2384 |
|
close (net); |
2385 |
|
continue; |
2386 |
} |
} |
2387 |
|
|
2388 |
|
perror("telnet: Unable to connect to remote host"); |
2389 |
|
return 0; |
2390 |
} |
} |
2391 |
if (_hostname) |
|
2392 |
free (_hostname); |
connected++; |
2393 |
_hostname = malloc (strlen (hostp) + 1); |
#if defined(AUTHENTICATION) || defined(ENCRYPTION) |
2394 |
if (_hostname) { |
auth_encrypt_connect(connected); |
2395 |
strcpy (_hostname, hostp); |
#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ |
2396 |
hostname = _hostname; |
} while (!connected); |
2397 |
} else { |
|
2398 |
printf ("Can't allocate memory to copy hostname\n"); |
freeaddrinfo (result); |
2399 |
setuid(getuid()); |
#else /* !IPV6 */ |
2400 |
return 0; |
temp = inet_addr (hostp); |
2401 |
} |
if (temp != (in_addr_t) -1) |
2402 |
#if defined(IP_OPTIONS) && defined(IPPROTO_IP) |
{ |
2403 |
|
sin.sin_addr.s_addr = temp; |
2404 |
|
sin.sin_family = AF_INET; |
2405 |
} |
} |
2406 |
#endif |
else |
2407 |
if (portp) { |
{ |
2408 |
if (*portp == '-') { |
host = gethostbyname (hostp); |
2409 |
portp++; |
if (host) |
2410 |
telnetport = 1; |
{ |
2411 |
} else |
sin.sin_family = host->h_addrtype; |
2412 |
telnetport = 0; |
memmove (&sin.sin_addr, host->h_addr_list[0], host->h_length); |
|
sin.sin_port = atoi(portp); |
|
|
if (sin.sin_port == 0) { |
|
|
sp = getservbyname(portp, "tcp"); |
|
|
if (sp) |
|
|
sin.sin_port = sp->s_port; |
|
|
else { |
|
|
printf("%s: bad port number\n", portp); |
|
|
setuid(getuid()); |
|
|
return 0; |
|
|
} |
|
|
} else { |
|
|
#if !HAVE_DECL_HTONS |
|
|
#ifndef htons |
|
|
u_short htons __P((unsigned short)); |
|
|
#endif |
|
|
#endif |
|
|
sin.sin_port = htons (sin.sin_port); |
|
2413 |
} |
} |
2414 |
} else { |
else |
2415 |
if (sp == 0) { |
{ |
2416 |
sp = getservbyname("telnet", "tcp"); |
printf ("Can't lookup hostname %s\n", hostp); |
2417 |
if (sp == 0) { |
return 0; |
|
fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); |
|
|
setuid(getuid()); |
|
|
return 0; |
|
|
} |
|
|
sin.sin_port = sp->s_port; |
|
2418 |
} |
} |
|
telnetport = 1; |
|
2419 |
} |
} |
2420 |
printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); |
|
2421 |
do { |
sin.sin_port = atoi (portp); |
2422 |
net = socket(AF_INET, SOCK_STREAM, 0); |
if (sin.sin_port == 0) |
2423 |
setuid(getuid()); |
{ |
2424 |
if (net < 0) { |
sp = getservbyname (portp, "tcp"); |
2425 |
perror("telnet: socket"); |
if (sp == 0) |
2426 |
return 0; |
{ |
2427 |
|
printf ("tcp/%s: unknown service\n", portp); |
2428 |
|
return 0; |
2429 |
} |
} |
2430 |
#if defined(IP_OPTIONS) && defined(IPPROTO_IP) |
sin.sin_port = sp->s_port; |
2431 |
if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) |
} |
2432 |
perror("setsockopt (IP_OPTIONS)"); |
else |
2433 |
#endif |
sin.sin_port = htons (sin.sin_port); |
2434 |
#if defined(IPPROTO_IP) && defined(IP_TOS) |
|
2435 |
|
printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); |
2436 |
|
do |
2437 |
|
{ |
2438 |
|
net = socket(AF_INET, SOCK_STREAM, 0); |
2439 |
|
if (net < 0) |
2440 |
{ |
{ |
2441 |
# if defined(HAS_GETTOS) |
perror("telnet: socket"); |
2442 |
struct tosent *tp; |
return 0; |
|
if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) |
|
|
tos = tp->t_tos; |
|
|
# endif |
|
|
if (tos < 0) |
|
|
tos = 020; /* Low Delay bit */ |
|
|
if (tos |
|
|
&& (setsockopt(net, IPPROTO_IP, IP_TOS, |
|
|
(char *)&tos, sizeof(int)) < 0) |
|
|
&& (errno != ENOPROTOOPT)) |
|
|
perror("telnet: setsockopt (IP_TOS) (ignored)"); |
|
2443 |
} |
} |
2444 |
|
#if defined(IPPROTO_IP) && defined(IP_TOS) |
2445 |
|
{ |
2446 |
|
#ifdef IPTOS_LOWDELAY |
2447 |
|
const int tos = IPTOS_LOWDELAY; |
2448 |
|
#else |
2449 |
|
const int tos = 0x10; |
2450 |
|
#endif |
2451 |
|
|
2452 |
|
err = setsockopt (net, IPPROTO_IP, IP_TOS, |
2453 |
|
(char *)&tos, sizeof(tos)); |
2454 |
|
if (err < 0 && errno != ENOPROTOOPT) |
2455 |
|
perror("telnet: setsockopt (IP_TOS) (ignored)"); |
2456 |
|
} |
2457 |
#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ |
#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ |
2458 |
|
|
2459 |
if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { |
if (debug && setsockopt(net, SOL_SOCKET, SO_DEBUG, &on, sizeof(on)) < 0) |
2460 |
perror("setsockopt (SO_DEBUG)"); |
perror("setsockopt (SO_DEBUG)"); |
|
} |
|
2461 |
|
|
2462 |
if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { |
if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) |
2463 |
#if defined(h_addr) /* In 4.3, this is a #define */ |
{ |
2464 |
if (host && host->h_addr_list[1]) { |
if (host && host->h_addr_list[1]) |
2465 |
int oerrno = errno; |
{ |
2466 |
|
int oerrno = errno; |
2467 |
fprintf(stderr, "telnet: connect to address %s: ", |
|
2468 |
inet_ntoa(sin.sin_addr)); |
fprintf(stderr, "telnet: connect to address %s: ", |
2469 |
errno = oerrno; |
inet_ntoa(sin.sin_addr)); |
2470 |
perror((char *)0); |
errno = oerrno; |
2471 |
host->h_addr_list++; |
perror((char *)0); |
2472 |
memmove((caddr_t)&sin.sin_addr, |
host->h_addr_list++; |
2473 |
host->h_addr_list[0], host->h_length); |
memmove((caddr_t)&sin.sin_addr, |
2474 |
(void) NetClose(net); |
host->h_addr_list[0], host->h_length); |
2475 |
continue; |
close (net); |
2476 |
|
continue; |
2477 |
} |
} |
2478 |
#endif /* defined(h_addr) */ |
perror("telnet: Unable to connect to remote host"); |
2479 |
perror("telnet: Unable to connect to remote host"); |
return 0; |
|
return 0; |
|
2480 |
} |
} |
2481 |
connected++; |
connected++; |
2482 |
#if defined(AUTHENTICATION) || defined(ENCRYPTION) |
#if defined(AUTHENTICATION) || defined(ENCRYPTION) |
2483 |
auth_encrypt_connect(connected); |
auth_encrypt_connect(connected); |
2484 |
#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ |
#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ |
2485 |
} while (connected == 0); |
} while (connected == 0); |
2486 |
cmdrc(hostp, hostname); |
#endif /* !IPV6 */ |
2487 |
if (autologin && user == NULL) { |
cmdrc(hostp, hostname); |
2488 |
struct passwd *pw; |
if (autologin && user == NULL) |
2489 |
|
{ |
2490 |
user = getenv("USER"); |
struct passwd *pw; |
2491 |
if (user == NULL || |
|
2492 |
(pw = getpwnam(user)) && pw->pw_uid != getuid()) { |
user = getenv("USER"); |
2493 |
if (pw = getpwuid(getuid())) |
if (user == NULL || |
2494 |
user = pw->pw_name; |
(pw = getpwnam(user)) && pw->pw_uid != getuid()) |
2495 |
else |
{ |
2496 |
user = NULL; |
if (pw = getpwuid(getuid())) |
2497 |
|
user = pw->pw_name; |
2498 |
|
else |
2499 |
|
user = NULL; |
2500 |
} |
} |
2501 |
} |
} |
2502 |
if (user) { |
if (user) |
2503 |
env_define((unsigned char *)"USER", (unsigned char *)user); |
{ |
2504 |
env_export((unsigned char *)"USER"); |
env_define((unsigned char *)"USER", (unsigned char *)user); |
2505 |
|
env_export((unsigned char *)"USER"); |
2506 |
} |
} |
2507 |
(void) call(status, "status", "notmuch", 0); |
(void) call(status, "status", "notmuch", 0); |
2508 |
if (setjmp(peerdied) == 0) |
if (setjmp(peerdied) == 0) |
2509 |
telnet(user); |
telnet(user); |
2510 |
(void) NetClose(net); |
|
2511 |
ExitString("Connection closed by foreign host.\n",1); |
close (net); |
2512 |
/*NOTREACHED*/ |
ExitString("Connection closed by foreign host.\n",1); |
2513 |
|
/*NOTREACHED*/ |
2514 |
|
|
2515 |
|
return 0; |
2516 |
} |
} |
2517 |
|
|
2518 |
#define HELPINDENT (sizeof ("connect")) |
#define HELPINDENT (sizeof ("connect")) |
2829 |
} |
} |
2830 |
fclose(rcfile); |
fclose(rcfile); |
2831 |
} |
} |
|
|
|
|
#if defined(IP_OPTIONS) && defined(IPPROTO_IP) |
|
|
|
|
|
/* |
|
|
* Source route is handed in as |
|
|
* [!]@hop1@hop2...[@|:]dst |
|
|
* If the leading ! is present, it is a |
|
|
* strict source route, otherwise it is |
|
|
* assmed to be a loose source route. |
|
|
* |
|
|
* We fill in the source route option as |
|
|
* hop1,hop2,hop3...dest |
|
|
* and return a pointer to hop1, which will |
|
|
* be the address to connect() to. |
|
|
* |
|
|
* Arguments: |
|
|
* arg: pointer to route list to decipher |
|
|
* |
|
|
* cpp: If *cpp is not equal to NULL, this is a |
|
|
* pointer to a pointer to a character array |
|
|
* that should be filled in with the option. |
|
|
* |
|
|
* lenp: pointer to an integer that contains the |
|
|
* length of *cpp if *cpp != NULL. |
|
|
* |
|
|
* Return values: |
|
|
* |
|
|
* Returns the address of the host to connect to. If the |
|
|
* return value is -1, there was a syntax error in the |
|
|
* option, either unknown characters, or too many hosts. |
|
|
* If the return value is 0, one of the hostnames in the |
|
|
* path is unknown, and *cpp is set to point to the bad |
|
|
* hostname. |
|
|
* |
|
|
* *cpp: If *cpp was equal to NULL, it will be filled |
|
|
* in with a pointer to our static area that has |
|
|
* the option filled in. This will be 32bit aligned. |
|
|
* |
|
|
* *lenp: This will be filled in with how long the option |
|
|
* pointed to by *cpp is. |
|
|
* |
|
|
*/ |
|
|
unsigned long |
|
|
sourceroute(char *arg, char **cpp, int *lenp) |
|
|
{ |
|
|
static char lsr[44]; |
|
|
#ifdef sysV88 |
|
|
static IOPTN ipopt; |
|
|
#endif |
|
|
char *cp, *cp2, *lsrp, *lsrep; |
|
|
register int tmp; |
|
|
struct in_addr sin_addr; |
|
|
register struct hostent *host = 0; |
|
|
register char c; |
|
|
|
|
|
/* |
|
|
* Verify the arguments, and make sure we have |
|
|
* at least 7 bytes for the option. |
|
|
*/ |
|
|
if (cpp == NULL || lenp == NULL) |
|
|
return((unsigned long)-1); |
|
|
if (*cpp != NULL && *lenp < 7) |
|
|
return((unsigned long)-1); |
|
|
/* |
|
|
* Decide whether we have a buffer passed to us, |
|
|
* or if we need to use our own static buffer. |
|
|
*/ |
|
|
if (*cpp) { |
|
|
lsrp = *cpp; |
|
|
lsrep = lsrp + *lenp; |
|
|
} else { |
|
|
*cpp = lsrp = lsr; |
|
|
lsrep = lsrp + 44; |
|
|
} |
|
|
|
|
|
cp = arg; |
|
|
|
|
|
/* |
|
|
* Next, decide whether we have a loose source |
|
|
* route or a strict source route, and fill in |
|
|
* the begining of the option. |
|
|
*/ |
|
|
#ifndef sysV88 |
|
|
if (*cp == '!') { |
|
|
cp++; |
|
|
*lsrp++ = IPOPT_SSRR; |
|
|
} else |
|
|
*lsrp++ = IPOPT_LSRR; |
|
|
#else |
|
|
if (*cp == '!') { |
|
|
cp++; |
|
|
ipopt.io_type = IPOPT_SSRR; |
|
|
} else |
|
|
ipopt.io_type = IPOPT_LSRR; |
|
|
#endif |
|
|
|
|
|
if (*cp != '@') |
|
|
return((unsigned long)-1); |
|
|
|
|
|
#ifndef sysV88 |
|
|
lsrp++; /* skip over length, we'll fill it in later */ |
|
|
*lsrp++ = 4; |
|
|
#endif |
|
|
|
|
|
cp++; |
|
|
|
|
|
sin_addr.s_addr = 0; |
|
|
|
|
|
for (c = 0;;) { |
|
|
if (c == ':') |
|
|
cp2 = 0; |
|
|
else for (cp2 = cp; c = *cp2; cp2++) { |
|
|
if (c == ',') { |
|
|
*cp2++ = '\0'; |
|
|
if (*cp2 == '@') |
|
|
cp2++; |
|
|
} else if (c == '@') { |
|
|
*cp2++ = '\0'; |
|
|
} else if (c == ':') { |
|
|
*cp2++ = '\0'; |
|
|
} else |
|
|
continue; |
|
|
break; |
|
|
} |
|
|
if (!c) |
|
|
cp2 = 0; |
|
|
|
|
|
if ((tmp = inet_addr(cp)) != -1) { |
|
|
sin_addr.s_addr = tmp; |
|
|
} else if (host = gethostbyname(cp)) { |
|
|
#if defined(h_addr) |
|
|
memmove((caddr_t)&sin_addr, |
|
|
host->h_addr_list[0], host->h_length); |
|
|
#else |
|
|
memmove((caddr_t)&sin_addr, host->h_addr, host->h_length); |
|
|
#endif |
|
|
} else { |
|
|
*cpp = cp; |
|
|
return(0); |
|
|
} |
|
|
memmove(lsrp, (char *)&sin_addr, 4); |
|
|
lsrp += 4; |
|
|
if (cp2) |
|
|
cp = cp2; |
|
|
else |
|
|
break; |
|
|
/* |
|
|
* Check to make sure there is space for next address |
|
|
*/ |
|
|
if (lsrp + 4 > lsrep) |
|
|
return((unsigned long)-1); |
|
|
} |
|
|
#ifndef sysV88 |
|
|
if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { |
|
|
*cpp = 0; |
|
|
*lenp = 0; |
|
|
return((unsigned long)-1); |
|
|
} |
|
|
*lsrp++ = IPOPT_NOP; /* 32 bit word align it */ |
|
|
*lenp = lsrp - *cpp; |
|
|
#else |
|
|
ipopt.io_len = lsrp - *cpp; |
|
|
if (ipopt.io_len <= 5) { /* Is 3 better ? */ |
|
|
*cpp = 0; |
|
|
*lenp = 0; |
|
|
return((unsigned long)-1); |
|
|
} |
|
|
*lenp = sizeof(ipopt); |
|
|
*cpp = (char *) &ipopt; |
|
|
#endif |
|
|
return(sin_addr.s_addr); |
|
|
} |
|
|
#endif |
|