1 /* 2 ** Copyright (C) 2001-2020 by Carnegie Mellon University. 3 ** 4 ** @OPENSOURCE_LICENSE_START@ 5 ** See license information in ../../LICENSE.txt 6 ** @OPENSOURCE_LICENSE_END@ 7 */ 8 9 /* 10 ** rwrec.h 11 ** 12 ** The SiLK Flow record (rwRec) definition and functions/macros for 13 ** manipulating it. 14 ** 15 */ 16 #ifndef _RWREC_H 17 #define _RWREC_H 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 #include <silk/silk.h> 23 24 RCSIDENTVAR(rcsID_RWREC_H, "$SiLK: rwrec.h ef14e54179be 2020-04-14 21:57:45Z mthomas $"); 25 26 #include <silk/silk_types.h> 27 28 #ifndef RWREC_OPAQUE 29 # define RWREC_OPAQUE 0 30 # include <silk/skipaddr.h> 31 #endif 32 33 34 /* 35 * The following documents macros defined in this file that work to 36 * access and manipulate the data in an rwRec. Although these are 37 * macros, they have been documented as functions in order to convey 38 * the expected types of the arguments. 39 * 40 * **** Convenience macros **** 41 * 42 * void RWREC_CLEAR(rwRec *r); 43 * Zero out the record, and set Sensor ID and Flowtype to invalid 44 * values. 45 * 46 * void RWREC_COPY(rwRec *dst, const rwRec *src); 47 * Copy the rwRec from 'src' to 'dst'. 48 * 49 * int rwRecIsICMP(const rwRec *r); 50 * Returns non-zero if the record is an ICMP record, zero otherwise. 51 * 52 * int rwRecIsWeb(const rwRec *r); 53 * Returns non-zero if the record can be represented using the SiLK 54 * web-specific file formats, zero otherwise. 55 * 56 * 57 * **** More macros **** 58 * 59 * Function versions of all of the following macros exist. Simply 60 * change the "rwRec" prefix of the macro to "rwrec_" to use the 61 * function version. 62 * 63 * *** Whether a record is IPv6 *** 64 * 65 * int rwRecIsIPv6(const rwRec *r); 66 * 67 * *** Set record as IPv4 or IPv6 *** 68 * 69 * void rwRecSetIPv6(rwRec *r); 70 * void rwRecSetIPv4(rwRec *r); 71 * 72 * It is important to note that the above two macros do not do any 73 * conversions on the contained IP addresses. They are primarily to 74 * be used when creating a new rwRec from scratch. See the following 75 * for conversion. 76 * 77 * *** Convert record to IPv4 or IPv6 *** 78 * 79 * int rwRecConvertToIPv4(rwRec *r); 80 * void rwRecConvertToIPv6(rwRec *r); 81 * 82 * These macros convert an rwRec to IPv4 or IPv6. The latter always 83 * succeeds. The former will return -1 if unable to convert due to 84 * the existence of IPv6 addresses that cannot be represented as IPv4 85 * (and return zero on success). 86 * 87 * **** rwRec accessor macros **** 88 * 89 * Most of the following accessor macros come in five standard 90 * variations: 91 * 92 * <fieldtype> rwRecGet<field>(const reRec *r) 93 * Gets the value of the field directly 94 * 95 * void rwRecSet<field>(rwRec *r, <fieldtype> in_v) 96 * Sets the value of the field to 'in_v' 97 * 98 * void rwRecMemGet<field>(const rwRec *r, <fieldtype> *out_vp) 99 * Copies the value of the field to location out_vp 100 * 101 * void rwRecMemSet<field>(rwRec *r, const <fieldtype> *in_vp) 102 * Copies the value in location in_vp into the field 103 * 104 * int rwRecMemCmp<field>(const rwRec *r, const <fieldtype> *vp) 105 * Compares the field to the value in location vp, returning a 106 * negative integer if the field is less than vp, 0 if equal, and a 107 * positive integer if greater than vp. 108 * 109 * For the rwRecMem{Get,Set,Cmp}<field>() macros, we use of 110 * <fieldtype> in the comment to explain the size of the data 111 * involved. With the exception of those dealing the skipaddr_t 112 * objects, the actual functions use void pointers; as a result, those 113 * macros do not require the value pointer to be aligned. The macros 114 * that handle values larger than uint8_t use memcpy() or memcmp() to 115 * copy or compare the values. 116 * 117 * ** IP Address Macros ** 118 * 119 * For handling IP addresses, there are three sets of macros: one for 120 * IPv4 addresses: one for IPv6 addresses, and one for skipaddr_t 121 * objects, which can represent either an IPv4 address or and IPv6 122 * object. 123 * 124 * In addition to the Get, Set, and Comparison macros, the follow 125 * macro exists in IPv4, IPv6, and skipaddr_t varieties: 126 * 127 * void rwRecApplyMask<field>(rwRec *r, const <fieldtype> mask); 128 * Modify the rwRec's <field> IP addresses by applying the 129 * specified mask (using a bit-wise AND) to that IP address. 130 * 131 * All of the macros that deal with IPv4 addresses assume that you 132 * know the rwRec holds IPv4 addresses. No conversion of the rwRec or 133 * of the address occurs. 134 * 135 * Using the Get macros for IPv6 on an rwRec that contains V4 data 136 * will return a properly encoded IPv4-in-IPv6 address. All other 137 * macros for IPv6 assume you know that the rwRec holds IPv6 138 * addresses. For IPv6, the rwRecGet<field>() and rwRecSet<field>() 139 * macros do not exist; you must use the rwRecMemGet<field>() and 140 * rwRecMemSet<field>() versions. 141 * 142 * Since an skipaddr_t can hold an IPv4 or an IPv6 address, the macros 143 * that use skipaddr_t objects will correctly handle with rwRecs that 144 * hold IPv4 or IPv6 data. Setting or masking an IPv4 rwRec with an 145 * IPv6 skipaddr_t may convert the record to IPv6. The comparison 146 * macros will operate in IPv6 space if either argument involves IPv6. 147 * Unlike all other rwRecMem{Get,Set,Cmp}<field>() macros, the 148 * functions that work with skipaddr_t pointers require the skipaddr_t 149 * to be properly aligned. 150 * 151 * The IPv4 macros include an extra DEPRECATED macro: 152 * 153 * uint32_t rwRecGetMask<field>v4(rwRec *r, uint32_t mask) 154 * Gets the value of the field with the given bit-mask applied 155 * 156 * *** Source IPv4 Address (sIP) *** 157 * 158 * uint32_t rwRecGetSIPv4(const rwRec *r); 159 * void rwRecSetSIPv4(rwRec *r, uint32_t in_v); 160 * void rwRecMemGetSIPv4(const rwRec *r, uint32_t *out_vp); 161 * void rwRecMemSetSIPv4(rwRec *r, const uint32_t *in_vp); 162 * int rwRecMemCmpSIPv4(const rwRec *r, const uint32_t *vp); 163 * void rwRecApplyMaskSIPv4(rwRec *r, uint32_t mask); 164 * uint32_t rwRecGetMaskSIPv4(const rwRec *r, uint32_t mask); 165 * 166 * *** Source IPv6 Address (sIP) *** 167 * 168 * void rwRecMemGetSIPv6(const rwRec *r, uint8_t[16] out_vp); 169 * void rwRecMemSetSIPv6(rwRec *r, const uint8_t[16] in_vp); 170 * int rwRecMemCmpSIPv6(const rwRec *r, const uint8_t[16] vp); 171 * void rwRecApplyMaskSIPv6(rwRec *r, const uint8_t[16] mask); 172 * 173 * *** Source IP Address (sIP) as skipaddr_t *** 174 * 175 * void rwRecMemGetSIP(const rwRec *r, skipaddr_t *out_addr); 176 * void rwRecMemSetSIP(rwRec *r, const skipaddr_t *in_addr); 177 * int rwRecMemCmpSIP(const rwRec *r, const skipaddr_t *addr); 178 * void rwRecApplyMaskSIP(rwRec *r, const skipaddr_t *mask); 179 * 180 * *** Destination IP Address (dIP) *** 181 * 182 * uint32_t rwRecGetDIPv4(const rwRec *r); 183 * void rwRecSetDIPv4(rwRec *r, uint32_t in_v); 184 * void rwRecMemGetDIPv4(const rwRec *r, uint32_t *out_vp); 185 * void rwRecMemSetDIPv4(rwRec *r, const uint32_t *in_vp); 186 * int rwRecMemCmpDIPv4(const rwRec *r, const uint32_t *vp); 187 * void rwRecApplyMaskDIPv4(rwRec *r, uint32_t mask); 188 * uint32_t rwRecGetMaskDIPv4(const rwRec *r, uint32_t mask); 189 * 190 * *** Destination IPv6 Address (dIP) *** 191 * 192 * void rwRecMemGetDIPv6(const rwRec *r, uint8_t[16] out_vp); 193 * void rwRecMemSetDIPv6(rwRec *r, const uint8_t[16] in_vp); 194 * int rwRecMemCmpDIPv6(const rwRec *r, const uint8_t[16] vp); 195 * void rwRecApplyMaskDIPv6(rwRec *r, const uint8_t[16] mask); 196 * 197 * *** Destination IP Address (dIP) as skipaddr_t *** 198 * 199 * void rwRecMemGetDIP(const rwRec *r, skipaddr_t *out_addr); 200 * void rwRecMemSetDIP(rwRec *r, const skipaddr_t *in_addr); 201 * int rwRecMemCmpDIP(const rwRec *r, const skipaddr_t *addr); 202 * void rwRecApplyMaskDIP(rwRec *r, const skipaddr_t *mask); 203 * 204 * *** Next Hop IP Address *** 205 * 206 * uint32_t rwRecGetNhIPv4(const rwRec *r); 207 * void rwRecSetNhIPv4(rwRec *r, uint32_t in_v); 208 * void rwRecMemGetNhIPv4(const rwRec *r, uint32_t *out_vp); 209 * void rwRecMemSetNhIPv4(rwRec *r, const uint32_t *in_vp); 210 * int rwRecMemCmpNhIPv4(const rwRec *r, const uint32_t *vp); 211 * void rwRecApplyMaskNhIPv4(rwRec *r, uint32_t mask); 212 * uint32_t rwRecGetMaskNhIPv4(const rwRec *r, uint32_t mask); 213 * 214 * *** Next Hop IPv6 Address (nhIP) *** 215 * 216 * void rwRecMemGetNhIPv6(const rwRec *r, uint8_t[16] out_vp); 217 * void rwRecMemSetNhIPv6(rwRec *r, const uint8_t[16] in_vp); 218 * int rwRecMemCmpNhIPv6(const rwRec *r, const uint8_t[16] vp); 219 * void rwRecApplyMaskNhIPv6(rwRec *r, const uint8_t[16] mask); 220 * 221 * *** Next Hop IP Address (nhIP) as skipaddr_t *** 222 * 223 * void rwRecMemGetNhIP(const rwRec *r, skipaddr_t *out_addr); 224 * void rwRecMemSetNhIP(rwRec *r, const skipaddr_t *in_addr); 225 * int rwRecMemCmpNhIP(const rwRec *r, const skipaddr_t *addr); 226 * void rwRecApplyMaskNhIP(rwRec *r, const skipaddr_t *mask); 227 * 228 * *** Source Port (sPort) *** 229 * 230 * uint16_t rwRecGetSPort(const rwRec *r); 231 * void rwRecSetSPort(rwRec *r, uint16_t in_v); 232 * void rwRecMemGetSPort(const rwRec *r, uint16_t *out_vp); 233 * void rwRecMemSetSPort(rwRec *r, const uint16_t *in_vp); 234 * int rwRecMemCmpSPort(const rwRec *r, const uint16_t *vp); 235 * 236 * *** Destination Port (dPort) *** 237 * 238 * uint16_t rwRecGetDPort(const rwRec *r); 239 * void rwRecSetDPort(rwRec *r, uint16_t in_v); 240 * void rwRecMemGetDPort(const rwRec *r, uint16_t *out_vp); 241 * void rwRecMemSetDPort(rwRec *r, const uint16_t *in_vp); 242 * int rwRecMemCmpDPort(const rwRec *r, const uint16_t *vp); 243 * 244 * *** Protocol *** 245 * 246 * uint8_t rwRecGetProto(const rwRec *r); 247 * void rwRecSetProto(rwRec *r, uint8_t in_v); 248 * void rwRecMemGetProto(const rwRec *r, uint8_t *out_vp); 249 * void rwRecMemSetProto(rwRec *r, const uint8_t *in_vp); 250 * int rwRecMemCmpProto(const rwRec *r, const uint8_t *vp); 251 * 252 * *** Packet Count (pkts) *** 253 * 254 * uint32_t rwRecGetPkts(const rwRec *r); 255 * void rwRecSetPkts(rwRec *r, uint32_t in_v); 256 * void rwRecMemGetPkts(const rwRec *r, uint32_t *out_vp); 257 * void rwRecMemSetPkts(rwRec *r, const uint32_t *in_vp); 258 * int rwRecMemCmpPkts(const rwRec *r, const uint32_t *vp); 259 * 260 * *** Byte count *** 261 * 262 * uint32_t rwRecGetBytes(const rwRec *r); 263 * void rwRecSetBytes(rwRec *r, uint32_t in_v); 264 * void rwRecMemGetBytes(const rwRec *r, uint32_t *out_vp); 265 * void rwRecMemSetBytes(rwRec *r, const uint32_t *in_vp); 266 * int rwRecMemCmpBytes(const rwRec *r, const uint32_t *vp); 267 * 268 * *** Bitwise OR of TCP Flags on ALL packets in flow *** 269 * 270 * uint8_t rwRecGetFlags(const rwRec *r); 271 * void rwRecSetFlags(rwRec *r, uint8_t in_v); 272 * void rwRecMemGetFlags(const rwRec *r, uint8_t *out_vp); 273 * void rwRecMemSetFlags(rwRec *r, const uint8_t *in_vp); 274 * int rwRecMemCmpFlags(const rwRec *r, const uint8_t *vp); 275 * 276 * *** TCP Flags seen on initial packet of flow *** 277 * 278 * uint8_t rwRecGetInitFlags(const rwRec *r); 279 * void rwRecSetInitFlags(rwRec *r, uint8_t in_v); 280 * void rwRecMemGetInitFlags(const rwRec *r, uint8_t *out_vp); 281 * void rwRecMemSetInitFlags(rwRec *r, const uint8_t *in_vp); 282 * int rwRecMemCmpInitFlags(const rwRec *r, const uint8_t *vp); 283 * 284 * *** Bitwise OR of TCP Flags on all packets in session except first *** 285 * 286 * uint8_t rwRecGetRestFlags(const rwRec *r); 287 * void rwRecSetRestFlags(rwRec *r, uint8_t in_v); 288 * void rwRecMemGetRestFlags(const rwRec *r, uint8_t *out_vp); 289 * void rwRecMemSetRestFlags(rwRec *r, const uint8_t *in_vp); 290 * int rwRecMemCmpRestFlags(const rwRec *r, const uint8_t *vp); 291 * 292 * *** Start Time as milliseconds since UNIX epoch (sTime) *** 293 * 294 * sktime_t rwRecGetStartTime(const rwRec *r); 295 * void rwRecSetStartTime(rwRec *r, sktime_t in_v); 296 * void rwRecMemGetStartTime(const rwRec *r, sktime_t *out_vp); 297 * void rwRecMemSetStartTime(rwRec *r, const sktime_t *in_vp); 298 * int rwRecMemCmpStartTime(const rwRec *r, const sktime_t *vp); 299 * 300 * uint32_t rwRecGetStartSeconds(const rwRec *r); 301 * void rwRecMemGetStartSeconds(const rwRec *r, uint32_t *out_vp); 302 * 303 * *** End Time is derived from the sTime and duration (eTime) *** 304 * 305 * sktime_t rwRecGetEndTime(const rwRec *r); 306 * void rwRecMemGetEndTime(const rwRec *r, sktime_t *out_vp); 307 * 308 * uint32_t rwRecGetEndSeconds(const rwRec *r); 309 * void rwRecMemGetEndSeconds(const rwRec *r, uint32_t *out_vp); 310 * 311 * There are no setter macros for end time, because end time is 312 * derived from start time and duration (elapsed time). 313 * 314 * *** Elapsed (duration) of the flow, in milliseconds *** 315 * 316 * uint32_t rwRecGetElapsed(const rwRec *r); 317 * void rwRecSetElapsed(rwRec *r, uint32_t in_v); 318 * void rwRecMemGetElapsed(const rwRec *r, uint32_t *out_vp); 319 * void rwRecMemSetElapsed(rwRec *r, const uint32_t *in_vp); 320 * int rwRecMemCmpElapsed(const rwRec *r, const uint32_t *vp); 321 * 322 * uint32_t rwRecGetElapsedSeconds(const rwRec *r); 323 * void rwRecMemGetElapsedSeconds(const rwRec *r, uint32_t *out_vp); 324 * 325 * *** Sensor ID (sID) *** 326 * 327 * sensorID_t rwRecGetSensor(const rwRec *r); 328 * void rwRecSetSensor(rwRec *r, sensorID_t in_v); 329 * void rwRecMemGetSensor(const rwRec *r, sensorID_t *out_vp); 330 * void rwRecMemSetSensor(rwRec *r, const sensorID_t *in_vp); 331 * int rwRecMemCmpSensor(const rwRec *r, const sensorID_t *vp); 332 * 333 * *** FlowType holds Class and Type *** 334 * 335 * flowtypeID_t rwRecGetFlowType(const rwRec *r); 336 * void rwRecSetFlowType(rwRec *r, flowtypeID_t in_v); 337 * void rwRecMemGetFlowType(const rwRec *r, flowtypeID_t *out_vp); 338 * void rwRecMemSetFlowType(rwRec *r, const flowtypeID_t *in_vp); 339 * int rwRecMemCmpFlowType(const rwRec *r, const flowtypeID_t *vp); 340 * 341 * *** SNMP Input Value (Router incoming/ingress interface/vlanId) *** 342 * 343 * uint16_t rwRecGetInput(const rwRec *r); 344 * void rwRecSetInput(rwRec *r, uint16_t in_v); 345 * void rwRecMemGetInput(const rwRec *r, uint16_t *out_vp); 346 * void rwRecMemSetInput(rwRec *r, const uint16_t *in_vp); 347 * int rwRecMemCmpInput(const rwRec *r, const uint16_t *vp); 348 * 349 * *** SNMP Output Value (Router outgoing/egress interface/postVlanId) *** 350 * 351 * uint16_t rwRecGetOutput(const rwRec *r); 352 * void rwRecSetOutput(rwRec *r, uint16_t in_v); 353 * void rwRecMemGetOutput(const rwRec *r, uint16_t *out_vp); 354 * void rwRecMemSetOutput(rwRec *r, const uint16_t *in_vp); 355 * int rwRecMemCmpOutput(const rwRec *r, const uint16_t *vp); 356 * 357 * *** TCP State (the Attributes field) *** 358 * 359 * uint8_t rwRecGetTcpState(const rwRec *r); 360 * void rwRecSetTcpState(rwRec *r, uint8_t in_v); 361 * void rwRecMemGetTcpState(const rwRec *r, uint8_t *out_vp); 362 * void rwRecMemSetTcpState(rwRec *r, const uint8_t *in_vp); 363 * int rwRecMemCmpTcpState(const rwRec *r, const uint8_t *vp); 364 * 365 * The TCP state field is a bit field which states certain miscellaneous 366 * information about the flow record. The following constants are 367 * defined which represent this information: 368 * 369 * #define SK_TCPSTATE_EXPANDED 0x01 370 * Expanded TCP-flags: This bit must be set if and only if the flow 371 * is TCP and the init_flags and rest_flags fields are set. 372 * 373 * #define SK_TCPSTATE_FIN_FOLLOWED_NOT_ACK 0x08 374 * Flow received packets following the FIN packet that were not ACK or 375 * RST packets. 376 * 377 * #define SK_TCPSTATE_UNIFORM_PACKET_SIZE 0x10 378 * Flow has packets all of the same size 379 * 380 * #define SK_TCPSTATE_TIMEOUT_KILLED 0x20 381 * Flow ends prematurely due to a timeout by the collector. 382 * 383 * #define SK_TCPSTATE_TIMEOUT_STARTED 0x40 384 * Flow is a continuation of a previous flow that was killed 385 * prematurely due to a timeout by the collector. 386 * 387 * Note: the most significant bit of tcp_state (0x80) is used as a flag 388 * to mark a record as having IPv6 addresses. The rwRecSetIPv4() and 389 * rwRecSetIPv6() macros should be used to modify this bit. 390 * 391 * Be careful when setting the TCP state. You usually want get the 392 * current TCP state, add or remove specific bits by masking, then set it 393 * with the resulting value. 394 * 395 * *** Application *** 396 * 397 * uint16_t rwRecGetApplication(const rwRec *r); 398 * void rwRecSetApplication(rwRec *r, uint16_t in_v); 399 * void rwRecMemGetApplication(const rwRec *r, uint16_t *out_vp); 400 * void rwRecMemSetApplication(rwRec *r, const uint16_t *in_vp); 401 * int rwRecMemCmpApplication(const rwRec *r, const uint16_t *vp); 402 * 403 * The application field can be set by the yaf flow generation 404 * software when it is configured with the "applabel" feature. This 405 * feature causes yaf to inspect the packets in the flow and guess as 406 * to the type of application (HTTP, SMTP, SSH, etc) the packets 407 * represent. The value for the field is the standard service port 408 * for that service (80, 25, 22, etc). 409 * 410 * *** Memo *** 411 * 412 * uint16_t rwRecGetMemo(const rwRec *r); 413 * void rwRecSetMemo(rwRec *r, uint16_t in_v); 414 * void rwRecMemGetMemo(const rwRec *r, uint16_t *out_vp); 415 * void rwRecMemSetMemo(rwRec *r, const uint16_t *in_vp); 416 * int rwRecMemCmpMemo(const rwRec *r, const uint16_t *vp); 417 * 418 * Currently unused. 419 * 420 * *** ICMP Type and Code is derived from the DPort *** 421 * 422 * uint8_t rwRecGetIcmpType(const rwRec *r); 423 * void rwRecSetIcmpType(rwRec *r, uint8_t in_v); 424 * void rwRecMemGetIcmpType(const rwRec *r, uint8_t *out_vp); 425 * 426 * uint8_t rwRecGetIcmpCode(const rwRec *r); 427 * void rwRecSetIcmpCode(rwRec *r, uint8_t in_v); 428 * void rwRecMemGetIcmpCode(const rwRec *r, uint8_t *out_vp); 429 * 430 * uint16_t rwRecGetIcmpTypeAndCode(const rwRec *r); 431 * void rwRecSetIcmpTypeAndCode(rwRec *r, uint16_t in_v); 432 * void rwRecMemGetIcmpTypeAndCode(const rwRec *r, uint16_t *out_vp); 433 * void rwRecMemSetIcmpTypeAndCode(rwRec *r, const uint16_t *in_vp); 434 * int rwRecMemCmpIcmpTypeAndCode(const rwRec *r, const uint16_t *vp); 435 * 436 * Since the ICMP Type and Code are stored in the dport field, modifying 437 * these will modify the return value of rwRecGetDPort() and friends. 438 */ 439 440 441 #define SK_WEBPORT_CHECK(p) ((p) == 80 || (p) == 443 || (p) == 8080) 442 /* 443 * Return a true value if port 'p' is a "web" port; false otherwise 444 */ 445 446 #define RWREC_CLEAR(rec) \ 447 do { \ 448 memset((rec), 0, sizeof(rwRec)); \ 449 rwRecSetSensor((rec), SK_INVALID_SENSOR); \ 450 rwRecSetFlowType((rec), SK_INVALID_FLOWTYPE); \ 451 } while(0) 452 /* 453 * Zero out the record, and set Sensor ID and Flowtype to invalid 454 * values. 455 */ 456 457 458 #define RWREC_COPY(dst, src) \ 459 memcpy((dst), (src), sizeof(rwRec)) 460 /* 461 * Copy the rwRec from 'src' to 'dst'. 462 */ 463 464 465 /* 466 * This is the generic SiLK Flow record returned from ANY file format 467 * containing packed SiLK Flow records. 468 * 469 * typedef struct rwGenericRec_V5_st rwGenericRec_V5_t; // silk_types.h 470 * typedef rwGenericRec_V5_t rwRec; // silk_types.h 471 */ 472 struct rwGenericRec_V5_st { 473 #if RWREC_OPAQUE && !defined(RWREC_DEFINE_BODY) 474 #if SK_ENABLE_IPV6 475 uint8_t ar[88]; 476 #else 477 uint8_t ar[52]; 478 #endif 479 #else 480 int64_t sTime; /* 0- 7 Flow start time in milliseconds 481 * since UNIX epoch */ 482 483 uint32_t elapsed; /* 8-11 Duration of flow in millisecs */ 484 485 uint16_t sPort; /* 12-13 Source port */ 486 uint16_t dPort; /* 14-15 Destination port */ 487 488 uint8_t proto; /* 16 IP protocol */ 489 sk_flowtype_id_t flow_type; /* 17 Class & Type info */ 490 sk_sensor_id_t sID; /* 18-19 Sensor ID */ 491 492 uint8_t flags; /* 20 OR of all flags (Netflow flags) */ 493 uint8_t init_flags; /* 21 TCP flags in first packet 494 * or blank for "legacy" data */ 495 uint8_t rest_flags; /* 22 TCP flags on non-initial packet 496 * or blank for "legacy" data */ 497 uint8_t tcp_state; /* 23 TCP state machine info (below) */ 498 499 uint16_t application; /* 24-25 "Service" port set by collector */ 500 uint16_t memo; /* 26-27 Application specific field */ 501 502 uint16_t input; /* 28-29 Router incoming SNMP interface */ 503 uint16_t output; /* 30-31 Router outgoing SNMP interface */ 504 505 uint32_t pkts; /* 32-35 Count of packets */ 506 uint32_t bytes; /* 36-39 Count of bytes */ 507 508 skIPUnion_t sIP; /* 40-43 (or 40-55 if IPv6) Source IP */ 509 skIPUnion_t dIP; /* 44-47 (or 56-71 if IPv6) Destination IP */ 510 skIPUnion_t nhIP; /* 48-51 (or 72-87 if IPv6) Routr NextHop IP*/ 511 #endif /* RWREC_OPAQUE && !defined(RWREC_DEFINE_BODY) */ 512 }; 513 514 515 /* 516 ** Values for tcp_state value in rwGeneric and packed formats 517 */ 518 519 /* No additional TCP-state machine information is available */ 520 #define SK_TCPSTATE_NO_INFO 0x00 521 522 /* Expanded TCP-flags: This bit must be set if and only if the flow is 523 * TCP and the init_flags and rest_flags fields are valid. */ 524 #define SK_TCPSTATE_EXPANDED 0x01 525 526 /* Unused SK_TCPSTATE_ 0x02 */ 527 /* Unused SK_TCPSTATE_ 0x04 */ 528 529 /* Flow received packets following the FIN packet that were not ACK or 530 * RST packets. */ 531 #define SK_TCPSTATE_FIN_FOLLOWED_NOT_ACK 0x08 532 533 /* Flow has packets all of the same size */ 534 #define SK_TCPSTATE_UNIFORM_PACKET_SIZE 0x10 535 536 /* Flow ends prematurely due to a timeout by the collector. */ 537 #define SK_TCPSTATE_TIMEOUT_KILLED 0x20 538 539 /* Flow is a continuation of a previous flow that was killed 540 * prematurely due to a timeout by the collector. */ 541 #define SK_TCPSTATE_TIMEOUT_STARTED 0x40 542 543 /* Define a mask that returns the defined bits in tcpstate. This is 544 * used internally by rwRecGetTcpState(), rwRecSetTcpState() */ 545 #define SK_TCPSTATE_MASK 0x79 546 547 /* Define a mask that returns the attribute bits in tcpstate. */ 548 #define SK_TCPSTATE_ATTRIBUTE_MASK 0x78 549 550 /* Note: the most significant bit of tcp_state (0x80) is used as a 551 * flag to mark a record as having IPv6 addresses. */ 552 553 554 /* the sizeof the fields in an rwRec */ 555 #define RWREC_SIZEOF_SIPv4 4 556 #define RWREC_SIZEOF_DIPv4 4 557 #define RWREC_SIZEOF_NHIPv4 4 558 #define RWREC_SIZEOF_SPORT 2 559 #define RWREC_SIZEOF_DPORT 2 560 #define RWREC_SIZEOF_INPUT 2 561 #define RWREC_SIZEOF_OUTPUT 2 562 #define RWREC_SIZEOF_STIME 8 563 #define RWREC_SIZEOF_ELAPSED 4 564 #define RWREC_SIZEOF_PKTS 4 565 #define RWREC_SIZEOF_BYTES 4 566 #define RWREC_SIZEOF_PROTO 1 567 #define RWREC_SIZEOF_FLOW_TYPE 1 568 #define RWREC_SIZEOF_SID 2 569 #define RWREC_SIZEOF_FLAGS 1 570 #define RWREC_SIZEOF_INIT_FLAGS 1 571 #define RWREC_SIZEOF_REST_FLAGS 1 572 #define RWREC_SIZEOF_TCP_STATE 1 573 #define RWREC_SIZEOF_APPLICATION 2 574 #define RWREC_SIZEOF_MEMO 2 575 #define RWREC_SIZEOF_SIPv6 16 576 #define RWREC_SIZEOF_DIPv6 16 577 #define RWREC_SIZEOF_NHIPv6 16 578 579 #if !SK_ENABLE_IPV6 580 # define RWREC_SIZEOF_SIP RWREC_SIZEOF_SIPv4 581 # define RWREC_SIZEOF_DIP RWREC_SIZEOF_DIPv4 582 # define RWREC_SIZEOF_NHIP RWREC_SIZEOF_NHIPv4 583 #else 584 # define RWREC_SIZEOF_SIP RWREC_SIZEOF_SIPv6 585 # define RWREC_SIZEOF_DIP RWREC_SIZEOF_DIPv6 586 # define RWREC_SIZEOF_NHIP RWREC_SIZEOF_NHIPv6 587 #endif /* SK_ENABLE_IPV6 */ 588 589 590 /* Helper macros */ 591 #if 0 592 # define MEMCPY8(dst, src) { *((uint8_t*)(dst)) = *((uint8_t*)(src)); } 593 # define MEMCPY16(dst, src) { *((uint16_t*)(dst)) = *((uint16_t*)(src)); } 594 # define MEMCPY32(dst, src) { *((uint32_t*)(dst)) = *((uint32_t*)(src)); } 595 #else 596 # define MEMCPY8(dst, src) memcpy((dst), (src), sizeof(uint8_t)) 597 # define MEMCPY16(dst, src) memcpy((dst), (src), sizeof(uint16_t)) 598 # define MEMCPY32(dst, src) memcpy((dst), (src), sizeof(uint32_t)) 599 #endif 600 601 602 /*** Whether record is ICMP ***/ 603 604 #define rwRecIsICMP(r) \ 605 ((IPPROTO_ICMP == rwRecGetProto(r)) \ 606 || (rwRecIsIPv6(r) && (IPPROTO_ICMPV6 == rwRecGetProto(r)))) 607 608 609 /*** Whether record is WEB/HTTP ***/ 610 611 #define rwRecIsWeb(r) \ 612 ((IPPROTO_TCP == rwRecGetProto(r)) \ 613 && (SK_WEBPORT_CHECK(rwRecGetSPort(r)) \ 614 || SK_WEBPORT_CHECK(rwRecGetDPort(r)))) 615 616 617 /*** Whether record is IPv6 ***/ 618 619 #if !SK_ENABLE_IPV6 620 # define rwRecIsIPv6(r) 0 621 #else 622 623 int rwrec_IsIPv6(const rwRec *r); 624 void rwrec_SetIPv6(rwRec *r); 625 void rwrec_SetIPv4(rwRec *r); 626 627 #define _recIsIPv6(r) \ 628 (((r)->tcp_state & 0x80) ? 1 : 0) 629 #define _recSetIPv6(r) \ 630 { (r)->tcp_state |= 0x80; } 631 #define _recSetIPv4(r) \ 632 { (r)->tcp_state &= 0x7F; } 633 634 #if RWREC_OPAQUE 635 # define rwRecIsIPv6(r) rwrec_IsIPv6(r) 636 # define rwRecSetIPv6(r) rwrec_SetIPv6(r) 637 # define rwRecSetIPv4(r) rwrec_SetIPv4(r) 638 #else 639 # define rwRecIsIPv6(r) _recIsIPv6(r) 640 # define rwRecSetIPv6(r) _recSetIPv6(r) 641 # define rwRecSetIPv4(r) _recSetIPv4(r) 642 #endif /* RWREC_OPAQUE */ 643 644 #endif /* SK_ENABLE_IPV6 */ 645 646 647 /*** Convert a Record to IPv6 or IPv4 ***/ 648 649 #if SK_ENABLE_IPV6 650 651 void rwrec_ConvertToIPv6(rwRec *r); 652 int rwrec_ConvertToIPv4(rwRec *r); 653 654 #define _recConvertToIPv6(r) \ 655 { \ 656 skIPUnion4to6(&(r)->sIP, &(r)->sIP); \ 657 skIPUnion4to6(&(r)->dIP, &(r)->dIP); \ 658 skIPUnion4to6(&(r)->nhIP, &(r)->nhIP); \ 659 _recSetIPv6(r); \ 660 } 661 662 #if RWREC_OPAQUE 663 # define rwRecConvertToIPv6(r) rwrec_ConvertToIPv6(r) 664 # define rwRecConvertToIPv4(r) rwrec_ConvertToIPv4(r) 665 #else 666 # define rwRecConvertToIPv6(r) _recConvertToIPv6(r) 667 # define rwRecConvertToIPv4(r) rwrec_ConvertToIPv4(r) 668 #endif /* RWREC_OPAQUE */ 669 670 #endif /* SK_ENABLE_IPV6 */ 671 672 673 /*** Source IPv4 Address (sIP) ***/ 674 675 uint32_t rwrec_GetSIPv4(const rwRec *r); 676 void rwrec_SetSIPv4(rwRec *r, uint32_t in_v); 677 void rwrec_MemGetSIPv4(const rwRec *r, void *out_vp); 678 void rwrec_MemSetSIPv4(rwRec *r, const void *in_vp); 679 int rwrec_MemCmpSIPv4(const rwRec *r, const void *vp); 680 uint32_t rwrec_GetMaskSIPv4(const rwRec *r, uint32_t mask); 681 void rwrec_ApplyMaskSIPv4(rwRec *r, uint32_t mask); 682 683 #define _recGetSIPv4(r) \ 684 ((r)->sIP.ipu_ipv4) 685 #define _recSetSIPv4(r, in_v) \ 686 { ((r)->sIP.ipu_ipv4) = (in_v); } 687 #define _recMemGetSIPv4(r, out_vp) \ 688 memcpy((out_vp), &((r)->sIP.ipu_ipv4), RWREC_SIZEOF_SIPv4) 689 #define _recMemSetSIPv4(r, in_vp) \ 690 memcpy(&((r)->sIP.ipu_ipv4), (in_vp), RWREC_SIZEOF_SIPv4) 691 #define _recMemCmpSIPv4(r, vp) \ 692 memcmp(&((r)->sIP.ipu_ipv4), (vp), RWREC_SIZEOF_SIPv4) 693 #define _recGetMaskSIPv4(r, mask) \ 694 (((r)->sIP.ipu_ipv4) & mask) 695 #define _recApplyMaskSIPv4(r, mask) \ 696 skIPUnionApplyMaskV4(&((r)->sIP), (mask)) 697 698 #if RWREC_OPAQUE 699 # define rwRecGetSIPv4(r) rwrec_GetSIPv4(r) 700 # define rwRecSetSIPv4(r, in_v) rwrec_SetSIPv4(r, in_v) 701 # define rwRecMemGetSIPv4(r, out_vp) rwrec_MemGetSIPv4(r, out_vp) 702 # define rwRecMemSetSIPv4(r, in_vp) rwrec_MemSetSIPv4(r, in_vp) 703 # define rwRecMemCmpSIPv4(r, vp) rwrec_MemCmpSIPv4(r, vp) 704 # define rwRecGetMaskSIPv4(r, mask) rwrec_GetMaskSIPv4(r, mask) 705 # define rwRecApplyMaskSIPv4(r, mask) rwrec_ApplyMaskSIPv4(r, mask) 706 #else 707 # define rwRecGetSIPv4(r) _recGetSIPv4(r) 708 # define rwRecSetSIPv4(r, in_v) _recSetSIPv4(r, in_v) 709 # define rwRecMemGetSIPv4(r, out_vp) _recMemGetSIPv4(r, out_vp) 710 # define rwRecMemSetSIPv4(r, in_vp) _recMemSetSIPv4(r, in_vp) 711 # define rwRecMemCmpSIPv4(r, vp) _recMemCmpSIPv4(r, vp) 712 # define rwRecGetMaskSIPv4(r, mask) _recGetMaskSIPv4(r, mask) 713 # define rwRecApplyMaskSIPv4(r, mask) _recApplyMaskSIPv4(r, mask) 714 #endif /* RWREC_OPAQUE */ 715 716 717 /*** Source IPv6 Address (sIP) ***/ 718 719 #if SK_ENABLE_IPV6 720 721 void rwrec_MemGetSIPv6(const rwRec *r, void *out_vp); 722 void rwrec_MemSetSIPv6(rwRec *r, const void *in_vp); 723 int rwrec_MemCmpSIPv6(const rwRec *r, const void *vp); 724 void rwrec_ApplyMaskSIPv6(rwRec *r, const void *mask_vp); 725 726 #define _recMemGetSIPv6(r, out_vp) \ 727 if (_recIsIPv6(r)) { \ 728 skIPUnionGetV6(&((r)->sIP), (out_vp)); \ 729 } else { \ 730 skIPUnionGetV4AsV6(&((r)->sIP), (out_vp)); \ 731 } 732 #define _recMemSetSIPv6(r, in_vp) \ 733 memcpy(&((r)->sIP.ipu_ipv6), (in_vp), RWREC_SIZEOF_SIPv6) 734 #define _recMemCmpSIPv6(r, vp) \ 735 memcmp(&((r)->sIP.ipu_ipv6), (vp), RWREC_SIZEOF_SIPv6) 736 #define _recApplyMaskSIPv6(r, mask) \ 737 skIPUnionApplyMaskV6(&((r)->sIP), (mask)) 738 739 #if RWREC_OPAQUE 740 # define rwRecMemGetSIPv6(r, out_vp) rwrec_MemGetSIPv6(r, out_vp) 741 # define rwRecMemSetSIPv6(r, in_vp) rwrec_MemSetSIPv6(r, in_vp) 742 # define rwRecMemCmpSIPv6(r, vp) rwrec_MemCmpSIPv6(r, vp) 743 # define rwRecApplyMaskSIPv6(r, mask) rwrec_ApplyMaskSIPv6(r, mask) 744 #else 745 # define rwRecMemGetSIPv6(r, out_vp) _recMemGetSIPv6(r, out_vp) 746 # define rwRecMemSetSIPv6(r, in_vp) _recMemSetSIPv6(r, in_vp) 747 # define rwRecMemCmpSIPv6(r, vp) _recMemCmpSIPv6(r, vp) 748 # define rwRecApplyMaskSIPv6(r, mask) _recApplyMaskSIPv6(r, mask) 749 #endif /* RWREC_OPAQUE */ 750 751 #endif /* SK_ENABLE_IPV6 */ 752 753 754 /*** Source IP Address (sIP) as skipaddr_t ***/ 755 756 void rwrec_MemGetSIP(const rwRec *r, skipaddr_t *out_addr); 757 void rwrec_MemSetSIP(rwRec *r, const skipaddr_t *in_addr); 758 int rwrec_MemCmpSIP(const rwRec *r, const skipaddr_t *addr); 759 void rwrec_ApplyMaskSIP(rwRec *r, const skipaddr_t *mask_addr); 760 761 #if !SK_ENABLE_IPV6 762 #define _recMemGetSIP _recMemGetSIPv4 763 #define _recMemSetSIP _recMemSetSIPv4 764 #define _recMemCmpSIP(r, addr) \ 765 _recMemCmpSIPv4((r), &((addr)->ip_ip.ipu_ipv4)) 766 #define _recApplyMaskSIP(r, addr) \ 767 _recApplyMaskSIPv4((r), (addr)->ip_ip.ipu_ipv4) 768 #else 769 #define _recMemGetSIP(r, out_addr) \ 770 do { \ 771 memcpy(out_addr, &((r)->sIP), sizeof(skIPUnion_t)); \ 772 skipaddrSetVersion((out_addr), _recIsIPv6(r)); \ 773 } while(0) 774 #define _recMemSetSIP(r, in_addr) \ 775 do { \ 776 if (skipaddrIsV6(in_addr) == _recIsIPv6(r)) { \ 777 /* both are either V4 or V6 */ \ 778 memcpy(&((r)->sIP), (in_addr), sizeof(skIPUnion_t)); \ 779 } else if (_recIsIPv6(r)) { \ 780 /* convert V4 IP to V6 */ \ 781 skIPUnion4to6(&((in_addr)->ip_ip), &((r)->sIP)); \ 782 } else { \ 783 /* must convert record to V6 */ \ 784 _recConvertToIPv6(r); \ 785 memcpy(&((r)->sIP), (in_addr), sizeof(skIPUnion_t)); \ 786 } \ 787 } while(0) 788 #define _recMemCmpSIP(r, addr) rwrec_MemCmpSIP(r, addr) 789 #define _recApplyMaskSIP(r, addr) rwrec_ApplyMaskSIP(r, addr) 790 #endif /* SK_ENABLE_IPV6 */ 791 792 #if RWREC_OPAQUE 793 # define rwRecMemGetSIP(r, out_addr) rwrec_MemGetSIP(r, out_addr) 794 # define rwRecMemSetSIP(r, in_addr) rwrec_MemSetSIP(r, in_addr) 795 # define rwRecMemCmpSIP(r, addr) rwrec_MemCmpSIP(r, addr) 796 # define rwRecApplyMaskSIP(r, addr) rwrec_ApplyMaskSIP(r, addr) 797 #else 798 # define rwRecMemGetSIP(r, out_addr) _recMemGetSIP(r, out_addr) 799 # define rwRecMemSetSIP(r, in_addr) _recMemSetSIP(r, in_addr) 800 # define rwRecMemCmpSIP(r, addr) _recMemCmpSIP(r, addr) 801 # define rwRecApplyMaskSIP(r, addr) _recApplyMaskSIP(r, addr) 802 #endif /* RWREC_OPAQUE */ 803 804 805 /*** Destination IP Address (dIP) ***/ 806 807 uint32_t rwrec_GetDIPv4(const rwRec *r); 808 void rwrec_SetDIPv4(rwRec *r, uint32_t in_v); 809 void rwrec_MemGetDIPv4(const rwRec *r, void *out_vp); 810 void rwrec_MemSetDIPv4(rwRec *r, const void *in_vp); 811 int rwrec_MemCmpDIPv4(const rwRec *r, const void *vp); 812 uint32_t rwrec_GetMaskDIPv4(const rwRec *r, uint32_t mask); 813 void rwrec_ApplyMaskDIPv4(rwRec *r, uint32_t mask); 814 815 #define _recGetDIPv4(r) \ 816 ((r)->dIP.ipu_ipv4) 817 #define _recSetDIPv4(r, in_v) \ 818 { ((r)->dIP.ipu_ipv4) = (in_v); } 819 #define _recMemGetDIPv4(r, out_vp) \ 820 memcpy((out_vp), &((r)->dIP.ipu_ipv4), RWREC_SIZEOF_DIPv4) 821 #define _recMemSetDIPv4(r, in_vp) \ 822 memcpy(&((r)->dIP.ipu_ipv4), (in_vp), RWREC_SIZEOF_DIPv4) 823 #define _recMemCmpDIPv4(r, vp) \ 824 memcmp(&((r)->dIP.ipu_ipv4), (vp), RWREC_SIZEOF_DIPv4) 825 #define _recGetMaskDIPv4(r, mask) \ 826 (((r)->dIP.ipu_ipv4) & mask) 827 #define _recApplyMaskDIPv4(r, mask) \ 828 skIPUnionApplyMaskV4(&((r)->dIP), (mask)) 829 830 831 #if RWREC_OPAQUE 832 # define rwRecGetDIPv4(r) rwrec_GetDIPv4(r) 833 # define rwRecSetDIPv4(r, in_v) rwrec_SetDIPv4(r, in_v) 834 # define rwRecMemGetDIPv4(r, out_vp) rwrec_MemGetDIPv4(r, out_vp) 835 # define rwRecMemSetDIPv4(r, in_vp) rwrec_MemSetDIPv4(r, in_vp) 836 # define rwRecMemCmpDIPv4(r, vp) rwrec_MemCmpDIPv4(r, vp) 837 # define rwRecGetMaskDIPv4(r, mask) rwrec_GetMaskDIPv4(r, mask) 838 # define rwRecApplyMaskDIPv4(r, mask) rwrec_ApplyMaskDIPv4(r, mask) 839 #else 840 # define rwRecGetDIPv4(r) _recGetDIPv4(r) 841 # define rwRecSetDIPv4(r, in_v) _recSetDIPv4(r, in_v) 842 # define rwRecMemGetDIPv4(r, out_vp) _recMemGetDIPv4(r, out_vp) 843 # define rwRecMemSetDIPv4(r, in_vp) _recMemSetDIPv4(r, in_vp) 844 # define rwRecMemCmpDIPv4(r, vp) _recMemCmpDIPv4(r, vp) 845 # define rwRecGetMaskDIPv4(r, mask) _recGetMaskDIPv4(r, mask) 846 # define rwRecApplyMaskDIPv4(r, mask) _recApplyMaskDIPv4(r, mask) 847 #endif /* RWREC_OPAQUE */ 848 849 850 /*** Destination IPv6 Address (dIP) ***/ 851 852 #if SK_ENABLE_IPV6 853 854 void rwrec_MemGetDIPv6(const rwRec *r, void *out_vp); 855 void rwrec_MemSetDIPv6(rwRec *r, const void *in_vp); 856 int rwrec_MemCmpDIPv6(const rwRec *r, const void *vp); 857 void rwrec_ApplyMaskDIPv6(rwRec *r, const void *mask_vp); 858 859 #define _recMemGetDIPv6(r, out_vp) \ 860 if (_recIsIPv6(r)) { \ 861 skIPUnionGetV6(&((r)->dIP), (out_vp)); \ 862 } else { \ 863 skIPUnionGetV4AsV6(&((r)->dIP), (out_vp)); \ 864 } 865 #define _recMemSetDIPv6(r, in_vp) \ 866 memcpy(&((r)->dIP.ipu_ipv6), (in_vp), RWREC_SIZEOF_DIPv6) 867 #define _recMemCmpDIPv6(r, vp) \ 868 memcmp(&((r)->dIP.ipu_ipv6), (vp), RWREC_SIZEOF_DIPv6) 869 #define _recApplyMaskDIPv6(r, mask) \ 870 skIPUnionApplyMaskV6(&((r)->dIP), (mask)) 871 872 #if RWREC_OPAQUE 873 # define rwRecMemGetDIPv6(r, out_vp) rwrec_MemGetDIPv6(r, out_vp) 874 # define rwRecMemSetDIPv6(r, in_vp) rwrec_MemSetDIPv6(r, in_vp) 875 # define rwRecMemCmpDIPv6(r, vp) rwrec_MemCmpDIPv6(r, vp) 876 # define rwRecApplyMaskDIPv6(r, mask) rwrec_ApplyMaskDIPv6(r, mask) 877 #else 878 # define rwRecMemGetDIPv6(r, out_vp) _recMemGetDIPv6(r, out_vp) 879 # define rwRecMemSetDIPv6(r, in_vp) _recMemSetDIPv6(r, in_vp) 880 # define rwRecMemCmpDIPv6(r, vp) _recMemCmpDIPv6(r, vp) 881 # define rwRecApplyMaskDIPv6(r, mask) _recApplyMaskDIPv6(r, mask) 882 #endif /* RWREC_OPAQUE */ 883 884 #endif /* SK_ENABLE_IPV6 */ 885 886 887 /*** Destination IP Address (dIP) as skipaddr_t ***/ 888 889 void rwrec_MemGetDIP(const rwRec *r, skipaddr_t *out_addr); 890 void rwrec_MemSetDIP(rwRec *r, const skipaddr_t *in_addr); 891 int rwrec_MemCmpDIP(const rwRec *r, const skipaddr_t *addr); 892 void rwrec_ApplyMaskDIP(rwRec *r, const skipaddr_t *mask_addr); 893 894 #if !SK_ENABLE_IPV6 895 #define _recMemGetDIP _recMemGetDIPv4 896 #define _recMemSetDIP _recMemSetDIPv4 897 #define _recMemCmpDIP(r, addr) \ 898 _recMemCmpDIPv4((r), &((addr)->ip_ip.ipu_ipv4)) 899 #define _recApplyMaskDIP(r, addr) \ 900 _recApplyMaskDIPv4((r), (addr)->ip_ip.ipu_ipv4) 901 #else 902 #define _recMemGetDIP(r, out_addr) \ 903 do { \ 904 memcpy(out_addr, &((r)->dIP), sizeof(skIPUnion_t)); \ 905 skipaddrSetVersion((out_addr), _recIsIPv6(r)); \ 906 } while(0) 907 #define _recMemSetDIP(r, in_addr) \ 908 do { \ 909 if (skipaddrIsV6(in_addr) == _recIsIPv6(r)) { \ 910 /* both are either V4 or V6 */ \ 911 memcpy(&((r)->dIP), (in_addr), sizeof(skIPUnion_t)); \ 912 } else if (_recIsIPv6(r)) { \ 913 /* convert V4 IP to V6 */ \ 914 skIPUnion4to6(&((in_addr)->ip_ip), &((r)->dIP)); \ 915 } else { \ 916 /* must convert record to V6 */ \ 917 _recConvertToIPv6(r); \ 918 memcpy(&((r)->dIP), (in_addr), sizeof(skIPUnion_t)); \ 919 } \ 920 } while(0) 921 #define _recMemCmpDIP(r, addr) rwrec_MemCmpDIP(r, addr) 922 #define _recApplyMaskDIP(r, addr) rwrec_ApplyMaskDIP(r, addr) 923 #endif /* SK_ENABLE_IPV6 */ 924 925 #if RWREC_OPAQUE 926 # define rwRecMemGetDIP(r, out_addr) rwrec_MemGetDIP(r, out_addr) 927 # define rwRecMemSetDIP(r, in_addr) rwrec_MemSetDIP(r, in_addr) 928 # define rwRecMemCmpDIP(r, addr) rwrec_MemCmpDIP(r, addr) 929 # define rwRecApplyMaskDIP(r, addr) rwrec_ApplyMaskDIP(r, addr) 930 #else 931 # define rwRecMemGetDIP(r, out_addr) _recMemGetDIP(r, out_addr) 932 # define rwRecMemSetDIP(r, in_addr) _recMemSetDIP(r, in_addr) 933 # define rwRecMemCmpDIP(r, addr) _recMemCmpDIP(r, addr) 934 # define rwRecApplyMaskDIP(r, addr) _recApplyMaskDIP(r, addr) 935 #endif /* RWREC_OPAQUE */ 936 937 938 /*** Next Hop IP (nhIP) Address ***/ 939 940 uint32_t rwrec_GetNhIPv4(const rwRec *r); 941 void rwrec_SetNhIPv4(rwRec *r, uint32_t in_v); 942 void rwrec_MemGetNhIPv4(const rwRec *r, void *out_vp); 943 void rwrec_MemSetNhIPv4(rwRec *r, const void *in_vp); 944 int rwrec_MemCmpNhIPv4(const rwRec *r, const void *vp); 945 uint32_t rwrec_GetMaskNhIPv4(const rwRec *r, uint32_t mask); 946 void rwrec_ApplyMaskNhIPv4(rwRec *r, uint32_t mask); 947 948 #define _recGetNhIPv4(r) \ 949 ((r)->nhIP.ipu_ipv4) 950 #define _recSetNhIPv4(r, in_v) \ 951 { ((r)->nhIP.ipu_ipv4) = (in_v); } 952 #define _recMemGetNhIPv4(r, out_vp) \ 953 memcpy((out_vp), &((r)->nhIP.ipu_ipv4), RWREC_SIZEOF_NHIPv4) 954 #define _recMemSetNhIPv4(r, in_vp) \ 955 memcpy(&((r)->nhIP.ipu_ipv4), (in_vp), RWREC_SIZEOF_NHIPv4) 956 #define _recMemCmpNhIPv4(r, vp) \ 957 memcmp(&((r)->nhIP.ipu_ipv4), (vp), RWREC_SIZEOF_NHIPv4) 958 #define _recGetMaskNhIPv4(r, mask) \ 959 (((r)->nhIP.ipu_ipv4) & mask) 960 #define _recApplyMaskNhIPv4(r, mask) \ 961 skIPUnionApplyMaskV4(&((r)->nhIP), (mask)) 962 963 964 #if RWREC_OPAQUE 965 # define rwRecGetNhIPv4(r) rwrec_GetNhIPv4(r) 966 # define rwRecSetNhIPv4(r, in_v) rwrec_SetNhIPv4(r, in_v) 967 # define rwRecMemGetNhIPv4(r, out_vp) rwrec_MemGetNhIPv4(r, out_vp) 968 # define rwRecMemSetNhIPv4(r, in_vp) rwrec_MemSetNhIPv4(r, in_vp) 969 # define rwRecMemCmpNhIPv4(r, vp) rwrec_MemCmpNhIPv4(r, vp) 970 # define rwRecGetMaskNhIPv4(r, mask) rwrec_GetMaskNhIPv4(r, mask) 971 # define rwRecApplyMaskNhIPv4(r, mask) rwrec_ApplyMaskNhIPv4(r, mask) 972 #else 973 # define rwRecGetNhIPv4(r) _recGetNhIPv4(r) 974 # define rwRecSetNhIPv4(r, in_v) _recSetNhIPv4(r, in_v) 975 # define rwRecMemGetNhIPv4(r, out_vp) _recMemGetNhIPv4(r, out_vp) 976 # define rwRecMemSetNhIPv4(r, in_vp) _recMemSetNhIPv4(r, in_vp) 977 # define rwRecMemCmpNhIPv4(r, vp) _recMemCmpNhIPv4(r, vp) 978 # define rwRecGetMaskNhIPv4(r, mask) _recGetMaskNhIPv4(r, mask) 979 # define rwRecApplyMaskNhIPv4(r, mask) _recApplyMaskNhIPv4(r, mask) 980 #endif /* RWREC_OPAQUE */ 981 982 983 /*** Next Hop IPv6 Address (nhIP) ***/ 984 985 #if SK_ENABLE_IPV6 986 987 void rwrec_MemGetNhIPv6(const rwRec *r, void *out_vp); 988 void rwrec_MemSetNhIPv6(rwRec *r, const void *in_vp); 989 int rwrec_MemCmpNhIPv6(const rwRec *r, const void *vp); 990 void rwrec_ApplyMaskNhIPv6(rwRec *r, const void *mask_vp); 991 992 #define _recMemGetNhIPv6(r, out_vp) \ 993 if (_recIsIPv6(r)) { \ 994 skIPUnionGetV6(&((r)->nhIP), (out_vp)); \ 995 } else { \ 996 skIPUnionGetV4AsV6(&((r)->nhIP), (out_vp)); \ 997 } 998 #define _recMemSetNhIPv6(r, in_vp) \ 999 memcpy(&((r)->nhIP.ipu_ipv6), (in_vp), RWREC_SIZEOF_NHIPv6) 1000 #define _recMemCmpNhIPv6(r, vp) \ 1001 memcmp(&((r)->nhIP.ipu_ipv6), (vp), RWREC_SIZEOF_NHIPv6) 1002 #define _recApplyMaskNhIPv6(r, mask) \ 1003 skIPUnionApplyMaskV6(&((r)->nhIP), (mask)) 1004 1005 #if RWREC_OPAQUE 1006 # define rwRecMemGetNhIPv6(r, out_vp) rwrec_MemGetNhIPv6(r, out_vp) 1007 # define rwRecMemSetNhIPv6(r, in_vp) rwrec_MemSetNhIPv6(r, in_vp) 1008 # define rwRecMemCmpNhIPv6(r, vp) rwrec_MemCmpNhIPv6(r, vp) 1009 # define rwRecApplyMaskNhIPv6(r, mask) rwrec_ApplyMaskNhIPv6(r, mask) 1010 #else 1011 # define rwRecMemGetNhIPv6(r, out_vp) _recMemGetNhIPv6(r, out_vp) 1012 # define rwRecMemSetNhIPv6(r, in_vp) _recMemSetNhIPv6(r, in_vp) 1013 # define rwRecMemCmpNhIPv6(r, vp) _recMemCmpNhIPv6(r, vp) 1014 # define rwRecApplyMaskNhIPv6(r, mask) _recApplyMaskNhIPv6(r, mask) 1015 #endif /* RWREC_OPAQUE */ 1016 1017 #endif /* SK_ENABLE_IPV6 */ 1018 1019 1020 /*** Next Hop IP Address (nhIP) as skipaddr_t ***/ 1021 1022 void rwrec_MemGetNhIP(const rwRec *r, skipaddr_t *out_addr); 1023 void rwrec_MemSetNhIP(rwRec *r, const skipaddr_t *in_addr); 1024 int rwrec_MemCmpNhIP(const rwRec *r, const skipaddr_t *addr); 1025 void rwrec_ApplyMaskNhIP(rwRec *r, const skipaddr_t *mask_addr); 1026 1027 #if !SK_ENABLE_IPV6 1028 #define _recMemGetNhIP _recMemGetNhIPv4 1029 #define _recMemSetNhIP _recMemSetNhIPv4 1030 #define _recMemCmpNhIP(r, addr) \ 1031 _recMemCmpNhIPv4((r), &((addr)->ip_ip.ipu_ipv4)) 1032 #define _recApplyMaskNhIP(r, addr) \ 1033 _recApplyMaskNhIPv4((r), (addr)->ip_ip.ipu_ipv4) 1034 #else 1035 #define _recMemGetNhIP(r, out_addr) \ 1036 do { \ 1037 memcpy(out_addr, &((r)->nhIP), sizeof(skIPUnion_t)); \ 1038 skipaddrSetVersion((out_addr), _recIsIPv6(r)); \ 1039 } while(0) 1040 #define _recMemSetNhIP(r, in_addr) \ 1041 do { \ 1042 if (skipaddrIsV6(in_addr) == _recIsIPv6(r)) { \ 1043 /* both are either V4 or V6 */ \ 1044 memcpy(&((r)->nhIP), (in_addr), sizeof(skIPUnion_t)); \ 1045 } else if (_recIsIPv6(r)) { \ 1046 /* convert V4 IP to V6 */ \ 1047 skIPUnion4to6(&((in_addr)->ip_ip), &((r)->nhIP)); \ 1048 } else { \ 1049 /* must convert record to V6 */ \ 1050 _recConvertToIPv6(r); \ 1051 memcpy(&((r)->nhIP), (in_addr), sizeof(skIPUnion_t)); \ 1052 } \ 1053 } while(0) 1054 #define _recMemCmpNhIP(r, addr) rwrec_MemCmpNhIP(r, addr) 1055 #define _recApplyMaskNhIP(r, addr) rwrec_ApplyMaskNhIP(r, addr) 1056 #endif /* SK_ENABLE_IPV6 */ 1057 1058 #if RWREC_OPAQUE 1059 # define rwRecMemGetNhIP(r, out_addr) rwrec_MemGetNhIP(r, out_addr) 1060 # define rwRecMemSetNhIP(r, in_addr) rwrec_MemSetNhIP(r, in_addr) 1061 # define rwRecMemCmpNhIP(r, addr) rwrec_MemCmpNhIP(r, addr) 1062 # define rwRecApplyMaskNhIP(r, addr) rwrec_ApplyMaskNhIP(r, addr) 1063 #else 1064 # define rwRecMemGetNhIP(r, out_addr) _recMemGetNhIP(r, out_addr) 1065 # define rwRecMemSetNhIP(r, in_addr) _recMemSetNhIP(r, in_addr) 1066 # define rwRecMemCmpNhIP(r, addr) _recMemCmpNhIP(r, addr) 1067 # define rwRecApplyMaskNhIP(r, addr) _recApplyMaskNhIP(r, addr) 1068 #endif /* RWREC_OPAQUE */ 1069 1070 1071 /*** Source Port (sPort) ***/ 1072 1073 uint16_t rwrec_GetSPort(const rwRec *r); 1074 void rwrec_SetSPort(rwRec *r, uint16_t in_v); 1075 void rwrec_MemGetSPort(const rwRec *r, void *out_vp); 1076 void rwrec_MemSetSPort(rwRec *r, const void *in_vp); 1077 int rwrec_MemCmpSPort(const rwRec *r, const void *vp); 1078 1079 #define _recGetSPort(r) \ 1080 ((r)->sPort) 1081 #define _recSetSPort(r, in_v) \ 1082 { ((r)->sPort) = (in_v); } 1083 #define _recMemGetSPort(r, out_vp) \ 1084 memcpy((out_vp), &((r)->sPort), RWREC_SIZEOF_SPORT) 1085 #define _recMemSetSPort(r, in_vp) \ 1086 memcpy(&((r)->sPort), (in_vp), RWREC_SIZEOF_SPORT) 1087 #define _recMemCmpSPort(r, vp) \ 1088 memcmp(&((r)->sPort), (vp), RWREC_SIZEOF_SPORT) 1089 1090 #if RWREC_OPAQUE 1091 # define rwRecGetSPort(r) rwrec_GetSPort(r) 1092 # define rwRecSetSPort(r, in_v) rwrec_SetSPort(r, in_v) 1093 # define rwRecMemGetSPort(r, out_vp) rwrec_MemGetSPort(r, out_vp) 1094 # define rwRecMemSetSPort(r, in_vp) rwrec_MemSetSPort(r, in_vp) 1095 # define rwRecMemCmpSPort(r, vp) rwrec_MemCmpSPort(r, vp) 1096 #else 1097 # define rwRecGetSPort(r) _recGetSPort(r) 1098 # define rwRecSetSPort(r, in_v) _recSetSPort(r, in_v) 1099 # define rwRecMemGetSPort(r, out_vp) _recMemGetSPort(r, out_vp) 1100 # define rwRecMemSetSPort(r, in_vp) _recMemSetSPort(r, in_vp) 1101 # define rwRecMemCmpSPort(r, vp) _recMemCmpSPort(r, vp) 1102 #endif /* RWREC_OPAQUE */ 1103 1104 1105 /*** Destination Port (dPort) ***/ 1106 1107 uint16_t rwrec_GetDPort(const rwRec *r); 1108 void rwrec_SetDPort(rwRec *r, uint16_t in_v); 1109 void rwrec_MemGetDPort(const rwRec *r, void *out_vp); 1110 void rwrec_MemSetDPort(rwRec *r, const void *in_vp); 1111 int rwrec_MemCmpDPort(const rwRec *r, const void *vp); 1112 1113 #define _recGetDPort(r) \ 1114 ((r)->dPort) 1115 #define _recSetDPort(r, in_v) \ 1116 { ((r)->dPort) = (in_v); } 1117 #define _recMemGetDPort(r, out_vp) \ 1118 memcpy((out_vp), &((r)->dPort), RWREC_SIZEOF_DPORT) 1119 #define _recMemSetDPort(r, in_vp) \ 1120 memcpy(&((r)->dPort), (in_vp), RWREC_SIZEOF_DPORT) 1121 #define _recMemCmpDPort(r, vp) \ 1122 memcmp(&((r)->dPort), (vp), RWREC_SIZEOF_DPORT) 1123 1124 #if RWREC_OPAQUE 1125 # define rwRecGetDPort(r) rwrec_GetDPort(r) 1126 # define rwRecSetDPort(r, in_v) rwrec_SetDPort(r, in_v) 1127 # define rwRecMemGetDPort(r, out_vp) rwrec_MemGetDPort(r, out_vp) 1128 # define rwRecMemSetDPort(r, in_vp) rwrec_MemSetDPort(r, in_vp) 1129 # define rwRecMemCmpDPort(r, vp) rwrec_MemCmpDPort(r, vp) 1130 #else 1131 # define rwRecGetDPort(r) _recGetDPort(r) 1132 # define rwRecSetDPort(r, in_v) _recSetDPort(r, in_v) 1133 # define rwRecMemGetDPort(r, out_vp) _recMemGetDPort(r, out_vp) 1134 # define rwRecMemSetDPort(r, in_vp) _recMemSetDPort(r, in_vp) 1135 # define rwRecMemCmpDPort(r, vp) _recMemCmpDPort(r, vp) 1136 #endif /* RWREC_OPAQUE */ 1137 1138 1139 /*** Protocol ***/ 1140 1141 uint8_t rwrec_GetProto(const rwRec *r); 1142 void rwrec_SetProto(rwRec *r, uint8_t in_v); 1143 void rwrec_MemGetProto(const rwRec *r, void *out_vp); 1144 void rwrec_MemSetProto(rwRec *r, const void *in_vp); 1145 int rwrec_MemCmpProto(const rwRec *r, const void *vp); 1146 1147 #define _recGetProto(r) \ 1148 ((r)->proto) 1149 #define _recSetProto(r, in_v) \ 1150 { ((r)->proto) = (in_v); } 1151 #define _recMemGetProto(r, out_vp) \ 1152 memcpy((out_vp), &((r)->proto), RWREC_SIZEOF_PROTO) 1153 #define _recMemSetProto(r, in_vp) \ 1154 memcpy(&((r)->proto), (in_vp), RWREC_SIZEOF_PROTO) 1155 #define _recMemCmpProto(r, vp) \ 1156 memcmp(&((r)->proto), (vp), RWREC_SIZEOF_PROTO) 1157 1158 #if RWREC_OPAQUE 1159 # define rwRecGetProto(r) rwrec_GetProto(r) 1160 # define rwRecSetProto(r, in_v) rwrec_SetProto(r, in_v) 1161 # define rwRecMemGetProto(r, out_vp) rwrec_MemGetProto(r, out_vp) 1162 # define rwRecMemSetProto(r, in_vp) rwrec_MemSetProto(r, in_vp) 1163 # define rwRecMemCmpProto(r, vp) rwrec_MemCmpProto(r, vp) 1164 #else 1165 # define rwRecGetProto(r) _recGetProto(r) 1166 # define rwRecSetProto(r, in_v) _recSetProto(r, in_v) 1167 # define rwRecMemGetProto(r, out_vp) _recMemGetProto(r, out_vp) 1168 # define rwRecMemSetProto(r, in_vp) _recMemSetProto(r, in_vp) 1169 # define rwRecMemCmpProto(r, vp) _recMemCmpProto(r, vp) 1170 #endif /* RWREC_OPAQUE */ 1171 1172 1173 /*** Packet Count (pkts) ***/ 1174 1175 uint32_t rwrec_GetPkts(const rwRec *r); 1176 void rwrec_SetPkts(rwRec *r, uint32_t in_v); 1177 void rwrec_MemGetPkts(const rwRec *r, void *out_vp); 1178 void rwrec_MemSetPkts(rwRec *r, const void *in_vp); 1179 int rwrec_MemCmpPkts(const rwRec *r, const void *vp); 1180 1181 #define _recGetPkts(r) \ 1182 ((r)->pkts) 1183 #define _recSetPkts(r, in_v) \ 1184 { ((r)->pkts) = (in_v); } 1185 #define _recMemGetPkts(r, out_vp) \ 1186 memcpy((out_vp), &((r)->pkts), RWREC_SIZEOF_PKTS) 1187 #define _recMemSetPkts(r, in_vp) \ 1188 memcpy(&((r)->pkts), (in_vp), RWREC_SIZEOF_PKTS) 1189 #define _recMemCmpPkts(r, vp) \ 1190 memcmp(&((r)->pkts), (vp), RWREC_SIZEOF_PKTS) 1191 1192 #if RWREC_OPAQUE 1193 # define rwRecGetPkts(r) rwrec_GetPkts(r) 1194 # define rwRecSetPkts(r, in_v) rwrec_SetPkts(r, in_v) 1195 # define rwRecMemGetPkts(r, out_vp) rwrec_MemGetPkts(r, out_vp) 1196 # define rwRecMemSetPkts(r, in_vp) rwrec_MemSetPkts(r, in_vp) 1197 # define rwRecMemCmpPkts(r, vp) rwrec_MemCmpPkts(r, vp) 1198 #else 1199 # define rwRecGetPkts(r) _recGetPkts(r) 1200 # define rwRecSetPkts(r, in_v) _recSetPkts(r, in_v) 1201 # define rwRecMemGetPkts(r, out_vp) _recMemGetPkts(r, out_vp) 1202 # define rwRecMemSetPkts(r, in_vp) _recMemSetPkts(r, in_vp) 1203 # define rwRecMemCmpPkts(r, vp) _recMemCmpPkts(r, vp) 1204 #endif /* RWREC_OPAQUE */ 1205 1206 1207 /*** Byte count ***/ 1208 1209 uint32_t rwrec_GetBytes(const rwRec *r); 1210 void rwrec_SetBytes(rwRec *r, uint32_t in_v); 1211 void rwrec_MemGetBytes(const rwRec *r, void *out_vp); 1212 void rwrec_MemSetBytes(rwRec *r, const void *in_vp); 1213 int rwrec_MemCmpBytes(const rwRec *r, const void *vp); 1214 1215 #define _recGetBytes(r) \ 1216 ((r)->bytes) 1217 #define _recSetBytes(r, in_v) \ 1218 { ((r)->bytes) = (in_v); } 1219 #define _recMemGetBytes(r, out_vp) \ 1220 memcpy((out_vp), &((r)->bytes), RWREC_SIZEOF_BYTES) 1221 #define _recMemSetBytes(r, in_vp) \ 1222 memcpy(&((r)->bytes), (in_vp), RWREC_SIZEOF_BYTES) 1223 #define _recMemCmpBytes(r, vp) \ 1224 memcmp(&((r)->bytes), (vp), RWREC_SIZEOF_BYTES) 1225 1226 #if RWREC_OPAQUE 1227 # define rwRecGetBytes(r) rwrec_GetBytes(r) 1228 # define rwRecSetBytes(r, in_v) rwrec_SetBytes(r, in_v) 1229 # define rwRecMemGetBytes(r, out_vp) rwrec_MemGetBytes(r, out_vp) 1230 # define rwRecMemSetBytes(r, in_vp) rwrec_MemSetBytes(r, in_vp) 1231 # define rwRecMemCmpBytes(r, vp) rwrec_MemCmpBytes(r, vp) 1232 #else 1233 # define rwRecGetBytes(r) _recGetBytes(r) 1234 # define rwRecSetBytes(r, in_v) _recSetBytes(r, in_v) 1235 # define rwRecMemGetBytes(r, out_vp) _recMemGetBytes(r, out_vp) 1236 # define rwRecMemSetBytes(r, in_vp) _recMemSetBytes(r, in_vp) 1237 # define rwRecMemCmpBytes(r, vp) _recMemCmpBytes(r, vp) 1238 #endif /* RWREC_OPAQUE */ 1239 1240 1241 /*** Bitwise OR of TCP Flags on ALL packets in flow ***/ 1242 1243 uint8_t rwrec_GetFlags(const rwRec *r); 1244 void rwrec_SetFlags(rwRec *r, uint8_t in_v); 1245 void rwrec_MemGetFlags(const rwRec *r, void *out_vp); 1246 void rwrec_MemSetFlags(rwRec *r, const void *in_vp); 1247 int rwrec_MemCmpFlags(const rwRec *r, const void *vp); 1248 1249 #define _recGetFlags(r) \ 1250 ((r)->flags) 1251 #define _recSetFlags(r, in_v) \ 1252 { ((r)->flags) = (in_v); } 1253 #define _recMemGetFlags(r, out_vp) \ 1254 memcpy((out_vp), &((r)->flags), RWREC_SIZEOF_FLAGS) 1255 #define _recMemSetFlags(r, in_vp) \ 1256 memcpy(&((r)->flags), (in_vp), RWREC_SIZEOF_FLAGS) 1257 #define _recMemCmpFlags(r, vp) \ 1258 memcmp(&((r)->flags), (vp), RWREC_SIZEOF_FLAGS) 1259 1260 #if RWREC_OPAQUE 1261 # define rwRecGetFlags(r) rwrec_GetFlags(r) 1262 # define rwRecSetFlags(r, in_v) rwrec_SetFlags(r, in_v) 1263 # define rwRecMemGetFlags(r, out_vp) rwrec_MemGetFlags(r, out_vp) 1264 # define rwRecMemSetFlags(r, in_vp) rwrec_MemSetFlags(r, in_vp) 1265 # define rwRecMemCmpFlags(r, vp) rwrec_MemCmpFlags(r, vp) 1266 #else 1267 # define rwRecGetFlags(r) _recGetFlags(r) 1268 # define rwRecSetFlags(r, in_v) _recSetFlags(r, in_v) 1269 # define rwRecMemGetFlags(r, out_vp) _recMemGetFlags(r, out_vp) 1270 # define rwRecMemSetFlags(r, in_vp) _recMemSetFlags(r, in_vp) 1271 # define rwRecMemCmpFlags(r, vp) _recMemCmpFlags(r, vp) 1272 #endif /* RWREC_OPAQUE */ 1273 1274 1275 /*** TCP Flags seen on initial packet of flow ***/ 1276 1277 uint8_t rwrec_GetInitFlags(const rwRec *r); 1278 void rwrec_SetInitFlags(rwRec *r, uint8_t in_v); 1279 void rwrec_MemGetInitFlags(const rwRec *r, void *out_vp); 1280 void rwrec_MemSetInitFlags(rwRec *r, const void *in_vp); 1281 int rwrec_MemCmpInitFlags(const rwRec *r, const void *vp); 1282 1283 #define _recGetInitFlags(r) \ 1284 ((r)->init_flags) 1285 #define _recSetInitFlags(r, in_v) \ 1286 { ((r)->init_flags) = (in_v); } 1287 #define _recMemGetInitFlags(r, out_vp) \ 1288 memcpy((out_vp), &((r)->init_flags), RWREC_SIZEOF_INIT_FLAGS) 1289 #define _recMemSetInitFlags(r, in_vp) \ 1290 memcpy(&((r)->init_flags), (in_vp), RWREC_SIZEOF_INIT_FLAGS) 1291 #define _recMemCmpInitFlags(r, vp) \ 1292 memcmp(&((r)->init_flags), (vp), RWREC_SIZEOF_INIT_FLAGS) 1293 1294 #if RWREC_OPAQUE 1295 # define rwRecGetInitFlags(r) rwrec_GetInitFlags(r) 1296 # define rwRecSetInitFlags(r, in_v) rwrec_SetInitFlags(r, in_v) 1297 # define rwRecMemGetInitFlags(r, out_vp) rwrec_MemGetInitFlags(r, out_vp) 1298 # define rwRecMemSetInitFlags(r, in_vp) rwrec_MemSetInitFlags(r, in_vp) 1299 # define rwRecMemCmpInitFlags(r, vp) rwrec_MemCmpInitFlags(r, vp) 1300 #else 1301 # define rwRecGetInitFlags(r) _recGetInitFlags(r) 1302 # define rwRecSetInitFlags(r, in_v) _recSetInitFlags(r, in_v) 1303 # define rwRecMemGetInitFlags(r, out_vp) _recMemGetInitFlags(r, out_vp) 1304 # define rwRecMemSetInitFlags(r, in_vp) _recMemSetInitFlags(r, in_vp) 1305 # define rwRecMemCmpInitFlags(r, vp) _recMemCmpInitFlags(r, vp) 1306 #endif /* RWREC_OPAQUE */ 1307 1308 1309 /*** Bitwise OR of TCP Flags on all packets in session except first ***/ 1310 1311 uint8_t rwrec_GetRestFlags(const rwRec *r); 1312 void rwrec_SetRestFlags(rwRec *r, uint8_t in_v); 1313 void rwrec_MemGetRestFlags(const rwRec *r, void *out_vp); 1314 void rwrec_MemSetRestFlags(rwRec *r, const void *in_vp); 1315 int rwrec_MemCmpRestFlags(const rwRec *r, const void *vp); 1316 1317 #define _recGetRestFlags(r) \ 1318 ((r)->rest_flags) 1319 #define _recSetRestFlags(r, in_v) \ 1320 { ((r)->rest_flags) = (in_v); } 1321 #define _recMemGetRestFlags(r, out_vp) \ 1322 memcpy((out_vp), &((r)->rest_flags), RWREC_SIZEOF_REST_FLAGS) 1323 #define _recMemSetRestFlags(r, in_vp) \ 1324 memcpy(&((r)->rest_flags), (in_vp), RWREC_SIZEOF_REST_FLAGS) 1325 #define _recMemCmpRestFlags(r, vp) \ 1326 memcmp(&((r)->rest_flags), (vp), RWREC_SIZEOF_REST_FLAGS) 1327 1328 #if RWREC_OPAQUE 1329 # define rwRecGetRestFlags(r) rwrec_GetRestFlags(r) 1330 # define rwRecSetRestFlags(r, in_v) rwrec_SetRestFlags(r, in_v) 1331 # define rwRecMemGetRestFlags(r, out_vp) rwrec_MemGetRestFlags(r, out_vp) 1332 # define rwRecMemSetRestFlags(r, in_vp) rwrec_MemSetRestFlags(r, in_vp) 1333 # define rwRecMemCmpRestFlags(r, vp) rwrec_MemCmpRestFlags(r, vp) 1334 #else 1335 # define rwRecGetRestFlags(r) _recGetRestFlags(r) 1336 # define rwRecSetRestFlags(r, in_v) _recSetRestFlags(r, in_v) 1337 # define rwRecMemGetRestFlags(r, out_vp) _recMemGetRestFlags(r, out_vp) 1338 # define rwRecMemSetRestFlags(r, in_vp) _recMemSetRestFlags(r, in_vp) 1339 # define rwRecMemCmpRestFlags(r, vp) _recMemCmpRestFlags(r, vp) 1340 #endif /* RWREC_OPAQUE */ 1341 1342 1343 /*** Start Time as milliseconds since UNIX epoch (sTime) ***/ 1344 1345 sktime_t rwrec_GetStartTime(const rwRec *r); 1346 void rwrec_SetStartTime(rwRec *r, sktime_t in_v); 1347 void rwrec_MemGetStartTime(const rwRec *r, void *out_vp); 1348 void rwrec_MemSetStartTime(rwRec *r, const void *in_vp); 1349 int rwrec_MemCmpStartTime(const rwRec *r, const void *vp); 1350 uint32_t rwrec_GetStartSeconds(const rwRec *r); 1351 void rwrec_MemGetStartSeconds(const rwRec *r, void *out_vp); 1352 1353 #define _recGetStartTime(r) \ 1354 ((r)->sTime) 1355 #define _recSetStartTime(r, in_v) \ 1356 { ((r)->sTime = (in_v)); } 1357 #define _recMemGetStartTime(r, out_vp) \ 1358 memcpy((out_vp), &((r)->sTime), RWREC_SIZEOF_STIME) 1359 #define _recMemSetStartTime(r, in_vp) \ 1360 memcpy(&((r)->sTime), (in_vp), RWREC_SIZEOF_STIME) 1361 #define _recMemCmpStartTime(r, vp) \ 1362 memcmp(&((r)->sTime), (vp), RWREC_SIZEOF_STIME) 1363 1364 #define _recGetStartSeconds(r) \ 1365 ((uint32_t)((r)->sTime / 1000)) 1366 #define _recMemGetStartSeconds(r, out_vp) { \ 1367 uint32_t _t = _recGetStartSeconds(r); \ 1368 memcpy((out_vp), &_t, sizeof(_t)); \ 1369 } 1370 1371 #if RWREC_OPAQUE 1372 # define rwRecGetStartTime(r) rwrec_GetStartTime(r) 1373 # define rwRecSetStartTime(r, in_v) rwrec_SetStartTime(r, in_v) 1374 # define rwRecMemGetStartTime(r, out_vp) rwrec_MemGetStartTime(r, out_vp) 1375 # define rwRecMemSetStartTime(r, in_vp) rwrec_MemSetStartTime(r, in_vp) 1376 # define rwRecMemCmpStartTime(r, vp) rwrec_MemCmpStartTime(r, vp) 1377 # define rwRecGetStartSeconds(r) rwrec_GetStartSeconds(r) 1378 # define rwRecMemGetStartSeconds(r, out_vp) \ 1379 rwrec_MemGetStartSeconds(r, out_vp) 1380 #else 1381 # define rwRecGetStartTime(r) _recGetStartTime(r) 1382 # define rwRecSetStartTime(r, in_v) _recSetStartTime(r, in_v) 1383 # define rwRecMemGetStartTime(r, out_vp) _recMemGetStartTime(r, out_vp) 1384 # define rwRecMemSetStartTime(r, in_vp) _recMemSetStartTime(r, in_vp) 1385 # define rwRecMemCmpStartTime(r, vp) _recMemCmpStartTime(r, vp) 1386 # define rwRecGetStartSeconds(r) _recGetStartSeconds(r) 1387 # define rwRecMemGetStartSeconds(r, out_vp) _recMemGetStartSeconds(r, out_vp) 1388 #endif /* RWREC_OPAQUE */ 1389 1390 1391 /*** Elapsed (duration) of the flow, in milliseconds ***/ 1392 1393 uint32_t rwrec_GetElapsed(const rwRec *r); 1394 void rwrec_SetElapsed(rwRec *r, sktime_t in_v); 1395 void rwrec_MemGetElapsed(const rwRec *r, void *out_vp); 1396 void rwrec_MemSetElapsed(rwRec *r, const void *in_vp); 1397 int rwrec_MemCmpElapsed(const rwRec *r, const void *vp); 1398 uint32_t rwrec_GetElapsedSeconds(const rwRec *r); 1399 void rwrec_MemGetElapsedSeconds(const rwRec *r, void *out_vp); 1400 1401 #define _recGetElapsed(r) \ 1402 ((r)->elapsed) 1403 #define _recSetElapsed(r, in_v) \ 1404 { (r)->elapsed = (uint32_t)(in_v); } 1405 #define _recMemGetElapsed(r, out_vp) \ 1406 memcpy((out_vp), &((r)->elapsed), RWREC_SIZEOF_ELAPSED) 1407 #define _recMemSetElapsed(r, in_vp) \ 1408 memcpy(&((r)->elapsed), (in_vp), RWREC_SIZEOF_ELAPSED) 1409 #define _recMemCmpElapsed(r, vp) \ 1410 memcmp(&((r)->elapsed), (vp), RWREC_SIZEOF_ELAPSED) 1411 1412 #define _recGetElapsedSeconds(r) \ 1413 ((uint32_t)((r)->elapsed / 1000)) 1414 #define _recMemGetElapsedSeconds(r, out_vp) { \ 1415 uint32_t _t = _recGetElapsedSeconds(r); \ 1416 memcpy((out_vp), &_t, sizeof(_t)); \ 1417 } 1418 1419 #if RWREC_OPAQUE 1420 # define rwRecGetElapsed(r) rwrec_GetElapsed(r) 1421 # define rwRecSetElapsed(r, in_v) rwrec_SetElapsed(r, in_v) 1422 # define rwRecMemGetElapsed(r, out_vp) rwrec_MemGetElapsed(r, out_vp) 1423 # define rwRecMemSetElapsed(r, in_vp) rwrec_MemSetElapsed(r, in_vp) 1424 # define rwRecMemCmpElapsed(r, vp) rwrec_MemCmpElapsed(r, vp) 1425 # define rwRecGetElapsedSeconds(r) rwrec_GetElapsedSeconds(r) 1426 # define rwRecMemGetElapsedSeconds(r, out_vp) \ 1427 rwrec_MemGetElapsedSeconds(r, out_vp) 1428 #else 1429 # define rwRecGetElapsed(r) _recGetElapsed(r) 1430 # define rwRecSetElapsed(r, in_v) _recSetElapsed(r, in_v) 1431 # define rwRecMemGetElapsed(r, out_vp) _recMemGetElapsed(r, out_vp) 1432 # define rwRecMemSetElapsed(r, in_vp) _recMemSetElapsed(r, in_vp) 1433 # define rwRecMemCmpElapsed(r, vp) _recMemCmpElapsed(r, vp) 1434 # define rwRecGetElapsedSeconds(r) _recGetElapsedSeconds(r) 1435 # define rwRecMemGetElapsedSeconds(r, out_vp) \ 1436 _recMemGetElapsedSeconds(r, out_vp) 1437 #endif /* RWREC_OPAQUE */ 1438 1439 1440 1441 /*** End Time is derived from the sTime and duration (eTime) ***/ 1442 1443 /* No Set macros/functions since this is a derived field */ 1444 1445 sktime_t rwrec_GetEndTime(const rwRec *r); 1446 void rwrec_MemGetEndTime(const rwRec *r, void *out_vp); 1447 uint32_t rwrec_GetEndSeconds(const rwRec *r); 1448 void rwrec_MemGetEndSeconds(const rwRec *r, void *out_vp); 1449 1450 #define _recGetEndTime(r) \ 1451 ((sktime_t)_recGetStartTime(r) + _recGetElapsed(r)) 1452 #define _recMemGetEndTime(r, out_vp) { \ 1453 sktime_t _t = _recGetEndTime(r); \ 1454 memcpy((out_vp), &_t, sizeof(_t)); \ 1455 } 1456 #define _recGetEndSeconds(r) \ 1457 ((uint32_t)(_recGetEndTime(r) / 1000)) 1458 #define _recMemGetEndSeconds(r, out_vp) { \ 1459 uint32_t _t = rwRecGetEndSeconds(r); \ 1460 memcpy((out_vp), &_t, sizeof(_t)); \ 1461 } 1462 1463 #if RWREC_OPAQUE 1464 # define rwRecGetEndTime(r) rwrec_GetEndTime(r) 1465 # define rwRecMemGetEndTime(r, out_vp) rwrec_MemGetEndTime(r, out_vp) 1466 # define rwRecGetEndSeconds(r) rwrec_GetEndSeconds(r) 1467 # define rwRecMemGetEndSeconds(r, out_vp) rwrec_MemGetEndSeconds(r, out_vp) 1468 #else 1469 # define rwRecGetEndTime(r) _recGetEndTime(r) 1470 # define rwRecMemGetEndTime(r, out_vp) _recMemGetEndTime(r, out_vp) 1471 # define rwRecGetEndSeconds(r) _recGetEndSeconds(r) 1472 # define rwRecMemGetEndSeconds(r, out_vp) _recMemGetEndSeconds(r, out_vp) 1473 #endif /* RWREC_OPAQUE */ 1474 1475 1476 /*** Sensor ID (sID) ***/ 1477 1478 sk_sensor_id_t rwrec_GetSensor(const rwRec *r); 1479 void rwrec_SetSensor(rwRec *r, sk_sensor_id_t in_v); 1480 void rwrec_MemGetSensor(const rwRec *r, void *out_vp); 1481 void rwrec_MemSetSensor(rwRec *r, const void *in_vp); 1482 int rwrec_MemCmpSensor(const rwRec *r, const void *vp); 1483 1484 #define _recGetSensor(r) \ 1485 ((r)->sID) 1486 #define _recSetSensor(r, in_v) \ 1487 { ((r)->sID) = (in_v); } 1488 #define _recMemGetSensor(r, out_vp) \ 1489 memcpy((out_vp), &((r)->sID), RWREC_SIZEOF_SID) 1490 #define _recMemSetSensor(r, in_vp) \ 1491 memcpy(&((r)->sID), (in_vp), RWREC_SIZEOF_SID) 1492 #define _recMemCmpSensor(r, vp) \ 1493 memcmp(&((r)->sID), (vp), RWREC_SIZEOF_SID) 1494 1495 #if RWREC_OPAQUE 1496 # define rwRecGetSensor(r) rwrec_GetSensor(r) 1497 # define rwRecSetSensor(r, in_v) rwrec_SetSensor(r, in_v) 1498 # define rwRecMemGetSensor(r, out_vp) rwrec_MemGetSensor(r, out_vp) 1499 # define rwRecMemSetSensor(r, in_vp) rwrec_MemSetSensor(r, in_vp) 1500 # define rwRecMemCmpSensor(r, vp) rwrec_MemCmpSensor(r, vp) 1501 #else 1502 # define rwRecGetSensor(r) _recGetSensor(r) 1503 # define rwRecSetSensor(r, in_v) _recSetSensor(r, in_v) 1504 # define rwRecMemGetSensor(r, out_vp) _recMemGetSensor(r, out_vp) 1505 # define rwRecMemSetSensor(r, in_vp) _recMemSetSensor(r, in_vp) 1506 # define rwRecMemCmpSensor(r, vp) _recMemCmpSensor(r, vp) 1507 #endif /* RWREC_OPAQUE */ 1508 1509 1510 /*** FlowType holds Class and Type ***/ 1511 1512 sk_flowtype_id_t rwrec_GetFlowType(const rwRec *r); 1513 void rwrec_SetFlowType(rwRec *r, sk_flowtype_id_t in_v); 1514 void rwrec_MemGetFlowType(const rwRec *r, void *out_vp); 1515 void rwrec_MemSetFlowType(rwRec *r, const void *in_vp); 1516 int rwrec_MemCmpFlowType(const rwRec *r, const void *vp); 1517 1518 #define _recGetFlowType(r) \ 1519 ((r)->flow_type) 1520 #define _recSetFlowType(r, in_v) \ 1521 { ((r)->flow_type) = (in_v); } 1522 #define _recMemGetFlowType(r, out_vp) \ 1523 memcpy((out_vp), &((r)->flow_type), RWREC_SIZEOF_FLOW_TYPE) 1524 #define _recMemSetFlowType(r, in_vp) \ 1525 memcpy(&((r)->flow_type), (in_vp), RWREC_SIZEOF_FLOW_TYPE) 1526 #define _recMemCmpFlowType(r, vp) \ 1527 memcmp(&((r)->flow_type), (vp), RWREC_SIZEOF_FLOW_TYPE) 1528 1529 #if RWREC_OPAQUE 1530 # define rwRecGetFlowType(r) rwrec_GetFlowType(r) 1531 # define rwRecSetFlowType(r, in_v) rwrec_SetFlowType(r, in_v) 1532 # define rwRecMemGetFlowType(r, out_vp) rwrec_MemGetFlowType(r, out_vp) 1533 # define rwRecMemSetFlowType(r, in_vp) rwrec_MemSetFlowType(r, in_vp) 1534 # define rwRecMemCmpFlowType(r, vp) rwrec_MemCmpFlowType(r, vp) 1535 #else 1536 # define rwRecGetFlowType(r) _recGetFlowType(r) 1537 # define rwRecSetFlowType(r, in_v) _recSetFlowType(r, in_v) 1538 # define rwRecMemGetFlowType(r, out_vp) _recMemGetFlowType(r, out_vp) 1539 # define rwRecMemSetFlowType(r, in_vp) _recMemSetFlowType(r, in_vp) 1540 # define rwRecMemCmpFlowType(r, vp) _recMemCmpFlowType(r, vp) 1541 #endif /* RWREC_OPAQUE */ 1542 1543 1544 /*** SNMP Input Value (Router incoming/ingress interface) ***/ 1545 1546 uint16_t rwrec_GetInput(const rwRec *r); 1547 void rwrec_SetInput(rwRec *r, uint16_t in_v); 1548 void rwrec_MemGetInput(const rwRec *r, void *out_vp); 1549 void rwrec_MemSetInput(rwRec *r, const void *in_vp); 1550 int rwrec_MemCmpInput(const rwRec *r, const void *vp); 1551 1552 #define _recGetInput(r) \ 1553 ((r)->input) 1554 #define _recSetInput(r, in_v) \ 1555 { ((r)->input) = (in_v); } 1556 #define _recMemGetInput(r, out_vp) \ 1557 memcpy((out_vp), &((r)->input), RWREC_SIZEOF_INPUT) 1558 #define _recMemSetInput(r, in_vp) \ 1559 memcpy(&((r)->input), (in_vp), RWREC_SIZEOF_INPUT) 1560 #define _recMemCmpInput(r, vp) \ 1561 memcmp(&((r)->input), (vp), RWREC_SIZEOF_INPUT) 1562 1563 #if RWREC_OPAQUE 1564 # define rwRecGetInput(r) rwrec_GetInput(r) 1565 # define rwRecSetInput(r, in_v) rwrec_SetInput(r, in_v) 1566 # define rwRecMemGetInput(r, out_vp) rwrec_MemGetInput(r, out_vp) 1567 # define rwRecMemSetInput(r, in_vp) rwrec_MemSetInput(r, in_vp) 1568 # define rwRecMemCmpInput(r, vp) rwrec_MemCmpInput(r, vp) 1569 #else 1570 # define rwRecGetInput(r) _recGetInput(r) 1571 # define rwRecSetInput(r, in_v) _recSetInput(r, in_v) 1572 # define rwRecMemGetInput(r, out_vp) _recMemGetInput(r, out_vp) 1573 # define rwRecMemSetInput(r, in_vp) _recMemSetInput(r, in_vp) 1574 # define rwRecMemCmpInput(r, vp) _recMemCmpInput(r, vp) 1575 #endif /* RWREC_OPAQUE */ 1576 1577 1578 /*** SNMP Output Value (Router outgoing/egress interface) ***/ 1579 1580 uint16_t rwrec_GetOutput(const rwRec *r); 1581 void rwrec_SetOutput(rwRec *r, uint16_t in_v); 1582 void rwrec_MemGetOutput(const rwRec *r, void *out_vp); 1583 void rwrec_MemSetOutput(rwRec *r, const void *in_vp); 1584 int rwrec_MemCmpOutput(const rwRec *r, const void *vp); 1585 1586 #define _recGetOutput(r) \ 1587 ((r)->output) 1588 #define _recSetOutput(r, in_v) \ 1589 { ((r)->output) = (in_v); } 1590 #define _recMemGetOutput(r, out_vp) \ 1591 memcpy((out_vp), &((r)->output), RWREC_SIZEOF_OUTPUT) 1592 #define _recMemSetOutput(r, in_vp) \ 1593 memcpy(&((r)->output), (in_vp), RWREC_SIZEOF_OUTPUT) 1594 #define _recMemCmpOutput(r, vp) \ 1595 memcmp(&((r)->output), (vp), RWREC_SIZEOF_OUTPUT) 1596 1597 #if RWREC_OPAQUE 1598 # define rwRecGetOutput(r) rwrec_GetOutput(r) 1599 # define rwRecSetOutput(r, in_v) rwrec_SetOutput(r, in_v) 1600 # define rwRecMemGetOutput(r, out_vp) rwrec_MemGetOutput(r, out_vp) 1601 # define rwRecMemSetOutput(r, in_vp) rwrec_MemSetOutput(r, in_vp) 1602 # define rwRecMemCmpOutput(r, vp) rwrec_MemCmpOutput(r, vp) 1603 #else 1604 # define rwRecGetOutput(r) _recGetOutput(r) 1605 # define rwRecSetOutput(r, in_v) _recSetOutput(r, in_v) 1606 # define rwRecMemGetOutput(r, out_vp) _recMemGetOutput(r, out_vp) 1607 # define rwRecMemSetOutput(r, in_vp) _recMemSetOutput(r, in_vp) 1608 # define rwRecMemCmpOutput(r, vp) _recMemCmpOutput(r, vp) 1609 #endif /* RWREC_OPAQUE */ 1610 1611 1612 /*** TCP State ***/ 1613 1614 uint8_t rwrec_GetTcpState(const rwRec *r); 1615 void rwrec_SetTcpState(rwRec *r, uint8_t in_v); 1616 void rwrec_MemGetTcpState(const rwRec *r, void *out_vp); 1617 void rwrec_MemSetTcpState(rwRec *r, const void *in_vp); 1618 int rwrec_MemCmpTcpState(const rwRec *r, const void *vp); 1619 1620 #define _recGetTcpState(r) \ 1621 ((uint8_t)((r)->tcp_state & SK_TCPSTATE_MASK)) 1622 #define _recSetTcpState(r, in_v) \ 1623 { ((r)->tcp_state) \ 1624 = ((r)->tcp_state & 0x80) | (SK_TCPSTATE_MASK & (in_v)); } 1625 #define _recMemGetTcpState(r, out_vp) \ 1626 { *((uint8_t*)(out_vp)) = _recGetTcpState(r); } 1627 #define _recMemSetTcpState(r, in_vp) \ 1628 _recSetTcpState((r), *((uint8_t*)(in_vp))) 1629 #define _recMemCmpTcpState(r, vp) \ 1630 ((int)(_recGetTcpState(r) \ 1631 - (uint8_t)(SK_TCPSTATE_MASK & *((uint8_t*)(vp))))) 1632 1633 #if RWREC_OPAQUE 1634 # define rwRecGetTcpState(r) rwrec_GetTcpState(r) 1635 # define rwRecSetTcpState(r, in_v) rwrec_SetTcpState(r, in_v) 1636 # define rwRecMemGetTcpState(r, out_vp) rwrec_MemGetTcpState(r, out_vp) 1637 # define rwRecMemSetTcpState(r, in_vp) rwrec_MemSetTcpState(r, in_vp) 1638 # define rwRecMemCmpTcpState(r, vp) rwrec_MemCmpTcpState(r, vp) 1639 #else 1640 # define rwRecGetTcpState(r) _recGetTcpState(r) 1641 # define rwRecSetTcpState(r, in_v) _recSetTcpState(r, in_v) 1642 # define rwRecMemGetTcpState(r, out_vp) _recMemGetTcpState(r, out_vp) 1643 # define rwRecMemSetTcpState(r, in_vp) _recMemSetTcpState(r, in_vp) 1644 # define rwRecMemCmpTcpState(r, vp) _recMemCmpTcpState(r, vp) 1645 #endif /* RWREC_OPAQUE */ 1646 1647 1648 /*** Application ***/ 1649 1650 uint16_t rwrec_GetApplication(const rwRec *r); 1651 void rwrec_SetApplication(rwRec *r, uint16_t in_v); 1652 void rwrec_MemGetApplication(const rwRec *r, void *out_vp); 1653 void rwrec_MemSetApplication(rwRec *r, const void *in_vp); 1654 int rwrec_MemCmpApplication(const rwRec *r, const void *vp); 1655 1656 #define _recGetApplication(r) \ 1657 ((r)->application) 1658 #define _recSetApplication(r, in_v) \ 1659 { ((r)->application) = (in_v); } 1660 #define _recMemGetApplication(r, out_vp) \ 1661 memcpy((out_vp), &((r)->application), RWREC_SIZEOF_APPLICATION) 1662 #define _recMemSetApplication(r, in_vp) \ 1663 memcpy(&((r)->application), (in_vp), RWREC_SIZEOF_APPLICATION) 1664 #define _recMemCmpApplication(r, vp) \ 1665 memcmp(&((r)->application), (vp), RWREC_SIZEOF_APPLICATION) 1666 1667 #if RWREC_OPAQUE 1668 # define rwRecGetApplication(r) rwrec_GetApplication(r) 1669 # define rwRecSetApplication(r, in_v) rwrec_SetApplication(r, in_v) 1670 # define rwRecMemGetApplication(r, out_vp) rwrec_MemGetApplication(r, out_vp) 1671 # define rwRecMemSetApplication(r, in_vp) rwrec_MemSetApplication(r, in_vp) 1672 # define rwRecMemCmpApplication(r, vp) rwrec_MemCmpApplication(r, vp) 1673 #else 1674 # define rwRecGetApplication(r) _recGetApplication(r) 1675 # define rwRecSetApplication(r, in_v) _recSetApplication(r, in_v) 1676 # define rwRecMemGetApplication(r, out_vp) _recMemGetApplication(r, out_vp) 1677 # define rwRecMemSetApplication(r, in_vp) _recMemSetApplication(r, in_vp) 1678 # define rwRecMemCmpApplication(r, vp) _recMemCmpApplication(r, vp) 1679 #endif /* RWREC_OPAQUE */ 1680 1681 1682 /*** Memo ***/ 1683 1684 uint16_t rwrec_GetMemo(const rwRec *r); 1685 void rwrec_SetMemo(rwRec *r, uint16_t in_v); 1686 void rwrec_MemGetMemo(const rwRec *r, void *out_vp); 1687 void rwrec_MemSetMemo(rwRec *r, const void *in_vp); 1688 int rwrec_MemCmpMemo(const rwRec *r, const void *vp); 1689 1690 #define _recGetMemo(r) \ 1691 ((r)->memo) 1692 #define _recSetMemo(r, in_v) \ 1693 { ((r)->memo) = (in_v); } 1694 #define _recMemGetMemo(r, out_vp) \ 1695 memcpy((out_vp), &((r)->memo), RWREC_SIZEOF_MEMO) 1696 #define _recMemSetMemo(r, in_vp) \ 1697 memcpy(&((r)->memo), (in_vp), RWREC_SIZEOF_MEMO) 1698 #define _recMemCmpMemo(r, vp) \ 1699 memcmp(&((r)->memo), (vp), RWREC_SIZEOF_MEMO) 1700 1701 #if RWREC_OPAQUE 1702 # define rwRecGetMemo(r) rwrec_GetMemo(r) 1703 # define rwRecSetMemo(r, in_v) rwrec_SetMemo(r, in_v) 1704 # define rwRecMemGetMemo(r, out_vp) rwrec_MemGetMemo(r, out_vp) 1705 # define rwRecMemSetMemo(r, in_vp) rwrec_MemSetMemo(r, in_vp) 1706 # define rwRecMemCmpMemo(r, vp) rwrec_MemCmpMemo(r, vp) 1707 #else 1708 # define rwRecGetMemo(r) _recGetMemo(r) 1709 # define rwRecSetMemo(r, in_v) _recSetMemo(r, in_v) 1710 # define rwRecMemGetMemo(r, out_vp) _recMemGetMemo(r, out_vp) 1711 # define rwRecMemSetMemo(r, in_vp) _recMemSetMemo(r, in_vp) 1712 # define rwRecMemCmpMemo(r, vp) _recMemCmpMemo(r, vp) 1713 #endif /* RWREC_OPAQUE */ 1714 1715 1716 /*** ICMP Type and Code is derived from the DPort ***/ 1717 1718 /* 1719 * In NetFlow, Cisco has traditionally encoded the ICMP type and 1720 * code in the destination port field as (type << 8 | code). 1721 * The following macros assume this Cisco-encoding. 1722 * 1723 * Due to various issues, sometimes the ICMP type and code is 1724 * encoded in the source port instead of the destination port. As 1725 * of SiLK-3.4.0, libsilk (skstream.c) handles these incorrect 1726 * encodings when the record is read and modifies the record to use 1727 * the traditional Cisco encoding. 1728 * 1729 * The following functions/macros do not check the protocol. 1730 */ 1731 uint8_t rwrec_GetIcmpType(const rwRec *r); 1732 void rwrec_SetIcmpType(rwRec *r, uint8_t in_v); 1733 void rwrec_MemGetIcmpType(const rwRec *r, void *out_vp); 1734 uint8_t rwrec_GetIcmpCode(const rwRec *r); 1735 void rwrec_SetIcmpCode(rwRec *r, uint8_t in_v); 1736 void rwrec_MemGetIcmpCode(const rwRec *r, void *out_vp); 1737 1738 uint16_t rwrec_GetIcmpTypeAndCode(const rwRec *r); 1739 void rwrec_SetIcmpTypeAndCode(rwRec *r, uint16_t in_v); 1740 void rwrec_MemGetIcmpTypeAndCode(const rwRec *r, void *out_vp); 1741 void rwrec_MemSetIcmpTypeAndCode(rwRec *r, const void *in_vp); 1742 int rwrec_MemCmpIcmpTypeAndCode(const rwRec *r, const void *vp); 1743 1744 #define _recGetIcmpTypeAndCode(r) _recGetDPort(r) 1745 #define _recSetIcmpTypeAndCode(r, in_v) _recSetDPort(r, in_v) 1746 #define _recMemGetIcmpTypeAndCode(r, out_vp) _recMemGetDPort(r, out_vp) 1747 #define _recMemSetIcmpTypeAndCode(r, in_vp) _recMemSetDPort(r, in_vp) 1748 #define _recMemCmpIcmpTypeAndCode(r, vp) _recMemCmpDPort(r, vp) 1749 1750 #define _recGetIcmpType(r) \ 1751 ((uint8_t)(0xFF & (_recGetIcmpTypeAndCode(r) >> 8))) 1752 #define _recSetIcmpType(r, in_v) \ 1753 _recSetIcmpTypeAndCode(r, ((_recGetIcmpTypeAndCode(r) & 0x00FF) \ 1754 | (((in_v) & 0xFF) << 8))) 1755 #define _recMemGetIcmpType(r, out_vp) \ 1756 { *out_vp = _recGetIcmpType(r); } 1757 1758 #define _recGetIcmpCode(r) \ 1759 ((uint8_t)(0xFF & _recGetIcmpTypeAndCode(r))) 1760 #define _recSetIcmpCode(r, in_v) \ 1761 _recSetIcmpTypeAndCode(r, ((_recGetIcmpTypeAndCode(r) & 0xFF00) \ 1762 | ((in_v) & 0xFF))) 1763 #define _recMemGetIcmpCode(r, out_vp) \ 1764 { *out_vp = _recGetIcmpCode(r); } 1765 1766 #if RWREC_OPAQUE 1767 # define rwRecGetIcmpType(r) rwrec_GetIcmpType(r) 1768 # define rwRecSetIcmpType(r, in_v) rwrec_SetIcmpType(r, in_v) 1769 # define rwRecMemGetIcmpType(r, out_vp) rwrec_MemGetIcmpType(r, out_vp) 1770 1771 # define rwRecGetIcmpCode(r) rwrec_GetIcmpCode(r) 1772 # define rwRecSetIcmpCode(r, in_v) rwrec_SetIcmpCode(r, in_v) 1773 # define rwRecMemGetIcmpCode(r, out_vp) rwrec_MemGetIcmpCode(r, out_vp) 1774 1775 # define rwRecGetIcmpTypeAndCode(r) rwrec_GetIcmpTypeAndCode(r) 1776 # define rwRecSetIcmpTypeAndCode(r, in_v) rwrec_SetIcmpTypeAndCode(r, in_v) 1777 # define rwRecMemGetIcmpTypeAndCode(r, out_vp) \ 1778 rwrec_MemGetIcmpTypeAndCode(r, out_vp) 1779 # define rwRecMemSetIcmpTypeAndCode(r, in_vp) \ 1780 rwrec_MemSetIcmpTypeAndCode(r, in_vp) 1781 # define rwRecMemCmpIcmpTypeAndCode(r, vp) \ 1782 rwrec_MemCmpIcmpTypeAndCode(r, vp) 1783 #else /* RWREC_OPAQUE */ 1784 # define rwRecGetIcmpType(r) _recGetIcmpType(r) 1785 # define rwRecSetIcmpType(r, in_v) _recSetIcmpType(r, in_v) 1786 # define rwRecMemGetIcmpType(r, out_vp) _recMemGetIcmpType(r, out_vp) 1787 1788 # define rwRecGetIcmpCode(r) _recGetIcmpCode(r) 1789 # define rwRecSetIcmpCode(r, in_v) _recSetIcmpCode(r, in_v) 1790 # define rwRecMemGetIcmpCode(r, out_vp) _recMemGetIcmpCode(r, out_vp) 1791 1792 # define rwRecGetIcmpTypeAndCode(r) _recGetIcmpTypeAndCode(r) 1793 # define rwRecSetIcmpTypeAndCode(r, in_v) _recSetIcmpTypeAndCode(r, in_v) 1794 # define rwRecMemGetIcmpTypeAndCode(r, out_vp) \ 1795 _recMemGetIcmpTypeAndCode(r, out_vp) 1796 # define rwRecMemSetIcmpTypeAndCode(r, in_vp) \ 1797 _recMemSetIcmpTypeAndCode(r, in_vp) 1798 # define rwRecMemCmpIcmpTypeAndCode(r, vp) \ 1799 _recMemCmpIcmpTypeAndCode(r, vp) 1800 #endif /* RWREC_OPAQUE */ 1801 1802 1803 #ifdef __cplusplus 1804 } 1805 #endif 1806 #endif /* _RWREC_H */ 1807 1808 /* 1809 ** Local Variables: 1810 ** mode:c 1811 ** indent-tabs-mode:nil 1812 ** c-basic-offset:4 1813 ** End: 1814 */ 1815