📄 ftdecode.c
字号:
/* * Copyright (c) 2001 Mark Fullmer and The Ohio State University * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: ftdecode.c,v 1.24 2003/02/13 02:38:41 maf Exp $ */#include "ftconfig.h"#include "ftlib.h"#include <stddef.h>#if HAVE_STRINGS_H #include <strings.h>#endif#if HAVE_STRING_H #include <string.h>#endif/* * function ftpdu_check_seq * * Check sequence number in decoded PDU * * ftpdu_verify must be called first * * Returns 0 - sequence number matched expected * -1 - sequence number did not match expected * seq_rcv, seq_exp updated*/int ftpdu_check_seq(struct ftpdu *ftpdu, struct ftseq *ftseq){ struct ftpdu_header *ph; int ret; u_int seq_index; /* version 1 exports do not have sequence numbers */ if (ftpdu->ftv.d_version == 1) return 0; ph = (struct ftpdu_header*)&ftpdu->buf;#if BYTE_ORDER == LITTLE_ENDIAN SWAPINT32(ph->flow_sequence); SWAPINT16(ph->count);#endif /* LITTLE_ENDIAN */ seq_index = ph->engine_id<<8 | ph->engine_type; /* first time always okay */ if (!ftseq->seq_set[seq_index]) { ftseq->seq_set[seq_index] = 1; ftseq->seq[seq_index] = ph->flow_sequence + ph->count; ret = 0; } else { /* if cur == expecting then okay, else reset */ if (ph->flow_sequence == ftseq->seq[seq_index]) { ftseq->seq[seq_index] += ph->count; ret = 0; } else { ftseq->seq_rcv = ph->flow_sequence; ftseq->seq_exp = ftseq->seq[seq_index]; ftseq->seq[seq_index] = ph->flow_sequence + ph->count; /* calculate lost sequence numbers, account for wraparound at 2^32 */ if (ftseq->seq_rcv > ftseq->seq_exp) ftseq->seq_lost = ftseq->seq_rcv - ftseq->seq_exp; else ftseq->seq_lost = (0xFFFFFFFF - ftseq->seq_exp) + ftseq->seq_rcv; ret = -1; } }#if BYTE_ORDER == LITTLE_ENDIAN SWAPINT32(ph->flow_sequence); SWAPINT16(ph->count);#endif /* LITTLE_ENDIAN */ return ret;} /* ftpdu_check_seq *//* * function: ftpdu_verify * * verify PDU is valid * count is not too high * version is valid * sizeof structure is valid * * iff the verification checks pass then ftpdu->ftver is initialized to the * pdu version * and ftpdu->decodef() is initialized to the decode function * * pdu must be in network byte order and is returned in network byte order **/int ftpdu_verify(struct ftpdu *ftpdu){ struct ftpdu_header *ph; int size, ret; ret = -1; /* enough bytes to decode the count and version? */ if (ftpdu->bused < 4) goto ftpdu_verify_out_quick; ph = (struct ftpdu_header*)&ftpdu->buf;#if BYTE_ORDER == LITTLE_ENDIAN SWAPINT16(ph->version); SWAPINT16(ph->count);#endif /* LITTLE_ENDIAN */ bzero(&ftpdu->ftv, sizeof (struct ftver)); ftpdu->ftv.s_version = FT_IO_SVERSION; switch (ph->version) { case 1: /* max PDU's in record */ if (ph->count > FT_PDU_V1_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v1, records) + ph->count * sizeof (struct ftrec_v1); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 1; ftpdu->decodef = fts3rec_pdu_v1_decode; break; case 5: /* max PDU's in record */ if (ph->count > FT_PDU_V5_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v5, records) + ph->count * sizeof (struct ftrec_v5); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 5; ftpdu->decodef = fts3rec_pdu_v5_decode; break; case 6: /* max PDU's in record */ if (ph->count > FT_PDU_V6_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v6, records) + ph->count * sizeof (struct ftrec_v6); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 6; ftpdu->decodef = fts3rec_pdu_v6_decode; break; case 7: /* max PDU's in record */ if (ph->count > FT_PDU_V7_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v7, records) + ph->count * sizeof (struct ftrec_v7); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 7; ftpdu->decodef = fts3rec_pdu_v7_decode; break; case 8: /* enough bytes to decode the aggregation method and version? */ if (ftpdu->bused < (offsetof(struct ftpdu_v8_gen, agg_version) + sizeof ((struct ftpdu_v8_gen *)0)->agg_version)) goto ftpdu_verify_out; ftpdu->ftv.agg_method = ((struct ftpdu_v8_gen *)&ftpdu->buf)->aggregation; ftpdu->ftv.agg_version = ((struct ftpdu_v8_gen *)&ftpdu->buf)->agg_version; /* XXX Juniper hack */ if (ftpdu->ftv.agg_version == 0) ftpdu->ftv.agg_version = 2; /* can only decode version 2 aggregation method packets */ if (ftpdu->ftv.agg_version != 2) goto ftpdu_verify_out; switch (ftpdu->ftv.agg_method) { case 1: /* max PDU's in record */ if (ph->count > FT_PDU_V8_1_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_1, records) + ph->count * sizeof (struct ftrec_v8_1); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 1; ftpdu->decodef = fts3rec_pdu_v8_1_decode; break; case 2: /* max PDU's in record */ if (ph->count > FT_PDU_V8_2_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_2, records) + ph->count * sizeof (struct ftrec_v8_2); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 2; ftpdu->decodef = fts3rec_pdu_v8_2_decode; break; case 3: /* max PDU's in record */ if (ph->count > FT_PDU_V8_3_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_3, records) + ph->count * sizeof (struct ftrec_v8_3); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 3; ftpdu->decodef = fts3rec_pdu_v8_3_decode; break; case 4: /* max PDU's in record */ if (ph->count > FT_PDU_V8_4_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_4, records) + ph->count * sizeof (struct ftrec_v8_4); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 4; ftpdu->decodef = fts3rec_pdu_v8_4_decode; break; case 5: /* max PDU's in record */ if (ph->count > FT_PDU_V8_5_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_5, records) + ph->count * sizeof (struct ftrec_v8_5); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 5; ftpdu->decodef = fts3rec_pdu_v8_5_decode; break; case 6: /* max PDU's in record */ if (ph->count > FT_PDU_V8_6_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_6, records) + ph->count * sizeof (struct ftrec_v8_6); /* PDU received size == PDU expected size? */ /* Catalyst pads exports, so use > instead of != */ if (size > ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 6; ftpdu->decodef = fts3rec_pdu_v8_6_decode; break; case 7: /* max PDU's in record */ if (ph->count > FT_PDU_V8_7_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_7, records) + ph->count * sizeof (struct ftrec_v8_7); /* PDU received size == PDU expected size? */ /* Catalyst pads exports, so use > instead of != */ if (size > ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 7; ftpdu->decodef = fts3rec_pdu_v8_7_decode; break; case 8: /* max PDU's in record */ if (ph->count > FT_PDU_V8_8_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_8, records) + ph->count * sizeof (struct ftrec_v8_8); /* PDU received size == PDU expected size? */ /* Catalyst pads exports, so use > instead of != */ if (size > ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 8; ftpdu->decodef = fts3rec_pdu_v8_8_decode; break; case 9: /* max PDU's in record */ if (ph->count > FT_PDU_V8_9_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_9, records) + ph->count * sizeof (struct ftrec_v8_9); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 9; ftpdu->decodef = fts3rec_pdu_v8_9_decode; break; case 10: /* max PDU's in record */ if (ph->count > FT_PDU_V8_10_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_10, records) + ph->count * sizeof (struct ftrec_v8_10); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 10; ftpdu->decodef = fts3rec_pdu_v8_10_decode; break; case 11: /* max PDU's in record */ if (ph->count > FT_PDU_V8_11_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_11, records) + ph->count * sizeof (struct ftrec_v8_11); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 11; ftpdu->decodef = fts3rec_pdu_v8_11_decode; break; case 12: /* max PDU's in record */ if (ph->count > FT_PDU_V8_12_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_12, records) + ph->count * sizeof (struct ftrec_v8_12); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 12; ftpdu->decodef = fts3rec_pdu_v8_12_decode; break; case 13: /* max PDU's in record */ if (ph->count > FT_PDU_V8_13_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_13, records) + ph->count * sizeof (struct ftrec_v8_13); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 13; ftpdu->decodef = fts3rec_pdu_v8_13_decode; break; case 14: /* max PDU's in record */ if (ph->count > FT_PDU_V8_14_MAXFLOWS) goto ftpdu_verify_out; size = offsetof(struct ftpdu_v8_14, records) + ph->count * sizeof (struct ftrec_v8_14); /* PDU received size == PDU expected size? */ if (size != ftpdu->bused) goto ftpdu_verify_out; ftpdu->ftv.d_version = 8; ftpdu->ftv.agg_method = 14;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -