mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
145 lines
3.7 KiB
C++
145 lines
3.7 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#include "zeek/script_opt/ZAM/BuiltInSupport.h"
|
|
|
|
#include "zeek/IPAddr.h"
|
|
#include "zeek/RE.h"
|
|
|
|
namespace zeek::detail {
|
|
|
|
FixedCatArg::FixedCatArg(TypePtr _t) : t(std::move(_t)) {
|
|
switch ( t->Tag() ) {
|
|
case TYPE_BOOL: max_size = 1; break;
|
|
|
|
case TYPE_INT:
|
|
case TYPE_COUNT:
|
|
max_size = 20; // sufficient for 64 bits
|
|
break;
|
|
|
|
case TYPE_DOUBLE:
|
|
case TYPE_TIME:
|
|
max_size = 32; // from modp_dtoa2 documentation
|
|
break;
|
|
|
|
case TYPE_ENUM: {
|
|
size_t n = 0;
|
|
for ( const auto& e : t->AsEnumType()->Names() )
|
|
n = std::max(n, e.first.size());
|
|
max_size = n;
|
|
break;
|
|
}
|
|
|
|
case TYPE_PORT:
|
|
max_size = 5 + 1 + 7; // <number> + / + "unknown"
|
|
break;
|
|
|
|
case TYPE_ADDR:
|
|
max_size = 39; // for IPv6
|
|
break;
|
|
|
|
case TYPE_SUBNET:
|
|
max_size = 39 + 1 + 3; // for IPv6 + / + <3-digits>
|
|
break;
|
|
|
|
default: reporter->InternalError("bad type in FixedCatArg constructor");
|
|
}
|
|
}
|
|
|
|
void FixedCatArg::RenderInto(const ZVal& z, char*& res) {
|
|
int n;
|
|
const char* text;
|
|
std::string str;
|
|
|
|
switch ( t->Tag() ) {
|
|
case TYPE_BOOL: *(res++) = z.AsInt() ? 'T' : 'F'; break;
|
|
|
|
case TYPE_INT:
|
|
n = modp_litoa10(z.AsInt(), res);
|
|
res += n;
|
|
break;
|
|
|
|
case TYPE_COUNT:
|
|
n = modp_ulitoa10(z.AsCount(), res);
|
|
res += n;
|
|
break;
|
|
|
|
case TYPE_DOUBLE:
|
|
case TYPE_TIME: {
|
|
auto d = z.AsDouble();
|
|
n = modp_dtoa2(d, res, 6);
|
|
res += n;
|
|
|
|
if ( util::approx_equal(d, nearbyint(d), 1e-9) && std::isfinite(d) ) {
|
|
// disambiguate from integer
|
|
*(res++) = '.';
|
|
*(res++) = '0';
|
|
}
|
|
break;
|
|
}
|
|
|
|
case TYPE_PATTERN:
|
|
text = z.AsPattern()->AsPattern()->PatternText();
|
|
*(res++) = '/';
|
|
strcpy(res, text);
|
|
res += strlen(text);
|
|
*(res++) = '/';
|
|
break;
|
|
|
|
case TYPE_ENUM:
|
|
text = t->AsEnumType()->Lookup(z.AsInt());
|
|
strcpy(res, text);
|
|
res += strlen(text);
|
|
break;
|
|
|
|
case TYPE_PORT: {
|
|
uint32_t full_p = static_cast<uint32_t>(z.AsCount());
|
|
zeek_uint_t p = full_p & ~PORT_SPACE_MASK;
|
|
n = modp_ulitoa10(p, res);
|
|
res += n;
|
|
|
|
if ( (full_p & TCP_PORT_MASK) == TCP_PORT_MASK ) {
|
|
strcpy(res, "/tcp");
|
|
res += 4;
|
|
}
|
|
|
|
else if ( (full_p & UDP_PORT_MASK) == UDP_PORT_MASK ) {
|
|
strcpy(res, "/udp");
|
|
res += 4;
|
|
}
|
|
|
|
else if ( (full_p & ICMP_PORT_MASK) == ICMP_PORT_MASK ) {
|
|
strcpy(res, "/icmp");
|
|
res += 5;
|
|
}
|
|
|
|
else {
|
|
strcpy(res, "/unknown");
|
|
res += 8;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case TYPE_ADDR:
|
|
str = z.AsAddr()->Get().AsString();
|
|
strcpy(res, str.c_str());
|
|
res += strlen(str.c_str());
|
|
break;
|
|
|
|
case TYPE_SUBNET:
|
|
str = z.AsSubNet()->Get().AsString();
|
|
strcpy(res, str.c_str());
|
|
res += strlen(str.c_str());
|
|
break;
|
|
|
|
default: reporter->InternalError("bad type in FixedCatArg::RenderInto");
|
|
}
|
|
}
|
|
|
|
size_t PatternCatArg::ComputeMaxSize(const ZVal& zv) {
|
|
text = zv.AsPattern()->AsPattern()->PatternText();
|
|
n = strlen(text);
|
|
return n;
|
|
}
|
|
|
|
} // namespace zeek::detail
|