ripe-atlas-cli ping 结果显示国标

从 ftp.ripe.net 下载 probes 存档,并使用 PHP 进行预处理:

<?php
ini_set("memory_limit", "-1");

function getFlags($code){
     if(strlen($str) != 2) return $str;

    $str = strtoupper($str);

    return mb_convert_encoding( '&amp;#' . ( 127397 + ord( $str[0] ) ) . ';', 'UTF-8', 'HTML-ENTITIES')
        . mb_convert_encoding( '&amp;#' . ( 127397 + ord( $str[1] ) ) . ';', 'UTF-8', 'HTML-ENTITIES');
}

$path = date("Y/m",strtotime("-1 day"));
$fileName = date("Ymd",strtotime("-1 day")) . ".json.bz2";
$jsonFileName = date("Ymd",strtotime("-1 day")) . ".json";
$fileUrl = "https://ftp.ripe.net/ripe/atlas/probes/archive/$path/$fileName";

echo $fileUrl . "\n";
if(file_exists($fileName)) {
    unlink($fileName);
}

echo "Retrieving http header...\n";
$header = get_headers($fileUrl);
$pp = "0";
echo json_encode($header, JSON_PRETTY_PRINT);
$key = key(preg_grep('/\bLength\b/i', $header));
$type = key(preg_grep('/\bType\b/i', $header));
$http = substr($header[0], 9, 3);
$tbytes = @explode(" ", $header[$key])[1];
$type = @explode("/", explode(" ", $header[$type])[1])[1];
echo " Target size: " . floor((($tbytes / 1000) / 1000)) . " Mo || " . floor(($tbytes / 1000)) . " Kb";
$remote = fopen($fileUrl, 'r');
$local = fopen($fileName, 'w');
$read_bytes = 0;
echo PHP_EOL;
while (!feof($remote)) {
    $buffer = fread($remote, intval($tbytes));
    fwrite($local, $buffer);
    $read_bytes += 2048;
    $progress = min(100, 100 * $read_bytes / $tbytes);
    $progress = substr($progress, 0, 6) * 4;
    $shell = 10; /* Progress bar width */
    $rt = $shell * $progress / 100;
    echo " \033[35;2m\e[0m Downloading: [" . round($progress, 3) . "%] " . floor((($read_bytes / 1000) * 4)) . "Kb ";
    if ($pp === $shell) {
        $pp = 0;
    };
    if ($rt === $shell) {
        $rt = 0;
    };
    echo str_repeat("█", $rt) . str_repeat("=", ($pp++)) . ">@\r";
    usleep(1000);
}
echo " \033[35;2m\e[0mDone [100%]  " . floor((($tbytes / 1000) / 1000)) . " Mo || " . floor(($tbytes / 1000)) . " Kb   \r";
echo PHP_EOL;
fclose($remote);
fclose($local);

echo 'bzip2 -d ' . $fileName . "\n";
system('bzip2 -d ' . $fileName);

echo "reading...\n";
$json = json_decode(file_get_contents($jsonFileName), true);
print_r($json['meta']);

$probes = [];
echo "convert...\n";
foreach ($json['objects'] as &amp;$item) {
    foreach ($item as $key => $value) {
        if(!in_array($key, ['id', 'address_v4', 'address_v6', 'asn_v4', 'asn_v6', 'country_code'])){
            unset($item[$key]);
        }

        if($key == 'country_code') {
            $item[$key] = getFlags($item[$key]) . "  " . $item[$key];
        }
    }

    $probes[$item['id']] = $item;
}

echo "write file: probes.json\n";
$json = json_encode($probes); //, JSON_PRETTY_PRINT);
file_put_contents("probes.json", $json);

echo "done.\n";



修改 ripe\atlas\tools\renderers\ping.py 文件,加入 JSON 解析:

# Copyright (c) 2016 RIPE NCC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

from .base import Renderer as BaseRenderer
import json
import io
class Renderer(BaseRenderer):

    RENDERS = [BaseRenderer.TYPE_PING]

    def on_result(self, result):

        packets = result.packets

        if not packets:
            return "No packets found\n"

        # Because the origin value is more reliable as "from" in v4 and as
        # "packet.source_address" in v6.
        origin = result.origin
        if ":" in origin:
            origin = packets[0].source_address

        f = io.open('/path/to/probes.json','r',encoding='utf-8')
        probes = json.load(f)
        # line = "{} bytes from probe #{:<5} {:15} to {} ({}): ttl={} times:{}\n"
        line = "{} bytes from probe #{:<6}{:<8} {:15} to {} ({}): ttl={} times:{}\n"
        return line.format(
            result.packet_size,
            str(result.probe_id),
            probes[str(result.probe_id)]['country_code'],
            origin,
            result.destination_name,
            result.destination_address,
            packets[0].ttl,
            " ".join(["{:8}".format(str(_.rtt) + ",") for _ in packets])
        )


顺便说几句,RIPE 全网 Probes 30885 个,已连接 9347 个,可供 ICMP 测试的 6096 个。中国的一共 118 个截止目前已连接的才 21 个

可供 ICMP 测试(system-ipv4-works)稳定在线 1 天(system-ipv4-stable-1d 24*5%=1.2h/d)及以上的有 5 个,30 天及以上的只有 2 个(system-ipv4-stable-30d 30*24*5%=36h/m)。

关于 tags 描述可以看这里,国际互联网链接质量堪忧啊……?

根据朋友描述,申请硬件 Probe 不是很容易,而且因为是平邮,即使在地址上写明手机号,也不一定会收到……

但目前 RIPE 提供了软件 Probes,申请还是比较容易的,之前申请被拒的可以考虑申请软件版本。

软件 Probes 对 CentOS 7 提供了 rpm 的安装方式,其他系统需要自行编译安装或者使用 Docker 运行。
申请地址:
https://labs.ripe.net/Members/alun_davies/ripe-atlas-software-probes

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据