12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480 |
- Subject: New implementation of IPFIX/Netflow v9 for supporting VLAN and Mac-address
- Origin: softflowd-0.9.9-12-g8ea92c3 <https://github.com/irino/softflowd/commit/softflowd-0.9.9-12-g8ea92c3>
- Upstream-Author: Hitoshi Irino <irino@sfc.wide.ad.jp>
- Date: Sun Aug 6 08:17:43 2017 +0900
- --- a/common.h
- +++ b/common.h
- @@ -45,6 +45,7 @@
- #include <netinet/tcp.h>
- #include <netinet/udp.h>
- #include <arpa/inet.h>
- +#include <net/ethernet.h>
-
- #include <unistd.h>
- #include <stdlib.h>
- --- a/ipfix.c
- +++ b/ipfix.c
- @@ -11,7 +11,7 @@
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- @@ -29,1048 +29,1173 @@
- #include "softflowd.h"
-
- #if defined (HAVE_DECL_HTONLL) && !defined (HAVE_DECL_HTOBE64)
- -#define htobe64 htonll
- +#define htobe64 htonll
- #endif
- -#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */
- +#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */
-
- /* IPFIX a.k.a. Netflow v.10 */
- -struct IPFIX_HEADER {
- - u_int16_t version, length;
- - u_int32_t export_time; /* in seconds */
- - u_int32_t sequence, od_id;
- -} __packed;
- -struct IPFIX_SET_HEADER {
- - u_int16_t set_id, length;
- -} __packed;
- -struct IPFIX_TEMPLATE_RECORD_HEADER {
- - u_int16_t template_id, count;
- -} __packed;
- -struct IPFIX_TEMPLATE_SET_HEADER {
- - struct IPFIX_SET_HEADER c;
- - struct IPFIX_TEMPLATE_RECORD_HEADER r;
- -} __packed;
- -struct IPFIX_OPTION_TEMPLATE_SET_HEADER {
- - struct IPFIX_SET_HEADER c;
- - struct IPFIX_TEMPLATE_RECORD_HEADER r;
- - u_int16_t scope_count;
- -} __packed;
- -struct IPFIX_FIELD_SPECIFIER {
- - u_int16_t ie, length;
- -} __packed;
- -struct IPFIX_VENDOR_FIELD_SPECIFIER {
- - u_int16_t ie, length;
- - u_int32_t pen;
- +struct IPFIX_HEADER
- +{
- + u_int16_t version, length;
- + u_int32_t export_time; /* in seconds */
- + u_int32_t sequence, od_id;
- +} __packed;
- +struct NFLOW9_HEADER
- +{
- + u_int16_t version, flows;
- + u_int32_t uptime_ms;
- + u_int32_t export_time; /* in seconds */
- + u_int32_t sequence, od_id;
- +} __packed;
- +struct IPFIX_SET_HEADER
- +{
- + u_int16_t set_id, length;
- +} __packed;
- +struct IPFIX_TEMPLATE_RECORD_HEADER
- +{
- + u_int16_t template_id, count;
- +} __packed;
- +struct IPFIX_TEMPLATE_SET_HEADER
- +{
- + struct IPFIX_SET_HEADER c;
- + struct IPFIX_TEMPLATE_RECORD_HEADER r;
- +} __packed;
- +struct IPFIX_OPTION_TEMPLATE_SET_HEADER
- +{
- + struct IPFIX_SET_HEADER c;
- + union
- + {
- + struct
- + {
- + struct IPFIX_TEMPLATE_RECORD_HEADER r;
- + u_int16_t scope_count;
- + } i;
- + struct
- + {
- + u_int16_t template_id;
- + u_int16_t scope_length;
- + u_int16_t option_length;
- + } n;
- + } u;
- +} __packed;
- +struct IPFIX_FIELD_SPECIFIER
- +{
- + u_int16_t ie, length;
- +} __packed;
- +struct IPFIX_VENDOR_FIELD_SPECIFIER
- +{
- + u_int16_t ie, length;
- + u_int32_t pen;
- } __packed;
- #define REVERSE_PEN 29305
-
- -#define IPFIX_TEMPLATE_SET_ID 2
- -#define IPFIX_OPTION_TEMPLATE_SET_ID 3
- -#define IPFIX_MIN_RECORD_SET_ID 256
- +#define NFLOW9_TEMPLATE_SET_ID 0
- +#define NFLOW9_OPTION_TEMPLATE_SET_ID 1
- +#define IPFIX_TEMPLATE_SET_ID 2
- +#define IPFIX_OPTION_TEMPLATE_SET_ID 3
- +#define IPFIX_MIN_RECORD_SET_ID 256
-
- /* Flowset record ies the we care about */
- -#define IPFIX_octetDeltaCount 1
- -#define IPFIX_packetDeltaCount 2
- +#define IPFIX_octetDeltaCount 1
- +#define IPFIX_packetDeltaCount 2
- /* ... */
- -#define IPFIX_protocolIdentifier 4
- -#define IPFIX_ipClassOfService 5
- +#define IPFIX_protocolIdentifier 4
- +#define IPFIX_ipClassOfService 5
- /* ... */
- -#define IPFIX_tcpControlBits 6
- -#define IPFIX_sourceTransportPort 7
- -#define IPFIX_sourceIPv4Address 8
- +#define IPFIX_tcpControlBits 6
- +#define IPFIX_sourceTransportPort 7
- +#define IPFIX_sourceIPv4Address 8
- /* ... */
- -#define IPFIX_ingressInterface 10
- -#define IPFIX_destinationTransportPort 11
- -#define IPFIX_destinationIPv4Address 12
- +#define IPFIX_ingressInterface 10
- +#define IPFIX_destinationTransportPort 11
- +#define IPFIX_destinationIPv4Address 12
- /* ... */
- -#define IPFIX_egressInterface 14
- +#define IPFIX_egressInterface 14
- /* ... */
- -#define IPFIX_flowEndSysUpTime 21
- -#define IPFIX_flowStartSysUpTime 22
- +#define IPFIX_flowEndSysUpTime 21
- +#define IPFIX_flowStartSysUpTime 22
- /* ... */
- -#define IPFIX_sourceIPv6Address 27
- -#define IPFIX_destinationIPv6Address 28
- +#define IPFIX_sourceIPv6Address 27
- +#define IPFIX_destinationIPv6Address 28
- /* ... */
- -#define IPFIX_icmpTypeCodeIPv4 32
- +#define IPFIX_icmpTypeCodeIPv4 32
- /* ... */
- +#define NFLOW9_SAMPLING_INTERVAL 34
- +#define NFLOW9_SAMPLING_ALGORITHM 35
- /* ... */
- -#define IPFIX_vlanId 58
- +#define IPFIX_sourceMacAddress 56
- +#define IPFIX_postDestinationMacAddress 57
- +#define IPFIX_vlanId 58
- +#define IPFIX_postVlanId 59
-
- -#define IPFIX_ipVersion 60
- +#define IPFIX_ipVersion 60
- /* ... */
- -#define IPFIX_icmpTypeCodeIPv6 139
- +#define IPFIX_icmpTypeCodeIPv6 139
- /* ... */
- -#define IPFIX_meteringProcessId 143
- +#define IPFIX_meteringProcessId 143
- /* ... */
- -#define IPFIX_flowStartSeconds 150
- -#define IPFIX_flowEndSeconds 151
- -#define IPFIX_flowStartMilliSeconds 152
- -#define IPFIX_flowEndMilliSeconds 153
- -#define IPFIX_flowStartMicroSeconds 154
- -#define IPFIX_flowEndMicroSeconds 155
- -#define IPFIX_flowStartNanoSeconds 156
- -#define IPFIX_flowEndNanoSeconds 157
- +#define IPFIX_flowStartSeconds 150
- +#define IPFIX_flowEndSeconds 151
- +#define IPFIX_flowStartMilliSeconds 152
- +#define IPFIX_flowEndMilliSeconds 153
- +#define IPFIX_flowStartMicroSeconds 154
- +#define IPFIX_flowEndMicroSeconds 155
- +#define IPFIX_flowStartNanoSeconds 156
- +#define IPFIX_flowEndNanoSeconds 157
- /* ... */
- -#define IPFIX_systemInitTimeMilliseconds 160
- +#define IPFIX_systemInitTimeMilliseconds 160
- /* ... */
- -#define PSAMP_selectorAlgorithm 304
- -#define PSAMP_samplingPacketInterval 305
- -#define PSAMP_samplingPacketSpace 306
- +#define PSAMP_selectorAlgorithm 304
- +#define PSAMP_samplingPacketInterval 305
- +#define PSAMP_samplingPacketSpace 306
- +
- +#define PSAMP_selectorAlgorithm_count 1
- +
- +#define NFLOW9_OPTION_SCOPE_INTERFACE 2
- +#define NFLOW9_SAMPLING_ALGORITHM_DETERMINISTIC 1
- +
- +const struct IPFIX_FIELD_SPECIFIER field_v4[] = {
- + {IPFIX_sourceIPv4Address, 4},
- + {IPFIX_destinationIPv4Address, 4}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_v6[] = {
- + {IPFIX_sourceIPv6Address, 16},
- + {IPFIX_destinationIPv6Address, 16}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_common[] = {
- + {IPFIX_octetDeltaCount, 4},
- + {IPFIX_packetDeltaCount, 4},
- + {IPFIX_ingressInterface, 4},
- + {IPFIX_egressInterface, 4}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_transport[] = {
- + {IPFIX_sourceTransportPort, 2},
- + {IPFIX_destinationTransportPort, 2},
- + {IPFIX_protocolIdentifier, 1},
- + {IPFIX_tcpControlBits, 1},
- + {IPFIX_ipVersion, 1},
- + {IPFIX_ipClassOfService, 1}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_icmp4[] = {
- + {IPFIX_icmpTypeCodeIPv4, 2},
- + {IPFIX_ipVersion, 1},
- + {IPFIX_ipClassOfService, 1}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_icmp6[] = {
- + {IPFIX_icmpTypeCodeIPv6, 2},
- + {IPFIX_ipVersion, 1},
- + {IPFIX_ipClassOfService, 1}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_vlan[] = {
- + {IPFIX_vlanId, 2},
- + {IPFIX_postVlanId, 2}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_ether[] = {
- + {IPFIX_sourceMacAddress, 6},
- + {IPFIX_postDestinationMacAddress, 6}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_timesec[] = {
- + {IPFIX_flowStartSeconds, 4},
- + {IPFIX_flowEndSeconds, 4}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_timemsec[] = {
- + {IPFIX_flowStartMilliSeconds, 8},
- + {IPFIX_flowEndMilliSeconds, 8}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_timeusec[] = {
- + {IPFIX_flowStartMicroSeconds, 8},
- + {IPFIX_flowEndMicroSeconds, 8}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_timensec[] = {
- + {IPFIX_flowStartNanoSeconds, 8},
- + {IPFIX_flowEndNanoSeconds, 8}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_timesysup[] = {
- + {IPFIX_flowStartSysUpTime, 4},
- + {IPFIX_flowEndSysUpTime, 4}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_bicommon[] = {
- + {IPFIX_octetDeltaCount, 4},
- + {IPFIX_packetDeltaCount, 4},
- + {IPFIX_ipClassOfService, 1}
- +};
-
- -#define PSAMP_selectorAlgorithm_count 1
- +const struct IPFIX_FIELD_SPECIFIER field_bitransport[] =
- + { {IPFIX_tcpControlBits, 1} };
- +
- +const struct IPFIX_FIELD_SPECIFIER field_biicmp4[] =
- + { {IPFIX_icmpTypeCodeIPv4, 2} };
- +
- +const struct IPFIX_FIELD_SPECIFIER field_biicmp6[] =
- + { {IPFIX_icmpTypeCodeIPv6, 2} };
- +
- +const struct IPFIX_FIELD_SPECIFIER field_scope[] =
- + { {IPFIX_meteringProcessId, 4} };
- +
- +const struct IPFIX_FIELD_SPECIFIER field_option[] = {
- + {IPFIX_systemInitTimeMilliseconds, 8},
- + {PSAMP_samplingPacketInterval, 4},
- + {PSAMP_samplingPacketSpace, 4},
- + {PSAMP_selectorAlgorithm, 2}
- +};
- +
- +const struct IPFIX_FIELD_SPECIFIER field_nf9scope[] =
- + { {NFLOW9_OPTION_SCOPE_INTERFACE, 4} };
- +
- +const struct IPFIX_FIELD_SPECIFIER field_nf9option[] = {
- + {NFLOW9_SAMPLING_INTERVAL, 4},
- + {NFLOW9_SAMPLING_ALGORITHM, 1}
- +};
-
- /* Stuff pertaining to the templates that softflowd uses */
- -#define IPFIX_SOFTFLOWD_TEMPLATE_COMMONRECORDS 14
- -#define IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS 2
- -#define IPFIX_SOFTFLOWD_TEMPLATE_VENDORRECORDS 5
- -
- -#define IPFIX_SOFTFLOWD_TEMPLATE_NRECORDS \
- - IPFIX_SOFTFLOWD_TEMPLATE_COMMONRECORDS + \
- - IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS
- -
- -#define IPFIX_SOFTFLOWD_TEMPLATE_BIDIRECTION_NRECORDS \
- - IPFIX_SOFTFLOWD_TEMPLATE_COMMONRECORDS + \
- - IPFIX_SOFTFLOWD_TEMPLATE_VENDORRECORDS + \
- - IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS
- -
- -struct IPFIX_SOFTFLOWD_TEMPLATE {
- - struct IPFIX_TEMPLATE_SET_HEADER h;
- - struct IPFIX_FIELD_SPECIFIER r[IPFIX_SOFTFLOWD_TEMPLATE_NRECORDS];
- -} __packed;
- -
- -struct IPFIX_SOFTFLOWD_BIDIRECTION_TEMPLATE {
- - struct IPFIX_TEMPLATE_SET_HEADER h;
- - struct IPFIX_FIELD_SPECIFIER r[IPFIX_SOFTFLOWD_TEMPLATE_COMMONRECORDS];
- - struct IPFIX_VENDOR_FIELD_SPECIFIER v[IPFIX_SOFTFLOWD_TEMPLATE_VENDORRECORDS];
- - struct IPFIX_FIELD_SPECIFIER t[IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS];
- -} __packed;
- -
- -#define IPFIX_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS 1
- -#define IPFIX_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS 4
- -struct IPFIX_SOFTFLOWD_OPTION_TEMPLATE {
- - struct IPFIX_OPTION_TEMPLATE_SET_HEADER h;
- - struct IPFIX_FIELD_SPECIFIER s[IPFIX_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS];
- - struct IPFIX_FIELD_SPECIFIER r[IPFIX_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS];
- +#define IPFIX_SOFTFLOWD_TEMPLATE_IPRECORDS \
- + sizeof(field_v4) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS \
- + sizeof(field_timesysup) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define IPFIX_SOFTFLOWD_TEMPLATE_COMMONRECORDS \
- + sizeof(field_common) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define IPFIX_SOFTFLOWD_TEMPLATE_TRANSPORTRECORDS \
- + sizeof(field_transport) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define IPFIX_SOFTFLOWD_TEMPLATE_ICMPRECORDS \
- + sizeof(field_icmp4) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define IPFIX_SOFTFLOWD_TEMPLATE_VLANRECORDS \
- + sizeof(field_vlan) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define IPFIX_SOFTFLOWD_TEMPLATE_ETHERRECORDS \
- + sizeof(field_ether) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +//#define IPFIX_SOFTFLOWD_TEMPLATE_VENDORRECORDS 5
- +#define IPFIX_SOFTFLOWD_TEMPLATE_BICOMMONRECORDS \
- + sizeof(field_bicommon) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define IPFIX_SOFTFLOWD_TEMPLATE_BITRANSPORTRECORDS \
- + sizeof(field_bitransport) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define IPFIX_SOFTFLOWD_TEMPLATE_BIICMPRECORDS \
- + sizeof(field_biicmp4) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +
- +#define IPFIX_SOFTFLOWD_TEMPLATE_NRECORDS \
- + IPFIX_SOFTFLOWD_TEMPLATE_IPRECORDS + \
- + IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS + \
- + IPFIX_SOFTFLOWD_TEMPLATE_COMMONRECORDS + \
- + IPFIX_SOFTFLOWD_TEMPLATE_TRANSPORTRECORDS + \
- + IPFIX_SOFTFLOWD_TEMPLATE_VLANRECORDS + \
- + IPFIX_SOFTFLOWD_TEMPLATE_ETHERRECORDS
- +
- +#define IPFIX_SOFTFLOWD_TEMPLATE_BI_NRECORDS \
- + IPFIX_SOFTFLOWD_TEMPLATE_BICOMMONRECORDS + \
- + IPFIX_SOFTFLOWD_TEMPLATE_BITRANSPORTRECORDS
- +
- +struct IPFIX_SOFTFLOWD_TEMPLATE
- +{
- + struct IPFIX_TEMPLATE_SET_HEADER h;
- + struct IPFIX_FIELD_SPECIFIER r[IPFIX_SOFTFLOWD_TEMPLATE_NRECORDS];
- + struct IPFIX_VENDOR_FIELD_SPECIFIER
- + v[IPFIX_SOFTFLOWD_TEMPLATE_BI_NRECORDS];
- + u_int16_t data_len, bi_count;
- +} __packed;
- +
- +#define IPFIX_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS \
- + sizeof(field_scope) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define IPFIX_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS \
- + sizeof(field_option) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +
- +#define NFLOW9_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS \
- + sizeof(field_nf9scope) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +#define NFLOW9_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS \
- + sizeof(field_nf9option) / sizeof(struct IPFIX_FIELD_SPECIFIER)
- +
- +
- +struct IPFIX_SOFTFLOWD_OPTION_TEMPLATE
- +{
- + struct IPFIX_OPTION_TEMPLATE_SET_HEADER h;
- + struct IPFIX_FIELD_SPECIFIER
- + s[IPFIX_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS];
- + struct IPFIX_FIELD_SPECIFIER r[IPFIX_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS];
- } __packed;
-
- /* softflowd data set */
- -struct IPFIX_SOFTFLOWD_DATA_COMMON {
- - u_int32_t octetDeltaCount, packetDeltaCount;
- - u_int32_t ingressInterface, egressInterface;
- - u_int16_t sourceTransportPort, destinationTransportPort;
- - u_int8_t protocolIdentifier, tcpControlBits, ipVersion, ipClassOfService;
- - u_int16_t icmpTypeCode, vlanId;
- -} __packed;
- -
- -struct IPFIX_SOFTFLOWD_DATA_BIDIRECTION {
- - u_int32_t octetDeltaCount, packetDeltaCount;
- - u_int8_t tcpControlBits, ipClassOfService;
- - u_int16_t icmpTypeCode;
- -} __packed;
- -
- -union IPFIX_SOFTFLOWD_DATA_TIME {
- - struct {
- - u_int32_t start;
- - u_int32_t end;
- - } u32;
- - struct {
- - u_int64_t start;
- - u_int64_t end;
- - } u64;
- -};
- +struct IPFIX_SOFTFLOWD_DATA_COMMON
- +{
- + u_int32_t octetDeltaCount, packetDeltaCount;
- + u_int32_t ingressInterface, egressInterface;
- +} __packed;
- +
- +struct IPFIX_SOFTFLOWD_DATA_TRANSPORT
- +{
- + u_int16_t sourceTransportPort, destinationTransportPort;
- + u_int8_t protocolIdentifier, tcpControlBits, ipVersion, ipClassOfService;
- +} __packed;
- +
- +struct IPFIX_SOFTFLOWD_DATA_ICMP
- +{
- + u_int16_t icmpTypeCode;
- + u_int8_t ipVersion, ipClassOfService;
- +} __packed;
- +
- +struct IPFIX_SOFTFLOWD_DATA_VLAN
- +{
- + u_int16_t vlanId, postVlanId;
- +} __packed;
-
- -struct IPFIX_SOFTFLOWD_DATA_V4 {
- - u_int32_t sourceIPv4Address, destinationIPv4Address;
- - struct IPFIX_SOFTFLOWD_DATA_COMMON c;
- - union IPFIX_SOFTFLOWD_DATA_TIME t;
- +struct IPFIX_SOFTFLOWD_DATA_ETHER
- +{
- + u_int8_t sourceMacAddress[6], destinationMacAddress[6];
- } __packed;
-
- -struct IPFIX_SOFTFLOWD_BIDIRECTION_DATA_V4 {
- - u_int32_t sourceIPv4Address, destinationIPv4Address;
- - struct IPFIX_SOFTFLOWD_DATA_COMMON c;
- - struct IPFIX_SOFTFLOWD_DATA_BIDIRECTION b;
- - union IPFIX_SOFTFLOWD_DATA_TIME t;
- +struct IPFIX_SOFTFLOWD_DATA_BICOMMON
- +{
- + u_int32_t octetDeltaCount, packetDeltaCount;
- + u_int8_t ipClassOfService;
- } __packed;
-
- -struct IPFIX_SOFTFLOWD_DATA_V6 {
- - struct in6_addr sourceIPv6Address, destinationIPv6Address;
- - struct IPFIX_SOFTFLOWD_DATA_COMMON c;
- - union IPFIX_SOFTFLOWD_DATA_TIME t;
- +struct IPFIX_SOFTFLOWD_DATA_BITRANSPORT
- +{
- + u_int8_t tcpControlBits;
- } __packed;
-
- -struct IPFIX_SOFTFLOWD_BIDIRECTION_DATA_V6 {
- - struct in6_addr sourceIPv6Address, destinationIPv6Address;
- - struct IPFIX_SOFTFLOWD_DATA_COMMON c;
- - struct IPFIX_SOFTFLOWD_DATA_BIDIRECTION b;
- - union IPFIX_SOFTFLOWD_DATA_TIME t;
- +struct IPFIX_SOFTFLOWD_DATA_BIICMP
- +{
- + u_int16_t icmpTypeCode;
- } __packed;
-
- -struct IPFIX_SOFTFLOWD_OPTION_DATA {
- - struct IPFIX_SET_HEADER c;
- - u_int32_t scope_pid;
- - u_int64_t systemInitTimeMilliseconds;
- - u_int16_t samplingAlgorithm;
- - u_int16_t samplingInterval;
- - u_int32_t samplingSpace;
- +union IPFIX_SOFTFLOWD_DATA_TIME
- +{
- + struct
- + {
- + u_int32_t start;
- + u_int32_t end;
- + } u32;
- + struct
- + {
- + u_int64_t start;
- + u_int64_t end;
- + } u64;
- +};
- +
- +struct IPFIX_SOFTFLOWD_DATA_V4ADDR
- +{
- + u_int32_t sourceIPv4Address, destinationIPv4Address;
- +} __packed;
- +
- +struct IPFIX_SOFTFLOWD_DATA_V6ADDR
- +{
- + struct in6_addr sourceIPv6Address, destinationIPv6Address;
- } __packed;
- -
- +
- +struct IPFIX_SOFTFLOWD_OPTION_DATA
- +{
- + struct IPFIX_SET_HEADER c;
- + u_int32_t scope_pid;
- + u_int64_t systemInitTimeMilliseconds;
- + u_int32_t samplingInterval;
- + u_int32_t samplingSpace;
- + u_int16_t samplingAlgorithm;
- +} __packed;
- +
- +struct NFLOW9_SOFTFLOWD_OPTION_DATA
- +{
- + struct IPFIX_SET_HEADER c;
- + u_int32_t scope_ifidx;
- + u_int32_t samplingInterval;
- + u_int8_t samplingAlgorithm;
- +} __packed;
- +
- /* Local data: templates and counters */
- -#define IPFIX_SOFTFLOWD_MAX_PACKET_SIZE 512
- -#define IPFIX_SOFTFLOWD_V4_TEMPLATE_ID 1024
- -#define IPFIX_SOFTFLOWD_V6_TEMPLATE_ID 2048
- -#define IPFIX_SOFTFLOWD_OPTION_TEMPLATE_ID 256
- +#define IPFIX_SOFTFLOWD_MAX_PACKET_SIZE 1428
- +#define IPFIX_SOFTFLOWD_V4_TEMPLATE_ID 1024
- +#define IPFIX_SOFTFLOWD_ICMPV4_TEMPLATE_ID 1025
- +#define IPFIX_SOFTFLOWD_V6_TEMPLATE_ID 2048
- +#define IPFIX_SOFTFLOWD_ICMPV6_TEMPLATE_ID 2049
- +#define IPFIX_SOFTFLOWD_OPTION_TEMPLATE_ID 256
-
- -#define IPFIX_DEFAULT_TEMPLATE_INTERVAL 16
- +#define IPFIX_DEFAULT_TEMPLATE_INTERVAL 16
-
- /* ... */
- -#define IPFIX_OPTION_SCOPE_SYSTEM 1
- -#define IPFIX_OPTION_SCOPE_INTERFACE 2
- -#define IPFIX_OPTION_SCOPE_LINECARD 3
- -#define IPFIX_OPTION_SCOPE_CACHE 4
- -#define IPFIX_OPTION_SCOPE_TEMPLATE 5
- +#define IPFIX_OPTION_SCOPE_SYSTEM 1
- +#define IPFIX_OPTION_SCOPE_INTERFACE 2
- +#define IPFIX_OPTION_SCOPE_LINECARD 3
- +#define IPFIX_OPTION_SCOPE_CACHE 4
- +#define IPFIX_OPTION_SCOPE_TEMPLATE 5
- /* ... */
- -#define IPFIX_SAMPLING_ALGORITHM_DETERMINISTIC 1
- -#define IPFIX_SAMPLING_ALGORITHM_RANDOM 2
- +#define IPFIX_SAMPLING_ALGORITHM_DETERMINISTIC 1
- +#define IPFIX_SAMPLING_ALGORITHM_RANDOM 2
- /* ... */
-
- -static struct IPFIX_SOFTFLOWD_TEMPLATE v4_template;
- -static struct IPFIX_SOFTFLOWD_TEMPLATE v6_template;
- -static struct IPFIX_SOFTFLOWD_BIDIRECTION_TEMPLATE v4_bidirection_template;
- -static struct IPFIX_SOFTFLOWD_BIDIRECTION_TEMPLATE v6_bidirection_template;
- +enum
- +{ TMPLV4, TMPLICMPV4, TMPLV6, TMPLICMPV6, TMPLMAX };
- +static struct IPFIX_SOFTFLOWD_TEMPLATE template[TMPLMAX];
- static struct IPFIX_SOFTFLOWD_OPTION_TEMPLATE option_template;
- static struct IPFIX_SOFTFLOWD_OPTION_DATA option_data;
- +static struct NFLOW9_SOFTFLOWD_OPTION_DATA nf9opt_data;
- +
- static int ipfix_pkts_until_template = -1;
-
- +static int
- +ipfix_init_fields (struct IPFIX_FIELD_SPECIFIER *dst,
- + u_int * index,
- + const struct IPFIX_FIELD_SPECIFIER *src,
- + u_int field_number)
- +{
- + int length = 0;
- + for (int i = 0; i < field_number; i++)
- + {
- + dst[*index + i].ie = htons (src[i].ie);
- + dst[*index + i].length = htons (src[i].length);
- + length += src[i].length;
- + }
- + *index += field_number;
- + return length;
- +}
- +
- +static int
- +ipfix_init_bifields (struct IPFIX_SOFTFLOWD_TEMPLATE *template,
- + u_int * index,
- + const struct IPFIX_FIELD_SPECIFIER *fields,
- + u_int field_number)
- +{
- + int length = 0;
- + for (int i = 0; i < field_number; i++)
- + {
- + template->v[*index + i].ie = htons (fields[i].ie | 0x8000);
- + template->v[*index + i].length = htons (fields[i].length);
- + template->v[*index + i].pen = htonl (REVERSE_PEN);
- + length += fields[i].length;
- + }
- + *index += field_number;
- + return length;
- +}
- +
- +static int
- +ipfix_init_template_time (struct FLOWTRACKPARAMETERS *param,
- + struct IPFIX_SOFTFLOWD_TEMPLATE *template,
- + u_int * index)
- +{
- + int length = 0;
- + if (param->time_format == 's')
- + {
- + length = ipfix_init_fields (template->r, index,
- + field_timesec,
- + IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS);
- + }
- + else if (param->time_format == 'm')
- + {
- + length = ipfix_init_fields (template->r, index,
- + field_timemsec,
- + IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS);
- + }
- + else if (param->time_format == 'M')
- + {
- + length = ipfix_init_fields (template->r, index,
- + field_timeusec,
- + IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS);
- + }
- + else if (param->time_format == 'n')
- + {
- + length = ipfix_init_fields (template->r, index,
- + field_timensec,
- + IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS);
- + }
- + else
- + {
- + length = ipfix_init_fields (template->r, index,
- + field_timesysup,
- + IPFIX_SOFTFLOWD_TEMPLATE_TIMERECORDS);
- + }
- + return length;
- +}
- +
- static void
- -ipfix_init_template(struct FLOWTRACKPARAMETERS *param)
- +ipfix_init_template_unity (struct FLOWTRACKPARAMETERS *param,
- + struct IPFIX_SOFTFLOWD_TEMPLATE *template,
- + u_int template_id, u_int8_t v6_flag,
- + u_int8_t icmp_flag, u_int8_t bi_flag,
- + u_int16_t version)
- {
- - bzero(&v4_template, sizeof(v4_template));
- - v4_template.h.c.set_id = htons(IPFIX_TEMPLATE_SET_ID);
- - v4_template.h.c.length = htons(sizeof(v4_template));
- - v4_template.h.r.template_id = htons(IPFIX_SOFTFLOWD_V4_TEMPLATE_ID);
- - v4_template.h.r.count = htons(IPFIX_SOFTFLOWD_TEMPLATE_NRECORDS);
- - v4_template.r[0].ie = htons(IPFIX_sourceIPv4Address);
- - v4_template.r[0].length = htons(4);
- - v4_template.r[1].ie = htons(IPFIX_destinationIPv4Address);
- - v4_template.r[1].length = htons(4);
- - v4_template.r[2].ie = htons(IPFIX_octetDeltaCount);
- - v4_template.r[2].length = htons(4);
- - v4_template.r[3].ie = htons(IPFIX_packetDeltaCount);
- - v4_template.r[3].length = htons(4);
- - v4_template.r[4].ie = htons(IPFIX_ingressInterface);
- - v4_template.r[4].length = htons(4);
- - v4_template.r[5].ie = htons(IPFIX_egressInterface);
- - v4_template.r[5].length = htons(4);
- - v4_template.r[6].ie = htons(IPFIX_sourceTransportPort);
- - v4_template.r[6].length = htons(2);
- - v4_template.r[7].ie = htons(IPFIX_destinationTransportPort);
- - v4_template.r[7].length = htons(2);
- - v4_template.r[8].ie = htons(IPFIX_protocolIdentifier);
- - v4_template.r[8].length = htons(1);
- - v4_template.r[9].ie = htons(IPFIX_tcpControlBits);
- - v4_template.r[9].length = htons(1);
- - v4_template.r[10].ie = htons(IPFIX_ipVersion);
- - v4_template.r[10].length = htons(1);
- - v4_template.r[11].ie = htons(IPFIX_ipClassOfService);
- - v4_template.r[11].length = htons(1);
- - v4_template.r[12].ie = htons(IPFIX_icmpTypeCodeIPv4);
- - v4_template.r[12].length = htons(2);
- - v4_template.r[13].ie = htons(IPFIX_vlanId);
- - v4_template.r[13].length = htons(2);
- - if (param->time_format == 's') {
- - v4_template.r[14].ie = htons(IPFIX_flowStartSeconds);
- - v4_template.r[14].length = htons(sizeof(u_int32_t));
- - v4_template.r[15].ie = htons(IPFIX_flowEndSeconds);
- - v4_template.r[15].length = htons(sizeof(u_int32_t));
- - } else if (param->time_format == 'm') {
- - v4_template.r[14].ie = htons(IPFIX_flowStartMilliSeconds);
- - v4_template.r[14].length = htons(sizeof(u_int64_t));
- - v4_template.r[15].ie = htons(IPFIX_flowEndMilliSeconds);
- - v4_template.r[15].length = htons(sizeof(u_int64_t));
- - } else if (param->time_format == 'M') {
- - v4_template.r[14].ie = htons(IPFIX_flowStartMicroSeconds);
- - v4_template.r[14].length = htons(sizeof(u_int64_t));
- - v4_template.r[15].ie = htons(IPFIX_flowEndMicroSeconds);
- - v4_template.r[15].length = htons(sizeof(u_int64_t));
- - } else if (param->time_format == 'n') {
- - v4_template.r[14].ie = htons(IPFIX_flowStartNanoSeconds);
- - v4_template.r[14].length = htons(sizeof(u_int64_t));
- - v4_template.r[15].ie = htons(IPFIX_flowEndNanoSeconds);
- - v4_template.r[15].length = htons(sizeof(u_int64_t));
- - } else {
- - v4_template.r[14].ie = htons(IPFIX_flowStartSysUpTime);
- - v4_template.r[14].length = htons(sizeof(u_int32_t));
- - v4_template.r[15].ie = htons(IPFIX_flowEndSysUpTime);
- - v4_template.r[15].length = htons(sizeof(u_int32_t));
- - }
- -
- - bzero(&v6_template, sizeof(v6_template));
- - v6_template.h.c.set_id = htons(IPFIX_TEMPLATE_SET_ID);
- - v6_template.h.c.length = htons(sizeof(v6_template));
- - v6_template.h.r.template_id = htons(IPFIX_SOFTFLOWD_V6_TEMPLATE_ID);
- - v6_template.h.r.count = htons(IPFIX_SOFTFLOWD_TEMPLATE_NRECORDS);
- - v6_template.r[0].ie = htons(IPFIX_sourceIPv6Address);
- - v6_template.r[0].length = htons(16);
- - v6_template.r[1].ie = htons(IPFIX_destinationIPv6Address);
- - v6_template.r[1].length = htons(16);
- - v6_template.r[2].ie = htons(IPFIX_octetDeltaCount);
- - v6_template.r[2].length = htons(4);
- - v6_template.r[3].ie = htons(IPFIX_packetDeltaCount);
- - v6_template.r[3].length = htons(4);
- - v6_template.r[4].ie = htons(IPFIX_ingressInterface);
- - v6_template.r[4].length = htons(4);
- - v6_template.r[5].ie = htons(IPFIX_egressInterface);
- - v6_template.r[5].length = htons(4);
- - v6_template.r[6].ie = htons(IPFIX_sourceTransportPort);
- - v6_template.r[6].length = htons(2);
- - v6_template.r[7].ie = htons(IPFIX_destinationTransportPort);
- - v6_template.r[7].length = htons(2);
- - v6_template.r[8].ie = htons(IPFIX_protocolIdentifier);
- - v6_template.r[8].length = htons(1);
- - v6_template.r[9].ie = htons(IPFIX_tcpControlBits);
- - v6_template.r[9].length = htons(1);
- - v6_template.r[10].ie = htons(IPFIX_ipVersion);
- - v6_template.r[10].length = htons(1);
- - v6_template.r[11].ie = htons(IPFIX_ipClassOfService);
- - v6_template.r[11].length = htons(1);
- - v6_template.r[12].ie = htons(IPFIX_icmpTypeCodeIPv6);
- - v6_template.r[12].length = htons(2);
- - v6_template.r[13].ie = htons(IPFIX_vlanId);
- - v6_template.r[13].length = htons(2);
- - if (param->time_format == 's') {
- - v6_template.r[14].ie = htons(IPFIX_flowStartSeconds);
- - v6_template.r[14].length = htons(sizeof(u_int32_t));
- - v6_template.r[15].ie = htons(IPFIX_flowEndSeconds);
- - v6_template.r[15].length = htons(sizeof(u_int32_t));
- - } else if (param->time_format == 'm') {
- - v6_template.r[14].ie = htons(IPFIX_flowStartMilliSeconds);
- - v6_template.r[14].length = htons(sizeof(u_int64_t));
- - v6_template.r[15].ie = htons(IPFIX_flowEndMilliSeconds);
- - v6_template.r[15].length = htons(sizeof(u_int64_t));
- - } else if (param->time_format == 'M') {
- - v6_template.r[14].ie = htons(IPFIX_flowStartMicroSeconds);
- - v6_template.r[14].length = htons(sizeof(u_int64_t));
- - v6_template.r[15].ie = htons(IPFIX_flowEndMicroSeconds);
- - v6_template.r[15].length = htons(sizeof(u_int64_t));
- - } else if (param->time_format == 'n') {
- - v6_template.r[14].ie = htons(IPFIX_flowStartNanoSeconds);
- - v6_template.r[14].length = htons(sizeof(u_int64_t));
- - v6_template.r[15].ie = htons(IPFIX_flowEndNanoSeconds);
- - v6_template.r[15].length = htons(sizeof(u_int64_t));
- - } else {
- - v6_template.r[14].ie = htons(IPFIX_flowStartSysUpTime);
- - v6_template.r[14].length = htons(sizeof(u_int32_t));
- - v6_template.r[15].ie = htons(IPFIX_flowEndSysUpTime);
- - v6_template.r[15].length = htons(sizeof(u_int32_t));
- - }
- + u_int index = 0, bi_index = 0, length = 0;
- + bzero (template, sizeof (*template));
- + template->h.c.set_id = htons (version == 10 ?
- + IPFIX_TEMPLATE_SET_ID :
- + NFLOW9_TEMPLATE_SET_ID);
- + template->h.r.template_id = htons (template_id);
- + if (v6_flag)
- + {
- + length += ipfix_init_fields (template->r, &index,
- + field_v6,
- + IPFIX_SOFTFLOWD_TEMPLATE_IPRECORDS);
- + }
- + else
- + {
- + length += ipfix_init_fields (template->r, &index,
- + field_v4,
- + IPFIX_SOFTFLOWD_TEMPLATE_IPRECORDS);
- + }
- + length += ipfix_init_template_time (param, template, &index);
- + length += ipfix_init_fields (template->r, &index,
- + field_common,
- + IPFIX_SOFTFLOWD_TEMPLATE_COMMONRECORDS);
- + if (icmp_flag)
- + {
- + if (v6_flag)
- + {
- + length += ipfix_init_fields (template->r, &index,
- + field_icmp6,
- + IPFIX_SOFTFLOWD_TEMPLATE_ICMPRECORDS);
- + }
- + else
- + {
- + length += ipfix_init_fields (template->r, &index,
- + field_icmp4,
- + IPFIX_SOFTFLOWD_TEMPLATE_ICMPRECORDS);
- + }
- + }
- + else
- + {
- + length += ipfix_init_fields (template->r, &index,
- + field_transport,
- + IPFIX_SOFTFLOWD_TEMPLATE_TRANSPORTRECORDS);
- + }
- + if (param->track_level >= TRACK_FULL_VLAN)
- + {
- + length += ipfix_init_fields (template->r, &index,
- + field_vlan,
- + IPFIX_SOFTFLOWD_TEMPLATE_VLANRECORDS);
- + }
- + if (param->track_level >= TRACK_FULL_VLAN_ETHER)
- + {
- + length += ipfix_init_fields (template->r, &index,
- + field_ether,
- + IPFIX_SOFTFLOWD_TEMPLATE_ETHERRECORDS);
- + }
- + if (bi_flag)
- + {
- + length +=
- + ipfix_init_bifields (template, &bi_index,
- + field_bicommon,
- + IPFIX_SOFTFLOWD_TEMPLATE_BICOMMONRECORDS);
- + if (icmp_flag)
- + {
- + if (v6_flag)
- + {
- + length +=
- + ipfix_init_bifields (template, &bi_index,
- + field_biicmp6,
- + IPFIX_SOFTFLOWD_TEMPLATE_BIICMPRECORDS);
- + }
- + else
- + {
- + length +=
- + ipfix_init_bifields (template, &bi_index,
- + field_biicmp4,
- + IPFIX_SOFTFLOWD_TEMPLATE_BIICMPRECORDS);
- + }
- + }
- + else
- + {
- + length +=
- + ipfix_init_bifields (template, &bi_index,
- + field_bitransport,
- + IPFIX_SOFTFLOWD_TEMPLATE_BITRANSPORTRECORDS);
- +
- + }
- + }
- + template->bi_count = bi_index;
- + template->h.r.count = htons (index + bi_index);
- + template->h.c.length =
- + htons (sizeof (struct IPFIX_TEMPLATE_SET_HEADER) +
- + index * sizeof (struct IPFIX_FIELD_SPECIFIER) +
- + bi_index * sizeof (struct IPFIX_VENDOR_FIELD_SPECIFIER));
- + template->data_len = length;
- }
-
- static void
- -ipfix_init_template_bidirection(struct FLOWTRACKPARAMETERS *param)
- +ipfix_init_template (struct FLOWTRACKPARAMETERS *param,
- + u_int8_t bi_flag, u_int16_t version)
- {
- - bzero(&v4_bidirection_template, sizeof(v4_bidirection_template));
- - v4_bidirection_template.h.c.set_id = htons(IPFIX_TEMPLATE_SET_ID);
- - v4_bidirection_template.h.c.length = htons(sizeof(v4_bidirection_template));
- - v4_bidirection_template.h.r.template_id = htons(IPFIX_SOFTFLOWD_V4_TEMPLATE_ID);
- - v4_bidirection_template.h.r.count = htons(IPFIX_SOFTFLOWD_TEMPLATE_BIDIRECTION_NRECORDS);
- - v4_bidirection_template.r[0].ie = htons(IPFIX_sourceIPv4Address);
- - v4_bidirection_template.r[0].length = htons(4);
- - v4_bidirection_template.r[1].ie = htons(IPFIX_destinationIPv4Address);
- - v4_bidirection_template.r[1].length = htons(4);
- - v4_bidirection_template.r[2].ie = htons(IPFIX_octetDeltaCount);
- - v4_bidirection_template.r[2].length = htons(4);
- - v4_bidirection_template.r[3].ie = htons(IPFIX_packetDeltaCount);
- - v4_bidirection_template.r[3].length = htons(4);
- - v4_bidirection_template.r[4].ie = htons(IPFIX_ingressInterface);
- - v4_bidirection_template.r[4].length = htons(4);
- - v4_bidirection_template.r[5].ie = htons(IPFIX_egressInterface);
- - v4_bidirection_template.r[5].length = htons(4);
- - v4_bidirection_template.r[6].ie = htons(IPFIX_sourceTransportPort);
- - v4_bidirection_template.r[6].length = htons(2);
- - v4_bidirection_template.r[7].ie = htons(IPFIX_destinationTransportPort);
- - v4_bidirection_template.r[7].length = htons(2);
- - v4_bidirection_template.r[8].ie = htons(IPFIX_protocolIdentifier);
- - v4_bidirection_template.r[8].length = htons(1);
- - v4_bidirection_template.r[9].ie = htons(IPFIX_tcpControlBits);
- - v4_bidirection_template.r[9].length = htons(1);
- - v4_bidirection_template.r[10].ie = htons(IPFIX_ipVersion);
- - v4_bidirection_template.r[10].length = htons(1);
- - v4_bidirection_template.r[11].ie = htons(IPFIX_ipClassOfService);
- - v4_bidirection_template.r[11].length = htons(1);
- - v4_bidirection_template.r[12].ie = htons(IPFIX_icmpTypeCodeIPv4);
- - v4_bidirection_template.r[12].length = htons(2);
- - v4_bidirection_template.r[13].ie = htons(IPFIX_vlanId);
- - v4_bidirection_template.r[13].length = htons(2);
- - v4_bidirection_template.v[0].ie = htons(IPFIX_octetDeltaCount | 0x8000);
- - v4_bidirection_template.v[0].length = htons(4);
- - v4_bidirection_template.v[0].pen = htonl(REVERSE_PEN);
- - v4_bidirection_template.v[1].ie = htons(IPFIX_packetDeltaCount | 0x8000);
- - v4_bidirection_template.v[1].length = htons(4);
- - v4_bidirection_template.v[1].pen = htonl(REVERSE_PEN);
- - v4_bidirection_template.v[2].ie = htons(IPFIX_tcpControlBits | 0x8000);
- - v4_bidirection_template.v[2].length = htons(1);
- - v4_bidirection_template.v[2].pen = htonl(REVERSE_PEN);
- - v4_bidirection_template.v[3].ie = htons(IPFIX_ipClassOfService | 0x8000);
- - v4_bidirection_template.v[3].length = htons(1);
- - v4_bidirection_template.v[3].pen = htonl(REVERSE_PEN);
- - v4_bidirection_template.v[4].ie = htons(IPFIX_icmpTypeCodeIPv4 | 0x8000);
- - v4_bidirection_template.v[4].length = htons(2);
- - v4_bidirection_template.v[4].pen = htonl(REVERSE_PEN);
- - if (param->time_format == 's') {
- - v4_bidirection_template.t[0].ie = htons(IPFIX_flowStartSeconds);
- - v4_bidirection_template.t[0].length = htons(sizeof(u_int32_t));
- - v4_bidirection_template.t[1].ie = htons(IPFIX_flowEndSeconds);
- - v4_bidirection_template.t[1].length = htons(sizeof(u_int32_t));
- - } else if (param->time_format == 'm') {
- - v4_bidirection_template.t[0].ie = htons(IPFIX_flowStartMilliSeconds);
- - v4_bidirection_template.t[0].length = htons(sizeof(u_int64_t));
- - v4_bidirection_template.t[1].ie = htons(IPFIX_flowEndMilliSeconds);
- - v4_bidirection_template.t[1].length = htons(sizeof(u_int64_t));
- - } else if (param->time_format == 'M') {
- - v4_bidirection_template.t[0].ie = htons(IPFIX_flowStartMicroSeconds);
- - v4_bidirection_template.t[0].length = htons(sizeof(u_int64_t));
- - v4_bidirection_template.t[1].ie = htons(IPFIX_flowEndMicroSeconds);
- - v4_bidirection_template.t[1].length = htons(sizeof(u_int64_t));
- - } else if (param->time_format == 'n') {
- - v4_bidirection_template.t[0].ie = htons(IPFIX_flowStartNanoSeconds);
- - v4_bidirection_template.t[0].length = htons(sizeof(u_int64_t));
- - v4_bidirection_template.t[1].ie = htons(IPFIX_flowEndNanoSeconds);
- - v4_bidirection_template.t[1].length = htons(sizeof(u_int64_t));
- - } else {
- - v4_bidirection_template.t[0].ie = htons(IPFIX_flowStartSysUpTime);
- - v4_bidirection_template.t[0].length = htons(sizeof(u_int32_t));
- - v4_bidirection_template.t[1].ie = htons(IPFIX_flowEndSysUpTime);
- - v4_bidirection_template.t[1].length = htons(sizeof(u_int32_t));
- - }
- -
- - bzero(&v6_bidirection_template, sizeof(v6_bidirection_template));
- - v6_bidirection_template.h.c.set_id = htons(IPFIX_TEMPLATE_SET_ID);
- - v6_bidirection_template.h.c.length = htons(sizeof(v6_bidirection_template));
- - v6_bidirection_template.h.r.template_id = htons(IPFIX_SOFTFLOWD_V6_TEMPLATE_ID);
- - v6_bidirection_template.h.r.count = htons(IPFIX_SOFTFLOWD_TEMPLATE_BIDIRECTION_NRECORDS);
- - v6_bidirection_template.r[0].ie = htons(IPFIX_sourceIPv6Address);
- - v6_bidirection_template.r[0].length = htons(16);
- - v6_bidirection_template.r[1].ie = htons(IPFIX_destinationIPv6Address);
- - v6_bidirection_template.r[1].length = htons(16);
- - v6_bidirection_template.r[2].ie = htons(IPFIX_octetDeltaCount);
- - v6_bidirection_template.r[2].length = htons(4);
- - v6_bidirection_template.r[3].ie = htons(IPFIX_packetDeltaCount);
- - v6_bidirection_template.r[3].length = htons(4);
- - v6_bidirection_template.r[4].ie = htons(IPFIX_ingressInterface);
- - v6_bidirection_template.r[4].length = htons(4);
- - v6_bidirection_template.r[5].ie = htons(IPFIX_egressInterface);
- - v6_bidirection_template.r[5].length = htons(4);
- - v6_bidirection_template.r[6].ie = htons(IPFIX_sourceTransportPort);
- - v6_bidirection_template.r[6].length = htons(2);
- - v6_bidirection_template.r[7].ie = htons(IPFIX_destinationTransportPort);
- - v6_bidirection_template.r[7].length = htons(2);
- - v6_bidirection_template.r[8].ie = htons(IPFIX_protocolIdentifier);
- - v6_bidirection_template.r[8].length = htons(1);
- - v6_bidirection_template.r[9].ie = htons(IPFIX_tcpControlBits);
- - v6_bidirection_template.r[9].length = htons(1);
- - v6_bidirection_template.r[10].ie = htons(IPFIX_ipVersion);
- - v6_bidirection_template.r[10].length = htons(1);
- - v6_bidirection_template.r[11].ie = htons(IPFIX_ipClassOfService);
- - v6_bidirection_template.r[11].length = htons(1);
- - v6_bidirection_template.r[12].ie = htons(IPFIX_icmpTypeCodeIPv6);
- - v6_bidirection_template.r[12].length = htons(2);
- - v6_bidirection_template.r[13].ie = htons(IPFIX_vlanId);
- - v6_bidirection_template.r[13].length = htons(2);
- - v6_bidirection_template.v[0].ie = htons(IPFIX_octetDeltaCount | 0x8000);
- - v6_bidirection_template.v[0].length = htons(4);
- - v6_bidirection_template.v[0].pen = htonl(REVERSE_PEN);
- - v6_bidirection_template.v[1].ie = htons(IPFIX_packetDeltaCount | 0x8000);
- - v6_bidirection_template.v[1].length = htons(4);
- - v6_bidirection_template.v[1].pen = htonl(REVERSE_PEN);
- - v6_bidirection_template.v[2].ie = htons(IPFIX_tcpControlBits | 0x8000);
- - v6_bidirection_template.v[2].length = htons(1);
- - v6_bidirection_template.v[2].pen = htonl(REVERSE_PEN);
- - v6_bidirection_template.v[3].ie = htons(IPFIX_ipClassOfService | 0x8000);
- - v6_bidirection_template.v[3].length = htons(1);
- - v6_bidirection_template.v[3].pen = htonl(REVERSE_PEN);
- - v6_bidirection_template.v[4].ie = htons(IPFIX_icmpTypeCodeIPv6 | 0x8000);
- - v6_bidirection_template.v[4].length = htons(2);
- - v6_bidirection_template.v[4].pen = htonl(REVERSE_PEN);
- - if (param->time_format == 's') {
- - v6_bidirection_template.t[0].ie = htons(IPFIX_flowStartSeconds);
- - v6_bidirection_template.t[0].length = htons(sizeof(u_int32_t));
- - v6_bidirection_template.t[1].ie = htons(IPFIX_flowEndSeconds);
- - v6_bidirection_template.t[1].length = htons(sizeof(u_int32_t));
- - } else if (param->time_format == 'm') {
- - v6_bidirection_template.t[0].ie = htons(IPFIX_flowStartMilliSeconds);
- - v6_bidirection_template.t[0].length = htons(sizeof(u_int64_t));
- - v6_bidirection_template.t[1].ie = htons(IPFIX_flowEndMilliSeconds);
- - v6_bidirection_template.t[1].length = htons(sizeof(u_int64_t));
- - } else if (param->time_format == 'M') {
- - v6_bidirection_template.t[0].ie = htons(IPFIX_flowStartMicroSeconds);
- - v6_bidirection_template.t[0].length = htons(sizeof(u_int64_t));
- - v6_bidirection_template.t[1].ie = htons(IPFIX_flowEndMicroSeconds);
- - v6_bidirection_template.t[1].length = htons(sizeof(u_int64_t));
- - } else if (param->time_format == 'n') {
- - v6_bidirection_template.t[0].ie = htons(IPFIX_flowStartNanoSeconds);
- - v6_bidirection_template.t[0].length = htons(sizeof(u_int64_t));
- - v6_bidirection_template.t[1].ie = htons(IPFIX_flowEndNanoSeconds);
- - v6_bidirection_template.t[1].length = htons(sizeof(u_int64_t));
- - } else {
- - v6_bidirection_template.t[0].ie = htons(IPFIX_flowStartSysUpTime);
- - v6_bidirection_template.t[0].length = htons(sizeof(u_int32_t));
- - v6_bidirection_template.t[1].ie = htons(IPFIX_flowEndSysUpTime);
- - v6_bidirection_template.t[1].length = htons(sizeof(u_int32_t));
- - }
- + u_int8_t v6_flag = 0, icmp_flag = 0;
- + u_int16_t template_id = 0;
- + for (int i = 0; i < TMPLMAX; i++)
- + {
- + switch (i)
- + {
- + case TMPLV4:
- + v6_flag = 0;
- + icmp_flag = 0;
- + template_id = IPFIX_SOFTFLOWD_V4_TEMPLATE_ID;
- + break;
- + case TMPLICMPV4:
- + v6_flag = 0;
- + icmp_flag = 1;
- + template_id = IPFIX_SOFTFLOWD_ICMPV4_TEMPLATE_ID;
- + break;
- + case TMPLV6:
- + v6_flag = 1;
- + icmp_flag = 0;
- + template_id = IPFIX_SOFTFLOWD_V6_TEMPLATE_ID;
- + break;
- + case TMPLICMPV6:
- + v6_flag = 1;
- + icmp_flag = 1;
- + template_id = IPFIX_SOFTFLOWD_ICMPV6_TEMPLATE_ID;
- + break;
- + }
- + ipfix_init_template_unity (param, &template[i],
- + template_id, v6_flag,
- + icmp_flag, bi_flag, version);
- + }
- }
-
- +static void
- +nflow9_init_option (u_int16_t ifidx, struct OPTION *option)
- +{
- + u_int scope_index = 0, option_index = 0;
- + u_int16_t scope_len =
- + NFLOW9_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS *
- + sizeof (struct IPFIX_FIELD_SPECIFIER);
- + u_int16_t opt_len =
- + NFLOW9_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS *
- + sizeof (struct IPFIX_FIELD_SPECIFIER);
- +
- + bzero (&option_template, sizeof (option_template));
- + option_template.h.c.set_id = htons (NFLOW9_OPTION_TEMPLATE_SET_ID);
- + option_template.h.c.length =
- + htons (sizeof (option_template.h) + scope_len + opt_len);
- + option_template.h.u.n.template_id
- + = htons (IPFIX_SOFTFLOWD_OPTION_TEMPLATE_ID);
- + option_template.h.u.n.scope_length = htons (scope_len);
- + option_template.h.u.n.option_length = htons (opt_len);
- + ipfix_init_fields (option_template.s, &scope_index,
- + field_nf9scope,
- + NFLOW9_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS);
- + ipfix_init_fields (option_template.r, &option_index,
- + field_nf9option,
- + NFLOW9_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS);
- + bzero (&nf9opt_data, sizeof (nf9opt_data));
- + nf9opt_data.c.set_id = htons (IPFIX_SOFTFLOWD_OPTION_TEMPLATE_ID);
- + nf9opt_data.c.length = htons (sizeof (nf9opt_data));
- + nf9opt_data.scope_ifidx = htonl (ifidx);
- + nf9opt_data.samplingInterval =
- + htonl (option->sample > 1 ? option->sample : 1);
- + nf9opt_data.samplingAlgorithm = NFLOW9_SAMPLING_ALGORITHM_DETERMINISTIC;
- +}
-
- static void
- -ipfix_init_option(struct timeval *system_boot_time, struct OPTION *option) {
- - bzero(&option_template, sizeof(option_template));
- - option_template.h.c.set_id = htons(IPFIX_OPTION_TEMPLATE_SET_ID);
- - option_template.h.c.length = htons(sizeof(option_template));
- - option_template.h.r.template_id = htons(IPFIX_SOFTFLOWD_OPTION_TEMPLATE_ID);
- - option_template.h.r.count = htons(IPFIX_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS + IPFIX_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS);
- - option_template.h.scope_count = htons(IPFIX_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS);
- - option_template.s[0].ie = htons(IPFIX_meteringProcessId);
- - option_template.s[0].length = htons(sizeof(option_data.scope_pid));
- - option_template.r[0].ie = htons(IPFIX_systemInitTimeMilliseconds);
- - option_template.r[0].length = htons(sizeof(option_data.systemInitTimeMilliseconds));
- - option_template.r[1].ie = htons(PSAMP_selectorAlgorithm);
- - option_template.r[1].length = htons(sizeof(option_data.samplingAlgorithm));
- - option_template.r[2].ie = htons(PSAMP_samplingPacketInterval);
- - option_template.r[2].length = htons(sizeof(option_data.samplingInterval));
- - option_template.r[3].ie = htons(PSAMP_samplingPacketSpace);
- - option_template.r[3].length = htons(sizeof(option_data.samplingSpace));
- -
- - bzero(&option_data, sizeof(option_data));
- - option_data.c.set_id = htons(IPFIX_SOFTFLOWD_OPTION_TEMPLATE_ID);
- - option_data.c.length = htons(sizeof(option_data));
- - option_data.scope_pid = htonl((u_int32_t)option->meteringProcessId);
- +ipfix_init_option (struct timeval *system_boot_time, struct OPTION *option)
- +{
- + u_int scope_index = 0, option_index = 0;
- + bzero (&option_template, sizeof (option_template));
- + option_template.h.c.set_id = htons (IPFIX_OPTION_TEMPLATE_SET_ID);
- + option_template.h.c.length = htons (sizeof (option_template));
- + option_template.h.u.i.r.template_id =
- + htons (IPFIX_SOFTFLOWD_OPTION_TEMPLATE_ID);
- + option_template.h.u.i.r.count =
- + htons (IPFIX_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS +
- + IPFIX_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS);
- + option_template.h.u.i.scope_count =
- + htons (IPFIX_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS);
- +
- + ipfix_init_fields (option_template.s, &scope_index,
- + field_scope,
- + IPFIX_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS);
- + ipfix_init_fields (option_template.r, &option_index, field_option,
- + IPFIX_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS);
- +
- + bzero (&option_data, sizeof (option_data));
- + option_data.c.set_id = htons (IPFIX_SOFTFLOWD_OPTION_TEMPLATE_ID);
- + option_data.c.length = htons (sizeof (option_data));
- + option_data.scope_pid = htonl ((u_int32_t) option->meteringProcessId);
- #if defined(htobe64) || defined(HAVE_DECL_HTOBE64)
- - option_data.systemInitTimeMilliseconds = htobe64((u_int64_t)system_boot_time->tv_sec * 1000 + (u_int64_t)system_boot_time->tv_usec / 1000);
- + option_data.systemInitTimeMilliseconds =
- + htobe64 ((u_int64_t) system_boot_time->tv_sec * 1000 +
- + (u_int64_t) system_boot_time->tv_usec / 1000);
- #endif
- - option_data.samplingAlgorithm = htons(PSAMP_selectorAlgorithm_count);
- - option_data.samplingInterval = htons(1);
- - option_data.samplingSpace = htonl(option->sample > 0 ? option->sample - 1 : 0);
- + option_data.samplingAlgorithm = htons (PSAMP_selectorAlgorithm_count);
- + option_data.samplingInterval = htonl (1);
- + option_data.samplingSpace =
- + htonl (option->sample > 0 ? option->sample - 1 : 0);
- }
-
- static int
- -ipfix_flow_to_flowset(const struct FLOW *flow, u_char *packet, u_int len,
- - u_int16_t ifidx, const struct timeval *system_boot_time, u_int *len_used,
- - struct FLOWTRACKPARAMETERS *param)
- -{
- - union {
- - struct IPFIX_SOFTFLOWD_DATA_V4 d4;
- - struct IPFIX_SOFTFLOWD_DATA_V6 d6;
- - } d[2];
- - struct IPFIX_SOFTFLOWD_DATA_COMMON *dc[2];
- - union IPFIX_SOFTFLOWD_DATA_TIME *dt[2];
- - u_int freclen, ret_len, nflows;
- -
- - bzero(d, sizeof(d));
- - *len_used = nflows = ret_len = 0;
- - switch (flow->af) {
- - case AF_INET:
- - freclen = sizeof(struct IPFIX_SOFTFLOWD_DATA_V4);
- - if (!(param->time_format == 'm' || param->time_format == 'M' || param->time_format == 'n')) {
- - freclen -= (sizeof(u_int64_t) - sizeof(u_int32_t)) * 2;
- - }
- - memcpy(&d[0].d4.sourceIPv4Address, &flow->addr[0].v4, 4);
- - memcpy(&d[0].d4.destinationIPv4Address, &flow->addr[1].v4, 4);
- - memcpy(&d[1].d4.sourceIPv4Address, &flow->addr[1].v4, 4);
- - memcpy(&d[1].d4.destinationIPv4Address, &flow->addr[0].v4, 4);
- - dc[0] = &d[0].d4.c;
- - dc[1] = &d[1].d4.c;
- - dt[0] = &d[0].d4.t;
- - dt[1] = &d[1].d4.t;
- - dc[0]->ipVersion = dc[1]->ipVersion = 4;
- - break;
- - case AF_INET6:
- - freclen = sizeof(struct IPFIX_SOFTFLOWD_DATA_V6);
- - if (!(param->time_format == 'm' || param->time_format == 'M' || param->time_format == 'n')) {
- - freclen -= (sizeof(u_int64_t) - sizeof(u_int32_t)) * 2;
- - }
- - memcpy(&d[0].d6.sourceIPv6Address, &flow->addr[0].v6, 16);
- - memcpy(&d[0].d6.destinationIPv6Address, &flow->addr[1].v6, 16);
- - memcpy(&d[1].d6.sourceIPv6Address, &flow->addr[1].v6, 16);
- - memcpy(&d[1].d6.destinationIPv6Address, &flow->addr[0].v6, 16);
- - dc[0] = &d[0].d6.c;
- - dc[1] = &d[1].d6.c;
- - dt[0] = &d[0].d6.t;
- - dt[1] = &d[1].d6.t;
- - dc[0]->ipVersion = dc[1]->ipVersion = 6;
- - break;
- - default:
- - return (-1);
- - }
- -
- - if (param->time_format == 's') {
- - dt[0]->u32.start = dt[1]->u32.start =
- - htonl(flow->flow_start.tv_sec);
- - dt[0]->u32.end = dt[1]->u32.end =
- - htonl(flow->flow_last.tv_sec);
- - }
- +copy_data_time (union IPFIX_SOFTFLOWD_DATA_TIME *dt,
- + const struct FLOW *flow,
- + const struct timeval *system_boot_time,
- + struct FLOWTRACKPARAMETERS *param)
- +{
- + int length = (param->time_format == 'm' || param->time_format == 'M'
- + || param->time_format == 'n') ? 16 : 8;
- + if (dt == NULL)
- + return -1;
- +
- + if (param->time_format == 's')
- + {
- + dt->u32.start = htonl (flow->flow_start.tv_sec);
- + dt->u32.end = htonl (flow->flow_last.tv_sec);
- + }
- #if defined(htobe64) || defined(HAVE_DECL_HTOBE64)
- - else if (param->time_format == 'm') { /* milliseconds */
- - dt[0]->u64.start = dt[1]->u64.start =
- - htobe64((u_int64_t)flow->flow_start.tv_sec * 1000 + (u_int64_t)flow->flow_start.tv_usec / 1000);
- - dt[0]->u64.end = dt[1]->u64.end =
- - htobe64((u_int64_t)flow->flow_last.tv_sec * 1000 + (u_int64_t)flow->flow_last.tv_usec / 1000);
- - } else if (param->time_format == 'M') { /* microseconds */
- - dt[0]->u64.start = dt[1]->u64.start =
- - htobe64(((u_int64_t)flow->flow_start.tv_sec + JAN_1970) << 32 | (u_int32_t)(((u_int64_t)flow->flow_start.tv_usec << 32) / 1e6));
- - dt[0]->u64.end = dt[1]->u64.end =
- - htobe64(((u_int64_t)flow->flow_last.tv_sec + JAN_1970) << 32 | (u_int32_t)(((u_int64_t)flow->flow_last.tv_usec << 32) / 1e6));
- - } else if (param->time_format == 'n') { /* nanoseconds */
- - dt[0]->u64.start = dt[1]->u64.start =
- - htobe64(((u_int64_t)flow->flow_start.tv_sec + JAN_1970) << 32 | (u_int32_t)(((u_int64_t)flow->flow_start.tv_usec << 32) / 1e9));
- - dt[0]->u64.end = dt[1]->u64.end =
- - htobe64(((u_int64_t)flow->flow_last.tv_sec + JAN_1970) << 32 | (u_int32_t)(((u_int64_t)flow->flow_last.tv_usec << 32) / 1e9));
- - }
- + else if (param->time_format == 'm')
- + { /* milliseconds */
- + dt->u64.start =
- + htobe64 ((u_int64_t) flow->flow_start.tv_sec * 1000 +
- + (u_int64_t) flow->flow_start.tv_usec / 1000);
- + dt->u64.end =
- + htobe64 ((u_int64_t) flow->flow_last.tv_sec * 1000 +
- + (u_int64_t) flow->flow_last.tv_usec / 1000);
- + }
- + else if (param->time_format == 'M')
- + { /* microseconds */
- + dt->u64.start =
- + htobe64 (((u_int64_t) flow->flow_start.tv_sec +
- + JAN_1970) << 32 | (u_int32_t) (((u_int64_t) flow->
- + flow_start.
- + tv_usec << 32) /
- + 1e6));
- + dt->u64.end =
- + htobe64 (((u_int64_t) flow->flow_last.tv_sec +
- + JAN_1970) << 32 | (u_int32_t) (((u_int64_t) flow->
- + flow_last.
- + tv_usec << 32) /
- + 1e6));
- + }
- + else if (param->time_format == 'n')
- + { /* nanoseconds */
- + dt->u64.start =
- + htobe64 (((u_int64_t) flow->flow_start.tv_sec +
- + JAN_1970) << 32 | (u_int32_t) (((u_int64_t) flow->
- + flow_start.
- + tv_usec << 32) /
- + 1e9));
- + dt->u64.end =
- + htobe64 (((u_int64_t) flow->flow_last.tv_sec +
- + JAN_1970) << 32 | (u_int32_t) (((u_int64_t) flow->
- + flow_last.
- + tv_usec << 32) /
- + 1e9));
- + }
- #endif
- - else {
- - dt[0]->u32.start = dt[1]->u32.start =
- - htonl(timeval_sub_ms(&flow->flow_start, system_boot_time));
- - dt[0]->u32.end = dt[1]->u32.end =
- - htonl(timeval_sub_ms(&flow->flow_last, system_boot_time));
- - }
- - dc[0]->octetDeltaCount = htonl(flow->octets[0]);
- - dc[1]->octetDeltaCount = htonl(flow->octets[1]);
- - dc[0]->packetDeltaCount = htonl(flow->packets[0]);
- - dc[1]->packetDeltaCount = htonl(flow->packets[1]);
- - dc[0]->ingressInterface = dc[0]->egressInterface = htonl(ifidx);
- - dc[1]->ingressInterface = dc[1]->egressInterface = htonl(ifidx);
- - dc[0]->sourceTransportPort = dc[1]->destinationTransportPort = flow->port[0];
- - dc[1]->sourceTransportPort = dc[0]->destinationTransportPort = flow->port[1];
- - dc[0]->protocolIdentifier = dc[1]->protocolIdentifier = flow->protocol;
- - dc[0]->tcpControlBits = flow->tcp_flags[0];
- - dc[1]->tcpControlBits = flow->tcp_flags[1];
- - dc[0]->ipClassOfService = flow->tos[0];
- - dc[1]->ipClassOfService = flow->tos[1];
- - if (flow->protocol == IPPROTO_ICMP || flow->protocol == IPPROTO_ICMPV6) {
- - dc[0]->icmpTypeCode = dc[0]->destinationTransportPort;
- - dc[1]->icmpTypeCode = dc[1]->destinationTransportPort;
- - }
- - dc[0]->vlanId = dc[1]->vlanId = htons(flow->vlanid);
- -
- - if (flow->octets[0] > 0) {
- - if (ret_len + freclen > len)
- - return (-1);
- - memcpy(packet + ret_len, &d[0], freclen);
- - ret_len += freclen;
- - nflows++;
- - }
- - if (flow->octets[1] > 0) {
- - if (ret_len + freclen > len)
- - return (-1);
- - memcpy(packet + ret_len, &d[1], freclen);
- - ret_len += freclen;
- - nflows++;
- - }
- + else
- + {
- + dt->u32.start =
- + htonl (timeval_sub_ms (&flow->flow_start, system_boot_time));
- + dt->u32.end =
- + htonl (timeval_sub_ms (&flow->flow_last, system_boot_time));
- + }
- + return length;
- +}
-
- - *len_used = ret_len;
- - return (nflows);
- +static u_int
- +ipfix_flow_to_template_index (const struct FLOW *flow)
- +{
- + u_int index = 0;
- + if (flow->af == AF_INET)
- + {
- + index = (flow->protocol == IPPROTO_ICMP) ? TMPLICMPV4 : TMPLV4;
- + }
- + else if (flow->af == AF_INET6)
- + {
- + index = (flow->protocol == IPPROTO_ICMPV6) ? TMPLICMPV6 : TMPLV6;
- + }
- + return index;
- }
-
- static int
- -ipfix_flow_to_bidirection_flowset(const struct FLOW *flow, u_char *packet,
- - u_int len, u_int16_t ifidx,
- - const struct timeval *system_boot_time,
- - u_int *len_used,
- - struct FLOWTRACKPARAMETERS *param)
- -{
- - union {
- - struct IPFIX_SOFTFLOWD_BIDIRECTION_DATA_V4 d4;
- - struct IPFIX_SOFTFLOWD_BIDIRECTION_DATA_V6 d6;
- - } d;
- - struct IPFIX_SOFTFLOWD_DATA_COMMON *dc;
- - struct IPFIX_SOFTFLOWD_DATA_BIDIRECTION *db;
- - union IPFIX_SOFTFLOWD_DATA_TIME *dt;
- - u_int freclen, ret_len, nflows;
- -
- - bzero(&d, sizeof(d));
- - *len_used = nflows = ret_len = 0;
- - switch (flow->af) {
- - case AF_INET:
- - freclen = sizeof(struct IPFIX_SOFTFLOWD_BIDIRECTION_DATA_V4);
- - if (!(param->time_format == 'm' || param->time_format == 'M' || param->time_format == 'n')) {
- - freclen -= (sizeof(u_int64_t) - sizeof(u_int32_t)) * 2;
- - }
- - memcpy(&d.d4.sourceIPv4Address, &flow->addr[0].v4, 4);
- - memcpy(&d.d4.destinationIPv4Address, &flow->addr[1].v4, 4);
- - dc = &d.d4.c;
- - db = &d.d4.b;
- - dt = &d.d4.t;
- - dc->ipVersion = 4;
- - break;
- - case AF_INET6:
- - freclen = sizeof(struct IPFIX_SOFTFLOWD_BIDIRECTION_DATA_V6);
- - if (!(param->time_format == 'm' || param->time_format == 'M' || param->time_format == 'n')) {
- - freclen -= (sizeof(u_int64_t) - sizeof(u_int32_t)) * 2;
- - }
- - memcpy(&d.d6.sourceIPv6Address, &flow->addr[0].v6, 16);
- - memcpy(&d.d6.destinationIPv6Address, &flow->addr[1].v6, 16);
- - dc = &d.d6.c;
- - db = &d.d6.b;
- - dt = &d.d6.t;
- - dc->ipVersion = 6;
- - break;
- - default:
- - return (-1);
- - }
- -
- - if (param->time_format == 's') {
- - dt->u32.start = htonl(flow->flow_start.tv_sec);
- - dt->u32.end = htonl(flow->flow_last.tv_sec);
- - }
- -#if defined(htobe64) || defined(HAVE_DECL_HTOBE64)
- - else if (param->time_format == 'm') { /* milliseconds */
- - dt->u64.start =
- - htobe64((u_int64_t)flow->flow_start.tv_sec * 1000 + (u_int64_t)flow->flow_start.tv_usec / 1000);
- - dt->u64.end =
- - htobe64((u_int64_t)flow->flow_last.tv_sec * 1000 + (u_int64_t)flow->flow_last.tv_usec / 1000);
- - } else if (param->time_format == 'M') { /* microseconds */
- - dt->u64.start =
- - htobe64(((u_int64_t)flow->flow_start.tv_sec + JAN_1970) << 32 | (u_int32_t)(((u_int64_t)flow->flow_start.tv_usec << 32) / 1e6));
- - dt->u64.end =
- - htobe64(((u_int64_t)flow->flow_last.tv_sec + JAN_1970) << 32 | (u_int32_t)(((u_int64_t)flow->flow_last.tv_usec << 32) / 1e6));
- - } else if (param->time_format == 'n') { /* nanoseconds */
- - dt->u64.start =
- - htobe64(((u_int64_t)flow->flow_start.tv_sec + JAN_1970) << 32 | (u_int32_t)(((u_int64_t)flow->flow_start.tv_usec << 32) / 1e9));
- - dt->u64.end =
- - htobe64(((u_int64_t)flow->flow_last.tv_sec + JAN_1970) << 32 | (u_int32_t)(((u_int64_t)flow->flow_last.tv_usec << 32) / 1e9));
- - }
- -#endif
- - else {
- - dt->u32.start =
- - htonl(timeval_sub_ms(&flow->flow_start, system_boot_time));
- - dt->u32.end =
- - htonl(timeval_sub_ms(&flow->flow_last, system_boot_time));
- - }
- - dc->octetDeltaCount = htonl(flow->octets[0]);
- - db->octetDeltaCount = htonl(flow->octets[1]);
- - dc->packetDeltaCount = htonl(flow->packets[0]);
- - db->packetDeltaCount = htonl(flow->packets[1]);
- - dc->ingressInterface = dc->egressInterface = htonl(ifidx);
- - dc->sourceTransportPort = flow->port[0];
- - dc->destinationTransportPort = flow->port[1];
- - dc->protocolIdentifier = flow->protocol;
- - dc->tcpControlBits = flow->tcp_flags[0];
- - db->tcpControlBits = flow->tcp_flags[1];
- - dc->ipClassOfService = flow->tos[0];
- - db->ipClassOfService = flow->tos[1];
- - if (flow->protocol == IPPROTO_ICMP || flow->protocol == IPPROTO_ICMPV6) {
- - dc->icmpTypeCode = flow->port[1];
- - db->icmpTypeCode = flow->port[0];
- - }
- - dc->vlanId = htons(flow->vlanid);
- -
- - if (flow->octets[0] > 0 || flow->octets[1] > 0) {
- - if (ret_len + freclen > len)
- - return (-1);
- - memcpy(packet + ret_len, &d, freclen);
- - ret_len += freclen;
- - nflows++;
- - }
- +ipfix_flow_to_flowset (const struct FLOW *flow, u_char * packet,
- + u_int len, u_int16_t ifidx,
- + const struct timeval *system_boot_time,
- + u_int * len_used,
- + struct FLOWTRACKPARAMETERS *param, u_int8_t bi_flag)
- +{
- + struct IPFIX_SOFTFLOWD_DATA_V4ADDR *d4[2] = { NULL, NULL };
- + struct IPFIX_SOFTFLOWD_DATA_V6ADDR *d6[2] = { NULL, NULL };
- + union IPFIX_SOFTFLOWD_DATA_TIME *dt[2] = { NULL, NULL };
- + struct IPFIX_SOFTFLOWD_DATA_COMMON *dc[2] = { NULL, NULL };
- + struct IPFIX_SOFTFLOWD_DATA_TRANSPORT *dtr[2] = { NULL, NULL };
- + struct IPFIX_SOFTFLOWD_DATA_ICMP *di[2] = { NULL, NULL };
- + struct IPFIX_SOFTFLOWD_DATA_VLAN *dv[2] = { NULL, NULL };
- + struct IPFIX_SOFTFLOWD_DATA_ETHER *de[2] = { NULL, NULL };
- + struct IPFIX_SOFTFLOWD_DATA_BICOMMON *dbc = NULL;
- + struct IPFIX_SOFTFLOWD_DATA_BITRANSPORT *dbtr = NULL;
- + struct IPFIX_SOFTFLOWD_DATA_BIICMP *dbi = NULL;
- +
- + u_int freclen = 0, nflows = 0, offset = 0;
- + u_int frecnum = bi_flag ? 1 : 2;
- + u_int tmplindex = ipfix_flow_to_template_index (flow);
- + freclen = template[tmplindex].data_len;
- + if (len < freclen * frecnum)
- + return (-1);
- +
- + for (int i = 0; i < frecnum; i++)
- + {
- + if (bi_flag == 0 && flow->octets[i] == 0)
- + continue;
- + nflows++;
- + if (flow->af == AF_INET)
- + {
- + d4[i] =
- + (struct IPFIX_SOFTFLOWD_DATA_V4ADDR *) &packet[offset];
- + memcpy (&d4[i]->sourceIPv4Address, &flow->addr[i].v4, 4);
- + memcpy (&d4[i]->destinationIPv4Address,
- + &flow->addr[i ^ 1].v4, 4);
- + offset += sizeof (struct IPFIX_SOFTFLOWD_DATA_V4ADDR);
- + }
- + else if (flow->af == AF_INET6)
- + {
- + d6[i] =
- + (struct IPFIX_SOFTFLOWD_DATA_V6ADDR *) &packet[offset];
- + memcpy (&d6[i]->sourceIPv6Address, &flow->addr[i].v6, 16);
- + memcpy (&d6[i]->destinationIPv6Address,
- + &flow->addr[i ^ 1].v6, 16);
- + offset += sizeof (struct IPFIX_SOFTFLOWD_DATA_V6ADDR);
- + }
- +
- + dt[i] = (union IPFIX_SOFTFLOWD_DATA_TIME *) &packet[offset];
- + offset += copy_data_time (dt[i], flow, system_boot_time, param);
- +
- + dc[i] = (struct IPFIX_SOFTFLOWD_DATA_COMMON *) &packet[offset];
- + dc[i]->octetDeltaCount = htonl (flow->octets[i]);
- + dc[i]->packetDeltaCount = htonl (flow->packets[i]);
- + dc[i]->ingressInterface = dc[i]->egressInterface = htonl (ifidx);
- + offset += sizeof (struct IPFIX_SOFTFLOWD_DATA_COMMON);
- +
- + if (flow->protocol != IPPROTO_ICMP
- + && flow->protocol != IPPROTO_ICMPV6)
- + {
- + dtr[i] =
- + (struct IPFIX_SOFTFLOWD_DATA_TRANSPORT *) &packet[offset];
- + dtr[i]->sourceTransportPort = flow->port[i];
- + dtr[i]->destinationTransportPort = flow->port[i ^ 1];
- + dtr[i]->protocolIdentifier = flow->protocol;
- + dtr[i]->tcpControlBits = flow->tcp_flags[i];
- + dtr[i]->ipClassOfService = flow->tos[i];
- + dtr[i]->ipVersion = (flow->af == AF_INET) ? 4 : 6;
- + offset += sizeof (struct IPFIX_SOFTFLOWD_DATA_TRANSPORT);
- + }
- + else
- + {
- + di[i] = (struct IPFIX_SOFTFLOWD_DATA_ICMP *) &packet[offset];
- + di[i]->icmpTypeCode = flow->port[i ^ 1];
- + di[i]->ipClassOfService = flow->tos[i];
- + di[i]->ipVersion = (flow->af == AF_INET) ? 4 : 6;
- + offset += sizeof (struct IPFIX_SOFTFLOWD_DATA_ICMP);
- + }
- + if (param->track_level >= TRACK_FULL_VLAN)
- + {
- + dv[i] = (struct IPFIX_SOFTFLOWD_DATA_VLAN *) &packet[offset];
- + dv[i]->vlanId = flow->vlanid[i];
- + dv[i]->postVlanId = flow->vlanid[i ^ 1];
- + offset += sizeof (struct IPFIX_SOFTFLOWD_DATA_VLAN);
- + }
- + if (param->track_level >= TRACK_FULL_VLAN_ETHER)
- + {
- + de[i] = (struct IPFIX_SOFTFLOWD_DATA_ETHER *) &packet[offset];
- + memcpy (&de[i]->sourceMacAddress, &flow->ethermac[i], 6);
- + memcpy (&de[i]->destinationMacAddress,
- + &flow->ethermac[i ^ 1], 6);
- + offset += sizeof (struct IPFIX_SOFTFLOWD_DATA_ETHER);
- + }
- + if (bi_flag && i == 0)
- + {
- + dbc =
- + (struct IPFIX_SOFTFLOWD_DATA_BICOMMON *) &packet[offset];
- + dbc->octetDeltaCount = htonl (flow->octets[1]);
- + dbc->packetDeltaCount = htonl (flow->packets[1]);
- + dbc->ipClassOfService = flow->tos[1];
- + offset += sizeof (struct IPFIX_SOFTFLOWD_DATA_BICOMMON);
- + if (flow->protocol != IPPROTO_ICMP
- + && flow->protocol != IPPROTO_ICMPV6)
- + {
- + dbtr =
- + (struct IPFIX_SOFTFLOWD_DATA_BITRANSPORT *)
- + &packet[offset];
- + dbtr->tcpControlBits = flow->tcp_flags[1];
- + offset +=
- + sizeof (struct IPFIX_SOFTFLOWD_DATA_BITRANSPORT);
- + }
- + else
- + {
- + dbi =
- + (struct IPFIX_SOFTFLOWD_DATA_BIICMP *)
- + &packet[offset];
- + dbi->icmpTypeCode = flow->port[1];
- + offset += sizeof (struct IPFIX_SOFTFLOWD_DATA_BIICMP);
- + }
- + }
- + }
- + *len_used = offset;
- + return (nflows);
- +}
-
- - *len_used = ret_len;
- - return (nflows);
- +static int
- +valuate_icmp (struct FLOW *flow)
- +{
- + if (flow == NULL)
- + return -1;
- + if (flow->af == AF_INET)
- + if (flow->protocol == IPPROTO_ICMP)
- + return 1;
- + else
- + return 0;
- + else if (flow->af == AF_INET6)
- + if (flow->protocol == IPPROTO_ICMPV6)
- + return 1;
- + else
- + return 0;
- + return -1;
- }
-
- +void
- +ipfix_resend_template (void)
- +{
- + if (ipfix_pkts_until_template > 0)
- + ipfix_pkts_until_template = 0;
- +}
- +
- +void
- +memcpy_template (u_char * packet, u_int * offset,
- + struct IPFIX_SOFTFLOWD_TEMPLATE *template, u_int8_t bi_flag)
- +{
- + int size = ntohs (template->h.c.length) -
- + template->bi_count * sizeof (struct IPFIX_VENDOR_FIELD_SPECIFIER);
- + memcpy (packet + *offset, template, size);
- + *offset += size;
- + if (bi_flag)
- + {
- + size =
- + template->bi_count *
- + sizeof (struct IPFIX_VENDOR_FIELD_SPECIFIER);
- + memcpy (packet + *offset, template->v, size);
- + *offset += size;
- + }
- +}
-
- /*
- - * Given an array of expired flows, send netflow v9 report packets
- + * Given an array of expired flows, send ipfix report packets
- * Returns number of packets sent or -1 on error
- */
- -int
- -send_ipfix(struct FLOW **flows, int num_flows, int nfsock,
- - u_int16_t ifidx, struct FLOWTRACKPARAMETERS *param,
- - int verbose_flag)
- -{
- - struct IPFIX_HEADER *ipfix;
- - struct IPFIX_SET_HEADER *dh;
- - struct timeval now;
- - u_int offset, last_af, i, j, num_packets, inc, last_valid;
- - socklen_t errsz;
- - int err, r;
- - u_int records;
- - u_char packet[IPFIX_SOFTFLOWD_MAX_PACKET_SIZE];
- - struct timeval *system_boot_time = ¶m->system_boot_time;
- - u_int64_t *flows_exported = ¶m->flows_exported;
- - u_int64_t *records_sent = ¶m->records_sent;
- - struct OPTION *option = ¶m->option;
- -
- - gettimeofday(&now, NULL);
- -
- - if (ipfix_pkts_until_template == -1) {
- - ipfix_init_template(param);
- - ipfix_pkts_until_template = 0;
- - if (option != NULL){
- - ipfix_init_option(system_boot_time, option);
- - }
- - }
- -
- - last_valid = num_packets = 0;
- - for (j = 0; j < num_flows;) {
- - bzero(packet, sizeof(packet));
- - ipfix = (struct IPFIX_HEADER *)packet;
- -
- - ipfix->version = htons(10);
- - ipfix->length = 0; /* Filled as we go, htons at end */
- - ipfix->export_time = htonl(time(NULL));
- - ipfix->od_id = 0;
- - offset = sizeof(*ipfix);
- -
- - /* Refresh template headers if we need to */
- - if (ipfix_pkts_until_template <= 0) {
- - memcpy(packet + offset, &v4_template,
- - sizeof(v4_template));
- - offset += sizeof(v4_template);
- - memcpy(packet + offset, &v6_template,
- - sizeof(v6_template));
- - offset += sizeof(v6_template);
- - if (option != NULL){
- - memcpy(packet + offset, &option_template,
- - sizeof(option_template));
- - offset += sizeof(option_template);
- - memcpy(packet + offset, &option_data,
- - sizeof(option_data));
- - offset += sizeof(option_data);
- - }
- -
- - ipfix_pkts_until_template = IPFIX_DEFAULT_TEMPLATE_INTERVAL;
- - }
- -
- - dh = NULL;
- - last_af = 0;
- - records = 0;
- - for (i = 0; i + j < num_flows; i++) {
- - if (dh == NULL || flows[i + j]->af != last_af) {
- - if (dh != NULL) {
- - if (offset % 4 != 0) {
- - /* Pad to multiple of 4 */
- - dh->length += 4 - (offset % 4);
- - offset += 4 - (offset % 4);
- - }
- - /* Finalise last header */
- - dh->length = htons(dh->length);
- - }
- - if (offset + sizeof(*dh) > sizeof(packet)) {
- - /* Mark header is finished */
- - dh = NULL;
- - break;
- - }
- - dh = (struct IPFIX_SET_HEADER *)
- - (packet + offset);
- - dh->set_id =
- - (flows[i + j]->af == AF_INET) ?
- - v4_template.h.r.template_id :
- - v6_template.h.r.template_id;
- - last_af = flows[i + j]->af;
- - last_valid = offset;
- - dh->length = sizeof(*dh); /* Filled as we go */
- - offset += sizeof(*dh);
- - }
- -
- - r = ipfix_flow_to_flowset(flows[i + j], packet + offset,
- - sizeof(packet) - offset, ifidx, system_boot_time, &inc, param);
- - if (r <= 0) {
- - /* yank off data header, if we had to go back */
- - if (last_valid)
- - offset = last_valid;
- - break;
- - }
- - records += (u_int)r;
- - offset += inc;
- - dh->length += inc;
- - last_valid = 0; /* Don't clobber this header now */
- - if (verbose_flag) {
- - logit(LOG_DEBUG, "Flow %d/%d: "
- - "r %d offset %d ie %04x len %d(0x%04x)",
- - r, i, j, offset,
- - dh->set_id, dh->length,
- - dh->length);
- - }
- - }
- - /* Don't finish header if it has already been done */
- - if (dh != NULL) {
- - if (offset % 4 != 0) {
- - /* Pad to multiple of 4 */
- - dh->length += 4 - (offset % 4);
- - offset += 4 - (offset % 4);
- - }
- - /* Finalise last header */
- - dh->length = htons(dh->length);
- - }
- - ipfix->length = htons(offset);
- - *records_sent += records;
- - ipfix->sequence = htonl((u_int32_t)(*records_sent & 0x00000000ffffffff));
- -
- - if (verbose_flag)
- - logit(LOG_DEBUG, "Sending flow packet len = %d", offset);
- - errsz = sizeof(err);
- - /* Clear ICMP errors */
- - getsockopt(nfsock, SOL_SOCKET, SO_ERROR, &err, &errsz);
- - if (send(nfsock, packet, (size_t)offset, 0) == -1)
- - return (-1);
- - num_packets++;
- - ipfix_pkts_until_template--;
- +static int
- +send_ipfix_common (struct FLOW **flows, int num_flows,
- + int nfsock, u_int16_t ifidx,
- + struct FLOWTRACKPARAMETERS *param,
- + int verbose_flag, u_int8_t bi_flag, u_int16_t version)
- +{
- + struct IPFIX_HEADER *ipfix;
- + struct NFLOW9_HEADER *nf9;
- + struct IPFIX_SET_HEADER *dh;
- + struct timeval now;
- + u_int offset, last_af, i, j, num_packets, inc, last_valid;
- + int8_t icmp_flag, last_icmp_flag;
- + socklen_t errsz;
- + int err, r;
- + u_int records;
- + u_char packet[IPFIX_SOFTFLOWD_MAX_PACKET_SIZE];
- + struct timeval *system_boot_time = ¶m->system_boot_time;
- + u_int64_t *flows_exported = ¶m->flows_exported;
- + u_int64_t *records_sent = ¶m->records_sent;
- + struct OPTION *option = ¶m->option;
- + u_int tmplindex = 0;
- +
- + gettimeofday (&now, NULL);
- +
- + if (ipfix_pkts_until_template == -1)
- + {
- + ipfix_init_template (param, bi_flag, version);
- + ipfix_pkts_until_template = 0;
- + if (option != NULL)
- + {
- + if (version == 10)
- + {
- + ipfix_init_option (system_boot_time, option);
- + }
- + else
- + {
- + nflow9_init_option (ifidx, option);
- + }
- + }
- + }
- +
- + last_valid = num_packets = 0;
- + for (j = 0; j < num_flows;)
- + {
- + bzero (packet, sizeof (packet));
- + if (version == 10)
- + {
- + ipfix = (struct IPFIX_HEADER *) packet;
- + ipfix->version = htons (version);
- + ipfix->length = 0; /* Filled as we go, htons at end */
- + ipfix->export_time = htonl (time (NULL));
- + ipfix->od_id = 0;
- + offset = sizeof (*ipfix);
- + }
- + else if (version == 9)
- + {
- + nf9 = (struct NFLOW9_HEADER *) packet;
- + nf9->version = htons (version);
- + nf9->flows = 0; /* Filled as we go, htons at end */
- + nf9->uptime_ms =
- + htonl (timeval_sub_ms (&now, system_boot_time));
- +
- + nf9->export_time = htonl (time (NULL));
- + nf9->od_id = 0;
- + offset = sizeof (*nf9);
- + }
- +
- + /* Refresh template headers if we need to */
- + if (ipfix_pkts_until_template <= 0)
- + {
- + for (int i = 0; i < TMPLMAX; i++)
- + {
- + memcpy_template (packet, &offset,
- + &template[i], bi_flag);
- + }
- + if (option != NULL)
- + {
- + u_int16_t opt_tmpl_len =
- + ntohs (option_template.h.c.length);
- + memcpy (packet + offset, &option_template,
- + opt_tmpl_len);
- + offset += opt_tmpl_len;
- + if (version == 10)
- + {
- + memcpy (packet + offset, &option_data,
- + sizeof (option_data));
- + offset += sizeof (option_data);
- + }
- + else if (version == 9)
- + {
- + memcpy (packet + offset, &nf9opt_data,
- + sizeof (nf9opt_data));
- + offset += sizeof (nf9opt_data);
- + }
- + }
- +
- + ipfix_pkts_until_template = IPFIX_DEFAULT_TEMPLATE_INTERVAL;
- + }
- +
- + dh = NULL;
- + last_af = 0;
- + last_icmp_flag = -1;
- + records = 0;
- + for (i = 0; i + j < num_flows; i++)
- + {
- + icmp_flag = valuate_icmp (flows[i + j]);
- + if (dh == NULL || flows[i + j]->af != last_af ||
- + icmp_flag != last_icmp_flag)
- + {
- + if (dh != NULL)
- + {
- + if (offset % 4 != 0)
- + {
- + /* Pad to multiple of 4 */
- + dh->length += 4 - (offset % 4);
- + offset += 4 - (offset % 4);
- + }
- + /* Finalise last header */
- + dh->length = htons (dh->length);
- + }
- + if (offset + sizeof (*dh) > sizeof (packet))
- + {
- + /* Mark header is finished */
- + dh = NULL;
- + break;
- + }
- + dh = (struct IPFIX_SET_HEADER *) (packet + offset);
- + tmplindex = ipfix_flow_to_template_index (flows[i + j]);
- + dh->set_id = template[tmplindex].h.r.template_id;
- + last_af = flows[i + j]->af;
- + last_icmp_flag = icmp_flag;
- + last_valid = offset;
- + dh->length = sizeof (*dh); /* Filled as we go */
- + offset += sizeof (*dh);
- + }
- + r = ipfix_flow_to_flowset (flows[i + j],
- + packet + offset,
- + sizeof (packet) - offset,
- + ifidx, system_boot_time,
- + &inc, param, bi_flag);
- + if (r <= 0)
- + {
- + /* yank off data header, if we had to go back */
- + if (last_valid)
- + offset = last_valid;
- + break;
- + }
- + records += (u_int) r;
- + offset += inc;
- + dh->length += inc;
- + last_valid = 0; /* Don't clobber this header now */
- + if (verbose_flag)
- + {
- + logit (LOG_DEBUG, "Flow %d/%d: "
- + "r %d offset %d ie %04x len %d(0x%04x)",
- + r, i, j, offset,
- + dh->set_id, dh->length, dh->length);
- + }
- + }
- + /* Don't finish header if it has already been done */
- + if (dh != NULL)
- + {
- + if (offset % 4 != 0)
- + {
- + /* Pad to multiple of 4 */
- + dh->length += 4 - (offset % 4);
- + offset += 4 - (offset % 4);
- + }
- + /* Finalise last header */
- + dh->length = htons (dh->length);
- + }
- + ipfix->length = htons (offset);
- + *records_sent += records;
- + ipfix->sequence =
- + htonl ((u_int32_t) (*records_sent & 0x00000000ffffffff));
- +
- + if (verbose_flag)
- + logit (LOG_DEBUG, "Sending flow packet len = %d", offset);
- + errsz = sizeof (err);
- + /* Clear ICMP errors */
- + getsockopt (nfsock, SOL_SOCKET, SO_ERROR, &err, &errsz);
- + if (send (nfsock, packet, (size_t) offset, 0) == -1)
- + return (-1);
- + num_packets++;
- + ipfix_pkts_until_template--;
-
- - j += i;
- - }
- + j += i;
- + }
-
- - *flows_exported += j;
- - return (num_packets);
- + *flows_exported += j;
- + return (num_packets);
- }
-
- -void
- -ipfix_resend_template(void)
- +int
- +send_nflow9 (struct FLOW **flows, int num_flows, int nfsock,
- + u_int16_t ifidx, struct FLOWTRACKPARAMETERS *param,
- + int verbose_flag)
- {
- - if (ipfix_pkts_until_template > 0)
- - ipfix_pkts_until_template = 0;
- + return send_ipfix_common (flows, num_flows, nfsock, ifidx,
- + param, verbose_flag, 0, 9);
- }
-
- -/*
- - * Given an array of expired flows, send netflow v9 report packets
- - * Returns number of packets sent or -1 on error
- - */
- int
- -send_ipfix_bidirection(struct FLOW **flows, int num_flows, int nfsock,
- - u_int16_t ifidx, struct FLOWTRACKPARAMETERS *param,
- - int verbose_flag)
- -{
- - struct IPFIX_HEADER *ipfix;
- - struct IPFIX_SET_HEADER *dh;
- - struct timeval now;
- - u_int offset, last_af, i, j, num_packets, inc, last_valid;
- - socklen_t errsz;
- - int err, r;
- - u_int records;
- - u_char packet[IPFIX_SOFTFLOWD_MAX_PACKET_SIZE];
- - struct timeval *system_boot_time = ¶m->system_boot_time;
- - u_int64_t *flows_exported = ¶m->flows_exported;
- - u_int64_t *records_sent = ¶m->records_sent;
- - struct OPTION *option = ¶m->option;
- -
- - gettimeofday(&now, NULL);
- -
- - if (ipfix_pkts_until_template == -1) {
- - ipfix_init_template_bidirection(param);
- - ipfix_pkts_until_template = 0;
- - if (option != NULL){
- - ipfix_init_option(system_boot_time, option);
- - }
- - }
- -
- - last_valid = num_packets = 0;
- - for (j = 0; j < num_flows;) {
- - bzero(packet, sizeof(packet));
- - ipfix = (struct IPFIX_HEADER *)packet;
- -
- - ipfix->version = htons(10);
- - ipfix->length = 0; /* Filled as we go, htons at end */
- - ipfix->export_time = htonl(time(NULL));
- - ipfix->od_id = 0;
- - offset = sizeof(*ipfix);
- -
- - /* Refresh template headers if we need to */
- - if (ipfix_pkts_until_template <= 0) {
- - memcpy(packet + offset, &v4_bidirection_template,
- - sizeof(v4_bidirection_template));
- - offset += sizeof(v4_bidirection_template);
- - memcpy(packet + offset, &v6_bidirection_template,
- - sizeof(v6_bidirection_template));
- - offset += sizeof(v6_bidirection_template);
- - if (option != NULL){
- - memcpy(packet + offset, &option_template,
- - sizeof(option_template));
- - offset += sizeof(option_template);
- - memcpy(packet + offset, &option_data,
- - sizeof(option_data));
- - offset += sizeof(option_data);
- - }
- -
- - ipfix_pkts_until_template = IPFIX_DEFAULT_TEMPLATE_INTERVAL;
- - }
- -
- - dh = NULL;
- - last_af = 0;
- - records = 0;
- - for (i = 0; i + j < num_flows; i++) {
- - if (dh == NULL || flows[i + j]->af != last_af) {
- - if (dh != NULL) {
- - if (offset % 4 != 0) {
- - /* Pad to multiple of 4 */
- - dh->length += 4 - (offset % 4);
- - offset += 4 - (offset % 4);
- - }
- - /* Finalise last header */
- - dh->length = htons(dh->length);
- - }
- - if (offset + sizeof(*dh) > sizeof(packet)) {
- - /* Mark header is finished */
- - dh = NULL;
- - break;
- - }
- - dh = (struct IPFIX_SET_HEADER *)
- - (packet + offset);
- - dh->set_id =
- - (flows[i + j]->af == AF_INET) ?
- - v4_bidirection_template.h.r.template_id :
- - v6_bidirection_template.h.r.template_id;
- - last_af = flows[i + j]->af;
- - last_valid = offset;
- - dh->length = sizeof(*dh); /* Filled as we go */
- - offset += sizeof(*dh);
- - }
- -
- - r = ipfix_flow_to_bidirection_flowset(flows[i + j],
- - packet + offset,
- - sizeof(packet) - offset,
- - ifidx,
- - system_boot_time,
- - &inc, param);
- - if (r <= 0) {
- - /* yank off data header, if we had to go back */
- - if (last_valid)
- - offset = last_valid;
- - break;
- - }
- - records += (u_int)r;
- - offset += inc;
- - dh->length += inc;
- - last_valid = 0; /* Don't clobber this header now */
- - if (verbose_flag) {
- - logit(LOG_DEBUG, "Flow %d/%d: "
- - "r %d offset %d ie %04x len %d(0x%04x)",
- - r, i, j, offset,
- - dh->set_id, dh->length,
- - dh->length);
- - }
- - }
- - /* Don't finish header if it has already been done */
- - if (dh != NULL) {
- - if (offset % 4 != 0) {
- - /* Pad to multiple of 4 */
- - dh->length += 4 - (offset % 4);
- - offset += 4 - (offset % 4);
- - }
- - /* Finalise last header */
- - dh->length = htons(dh->length);
- - }
- - ipfix->length = htons(offset);
- - *records_sent += records;
- - ipfix->sequence = htonl((u_int32_t)(*records_sent & 0x00000000ffffffff));
- -
- - if (verbose_flag)
- - logit(LOG_DEBUG, "Sending flow packet len = %d", offset);
- - errsz = sizeof(err);
- - /* Clear ICMP errors */
- - getsockopt(nfsock, SOL_SOCKET, SO_ERROR, &err, &errsz);
- - if (send(nfsock, packet, (size_t)offset, 0) == -1)
- - return (-1);
- - num_packets++;
- - ipfix_pkts_until_template--;
- -
- - j += i;
- - }
- +send_ipfix (struct FLOW **flows, int num_flows, int nfsock,
- + u_int16_t ifidx, struct FLOWTRACKPARAMETERS *param,
- + int verbose_flag)
- +{
- + return send_ipfix_common (flows, num_flows, nfsock, ifidx,
- + param, verbose_flag, 0, 10);
- +}
-
- - *flows_exported += j;
- - return (num_packets);
- +int
- +send_ipfix_bi (struct FLOW **flows, int num_flows, int nfsock,
- + u_int16_t ifidx,
- + struct FLOWTRACKPARAMETERS *param, int verbose_flag)
- +{
- + return send_ipfix_common (flows, num_flows, nfsock, ifidx,
- + param, verbose_flag, 1, 10);
- }
- --- a/softflowd.c
- +++ b/softflowd.c
- @@ -110,8 +110,9 @@
- static const struct NETFLOW_SENDER nf[] = {
- { 5, send_netflow_v5, NULL, 0 },
- { 1, send_netflow_v1, NULL, 0 },
- - { 9, send_netflow_v9, NULL, 1 },
- - { 10, send_ipfix, send_ipfix_bidirection, 1 },
- + //{ 9, send_netflow_v9, NULL, 1 },
- + { 9, send_nflow9, NULL, 1 },
- + { 10, send_ipfix, send_ipfix_bi, 1 },
- { -1, NULL, NULL, 0 },
- };
-
- @@ -147,6 +148,12 @@
- if (a->vlanid != b->vlanid)
- return (a->vlanid > b->vlanid ? 1 : -1);
-
- + if ((r = memcmp(&a->ethermac[0], &b->ethermac[0], 6)) != 0)
- + return (r > 0 ? 1 : -1);
- +
- + if ((r = memcmp(&a->ethermac[1], &b->ethermac[1], 6)) != 0)
- + return (r > 0 ? 1 : -1);
- +
- if (a->af != b->af)
- return (a->af > b->af ? 1 : -1);
-
- @@ -356,29 +363,34 @@
- return (0);
- }
-
- -/* Convert a IPv4 packet to a partial flow record (used for comparison) */
- static int
- -ipv4_to_flowrec(struct FLOW *flow, const u_int8_t *pkt, size_t caplen,
- - size_t len, int *isfrag, int af, u_int16_t vlanid)
- -{
- - const struct ip *ip = (const struct ip *)pkt;
- - int ndx;
- -
- +make_ndx_ipv4(const struct ip *ip, size_t caplen) {
- if (caplen < 20 || caplen < ip->ip_hl * 4)
- return (-1); /* Runt packet */
- if (ip->ip_v != 4)
- return (-1); /* Unsupported IP version */
- -
- +
- /* Prepare to store flow in canonical format */
- - ndx = memcmp(&ip->ip_src, &ip->ip_dst, sizeof(ip->ip_src)) > 0 ? 1 : 0;
- -
- + return(memcmp(&ip->ip_src, &ip->ip_dst, sizeof(ip->ip_src)) > 0 ? 1 : 0);
- +}
- +
- +/* Convert a IPv4 packet to a partial flow record (used for comparison) */
- +static int
- +ipv4_to_flowrec(struct FLOW *flow, const u_int8_t *pkt, size_t caplen,
- + size_t len, int *isfrag, int af, int ndx)
- +{
- + const struct ip *ip = (const struct ip *)pkt;
- + //int ndx = make_ndx_ipv4 (ip, caplen);
- + if (ndx < 0)
- + return (-1);
- +
- flow->af = af;
- flow->addr[ndx].v4 = ip->ip_src;
- flow->addr[ndx ^ 1].v4 = ip->ip_dst;
- flow->protocol = ip->ip_p;
- flow->octets[ndx] = len;
- flow->packets[ndx] = 1;
- - flow->vlanid = vlanid;
- + flow->tos[ndx] = ip->ip_tos;
-
- *isfrag = (ntohs(ip->ip_off) & (IP_OFFMASK|IP_MF)) ? 1 : 0;
-
- @@ -390,16 +402,8 @@
- caplen - (ip->ip_hl * 4), *isfrag, ip->ip_p, ndx));
- }
-
- -/* Convert a IPv6 packet to a partial flow record (used for comparison) */
- static int
- -ipv6_to_flowrec(struct FLOW *flow, const u_int8_t *pkt, size_t caplen,
- - size_t len, int *isfrag, int af, u_int16_t vlanid)
- -{
- - const struct ip6_hdr *ip6 = (const struct ip6_hdr *)pkt;
- - const struct ip6_ext *eh6;
- - const struct ip6_frag *fh6;
- - int ndx, nxt;
- -
- +make_ndx_ipv6(const struct ip6_hdr *ip6, size_t caplen) {
- if (caplen < sizeof(*ip6))
- return (-1); /* Runt packet */
-
- @@ -407,16 +411,30 @@
- return (-1); /* Unsupported IPv6 version */
-
- /* Prepare to store flow in canonical format */
- - ndx = memcmp(&ip6->ip6_src, &ip6->ip6_dst,
- - sizeof(ip6->ip6_src)) > 0 ? 1 : 0;
- -
- + return(memcmp(&ip6->ip6_src, &ip6->ip6_dst,
- + sizeof(ip6->ip6_src)) > 0 ? 1 : 0);
- +}
- +
- +/* Convert a IPv6 packet to a partial flow record (used for comparison) */
- +static int
- +ipv6_to_flowrec(struct FLOW *flow, const u_int8_t *pkt, size_t caplen,
- + size_t len, int *isfrag, int af, int ndx)
- +{
- + const struct ip6_hdr *ip6 = (const struct ip6_hdr *)pkt;
- + const struct ip6_ext *eh6;
- + const struct ip6_frag *fh6;
- + int nxt;
- +
- + if (ndx < 0)
- + return (-1);
- +
- flow->af = af;
- flow->ip6_flowlabel[ndx] = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
- flow->addr[ndx].v6 = ip6->ip6_src;
- flow->addr[ndx ^ 1].v6 = ip6->ip6_dst;
- flow->octets[ndx] = len;
- flow->packets[ndx] = 1;
- - flow->vlanid = vlanid;
- + flow->tos[ndx] = (ntohl(ip6->ip6_flow) & ntohl(0x0ff00000)) >> 20;
-
- *isfrag = 0;
- nxt = ip6->ip6_nxt;
- @@ -457,6 +475,27 @@
- return (transport_to_flowrec(flow, pkt, caplen, *isfrag, nxt, ndx));
- }
-
- +static int
- +vlan_to_flowrec(struct FLOW *flow, u_int16_t vlanid, int ndx)
- +{
- + if (ndx < 0)
- + return (-1);
- + return (flow->vlanid[ndx] = vlanid);
- +
- +}
- +
- +static int
- +ether_to_flowrec(struct FLOW *flow, struct ether_header *ether, int ndx)
- +{
- + if (ndx < 0)
- + return (-1);
- + if (ether == NULL)
- + return (-1);
- + memcpy(flow->ethermac[ndx], ether->ether_shost, ETH_ALEN);
- + memcpy(flow->ethermac[ndx^1], ether->ether_dhost, ETH_ALEN);
- + return (1);
- +}
- +
- static void
- flow_update_expiry(struct FLOWTRACK *ft, struct FLOW *flow)
- {
- @@ -555,11 +594,11 @@
- */
- static int
- process_packet(struct FLOWTRACK *ft, const u_int8_t *pkt, int af,
- - const u_int32_t caplen, const u_int32_t len, u_int16_t vlanid,
- - const struct timeval *received_time)
- + const u_int32_t caplen, const u_int32_t len, struct ether_header *ether,
- + u_int16_t vlanid, const struct timeval *received_time)
- {
- struct FLOW tmp, *flow;
- - int frag;
- + int frag, ndx;
-
- ft->param.total_packets++;
-
- @@ -567,11 +606,13 @@
- memset(&tmp, 0, sizeof(tmp));
- switch (af) {
- case AF_INET:
- - if (ipv4_to_flowrec(&tmp, pkt, caplen, len, &frag, af, vlanid) == -1)
- + ndx = make_ndx_ipv4((const struct ip *)pkt, caplen);
- + if (ipv4_to_flowrec(&tmp, pkt, caplen, len, &frag, af, ndx) == -1)
- goto bad;
- break;
- case AF_INET6:
- - if (ipv6_to_flowrec(&tmp, pkt, caplen, len, &frag, af, vlanid) == -1)
- + ndx = make_ndx_ipv6((const struct ip6_hdr *)pkt, caplen);
- + if (ipv6_to_flowrec(&tmp, pkt, caplen, len, &frag, af, ndx) == -1)
- goto bad;
- break;
- default:
- @@ -593,8 +634,11 @@
- tmp.tcp_flags[0] = tmp.tcp_flags[1] = 0;
- /* FALLTHROUGH */
- case TRACK_FULL:
- - tmp.vlanid = 0;
- + //tmp.vlanid = 0;
- case TRACK_FULL_VLAN:
- + vlan_to_flowrec(&tmp, vlanid, ndx);
- + case TRACK_FULL_VLAN_ETHER:
- + ether_to_flowrec(&tmp, ether, ndx);
- break;
- }
-
- @@ -1092,7 +1136,7 @@
- * packet should be skipped
- */
- static int
- -datalink_check(int linktype, const u_int8_t *pkt, u_int32_t caplen, int *af, u_int16_t *vlanid)
- +datalink_check(int linktype, const u_int8_t *pkt, u_int32_t caplen, int *af, struct ether_header **ether, u_int16_t *vlanid)
- {
- int i, j;
- u_int32_t frametype;
- @@ -1116,12 +1160,14 @@
-
- /* Processing 802.1Q vlan in ethernet */
- if (linktype == DLT_EN10MB) {
- + if (ether != NULL)
- + *ether = (struct ether_header *)pkt;
- for (j = 0; j < dl->ft_len; j++) {
- frametype <<= 8;
- frametype |= pkt[j + dl->ft_off];
- }
- frametype &= dl->ft_mask;
- - if (frametype == 0x8100) {
- + if (frametype == ETHERTYPE_VLAN) {
- for (j = 0; j < 2; j++) {
- *vlanid <<= 8;
- *vlanid |= pkt[j + dl->skiplen];
- @@ -1166,6 +1212,7 @@
- struct CB_CTXT *cb_ctxt = (struct CB_CTXT *)user_data;
- struct timeval tv;
- u_int16_t vlanid = 0;
- + struct ether_header *ether = NULL;
-
- if (cb_ctxt->ft->param.option.sample &&
- (cb_ctxt->ft->param.total_packets +
- @@ -1174,14 +1221,14 @@
- cb_ctxt->ft->param.non_sampled_packets++;
- return;
- }
- - s = datalink_check(cb_ctxt->linktype, pkt, phdr->caplen, &af, &vlanid);
- + s = datalink_check(cb_ctxt->linktype, pkt, phdr->caplen, &af, ðer, &vlanid);
- if (s < 0 || (!cb_ctxt->want_v6 && af == AF_INET6)) {
- cb_ctxt->ft->param.non_ip_packets++;
- } else {
- tv.tv_sec = phdr->ts.tv_sec;
- tv.tv_usec = phdr->ts.tv_usec;
- if (process_packet(cb_ctxt->ft, pkt + s, af, phdr->caplen - s,
- - phdr->len - s, vlanid, &tv) == PP_MALLOC_FAIL)
- + phdr->len - s, ether, vlanid, &tv) == PP_MALLOC_FAIL)
- cb_ctxt->fatal = 1;
- }
- }
- @@ -1433,7 +1480,7 @@
- bpf_net = bpf_mask = 0;
- }
- *linktype = pcap_datalink(*pcap);
- - if (datalink_check(*linktype, NULL, 0, NULL, NULL) == -1) {
- + if (datalink_check(*linktype, NULL, 0, NULL, NULL, NULL) == -1) {
- fprintf(stderr, "Unsupported datalink type %d\n", *linktype);
- exit(1);
- }
- @@ -1819,6 +1866,9 @@
- flowtrack.param.track_level = TRACK_IP_ONLY;
- else if (strcasecmp(optarg, "vlan") == 0)
- flowtrack.param.track_level = TRACK_FULL_VLAN;
- + else if (strcasecmp(optarg, "ether") == 0)
- + flowtrack.param.track_level = TRACK_FULL_VLAN_ETHER;
- +
- else {
- fprintf(stderr, "Unknown flow tracking "
- "level\n");
- @@ -1953,7 +2003,12 @@
-
- if ((pidfile = fopen(pidfile_path, "r")) != NULL) {
- int pid;
- - fscanf(pidfile,"%u", &pid);
- + if (fscanf(pidfile,"%u", &pid) == EOF) {
- + //fscanf error
- + if (ferror(pidfile)){
- + perror("fscanf");
- + }
- + }
- fclose(pidfile);
-
- /* Check if the pid exists */
- --- a/softflowd.h
- +++ b/softflowd.h
- @@ -74,6 +74,7 @@
- #define TRACK_IP_PROTO 3 /* src/dst/proto 3-tuple */
- #define TRACK_IP_ONLY 4 /* src/dst tuple */
- #define TRACK_FULL_VLAN 5 /* src/dst/addr/port/proto/tos/vlanid 7-tuple */
- +#define TRACK_FULL_VLAN_ETHER 6 /* src/dst/addr/port/proto/tos/vlanid/src-mac/dst-mac 9-tuple */
-
- /*
- * This structure contains optional information carried by Option Data
- @@ -190,7 +191,8 @@
- u_int16_t port[2]; /* Endpoint ports */
- u_int8_t tcp_flags[2]; /* Cumulative OR of flags */
- u_int8_t tos[2]; /* Tos */
- - u_int16_t vlanid; /* vlanid */
- + u_int16_t vlanid[2]; /* vlanid */
- + uint8_t ethermac[2][6];
- u_int8_t protocol; /* Protocol */
- };
-
- @@ -232,13 +234,16 @@
- int send_netflow_v9(struct FLOW **flows, int num_flows, int nfsock,
- u_int16_t ifidx, struct FLOWTRACKPARAMETERS *param,
- int verbose_flag);
- +int send_nflow9(struct FLOW **flows, int num_flows, int nfsock,
- + u_int16_t ifidx, struct FLOWTRACKPARAMETERS *param,
- + int verbose_flag);
- int send_ipfix(struct FLOW **flows, int num_flows, int nfsock,
- - u_int16_t ifidx, struct FLOWTRACKPARAMETERS *param,
- - int verbose_flag);
- -int send_ipfix_bidirection(struct FLOW **flows, int num_flows, int nfsock,
- - u_int16_t ifidx,
- - struct FLOWTRACKPARAMETERS *param,
- + u_int16_t ifidx, struct FLOWTRACKPARAMETERS *param,
- int verbose_flag);
- +int send_ipfix_bi(struct FLOW **flows, int num_flows, int nfsock,
- + u_int16_t ifidx,
- + struct FLOWTRACKPARAMETERS *param,
- + int verbose_flag);
-
- /* Force a resend of the flow template */
- void netflow9_resend_template(void);
|