Tutorial: Plugin Programming Cheatsheet

This cheatsheet summarises the most important functions, macros and structures required to write your own plugins. For more details about the different aspects of writing your own plugins, refer to the t2PSkel plugin or to one of the tutorials.

Tutorials

Plugin Initialization

Callbacks

Describing Flow File Output

Generating Output

Structures

flow_t

The flow_t structure is defined in tranalyzer2/src/flow.h as follows:

typedef struct flow_s {
    struct flow_s *lruNextFlow, *lruPrevFlow;   // pointers to the next and previous flow in LRU list

    struct timeval lastSeen;                    // last time we've seen this flow
    struct timeval firstSeen;                   // first time we've seen this flow
    struct timeval duration;                    // lastSeen - firstSeen
                                                // (NOT available before flow completely terminated)

    // -------------------------------------------------------------------------
    // Begin flow identification
    // -------------------------------------------------------------------------

#if IPV6_ACTIVATE > 0
    ipAddr_t srcIP, dstIP;
#else // IPV6_ACTIVATE == 0
    ip4Addr_t srcIP, dstIP;
#endif // IPV6_ACTIVATE == 0

#if ETH_ACTIVATE > 0
    ethDS_t ethDS;
#endif

#if (IPV6_ACTIVATE == 2 || ETH_ACTIVATE > 0)
    uint16_t ethType;
#endif

    uint16_t vlanID;

    union {
        struct {
            uint16_t srcPort;
            uint16_t dstPort;
        };
        uint32_t fragID;
    };

#if SCTP_ACTIVATE == 1
    uint16_t sctpStrm;
#endif

    uint8_t layer4Protocol;

    // -------------------------------------------------------------------------
    // End flow identification
    // -------------------------------------------------------------------------

    uint64_t findex; // flow index

#if (SCTP_ACTIVATE == 1 && SCTP_STATFINDEX == 1)
    unsigned long sctpFindex;
#endif

    // for fragPend hash cleanup
#if IPV6_ACTIVATE > 0
    uint32_t lastFragIPID;
#else // IPV6_ACTIVATE == 0
    uint16_t lastFragIPID;
#endif // IPV6_ACTIVATE == 0

    uint32_t lastIPID;                  // for duplicate IP ID detection

#if SUBNET_INIT != 0
    uint32_t subnetNrSrc, subnetNrDst;
#endif // SUBNET_INIT != 0

    uint64_t status;                    // status of flow, e.g., fragmentation processing

    unsigned long flowIndex;
    unsigned long oppositeFlowIndex;

    float timeout;                      // the timeout of this flow in seconds
} __attribute__((packed)) flow_t;

packet_t

The packet_t structure is defined in tranalyzer2/src/packet.h as follows:

// a common packet pointer, holds pointers to each layer's header

typedef struct {
#if T2_PRI_HDRDESC == 1
    char hdrDesc[T2_HDRDESC_LEN];                // header description, e.g., eth:ipv4:tcp
    uint16_t hdrDescPos;                         // header description position
    uint16_t numHdrDesc;                         // number of headers description
#endif // T2_PRI_HDRDESC == 1

    const u_char * const raw_packet;             // Pointer to the beginning of the packet
    const u_char * const end_packet;             // Pointer to the end of the packet

    const struct pcap_pkthdr * const pcapHeader; // Network order

    const l2Header_t *layer2Header;              // Network order
    const uint32_t *vlans;                       // Network order, ptr to vlans
    const etherLLCHeader_t *etherLLC;            // Ethernet header LLC part if present
    const uint32_t *mpls;                        // Network order, MPLS pointer

    const l3Header_t *layer3Header;
    const l4Header_t *layer4Header;

    const greHeader_t *greHdr;                   // Network order pointer to GRE v1,2 header
    const uint16_t *l2TPHdr;                     // Network order uint16 pointer to L2TPv2 header
    const l3Header_t *greLayer3Hdr;              // Network order
    const l3Header_t *l2tpLayer3Hdr;             // Network order

    const pppHu_t  *pppHdr;                      // Network order, pointer to PPP header
    const pppoEH_t *pppoEHdr;                    // Network order, pointer to PPPoE header

    const ip6OptHdr_t   *ip6HHOptHdr;
    const ip6OptHdr_t   *ip6DOptHdr;
    const ip6FragHdr_t  *ip6FragHdr;
    const ip6RouteHdr_t *ip6RouteHdr;

    const uint8_t *trdoOIHdr;
    const uint8_t *trdoAHdr;

    const uint8_t *layer7Header;     // pointer to payload

#if SCTP_ACTIVATE == 1
    const uint8_t *layer7SCTPHeader; // pointer to 1. SCTP payload
    uint16_t snapSCTPL7Length;       // Host order, only higher packet payload (layer 7),
                                     // can be truncated due to limited snaplength
#endif // SCTP_ACTIVATE == 1

    uint16_t l2HdrLen;               // Host order
    uint16_t l3HdrLen;               // Host order
    uint16_t l4HdrLen;               // Host order

    const uint32_t rawLength;        // Host order, extracted from pcapHeader
    const uint32_t snapLength;       // Host order, extracted from pcapHeader

    uint32_t snapL2Length;           // Host order, includes layer2 header, can be truncated due to limited snaplength, will be processed by header dissection
    uint32_t snapL3Length;           // Host order, includes layer3 header, can be truncated due to limited snaplength, derived by header dissection

    uint32_t packetL2Length;         // Host order, derived from IP header length field + length of L2 header
    uint32_t packetLength;           // Host order, derived from IP header length field, defined by PACKETLENGTH in packetCapture.h
                                     // (0: including L2-4 header, including L3-4 header, 2: including L4 header, 3: Only payload L7)
    uint16_t snapL4Length;           // Host order, includes layer4 header, can be truncated due to limited snaplength, derived by header dissection
    uint16_t snapL7Length;           // Host order, only higher packet payload (layer 7), can be truncated due to limited snaplength, derived by header dissection
    uint16_t packetL7Length;         // Layer7 Length

    uint16_t srcPort, dstPort;       // Host order

    uint16_t innerVLANID;

    uint16_t outerL2Type;            // Ethernet, ...
    uint16_t layer2Type;             // Ethernet, ...
    uint16_t layer3Type;             // IPv4, IPv6, ...

    uint64_t status;
#if (FDURLIMIT > 0 && FDLSFINDEX == 1)
    uint64_t findex;
#endif //(FDURLIMIT > 0 && FDLSFINDEX == 1)
#if IPV6_ACTIVATE > 0
    ipAddr_t srcIP;
    ipAddr_t dstIP;
#else // IPV6_ACTIVATE == 0
    ip4Addr_t srcIP;
    ip4Addr_t dstIP;
#endif // IPV6_ACTIVATE == 0

#if ((SUBNET_INIT != 0) || (AGGREGATIONFLAG & (SUBNET | SRCIP | DSTIP)))
#if IPV6_ACTIVATE > 0
    ipAddr_t srcIPC;
    ipAddr_t dstIPC;
#else // IPV6_ACTIVATE == 0
    ip4Addr_t srcIPC;
    ip4Addr_t dstIPC;
#endif // IPV6_ACTIVATE == 0
    uint32_t subnetNrSrc, subnetNrDst;
    uint16_t srcPortC, dstPortC;
    uint8_t layer4TypeC;
#endif // SUBNET_INIT != 0

    uint8_t layer4Type;              // TCP, UDP, ICMP, IGMP, ...
    uint8_t vlanHdrCnt;
    uint8_t mplsHdrCnt;
} packet_t;

Reporting errors, warnings and other information

  • The following macros output to stdout or to the *_log.txt* file if t2 -l option is used:
  • If you do not want to output the [INF], [OK], [WRN] or [ERR] prefix:
  • Alternatively, specify the output stream:
  • If you do not want to output the [INF], [OK], [WRN] or [ERR] prefix:

Reporting numbers

Macros