LCOV - code coverage report
Current view: top level - lib - sflow_receiver.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 259 468 55.3 %
Date: 2016-09-14 01:02:56 Functions: 25 57 43.9 %
Branches: 57 125 45.6 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright (c) 2002-2009 InMon Corp. Licensed under the terms of either the
       2                 :            :  *   Sun Industry Standards Source License 1.1, that is available at:
       3                 :            :  *    http://host-sflow.sourceforge.net/sissl.html
       4                 :            :  * or the InMon sFlow License, that is available at:
       5                 :            :  *    http://www.inmon.com/technology/sflowlicense.txt
       6                 :            :  */
       7                 :            : 
       8                 :            : #ifndef __CHECKER__            /* Don't run sparse on anything in this file. */
       9                 :            : 
      10                 :            : #include <assert.h>
      11                 :            : #include "sflow_api.h"
      12                 :            : 
      13                 :            : static void resetSampleCollector(SFLReceiver *receiver);
      14                 :            : static void sendSample(SFLReceiver *receiver);
      15                 :            : static void sflError(SFLReceiver *receiver, char *errm);
      16                 :            : inline static void putNet32(SFLReceiver *receiver, u_int32_t val);
      17                 :            : inline static void putAddress(SFLReceiver *receiver, SFLAddress *addr);
      18                 :            : #ifdef SFLOW_DO_SOCKET
      19                 :            : static void initSocket(SFLReceiver *receiver);
      20                 :            : #endif
      21                 :            : 
      22                 :            : /*_________________--------------------------__________________
      23                 :            :   _________________    sfl_receiver_init     __________________
      24                 :            :   -----------------__________________________------------------
      25                 :            : */
      26                 :            : 
      27                 :          6 : void sfl_receiver_init(SFLReceiver *receiver, SFLAgent *agent)
      28                 :            : {
      29                 :            :     /* first clear everything */
      30                 :          6 :     memset(receiver, 0, sizeof(*receiver));
      31                 :            : 
      32                 :            :     /* now copy in the parameters */
      33                 :          6 :     receiver->agent = agent;
      34                 :            : 
      35                 :            :     /* set defaults */
      36                 :          6 :     receiver->sFlowRcvrMaximumDatagramSize = SFL_DEFAULT_DATAGRAM_SIZE;
      37                 :          6 :     receiver->sFlowRcvrPort = SFL_DEFAULT_COLLECTOR_PORT;
      38                 :            : 
      39                 :            : #ifdef SFLOW_DO_SOCKET
      40                 :            :     /* initialize the socket address */
      41                 :            :     initSocket(receiver);
      42                 :            : #endif
      43                 :            : 
      44                 :            :     /* preset some of the header fields */
      45                 :          6 :     receiver->sampleCollector.datap = receiver->sampleCollector.data;
      46                 :          6 :     putNet32(receiver, SFLDATAGRAM_VERSION5);
      47                 :          6 :     putAddress(receiver, &agent->myIP);
      48                 :          6 :     putNet32(receiver, agent->subId);
      49                 :            : 
      50                 :            :     /* prepare to receive the first sample */
      51                 :          6 :     resetSampleCollector(receiver);
      52                 :          6 : }
      53                 :            : 
      54                 :            : /*_________________---------------------------__________________
      55                 :            :   _________________      reset                __________________
      56                 :            :   -----------------___________________________------------------
      57                 :            : 
      58                 :            :   called on timeout, or when owner string is cleared
      59                 :            : */
      60                 :            : 
      61                 :          0 : static void reset(SFLReceiver *receiver) {
      62                 :            :     // ask agent to tell samplers and pollers to stop sending samples
      63                 :          0 :     sfl_agent_resetReceiver(receiver->agent, receiver);
      64                 :            :     // reinitialize
      65                 :          0 :     sfl_receiver_init(receiver, receiver->agent);
      66                 :          0 : }
      67                 :            : 
      68                 :            : #ifdef SFLOW_DO_SOCKET
      69                 :            : /*_________________---------------------------__________________
      70                 :            :   _________________      initSocket           __________________
      71                 :            :   -----------------___________________________------------------
      72                 :            : */
      73                 :            : 
      74                 :            : static void initSocket(SFLReceiver *receiver) {
      75                 :            :     if(receiver->sFlowRcvrAddress.type == SFLADDRESSTYPE_IP_V6) {
      76                 :            :     struct sockaddr_in6 *sa6 = &receiver->receiver6;
      77                 :            :     sa6->sin6_port = htons((u_int16_t)receiver->sFlowRcvrPort);
      78                 :            :     sa6->sin6_family = AF_INET6;
      79                 :            :     sa6->sin6_addr = receiver->sFlowRcvrAddress.address.ip_v6;
      80                 :            :     }
      81                 :            :     else {
      82                 :            :     struct sockaddr_in *sa4 = &receiver->receiver4;
      83                 :            :     sa4->sin_port = htons((u_int16_t)receiver->sFlowRcvrPort);
      84                 :            :     sa4->sin_family = AF_INET;
      85                 :            :     sa4->sin_addr = receiver->sFlowRcvrAddress.address.ip_v4;
      86                 :            :     }
      87                 :            : }
      88                 :            : #endif
      89                 :            : 
      90                 :            : /*_________________----------------------------------------_____________
      91                 :            :   _________________          MIB Vars                      _____________
      92                 :            :   -----------------________________________________________-------------
      93                 :            : */
      94                 :            : 
      95                 :          0 : char * sfl_receiver_get_sFlowRcvrOwner(SFLReceiver *receiver) {
      96                 :          0 :     return receiver->sFlowRcvrOwner;
      97                 :            : }
      98                 :          6 : void sfl_receiver_set_sFlowRcvrOwner(SFLReceiver *receiver, char *sFlowRcvrOwner) {
      99                 :          6 :     receiver->sFlowRcvrOwner = sFlowRcvrOwner;
     100 [ +  - ][ -  + ]:          6 :     if(sFlowRcvrOwner == NULL || sFlowRcvrOwner[0] == '\0') {
     101                 :            :     // reset condition! owner string was cleared
     102                 :          0 :     reset(receiver);
     103                 :            :     }
     104                 :          6 : }
     105                 :          0 : time_t sfl_receiver_get_sFlowRcvrTimeout(SFLReceiver *receiver) {
     106                 :          0 :     return receiver->sFlowRcvrTimeout;
     107                 :            : }
     108                 :          6 : void sfl_receiver_set_sFlowRcvrTimeout(SFLReceiver *receiver, time_t sFlowRcvrTimeout) {
     109                 :          6 :     receiver->sFlowRcvrTimeout =sFlowRcvrTimeout;
     110                 :          6 : }
     111                 :          0 : u_int32_t sfl_receiver_get_sFlowRcvrMaximumDatagramSize(SFLReceiver *receiver) {
     112                 :          0 :     return receiver->sFlowRcvrMaximumDatagramSize;
     113                 :            : }
     114                 :          0 : void sfl_receiver_set_sFlowRcvrMaximumDatagramSize(SFLReceiver *receiver, u_int32_t sFlowRcvrMaximumDatagramSize) {
     115                 :          0 :     u_int32_t mdz = sFlowRcvrMaximumDatagramSize;
     116         [ #  # ]:          0 :     if(mdz < SFL_MIN_DATAGRAM_SIZE) mdz = SFL_MIN_DATAGRAM_SIZE;
     117                 :          0 :     receiver->sFlowRcvrMaximumDatagramSize = mdz;
     118                 :          0 : }
     119                 :          0 : SFLAddress *sfl_receiver_get_sFlowRcvrAddress(SFLReceiver *receiver) {
     120                 :          0 :     return &receiver->sFlowRcvrAddress;
     121                 :            : }
     122                 :          0 : void sfl_receiver_set_sFlowRcvrAddress(SFLReceiver *receiver, SFLAddress *sFlowRcvrAddress) {
     123         [ #  # ]:          0 :     if(sFlowRcvrAddress) receiver->sFlowRcvrAddress = *sFlowRcvrAddress; // structure copy
     124                 :            : #ifdef SFLOW_DO_SOCKET
     125                 :            :     initSocket(receiver);
     126                 :            : #endif
     127                 :          0 : }
     128                 :          0 : u_int32_t sfl_receiver_get_sFlowRcvrPort(SFLReceiver *receiver) {
     129                 :          0 :     return receiver->sFlowRcvrPort;
     130                 :            : }
     131                 :          0 : void sfl_receiver_set_sFlowRcvrPort(SFLReceiver *receiver, u_int32_t sFlowRcvrPort) {
     132                 :          0 :     receiver->sFlowRcvrPort = sFlowRcvrPort;
     133                 :            :     // update the socket structure
     134                 :            : #ifdef SFLOW_DO_SOCKET
     135                 :            :     initSocket(receiver);
     136                 :            : #endif
     137                 :          0 : }
     138                 :            : 
     139                 :            : /*_________________---------------------------__________________
     140                 :            :   _________________   sfl_receiver_tick       __________________
     141                 :            :   -----------------___________________________------------------
     142                 :            : */
     143                 :            : 
     144                 :         15 : void sfl_receiver_tick(SFLReceiver *receiver, time_t now)
     145                 :            : {
     146                 :            :     // if there are any samples to send, flush them now
     147         [ +  + ]:         15 :     if(receiver->sampleCollector.numSamples > 0) sendSample(receiver);
     148                 :            :     // check the timeout
     149 [ +  - ][ -  + ]:         15 :     if(receiver->sFlowRcvrTimeout && (u_int32_t)receiver->sFlowRcvrTimeout != 0xFFFFFFFF) {
     150                 :            :     // count down one tick and reset if we reach 0
     151         [ #  # ]:          0 :     if(--receiver->sFlowRcvrTimeout == 0) reset(receiver);
     152                 :            :     }
     153                 :         15 : }
     154                 :            : 
     155                 :            : /*_________________-----------------------------__________________
     156                 :            :   _________________   receiver write utilities  __________________
     157                 :            :   -----------------_____________________________------------------
     158                 :            : */
     159                 :            : 
     160                 :         14 : inline static void put32(SFLReceiver *receiver, u_int32_t val)
     161                 :            : {
     162                 :         14 :     *receiver->sampleCollector.datap++ = val;
     163                 :         14 : }
     164                 :            : 
     165                 :        915 : inline static void putNet32(SFLReceiver *receiver, u_int32_t val)
     166                 :            : {
     167                 :        915 :     *receiver->sampleCollector.datap++ = htonl(val);
     168                 :        915 : }
     169                 :            : 
     170                 :          4 : inline static void putNet32_run(SFLReceiver *receiver, void *obj, size_t quads)
     171                 :            : {
     172                 :          4 :     u_int32_t *from = (u_int32_t *)obj;
     173         [ +  + ]:          7 :     while(quads--) putNet32(receiver, *from++);
     174                 :          4 : }
     175                 :            : 
     176                 :         68 : inline static void putNet64(SFLReceiver *receiver, u_int64_t val64)
     177                 :            : {
     178                 :         68 :     u_int32_t *firstQuadPtr = receiver->sampleCollector.datap;
     179                 :            :     // first copy the bytes in
     180                 :         68 :     memcpy((u_char *)firstQuadPtr, &val64, 8);
     181         [ +  - ]:         68 :     if(htonl(1) != 1) {
     182                 :            :     // swap the bytes, and reverse the quads too
     183                 :         68 :     u_int32_t tmp = *receiver->sampleCollector.datap++;
     184                 :         68 :     *firstQuadPtr = htonl(*receiver->sampleCollector.datap);
     185                 :         68 :     *receiver->sampleCollector.datap++ = htonl(tmp);
     186                 :            :     }
     187                 :          0 :     else receiver->sampleCollector.datap += 2;
     188                 :         68 : }
     189                 :            : 
     190                 :          0 : inline static void put128(SFLReceiver *receiver, u_char *val)
     191                 :            : {
     192                 :          0 :     memcpy(receiver->sampleCollector.datap, val, 16);
     193                 :          0 :     receiver->sampleCollector.datap += 4;
     194                 :          0 : }
     195                 :            : 
     196                 :         14 : inline static void putString(SFLReceiver *receiver, SFLString *s)
     197                 :            : {
     198                 :         14 :     putNet32(receiver, s->len);
     199                 :         14 :     memcpy(receiver->sampleCollector.datap, s->str, s->len);
     200                 :         14 :     receiver->sampleCollector.datap += (s->len + 3) / 4; /* pad to 4-byte boundary */
     201         [ +  - ]:         14 :     if ((s->len % 4) != 0){
     202                 :         14 :         u_int8_t padding = 4 - (s->len % 4);
     203                 :         14 :         memset(((u_int8_t*)receiver->sampleCollector.datap)-padding, 0, padding);
     204                 :            :     }
     205                 :         14 : }
     206                 :            : 
     207                 :         14 : inline static u_int32_t stringEncodingLength(SFLString *s) {
     208                 :            :     // answer in bytes,  so remember to mulitply by 4 after rounding up to nearest 4-byte boundary
     209                 :         14 :     return 4 + (((s->len + 3) / 4) * 4);
     210                 :            : }
     211                 :            : 
     212                 :          8 : inline static void putAddress(SFLReceiver *receiver, SFLAddress *addr)
     213                 :            : {
     214                 :            :     // encode unspecified addresses as IPV4:0.0.0.0 - or should we flag this as an error?
     215         [ +  + ]:          8 :     if(addr->type == 0) {
     216                 :          2 :     putNet32(receiver, SFLADDRESSTYPE_IP_V4);
     217                 :          2 :     put32(receiver, 0);
     218                 :            :     }
     219                 :            :     else {
     220                 :          6 :     putNet32(receiver, addr->type);
     221         [ +  - ]:          6 :     if(addr->type == SFLADDRESSTYPE_IP_V4) put32(receiver, addr->address.ip_v4.addr);
     222                 :          0 :     else put128(receiver, addr->address.ip_v6.addr);
     223                 :            :     }
     224                 :          8 : }
     225                 :            : 
     226                 :          2 : inline static u_int32_t addressEncodingLength(SFLAddress *addr) {
     227         [ -  + ]:          2 :     return (addr->type == SFLADDRESSTYPE_IP_V6) ? 20 : 8;  // type + address (unspecified == IPV4)
     228                 :            : }
     229                 :            : 
     230                 :          4 : inline static void putMACAddress(SFLReceiver *receiver,
     231                 :            :                                  const struct eth_addr mac)
     232                 :            : {
     233                 :          4 :     memcpy(receiver->sampleCollector.datap, &mac, 6);
     234                 :          4 :     receiver->sampleCollector.datap += 2;
     235                 :          4 : }
     236                 :            : 
     237                 :         14 : inline static void putSwitch(SFLReceiver *receiver, SFLExtended_switch *sw)
     238                 :            : {
     239                 :         14 :     putNet32(receiver, sw->src_vlan);
     240                 :         14 :     putNet32(receiver, sw->src_priority);
     241                 :         14 :     putNet32(receiver, sw->dst_vlan);
     242                 :         14 :     putNet32(receiver, sw->dst_priority);
     243                 :         14 : }
     244                 :            : 
     245                 :          0 : inline static void putRouter(SFLReceiver *receiver, SFLExtended_router *router)
     246                 :            : {
     247                 :          0 :     putAddress(receiver, &router->nexthop);
     248                 :          0 :     putNet32(receiver, router->src_mask);
     249                 :          0 :     putNet32(receiver, router->dst_mask);
     250                 :          0 : }
     251                 :            : 
     252                 :          0 : inline static u_int32_t routerEncodingLength(SFLExtended_router *router) {
     253                 :          0 :     return addressEncodingLength(&router->nexthop) + 8;
     254                 :            : }
     255                 :            : 
     256                 :          0 : inline static void putGateway(SFLReceiver *receiver, SFLExtended_gateway *gw)
     257                 :            : {
     258                 :          0 :     putAddress(receiver, &gw->nexthop);
     259                 :          0 :     putNet32(receiver, gw->as);
     260                 :          0 :     putNet32(receiver, gw->src_as);
     261                 :          0 :     putNet32(receiver, gw->src_peer_as);
     262                 :          0 :     putNet32(receiver, gw->dst_as_path_segments);
     263                 :            :     {
     264                 :          0 :     u_int32_t seg = 0;
     265         [ #  # ]:          0 :     for(; seg < gw->dst_as_path_segments; seg++) {
     266                 :          0 :         putNet32(receiver, gw->dst_as_path[seg].type);
     267                 :          0 :         putNet32(receiver, gw->dst_as_path[seg].length);
     268                 :          0 :         putNet32_run(receiver, gw->dst_as_path[seg].as.seq, gw->dst_as_path[seg].length);
     269                 :            :     }
     270                 :            :     }
     271                 :          0 :     putNet32(receiver, gw->communities_length);
     272                 :          0 :     putNet32_run(receiver, gw->communities, gw->communities_length);
     273                 :          0 :     putNet32(receiver, gw->localpref);
     274                 :          0 : }
     275                 :            : 
     276                 :          0 : inline static u_int32_t gatewayEncodingLength(SFLExtended_gateway *gw) {
     277                 :          0 :     u_int32_t elemSiz = addressEncodingLength(&gw->nexthop);
     278                 :          0 :     u_int32_t seg = 0;
     279                 :          0 :     elemSiz += 16; // as, src_as, src_peer_as, dst_as_path_segments
     280         [ #  # ]:          0 :     for(; seg < gw->dst_as_path_segments; seg++) {
     281                 :          0 :     elemSiz += 8; // type, length
     282                 :          0 :     elemSiz += 4 * gw->dst_as_path[seg].length; // set/seq bytes
     283                 :            :     }
     284                 :          0 :     elemSiz += 4; // communities_length
     285                 :          0 :     elemSiz += 4 * gw->communities_length; // communities
     286                 :          0 :     elemSiz += 4; // localpref
     287                 :          0 :     return elemSiz;
     288                 :            : }
     289                 :            : 
     290                 :          0 : inline static void putUser(SFLReceiver *receiver, SFLExtended_user *user)
     291                 :            : {
     292                 :          0 :     putNet32(receiver, user->src_charset);
     293                 :          0 :     putString(receiver, &user->src_user);
     294                 :          0 :     putNet32(receiver, user->dst_charset);
     295                 :          0 :     putString(receiver, &user->dst_user);
     296                 :          0 : }
     297                 :            : 
     298                 :          0 : inline static u_int32_t userEncodingLength(SFLExtended_user *user) {
     299                 :          0 :     return 4
     300                 :          0 :     + stringEncodingLength(&user->src_user)
     301                 :            :     + 4
     302                 :          0 :     + stringEncodingLength(&user->dst_user);
     303                 :            : }
     304                 :            : 
     305                 :          0 : inline static void putUrl(SFLReceiver *receiver, SFLExtended_url *url)
     306                 :            : {
     307                 :          0 :     putNet32(receiver, url->direction);
     308                 :          0 :     putString(receiver, &url->url);
     309                 :          0 :     putString(receiver, &url->host);
     310                 :          0 : }
     311                 :            : 
     312                 :          0 : inline static u_int32_t urlEncodingLength(SFLExtended_url *url) {
     313                 :          0 :     return 4
     314                 :          0 :     + stringEncodingLength(&url->url)
     315                 :          0 :     + stringEncodingLength(&url->host);
     316                 :            : }
     317                 :            : 
     318                 :          4 : inline static void putLabelStack(SFLReceiver *receiver, SFLLabelStack *labelStack)
     319                 :            : {
     320                 :          4 :     putNet32(receiver, labelStack->depth);
     321                 :          4 :     putNet32_run(receiver, labelStack->stack, labelStack->depth);
     322                 :          4 : }
     323                 :            : 
     324                 :          4 : inline static u_int32_t labelStackEncodingLength(SFLLabelStack *labelStack) {
     325                 :          4 :     return 4 + (4 * labelStack->depth);
     326                 :            : }
     327                 :            : 
     328                 :          2 : inline static void putMpls(SFLReceiver *receiver, SFLExtended_mpls *mpls)
     329                 :            : {
     330                 :          2 :     putAddress(receiver, &mpls->nextHop);
     331                 :          2 :     putLabelStack(receiver, &mpls->in_stack);
     332                 :          2 :     putLabelStack(receiver, &mpls->out_stack);
     333                 :          2 : }
     334                 :            : 
     335                 :          2 : inline static u_int32_t mplsEncodingLength(SFLExtended_mpls *mpls) {
     336                 :          4 :     return addressEncodingLength(&mpls->nextHop)
     337                 :          2 :     + labelStackEncodingLength(&mpls->in_stack)
     338                 :          2 :     + labelStackEncodingLength(&mpls->out_stack);
     339                 :            : }
     340                 :            : 
     341                 :          0 : inline static void putNat(SFLReceiver *receiver, SFLExtended_nat *nat)
     342                 :            : {
     343                 :          0 :     putAddress(receiver, &nat->src);
     344                 :          0 :     putAddress(receiver, &nat->dst);
     345                 :          0 : }
     346                 :            : 
     347                 :          0 : inline static u_int32_t natEncodingLength(SFLExtended_nat *nat) {
     348                 :          0 :     return addressEncodingLength(&nat->src)
     349                 :          0 :     + addressEncodingLength(&nat->dst);
     350                 :            : }
     351                 :            : 
     352                 :          0 : inline static void putMplsTunnel(SFLReceiver *receiver, SFLExtended_mpls_tunnel *tunnel)
     353                 :            : {
     354                 :          0 :     putString(receiver, &tunnel->tunnel_lsp_name);
     355                 :          0 :     putNet32(receiver, tunnel->tunnel_id);
     356                 :          0 :     putNet32(receiver, tunnel->tunnel_cos);
     357                 :          0 : }
     358                 :            : 
     359                 :          0 : inline static u_int32_t mplsTunnelEncodingLength(SFLExtended_mpls_tunnel *tunnel) {
     360                 :          0 :     return stringEncodingLength(&tunnel->tunnel_lsp_name) + 8;
     361                 :            : }
     362                 :            : 
     363                 :          0 : inline static void putMplsVc(SFLReceiver *receiver, SFLExtended_mpls_vc *vc)
     364                 :            : {
     365                 :          0 :     putString(receiver, &vc->vc_instance_name);
     366                 :          0 :     putNet32(receiver, vc->vll_vc_id);
     367                 :          0 :     putNet32(receiver, vc->vc_label_cos);
     368                 :          0 : }
     369                 :            : 
     370                 :          0 : inline static u_int32_t mplsVcEncodingLength(SFLExtended_mpls_vc *vc) {
     371                 :          0 :     return stringEncodingLength( &vc->vc_instance_name) + 8;
     372                 :            : }
     373                 :            : 
     374                 :          0 : inline static void putMplsFtn(SFLReceiver *receiver, SFLExtended_mpls_FTN *ftn)
     375                 :            : {
     376                 :          0 :     putString(receiver, &ftn->mplsFTNDescr);
     377                 :          0 :     putNet32(receiver, ftn->mplsFTNMask);
     378                 :          0 : }
     379                 :            : 
     380                 :          0 : inline static u_int32_t mplsFtnEncodingLength(SFLExtended_mpls_FTN *ftn) {
     381                 :          0 :     return stringEncodingLength( &ftn->mplsFTNDescr) + 4;
     382                 :            : }
     383                 :            : 
     384                 :          0 : inline static void putMplsLdpFec(SFLReceiver *receiver, SFLExtended_mpls_LDP_FEC *ldpfec)
     385                 :            : {
     386                 :          0 :     putNet32(receiver, ldpfec->mplsFecAddrPrefixLength);
     387                 :          0 : }
     388                 :            : 
     389                 :          0 : inline static u_int32_t mplsLdpFecEncodingLength(SFLExtended_mpls_LDP_FEC *ldpfec) {
     390                 :          0 :     return 4;
     391                 :            : }
     392                 :            : 
     393                 :          0 : inline static void putVlanTunnel(SFLReceiver *receiver, SFLExtended_vlan_tunnel *vlanTunnel)
     394                 :            : {
     395                 :          0 :     putLabelStack(receiver, &vlanTunnel->stack);
     396                 :          0 : }
     397                 :            : 
     398                 :          0 : inline static u_int32_t vlanTunnelEncodingLength(SFLExtended_vlan_tunnel *vlanTunnel) {
     399                 :          0 :     return labelStackEncodingLength(&vlanTunnel->stack);
     400                 :            : }
     401                 :            : 
     402                 :            : 
     403                 :         14 : inline static void putGenericCounters(SFLReceiver *receiver, SFLIf_counters *counters)
     404                 :            : {
     405                 :         14 :     putNet32(receiver, counters->ifIndex);
     406                 :         14 :     putNet32(receiver, counters->ifType);
     407                 :         14 :     putNet64(receiver, counters->ifSpeed);
     408                 :         14 :     putNet32(receiver, counters->ifDirection);
     409                 :         14 :     putNet32(receiver, counters->ifStatus);
     410                 :         14 :     putNet64(receiver, counters->ifInOctets);
     411                 :         14 :     putNet32(receiver, counters->ifInUcastPkts);
     412                 :         14 :     putNet32(receiver, counters->ifInMulticastPkts);
     413                 :         14 :     putNet32(receiver, counters->ifInBroadcastPkts);
     414                 :         14 :     putNet32(receiver, counters->ifInDiscards);
     415                 :         14 :     putNet32(receiver, counters->ifInErrors);
     416                 :         14 :     putNet32(receiver, counters->ifInUnknownProtos);
     417                 :         14 :     putNet64(receiver, counters->ifOutOctets);
     418                 :         14 :     putNet32(receiver, counters->ifOutUcastPkts);
     419                 :         14 :     putNet32(receiver, counters->ifOutMulticastPkts);
     420                 :         14 :     putNet32(receiver, counters->ifOutBroadcastPkts);
     421                 :         14 :     putNet32(receiver, counters->ifOutDiscards);
     422                 :         14 :     putNet32(receiver, counters->ifOutErrors);
     423                 :         14 :     putNet32(receiver, counters->ifPromiscuousMode);
     424                 :         14 : }
     425                 :            : 
     426                 :            : 
     427                 :            : /*_________________-----------------------------__________________
     428                 :            :   _________________      computeFlowSampleSize  __________________
     429                 :            :   -----------------_____________________________------------------
     430                 :            : */
     431                 :            : 
     432                 :         14 : static int computeFlowSampleSize(SFLReceiver *receiver, SFL_FLOW_SAMPLE_TYPE *fs)
     433                 :            : {
     434                 :         14 :     SFLFlow_sample_element *elem = fs->elements;
     435                 :            : #ifdef SFL_USE_32BIT_INDEX
     436                 :            :     u_int siz = 52; /* tag, length, sequence_number, ds_class, ds_index, sampling_rate,
     437                 :            :                sample_pool, drops, inputFormat, input, outputFormat, output, number of elements */
     438                 :            : #else
     439                 :         14 :     u_int siz = 40; /* tag, length, sequence_number, source_id, sampling_rate,
     440                 :            :                sample_pool, drops, input, output, number of elements */
     441                 :            : #endif
     442                 :            : 
     443                 :         14 :     fs->num_elements = 0; /* we're going to count them again even if this was set by the client */
     444         [ +  + ]:         48 :     for(; elem != NULL; elem = elem->nxt) {
     445                 :         34 :     u_int elemSiz = 0;
     446                 :         34 :     fs->num_elements++;
     447                 :         34 :     siz += 8; /* tag, length */
     448   [ +  -  -  -  :         34 :     switch(elem->tag) {
          +  -  -  -  -  
          +  -  -  -  -  
             -  -  +  +  
                      - ]
     449                 :            :     case SFLFLOW_HEADER:
     450                 :         14 :         elemSiz = 16; /* header_protocol, frame_length, stripped, header_length */
     451                 :         14 :         elemSiz += ((elem->flowType.header.header_length + 3) / 4) * 4; /* header, rounded up to nearest 4 bytes */
     452                 :         14 :         break;
     453                 :          0 :     case SFLFLOW_ETHERNET: elemSiz = sizeof(SFLSampled_ethernet); break;
     454                 :          0 :     case SFLFLOW_IPV4: elemSiz = sizeof(SFLSampled_ipv4); break;
     455                 :          0 :     case SFLFLOW_IPV6: elemSiz = sizeof(SFLSampled_ipv6); break;
     456                 :         14 :     case SFLFLOW_EX_SWITCH: elemSiz = sizeof(SFLExtended_switch); break;
     457                 :          0 :     case SFLFLOW_EX_ROUTER: elemSiz = routerEncodingLength(&elem->flowType.router); break;
     458                 :          0 :     case SFLFLOW_EX_GATEWAY: elemSiz = gatewayEncodingLength(&elem->flowType.gateway); break;
     459                 :          0 :     case SFLFLOW_EX_USER: elemSiz = userEncodingLength(&elem->flowType.user); break;
     460                 :          0 :     case SFLFLOW_EX_URL: elemSiz = urlEncodingLength(&elem->flowType.url); break;
     461                 :          2 :     case SFLFLOW_EX_MPLS: elemSiz = mplsEncodingLength(&elem->flowType.mpls); break;
     462                 :          0 :     case SFLFLOW_EX_NAT: elemSiz = natEncodingLength(&elem->flowType.nat); break;
     463                 :          0 :     case SFLFLOW_EX_MPLS_TUNNEL: elemSiz = mplsTunnelEncodingLength(&elem->flowType.mpls_tunnel); break;
     464                 :          0 :     case SFLFLOW_EX_MPLS_VC: elemSiz = mplsVcEncodingLength(&elem->flowType.mpls_vc); break;
     465                 :          0 :     case SFLFLOW_EX_MPLS_FTN: elemSiz = mplsFtnEncodingLength(&elem->flowType.mpls_ftn); break;
     466                 :          0 :     case SFLFLOW_EX_MPLS_LDP_FEC: elemSiz = mplsLdpFecEncodingLength(&elem->flowType.mpls_ldp_fec); break;
     467                 :          0 :     case SFLFLOW_EX_VLAN_TUNNEL: elemSiz = vlanTunnelEncodingLength(&elem->flowType.vlan_tunnel); break;
     468                 :            :     case SFLFLOW_EX_IPV4_TUNNEL_EGRESS:
     469                 :            :     case SFLFLOW_EX_IPV4_TUNNEL_INGRESS:
     470                 :          2 :         elemSiz = sizeof(SFLSampled_ipv4);
     471                 :          2 :         break;
     472                 :            :     case SFLFLOW_EX_VNI_EGRESS:
     473                 :            :     case SFLFLOW_EX_VNI_INGRESS:
     474                 :          2 :         elemSiz = sizeof(SFLExtended_vni);
     475                 :          2 :         break;
     476                 :            :     default:
     477                 :          0 :         sflError(receiver, "unexpected packet_data_tag");
     478                 :          0 :         return -1;
     479                 :            :         break;
     480                 :            :     }
     481                 :            :     // cache the element size, and accumulate it into the overall FlowSample size
     482                 :         34 :     elem->length = elemSiz;
     483                 :         34 :     siz += elemSiz;
     484                 :            :     }
     485                 :            : 
     486                 :         14 :     return siz;
     487                 :            : }
     488                 :            : 
     489                 :            : /*_________________-------------------------------__________________
     490                 :            :   _________________ sfl_receiver_writeFlowSample  __________________
     491                 :            :   -----------------_______________________________------------------
     492                 :            : */
     493                 :            : 
     494                 :         14 : int sfl_receiver_writeFlowSample(SFLReceiver *receiver, SFL_FLOW_SAMPLE_TYPE *fs)
     495                 :            : {
     496                 :            :     int packedSize;
     497         [ -  + ]:         14 :     if(fs == NULL) return -1;
     498         [ -  + ]:         14 :     if((packedSize = computeFlowSampleSize(receiver, fs)) == -1) return -1;
     499                 :            : 
     500                 :            :     // check in case this one sample alone is too big for the datagram
     501                 :            :     // in fact - if it is even half as big then we should ditch it. Very
     502                 :            :     // important to avoid overruning the packet buffer.
     503         [ -  + ]:         14 :     if(packedSize > (int)(receiver->sFlowRcvrMaximumDatagramSize / 2)) {
     504                 :          0 :     sflError(receiver, "flow sample too big for datagram");
     505                 :          0 :     return -1;
     506                 :            :     }
     507                 :            : 
     508                 :            :     // if the sample pkt is full enough so that this sample might put
     509                 :            :     // it over the limit, then we should send it now before going on.
     510         [ -  + ]:         14 :     if((receiver->sampleCollector.pktlen + packedSize) >= receiver->sFlowRcvrMaximumDatagramSize)
     511                 :          0 :     sendSample(receiver);
     512                 :            : 
     513                 :         14 :     receiver->sampleCollector.numSamples++;
     514                 :            : 
     515                 :            : #ifdef SFL_USE_32BIT_INDEX
     516                 :            :     putNet32(receiver, SFLFLOW_SAMPLE_EXPANDED);
     517                 :            : #else
     518                 :         14 :     putNet32(receiver, SFLFLOW_SAMPLE);
     519                 :            : #endif
     520                 :            : 
     521                 :         14 :     putNet32(receiver, packedSize - 8); // don't include tag and len
     522                 :         14 :     putNet32(receiver, fs->sequence_number);
     523                 :            : 
     524                 :            : #ifdef SFL_USE_32BIT_INDEX
     525                 :            :     putNet32(receiver, fs->ds_class);
     526                 :            :     putNet32(receiver, fs->ds_index);
     527                 :            : #else
     528                 :         14 :     putNet32(receiver, fs->source_id);
     529                 :            : #endif
     530                 :            : 
     531                 :         14 :     putNet32(receiver, fs->sampling_rate);
     532                 :         14 :     putNet32(receiver, fs->sample_pool);
     533                 :         14 :     putNet32(receiver, fs->drops);
     534                 :            : 
     535                 :            : #ifdef SFL_USE_32BIT_INDEX
     536                 :            :     putNet32(receiver, fs->inputFormat);
     537                 :            :     putNet32(receiver, fs->input);
     538                 :            :     putNet32(receiver, fs->outputFormat);
     539                 :            :     putNet32(receiver, fs->output);
     540                 :            : #else
     541                 :         14 :     putNet32(receiver, fs->input);
     542                 :         14 :     putNet32(receiver, fs->output);
     543                 :            : #endif
     544                 :            : 
     545                 :         14 :     putNet32(receiver, fs->num_elements);
     546                 :            : 
     547                 :            :     {
     548                 :         14 :     SFLFlow_sample_element *elem = fs->elements;
     549         [ +  + ]:         48 :     for(; elem != NULL; elem = elem->nxt) {
     550                 :            : 
     551                 :         34 :         putNet32(receiver, elem->tag);
     552                 :         34 :         putNet32(receiver, elem->length); // length cached in computeFlowSampleSize()
     553                 :            : 
     554   [ +  -  +  -  :         34 :         switch(elem->tag) {
          +  -  -  -  -  
          +  -  -  -  -  
             -  -  +  - ]
     555                 :            :         case SFLFLOW_HEADER:
     556                 :         14 :         putNet32(receiver, elem->flowType.header.header_protocol);
     557                 :         14 :         putNet32(receiver, elem->flowType.header.frame_length);
     558                 :         14 :         putNet32(receiver, elem->flowType.header.stripped);
     559                 :         14 :         putNet32(receiver, elem->flowType.header.header_length);
     560                 :            :         /* the header */
     561                 :         14 :         memcpy(receiver->sampleCollector.datap, elem->flowType.header.header_bytes, elem->flowType.header.header_length);
     562                 :            :         /* round up to multiple of 4 to preserve alignment */
     563                 :         14 :         receiver->sampleCollector.datap += ((elem->flowType.header.header_length + 3) / 4);
     564                 :         14 :         break;
     565                 :            :         case SFLFLOW_ETHERNET:
     566                 :          0 :         putNet32(receiver, elem->flowType.ethernet.eth_len);
     567                 :          0 :         putMACAddress(receiver, elem->flowType.ethernet.src_mac);
     568                 :          0 :         putMACAddress(receiver, elem->flowType.ethernet.dst_mac);
     569                 :          0 :         putNet32(receiver, elem->flowType.ethernet.eth_type);
     570                 :          0 :         break;
     571                 :            :         case SFLFLOW_IPV4:
     572                 :            :         case SFLFLOW_EX_IPV4_TUNNEL_EGRESS:
     573                 :            :         case SFLFLOW_EX_IPV4_TUNNEL_INGRESS:
     574                 :          2 :         putNet32(receiver, elem->flowType.ipv4.length);
     575                 :          2 :         putNet32(receiver, elem->flowType.ipv4.protocol);
     576                 :          2 :         put32(receiver, elem->flowType.ipv4.src_ip.addr);
     577                 :          2 :         put32(receiver, elem->flowType.ipv4.dst_ip.addr);
     578                 :          2 :         putNet32(receiver, elem->flowType.ipv4.src_port);
     579                 :          2 :         putNet32(receiver, elem->flowType.ipv4.dst_port);
     580                 :          2 :         putNet32(receiver, elem->flowType.ipv4.tcp_flags);
     581                 :          2 :         putNet32(receiver, elem->flowType.ipv4.tos);
     582                 :          2 :         break;
     583                 :            :         case SFLFLOW_IPV6:
     584                 :          0 :         putNet32(receiver, elem->flowType.ipv6.length);
     585                 :          0 :         putNet32(receiver, elem->flowType.ipv6.protocol);
     586                 :          0 :         put128(receiver, elem->flowType.ipv6.src_ip.addr);
     587                 :          0 :         put128(receiver, elem->flowType.ipv6.dst_ip.addr);
     588                 :          0 :         putNet32(receiver, elem->flowType.ipv6.src_port);
     589                 :          0 :         putNet32(receiver, elem->flowType.ipv6.dst_port);
     590                 :          0 :         putNet32(receiver, elem->flowType.ipv6.tcp_flags);
     591                 :          0 :         putNet32(receiver, elem->flowType.ipv6.priority);
     592                 :          0 :         break;
     593                 :         14 :         case SFLFLOW_EX_SWITCH: putSwitch(receiver, &elem->flowType.sw); break;
     594                 :          0 :         case SFLFLOW_EX_ROUTER: putRouter(receiver, &elem->flowType.router); break;
     595                 :          0 :         case SFLFLOW_EX_GATEWAY: putGateway(receiver, &elem->flowType.gateway); break;
     596                 :          0 :         case SFLFLOW_EX_USER: putUser(receiver, &elem->flowType.user); break;
     597                 :          0 :         case SFLFLOW_EX_URL: putUrl(receiver, &elem->flowType.url); break;
     598                 :          2 :         case SFLFLOW_EX_MPLS: putMpls(receiver, &elem->flowType.mpls); break;
     599                 :          0 :         case SFLFLOW_EX_NAT: putNat(receiver, &elem->flowType.nat); break;
     600                 :          0 :         case SFLFLOW_EX_MPLS_TUNNEL: putMplsTunnel(receiver, &elem->flowType.mpls_tunnel); break;
     601                 :          0 :         case SFLFLOW_EX_MPLS_VC: putMplsVc(receiver, &elem->flowType.mpls_vc); break;
     602                 :          0 :         case SFLFLOW_EX_MPLS_FTN: putMplsFtn(receiver, &elem->flowType.mpls_ftn); break;
     603                 :          0 :         case SFLFLOW_EX_MPLS_LDP_FEC: putMplsLdpFec(receiver, &elem->flowType.mpls_ldp_fec); break;
     604                 :          0 :         case SFLFLOW_EX_VLAN_TUNNEL: putVlanTunnel(receiver, &elem->flowType.vlan_tunnel); break;
     605                 :            :         case SFLFLOW_EX_VNI_EGRESS:
     606                 :            :         case SFLFLOW_EX_VNI_INGRESS:
     607                 :          2 :         putNet32(receiver, elem->flowType.tunnel_vni.vni);
     608                 :          2 :         break;
     609                 :            : 
     610                 :            :         default:
     611                 :          0 :         sflError(receiver, "unexpected packet_data_tag");
     612                 :          0 :         return -1;
     613                 :            :         break;
     614                 :            :         }
     615                 :            :     }
     616                 :            :     }
     617                 :            : 
     618                 :            :     // sanity check
     619         [ -  + ]:         14 :     assert(((u_char *)receiver->sampleCollector.datap
     620                 :            :         - (u_char *)receiver->sampleCollector.data
     621                 :            :         - receiver->sampleCollector.pktlen)  == (u_int32_t)packedSize);
     622                 :            : 
     623                 :            :     // update the pktlen
     624                 :         14 :     receiver->sampleCollector.pktlen = (u_char *)receiver->sampleCollector.datap - (u_char *)receiver->sampleCollector.data;
     625                 :         14 :     return packedSize;
     626                 :            : }
     627                 :            : 
     628                 :            : /*_________________-----------------------------__________________
     629                 :            :   _________________ computeCountersSampleSize   __________________
     630                 :            :   -----------------_____________________________------------------
     631                 :            : */
     632                 :            : 
     633                 :         20 : static int computeCountersSampleSize(SFLReceiver *receiver, SFL_COUNTERS_SAMPLE_TYPE *cs)
     634                 :            : {
     635                 :         20 :     SFLCounters_sample_element *elem = cs->elements;
     636                 :            : #ifdef SFL_USE_32BIT_INDEX
     637                 :            :     u_int siz = 24; /* tag, length, sequence_number, ds_class, ds_index, number of elements */
     638                 :            : #else
     639                 :         20 :     u_int siz = 20; /* tag, length, sequence_number, source_id, number of elements */
     640                 :            : #endif
     641                 :            : 
     642                 :         20 :     cs->num_elements = 0; /* we're going to count them again even if this was set by the client */
     643         [ +  + ]:         76 :     for(; elem != NULL; elem = elem->nxt) {
     644                 :         56 :     u_int elemSiz = 0;
     645                 :         56 :     cs->num_elements++;
     646                 :         56 :     siz += 8; /* tag, length */
     647   [ +  -  -  -  :         56 :     switch(elem->tag) {
          -  +  +  +  +  
                   +  - ]
     648                 :         14 :     case SFLCOUNTERS_GENERIC:  elemSiz = SFL_CTR_GENERIC_XDR_SIZE; break;
     649                 :          0 :     case SFLCOUNTERS_ETHERNET: elemSiz = SFL_CTR_ETHERNET_XDR_SIZE; break;
     650                 :          0 :     case SFLCOUNTERS_TOKENRING: elemSiz = sizeof(elem->counterBlock.tokenring); break;
     651                 :          0 :     case SFLCOUNTERS_VG: elemSiz = sizeof(elem->counterBlock.vg); break;
     652                 :          0 :     case SFLCOUNTERS_VLAN: elemSiz = sizeof(elem->counterBlock.vlan); break;
     653                 :          2 :     case SFLCOUNTERS_LACP: elemSiz = SFL_CTR_LACP_XDR_SIZE; break;
     654                 :         14 :     case SFLCOUNTERS_OPENFLOWPORT: elemSiz = SFL_CTR_OPENFLOWPORT_XDR_SIZE; break;
     655                 :         14 :     case SFLCOUNTERS_PORTNAME: elemSiz = stringEncodingLength(&elem->counterBlock.portName.portName); break;
     656                 :          6 :     case SFLCOUNTERS_APP_RESOURCES: elemSiz = SFL_CTR_APP_RESOURCES_XDR_SIZE; break;
     657                 :          6 :     case SFLCOUNTERS_OVSDP: elemSiz = SFL_CTR_OVSDP_XDR_SIZE; break;
     658                 :            :     default:
     659                 :          0 :         sflError(receiver, "unexpected counters_tag");
     660                 :          0 :         return -1;
     661                 :            :         break;
     662                 :            :     }
     663                 :            :     // cache the element size, and accumulate it into the overall FlowSample size
     664                 :         56 :     elem->length = elemSiz;
     665                 :         56 :     siz += elemSiz;
     666                 :            :     }
     667                 :         20 :     return siz;
     668                 :            : }
     669                 :            : 
     670                 :            : /*_________________----------------------------------__________________
     671                 :            :   _________________ sfl_receiver_writeCountersSample __________________
     672                 :            :   -----------------__________________________________------------------
     673                 :            : */
     674                 :            : 
     675                 :         20 : int sfl_receiver_writeCountersSample(SFLReceiver *receiver, SFL_COUNTERS_SAMPLE_TYPE *cs)
     676                 :            : {
     677                 :            :     int packedSize;
     678         [ -  + ]:         20 :     if(cs == NULL) return -1;
     679                 :            :     // if the sample pkt is full enough so that this sample might put
     680                 :            :     // it over the limit, then we should send it now.
     681         [ -  + ]:         20 :     if((packedSize = computeCountersSampleSize(receiver, cs)) == -1) return -1;
     682                 :            : 
     683                 :            :     // check in case this one sample alone is too big for the datagram
     684                 :            :     // in fact - if it is even half as big then we should ditch it. Very
     685                 :            :     // important to avoid overruning the packet buffer.
     686         [ -  + ]:         20 :     if(packedSize > (int)(receiver->sFlowRcvrMaximumDatagramSize / 2)) {
     687                 :          0 :     sflError(receiver, "counters sample too big for datagram");
     688                 :          0 :     return -1;
     689                 :            :     }
     690                 :            : 
     691         [ -  + ]:         20 :     if((receiver->sampleCollector.pktlen + packedSize) >= receiver->sFlowRcvrMaximumDatagramSize)
     692                 :          0 :     sendSample(receiver);
     693                 :            : 
     694                 :         20 :     receiver->sampleCollector.numSamples++;
     695                 :            : 
     696                 :            : #ifdef SFL_USE_32BIT_INDEX
     697                 :            :     putNet32(receiver, SFLCOUNTERS_SAMPLE_EXPANDED);
     698                 :            : #else
     699                 :         20 :     putNet32(receiver, SFLCOUNTERS_SAMPLE);
     700                 :            : #endif
     701                 :            : 
     702                 :         20 :     putNet32(receiver, packedSize - 8); // tag and length not included
     703                 :         20 :     putNet32(receiver, cs->sequence_number);
     704                 :            : 
     705                 :            : #ifdef SFL_USE_32BIT_INDEX
     706                 :            :     putNet32(receiver, cs->ds_class);
     707                 :            :     putNet32(receiver, cs->ds_index);
     708                 :            : #else
     709                 :         20 :     putNet32(receiver, cs->source_id);
     710                 :            : #endif
     711                 :            : 
     712                 :         20 :     putNet32(receiver, cs->num_elements);
     713                 :            : 
     714                 :            :     {
     715                 :         20 :     SFLCounters_sample_element *elem = cs->elements;
     716         [ +  + ]:         76 :     for(; elem != NULL; elem = elem->nxt) {
     717                 :            : 
     718                 :         56 :         putNet32(receiver, elem->tag);
     719                 :         56 :         putNet32(receiver, elem->length); // length cached in computeCountersSampleSize()
     720                 :            : 
     721   [ +  -  -  -  :         56 :         switch(elem->tag) {
          -  +  +  +  +  
                   +  - ]
     722                 :            :         case SFLCOUNTERS_GENERIC:
     723                 :         14 :         putGenericCounters(receiver, &(elem->counterBlock.generic));
     724                 :         14 :         break;
     725                 :            :         case SFLCOUNTERS_ETHERNET:
     726                 :            :         // all these counters are 32-bit
     727                 :          0 :         putNet32_run(receiver, &elem->counterBlock.ethernet, sizeof(elem->counterBlock.ethernet) / 4);
     728                 :          0 :         break;
     729                 :            :         case SFLCOUNTERS_TOKENRING:
     730                 :            :         // all these counters are 32-bit
     731                 :          0 :         putNet32_run(receiver, &elem->counterBlock.tokenring, sizeof(elem->counterBlock.tokenring) / 4);
     732                 :          0 :         break;
     733                 :            :         case SFLCOUNTERS_VG:
     734                 :            :         // mixed sizes
     735                 :          0 :         putNet32(receiver, elem->counterBlock.vg.dot12InHighPriorityFrames);
     736                 :          0 :         putNet64(receiver, elem->counterBlock.vg.dot12InHighPriorityOctets);
     737                 :          0 :         putNet32(receiver, elem->counterBlock.vg.dot12InNormPriorityFrames);
     738                 :          0 :         putNet64(receiver, elem->counterBlock.vg.dot12InNormPriorityOctets);
     739                 :          0 :         putNet32(receiver, elem->counterBlock.vg.dot12InIPMErrors);
     740                 :          0 :         putNet32(receiver, elem->counterBlock.vg.dot12InOversizeFrameErrors);
     741                 :          0 :         putNet32(receiver, elem->counterBlock.vg.dot12InDataErrors);
     742                 :          0 :         putNet32(receiver, elem->counterBlock.vg.dot12InNullAddressedFrames);
     743                 :          0 :         putNet32(receiver, elem->counterBlock.vg.dot12OutHighPriorityFrames);
     744                 :          0 :         putNet64(receiver, elem->counterBlock.vg.dot12OutHighPriorityOctets);
     745                 :          0 :         putNet32(receiver, elem->counterBlock.vg.dot12TransitionIntoTrainings);
     746                 :          0 :         putNet64(receiver, elem->counterBlock.vg.dot12HCInHighPriorityOctets);
     747                 :          0 :         putNet64(receiver, elem->counterBlock.vg.dot12HCInNormPriorityOctets);
     748                 :          0 :         putNet64(receiver, elem->counterBlock.vg.dot12HCOutHighPriorityOctets);
     749                 :          0 :         break;
     750                 :            :         case SFLCOUNTERS_VLAN:
     751                 :            :         // mixed sizes
     752                 :          0 :         putNet32(receiver, elem->counterBlock.vlan.vlan_id);
     753                 :          0 :         putNet64(receiver, elem->counterBlock.vlan.octets);
     754                 :          0 :         putNet32(receiver, elem->counterBlock.vlan.ucastPkts);
     755                 :          0 :         putNet32(receiver, elem->counterBlock.vlan.multicastPkts);
     756                 :          0 :         putNet32(receiver, elem->counterBlock.vlan.broadcastPkts);
     757                 :          0 :         putNet32(receiver, elem->counterBlock.vlan.discards);
     758                 :          0 :         break;
     759                 :            :         case SFLCOUNTERS_LACP:
     760                 :          2 :         putMACAddress(receiver, elem->counterBlock.lacp.actorSystemID);
     761                 :          2 :         putMACAddress(receiver, elem->counterBlock.lacp.partnerSystemID);
     762                 :          2 :         putNet32(receiver, elem->counterBlock.lacp.attachedAggID);
     763                 :          2 :         put32(receiver, elem->counterBlock.lacp.portState.all);
     764                 :          2 :         putNet32(receiver, elem->counterBlock.lacp.LACPDUsRx);
     765                 :          2 :         putNet32(receiver, elem->counterBlock.lacp.markerPDUsRx);
     766                 :          2 :         putNet32(receiver, elem->counterBlock.lacp.markerResponsePDUsRx);
     767                 :          2 :         putNet32(receiver, elem->counterBlock.lacp.unknownRx);
     768                 :          2 :         putNet32(receiver, elem->counterBlock.lacp.illegalRx);
     769                 :          2 :         putNet32(receiver, elem->counterBlock.lacp.LACPDUsTx);
     770                 :          2 :         putNet32(receiver, elem->counterBlock.lacp.markerPDUsTx);
     771                 :          2 :         putNet32(receiver, elem->counterBlock.lacp.markerResponsePDUsTx);
     772                 :          2 :         break;
     773                 :            :         case SFLCOUNTERS_OPENFLOWPORT:
     774                 :         14 :         putNet64(receiver, elem->counterBlock.ofPort.datapath_id);
     775                 :         14 :         putNet32(receiver, elem->counterBlock.ofPort.port_no);
     776                 :         14 :         break;
     777                 :            :         case SFLCOUNTERS_PORTNAME:
     778                 :         14 :         putString(receiver, &elem->counterBlock.portName.portName);
     779                 :         14 :         break;
     780                 :            :         case SFLCOUNTERS_APP_RESOURCES:
     781                 :          6 :         putNet32(receiver, elem->counterBlock.appResources.user_time);
     782                 :          6 :         putNet32(receiver, elem->counterBlock.appResources.system_time);
     783                 :          6 :         putNet64(receiver, elem->counterBlock.appResources.mem_used);
     784                 :          6 :         putNet64(receiver, elem->counterBlock.appResources.mem_max);
     785                 :          6 :         putNet32(receiver, elem->counterBlock.appResources.fd_open);
     786                 :          6 :         putNet32(receiver, elem->counterBlock.appResources.fd_max);
     787                 :          6 :         putNet32(receiver, elem->counterBlock.appResources.conn_open);
     788                 :          6 :         putNet32(receiver, elem->counterBlock.appResources.conn_max);
     789                 :          6 :         break;
     790                 :            :         case SFLCOUNTERS_OVSDP:
     791                 :          6 :         putNet32(receiver, elem->counterBlock.ovsdp.n_hit);
     792                 :          6 :         putNet32(receiver, elem->counterBlock.ovsdp.n_missed);
     793                 :          6 :         putNet32(receiver, elem->counterBlock.ovsdp.n_lost);
     794                 :          6 :         putNet32(receiver, elem->counterBlock.ovsdp.n_mask_hit);
     795                 :          6 :         putNet32(receiver, elem->counterBlock.ovsdp.n_flows);
     796                 :          6 :         putNet32(receiver, elem->counterBlock.ovsdp.n_masks);
     797                 :          6 :         break;
     798                 :            :         default:
     799                 :          0 :         sflError(receiver, "unexpected counters_tag");
     800                 :          0 :         return -1;
     801                 :            :         break;
     802                 :            :         }
     803                 :            :     }
     804                 :            :     }
     805                 :            :     // sanity check
     806         [ -  + ]:         20 :     assert(((u_char *)receiver->sampleCollector.datap
     807                 :            :         - (u_char *)receiver->sampleCollector.data
     808                 :            :         - receiver->sampleCollector.pktlen)  == (u_int32_t)packedSize);
     809                 :            : 
     810                 :            :     // update the pktlen
     811                 :         20 :     receiver->sampleCollector.pktlen = (u_char *)receiver->sampleCollector.datap - (u_char *)receiver->sampleCollector.data;
     812                 :         20 :     return packedSize;
     813                 :            : }
     814                 :            : 
     815                 :            : /*_________________---------------------------------__________________
     816                 :            :   _________________ sfl_receiver_samplePacketsSent  __________________
     817                 :            :   -----------------_________________________________------------------
     818                 :            : */
     819                 :            : 
     820                 :          0 : u_int32_t sfl_receiver_samplePacketsSent(SFLReceiver *receiver)
     821                 :            : {
     822                 :          0 :     return receiver->sampleCollector.packetSeqNo;
     823                 :            : }
     824                 :            : 
     825                 :            : /*_________________---------------------------__________________
     826                 :            :   _________________     sendSample            __________________
     827                 :            :   -----------------___________________________------------------
     828                 :            : */
     829                 :            : 
     830                 :          9 : static void sendSample(SFLReceiver *receiver)
     831                 :            : {
     832                 :            :     /* construct and send out the sample, then reset for the next one... */
     833                 :            :     /* first fill in the header with the latest values */
     834                 :            :     /* version, agent_address and sub_agent_id were pre-set. */
     835         [ -  + ]:          9 :     u_int32_t hdrIdx = (receiver->agent->myIP.type == SFLADDRESSTYPE_IP_V6) ? 7 : 4;
     836                 :          9 :     receiver->sampleCollector.data[hdrIdx++] = htonl(++receiver->sampleCollector.packetSeqNo); /* seq no */
     837                 :          9 :     receiver->sampleCollector.data[hdrIdx++] = htonl((receiver->agent->now - receiver->agent->bootTime) * 1000); /* uptime */
     838                 :          9 :     receiver->sampleCollector.data[hdrIdx++] = htonl(receiver->sampleCollector.numSamples); /* num samples */
     839                 :            :     /* send */
     840         [ +  - ]:          9 :     if(receiver->agent->sendFn) (*receiver->agent->sendFn)(receiver->agent->magic,
     841                 :            :                                receiver->agent,
     842                 :            :                                receiver,
     843                 :          9 :                                (u_char *)receiver->sampleCollector.data,
     844                 :            :                                receiver->sampleCollector.pktlen);
     845                 :            :     else {
     846                 :            : #ifdef SFLOW_DO_SOCKET
     847                 :            :     /* send it myself */
     848                 :            :     if (receiver->sFlowRcvrAddress.type == SFLADDRESSTYPE_IP_V6) {
     849                 :            :         u_int32_t soclen = sizeof(struct sockaddr_in6);
     850                 :            :         int result = sendto(receiver->agent->receiverSocket6,
     851                 :            :                 receiver->sampleCollector.data,
     852                 :            :                 receiver->sampleCollector.pktlen,
     853                 :            :                 0,
     854                 :            :                 (struct sockaddr *)&receiver->receiver6,
     855                 :            :                 soclen);
     856                 :            :         if(result == -1 && errno != EINTR) sfl_agent_sysError(receiver->agent, "receiver", "IPv6 socket sendto error");
     857                 :            :         if(result == 0) sfl_agent_error(receiver->agent, "receiver", "IPv6 socket sendto returned 0");
     858                 :            :     }
     859                 :            :     else {
     860                 :            :         u_int32_t soclen = sizeof(struct sockaddr_in);
     861                 :            :         int result = sendto(receiver->agent->receiverSocket4,
     862                 :            :                 receiver->sampleCollector.data,
     863                 :            :                 receiver->sampleCollector.pktlen,
     864                 :            :                 0,
     865                 :            :                 (struct sockaddr *)&receiver->receiver4,
     866                 :            :                 soclen);
     867                 :            :         if(result == -1 && errno != EINTR) sfl_agent_sysError(receiver->agent, "receiver", "socket sendto error");
     868                 :            :         if(result == 0) sfl_agent_error(receiver->agent, "receiver", "socket sendto returned 0");
     869                 :            :     }
     870                 :            : #endif
     871                 :            :     }
     872                 :            : 
     873                 :            :     /* reset for the next time */
     874                 :          9 :     resetSampleCollector(receiver);
     875                 :          9 : }
     876                 :            : 
     877                 :            : /*_________________---------------------------__________________
     878                 :            :   _________________   resetSampleCollector    __________________
     879                 :            :   -----------------___________________________------------------
     880                 :            : */
     881                 :            : 
     882                 :         15 : static void resetSampleCollector(SFLReceiver *receiver)
     883                 :            : {
     884                 :         15 :     receiver->sampleCollector.pktlen = 0;
     885                 :         15 :     receiver->sampleCollector.numSamples = 0;
     886                 :            :     /* point the datap to just after the header */
     887                 :         30 :     receiver->sampleCollector.datap = (receiver->agent->myIP.type == SFLADDRESSTYPE_IP_V6) ?
     888         [ -  + ]:         15 :     (receiver->sampleCollector.data + 10) :  (receiver->sampleCollector.data + 7);
     889                 :            : 
     890                 :         15 :     receiver->sampleCollector.pktlen = (u_char *)receiver->sampleCollector.datap - (u_char *)receiver->sampleCollector.data;
     891                 :         15 : }
     892                 :            : 
     893                 :            : /*_________________---------------------------__________________
     894                 :            :   _________________         sflError          __________________
     895                 :            :   -----------------___________________________------------------
     896                 :            : */
     897                 :            : 
     898                 :          0 : static void sflError(SFLReceiver *receiver, char *msg)
     899                 :            : {
     900                 :          0 :     sfl_agent_error(receiver->agent, "receiver", msg);
     901                 :          0 :     resetSampleCollector(receiver);
     902                 :          0 : }
     903                 :            : 
     904                 :            : #endif  /* !__CHECKER__ */

Generated by: LCOV version 1.12