📄 trpr.cpp
字号:
/********************************************************************* * * AUTHORIZATION TO USE AND DISTRIBUTE * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: * * (1) source code distributions retain this paragraph in its entirety, * * (2) distributions including binary code include this paragraph in * its entirety in the documentation or other materials provided * with the distribution, and * * (3) all advertising materials mentioning features or use of this * software display the following acknowledgment: * * "This product includes software written and developed * by Brian Adamson and Joe Macker of the Naval Research * Laboratory (NRL)." * * The name of NRL, the name(s) of NRL employee(s), or any entity * of the United States Government may not be used to endorse or * promote products derived from this software, nor does the * inclusion of the NRL written and developed software directly or * indirectly suggest NRL or United States Government endorsement * of this product. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ********************************************************************/ #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <limits.h> // for PATH_MAX#include <string.h>#include <math.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h> #include <sys/time.h> // for gettimeofday()#include <sys/types.h>#define VERSION "1.9b9"#ifndef MIN#define MIN(X,Y) ((X<Y)?X:Y)#define MAX(X,Y) ((X>Y)?X:Y)#endif // !MINconst int MAX_LINE = 256;enum TraceFormat {TCPDUMP, DREC, NS};enum PlotMode {RATE, INTERARRIVAL, LATENCY, DROPS, LOSS, LOSS2, VELOCITY};class FastReader{ public: enum Result {OK, ERROR, DONE, TIMEOUT}; FastReader(); FastReader::Result Read(FILE* filePtr, char* buffer, unsigned int* len, double timeout = -1.0); FastReader::Result Readline(FILE* filePtr, char* buffer, unsigned int* len, double timeout = -1.0); private: enum {BUFSIZE = 2048}; char savebuf[BUFSIZE]; char* saveptr; unsigned int savecount;}; // end class FastReaderclass Waiter{ public: Waiter(); void Reset(); bool Wait(double seconds); private: struct timeval last_time; double excess; }; // end class WaiterWaiter::Waiter() : excess(0.0){ Reset();}void Waiter::Reset(){ struct timezone tz; gettimeofday(&last_time, &tz); excess = 0.0; } // end Waiter::Reset()bool Waiter::Wait(double delay){ delay -= excess; struct timeval timeout; if (delay >= (double)0.0) { timeout.tv_sec = (unsigned long) delay; timeout.tv_usec = (unsigned long)(1000000.0 * (delay - timeout.tv_sec)); } else { timeout.tv_sec = timeout.tv_usec = 0; } fd_set fdSet; FD_ZERO(&fdSet); select(0, (fd_set*)NULL, (fd_set*)NULL, (fd_set*)NULL, &timeout); struct timeval thisTime; struct timezone tz; gettimeofday(&thisTime, &tz); double actual = thisTime.tv_sec - last_time.tv_sec; if (thisTime.tv_usec < last_time.tv_usec) actual -= ((double)(thisTime.tv_usec - last_time.tv_usec)) * 1.0e-06; else actual += ((double)(thisTime.tv_usec - last_time.tv_usec)) * 1.0e-06; excess = actual - delay; if (excess < -2.0) { fprintf(stderr, "Waiter::Wait() Warning! dropping behind real time ...\n"); excess = 0.0; } memcpy(&last_time, &thisTime, sizeof(struct timeval)); return true;} // end Waiter::Wait()class FlowId{ public: FlowId() : valid(false) {} FlowId(unsigned long x) : valid(true), value(x) {} bool IsValid() const {return valid;} unsigned long Value() const {return value;} void Invalidate() {valid = false;} operator unsigned long() const {return value;} bool Match(unsigned long x) const; private: bool valid; unsigned long value;}; // end class FlowIdbool FlowId::Match(unsigned long x) const{ if (!valid || (x == value)) return true; else return false;} // end FlowId::Match()class Address{ public: enum Domain {IPv4, IPv6, OTHER}; Address() {addr[0] = '\0';} Address(unsigned long value, Domain domain) {Set(value, domain);} Address(const char* string) {Set(string);} void Set(const char* string) { strncpy(addr, string, 63); addr[63] = '\0'; } void Set(unsigned long value, Domain domain) { if (IPv4 == domain) { unsigned char* a = (unsigned char*)&value; sprintf(addr, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]); } else { sprintf(addr, "%lu", value); } } // buf is network order IPv6 address void SetIPv6(unsigned long* buf) { addr[0] = '\0'; for (unsigned int i = 0; i < 4; i++) { unsigned short* a = (unsigned short*)(buf+i); char temp[16]; sprintf(temp, "%x:%x%s", ntohs(a[0]), ntohs(a[1]), (i < 3) ? ":" : ""); strcat(addr, temp); } } void Invalidate() {addr[0] = '\0';} bool IsValid() const {return ('\0' != addr[0]);} bool operator==(const Address& x) const {return (0 == strcmp(addr, x.addr));} void PrintDescription(FILE* f) const {fprintf(f, "%s", addr);} private: char addr[64]; }; // end class Address class PacketEvent{ public: enum EventType {INVALID, RECEPTION, TRANSMISSION, DROP, LOSS, TIMEOUT}; PacketEvent(); ~PacketEvent(); // Generalized tracepoint node(a,[b]) NS class TracePoint { public: TracePoint() : src_port(-1), dst_port(-1) {} TracePoint(const Address& sa) : src_addr(sa), src_port(-1), dst_port(-1) {} TracePoint(const Address& sa, unsigned short sp) : src_addr(sa), src_port(sp), dst_port(-1) {} TracePoint(const Address& sa, unsigned short sp, const Address& da, unsigned short dp) : src_addr(sa), src_port(sp), dst_addr(da), dst_port(dp) {} bool Match(const TracePoint& p) const; const Address& SrcAddr() const {return src_addr;} unsigned short SrcPort() const {return src_port;} const Address& DstAddr() const {return dst_addr;} unsigned short DstPort() const {return dst_port;} bool IsValid() const {return (src_addr.IsValid() || dst_addr.IsValid());} void Invalidate() { src_addr.Invalidate(); src_port = -1; dst_addr.Invalidate(); dst_port = -1; } void SetSrc(const Address& srcAddr) { src_addr = srcAddr; src_port = -1; } void SetSrc(const Address& srcAddr, unsigned short srcPort) { src_addr = srcAddr; src_port = srcPort; } void SetDst(const Address& dstAddr) { dst_addr = dstAddr; dst_port = -1; } void SetDst(const Address& dstAddr, unsigned short dstPort) { dst_addr = dstAddr; dst_port = -1; } void PrintDescription(FILE* f) const { src_addr.PrintDescription(f); if (src_port >= 0) fprintf(f, ":%d", src_port); fprintf(f, ", "); dst_addr.PrintDescription(f); if (dst_port >= 0) fprintf(f, ":%d", dst_port); } private: Address src_addr; int src_port; // -1 is invalid Address dst_addr; int dst_port; // -1 is invalid }; // end class TracePoint EventType Type() {return type;} void SetType(EventType theType) {type = theType;} double Time() {return time;} void SetTime(double theTime) {time = theTime;} PacketEvent::TracePoint& Link() {return link;} void LinkClear() {link.Invalidate();} void SetLinkSrc(const Address& srcAddr) {link.SetSrc(srcAddr);} void SetLinkSrc(const Address& srcAddr, unsigned short srcPort) {link.SetSrc(srcAddr,srcPort);} void SetLinkDst(const Address& dstAddr) {link.SetDst(dstAddr);} void SetLinkDst(const Address& dstAddr, unsigned short dstPort) {link.SetDst(dstAddr, dstPort);} const Address& SrcAddr() {return src_addr;} void SetSrcAddr(const Address& theAddr) {src_addr = theAddr;} unsigned short SrcPort() {return src_port;} void SetSrcPort(unsigned short thePort) {src_port = thePort;} const Address& DstAddr() {return dst_addr;} void SetDstAddr(const Address& theAddr) {dst_addr = theAddr;} unsigned short DstPort() {return dst_port;} void SetDstPort(unsigned short thePort) {dst_port = thePort;} const char* Protocol() {return protocol;} bool SetProtocol(const char* name); unsigned int Size() {return size;} void SetSize(unsigned int theSize) {size = theSize;} double RxTime() {return rx_time;} void SetRxTime(double theTime) {rx_time = theTime;} double TxTime() {return tx_time;} void SetTxTime(double theTime) {tx_time = theTime;} unsigned long Sequence() {return sequence;} void SetSequence(unsigned long theSequence) {sequence = theSequence;} unsigned long FlowId() {return flow_id.Value();} void SetFlowId(unsigned long id) {flow_id = id;} void SetPosition(double x, double y) {pos_x = x; pos_y = y;} double PosX() {return pos_x;} double PosY() {return pos_y;} private: EventType type; double time; TracePoint link; Address src_addr; // (TBD) Use NetworkAddress class here? int src_port; Address dst_addr; int dst_port; unsigned int size; char* protocol; double tx_time; double rx_time; unsigned long sequence; ::FlowId flow_id; double pos_x; // drec GPS only double pos_y; // drec GPS only }; // end class PacketEventPacketEvent::PacketEvent(): type(INVALID), time(-1.0), src_port(-1), dst_port(-1), size(0), protocol(NULL), pos_x(999.0), pos_y(999.0){}PacketEvent::~PacketEvent(){ if (protocol) delete protocol;}bool PacketEvent::SetProtocol(const char* name){ if (protocol) delete protocol; unsigned int len = name ? strlen(name) + 1 : 0; if (len) { protocol = new char[len]; if (protocol) { strcpy(protocol, name); return true; } else { perror("trpr: PacketEvent::SetProtocol() \"new()\" error"); return false; } } else { protocol = NULL; return true; }} // end PacketEvent::SetProtocol()bool PacketEvent::TracePoint::Match(const TracePoint& p) const{ if ((!src_addr.IsValid() || src_addr == p.SrcAddr()) && ((-1 == src_port) || (src_port == p.SrcPort())) && (!dst_addr.IsValid() || dst_addr == p.DstAddr()) && ((-1 == dst_port) || (dst_port == p.DstPort()))) { fprintf(stderr, ""); return true; } else { return false; } } // end PacketEvent::TracePoint::Match()class EventParser{ public: virtual bool GetNextPacketEvent(FILE* filePtr, PacketEvent* theEvent, double timeout = -1.0) = 0; protected: FastReader reader; }; // end class EventParserclass NsEventParser : public EventParser{ public: enum NodeType {AGT, RTR, MAC}; bool GetNextPacketEvent(FILE* filePtr, PacketEvent* theEvent, double timeout = -1.0); }; // end class EventParserclass TcpdumpEventParser : public EventParser{ public: bool GetNextPacketEvent(FILE* filePtr, PacketEvent* theEvent, double timeout = -1.0); unsigned int PackHexLine(char* text, char* buf, unsigned int buflen); unsigned int Version(const char* hdr) const { return (((unsigned char)hdr[0] >> 4 ) & 0x0f);} unsigned int HeaderLength(const char* hdr) const { if(Version(hdr) == 4) return 4 * (((unsigned char)hdr[0]) & 0x0f); else return 40; } unsigned int PayloadLength(const char* hdr) {return (256 * (unsigned char)hdr[4] + (unsigned char)hdr[5]);} unsigned int TotalLength(const char* hdr) { if(Version(hdr) == 4) return (256*((unsigned char)hdr[2]) + ((unsigned char)hdr[3])); else return (PayloadLength(hdr) + 40); } unsigned char Protocol(char* hdr) { if(Version(hdr) == 4) return ((unsigned char)hdr[9]); else return ((unsigned char)hdr[6]); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -