From 52bca474a6122d4130a15199afc37f622a71f466 Mon Sep 17 00:00:00 2001 From: Christoffer Date: Fri, 14 Dec 2018 13:05:20 +0000 Subject: [PATCH] Updated roagen script to be able to capture and use max-length value --- roagen.php | 357 +++++++++++++++++++++++++++++------------------------ 1 file changed, 196 insertions(+), 161 deletions(-) diff --git a/roagen.php b/roagen.php index 21e61e3..ad64699 100755 --- a/roagen.php +++ b/roagen.php @@ -5,196 +5,231 @@ echo shell_exec("/usr/bin/git -C ../registry/ pull origin master:master 2>&1"); /* * Function: - * startsWith( $string, 'word') + * startsWith ($string, "word", $length) * - * Find lines beginning with 'word'. + * Find lines beginning with "word". Optionally + * give the length of the string you are looking for. */ -function startsWith($haystack, $needle) +function startsWith ($haystack, $needle, $length = "0") { - $length = strlen($needle); - return (substr($haystack, 0, $length) === $needle); + if ($length <= 0 || $length > (strlen ($needle))) + $length = strlen ($needle); + + return (substr ($haystack, 0, $length) === $needle); } /* * Function: - * endsWith( $string, 'word') + * endsWith ($string, "word") * - * Find lines ending with 'word'. + * Find lines ending with "word". */ -function endsWith($haystack, $needle) +function endsWith ($haystack, $needle) { - $length = strlen($needle); - if ($length == 0) { - return true; - } + $length = strlen ($needle); - return (substr($haystack, -$length) === $needle); + if ($length == 0) + return true; + + return (substr( $haystack, -$length) === $needle); } -// Create empty array $roas +/* + * Function: + * trim_special_chars ($string) + * + * Remove special characters. + */ +function trim_special_chars ($string) +{ + return (trim ($string, " \t\n\r\0\x0B")); +} + +// Define array() we are going to populate with data. $roas = array(); +// Set folders we need to scan. +$files6 = scandir("../registry/data/route6/"); +$files4 = scandir("../registry/data/route/"); + /* * - * IPv6 route objects + * IPv6 * */ -// Set directory for which all files are to be scanned -$files = scandir('../registry/data/route6/'); - -$h = 0; // count up when reading new file -$i = 0; // used when loop through sub-arrays. I.e. when route objects have more than one listed origin asn - -foreach($files as $file) +$i = 0; // Counter used with tmp $raw_array. +$raw_array = array(); // tmp array() used for storing data to be processed +foreach ($files6 as $file) { - $handle = fopen("../registry/data/route6/$file", "r"); - while (($line = fgets($handle)) !== false) { - // extract var $ta - if (startsWith($line,'source')) { - $source = array(); - preg_match('/([A-Z0-4]+)/',explode(':', $line)[1], $source); - $ta = $source[1]; - } - // extract var $route - // extract var $maskLength - if (startsWith($line,'route6')) { - $prefix = array(); - $line2 = explode('6: ', $line); - // validate v6 netmasks with following cmd - // cmd: ls -1 ../registry/data/route6/ | egrep -o "\b\_[0-9]+\b" | sed 's/\_//' | sort -n | uniq - preg_match('/([a-f0-9\:]{0,128})\/(32|40|4[4-9]|5[0-9]|6[0-4]|80)/', $line2[1], $prefix); - $route = $prefix[0]; - $mask = $prefix[2]; - } - // extract var $maxLength - /*if (startsWith($line,'max-length')) { - $maxLength = array(); - preg_match('/([0-9]+)/',explode(':', $line)[1], $maxLength); - $maxLength = $maxLength[1]; - } else { - $maxLength = ''; - }*/ - // extract var $asn - if (startsWith($line, 'origin')) { - $asn = array(); - preg_match('/AS[0-9]+/', explode(':', $line)[1], $asn); - if (count($asn) > 1) { - foreach ($asn as $key => $value) { - if (!empty($value)) { - $roas['roas'][$i]['asn'] = $asn[0]; - $roas['roas'][$i]['prefix'] = $route; - /*if (isset($ta)) { - if ($ta == 'DN42') { - $mask = ($mask <= 64 ? '64' : $mask); - if ($maxLength != '') $mask = $maxLength; - } - } else { - $ta = 'NULL'; - }*/ - $roas['roas'][$i]['maxLength'] = $mask; - $roas['roas'][$i]['ta'] = (empty($ta) ? '' : $ta); - $i++; - } - } - } else { - $roas['roas'][$i]['asn'] = $asn[0]; - $roas['roas'][$i]['prefix'] = $route; - /*if (isset($ta)) { - if ($ta == 'DN42') { - $mask = ($mask <= 64 ? '64' : $mask); - if ($maxLength != '') $mask = $maxLength; - } - } else { - $ta = 'NULL'; - }*/ - $roas['roas'][$i]['maxLength'] = $mask; - $roas['roas'][$i]['ta'] = (empty($ta) ? '' : $ta); - $i++; - } - } - } - fclose($handle); // close $file when finished reading data - $h++; + $j = 0; + + /* + * route6 with maxLength value set: + * - fd42:5d71:219::/48 + * + * $ cat ../registry/data/route6/fd42:5d71:219::_48 + * route6: fd42:5d71:219::/48 + * origin: AS4242420119 + * max-length: 48 + * mnt-by: JRB0001-MNT + * source: DN42 + */ + + $data = file("../registry/data/route6/$file"); + + foreach ($data as $str) + { + $str = trim_special_chars ($str); + + if (startsWith ($str, ("max"), 3)) $raw_array[$i]["max"] = $str; + elseif (startsWith ($str, ("source"), 6)) $raw_array[$i]["source"] = $str; + elseif (startsWith ($str, ("route"), 5)) $raw_array[$i]["route"] = $str; + elseif (startsWith ($str, ("origin"), 6)) $raw_array[$i]["asn"][$j++] = $str; + + // Catch max-length not set in route object. + if (empty ($raw_array[$i]["max"])) $raw_array[$i]["max"] = -1; + } + $i++; +} + +$k = 0; + +foreach ($raw_array as $sub_array) +{ + // Extract prefix and subnet size + // Match prefix sizes 29-64, 80. + $prefix = array(); + preg_match("/([a-f0-9\:]{0,128})\/(29|[3-5][0-9]|6[0-4]|80)/", + explode("6: ", $sub_array["route"])[1], + $prefix); + + // Extract ta information + $source = array(); + preg_match ("/([A-Z0-4]+)/", + explode(":", $sub_array["source"])[1], + $source); + + // Try to extract max-length information + $maxlength = array(); + if (($sub_array["max"]) != -1) + preg_match ("/([0-9]+)/", + explode(":", $sub_array["max"])[1], + $maxlength); + + // Store extracted values + $_prefix = $prefix[0]; + $_ta = (isset ($source[0]) ? $source[0] : ""); + // We need to do conditional setting of maxLength to avoid errornous output. + if (($sub_array["max"]) != -1) + $_maxlength = (isset ($maxlength[0]) ? $maxlength[0] : ""); + else + // Do fallback to default prefix size if max-length was not set. + $_maxlength = $prefix[2]; + + // Loop through each asn in single route6 object and assign + // other values accordingly. + foreach ($sub_array["asn"] as $asn) + { + // Extract ASxxxxx from string. + preg_match ("/AS[0-9]+/", explode (":", $asn)[1], $_asn); + + $roas["roas"][$k]["asn"] = $_asn[0]; + $roas["roas"][$k]["prefix"] = $_prefix; + $roas["roas"][$k]["maxLength"] = $_maxlength; + $roas["roas"][$k]["ta"] = $_ta; + + $k++; + } } /* * - * IPv4 route objects + * IPv4 * */ -// Set directory for which all files are to be scanned -$files = scandir('../registry/data/route/'); - -foreach($files as $file) +$i = 0; // Counter used with tmp $raw_array. +$raw_array = array(); // tmp array() used for storing data to be processed +foreach ($files4 as $file) { - $handle = fopen("../registry/data/route/$file", "r"); - while (($line = fgets($handle)) !== false) { - // extract var $ta - if (startsWith($line,'source')) { - $source = array(); - preg_match('/([A-Z0-4]+)/',explode(':', $line)[1], $source); - $ta = $source[1]; - } - // extract var $route - // extract var $maskLength - if (startsWith($line,'route')) { - $prefix = array(); - preg_match('/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(3[0-2]|[0-2]?[0-9])/', explode(':', $line)[1], $prefix); - $route = $prefix[0]; - $mask = $prefix[5]; - } - // extract var $maxLength - /*$maxLength = ''; // ensure var is null when starting new loop - if (startsWith($line,'max-length')) { - $maxLength = array(); - preg_match('/([0-9]+)/',explode(':', $line)[1], $maxLength); - $maxLength = $maxLength[1]; - } else { - $maxLength = ''; - }*/ - // extract var $asn - if (startsWith($line, 'origin')) { - $asn = array(); - preg_match('/AS[0-9]+/', explode(':', $line)[1], $asn); - if (count($asn) > 1) { - foreach ($asn as $key => $value) { - if (!empty($value)) { - $roas['roas'][$i]['asn'] = $asn[0]; - $roas['roas'][$i]['prefix'] = $route; - /*if (isset($ta)) { - if ($ta == 'DN42') { - $mask = ($mask <= 28 ? '28' : $mask); - if ($maxLength != '') $mask = $maxLength; - } - } else { - $ta = 'NULL'; - }*/ - $roas['roas'][$i]['maxLength'] = $mask; - $roas['roas'][$i]['ta'] = (empty($ta) ? '' : $ta); - $i++; - } - } - } else { - $roas['roas'][$i]['asn'] = $asn[0]; - $roas['roas'][$i]['prefix'] = $route; - /*if (isset($ta)) { - if ($ta == 'DN42') { - $mask = ($mask <= 28 ? '28' : $mask); - if ($maxLength != '') $mask = $maxLength; - } - } else { - $ta = 'NULL'; - }*/ - $roas['roas'][$i]['maxLength'] = $mask; - $roas['roas'][$i]['ta'] = (empty($ta) ? '' : $ta); - $i++; - } - } - } - fclose($handle); // close $file when finished reading data - $h++; + $j = 0; + + /* + * route with maxLength value set: + * - 172.20.1.0/24 + * + * $ cat ../registry/data/route/172.20.1.0_24 + * route: 172.20.1.0/24 + * origin: AS4242420119 + * max-length: 24 + * mnt-by: JRB0001-MNT + * source: DN42 + */ + + $data = file("../registry/data/route/$file"); + + foreach ($data as $str) + { + $str = trim_special_chars ($str); + + if (startsWith ($str, ("max"), 3)) $raw_array[$i]["max"] = $str; + elseif (startsWith ($str, ("source"), 6)) $raw_array[$i]["source"] = $str; + elseif (startsWith ($str, ("route"), 5)) $raw_array[$i]["route"] = $str; + elseif (startsWith ($str, ("origin"), 6)) $raw_array[$i]["asn"][$j++] = $str; + + // Catch max-length not set in route object. + if (empty ($raw_array[$i]["max"])) $raw_array[$i]["max"] = -1; + } + $i++; +} + +foreach ($raw_array as $sub_array) +{ + // Extract prefix and subnet size + // Match prefix sizes 8-32. + $prefix = array(); + preg_match("/([0-9\.]{7,15})\/([8-9]|[1-2][0-9]|3[0-2])/", + explode(":", $sub_array["route"])[1], + $prefix); + + // Extract ta information + $source = array(); + preg_match ("/([A-Z0-4]+)/", + explode(":", $sub_array["source"])[1], + $source); + + // Try to extract max-length information + $maxlength = array(); + if (($sub_array["max"]) != -1) + preg_match ("/([0-9]+)/", + explode(":", $sub_array["max"])[1], + $maxlength); + + // Store extracted values + $_prefix = $prefix[0]; + $_ta = (isset ($source[0]) ? $source[0] : ""); + // We need to do conditional setting of maxLength to avoid errornous output. + if (($sub_array["max"]) != -1) + $_maxlength = (isset ($maxlength[0]) ? $maxlength[0] : ""); + else + // Do fallback to default prefix size if max-length was not set. + $_maxlength = $prefix[2]; + + // Loop through each asn in single route6 object and assign + // other values accordingly. + foreach ($sub_array["asn"] as $asn) + { + // Extract ASxxxxx from string. + preg_match ("/AS[0-9]+/", explode (":", $asn)[1], $_asn); + + $roas["roas"][$k]["asn"] = $_asn[0]; + $roas["roas"][$k]["prefix"] = $_prefix; + $roas["roas"][$k]["maxLength"] = $_maxlength; + $roas["roas"][$k]["ta"] = $_ta; + + $k++; + } } // Do JSON encoding before writing result to file