📄 _w3mux.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-w3mux.c,v 1.7 1998/06/27 03:12:45 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 w3mux_header {
u_int32_t header;
u_int32_t longlength;
};
#define MUX_CONTROL 0x00800000
#define MUX_CONTROL_SHIFT 23
#define MUX_CONTROL_CODE 0x00780000
#define MUX_CONTROL_CODE_SHIFT 19
#define MUX_SYN 0x00400000
#define MUX_SYN_SHIFT 22
#define MUX_FIN 0x00200000
#define MUX_FIN_SHIFT 21
#define MUX_RST 0x00100000
#define MUX_RST_SHIFT 20
#define MUX_PUSH 0x00080000
#define MUX_PUSH_SHIFT 19
#define MUX_LONG_LENGTH 0x00040000
#define MUX_LONG_LENGTH_SHIFT 18
#define MUX_SESSION 0xFF000000
#define MUX_SESSION_SHIFT 24
#define MUX_FRAGMENT_SIZE 0x0003FFFF
#define MUX_FRAGMENT_SIZE_SHIFT 0
#define HEADER_EXTENDED(ptr) ((((struct w3mux_header *)ptr)->header & MUX_LONG_LENGTH) != 0)
#define HEADER_FRAGMENT_SIZE(ptr) (((struct w3mux_header *)ptr)->header & MUX_FRAGMENT_SIZE)
#define HEADER_CHUNK_SIZE(ptr) (HEADER_EXTENDED(ptr)?(((struct w3mux_header *)ptr)->longlength):HEADER_FRAGMENT_SIZE(ptr))
#define HEADER_SESSION_ID(ptr) ((((struct w3mux_header *)ptr)->header & MUX_SESSION) >> MUX_SESSION_SHIFT)
#define HEADER_CHANNEL_ID(ptr) (((struct w3mux_header *)ptr)->header & MUX_FRAGMENT_SIZE)
#define HEADER_MAX_FRAGMENT_SIZE(ptr) (((struct w3mux_header *)ptr)->header & MUX_FRAGMENT_SIZE)
#define HEADER_CREDIT_SIZE(ptr) (((struct w3mux_header *)ptr)->header & MUX_FRAGMENT_SIZE)
#define HEADER_DEFAULT_CREDIT_SIZE(ptr) (((struct w3mux_header *)ptr)->header & MUX_FRAGMENT_SIZE)
#define HEADER_ATOM_STR_LENGTH(ptr) (((struct w3mux_header *)ptr)->header & MUX_FRAGMENT_SIZE)
#define HEADER_ENDPOINT_LENGTH(ptr) (((struct w3mux_header *)ptr)->header & MUX_FRAGMENT_SIZE)
#define HEADER_CONTROL_MSG(ptr) ((((struct w3mux_header *)ptr)->header & MUX_CONTROL) != 0)
#define HEADER_CONTROL_CODE(ptr) ((((struct w3mux_header *)ptr)->header & MUX_CONTROL_CODE) >> MUX_CONTROL_CODE_SHIFT)
#define HEADER_LAST_CHUNK(ptr) ((((struct w3mux_header *)ptr)->header & MUX_PUSH) != 0)
#define HEADER_NEW_SESSION(ptr) ((((struct w3mux_header *)ptr)->header & MUX_SYN) != 0)
#define HEADER_LAST_MSG(ptr) ((((struct w3mux_header *)ptr)->header & MUX_FIN) != 0)
#define HEADER_RESET(ptr) ((((struct w3mux_header *)ptr)->header & MUX_RST) != 0)
/* control codes
*/
#define MUX_InternAtom 0
#define MUX_DefineEndpoint 1
#define MUX_SetMSS 2
#define MUX_AddCredit 3
#define MUX_SetDefaultCredit 4
#define MUX_NoOp 5
#define MUX_ATOM_BASE 2000
struct w3mux_state {
u_int32_t srcaddr, dstaddr;
u_short srcport, dstport;
struct w3mux_header header;
u_int32_t pending; /* number of bytes still to be read in chunk */
u_int partial : 3; /* number of bytes in pbytes so far, always less than 8 */
u_int initiated : 1; /* 1 if "src" initiated connection, 0 otherwise */
u_int reading_header : 1; /* 1 if reading header, 0 otherwise */
u_int reading_longlen : 1; /* 1 if reading long len, 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; /* connection identifier */
};
struct state_list {
struct state_list *next;
struct w3mux_state state;
};
static struct state_list *connections = NULL;
static struct w3mux_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 w3mux_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 w3mux_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 w3mux_state *s;
struct state_list *rm = NULL;
u_char flags;
u_int started = 0;
u_int dumped = 0;
u_int continued = 0;
u_short sport, dport;
u_int32_t saddr, daddr;
static u_int conn_id = 0;
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 += 256);
s->reading_header = 1;
}
if (flags & TH_SYN)
s->initiated = 1;
#if 0
PRINTF (" w3mux,s=%p,rm=%p,pending=%lu,initiated=%s,src=%8.8x:%lu,dst=%8.8x:%lu ",
s, rm, s->pending, s->initiated ? "yes" : "no",
saddr, sport, daddr, dport);
#endif
while (length > 0)
{
if (s->reading_header)
{
continued = 0;
/* partial header? */
if (length < (4 - s->partial))
{
memcpy ((char*)&s->header.header + s->partial, bp, length);
length = 0;
s->partial += length;
break;
}
if (s->partial > 0)
{
memcpy ((char*)&s->header.header + s->partial, bp, 4 - s->partial);
length -= 4 - s->partial;
bp += 4 - s->partial;
s->partial = 0;
s->header.header = ntohl (s->header.header);
}
else
{
s->header.header = ntohl (*((u_int32_t*)bp));
length -= 4;
bp += 4;
}
s->reading_header = 0;
if (HEADER_EXTENDED (&s->header))
{
s->reading_longlen = 1;
continue;
}
else
{
s->pending = HEADER_CHUNK_SIZE (&s->header);
}
}
else if (s->reading_longlen)
{
continued = 0;
if (length < (4 - s->partial))
{
memcpy ((char*)&s->header.longlength + s->partial, bp, length);
length = 0;
s->partial += length;
break;
}
else if (s->partial > 0)
{
memcpy ((char*)&s->header.longlength + s->partial, bp, 4 - s->partial);
length -= 4 - s->partial;
bp += 4 - s->partial;
s->partial = 0;
s->header.longlength = ntohl (s->header.longlength);
}
else
{
s->header.longlength = ntohl (*((u_int32_t*)bp));
length -= 4;
bp += 4;
}
s->reading_longlen = 0;
s->pending = HEADER_CHUNK_SIZE (&s->header);
}
else
continued = 1;
if (!started)
{
PUTS (" <w3mux");
started = 1;
}
if (!continued)
{
if (Pflag)
PUTS ("\n ");
if (HEADER_CONTROL_MSG (&s->header))
{
switch (HEADER_CONTROL_CODE (&s->header))
{
case MUX_InternAtom:
PRINTF (" c(InternAtom,atom=%lu,%luB)",
MUX_ATOM_BASE + HEADER_SESSION_ID (&s->header));
break;
case MUX_DefineEndpoint:
PRINTF (" c(DefineEndpoint,%luB)", s->pending);
break;
case MUX_SetMSS:
PRINTF (" c(SetMSS,%lu)", HEADER_MAX_FRAGMENT_SIZE (&s->header));
s->pending = 0;
break;
case MUX_AddCredit:
PRINTF (" c(AddCredit,sess=%lu,credit=%lu)",
HEADER_SESSION_ID (&s->header),
HEADER_CREDIT_SIZE (&s->header));
s->pending = 0;
break;
case MUX_SetDefaultCredit:
PRINTF (" c(SetDefaultCredit,%lu)",
HEADER_DEFAULT_CREDIT_SIZE (&s->header));
s->pending = 0;
break;
case MUX_NoOp:
PUTS (" c(NoOp)");
break;
default:
PRINTF (" c(%lu)", HEADER_CONTROL_CODE (&s->header));
break;
}
}
else
{
PRINTF (" %s(sess=%lu",
HEADER_EXTENDED (&s->header) ? "D" : "d",
HEADER_SESSION_ID (&s->header));
if (HEADER_NEW_SESSION (&s->header))
PRINTF (",syn(channel=%lu)", HEADER_CHANNEL_ID (&s->header));
if (HEADER_LAST_CHUNK (&s->header))
PUTS (",push");
if (HEADER_LAST_MSG (&s->header))
PUTS (",fin");
if (HEADER_RESET (&s->header))
PUTS (",reset");
PRINTF (",bytes=%lu)", HEADER_CHUNK_SIZE (&s->header));
if (HEADER_CHUNK_SIZE (&s->header) > (s->msgbufsize - s->msgbufused))
{
if (s->msgbuf)
s->msgbuf = realloc (s->msgbuf, s->msgbufsize + HEADER_CHUNK_SIZE (&s->header));
else s->msgbuf = malloc (s->msgbufsize + HEADER_CHUNK_SIZE (&s->header));
s->msgbufsize = s->msgbuf ? (s->msgbufsize + HEADER_CHUNK_SIZE (&s->header)) : 0;
}
}
}
if (Pflag)
{
if (!continued && vflag)
{
struct {
u_int32_t f1;
u_int32_t f2;
} x;
x.f1 = htonl (s->header.header);
x.f2 = htonl (s->header.longlength);
default_print ((const u_char*)&x, HEADER_EXTENDED (&s->header) ? 8 : 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 (HEADER_LAST_CHUNK (&s->header) && !HEADER_CONTROL_MSG (&s->header))
{
switch (messagetype)
{
case MT_W3NG:
w3ng_print (s->conn_id + HEADER_SESSION_ID (&s->header), s->msgbuf, s->msgbufused);
break;
case MT_ONCRPC:
oncrpc_print (s->conn_id + HEADER_SESSION_ID (&s->header), s->msgbuf, s->msgbufused);
break;
case MT_GIOP:
giop_print (s->conn_id + HEADER_SESSION_ID (&s->header), s->msgbuf, s->msgbufused);
break;
}
s->msgbufused = 0;
}
s->reading_header = 1;
}
}
if (dumped)
PUTCHAR ('\n');
if (started)
PUTCHAR ('>');
free_state (rm);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -