1 /*
2  * Copyright (c) 2001 Mark Fullmer and The Ohio State University
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      $Id: ftdecode.c,v 1.25 2005/05/10 15:45:47 maf Exp $
27  */
28 
29 #include "ftconfig.h"
30 #include "ftlib.h"
31 
32 #include <stddef.h>
33 #if HAVE_STRINGS_H
34  #include <strings.h>
35 #endif
36 #if HAVE_STRING_H
37   #include <string.h>
38 #endif
39 
40 /*
41  * function ftpdu_check_seq
42  *
43  * Check sequence number in decoded PDU
44  *
45  * ftpdu_verify must be called first
46  *
47  * Returns  0  - sequence number matched expected
48  *          -1 - sequence number did not match expected
49  *               seq_rcv, seq_exp updated
50 */
ftpdu_check_seq(struct ftpdu * ftpdu,struct ftseq * ftseq)51 int ftpdu_check_seq(struct ftpdu *ftpdu, struct ftseq *ftseq)
52 {
53   struct ftpdu_header *ph;
54   int ret;
55   unsigned int seq_index;
56 
57   /* version 1 exports do not have sequence numbers */
58   if (ftpdu->ftv.d_version == 1)
59     return 0;
60 
61   ph = (struct ftpdu_header*)&ftpdu->buf;
62 
63 #if BYTE_ORDER == LITTLE_ENDIAN
64   SWAPINT32(ph->flow_sequence);
65   SWAPINT16(ph->count);
66 #endif /* LITTLE_ENDIAN */
67 
68   seq_index = ph->engine_id<<8 | ph->engine_type;
69 
70   /* first time always okay */
71   if (!ftseq->seq_set[seq_index]) {
72     ftseq->seq_set[seq_index] = 1;
73     ftseq->seq[seq_index] = ph->flow_sequence + ph->count;
74     ret = 0;
75   } else {
76     /* if cur == expecting then okay, else reset */
77     if (ph->flow_sequence == ftseq->seq[seq_index]) {
78       ftseq->seq[seq_index] += ph->count;
79       ret = 0;
80     } else {
81       ftseq->seq_rcv = ph->flow_sequence;
82       ftseq->seq_exp = ftseq->seq[seq_index];
83       ftseq->seq[seq_index] = ph->flow_sequence + ph->count;
84 
85       /* calculate lost sequence numbers, account for wraparound at 2^32 */
86       if (ftseq->seq_rcv > ftseq->seq_exp)
87         ftseq->seq_lost = ftseq->seq_rcv - ftseq->seq_exp;
88       else
89         ftseq->seq_lost = (0xFFFFFFFF - ftseq->seq_exp) + ftseq->seq_rcv;
90       ret = -1;
91     }
92   }
93 
94 #if BYTE_ORDER == LITTLE_ENDIAN
95   SWAPINT32(ph->flow_sequence);
96   SWAPINT16(ph->count);
97 #endif /* LITTLE_ENDIAN */
98 
99   return ret;
100 
101 } /* ftpdu_check_seq */
102 
103 /*
104  * function: ftpdu_verify
105  *
106  * verify PDU is valid
107  *   count is not too high
108  *   version is valid
109  *   sizeof structure is valid
110  *
111  * iff the verification checks pass then ftpdu->ftver is initialized to the
112  * pdu version * and ftpdu->decodef() is initialized to the decode function
113  *
114  * pdu must be in network byte order and is returned in network byte order
115  *
116 */
ftpdu_verify(struct ftpdu * ftpdu)117 int ftpdu_verify(struct ftpdu *ftpdu)
118 {
119   struct ftpdu_header *ph;
120   int size, ret;
121 
122   ret = -1;
123 
124   /* enough bytes to decode the count and version? */
125   if (ftpdu->bused < 4) {
126     fterr_warnx("not enough bytes to decode the count and version.");
127     goto ftpdu_verify_out_quick;
128   }
129 
130   ph = (struct ftpdu_header*)&ftpdu->buf;
131 
132 #if BYTE_ORDER == LITTLE_ENDIAN
133   SWAPINT16(ph->version);
134   SWAPINT16(ph->count);
135 #endif /* LITTLE_ENDIAN */
136 
137   bzero(&ftpdu->ftv, sizeof (struct ftver));
138   ftpdu->ftv.s_version = FT_IO_SVERSION;
139 
140   switch (ph->version) {
141 
142     case 1:
143 
144       /* max PDU's in record */
145       if (ph->count > FT_PDU_V1_MAXFLOWS)
146         goto ftpdu_verify_out;
147 
148       size = offsetof(struct ftpdu_v1, records) +
149              ph->count * sizeof (struct ftrec_v1);
150 
151       /* PDU received size == PDU expected size? */
152       if (size != ftpdu->bused)
153         goto ftpdu_verify_out;
154 
155       ftpdu->ftv.d_version = 1;
156       ftpdu->decodef = fts3rec_pdu_v1_decode;
157 
158       break;
159 
160     case 5:
161 
162       /* max PDU's in record */
163       if (ph->count > FT_PDU_V5_MAXFLOWS) {
164 	fterr_warnx("too many pdus (%d) in record, max %d", ph->count,
165 		FT_PDU_V5_MAXFLOWS);
166         goto ftpdu_verify_out;
167       }
168 
169 
170       size = offsetof(struct ftpdu_v5, records) +
171              ph->count * sizeof (struct ftrec_v5);
172 
173       /* PDU received size == PDU expected size? */
174       if (size != ftpdu->bused) {
175         fterr_warnx("pdu received size was wrong.  expected %d got %d",
176                 ftpdu->bused, size);
177         goto ftpdu_verify_out;
178       }
179 
180       ftpdu->ftv.d_version = 5;
181       ftpdu->decodef = fts3rec_pdu_v5_decode;
182 
183       break;
184 
185     case 6:
186 
187       /* max PDU's in record */
188       if (ph->count > FT_PDU_V6_MAXFLOWS)
189         goto ftpdu_verify_out;
190 
191       size = offsetof(struct ftpdu_v6, records) +
192              ph->count * sizeof (struct ftrec_v6);
193 
194       /* PDU received size == PDU expected size? */
195       if (size != ftpdu->bused)
196         goto ftpdu_verify_out;
197 
198       ftpdu->ftv.d_version = 6;
199       ftpdu->decodef = fts3rec_pdu_v6_decode;
200 
201       break;
202 
203     case 7:
204 
205       /* max PDU's in record */
206       if (ph->count > FT_PDU_V7_MAXFLOWS)
207         goto ftpdu_verify_out;
208 
209       size = offsetof(struct ftpdu_v7, records) +
210              ph->count * sizeof (struct ftrec_v7);
211 
212       /* PDU received size == PDU expected size? */
213       if (size != ftpdu->bused)
214         goto ftpdu_verify_out;
215 
216       ftpdu->ftv.d_version = 7;
217       ftpdu->decodef = fts3rec_pdu_v7_decode;
218 
219       break;
220 
221     case 8:
222 
223       /* enough bytes to decode the aggregation method and version? */
224       if (ftpdu->bused < (offsetof(struct ftpdu_v8_gen, agg_version) +
225                         sizeof ((struct ftpdu_v8_gen *)0)->agg_version))
226         goto ftpdu_verify_out;
227 
228       ftpdu->ftv.agg_method = ((struct ftpdu_v8_gen *)&ftpdu->buf)->aggregation;
229       ftpdu->ftv.agg_version =
230         ((struct ftpdu_v8_gen *)&ftpdu->buf)->agg_version;
231 
232       /* XXX Juniper hack */
233       if (ftpdu->ftv.agg_version == 0)
234         ftpdu->ftv.agg_version = 2;
235 
236       /* can only decode version 2 aggregation method packets */
237       if (ftpdu->ftv.agg_version != 2)
238         goto ftpdu_verify_out;
239 
240       switch (ftpdu->ftv.agg_method) {
241 
242         case 1:
243 
244           /* max PDU's in record */
245           if (ph->count > FT_PDU_V8_1_MAXFLOWS)
246             goto ftpdu_verify_out;
247 
248           size = offsetof(struct ftpdu_v8_1, records) +
249                  ph->count * sizeof (struct ftrec_v8_1);
250 
251           /* PDU received size == PDU expected size? */
252           if (size != ftpdu->bused)
253             goto ftpdu_verify_out;
254 
255           ftpdu->ftv.d_version = 8;
256           ftpdu->ftv.agg_method = 1;
257           ftpdu->decodef = fts3rec_pdu_v8_1_decode;
258 
259           break;
260 
261         case 2:
262 
263           /* max PDU's in record */
264           if (ph->count > FT_PDU_V8_2_MAXFLOWS)
265             goto ftpdu_verify_out;
266 
267           size = offsetof(struct ftpdu_v8_2, records) +
268                  ph->count * sizeof (struct ftrec_v8_2);
269 
270           /* PDU received size == PDU expected size? */
271           if (size != ftpdu->bused)
272             goto ftpdu_verify_out;
273 
274           ftpdu->ftv.d_version = 8;
275           ftpdu->ftv.agg_method = 2;
276           ftpdu->decodef = fts3rec_pdu_v8_2_decode;
277 
278           break;
279 
280         case 3:
281 
282           /* max PDU's in record */
283           if (ph->count > FT_PDU_V8_3_MAXFLOWS)
284             goto ftpdu_verify_out;
285 
286           size = offsetof(struct ftpdu_v8_3, records) +
287                  ph->count * sizeof (struct ftrec_v8_3);
288 
289           /* PDU received size == PDU expected size? */
290           if (size != ftpdu->bused)
291             goto ftpdu_verify_out;
292 
293           ftpdu->ftv.d_version = 8;
294           ftpdu->ftv.agg_method = 3;
295           ftpdu->decodef = fts3rec_pdu_v8_3_decode;
296 
297           break;
298 
299         case 4:
300 
301           /* max PDU's in record */
302           if (ph->count > FT_PDU_V8_4_MAXFLOWS)
303             goto ftpdu_verify_out;
304 
305           size = offsetof(struct ftpdu_v8_4, records) +
306                  ph->count * sizeof (struct ftrec_v8_4);
307 
308           /* PDU received size == PDU expected size? */
309           if (size != ftpdu->bused)
310             goto ftpdu_verify_out;
311 
312           ftpdu->ftv.d_version = 8;
313           ftpdu->ftv.agg_method = 4;
314           ftpdu->decodef = fts3rec_pdu_v8_4_decode;
315 
316           break;
317 
318         case 5:
319 
320           /* max PDU's in record */
321           if (ph->count > FT_PDU_V8_5_MAXFLOWS)
322             goto ftpdu_verify_out;
323 
324           size = offsetof(struct ftpdu_v8_5, records) +
325                  ph->count * sizeof (struct ftrec_v8_5);
326 
327           /* PDU received size == PDU expected size? */
328           if (size != ftpdu->bused)
329             goto ftpdu_verify_out;
330 
331           ftpdu->ftv.d_version = 8;
332           ftpdu->ftv.agg_method = 5;
333           ftpdu->decodef = fts3rec_pdu_v8_5_decode;
334 
335           break;
336 
337         case 6:
338 
339           /* max PDU's in record */
340           if (ph->count > FT_PDU_V8_6_MAXFLOWS)
341             goto ftpdu_verify_out;
342 
343           size = offsetof(struct ftpdu_v8_6, records) +
344                  ph->count * sizeof (struct ftrec_v8_6);
345 
346           /* PDU received size == PDU expected size? */
347           /* Catalyst pads exports, so use > instead of != */
348           if (size > ftpdu->bused)
349             goto ftpdu_verify_out;
350 
351           ftpdu->ftv.d_version = 8;
352           ftpdu->ftv.agg_method = 6;
353           ftpdu->decodef = fts3rec_pdu_v8_6_decode;
354 
355           break;
356 
357 
358         case 7:
359 
360           /* max PDU's in record */
361           if (ph->count > FT_PDU_V8_7_MAXFLOWS)
362             goto ftpdu_verify_out;
363 
364           size = offsetof(struct ftpdu_v8_7, records) +
365                  ph->count * sizeof (struct ftrec_v8_7);
366 
367           /* PDU received size == PDU expected size? */
368           /* Catalyst pads exports, so use > instead of != */
369           if (size > ftpdu->bused)
370             goto ftpdu_verify_out;
371 
372           ftpdu->ftv.d_version = 8;
373           ftpdu->ftv.agg_method = 7;
374           ftpdu->decodef = fts3rec_pdu_v8_7_decode;
375 
376           break;
377 
378 
379         case 8:
380 
381           /* max PDU's in record */
382           if (ph->count > FT_PDU_V8_8_MAXFLOWS)
383             goto ftpdu_verify_out;
384 
385           size = offsetof(struct ftpdu_v8_8, records) +
386                  ph->count * sizeof (struct ftrec_v8_8);
387 
388           /* PDU received size == PDU expected size? */
389           /* Catalyst pads exports, so use > instead of != */
390           if (size > ftpdu->bused)
391             goto ftpdu_verify_out;
392 
393           ftpdu->ftv.d_version = 8;
394           ftpdu->ftv.agg_method = 8;
395           ftpdu->decodef = fts3rec_pdu_v8_8_decode;
396 
397           break;
398 
399 
400         case 9:
401 
402           /* max PDU's in record */
403           if (ph->count > FT_PDU_V8_9_MAXFLOWS)
404             goto ftpdu_verify_out;
405 
406           size = offsetof(struct ftpdu_v8_9, records) +
407                  ph->count * sizeof (struct ftrec_v8_9);
408 
409           /* PDU received size == PDU expected size? */
410           if (size != ftpdu->bused)
411             goto ftpdu_verify_out;
412 
413           ftpdu->ftv.d_version = 8;
414           ftpdu->ftv.agg_method = 9;
415           ftpdu->decodef = fts3rec_pdu_v8_9_decode;
416 
417           break;
418 
419 
420         case 10:
421 
422           /* max PDU's in record */
423           if (ph->count > FT_PDU_V8_10_MAXFLOWS)
424             goto ftpdu_verify_out;
425 
426           size = offsetof(struct ftpdu_v8_10, records) +
427                  ph->count * sizeof (struct ftrec_v8_10);
428 
429           /* PDU received size == PDU expected size? */
430           if (size != ftpdu->bused)
431             goto ftpdu_verify_out;
432 
433           ftpdu->ftv.d_version = 8;
434           ftpdu->ftv.agg_method = 10;
435           ftpdu->decodef = fts3rec_pdu_v8_10_decode;
436 
437           break;
438 
439 
440         case 11:
441 
442           /* max PDU's in record */
443           if (ph->count > FT_PDU_V8_11_MAXFLOWS)
444             goto ftpdu_verify_out;
445 
446           size = offsetof(struct ftpdu_v8_11, records) +
447                  ph->count * sizeof (struct ftrec_v8_11);
448 
449           /* PDU received size == PDU expected size? */
450           if (size != ftpdu->bused)
451             goto ftpdu_verify_out;
452 
453           ftpdu->ftv.d_version = 8;
454           ftpdu->ftv.agg_method = 11;
455           ftpdu->decodef = fts3rec_pdu_v8_11_decode;
456 
457           break;
458 
459 
460         case 12:
461 
462           /* max PDU's in record */
463           if (ph->count > FT_PDU_V8_12_MAXFLOWS)
464             goto ftpdu_verify_out;
465 
466           size = offsetof(struct ftpdu_v8_12, records) +
467                  ph->count * sizeof (struct ftrec_v8_12);
468 
469           /* PDU received size == PDU expected size? */
470           if (size != ftpdu->bused)
471             goto ftpdu_verify_out;
472 
473           ftpdu->ftv.d_version = 8;
474           ftpdu->ftv.agg_method = 12;
475           ftpdu->decodef = fts3rec_pdu_v8_12_decode;
476 
477           break;
478 
479 
480         case 13:
481 
482           /* max PDU's in record */
483           if (ph->count > FT_PDU_V8_13_MAXFLOWS)
484             goto ftpdu_verify_out;
485 
486           size = offsetof(struct ftpdu_v8_13, records) +
487                  ph->count * sizeof (struct ftrec_v8_13);
488 
489           /* PDU received size == PDU expected size? */
490           if (size != ftpdu->bused)
491             goto ftpdu_verify_out;
492 
493           ftpdu->ftv.d_version = 8;
494           ftpdu->ftv.agg_method = 13;
495           ftpdu->decodef = fts3rec_pdu_v8_13_decode;
496 
497           break;
498 
499 
500         case 14:
501 
502           /* max PDU's in record */
503           if (ph->count > FT_PDU_V8_14_MAXFLOWS)
504             goto ftpdu_verify_out;
505 
506           size = offsetof(struct ftpdu_v8_14, records) +
507                  ph->count * sizeof (struct ftrec_v8_14);
508 
509           /* PDU received size == PDU expected size? */
510           if (size != ftpdu->bused)
511             goto ftpdu_verify_out;
512 
513           ftpdu->ftv.d_version = 8;
514           ftpdu->ftv.agg_method = 14;
515           ftpdu->decodef = fts3rec_pdu_v8_14_decode;
516 
517           break;
518 
519 
520         default:
521           goto ftpdu_verify_out;
522 
523       } /* switch ph->agg_method */
524 
525       break; /* 8 */
526 
527       default:
528 	  fterr_warnx("ftpdu version not set.");
529           goto ftpdu_verify_out;
530 
531   } /* switch ph->version */
532 
533   ret = 0;
534 
535 ftpdu_verify_out:
536 
537 #if BYTE_ORDER == LITTLE_ENDIAN
538   SWAPINT16(ph->version);
539   SWAPINT16(ph->count);
540 #endif /* LITTLE_ENDIAN */
541 
542 ftpdu_verify_out_quick:
543 
544   return ret;
545 
546 }
547 
548 /*
549  * function: fts3rec_pdu_decode
550  *
551  * pdu must be in network byte order.  Caller must initialize
552  * ftpdu->ftd.byte_order and ftpdu->ftd.as_sub
553  *
554  * stream records are returned in the byte order defined by
555  * ftpdu->ftd.byte_order
556  *
557  * AS 0 is substituted with ftpdu->ftd.as_sub
558  *
559  * ftpdu_verify() must be called first to ensure the packet will
560  * not overrun buffers and to initialize the decode jump table
561  *
562  * returns: # of stream records decoded.  PDU is no longer valid
563  * after calling (bytes may be swapped)
564 */
fts3rec_pdu_decode(struct ftpdu * ftpdu)565 int fts3rec_pdu_decode(struct ftpdu *ftpdu)
566 {
567   int n;
568   struct ftpdu_header *ph;
569 
570   n = -1;
571 
572   bzero(&ftpdu->ftd.buf, FT_IO_MAXDECODE);
573 
574   /* take advantage that all pdu's have a common header. */
575 
576   ph = (struct ftpdu_header*)&ftpdu->buf;
577 
578 /*
579  * If this is a LITTLE_ENDIAN architecture ph->version and ph->count
580  * need to be swapped before being used.
581  *
582  * ftpdu->ftd->exporter_ip and ftpdu->ftd->as_sub are in LITTLE_ENDIAN, the
583  * rest of the PDU is BIG_ENDIAN.  Flip these to BIG_ENDIAN to make the
584  * conversions below easier (everything in the PDU is BIG)
585  */
586 
587 #if BYTE_ORDER == LITTLE_ENDIAN
588   SWAPINT16(ph->version);
589   SWAPINT16(ph->count);
590 
591   SWAPINT16(ftpdu->ftd.as_sub);
592   SWAPINT32(ftpdu->ftd.exporter_ip);
593 #endif /* LITTLE_ENDIAN */
594 
595   ftpdu->ftd.count = ph->count;
596 
597   /* decode it */
598   n = ftpdu->decodef(ftpdu);
599 
600   /* restore ftd */
601 #if BYTE_ORDER == LITTLE_ENDIAN
602   SWAPINT16(ftpdu->ftd.as_sub);
603   SWAPINT32(ftpdu->ftd.exporter_ip);
604 #endif /* LITTLE_ENDIAN */
605 
606   return n;
607 
608 } /* fts3rec_pdu_decode */
609 
610 /*
611  * function: fts3rec_pdu_v1_decode
612  *
613  * subfunction to fts3rec_pdu_decode
614  *
615  * returns: # of stream records decoded
616 */
fts3rec_pdu_v1_decode(struct ftpdu * ftpdu)617 int fts3rec_pdu_v1_decode(struct ftpdu *ftpdu)
618 {
619   int n;
620   struct ftpdu_header *ph;
621   struct ftpdu_v1 *pdu_v1;
622   struct fts3rec_v1 *rec_v1;
623 
624   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v1);
625   pdu_v1 = (struct ftpdu_v1*)&ftpdu->buf;
626   ph = (struct ftpdu_header*)&ftpdu->buf;
627 
628   /* preswap */
629   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
630     SWAPINT32(ph->sysUpTime);
631     SWAPINT32(ph->unix_secs);
632     SWAPINT32(ph->unix_nsecs);
633   }
634 
635   for (n = 0; n < ftpdu->ftd.count; ++n) {
636 
637     rec_v1 = (struct fts3rec_v1*) (ftpdu->ftd.buf + (n*ftpdu->ftd.rec_size));
638 
639     rec_v1->unix_nsecs = ph->unix_nsecs;
640     rec_v1->unix_secs = ph->unix_secs;
641     rec_v1->sysUpTime = ph->sysUpTime;
642 
643     rec_v1->srcaddr = pdu_v1->records[n].srcaddr;
644     rec_v1->dstaddr = pdu_v1->records[n].dstaddr;
645     rec_v1->nexthop = pdu_v1->records[n].nexthop;
646     rec_v1->input = pdu_v1->records[n].input;
647     rec_v1->output = pdu_v1->records[n].output;
648     rec_v1->dPkts = pdu_v1->records[n].dPkts;
649     rec_v1->dOctets = pdu_v1->records[n].dOctets;
650     rec_v1->First = pdu_v1->records[n].First;
651     rec_v1->Last = pdu_v1->records[n].Last;
652     rec_v1->dstport = pdu_v1->records[n].dstport;
653     rec_v1->srcport = pdu_v1->records[n].srcport;
654     rec_v1->prot = pdu_v1->records[n].prot;
655     rec_v1->tos = pdu_v1->records[n].tos;
656     rec_v1->tcp_flags = pdu_v1->records[n].flags;
657 
658     /* copy in exporter IP */
659     rec_v1->exaddr = ftpdu->ftd.exporter_ip;
660 
661     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
662 
663       SWAPINT32(rec_v1->srcaddr);
664       SWAPINT32(rec_v1->dstaddr);
665       SWAPINT32(rec_v1->nexthop);
666       SWAPINT16(rec_v1->input);
667       SWAPINT16(rec_v1->output);
668       SWAPINT32(rec_v1->dPkts);
669       SWAPINT32(rec_v1->dOctets);
670       SWAPINT32(rec_v1->First);
671       SWAPINT32(rec_v1->Last);
672       SWAPINT16(rec_v1->dstport);
673       SWAPINT16(rec_v1->srcport);
674 
675       SWAPINT32(rec_v1->exaddr);
676 
677     }
678 
679   } /* for n */
680 
681   return ftpdu->ftd.count;
682 
683 } /* fts3rec_pdu_v1_decode */
684 
685 /*
686  * function: fts3rec_pdu_v5_decode
687  *
688  * subfunction to fts3rec_pdu_decode
689  *
690  * returns: # of stream records decoded
691 */
fts3rec_pdu_v5_decode(struct ftpdu * ftpdu)692 int fts3rec_pdu_v5_decode(struct ftpdu *ftpdu)
693 {
694   int n;
695   struct ftpdu_header *ph;
696   struct ftpdu_v5 *pdu_v5;
697   struct fts3rec_v5 *rec_v5;
698 
699   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v5);
700   pdu_v5 = (struct ftpdu_v5*)&ftpdu->buf;
701   ph = (struct ftpdu_header*)&ftpdu->buf;
702 
703   /* preswap */
704   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
705     SWAPINT32(ph->sysUpTime);
706     SWAPINT32(ph->unix_secs);
707     SWAPINT32(ph->unix_nsecs);
708   }
709 
710   for (n = 0; n < pdu_v5->count; ++n) {
711 
712     rec_v5 = (struct fts3rec_v5*) (ftpdu->ftd.buf + (n*ftpdu->ftd.rec_size));
713 
714     rec_v5->unix_nsecs = ph->unix_nsecs;
715     rec_v5->unix_secs = ph->unix_secs;
716     rec_v5->sysUpTime = ph->sysUpTime;
717 
718     rec_v5->engine_type = pdu_v5->engine_type;
719     rec_v5->engine_id = pdu_v5->engine_id;
720 
721 
722     rec_v5->srcaddr = pdu_v5->records[n].srcaddr;
723     rec_v5->dstaddr = pdu_v5->records[n].dstaddr;
724     rec_v5->nexthop = pdu_v5->records[n].nexthop;
725     rec_v5->input = pdu_v5->records[n].input;
726     rec_v5->output = pdu_v5->records[n].output;
727     rec_v5->dPkts = pdu_v5->records[n].dPkts;
728     rec_v5->dOctets = pdu_v5->records[n].dOctets;
729     rec_v5->First = pdu_v5->records[n].First;
730     rec_v5->Last = pdu_v5->records[n].Last;
731     rec_v5->dstport = pdu_v5->records[n].dstport;
732     rec_v5->srcport = pdu_v5->records[n].srcport;
733     rec_v5->prot = pdu_v5->records[n].prot;
734     rec_v5->tos = pdu_v5->records[n].tos;
735     rec_v5->tcp_flags = pdu_v5->records[n].tcp_flags;
736     rec_v5->src_as = pdu_v5->records[n].src_as;
737     rec_v5->dst_as = pdu_v5->records[n].dst_as;
738     rec_v5->src_mask = pdu_v5->records[n].src_mask;
739     rec_v5->dst_mask = pdu_v5->records[n].dst_mask;
740 
741     /* perform AS substitution */
742     rec_v5->src_as = (rec_v5->src_as) ? rec_v5->src_as : ftpdu->ftd.as_sub;
743     rec_v5->dst_as = (rec_v5->dst_as) ? rec_v5->dst_as : ftpdu->ftd.as_sub;
744 
745     /* copy in exporter IP */
746     rec_v5->exaddr = ftpdu->ftd.exporter_ip;
747 
748     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
749 
750       SWAPINT32(rec_v5->srcaddr);
751       SWAPINT32(rec_v5->dstaddr);
752       SWAPINT32(rec_v5->nexthop);
753       SWAPINT16(rec_v5->input);
754       SWAPINT16(rec_v5->output);
755       SWAPINT32(rec_v5->dPkts);
756       SWAPINT32(rec_v5->dOctets);
757       SWAPINT32(rec_v5->First);
758       SWAPINT32(rec_v5->Last);
759       SWAPINT16(rec_v5->dstport);
760       SWAPINT16(rec_v5->srcport);
761       SWAPINT16(rec_v5->src_as);
762       SWAPINT16(rec_v5->dst_as);
763 
764       SWAPINT32(rec_v5->exaddr);
765 
766     }
767 
768   } /* for n */
769 
770   return ftpdu->ftd.count;
771 
772 } /* fts3rec_pdu_v5_decode */
773 
774 /*
775  * function: fts3rec_pdu_v6_decode
776  *
777  * subfunction to fts3rec_pdu_decode
778  *
779  * returns: # of stream records decoded
780 */
fts3rec_pdu_v6_decode(struct ftpdu * ftpdu)781 int fts3rec_pdu_v6_decode(struct ftpdu *ftpdu)
782 {
783   int n;
784   struct ftpdu_header *ph;
785   struct ftpdu_v6 *pdu_v6;
786   struct fts3rec_v6 *rec_v6;
787 
788   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v6);
789   pdu_v6 = (struct ftpdu_v6*)&ftpdu->buf;
790   ph = (struct ftpdu_header*)&ftpdu->buf;
791 
792   /* preswap */
793   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
794     SWAPINT32(ph->sysUpTime);
795     SWAPINT32(ph->unix_secs);
796     SWAPINT32(ph->unix_nsecs);
797   }
798 
799   for (n = 0; n < pdu_v6->count; ++n) {
800 
801     rec_v6 = (struct fts3rec_v6*) (ftpdu->ftd.buf + (n*ftpdu->ftd.rec_size));
802 
803     rec_v6->unix_nsecs = ph->unix_nsecs;
804     rec_v6->unix_secs = ph->unix_secs;
805     rec_v6->sysUpTime = ph->sysUpTime;
806 
807     rec_v6->engine_type = pdu_v6->engine_type;
808     rec_v6->engine_type = pdu_v6->engine_id;
809 
810 
811     rec_v6->srcaddr = pdu_v6->records[n].srcaddr;
812     rec_v6->dstaddr = pdu_v6->records[n].dstaddr;
813     rec_v6->nexthop = pdu_v6->records[n].nexthop;
814     rec_v6->input = pdu_v6->records[n].input;
815     rec_v6->output = pdu_v6->records[n].output;
816     rec_v6->dPkts = pdu_v6->records[n].dPkts;
817     rec_v6->dOctets = pdu_v6->records[n].dOctets;
818     rec_v6->First = pdu_v6->records[n].First;
819     rec_v6->Last = pdu_v6->records[n].Last;
820     rec_v6->dstport = pdu_v6->records[n].dstport;
821     rec_v6->srcport = pdu_v6->records[n].srcport;
822     rec_v6->prot = pdu_v6->records[n].prot;
823     rec_v6->tos = pdu_v6->records[n].tos;
824     rec_v6->tcp_flags = pdu_v6->records[n].tcp_flags;
825     rec_v6->src_as = pdu_v6->records[n].src_as;
826     rec_v6->dst_as = pdu_v6->records[n].dst_as;
827     rec_v6->src_mask = pdu_v6->records[n].src_mask;
828     rec_v6->dst_mask = pdu_v6->records[n].dst_mask;
829 
830     /* perform AS substitution */
831     rec_v6->src_as = (rec_v6->src_as) ? rec_v6->src_as : ftpdu->ftd.as_sub;
832     rec_v6->dst_as = (rec_v6->dst_as) ? rec_v6->dst_as : ftpdu->ftd.as_sub;
833 
834     /* copy in exporter IP */
835     rec_v6->exaddr = ftpdu->ftd.exporter_ip;
836 
837     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
838 
839       SWAPINT32(rec_v6->srcaddr);
840       SWAPINT32(rec_v6->dstaddr);
841       SWAPINT32(rec_v6->nexthop);
842       SWAPINT16(rec_v6->input);
843       SWAPINT16(rec_v6->output);
844       SWAPINT32(rec_v6->dPkts);
845       SWAPINT32(rec_v6->dOctets);
846       SWAPINT32(rec_v6->First);
847       SWAPINT32(rec_v6->Last);
848       SWAPINT16(rec_v6->dstport);
849       SWAPINT16(rec_v6->srcport);
850       SWAPINT16(rec_v6->src_as);
851       SWAPINT16(rec_v6->dst_as);
852 
853       SWAPINT32(rec_v6->exaddr);
854 
855     }
856 
857   } /* for n */
858 
859   return ftpdu->ftd.count;
860 
861 } /* fts3rec_pdu_v6_decode */
862 
863 /*
864  * function: fts3rec_pdu_v7_decode
865  *
866  * subfunction to fts3rec_pdu_decode
867  *
868  * returns: # of stream records decoded
869 */
fts3rec_pdu_v7_decode(struct ftpdu * ftpdu)870 int fts3rec_pdu_v7_decode(struct ftpdu *ftpdu)
871 {
872   int n;
873   struct ftpdu_header *ph;
874   struct ftpdu_v7 *pdu_v7;
875   struct fts3rec_v7 *rec_v7;
876 
877   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v7);
878   pdu_v7 = (struct ftpdu_v7*)&ftpdu->buf;
879   ph = (struct ftpdu_header*)&ftpdu->buf;
880 
881   /* preswap */
882   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
883     SWAPINT32(ph->sysUpTime);
884     SWAPINT32(ph->unix_secs);
885     SWAPINT32(ph->unix_nsecs);
886   }
887 
888   for (n = 0; n < pdu_v7->count; ++n) {
889 
890     rec_v7 = (struct fts3rec_v7*) (ftpdu->ftd.buf + (n*ftpdu->ftd.rec_size));
891 
892     rec_v7->unix_nsecs = ph->unix_nsecs;
893     rec_v7->unix_secs = ph->unix_secs;
894     rec_v7->sysUpTime = ph->sysUpTime;
895 
896     rec_v7->engine_type = pdu_v7->engine_type;
897     rec_v7->engine_type = pdu_v7->engine_id;
898 
899     rec_v7->srcaddr = pdu_v7->records[n].srcaddr;
900     rec_v7->dstaddr = pdu_v7->records[n].dstaddr;
901     rec_v7->nexthop = pdu_v7->records[n].nexthop;
902     rec_v7->input = pdu_v7->records[n].input;
903     rec_v7->output = pdu_v7->records[n].output;
904     rec_v7->dPkts = pdu_v7->records[n].dPkts;
905     rec_v7->dOctets = pdu_v7->records[n].dOctets;
906     rec_v7->First = pdu_v7->records[n].First;
907     rec_v7->Last = pdu_v7->records[n].Last;
908     rec_v7->dstport = pdu_v7->records[n].dstport;
909     rec_v7->srcport = pdu_v7->records[n].srcport;
910     rec_v7->prot = pdu_v7->records[n].prot;
911     rec_v7->tos = pdu_v7->records[n].tos;
912     rec_v7->tcp_flags = pdu_v7->records[n].tcp_flags;
913     rec_v7->src_as = pdu_v7->records[n].src_as;
914     rec_v7->dst_as = pdu_v7->records[n].dst_as;
915     rec_v7->src_mask = pdu_v7->records[n].src_mask;
916     rec_v7->dst_mask = pdu_v7->records[n].dst_mask;
917     rec_v7->router_sc = pdu_v7->records[n].router_sc;
918 
919     /* perform AS substitution */
920     rec_v7->src_as = (rec_v7->src_as) ? rec_v7->src_as : ftpdu->ftd.as_sub;
921     rec_v7->dst_as = (rec_v7->dst_as) ? rec_v7->dst_as : ftpdu->ftd.as_sub;
922 
923     /* copy in exporter IP */
924     rec_v7->exaddr = ftpdu->ftd.exporter_ip;
925 
926     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
927 
928       SWAPINT32(rec_v7->srcaddr);
929       SWAPINT32(rec_v7->dstaddr);
930       SWAPINT32(rec_v7->nexthop);
931       SWAPINT16(rec_v7->input);
932       SWAPINT16(rec_v7->output);
933       SWAPINT32(rec_v7->dPkts);
934       SWAPINT32(rec_v7->dOctets);
935       SWAPINT32(rec_v7->First);
936       SWAPINT32(rec_v7->Last);
937       SWAPINT16(rec_v7->dstport);
938       SWAPINT16(rec_v7->srcport);
939       SWAPINT16(rec_v7->src_as);
940       SWAPINT16(rec_v7->dst_as);
941       SWAPINT32(rec_v7->router_sc);
942 
943       SWAPINT32(rec_v7->exaddr);
944 
945     }
946   } /* for */
947 
948   return ftpdu->ftd.count;
949 
950 } /* fts3rec_pdu_v7_decode */
951 
952 /*
953  * function: fts3rec_pdu_v8_1_decode
954  *
955  * subfunction to fts3rec_pdu_decode
956  *
957  * returns: # of stream records decoded
958 */
fts3rec_pdu_v8_1_decode(struct ftpdu * ftpdu)959 int fts3rec_pdu_v8_1_decode(struct ftpdu *ftpdu)
960 {
961   int n;
962   struct ftpdu_header *ph;
963   struct ftpdu_v8_1 *pdu_v8_1;
964   struct fts3rec_v8_1 *rec_v8_1;
965 
966   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_1);
967   pdu_v8_1 = (struct ftpdu_v8_1*)&ftpdu->buf;
968   ph = (struct ftpdu_header*)&ftpdu->buf;
969 
970   /* preswap */
971   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
972     SWAPINT32(ph->sysUpTime);
973     SWAPINT32(ph->unix_secs);
974     SWAPINT32(ph->unix_nsecs);
975   }
976 
977   for (n = 0; n < pdu_v8_1->count; ++n) {
978 
979     rec_v8_1 = (struct fts3rec_v8_1*) (ftpdu->ftd.buf +
980       (n*ftpdu->ftd.rec_size));
981 
982     rec_v8_1->unix_nsecs = ph->unix_nsecs;
983     rec_v8_1->unix_secs = ph->unix_secs;
984     rec_v8_1->sysUpTime = ph->sysUpTime;
985 
986     rec_v8_1->engine_type = pdu_v8_1->engine_type;
987     rec_v8_1->engine_type = pdu_v8_1->engine_id;
988 
989     rec_v8_1->dFlows = pdu_v8_1->records[n].dFlows;
990     rec_v8_1->dPkts = pdu_v8_1->records[n].dPkts;
991     rec_v8_1->dOctets = pdu_v8_1->records[n].dOctets;
992     rec_v8_1->First = pdu_v8_1->records[n].First;
993     rec_v8_1->Last = pdu_v8_1->records[n].Last;
994     rec_v8_1->src_as = pdu_v8_1->records[n].src_as;
995     rec_v8_1->dst_as = pdu_v8_1->records[n].dst_as;
996     rec_v8_1->input = pdu_v8_1->records[n].input;
997     rec_v8_1->output = pdu_v8_1->records[n].output;
998 
999     /* perform AS substitution */
1000     rec_v8_1->src_as = (rec_v8_1->src_as) ? rec_v8_1->src_as :
1001       ftpdu->ftd.as_sub;
1002     rec_v8_1->dst_as = (rec_v8_1->dst_as) ? rec_v8_1->dst_as :
1003       ftpdu->ftd.as_sub;
1004 
1005     /* copy in exporter IP */
1006     rec_v8_1->exaddr = ftpdu->ftd.exporter_ip;
1007 
1008     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1009 
1010       SWAPINT32(rec_v8_1->dFlows);
1011       SWAPINT32(rec_v8_1->dPkts);
1012       SWAPINT32(rec_v8_1->dOctets);
1013       SWAPINT32(rec_v8_1->First);
1014       SWAPINT32(rec_v8_1->Last);
1015       SWAPINT16(rec_v8_1->src_as);
1016       SWAPINT16(rec_v8_1->dst_as);
1017       SWAPINT16(rec_v8_1->input);
1018       SWAPINT16(rec_v8_1->output);
1019 
1020       SWAPINT32(rec_v8_1->exaddr);
1021 
1022     }
1023 
1024   } /* for */
1025 
1026   return ftpdu->ftd.count;
1027 
1028 } /* fts3rec_pdu_v8_1_decode */
1029 
1030 /*
1031  * function: fts3rec_pdu_v8_2_decode
1032  *
1033  * subfunction to fts3rec_pdu_decode
1034  *
1035  * returns: # of stream records decoded
1036 */
fts3rec_pdu_v8_2_decode(struct ftpdu * ftpdu)1037 int fts3rec_pdu_v8_2_decode(struct ftpdu *ftpdu)
1038 {
1039   int n;
1040   struct ftpdu_header *ph;
1041   struct ftpdu_v8_2 *pdu_v8_2;
1042   struct fts3rec_v8_2 *rec_v8_2;
1043 
1044   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_2);
1045   pdu_v8_2 = (struct ftpdu_v8_2*)&ftpdu->buf;
1046   ph = (struct ftpdu_header*)&ftpdu->buf;
1047 
1048   /* preswap */
1049   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1050     SWAPINT32(ph->sysUpTime);
1051     SWAPINT32(ph->unix_secs);
1052     SWAPINT32(ph->unix_nsecs);
1053   }
1054 
1055   for (n = 0; n < pdu_v8_2->count; ++n) {
1056 
1057     rec_v8_2 = (struct fts3rec_v8_2*) (ftpdu->ftd.buf +
1058       (n*ftpdu->ftd.rec_size));
1059 
1060     rec_v8_2->unix_nsecs = ph->unix_nsecs;
1061     rec_v8_2->unix_secs = ph->unix_secs;
1062     rec_v8_2->sysUpTime = ph->sysUpTime;
1063 
1064     rec_v8_2->engine_type = pdu_v8_2->engine_type;
1065     rec_v8_2->engine_type = pdu_v8_2->engine_id;
1066 
1067     rec_v8_2->dFlows = pdu_v8_2->records[n].dFlows;
1068     rec_v8_2->dPkts = pdu_v8_2->records[n].dPkts;
1069     rec_v8_2->dOctets = pdu_v8_2->records[n].dOctets;
1070     rec_v8_2->First = pdu_v8_2->records[n].First;
1071     rec_v8_2->Last = pdu_v8_2->records[n].Last;
1072     rec_v8_2->srcport = pdu_v8_2->records[n].srcport;
1073     rec_v8_2->dstport = pdu_v8_2->records[n].dstport;
1074     rec_v8_2->prot = pdu_v8_2->records[n].prot;
1075 
1076     /* copy in exporter IP */
1077     rec_v8_2->exaddr = ftpdu->ftd.exporter_ip;
1078 
1079     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1080 
1081       SWAPINT32(rec_v8_2->dFlows);
1082       SWAPINT32(rec_v8_2->dPkts);
1083       SWAPINT32(rec_v8_2->dOctets);
1084       SWAPINT32(rec_v8_2->First);
1085       SWAPINT32(rec_v8_2->Last);
1086       SWAPINT16(rec_v8_2->srcport);
1087       SWAPINT16(rec_v8_2->dstport);
1088 
1089       SWAPINT32(rec_v8_2->exaddr);
1090 
1091     }
1092 
1093   } /* for */
1094 
1095   return ftpdu->ftd.count;
1096 
1097 } /* fts3rec_pdu_v8_2_decode */
1098 
1099 /*
1100  * function: fts3rec_pdu_v8_3_decode
1101  *
1102  * subfunction to fts3rec_pdu_decode
1103  *
1104  * returns: # of stream records decoded
1105 */
fts3rec_pdu_v8_3_decode(struct ftpdu * ftpdu)1106 int fts3rec_pdu_v8_3_decode(struct ftpdu *ftpdu)
1107 {
1108   int n;
1109   struct ftpdu_header *ph;
1110   struct ftpdu_v8_3 *pdu_v8_3;
1111   struct fts3rec_v8_3 *rec_v8_3;
1112 
1113   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_3);
1114   pdu_v8_3 = (struct ftpdu_v8_3*)&ftpdu->buf;
1115   ph = (struct ftpdu_header*)&ftpdu->buf;
1116 
1117   /* preswap */
1118   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1119     SWAPINT32(ph->sysUpTime);
1120     SWAPINT32(ph->unix_secs);
1121     SWAPINT32(ph->unix_nsecs);
1122   }
1123 
1124   for (n = 0; n < pdu_v8_3->count; ++n) {
1125 
1126     rec_v8_3 = (struct fts3rec_v8_3*) (ftpdu->ftd.buf +
1127       (n*ftpdu->ftd.rec_size));
1128 
1129     rec_v8_3->unix_nsecs = ph->unix_nsecs;
1130     rec_v8_3->unix_secs = ph->unix_secs;
1131     rec_v8_3->sysUpTime = ph->sysUpTime;
1132 
1133     rec_v8_3->engine_type = pdu_v8_3->engine_type;
1134     rec_v8_3->engine_type = pdu_v8_3->engine_id;
1135 
1136     rec_v8_3->dFlows = pdu_v8_3->records[n].dFlows;
1137     rec_v8_3->dPkts = pdu_v8_3->records[n].dPkts;
1138     rec_v8_3->dOctets = pdu_v8_3->records[n].dOctets;
1139     rec_v8_3->First = pdu_v8_3->records[n].First;
1140     rec_v8_3->Last = pdu_v8_3->records[n].Last;
1141     rec_v8_3->srcaddr = pdu_v8_3->records[n].src_prefix;
1142     rec_v8_3->src_mask = pdu_v8_3->records[n].src_mask;
1143     rec_v8_3->src_as = pdu_v8_3->records[n].src_as;
1144     rec_v8_3->input = pdu_v8_3->records[n].input;
1145 
1146     /* perform AS substitution */
1147     rec_v8_3->src_as = (rec_v8_3->src_as) ? rec_v8_3->src_as :
1148       ftpdu->ftd.as_sub;
1149 
1150     /* copy in exporter IP */
1151     rec_v8_3->exaddr = ftpdu->ftd.exporter_ip;
1152 
1153     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1154 
1155       SWAPINT32(rec_v8_3->dFlows);
1156       SWAPINT32(rec_v8_3->dPkts);
1157       SWAPINT32(rec_v8_3->dOctets);
1158       SWAPINT32(rec_v8_3->First);
1159       SWAPINT32(rec_v8_3->Last);
1160       SWAPINT32(rec_v8_3->srcaddr);
1161       SWAPINT16(rec_v8_3->src_as);
1162       SWAPINT16(rec_v8_3->input);
1163 
1164       SWAPINT32(rec_v8_3->exaddr);
1165 
1166     }
1167 
1168   } /* for */
1169 
1170   return ftpdu->ftd.count;
1171 
1172 } /* fts3rec_pdu_v8_3_decode */
1173 
1174 /*
1175  * function: fts3rec_pdu_v8_4_decode
1176  *
1177  * subfunction to fts3rec_pdu_decode
1178  *
1179  * returns: # of stream records decoded
1180 */
fts3rec_pdu_v8_4_decode(struct ftpdu * ftpdu)1181 int fts3rec_pdu_v8_4_decode(struct ftpdu *ftpdu)
1182 {
1183   int n;
1184   struct ftpdu_header *ph;
1185   struct ftpdu_v8_4 *pdu_v8_4;
1186   struct fts3rec_v8_4 *rec_v8_4;
1187 
1188   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_4);
1189   pdu_v8_4 = (struct ftpdu_v8_4*)&ftpdu->buf;
1190   ph = (struct ftpdu_header*)&ftpdu->buf;
1191 
1192   /* preswap */
1193   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1194     SWAPINT32(ph->sysUpTime);
1195     SWAPINT32(ph->unix_secs);
1196     SWAPINT32(ph->unix_nsecs);
1197   }
1198 
1199   for (n = 0; n < pdu_v8_4->count; ++n) {
1200 
1201     rec_v8_4 = (struct fts3rec_v8_4*) (ftpdu->ftd.buf +
1202       (n*ftpdu->ftd.rec_size));
1203 
1204     rec_v8_4->unix_nsecs = ph->unix_nsecs;
1205     rec_v8_4->unix_secs = ph->unix_secs;
1206     rec_v8_4->sysUpTime = ph->sysUpTime;
1207 
1208     rec_v8_4->engine_type = pdu_v8_4->engine_type;
1209     rec_v8_4->engine_type = pdu_v8_4->engine_id;
1210 
1211     rec_v8_4->dFlows = pdu_v8_4->records[n].dFlows;
1212     rec_v8_4->dPkts = pdu_v8_4->records[n].dPkts;
1213     rec_v8_4->dOctets = pdu_v8_4->records[n].dOctets;
1214     rec_v8_4->First = pdu_v8_4->records[n].First;
1215     rec_v8_4->Last = pdu_v8_4->records[n].Last;
1216     rec_v8_4->dstaddr = pdu_v8_4->records[n].dst_prefix;
1217     rec_v8_4->dst_mask = pdu_v8_4->records[n].dst_mask;
1218     rec_v8_4->dst_as = pdu_v8_4->records[n].dst_as;
1219     rec_v8_4->output = pdu_v8_4->records[n].output;
1220 
1221     /* perform AS substitution */
1222     rec_v8_4->dst_as = (rec_v8_4->dst_as) ? rec_v8_4->dst_as :
1223       ftpdu->ftd.as_sub;
1224 
1225     /* copy in exporter IP */
1226     rec_v8_4->exaddr = ftpdu->ftd.exporter_ip;
1227 
1228     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1229 
1230       SWAPINT32(rec_v8_4->dFlows);
1231       SWAPINT32(rec_v8_4->dPkts);
1232       SWAPINT32(rec_v8_4->dOctets);
1233       SWAPINT32(rec_v8_4->First);
1234       SWAPINT32(rec_v8_4->Last);
1235       SWAPINT32(rec_v8_4->dstaddr);
1236       SWAPINT16(rec_v8_4->dst_as);
1237       SWAPINT16(rec_v8_4->output);
1238 
1239       SWAPINT32(rec_v8_4->exaddr);
1240 
1241     }
1242 
1243   } /* for */
1244 
1245   return ftpdu->ftd.count;
1246 
1247 } /* fts3rec_pdu_v8_4_decode */
1248 
1249 /*
1250  * function: fts3rec_pdu_v8_5_decode
1251  *
1252  * subfunction to fts3rec_pdu_decode
1253  *
1254  * returns: # of stream records decoded
1255 */
fts3rec_pdu_v8_5_decode(struct ftpdu * ftpdu)1256 int fts3rec_pdu_v8_5_decode(struct ftpdu *ftpdu)
1257 {
1258   int n;
1259   struct ftpdu_header *ph;
1260   struct ftpdu_v8_5 *pdu_v8_5;
1261   struct fts3rec_v8_5 *rec_v8_5;
1262 
1263   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_5);
1264   pdu_v8_5 = (struct ftpdu_v8_5*)&ftpdu->buf;
1265   ph = (struct ftpdu_header*)&ftpdu->buf;
1266 
1267   /* preswap */
1268   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1269     SWAPINT32(ph->sysUpTime);
1270     SWAPINT32(ph->unix_secs);
1271     SWAPINT32(ph->unix_nsecs);
1272   }
1273 
1274   for (n = 0; n < pdu_v8_5->count; ++n) {
1275 
1276     rec_v8_5 = (struct fts3rec_v8_5*) (ftpdu->ftd.buf +
1277       (n*ftpdu->ftd.rec_size));
1278 
1279     rec_v8_5->unix_nsecs = ph->unix_nsecs;
1280     rec_v8_5->unix_secs = ph->unix_secs;
1281     rec_v8_5->sysUpTime = ph->sysUpTime;
1282 
1283     rec_v8_5->engine_type = pdu_v8_5->engine_type;
1284     rec_v8_5->engine_type = pdu_v8_5->engine_id;
1285 
1286     rec_v8_5->dFlows = pdu_v8_5->records[n].dFlows;
1287     rec_v8_5->dPkts = pdu_v8_5->records[n].dPkts;
1288     rec_v8_5->dOctets = pdu_v8_5->records[n].dOctets;
1289     rec_v8_5->First = pdu_v8_5->records[n].First;
1290     rec_v8_5->Last = pdu_v8_5->records[n].Last;
1291     rec_v8_5->srcaddr = pdu_v8_5->records[n].src_prefix;
1292     rec_v8_5->dstaddr = pdu_v8_5->records[n].dst_prefix;
1293     rec_v8_5->src_mask = pdu_v8_5->records[n].src_mask;
1294     rec_v8_5->dst_mask = pdu_v8_5->records[n].dst_mask;
1295     rec_v8_5->src_as = pdu_v8_5->records[n].src_as;
1296     rec_v8_5->dst_as = pdu_v8_5->records[n].dst_as;
1297     rec_v8_5->input = pdu_v8_5->records[n].input;
1298     rec_v8_5->output = pdu_v8_5->records[n].output;
1299 
1300     /* perform AS substitution */
1301     rec_v8_5->src_as = (rec_v8_5->src_as) ? rec_v8_5->src_as :
1302       ftpdu->ftd.as_sub;
1303     rec_v8_5->dst_as = (rec_v8_5->dst_as) ? rec_v8_5->dst_as :
1304       ftpdu->ftd.as_sub;
1305 
1306     /* copy in exporter IP */
1307     rec_v8_5->exaddr = ftpdu->ftd.exporter_ip;
1308 
1309     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1310 
1311       SWAPINT32(rec_v8_5->dFlows);
1312       SWAPINT32(rec_v8_5->dPkts);
1313       SWAPINT32(rec_v8_5->dOctets);
1314       SWAPINT32(rec_v8_5->First);
1315       SWAPINT32(rec_v8_5->Last);
1316       SWAPINT32(rec_v8_5->srcaddr);
1317       SWAPINT32(rec_v8_5->dstaddr);
1318       SWAPINT16(rec_v8_5->src_as);
1319       SWAPINT16(rec_v8_5->dst_as);
1320       SWAPINT16(rec_v8_5->input);
1321       SWAPINT16(rec_v8_5->output);
1322 
1323       SWAPINT32(rec_v8_5->exaddr);
1324 
1325     }
1326 
1327   } /* for */
1328 
1329   return ftpdu->ftd.count;
1330 
1331 } /* fts3rec_pdu_v8_5_decode */
1332 
1333 /*
1334  * function: fts3rec_pdu_v8_6_decode
1335  *
1336  * subfunction to fts3rec_pdu_decode
1337  *
1338  * returns: # of stream records decoded
1339 */
fts3rec_pdu_v8_6_decode(struct ftpdu * ftpdu)1340 int fts3rec_pdu_v8_6_decode(struct ftpdu *ftpdu)
1341 {
1342   int n;
1343   struct ftpdu_header *ph;
1344   struct ftpdu_v8_6 *pdu_v8_6;
1345   struct fts3rec_v8_6 *rec_v8_6;
1346 
1347   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_6);
1348   pdu_v8_6 = (struct ftpdu_v8_6*)&ftpdu->buf;
1349   ph = (struct ftpdu_header*)&ftpdu->buf;
1350 
1351   /* preswap */
1352   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1353     SWAPINT32(ph->sysUpTime);
1354     SWAPINT32(ph->unix_secs);
1355     SWAPINT32(ph->unix_nsecs);
1356   }
1357 
1358   for (n = 0; n < pdu_v8_6->count; ++n) {
1359 
1360     rec_v8_6 = (struct fts3rec_v8_6*) (ftpdu->ftd.buf +
1361       (n*ftpdu->ftd.rec_size));
1362 
1363     rec_v8_6->unix_nsecs = ph->unix_nsecs;
1364     rec_v8_6->unix_secs = ph->unix_secs;
1365     rec_v8_6->sysUpTime = ph->sysUpTime;
1366 
1367     rec_v8_6->engine_type = pdu_v8_6->engine_type;
1368     rec_v8_6->engine_type = pdu_v8_6->engine_id;
1369 
1370     rec_v8_6->dPkts = pdu_v8_6->records[n].dPkts;
1371     rec_v8_6->dOctets = pdu_v8_6->records[n].dOctets;
1372     rec_v8_6->First = pdu_v8_6->records[n].First;
1373     rec_v8_6->Last = pdu_v8_6->records[n].Last;
1374     rec_v8_6->dstaddr = pdu_v8_6->records[n].dstaddr;
1375     rec_v8_6->extra_pkts = pdu_v8_6->records[n].extra_pkts;
1376     rec_v8_6->router_sc = pdu_v8_6->records[n].router_sc;
1377     rec_v8_6->output = pdu_v8_6->records[n].output;
1378     rec_v8_6->tos = pdu_v8_6->records[n].tos;
1379     rec_v8_6->marked_tos = pdu_v8_6->records[n].marked_tos;
1380 
1381     /* copy in exporter IP */
1382     rec_v8_6->exaddr = ftpdu->ftd.exporter_ip;
1383 
1384     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1385 
1386       SWAPINT32(rec_v8_6->dPkts);
1387       SWAPINT32(rec_v8_6->dOctets);
1388       SWAPINT32(rec_v8_6->First);
1389       SWAPINT32(rec_v8_6->Last);
1390       SWAPINT32(rec_v8_6->dstaddr);
1391       SWAPINT32(rec_v8_6->extra_pkts);
1392       SWAPINT32(rec_v8_6->router_sc);
1393       SWAPINT16(rec_v8_6->output);
1394 
1395       SWAPINT32(rec_v8_6->exaddr);
1396 
1397     }
1398 
1399   } /* for */
1400 
1401   return ftpdu->ftd.count;
1402 
1403 } /* fts3rec_pdu_v8_6_decode */
1404 
1405 /*
1406  * function: fts3rec_pdu_v8_7_decode
1407  *
1408  * subfunction to fts3rec_pdu_decode
1409  *
1410  * returns: # of stream records decoded
1411 */
fts3rec_pdu_v8_7_decode(struct ftpdu * ftpdu)1412 int fts3rec_pdu_v8_7_decode(struct ftpdu *ftpdu)
1413 {
1414   int n;
1415   struct ftpdu_header *ph;
1416   struct ftpdu_v8_7 *pdu_v8_7;
1417   struct fts3rec_v8_7 *rec_v8_7;
1418 
1419   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_7);
1420   pdu_v8_7 = (struct ftpdu_v8_7*)&ftpdu->buf;
1421   ph = (struct ftpdu_header*)&ftpdu->buf;
1422 
1423   /* preswap */
1424   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1425     SWAPINT32(ph->sysUpTime);
1426     SWAPINT32(ph->unix_secs);
1427     SWAPINT32(ph->unix_nsecs);
1428   }
1429 
1430   for (n = 0; n < pdu_v8_7->count; ++n) {
1431 
1432     rec_v8_7 = (struct fts3rec_v8_7*) (ftpdu->ftd.buf +
1433       (n*ftpdu->ftd.rec_size));
1434 
1435     rec_v8_7->unix_nsecs = ph->unix_nsecs;
1436     rec_v8_7->unix_secs = ph->unix_secs;
1437     rec_v8_7->sysUpTime = ph->sysUpTime;
1438 
1439     rec_v8_7->engine_type = pdu_v8_7->engine_type;
1440     rec_v8_7->engine_type = pdu_v8_7->engine_id;
1441 
1442     rec_v8_7->dPkts = pdu_v8_7->records[n].dPkts;
1443     rec_v8_7->dOctets = pdu_v8_7->records[n].dOctets;
1444     rec_v8_7->First = pdu_v8_7->records[n].First;
1445     rec_v8_7->Last = pdu_v8_7->records[n].Last;
1446     rec_v8_7->dstaddr = pdu_v8_7->records[n].dstaddr;
1447     rec_v8_7->srcaddr = pdu_v8_7->records[n].srcaddr;
1448     rec_v8_7->extra_pkts = pdu_v8_7->records[n].extra_pkts;
1449     rec_v8_7->router_sc = pdu_v8_7->records[n].router_sc;
1450     rec_v8_7->output = pdu_v8_7->records[n].output;
1451     rec_v8_7->input = pdu_v8_7->records[n].input;
1452     rec_v8_7->tos = pdu_v8_7->records[n].tos;
1453     rec_v8_7->marked_tos = pdu_v8_7->records[n].marked_tos;
1454 
1455     /* copy in exporter IP */
1456     rec_v8_7->exaddr = ftpdu->ftd.exporter_ip;
1457 
1458     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1459 
1460       SWAPINT32(rec_v8_7->dPkts);
1461       SWAPINT32(rec_v8_7->dOctets);
1462       SWAPINT32(rec_v8_7->First);
1463       SWAPINT32(rec_v8_7->Last);
1464       SWAPINT32(rec_v8_7->dstaddr);
1465       SWAPINT32(rec_v8_7->srcaddr);
1466       SWAPINT32(rec_v8_7->extra_pkts);
1467       SWAPINT32(rec_v8_7->router_sc);
1468       SWAPINT16(rec_v8_7->output);
1469       SWAPINT16(rec_v8_7->input);
1470 
1471       SWAPINT32(rec_v8_7->exaddr);
1472 
1473     }
1474 
1475   } /* for */
1476 
1477   return ftpdu->ftd.count;
1478 
1479 } /* fts3rec_pdu_v8_7_decode */
1480 
1481 /*
1482  * function: fts3rec_pdu_v8_8_decode
1483  *
1484  * subfunction to fts3rec_pdu_decode
1485  *
1486  * returns: # of stream records decoded
1487 */
fts3rec_pdu_v8_8_decode(struct ftpdu * ftpdu)1488 int fts3rec_pdu_v8_8_decode(struct ftpdu *ftpdu)
1489 {
1490   int n;
1491   struct ftpdu_header *ph;
1492   struct ftpdu_v8_8 *pdu_v8_8;
1493   struct fts3rec_v8_8 *rec_v8_8;
1494 
1495   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_8);
1496   pdu_v8_8 = (struct ftpdu_v8_8*)&ftpdu->buf;
1497   ph = (struct ftpdu_header*)&ftpdu->buf;
1498 
1499   /* preswap */
1500   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1501     SWAPINT32(ph->sysUpTime);
1502     SWAPINT32(ph->unix_secs);
1503     SWAPINT32(ph->unix_nsecs);
1504   }
1505 
1506   for (n = 0; n < pdu_v8_8->count; ++n) {
1507 
1508     rec_v8_8 = (struct fts3rec_v8_8*) (ftpdu->ftd.buf +
1509       (n*ftpdu->ftd.rec_size));
1510 
1511     rec_v8_8->unix_nsecs = ph->unix_nsecs;
1512     rec_v8_8->unix_secs = ph->unix_secs;
1513     rec_v8_8->sysUpTime = ph->sysUpTime;
1514 
1515     rec_v8_8->engine_type = pdu_v8_8->engine_type;
1516     rec_v8_8->engine_type = pdu_v8_8->engine_id;
1517 
1518     rec_v8_8->dstaddr = pdu_v8_8->records[n].dstaddr;
1519     rec_v8_8->srcaddr = pdu_v8_8->records[n].srcaddr;
1520     rec_v8_8->dstport = pdu_v8_8->records[n].dstport;
1521     rec_v8_8->srcport = pdu_v8_8->records[n].srcport;
1522     rec_v8_8->dPkts = pdu_v8_8->records[n].dPkts;
1523     rec_v8_8->dOctets = pdu_v8_8->records[n].dOctets;
1524     rec_v8_8->First = pdu_v8_8->records[n].First;
1525     rec_v8_8->Last = pdu_v8_8->records[n].Last;
1526     rec_v8_8->output = pdu_v8_8->records[n].output;
1527     rec_v8_8->input = pdu_v8_8->records[n].input;
1528     rec_v8_8->tos = pdu_v8_8->records[n].tos;
1529     rec_v8_8->prot = pdu_v8_8->records[n].prot;
1530     rec_v8_8->marked_tos = pdu_v8_8->records[n].marked_tos;
1531     rec_v8_8->extra_pkts = pdu_v8_8->records[n].extra_pkts;
1532     rec_v8_8->router_sc = pdu_v8_8->records[n].router_sc;
1533 
1534     /* copy in exporter IP */
1535     rec_v8_8->exaddr = ftpdu->ftd.exporter_ip;
1536 
1537     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1538 
1539       SWAPINT32(rec_v8_8->dstaddr);
1540       SWAPINT32(rec_v8_8->srcaddr);
1541       SWAPINT16(rec_v8_8->dstport);
1542       SWAPINT16(rec_v8_8->srcport);
1543       SWAPINT32(rec_v8_8->dPkts);
1544       SWAPINT32(rec_v8_8->dOctets);
1545       SWAPINT32(rec_v8_8->First);
1546       SWAPINT32(rec_v8_8->Last);
1547       SWAPINT16(rec_v8_8->output);
1548       SWAPINT16(rec_v8_8->input);
1549       SWAPINT32(rec_v8_8->extra_pkts);
1550       SWAPINT32(rec_v8_8->router_sc);
1551 
1552       SWAPINT32(rec_v8_8->exaddr);
1553 
1554     }
1555 
1556   } /* for */
1557 
1558   return ftpdu->ftd.count;
1559 
1560 } /* fts3rec_pdu_v8_8_decode */
1561 
1562 /*
1563  * function: fts3rec_pdu_v8_9_decode
1564  *
1565  * subfunction to fts3rec_pdu_decode
1566  *
1567  * returns: # of stream records decoded
1568 */
fts3rec_pdu_v8_9_decode(struct ftpdu * ftpdu)1569 int fts3rec_pdu_v8_9_decode(struct ftpdu *ftpdu)
1570 {
1571   int n;
1572   struct ftpdu_header *ph;
1573   struct ftpdu_v8_9 *pdu_v8_9;
1574   struct fts3rec_v8_9 *rec_v8_9;
1575 
1576   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_9);
1577   pdu_v8_9 = (struct ftpdu_v8_9*)&ftpdu->buf;
1578   ph = (struct ftpdu_header*)&ftpdu->buf;
1579 
1580   /* preswap */
1581   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1582     SWAPINT32(ph->sysUpTime);
1583     SWAPINT32(ph->unix_secs);
1584     SWAPINT32(ph->unix_nsecs);
1585   }
1586 
1587   for (n = 0; n < pdu_v8_9->count; ++n) {
1588 
1589     rec_v8_9 = (struct fts3rec_v8_9*) (ftpdu->ftd.buf +
1590       (n*ftpdu->ftd.rec_size));
1591 
1592     rec_v8_9->unix_nsecs = ph->unix_nsecs;
1593     rec_v8_9->unix_secs = ph->unix_secs;
1594     rec_v8_9->sysUpTime = ph->sysUpTime;
1595 
1596     rec_v8_9->engine_type = pdu_v8_9->engine_type;
1597     rec_v8_9->engine_type = pdu_v8_9->engine_id;
1598 
1599     rec_v8_9->dFlows = pdu_v8_9->records[n].dFlows;
1600     rec_v8_9->dPkts = pdu_v8_9->records[n].dPkts;
1601     rec_v8_9->dOctets = pdu_v8_9->records[n].dOctets;
1602     rec_v8_9->First = pdu_v8_9->records[n].First;
1603     rec_v8_9->Last = pdu_v8_9->records[n].Last;
1604     rec_v8_9->src_as = pdu_v8_9->records[n].src_as;
1605     rec_v8_9->dst_as = pdu_v8_9->records[n].dst_as;
1606     rec_v8_9->input = pdu_v8_9->records[n].input;
1607     rec_v8_9->output = pdu_v8_9->records[n].output;
1608     rec_v8_9->tos = pdu_v8_9->records[n].tos;
1609 
1610     /* perform AS substitution */
1611     rec_v8_9->src_as = (rec_v8_9->src_as) ? rec_v8_9->src_as :
1612       ftpdu->ftd.as_sub;
1613     rec_v8_9->dst_as = (rec_v8_9->dst_as) ? rec_v8_9->dst_as :
1614       ftpdu->ftd.as_sub;
1615 
1616     /* copy in exporter IP */
1617     rec_v8_9->exaddr = ftpdu->ftd.exporter_ip;
1618 
1619     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1620 
1621       SWAPINT32(rec_v8_9->dFlows);
1622       SWAPINT32(rec_v8_9->dPkts);
1623       SWAPINT32(rec_v8_9->dOctets);
1624       SWAPINT32(rec_v8_9->First);
1625       SWAPINT32(rec_v8_9->Last);
1626       SWAPINT16(rec_v8_9->src_as);
1627       SWAPINT16(rec_v8_9->dst_as);
1628       SWAPINT16(rec_v8_9->input);
1629       SWAPINT16(rec_v8_9->output);
1630 
1631       SWAPINT32(rec_v8_9->exaddr);
1632 
1633     }
1634 
1635   } /* for */
1636 
1637   return ftpdu->ftd.count;
1638 
1639 } /* fts3rec_pdu_v8_9_decode */
1640 
1641 /*
1642  * function: fts3rec_pdu_v8_10_decode
1643  *
1644  * subfunction to fts3rec_pdu_decode
1645  *
1646  * returns: # of stream records decoded
1647 */
fts3rec_pdu_v8_10_decode(struct ftpdu * ftpdu)1648 int fts3rec_pdu_v8_10_decode(struct ftpdu *ftpdu)
1649 {
1650   int n;
1651   struct ftpdu_header *ph;
1652   struct ftpdu_v8_10 *pdu_v8_10;
1653   struct fts3rec_v8_10 *rec_v8_10;
1654 
1655   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_10);
1656   pdu_v8_10 = (struct ftpdu_v8_10*)&ftpdu->buf;
1657   ph = (struct ftpdu_header*)&ftpdu->buf;
1658 
1659   /* preswap */
1660   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1661     SWAPINT32(ph->sysUpTime);
1662     SWAPINT32(ph->unix_secs);
1663     SWAPINT32(ph->unix_nsecs);
1664   }
1665 
1666   for (n = 0; n < pdu_v8_10->count; ++n) {
1667 
1668     rec_v8_10 = (struct fts3rec_v8_10*) (ftpdu->ftd.buf +
1669       (n*ftpdu->ftd.rec_size));
1670 
1671     rec_v8_10->unix_nsecs = ph->unix_nsecs;
1672     rec_v8_10->unix_secs = ph->unix_secs;
1673     rec_v8_10->sysUpTime = ph->sysUpTime;
1674 
1675     rec_v8_10->engine_type = pdu_v8_10->engine_type;
1676     rec_v8_10->engine_type = pdu_v8_10->engine_id;
1677 
1678     rec_v8_10->dFlows = pdu_v8_10->records[n].dFlows;
1679     rec_v8_10->dPkts = pdu_v8_10->records[n].dPkts;
1680     rec_v8_10->dOctets = pdu_v8_10->records[n].dOctets;
1681     rec_v8_10->First = pdu_v8_10->records[n].First;
1682     rec_v8_10->Last = pdu_v8_10->records[n].Last;
1683     rec_v8_10->prot = pdu_v8_10->records[n].prot;
1684     rec_v8_10->tos = pdu_v8_10->records[n].tos;
1685     rec_v8_10->srcport = pdu_v8_10->records[n].srcport;
1686     rec_v8_10->dstport = pdu_v8_10->records[n].dstport;
1687     rec_v8_10->prot = pdu_v8_10->records[n].prot;
1688 
1689     /* copy in exporter IP */
1690     rec_v8_10->exaddr = ftpdu->ftd.exporter_ip;
1691 
1692     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1693 
1694       SWAPINT32(rec_v8_10->dFlows);
1695       SWAPINT32(rec_v8_10->dPkts);
1696       SWAPINT32(rec_v8_10->dOctets);
1697       SWAPINT32(rec_v8_10->First);
1698       SWAPINT32(rec_v8_10->Last);
1699       SWAPINT16(rec_v8_10->srcport);
1700       SWAPINT16(rec_v8_10->dstport);
1701 
1702       SWAPINT32(rec_v8_10->exaddr);
1703 
1704     }
1705 
1706   } /* for */
1707 
1708   return ftpdu->ftd.count;
1709 
1710 } /* fts3rec_pdu_v8_10_decode */
1711 
1712 /*
1713  * function: fts3rec_pdu_v8_11_decode
1714  *
1715  * subfunction to fts3rec_pdu_decode
1716  *
1717  * returns: # of stream records decoded
1718 */
fts3rec_pdu_v8_11_decode(struct ftpdu * ftpdu)1719 int fts3rec_pdu_v8_11_decode(struct ftpdu *ftpdu)
1720 {
1721   int n;
1722   struct ftpdu_header *ph;
1723   struct ftpdu_v8_11 *pdu_v8_11;
1724   struct fts3rec_v8_11 *rec_v8_11;
1725 
1726   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_11);
1727   pdu_v8_11 = (struct ftpdu_v8_11*)&ftpdu->buf;
1728   ph = (struct ftpdu_header*)&ftpdu->buf;
1729 
1730   /* preswap */
1731   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1732     SWAPINT32(ph->sysUpTime);
1733     SWAPINT32(ph->unix_secs);
1734     SWAPINT32(ph->unix_nsecs);
1735   }
1736 
1737   for (n = 0; n < pdu_v8_11->count; ++n) {
1738 
1739     rec_v8_11 = (struct fts3rec_v8_11*) (ftpdu->ftd.buf +
1740       (n*ftpdu->ftd.rec_size));
1741 
1742     rec_v8_11->unix_nsecs = ph->unix_nsecs;
1743     rec_v8_11->unix_secs = ph->unix_secs;
1744     rec_v8_11->sysUpTime = ph->sysUpTime;
1745 
1746     rec_v8_11->engine_type = pdu_v8_11->engine_type;
1747     rec_v8_11->engine_type = pdu_v8_11->engine_id;
1748 
1749     rec_v8_11->dFlows = pdu_v8_11->records[n].dFlows;
1750     rec_v8_11->dPkts = pdu_v8_11->records[n].dPkts;
1751     rec_v8_11->dOctets = pdu_v8_11->records[n].dOctets;
1752     rec_v8_11->First = pdu_v8_11->records[n].First;
1753     rec_v8_11->Last = pdu_v8_11->records[n].Last;
1754     rec_v8_11->srcaddr = pdu_v8_11->records[n].src_prefix;
1755     rec_v8_11->src_mask = pdu_v8_11->records[n].src_mask;
1756     rec_v8_11->tos = pdu_v8_11->records[n].tos;
1757     rec_v8_11->src_as = pdu_v8_11->records[n].src_as;
1758     rec_v8_11->input = pdu_v8_11->records[n].input;
1759 
1760     /* perform AS substitution */
1761     rec_v8_11->src_as = (rec_v8_11->src_as) ? rec_v8_11->src_as :
1762       ftpdu->ftd.as_sub;
1763 
1764     /* copy in exporter IP */
1765     rec_v8_11->exaddr = ftpdu->ftd.exporter_ip;
1766 
1767     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1768 
1769       SWAPINT32(rec_v8_11->dFlows);
1770       SWAPINT32(rec_v8_11->dPkts);
1771       SWAPINT32(rec_v8_11->dOctets);
1772       SWAPINT32(rec_v8_11->First);
1773       SWAPINT32(rec_v8_11->Last);
1774       SWAPINT32(rec_v8_11->srcaddr);
1775       SWAPINT16(rec_v8_11->src_as);
1776       SWAPINT16(rec_v8_11->input);
1777 
1778       SWAPINT32(rec_v8_11->exaddr);
1779 
1780     }
1781 
1782   } /* for */
1783 
1784   return ftpdu->ftd.count;
1785 
1786 } /* fts3rec_pdu_v8_11_decode */
1787 
1788 /*
1789  * function: fts3rec_pdu_v8_12_decode
1790  *
1791  * subfunction to fts3rec_pdu_decode
1792  *
1793  * returns: # of stream records decoded
1794 */
fts3rec_pdu_v8_12_decode(struct ftpdu * ftpdu)1795 int fts3rec_pdu_v8_12_decode(struct ftpdu *ftpdu)
1796 {
1797   int n;
1798   struct ftpdu_header *ph;
1799   struct ftpdu_v8_12 *pdu_v8_12;
1800   struct fts3rec_v8_12 *rec_v8_12;
1801 
1802   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_12);
1803   pdu_v8_12 = (struct ftpdu_v8_12*)&ftpdu->buf;
1804   ph = (struct ftpdu_header*)&ftpdu->buf;
1805 
1806   /* preswap */
1807   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1808     SWAPINT32(ph->sysUpTime);
1809     SWAPINT32(ph->unix_secs);
1810     SWAPINT32(ph->unix_nsecs);
1811   }
1812 
1813   for (n = 0; n < pdu_v8_12->count; ++n) {
1814 
1815     rec_v8_12 = (struct fts3rec_v8_12*) (ftpdu->ftd.buf +
1816       (n*ftpdu->ftd.rec_size));
1817 
1818     rec_v8_12->unix_nsecs = ph->unix_nsecs;
1819     rec_v8_12->unix_secs = ph->unix_secs;
1820     rec_v8_12->sysUpTime = ph->sysUpTime;
1821 
1822     rec_v8_12->engine_type = pdu_v8_12->engine_type;
1823     rec_v8_12->engine_type = pdu_v8_12->engine_id;
1824 
1825     rec_v8_12->dFlows = pdu_v8_12->records[n].dFlows;
1826     rec_v8_12->dPkts = pdu_v8_12->records[n].dPkts;
1827     rec_v8_12->dOctets = pdu_v8_12->records[n].dOctets;
1828     rec_v8_12->First = pdu_v8_12->records[n].First;
1829     rec_v8_12->Last = pdu_v8_12->records[n].Last;
1830     rec_v8_12->dstaddr = pdu_v8_12->records[n].dst_prefix;
1831     rec_v8_12->tos = pdu_v8_12->records[n].tos;
1832     rec_v8_12->dst_mask = pdu_v8_12->records[n].dst_mask;
1833     rec_v8_12->dst_as = pdu_v8_12->records[n].dst_as;
1834     rec_v8_12->output = pdu_v8_12->records[n].output;
1835 
1836     /* perform AS substitution */
1837     rec_v8_12->dst_as = (rec_v8_12->dst_as) ? rec_v8_12->dst_as :
1838       ftpdu->ftd.as_sub;
1839 
1840     /* copy in exporter IP */
1841     rec_v8_12->exaddr = ftpdu->ftd.exporter_ip;
1842 
1843     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1844 
1845       SWAPINT32(rec_v8_12->dFlows);
1846       SWAPINT32(rec_v8_12->dPkts);
1847       SWAPINT32(rec_v8_12->dOctets);
1848       SWAPINT32(rec_v8_12->First);
1849       SWAPINT32(rec_v8_12->Last);
1850       SWAPINT32(rec_v8_12->dstaddr);
1851       SWAPINT16(rec_v8_12->dst_as);
1852       SWAPINT16(rec_v8_12->output);
1853 
1854       SWAPINT32(rec_v8_12->exaddr);
1855 
1856     }
1857 
1858   } /* for */
1859 
1860   return ftpdu->ftd.count;
1861 
1862 } /* fts3rec_pdu_v8_12_decode */
1863 
1864 /*
1865  * function: fts3rec_pdu_v8_13_decode
1866  *
1867  * subfunction to fts3rec_pdu_decode
1868  *
1869  * returns: # of stream records decoded
1870 */
fts3rec_pdu_v8_13_decode(struct ftpdu * ftpdu)1871 int fts3rec_pdu_v8_13_decode(struct ftpdu *ftpdu)
1872 {
1873   int n;
1874   struct ftpdu_header *ph;
1875   struct ftpdu_v8_13 *pdu_v8_13;
1876   struct fts3rec_v8_13 *rec_v8_13;
1877 
1878   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_13);
1879   pdu_v8_13 = (struct ftpdu_v8_13*)&ftpdu->buf;
1880   ph = (struct ftpdu_header*)&ftpdu->buf;
1881 
1882   /* preswap */
1883   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1884     SWAPINT32(ph->sysUpTime);
1885     SWAPINT32(ph->unix_secs);
1886     SWAPINT32(ph->unix_nsecs);
1887   }
1888 
1889   for (n = 0; n < pdu_v8_13->count; ++n) {
1890 
1891     rec_v8_13 = (struct fts3rec_v8_13*) (ftpdu->ftd.buf +
1892       (n*ftpdu->ftd.rec_size));
1893 
1894     rec_v8_13->unix_nsecs = ph->unix_nsecs;
1895     rec_v8_13->unix_secs = ph->unix_secs;
1896     rec_v8_13->sysUpTime = ph->sysUpTime;
1897 
1898     rec_v8_13->engine_type = pdu_v8_13->engine_type;
1899     rec_v8_13->engine_type = pdu_v8_13->engine_id;
1900 
1901     rec_v8_13->dFlows = pdu_v8_13->records[n].dFlows;
1902     rec_v8_13->dPkts = pdu_v8_13->records[n].dPkts;
1903     rec_v8_13->dOctets = pdu_v8_13->records[n].dOctets;
1904     rec_v8_13->First = pdu_v8_13->records[n].First;
1905     rec_v8_13->Last = pdu_v8_13->records[n].Last;
1906     rec_v8_13->srcaddr = pdu_v8_13->records[n].src_prefix;
1907     rec_v8_13->dstaddr = pdu_v8_13->records[n].dst_prefix;
1908     rec_v8_13->src_mask = pdu_v8_13->records[n].src_mask;
1909     rec_v8_13->dst_mask = pdu_v8_13->records[n].dst_mask;
1910     rec_v8_13->tos = pdu_v8_13->records[n].tos;
1911     rec_v8_13->src_as = pdu_v8_13->records[n].src_as;
1912     rec_v8_13->dst_as = pdu_v8_13->records[n].dst_as;
1913     rec_v8_13->input = pdu_v8_13->records[n].input;
1914     rec_v8_13->output = pdu_v8_13->records[n].output;
1915 
1916     /* perform AS substitution */
1917     rec_v8_13->src_as = (rec_v8_13->src_as) ? rec_v8_13->src_as :
1918       ftpdu->ftd.as_sub;
1919     rec_v8_13->dst_as = (rec_v8_13->dst_as) ? rec_v8_13->dst_as :
1920       ftpdu->ftd.as_sub;
1921 
1922     /* copy in exporter IP */
1923     rec_v8_13->exaddr = ftpdu->ftd.exporter_ip;
1924 
1925     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1926 
1927       SWAPINT32(rec_v8_13->dFlows);
1928       SWAPINT32(rec_v8_13->dPkts);
1929       SWAPINT32(rec_v8_13->dOctets);
1930       SWAPINT32(rec_v8_13->First);
1931       SWAPINT32(rec_v8_13->Last);
1932       SWAPINT32(rec_v8_13->srcaddr);
1933       SWAPINT32(rec_v8_13->dstaddr);
1934       SWAPINT16(rec_v8_13->src_as);
1935       SWAPINT16(rec_v8_13->dst_as);
1936       SWAPINT16(rec_v8_13->input);
1937       SWAPINT16(rec_v8_13->output);
1938 
1939       SWAPINT32(rec_v8_13->exaddr);
1940 
1941     }
1942 
1943   } /* for */
1944 
1945   return ftpdu->ftd.count;
1946 
1947 } /* fts3rec_pdu_v8_13_decode */
1948 
1949 /*
1950  * function: fts3rec_pdu_v8_14_decode
1951  *
1952  * subfunction to fts3rec_pdu_decode
1953  *
1954  * returns: # of stream records decoded
1955 */
fts3rec_pdu_v8_14_decode(struct ftpdu * ftpdu)1956 int fts3rec_pdu_v8_14_decode(struct ftpdu *ftpdu)
1957 {
1958   int n;
1959   struct ftpdu_header *ph;
1960   struct ftpdu_v8_14 *pdu_v8_14;
1961   struct fts3rec_v8_14 *rec_v8_14;
1962 
1963   ftpdu->ftd.rec_size = sizeof (struct fts3rec_v8_14);
1964   pdu_v8_14 = (struct ftpdu_v8_14*)&ftpdu->buf;
1965   ph = (struct ftpdu_header*)&ftpdu->buf;
1966 
1967   /* preswap */
1968   if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
1969     SWAPINT32(ph->sysUpTime);
1970     SWAPINT32(ph->unix_secs);
1971     SWAPINT32(ph->unix_nsecs);
1972   }
1973 
1974   for (n = 0; n < pdu_v8_14->count; ++n) {
1975 
1976     rec_v8_14 = (struct fts3rec_v8_14*) (ftpdu->ftd.buf +
1977       (n*ftpdu->ftd.rec_size));
1978 
1979     rec_v8_14->unix_nsecs = ph->unix_nsecs;
1980     rec_v8_14->unix_secs = ph->unix_secs;
1981     rec_v8_14->sysUpTime = ph->sysUpTime;
1982 
1983     rec_v8_14->engine_type = pdu_v8_14->engine_type;
1984     rec_v8_14->engine_type = pdu_v8_14->engine_id;
1985 
1986     rec_v8_14->dFlows = pdu_v8_14->records[n].dFlows;
1987     rec_v8_14->dPkts = pdu_v8_14->records[n].dPkts;
1988     rec_v8_14->dOctets = pdu_v8_14->records[n].dOctets;
1989     rec_v8_14->First = pdu_v8_14->records[n].First;
1990     rec_v8_14->Last = pdu_v8_14->records[n].Last;
1991     rec_v8_14->srcaddr = pdu_v8_14->records[n].src_prefix;
1992     rec_v8_14->dstaddr = pdu_v8_14->records[n].dst_prefix;
1993     rec_v8_14->src_mask = pdu_v8_14->records[n].src_mask;
1994     rec_v8_14->dst_mask = pdu_v8_14->records[n].dst_mask;
1995     rec_v8_14->tos = pdu_v8_14->records[n].tos;
1996     rec_v8_14->prot = pdu_v8_14->records[n].prot;
1997     rec_v8_14->srcport = pdu_v8_14->records[n].srcport;
1998     rec_v8_14->dstport = pdu_v8_14->records[n].dstport;
1999     rec_v8_14->input = pdu_v8_14->records[n].input;
2000     rec_v8_14->output = pdu_v8_14->records[n].output;
2001 
2002     /* copy in exporter IP */
2003     rec_v8_14->exaddr = ftpdu->ftd.exporter_ip;
2004 
2005     if (ftpdu->ftd.byte_order == FT_HEADER_LITTLE_ENDIAN) {
2006 
2007       SWAPINT32(rec_v8_14->dFlows);
2008       SWAPINT32(rec_v8_14->dPkts);
2009       SWAPINT32(rec_v8_14->dOctets);
2010       SWAPINT32(rec_v8_14->First);
2011       SWAPINT32(rec_v8_14->Last);
2012       SWAPINT32(rec_v8_14->srcaddr);
2013       SWAPINT32(rec_v8_14->dstaddr);
2014       SWAPINT16(rec_v8_14->srcport);
2015       SWAPINT16(rec_v8_14->dstport);
2016       SWAPINT16(rec_v8_14->input);
2017       SWAPINT16(rec_v8_14->output);
2018 
2019       SWAPINT32(rec_v8_14->exaddr);
2020 
2021     }
2022 
2023   } /* for */
2024 
2025   return ftpdu->ftd.count;
2026 
2027 } /* fts3rec_pdu_v8_14_decode */
2028 
2029