一个标题党,在第一个点一个很大的标题来吸引各位看官来。
其实原理很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文件:
最后的效果如图所看到的:
优化一下,区分链路的等级:
看到结果有点小小的激动。博主根本停不下来,又把小日本弄来玩了一把,奈何日本土地稀缺却网络发达,图像太拥挤很不利于观摩。上个图作为结尾吧
版权声明:本文博客原创文章。博客,未经同意,不得转载。