• 教你绘制整个越南骨干路由拓扑每分钟


    一个标题党,在第一个点一个很大的标题来吸引各位看官来。

    其实原理很easy,我们的工作就是做一些数据的处理,最后生成kml剧本是现在Google Earth上。

    进入专题:

    首先数据源http://www.caida.org .这是一个英特网数据分析的合作组织,数据比較权威,全球非常多网络方面的科研数据都来源于此。

    而对本文实用的信息在这里:http://www.caida.org/data/internet-topology-data-kit/  这里面是一些英特网的拓扑信息数据。并且每半年左右都在更新。

    就从这里获取最新的版本号:


    进去之后到这个地方:http://data.caida.org/datasets/topology/ark/ipv4/itdk/2011-10/  如图所看到的:



    数据分为两组,是用不同的工具和探測方式获得的。各自是增加使用kapar和不增加。两组数据的差别在于前者更为详尽,而后者更精确。

    详细探測原理等能够在caida上找到。

    我以不加入kapar工具获取的数据为样例。

    数据一共同拥有三个文件,当中以.links结尾的路径数据,以.nodes结尾的是节点路由数据,以.nodes.geo结尾的是地理位置数据。

    详细的格式等能够见以下的图:


    上图是路径数据的文件截图。第一二列是路径的编号。后面N开头的一串数字路由器的编号,后面假设接有IP地址,则是它在路径上的出口,没有即为该接口数据未被探測到。

    于是一行数据就代表了一条网络层的路径,每一个带编号的路由器就是位于其上的节点。

    上图是地理位置文件截图。每一行列出了每一个被探測到的路由器的地理位置信息。包含国家,地区。城市,经纬度等


    上图是路由器节点数据文件的截图,每一行标识出了每一个路由器上的接口的IP地址。


    接下来。进行数据处理。思路是,先从地理位置文件把属于越南的路由器筛选出来。

    然后把这些路由器代入到路径文件中去查找,选出满足条件的路径。最后把这些路由器和路径写入到KML脚本里。用Google Earth读取就可以。


    写了一个筛选的小程序,把这个过程泛化了一下,能够实现对不论什么一个国家拓扑脚本的生成。为了赶进度,代码有点乱。。。看官们勿怪。。

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    
    #define MAX_LINE_SIZE	512 
    #define MAX_CITY_NUM	1200 
    #define MAX_ROUTE_NUM	100000 
    
    typedef struct Route_info{
    //	char fileinfo[10];
    	char route_id[10];
    //	char continent[5];
    	char country[5];
    //	char region[6];
    	char city[25];
    	float latitude;
    	float longtitude;
    }Route_info;
    
    typedef struct Location {
    	float latitude;
    	float longtitude;
    }Location;
    
    char city_list[MAX_CITY_NUM][25];
    int current_citynum = 0;
    
    Route_info routeinfo_set[MAX_ROUTE_NUM];  //route_id include character ':'
    int routeinfo_index = 0;
    
    Location location_set[MAX_CITY_NUM];
    int location_index = 0;
    
    int get_line(int *fd, char* line_buf, int line_size)
    {
    	int a, i = 0;
    	memset(line_buf, 0, MAX_LINE_SIZE);
    	while (((a = getchar()) != '
    ' && a != EOF) && i < line_size-2) //mark
    		line_buf[i++] = a;
    
    	line_buf[i] = '
    '; //add 
     to process data convinently
    	if (a == -1)
    		return 0;
    	else
    		return i+1;  //include 
    
    }
    
    int read_raw_linkfile(char *postfix)
    {
    	int fd_in, fd_out, line_size;
    	char line_buf[MAX_LINE_SIZE], outfile_name[20];
    	if ((fd_in = open("./midar-iff.links.in", O_RDONLY)) == -1) {
    		perror("Fail to open:");
    		return 0;
    	}
    
    	memset(outfile_name, 0, 20);
    	strcpy(outfile_name, "link.");
    	strcat(outfile_name, postfix);
    
    	if ((fd_out = open(outfile_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
    		perror("Fail to open:");
    		return 0;
    	}
    	dup2(fd_in, STDIN_FILENO);
    	
    	printf("fetching %s's link data...
    ", postfix);
    	while (line_size = get_line(STDIN_FILENO, line_buf, MAX_LINE_SIZE))
    	{
    		if (line_buf[0] == '#')
    			continue;
    		if (check_link(line_buf))
    			write(fd_out, line_buf, line_size);
    	}
    
    	close(fd_in);
    	close(fd_out);
    	return 1;
    }
    
    void get_location(char *line_buf)
    {
    	char *ptr = line_buf;
    	int len = strlen(line_buf);
    	ptr += (len - 2);
    	while ((*ptr >= 48 && *ptr <= 57) || *ptr == '	' || *ptr == '.' /*|| *ptr == 32*/) ptr--;
    	ptr++; //mark
    	sscanf(ptr, "%f %f", &location_set[location_index].latitude, &location_set[location_index].longtitude);
    	location_index++;
    }
    
    void get_routeinfo(char *line_buf)
    {
    	char id_tmp[10], *ptr;
    	memset(id_tmp, 0, 10);
    	sscanf(line_buf, "%*s %s", routeinfo_set[routeinfo_index].route_id);
    
    
    	/* drop char ':' */
    	//for (ptr = id_tmp; *ptr != ':'; ptr++);
    //	memcpy(routeinfo_set[routeinfo_index].route_id, id_tmp, ptr - id_tmp);
    
    	ptr = line_buf;
    	int len = strlen(line_buf);
    	ptr += (len - 2);
    	while ((*ptr >= 48 && *ptr <= 57) || *ptr == '	' || *ptr == '.' ) ptr--;
    	ptr++; //mark
    	sscanf(ptr, "%f %f", &routeinfo_set[routeinfo_index].latitude, &routeinfo_set[routeinfo_index].longtitude);
    	routeinfo_index++;
    }
    
    int read_raw_routefile(char *postfix)
    {
    	int fd_in, fd_out, fd_out_norep, line_size;
    	char line_buf[MAX_LINE_SIZE], outfile_name[20], outfilenorep_name[20];
    	if ((fd_in = open("./midar-iff.nodes.geo.in", O_RDONLY)) == -1) {
    		perror("Fail to open:");
    		return 0;
    	}
    
    	memset(outfile_name, 0, 20);
    	strcpy(outfile_name, "route.");
    	strcat(outfile_name, postfix);
    
    	memset(outfilenorep_name, 0, 20);
    	strcpy(outfilenorep_name, "route_city.");
    	strcat(outfilenorep_name, postfix);
    
    	if ((fd_out = open(outfile_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
    		perror("Fail to open:");
    		return 0;
    	}
    
    	if ((fd_out_norep = open(outfilenorep_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
    		perror("Fail to open:");
    		return 0;
    	}
    
    	dup2(fd_in, STDIN_FILENO);
    	
    	Route_info rinfo;
    	while (line_size = get_line(STDIN_FILENO, line_buf, MAX_LINE_SIZE))
    	{
    		if (line_buf[0] == '#')
    			continue;
    		memset((char*)&rinfo, 0, sizeof(Route_info));
    		sscanf(line_buf, "%*s %s %*s %s %*s %s 	%f %f", rinfo.route_id, rinfo.country, rinfo.city, &rinfo.latitude, &rinfo.longtitude);
    		if (!strcmp(rinfo.country, postfix)) {
    			if (!check_cityrepeatition(rinfo.city)) {
    				write(fd_out_norep, line_buf, line_size);
    				get_location(line_buf);
    			}
    
    			get_routeinfo(line_buf);
    			//strcpy(route_list[current_routenum++], rinfo.route_id);
    			write(fd_out, line_buf, line_size);
    		}
    	}
    
    	close(fd_in);
    	close(fd_out);
    	return 1;
    }
    
    
    void print_locationset()
    {
    	int i;
    	for (i = 0; i < location_index; i++)
    		printf("%f %f
    ",location_set[i].latitude, location_set[i].longtitude);
    }
    void print_routeinfoset()
    {
    	int i;
    	for (i = 0; i < routeinfo_index; i++)
    		printf("%s %f %f
    ", routeinfo_set[i].route_id, routeinfo_set[i].latitude, routeinfo_set[i].longtitude);
    }
    /* drop the repeative city */
    int check_cityrepeatition(char *city)
    {
    	int i;
    	for (i = 0; i < current_citynum; i++)
    	{
    		if (!strcmp(city, city_list[i]))
    			return 1;
    	}
    
    	strcpy(city_list[current_citynum++], city);
    	return 0;
    }
    
    /* at least two adjacent route on the link */
    int check_link(char *line_buf)
    {
    	char *ptr = line_buf, route_id[10], *tmp;
    	int i, pre_flag = 0;
    	while (*ptr != '
    ' && *ptr != EOF)
    	{
    		memset(route_id, 0, 10*sizeof(char));
    		ptr = strchr(ptr, 'N');
    		if (!ptr)
    			break;
    		tmp = ptr;
    		while (*tmp != ' ' && *tmp != ':' && *tmp != '
    ') tmp++;
    		for (i = 0; (ptr + i) < tmp; i++)
    			route_id[i] = *(ptr+i);
    		route_id[i] = ':';          //match the format
    		if (check_route(route_id)) {
    			if (pre_flag)
    				return 1;
    			else 
    				pre_flag = 1;
    
    		}
    		else 
    			pre_flag = 0;
    		ptr = tmp;
    	}
    	return 0;
    }
    
    int check_route(char *route_id) 
    {
    	int i;
    	for (i = 0; i < routeinfo_index; i++)
    		if (!strcmp(routeinfo_set[i].route_id, route_id)) {
    			return 1;
    		}
    	return 0;
    }
    
    void draw_route(char *kmlfile_name)
    {
    	int i, fd_out;
    	char buf[1024];
    
    	if ((fd_out = open(kmlfile_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
    		perror("Fail to open:");
    		return;
    	}
    	printf("generate the routes kml file...
    ");
    
    	memset(buf, 0, 1024);
    	sprintf(buf, "<Document>
    <Style id="icon_style">
    <IconStyle>
    <Icon>
    <href>juanjo_Router.png</href>
    </Icon>
    <scale>0.8</scale>
    </IconStyle>
    </Style>
    ");
    	write(fd_out, buf, strlen(buf));
    	memset(buf, 0, 1024);
    
    	for (i = 0; i < location_index; i++)
    	{
    		sprintf(buf, "<Placemark>
    <styleUrl>#icon_style</styleUrl>
    <Point>
    <coordinates>%f,%f,0</coordinates>
    </Point>
    </Placemark>
    ", location_set[i].longtitude, location_set[i].latitude);
    		write(fd_out, buf, strlen(buf));
    		memset(buf, 0, 1024);
    	}
    
    	close(fd_out);
    }
    
    
    void get_routeloca(char *route_id, float* lati, float* longti)
    {
    	int i;
    	for (i = 0; i < routeinfo_index; i++)
    		if (!strcmp(routeinfo_set[i].route_id, route_id)) {
    			*lati = routeinfo_set[i].latitude;
    			*longti = routeinfo_set[i].longtitude;
    			return;
    		}
    }
    
    void get_endofline(char*line_buf, float* start_la, float* start_long, float* end_la, float* end_long)
    {
    	char *ptr = line_buf, route_id[10], *tmp;
    	int i, pre_flag = 0;
    	while (*ptr != '
    ' && *ptr != EOF)
    	{
    		memset(route_id, 0, 10*sizeof(char));
    		ptr = strchr(ptr, 'N');
    		if (!ptr)
    			break;
    		tmp = ptr;
    		while (*tmp != ' ' && *tmp != ':' && *tmp != '
    ') tmp++;
    		for (i = 0; (ptr + i) < tmp; i++)
    			route_id[i] = *(ptr+i);
    		route_id[i] = ':';          //match the format
    		if (check_route(route_id)) {
    			if (pre_flag) {
    				get_routeloca(route_id, end_la, end_long);
    				return ;
    			}
    			else {
    				get_routeloca(route_id, start_la, start_long);
    				pre_flag = 1;
    			}
    		}
    		else 
    			pre_flag = 0;
    		ptr = tmp;
    	}
    	return ;
    }
    
    void draw_line(char* postfix, char *kmlfile_name)
    {
    	int fd_in, fd_out, line_size;
    	char file_name[20], buf[1024], line_buf[MAX_LINE_SIZE];
    	Location start, end;
    
    	memset(file_name, 0, 20);
    	strcpy(file_name, "link.");
    	strcat(file_name, postfix);
    
    	if ((fd_in = open(file_name, O_RDONLY)) == -1) {
    		perror("Fail to open:");
    		return ;
    	}
    
    	if ((fd_out = open(kmlfile_name, O_RDWR | O_APPEND)) == -1) {
    		perror("Fail to open:");
    		return ;
    	}
    
    	dup2(fd_in, STDIN_FILENO);
    	
    	printf("generate the link between routes...
    ");
    
    	sprintf(buf, "<Style id="color_line">
    <LineStyle>
    <color>ff00FF00</color>
    <width>2</width>
    </LineStyle>
    </Style>
    ");
    	write(fd_out, buf, strlen(buf));
    	memset(buf, 0, 1024);
    
    	while (line_size = get_line(STDIN_FILENO, line_buf, MAX_LINE_SIZE))
    	{
    		get_endofline(line_buf, &start.latitude, &start.longtitude, &end.latitude, &end.longtitude);
    		sprintf(buf, "<Placemark>
    <styleUrl>#color_line</styleUrl>
    <LineString>
    <extrude>0</extrude>
    <tessellate>1</tessellate>
    <altitudeMode>clampToGround</altitudeMode>
    <coordinates>
    %f,%f,0
    %f,%f,0
    </coordinates>
    </LineString>
    </Placemark>
    ", start.longtitude, start.latitude, end.longtitude, end.latitude);
    		write(fd_out, buf, strlen(buf));
    		memset(buf, 0, 1024);
    	}
    
    	sprintf(buf, "</Document>
    ");
    	write(fd_out, buf, strlen(buf));
    
    	printf("Success to generate the %s's kml files
    ", postfix);
    	close(fd_in);
    	close(fd_out);
    }
    
    int main(int argc, char* argv[])
    {
    	if (argc != 2) {
    		printf("Usage: ./<pram> <country_name>");
    		return 1;
    	}
    
    	char kmlfile_name[20];
    
    	memset(kmlfile_name, 0, 20);
    	strcpy(kmlfile_name, argv[1]);
    	strcat(kmlfile_name, ".kml");
    	
    
    	if (read_raw_routefile(argv[1]))
    		printf("Success to read %s's data from raw route data file
    ", argv[1]);
    
    	print_locationset();
    
    	print_routeinfoset();
    
    	draw_route(kmlfile_name);
    
    	if (read_raw_linkfile(argv[1]))
    		printf("Success to read %s's data from raw link data file
    ", argv[1]);
    
    	draw_line(argv[1], kmlfile_name);
    	return 0;
    }

    程序运行有生成两个暂时的文件,各自是过滤出的国家的路由和链路。如图,越南的数据例如以下:





    终于得到KML文件:


    最后的效果如图所看到的:


    优化一下,区分链路的等级:


    看到结果有点小小的激动。博主根本停不下来,又把小日本弄来玩了一把,奈何日本土地稀缺却网络发达,图像太拥挤很不利于观摩。上个图作为结尾吧


    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    gps示例代码
    UART 串口示例代码
    Linux soft lockup 和 hard lockup
    Linux嵌入式kgdb调试环境搭建
    Linux嵌入式GDB调试环境搭建
    Linux-workqueue讲解
    USB之hub3
    USB之设备插入波形变化2
    我运营公众号这一个月
    从12306帐号泄漏谈用户密码安全
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4671154.html
Copyright © 2020-2023  润新知