📄 report.c
字号:
/* -*- Mode: C; -*- *//******************************************************************************* ** Copyright 2005 University of Cambridge Computer Laboratory. ** ** This file is part of Nprobe. ** ** Nprobe is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** Nprobe is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Nprobe; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** *******************************************************************************/#include <stdio.h>#include <stdlib.h>#include <strings.h>#include <ctype.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/resource.h>#ifdef __alpha__#include <sys/mbuf.h>#endif#include <net/route.h>#include <net/if.h>#include <netdb.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#ifdef __alpha__#include <netinet/ip_var.h>#endif#include <netinet/tcp.h>#include <netinet/if_ether.h>#include <arpa/inet.h>#include <signal.h>#include <unistd.h>#include <linux/limits.h>#include <assert.h>#include "list.h"#include "pkt.h"#include "seq.h"#include "flows.h"#include "http.h"#include "tcp.h"#include "service.h"#include "udp.h"#include "udp_ns.h"#include "icmp.h"#include "print_util.h"#include "procstat.h"#include "sundry_records.h"#include "if_stats.h"#include "report.h"#include "output.h"#include "counters.h"#include "writer.h"#include "wread_util.h"#include "http_util.h"#include "content_t.h"//#include "probe_config.h"#define MIN(x, y) ((x) < (y) ? (x) : (y))#define MAX(x, y) ((x) > (y) ? (x) : (y))#if defined FINAL_REPORT || defined REPORTint report = 0;#endif /* defined FINAL_REPORT || defined REPORT *//* * HTTP stuff */void print_trans(FILE *f, http_trans_t *tp, int indx, int client_seen, int server_seen, unsigned int addit_fields, us_clock_t start){ int non_prints = 0; int need_nl = 0;#if 0 printf("%u\n%u\n%u\n%u\n(0 %u %u %u) \n", tp->inner.cinf.reqstart_us, tp->inner.cinf.reqend_us, tp->inner.sinf.repstart_us, tp->inner.sinf.repend_us, tp->inner.cinf.reqend_us - tp->inner.cinf.reqstart_us, tp->inner.sinf.repstart_us - tp->inner.cinf.reqend_us, tp->inner.sinf.repend_us - tp->inner.sinf.repstart_us);#endif if (indx >= 0) REP(f, " Transaction #%d\n", indx); if (client_seen) { REP(f, " Req %s - ", us_clock_ts_string(tp->inner.cinf.reqstart_us + start)); REP(f, "%s = %dms (%dus)\n", us_clock_ts_string(tp->inner.cinf.reqend_us + start), (tp->inner.cinf.reqend_us-tp->inner.cinf.reqstart_us)/US_IN_MS, tp->inner.cinf.reqend_us-tp->inner.cinf.reqstart_us); } if (server_seen) { REP(f, " Rep %s - ", us_clock_ts_string(tp->inner.sinf.repstart_us + start)); REP(f, "%s = %dms (%dus)\n", us_clock_ts_string(tp->inner.sinf.repend_us + start), (tp->inner.sinf.repend_us-tp->inner.sinf.repstart_us)/US_IN_MS, tp->inner.sinf.repend_us-tp->inner.sinf.repstart_us); if (addit_fields & AF_FIRST_REP_DATA_TM) { REP(f, " (Body %+dms (%+dus))\n", (tp->inner.first_sdata_pkt_us-tp->inner.sinf.repstart_us)/US_IN_MS, tp->inner.first_sdata_pkt_us-tp->inner.sinf.repstart_us); } } if (client_seen && server_seen) REP(f, " Req end - Rep start = %dms (%dus)\n", (tp->inner.sinf.repstart_us-tp->inner.cinf.reqend_us)/US_IN_MS, tp->inner.sinf.repstart_us-tp->inner.cinf.reqend_us); if (client_seen) { if (!(tp->inner.hclient.status & TRANS_VAL)) { REP(f, " Client transaction invalid\n"); goto c_inval; } if (tp->inner.hclient.status & TRANS_ERR) REP(f, " Error %d %s\n", tp->inner.hclient.error, http_err_string(tp->inner.hclient.error)); if (tp->inner.hclient.status & TRANS_DUMMY_UNSYNCH) { REP(f, " Unsynchronised: %u/%u from client (start %u)\n", tp->inner.hclient.recd_len, tp->inner.hclient.recd_pkts, tp->inner.cinf.reqstart_us); if (tp->inner.hclient.gaps_bytes) REP(f, " missing: %u/%u\n", tp->inner.hclient.gaps_bytes, tp->inner.hclient.gaps_pkts); } else if (tp->inner.hclient.status & TRANS_DUMMY_ERR) { REP(f, " Following error: %u%u from client\n", tp->inner.hclient.recd_len, tp->inner.hclient.recd_pkts); } else { REP(f, " Method: %s ", method_string(tp->inner.cinf.method)); if (tp->inner.cinf.reqlen || 1) { REP(f, "Object "); non_prints = print_seq2str(f, tp->req, tp->inner.cinf.reqlen); } REP(f, "\n"); //if (tp->inner.hclient.content_type != CT_UNKNOWN) REP(f, " Content type %s ", content_type_string(tp->inner.hclient.content_type)); if (tp->inner.hclient.recd_len || tp->inner.hclient.recd_pkts) REP(f, " %u of %d in %u pkts ", tp->inner.hclient.recd_len, tp->inner.hclient.body_len, tp->inner.hclient.recd_pkts); REP(f, " %s %s %s %s %s", tp->inner.hclient.status & TRANS_CHUNKED ? "Chunked" : "", tp->inner.hclient.status & TRANS_INCOMPLETE ? "Incomplete" : "", tp->inner.hclient.status & TRANS_RESYNCHED ? "Resynched" : "", tp->inner.hclient.status & TRANS_LOST_SYNCH ? "Lost synch" : "", tp->inner.hclient.status & TRANS_HDR_FRAG ? "Hdr. frag." : ""); REP(f, "\n"); if (non_prints) REP(f, "XXX Caution - request contains non-printing characters XXX\n"); if (tp->inner.cinf.hostlen) { REP(f, " Host: "); non_prints = print_seq2str(f, tp->host, tp->inner.cinf.hostlen); REP(f, "\n"); if (non_prints) REP(f, "XXX Caution - reference contains non-printing characters XXX\n"); } if (tp->inner.cinf.reflen) { REP(f, " Referer: "); non_prints = print_seq2str(f, tp->ref, tp->inner.cinf.reflen); REP(f, "\n"); if (non_prints) REP(f, "XXX Caution - reference contains non-printing characters XXX\n"); } if (tp->inner.cinf.uagentlen) { REP(f, " User agent: "); non_prints = print_seq2str(f, tp->uagent, tp->inner.cinf.uagentlen); REP(f, "\n"); if (non_prints) REP(f, "XXX Caution - reference contains non-printing characters XXX\n"); } if (tp->inner.cinf.vialen) { REP(f, " Via: "); non_prints = print_seq2str(f, tp->cvia, tp->inner.cinf.vialen); REP(f, "\n"); if (non_prints) REP(f, "XXX Caution - reference contains non-printing characters XXX\n"); } if (tp->inner.hclient.gaps_bytes) REP(f, " missing: %u/%u\n", tp->inner.hclient.gaps_bytes, tp->inner.hclient.gaps_pkts); } } c_inval: if (server_seen) { if (!(tp->inner.hserver.status & TRANS_VAL)) { REP(f, " Server transaction invalid\n"); goto s_inval; } if (tp->inner.hserver.status & TRANS_ERR) REP(f, " Error %d %s\n", tp->inner.hserver.error, http_err_string(tp->inner.hserver.error)); if (tp->inner.hserver.status & TRANS_DUMMY_UNSYNCH) { REP(f, " Unsynchronised: %u/%u from server (%u - %u)\n", tp->inner.hserver.recd_len, tp->inner.hserver.recd_pkts, tp->inner.sinf.repstart_us, tp->inner.sinf.repend_us); if (tp->inner.hserver.gaps_bytes) REP(f, " missing: %u/%u\n", tp->inner.hserver.gaps_bytes, tp->inner.hserver.gaps_pkts); } else if (tp->inner.hserver.status & TRANS_DUMMY_ERR) { REP(f, " Following error: %u/%u from server\n", tp->inner.hserver.recd_len, tp->inner.hserver.recd_pkts); } else { //t1 = (float)tp->inner.req_us; //t2 = (float)tp->inner.repstart_us; //t3 = (float)tp->inner.repend_us; REP(f, " Reply: type %s %u of %d in %u pkts %s %s %s %s %s %s\n finger %08x:%08x %u\n", content_type_string(tp->inner.hserver.content_type), tp->inner.hserver.recd_len, tp->inner.hserver.body_len, tp->inner.hserver.recd_pkts, tp->inner.hserver.status & TRANS_CHUNKED ? "Chunked" : "", tp->inner.hserver.status & TRANS_INCOMPLETE ? "Incomplete" : "", tp->inner.hserver.status & TRANS_FINISHED ? "Finished" : "", tp->inner.hserver.status & TRANS_RESYNCHED ? "Resynched" : "", tp->inner.hserver.status & TRANS_LOST_SYNCH ? "Lost synch" : "", tp->inner.hserver.status & TRANS_HDR_FRAG ? "Hdr. frag." : "", tp->inner.sinf.finger.hi, tp->inner.sinf.finger.lo, tp->inner.sinf.finger.tot); if (addit_fields & AF_REP_HDR_LEN) REP(f, " (HTTP hdr len %d)\n", tp->inner.rep_hdr_len); if (tp->inner.sinf.serverlen) { REP(f, " Server: "); non_prints = print_seq2str(f, tp->server, tp->inner.sinf.serverlen); REP(f, "\n"); if (non_prints) REP(f, "XXX Caution - reference contains non-printing characters XXX\n"); } if (tp->inner.sinf.vialen) { REP(f, " Via: "); non_prints = print_seq2str(f, tp->svia, tp->inner.sinf.vialen); REP(f, "\n"); if (non_prints) REP(f, "XXX Caution - reference contains non-printing characters XXX\n"); }#if 0 REP(f, " Req. seen %.3f req.end %.3f first served %.3f last served %.3f\n", ((float)tp->inner.cinf.reqstart_us)/US_IN_MS, ((float)tp->inner.cinf.reqend_us)/US_IN_MS, ((float)tp->inner.sinf.repstart_us)/US_IN_MS, ((float)tp->inner.sinf.repend_us)/US_IN_MS);#endif REP(f, " Status: %hd %s ", tp->inner.sinf.status_code, status_string(tp->inner.sinf.status_code)); if (client_seen && tp->inner.cinf.reqstart_us != 0) REP(f, "%.3f/", ((float)(tp->inner.sinf.repstart_us - tp->inner.cinf.reqstart_us))/US_IN_MS); else REP(f, "X/"); if (tp->inner.sinf.repend_us != 0 && tp->inner.sinf.repstart_us != 0) REP(f, "%.3f ms\n", ((float)(tp->inner.sinf.repend_us - tp->inner.sinf.repstart_us))/US_IN_MS); else REP(f, "X ms\n"); if (tp->inner.hserver.gaps_bytes) REP(f, " missing: %u/%u\n", tp->inner.hserver.gaps_bytes, tp->inner.hserver.gaps_pkts); if (tp->links.totchars != 0) {#ifdef WREAD /* all in one buffer */ print_links_buf(f, tp->links.buf, tp->links.totchars, "References");#else /* in buffer chain */ { char *start; char *cp; links_buf_t *bp = tp->links.chain; REP(f, " References:-\n"); while(bp != NULL) { cp = bp->buf; start = cp; while(*cp != '\0' && cp - start < bp->nchars) { REP(f, " \"%s\"\n", cp++); cp += strlen(cp) + 1; } bp = bp->next; } }#endif /* ifdef WREAD */ if (tp->inner.hserver.status & TRANS_LINKS_CHARS_EX) REP(f, " truncated!"); } } } s_inval: REP(f, "\n"); return;}/*****************************************************************************/#if defined FINAL_REPORT || defined REPORT || defined WREAD || defined BIN_REPORT/* * TCP stuff */void report_tcp_close(FILE *f, unsigned int state){ int full = 0; int closed = 0; if (state & TCP_FULL_CLOSE) { full++; closed++; REP(f, "full close "); } if (state & TCP_FORCED_CLOSE) { closed++; REP(f, "forced close "); } if (state & TCP_EFFECTIVE_CLOSE) { closed++; REP(f, "effective close "); } if (state & TCP_QUICK_CLOSE) { closed++; REP(f, "quick close "); } if (!full && (state & (TCP_CLI_FIN | TCP_SERV_FIN))) { REP(f, "closed "); if (state & TCP_CLI_FIN) { REP(f, "(client"); if (state & TCP_SERV_FIN) REP(f, "/server) "); else REP(f, ") "); } else { REP(f, "(server) "); } } if (state & (TCP_CLI_RST | TCP_SERV_RST)) { closed++; REP(f, "reset "); if (state & TCP_CLI_RST) { REP(f, "(client"); if (state & TCP_SERV_RST) REP(f, "/server) "); else REP(f, ") "); } else REP(f, "(server) "); } if (!closed) REP(f, "open "); if (state & TCP_TIMEO) { REP(f, "timed out "); } if (state & TCP_RUNEND) REP(f, "run ended "); if(state & (TCP_SERV_SERV_ERR | TCP_CLI_SERV_ERR)) { REP(f, "error "); if (state & TCP_CLI_SERV_ERR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -