Skip to content

Instantly share code, notes, and snippets.

@noktoborus
Last active September 1, 2016 09:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noktoborus/9a4ee57ad818f6f42376b16c191395de to your computer and use it in GitHub Desktop.
Save noktoborus/9a4ee57ad818f6f42376b16c191395de to your computer and use it in GitHub Desktop.
/* vim: ft=c ff=unix fenc=utf-8
* file: s.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <regex.h>
#include <inttypes.h>
const char *in[] = {
/* 3 probes */
"traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 38 byte packets\n"
" 1 * 10.83.255.190 (10.83.255.190) 7.858 ms 10.957 ms\n"
" 2 lag-3-438.bgw01.spb.ertelecom.ru (109.195.88.30) 0.547 ms 0.645 ms 0.638 ms\n"
" 3 net131.234.188-158.ertelecom.ru (188.234.131.158) 0.683 ms 1.389 ms 0.811 ms\n"
" 4 net131.234.188-159.ertelecom.ru (188.234.131.159) 2.080 ms 1.539 ms 1.328 ms\n"
" 5 216.239.42.53 (216.239.42.53) 5.242 ms 5.177 ms 13.292 ms\n"
" 6 209.85.249.77 (209.85.249.77) 5.039 ms 209.85.240.79 (209.85.240.79) 5.405 ms 5.316 ms\n"
" 7 209.85.244.210 (209.85.244.210) 5.462 ms 209.85.251.36 (209.85.251.36) 6.172 ms 209.85.244.210 (209.85.244.210) 7.106 ms\n"
" 8 * * *\n"
" 9 * * *\n"
"10 * * *\n"
"11 * * *\n"
"12 * * *\n"
"13 * * *\n"
"14 * * *\n"
"15 * * *\n"
"16 google-public-dns-a.google.com (8.8.8.8) 5.149 ms 5.070 ms 5.086 ms\n",
/* 3 probes */
"traceroute to ya.ru (213.180.193.3), 30 hops max, 38 byte packets\n"
"1 10.83.255.190 (10.83.255.190) 640.623 ms 589.116 ms 719.537 ms\n"
"2 lag-3-438.bgw01.spb.ertelecom.ru (109.195.88.30) 0.599 ms 0.636 ms 0.608 ms\n"
"3 193-28-6-60.peering.pirix.ru (193.28.6.60) 0.777 ms 0.875 ms 1.024 ms\n"
"4 spb2-b1-ae0-601.yndx.net (37.140.137.94) 1.203 ms 1.250 ms 1.369 ms\n"
"5 m9-p2-100ge-2-0-3.yndx.net (213.180.213.16) 14.349 ms 10.441 ms 10.830 ms\n"
"6 fol5-c2-ae7.yndx.net (87.250.239.84) 8.660 ms 8.620 ms 8.601 ms\n"
"7 * www.yandex.ru (213.180.193.3) 8.694 ms *\n",
/* 1 probe per host */
"traceroute to ya.ru (213.180.204.3), 30 hops max, 38 byte packets\n"
" 1 10.83.255.190 (10.83.255.190) 13.467 ms\n"
" 2 lag-3-438.bgw01.spb.ertelecom.ru (109.195.88.30) 0.617 ms\n"
" 3 193-28-6-60.peering.pirix.ru (193.28.6.60) 0.873 ms\n"
" 4 spb2-b1-ae0-601.yndx.net (37.140.137.94) 1.249 ms\n"
" 5 m9-p2-100ge-2-0-3.yndx.net (213.180.213.16) 11.142 ms\n"
" 6 m9-p1-be6.yndx.net (87.250.239.51) 9.651 ms\n"
" 7 iva-b-c2-ae4.yndx.net (87.250.239.117) 9.586 ms\n"
" 8 *\n"
" 9 www.yandex.ru (213.180.204.3) 9.495 ms\n",
/* 2 probes per hsot */
"traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 38 byte packets\n"
" 1 10.83.255.190 (10.83.255.190) 1.238 ms 0.941 ms\n"
" 2 lag-3-438.bgw01.spb.ertelecom.ru (109.195.88.30) 0.638 ms 0.718 ms\n"
" 3 net131.234.188-158.ertelecom.ru (188.234.131.158) 0.717 ms 0.854 ms\n"
" 4 net131.234.188-159.ertelecom.ru (188.234.131.159) 1.924 ms 1.403 ms\n"
" 5 216.239.42.53 (216.239.42.53) 14.019 ms 5.724 ms\n"
" 6 209.85.249.79 (209.85.249.79) 5.081 ms 216.239.40.237 (216.239.40.237) 5.570 ms\n"
" 7 216.239.46.132 (216.239.46.132) 19.342 ms 216.239.47.137 (216.239.47.137) 16.796 ms\n"
" 8 * *\n"
" 9 * *\n"
"10 * *\n"
"11 * *\n"
"12 * *\n"
"13 * *\n"
"14 * *\n"
"15 * *\n"
"16 google-public-dns-a.google.com (8.8.8.8) 4.992 ms 5.136 ms\n",
NULL
};
void
regmatch_print(const char *in, regmatch_t *pmatch, size_t nmatch)
{
size_t n = 0u;
for (n = 0u; n < nmatch; n++) {
if (pmatch[n].rm_so == -1)
continue;
printf("%"PRIuPTR": m=%03d:%03d, l=%d, s=%.*s\n",
n, pmatch[n].rm_so, pmatch[n].rm_eo,
pmatch[n].rm_eo - pmatch[n].rm_so,
pmatch[n].rm_eo - pmatch[n].rm_so,
in + pmatch[n].rm_so);
}
}
struct HopHost {
char host[256];
char addr[256];
char times[16];
};
void
hh_print(struct HopHost *hh)
{
printf("{host='%s', addr='%s', times='%s'}\n",
hh->host, hh->addr, hh->times);
}
static inline bool
reg_isnull(regmatch_t *pmatch)
{
if (pmatch->rm_so == -1) {
return true;
}
return false;
}
void
tr_process(FILE *f)
{
int r = 0;
char l[1024] = {};
const char reg[] = "[[:space:]]*([0-9]*)[[:space:]]*"
/* first column */
"("
"\\*|"
"([-_0-9a-zA-Z\\.]+) \\(([0-9\\.]*)\\)[[:space:]]{1,}([0-9]*)[\\.0-9]* ms"
")[[:space:]]*"
/* second column */
"("
"\\*[[:space:]]+|"
"([-_0-9a-zA-Z\\.]+) \\(([0-9\\.]+)\\)[[:space:]]+([0-9]+)[\\.0-9]* ms[[:space:]]+|"
"([0-9]*)[\\.0-9]* ms[[:space:]]+"
")*"
/* third column */
"("
"\\*[[:space:]]*|"
"([-_0-9a-zA-Z\\.]+) \\(([0-9\\.]+)\\)[[:space:]]+([0-9]+)[\\.0-9]* ms[[:space:]]*|"
"([0-9]*)[\\.0-9]* ms[[:space:]]*"
")*"
"\n";
regex_t preg = {};
regmatch_t pmatch[34] = {};
size_t nmatch = sizeof(pmatch) / sizeof(*pmatch);
if ((r = regcomp(&preg, reg, REG_EXTENDED)) != 0) {
printf("regcomp(): %d\n", r);
return;
}
struct HopHost hh = {};
while (fgets(l, sizeof(l), f) != NULL) {
if (regexec(&preg, l, nmatch, pmatch, 0)) {
if (!strncmp("traceroute", l, 10)) {
/* skip header */
continue;
}
printf("line not matched: %.*s\n", *l ? ((int)strlen(l) - 1) : 0, l);
continue;
}
memset(&hh, 0, sizeof(hh));
/*
regmatch_print(l, pmatch, nmatch);
continue;
*/
/* first column */
if (reg_isnull(&pmatch[5])) {
/* no time */
strcat(hh.times, "*");
} else {
/* copy host */
snprintf(hh.host, sizeof(hh.host), "%.*s",
pmatch[3].rm_eo - pmatch[3].rm_so,
l + pmatch[3].rm_so);
/* copy addr */
snprintf(hh.addr, sizeof(hh.addr), "%.*s",
pmatch[4].rm_eo - pmatch[4].rm_so,
l + pmatch[4].rm_so);
/* copy time */
snprintf(hh.times, sizeof(hh.times),
"%.*s",
pmatch[5].rm_eo - pmatch[5].rm_so,
l + pmatch[5].rm_so);
}
for (r = 0; r < 2; r++) {
/* second, third, <n> column */
if (!reg_isnull(&pmatch[6 + 5 * r])) {
size_t len = 0u;
/* copy host && addr */
if (!*hh.host && !reg_isnull(&pmatch[7 + 5 * r])) {
snprintf(hh.host, sizeof(hh.host), "%.*s",
pmatch[7 + 5 * r].rm_eo - pmatch[7 + 5 * r].rm_so,
l + pmatch[7 + 5 * r].rm_so);
snprintf(hh.addr, sizeof(hh.addr), "%.*s",
pmatch[8 + 5 * r].rm_eo - pmatch[8 + 5 * r].rm_so,
l + pmatch[8 + 5 * r].rm_so);
}
/* copy time */
len = strlen(hh.times);
if (!reg_isnull(&pmatch[9 + 5 * r])) {
/* copy from 'host (addr) time' */
snprintf(hh.times + len, sizeof(hh.times) - len,
",%.*s",
pmatch[9 + 5 * r].rm_eo - pmatch[9 + 5 * r].rm_so,
l + pmatch[9 + 5 * r].rm_so);
} else if (!reg_isnull(&pmatch[10 + 5 * r])) {
/* copy from 'time' */
snprintf(hh.times + len, sizeof(hh.times) - len,
",%.*s",
pmatch[10 + 5 * r].rm_eo - pmatch[10 + 5 * r].rm_so,
l + pmatch[10 + 5 * r].rm_so);
} else {
snprintf(hh.times + len, sizeof(hh.times) - len, ",*");
}
}
}
hh_print(&hh);
}
regfree(&preg);
}
int
main(int argc, char *argv[])
{
FILE *f = NULL;
char *p = NULL;
int i = 0;
for (i = 0; in[i]; i++) {
f = fmemopen((void*)in[i], strlen(in[i]), "r");
if (!f) {
perror("fmemopen");
return EXIT_FAILURE;
}
tr_process(f);
fclose(f);
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment