1 /* Copyright (c) 2002-2009 InMon Corp. Licensed under the terms of the InMon sFlow licence: */
2 /* http://www.inmon.com/technology/sflowlicense.txt */
6 /*_________________--------------------------__________________
7 _________________ sfl_poller_init __________________
8 -----------------__________________________------------------
11 void sfl_poller_init(SFLPoller
*poller
,
13 SFLDataSource_instance
*pdsi
,
14 void *magic
, /* ptr to pass back in getCountersFn() */
15 getCountersFn_t getCountersFn
)
17 /* copy the dsi in case it points to poller->dsi, which we are about to clear */
18 SFLDataSource_instance dsi
= *pdsi
;
20 /* preserve the *nxt pointer too, in case we are resetting this poller and it is
21 already part of the agent's linked list (thanks to Matt Woodly for pointing this out) */
22 SFLPoller
*nxtPtr
= poller
->nxt
;
24 /* clear everything */
25 memset(poller
, 0, sizeof(*poller
));
27 /* restore the linked list ptr */
30 /* now copy in the parameters */
31 poller
->agent
= agent
;
32 poller
->dsi
= dsi
; /* structure copy */
33 poller
->magic
= magic
;
34 poller
->getCountersFn
= getCountersFn
;
37 /*_________________--------------------------__________________
38 _________________ reset __________________
39 -----------------__________________________------------------
42 static void reset(SFLPoller
*poller
)
44 SFLDataSource_instance dsi
= poller
->dsi
;
45 sfl_poller_init(poller
, poller
->agent
, &dsi
, poller
->magic
, poller
->getCountersFn
);
48 /*_________________---------------------------__________________
49 _________________ MIB access __________________
50 -----------------___________________________------------------
52 u_int32_t
sfl_poller_get_sFlowCpReceiver(SFLPoller
*poller
) {
53 return poller
->sFlowCpReceiver
;
56 void sfl_poller_set_sFlowCpReceiver(SFLPoller
*poller
, u_int32_t sFlowCpReceiver
) {
57 poller
->sFlowCpReceiver
= sFlowCpReceiver
;
58 if(sFlowCpReceiver
== 0) reset(poller
);
60 /* retrieve and cache a direct pointer to my receiver */
61 poller
->myReceiver
= sfl_agent_getReceiver(poller
->agent
, poller
->sFlowCpReceiver
);
65 u_int32_t
sfl_poller_get_sFlowCpInterval(SFLPoller
*poller
) {
66 return poller
->sFlowCpInterval
;
69 void sfl_poller_set_sFlowCpInterval(SFLPoller
*poller
, u_int32_t sFlowCpInterval
) {
70 poller
->sFlowCpInterval
= sFlowCpInterval
;
71 /* Set the countersCountdown to be a randomly selected value between 1 and
72 sFlowCpInterval. That way the counter polling would be desynchronised
73 (on a 200-port switch, polling all the counters in one second could be harmful). */
74 poller
->countersCountdown
= 1 + (random() % sFlowCpInterval
);
77 /*_________________---------------------------------__________________
78 _________________ bridge port __________________
79 -----------------_________________________________------------------
80 May need a separate number to reference the local bridge port
81 to get counters if it is not the same as the global ifIndex.
84 void sfl_poller_set_bridgePort(SFLPoller
*poller
, u_int32_t port_no
) {
85 poller
->bridgePort
= port_no
;
88 u_int32_t
sfl_poller_get_bridgePort(SFLPoller
*poller
) {
89 return poller
->bridgePort
;
92 /*_________________---------------------------------__________________
93 _________________ sequence number reset __________________
94 -----------------_________________________________------------------
95 Used to indicate a counter discontinuity
96 so that the sflow collector will know to ignore the next delta.
98 void sfl_poller_resetCountersSeqNo(SFLPoller
*poller
) { poller
->countersSampleSeqNo
= 0; }
100 /*_________________---------------------------__________________
101 _________________ sfl_poller_tick __________________
102 -----------------___________________________------------------
105 void sfl_poller_tick(SFLPoller
*poller
, time_t now
)
107 if(poller
->countersCountdown
== 0) return; /* counters retrieval was not enabled */
108 if(poller
->sFlowCpReceiver
== 0) return;
110 if(--poller
->countersCountdown
== 0) {
111 if(poller
->getCountersFn
!= NULL
) {
112 /* call out for counters */
113 SFL_COUNTERS_SAMPLE_TYPE cs
;
114 memset(&cs
, 0, sizeof(cs
));
115 poller
->getCountersFn(poller
->magic
, poller
, &cs
);
116 /* this countersFn is expected to fill in some counter block elements
117 and then call sfl_poller_writeCountersSample(poller, &cs); */
119 /* reset the countdown */
120 poller
->countersCountdown
= poller
->sFlowCpInterval
;
124 /*_________________---------------------------------__________________
125 _________________ sfl_poller_writeCountersSample __________________
126 -----------------_________________________________------------------
129 void sfl_poller_writeCountersSample(SFLPoller
*poller
, SFL_COUNTERS_SAMPLE_TYPE
*cs
)
131 /* fill in the rest of the header fields, and send to the receiver */
132 cs
->sequence_number
= ++poller
->countersSampleSeqNo
;
133 #ifdef SFL_USE_32BIT_INDEX
134 cs
->ds_class
= SFL_DS_CLASS(poller
->dsi
);
135 cs
->ds_index
= SFL_DS_INDEX(poller
->dsi
);
137 cs
->source_id
= SFL_DS_DATASOURCE(poller
->dsi
);
139 /* sent to my receiver */
140 if(poller
->myReceiver
) sfl_receiver_writeCountersSample(poller
->myReceiver
, cs
);