// See the file "COPYING" in the main distribution directory for copyright. #ifndef REPORTER_H #define REPORTER_H #include #include #include #include "util.h" #include "net_util.h" #include "EventHandler.h" class Connection; class Location; class Reporter; // One cannot raise this exception directly, go through the // Reporter's methods instead. class ReporterException { protected: friend class Reporter; ReporterException() {} }; class InterpreterException : public ReporterException { protected: friend class Reporter; InterpreterException() {} }; // Check printf-style variadic arguments if we can. #if __GNUC__ #define FMT_ATTR __attribute__((format(printf, 2, 3))) // sic! 1st is "this" I guess. #else #define FMT_ATTR #endif class Reporter { public: Reporter(); ~Reporter(); // Report an informational message, nothing that needs specific // attention. void Info(const char* fmt, ...) FMT_ATTR; // Report a warning that may indicate a problem. void Warning(const char* fmt, ...) FMT_ATTR; // Report a non-fatal error. Processing proceeds normally after the error // has been reported. void Error(const char* fmt, ...) FMT_ATTR; // Returns the number of errors reported so far. int Errors() { return errors; } // Report a fatal error. Bro will terminate after the message has been // reported. void FatalError(const char* fmt, ...) FMT_ATTR; // Report a fatal error. Bro will terminate after the message has been // reported and always generate a core dump. void FatalErrorWithCore(const char* fmt, ...) FMT_ATTR; // Report a runtime error in evaluating a Bro script expression. This // function will not return but raise an InterpreterException. void ExprRuntimeError(const Expr* expr, const char* fmt, ...); // Report a traffic weirdness, i.e., an unexpected protocol situation // that may lead to incorrectly processing a connnection. void Weird(const char* name); // Raises net_weird(). void Weird(Connection* conn, const char* name, const char* addl = ""); // Raises conn_weird(). void Weird(Val* conn_val, const char* name, const char* addl = ""); // Raises conn_weird(). void Weird(const uint32* orig, const uint32* resp, const char* name); // Raises flow_weird(). // Syslog a message. This methods does nothing if we're running // offline from a trace. void Syslog(const char* fmt, ...) FMT_ATTR; // Report about a potential internal problem. Bro will continue // normally. void InternalWarning(const char* fmt, ...) FMT_ATTR; // Report an internal program error. Bro will terminate with a core // dump after the message has been reported. void InternalError(const char* fmt, ...) FMT_ATTR; // Toggle whether non-fatal messages should be reported through the // scripting layer rather on standard output. Fatal errors are always // reported via stderr. void ReportViaEvents(bool arg_via_events) { via_events = arg_via_events; } // Associates the given location with subsequent output. We create a // stack of location so that the most recent is always the one that // will be assumed to be the current one. The pointer must remain // valid until the location is popped. void PushLocation(const Location* location) { locations.push_back(std::pair(location, 0)); } void PushLocation(const Location* loc1, const Location* loc2) { locations.push_back(std::pair(loc1, loc2)); } // Removes the top-most location information from stack. void PopLocation() { locations.pop_back(); } // Signals that we're entering processing an error handler event. void BeginErrorHandler() { ++in_error_handler; } // Signals that we're done processing an error handler event. void EndErrorHandler() { --in_error_handler; } private: void DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Connection* conn, val_list* addl, bool location, bool time, const char* postfix, const char* fmt, va_list ap); // The order if addl, name needs to be like that since fmt_name can // contain format specifiers void WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* addl, const char* fmt_name, ...); void WeirdFlowHelper(const uint32* orig, const uint32* resp, const char* fmt_name, ...); int errors; bool via_events; int in_error_handler; std::list > locations; }; extern Reporter* reporter; #endif