📄 ftio.c
字号:
return ftrec_size(&ver);} /* ftio_rec_size *//* * function: readn * * read()'s n bytes from fd * returns # of butes read, or -1 for error */int readn(register int fd, register void *ptr, register int nbytes){ int nleft, nread; nleft = nbytes; while (nleft > 0) { nread = read(fd, ptr, nleft); if (nread < 0) return nread; else if (nread == 0) break; nleft -= nread; (char*)ptr += nread; } return (nbytes - nleft);} /* readn *//* From Stevens * * function: writen * * write()'s n bytes to fd. * returns # of bytes written, or -1 for error */int writen(register int fd, register void *ptr, register int nbytes){ int nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write(fd, ptr, nleft); if (nwritten <= 0) return(nwritten); /* error */ nleft -= nwritten; (char*)ptr += nwritten; } return(nbytes - nleft);} /* writen *//* * function: ftiheader_read * * load a ftheader, possibly converting from an older version * * header is returned in host byte order * * returns: <0 error * >= 0 okay */int ftiheader_read(int fd, struct ftiheader *ihead){ struct fts1header *h1; struct ftheader_gen head_gen; struct fttlv tlv; struct ftmap_ifname *ftmin; struct ftmap_ifalias *ftmia; int n, ret, len_read, len_buf, off, flip, left; u_int32 ip; u_int16 entries, ifIndex, *ifIndex_list; u_int32 head_off_d; char *dp, *c, *enc_buf; ret = -1; enc_buf = (char*)0L; ifIndex_list = (u_int16*)0L; bzero(ihead, sizeof (struct ftiheader)); /* read the stream header version area */ if ((n = readn(fd, (char*)&head_gen, sizeof head_gen)) < 0) { fterr_warn("read()"); goto ftiheader_read_out; } if (n != sizeof head_gen) { fterr_warnx( "ftiheader_read(): Warning, short read while loading header top."); goto ftiheader_read_out; } /* verify magic */ if ((head_gen.magic1 != FT_HEADER_MAGIC1) || (head_gen.magic2 != FT_HEADER_MAGIC2)) { fterr_warnx("ftiheader_read(): Warning, bad magic number"); goto ftiheader_read_out; }#if BYTE_ORDER == BIG_ENDIAN if (head_gen.byte_order == FT_HEADER_LITTLE_ENDIAN) flip = 1; else flip = 0;#endif /* BYTE_ORDER == BIG_ENDIAN */#if BYTE_ORDER == LITTLE_ENDIAN if (head_gen.byte_order == FT_HEADER_BIG_ENDIAN) flip = 1; else flip = 0;#endif /* BYTE_ORDER == LITTLE_ENDIAN */ /* determine how many bytes to read */ if (head_gen.s_version == 1) { /* v1 header size static */ len_read = (sizeof (struct fts1header)) - sizeof head_gen; len_buf = sizeof (struct fts1header); } else if (head_gen.s_version == 3) { /* read the version 3 index */ if ((n = readn(fd, (char*)&head_off_d, sizeof head_off_d)) < 0) { fterr_warn("read()"); goto ftiheader_read_out; } if (n != sizeof head_off_d) { fterr_warnx( "ftiheader_read(): Error, short read while loading header data offset."); goto ftiheader_read_out; } /* data offset must be in host byte order */ if (flip) SWAPINT32(head_off_d); /* v3 dynamic header size */ len_read = head_off_d - sizeof head_gen - sizeof head_off_d; len_buf = len_read + sizeof head_gen + sizeof head_off_d; } else { fterr_warnx("Stream format must be 1 or 3, not %d", (int)head_gen.s_version); goto ftiheader_read_out; } /* allocate storage for decode */ if (!(enc_buf = (char*)malloc(len_buf))) { fterr_warn("malloc()"); goto ftiheader_read_out; } ihead->enc_len = len_buf; /* insert the generic part to the top of the buffer */ bcopy(&head_gen, enc_buf, sizeof head_gen); off = sizeof head_gen; /* for version 3 insert the data offset */ if (head_gen.s_version == 3) { bcopy(&head_off_d, enc_buf+off, sizeof head_off_d); off += sizeof head_off_d; } /* read the rest of the header */ if ((n = readn(fd, (char*)enc_buf+off, len_read)) < 0) { fterr_warn("read()"); goto ftiheader_read_out; } if (n != len_read) { fterr_warnx("Short read while loading header"); goto ftiheader_read_out; } /* v1 header? yes, convert it directly to internal format */ if (head_gen.s_version == 1) { h1 = (struct fts1header*) enc_buf; ihead->magic1 = h1->magic1; ihead->magic2 = h1->magic2; ihead->byte_order = h1->byte_order; ihead->s_version = h1->s_version; ihead->d_version = h1->d_version; ihead->cap_start = h1->start; ihead->cap_end = h1->end; ihead->flags = h1->flags; ihead->rotation = h1->rotation; ihead->flows_count = h1->nflows; ihead->flows_lost = h1->pdu_drops; ihead->flows_misordered = h1->pdu_misordered; /* translated from v1 */ ihead->flags |= FT_HEADER_FLAG_XLATE; ihead->fields = FT_FIELD_VENDOR | FT_FIELD_EX_VER | FT_TLV_CAP_START | FT_TLV_CAP_END | FT_FIELD_HEADER_FLAGS | FT_FIELD_ROT_SCHEDULE | FT_FIELD_FLOW_COUNT; /* convert to host byte order */ if (flip) { SWAPINT16(ihead->d_version); SWAPINT32(ihead->cap_start); SWAPINT32(ihead->cap_end); SWAPINT32(ihead->flags); SWAPINT32(ihead->rotation); SWAPINT32(ihead->flows_count); SWAPINT32(ihead->exporter_ip); SWAPINT32(ihead->flows_lost); SWAPINT32(ihead->flows_misordered); SWAPINT32(ihead->pkts_corrupt); SWAPINT32(ihead->seq_reset); } /* flip */ if (h1->hostname[0]) { if (!(ihead->cap_hostname = (char*)malloc(FT_HEADER1_HN_LEN))) { fterr_warn("malloc()"); goto ftiheader_read_out; } strcpy(ihead->cap_hostname, h1->hostname); ihead->fields |= FT_FIELD_CAP_HOSTNAME; } if (h1->comments[0]) { if (!(ihead->comments = (char*)malloc(FT_HEADER1_CMNT_LEN))) { fterr_warn("malloc()"); goto ftiheader_read_out; } strcpy(ihead->comments, h1->comments); ihead->fields |= FT_FIELD_COMMENTS; } } else if (head_gen.s_version == 3) { /* set decode pointer to first tlv */ dp = enc_buf + sizeof head_gen + sizeof head_off_d; left = len_read; /* copy generic header to internal */ ihead->magic1 = head_gen.magic1; ihead->magic2 = head_gen.magic2; ihead->byte_order = head_gen.byte_order; ihead->s_version = head_gen.s_version; /* smallest TLV is 2+2+0 (null TLV). Don't try to read padding added * for alignment. */ while (left >= 4) { /* parse type, store in host byte order */ bcopy(dp, &tlv.t, 2); if (flip) SWAPINT16(tlv.t); dp += 2; left -= 2; /* parse len, store in host byte order */ bcopy(dp, &tlv.l, 2); if (flip) SWAPINT16(tlv.l); dp += 2; left -= 2; /* parse val */ tlv.v = dp; /* point decode buf at next tlv */ dp += tlv.l; left -= tlv.l; /* TLV length sane? */ if (left < 0) break; switch (tlv.t) { case FT_TLV_NULL: break; case FT_TLV_VENDOR: bcopy(tlv.v, &ihead->vendor, 2); if (flip) SWAPINT16(ihead->vendor); ihead->fields |= FT_FIELD_VENDOR; break; case FT_TLV_EX_VER: bcopy(tlv.v, &ihead->d_version, 2); if (flip) SWAPINT16(ihead->d_version); ihead->fields |= FT_FIELD_EX_VER; break; case FT_TLV_AGG_VER: bcopy(tlv.v, &ihead->agg_version, 1); ihead->fields |= FT_FIELD_AGG_VER; break; case FT_TLV_AGG_METHOD: bcopy(tlv.v, &ihead->agg_method, 1); ihead->fields |= FT_FIELD_AGG_METHOD; break; case FT_TLV_EXPORTER_IP: bcopy(tlv.v, &ihead->exporter_ip, 4); if (flip) SWAPINT32(ihead->exporter_ip); ihead->fields |= FT_FIELD_EXPORTER_IP; break; case FT_TLV_CAP_START: bcopy(tlv.v, &ihead->cap_start, 4); if (flip) SWAPINT32(ihead->cap_start); ihead->fields |= FT_FIELD_CAP_START; break; case FT_TLV_CAP_END: bcopy(tlv.v, &ihead->cap_end, 4); if (flip) SWAPINT32(ihead->cap_end); ihead->fields |= FT_FIELD_CAP_END; break; case FT_TLV_HEADER_FLAGS: bcopy(tlv.v, &ihead->flags, 4); if (flip) SWAPINT32(ihead->flags); ihead->fields |= FT_FIELD_HEADER_FLAGS; break; case FT_TLV_ROT_SCHEDULE: bcopy(tlv.v, &ihead->rotation, 4); if (flip) SWAPINT32(ihead->rotation); ihead->fields |= FT_FIELD_ROT_SCHEDULE; break; case FT_TLV_FLOW_COUNT: bcopy(tlv.v, &ihead->flows_count, 4); if (flip) SWAPINT32(ihead->flows_count); ihead->fields |= FT_FIELD_FLOW_COUNT; break; case FT_TLV_FLOW_LOST: bcopy(tlv.v, &ihead->flows_lost, 4); if (flip) SWAPINT32(ihead->flows_lost); ihead->fields |= FT_FIELD_FLOW_LOST; break; case FT_TLV_FLOW_MISORDERED: bcopy(tlv.v, &ihead->flows_misordered, 4); if (flip) SWAPINT32(ihead->flows_misordered); ihead->fields |= FT_FIELD_FLOW_MISORDERED; break; case FT_TLV_PKT_CORRUPT: bcopy(tlv.v, &ihead->pkts_corrupt, 4); if (flip) SWAPINT32(ihead->pkts_corrupt); ihead->fields |= FT_FIELD_PKT_CORRUPT; break; case FT_TLV_SEQ_RESET: bcopy(tlv.v, &ihead->seq_reset, 4); if (flip) SWAPINT32(ihead->seq_reset); ihead->fields |= FT_FIELD_SEQ_RESET; break; case FT_TLV_CAP_HOSTNAME: if (!(ihead->cap_hostname = (char*)malloc(tlv.l))) { fterr_warn("malloc()"); goto ftiheader_read_out; } strcpy(ihead->cap_hostname, tlv.v); ihead->fields |= FT_FIELD_CAP_HOSTNAME; break; case FT_TLV_COMMENTS: if (!(ihead->comments = (char*)malloc(tlv.l))) { fterr_warn("malloc()"); goto ftiheader_read_out; } strcpy(ihead->comments, tlv.v); ihead->fields |= FT_FIELD_COMMENTS; break; case FT_TLV_IF_NAME: if (!ihead->ftmap) { if (!(ihead->ftmap = ftmap_new())) { fterr_warnx("ftmap_new(): failed"); goto ftiheader_read_out; } } ihead->fields |= FT_FIELD_IF_NAME; /* decode the value */ bcopy(tlv.v, &ip, 4); if (flip) SWAPINT32(ip); bcopy(tlv.v+4, &ifIndex, 2); if (flip) SWAPINT32(ifIndex); c = tlv.v+6; /* allocate space for a ifname */ if (!(ftmin = ftmap_ifname_new(ip, ifIndex, c))) { fterr_warnx("ftmap_ifname_new(): failed"); goto ftiheader_read_out; } /* and link it in */ FT_LIST_INSERT_HEAD(&ihead->ftmap->ifname, ftmin, chain); break; case FT_TLV_IF_ALIAS: if (!ihead->ftmap) { if (!(ihead->ftmap = ftmap_new())) { fterr_warnx("ftmap_new(): failed"); goto ftiheader_read_out; } } ihead->fields |= FT_FIELD_IF_ALIAS; /* decode the value */ bcopy(tlv.v, &ip, 4); if (flip) SWAPINT32(ip); bcopy(tlv.v+4, &entries, 2); if (flip) SWAPINT32(entries); c = tlv.v+6 + (entries*2); if (!(ifIndex_list = (u_int16*)malloc(entries*2))) { fterr_warn("malloc()"); goto ftiheader_read_out; } bcopy(tlv.v+6, ifIndex_list, entries*2); /* allocate space for a ifname */ if (!(ftmia = ftmap_ifalias_new(ip, ifIndex_list, entries, c))) { fterr_warnx("ftmap_ifalias_new(): failed"); goto ftiheader_read_out; } free(ifIndex_list); ifIndex_list = (u_int16*)0L; /* and link it in */ FT_LIST_INSERT_HEAD(&ihead->ftmap->ifalias, ftmia, chain); break; default: break; } /* switch */ } /* while */ } /* s_version == 3 */ ret = 0;ftiheader_read_out: if (ifIndex_list) free(ifIndex_list); if (enc_buf) free(enc_buf); return ret;} /* ftiheader_read *//* * function: ftio_check_generic * * check if this io stream can be used with the ftstrec_gen * pseudo record. fts3rec_gen overlays the common fields of * v1, v5, v6, and v7 formats * * returns: <0 error * >= 0 okay */int ftio_check_generic(struct ftio *ftio){ struct ftver ver; ftio_get_ver(ftio, &ver); if ((ver.d_version != 1) && (ver.d_version != 5) && (ver.d_version != 6) && (ver.d_version != 7)) { fterr_warnx("Export version %d not supported by format", (int)ver.d_version); return -1; } return 0;} /* ftio_check_generic *//* * function: ftio_check_generic5 * * check if this io stream can be used with the ftstrec_gen * pseudo record. fts3rec_gen overlays the common fields of * v5, v6, and v7 formats * * returns: <0 error * >= 0 okay */int ftio_check_generic5(struct ftio *ftio){ struct ftver ver; ftio_get_ver(ftio, &ver); if ((ver.d_version != 5) && (ver.d_version != 6) && (ver.d_version != 7)) { fterr_warnx("Export version %d not supported by format", (int)ver.d_version); return -1; } return 0;} /* ftio_check_generic5 *//* * function: ftltime * * Flow exports represent time with a combination of uptime of the * router, real time, and offsets from the router uptime. ftltime * converts from the PDU to a standard unix seconds/milliseconds * representation * * returns: struct fttime */struct fttime ftltime(u_int32 sys, u_int32 secs, u_int32 nsecs, u_int32 t){ u_int32 sys_s, sys_m; struct fttime ftt; /* sysUpTime is in milliseconds, convert to seconds/milliseconds */ sys_s = sys / 1000; sys_m = sys % 1000; /* unix seconds/nanoseconds to secon
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -