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: ftencode.c,v 1.13 2003/02/13 02:38:41 maf Exp $
27  */
28 
29 #include "ftconfig.h"
30 #include "ftlib.h"
31 
32 #if HAVE_STRINGS_H
33  #include <strings.h>
34 #endif
35 #if HAVE_STRING_H
36   #include <string.h>
37 #endif
38 
39 /*
40  * function: ftencode_init
41  *
42  * Initialize a ftencode structure, must be called before
43  * first attempt to encode pdu with fts3rec_*_encode()
44 */
ftencode_init(struct ftencode * enc,int flags)45 void ftencode_init(struct ftencode *enc, int flags)
46 {
47 
48   bzero(enc, sizeof (struct ftencode));
49 
50   enc->flags = flags;
51 
52   if (enc->flags & FT_ENC_FLAGS_IPHDR)
53     enc->buf_enc = (char*)&enc->buf + FT_ENC_IPHDR_LEN;
54   else
55     enc->buf_enc = (char*)&enc->buf;
56 
57 } /* ftencode_init */
58 
59 /*
60  * function: ftencode_reset
61  *
62  * Use between successive calls to f2s2rec_*_encode()
63 */
ftencode_reset(struct ftencode * enc)64 void ftencode_reset(struct ftencode *enc)
65 {
66   int len;
67 
68   if (enc->flags & FT_ENC_FLAGS_IPHDR)
69     len = FT_IO_MAXENCODE -  FT_ENC_IPHDR_LEN;
70   else
71     len = FT_IO_MAXENCODE;
72 
73   bzero (enc->buf_enc, len);
74 
75   enc->buf_size = 0;
76 
77 } /* ftencode_reset */
78 
79 /*
80  * function: ftencode_sum_data
81  *
82  * calculate checksum of PDU (just the data)
83  *
84  */
ftencode_sum_data(struct ftencode * enc)85 void ftencode_sum_data(struct ftencode *enc)
86 {
87   int size;
88   unsigned short *word;
89   int sum;
90 
91   sum = 0;
92   size = enc->buf_size;
93   word = (unsigned short*)enc->buf_enc;
94 
95   for (size = enc->buf_size; size > 1; size -=2)
96     sum += *word++;
97 
98   /* odd byte */
99   if (size == 1)
100     sum += htons(*(u_char*)word<<8);
101 
102   enc->d_sum = sum;
103 
104 } /* ftencode_cksum_data */
105 
106 
107 /*
108  * function: fts3rec_pdu_encode
109  *
110  * Encode any type f2s2rec_* into a PDU
111  * wrapper function for other f2s2rec_pdu_*_encode
112  *
113  * Note ftencode_init() must be called on the ftencode
114  * first, and ftencode_reset() must be called after each
115  * PDU is processed by the caller before calling this
116  * function again.
117  *
118  * returns: -1 error encoding, PDU not encoded.
119  *           0 PDU encoded.  Hint next call will fail.
120  *           1 PDU encoded.  Room for more.
121  *
122 */
fts3rec_pdu_encode(struct ftencode * enc,void * rec)123 int fts3rec_pdu_encode(struct ftencode *enc, void *rec)
124 {
125 
126   switch (enc->ver.d_version) {
127 
128     case 1:
129       return (fts3rec_pdu_v1_encode(enc, (struct fts3rec_v1*)rec));
130       break;
131 
132     case 5:
133       return (fts3rec_pdu_v5_encode(enc, (struct fts3rec_v5*)rec));
134       break;
135 
136     case 6:
137       return (fts3rec_pdu_v6_encode(enc, (struct fts3rec_v6*)rec));
138       break;
139 
140     case 7:
141       return (fts3rec_pdu_v7_encode(enc, (struct fts3rec_v7*)rec));
142       break;
143 
144     case 8:
145 
146       switch (enc->ver.agg_method) {
147 
148         case 1:
149           return (fts3rec_pdu_v8_1_encode(enc, (struct fts3rec_v8_1*)rec));
150           break;
151 
152         case 2:
153           return (fts3rec_pdu_v8_2_encode(enc, (struct fts3rec_v8_2*)rec));
154           break;
155 
156         case 3:
157           return (fts3rec_pdu_v8_3_encode(enc, (struct fts3rec_v8_3*)rec));
158           break;
159 
160         case 4:
161           return (fts3rec_pdu_v8_4_encode(enc, (struct fts3rec_v8_4*)rec));
162           break;
163 
164         case 5:
165           return (fts3rec_pdu_v8_5_encode(enc, (struct fts3rec_v8_5*)rec));
166           break;
167 
168         case 6:
169           return (fts3rec_pdu_v8_6_encode(enc, (struct fts3rec_v8_6*)rec));
170           break;
171 
172         case 7:
173           return (fts3rec_pdu_v8_7_encode(enc, (struct fts3rec_v8_7*)rec));
174           break;
175 
176         case 8:
177           return (fts3rec_pdu_v8_8_encode(enc, (struct fts3rec_v8_8*)rec));
178           break;
179 
180         case 9:
181           return (fts3rec_pdu_v8_9_encode(enc, (struct fts3rec_v8_9*)rec));
182           break;
183 
184         case 10:
185           return (fts3rec_pdu_v8_10_encode(enc, (struct fts3rec_v8_10*)rec));
186           break;
187 
188         case 11:
189           return (fts3rec_pdu_v8_11_encode(enc, (struct fts3rec_v8_11*)rec));
190           break;
191 
192         case 12:
193           return (fts3rec_pdu_v8_12_encode(enc, (struct fts3rec_v8_12*)rec));
194           break;
195 
196         case 13:
197           return (fts3rec_pdu_v8_13_encode(enc, (struct fts3rec_v8_13*)rec));
198           break;
199 
200         case 14:
201           return (fts3rec_pdu_v8_14_encode(enc, (struct fts3rec_v8_14*)rec));
202           break;
203 
204       } /* switch */
205       break;
206 
207   } /* switch */
208 
209   return -1;
210 
211 } /* fts3rec_pdu_encode */
212 
213 /*
214  * function: fts3rec_pdu_v1_encode
215  *
216  * Encode a fts3rec into a version 1 PDU
217  *
218  * returns: -1 error encoding, PDU not encoded.
219  *           0 PDU encoded.  Hint next call will fail.
220  *           1 PDU encoded.  Room for more.
221  *
222 */
fts3rec_pdu_v1_encode(struct ftencode * enc,struct fts3rec_v1 * rec_v1)223 int fts3rec_pdu_v1_encode(struct ftencode *enc, struct fts3rec_v1 *rec_v1)
224 {
225   struct ftpdu_v1 *pdu_v1;
226   int i;
227 
228   pdu_v1 = (struct ftpdu_v1*) enc->buf_enc;
229 
230   i = pdu_v1->count;
231 
232   /* space to encode more ? */
233   if (i >= FT_PDU_V1_MAXFLOWS)
234     return -1;
235 
236   /* if this is the first record, fill in the header */
237   if (!i) {
238 
239     pdu_v1->version = 1;
240     pdu_v1->sysUpTime = rec_v1->sysUpTime;
241     pdu_v1->unix_secs = rec_v1->unix_secs;
242     pdu_v1->unix_nsecs = rec_v1->unix_nsecs;
243     enc->buf_size = 16; /* pdu header size */
244 
245   } else {
246 
247     /*  sysUpTime, unix_secs, and unix_nsecs must match for
248      *  each pdu.  If a stream is being re-encoded this will normally
249      *  work out fine, if the stream was sorted or changed in some way
250      *  the PDU may only be able to hold one record.
251     */
252 
253     if ((pdu_v1->sysUpTime != rec_v1->sysUpTime) ||
254         (pdu_v1->unix_secs != rec_v1->unix_secs) ||
255         (pdu_v1->unix_nsecs != rec_v1->unix_nsecs))
256         return -1;
257 
258   }
259 
260   pdu_v1->records[i].srcaddr = rec_v1->srcaddr;
261   pdu_v1->records[i].dstaddr = rec_v1->dstaddr;
262   pdu_v1->records[i].nexthop = rec_v1->nexthop;
263   pdu_v1->records[i].input = rec_v1->input;
264   pdu_v1->records[i].output = rec_v1->output;
265   pdu_v1->records[i].dPkts = rec_v1->dPkts;
266   pdu_v1->records[i].dOctets = rec_v1->dOctets;
267   pdu_v1->records[i].First = rec_v1->First;
268   pdu_v1->records[i].Last = rec_v1->Last;
269   pdu_v1->records[i].srcport = rec_v1->srcport;
270   pdu_v1->records[i].dstport = rec_v1->dstport;
271   pdu_v1->records[i].prot = rec_v1->prot;
272   pdu_v1->records[i].tos = rec_v1->tos;
273   pdu_v1->records[i].flags = rec_v1->tcp_flags;
274 
275   pdu_v1->count ++;
276   enc->buf_size += sizeof (struct ftrec_v1);
277 
278   if (pdu_v1->count >= FT_PDU_V1_MAXFLOWS)
279     return 0;
280   else
281     return 1;
282 }
283 
284 /*
285  * function: fts3rec_pdu_v5_encode
286  *
287  * Encode a fts3rec into a version 5 PDU
288  *
289  * returns: -1 error encoding, PDU not encoded.
290  *           0 PDU encoded.  Hint next call will fail.
291  *           1 PDU encoded.  Room for more.
292  *
293 */
fts3rec_pdu_v5_encode(struct ftencode * enc,struct fts3rec_v5 * rec_v5)294 int fts3rec_pdu_v5_encode(struct ftencode *enc, struct fts3rec_v5 *rec_v5)
295 {
296   struct ftpdu_v5 *pdu_v5;
297   unsigned int seq_index;
298   int i;
299 
300   pdu_v5 = (struct ftpdu_v5*) enc->buf_enc;
301 
302   i = pdu_v5->count;
303 
304   /* index to sequence # */
305   seq_index = rec_v5->engine_id<<8 | rec_v5->engine_type;
306 
307   /* space to encode more ? */
308   if (i >= FT_PDU_V5_MAXFLOWS)
309     return -1;
310 
311   /* if this is the first record, fill in the header */
312   if (!i) {
313 
314     pdu_v5->version = 5;
315     pdu_v5->sysUpTime = rec_v5->sysUpTime;
316     pdu_v5->unix_secs = rec_v5->unix_secs;
317     pdu_v5->unix_nsecs = rec_v5->unix_nsecs;
318     pdu_v5->engine_type = rec_v5->engine_type;
319     pdu_v5->engine_id = rec_v5->engine_id;
320     pdu_v5->flow_sequence = enc->seq_next[seq_index];
321     enc->buf_size = 24; /* pdu header size */
322 
323   } else {
324 
325     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
326      *  each pdu.  If a stream is being re-encoded this will normally
327      *  work out fine, if the stream was sorted or changed in some way
328      *  the PDU may only be able to hold one record.
329     */
330 
331     if ((pdu_v5->sysUpTime != rec_v5->sysUpTime) ||
332         (pdu_v5->unix_secs != rec_v5->unix_secs) ||
333         (pdu_v5->unix_nsecs != rec_v5->unix_nsecs) ||
334         (pdu_v5->engine_id != rec_v5->engine_id) ||
335         (pdu_v5->engine_type != rec_v5->engine_type))
336         return -1;
337 
338   }
339 
340   pdu_v5->records[i].srcaddr = rec_v5->srcaddr;
341   pdu_v5->records[i].dstaddr = rec_v5->dstaddr;
342   pdu_v5->records[i].nexthop = rec_v5->nexthop;
343   pdu_v5->records[i].input = rec_v5->input;
344   pdu_v5->records[i].output = rec_v5->output;
345   pdu_v5->records[i].dPkts = rec_v5->dPkts;
346   pdu_v5->records[i].dOctets = rec_v5->dOctets;
347   pdu_v5->records[i].First = rec_v5->First;
348   pdu_v5->records[i].Last = rec_v5->Last;
349   pdu_v5->records[i].srcport = rec_v5->srcport;
350   pdu_v5->records[i].dstport = rec_v5->dstport;
351   pdu_v5->records[i].prot = rec_v5->prot;
352   pdu_v5->records[i].tos = rec_v5->tos;
353   pdu_v5->records[i].tcp_flags = rec_v5->tcp_flags;
354   pdu_v5->records[i].src_as = rec_v5->src_as;
355   pdu_v5->records[i].dst_as = rec_v5->dst_as;
356   pdu_v5->records[i].src_mask = rec_v5->src_mask;
357   pdu_v5->records[i].dst_mask = rec_v5->dst_mask;
358 
359   /* increment sequence # */
360   enc->seq_next[seq_index]++;
361 
362   pdu_v5->count ++;
363   enc->buf_size += sizeof (struct ftrec_v5);
364 
365   if (pdu_v5->count >= FT_PDU_V5_MAXFLOWS)
366     return 0;
367   else
368     return 1;
369 
370 } /* fts3rec_pdu_v5_encode */
371 
372 /*
373  * function: fts3rec_pdu_v6_encode
374  *
375  * Encode a fts3rec into a version 6 PDU
376  *
377  * returns: -1 error encoding, PDU not encoded.
378  *           0 PDU encoded.  Hint next call will fail.
379  *           1 PDU encoded.  Room for more.
380  *
381 */
fts3rec_pdu_v6_encode(struct ftencode * enc,struct fts3rec_v6 * rec_v6)382 int fts3rec_pdu_v6_encode(struct ftencode *enc, struct fts3rec_v6 *rec_v6)
383 {
384   struct ftpdu_v6 *pdu_v6;
385   unsigned int seq_index;
386   int i;
387 
388   pdu_v6 = (struct ftpdu_v6*) enc->buf_enc;
389 
390   /* index to sequence # */
391   seq_index = rec_v6->engine_id<<8 | rec_v6->engine_type;
392 
393   i = pdu_v6->count;
394 
395   /* space to encode more ? */
396   if (i >= FT_PDU_V6_MAXFLOWS)
397     return -1;
398 
399   /* if this is the first record, fill in the header */
400   if (!i) {
401 
402     pdu_v6->version = 6;
403     pdu_v6->sysUpTime = rec_v6->sysUpTime;
404     pdu_v6->unix_secs = rec_v6->unix_secs;
405     pdu_v6->unix_nsecs = rec_v6->unix_nsecs;
406     pdu_v6->engine_type = rec_v6->engine_type;
407     pdu_v6->engine_id = rec_v6->engine_id;
408     pdu_v6->flow_sequence = enc->seq_next[seq_index];
409     enc->buf_size = 24; /* pdu header size */
410 
411   } else {
412 
413     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
414      *  each pdu.  If a stream is being re-encoded this will normally
415      *  work out fine, if the stream was sorted or changed in some way
416      *  the PDU may only be able to hold one record.
417     */
418 
419     if ((pdu_v6->sysUpTime != rec_v6->sysUpTime) ||
420         (pdu_v6->unix_secs != rec_v6->unix_secs) ||
421         (pdu_v6->unix_nsecs != rec_v6->unix_nsecs) ||
422         (pdu_v6->engine_id != rec_v6->engine_id) ||
423         (pdu_v6->engine_type != rec_v6->engine_type))
424         return -1;
425 
426   }
427 
428   pdu_v6->records[i].srcaddr = rec_v6->srcaddr;
429   pdu_v6->records[i].dstaddr = rec_v6->dstaddr;
430   pdu_v6->records[i].nexthop = rec_v6->nexthop;
431   pdu_v6->records[i].input = rec_v6->input;
432   pdu_v6->records[i].output = rec_v6->output;
433   pdu_v6->records[i].dPkts = rec_v6->dPkts;
434   pdu_v6->records[i].dOctets = rec_v6->dOctets;
435   pdu_v6->records[i].First = rec_v6->First;
436   pdu_v6->records[i].Last = rec_v6->Last;
437   pdu_v6->records[i].srcport = rec_v6->srcport;
438   pdu_v6->records[i].dstport = rec_v6->dstport;
439   pdu_v6->records[i].prot = rec_v6->prot;
440   pdu_v6->records[i].tos = rec_v6->tos;
441   pdu_v6->records[i].tcp_flags = rec_v6->tcp_flags;
442   pdu_v6->records[i].src_as = rec_v6->src_as;
443   pdu_v6->records[i].dst_as = rec_v6->dst_as;
444   pdu_v6->records[i].src_mask = rec_v6->src_mask;
445   pdu_v6->records[i].dst_mask = rec_v6->dst_mask;
446   pdu_v6->records[i].in_encaps = rec_v6->in_encaps;
447   pdu_v6->records[i].out_encaps = rec_v6->out_encaps;
448   pdu_v6->records[i].peer_nexthop = rec_v6->peer_nexthop;
449 
450   /* increment sequence # */
451   enc->seq_next[seq_index]++;
452 
453   pdu_v6->count ++;
454   enc->buf_size += sizeof (struct ftrec_v6);
455 
456   if (pdu_v6->count >= FT_PDU_V6_MAXFLOWS)
457     return 0;
458   else
459     return 1;
460 }
461 
462 /*
463  * function: fts3rec_pdu_v7_encode
464  *
465  * Encode a fts3rec into a version 7 PDU
466  *
467  * returns: -1 error encoding, PDU not encoded.
468  *           0 PDU encoded.  Hint next call will fail.
469  *           1 PDU encoded.  Room for more.
470  *
471 */
fts3rec_pdu_v7_encode(struct ftencode * enc,struct fts3rec_v7 * rec_v7)472 int fts3rec_pdu_v7_encode(struct ftencode *enc, struct fts3rec_v7 *rec_v7)
473 {
474   struct ftpdu_v7 *pdu_v7;
475   unsigned int seq_index;
476   int i;
477 
478   pdu_v7 = (struct ftpdu_v7*) enc->buf_enc;
479 
480   /* index to sequence # */
481   seq_index = rec_v7->engine_id<<8 | rec_v7->engine_type;
482 
483   i = pdu_v7->count;
484 
485   /* space to encode more ? */
486   if (i >= FT_PDU_V7_MAXFLOWS)
487     return -1;
488 
489   /* if this is the first record, fill in the header */
490   if (!i) {
491 
492     pdu_v7->version = 7;
493     pdu_v7->sysUpTime = rec_v7->sysUpTime;
494     pdu_v7->unix_secs = rec_v7->unix_secs;
495     pdu_v7->unix_nsecs = rec_v7->unix_nsecs;
496     pdu_v7->engine_type = rec_v7->engine_type;
497     pdu_v7->engine_id = rec_v7->engine_id;
498     pdu_v7->flow_sequence = enc->seq_next[seq_index];
499     enc->buf_size = 24; /* pdu header size */
500 
501   } else {
502 
503     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
504      *  each pdu.  If a stream is being re-encoded this will normally
505      *  work out fine, if the stream was sorted or changed in some way
506      *  the PDU may only be able to hold one record.
507     */
508 
509     if ((pdu_v7->sysUpTime != rec_v7->sysUpTime) ||
510         (pdu_v7->unix_secs != rec_v7->unix_secs) ||
511         (pdu_v7->unix_nsecs != rec_v7->unix_nsecs) ||
512         (pdu_v7->engine_id != rec_v7->engine_id) ||
513         (pdu_v7->engine_type != rec_v7->engine_type))
514         return -1;
515 
516   }
517 
518   pdu_v7->records[i].srcaddr = rec_v7->srcaddr;
519   pdu_v7->records[i].dstaddr = rec_v7->dstaddr;
520   pdu_v7->records[i].nexthop = rec_v7->nexthop;
521   pdu_v7->records[i].input = rec_v7->input;
522   pdu_v7->records[i].output = rec_v7->output;
523   pdu_v7->records[i].dPkts = rec_v7->dPkts;
524   pdu_v7->records[i].dOctets = rec_v7->dOctets;
525   pdu_v7->records[i].First = rec_v7->First;
526   pdu_v7->records[i].Last = rec_v7->Last;
527   pdu_v7->records[i].srcport = rec_v7->srcport;
528   pdu_v7->records[i].dstport = rec_v7->dstport;
529   pdu_v7->records[i].prot = rec_v7->prot;
530   pdu_v7->records[i].tos = rec_v7->tos;
531   pdu_v7->records[i].tcp_flags = rec_v7->tcp_flags;
532   pdu_v7->records[i].src_as = rec_v7->src_as;
533   pdu_v7->records[i].dst_as = rec_v7->dst_as;
534   pdu_v7->records[i].src_mask = rec_v7->src_mask;
535   pdu_v7->records[i].dst_mask = rec_v7->dst_mask;
536   pdu_v7->records[i].router_sc = rec_v7->router_sc;
537 
538   /* increment sequence # */
539   enc->seq_next[seq_index]++;
540 
541   pdu_v7->count ++;
542   enc->buf_size += sizeof (struct ftrec_v7);
543 
544   if (pdu_v7->count >= FT_PDU_V7_MAXFLOWS)
545     return 0;
546   else
547     return 1;
548 }
549 
550 /*
551  * function: fts3rec_pdu_v8_1_encode
552  *
553  * Encode a fts3rec into a version 8 Agg method 1
554  *
555  * returns: -1 error encoding, PDU not encoded.
556  *           0 PDU encoded.  Hint next call will fail.
557  *           1 PDU encoded.  Room for more.
558  *
559 */
fts3rec_pdu_v8_1_encode(struct ftencode * enc,struct fts3rec_v8_1 * rec_v8_1)560 int fts3rec_pdu_v8_1_encode(struct ftencode *enc,
561   struct fts3rec_v8_1 *rec_v8_1)
562 {
563   struct ftpdu_v8_1 *pdu_v8_1;
564   unsigned int seq_index;
565   int i;
566 
567   pdu_v8_1 = (struct ftpdu_v8_1*) enc->buf_enc;
568 
569   /* index to sequence # */
570   seq_index = rec_v8_1->engine_id<<8 | rec_v8_1->engine_type;
571 
572   i = pdu_v8_1->count;
573 
574   /* space to encode more ? */
575   if (i >= FT_PDU_V8_1_MAXFLOWS)
576     return -1;
577 
578   /* if this is the first record, fill in the header */
579   if (!i) {
580 
581     pdu_v8_1->version = 8;
582     pdu_v8_1->sysUpTime = rec_v8_1->sysUpTime;
583     pdu_v8_1->unix_secs = rec_v8_1->unix_secs;
584     pdu_v8_1->unix_nsecs = rec_v8_1->unix_nsecs;
585     pdu_v8_1->engine_type = rec_v8_1->engine_type;
586     pdu_v8_1->engine_id = rec_v8_1->engine_id;
587     pdu_v8_1->aggregation = 1;
588     pdu_v8_1->agg_version = 2;
589     pdu_v8_1->flow_sequence = enc->seq_next[seq_index];
590     enc->buf_size = 28; /* pdu header size */
591 
592   } else {
593 
594     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
595      *  each pdu.  If a stream is being re-encoded this will normally
596      *  work out fine, if the stream was sorted or changed in some way
597      *  the PDU may only be able to hold one record.
598     */
599 
600     if ((pdu_v8_1->sysUpTime != rec_v8_1->sysUpTime) ||
601         (pdu_v8_1->unix_secs != rec_v8_1->unix_secs) ||
602         (pdu_v8_1->unix_nsecs != rec_v8_1->unix_nsecs) ||
603         (pdu_v8_1->engine_id != rec_v8_1->engine_id) ||
604         (pdu_v8_1->engine_type != rec_v8_1->engine_type))
605         return -1;
606 
607   }
608 
609   pdu_v8_1->records[i].dFlows = rec_v8_1->dFlows;
610   pdu_v8_1->records[i].dPkts = rec_v8_1->dPkts;
611   pdu_v8_1->records[i].dOctets = rec_v8_1->dOctets;
612   pdu_v8_1->records[i].First = rec_v8_1->First;
613   pdu_v8_1->records[i].Last = rec_v8_1->Last;
614   pdu_v8_1->records[i].src_as = rec_v8_1->src_as;
615   pdu_v8_1->records[i].dst_as = rec_v8_1->dst_as;
616   pdu_v8_1->records[i].input = rec_v8_1->input;
617   pdu_v8_1->records[i].output = rec_v8_1->output;
618 
619   /* increment sequence # */
620   enc->seq_next[seq_index]++;
621 
622   pdu_v8_1->count ++;
623   enc->buf_size += sizeof (struct ftrec_v8_1);
624 
625   if (pdu_v8_1->count >= FT_PDU_V8_1_MAXFLOWS)
626     return 0;
627   else
628     return 1;
629 } /* fts3rec_pdu_v8_1_encode */
630 
631 /*
632  * function: fts3rec_pdu_v8_2_encode
633  *
634  * Encode a fts3rec into a version 8 Agg method 2
635  *
636  * returns: -1 error encoding, PDU not encoded.
637  *           0 PDU encoded.  Hint next call will fail.
638  *           1 PDU encoded.  Room for more.
639  *
640 */
fts3rec_pdu_v8_2_encode(struct ftencode * enc,struct fts3rec_v8_2 * rec_v8_2)641 int fts3rec_pdu_v8_2_encode(struct ftencode *enc,
642   struct fts3rec_v8_2 *rec_v8_2)
643 {
644   struct ftpdu_v8_2 *pdu_v8_2;
645   unsigned int seq_index;
646   int i;
647 
648   pdu_v8_2 = (struct ftpdu_v8_2*) enc->buf_enc;
649 
650   /* index to sequence # */
651   seq_index = rec_v8_2->engine_id<<8 | rec_v8_2->engine_type;
652 
653   i = pdu_v8_2->count;
654 
655   /* space to encode more ? */
656   if (i >= FT_PDU_V8_2_MAXFLOWS)
657     return -1;
658 
659   /* if this is the first record, fill in the header */
660   if (!i) {
661 
662     pdu_v8_2->version = 8;
663     pdu_v8_2->sysUpTime = rec_v8_2->sysUpTime;
664     pdu_v8_2->unix_secs = rec_v8_2->unix_secs;
665     pdu_v8_2->unix_nsecs = rec_v8_2->unix_nsecs;
666     pdu_v8_2->engine_type = rec_v8_2->engine_type;
667     pdu_v8_2->engine_id = rec_v8_2->engine_id;
668     pdu_v8_2->aggregation = 2;
669     pdu_v8_2->agg_version = 2;
670     pdu_v8_2->flow_sequence = enc->seq_next[seq_index];
671     enc->buf_size = 28; /* pdu header size */
672 
673   } else {
674 
675     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
676      *  each pdu.  If a stream is being re-encoded this will normally
677      *  work out fine, if the stream was sorted or changed in some way
678      *  the PDU may only be able to hold one record.
679     */
680 
681     if ((pdu_v8_2->sysUpTime != rec_v8_2->sysUpTime) ||
682         (pdu_v8_2->unix_secs != rec_v8_2->unix_secs) ||
683         (pdu_v8_2->unix_nsecs != rec_v8_2->unix_nsecs) ||
684         (pdu_v8_2->engine_id != rec_v8_2->engine_id) ||
685         (pdu_v8_2->engine_type != rec_v8_2->engine_type))
686         return -1;
687 
688   }
689 
690   pdu_v8_2->records[i].dFlows = rec_v8_2->dFlows;
691   pdu_v8_2->records[i].dPkts = rec_v8_2->dPkts;
692   pdu_v8_2->records[i].dOctets = rec_v8_2->dOctets;
693   pdu_v8_2->records[i].First = rec_v8_2->First;
694   pdu_v8_2->records[i].Last = rec_v8_2->Last;
695   pdu_v8_2->records[i].prot = rec_v8_2->prot;
696   pdu_v8_2->records[i].srcport = rec_v8_2->srcport;
697   pdu_v8_2->records[i].dstport = rec_v8_2->dstport;
698 
699   /* increment sequence # */
700   enc->seq_next[seq_index]++;
701 
702   pdu_v8_2->count ++;
703   enc->buf_size += sizeof (struct ftrec_v8_2);
704 
705   if (pdu_v8_2->count >= FT_PDU_V8_2_MAXFLOWS)
706     return 0;
707   else
708     return 1;
709 } /* fts3rec_pdu_v8_2_encode */
710 
711 /*
712  * function: fts3rec_pdu_v8_3_encode
713  *
714  * Encode a fts3rec into a version 8 Agg method 3
715  *
716  * returns: -1 error encoding, PDU not encoded.
717  *           0 PDU encoded.  Hint next call will fail.
718  *           1 PDU encoded.  Room for more.
719  *
720 */
fts3rec_pdu_v8_3_encode(struct ftencode * enc,struct fts3rec_v8_3 * rec_v8_3)721 int fts3rec_pdu_v8_3_encode(struct ftencode *enc,
722   struct fts3rec_v8_3 *rec_v8_3)
723 {
724   struct ftpdu_v8_3 *pdu_v8_3;
725   unsigned int seq_index;
726   int i;
727 
728   pdu_v8_3 = (struct ftpdu_v8_3*) enc->buf_enc;
729 
730   /* index to sequence # */
731   seq_index = rec_v8_3->engine_id<<8 | rec_v8_3->engine_type;
732 
733   i = pdu_v8_3->count;
734 
735   /* space to encode more ? */
736   if (i >= FT_PDU_V8_3_MAXFLOWS)
737     return -1;
738 
739   /* if this is the first record, fill in the header */
740   if (!i) {
741 
742     pdu_v8_3->version = 8;
743     pdu_v8_3->sysUpTime = rec_v8_3->sysUpTime;
744     pdu_v8_3->unix_secs = rec_v8_3->unix_secs;
745     pdu_v8_3->unix_nsecs = rec_v8_3->unix_nsecs;
746     pdu_v8_3->engine_type = rec_v8_3->engine_type;
747     pdu_v8_3->engine_id = rec_v8_3->engine_id;
748     pdu_v8_3->aggregation = 3;
749     pdu_v8_3->agg_version = 2;
750     pdu_v8_3->flow_sequence = enc->seq_next[seq_index];
751     enc->buf_size = 28; /* pdu header size */
752 
753   } else {
754 
755     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
756      *  each pdu.  If a stream is being re-encoded this will normally
757      *  work out fine, if the stream was sorted or changed in some way
758      *  the PDU may only be able to hold one record.
759     */
760 
761     if ((pdu_v8_3->sysUpTime != rec_v8_3->sysUpTime) ||
762         (pdu_v8_3->unix_secs != rec_v8_3->unix_secs) ||
763         (pdu_v8_3->unix_nsecs != rec_v8_3->unix_nsecs) ||
764         (pdu_v8_3->engine_id != rec_v8_3->engine_id) ||
765         (pdu_v8_3->engine_type != rec_v8_3->engine_type))
766         return -1;
767 
768   }
769 
770   pdu_v8_3->records[i].dFlows = rec_v8_3->dFlows;
771   pdu_v8_3->records[i].dPkts = rec_v8_3->dPkts;
772   pdu_v8_3->records[i].dOctets = rec_v8_3->dOctets;
773   pdu_v8_3->records[i].First = rec_v8_3->First;
774   pdu_v8_3->records[i].Last = rec_v8_3->Last;
775   pdu_v8_3->records[i].src_prefix = rec_v8_3->srcaddr;
776   pdu_v8_3->records[i].src_mask = rec_v8_3->src_mask;
777   pdu_v8_3->records[i].src_as = rec_v8_3->src_as;
778   pdu_v8_3->records[i].input = rec_v8_3->input;
779 
780   /* increment sequence # */
781   enc->seq_next[seq_index]++;
782 
783   pdu_v8_3->count ++;
784   enc->buf_size += sizeof (struct ftrec_v8_3);
785 
786   if (pdu_v8_3->count >= FT_PDU_V8_3_MAXFLOWS)
787     return 0;
788   else
789     return 1;
790 } /* fts3rec_pdu_v8_3_encode */
791 
792 /*
793  * function: fts3rec_pdu_v8_4_encode
794  *
795  * Encode a fts3rec into a version 8 Agg method 4
796  *
797  * returns: -1 error encoding, PDU not encoded.
798  *           0 PDU encoded.  Hint next call will fail.
799  *           1 PDU encoded.  Room for more.
800  *
801 */
fts3rec_pdu_v8_4_encode(struct ftencode * enc,struct fts3rec_v8_4 * rec_v8_4)802 int fts3rec_pdu_v8_4_encode(struct ftencode *enc,
803   struct fts3rec_v8_4 *rec_v8_4)
804 {
805   struct ftpdu_v8_4 *pdu_v8_4;
806   unsigned int seq_index;
807   int i;
808 
809   pdu_v8_4 = (struct ftpdu_v8_4*) enc->buf_enc;
810 
811   /* index to sequence # */
812   seq_index = rec_v8_4->engine_id<<8 | rec_v8_4->engine_type;
813 
814   i = pdu_v8_4->count;
815 
816   /* space to encode more ? */
817   if (i >= FT_PDU_V8_4_MAXFLOWS)
818     return -1;
819 
820   /* if this is the first record, fill in the header */
821   if (!i) {
822 
823     pdu_v8_4->version = 8;
824     pdu_v8_4->sysUpTime = rec_v8_4->sysUpTime;
825     pdu_v8_4->unix_secs = rec_v8_4->unix_secs;
826     pdu_v8_4->unix_nsecs = rec_v8_4->unix_nsecs;
827     pdu_v8_4->engine_type = rec_v8_4->engine_type;
828     pdu_v8_4->engine_id = rec_v8_4->engine_id;
829     pdu_v8_4->aggregation = 4;
830     pdu_v8_4->agg_version = 2;
831     pdu_v8_4->flow_sequence = enc->seq_next[seq_index];
832     enc->buf_size = 28; /* pdu header size */
833 
834   } else {
835 
836     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
837      *  each pdu.  If a stream is being re-encoded this will normally
838      *  work out fine, if the stream was sorted or changed in some way
839      *  the PDU may only be able to hold one record.
840     */
841 
842     if ((pdu_v8_4->sysUpTime != rec_v8_4->sysUpTime) ||
843         (pdu_v8_4->unix_secs != rec_v8_4->unix_secs) ||
844         (pdu_v8_4->unix_nsecs != rec_v8_4->unix_nsecs) ||
845         (pdu_v8_4->engine_id != rec_v8_4->engine_id) ||
846         (pdu_v8_4->engine_type != rec_v8_4->engine_type))
847         return -1;
848 
849   }
850 
851   pdu_v8_4->records[i].dFlows = rec_v8_4->dFlows;
852   pdu_v8_4->records[i].dPkts = rec_v8_4->dPkts;
853   pdu_v8_4->records[i].dOctets = rec_v8_4->dOctets;
854   pdu_v8_4->records[i].First = rec_v8_4->First;
855   pdu_v8_4->records[i].Last = rec_v8_4->Last;
856   pdu_v8_4->records[i].dst_prefix = rec_v8_4->dstaddr;
857   pdu_v8_4->records[i].dst_mask = rec_v8_4->dst_mask;
858   pdu_v8_4->records[i].dst_as = rec_v8_4->dst_as;
859   pdu_v8_4->records[i].output = rec_v8_4->output;
860 
861   /* increment sequence # */
862   enc->seq_next[seq_index]++;
863 
864   pdu_v8_4->count ++;
865   enc->buf_size += sizeof (struct ftrec_v8_4);
866 
867   if (pdu_v8_4->count >= FT_PDU_V8_4_MAXFLOWS)
868     return 0;
869   else
870     return 1;
871 } /* fts3rec_pdu_v8_4_encode */
872 
873 /*
874  * function: fts3rec_pdu_v8_5_encode
875  *
876  * Encode a fts3rec into a version 8 Agg method 5
877  *
878  * returns: -1 error encoding, PDU not encoded.
879  *           0 PDU encoded.  Hint next call will fail.
880  *           1 PDU encoded.  Room for more.
881  *
882 */
fts3rec_pdu_v8_5_encode(struct ftencode * enc,struct fts3rec_v8_5 * rec_v8_5)883 int fts3rec_pdu_v8_5_encode(struct ftencode *enc,
884   struct fts3rec_v8_5 *rec_v8_5)
885 {
886   struct ftpdu_v8_5 *pdu_v8_5;
887   unsigned int seq_index;
888   int i;
889 
890   pdu_v8_5 = (struct ftpdu_v8_5*) enc->buf_enc;
891 
892   /* index to sequence # */
893   seq_index = rec_v8_5->engine_id<<8 | rec_v8_5->engine_type;
894 
895   i = pdu_v8_5->count;
896 
897   /* space to encode more ? */
898   if (i >= FT_PDU_V8_5_MAXFLOWS)
899     return -1;
900 
901   /* if this is the first record, fill in the header */
902   if (!i) {
903 
904     pdu_v8_5->version = 8;
905     pdu_v8_5->sysUpTime = rec_v8_5->sysUpTime;
906     pdu_v8_5->unix_secs = rec_v8_5->unix_secs;
907     pdu_v8_5->unix_nsecs = rec_v8_5->unix_nsecs;
908     pdu_v8_5->engine_type = rec_v8_5->engine_type;
909     pdu_v8_5->engine_id = rec_v8_5->engine_id;
910     pdu_v8_5->aggregation = 5;
911     pdu_v8_5->agg_version = 2;
912     pdu_v8_5->flow_sequence = enc->seq_next[seq_index];
913     enc->buf_size = 28; /* pdu header size */
914 
915   } else {
916 
917     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
918      *  each pdu.  If a stream is being re-encoded this will normally
919      *  work out fine, if the stream was sorted or changed in some way
920      *  the PDU may only be able to hold one record.
921     */
922 
923     if ((pdu_v8_5->sysUpTime != rec_v8_5->sysUpTime) ||
924         (pdu_v8_5->unix_secs != rec_v8_5->unix_secs) ||
925         (pdu_v8_5->unix_nsecs != rec_v8_5->unix_nsecs) ||
926         (pdu_v8_5->engine_id != rec_v8_5->engine_id) ||
927         (pdu_v8_5->engine_type != rec_v8_5->engine_type))
928         return -1;
929 
930   }
931 
932   pdu_v8_5->records[i].dFlows = rec_v8_5->dFlows;
933   pdu_v8_5->records[i].dPkts = rec_v8_5->dPkts;
934   pdu_v8_5->records[i].dOctets = rec_v8_5->dOctets;
935   pdu_v8_5->records[i].First = rec_v8_5->First;
936   pdu_v8_5->records[i].Last = rec_v8_5->Last;
937   pdu_v8_5->records[i].src_prefix = rec_v8_5->srcaddr;
938   pdu_v8_5->records[i].dst_prefix = rec_v8_5->dstaddr;
939   pdu_v8_5->records[i].dst_mask = rec_v8_5->dst_mask;
940   pdu_v8_5->records[i].src_mask = rec_v8_5->src_mask;
941   pdu_v8_5->records[i].src_as = rec_v8_5->src_as;
942   pdu_v8_5->records[i].dst_as = rec_v8_5->dst_as;
943   pdu_v8_5->records[i].input = rec_v8_5->input;
944   pdu_v8_5->records[i].output = rec_v8_5->output;
945 
946   /* increment sequence # */
947   enc->seq_next[seq_index]++;
948 
949   pdu_v8_5->count ++;
950   enc->buf_size += sizeof (struct ftrec_v8_5);
951 
952   if (pdu_v8_5->count >= FT_PDU_V8_5_MAXFLOWS)
953     return 0;
954   else
955     return 1;
956 } /* fts3rec_pdu_v8_5_encode */
957 
958 
959 /*
960  * function: fts3rec_pdu_v8_6_encode
961  *
962  * Encode a fts3rec into a version 8 Agg method 6
963  *
964  * returns: -1 error encoding, PDU not encoded.
965  *           0 PDU encoded.  Hint next call will fail.
966  *           1 PDU encoded.  Room for more.
967  *
968 */
fts3rec_pdu_v8_6_encode(struct ftencode * enc,struct fts3rec_v8_6 * rec_v8_6)969 int fts3rec_pdu_v8_6_encode(struct ftencode *enc,
970   struct fts3rec_v8_6 *rec_v8_6)
971 {
972   struct ftpdu_v8_6 *pdu_v8_6;
973   unsigned int seq_index;
974   int i;
975 
976   pdu_v8_6 = (struct ftpdu_v8_6*) enc->buf_enc;
977 
978   /* index to sequence # */
979   seq_index = rec_v8_6->engine_id<<8 | rec_v8_6->engine_type;
980 
981   i = pdu_v8_6->count;
982 
983   /* space to encode more ? */
984   if (i >= FT_PDU_V8_6_MAXFLOWS)
985     return -1;
986 
987   /* if this is the first record, fill in the header */
988   if (!i) {
989 
990     pdu_v8_6->version = 8;
991     pdu_v8_6->sysUpTime = rec_v8_6->sysUpTime;
992     pdu_v8_6->unix_secs = rec_v8_6->unix_secs;
993     pdu_v8_6->unix_nsecs = rec_v8_6->unix_nsecs;
994     pdu_v8_6->engine_type = rec_v8_6->engine_type;
995     pdu_v8_6->engine_id = rec_v8_6->engine_id;
996     pdu_v8_6->aggregation = 6;
997     pdu_v8_6->agg_version = 2;
998     pdu_v8_6->flow_sequence = enc->seq_next[seq_index];
999     enc->buf_size = 28; /* pdu header size */
1000 
1001   } else {
1002 
1003     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
1004      *  each pdu.  If a stream is being re-encoded this will normally
1005      *  work out fine, if the stream was sorted or changed in some way
1006      *  the PDU may only be able to hold one record.
1007     */
1008 
1009     if ((pdu_v8_6->sysUpTime != rec_v8_6->sysUpTime) ||
1010         (pdu_v8_6->unix_secs != rec_v8_6->unix_secs) ||
1011         (pdu_v8_6->unix_nsecs != rec_v8_6->unix_nsecs) ||
1012         (pdu_v8_6->engine_id != rec_v8_6->engine_id) ||
1013         (pdu_v8_6->engine_type != rec_v8_6->engine_type))
1014         return -1;
1015 
1016   }
1017 
1018   pdu_v8_6->records[i].dstaddr = rec_v8_6->dstaddr;
1019   pdu_v8_6->records[i].dPkts = rec_v8_6->dPkts;
1020   pdu_v8_6->records[i].dOctets = rec_v8_6->dOctets;
1021   pdu_v8_6->records[i].First = rec_v8_6->First;
1022   pdu_v8_6->records[i].Last = rec_v8_6->Last;
1023   pdu_v8_6->records[i].output = rec_v8_6->output;
1024   pdu_v8_6->records[i].tos = rec_v8_6->tos;
1025   pdu_v8_6->records[i].marked_tos = rec_v8_6->marked_tos;
1026   pdu_v8_6->records[i].extra_pkts = rec_v8_6->extra_pkts;
1027   pdu_v8_6->records[i].router_sc = rec_v8_6->router_sc;
1028 
1029   /* increment sequence # */
1030   enc->seq_next[seq_index]++;
1031 
1032   pdu_v8_6->count ++;
1033   enc->buf_size += sizeof (struct ftrec_v8_6);
1034 
1035   if (pdu_v8_6->count >= FT_PDU_V8_6_MAXFLOWS)
1036     return 0;
1037   else
1038     return 1;
1039 } /* fts3rec_pdu_v8_6_encode */
1040 
1041 /*
1042  * function: fts3rec_pdu_v8_7_encode
1043  *
1044  * Encode a fts3rec into a version 8 Agg method 7
1045  *
1046  * returns: -1 error encoding, PDU not encoded.
1047  *           0 PDU encoded.  Hint next call will fail.
1048  *           1 PDU encoded.  Room for more.
1049  *
1050 */
fts3rec_pdu_v8_7_encode(struct ftencode * enc,struct fts3rec_v8_7 * rec_v8_7)1051 int fts3rec_pdu_v8_7_encode(struct ftencode *enc,
1052   struct fts3rec_v8_7 *rec_v8_7)
1053 {
1054   struct ftpdu_v8_7 *pdu_v8_7;
1055   unsigned int seq_index;
1056   int i;
1057 
1058   pdu_v8_7 = (struct ftpdu_v8_7*) enc->buf_enc;
1059 
1060   /* index to sequence # */
1061   seq_index = rec_v8_7->engine_id<<8 | rec_v8_7->engine_type;
1062 
1063   i = pdu_v8_7->count;
1064 
1065   /* space to encode more ? */
1066   if (i >= FT_PDU_V8_7_MAXFLOWS)
1067     return -1;
1068 
1069   /* if this is the first record, fill in the header */
1070   if (!i) {
1071 
1072     pdu_v8_7->version = 8;
1073     pdu_v8_7->sysUpTime = rec_v8_7->sysUpTime;
1074     pdu_v8_7->unix_secs = rec_v8_7->unix_secs;
1075     pdu_v8_7->unix_nsecs = rec_v8_7->unix_nsecs;
1076     pdu_v8_7->engine_type = rec_v8_7->engine_type;
1077     pdu_v8_7->engine_id = rec_v8_7->engine_id;
1078     pdu_v8_7->aggregation = 7;
1079     pdu_v8_7->agg_version = 2;
1080     pdu_v8_7->flow_sequence = enc->seq_next[seq_index];
1081     enc->buf_size = 28; /* pdu header size */
1082 
1083   } else {
1084 
1085     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
1086      *  each pdu.  If a stream is being re-encoded this will normally
1087      *  work out fine, if the stream was sorted or changed in some way
1088      *  the PDU may only be able to hold one record.
1089     */
1090 
1091     if ((pdu_v8_7->sysUpTime != rec_v8_7->sysUpTime) ||
1092         (pdu_v8_7->unix_secs != rec_v8_7->unix_secs) ||
1093         (pdu_v8_7->unix_nsecs != rec_v8_7->unix_nsecs) ||
1094         (pdu_v8_7->engine_id != rec_v8_7->engine_id) ||
1095         (pdu_v8_7->engine_type != rec_v8_7->engine_type))
1096         return -1;
1097 
1098   }
1099 
1100   pdu_v8_7->records[i].dstaddr = rec_v8_7->dstaddr;
1101   pdu_v8_7->records[i].srcaddr = rec_v8_7->srcaddr;
1102   pdu_v8_7->records[i].dPkts = rec_v8_7->dPkts;
1103   pdu_v8_7->records[i].dOctets = rec_v8_7->dOctets;
1104   pdu_v8_7->records[i].First = rec_v8_7->First;
1105   pdu_v8_7->records[i].Last = rec_v8_7->Last;
1106   pdu_v8_7->records[i].output = rec_v8_7->output;
1107   pdu_v8_7->records[i].input = rec_v8_7->input;
1108   pdu_v8_7->records[i].tos = rec_v8_7->tos;
1109   pdu_v8_7->records[i].marked_tos = rec_v8_7->marked_tos;
1110   pdu_v8_7->records[i].extra_pkts = rec_v8_7->extra_pkts;
1111   pdu_v8_7->records[i].router_sc = rec_v8_7->router_sc;
1112 
1113   /* increment sequence # */
1114   enc->seq_next[seq_index]++;
1115 
1116   pdu_v8_7->count ++;
1117   enc->buf_size += sizeof (struct ftrec_v8_7);
1118 
1119   if (pdu_v8_7->count >= FT_PDU_V8_7_MAXFLOWS)
1120     return 0;
1121   else
1122     return 1;
1123 } /* fts3rec_pdu_v8_7_encode */
1124 
1125 /*
1126  * function: fts3rec_pdu_v8_8_encode
1127  *
1128  * Encode a fts3rec into a version 8 Agg method 8
1129  *
1130  * returns: -1 error encoding, PDU not encoded.
1131  *           0 PDU encoded.  Hint next call will fail.
1132  *           1 PDU encoded.  Room for more.
1133  *
1134 */
fts3rec_pdu_v8_8_encode(struct ftencode * enc,struct fts3rec_v8_8 * rec_v8_8)1135 int fts3rec_pdu_v8_8_encode(struct ftencode *enc,
1136   struct fts3rec_v8_8 *rec_v8_8)
1137 {
1138   struct ftpdu_v8_8 *pdu_v8_8;
1139   unsigned int seq_index;
1140   int i;
1141 
1142   pdu_v8_8 = (struct ftpdu_v8_8*) enc->buf_enc;
1143 
1144   /* index to sequence # */
1145   seq_index = rec_v8_8->engine_id<<8 | rec_v8_8->engine_type;
1146 
1147   i = pdu_v8_8->count;
1148 
1149   /* space to encode more ? */
1150   if (i >= FT_PDU_V8_8_MAXFLOWS)
1151     return -1;
1152 
1153   /* if this is the first record, fill in the header */
1154   if (!i) {
1155 
1156     pdu_v8_8->version = 8;
1157     pdu_v8_8->sysUpTime = rec_v8_8->sysUpTime;
1158     pdu_v8_8->unix_secs = rec_v8_8->unix_secs;
1159     pdu_v8_8->unix_nsecs = rec_v8_8->unix_nsecs;
1160     pdu_v8_8->engine_type = rec_v8_8->engine_type;
1161     pdu_v8_8->engine_id = rec_v8_8->engine_id;
1162     pdu_v8_8->aggregation = 8;
1163     pdu_v8_8->agg_version = 2;
1164     pdu_v8_8->flow_sequence = enc->seq_next[seq_index];
1165     enc->buf_size = 28; /* pdu header size */
1166 
1167   } else {
1168 
1169     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
1170      *  each pdu.  If a stream is being re-encoded this will normally
1171      *  work out fine, if the stream was sorted or changed in some way
1172      *  the PDU may only be able to hold one record.
1173     */
1174 
1175     if ((pdu_v8_8->sysUpTime != rec_v8_8->sysUpTime) ||
1176         (pdu_v8_8->unix_secs != rec_v8_8->unix_secs) ||
1177         (pdu_v8_8->unix_nsecs != rec_v8_8->unix_nsecs) ||
1178         (pdu_v8_8->engine_id != rec_v8_8->engine_id) ||
1179         (pdu_v8_8->engine_type != rec_v8_8->engine_type))
1180         return -1;
1181 
1182   }
1183 
1184   pdu_v8_8->records[i].dstaddr = rec_v8_8->dstaddr;
1185   pdu_v8_8->records[i].srcaddr = rec_v8_8->srcaddr;
1186   pdu_v8_8->records[i].dstport = rec_v8_8->dstport;
1187   pdu_v8_8->records[i].srcport = rec_v8_8->srcport;
1188   pdu_v8_8->records[i].dPkts = rec_v8_8->dPkts;
1189   pdu_v8_8->records[i].dOctets = rec_v8_8->dOctets;
1190   pdu_v8_8->records[i].First = rec_v8_8->First;
1191   pdu_v8_8->records[i].Last = rec_v8_8->Last;
1192   pdu_v8_8->records[i].output = rec_v8_8->output;
1193   pdu_v8_8->records[i].input = rec_v8_8->input;
1194   pdu_v8_8->records[i].tos = rec_v8_8->tos;
1195   pdu_v8_8->records[i].marked_tos = rec_v8_8->marked_tos;
1196   pdu_v8_8->records[i].extra_pkts = rec_v8_8->extra_pkts;
1197   pdu_v8_8->records[i].router_sc = rec_v8_8->router_sc;
1198 
1199   /* increment sequence # */
1200   enc->seq_next[seq_index]++;
1201 
1202   pdu_v8_8->count ++;
1203   enc->buf_size += sizeof (struct ftrec_v8_8);
1204 
1205   if (pdu_v8_8->count >= FT_PDU_V8_8_MAXFLOWS)
1206     return 0;
1207   else
1208     return 1;
1209 } /* fts3rec_pdu_v8_8_encode */
1210 
1211 /*
1212  * function: fts3rec_pdu_v8_9_encode
1213  *
1214  * Encode a fts3rec into a version 8 Agg method 9
1215  *
1216  * returns: -1 error encoding, PDU not encoded.
1217  *           0 PDU encoded.  Hint next call will fail.
1218  *           1 PDU encoded.  Room for more.
1219  *
1220 */
fts3rec_pdu_v8_9_encode(struct ftencode * enc,struct fts3rec_v8_9 * rec_v8_9)1221 int fts3rec_pdu_v8_9_encode(struct ftencode *enc,
1222   struct fts3rec_v8_9 *rec_v8_9)
1223 {
1224   struct ftpdu_v8_9 *pdu_v8_9;
1225   unsigned int seq_index;
1226   int i;
1227 
1228   pdu_v8_9 = (struct ftpdu_v8_9*) enc->buf_enc;
1229 
1230   /* index to sequence # */
1231   seq_index = rec_v8_9->engine_id<<8 | rec_v8_9->engine_type;
1232 
1233   i = pdu_v8_9->count;
1234 
1235   /* space to encode more ? */
1236   if (i >= FT_PDU_V8_9_MAXFLOWS)
1237     return -1;
1238 
1239   /* if this is the first record, fill in the header */
1240   if (!i) {
1241 
1242     pdu_v8_9->version = 8;
1243     pdu_v8_9->sysUpTime = rec_v8_9->sysUpTime;
1244     pdu_v8_9->unix_secs = rec_v8_9->unix_secs;
1245     pdu_v8_9->unix_nsecs = rec_v8_9->unix_nsecs;
1246     pdu_v8_9->engine_type = rec_v8_9->engine_type;
1247     pdu_v8_9->engine_id = rec_v8_9->engine_id;
1248     pdu_v8_9->aggregation = 9;
1249     pdu_v8_9->agg_version = 2;
1250     pdu_v8_9->flow_sequence = enc->seq_next[seq_index];
1251     enc->buf_size = 28; /* pdu header size */
1252 
1253   } else {
1254 
1255     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
1256      *  each pdu.  If a stream is being re-encoded this will normally
1257      *  work out fine, if the stream was sorted or changed in some way
1258      *  the PDU may only be able to hold one record.
1259     */
1260 
1261     if ((pdu_v8_9->sysUpTime != rec_v8_9->sysUpTime) ||
1262         (pdu_v8_9->unix_secs != rec_v8_9->unix_secs) ||
1263         (pdu_v8_9->unix_nsecs != rec_v8_9->unix_nsecs) ||
1264         (pdu_v8_9->engine_id != rec_v8_9->engine_id) ||
1265         (pdu_v8_9->engine_type != rec_v8_9->engine_type))
1266         return -1;
1267 
1268   }
1269 
1270   pdu_v8_9->records[i].dFlows = rec_v8_9->dFlows;
1271   pdu_v8_9->records[i].dPkts = rec_v8_9->dPkts;
1272   pdu_v8_9->records[i].dOctets = rec_v8_9->dOctets;
1273   pdu_v8_9->records[i].First = rec_v8_9->First;
1274   pdu_v8_9->records[i].Last = rec_v8_9->Last;
1275   pdu_v8_9->records[i].src_as = rec_v8_9->src_as;
1276   pdu_v8_9->records[i].dst_as = rec_v8_9->dst_as;
1277   pdu_v8_9->records[i].input = rec_v8_9->input;
1278   pdu_v8_9->records[i].output = rec_v8_9->output;
1279   pdu_v8_9->records[i].tos = rec_v8_9->tos;
1280 
1281   /* increment sequence # */
1282   enc->seq_next[seq_index]++;
1283 
1284   pdu_v8_9->count ++;
1285   enc->buf_size += sizeof (struct ftrec_v8_9);
1286 
1287   if (pdu_v8_9->count >= FT_PDU_V8_9_MAXFLOWS)
1288     return 0;
1289   else
1290     return 1;
1291 } /* fts3rec_pdu_v8_9_encode */
1292 
1293 /*
1294  * function: fts3rec_pdu_v8_10_encode
1295  *
1296  * Encode a fts3rec into a version 8 Agg method 10
1297  *
1298  * returns: -1 error encoding, PDU not encoded.
1299  *           0 PDU encoded.  Hint next call will fail.
1300  *           1 PDU encoded.  Room for more.
1301  *
1302 */
fts3rec_pdu_v8_10_encode(struct ftencode * enc,struct fts3rec_v8_10 * rec_v8_10)1303 int fts3rec_pdu_v8_10_encode(struct ftencode *enc,
1304   struct fts3rec_v8_10 *rec_v8_10)
1305 {
1306   struct ftpdu_v8_10 *pdu_v8_10;
1307   unsigned int seq_index;
1308   int i;
1309 
1310   pdu_v8_10 = (struct ftpdu_v8_10*) enc->buf_enc;
1311 
1312   /* index to sequence # */
1313   seq_index = rec_v8_10->engine_id<<8 | rec_v8_10->engine_type;
1314 
1315   i = pdu_v8_10->count;
1316 
1317   /* space to encode more ? */
1318   if (i >= FT_PDU_V8_10_MAXFLOWS)
1319     return -1;
1320 
1321   /* if this is the first record, fill in the header */
1322   if (!i) {
1323 
1324     pdu_v8_10->version = 8;
1325     pdu_v8_10->sysUpTime = rec_v8_10->sysUpTime;
1326     pdu_v8_10->unix_secs = rec_v8_10->unix_secs;
1327     pdu_v8_10->unix_nsecs = rec_v8_10->unix_nsecs;
1328     pdu_v8_10->engine_type = rec_v8_10->engine_type;
1329     pdu_v8_10->engine_id = rec_v8_10->engine_id;
1330     pdu_v8_10->aggregation = 10;
1331     pdu_v8_10->agg_version = 2;
1332     pdu_v8_10->flow_sequence = enc->seq_next[seq_index];
1333     enc->buf_size = 28; /* pdu header size */
1334 
1335   } else {
1336 
1337     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
1338      *  each pdu.  If a stream is being re-encoded this will normally
1339      *  work out fine, if the stream was sorted or changed in some way
1340      *  the PDU may only be able to hold one record.
1341     */
1342 
1343     if ((pdu_v8_10->sysUpTime != rec_v8_10->sysUpTime) ||
1344         (pdu_v8_10->unix_secs != rec_v8_10->unix_secs) ||
1345         (pdu_v8_10->unix_nsecs != rec_v8_10->unix_nsecs) ||
1346         (pdu_v8_10->engine_id != rec_v8_10->engine_id) ||
1347         (pdu_v8_10->engine_type != rec_v8_10->engine_type))
1348         return -1;
1349 
1350   }
1351 
1352   pdu_v8_10->records[i].dFlows = rec_v8_10->dFlows;
1353   pdu_v8_10->records[i].dPkts = rec_v8_10->dPkts;
1354   pdu_v8_10->records[i].dOctets = rec_v8_10->dOctets;
1355   pdu_v8_10->records[i].First = rec_v8_10->First;
1356   pdu_v8_10->records[i].Last = rec_v8_10->Last;
1357   pdu_v8_10->records[i].srcport = rec_v8_10->srcport;
1358   pdu_v8_10->records[i].dstport = rec_v8_10->dstport;
1359   pdu_v8_10->records[i].prot = rec_v8_10->prot;
1360   pdu_v8_10->records[i].tos = rec_v8_10->tos;
1361 
1362   /* increment sequence # */
1363   enc->seq_next[seq_index]++;
1364 
1365   pdu_v8_10->count ++;
1366   enc->buf_size += sizeof (struct ftrec_v8_10);
1367 
1368   if (pdu_v8_10->count >= FT_PDU_V8_10_MAXFLOWS)
1369     return 0;
1370   else
1371     return 1;
1372 } /* fts3rec_pdu_v8_10_encode */
1373 
1374 /*
1375  * function: fts3rec_pdu_v8_11_encode
1376  *
1377  * Encode a fts3rec into a version 8 Agg method 11
1378  *
1379  * returns: -1 error encoding, PDU not encoded.
1380  *           0 PDU encoded.  Hint next call will fail.
1381  *           1 PDU encoded.  Room for more.
1382  *
1383 */
fts3rec_pdu_v8_11_encode(struct ftencode * enc,struct fts3rec_v8_11 * rec_v8_11)1384 int fts3rec_pdu_v8_11_encode(struct ftencode *enc,
1385   struct fts3rec_v8_11 *rec_v8_11)
1386 {
1387   struct ftpdu_v8_11 *pdu_v8_11;
1388   unsigned int seq_index;
1389   int i;
1390 
1391   pdu_v8_11 = (struct ftpdu_v8_11*) enc->buf_enc;
1392 
1393   /* index to sequence # */
1394   seq_index = rec_v8_11->engine_id<<8 | rec_v8_11->engine_type;
1395 
1396   i = pdu_v8_11->count;
1397 
1398   /* space to encode more ? */
1399   if (i >= FT_PDU_V8_11_MAXFLOWS)
1400     return -1;
1401 
1402   /* if this is the first record, fill in the header */
1403   if (!i) {
1404 
1405     pdu_v8_11->version = 8;
1406     pdu_v8_11->sysUpTime = rec_v8_11->sysUpTime;
1407     pdu_v8_11->unix_secs = rec_v8_11->unix_secs;
1408     pdu_v8_11->unix_nsecs = rec_v8_11->unix_nsecs;
1409     pdu_v8_11->engine_type = rec_v8_11->engine_type;
1410     pdu_v8_11->engine_id = rec_v8_11->engine_id;
1411     pdu_v8_11->aggregation = 11;
1412     pdu_v8_11->agg_version = 2;
1413     pdu_v8_11->flow_sequence = enc->seq_next[seq_index];
1414     enc->buf_size = 28; /* pdu header size */
1415 
1416   } else {
1417 
1418     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
1419      *  each pdu.  If a stream is being re-encoded this will normally
1420      *  work out fine, if the stream was sorted or changed in some way
1421      *  the PDU may only be able to hold one record.
1422     */
1423 
1424     if ((pdu_v8_11->sysUpTime != rec_v8_11->sysUpTime) ||
1425         (pdu_v8_11->unix_secs != rec_v8_11->unix_secs) ||
1426         (pdu_v8_11->unix_nsecs != rec_v8_11->unix_nsecs) ||
1427         (pdu_v8_11->engine_id != rec_v8_11->engine_id) ||
1428         (pdu_v8_11->engine_type != rec_v8_11->engine_type))
1429         return -1;
1430 
1431   }
1432 
1433   pdu_v8_11->records[i].dFlows = rec_v8_11->dFlows;
1434   pdu_v8_11->records[i].dPkts = rec_v8_11->dPkts;
1435   pdu_v8_11->records[i].dOctets = rec_v8_11->dOctets;
1436   pdu_v8_11->records[i].First = rec_v8_11->First;
1437   pdu_v8_11->records[i].Last = rec_v8_11->Last;
1438   pdu_v8_11->records[i].src_prefix = rec_v8_11->srcaddr;
1439   pdu_v8_11->records[i].src_mask = rec_v8_11->src_mask;
1440   pdu_v8_11->records[i].tos = rec_v8_11->tos;
1441   pdu_v8_11->records[i].src_as = rec_v8_11->src_as;
1442   pdu_v8_11->records[i].input = rec_v8_11->input;
1443 
1444   /* increment sequence # */
1445   enc->seq_next[seq_index]++;
1446 
1447   pdu_v8_11->count ++;
1448   enc->buf_size += sizeof (struct ftrec_v8_11);
1449 
1450   if (pdu_v8_11->count >= FT_PDU_V8_11_MAXFLOWS)
1451     return 0;
1452   else
1453     return 1;
1454 } /* fts3rec_pdu_v8_11_encode */
1455 
1456 /*
1457  * function: fts3rec_pdu_v8_12_encode
1458  *
1459  * Encode a fts3rec into a version 8 Agg method 12
1460  *
1461  * returns: -1 error encoding, PDU not encoded.
1462  *           0 PDU encoded.  Hint next call will fail.
1463  *           1 PDU encoded.  Room for more.
1464  *
1465 */
fts3rec_pdu_v8_12_encode(struct ftencode * enc,struct fts3rec_v8_12 * rec_v8_12)1466 int fts3rec_pdu_v8_12_encode(struct ftencode *enc,
1467   struct fts3rec_v8_12 *rec_v8_12)
1468 {
1469   struct ftpdu_v8_12 *pdu_v8_12;
1470   unsigned int seq_index;
1471   int i;
1472 
1473   pdu_v8_12 = (struct ftpdu_v8_12*) enc->buf_enc;
1474 
1475   /* index to sequence # */
1476   seq_index = rec_v8_12->engine_id<<8 | rec_v8_12->engine_type;
1477 
1478   i = pdu_v8_12->count;
1479 
1480   /* space to encode more ? */
1481   if (i >= FT_PDU_V8_12_MAXFLOWS)
1482     return -1;
1483 
1484   /* if this is the first record, fill in the header */
1485   if (!i) {
1486 
1487     pdu_v8_12->version = 8;
1488     pdu_v8_12->sysUpTime = rec_v8_12->sysUpTime;
1489     pdu_v8_12->unix_secs = rec_v8_12->unix_secs;
1490     pdu_v8_12->unix_nsecs = rec_v8_12->unix_nsecs;
1491     pdu_v8_12->engine_type = rec_v8_12->engine_type;
1492     pdu_v8_12->engine_id = rec_v8_12->engine_id;
1493     pdu_v8_12->aggregation = 12;
1494     pdu_v8_12->agg_version = 2;
1495     pdu_v8_12->flow_sequence = enc->seq_next[seq_index];
1496     enc->buf_size = 28; /* pdu header size */
1497 
1498   } else {
1499 
1500     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
1501      *  each pdu.  If a stream is being re-encoded this will normally
1502      *  work out fine, if the stream was sorted or changed in some way
1503      *  the PDU may only be able to hold one record.
1504     */
1505 
1506     if ((pdu_v8_12->sysUpTime != rec_v8_12->sysUpTime) ||
1507         (pdu_v8_12->unix_secs != rec_v8_12->unix_secs) ||
1508         (pdu_v8_12->unix_nsecs != rec_v8_12->unix_nsecs) ||
1509         (pdu_v8_12->engine_id != rec_v8_12->engine_id) ||
1510         (pdu_v8_12->engine_type != rec_v8_12->engine_type))
1511         return -1;
1512 
1513   }
1514 
1515   pdu_v8_12->records[i].dFlows = rec_v8_12->dFlows;
1516   pdu_v8_12->records[i].dPkts = rec_v8_12->dPkts;
1517   pdu_v8_12->records[i].dOctets = rec_v8_12->dOctets;
1518   pdu_v8_12->records[i].First = rec_v8_12->First;
1519   pdu_v8_12->records[i].Last = rec_v8_12->Last;
1520   pdu_v8_12->records[i].dst_prefix = rec_v8_12->dstaddr;
1521   pdu_v8_12->records[i].output = rec_v8_12->output;
1522   pdu_v8_12->records[i].dst_mask = rec_v8_12->dst_mask;
1523   pdu_v8_12->records[i].dst_as = rec_v8_12->dst_as;
1524   pdu_v8_12->records[i].tos = rec_v8_12->tos;
1525 
1526   /* increment sequence # */
1527   enc->seq_next[seq_index]++;
1528 
1529   pdu_v8_12->count ++;
1530   enc->buf_size += sizeof (struct ftrec_v8_12);
1531 
1532   if (pdu_v8_12->count >= FT_PDU_V8_12_MAXFLOWS)
1533     return 0;
1534   else
1535     return 1;
1536 } /* fts3rec_pdu_v8_12_encode */
1537 
1538 /*
1539  * function: fts3rec_pdu_v8_13_encode
1540  *
1541  * Encode a fts3rec into a version 8 Agg method 13
1542  *
1543  * returns: -1 error encoding, PDU not encoded.
1544  *           0 PDU encoded.  Hint next call will fail.
1545  *           1 PDU encoded.  Room for more.
1546  *
1547 */
fts3rec_pdu_v8_13_encode(struct ftencode * enc,struct fts3rec_v8_13 * rec_v8_13)1548 int fts3rec_pdu_v8_13_encode(struct ftencode *enc,
1549   struct fts3rec_v8_13 *rec_v8_13)
1550 {
1551   struct ftpdu_v8_13 *pdu_v8_13;
1552   unsigned int seq_index;
1553   int i;
1554 
1555   pdu_v8_13 = (struct ftpdu_v8_13*) enc->buf_enc;
1556 
1557   /* index to sequence # */
1558   seq_index = rec_v8_13->engine_id<<8 | rec_v8_13->engine_type;
1559 
1560   i = pdu_v8_13->count;
1561 
1562   /* space to encode more ? */
1563   if (i >= FT_PDU_V8_13_MAXFLOWS)
1564     return -1;
1565 
1566   /* if this is the first record, fill in the header */
1567   if (!i) {
1568 
1569     pdu_v8_13->version = 8;
1570     pdu_v8_13->sysUpTime = rec_v8_13->sysUpTime;
1571     pdu_v8_13->unix_secs = rec_v8_13->unix_secs;
1572     pdu_v8_13->unix_nsecs = rec_v8_13->unix_nsecs;
1573     pdu_v8_13->engine_type = rec_v8_13->engine_type;
1574     pdu_v8_13->engine_id = rec_v8_13->engine_id;
1575     pdu_v8_13->aggregation = 13;
1576     pdu_v8_13->agg_version = 2;
1577     pdu_v8_13->flow_sequence = enc->seq_next[seq_index];
1578     enc->buf_size = 28; /* pdu header size */
1579 
1580   } else {
1581 
1582     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
1583      *  each pdu.  If a stream is being re-encoded this will normally
1584      *  work out fine, if the stream was sorted or changed in some way
1585      *  the PDU may only be able to hold one record.
1586     */
1587 
1588     if ((pdu_v8_13->sysUpTime != rec_v8_13->sysUpTime) ||
1589         (pdu_v8_13->unix_secs != rec_v8_13->unix_secs) ||
1590         (pdu_v8_13->unix_nsecs != rec_v8_13->unix_nsecs) ||
1591         (pdu_v8_13->engine_id != rec_v8_13->engine_id) ||
1592         (pdu_v8_13->engine_type != rec_v8_13->engine_type))
1593         return -1;
1594 
1595   }
1596 
1597   pdu_v8_13->records[i].dFlows = rec_v8_13->dFlows;
1598   pdu_v8_13->records[i].dPkts = rec_v8_13->dPkts;
1599   pdu_v8_13->records[i].dOctets = rec_v8_13->dOctets;
1600   pdu_v8_13->records[i].First = rec_v8_13->First;
1601   pdu_v8_13->records[i].Last = rec_v8_13->Last;
1602   pdu_v8_13->records[i].src_prefix = rec_v8_13->srcaddr;
1603   pdu_v8_13->records[i].dst_prefix = rec_v8_13->dstaddr;
1604   pdu_v8_13->records[i].dst_mask = rec_v8_13->dst_mask;
1605   pdu_v8_13->records[i].src_mask = rec_v8_13->src_mask;
1606   pdu_v8_13->records[i].tos = rec_v8_13->tos;
1607   pdu_v8_13->records[i].src_as = rec_v8_13->src_as;
1608   pdu_v8_13->records[i].dst_as = rec_v8_13->dst_as;
1609   pdu_v8_13->records[i].input = rec_v8_13->input;
1610   pdu_v8_13->records[i].output = rec_v8_13->output;
1611 
1612   /* increment sequence # */
1613   enc->seq_next[seq_index]++;
1614 
1615   pdu_v8_13->count ++;
1616   enc->buf_size += sizeof (struct ftrec_v8_13);
1617 
1618   if (pdu_v8_13->count >= FT_PDU_V8_13_MAXFLOWS)
1619     return 0;
1620   else
1621     return 1;
1622 } /* fts3rec_pdu_v8_13_encode */
1623 
1624 /*
1625  * function: fts3rec_pdu_v8_14_encode
1626  *
1627  * Encode a fts3rec into a version 8 Agg method 14
1628  *
1629  * returns: -1 error encoding, PDU not encoded.
1630  *           0 PDU encoded.  Hint next call will fail.
1631  *           1 PDU encoded.  Room for more.
1632  *
1633 */
fts3rec_pdu_v8_14_encode(struct ftencode * enc,struct fts3rec_v8_14 * rec_v8_14)1634 int fts3rec_pdu_v8_14_encode(struct ftencode *enc,
1635   struct fts3rec_v8_14 *rec_v8_14)
1636 {
1637   struct ftpdu_v8_14 *pdu_v8_14;
1638   unsigned int seq_index;
1639   int i;
1640 
1641   pdu_v8_14 = (struct ftpdu_v8_14*) enc->buf_enc;
1642 
1643   /* index to sequence # */
1644   seq_index = rec_v8_14->engine_id<<8 | rec_v8_14->engine_type;
1645 
1646   i = pdu_v8_14->count;
1647 
1648   /* space to encode more ? */
1649   if (i >= FT_PDU_V8_14_MAXFLOWS)
1650     return -1;
1651 
1652   /* if this is the first record, fill in the header */
1653   if (!i) {
1654 
1655     pdu_v8_14->version = 8;
1656     pdu_v8_14->sysUpTime = rec_v8_14->sysUpTime;
1657     pdu_v8_14->unix_secs = rec_v8_14->unix_secs;
1658     pdu_v8_14->unix_nsecs = rec_v8_14->unix_nsecs;
1659     pdu_v8_14->engine_type = rec_v8_14->engine_type;
1660     pdu_v8_14->engine_id = rec_v8_14->engine_id;
1661     pdu_v8_14->aggregation = 14;
1662     pdu_v8_14->agg_version = 2;
1663     pdu_v8_14->flow_sequence = enc->seq_next[seq_index];
1664     enc->buf_size = 28; /* pdu header size */
1665 
1666   } else {
1667 
1668     /*  sysUpTime, unix_secs, unix_nsecs, and engine_* must match for
1669      *  each pdu.  If a stream is being re-encoded this will normally
1670      *  work out fine, if the stream was sorted or changed in some way
1671      *  the PDU may only be able to hold one record.
1672     */
1673 
1674     if ((pdu_v8_14->sysUpTime != rec_v8_14->sysUpTime) ||
1675         (pdu_v8_14->unix_secs != rec_v8_14->unix_secs) ||
1676         (pdu_v8_14->unix_nsecs != rec_v8_14->unix_nsecs) ||
1677         (pdu_v8_14->engine_id != rec_v8_14->engine_id) ||
1678         (pdu_v8_14->engine_type != rec_v8_14->engine_type))
1679         return -1;
1680 
1681   }
1682 
1683   pdu_v8_14->records[i].dFlows = rec_v8_14->dFlows;
1684   pdu_v8_14->records[i].dPkts = rec_v8_14->dPkts;
1685   pdu_v8_14->records[i].dOctets = rec_v8_14->dOctets;
1686   pdu_v8_14->records[i].First = rec_v8_14->First;
1687   pdu_v8_14->records[i].Last = rec_v8_14->Last;
1688   pdu_v8_14->records[i].src_prefix = rec_v8_14->srcaddr;
1689   pdu_v8_14->records[i].dst_prefix = rec_v8_14->dstaddr;
1690   pdu_v8_14->records[i].srcport = rec_v8_14->srcport;
1691   pdu_v8_14->records[i].dstport = rec_v8_14->dstport;
1692   pdu_v8_14->records[i].input = rec_v8_14->input;
1693   pdu_v8_14->records[i].output = rec_v8_14->output;
1694   pdu_v8_14->records[i].dst_mask = rec_v8_14->dst_mask;
1695   pdu_v8_14->records[i].src_mask = rec_v8_14->src_mask;
1696   pdu_v8_14->records[i].tos = rec_v8_14->tos;
1697   pdu_v8_14->records[i].prot = rec_v8_14->prot;
1698 
1699   /* increment sequence # */
1700   enc->seq_next[seq_index]++;
1701 
1702   pdu_v8_14->count ++;
1703   enc->buf_size += sizeof (struct ftrec_v8_14);
1704 
1705   if (pdu_v8_14->count >= FT_PDU_V8_14_MAXFLOWS)
1706     return 0;
1707   else
1708     return 1;
1709 } /* fts3rec_pdu_v8_14_encode */
1710