mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 00:28:21 +00:00

It works with a simple example, but that's as much testing as it has seen so far. Remote::Destination has a new attribute "request_logs: bool" indicating whether we are interested in the peer's log. Default is false. If true, Bro will send an explicit "I want your logs" message over to the other side, which will then start sending log records back. When such log records are received, they will be recorded exactly in the same way as on the remote side, i.e., same fields/writer/path. All filtering is already performed on the remote side. Log::Filter has two new attributes, "log_local: bool" and "log_remote: bool" (both true by default). If log_local is false, this filter will not record anything locally but still process everything normally otherwise and potentially forward to remote. If log_remote is false, this filter will never send anything to remote even if a peer has requested logs. (Note that with the defaults, requesting logs will mean getting everything.) Note that with log forwarding, *both* sides must create the Filter::Stream. If the remote sends log records for a specific stream, but the local side hasn't created it, the data will be discarded. Filtes on the other hand shouldn't created locally; and if they are, they are ignored for records received from remote).
530 lines
11 KiB
C++
530 lines
11 KiB
C++
// $Id: SerializationFormat.cc 5873 2008-06-28 19:25:03Z vern $
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "net_util.h"
|
|
#include "SerializationFormat.h"
|
|
#include "Serializer.h"
|
|
|
|
SerializationFormat::SerializationFormat()
|
|
{
|
|
output = 0;
|
|
}
|
|
|
|
SerializationFormat::~SerializationFormat()
|
|
{
|
|
delete [] output;
|
|
}
|
|
|
|
void SerializationFormat::StartRead(char* data, uint32 arg_len)
|
|
{
|
|
input = data;
|
|
input_len = arg_len;
|
|
input_pos = 0;
|
|
}
|
|
|
|
void SerializationFormat::EndRead()
|
|
{
|
|
input = 0;
|
|
}
|
|
|
|
void SerializationFormat::StartWrite()
|
|
{
|
|
if ( output && output_size > INITIAL_SIZE )
|
|
{
|
|
delete [] output;
|
|
output = 0;
|
|
}
|
|
|
|
if ( ! output )
|
|
{
|
|
output = new char[INITIAL_SIZE];
|
|
output_size = INITIAL_SIZE;
|
|
}
|
|
|
|
output_pos = 0;
|
|
bytes_written = 0;
|
|
bytes_read = 0;
|
|
}
|
|
|
|
uint32 SerializationFormat::EndWrite(char** data)
|
|
{
|
|
*data = new char[output_pos];
|
|
memcpy(*data, output, output_pos);
|
|
return output_pos;
|
|
}
|
|
|
|
bool SerializationFormat::ReadData(void* b, size_t count)
|
|
{
|
|
if ( input_pos + count > input_len )
|
|
{
|
|
error("data underflow during read in binary format");
|
|
abort();
|
|
return false;
|
|
}
|
|
|
|
memcpy(b, input + input_pos, count);
|
|
input_pos += count;
|
|
bytes_read += count;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool SerializationFormat::WriteData(const void* b, size_t count)
|
|
{
|
|
// Increase buffer if necessary.
|
|
while ( output_pos + count > output_size )
|
|
{
|
|
output_size = output_pos + count + INITIAL_SIZE;
|
|
char* tmp = new char[output_size];
|
|
memcpy(tmp, output, output_pos);
|
|
delete [] output;
|
|
output = tmp;
|
|
}
|
|
|
|
memcpy(output + output_pos, b, count);
|
|
output_pos += count;
|
|
bytes_written += count;
|
|
|
|
return true;
|
|
}
|
|
|
|
BinarySerializationFormat::BinarySerializationFormat()
|
|
{
|
|
}
|
|
|
|
BinarySerializationFormat::~BinarySerializationFormat()
|
|
{
|
|
}
|
|
|
|
bool BinarySerializationFormat::Read(int* v, const char* tag)
|
|
{
|
|
uint32 tmp;
|
|
if ( ! ReadData(&tmp, sizeof(tmp)) )
|
|
return false;
|
|
|
|
*v = (int) ntohl(tmp);
|
|
DBG_LOG(DBG_SERIAL, "Read int %d [%s]", *v, tag);
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Read(uint16* v, const char* tag)
|
|
{
|
|
if ( ! ReadData(v, sizeof(*v)) )
|
|
return false;
|
|
|
|
*v = ntohs(*v);
|
|
DBG_LOG(DBG_SERIAL, "Read uint16 %hu [%s]", *v, tag);
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Read(uint32* v, const char* tag)
|
|
{
|
|
if ( ! ReadData(v, sizeof(*v)) )
|
|
return false;
|
|
|
|
*v = ntohl(*v);
|
|
DBG_LOG(DBG_SERIAL, "Read uint32 %ld [%s]", *v, tag);
|
|
return true;
|
|
}
|
|
|
|
|
|
bool BinarySerializationFormat::Read(int64* v, const char* tag)
|
|
{
|
|
uint32 x[2];
|
|
if ( ! ReadData(x, sizeof(x)) )
|
|
return false;
|
|
|
|
*v = ((int64(ntohl(x[0]))) << 32) | ntohl(x[1]);
|
|
DBG_LOG(DBG_SERIAL, "Read int64 %lld [%s]", *v, tag);
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Read(uint64* v, const char* tag)
|
|
{
|
|
uint32 x[2];
|
|
if ( ! ReadData(x, sizeof(x)) )
|
|
return false;
|
|
|
|
*v = ((uint64(ntohl(x[0]))) << 32) | ntohl(x[1]);
|
|
DBG_LOG(DBG_SERIAL, "Read uint64 %llu [%s]", *v, tag);
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Read(bool* v, const char* tag)
|
|
{
|
|
char c;
|
|
if ( ! ReadData(&c, 1) )
|
|
return false;
|
|
|
|
*v = c == '\1' ? true : false;
|
|
DBG_LOG(DBG_SERIAL, "Read bool %s [%s]", *v ? "true" : "false", tag);
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Read(double* d, const char* tag)
|
|
{
|
|
if ( ! ReadData(d, sizeof(*d)) )
|
|
return false;
|
|
|
|
*d = ntohd(*d);
|
|
DBG_LOG(DBG_SERIAL, "Read double %.6f [%s]", *d, tag);
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Read(char* v, const char* tag)
|
|
{
|
|
bool ret = ReadData(v, 1);
|
|
DBG_LOG(DBG_SERIAL, "Read char %s [%s]", fmt_bytes(v, 1), tag);
|
|
return ret;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Read(char** str, int* len, const char* tag)
|
|
{
|
|
int l;
|
|
if ( ! ReadData(&l, sizeof(l)) )
|
|
return false;
|
|
|
|
l = ntohl(l);
|
|
char* s = new char[l + 1];
|
|
|
|
if ( ! ReadData(s, l) )
|
|
{
|
|
delete [] s;
|
|
*str = 0;
|
|
return false;
|
|
}
|
|
|
|
if ( len )
|
|
*len = l;
|
|
else
|
|
{
|
|
// If len isn't given, make sure that the string
|
|
// doesn't contain any nulls.
|
|
for ( int i = 0; i < l; i++ )
|
|
if ( ! s[i] )
|
|
{
|
|
error("binary Format: string contains null; replaced by '_'");
|
|
s[i] = '_';
|
|
}
|
|
}
|
|
|
|
s[l] = '\0';
|
|
|
|
*str = s;
|
|
|
|
DBG_LOG(DBG_SERIAL, "Read %d bytes |%s| [%s]", l, fmt_bytes(*str, l), tag);
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Read(string* v, const char* tag)
|
|
{
|
|
char* buffer;
|
|
int len;
|
|
|
|
if ( ! Read(&buffer, &len, tag) )
|
|
return false;
|
|
|
|
*v = string(buffer, len);
|
|
|
|
delete [] buffer;
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(char v, const char* tag)
|
|
{
|
|
DBG_LOG(DBG_SERIAL, "Write char %s [%s]", fmt_bytes(&v, 1), tag);
|
|
return WriteData(&v, 1);
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(uint16 v, const char* tag)
|
|
{
|
|
DBG_LOG(DBG_SERIAL, "Write uint16 %hu [%s]", v, tag);
|
|
v = htons(v);
|
|
return WriteData(&v, sizeof(v));
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(uint32 v, const char* tag)
|
|
{
|
|
DBG_LOG(DBG_SERIAL, "Write uint32 %ld [%s]", v, tag);
|
|
v = htonl(v);
|
|
return WriteData(&v, sizeof(v));
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(int v, const char* tag)
|
|
{
|
|
DBG_LOG(DBG_SERIAL, "Write int %d [%s]", v, tag);
|
|
uint32 tmp = htonl((uint32) v);
|
|
return WriteData(&tmp, sizeof(tmp));
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(uint64 v, const char* tag)
|
|
{
|
|
DBG_LOG(DBG_SERIAL, "Write uint64 %lu [%s]", v, tag);
|
|
uint32 x[2];
|
|
x[0] = htonl(v >> 32);
|
|
x[1] = htonl(v & 0xffffffff);
|
|
return WriteData(x, sizeof(x));
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(int64 v, const char* tag)
|
|
{
|
|
DBG_LOG(DBG_SERIAL, "Write int64 %ld [%s]", v, tag);
|
|
uint32 x[2];
|
|
x[0] = htonl(v >> 32);
|
|
x[1] = htonl(v & 0xffffffff);
|
|
return WriteData(x, sizeof(x));
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(double d, const char* tag)
|
|
{
|
|
DBG_LOG(DBG_SERIAL, "Write double %.6f [%s]", d, tag);
|
|
d = htond(d);
|
|
return WriteData(&d, sizeof(d));
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(bool v, const char* tag)
|
|
{
|
|
DBG_LOG(DBG_SERIAL, "Write bool %s [%s]", v ? "true" : "false", tag);
|
|
char c = v ? '\1' : '\0';
|
|
return WriteData(&c, 1);
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(const char* s, const char* tag)
|
|
{
|
|
return Write(s, strlen(s), tag);
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(const string& s, const char* tag)
|
|
{
|
|
return Write(s.data(), s.size(), tag);
|
|
}
|
|
|
|
bool BinarySerializationFormat::WriteOpenTag(const char* tag)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::WriteCloseTag(const char* tag)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::WriteSeparator()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool BinarySerializationFormat::Write(const char* buf, int len, const char* tag)
|
|
{
|
|
DBG_LOG(DBG_SERIAL, "Write bytes |%s| [%s]", fmt_bytes(buf, len), tag);
|
|
uint32 l = htonl(len);
|
|
return WriteData(&l, sizeof(l)) && WriteData(buf, len);
|
|
}
|
|
|
|
XMLSerializationFormat::XMLSerializationFormat()
|
|
{
|
|
}
|
|
|
|
XMLSerializationFormat::~XMLSerializationFormat()
|
|
{
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(int* v, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(uint16* v, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(uint32* v, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(int64* v, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(uint64* v, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(bool* v, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(double* d, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(char* v, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(char** str, int* len, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Read(string* s, const char* tag)
|
|
{
|
|
internal_error("no reading of xml");
|
|
return false;
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(char v, const char* tag)
|
|
{
|
|
return WriteElem(tag, "char", &v, 1);
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(uint16 v, const char* tag)
|
|
{
|
|
const char* tmp = fmt("%"PRIu16, v);
|
|
return WriteElem(tag, "uint16", tmp, strlen(tmp));
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(uint32 v, const char* tag)
|
|
{
|
|
const char* tmp = fmt("%"PRIu32, v);
|
|
return WriteElem(tag, "uint32", tmp, strlen(tmp));
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(uint64 v, const char* tag)
|
|
{
|
|
const char* tmp = fmt("%"PRIu64, v);
|
|
return WriteElem(tag, "uint64", tmp, strlen(tmp));
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(int64 v, const char* tag)
|
|
{
|
|
const char* tmp = fmt("%"PRId64, v);
|
|
return WriteElem(tag, "int64", tmp, strlen(tmp));
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(int v, const char* tag)
|
|
{
|
|
const char* tmp = fmt("%d", v);
|
|
return WriteElem(tag, "int", tmp, strlen(tmp));
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(double d, const char* tag)
|
|
{
|
|
const char* tmp = fmt("%f", d);
|
|
return WriteElem(tag, "double", tmp, strlen(tmp));
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(bool v, const char* tag)
|
|
{
|
|
if ( v )
|
|
return WriteElem(tag, "bool", "true", 4);
|
|
else
|
|
return WriteElem(tag, "bool", "false", 5);
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(const char* s, const char* tag)
|
|
{
|
|
return WriteElem(tag, "string", s, strlen(s));
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(const string& s, const char* tag)
|
|
{
|
|
return WriteElem(tag, "string", s.data(), s.size());
|
|
}
|
|
|
|
bool XMLSerializationFormat::WriteOpenTag(const char* tag)
|
|
{
|
|
return WriteData("<", 1) && WriteData(tag, strlen(tag) && WriteData(">", 1));
|
|
}
|
|
|
|
bool XMLSerializationFormat::WriteCloseTag(const char* tag)
|
|
{
|
|
return WriteData("</", 2) && WriteData(tag, strlen(tag))
|
|
&& WriteData(">", 1);
|
|
}
|
|
|
|
bool XMLSerializationFormat::WriteSeparator()
|
|
{
|
|
return WriteData("\n", 1);
|
|
}
|
|
|
|
bool XMLSerializationFormat::Write(const char* buf, int len, const char* tag)
|
|
{
|
|
return WriteElem(tag, "string", buf, len);
|
|
}
|
|
|
|
bool XMLSerializationFormat::WriteEncodedString(const char* s, int len)
|
|
{
|
|
while ( len-- )
|
|
{
|
|
int success = false;
|
|
if ( ! isprint(*s) )
|
|
{
|
|
const char* tmp = fmt("%.4x", (int)* s++);
|
|
success = WriteData("&#x", 3) && WriteData(tmp, 4) &&
|
|
WriteData(";", 1);
|
|
}
|
|
else
|
|
{
|
|
switch ( *s ) {
|
|
case '"':
|
|
success = WriteData(""", 6);
|
|
break;
|
|
case '&':
|
|
success = WriteData("&", 5);
|
|
break;
|
|
case '<':
|
|
success = WriteData("<", 4);
|
|
break;
|
|
case '>':
|
|
success = WriteData(">", 4);
|
|
break;
|
|
default:
|
|
success = WriteData(s, 1);
|
|
}
|
|
|
|
if ( ! success )
|
|
return false;
|
|
|
|
++s;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool XMLSerializationFormat::WriteElem(const char* tag, const char* type,
|
|
const char* content, int len)
|
|
{
|
|
if ( ! tag )
|
|
return true;
|
|
|
|
return WriteData("<", 1) &&
|
|
WriteData(tag, strlen(tag)) &&
|
|
#if 0
|
|
WriteData(" type=\"", 7) &&
|
|
WriteData(type, strlen(type)) &&
|
|
WriteData("\"", 1) &&
|
|
#endif
|
|
WriteData(">", 1) &&
|
|
WriteEncodedString(content, len) &&
|
|
WriteData("</", 2) &&
|
|
WriteData(tag, strlen(tag)) &&
|
|
WriteData(">", 1);
|
|
}
|