/* radb AS object LOOKing UP utility*/
/* ASLOOKUP */
/* $Id: aslookup.c,v 1.15 2000/04/05 08:35:54 kuniaki Exp $ */
/*
 * Copyright (c) 1998-2000 Internet Initiative Japan Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistribution with functional modification must include
 *    prominent notice stating how and when and by whom it is
 *    modified.
 * 3. Redistributions in binary form have to be along with the source
 *    code or documentation which include above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 4. All commercial advertising materials mentioning features or use
 *    of this software must display the following acknowledgement:
 *      This product includes software developed by Internet
 *      Initiative Japan Inc.
 *
 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>

#ifdef SOLARIS
#include <arpa/inet.h>
#endif

#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#define VERSION	"ASLookup Alpha Version 0.12"
#define COPYRIGHT "Copyright (C) 1998 - 2000 K.Kondo, Internet Initiative Japan Inc."
#define REVISION "$Id: aslookup.c,v 1.15 2000/04/05 08:35:54 kuniaki Exp $"

#ifdef RALOCAL
#define RADB	"localhost"
#define WHOIS	43
#endif /* _ifedef RALOCAL */
#ifndef RALOCAL
#define RADB	"whois.ra.net"
#define WHOIS	43
#endif /* _ifndef RALOCAL */


#ifdef LOG
#define LOGFILE "/var/log/aslookup.log"
#endif /* _ifdef LOG */

#define STDWHOIS	43
#define JPWHOIS 	"whois.nic.ad.jp"
#define APWHOIS 	"whois.apnic.net"
#define JIWHOIS		"whois.jpix.ad.jp"
#define ARINWHOIS	"whois.arin.net"

#define SKIP		59
#define STRBUFLEN	2048

#define JPNICTAG	"JNIC-ASN"
#define APNICTAG	"APNIC-AS-BLOCK"

typedef struct {
	void *next;
	char pathstr[1024];
	char data[128];
} ASPATHCACHE;

ASPATHCACHE *head;

int	sc; 	/* Socket for RADB */

#ifdef LOG
void connectlog(connecthost)
char *connecthost;
{
	FILE *logfp;
	time_t tmt;
	char timestr[30],*tmp;

	if ((logfp = fopen(LOGFILE, "a")) == NULL) {
		printf("Could not open Logfile\n");
		return;
	}
	tmt = time(NULL);
	tmp = ctime(&tmt);
	strcpy(timestr, tmp);
	timestr[strlen(timestr)-1] = '\0';
	fprintf(logfp, "%s : Connected to %s\n", timestr, connecthost);
	fclose(logfp);
}
#endif /* _ifdef LOG */

int dbopen()
{
	struct hostent		*hp;
	struct sockaddr_in	sin;

	if ((hp = gethostbyname(RADB)) == NULL) {
		printf("%s Unknown Host. FATAL Error \n", RADB);
		exit(1);
	}

	if ((sc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		printf("Socket: FATAL Error\n");
		exit(2);
	}

	sin.sin_family	= AF_INET;
	sin.sin_port	= htons(WHOIS);
	bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

	if (connect(sc, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		printf("Client: Connect : FATAL Error\n");
		exit(3);
	}
#ifdef LOG
	connectlog(RADB);
#endif
}

int dbclose()
{
	write(sc, "q\n", 2);
	close(sc);

}

int batchmode()
{
	write(sc, "!!\n", 3);
}

int getcontrol(type)
char *type;
{
	char 	line[1024];
	char	c;
	int	cnt;
	int	ret;

	bzero(line, 1024);
	cnt = 0;
	while(1) {
		read(sc, &c, 1);
		if (c == '\n') break;
		line[cnt] = c;
		cnt++;
	}

	ret = 0;
	switch(line[0]) {
	case 'A':
		*type = 'A';
		ret = atoi(&line[1]);
		break;
	case 'B':
		*type = 'B';
		break;
	case 'C':
		*type = 'C';
		ret = -1;
		break;
	case 'D':
		*type = 'D';
		ret = -1;
		break;
	case 'E':
		*type = 'E';
		break;
	case 'F':
		*type = 'F';
		break;
	default:
		*type = 'Z';
		ret = 0;
	}
	return(ret);
}

int sread(buf, len)
char *buf;
int  len;
{
	int	cnt;
	int	rel;

	cnt = 0;
	bzero(buf, len);
	while(cnt < len) {
		rel = read(sc, (char *)(buf + cnt), (len-cnt));
		cnt += rel;
#ifdef DEBUG
		printf("Reading %d/%d/%d\n",rel,cnt,len);
		fflush(stdout);
#endif
	}
	*(buf+len) = '\0';
#ifdef DEBUG
	printf("%d:%s", strlen(buf), buf);
#endif
}

char *readdata()
{
	char 	type;
	int	result;
	char	*data;
	int	stop;
	int	getdata;

	data = NULL;
	stop = 0;
	getdata = 0;
	while(stop == 0){
		result = getcontrol(&type);

#ifdef DEBUG
		printf("DATA Type %c\n",type);
#endif

		switch(type) {
		case 'A':
#ifdef DEBUG
			printf("reading data = %d byte\n",result);
#endif
			data = (char *)malloc(result+1);
#ifdef DEBUG
			printf("MALLOCED ADDRESS:0x%08X\n", data);
#endif
			sread(data, result);
			getdata = 1;
			break;
	
		case 'B':
			stop = 1;
			break;
		case 'C':
#ifdef DEBUG
			printf("Compleate\n");
#endif
			stop = 1;
			break;
		case 'D':
			stop = 1;
			break;
		case 'E':
			stop = 1;
			break;
		case 'F':
			stop = 1;
			break;
		default:
			stop = 1;
			break;
		}
	}

	return(data);
}

char *getasobj(asn)
u_long asn;
{
	char	asstr[128];
	char	*data;

	sprintf(asstr, "!man,AS%d\n", asn);

#ifdef DEBUG
	printf("Command : %s", asstr);
#endif

	write(sc, asstr, strlen(asstr));
	data = readdata();

	return(data);
}

#ifdef JPIXDB
char *jpixroute(route)
char 	*route;
{
	struct hostent		*hp;
	struct sockaddr_in	sin;
	int			jisoc;
	FILE			*jifd;
	char			line[1024];
	char			*ptr;
	char			*retc;

	if ((hp = gethostbyname(JIWHOIS)) == NULL) {
		printf("%s Unknown Host. FATAL Error \n", JIWHOIS);
		exit(1);
	}

	if ((jisoc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		printf("Socket: FATAL Error\n");
		exit(2);
	}

	sin.sin_family	= AF_INET;
	sin.sin_port	= htons(STDWHOIS);
	bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

	if (connect(jisoc, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		printf("Client: Connect : FATAL Error\n");
		exit(3);
	}
#ifdef LOG
	connectlog(JIWHOIS);
#endif

	retc = (char *)malloc(STRBUFLEN);
	if (retc == NULL) {
		close(jisoc);
		return(NULL);
	}
	sprintf(line, "%s\n", route);
	write(jisoc,line,strlen(line));

	jifd = fdopen(jisoc, "r");
	strcpy(retc,"");
	while(!feof(jifd)) {
		fgets(line, 1024, jifd);
		if ((strstr(line, "route:") == &line[0]) ||
		    (strstr(line, "origin:") == &line[0])) {
			strcat(retc, line);
		}
		if (strstr(line, "\% No entries") == &line[0]) break;
		strcpy(line, "");
	}
	fclose(jifd);
	close(jisoc);

	if (strlen(retc) > 0) {
		return(retc);
	} else {
		return(NULL);
	}

}
#endif /* _JPIXDB */

int getas(addr, retas)
char *addr;
char *retas;
{
	char 	cmdstr[128];
	char	*data;
	char	*descs, *desce;
	int	flg;

#ifdef JPIXDB
	sprintf(cmdstr, "%s", addr);
#ifdef DEBUG
	printf("Command (JPIX): %s\n", cmdstr);
#endif
#endif
#ifndef JPIXDB
	sprintf(cmdstr, "!r%s/32,l\n", addr);
#ifdef DEBUG
	printf("Command: %s", cmdstr);
#endif
#endif


#ifdef JPIXDB
	data = jpixroute(addr);
#endif
#ifndef JPIXDB
	write(sc, cmdstr, strlen(cmdstr));
	data = readdata();
#endif

	strcpy(retas, "");
	if (data != NULL) {
		descs = data;
		while(*descs != '\0') {
			flg = 0;
			if (strstr(descs, "origin:") == descs) {
				descs += 7;
				while(1) {
					if ((*descs != ' ') && 
					    (*descs != '\t')) {
						break;
					}
					descs++;
				}
				descs += 2;
				desce = strchr(descs, '\n');
				flg = 1;
			} else if (strstr(descs, "route:") == descs) {
				descs += 6;
				while(1) {
					if ((*descs != ' ') && 
					    (*descs != '\t')) {
						break;
					}
					descs++;
				}
				desce = strchr(descs, '\n');
				flg = 2;
			} else if (strstr(descs, "*or:") == descs) {
				descs += 4;
				while(1) {
					if ((*descs != ' ') && 
					    (*descs != '\t')) {
						break;
					}
					descs++;
				}
				descs += 2;
				desce = strchr(descs, '\n');
				flg = 1;
			} else if (strstr(descs, "*rt:") == descs) {
				descs += 4;
				while(1) {
					if ((*descs != ' ') && 
					    (*descs != '\t')) {
						break;
					}
					descs++;
				}
				desce = strchr(descs, '\n');
				flg = 2;
			}
			if (desce != NULL) {
				*desce = '\0';
			}
			if (flg > 0) {
				strcat(retas, descs);
				switch(flg) {
				case 1:
					strcat(retas, " ");
					break;
				case 2:
					strcat(retas, ":");
					break;
				}
				descs = desce + 1;
			} else {
				descs++;
			}
			if (descs == NULL) break;
		}
#ifdef DEBUG
		printf("Searched Pairs:%s\n", retas);
#endif
		free(data);
	}

	if (strlen(retas) > 0) {
		return(1);
	} else {
		return(0);
	}
}

#ifdef JPNICDB
char *jpnic(asn, retc)
u_long 	asn;
char	*retc;
{
	struct hostent		*hp;
	struct sockaddr_in	sin;
	int			jpsoc;
	FILE			*jpfd;
	char			line[1024];
	char			*ptr;


	if ((hp = gethostbyname(JPWHOIS)) == NULL) {
		printf("%s Unknown Host. FATAL Error \n", JPWHOIS);
		exit(1);
	}

	if ((jpsoc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		printf("Socket: FATAL Error\n");
		exit(2);
	}

	sin.sin_family	= AF_INET;
	sin.sin_port	= htons(STDWHOIS);
	bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

	if (connect(jpsoc, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		printf("Client: Connect : FATAL Error\n");
		exit(3);
	}
#ifdef LOG
	connectlog(JPWHOIS);
#endif

	sprintf(line, "AS%d\n", asn);
	write(jpsoc,line,strlen(line));

	jpfd = fdopen(jpsoc, "r");
	while(!feof(jpfd)) {
		fgets(line, 1024, jpfd);
		if (strstr(line, "b. [") == &line[0]) break;
		if (strstr(line, "No match!!") == &line[0]) break;
		strcpy(line, "");
	}
	fclose(jpfd);
	close(jpsoc);

	if (strlen(line) > 38) {
		strcpy(retc, &line[38]);
		retc[strlen(retc)-1] = '\0';
		return(retc);
	} else {
		return(NULL);
	}

}
#endif /* _JPCNIDB_ */

#ifdef APNICDB
char *apnic(asn, retc)
u_long 	asn;
char	*retc;
{
	struct hostent		*hp;
	struct sockaddr_in	sin;
	int			apsoc;
	FILE			*apfd;
	char			line[1024];
	char			*ptr;


	if ((hp = gethostbyname(APWHOIS)) == NULL) {
		printf("%s Unknown Host. FATAL Error \n", APWHOIS);
		exit(1);
	}

	if ((apsoc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		printf("Socket: FATAL Error\n");
		exit(2);
	}

	sin.sin_family	= AF_INET;
	sin.sin_port	= htons(STDWHOIS);
	bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

	if (connect(apsoc, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		printf("Client: Connect : FATAL Error\n");
		exit(3);
	}
#ifdef LOG
	connectlog(APWHOIS);
#endif

	sprintf(line, "AS%d\n", asn);
	write(apsoc,line,strlen(line));

	apfd = fdopen(apsoc, "r");
	while(!feof(apfd)) {
		fgets(line, 1024, apfd);
		if (strstr(line, "descr:") == &line[0]) break;
		if (strstr(line, "No match!!") == &line[0]) break;
		strcpy(line, "");
	}
	fclose(apfd);
	close(apsoc);

	if (strlen(line) > 13) {
		strcpy(retc, &line[13]);
		retc[strlen(retc)-1] = '\0';
		return(retc);
	} else {
		return(NULL);
	}

}
#endif /* _APNICDB_ */

#ifdef ARINDB
char *arin(asn, retc)
u_long	asn;
char	*retc;
{
	struct hostent		*hp;
	struct sockaddr_in	sin;
	int			arinsoc;
	FILE			*arinfd;
	char			line[1024];
	char			*ptr;

	if ((hp = gethostbyname(ARINWHOIS)) == NULL) {
		printf("%s Unknown Host. FATAL Error\n", ARINWHOIS);
		exit(1);
	}

	if ((arinsoc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		printf("Socket: FATAL Error\n");
		exit(2);
	}

	sin.sin_family	= AF_INET;
	sin.sin_port	= htons(STDWHOIS);
	bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

	if (connect(arinsoc, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		printf("Client: Connect: FATAL Error\n");
		exit(3);
	}
#ifdef LOG
	connectlog(ARINWHOIS);
#endif

	sprintf(line, "as %d\r\n", asn);
	write(arinsoc, line, strlen(line));

	arinfd = fdopen(arinsoc, "r");
	while(!feof(arinfd)) {
		fgets(line, 1020, arinfd);
		if (strstr(line, "   Autonomous System Name:")
							 == &line[0]) break;
		strcpy(line, "");
	}
	fclose(arinfd);
	close(arinsoc);

	if (strlen(line) > 27) {
		strcpy(retc, &line[27]);
		retc[strlen(retc)-1] = '\0';
		return(retc);
	} else {
		return(NULL);
	}
}
#endif /* ARINDB */

#ifdef JPIXDB
char *jpix(asn, retc)
u_long 	asn;
char	*retc;
{
	struct hostent		*hp;
	struct sockaddr_in	sin;
	int			jisoc;
	FILE			*jifd;
	char			line[1024];
	char			*ptr;

	if ((hp = gethostbyname(JIWHOIS)) == NULL) {
		printf("%s Unknown Host. FATAL Error \n", JIWHOIS);
		exit(1);
	}

	if ((jisoc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		printf("Socket: FATAL Error\n");
		exit(2);
	}

	sin.sin_family	= AF_INET;
	sin.sin_port	= htons(STDWHOIS);
	bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

	if (connect(jisoc, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		printf("Client: Connect : FATAL Error\n");
		exit(3);
	}
#ifdef LOG
	connectlog(JIWHOIS);
#endif

	sprintf(line, "AS%d\n", asn);
	write(jisoc,line,strlen(line));

	jifd = fdopen(jisoc, "r");
	while(!feof(jifd)) {
		fgets(line, 1024, jifd);
		if (strstr(line, "descr:") == &line[0]) break;
		if (strstr(line, "\% No entries") == &line[0]) break;
		strcpy(line, "");
	}
	fclose(jifd);
	close(jisoc);

	if (strlen(line) > 13) {
		strcpy(retc, &line[13]);
		retc[strlen(retc)-1] = '\0';
		return(retc);
	} else {
		return(NULL);
	}

}
#endif /* _JPIXDB */

int searchas(aslist)
char *aslist;
{
	char	aslistbuf[1024];
	u_long	asnum;
	char	*asptr;
	char	*obj;
	char	*descs,*desce;
	char	asname[1024];

	strcpy(aslistbuf, aslist);
	asptr = strtok(aslistbuf, " \t.()[]_*^$+ie?\n\r");
	while(asptr != NULL) {
		asnum = atol(asptr);
#ifdef DEBUG
		printf("Searching AS : %d\n",asnum);
#endif

#ifndef JPIXDB
		obj = getasobj(asnum);
		if (obj != NULL) {
			descs = strstr(obj, "*de");
			if (descs == NULL) {
				descs = strstr(obj, "descr:");
				if (descs == NULL) {
#ifdef DEBUG
					printf("DEBUG: descr field not found\n");
#endif
					printf("  AS%d:????????\n", asnum);
				}
#ifdef DEBUG
				printf("DB Type -> RPSL?\n");
#endif
				descs += 6;
				/* Skip Space */
				while(1) {
					if ((*descs != ' ') &&
					    (*descs != '\t')) {
						break;
					}
					descs++;
				}
			} else {
#ifdef DEBUG
				printf("DB Type -> RIPE181?\n");
#endif
				descs += 3;
				/* Skip Space */
				while(1) {
					if ((*descs != ' ') &&
					    (*descs != '\t')) {
						break;
					}
					descs++;
				}
			}
			if (descs != NULL) {
				desce = strchr(descs, '\n');
				if (desce != NULL) {
					*desce = '\0';
				}
				printf("  AS%d:%s\n", asnum, descs);
			}
			free(obj);
		} else {
#endif /* _JPIXDB_ */

#ifdef JPIXDB
		if (jpix(asnum, &asname) != NULL) {
			printf("  AS%d:%s\n", asnum, asname);
		} else {
#endif
#ifdef ARINDB
			strcpy(asname, "");
			if (arin(asnum, &asname) != NULL) {
				int	fg;
				fg = 0;
#ifdef JPNICDB
				if (strcmp(asname, JPNICTAG) == 0) {
					if (jpnic(asnum, &asname) != NULL) {
						printf("  AS%d:%s (JPNIC)\n",
								 asnum, asname);
						fg = 1;
					} else {
						strcpy(asname, "");
					}
				}
#endif
#ifdef APNICDB
				if (strcmp(asname, APNICTAG) == 0) {
					if (apnic(asnum, &asname) != NULL) {
						printf("  AS%d:%s (APNIC)\n",
								 asnum, asname);
						fg = 1;
					} else {
						strcpy(asname, "");
					}
				}
#endif
				if (strlen(asname) != 0) {
					if (fg == 0) {
						printf("  AS%d:%s (ARIN)\n",
								 asnum, asname);
					}
				} else {
					printf("  AS%d:????????\n", asnum);
				}
			}
#endif /* ARINDB */
#ifndef ARINDB
#ifdef JPNICDB
#ifdef APNICDB
			if (jpnic(asnum, &asname) != NULL) {
				printf("  AS%d:%s (JPNIC)\n", asnum, asname);
			} else if (apnic(asnum, &asname) != NULL) {
				printf("  AS%d:%s (APNIC)\n", asnum, asname);
			} else {
				printf("  AS%d:????????\n", asnum);
			}
#endif
#endif

#ifdef JPNICDB
#ifndef APNICDB
			if (jpnic(asnum, &asname) != NULL) {
				printf("  AS%d:%s (JPNIC)\n", asnum, asname);
			} else {
				printf("  AS%d:????????\n", asnum);
			}
#endif
#endif

#ifndef JPNICDB
#ifdef APNICDB
			if (apnic(asnum, &asname) != NULL) {
				printf("  AS%d:%s (APNIC)\n", asnum, asname);
			} else {
				printf("  AS%d:????????\n", asnum);
			}
#endif
#endif

#ifndef JPNICDB
#ifndef APNICDB
			printf("  AS%d:????????\n", asnum);
#endif
#endif

#endif /* ARINDB */

		}
		asptr = strtok(NULL, " \t.()[]_*^$+ie?\n\r");
	}
}

int checkpath(data)
ASPATHCACHE *data;
{
	int		ret;
	ASPATHCACHE	*ptr,*bptr;

#ifdef DEBUG
	printf("Caching Path\n");
#endif
	ret = 0;
	ptr = head;
	bptr = NULL;
	while(ptr != NULL) {
		if (strcmp(ptr->pathstr, data->pathstr) == 0) {
#ifdef DEBUG
			printf("Duplicated Route Found\n");
#endif
			ret = 1;
			break;
		}
		bptr = ptr;
		ptr = ptr->next;
	}

	if (ret == 0) {
#ifdef DEBUG
		printf("Newly Path Found: %s\n",data->pathstr);
#endif
		ptr = (ASPATHCACHE *)malloc(sizeof(ASPATHCACHE));
		if (head == NULL) {
			head = ptr;
		} else {
			bptr->next = ptr;
		}
		ptr->next = NULL;
		strcpy(ptr->pathstr, data->pathstr);
		strcpy(ptr->data, data->data);
	}
	return(ret);
}

int freecache()
{
	ASPATHCACHE *ptr;

	ptr = head;
	while(ptr != NULL) {
		head = ptr->next;
		free(ptr);
		ptr = head;
	}
}

int parsestdin()
{

	char	line[2048];
	ASPATHCACHE	pathcache;
	char	olddata[40];
	char	buf[40];

	bzero(olddata, 40);
        bzero(buf,40);
	while(!feof(stdin)) {
		bzero(line, 2048);
		fgets(line, 2048, stdin);
		if (strlen(line) == 0) continue;
#ifdef DEBUG
		printf("Reading Data:%s",line);
#endif

		line[SKIP-1] = '\0';
		bzero(&pathcache, sizeof(ASPATHCACHE));
		strcpy(pathcache.data, line);
		strcpy(pathcache.pathstr, &line[SKIP]);
		pathcache.next = NULL;

		if (strncmp(&line[3], "       ", 7) == 0) {
#ifdef DEBUG
			printf("Old Data Concatinate\n");
#endif
			bzero(buf,40);
			strncpy(buf, pathcache.data, 3);
			strcat(buf, olddata);
			strcat(buf, &(pathcache.data[20]));
			strcpy(pathcache.data, buf);
		} else {
			bzero(olddata, 40);
			strncpy(olddata, &line[3], 17);
		}

		if (checkpath(&pathcache) == 0) {
			printf("%s:\n",pathcache.data);
			searchas(pathcache.pathstr);
		} else {
			printf("%s: Dplicated AS Path\n",pathcache.data);
		}
	}
	freecache();
}

int parsefile(fname)
char *fname;
{

	char	line[2048];
	FILE	*fp;
	ASPATHCACHE     pathcache;
	char    olddata[128];
	char    buf[128];

	if ((fp = fopen(fname, "r")) == NULL){
		printf("Could Not Open File : %s\n",fname);
		return(1);
	}

	bzero(olddata, 40);
        bzero(buf,40);
	while(!feof(fp)) {
		bzero(line, 2048);
		fgets(line, 2048, fp);
		if (strlen(line) == 0) continue;

		line[SKIP-1] = '\0';
                strcpy(pathcache.data, line);
                strcpy(pathcache.pathstr, &line[SKIP]);
                pathcache.next = NULL;

                if (strncmp(&line[3], "       ", 7) == 0) {
#ifdef DEBUG
                        printf("Old Data Concatinate: %s\n",olddata);
#endif
                        if (strlen(olddata) > 0) {
                                bzero(buf,40);
                                strncpy(buf, pathcache.data, 3);
                                strcat(buf, olddata);
                                strcat(buf, &(pathcache.data[20]));
                                strcpy(pathcache.data, buf);
                        }
                } else {
                        bzero(olddata, 40);
                        strncpy(olddata, &line[3], 17);
#ifdef DEBUG
                        printf("Change Old Data: %s\n",olddata);
#endif
                }
                if (checkpath(&pathcache) == 0) {
                        printf("%s:\n",pathcache.data);
                        searchas(pathcache.pathstr);
                } else {
                        printf("%s: Dplicated AS Path\n",pathcache.data);
                }
	}
	fclose(fp);
	freecache();
}

int host2as(hn)
char	*hn;
{
	char			getasnum[STRBUFLEN];
	char			asstr[1024];
	char			adstr[128];
	struct hostent		*hp;
	struct sockaddr_in	sin;
	int			a;
	int			asptr,stp;

#ifndef SOLARIS
	a = inet_aton(hn, &sin);
#endif
#ifdef SOLARIS
	sin.sin_addr.s_addr = inet_addr(hn);
#endif
	if (a == 0) {
		hp = gethostbyname(hn);
		if (hp == NULL) {
			printf("Could not resolv : %s\n",hn);
			return(1);
		}
		bzero(&sin, sizeof(struct sockaddr_in));
		bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
		sprintf(adstr, "%s", inet_ntoa(sin.sin_addr));
		printf("Target Address : %s(%s)\n",hn, adstr);
	} else {
#ifdef SOLARIS
		sprintf(adstr, "%s", inet_ntoa(sin.sin_addr));
#endif
#ifndef SOLARIS
		sprintf(adstr, "%s", inet_ntoa(sin));
#endif
		printf("Target Address : %s\n", adstr);
	}

#ifdef DEBUG
	printf("Host name : %s\n",hn);
	printf("Changed n : %s\n",adstr);
#endif

	if (getas(adstr, &getasnum) == 0) {
		printf("% Search Fail\n");
	} else {
#ifdef DEBUG
		printf("Search AS : %s\n",getasnum);
#endif
		asptr = 0;
		stp = 0;
		while(getasnum[asptr] != NULL) {
			switch(getasnum[asptr]) {
			case ':':
				getasnum[asptr] = '\0';
				printf("  %15s:",&getasnum[stp]);
				stp = asptr + 1;
				break;
			case ' ':
				getasnum[asptr] = '\0';
				searchas(&getasnum[stp]);
				stp = asptr + 1;
				break;
			}
			asptr++;
		}
	}
}


main(argc, argv)
int argc;
char *argv[];
{
	int	cnt;
	int	filtern;
	char	aslist[1024];


	if (argc > 1) {
		if (strcmp(argv[1], "-h") == 0) {
			printf("Usage: %s <AS List>\n",argv[0]);
			exit(0);
		}
		if (strcmp(argv[1], "-v") == 0) {
			printf("%s\n%s\n%s\n", 
				VERSION, COPYRIGHT, REVISION);
			exit(0);
		}
	}

	head = NULL;
#ifndef JPIXDB
	dbopen();
	batchmode();
#endif /* _JPIXDB */

	if (argc > 1) {
		if (strcmp(argv[1], "-r") == 0) {
			if (argc > 2) {
				host2as(argv[2]);
			} else {
				printf("Enough Parameter\n");
			}
			exit(0);
		} else if (argc > 2) {
			if (strcmp(argv[1], "-f") == 0) {
				parsefile(argv[2]);
			} else {
				bzero(aslist, 1024);
				for(cnt=1; cnt<argc; cnt++) {
					strcat(aslist, argv[cnt]);
					strcat(aslist, " ");
				}
				searchas(aslist);
			}
		} else {
			bzero(aslist, 1024);
			for(cnt=1; cnt<argc; cnt++) {
				strcat(aslist, argv[cnt]);
				strcat(aslist, " ");
			}
#ifdef DEBUG
			printf("AS Path List : %s\n",aslist);
#endif
			searchas(aslist);
		}
	} else {
		parsestdin();
	}

#ifndef JPIXDB
	dbclose();
#endif /* _JPIXDB */
}
