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

📄 _sunrpcr.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
字号:
/*
 * Copyright (c) 1992, 1993, 1994, 1995, 1996
 * The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * 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 acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * 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.
 */

#if 0
static const char rcsid[] =
  "@(#) $Header: /ng/src/proto-analyser/tcpdump/RCS/print-sunrpcrm.c,v 1.6 1998/06/27 03:12:21 janssen Exp $ (LBL)";
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <ctype.h>

#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>

#include "interfac.h"
#include "a2name.h"

struct sunrpcrm_state {
  u_int32_t srcaddr, dstaddr;
  u_short   srcport, dstport;
  u_int32_t pending;        /* number of bytes still to be read in chunk */
  u_char    pbytes[4];      /* buffer for partial header */
  u_int     partial;        /* number of bytes in pbytes so far, always less than 4 */
  u_int     lastchunk;      /* 1 if current chunk is last chunk of message, 0 otherwise */
  u_int     initiated;      /* 1 if "src" initiated connection, 0 otherwise */
  u_char   *msgbuf;         /* buffer to hold message */
  u_char    msgbufsize;     /* size of "msgbuf" */
  u_char    msgbufused;     /* number of bytes currently used in msgbuf */
  u_int     conn_id;
};

struct state_list {
       struct state_list    *next;
       struct sunrpcrm_state state;
     };

static struct state_list *connections = NULL;

static struct sunrpcrm_state *add_state (u_int32_t saddr, u_short sport,
                                         u_int32_t daddr, u_int32_t dport)
{
  struct state_list *newstate = calloc (sizeof(*newstate), 1);

  newstate->state.dstaddr = daddr;
  newstate->state.dstport = dport;
  newstate->state.srcaddr = saddr;
  newstate->state.srcport = sport;

  newstate->next = connections;
  connections    = newstate;
  return (&newstate->state);
}

static struct sunrpcrm_state *find_state (u_int32_t saddr, u_short sport,
                                          u_int32_t daddr, u_int32_t dport)
{
  struct state_list *p;

  for (p = connections; p; p = p->next)
  {
    if (p->state.srcaddr == saddr && p->state.srcport == sport &&
        p->state.dstaddr == daddr && p->state.dstport == dport)
      return (&p->state);
  }
  return (NULL);
}

static struct state_list *remove_state (u_int32_t saddr, u_short sport,
                                        u_int32_t daddr, u_int32_t dport)
{
  struct state_list *p, **last;

  for (p = connections, last = &connections; p; last = &p->next, p = p->next)
  {
    if (p->state.srcaddr == saddr && p->state.srcport == sport &&
        p->state.dstaddr == daddr && p->state.dstport == dport)
    {
      *last = p->next;
      return (p);
    }
  }
  return (NULL);
}

static void free_state (struct state_list *s)
{
  if (s)
  {
    if (s->state.msgbuf)
       free (s->state.msgbuf);
    free (s);
  }
}

void sunrpcrm_print (const u_char *bp, u_int length, const u_char *bp2,
                     const u_char *bp3)
{
  struct ip             *ip = (struct ip *) bp2;
  struct tcphdr         *tp = (struct tcphdr *) bp3;
  struct sunrpcrm_state *s;
  struct state_list     *rm = NULL;
  static u_int conn_id = 0;

  u_char    flags;
  u_int     started = 0, dumped = 0, continued = 0;
  u_short   sport, dport;
  u_int32_t saddr, daddr, header;

  saddr = ntohl (ip->ip_src.s_addr);
  sport = ntohs (tp->th_sport);
  daddr = ntohl (ip->ip_dst.s_addr);
  dport = ntohs (tp->th_dport);

  s = find_state (saddr, sport, daddr, dport);
  flags = tp->th_flags;
  if ((flags & (TH_FIN | TH_RST)) && s)
     rm = remove_state (saddr, sport, daddr, dport);
  else if (s == 0)
  {
    s = add_state (saddr, sport, daddr, dport);
    s->conn_id = ++conn_id;
    if (flags & TH_SYN)
       s->initiated = 1;
  }

#if 0
  PRINTF (" sunrpcrm,s=%p,rm=%p,pending=%lu,src=%8.8x:%lu,dst=%8.8x:%lu ",
          s, rm, s->pending, saddr, sport, daddr, dport);
#endif

  while (length > 0)
  {
    continued = (s->pending > 0);

    if (continued)
       ;

    /* partial header? */
    else if (length < (4 - s->partial))
    {
      memcpy (s->pbytes + s->partial, bp, length);
      s->partial += length;
      break;
    }
    else if (s->partial > 0)
    {
      memcpy (s->pbytes + s->partial, bp, 4 - s->partial);
      length -= 4 - s->partial;
      bp     += 4 - s->partial;
      s->partial = 0;
      header = ntohl (*((u_int32_t*)&s->partial));
    }
    else
    {
      header  = ntohl (*((u_int32_t*)bp));
      length -= 4;
      bp     += 4;
    }

    if (!continued)
    {
      s->pending   = header & 0x7FFFFFFF;
      s->lastchunk = ((header & 0x80000000) != 1);
    }

    if (!started)
    {
      PUTS (" <sunrpcrm");
      started = 1;
    }

    if (!continued)
    {
      PRINTF ("%s d(bytes=%lu%s)",
              Pflag ? "\n " : "", s->pending, s->lastchunk ? ",push" : "");

      if (s->pending > (s->msgbufsize - s->msgbufused))
      {
        if (s->msgbuf)
             s->msgbuf = realloc (s->msgbuf, s->msgbufsize + s->pending);
        else s->msgbuf = malloc (s->msgbufsize + s->pending);
        s->msgbufsize = s->msgbuf ? (s->msgbufsize + s->pending) : 0;
      }
    }

    if (Pflag)
    {
      if (!continued && vflag)
      {
        header = htonl (header);
        default_print ((const u_char*)&header, 4);
      }
      if (s->pending > 0)
         default_print (bp, min (length, s->pending));
      dumped = ((!continued && vflag) || (s->pending > 0));
    }

    if (length < s->pending)
    {
      memcpy (s->msgbuf + s->msgbufused, bp, length);
      s->msgbufused += length;
      bp            += length;
      s->pending    -= length;
      length = 0;
    }
    else if (s->pending > 0)
    {
      memcpy (s->msgbuf + s->msgbufused, bp, s->pending);
      s->msgbufused += s->pending;
      bp            += s->pending;
      length        -= s->pending;
      s->pending = 0;
    }

    if (s->pending == 0)
    {
      if (s->lastchunk)
      {
        switch (messagetype)
        {
          case MT_W3NG:
               w3ng_print (s->conn_id, s->msgbuf, s->msgbufused);
               break;

          case MT_ONCRPC:
               oncrpc_print (s->conn_id, s->msgbuf, s->msgbufused);
               break;

          case MT_GIOP:
               giop_print (s->conn_id, s->msgbuf, s->msgbufused);
               break;

          default:
               break;
        }
        s->msgbufused = 0;
      }
    }
  }

  if (dumped)
     PUTCHAR ('\n');
  if (started)
     PUTCHAR ('>');
  free_state (rm);
}

⌨️ 快捷键说明

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