/* rsyslog rainerscript definitions * * Copyright 2011-2018 Rainer Gerhards * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INC_UTILS_H #define INC_UTILS_H #include #include #include #include #include #include #include "typedefs.h" #define LOG_NFACILITIES 24+1 /* we copy&paste this as including rsyslog.h gets us in off64_t trouble... :-( */ #define CNFFUNC_MAX_ARGS 32 /**< maximum number of arguments that any function can have (among * others, this is used to size data structures). */ enum cnfobjType { CNFOBJ_ACTION, CNFOBJ_RULESET, CNFOBJ_GLOBAL, CNFOBJ_INPUT, CNFOBJ_MODULE, CNFOBJ_TPL, CNFOBJ_PROPERTY, CNFOBJ_CONSTANT, CNFOBJ_MAINQ, CNFOBJ_LOOKUP_TABLE, CNFOBJ_PARSER, CNFOBJ_TIMEZONE, CNFOBJ_DYN_STATS, CNFOBJ_PERCTILE_STATS, CNFOBJ_INVALID = 0 }; const char* cnfobjType2str(enum cnfobjType ot); /* a variant type, for example used for expression evaluation * 2011-07-15/rger: note that there exists a "legacy" object var, * which implements the same idea, but in a suboptimal manner. I have * stipped this down as much as possible, but will keep it for a while * to avoid unnecessary complexity during development. TODO: in the long * term, var shall be replaced by struct svar. */ struct svar{ union { es_str_t *estr; struct cnfarray *ar; long long n; struct json_object *json; } d; char datatype; /* 'N' number, 'S' string, 'J' JSON, 'A' array * Note: 'A' is only supported during config phase */ }; struct cnfobj { enum cnfobjType objType; struct nvlst *nvlst; struct objlst *subobjs; struct cnfstmt *script; }; struct objlst { struct objlst *next; struct cnfobj *obj; }; struct nvlst { struct nvlst *next; es_str_t *name; struct svar val; unsigned char bUsed; /**< was this node used during config processing? If not, this * indicates an error. After all, the user specified a setting * that the software does not know. */ }; /* the following structures support expressions, and may (very much later * be the sole foundation for the AST. * * nodetypes (list not yet complete) * A - (string) array * F - function * N - number * P - fparamlst * R - rule * S - string * V - var * ... plus the S_* #define's below: */ #define S_STOP 4000 #define S_PRIFILT 4001 #define S_PROPFILT 4002 #define S_IF 4003 #define S_ACT 4004 #define S_NOP 4005 /* usually used to disable some statement */ #define S_SET 4006 #define S_UNSET 4007 #define S_CALL 4008 #define S_FOREACH 4009 #define S_RELOAD_LOOKUP_TABLE 4010 #define S_CALL_INDIRECT 4011 #define S_FUNC_EXISTS 4012 /* special case function which must get varname only */ enum cnfFiltType { CNFFILT_NONE, CNFFILT_PRI, CNFFILT_PROP, CNFFILT_SCRIPT }; const char* cnfFiltType2str(const enum cnfFiltType filttype); struct cnfstmt { unsigned nodetype; struct cnfstmt *next; uchar *printable; /* printable text for debugging */ union { struct { struct cnfexpr *expr; struct cnfstmt *t_then; struct cnfstmt *t_else; } s_if; struct { uchar *varname; struct cnfexpr *expr; int force_reset; } s_set; struct { uchar *varname; } s_unset; struct { es_str_t *name; struct cnfstmt *stmt; ruleset_t *ruleset; /* non-NULL if the ruleset has a queue assigned */ } s_call; struct { struct cnfexpr *expr; } s_call_ind; struct { uchar pmask[LOG_NFACILITIES+1]; /* priority mask */ struct cnfstmt *t_then; struct cnfstmt *t_else; } s_prifilt; struct { fiop_t operation; regex_t *regex_cache;/* cache for compiled REs, if used */ struct cstr_s *pCSCompValue;/* value to "compare" against */ sbool isNegated; msgPropDescr_t prop; /* requested property */ struct cnfstmt *t_then; struct cnfstmt *t_else; } s_propfilt; struct action_s *act; struct { struct cnfitr *iter; struct cnfstmt *body; } s_foreach; struct { lookup_ref_t *table; uchar *table_name; uchar *stub_value; } s_reload_lookup_table; } d; }; struct cnfexpr { unsigned nodetype; struct cnfexpr *l; struct cnfexpr *r; } __attribute__((aligned (8))); struct cnfitr { char* var; struct cnfexpr* collection; } __attribute__((aligned (8))); struct cnfnumval { unsigned nodetype; long long val; } __attribute__((aligned (8))); struct cnfstringval { unsigned nodetype; es_str_t *estr; } __attribute__((aligned (8))); struct cnfvar { unsigned nodetype; char *name; msgPropDescr_t prop; } __attribute__((aligned (8))); struct cnfarray { unsigned nodetype; int nmemb; es_str_t **arr; } __attribute__((aligned (8))); struct cnffparamlst { unsigned nodetype; /* P */ struct cnffparamlst *next; struct cnfexpr *expr; } __attribute__((aligned (8))); enum cnffuncid { CNFFUNC_INVALID = 0, /**< defunct entry, do not use (should normally not be present) */ CNFFUNC_NAME = 1, /**< use name to call function (for future use) */ CNFFUNC_STRLEN, CNFFUNC_SUBSTRING, CNFFUNC_GETENV, CNFFUNC_TOLOWER, CNFFUNC_CSTR, CNFFUNC_CNUM, CNFFUNC_RE_MATCH, CNFFUNC_RE_EXTRACT, CNFFUNC_FIELD, CNFFUNC_PRIFILT, CNFFUNC_LOOKUP, CNFFUNC_EXEC_TEMPLATE, CNFFUNC_REPLACE, CNFFUNC_WRAP, CNFFUNC_RANDOM, CNFFUNC_DYN_INC, CNFFUNC_IPV42NUM, CNFFUNC_NUM2IPV4, CNFFUNC_INT2HEX, CNFFUNC_LTRIM, CNFFUNC_RTRIM, CNFFUNC_FORMAT_TIME, CNFFUNC_PARSE_TIME, CNFFUNC_PARSE_JSON, CNFFUNC_GET_PROPERTY, CNFFUNC_PREVIOUS_ACTION_SUSPENDED, CNFFUNC_SCRIPT_ERROR, CNFFUNC_HTTP_REQUEST, CNFFUNC_IS_TIME }; typedef struct cnffunc cnffunc_t; typedef void (*rscriptFuncPtr) (cnffunc_t *, struct svar *, void *, wti_t *); struct cnffunc { unsigned nodetype; es_str_t *fname; unsigned short nParams; rscriptFuncPtr fPtr; void *funcdata; /* global data for function-specific use (e.g. compiled regex) */ uint8_t destructable_funcdata; struct cnfexpr *expr[]; } __attribute__((aligned (8))); struct cnffuncexists { unsigned nodetype; const char *varname; msgPropDescr_t prop; } __attribute__((aligned (8))); struct scriptFunct { const char *fname; unsigned short minParams; unsigned short maxParams; rscriptFuncPtr fPtr; rsRetVal (*initFunc) (struct cnffunc *); void (*destruct) (struct cnffunc *); /* currently no optimizer entrypoint, may be added later. * Since the optimizer needs metadata about functions, it does * not seem practical to add such a function at the current state */ }; /* future extensions struct x { int nodetype; }; */ /* the following defines describe the parameter block for puling * config parameters. Note that the focus is on ease and saveness of * use, not performance. For example, we address parameters by name * instead of index, because the former is less error-prone. The (severe) * performance hit does not matter, as it is a one-time hit during config * load but never during actual processing. So there is really no reason * to care. */ struct cnfparamdescr { /* first the param description */ const char *name;/**< not a es_str_t to ease definition in code */ ecslCmdHdrlType type; unsigned flags; }; /* flags for cnfparamdescr: */ #define CNFPARAM_REQUIRED 0x0001 #define CNFPARAM_DEPRECATED 0x0002 struct cnfparamblk { /* now the actual param block use in API calls */ unsigned short version; unsigned short nParams; struct cnfparamdescr *descr; }; #define CNFPARAMBLK_VERSION 1 /**< caller must have same version as engine -- else things may * be messed up. But note that we may support multiple versions * inside the engine, if at some later stage we want to do * that. -- rgerhards, 2011-07-15 */ struct cnfparamvals { /* the values we obtained for param descr. */ struct svar val; unsigned char bUsed; }; struct funcData_prifilt { uchar pmask[LOG_NFACILITIES+1]; /* priority mask */ }; /* script errno-like interface error codes: */ #define RS_SCRIPT_EOK 0 #define RS_SCRIPT_EINVAL 1 void varFreeMembers(const struct svar *r); rsRetVal addMod2List(const int version, struct scriptFunct *functArray); void readConfFile(FILE *fp, es_str_t **str); struct objlst* objlstNew(struct cnfobj *obj); void objlstDestruct(struct objlst *lst); void objlstPrint(struct objlst *lst); struct nvlst* nvlstNewArray(struct cnfarray *ar); struct nvlst* nvlstNewStr(es_str_t *value); struct nvlst* nvlstNewStrBackticks(es_str_t *const value); struct nvlst* nvlstSetName(struct nvlst *lst, es_str_t *name); void nvlstDestruct(struct nvlst *lst); void nvlstPrint(struct nvlst *lst); void nvlstChkUnused(struct nvlst *lst); struct nvlst* nvlstFindName(struct nvlst *lst, es_str_t *name); int nvlstChkDisabled(struct nvlst *lst); struct cnfobj* cnfobjNew(enum cnfobjType objType, struct nvlst *lst); void cnfobjDestruct(struct cnfobj *o); void cnfobjPrint(struct cnfobj *o); struct cnfexpr* cnfexprNew(unsigned nodetype, struct cnfexpr *l, struct cnfexpr *r); void cnfexprPrint(struct cnfexpr *expr, int indent); void cnfexprEval(const struct cnfexpr *const expr, struct svar *ret, void *pusr, wti_t *pWti); int cnfexprEvalBool(struct cnfexpr *expr, void *usrptr, wti_t *pWti); struct json_object* cnfexprEvalCollection(struct cnfexpr * const expr, void * const usrptr, wti_t *pWti); void cnfexprDestruct(struct cnfexpr *expr); struct cnfnumval* cnfnumvalNew(long long val); struct cnfstringval* cnfstringvalNew(es_str_t *estr); struct cnfvar* cnfvarNew(char *name); struct cnffunc * cnffuncNew(es_str_t *fname, struct cnffparamlst* paramlst); struct cnffuncexists * cnffuncexistsNew(const char *varname); struct cnffparamlst * cnffparamlstNew(struct cnfexpr *expr, struct cnffparamlst *next); int cnfDoInclude(const char *name, const int optional); int cnfparamGetIdx(struct cnfparamblk *params, const char *name); struct cnfparamvals* nvlstGetParams(struct nvlst *lst, struct cnfparamblk *params, struct cnfparamvals *vals); void cnfparamsPrint(const struct cnfparamblk *params, const struct cnfparamvals *vals); int cnfparamvalsIsSet(struct cnfparamblk *params, struct cnfparamvals *vals); void varDelete(const struct svar *v); void cnfparamvalsDestruct(const struct cnfparamvals *paramvals, const struct cnfparamblk *blk); struct cnfstmt * cnfstmtNew(unsigned s_type); struct cnfitr * cnfNewIterator(char *var, struct cnfexpr *collection); void cnfstmtPrintOnly(struct cnfstmt *stmt, int indent, sbool subtree); void cnfstmtPrint(struct cnfstmt *stmt, int indent); struct cnfstmt* scriptAddStmt(struct cnfstmt *root, struct cnfstmt *s); struct objlst* objlstAdd(struct objlst *root, struct cnfobj *o); char *rmLeadingSpace(char *s); struct cnfstmt * cnfstmtNewPRIFILT(char *prifilt, struct cnfstmt *t_then); struct cnfstmt * cnfstmtNewPROPFILT(char *propfilt, struct cnfstmt *t_then); struct cnfstmt * cnfstmtNewAct(struct nvlst *lst); struct cnfstmt * cnfstmtNewLegaAct(char *actline); struct cnfstmt * cnfstmtNewSet(char *var, struct cnfexpr *expr, int force_reset); struct cnfstmt * cnfstmtNewUnset(char *var); struct cnfstmt * cnfstmtNewCall(es_str_t *name); struct cnfstmt * cnfstmtNewContinue(void); struct cnfstmt * cnfstmtNewReloadLookupTable(struct cnffparamlst *fparams); void cnfstmtDestructLst(struct cnfstmt *root); struct cnfstmt *cnfstmtOptimize(struct cnfstmt *root); struct cnfarray* cnfarrayNew(es_str_t *val); struct cnfarray* cnfarrayDup(struct cnfarray *old); struct cnfarray* cnfarrayAdd(struct cnfarray *ar, es_str_t *val); void cnfarrayContentDestruct(struct cnfarray *ar); const char* getFIOPName(unsigned iFIOP); rsRetVal initRainerscript(void); void unescapeStr(uchar *s, int len); const char * tokenval2str(int tok); uchar* var2CString(struct svar *__restrict__ const r, int *__restrict__ const bMustFree); long long var2Number(struct svar *r, int *bSuccess); void includeProcessCnf(struct nvlst *const lst); /* debug helper */ void cstrPrint(const char *text, es_str_t *estr); #endif