/* ** Copyright (C) 2001-2012 by Carnegie Mellon University. ** ** @OPENSOURCE_HEADER_START@ ** ** Use of the SILK system and related source code is subject to the terms ** of the following licenses: ** ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991 ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.227.7013 ** ** NO WARRANTY ** ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE ** DELIVERABLES UNDER THIS LICENSE. ** ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie ** Mellon University, its trustees, officers, employees, and agents from ** all claims or demands made against them (and any related losses, ** expenses, or attorney's fees) arising out of, or relating to Licensee's ** and/or its sub licensees' negligent use or willful misuse of or ** negligent conduct or willful misconduct regarding the Software, ** facilities, or other rights or assistance granted by Carnegie Mellon ** University under this License, including, but not limited to, any ** claims of product liability, personal injury, death, damage to ** property, or violation of any laws or regulations. ** ** Carnegie Mellon University Software Engineering Institute authored ** documents are sponsored by the U.S. Department of Defense under ** Contract FA8721-05-C-0003. Carnegie Mellon University retains ** copyrights in all material produced under this contract. The U.S. ** Government retains a non-exclusive, royalty-free license to publish or ** reproduce these documents, or allow others to do so, for U.S. ** Government purposes only pursuant to the copyright license under the ** contract clause at 252.227.7013. ** ** @OPENSOURCE_HEADER_END@ */ /* ** rwrec.h ** ** The SiLK Flow record (rwRec) definition and functions/macros for ** manipulating it. ** */ #ifndef _RWREC_H #define _RWREC_H #ifdef __cplusplus extern "C" { #endif #include RCSIDENTVAR(rcsID_RWREC_H, "$Id$"); #include #ifndef RWREC_OPAQUE # define RWREC_OPAQUE 0 # include #endif /* * The following documents macros defined in this file that work to * access and manipulate the data in an rwRec. Although these are * macros, they have been documented as functions in order to convey * the expected types of the arguments. * * **** Convenience macros **** * * void RWREC_CLEAR(rwRec *r); * Zero out the record, and set Sensor ID and Flowtype to invalid * values. * * void RWREC_COPY(rwRec *dst, const rwRec *src); * Copy the rwRec from 'src' to 'dst'. * * int rwRecIsICMP(const rwRec *r); * Returns non-zero if the record is an ICMP record, zero otherwise. * * int rwRecIsWeb(const rwRec *r); * Returns non-zero if the record can be represented using the SiLK * web-specific file formats, zero otherwise. * * * **** More macros **** * * Function versions of all of the following macros exist. Simply * change the "rwRec" prefix of the macro to "rwrec_" to use the * function version. * * *** Whether a record is IPv6 *** * * int rwRecIsIPv6(const rwRec *r); * * *** Set record as IPv4 or IPv6 *** * * void rwRecSetIPv6(rwRec *r); * void rwRecSetIPv4(rwRec *r); * * It is important to note that the above two macros do not do any * conversions on the contained IP addresses. They are primarily to * be used when creating a new rwRec from scratch. See the following * for conversion. * * *** Convert record to IPv4 or IPv6 *** * * int rwRecConvertToIPv4(rwRec *r); * void rwRecConvertToIPv6(rwRec *r); * * These macros convert an rwRec to IPv4 or IPv6. The latter always * succeeds. The former will return -1 if unable to convert due to * the existence of IPv6 addresses that cannot be represented as IPv4 * (and return zero on success). * * **** rwRec accessor macros **** * * Most of the following accessor macros come in five standard * variations: * * rwRecGet(const reRec *r) * Gets the value of the field directly * * void rwRecSet(rwRec *r, in_v) * Sets the value of the field to 'in_v' * * void rwRecMemGet(const rwRec *r, *out_vp) * Copies the value of the field to location out_vp * * void rwRecMemSet(rwRec *r, const *in_vp) * Copies the value in location in_vp into the field * * int rwRecMemCmp(const rwRec *r, const *vp) * Compares the field to the value in location vp, returning a * negative integer if the field is less than vp, 0 if equal, and a * positive integer if greater than vp. * * For the rwRecMem{Get,Set,Cmp}() macros, we use of * in the comment to explain the size of the data * involved. With the exception of those dealing the skipaddr_t * objects, the actual functions use void pointers; as a result, those * macros do not require the value pointer to be aligned. The macros * that handle values larger than uint8_t use memcpy() or memcmp() to * copy or compare the values. * * ** IP Address Macros ** * * For handling IP addresses, there are three sets of macros: one for * IPv4 addresses: one for IPv6 addresses, and one for skipaddr_t * objects, which can represent either an IPv4 address or and IPv6 * object. * * In addition to the Get, Set, and Comparison macros, the follow * macro exists in IPv4, IPv6, and skipaddr_t varieties: * * void rwRecApplyMask(rwRec *r, const mask); * Modify the rwRec's IP addresses by applying the * specified mask (using a bit-wise AND) to that IP address. * * All of the macros that deal with IPv4 addresses assume that you * know the rwRec holds IPv4 addresses. No conversion of the rwRec or * of the address occurs. * * Using the Get macros for IPv6 on an rwRec that contains V4 data * will return a properly encoded IPv4-in-IPv6 address. All other * macros for IPv6 assume you know that the rwRec holds IPv6 * addresses. For IPv6, the rwRecGet() and rwRecSet() * macros do not exist; you must use the rwRecMemGet() and * rwRecMemSet() versions. * * Since an skipaddr_t can hold an IPv4 or an IPv6 address, the macros * that use skipaddr_t objects will correctly handle with rwRecs that * hold IPv4 or IPv6 data. Setting or masking an IPv4 rwRec with an * IPv6 skipaddr_t may convert the record to IPv6. The comparison * macros will operate in IPv6 space if either argument involves IPv6. * Unlike all other rwRecMem{Get,Set,Cmp}() macros, the * functions that work with skipaddr_t pointers require the skipaddr_t * to be properly aligned. * * The IPv4 macros include an extra DEPRECATED macro: * * uint32_t rwRecGetMaskv4(rwRec *r, uint32_t mask) * Gets the value of the field with the given bit-mask applied * * *** Source IPv4 Address (sIP) *** * * uint32_t rwRecGetSIPv4(const rwRec *r); * void rwRecSetSIPv4(rwRec *r, uint32_t in_v); * void rwRecMemGetSIPv4(const rwRec *r, uint32_t *out_vp); * void rwRecMemSetSIPv4(rwRec *r, const uint32_t *in_vp); * int rwRecMemCmpSIPv4(const rwRec *r, const uint32_t *vp); * void rwRecApplyMaskSIPv4(rwRec *r, uint32_t mask); * uint32_t rwRecGetMaskSIPv4(const rwRec *r, uint32_t mask); * * *** Source IPv6 Address (sIP) *** * * void rwRecMemGetSIPv6(const rwRec *r, uint8_t[16] out_vp); * void rwRecMemSetSIPv6(rwRec *r, const uint8_t[16] in_vp); * int rwRecMemCmpSIPv6(const rwRec *r, const uint8_t[16] vp); * void rwRecApplyMaskSIPv6(rwRec *r, const uint8_t[16] mask); * * *** Source IP Address (sIP) as skipaddr_t *** * * void rwRecMemGetSIP(const rwRec *r, skipaddr_t *out_addr); * void rwRecMemSetSIP(rwRec *r, const skipaddr_t *in_addr); * int rwRecMemCmpSIP(const rwRec *r, const skipaddr_t *addr); * void rwRecApplyMaskSIP(rwRec *r, const skipaddr_t *mask); * * *** Destination IP Address (dIP) *** * * uint32_t rwRecGetDIPv4(const rwRec *r); * void rwRecSetDIPv4(rwRec *r, uint32_t in_v); * void rwRecMemGetDIPv4(const rwRec *r, uint32_t *out_vp); * void rwRecMemSetDIPv4(rwRec *r, const uint32_t *in_vp); * int rwRecMemCmpDIPv4(const rwRec *r, const uint32_t *vp); * void rwRecApplyMaskDIPv4(rwRec *r, uint32_t mask); * uint32_t rwRecGetMaskDIPv4(const rwRec *r, uint32_t mask); * * *** Destination IPv6 Address (dIP) *** * * void rwRecMemGetDIPv6(const rwRec *r, uint8_t[16] out_vp); * void rwRecMemSetDIPv6(rwRec *r, const uint8_t[16] in_vp); * int rwRecMemCmpDIPv6(const rwRec *r, const uint8_t[16] vp); * void rwRecApplyMaskDIPv6(rwRec *r, const uint8_t[16] mask); * * *** Destination IP Address (dIP) as skipaddr_t *** * * void rwRecMemGetDIP(const rwRec *r, skipaddr_t *out_addr); * void rwRecMemSetDIP(rwRec *r, const skipaddr_t *in_addr); * int rwRecMemCmpDIP(const rwRec *r, const skipaddr_t *addr); * void rwRecApplyMaskDIP(rwRec *r, const skipaddr_t *mask); * * *** Next Hop IP Address *** * * uint32_t rwRecGetNhIPv4(const rwRec *r); * void rwRecSetNhIPv4(rwRec *r, uint32_t in_v); * void rwRecMemGetNhIPv4(const rwRec *r, uint32_t *out_vp); * void rwRecMemSetNhIPv4(rwRec *r, const uint32_t *in_vp); * int rwRecMemCmpNhIPv4(const rwRec *r, const uint32_t *vp); * void rwRecApplyMaskNhIPv4(rwRec *r, uint32_t mask); * uint32_t rwRecGetMaskNhIPv4(const rwRec *r, uint32_t mask); * * *** Next Hop IPv6 Address (nhIP) *** * * void rwRecMemGetNhIPv6(const rwRec *r, uint8_t[16] out_vp); * void rwRecMemSetNhIPv6(rwRec *r, const uint8_t[16] in_vp); * int rwRecMemCmpNhIPv6(const rwRec *r, const uint8_t[16] vp); * void rwRecApplyMaskNhIPv6(rwRec *r, const uint8_t[16] mask); * * *** Next Hop IP Address (nhIP) as skipaddr_t *** * * void rwRecMemGetNhIP(const rwRec *r, skipaddr_t *out_addr); * void rwRecMemSetNhIP(rwRec *r, const skipaddr_t *in_addr); * int rwRecMemCmpNhIP(const rwRec *r, const skipaddr_t *addr); * void rwRecApplyMaskNhIP(rwRec *r, const skipaddr_t *mask); * * *** Source Port (sPort) *** * * uint16_t rwRecGetSPort(const rwRec *r); * void rwRecSetSPort(rwRec *r, uint16_t in_v); * void rwRecMemGetSPort(const rwRec *r, uint16_t *out_vp); * void rwRecMemSetSPort(rwRec *r, const uint16_t *in_vp); * int rwRecMemCmpSPort(const rwRec *r, const uint16_t *vp); * * *** Destination Port (dPort) *** * * uint16_t rwRecGetDPort(const rwRec *r); * void rwRecSetDPort(rwRec *r, uint16_t in_v); * void rwRecMemGetDPort(const rwRec *r, uint16_t *out_vp); * void rwRecMemSetDPort(rwRec *r, const uint16_t *in_vp); * int rwRecMemCmpDPort(const rwRec *r, const uint16_t *vp); * * *** Protocol *** * * uint8_t rwRecGetProto(const rwRec *r); * void rwRecSetProto(rwRec *r, uint8_t in_v); * void rwRecMemGetProto(const rwRec *r, uint8_t *out_vp); * void rwRecMemSetProto(rwRec *r, const uint8_t *in_vp); * int rwRecMemCmpProto(const rwRec *r, const uint8_t *vp); * * *** Packet Count (pkts) *** * * uint32_t rwRecGetPkts(const rwRec *r); * void rwRecSetPkts(rwRec *r, uint32_t in_v); * void rwRecMemGetPkts(const rwRec *r, uint32_t *out_vp); * void rwRecMemSetPkts(rwRec *r, const uint32_t *in_vp); * int rwRecMemCmpPkts(const rwRec *r, const uint32_t *vp); * * *** Byte count *** * * uint32_t rwRecGetBytes(const rwRec *r); * void rwRecSetBytes(rwRec *r, uint32_t in_v); * void rwRecMemGetBytes(const rwRec *r, uint32_t *out_vp); * void rwRecMemSetBytes(rwRec *r, const uint32_t *in_vp); * int rwRecMemCmpBytes(const rwRec *r, const uint32_t *vp); * * *** Bitwise OR of TCP Flags on ALL packets in flow *** * * uint8_t rwRecGetFlags(const rwRec *r); * void rwRecSetFlags(rwRec *r, uint8_t in_v); * void rwRecMemGetFlags(const rwRec *r, uint8_t *out_vp); * void rwRecMemSetFlags(rwRec *r, const uint8_t *in_vp); * int rwRecMemCmpFlags(const rwRec *r, const uint8_t *vp); * * *** TCP Flags seen on initial packet of flow *** * * uint8_t rwRecGetInitFlags(const rwRec *r); * void rwRecSetInitFlags(rwRec *r, uint8_t in_v); * void rwRecMemGetInitFlags(const rwRec *r, uint8_t *out_vp); * void rwRecMemSetInitFlags(rwRec *r, const uint8_t *in_vp); * int rwRecMemCmpInitFlags(const rwRec *r, const uint8_t *vp); * * *** Bitwise OR of TCP Flags on all packets in session except first *** * * uint8_t rwRecGetRestFlags(const rwRec *r); * void rwRecSetRestFlags(rwRec *r, uint8_t in_v); * void rwRecMemGetRestFlags(const rwRec *r, uint8_t *out_vp); * void rwRecMemSetRestFlags(rwRec *r, const uint8_t *in_vp); * int rwRecMemCmpRestFlags(const rwRec *r, const uint8_t *vp); * * *** Start Time as milliseconds since UNIX epoch (sTime) *** * * sktime_t rwRecGetStartTime(const rwRec *r); * void rwRecSetStartTime(rwRec *r, sktime_t in_v); * void rwRecMemGetStartTime(const rwRec *r, sktime_t *out_vp); * void rwRecMemSetStartTime(rwRec *r, const sktime_t *in_vp); * int rwRecMemCmpStartTime(const rwRec *r, const sktime_t *vp); * * uint32_t rwRecGetStartSeconds(const rwRec *r); * void rwRecMemGetStartSeconds(const rwRec *r, uint32_t *out_vp); * uint16_t rwRecGetStartMSec(const rwRec *r); * void rwRecMemGetStartMSec(const rwRec *r, uint16_t *out_vp); * * The second set of macros return the integer number of seconds and * the millisecond remainder. In particular: * * rwRecGetStartTime(r) == * rwRecGetStartSeconds(r) * (uint64_t)1000 + rwRecGetStartMSec(r) * * *** End Time is derived from the sTime and duration (eTime) *** * * sktime_t rwRecGetEndTime(const rwRec *r); * void rwRecMemGetEndTime(const rwRec *r, sktime_t *out_vp); * * uint32_t rwRecGetEndSeconds(const rwRec *r); * void rwRecMemGetEndSeconds(const rwRec *r, uint32_t *out_vp); * uint16_t rwRecGetEndMSec(const rwRec *r); * void rwRecMemGetEndMSec(const rwRec *r, uint16_t *out_vp); * * There are no setter macros for end time, because end time is * derived from start time and duration (elapsed time). * * The second set of macros return the integer number of seconds and * the millisecond remainder. In particular: * * rwRecGetEndTime(r) == * rwRecGetEndSeconds(r) * (uint64_t)1000 + rwRecGetEndMSec(r) * * *** Elapsed (duration) of the flow, in milliseconds *** * * uint32_t rwRecGetElapsed(const rwRec *r); * void rwRecSetElapsed(rwRec *r, uint32_t in_v); * void rwRecMemGetElapsed(const rwRec *r, uint32_t *out_vp); * void rwRecMemSetElapsed(rwRec *r, const uint32_t *in_vp); * int rwRecMemCmpElapsed(const rwRec *r, const uint32_t *vp); * * uint32_t rwRecGetElapsedSeconds(const rwRec *r); * void rwRecMemGetElapsedSeconds(const rwRec *r, uint32_t *out_vp); * uint16_t rwRecGetElapsedMSec(const rwRec *r); * void rwRecMemGetElapsedMSec(const rwRec *r, uint16_t *out_vp); * * The second set of macros return the integer number of seconds and * the millisecond remainder. In particular: * * rwRecGetElapsedTime(r) == * rwRecGetElapsedSeconds(r) * 1000 + rwRecGetElapsedMSec(r) * * *** Sensor ID (sID) *** * * sensorID_t rwRecGetSensor(const rwRec *r); * void rwRecSetSensor(rwRec *r, sensorID_t in_v); * void rwRecMemGetSensor(const rwRec *r, sensorID_t *out_vp); * void rwRecMemSetSensor(rwRec *r, const sensorID_t *in_vp); * int rwRecMemCmpSensor(const rwRec *r, const sensorID_t *vp); * * *** FlowType holds Class and Type *** * * flowtypeID_t rwRecGetFlowType(const rwRec *r); * void rwRecSetFlowType(rwRec *r, flowtypeID_t in_v); * void rwRecMemGetFlowType(const rwRec *r, flowtypeID_t *out_vp); * void rwRecMemSetFlowType(rwRec *r, const flowtypeID_t *in_vp); * int rwRecMemCmpFlowType(const rwRec *r, const flowtypeID_t *vp); * * *** SNMP Input Value (Router incoming/ingress interface/vlanId) *** * * uint16_t rwRecGetInput(const rwRec *r); * void rwRecSetInput(rwRec *r, uint16_t in_v); * void rwRecMemGetInput(const rwRec *r, uint16_t *out_vp); * void rwRecMemSetInput(rwRec *r, const uint16_t *in_vp); * int rwRecMemCmpInput(const rwRec *r, const uint16_t *vp); * * *** SNMP Output Value (Router outgoing/egress interface/postVlanId) *** * * uint16_t rwRecGetOutput(const rwRec *r); * void rwRecSetOutput(rwRec *r, uint16_t in_v); * void rwRecMemGetOutput(const rwRec *r, uint16_t *out_vp); * void rwRecMemSetOutput(rwRec *r, const uint16_t *in_vp); * int rwRecMemCmpOutput(const rwRec *r, const uint16_t *vp); * * *** TCP State (the Attributes field) *** * * uint8_t rwRecGetTcpState(const rwRec *r); * void rwRecSetTcpState(rwRec *r, uint8_t in_v); * void rwRecMemGetTcpState(const rwRec *r, uint8_t *out_vp); * void rwRecMemSetTcpState(rwRec *r, const uint8_t *in_vp); * int rwRecMemCmpTcpState(const rwRec *r, const uint8_t *vp); * * The TCP state field is a bit field which states certain miscellaneous * information about the flow record. The following constants are * defined which represent this information: * * #define SK_TCPSTATE_EXPANDED 0x01 * Additional TCP-state machine information is available. This must * be set for every TCP flow where the init_flags and rest_flags * fields are set. * * #define SK_TCPSTATE_FIN_FOLLOWED_NOT_ACK 0x08 * Flow received packets following the FIN packet that were not ACK or * RST packets. * * #define SK_TCPSTATE_UNIFORM_PACKET_SIZE 0x10 * Flow has packets all of the same size * * #define SK_TCPSTATE_TIMEOUT_KILLED 0x20 * Flow ends prematurely due to a timeout by the collector. * * #define SK_TCPSTATE_TIMEOUT_STARTED 0x40 * Flow is a continuation of a previous flow that was killed * prematurely due to a timeout by the collector. * * Note: the most significant bit of tcp_state (0x80) is used as a flag * to mark a record as having IPv6 addresses. The rwRecSetIPv4() and * rwRecSetIPv6() macros should be used to modify this bit. * * Be careful when setting the TCP state. You usually want get the * current TCP state, add or remove specific bits by masking, then set it * with the resulting value. * * *** Application *** * * uint16_t rwRecGetApplication(const rwRec *r); * void rwRecSetApplication(rwRec *r, uint16_t in_v); * void rwRecMemGetApplication(const rwRec *r, uint16_t *out_vp); * void rwRecMemSetApplication(rwRec *r, const uint16_t *in_vp); * int rwRecMemCmpApplication(const rwRec *r, const uint16_t *vp); * * The application field can be set by the yaf flow generation * software when it is configured with the "applabel" feature. This * feature causes yaf to inspect the packets in the flow and guess as * to the type of application (HTTP, SMTP, SSH, etc) the packets * represent. The value for the field is the standard service port * for that service (80, 25, 22, etc). * * *** Memo *** * * uint16_t rwRecGetMemo(const rwRec *r); * void rwRecSetMemo(rwRec *r, uint16_t in_v); * void rwRecMemGetMemo(const rwRec *r, uint16_t *out_vp); * void rwRecMemSetMemo(rwRec *r, const uint16_t *in_vp); * int rwRecMemCmpMemo(const rwRec *r, const uint16_t *vp); * * Currently unused. * * *** ICMP Type and Code is derived from the DPort *** * * uint8_t rwRecGetIcmpType(const rwRec *r); * void rwRecSetIcmpType(rwRec *r, uint8_t in_v); * void rwRecMemGetIcmpType(const rwRec *r, uint8_t *out_vp); * * uint8_t rwRecGetIcmpCode(const rwRec *r); * void rwRecSetIcmpCode(rwRec *r, uint8_t in_v); * void rwRecMemGetIcmpCode(const rwRec *r, uint8_t *out_vp); * * uint16_t rwRecGetIcmpTypeAndCode(const rwRec *r); * void rwRecSetIcmpTypeAndCode(rwRec *r, uint16_t in_v); * void rwRecMemGetIcmpTypeAndCode(const rwRec *r, uint16_t *out_vp); * void rwRecMemSetIcmpTypeAndCode(rwRec *r, const uint16_t *in_vp); * int rwRecMemCmpIcmpTypeAndCode(const rwRec *r, const uint16_t *vp); * * Since the ICMP Type and Code are stored in the dport field, modifying * these will modify the return value of rwRecGetDPort() and friends. */ #define SK_WEBPORT_CHECK(p) ((p) == 80 || (p) == 443 || (p) == 8080) /* * Return a true value if port 'p' is a "web" port; false otherwise */ #define RWREC_CLEAR(rec) \ do { \ memset((rec), 0, sizeof(rwRec)); \ rwRecSetSensor((rec), SK_INVALID_SENSOR); \ rwRecSetFlowType((rec), SK_INVALID_FLOWTYPE); \ } while(0) /* * Zero out the record, and set Sensor ID and Flowtype to invalid * values. */ #define RWREC_COPY(dst, src) \ memcpy((dst), (src), sizeof(rwRec)) /* * Copy the rwRec from 'src' to 'dst'. */ /* * This is the generic SiLK Flow record returned from ANY file format * containing packed SiLK Flow records. * * typedef struct rwGenericRec_V5_st rwGenericRec_V5_t; // silk_types.h * typedef rwGenericRec_V5_t rwRec; // silk_types.h */ struct rwGenericRec_V5_st { #if RWREC_OPAQUE && !defined(RWREC_DEFINE_BODY) #if SK_ENABLE_IPV6 uint8_t ar[88]; #else uint8_t ar[52]; #endif #else int64_t sTime; /* 0- 7 Flow start time in milliseconds * since UNIX epoch */ uint32_t elapsed; /* 8-11 Duration of flow in millisecs */ uint16_t sPort; /* 12-13 Source port */ uint16_t dPort; /* 14-15 Destination port */ uint8_t proto; /* 16 IP protocol */ flowtypeID_t flow_type; /* 17 Class & Type info */ sensorID_t sID; /* 18-19 Sensor ID */ uint8_t flags; /* 20 OR of all flags (Netflow flags) */ uint8_t init_flags; /* 21 TCP flags in first packet * or blank for "legacy" data */ uint8_t rest_flags; /* 22 TCP flags on non-initial packet * or blank for "legacy" data */ uint8_t tcp_state; /* 23 TCP state machine info (below) */ uint16_t application; /* 24-25 "Service" port set by collector */ uint16_t memo; /* 26-27 Application specific field */ uint16_t input; /* 28-29 Router incoming SNMP interface */ uint16_t output; /* 30-31 Router outgoing SNMP interface */ uint32_t pkts; /* 32-35 Count of packets */ uint32_t bytes; /* 36-39 Count of bytes */ ipUnion sIP; /* 40-43 (or 40-55 if IPv6) Source IP */ ipUnion dIP; /* 44-47 (or 56-71 if IPv6) Destination IP */ ipUnion nhIP; /* 48-51 (or 72-87 if IPv6) Router Next Hop IP */ #endif /* RWREC_OPAQUE && !defined(RWREC_DEFINE_BODY) */ }; /* ** Values for tcp_state value in rwGeneric and packed formats */ /* No additional TCP-state machine information is available */ #define SK_TCPSTATE_NO_INFO 0x00 /* Additional TCP-state machine information is available. This must * be set for every TCP flow where the init_flags and rest_flags * fields are set. */ #define SK_TCPSTATE_EXPANDED 0x01 /* Flow received packets following the FIN packet that were not ACK or * RST packets. */ #define SK_TCPSTATE_FIN_FOLLOWED_NOT_ACK 0x08 /* Flow has packets all of the same size */ #define SK_TCPSTATE_UNIFORM_PACKET_SIZE 0x10 /* Flow ends prematurely due to a timeout by the collector. */ #define SK_TCPSTATE_TIMEOUT_KILLED 0x20 /* Flow is a continuation of a previous flow that was killed * prematurely due to a timeout by the collector. */ #define SK_TCPSTATE_TIMEOUT_STARTED 0x40 /* Note: the most significant bit of tcp_state (0x80) is used as a * flag to mark a record as having IPv6 addresses. */ /* the sizeof the fields in an rwRec */ #define RWREC_SIZEOF_SIPv4 4 #define RWREC_SIZEOF_DIPv4 4 #define RWREC_SIZEOF_NHIPv4 4 #define RWREC_SIZEOF_SPORT 2 #define RWREC_SIZEOF_DPORT 2 #define RWREC_SIZEOF_INPUT 2 #define RWREC_SIZEOF_OUTPUT 2 #define RWREC_SIZEOF_STIME 8 #define RWREC_SIZEOF_ELAPSED 4 #define RWREC_SIZEOF_PKTS 4 #define RWREC_SIZEOF_BYTES 4 #define RWREC_SIZEOF_PROTO 1 #define RWREC_SIZEOF_FLOW_TYPE 1 #define RWREC_SIZEOF_SID 2 #define RWREC_SIZEOF_FLAGS 1 #define RWREC_SIZEOF_INIT_FLAGS 1 #define RWREC_SIZEOF_REST_FLAGS 1 #define RWREC_SIZEOF_TCP_STATE 1 #define RWREC_SIZEOF_APPLICATION 2 #define RWREC_SIZEOF_MEMO 2 #define RWREC_SIZEOF_SIPv6 16 #define RWREC_SIZEOF_DIPv6 16 #define RWREC_SIZEOF_NHIPv6 16 #if !SK_ENABLE_IPV6 # define RWREC_SIZEOF_SIP RWREC_SIZEOF_SIPv4 # define RWREC_SIZEOF_DIP RWREC_SIZEOF_DIPv4 # define RWREC_SIZEOF_NHIP RWREC_SIZEOF_NHIPv4 #else # define RWREC_SIZEOF_SIP RWREC_SIZEOF_SIPv6 # define RWREC_SIZEOF_DIP RWREC_SIZEOF_DIPv6 # define RWREC_SIZEOF_NHIP RWREC_SIZEOF_NHIPv6 #endif /* SK_ENABLE_IPV6 */ /* Helper macros */ #if 0 # define MEMCPY8(dst, src) { *((uint8_t*)(dst)) = *((uint8_t*)(src)); } # define MEMCPY16(dst, src) { *((uint16_t*)(dst)) = *((uint16_t*)(src)); } # define MEMCPY32(dst, src) { *((uint32_t*)(dst)) = *((uint32_t*)(src)); } #else # define MEMCPY8(dst, src) memcpy((dst), (src), sizeof(uint8_t)) # define MEMCPY16(dst, src) memcpy((dst), (src), sizeof(uint16_t)) # define MEMCPY32(dst, src) memcpy((dst), (src), sizeof(uint32_t)) #endif /*** Whether record is ICMP ***/ #define rwRecIsICMP(r) \ ((IPPROTO_ICMP == rwRecGetProto(r)) \ || (rwRecIsIPv6(r) && (IPPROTO_ICMPV6 == rwRecGetProto(r)))) /*** Whether record is WEB/HTTP ***/ #define rwRecIsWeb(r) \ ((IPPROTO_TCP == rwRecGetProto(r)) \ && (SK_WEBPORT_CHECK(rwRecGetSPort(r)) \ || SK_WEBPORT_CHECK(rwRecGetDPort(r)))) /*** Whether record is IPv6 ***/ #if !SK_ENABLE_IPV6 # define rwRecIsIPv6(r) 0 #else int rwrec_IsIPv6(const rwRec *r); void rwrec_SetIPv6(rwRec *r); void rwrec_SetIPv4(rwRec *r); #define _recIsIPv6(r) \ (((r)->tcp_state & 0x80) ? 1 : 0) #define _recSetIPv6(r) \ { (r)->tcp_state |= 0x80; } #define _recSetIPv4(r) \ { (r)->tcp_state &= 0x7F; } #if RWREC_OPAQUE # define rwRecIsIPv6(r) rwrec_IsIPv6(r) # define rwRecSetIPv6(r) rwrec_SetIPv6(r) # define rwRecSetIPv4(r) rwrec_SetIPv4(r) #else # define rwRecIsIPv6(r) _recIsIPv6(r) # define rwRecSetIPv6(r) _recSetIPv6(r) # define rwRecSetIPv4(r) _recSetIPv4(r) #endif /* RWREC_OPAQUE */ #endif /* SK_ENABLE_IPV6 */ /*** Convert a Record to IPv6 or IPv4 ***/ #if SK_ENABLE_IPV6 void rwrec_ConvertToIPv6(rwRec *r); int rwrec_ConvertToIPv4(rwRec *r); #define _recConvertToIPv6(r) \ { \ ipUnion4to6(&(r)->sIP, &(r)->sIP); \ ipUnion4to6(&(r)->dIP, &(r)->dIP); \ ipUnion4to6(&(r)->nhIP, &(r)->nhIP); \ _recSetIPv6(r); \ } #if RWREC_OPAQUE # define rwRecConvertToIPv6(r) rwrec_ConvertToIPv6(r) # define rwRecConvertToIPv4(r) rwrec_ConvertToIPv4(r) #else # define rwRecConvertToIPv6(r) _recConvertToIPv6(r) # define rwRecConvertToIPv4(r) rwrec_ConvertToIPv4(r) #endif /* RWREC_OPAQUE */ #endif /* SK_ENABLE_IPV6 */ /*** Source IPv4 Address (sIP) ***/ uint32_t rwrec_GetSIPv4(const rwRec *r); void rwrec_SetSIPv4(rwRec *r, uint32_t in_v); void rwrec_MemGetSIPv4(const rwRec *r, void *out_vp); void rwrec_MemSetSIPv4(rwRec *r, const void *in_vp); int rwrec_MemCmpSIPv4(const rwRec *r, const void *vp); uint32_t rwrec_GetMaskSIPv4(const rwRec *r, uint32_t mask); void rwrec_ApplyMaskSIPv4(rwRec *r, uint32_t mask); #define _recGetSIPv4(r) \ ((r)->sIP.ipu_ipv4) #define _recSetSIPv4(r, in_v) \ { ((r)->sIP.ipu_ipv4) = (in_v); } #define _recMemGetSIPv4(r, out_vp) \ memcpy((out_vp), &((r)->sIP.ipu_ipv4), RWREC_SIZEOF_SIPv4) #define _recMemSetSIPv4(r, in_vp) \ memcpy(&((r)->sIP.ipu_ipv4), (in_vp), RWREC_SIZEOF_SIPv4) #define _recMemCmpSIPv4(r, vp) \ memcmp(&((r)->sIP.ipu_ipv4), (vp), RWREC_SIZEOF_SIPv4) #define _recGetMaskSIPv4(r, mask) \ (((r)->sIP.ipu_ipv4) & mask) #define _recApplyMaskSIPv4(r, mask) \ ipUnionApplyMaskV4(&((r)->sIP), (mask)) #if RWREC_OPAQUE # define rwRecGetSIPv4(r) rwrec_GetSIPv4(r) # define rwRecSetSIPv4(r, in_v) rwrec_SetSIPv4(r, in_v) # define rwRecMemGetSIPv4(r, out_vp) rwrec_MemGetSIPv4(r, out_vp) # define rwRecMemSetSIPv4(r, in_vp) rwrec_MemSetSIPv4(r, in_vp) # define rwRecMemCmpSIPv4(r, vp) rwrec_MemCmpSIPv4(r, vp) # define rwRecGetMaskSIPv4(r, mask) rwrec_GetMaskSIPv4(r, mask) # define rwRecApplyMaskSIPv4(r, mask) rwrec_ApplyMaskSIPv4(r, mask) #else # define rwRecGetSIPv4(r) _recGetSIPv4(r) # define rwRecSetSIPv4(r, in_v) _recSetSIPv4(r, in_v) # define rwRecMemGetSIPv4(r, out_vp) _recMemGetSIPv4(r, out_vp) # define rwRecMemSetSIPv4(r, in_vp) _recMemSetSIPv4(r, in_vp) # define rwRecMemCmpSIPv4(r, vp) _recMemCmpSIPv4(r, vp) # define rwRecGetMaskSIPv4(r, mask) _recGetMaskSIPv4(r, mask) # define rwRecApplyMaskSIPv4(r, mask) _recApplyMaskSIPv4(r, mask) #endif /* RWREC_OPAQUE */ /*** Source IPv6 Address (sIP) ***/ #if SK_ENABLE_IPV6 void rwrec_MemGetSIPv6(const rwRec *r, void *out_vp); void rwrec_MemSetSIPv6(rwRec *r, const void *in_vp); int rwrec_MemCmpSIPv6(const rwRec *r, const void *vp); void rwrec_ApplyMaskSIPv6(rwRec *r, const void *mask_vp); #define _recMemGetSIPv6(r, out_vp) \ if (_recIsIPv6(r)) { \ ipUnionGetV6(&((r)->sIP), (out_vp)); \ } else { \ ipUnionGetV4AsV6(&((r)->sIP), (out_vp)); \ } #define _recMemSetSIPv6(r, in_vp) \ memcpy(&((r)->sIP.ipu_ipv6), (in_vp), RWREC_SIZEOF_SIPv6) #define _recMemCmpSIPv6(r, vp) \ memcmp(&((r)->sIP.ipu_ipv6), (vp), RWREC_SIZEOF_SIPv6) #define _recApplyMaskSIPv6(r, mask) \ ipUnionApplyMaskV6(&((r)->sIP), (mask)) #if RWREC_OPAQUE # define rwRecMemGetSIPv6(r, out_vp) rwrec_MemGetSIPv6(r, out_vp) # define rwRecMemSetSIPv6(r, in_vp) rwrec_MemSetSIPv6(r, in_vp) # define rwRecMemCmpSIPv6(r, vp) rwrec_MemCmpSIPv6(r, vp) # define rwRecApplyMaskSIPv6(r, mask) rwrec_ApplyMaskSIPv6(r, mask) #else # define rwRecMemGetSIPv6(r, out_vp) _recMemGetSIPv6(r, out_vp) # define rwRecMemSetSIPv6(r, in_vp) _recMemSetSIPv6(r, in_vp) # define rwRecMemCmpSIPv6(r, vp) _recMemCmpSIPv6(r, vp) # define rwRecApplyMaskSIPv6(r, mask) _recApplyMaskSIPv6(r, mask) #endif /* RWREC_OPAQUE */ #endif /* SK_ENABLE_IPV6 */ /*** Source IP Address (sIP) as skipaddr_t ***/ void rwrec_MemGetSIP(const rwRec *r, skipaddr_t *out_addr); void rwrec_MemSetSIP(rwRec *r, const skipaddr_t *in_addr); int rwrec_MemCmpSIP(const rwRec *r, const skipaddr_t *addr); void rwrec_ApplyMaskSIP(rwRec *r, const skipaddr_t *mask_addr); #if !SK_ENABLE_IPV6 #define _recMemGetSIP _recMemGetSIPv4 #define _recMemSetSIP _recMemSetSIPv4 #define _recMemCmpSIP(r, addr) \ _recMemCmpSIPv4((r), &((addr)->ip_ip.ipu_ipv4)) #define _recApplyMaskSIP(r, addr) \ _recApplyMaskSIPv4((r), (addr)->ip_ip.ipu_ipv4) #else #define _recMemGetSIP(r, out_addr) \ do { \ memcpy(out_addr, &((r)->sIP), sizeof(ipUnion)); \ skipaddrSetVersion((out_addr), _recIsIPv6(r)); \ } while(0) #define _recMemSetSIP(r, in_addr) \ do { \ if (skipaddrIsV6(in_addr) == _recIsIPv6(r)) { \ /* both are either V4 or V6 */ \ memcpy(&((r)->sIP), (in_addr), sizeof(ipUnion)); \ } else if (_recIsIPv6(r)) { \ /* convert V4 IP to V6 */ \ ipUnion4to6(&((in_addr)->ip_ip), &((r)->sIP)); \ } else { \ /* must convert record to V6 */ \ _recConvertToIPv6(r); \ memcpy(&((r)->sIP), (in_addr), sizeof(ipUnion)); \ } \ } while(0) #define _recMemCmpSIP(r, addr) rwrec_MemCmpSIP(r, addr) #define _recApplyMaskSIP(r, addr) rwrec_ApplyMaskSIP(r, addr) #endif /* SK_ENABLE_IPV6 */ #if RWREC_OPAQUE # define rwRecMemGetSIP(r, out_addr) rwrec_MemGetSIP(r, out_addr) # define rwRecMemSetSIP(r, in_addr) rwrec_MemSetSIP(r, in_addr) # define rwRecMemCmpSIP(r, addr) rwrec_MemCmpSIP(r, addr) # define rwRecApplyMaskSIP(r, addr) rwrec_ApplyMaskSIP(r, addr) #else # define rwRecMemGetSIP(r, out_addr) _recMemGetSIP(r, out_addr) # define rwRecMemSetSIP(r, in_addr) _recMemSetSIP(r, in_addr) # define rwRecMemCmpSIP(r, addr) _recMemCmpSIP(r, addr) # define rwRecApplyMaskSIP(r, addr) _recApplyMaskSIP(r, addr) #endif /* RWREC_OPAQUE */ /*** Destination IP Address (dIP) ***/ uint32_t rwrec_GetDIPv4(const rwRec *r); void rwrec_SetDIPv4(rwRec *r, uint32_t in_v); void rwrec_MemGetDIPv4(const rwRec *r, void *out_vp); void rwrec_MemSetDIPv4(rwRec *r, const void *in_vp); int rwrec_MemCmpDIPv4(const rwRec *r, const void *vp); uint32_t rwrec_GetMaskDIPv4(const rwRec *r, uint32_t mask); void rwrec_ApplyMaskDIPv4(rwRec *r, uint32_t mask); #define _recGetDIPv4(r) \ ((r)->dIP.ipu_ipv4) #define _recSetDIPv4(r, in_v) \ { ((r)->dIP.ipu_ipv4) = (in_v); } #define _recMemGetDIPv4(r, out_vp) \ memcpy((out_vp), &((r)->dIP.ipu_ipv4), RWREC_SIZEOF_DIPv4) #define _recMemSetDIPv4(r, in_vp) \ memcpy(&((r)->dIP.ipu_ipv4), (in_vp), RWREC_SIZEOF_DIPv4) #define _recMemCmpDIPv4(r, vp) \ memcmp(&((r)->dIP.ipu_ipv4), (vp), RWREC_SIZEOF_DIPv4) #define _recGetMaskDIPv4(r, mask) \ (((r)->dIP.ipu_ipv4) & mask) #define _recApplyMaskDIPv4(r, mask) \ ipUnionApplyMaskV4(&((r)->dIP), (mask)) #if RWREC_OPAQUE # define rwRecGetDIPv4(r) rwrec_GetDIPv4(r) # define rwRecSetDIPv4(r, in_v) rwrec_SetDIPv4(r, in_v) # define rwRecMemGetDIPv4(r, out_vp) rwrec_MemGetDIPv4(r, out_vp) # define rwRecMemSetDIPv4(r, in_vp) rwrec_MemSetDIPv4(r, in_vp) # define rwRecMemCmpDIPv4(r, vp) rwrec_MemCmpDIPv4(r, vp) # define rwRecGetMaskDIPv4(r, mask) rwrec_GetMaskDIPv4(r, mask) # define rwRecApplyMaskDIPv4(r, mask) rwrec_ApplyMaskDIPv4(r, mask) #else # define rwRecGetDIPv4(r) _recGetDIPv4(r) # define rwRecSetDIPv4(r, in_v) _recSetDIPv4(r, in_v) # define rwRecMemGetDIPv4(r, out_vp) _recMemGetDIPv4(r, out_vp) # define rwRecMemSetDIPv4(r, in_vp) _recMemSetDIPv4(r, in_vp) # define rwRecMemCmpDIPv4(r, vp) _recMemCmpDIPv4(r, vp) # define rwRecGetMaskDIPv4(r, mask) _recGetMaskDIPv4(r, mask) # define rwRecApplyMaskDIPv4(r, mask) _recApplyMaskDIPv4(r, mask) #endif /* RWREC_OPAQUE */ /*** Destination IPv6 Address (dIP) ***/ #if SK_ENABLE_IPV6 void rwrec_MemGetDIPv6(const rwRec *r, void *out_vp); void rwrec_MemSetDIPv6(rwRec *r, const void *in_vp); int rwrec_MemCmpDIPv6(const rwRec *r, const void *vp); void rwrec_ApplyMaskDIPv6(rwRec *r, const void *mask_vp); #define _recMemGetDIPv6(r, out_vp) \ if (_recIsIPv6(r)) { \ ipUnionGetV6(&((r)->dIP), (out_vp)); \ } else { \ ipUnionGetV4AsV6(&((r)->dIP), (out_vp)); \ } #define _recMemSetDIPv6(r, in_vp) \ memcpy(&((r)->dIP.ipu_ipv6), (in_vp), RWREC_SIZEOF_DIPv6) #define _recMemCmpDIPv6(r, vp) \ memcmp(&((r)->dIP.ipu_ipv6), (vp), RWREC_SIZEOF_DIPv6) #define _recApplyMaskDIPv6(r, mask) \ ipUnionApplyMaskV6(&((r)->dIP), (mask)) #if RWREC_OPAQUE # define rwRecMemGetDIPv6(r, out_vp) rwrec_MemGetDIPv6(r, out_vp) # define rwRecMemSetDIPv6(r, in_vp) rwrec_MemSetDIPv6(r, in_vp) # define rwRecMemCmpDIPv6(r, vp) rwrec_MemCmpDIPv6(r, vp) # define rwRecApplyMaskDIPv6(r, mask) rwrec_ApplyMaskDIPv6(r, mask) #else # define rwRecMemGetDIPv6(r, out_vp) _recMemGetDIPv6(r, out_vp) # define rwRecMemSetDIPv6(r, in_vp) _recMemSetDIPv6(r, in_vp) # define rwRecMemCmpDIPv6(r, vp) _recMemCmpDIPv6(r, vp) # define rwRecApplyMaskDIPv6(r, mask) _recApplyMaskDIPv6(r, mask) #endif /* RWREC_OPAQUE */ #endif /* SK_ENABLE_IPV6 */ /*** Destination IP Address (dIP) as skipaddr_t ***/ void rwrec_MemGetDIP(const rwRec *r, skipaddr_t *out_addr); void rwrec_MemSetDIP(rwRec *r, const skipaddr_t *in_addr); int rwrec_MemCmpDIP(const rwRec *r, const skipaddr_t *addr); void rwrec_ApplyMaskDIP(rwRec *r, const skipaddr_t *mask_addr); #if !SK_ENABLE_IPV6 #define _recMemGetDIP _recMemGetDIPv4 #define _recMemSetDIP _recMemSetDIPv4 #define _recMemCmpDIP(r, addr) \ _recMemCmpDIPv4((r), &((addr)->ip_ip.ipu_ipv4)) #define _recApplyMaskDIP(r, addr) \ _recApplyMaskDIPv4((r), (addr)->ip_ip.ipu_ipv4) #else #define _recMemGetDIP(r, out_addr) \ do { \ memcpy(out_addr, &((r)->dIP), sizeof(ipUnion)); \ skipaddrSetVersion((out_addr), _recIsIPv6(r)); \ } while(0) #define _recMemSetDIP(r, in_addr) \ do { \ if (skipaddrIsV6(in_addr) == _recIsIPv6(r)) { \ /* both are either V4 or V6 */ \ memcpy(&((r)->dIP), (in_addr), sizeof(ipUnion)); \ } else if (_recIsIPv6(r)) { \ /* convert V4 IP to V6 */ \ ipUnion4to6(&((in_addr)->ip_ip), &((r)->dIP)); \ } else { \ /* must convert record to V6 */ \ _recConvertToIPv6(r); \ memcpy(&((r)->dIP), (in_addr), sizeof(ipUnion)); \ } \ } while(0) #define _recMemCmpDIP(r, addr) rwrec_MemCmpDIP(r, addr) #define _recApplyMaskDIP(r, addr) rwrec_ApplyMaskDIP(r, addr) #endif /* SK_ENABLE_IPV6 */ #if RWREC_OPAQUE # define rwRecMemGetDIP(r, out_addr) rwrec_MemGetDIP(r, out_addr) # define rwRecMemSetDIP(r, in_addr) rwrec_MemSetDIP(r, in_addr) # define rwRecMemCmpDIP(r, addr) rwrec_MemCmpDIP(r, addr) # define rwRecApplyMaskDIP(r, addr) rwrec_ApplyMaskDIP(r, addr) #else # define rwRecMemGetDIP(r, out_addr) _recMemGetDIP(r, out_addr) # define rwRecMemSetDIP(r, in_addr) _recMemSetDIP(r, in_addr) # define rwRecMemCmpDIP(r, addr) _recMemCmpDIP(r, addr) # define rwRecApplyMaskDIP(r, addr) _recApplyMaskDIP(r, addr) #endif /* RWREC_OPAQUE */ /*** Next Hop IP (nhIP) Address ***/ uint32_t rwrec_GetNhIPv4(const rwRec *r); void rwrec_SetNhIPv4(rwRec *r, uint32_t in_v); void rwrec_MemGetNhIPv4(const rwRec *r, void *out_vp); void rwrec_MemSetNhIPv4(rwRec *r, const void *in_vp); int rwrec_MemCmpNhIPv4(const rwRec *r, const void *vp); uint32_t rwrec_GetMaskNhIPv4(const rwRec *r, uint32_t mask); void rwrec_ApplyMaskNhIPv4(rwRec *r, uint32_t mask); #define _recGetNhIPv4(r) \ ((r)->nhIP.ipu_ipv4) #define _recSetNhIPv4(r, in_v) \ { ((r)->nhIP.ipu_ipv4) = (in_v); } #define _recMemGetNhIPv4(r, out_vp) \ memcpy((out_vp), &((r)->nhIP.ipu_ipv4), RWREC_SIZEOF_NHIPv4) #define _recMemSetNhIPv4(r, in_vp) \ memcpy(&((r)->nhIP.ipu_ipv4), (in_vp), RWREC_SIZEOF_NHIPv4) #define _recMemCmpNhIPv4(r, vp) \ memcmp(&((r)->nhIP.ipu_ipv4), (vp), RWREC_SIZEOF_NHIPv4) #define _recGetMaskNhIPv4(r, mask) \ (((r)->nhIP.ipu_ipv4) & mask) #define _recApplyMaskNhIPv4(r, mask) \ ipUnionApplyMaskV4(&((r)->nhIP), (mask)) #if RWREC_OPAQUE # define rwRecGetNhIPv4(r) rwrec_GetNhIPv4(r) # define rwRecSetNhIPv4(r, in_v) rwrec_SetNhIPv4(r, in_v) # define rwRecMemGetNhIPv4(r, out_vp) rwrec_MemGetNhIPv4(r, out_vp) # define rwRecMemSetNhIPv4(r, in_vp) rwrec_MemSetNhIPv4(r, in_vp) # define rwRecMemCmpNhIPv4(r, vp) rwrec_MemCmpNhIPv4(r, vp) # define rwRecGetMaskNhIPv4(r, mask) rwrec_GetMaskNhIPv4(r, mask) # define rwRecApplyMaskNhIPv4(r, mask) rwrec_ApplyMaskNhIPv4(r, mask) #else # define rwRecGetNhIPv4(r) _recGetNhIPv4(r) # define rwRecSetNhIPv4(r, in_v) _recSetNhIPv4(r, in_v) # define rwRecMemGetNhIPv4(r, out_vp) _recMemGetNhIPv4(r, out_vp) # define rwRecMemSetNhIPv4(r, in_vp) _recMemSetNhIPv4(r, in_vp) # define rwRecMemCmpNhIPv4(r, vp) _recMemCmpNhIPv4(r, vp) # define rwRecGetMaskNhIPv4(r, mask) _recGetMaskNhIPv4(r, mask) # define rwRecApplyMaskNhIPv4(r, mask) _recApplyMaskNhIPv4(r, mask) #endif /* RWREC_OPAQUE */ /*** Next Hop IPv6 Address (nhIP) ***/ #if SK_ENABLE_IPV6 void rwrec_MemGetNhIPv6(const rwRec *r, void *out_vp); void rwrec_MemSetNhIPv6(rwRec *r, const void *in_vp); int rwrec_MemCmpNhIPv6(const rwRec *r, const void *vp); void rwrec_ApplyMaskNhIPv6(rwRec *r, const void *mask_vp); #define _recMemGetNhIPv6(r, out_vp) \ if (_recIsIPv6(r)) { \ ipUnionGetV6(&((r)->nhIP), (out_vp)); \ } else { \ ipUnionGetV4AsV6(&((r)->nhIP), (out_vp)); \ } #define _recMemSetNhIPv6(r, in_vp) \ memcpy(&((r)->nhIP.ipu_ipv6), (in_vp), RWREC_SIZEOF_NHIPv6) #define _recMemCmpNhIPv6(r, vp) \ memcmp(&((r)->nhIP.ipu_ipv6), (vp), RWREC_SIZEOF_NHIPv6) #define _recApplyMaskNhIPv6(r, mask) \ ipUnionApplyMaskV6(&((r)->nhIP), (mask)) #if RWREC_OPAQUE # define rwRecMemGetNhIPv6(r, out_vp) rwrec_MemGetNhIPv6(r, out_vp) # define rwRecMemSetNhIPv6(r, in_vp) rwrec_MemSetNhIPv6(r, in_vp) # define rwRecMemCmpNhIPv6(r, vp) rwrec_MemCmpNhIPv6(r, vp) # define rwRecApplyMaskNhIPv6(r, mask) rwrec_ApplyMaskNhIPv6(r, mask) #else # define rwRecMemGetNhIPv6(r, out_vp) _recMemGetNhIPv6(r, out_vp) # define rwRecMemSetNhIPv6(r, in_vp) _recMemSetNhIPv6(r, in_vp) # define rwRecMemCmpNhIPv6(r, vp) _recMemCmpNhIPv6(r, vp) # define rwRecApplyMaskNhIPv6(r, mask) _recApplyMaskNhIPv6(r, mask) #endif /* RWREC_OPAQUE */ #endif /* SK_ENABLE_IPV6 */ /*** Next Hop IP Address (nhIP) as skipaddr_t ***/ void rwrec_MemGetNhIP(const rwRec *r, skipaddr_t *out_addr); void rwrec_MemSetNhIP(rwRec *r, const skipaddr_t *in_addr); int rwrec_MemCmpNhIP(const rwRec *r, const skipaddr_t *addr); void rwrec_ApplyMaskNhIP(rwRec *r, const skipaddr_t *mask_addr); #if !SK_ENABLE_IPV6 #define _recMemGetNhIP _recMemGetNhIPv4 #define _recMemSetNhIP _recMemSetNhIPv4 #define _recMemCmpNhIP(r, addr) \ _recMemCmpNhIPv4((r), &((addr)->ip_ip.ipu_ipv4)) #define _recApplyMaskNhIP(r, addr) \ _recApplyMaskNhIPv4((r), (addr)->ip_ip.ipu_ipv4) #else #define _recMemGetNhIP(r, out_addr) \ do { \ memcpy(out_addr, &((r)->nhIP), sizeof(ipUnion)); \ skipaddrSetVersion((out_addr), _recIsIPv6(r)); \ } while(0) #define _recMemSetNhIP(r, in_addr) \ do { \ if (skipaddrIsV6(in_addr) == _recIsIPv6(r)) { \ /* both are either V4 or V6 */ \ memcpy(&((r)->nhIP), (in_addr), sizeof(ipUnion)); \ } else if (_recIsIPv6(r)) { \ /* convert V4 IP to V6 */ \ ipUnion4to6(&((in_addr)->ip_ip), &((r)->nhIP)); \ } else { \ /* must convert record to V6 */ \ _recConvertToIPv6(r); \ memcpy(&((r)->nhIP), (in_addr), sizeof(ipUnion)); \ } \ } while(0) #define _recMemCmpNhIP(r, addr) rwrec_MemCmpNhIP(r, addr) #define _recApplyMaskNhIP(r, addr) rwrec_ApplyMaskNhIP(r, addr) #endif /* SK_ENABLE_IPV6 */ #if RWREC_OPAQUE # define rwRecMemGetNhIP(r, out_addr) rwrec_MemGetNhIP(r, out_addr) # define rwRecMemSetNhIP(r, in_addr) rwrec_MemSetNhIP(r, in_addr) # define rwRecMemCmpNhIP(r, addr) rwrec_MemCmpNhIP(r, addr) # define rwRecApplyMaskNhIP(r, addr) rwrec_ApplyMaskNhIP(r, addr) #else # define rwRecMemGetNhIP(r, out_addr) _recMemGetNhIP(r, out_addr) # define rwRecMemSetNhIP(r, in_addr) _recMemSetNhIP(r, in_addr) # define rwRecMemCmpNhIP(r, addr) _recMemCmpNhIP(r, addr) # define rwRecApplyMaskNhIP(r, addr) _recApplyMaskNhIP(r, addr) #endif /* RWREC_OPAQUE */ /*** Source Port (sPort) ***/ uint16_t rwrec_GetSPort(const rwRec *r); void rwrec_SetSPort(rwRec *r, uint16_t in_v); void rwrec_MemGetSPort(const rwRec *r, void *out_vp); void rwrec_MemSetSPort(rwRec *r, const void *in_vp); int rwrec_MemCmpSPort(const rwRec *r, const void *vp); #define _recGetSPort(r) \ ((r)->sPort) #define _recSetSPort(r, in_v) \ { ((r)->sPort) = (in_v); } #define _recMemGetSPort(r, out_vp) \ memcpy((out_vp), &((r)->sPort), RWREC_SIZEOF_SPORT) #define _recMemSetSPort(r, in_vp) \ memcpy(&((r)->sPort), (in_vp), RWREC_SIZEOF_SPORT) #define _recMemCmpSPort(r, vp) \ memcmp(&((r)->sPort), (vp), RWREC_SIZEOF_SPORT) #if RWREC_OPAQUE # define rwRecGetSPort(r) rwrec_GetSPort(r) # define rwRecSetSPort(r, in_v) rwrec_SetSPort(r, in_v) # define rwRecMemGetSPort(r, out_vp) rwrec_MemGetSPort(r, out_vp) # define rwRecMemSetSPort(r, in_vp) rwrec_MemSetSPort(r, in_vp) # define rwRecMemCmpSPort(r, vp) rwrec_MemCmpSPort(r, vp) #else # define rwRecGetSPort(r) _recGetSPort(r) # define rwRecSetSPort(r, in_v) _recSetSPort(r, in_v) # define rwRecMemGetSPort(r, out_vp) _recMemGetSPort(r, out_vp) # define rwRecMemSetSPort(r, in_vp) _recMemSetSPort(r, in_vp) # define rwRecMemCmpSPort(r, vp) _recMemCmpSPort(r, vp) #endif /* RWREC_OPAQUE */ /*** Destination Port (dPort) ***/ uint16_t rwrec_GetDPort(const rwRec *r); void rwrec_SetDPort(rwRec *r, uint16_t in_v); void rwrec_MemGetDPort(const rwRec *r, void *out_vp); void rwrec_MemSetDPort(rwRec *r, const void *in_vp); int rwrec_MemCmpDPort(const rwRec *r, const void *vp); #define _recGetDPort(r) \ ((r)->dPort) #define _recSetDPort(r, in_v) \ { ((r)->dPort) = (in_v); } #define _recMemGetDPort(r, out_vp) \ memcpy((out_vp), &((r)->dPort), RWREC_SIZEOF_DPORT) #define _recMemSetDPort(r, in_vp) \ memcpy(&((r)->dPort), (in_vp), RWREC_SIZEOF_DPORT) #define _recMemCmpDPort(r, vp) \ memcmp(&((r)->dPort), (vp), RWREC_SIZEOF_DPORT) #if RWREC_OPAQUE # define rwRecGetDPort(r) rwrec_GetDPort(r) # define rwRecSetDPort(r, in_v) rwrec_SetDPort(r, in_v) # define rwRecMemGetDPort(r, out_vp) rwrec_MemGetDPort(r, out_vp) # define rwRecMemSetDPort(r, in_vp) rwrec_MemSetDPort(r, in_vp) # define rwRecMemCmpDPort(r, vp) rwrec_MemCmpDPort(r, vp) #else # define rwRecGetDPort(r) _recGetDPort(r) # define rwRecSetDPort(r, in_v) _recSetDPort(r, in_v) # define rwRecMemGetDPort(r, out_vp) _recMemGetDPort(r, out_vp) # define rwRecMemSetDPort(r, in_vp) _recMemSetDPort(r, in_vp) # define rwRecMemCmpDPort(r, vp) _recMemCmpDPort(r, vp) #endif /* RWREC_OPAQUE */ /*** Protocol ***/ uint8_t rwrec_GetProto(const rwRec *r); void rwrec_SetProto(rwRec *r, uint8_t in_v); void rwrec_MemGetProto(const rwRec *r, void *out_vp); void rwrec_MemSetProto(rwRec *r, const void *in_vp); int rwrec_MemCmpProto(const rwRec *r, const void *vp); #define _recGetProto(r) \ ((r)->proto) #define _recSetProto(r, in_v) \ { ((r)->proto) = (in_v); } #define _recMemGetProto(r, out_vp) \ memcpy((out_vp), &((r)->proto), RWREC_SIZEOF_PROTO) #define _recMemSetProto(r, in_vp) \ memcpy(&((r)->proto), (in_vp), RWREC_SIZEOF_PROTO) #define _recMemCmpProto(r, vp) \ memcmp(&((r)->proto), (vp), RWREC_SIZEOF_PROTO) #if RWREC_OPAQUE # define rwRecGetProto(r) rwrec_GetProto(r) # define rwRecSetProto(r, in_v) rwrec_SetProto(r, in_v) # define rwRecMemGetProto(r, out_vp) rwrec_MemGetProto(r, out_vp) # define rwRecMemSetProto(r, in_vp) rwrec_MemSetProto(r, in_vp) # define rwRecMemCmpProto(r, vp) rwrec_MemCmpProto(r, vp) #else # define rwRecGetProto(r) _recGetProto(r) # define rwRecSetProto(r, in_v) _recSetProto(r, in_v) # define rwRecMemGetProto(r, out_vp) _recMemGetProto(r, out_vp) # define rwRecMemSetProto(r, in_vp) _recMemSetProto(r, in_vp) # define rwRecMemCmpProto(r, vp) _recMemCmpProto(r, vp) #endif /* RWREC_OPAQUE */ /*** Packet Count (pkts) ***/ uint32_t rwrec_GetPkts(const rwRec *r); void rwrec_SetPkts(rwRec *r, uint32_t in_v); void rwrec_MemGetPkts(const rwRec *r, void *out_vp); void rwrec_MemSetPkts(rwRec *r, const void *in_vp); int rwrec_MemCmpPkts(const rwRec *r, const void *vp); #define _recGetPkts(r) \ ((r)->pkts) #define _recSetPkts(r, in_v) \ { ((r)->pkts) = (in_v); } #define _recMemGetPkts(r, out_vp) \ memcpy((out_vp), &((r)->pkts), RWREC_SIZEOF_PKTS) #define _recMemSetPkts(r, in_vp) \ memcpy(&((r)->pkts), (in_vp), RWREC_SIZEOF_PKTS) #define _recMemCmpPkts(r, vp) \ memcmp(&((r)->pkts), (vp), RWREC_SIZEOF_PKTS) #if RWREC_OPAQUE # define rwRecGetPkts(r) rwrec_GetPkts(r) # define rwRecSetPkts(r, in_v) rwrec_SetPkts(r, in_v) # define rwRecMemGetPkts(r, out_vp) rwrec_MemGetPkts(r, out_vp) # define rwRecMemSetPkts(r, in_vp) rwrec_MemSetPkts(r, in_vp) # define rwRecMemCmpPkts(r, vp) rwrec_MemCmpPkts(r, vp) #else # define rwRecGetPkts(r) _recGetPkts(r) # define rwRecSetPkts(r, in_v) _recSetPkts(r, in_v) # define rwRecMemGetPkts(r, out_vp) _recMemGetPkts(r, out_vp) # define rwRecMemSetPkts(r, in_vp) _recMemSetPkts(r, in_vp) # define rwRecMemCmpPkts(r, vp) _recMemCmpPkts(r, vp) #endif /* RWREC_OPAQUE */ /*** Byte count ***/ uint32_t rwrec_GetBytes(const rwRec *r); void rwrec_SetBytes(rwRec *r, uint32_t in_v); void rwrec_MemGetBytes(const rwRec *r, void *out_vp); void rwrec_MemSetBytes(rwRec *r, const void *in_vp); int rwrec_MemCmpBytes(const rwRec *r, const void *vp); #define _recGetBytes(r) \ ((r)->bytes) #define _recSetBytes(r, in_v) \ { ((r)->bytes) = (in_v); } #define _recMemGetBytes(r, out_vp) \ memcpy((out_vp), &((r)->bytes), RWREC_SIZEOF_BYTES) #define _recMemSetBytes(r, in_vp) \ memcpy(&((r)->bytes), (in_vp), RWREC_SIZEOF_BYTES) #define _recMemCmpBytes(r, vp) \ memcmp(&((r)->bytes), (vp), RWREC_SIZEOF_BYTES) #if RWREC_OPAQUE # define rwRecGetBytes(r) rwrec_GetBytes(r) # define rwRecSetBytes(r, in_v) rwrec_SetBytes(r, in_v) # define rwRecMemGetBytes(r, out_vp) rwrec_MemGetBytes(r, out_vp) # define rwRecMemSetBytes(r, in_vp) rwrec_MemSetBytes(r, in_vp) # define rwRecMemCmpBytes(r, vp) rwrec_MemCmpBytes(r, vp) #else # define rwRecGetBytes(r) _recGetBytes(r) # define rwRecSetBytes(r, in_v) _recSetBytes(r, in_v) # define rwRecMemGetBytes(r, out_vp) _recMemGetBytes(r, out_vp) # define rwRecMemSetBytes(r, in_vp) _recMemSetBytes(r, in_vp) # define rwRecMemCmpBytes(r, vp) _recMemCmpBytes(r, vp) #endif /* RWREC_OPAQUE */ /*** Bitwise OR of TCP Flags on ALL packets in flow ***/ uint8_t rwrec_GetFlags(const rwRec *r); void rwrec_SetFlags(rwRec *r, uint8_t in_v); void rwrec_MemGetFlags(const rwRec *r, void *out_vp); void rwrec_MemSetFlags(rwRec *r, const void *in_vp); int rwrec_MemCmpFlags(const rwRec *r, const void *vp); #define _recGetFlags(r) \ ((r)->flags) #define _recSetFlags(r, in_v) \ { ((r)->flags) = (in_v); } #define _recMemGetFlags(r, out_vp) \ memcpy((out_vp), &((r)->flags), RWREC_SIZEOF_FLAGS) #define _recMemSetFlags(r, in_vp) \ memcpy(&((r)->flags), (in_vp), RWREC_SIZEOF_FLAGS) #define _recMemCmpFlags(r, vp) \ memcmp(&((r)->flags), (vp), RWREC_SIZEOF_FLAGS) #if RWREC_OPAQUE # define rwRecGetFlags(r) rwrec_GetFlags(r) # define rwRecSetFlags(r, in_v) rwrec_SetFlags(r, in_v) # define rwRecMemGetFlags(r, out_vp) rwrec_MemGetFlags(r, out_vp) # define rwRecMemSetFlags(r, in_vp) rwrec_MemSetFlags(r, in_vp) # define rwRecMemCmpFlags(r, vp) rwrec_MemCmpFlags(r, vp) #else # define rwRecGetFlags(r) _recGetFlags(r) # define rwRecSetFlags(r, in_v) _recSetFlags(r, in_v) # define rwRecMemGetFlags(r, out_vp) _recMemGetFlags(r, out_vp) # define rwRecMemSetFlags(r, in_vp) _recMemSetFlags(r, in_vp) # define rwRecMemCmpFlags(r, vp) _recMemCmpFlags(r, vp) #endif /* RWREC_OPAQUE */ /*** TCP Flags seen on initial packet of flow ***/ uint8_t rwrec_GetInitFlags(const rwRec *r); void rwrec_SetInitFlags(rwRec *r, uint8_t in_v); void rwrec_MemGetInitFlags(const rwRec *r, void *out_vp); void rwrec_MemSetInitFlags(rwRec *r, const void *in_vp); int rwrec_MemCmpInitFlags(const rwRec *r, const void *vp); #define _recGetInitFlags(r) \ ((r)->init_flags) #define _recSetInitFlags(r, in_v) \ { ((r)->init_flags) = (in_v); } #define _recMemGetInitFlags(r, out_vp) \ memcpy((out_vp), &((r)->init_flags), RWREC_SIZEOF_INIT_FLAGS) #define _recMemSetInitFlags(r, in_vp) \ memcpy(&((r)->init_flags), (in_vp), RWREC_SIZEOF_INIT_FLAGS) #define _recMemCmpInitFlags(r, vp) \ memcmp(&((r)->init_flags), (vp), RWREC_SIZEOF_INIT_FLAGS) #if RWREC_OPAQUE # define rwRecGetInitFlags(r) rwrec_GetInitFlags(r) # define rwRecSetInitFlags(r, in_v) rwrec_SetInitFlags(r, in_v) # define rwRecMemGetInitFlags(r, out_vp) rwrec_MemGetInitFlags(r, out_vp) # define rwRecMemSetInitFlags(r, in_vp) rwrec_MemSetInitFlags(r, in_vp) # define rwRecMemCmpInitFlags(r, vp) rwrec_MemCmpInitFlags(r, vp) #else # define rwRecGetInitFlags(r) _recGetInitFlags(r) # define rwRecSetInitFlags(r, in_v) _recSetInitFlags(r, in_v) # define rwRecMemGetInitFlags(r, out_vp) _recMemGetInitFlags(r, out_vp) # define rwRecMemSetInitFlags(r, in_vp) _recMemSetInitFlags(r, in_vp) # define rwRecMemCmpInitFlags(r, vp) _recMemCmpInitFlags(r, vp) #endif /* RWREC_OPAQUE */ /*** Bitwise OR of TCP Flags on all packets in session except first ***/ uint8_t rwrec_GetRestFlags(const rwRec *r); void rwrec_SetRestFlags(rwRec *r, uint8_t in_v); void rwrec_MemGetRestFlags(const rwRec *r, void *out_vp); void rwrec_MemSetRestFlags(rwRec *r, const void *in_vp); int rwrec_MemCmpRestFlags(const rwRec *r, const void *vp); #define _recGetRestFlags(r) \ ((r)->rest_flags) #define _recSetRestFlags(r, in_v) \ { ((r)->rest_flags) = (in_v); } #define _recMemGetRestFlags(r, out_vp) \ memcpy((out_vp), &((r)->rest_flags), RWREC_SIZEOF_REST_FLAGS) #define _recMemSetRestFlags(r, in_vp) \ memcpy(&((r)->rest_flags), (in_vp), RWREC_SIZEOF_REST_FLAGS) #define _recMemCmpRestFlags(r, vp) \ memcmp(&((r)->rest_flags), (vp), RWREC_SIZEOF_REST_FLAGS) #if RWREC_OPAQUE # define rwRecGetRestFlags(r) rwrec_GetRestFlags(r) # define rwRecSetRestFlags(r, in_v) rwrec_SetRestFlags(r, in_v) # define rwRecMemGetRestFlags(r, out_vp) rwrec_MemGetRestFlags(r, out_vp) # define rwRecMemSetRestFlags(r, in_vp) rwrec_MemSetRestFlags(r, in_vp) # define rwRecMemCmpRestFlags(r, vp) rwrec_MemCmpRestFlags(r, vp) #else # define rwRecGetRestFlags(r) _recGetRestFlags(r) # define rwRecSetRestFlags(r, in_v) _recSetRestFlags(r, in_v) # define rwRecMemGetRestFlags(r, out_vp) _recMemGetRestFlags(r, out_vp) # define rwRecMemSetRestFlags(r, in_vp) _recMemSetRestFlags(r, in_vp) # define rwRecMemCmpRestFlags(r, vp) _recMemCmpRestFlags(r, vp) #endif /* RWREC_OPAQUE */ /*** Start Time as milliseconds since UNIX epoch (sTime) ***/ sktime_t rwrec_GetStartTime(const rwRec *r); void rwrec_SetStartTime(rwRec *r, sktime_t in_v); void rwrec_MemGetStartTime(const rwRec *r, void *out_vp); void rwrec_MemSetStartTime(rwRec *r, const void *in_vp); int rwrec_MemCmpStartTime(const rwRec *r, const void *vp); uint32_t rwrec_GetStartSeconds(const rwRec *r); void rwrec_MemGetStartSeconds(const rwRec *r, void *out_vp); uint16_t rwrec_GetStartMSec(const rwRec *r); void rwrec_MemGetStartMSec(const rwRec *r, void *out_vp); #define _recGetStartTime(r) \ ((r)->sTime) #define _recSetStartTime(r, in_v) \ { ((r)->sTime = (in_v)); } #define _recMemGetStartTime(r, out_vp) \ memcpy((out_vp), &((r)->sTime), RWREC_SIZEOF_STIME) #define _recMemSetStartTime(r, in_vp) \ memcpy(&((r)->sTime), (in_vp), RWREC_SIZEOF_STIME) #define _recMemCmpStartTime(r, vp) \ memcmp(&((r)->sTime), (vp), RWREC_SIZEOF_STIME) #define _recGetStartSeconds(r) \ ((uint32_t)((r)->sTime / 1000)) #define _recMemGetStartSeconds(r, out_vp) { \ uint32_t _t = _recGetStartSeconds(r); \ memcpy((out_vp), &_t, sizeof(_t)); \ } #define _recGetStartMSec(r) \ ((uint16_t)((r)->sTime % 1000)) #define _recMemGetStartMSec(r, out_vp) { \ uint16_t _t = _recGetStartMSec(r); \ memcpy((out_vp), &_t, sizeof(_t)); \ } #if RWREC_OPAQUE # define rwRecGetStartTime(r) rwrec_GetStartTime(r) # define rwRecSetStartTime(r, in_v) rwrec_SetStartTime(r, in_v) # define rwRecMemGetStartTime(r, out_vp) rwrec_MemGetStartTime(r, out_vp) # define rwRecMemSetStartTime(r, in_vp) rwrec_MemSetStartTime(r, in_vp) # define rwRecMemCmpStartTime(r, vp) rwrec_MemCmpStartTime(r, vp) # define rwRecGetStartSeconds(r) rwrec_GetStartSeconds(r) # define rwRecMemGetStartSeconds(r, out_vp) \ rwrec_MemGetStartSeconds(r, out_vp) # define rwRecGetStartMSec(r) rwrec_GetStartMSec(r) # define rwRecMemGetStartMSec(r, out_vp) rwrec_MemGetStartMSec(r, out_vp) #else # define rwRecGetStartTime(r) _recGetStartTime(r) # define rwRecSetStartTime(r, in_v) _recSetStartTime(r, in_v) # define rwRecMemGetStartTime(r, out_vp) _recMemGetStartTime(r, out_vp) # define rwRecMemSetStartTime(r, in_vp) _recMemSetStartTime(r, in_vp) # define rwRecMemCmpStartTime(r, vp) _recMemCmpStartTime(r, vp) # define rwRecGetStartSeconds(r) _recGetStartSeconds(r) # define rwRecMemGetStartSeconds(r, out_vp) _recMemGetStartSeconds(r, out_vp) # define rwRecGetStartMSec(r) _recGetStartMSec(r) # define rwRecMemGetStartMSec(r, out_vp) _recMemGetStartMSec(r, out_vp) #endif /* RWREC_OPAQUE */ /*** Elapsed (duration) of the flow, in milliseconds ***/ uint32_t rwrec_GetElapsed(const rwRec *r); void rwrec_SetElapsed(rwRec *r, sktime_t in_v); void rwrec_MemGetElapsed(const rwRec *r, void *out_vp); void rwrec_MemSetElapsed(rwRec *r, const void *in_vp); int rwrec_MemCmpElapsed(const rwRec *r, const void *vp); uint32_t rwrec_GetElapsedSeconds(const rwRec *r); void rwrec_MemGetElapsedSeconds(const rwRec *r, void *out_vp); uint16_t rwrec_GetElapsedMSec(const rwRec *r); void rwrec_MemGetElapsedMSec(const rwRec *r, void *out_vp); #define _recGetElapsed(r) \ ((r)->elapsed) #define _recSetElapsed(r, in_v) \ { (r)->elapsed = (uint32_t)(in_v); } #define _recMemGetElapsed(r, out_vp) \ memcpy((out_vp), &((r)->elapsed), RWREC_SIZEOF_ELAPSED) #define _recMemSetElapsed(r, in_vp) \ memcpy(&((r)->elapsed), (in_vp), RWREC_SIZEOF_ELAPSED) #define _recMemCmpElapsed(r, vp) \ memcmp(&((r)->elapsed), (vp), RWREC_SIZEOF_ELAPSED) #define _recGetElapsedSeconds(r) \ ((uint32_t)((r)->elapsed / 1000)) #define _recMemGetElapsedSeconds(r, out_vp) { \ uint32_t _t = _recGetElapsedSeconds(r); \ memcpy((out_vp), &_t, sizeof(_t)); \ } #define _recGetElapsedMSec(r) \ ((uint16_t)((r)->elapsed % 1000)) #define _recMemGetElapsedMSec(r, out_vp) { \ uint16_t _t = _recGetElapsedMSec(r); \ memcpy((out_vp), &_t, sizeof(_t)); \ } #if RWREC_OPAQUE # define rwRecGetElapsed(r) rwrec_GetElapsed(r) # define rwRecSetElapsed(r, in_v) rwrec_SetElapsed(r, in_v) # define rwRecMemGetElapsed(r, out_vp) rwrec_MemGetElapsed(r, out_vp) # define rwRecMemSetElapsed(r, in_vp) rwrec_MemSetElapsed(r, in_vp) # define rwRecMemCmpElapsed(r, vp) rwrec_MemCmpElapsed(r, vp) # define rwRecGetElapsedSeconds(r) rwrec_GetElapsedSeconds(r) # define rwRecMemGetElapsedSeconds(r, out_vp) \ rwrec_MemGetElapsedSeconds(r, out_vp) # define rwRecGetElapsedMSec(r) rwrec_GetElapsedMSec(r) # define rwRecMemGetElapsedMSec(r, out_vp) rwrec_MemGetElapsedMSec(r, out_vp) #else # define rwRecGetElapsed(r) _recGetElapsed(r) # define rwRecSetElapsed(r, in_v) _recSetElapsed(r, in_v) # define rwRecMemGetElapsed(r, out_vp) _recMemGetElapsed(r, out_vp) # define rwRecMemSetElapsed(r, in_vp) _recMemSetElapsed(r, in_vp) # define rwRecMemCmpElapsed(r, vp) _recMemCmpElapsed(r, vp) # define rwRecGetElapsedSeconds(r) _recGetElapsedSeconds(r) # define rwRecMemGetElapsedSeconds(r, out_vp) \ _recMemGetElapsedSeconds(r, out_vp) # define rwRecGetElapsedMSec(r) _recGetElapsedMSec(r) # define rwRecMemGetElapsedMSec(r, out_vp) _recMemGetElapsedMSec(r, out_vp) #endif /* RWREC_OPAQUE */ /*** End Time is derived from the sTime and duration (eTime) ***/ /* No Set macros/functions since this is a derived field */ sktime_t rwrec_GetEndTime(const rwRec *r); void rwrec_MemGetEndTime(const rwRec *r, void *out_vp); uint32_t rwrec_GetEndSeconds(const rwRec *r); void rwrec_MemGetEndSeconds(const rwRec *r, void *out_vp); uint16_t rwrec_GetEndMSec(const rwRec *r); void rwrec_MemGetEndMSec(const rwRec *r, void *out_vp); #define _recGetEndTime(r) \ ((sktime_t)_recGetStartTime(r) + _recGetElapsed(r)) #define _recMemGetEndTime(r, out_vp) { \ sktime_t _t = _recGetEndTime(r); \ memcpy((out_vp), &_t, sizeof(_t)); \ } #define _recGetEndSeconds(r) \ ((uint32_t)(_recGetEndTime(r) / 1000)) #define _recMemGetEndSeconds(r, out_vp) { \ uint32_t _t = rwRecGetEndSeconds(r); \ memcpy((out_vp), &_t, sizeof(_t)); \ } #define _recGetEndMSec(r) \ ((uint16_t)(_recGetEndTime(r) % 1000)) #define _recMemGetEndMSec(r, out_vp) { \ uint16_t _t = _recGetEndMSec(r); \ memcpy((out_vp), &_t, sizeof(_t)); \ } #if RWREC_OPAQUE # define rwRecGetEndTime(r) rwrec_GetEndTime(r) # define rwRecMemGetEndTime(r, out_vp) rwrec_MemGetEndTime(r, out_vp) # define rwRecGetEndSeconds(r) rwrec_GetEndSeconds(r) # define rwRecMemGetEndSeconds(r, out_vp) rwrec_MemGetEndSeconds(r, out_vp) # define rwRecGetEndMSec(r) rwrec_GetEndMSec(r) # define rwRecMemGetEndMSec(r, out_vp) rwrec_MemGetEndMSec(r, out_vp) #else # define rwRecGetEndTime(r) _recGetEndTime(r) # define rwRecMemGetEndTime(r, out_vp) _recMemGetEndTime(r, out_vp) # define rwRecGetEndSeconds(r) _recGetEndSeconds(r) # define rwRecMemGetEndSeconds(r, out_vp) _recMemGetEndSeconds(r, out_vp) # define rwRecGetEndMSec(r) _recGetEndMSec(r) # define rwRecMemGetEndMSec(r, out_vp) _recMemGetEndMSec(r, out_vp) #endif /* RWREC_OPAQUE */ /*** Sensor ID (sID) ***/ sensorID_t rwrec_GetSensor(const rwRec *r); void rwrec_SetSensor(rwRec *r, sensorID_t in_v); void rwrec_MemGetSensor(const rwRec *r, void *out_vp); void rwrec_MemSetSensor(rwRec *r, const void *in_vp); int rwrec_MemCmpSensor(const rwRec *r, const void *vp); #define _recGetSensor(r) \ ((r)->sID) #define _recSetSensor(r, in_v) \ { ((r)->sID) = (in_v); } #define _recMemGetSensor(r, out_vp) \ memcpy((out_vp), &((r)->sID), RWREC_SIZEOF_SID) #define _recMemSetSensor(r, in_vp) \ memcpy(&((r)->sID), (in_vp), RWREC_SIZEOF_SID) #define _recMemCmpSensor(r, vp) \ memcmp(&((r)->sID), (vp), RWREC_SIZEOF_SID) #if RWREC_OPAQUE # define rwRecGetSensor(r) rwrec_GetSensor(r) # define rwRecSetSensor(r, in_v) rwrec_SetSensor(r, in_v) # define rwRecMemGetSensor(r, out_vp) rwrec_MemGetSensor(r, out_vp) # define rwRecMemSetSensor(r, in_vp) rwrec_MemSetSensor(r, in_vp) # define rwRecMemCmpSensor(r, vp) rwrec_MemCmpSensor(r, vp) #else # define rwRecGetSensor(r) _recGetSensor(r) # define rwRecSetSensor(r, in_v) _recSetSensor(r, in_v) # define rwRecMemGetSensor(r, out_vp) _recMemGetSensor(r, out_vp) # define rwRecMemSetSensor(r, in_vp) _recMemSetSensor(r, in_vp) # define rwRecMemCmpSensor(r, vp) _recMemCmpSensor(r, vp) #endif /* RWREC_OPAQUE */ /*** FlowType holds Class and Type ***/ flowtypeID_t rwrec_GetFlowType(const rwRec *r); void rwrec_SetFlowType(rwRec *r, flowtypeID_t in_v); void rwrec_MemGetFlowType(const rwRec *r, void *out_vp); void rwrec_MemSetFlowType(rwRec *r, const void *in_vp); int rwrec_MemCmpFlowType(const rwRec *r, const void *vp); #define _recGetFlowType(r) \ ((r)->flow_type) #define _recSetFlowType(r, in_v) \ { ((r)->flow_type) = (in_v); } #define _recMemGetFlowType(r, out_vp) \ memcpy((out_vp), &((r)->flow_type), RWREC_SIZEOF_FLOW_TYPE) #define _recMemSetFlowType(r, in_vp) \ memcpy(&((r)->flow_type), (in_vp), RWREC_SIZEOF_FLOW_TYPE) #define _recMemCmpFlowType(r, vp) \ memcmp(&((r)->flow_type), (vp), RWREC_SIZEOF_FLOW_TYPE) #if RWREC_OPAQUE # define rwRecGetFlowType(r) rwrec_GetFlowType(r) # define rwRecSetFlowType(r, in_v) rwrec_SetFlowType(r, in_v) # define rwRecMemGetFlowType(r, out_vp) rwrec_MemGetFlowType(r, out_vp) # define rwRecMemSetFlowType(r, in_vp) rwrec_MemSetFlowType(r, in_vp) # define rwRecMemCmpFlowType(r, vp) rwrec_MemCmpFlowType(r, vp) #else # define rwRecGetFlowType(r) _recGetFlowType(r) # define rwRecSetFlowType(r, in_v) _recSetFlowType(r, in_v) # define rwRecMemGetFlowType(r, out_vp) _recMemGetFlowType(r, out_vp) # define rwRecMemSetFlowType(r, in_vp) _recMemSetFlowType(r, in_vp) # define rwRecMemCmpFlowType(r, vp) _recMemCmpFlowType(r, vp) #endif /* RWREC_OPAQUE */ /*** SNMP Input Value (Router incoming/ingress interface) ***/ uint16_t rwrec_GetInput(const rwRec *r); void rwrec_SetInput(rwRec *r, uint16_t in_v); void rwrec_MemGetInput(const rwRec *r, void *out_vp); void rwrec_MemSetInput(rwRec *r, const void *in_vp); int rwrec_MemCmpInput(const rwRec *r, const void *vp); #define _recGetInput(r) \ ((r)->input) #define _recSetInput(r, in_v) \ { ((r)->input) = (in_v); } #define _recMemGetInput(r, out_vp) \ memcpy((out_vp), &((r)->input), RWREC_SIZEOF_INPUT) #define _recMemSetInput(r, in_vp) \ memcpy(&((r)->input), (in_vp), RWREC_SIZEOF_INPUT) #define _recMemCmpInput(r, vp) \ memcmp(&((r)->input), (vp), RWREC_SIZEOF_INPUT) #if RWREC_OPAQUE # define rwRecGetInput(r) rwrec_GetInput(r) # define rwRecSetInput(r, in_v) rwrec_SetInput(r, in_v) # define rwRecMemGetInput(r, out_vp) rwrec_MemGetInput(r, out_vp) # define rwRecMemSetInput(r, in_vp) rwrec_MemSetInput(r, in_vp) # define rwRecMemCmpInput(r, vp) rwrec_MemCmpInput(r, vp) #else # define rwRecGetInput(r) _recGetInput(r) # define rwRecSetInput(r, in_v) _recSetInput(r, in_v) # define rwRecMemGetInput(r, out_vp) _recMemGetInput(r, out_vp) # define rwRecMemSetInput(r, in_vp) _recMemSetInput(r, in_vp) # define rwRecMemCmpInput(r, vp) _recMemCmpInput(r, vp) #endif /* RWREC_OPAQUE */ /*** SNMP Output Value (Router outgoing/egress interface) ***/ uint16_t rwrec_GetOutput(const rwRec *r); void rwrec_SetOutput(rwRec *r, uint16_t in_v); void rwrec_MemGetOutput(const rwRec *r, void *out_vp); void rwrec_MemSetOutput(rwRec *r, const void *in_vp); int rwrec_MemCmpOutput(const rwRec *r, const void *vp); #define _recGetOutput(r) \ ((r)->output) #define _recSetOutput(r, in_v) \ { ((r)->output) = (in_v); } #define _recMemGetOutput(r, out_vp) \ memcpy((out_vp), &((r)->output), RWREC_SIZEOF_OUTPUT) #define _recMemSetOutput(r, in_vp) \ memcpy(&((r)->output), (in_vp), RWREC_SIZEOF_OUTPUT) #define _recMemCmpOutput(r, vp) \ memcmp(&((r)->output), (vp), RWREC_SIZEOF_OUTPUT) #if RWREC_OPAQUE # define rwRecGetOutput(r) rwrec_GetOutput(r) # define rwRecSetOutput(r, in_v) rwrec_SetOutput(r, in_v) # define rwRecMemGetOutput(r, out_vp) rwrec_MemGetOutput(r, out_vp) # define rwRecMemSetOutput(r, in_vp) rwrec_MemSetOutput(r, in_vp) # define rwRecMemCmpOutput(r, vp) rwrec_MemCmpOutput(r, vp) #else # define rwRecGetOutput(r) _recGetOutput(r) # define rwRecSetOutput(r, in_v) _recSetOutput(r, in_v) # define rwRecMemGetOutput(r, out_vp) _recMemGetOutput(r, out_vp) # define rwRecMemSetOutput(r, in_vp) _recMemSetOutput(r, in_vp) # define rwRecMemCmpOutput(r, vp) _recMemCmpOutput(r, vp) #endif /* RWREC_OPAQUE */ /*** TCP State ***/ uint8_t rwrec_GetTcpState(const rwRec *r); void rwrec_SetTcpState(rwRec *r, uint8_t in_v); void rwrec_MemGetTcpState(const rwRec *r, void *out_vp); void rwrec_MemSetTcpState(rwRec *r, const void *in_vp); int rwrec_MemCmpTcpState(const rwRec *r, const void *vp); #define _recGetTcpState(r) \ ((uint8_t)((r)->tcp_state & 0x7F)) #define _recSetTcpState(r, in_v) \ { ((r)->tcp_state) = ((r)->tcp_state & 0x80) | (0x7F & (in_v)); } #define _recMemGetTcpState(r, out_vp) \ { *((uint8_t*)(out_vp)) = _recGetTcpState(r); } #define _recMemSetTcpState(r, in_vp) \ _recSetTcpState((r), *((uint8_t*)(in_vp))) #define _recMemCmpTcpState(r, vp) \ ((int)(_recGetTcpState(r) - (uint8_t)(0x7f & *((uint8_t*)(vp))))) #if RWREC_OPAQUE # define rwRecGetTcpState(r) rwrec_GetTcpState(r) # define rwRecSetTcpState(r, in_v) rwrec_SetTcpState(r, in_v) # define rwRecMemGetTcpState(r, out_vp) rwrec_MemGetTcpState(r, out_vp) # define rwRecMemSetTcpState(r, in_vp) rwrec_MemSetTcpState(r, in_vp) # define rwRecMemCmpTcpState(r, vp) rwrec_MemCmpTcpState(r, vp) #else # define rwRecGetTcpState(r) _recGetTcpState(r) # define rwRecSetTcpState(r, in_v) _recSetTcpState(r, in_v) # define rwRecMemGetTcpState(r, out_vp) _recMemGetTcpState(r, out_vp) # define rwRecMemSetTcpState(r, in_vp) _recMemSetTcpState(r, in_vp) # define rwRecMemCmpTcpState(r, vp) _recMemCmpTcpState(r, vp) #endif /* RWREC_OPAQUE */ /*** Application ***/ uint16_t rwrec_GetApplication(const rwRec *r); void rwrec_SetApplication(rwRec *r, uint16_t in_v); void rwrec_MemGetApplication(const rwRec *r, void *out_vp); void rwrec_MemSetApplication(rwRec *r, const void *in_vp); int rwrec_MemCmpApplication(const rwRec *r, const void *vp); #define _recGetApplication(r) \ ((r)->application) #define _recSetApplication(r, in_v) \ { ((r)->application) = (in_v); } #define _recMemGetApplication(r, out_vp) \ memcpy((out_vp), &((r)->application), RWREC_SIZEOF_APPLICATION) #define _recMemSetApplication(r, in_vp) \ memcpy(&((r)->application), (in_vp), RWREC_SIZEOF_APPLICATION) #define _recMemCmpApplication(r, vp) \ memcmp(&((r)->application), (vp), RWREC_SIZEOF_APPLICATION) #if RWREC_OPAQUE # define rwRecGetApplication(r) rwrec_GetApplication(r) # define rwRecSetApplication(r, in_v) rwrec_SetApplication(r, in_v) # define rwRecMemGetApplication(r, out_vp) rwrec_MemGetApplication(r, out_vp) # define rwRecMemSetApplication(r, in_vp) rwrec_MemSetApplication(r, in_vp) # define rwRecMemCmpApplication(r, vp) rwrec_MemCmpApplication(r, vp) #else # define rwRecGetApplication(r) _recGetApplication(r) # define rwRecSetApplication(r, in_v) _recSetApplication(r, in_v) # define rwRecMemGetApplication(r, out_vp) _recMemGetApplication(r, out_vp) # define rwRecMemSetApplication(r, in_vp) _recMemSetApplication(r, in_vp) # define rwRecMemCmpApplication(r, vp) _recMemCmpApplication(r, vp) #endif /* RWREC_OPAQUE */ /*** Memo ***/ uint16_t rwrec_GetMemo(const rwRec *r); void rwrec_SetMemo(rwRec *r, uint16_t in_v); void rwrec_MemGetMemo(const rwRec *r, void *out_vp); void rwrec_MemSetMemo(rwRec *r, const void *in_vp); int rwrec_MemCmpMemo(const rwRec *r, const void *vp); #define _recGetMemo(r) \ ((r)->memo) #define _recSetMemo(r, in_v) \ { ((r)->memo) = (in_v); } #define _recMemGetMemo(r, out_vp) \ memcpy((out_vp), &((r)->memo), RWREC_SIZEOF_MEMO) #define _recMemSetMemo(r, in_vp) \ memcpy(&((r)->memo), (in_vp), RWREC_SIZEOF_MEMO) #define _recMemCmpMemo(r, vp) \ memcmp(&((r)->memo), (vp), RWREC_SIZEOF_MEMO) #if RWREC_OPAQUE # define rwRecGetMemo(r) rwrec_GetMemo(r) # define rwRecSetMemo(r, in_v) rwrec_SetMemo(r, in_v) # define rwRecMemGetMemo(r, out_vp) rwrec_MemGetMemo(r, out_vp) # define rwRecMemSetMemo(r, in_vp) rwrec_MemSetMemo(r, in_vp) # define rwRecMemCmpMemo(r, vp) rwrec_MemCmpMemo(r, vp) #else # define rwRecGetMemo(r) _recGetMemo(r) # define rwRecSetMemo(r, in_v) _recSetMemo(r, in_v) # define rwRecMemGetMemo(r, out_vp) _recMemGetMemo(r, out_vp) # define rwRecMemSetMemo(r, in_vp) _recMemSetMemo(r, in_vp) # define rwRecMemCmpMemo(r, vp) _recMemCmpMemo(r, vp) #endif /* RWREC_OPAQUE */ /*** ICMP Type and Code is derived from the DPort ***/ /* * In NetFlow, Cisco has traditionally encoded the ICMP type and * code in the DESTPORT field as (type << 8 | code); however, some * routers encode it in the SRCPORT field as (code << 8 | type) * (basically byteswapping the 32-bit "SRCPORT DESTPORT" value). * * Our current packing code will modify these odd SRCPORT encodings * to be in the more traditional DESTPORT encoding when the record * is initially packed, though these macros will work for the * window before our packing code was modified. If the DESTPORT is * non-zero, we assume it contains the ICMP values; otherwise, we * look at the SRCPORT values. Note that these functions/macros do * not check the protocol. */ uint8_t rwrec_GetIcmpType(const rwRec *r); void rwrec_SetIcmpType(rwRec *r, uint8_t in_v); void rwrec_MemGetIcmpType(const rwRec *r, void *out_vp); uint8_t rwrec_GetIcmpCode(const rwRec *r); void rwrec_SetIcmpCode(rwRec *r, uint8_t in_v); void rwrec_MemGetIcmpCode(const rwRec *r, void *out_vp); #define rwrec_GetIcmpTypeAndCode rwrec_GetDPort #define rwrec_SetIcmpTypeAndCode rwrec_SetDPort #define rwrec_MemGetIcmpTypeAndCode rwrec_MemGetDPort #define rwrec_MemSetIcmpTypeAndCode rwrec_MemSetDPort #define rwrec_MemCmpIcmpTypeAndCode rwrec_MemCmpDPort #define _recGetIcmpType(r) \ ((uint8_t)(0xFF & ((r)->dPort >> 8))) #define _recSetIcmpType(r, in_v) \ { (r)->dPort = ((((in_v) & 0xFF) << 8) | ((r)->dPort & 0x00FF)); } #define _recMemGetIcmpType(r, out_vp) \ { *out_vp = _recGetIcmpType(r); } #define _recGetIcmpCode(r) \ ((uint8_t)(0xFF & (r)->dPort)) #define _recSetIcmpCode(r, in_v) \ { (r)->dPort = (((r)->dPort & 0xFF00) | ((in_v) & 0xFF)); } #define _recMemGetIcmpCode(r, out_vp) \ { *out_vp = rwRecGetIcmpCode(r); } #if RWREC_OPAQUE # define rwRecGetIcmpType(r) rwrec_GetIcmpType(r) # define rwRecSetIcmpType(r, in_v) rwrec_SetIcmpType(r, in_v) # define rwRecMemGetIcmpType(r, out_vp) rwrec_MemGetIcmpType(r, out_vp) # define rwRecGetIcmpCode(r) rwrec_GetIcmpCode(r) # define rwRecSetIcmpCode(r, in_v) rwrec_SetIcmpCode(r, in_v) # define rwRecMemGetIcmpCode(r, out_vp) rwrec_MemGetIcmpCode(r, out_vp) # define rwRecGetIcmpTypeAndCode(r) rwrec_GetIcmpTypeAndCode(r) # define rwRecSetIcmpTypeAndCode(r, in_v) rwrec_SetIcmpTypeAndCode(r, in_v) # define rwRecMemGetIcmpTypeAndCode(r, out_vp) \ rwrec_MemGetIcmpTypeAndCode(r, out_vp) # define rwRecMemSetIcmpTypeAndCode(r, in_vp) \ rwrec_MemSetIcmpTypeAndCode(r, in_vp) # define rwRecMemCmpIcmpTypeAndCode(r, vp) \ rwrec_MemCmpIcmpTypeAndCode(r, vp) #else /* RWREC_OPAQUE */ # define rwRecGetIcmpType(r) _recGetIcmpType(r) # define rwRecSetIcmpType(r, in_v) _recSetIcmpType(r, in_v) # define rwRecMemGetIcmpType(r, out_vp) _recMemGetIcmpType(r, out_vp) # define rwRecGetIcmpCode(r) _recGetIcmpCode(r) # define rwRecSetIcmpCode(r, in_v) _recSetIcmpCode(r, in_v) # define rwRecMemGetIcmpCode(r, out_vp) _recMemGetIcmpCode(r, out_vp) # define rwRecGetIcmpTypeAndCode(r) _recGetDPort(r) # define rwRecSetIcmpTypeAndCode(r, in_v) _recSetDPort(r, in_v) # define rwRecMemGetIcmpTypeAndCode(r, out_vp) _recMemGetDPort(r, out_vp) # define rwRecMemSetIcmpTypeAndCode(r, in_vp) _recMemSetDPort(r, in_vp) # define rwRecMemCmpIcmpTypeAndCode(r, vp) _recMemCmpDPort(r, vp) #endif /* RWREC_OPAQUE */ #ifdef __cplusplus } #endif #endif /* _RWREC_H */ /* ** Local Variables: ** mode:c ** indent-tabs-mode:nil ** c-basic-offset:4 ** End: */