⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcstat.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/*
 *  Update and printing of MAC/IP/ICMP/IGMP/UDP/TCP input/output
 *  statistics counters.
 *
 *  G. Vanem <giva@bgnett.no> 1997
 */

#include <stdio.h>
#include <time.h>

#include "wattcp.h"
#include "strings.h"
#include "sock_ini.h"
#include "pcconfig.h"
#include "pcicmp.h"
#include "pcqueue.h"
#include "pcsed.h"
#include "pcpkt.h"
#include "pcstat.h"

int sock_stats (tcp_Socket *s, WORD *days, WORD *inactive,
                WORD *cwindow, WORD *avg,  WORD *sd)
{
  time_t now = time (NULL);

  if (s->ip_type != TCP_PROTO)
     return (0);

  if (days)     *days     = (WORD) (now / (3600*24) - _watt_start_day);
  if (inactive) *inactive = sock_inactive;
#if defined(USE_UDP_ONLY)
  if (cwindow)  *cwindow  = 0;
  if (avg)      *avg      = 0;
  if (sd)       *sd       = 0;
#else
  if (cwindow)  *cwindow  = s->cwindow;
  if (avg)      *avg      = s->vj_sa >> 3;
  if (sd)       *sd       = s->vj_sd >> 2;
#endif
  return (1);
}

#if !defined(USE_STATISTICS)
  void print_ip_stats  (void) {}
  void print_icmp_stats(void) {}
  void print_igmp_stats(void) {}
  void print_udp_stats (void) {}
  void print_tcp_stats (void) {}
  void print_all_stats (void) {}
  void reset_stats     (void) {}

#else  /* rest of file */

struct macstat   macstats;
struct ipstat    ipstats;
struct udpstat   udpstats;
struct tcpstat   tcpstats;
struct icmpstat  icmpstats;
struct igmpstat  igmpstats;
struct pppoestat pppoestats;

void reset_stats (void)
{
  memset (&macstats, 0, sizeof(macstats));
  memset (&ipstats,  0, sizeof(ipstats));
  memset (&udpstats, 0, sizeof(udpstats));
  memset (&tcpstats, 0, sizeof(tcpstats));
  memset (&icmpstats,0, sizeof(icmpstats));
  memset (&igmpstats,0, sizeof(igmpstats));
}

static void show_stat (const char *name, DWORD num)
{
  if (num)
    (*_printf) ("    %-12s %10lu\r\n", name, num);
}

void print_mac_stats (void)
{
  (*_printf)("MAC input stats:\r\n"
             "    IP:     drop %d, waiting %d\r\n"
             "    non-IP: drop %d, waiting %d, recv/sent %lu/%lu\r\n"
             "    unknown type %lu, LLC frames %lu\r\n",
             pkt_dropped_ip(), pkt_waiting_ip(),
             pkt_dropped_arp(),pkt_waiting_arp(),
             macstats.non_ip_recv, macstats.non_ip_sent,
             macstats.num_err_type, macstats.num_llc_frames);

  (*_printf)("MAC output stats:\r\n"
             "    Tx errors    %10lu\r\n", macstats.num_tx_err);
}

void print_arp_stats (void)
{
  (*_printf)("ARP Requests:    %10lu recv\r\n"
             "    Requests:    %10lu sent\r\n"
             "    Replies:     %10lu recv\r\n"
             "    Replies:     %10lu sent\r\n",
             macstats.arp.request_recv, macstats.arp.request_sent,
             macstats.arp.reply_recv, macstats.arp.reply_sent);
}

void print_ip_stats (void)
{
  (*_printf)("IP input stats:\r\n");
  show_stat ("total:",     ipstats.ips_total);
  show_stat ("badsum:",    ipstats.ips_badsum);
  show_stat ("badver:",    ipstats.ips_badvers);
  show_stat ("short:",     ipstats.ips_tooshort);
  show_stat ("frags:",     ipstats.ips_fragments);
  show_stat ("fragdrop:",  ipstats.ips_fragdropped);
  show_stat ("fragtime:",  ipstats.ips_fragtimeout);
  show_stat ("reassemble:",ipstats.ips_reassembled);
  show_stat ("noproto:",   ipstats.ips_noproto);
  show_stat ("delivered:", ipstats.ips_delivered);
  show_stat ("badoptions:",ipstats.ips_badoptions);
  show_stat ("dropped:",   ipstats.ips_idropped);

  (*_printf)("IP output stats:\r\n");
  show_stat ("total:",     ipstats.ips_rawout);
  show_stat ("noroute:",   ipstats.ips_noroute);
  show_stat ("frags:",     ipstats.ips_ofragments);
  show_stat ("dropped:",   ipstats.ips_odropped);
}

void print_icmp_stats (void)
{
  DWORD  total_in  = 0;
  DWORD  total_out = 0;
  int    i;
  static char *types[ICMP_MAXTYPE+1] = {
              "echoreply:", "", "",   /* 0-2 */
              "unreach:",
              "srcquench:",
              "redirect:", "", "",    /* 5-7 */
              "echorequest:",
              "router adv:", "router sol:",
              "timex:",
              "parm prob:",
              "tstamp req:", "tstamp rep:",
              "info req:",   "info rep:",
              "mask req:",   "mask rep:"
            };

  (*_printf)("ICMP input stats:\r\n");
  for (i = 0; i < ICMP_MAXTYPE; i++)
      total_in += icmpstats.icps_inhist[i];
  show_stat ("total:", total_in);

  show_stat ("badsum:", icmpstats.icps_checksum);
  show_stat ("badcode:",icmpstats.icps_badcode);
  show_stat ("short:",  icmpstats.icps_tooshort);

  for (i = 0; i < ICMP_MAXTYPE; i++)
     show_stat (types[i], icmpstats.icps_inhist[i]);

  (*_printf)("ICMP output stats:\r\n");
  for (i = 0; i < ICMP_MAXTYPE; i++)
      total_out += icmpstats.icps_outhist[i];
  show_stat ("total:", total_out);

  for (i = 0; i < ICMP_MAXTYPE; i++)
     show_stat (types[i], icmpstats.icps_outhist[i]);
}

void print_igmp_stats (void)
{
  (*_printf)("IGMP input stats:\r\n");
  show_stat ("total:",        igmpstats.igps_rcv_total);
  show_stat ("badsum:",       igmpstats.igps_rcv_badsum);
  show_stat ("short:",        igmpstats.igps_rcv_tooshort);
  show_stat ("queries:",      igmpstats.igps_rcv_queries);
  show_stat ("queries (bad):",igmpstats.igps_rcv_badqueries);
  show_stat ("reports:",      igmpstats.igps_rcv_reports);
  show_stat ("reports (bad):",igmpstats.igps_rcv_badreports);
  show_stat ("reports (grp):",igmpstats.igps_rcv_ourreports);

  (*_printf)("IGMP output stats:\r\n");
  show_stat ("reports:", igmpstats.igps_snd_reports);
}

void print_udp_stats (void)
{
  (*_printf)("UDP input stats:\r\n");
  show_stat ("total:",      udpstats.udps_ipackets);
  show_stat ("drops:",      udpstats.udps_hdrops);
  show_stat ("badsum:",     udpstats.udps_badsum);
  show_stat ("no service:", udpstats.udps_noport);
  show_stat ("broadcast:",  udpstats.udps_noportbcast);
  show_stat ("queue full:", udpstats.udps_fullsock);

  (*_printf)("UDP output stats:\r\n");
  show_stat ("total:",      udpstats.udps_opackets);
}

void print_tcp_stats (void)
{
  (*_printf)("TCP input stats:\r\n");
  show_stat ("total:",       tcpstats.tcps_rcvtotal);
  show_stat ("drops:",       tcpstats.tcps_drops);
  show_stat ("badsum:",      tcpstats.tcps_rcvbadsum);
  show_stat ("con-attempt:", tcpstats.tcps_connattempt);
  show_stat ("con-drops:",   tcpstats.tcps_conndrops);
  show_stat ("OOB pkt:",     tcpstats.tcps_rcvoopack);
  show_stat ("OOB byte:",    tcpstats.tcps_rcvoobyte);
  show_stat ("ACK pkt:",     tcpstats.tcps_rcvackpack);
  show_stat ("pers-drop:",   tcpstats.tcps_persistdrop);

  (*_printf)("TCP output stats:\r\n");
  show_stat ("total:",       tcpstats.tcps_sndtotal);
  show_stat ("data pkt:",    tcpstats.tcps_sndpack);
  show_stat ("data byte:",   tcpstats.tcps_sndbyte);
  show_stat ("SYN/FIN/RST:", tcpstats.tcps_sndctrl);
  show_stat ("OOB pkt:",     tcpstats.tcps_sndurg);
  show_stat ("ACK pkt:",     tcpstats.tcps_sndacks);
  show_stat ("ACK dly:",     tcpstats.tcps_delack);
  show_stat ("retrans to:",  tcpstats.tcps_rexmttimeo);
  show_stat ("keepalive pr:",tcpstats.tcps_keepprobe);
  show_stat ("keepalive to:",tcpstats.tcps_keeptimeo);
}

void print_all_stats (void)
{
  print_mac_stats();
  print_arp_stats();
  print_ip_stats();
  print_icmp_stats();
#if defined(USE_MULTICAST)
  print_igmp_stats();
#endif
  print_udp_stats();
  print_tcp_stats();
}

/*
 * Called from the link-layer input routine _eth_arrived().
 */
void update_in_stat (const void *pkt, WORD proto)
{
  const in_Header *ip;

  if (proto == ARP_TYPE)
  {
    const arp_Header *arp = (const arp_Header*) pkt;

    macstats.non_ip_recv++;
    if (arp->opcode == ARP_REQUEST)
       macstats.arp.request_recv++;
    else if (arp->opcode == ARP_REPLY)
       macstats.arp.reply_recv++;
    return;
  }

#if defined(USE_RARP)
  if (proto == RARP_TYPE)
  {
    const rarp_Header *rarp = (const rarp_Header*) pkt;

    macstats.non_ip_recv++;

    if (rarp->opcode == RARP_REQUEST)
       macstats.rarp.request_recv++;
    else if (rarp->opcode == RARP_REPLY)
       macstats.rarp.reply_recv++;
    return;
  }
#endif

#if defined(USE_PPPOE)
  if (proto == PPPOE_DISC_TYPE || proto == PPPOE_SESS_TYPE)
  {
    if (proto == PPPOE_DISC_TYPE)
       pppoestats.num_disc_recv++;
    else if (proto == PPPOE_SESS_TYPE)
       pppoestats.num_sess_recv++;
    macstats.non_ip_recv++;
    return;
  }
#endif

  if (proto != IP_TYPE)    /* should never happen */
  {
    macstats.non_ip_recv++;
    return;
  }

  ipstats.ips_total++;
  ip = (const in_Header*) pkt;

  switch (ip->proto)
  {
    case ICMP_PROTO:  /* counted in pcicmp.c */
         return;

    case IGMP_PROTO:
         igmpstats.igps_rcv_total++;
         return;

    case UDP_PROTO:
         udpstats.udps_ipackets++;
         return;

    case TCP_PROTO:
         tcpstats.tcps_rcvtotal++;
         return;
  }
}

/*
 * Called from the link-layer output routine _eth_send().
 */
void update_out_stat (const void *pkt, WORD proto)
{
  unsigned   hlen;
  DWORD      ofs;
  in_Header *ip;

  if (proto == ARP_TYPE)
  {
    const arp_Header *arp = (arp_Header*) pkt;

    macstats.non_ip_sent++;
    if (arp->opcode == ARP_REQUEST)
       macstats.arp.request_sent++;
    else if (arp->opcode == ARP_REPLY)
       macstats.arp.reply_sent++;
    return;
  }

#if defined(USE_RARP)
  if (proto == RARP_TYPE)
  {
    const rarp_Header *rarp = (rarp_Header*) pkt;

    macstats.non_ip_sent++;
    if (rarp->opcode == RARP_REQUEST)
       macstats.rarp.request_sent++;
    else if (rarp->opcode == RARP_REPLY)
       macstats.rarp.reply_sent++;
    return;
  }
#endif

#if defined(USE_PPPOE)
  if (proto == PPPOE_DISC_TYPE)
  {
    pppoestats.num_disc_sent++;
    return;
  }
  if (proto == PPPOE_SESS_TYPE)
  {
    pppoestats.num_sess_sent++;
    return;
  }
#endif

  if (proto != IP_TYPE)    /* should never happen */
  {
    macstats.non_ip_sent++;
    return; 
  }

  ipstats.ips_rawout++;   /* count raw IP (fragmented or not) */

  ip  = (in_Header*) pkt;
  ofs = intel16 (ip->frag_ofs);
  ofs = (ofs & IP_OFFMASK) << 3;
   
  if (ofs)       /* don't count each fragment (only with ofs 0) */
     return;  

  hlen = in_GetHdrLen (ip);

  if (ip->proto == ICMP_PROTO)
  {
    const ICMP_PKT *icmp = (const ICMP_PKT*) ((BYTE*)ip + hlen);
    BYTE            type = icmp->unused.type;

    if (type <= ICMP_MAXTYPE)
       icmpstats.icps_outhist[(int)type]++;
    return;
  }

  if (ip->proto == IGMP_PROTO)
  {
    const IGMP_packet *igmp = (const IGMP_packet*) ((BYTE*)ip + hlen);

    if (igmp->type == IGMP_REPORT)
       igmpstats.igps_snd_reports++;
    return;
  }

  if (ip->proto == UDP_PROTO)
  {
    udpstats.udps_opackets++;
    return;
  }

  if (ip->proto == TCP_PROTO)
  {
    tcp_Header *tcp   = (tcp_Header*) ((BYTE*)ip + hlen);
    BYTE        flags = tcp->flags & tcp_FlagMASK;
    int         tlen  = intel16 (ip->length) - hlen - (tcp->offset << 2);

    tcpstats.tcps_sndtotal++;

    if (tlen > 0)                 /* segments with data */
    {
      tcpstats.tcps_sndpack++;
      tcpstats.tcps_sndbyte += tlen;
    }
    if (flags & (tcp_FlagSYN|tcp_FlagFIN|tcp_FlagRST))
       tcpstats.tcps_sndctrl++;
    else if (flags & tcp_FlagACK) /* ACK only */
       tcpstats.tcps_sndacks++;
    if (flags & tcp_FlagURG)
       tcpstats.tcps_sndurg++;
    return;
  }
}
#endif  /* USE_STATISTICS */


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -