////////////////////////////////////////////////////////////////////// // IP traffic analyzer - data objects // Written by Jonathan A. Foster // Started April 23rd, 2021 // Copyright JF Possibilities, Inc. All rights reserved. ////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include "data.h" ////////////////////////////////////////////////////////////////////// // Utils ////////////////////////////////////////////////////////////////////// std::string ipv6opt(const std::string &addr) { in6_addr buf; char s[256]; if(inet_pton(AF_INET6, addr.c_str(), &buf)<1) throw std::runtime_error("ipv6opt: inet_pton() says '"+addr+"' is not a valid IPv6 address"); if(!inet_ntop(AF_INET6, &buf, s, 255)) throw // should never happen std::runtime_error("ipv6opt: inet_ntop() refused to convert the address back"); return std::string(s); } int addr_wild_comp(const std::string &str1, const std::string &str2) { int spre1=0, spre2=0; if(str1=="*" || str2=="*") return 0; if(str1!="" && (str1.end()[-1]=='.' || str1.end()[-1]==':')) spre1=str1.size(); if(str2!="" && (str2.end()[-1]=='.' || str2.end()[-1]==':')) spre2=str2.size(); if(spre2>spre1) spre1=spre2; if(spre1) return strncmp(str1.c_str(), str2.c_str(), spre1); else if(str1str2) return 1; return 0; } ////////////////////////////////////////////////////////////////////// // Conn ////////////////////////////////////////////////////////////////////// void Conn::clear() { us = them = name = protocol = ""; in=false; us_port = them_port = 0; } void Conn::compact() { if(us.find(':')!=us.npos) us=ipv6opt(us); if(them.find(':')!=us.npos) them=ipv6opt(them); } void Conn::swap() { std::string s; int x; s = us; us = them; them =s; x = us_port; us_port = them_port; them_port = x; in=!in; } Conn &Conn::operator=(const Splits &sp) { int x; clear(); for(x=0; xgtr.name) return 1; } if(protocolgtr.protocol) return 1; if(ingtr.in) return 1; return 0; } std::ostream &operator<<(std::ostream &out, const Conn &c) { out << c.us << ( c.in ? " <- " : " -> " ) << c.them << " " << c.protocol << "[" << ( c.in ? c.us_port : c.them_port ) << "] " << c.name; return out; } const Splits &operator>>(const Splits &tsv, Conn &conn) { if(tsv.count<7) throw std::runtime_error("Conn=TSV: too few columns"); conn.clear(); conn.us = tsv[0]; conn.us_port = atoi(tsv.fields[1]); conn.them = tsv[2]; conn.them_port = atoi(tsv.fields[3]); conn.name = tsv[4]; conn.protocol = tsv[5]; conn.in = tsv[6]=="1"; return tsv; } ////////////////////////////////////////////////////////////////////// // ConnList ////////////////////////////////////////////////////////////////////// int ConnList::find(Conn &needle) { int r; for(r=0; r