📄 _iiop.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.5 1998/06/25 23:39:31 janssen Exp janssen $ (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"
#define HEADERLEN 12
#define GIOP_MSGTYPE_REQUEST 0
#define GIOP_MSGTYPE_REPLY 1
#define GIOP_MSGTYPE_CANCEL_REQUEST 2
#define GIOP_MSGTYPE_LOCATE_REQUEST 3
#define GIOP_MSGTYPE_LOCATE_REPLY 4
#define GIOP_MSGTYPE_CLOSE_CONNECTION 5
#define GIOP_MSGTYPE_MESSAGE_ERROR 6
#define GIOP_MSGTYPE_FRAGMENT 7
struct iiop_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[HEADERLEN]; /* buffer for partial header */
u_int partial; /* number of bytes in pbytes so far, always less than HEADERLEN */
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_int major; /* major version number */
u_int minor; /* major version number */
u_int flags; /* from flags byte of message header */
u_int little_endian; /* 1 if little-endian on wire, 0 for big-endian */
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 iiop_state state;
};
static struct state_list *connections = NULL;
static struct iiop_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);
if (!newstate)
return (NULL);
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 iiop_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);
}
}
#define SWAP_WORD(a) ( ((a) << 24) | \
(((a) << 8) & 0x00ff0000) | \
(((a) >> 8) & 0x0000ff00) | \
((u_int32_t)(a) >>24) )
static u_int32_t gtohl (u_int32_t val, u_int little_endian)
{
if (!little_endian)
return SWAP_WORD (val);
return (val);
}
void iiop_print (const u_char *bp, u_int length, const u_char *bp2,
const u_char *bp3)
{
struct iiop_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;
struct ip *ip = (struct ip *) bp2;
struct tcphdr *tp = (struct tcphdr *) bp3;
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)
{
s = add_state (saddr, sport, daddr, dport);
s->conn_id = ++conn_id;
if (flags & TH_SYN)
s->initiated = 1;
}
#if 0
PRINTF (" iiop,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? */
if (length < (HEADERLEN - s->partial))
{
memcpy (s->pbytes + s->partial, bp, length);
s->partial += length;
break;
}
else if (s->partial > 0)
{
memcpy (s->pbytes + s->partial, bp, HEADERLEN - s->partial);
length -= (HEADERLEN - s->partial);
bp += (HEADERLEN - s->partial);
s->partial = 0;
}
else
{
memcpy (s->pbytes, bp, HEADERLEN);
bp += HEADERLEN;
length -= HEADERLEN;
}
}
if (!started)
{
PUTS (" <iiop");
started = 1;
}
if (memcmp (s->pbytes, "GIOP", 4))
{
PUTS ("[bad magic header!]\n");
return;
}
if (!continued)
{
s->major = s->pbytes[4];
s->minor = s->pbytes[5];
s->flags = s->pbytes[6];
s->little_endian = ((s->flags & 0x1) == 0x1);
s->lastchunk = ((s->minor > 0) ? ((s->flags & 0x2) == 0) : 1);
s->pending = gtohl (*(u_int32_t *) (&s->pbytes[8]), s->little_endian);
if (s->major != 1 || s->minor > 1)
{
PRINTF ("[version %u.%u not understood]\n", s->major, s->minor);
return;
}
}
if (!continued)
{
PRINTF ("%s d(bytes=%lu%s,vers=%u.%u,%s-endian)",
Pflag ? "\n " : "",
s->pending,
s->lastchunk ? ",push" : "",
s->major, s->minor,
s->little_endian ? "little" : "big");
if (s->msgbufused == 0)
{
if (HEADERLEN > (s->msgbufsize - s->msgbufused))
{
if (s->msgbuf)
s->msgbuf = realloc (s->msgbuf, s->msgbufsize + HEADERLEN);
else s->msgbuf = malloc (s->msgbufsize + HEADERLEN);
s->msgbufsize = s->msgbuf ? (s->msgbufsize + HEADERLEN) : 0;
}
memcpy (s->msgbuf, s->pbytes, HEADERLEN);
s->msgbufused += HEADERLEN;
}
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)
default_print ((const u_char *) s->pbytes, HEADERLEN);
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 + -