Branch data Line data Source code
1 : : // $Id: Val.h 6916 2009-09-24 20:48:36Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef val_h
6 : : #define val_h
7 : :
8 : : // BRO values.
9 : :
10 : : #include <vector>
11 : : #include <list>
12 : :
13 : : #include "net_util.h"
14 : : #include "Type.h"
15 : : #include "Dict.h"
16 : : #include "CompHash.h"
17 : : #include "BroString.h"
18 : : #include "Attr.h"
19 : : #include "Timer.h"
20 : : #include "ID.h"
21 : : #include "Scope.h"
22 : : #include "StateAccess.h"
23 : :
24 : : class Val;
25 : : class Func;
26 : : class BroFile;
27 : : class RE_Matcher;
28 : : class PrefixTable;
29 : : class SerialInfo;
30 : :
31 : : class PortVal;
32 : : class AddrVal;
33 : : class NetVal;
34 : : class SubNetVal;
35 : :
36 : : class IntervalVal;
37 : : class PatternVal;
38 : : class TableVal;
39 : : class RecordVal;
40 : : class ListVal;
41 : : class StringVal;
42 : : class MutableVal;
43 : :
44 : : class StateAccess;
45 : :
46 : : class VectorVal;
47 : :
48 : : class TableEntryVal;
49 [ + - ][ # # ]: 164155 : declare(PDict,TableEntryVal);
50 : :
51 : : typedef union {
52 : : // Used for bool, int, enum.
53 : : bro_int_t int_val;
54 : :
55 : : // Used for count, counter, port, subnet.
56 : : bro_uint_t uint_val;
57 : :
58 : : // Used for addr, net
59 : : addr_type addr_val;
60 : :
61 : : // Used for subnet
62 : : subnet_type subnet_val;
63 : :
64 : : // Used for double, time, interval.
65 : : double double_val;
66 : :
67 : : BroString* string_val;
68 : : Func* func_val;
69 : : BroFile* file_val;
70 : : RE_Matcher* re_val;
71 : : PDict(TableEntryVal)* table_val;
72 : : val_list* val_list_val;
73 : :
74 : : vector<Val*>* vector_val;
75 : :
76 : : } BroValUnion;
77 : :
78 : : class Val : public BroObj {
79 : : public:
80 : 93365 : Val(bool b, TypeTag t)
81 : 93365 : {
82 : 93365 : val.int_val = b;
83 : 93365 : type = base_type(t);
84 : 93365 : attribs = 0;
85 : : #ifdef DEBUG
86 : 93365 : bound_id = 0;
87 : : #endif
88 : 93365 : }
89 : :
90 : 197426 : Val(int i, TypeTag t)
91 : 197426 : {
92 : 197426 : val.int_val = bro_int_t(i);
93 : 197426 : type = base_type(t);
94 : 197426 : attribs = 0;
95 : : #ifdef DEBUG
96 : 197426 : bound_id = 0;
97 : : #endif
98 : 197426 : }
99 : :
100 : : Val(long i, TypeTag t)
101 : : {
102 : : val.int_val = bro_int_t(i);
103 : : type = base_type(t);
104 : : attribs = 0;
105 : : #ifdef DEBUG
106 : : bound_id = 0;
107 : : #endif
108 : : }
109 : :
110 : 2428 : Val(unsigned int u, TypeTag t)
111 : 2428 : {
112 : 2428 : val.uint_val = bro_uint_t(u);
113 : 2428 : type = base_type(t);
114 : 2428 : attribs = 0;
115 : : #ifdef DEBUG
116 : 2428 : bound_id = 0;
117 : : #endif
118 : 2428 : }
119 : :
120 : : Val(unsigned long u, TypeTag t)
121 : : {
122 : : val.uint_val = bro_uint_t(u);
123 : : type = base_type(t);
124 : : attribs = 0;
125 : : #ifdef DEBUG
126 : : bound_id = 0;
127 : : #endif
128 : : }
129 : :
130 : 98924 : Val(int64 i, TypeTag t)
131 : 98924 : {
132 : 98924 : val.int_val = i;
133 : 98924 : type = base_type(t);
134 : 98924 : attribs = 0;
135 : : #ifdef DEBUG
136 : 98924 : bound_id = 0;
137 : : #endif
138 : 98924 : }
139 : :
140 : 1765 : Val(uint64 u, TypeTag t)
141 : 1765 : {
142 : 1765 : val.uint_val = u;
143 : 1765 : type = base_type(t);
144 : 1765 : attribs = 0;
145 : : #ifdef DEBUG
146 : 1765 : bound_id = 0;
147 : : #endif
148 : 1765 : }
149 : :
150 : 40737 : Val(double d, TypeTag t)
151 : 40737 : {
152 : 40737 : val.double_val = d;
153 : 40737 : type = base_type(t);
154 : 40737 : attribs = 0;
155 : : #ifdef DEBUG
156 : 40737 : bound_id = 0;
157 : : #endif
158 : 40737 : }
159 : :
160 : : Val(Func* f);
161 : :
162 : : // Note, will unref 'f' when it's done, closing it unless
163 : : // class has ref'd it.
164 : : Val(BroFile* f);
165 : :
166 : 0 : Val()
167 : 0 : {
168 : 0 : val.int_val = 0;
169 : 0 : type = base_type(TYPE_ERROR);
170 : 0 : attribs = 0;
171 : : #ifdef DEBUG
172 : 0 : bound_id = 0;
173 : : #endif
174 : 0 : }
175 : :
176 : : virtual ~Val();
177 : :
178 : 2052299 : Val* Ref() { ::Ref(this); return this; }
179 : : virtual Val* Clone() const;
180 : :
181 : : RecordVal* GetAttribs(bool instantiate);
182 : 0 : void SetAttribs(RecordVal* arg_attribs)
183 : : {
184 : 0 : Unref((Val*) attribs);
185 : 0 : attribs = arg_attribs;
186 : 0 : }
187 : :
188 : : int IsZero() const;
189 : : int IsOne() const;
190 : :
191 : : bro_int_t InternalInt() const;
192 : : bro_uint_t InternalUnsigned() const;
193 : : double InternalDouble() const;
194 : :
195 : : bro_int_t CoerceToInt() const;
196 : : bro_uint_t CoerceToUnsigned() const;
197 : : double CoerceToDouble() const;
198 : :
199 : : // Returns a new Val with the "size" of this Val. What constitutes
200 : : // size depends on the Val's type.
201 : : virtual Val* SizeVal() const;
202 : :
203 : : // Bytes in total value object.
204 : : virtual unsigned int MemoryAllocation() const;
205 : :
206 : : // Add this value to the given value (if appropriate).
207 : : // Returns true if succcessful. is_first_init is true only if
208 : : // this is the *first* initialization of the value, not
209 : : // if it's a subsequent += initialization.
210 : : virtual int AddTo(Val* v, int is_first_init) const;
211 : :
212 : : // Remove this value from the given value (if appropriate).
213 : : virtual int RemoveFrom(Val* v) const;
214 : :
215 : 1870670 : BroType* Type() { return type; }
216 : 239958 : const BroType* Type() const { return type; }
217 : :
218 : : #define CONST_ACCESSOR(tag, ctype, accessor, name) \
219 : : const ctype name() const \
220 : : { \
221 : : CHECK_TAG(type->Tag(), tag, "Val::CONST_ACCESSOR", type_name) \
222 : : return val.accessor; \
223 : : }
224 : :
225 : : // Needed for g++ 4.3's pickiness.
226 : : #define CONST_ACCESSOR2(tag, ctype, accessor, name) \
227 : : ctype name() const \
228 : : { \
229 : : CHECK_TAG(type->Tag(), tag, "Val::CONST_ACCESSOR", type_name) \
230 : : return val.accessor; \
231 : : }
232 : :
233 [ - + ]: 176 : CONST_ACCESSOR2(TYPE_BOOL, bool, int_val, AsBool)
234 [ - + ]: 2 : CONST_ACCESSOR2(TYPE_INT, bro_int_t, int_val, AsInt)
235 [ - + ]: 157 : CONST_ACCESSOR2(TYPE_COUNT, bro_uint_t, uint_val, AsCount)
236 : : CONST_ACCESSOR2(TYPE_COUNTER, bro_uint_t, uint_val, AsCounter)
237 [ - + ]: 2 : CONST_ACCESSOR2(TYPE_DOUBLE, double, double_val, AsDouble)
238 [ - + ]: 2 : CONST_ACCESSOR2(TYPE_TIME, double, double_val, AsTime)
239 [ - + ]: 342 : CONST_ACCESSOR2(TYPE_INTERVAL, double, double_val, AsInterval)
240 [ # # ]: 0 : CONST_ACCESSOR2(TYPE_ENUM, int, int_val, AsEnum)
241 [ - + ]: 437666 : CONST_ACCESSOR(TYPE_STRING, BroString*, string_val, AsString)
242 [ # # ]: 0 : CONST_ACCESSOR(TYPE_FUNC, Func*, func_val, AsFunc)
243 [ - + ]: 179518 : CONST_ACCESSOR(TYPE_TABLE, PDict(TableEntryVal)*, table_val, AsTable)
244 [ - + ]: 553918 : CONST_ACCESSOR(TYPE_RECORD, val_list*, val_list_val, AsRecord)
245 [ # # ]: 0 : CONST_ACCESSOR(TYPE_FILE, BroFile*, file_val, AsFile)
246 [ - + ]: 2 : CONST_ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern)
247 : : CONST_ACCESSOR(TYPE_VECTOR, vector<Val*>*, vector_val, AsVector)
248 : :
249 : 70 : const subnet_type* AsSubNet() const
250 : : {
251 [ - + ]: 70 : CHECK_TAG(type->Tag(), TYPE_SUBNET, "Val::SubNet", type_name)
252 : 70 : return &val.subnet_val;
253 : : }
254 : :
255 : : // ... in network byte order
256 : 59380 : const addr_type AsAddr() const
257 : : {
258 [ - + ][ # # ]: 59380 : if ( type->Tag() != TYPE_ADDR && type->Tag() != TYPE_NET )
[ - + ]
259 : 0 : BadTag("Val::AsAddr", type_name(type->Tag()));
260 : 59380 : return val.addr_val;
261 : : }
262 : :
263 : : #define ACCESSOR(tag, ctype, accessor, name) \
264 : : ctype name() \
265 : : { \
266 : : CHECK_TAG(type->Tag(), tag, "Val::ACCESSOR", type_name) \
267 : : return val.accessor; \
268 : : }
269 : :
270 : : // Accessors for mutable values are called AsNonConst* and
271 : : // are protected to avoid external state changes.
272 : : // ACCESSOR(TYPE_STRING, BroString*, string_val, AsString)
273 [ - + ]: 205655 : ACCESSOR(TYPE_FUNC, Func*, func_val, AsFunc)
274 [ - + ]: 5009 : ACCESSOR(TYPE_FILE, BroFile*, file_val, AsFile)
275 [ - + ]: 2748 : ACCESSOR(TYPE_PATTERN, RE_Matcher*, re_val, AsPattern)
276 [ # # ]: 0 : ACCESSOR(TYPE_VECTOR, vector<Val*>*, vector_val, AsVector)
277 : :
278 : 0 : subnet_type* AsSubNet()
279 : : {
280 [ # # ]: 0 : CHECK_TAG(type->Tag(), TYPE_SUBNET, "Val::SubNet", type_name)
281 : 0 : return &val.subnet_val;
282 : : }
283 : :
284 : : // Gives fast access to the bits of something that is one of
285 : : // bool, int, count, or counter.
286 : 22421 : bro_int_t ForceAsInt() const { return val.int_val; }
287 : 50708 : bro_uint_t ForceAsUInt() const { return val.uint_val; }
288 : :
289 : : #define CONVERTER(tag, ctype, name) \
290 : : ctype name() \
291 : : { \
292 : : CHECK_TAG(type->Tag(), tag, "Val::CONVERTER", type_name) \
293 : : return (ctype)(this); \
294 : : }
295 : :
296 [ - + ]: 2 : CONVERTER(TYPE_PATTERN, PatternVal*, AsPatternVal)
297 [ - + ]: 9171 : CONVERTER(TYPE_PORT, PortVal*, AsPortVal)
298 : : CONVERTER(TYPE_NET, NetVal*, AsNetVal)
299 [ # # ]: 0 : CONVERTER(TYPE_SUBNET, SubNetVal*, AsSubNetVal)
300 [ - + ]: 137132 : CONVERTER(TYPE_TABLE, TableVal*, AsTableVal)
301 [ - + ]: 307532 : CONVERTER(TYPE_RECORD, RecordVal*, AsRecordVal)
302 [ - + ]: 87297 : CONVERTER(TYPE_LIST, ListVal*, AsListVal)
303 [ - + ]: 157511 : CONVERTER(TYPE_STRING, StringVal*, AsStringVal)
304 [ - + ]: 23567 : CONVERTER(TYPE_VECTOR, VectorVal*, AsVectorVal)
305 : :
306 : : #define CONST_CONVERTER(tag, ctype, name) \
307 : : const ctype name() const \
308 : : { \
309 : : CHECK_TAG(type->Tag(), tag, "Val::CONVERTER", type_name) \
310 : : return (const ctype)(this); \
311 : : }
312 : :
313 : : CONST_CONVERTER(TYPE_PATTERN, PatternVal*, AsPatternVal)
314 : : CONST_CONVERTER(TYPE_PORT, PortVal*, AsPortVal)
315 : : CONST_CONVERTER(TYPE_NET, NetVal*, AsNetVal)
316 : : CONST_CONVERTER(TYPE_SUBNET, SubNetVal*, AsSubNetVal)
317 [ # # ]: 0 : CONST_CONVERTER(TYPE_TABLE, TableVal*, AsTableVal)
318 [ # # ]: 0 : CONST_CONVERTER(TYPE_RECORD, RecordVal*, AsRecordVal)
319 [ - + ]: 110088 : CONST_CONVERTER(TYPE_LIST, ListVal*, AsListVal)
320 : : CONST_CONVERTER(TYPE_STRING, StringVal*, AsStringVal)
321 [ # # ]: 0 : CONST_CONVERTER(TYPE_VECTOR, VectorVal*, AsVectorVal)
322 : :
323 : 1937 : bool IsMutableVal() const
324 : : {
325 [ + - ][ + + ]: 1937 : return IsMutable(type->Tag());
[ + + ]
326 : : }
327 : :
328 : 0 : const MutableVal* AsMutableVal() const
329 : : {
330 [ # # ]: 0 : if ( ! IsMutableVal() )
331 : 0 : BadTag("Val::AsMutableVal", type_name(type->Tag()));
332 : 0 : return (MutableVal*) this;
333 : : }
334 : :
335 : 619 : MutableVal* AsMutableVal()
336 : : {
337 [ - + ]: 619 : if ( ! IsMutableVal() )
338 : 0 : BadTag("Val::AsMutableVal", type_name(type->Tag()));
339 : 619 : return (MutableVal*) this;
340 : : }
341 : :
342 : : void Describe(ODesc* d) const;
343 : :
344 : : bool Serialize(SerialInfo* info) const;
345 : 0 : static Val* Unserialize(UnserialInfo* info, TypeTag type = TYPE_ANY)
346 : 0 : { return Unserialize(info, type, 0); }
347 : 0 : static Val* Unserialize(UnserialInfo* info, const BroType* exact_type)
348 : 0 : { return Unserialize(info, exact_type->Tag(), exact_type); }
349 : :
350 : 6 : DECLARE_SERIAL(Val);
351 : :
352 : : #ifdef DEBUG
353 : : // For debugging, we keep a reference to the global ID to which a
354 : : // value has been bound *last*.
355 : 0 : ID* GetID() const { return bound_id; }
356 : 5569 : void SetID(ID* id)
357 : : {
358 [ + + ]: 5569 : if ( bound_id )
359 : 122 : ::Unref(bound_id);
360 : 5569 : bound_id = id;
361 : 5569 : ::Ref(bound_id);
362 : 5569 : }
363 : : #endif
364 : :
365 : : protected:
366 : : Val(BroString* s, TypeTag t)
367 : : {
368 : : val.string_val = s;
369 : : type = base_type(t);
370 : : attribs = 0;
371 : : #ifdef DEBUG
372 : : bound_id = 0;
373 : : #endif
374 : : }
375 : :
376 : : virtual void ValDescribe(ODesc* d) const;
377 : :
378 : 198552 : Val(TypeTag t)
379 : 198552 : {
380 : 198552 : type = base_type(t);
381 : 198552 : attribs = 0;
382 : : #ifdef DEBUG
383 : 198552 : bound_id = 0;
384 : : #endif
385 : 198552 : }
386 : :
387 : 202499 : Val(BroType* t)
388 : 202499 : {
389 : 202499 : type = t->Ref();
390 : 202499 : attribs = 0;
391 : : #ifdef DEBUG
392 : 202499 : bound_id = 0;
393 : : #endif
394 : 202499 : }
395 : :
396 [ - + ]: 48475 : ACCESSOR(TYPE_TABLE, PDict(TableEntryVal)*, table_val, AsNonConstTable)
397 [ - + ]: 264825 : ACCESSOR(TYPE_RECORD, val_list*, val_list_val, AsNonConstRecord)
398 : :
399 : : // Just an internal helper.
400 : : static Val* Unserialize(UnserialInfo* info, TypeTag type,
401 : : const BroType* exact_type);
402 : :
403 : : BroValUnion val;
404 : : BroType* type;
405 : : RecordVal* attribs;
406 : :
407 : : #ifdef DEBUG
408 : : // For debugging, we keep the ID to which a Val is bound.
409 : : ID* bound_id;
410 : : #endif
411 : :
412 : : };
413 : :
414 : : class MutableVal : public Val {
415 : : public:
416 : : // Each MutableVal gets a globally unique ID that can be used to
417 : : // reference it no matter if it's directly bound to any user-visible
418 : : // ID. This ID is inserted into the global namespace.
419 [ # # ]: 0 : ID* UniqueID() const { return id ? id : Bind(); }
420 : :
421 : : // Returns true if we've already generated a unique ID.
422 : 0 : bool HasUniqueID() const { return id; }
423 : :
424 : : // Transfers the unique ID of the given value to this value. We keep our
425 : : // old ID as an alias.
426 : : void TransferUniqueID(MutableVal* mv);
427 : :
428 : : // MutableVals can have properties (let's refrain from calling them
429 : : // attributes!). Most properties are recursive. If a derived object
430 : : // can contain MutableVals itself, the object has to override
431 : : // {Add,Remove}Properties(). RecursiveProp(state) masks out all non-
432 : : // recursive properties. If this is non-null, an overriden method must
433 : : // call itself with RecursiveProp(state) as argument for all contained
434 : : // values. (In any case, don't forget to call the parent's method.)
435 : : typedef char Properties;
436 : :
437 : : static const int PERSISTENT = 0x01;
438 : : static const int SYNCHRONIZED = 0x02;
439 : :
440 : : // Tracked by NotifierRegistry, not recursive.
441 : : static const int TRACKED = 0x04;
442 : :
443 : 11 : int RecursiveProps(int prop) const { return prop & ~TRACKED; }
444 : :
445 : 0 : Properties GetProperties() const { return props; }
446 : : virtual bool AddProperties(Properties state);
447 : : virtual bool RemoveProperties(Properties state);
448 : :
449 : : // Whether StateAccess:LogAccess needs to be called.
450 : 321128 : bool LoggingAccess() const
451 : : {
452 : : #ifndef DEBUG
453 : : return props & (SYNCHRONIZED|PERSISTENT|TRACKED);
454 : : #else
455 : : return debug_logger.IsVerbose() ||
456 [ + - ][ - + ]: 321128 : (props & (SYNCHRONIZED|PERSISTENT|TRACKED));
457 : : #endif
458 : : }
459 : :
460 : 0 : virtual uint64 LastModified() const { return last_modified; }
461 : :
462 : : // Mark value as changed.
463 : 291575 : void Modified()
464 : : {
465 : 291575 : last_modified = IncreaseTimeCounter();
466 : 291575 : }
467 : :
468 : : protected:
469 : 53258 : MutableVal(BroType* t) : Val(t)
470 : 53258 : { props = 0; id = 0; last_modified = SerialObj::ALWAYS; }
471 : 0 : MutableVal() { id = 0; last_modified = SerialObj::ALWAYS; }
472 : : ~MutableVal();
473 : :
474 : : friend class ID;
475 : : friend class Val;
476 : :
477 : 0 : void SetID(ID* arg_id) { Unref(id); id = arg_id; }
478 : :
479 : 0 : DECLARE_SERIAL(MutableVal);
480 : :
481 : : private:
482 : : ID* Bind() const;
483 : :
484 : : mutable ID* id;
485 : : list<ID*> aliases;
486 : : Properties props;
487 : : uint64 last_modified;
488 : : };
489 : :
490 : : #define Microseconds 1e-6
491 : : #define Milliseconds 1e-3
492 : : #define Seconds 1.0
493 : : #define Minutes (60*Seconds)
494 : : #define Hours (60*Minutes)
495 : : #define Days (24*Hours)
496 : :
497 [ + - ][ # # ]: 6 : class IntervalVal : public Val {
498 : : public:
499 : : IntervalVal(double quantity, double units);
500 : :
501 : : protected:
502 : 0 : IntervalVal() {}
503 : :
504 : : void ValDescribe(ODesc* d) const;
505 : :
506 : 6 : DECLARE_SERIAL(IntervalVal);
507 : : };
508 : :
509 : :
510 : : // We have four different port name spaces: TCP, UDP, ICMP, and UNKNOWN.
511 : : // We distinguish between them based on the bits specified in the *_PORT_MASK
512 : : // entries specified below.
513 : : #define NUM_PORT_SPACES 4
514 : : #define PORT_SPACE_MASK 0x30000
515 : :
516 : : #define TCP_PORT_MASK 0x10000
517 : : #define UDP_PORT_MASK 0x20000
518 : : #define ICMP_PORT_MASK 0x30000
519 : :
520 : : typedef enum {
521 : : TRANSPORT_UNKNOWN, TRANSPORT_TCP, TRANSPORT_UDP, TRANSPORT_ICMP,
522 : : } TransportProto;
523 : :
524 [ + - ][ # # ]: 4744 : class PortVal : public Val {
525 : : public:
526 : : // Constructors - both take the port number in host order.
527 : : PortVal(uint32 p, TransportProto port_type);
528 : : PortVal(uint32 p); // used for already-massaged port value.
529 : :
530 : 0 : Val* SizeVal() const { return new Val(val.uint_val, TYPE_INT); }
531 : :
532 : : // Returns the port number in host order (not including the mask).
533 : : uint32 Port() const;
534 : :
535 : : // Tests for protocol types.
536 : : int IsTCP() const;
537 : : int IsUDP() const;
538 : : int IsICMP() const;
539 : :
540 : 2289 : TransportProto PortType() const
541 : : {
542 [ + + ]: 2289 : if ( IsTCP() )
543 : 1600 : return TRANSPORT_TCP;
544 [ + + ]: 689 : else if ( IsUDP() )
545 : 684 : return TRANSPORT_UDP;
546 [ + - ]: 5 : else if ( IsICMP() )
547 : 5 : return TRANSPORT_ICMP;
548 : : else
549 : 2289 : return TRANSPORT_UNKNOWN;
550 : : }
551 : :
552 : : protected:
553 : : friend class Val;
554 : 0 : PortVal() {}
555 : :
556 : : void ValDescribe(ODesc* d) const;
557 : :
558 : 0 : DECLARE_SERIAL(PortVal);
559 : : };
560 : :
561 : : class AddrVal : public Val {
562 : : public:
563 : : AddrVal(const char* text);
564 : : ~AddrVal();
565 : :
566 : : Val* SizeVal() const;
567 : :
568 : : // Constructor for address already in network order.
569 : : AddrVal(uint32 addr);
570 : : AddrVal(const uint32* addr);
571 : :
572 : : unsigned int MemoryAllocation() const;
573 : :
574 : : protected:
575 : : friend class Val;
576 : 0 : AddrVal() {}
577 : 0 : AddrVal(TypeTag t) : Val(t) { }
578 : : AddrVal(BroType* t) : Val(t) { }
579 : :
580 : : void Init(uint32 addr);
581 : : void Init(const uint32* addr);
582 : :
583 : 0 : DECLARE_SERIAL(AddrVal);
584 : : };
585 : :
586 [ # # ][ # # ]: 0 : class NetVal : public AddrVal {
587 : : public:
588 : : NetVal(const char* text);
589 : : NetVal(uint32 addr);
590 : : NetVal(const uint32* addr);
591 : :
592 : : Val* SizeVal() const;
593 : :
594 : : protected:
595 : : friend class Val;
596 : 0 : NetVal() {}
597 : :
598 : : void ValDescribe(ODesc* d) const;
599 : :
600 : 0 : DECLARE_SERIAL(NetVal);
601 : : };
602 : :
603 [ + - ][ # # ]: 14 : class SubNetVal : public Val {
604 : : public:
605 : : SubNetVal(const char* text);
606 : : SubNetVal(const char* text, int width);
607 : : SubNetVal(uint32 addr, int width); // for address already massaged
608 : : SubNetVal(const uint32* addr, int width); // ditto
609 : :
610 : : Val* SizeVal() const;
611 : :
612 : 0 : int Width() const { return val.subnet_val.width; }
613 : : addr_type Mask() const; // returns host byte order
614 : :
615 : : bool Contains(const uint32 addr) const;
616 : : bool Contains(const uint32* addr) const;
617 : :
618 : 0 : unsigned int MemoryAllocation() const
619 : : {
620 : 0 : return Val::MemoryAllocation() + padded_sizeof(*this) - padded_sizeof(Val);
621 : : }
622 : :
623 : : protected:
624 : : friend class Val;
625 : 0 : SubNetVal() {}
626 : :
627 : : void Init(const char* text, int width);
628 : : void Init(uint32 addr, int width);
629 : : void Init(const uint32 *addr, int width);
630 : :
631 : : void ValDescribe(ODesc* d) const;
632 : :
633 : 0 : DECLARE_SERIAL(SubNetVal);
634 : : };
635 : :
636 [ + - ][ # # ]: 184294 : class StringVal : public Val {
637 : : public:
638 : : StringVal(BroString* s);
639 : : StringVal(const char* s);
640 : : StringVal(int length, const char* s);
641 : :
642 : 0 : Val* SizeVal() const
643 : 0 : { return new Val(val.string_val->Len(), TYPE_COUNT); }
644 : :
645 : 134167 : int Len() { return AsString()->Len(); }
646 : 85524 : const u_char* Bytes() { return AsString()->Bytes(); }
647 : 1443 : const char* CheckString() { return AsString()->CheckString(); }
648 : :
649 : : // Note that one needs to de-allocate the return value of
650 : : // ExpandedString() to avoid a memory leak.
651 : : // char* ExpandedString(int format = BroString::EXPANDED_STRING)
652 : : // { return AsString()->ExpandedString(format); }
653 : :
654 : : StringVal* ToUpper();
655 : :
656 : : unsigned int MemoryAllocation() const;
657 : :
658 : : protected:
659 : : friend class Val;
660 : 0 : StringVal() {}
661 : :
662 : : void ValDescribe(ODesc* d) const;
663 : :
664 : 0 : DECLARE_SERIAL(StringVal);
665 : : };
666 : :
667 : : class PatternVal : public Val {
668 : : public:
669 : : PatternVal(RE_Matcher* re);
670 : : ~PatternVal();
671 : :
672 : : int AddTo(Val* v, int is_first_init) const;
673 : :
674 : : void SetMatcher(RE_Matcher* re);
675 : :
676 : : unsigned int MemoryAllocation() const;
677 : :
678 : : protected:
679 : : friend class Val;
680 : 0 : PatternVal() {}
681 : :
682 : : void ValDescribe(ODesc* d) const;
683 : :
684 : 0 : DECLARE_SERIAL(PatternVal);
685 : : };
686 : :
687 : : class ListVal : public Val {
688 : : public:
689 : : ListVal(TypeTag t);
690 : : ~ListVal();
691 : :
692 : 1669 : TypeTag BaseTag() const { return tag; }
693 : :
694 : 0 : Val* SizeVal() const { return new Val(vals.length(), TYPE_COUNT); }
695 : :
696 : 11709 : int Length() const { return vals.length(); }
697 : 90080 : Val* Index(const int n) { return vals[n]; }
698 : 1454 : const Val* Index(const int n) const { return vals[n]; }
699 : :
700 : : // Returns offset of where str includes one of the strings in this
701 : : // ListVal (which had better be a list of strings), nil if none.
702 : : //
703 : : // Assumes that all of the strings in the list are NUL-terminated
704 : : // and do not have any embedded NULs.
705 : : const char* IncludedInString(const char* str) const;
706 : :
707 : : // Returns an RE_Matcher() that will match any string that
708 : : // includes embedded within it one of the patterns listed
709 : : // (as a string, e.g., "foo|bar") in this ListVal.
710 : : //
711 : : // Assumes that all of the strings in the list are NUL-terminated
712 : : // and do not have any embedded NULs.
713 : : //
714 : : // The return RE_Matcher has not yet been compiled.
715 : : RE_Matcher* BuildRE() const;
716 : :
717 : : void Append(Val* v);
718 : :
719 : : // Returns a Set representation of the list (which must be homogeneous).
720 : : TableVal* ConvertToSet() const;
721 : :
722 : 108632 : const val_list* Vals() const { return &vals; }
723 : 1669 : val_list* Vals() { return &vals; }
724 : :
725 : : void Describe(ODesc* d) const;
726 : :
727 : : unsigned int MemoryAllocation() const;
728 : :
729 : : protected:
730 : : friend class Val;
731 : 0 : ListVal() {}
732 : :
733 : 0 : DECLARE_SERIAL(ListVal);
734 : :
735 : : val_list vals;
736 : : TypeTag tag;
737 : : };
738 : :
739 : : extern double bro_start_network_time;
740 : :
741 : : class TableEntryVal {
742 : : public:
743 : 32348 : TableEntryVal(Val* v)
744 : : {
745 : 32348 : val = v;
746 : 32348 : last_access_time = network_time;
747 : : expire_access_time = last_read_update =
748 : 32348 : int(network_time - bro_start_network_time);
749 : 32348 : }
750 : 29255 : ~TableEntryVal() { }
751 : :
752 : 109150 : Val* Value() { return val; }
753 : 169 : void Ref() { val->Ref(); }
754 : 28163 : void Unref() { ::Unref(val); }
755 : :
756 : : // Returns/sets time of last expiration relevant access to this value.
757 : 21340 : double ExpireAccessTime() const
758 : 21340 : { return bro_start_network_time + expire_access_time; }
759 : 29553 : void SetExpireAccess(double time)
760 : 29553 : { expire_access_time = int(time - bro_start_network_time); }
761 : :
762 : : // Returns/sets time of when we propagated the last OP_READ_IDX
763 : : // for this item.
764 : 0 : double LastReadUpdate() const
765 : 0 : { return bro_start_network_time + last_read_update; }
766 : 0 : void SetLastReadUpdate(double time)
767 : 0 : { last_read_update = int(time - bro_start_network_time); }
768 : :
769 : : protected:
770 : : friend class TableVal;
771 : :
772 : : Val* val;
773 : : double last_access_time;
774 : :
775 : : // The next two entries store seconds since Bro's start. We use
776 : : // ints here to save a few bytes, as we do not need a high resolution
777 : : // for these anyway.
778 : : int expire_access_time;
779 : : int last_read_update;
780 : : };
781 : :
782 : : class TableValTimer : public Timer {
783 : : public:
784 : : TableValTimer(TableVal* val, double t);
785 : : ~TableValTimer();
786 : :
787 : : virtual void Dispatch(double t, int is_expire);
788 : :
789 : : TableVal* Table() { return table; }
790 : :
791 : : protected:
792 : : TableVal* table;
793 : : };
794 : :
795 : : class CompositeHash;
796 : : class TableVal : public MutableVal {
797 : : public:
798 : : TableVal(TableType* t, Attributes* attrs = 0);
799 : : ~TableVal();
800 : :
801 : : // Returns true if the assignment typechecked, false if not.
802 : : // Second version takes a HashKey and Unref()'s it when done.
803 : : // If we're a set, new_val has to be nil.
804 : : // If we aren't a set, index may be nil in the second version.
805 : : int Assign(Val* index, Val* new_val, Opcode op = OP_ASSIGN);
806 : : int Assign(Val* index, HashKey* k, Val* new_val, Opcode op = OP_ASSIGN);
807 : :
808 : 1085 : Val* SizeVal() const { return new Val(Size(), TYPE_COUNT); }
809 : :
810 : : // Add the entire contents of the table to the given value,
811 : : // which must also be a TableVal.
812 : : // Returns true if the addition typechecked, false if not.
813 : : // If is_first_init is true, then this is the *first* initialization
814 : : // (and so should be strictly adding new elements).
815 : : int AddTo(Val* v, int is_first_init) const;
816 : :
817 : : // Same but allows suppression of state operations.
818 : : int AddTo(Val* v, int is_first_init, bool propagate_ops) const;
819 : :
820 : : // Remove the entire contents.
821 : : void RemoveAll();
822 : :
823 : : // Remove the entire contents of the table from the given value.
824 : : // which must also be a TableVal.
825 : : // Returns true if the addition typechecked, false if not.
826 : : int RemoveFrom(Val* v) const;
827 : :
828 : : // Expands any lists in the index into multiple initializations.
829 : : // Returns true if the initializations typecheck, false if not.
830 : : int ExpandAndInit(Val* index, Val* new_val);
831 : :
832 : : // Returns the element's value if it exists in the table,
833 : : // nil otherwise. Note, "index" is not const because we
834 : : // need to Ref/Unref it when calling the default function.
835 : : Val* Lookup(Val* index, bool use_default_val = true);
836 : :
837 : : // Sets the timestamp for the given index to network time.
838 : : // Returns false if index does not exist.
839 : : bool UpdateTimestamp(Val* index);
840 : :
841 : : // Returns the index corresponding to the given HashKey.
842 : : ListVal* RecoverIndex(const HashKey* k) const;
843 : :
844 : : // Returns the element if it was in the table, false otherwise.
845 : : Val* Delete(const Val* index);
846 : : Val* Delete(const HashKey* k);
847 : :
848 : : // Returns a ListVal representation of the table (which must be a set).
849 : : ListVal* ConvertToList(TypeTag t=TYPE_ANY) const;
850 : : ListVal* ConvertToPureList() const; // must be single index type
851 : :
852 : : void SetAttrs(Attributes* attrs);
853 : 4106 : Attr* FindAttr(attr_tag t) const
854 [ + + ]: 4106 : { return attrs ? attrs->FindAttr(t) : 0; }
855 : 1350 : Attributes* Attrs() { return attrs; }
856 : :
857 : : // Returns the size of the table.
858 : 4146 : int Size() const { return AsTable()->Length(); }
859 : : int RecursiveSize() const;
860 : :
861 : : void Describe(ODesc* d) const;
862 : :
863 : : void InitTimer(double delay);
864 : : void DoExpire(double t);
865 : :
866 : : unsigned int MemoryAllocation() const;
867 : :
868 : 15852 : void ClearTimer(Timer* t)
869 : : {
870 [ + + ]: 15852 : if ( timer == t )
871 : 8021 : timer = 0;
872 : 15852 : }
873 : :
874 : : protected:
875 : : friend class Val;
876 : : friend class StateAccess;
877 : 0 : TableVal() {}
878 : :
879 : : void Init(TableType* t);
880 : :
881 : : void CheckExpireAttr(attr_tag at);
882 : : int ExpandCompoundAndInit(val_list* vl, int k, Val* new_val);
883 : : int CheckAndAssign(Val* index, Val* new_val, Opcode op = OP_ASSIGN);
884 : 110860 : HashKey* ComputeHash(const Val* index) const
885 : 110860 : { return table_hash->ComputeHash(index, 1); }
886 : :
887 : : bool AddProperties(Properties arg_state);
888 : : bool RemoveProperties(Properties arg_state);
889 : :
890 : : // Calculates default value for index. Returns 0 if none.
891 : : Val* Default(Val* index);
892 : :
893 : : // Calls &expire_func and returns its return interval;
894 : : // takes ownership of the reference.
895 : : double CallExpireFunc(Val *idx);
896 : :
897 : : // Propagates a read operation if necessary.
898 : : void ReadOperation(Val* index, TableEntryVal *v);
899 : :
900 : 2 : DECLARE_SERIAL(TableVal);
901 : :
902 : : const TableType* table_type;
903 : : CompositeHash* table_hash;
904 : : Attributes* attrs;
905 : : double expire_time;
906 : : Expr* expire_expr;
907 : : TableValTimer* timer;
908 : : IterCookie* expire_cookie;
909 : : PrefixTable* subnets;
910 : : Val* def_val;
911 : : };
912 : :
913 : : class RecordVal : public MutableVal {
914 : : public:
915 : : RecordVal(RecordType* t);
916 : : ~RecordVal();
917 : :
918 : 0 : Val* SizeVal() const
919 : 0 : { return new Val(record_type->NumFields(), TYPE_COUNT); }
920 : :
921 : : void Assign(int field, Val* new_val, Opcode op = OP_ASSIGN);
922 : : Val* Lookup(int field) const;
923 : :
924 : : void Describe(ODesc* d) const;
925 : :
926 : : // This is an experiment to associate a BroObj within the
927 : : // event engine to a record value in bro script.
928 : 19340 : void SetOrigin(BroObj* o) { origin = o; }
929 : 204 : BroObj* GetOrigin() const { return origin; }
930 : :
931 : : unsigned int MemoryAllocation() const;
932 : :
933 : : protected:
934 : : friend class Val;
935 : 0 : RecordVal() {}
936 : :
937 : : bool AddProperties(Properties arg_state);
938 : : bool RemoveProperties(Properties arg_state);
939 : :
940 : 0 : DECLARE_SERIAL(RecordVal);
941 : :
942 : : RecordType* record_type;
943 : : BroObj* origin;
944 : : };
945 : :
946 [ + - ][ # # ]: 3668 : class EnumVal : public Val {
947 : : public:
948 : 4579 : EnumVal(int i, EnumType* t) : Val(t)
949 : : {
950 : 4579 : val.int_val = i;
951 : 4579 : type = t;
952 : 4579 : attribs = 0;
953 : 4579 : }
954 : :
955 : 0 : Val* SizeVal() const { return new Val(val.int_val, TYPE_INT); }
956 : :
957 : : protected:
958 : : friend class Val;
959 : 0 : EnumVal() {}
960 : :
961 : : void ValDescribe(ODesc* d) const;
962 : :
963 : 0 : DECLARE_SERIAL(EnumVal);
964 : : };
965 : :
966 : :
967 : : // The minimum index for vectors (0 or 1).
968 : : const int VECTOR_MIN = 1;
969 : :
970 : : class VectorVal : public MutableVal {
971 : : public:
972 : : VectorVal(VectorType* t);
973 : : ~VectorVal();
974 : :
975 : 110 : Val* SizeVal() const
976 : 110 : { return new Val(uint32(val.vector_val->size()), TYPE_COUNT); }
977 : :
978 : : // Returns false if the type of the argument was wrong.
979 : : // The vector will automatically grow to accomodate the index.
980 : : // 'assigner" is the expression that is doing the assignment;
981 : : // it's just used for pinpointing errors.
982 : : //
983 : : // Note: does NOT Ref() the element! Remember to do so unless
984 : : // the element was just created and thus has refcount 1.
985 : : //
986 : : bool Assign(unsigned int index, Val* element, const Expr* assigner,
987 : : Opcode op = OP_ASSIGN);
988 : : bool Assign(Val* index, Val* element, const Expr* assigner,
989 : 0 : Opcode op = OP_ASSIGN)
990 : : {
991 : : return Assign(index->AsListVal()->Index(0)->CoerceToUnsigned(),
992 : 0 : element, assigner, op);
993 : : }
994 : :
995 : : // Assigns the value to how_many locations starting at index.
996 : : bool AssignRepeat(unsigned int index, unsigned int how_many,
997 : : Val* element, const Expr* assigner);
998 : :
999 : : // Returns nil if no element was at that value.
1000 : : // Lookup does NOT grow the vector to this size.
1001 : : // The Val* variant assumes that the index Val* has been type-checked.
1002 : : Val* Lookup(unsigned int index) const;
1003 : 22174 : Val* Lookup(Val* index)
1004 : : {
1005 : 22174 : bro_uint_t i = index->AsListVal()->Index(0)->CoerceToUnsigned();
1006 : 22174 : return Lookup(static_cast<unsigned int>(i));
1007 : : }
1008 : :
1009 : 24822 : unsigned int Size() const { return val.vector_val->size(); }
1010 : :
1011 : : // Is there any way to reclaim previously-allocated memory when you
1012 : : // shrink a vector? The return value is the old size.
1013 : : unsigned int Resize(unsigned int new_num_elements);
1014 : :
1015 : : // Won't shrink size.
1016 : : unsigned int ResizeAtLeast(unsigned int new_num_elements);
1017 : :
1018 : : protected:
1019 : : friend class Val;
1020 : 0 : VectorVal() { }
1021 : :
1022 : : bool AddProperties(Properties arg_state);
1023 : : bool RemoveProperties(Properties arg_state);
1024 : : void ValDescribe(ODesc* d) const;
1025 : :
1026 : 0 : DECLARE_SERIAL(VectorVal);
1027 : :
1028 : : VectorType* vector_type;
1029 : : };
1030 : :
1031 : :
1032 : : // Checks the given value for consistency with the given type. If an
1033 : : // exact match, returns it. If promotable, returns the promoted version,
1034 : : // Unref()'ing the original. If not a match, generates an error message
1035 : : // and returns nil, also Unref()'ing v. If is_init is true, then
1036 : : // the checking is done in the context of an initialization.
1037 : : extern Val* check_and_promote(Val* v, const BroType* t, int is_init);
1038 : :
1039 : : // Given a pointer to where a Val's core (i.e., its BRO value) resides,
1040 : : // returns a corresponding newly-created or Ref()'d Val. ptr must already
1041 : : // be properly aligned. Returns the size of the core in bytes in 'n'.
1042 : : // If t corresponds to a variable-length type, n must give the size on entry.
1043 : : Val* recover_val(void* ptr, BroType* t, int& n);
1044 : :
1045 : : extern int same_val(const Val* v1, const Val* v2);
1046 : : extern int same_atomic_val(const Val* v1, const Val* v2);
1047 : : extern bool is_atomic_val(const Val* v);
1048 : : extern void describe_vals(const val_list* vals, ODesc* d, int offset=0);
1049 : : extern void delete_vals(val_list* vals);
1050 : :
1051 : : // True if the given Val* has a vector type.
1052 : 676280 : inline bool is_vector(Val* v) { return v->Type()->Tag() == TYPE_VECTOR; }
1053 : :
1054 : : #endif
|