📄 _sunrpcr.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 + -