/***************************************************************************
* DBS: Distributed Benchmark System
* Copyright (c) 1995, 1996, 1997 Yukio Murayama
* Copyright (c) 1995, 1996, 1997 Nara Institute of Science and Technology
* All rights reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided only with the following
* conditions are satisfied:
*
* 1. Both the copyright notice and this permission notice appear in
* all copies of the software, derivative works or modified versions,
* and any portions thereof, and that both notices appear in
* supporting documentation.
* 2. All advertising materials mentioning features or use of this
* software must display the following acknowledgement:
* This product includes software developed by Nara Institute of
* Science and Technology and its contributors.
* 3. Neither the name of Nara Institute of Science and Technology 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 BY THE DEVELOPER ``AS IS'' AND NARA
* INSTITUTE OF SCIENCE AND TECHNOLOGY DISCLAIMS ANY LIABILITY OF
* ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
* THIS SOFTWARE. ALSO, THERE IS NO WARRANTY IMPLIED OR OTHERWISE,
* NOR IS SUPPORT PROVIDED.
*
* Feedback of the results generated from any improvements or
* extensions made to this software would be much appreciated.
* Any such feedback should be sent to:
*
* Yukio Murayama
* E-mail: <yukio-m@is.aist-nara.ac.jp>
* URL: <http://shika.aist-nara.ac.jp/member/yukio-m/index.html>
* Address: Graduate School of Information Science,
* Nara Institute of Science and Technology,
* Takayama 8916-5, Ikoma, Nara, Japan
*
* Nara Institute of Science and Technology has the rights to
* redistribute these changes.
***************************************************************************/
/*****************************************************************
* Distributed Benchmark System
* TCP Trace
* $Revision: 1.16 $
* $Date: 1997/05/05 17:02:18 $
* $Author: yukio-m $
*****************************************************************/
#define TCP_TRACE
/*#if !defined(SYSTYPE_SVR4)*/
#include <sys/types.h>
#if defined(__osf__) || defined(__bsdi__)
#include <paths.h>
#endif
#if defined(__osf__) || defined(__bsdi__)
#include <machine/endian.h>
#endif
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <nlist.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if defined(__svr4__)
#include <sys/fcntl.h>
#endif
#include "dbs.h"
#include "dbsd.h"
#include "record.h"
/*#include <netinet/tcp_debug.h>*/
#define IFASSOSIATION if (rt->d[rt->n].td_tcb == rt->tcp_addr)
/*
#define IFASSOSIATION if (\
(\
ntohl(rt->d[rt->n].td_ti.ti_src.s_addr) == ntohl(a->dest_address) &&\
ntohl(rt->d[rt->n].td_ti.ti_dst.s_addr) == ntohl(a->source_address) &&\
ntohl(rt->d[rt->n].td_ti.ti_sport) == ntohl(a->dest_port) &&\
ntohl(rt->d[rt->n].td_ti.ti_dport) == ntohl(a->source_port)) ||\
(\
ntohl(rt->d[rt->n].td_ti.ti_src.s_addr) == ntohl(a->source_address) &&\
ntohl(rt->d[rt->n].td_ti.ti_dst.s_addr) == ntohl(a->dest_address) &&\
ntohl(rt->d[rt->n].td_ti.ti_sport) == ntohl(a->source_port) &&\
ntohl(rt->d[rt->n].td_ti.ti_dport) == ntohl(a->dest_port))\
)
*/
#define IFASSO if (\
(int)my_tcp_debug.td_act == act &&\
(\
((act == TA_INPUT) &&\
((int)my_tcp_debug.td_ti.ti_flags & (int)TH_SYN) != 0 &&\
ntohl(my_tcp_debug.td_ti.ti_src.s_addr) == ntohl(a->dest_address) &&\
ntohl(my_tcp_debug.td_ti.ti_dst.s_addr) == ntohl(a->source_address) &&\
ntohl(my_tcp_debug.td_ti.ti_sport) == ntohl(a->dest_port) &&\
ntohl(my_tcp_debug.td_ti.ti_dport) == ntohl(a->source_port))\
||\
((act == TA_OUTPUT) &&\
((int)my_tcp_debug.td_ti.ti_flags & (int)TH_SYN) != 0 &&\
ntohl(my_tcp_debug.td_ti.ti_src.s_addr) == ntohl(a->source_address) &&\
ntohl(my_tcp_debug.td_ti.ti_dst.s_addr) == ntohl(a->dest_address) &&\
ntohl(my_tcp_debug.td_ti.ti_sport) == ntohl(a->source_port) &&\
ntohl(my_tcp_debug.td_ti.ti_dport) == ntohl(a->dest_port))\
)\
)
#ifdef DEBUGMODE
#define IF_ASSOSIATION DEBUGMSG2(5, tcp_trace_debug(&rt->d[rt->n], rt->n, i));\
IFASSOSIATION
#define IF_ASSO DEBUGMSG2(5, tcp_trace_debug(&my_tcp_debug, 0, i));\
IFASSO
#else
#define IF_ASSOSIATION IFASSOSIATION
#define IF_ASSO IFASSO
#endif
int get_tcp_debx __P((int memf));
caddr_t search_syn __P((int memf, struct assosiation *a, int *debx, int act));
void tcp_trace_debug __P((struct tcp_debug *d, int i, int p));
void tcp_trace_debug2 __P((struct assosiation *a, int act));
#ifdef TCP_NDEBUG /********** IFDEF TCP_NDEBUG **********/
static struct tcp_debug my_tcp_debug;
static int my_tcp_debx;
struct nlist nl[] = {
#define N_TCP_DEBUG 0
{ "_tcp_debug" },
#define N_TCP_DEBX 1
{ "_tcp_debx" },
{ "" }
};
/*
* Trace TCP_CB and Store it into buffer
*/
void record_tcp_trace(rt, a, act)
struct tcp_trace *rt;
struct assosiation *a;
int act; /* XXX act is not used by this virson */
{
int i, now_p, n1, n2;
if (rt->n >= rt->size)
return;
now_p = get_tcp_debx(rt->memf);
n1 = rt->p;
n2 = now_p;
if (rt->p >= TCP_NDEBUG) {
fprintf(stderr, "rt->p=%d now_p=%d TCP_NDEBUG=%d: Internal Error!!! \n", rt->p, now_p, TCP_NDEBUG);
safe_exit(INTERNALERROR, "TCP_DEBUG.rt->p", "");
}
if (n1 < n2) {
(void)lseek(rt->memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
(void)lseek(rt->memf, (off_t)(sizeof(struct tcp_debug)*n1), SEEK_CUR);
for (i=n1; i != n2; i = (i+1) % TCP_NDEBUG) {
if (read(rt->memf, (char *)&rt->d[rt->n], sizeof(struct tcp_debug)) != sizeof(struct tcp_debug))
safe_exit(TCPDEBUG, "TCP_DEBUG.read(kernel)", strerror(errno));
IF_ASSOSIATION {
rt->n++;
}
}
} else if (n1 > n2) {
(void)lseek(rt->memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
(void)lseek(rt->memf, (off_t)(sizeof(struct tcp_debug)*n1), SEEK_CUR);
for (i=n1; i < TCP_NDEBUG; i++) {
if (read(rt->memf, (char *)&rt->d[rt->n], sizeof(struct tcp_debug)) != sizeof(struct tcp_debug))
safe_exit(TCPDEBUG, "TCP_DEBUG.read(kernel)", strerror(errno));
IF_ASSOSIATION {
rt->n++;
}
}
if (n2 > 0) {
(void)lseek(rt->memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
for (i=0; i < n2; i++) {
if (read(rt->memf, (char *)&rt->d[rt->n], sizeof(struct tcp_debug)) != sizeof(struct tcp_debug))
safe_exit(TCPDEBUG, "TCP_DEBUG.read(kernel)", strerror(errno));
IF_ASSOSIATION {
rt->n++;
}
}
}
}
rt->p = now_p;
}
void record_tcp_trace2(rt, a, flg)
struct tcp_trace *rt;
struct assosiation *a;
int flg; /* XXX flg is not used by this virson */
{
int i, now_p, n1, n2;
if (rt->n >= rt->size)
return;
now_p = get_tcp_debx(rt->memf);
n1 = rt->p;
n2 = now_p;
if (rt->p >= TCP_NDEBUG) {
fprintf(stderr, "rt->p=%d now_p=%d TCP_NDEBUG=%d: Internal Error!!! \n", rt->p, now_p, TCP_NDEBUG);
safe_exit(INTERNALERROR, "TCP_DEBUG2.rt->p", "");
}
if (n1 < n2) {
(void)lseek(rt->memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
(void)lseek(rt->memf, (off_t)(sizeof(struct tcp_debug)*n1), SEEK_CUR);
for (i=n1; i != n2; i = (i+1) % TCP_NDEBUG) {
if (read(rt->memf, (char *)&rt->d[rt->n], sizeof(struct tcp_debug)) != sizeof(struct tcp_debug))
safe_exit(TCPDEBUG, "TCP_DEBUG2.read(kernel)", strerror(errno));
IF_ASSOSIATION {
if(((int)rt->d[rt->n].td_ti.ti_flags & (int)TH_FIN) != 0)
return;
else
rt->n++;
}
}
} else if (n1 > n2) {
(void)lseek(rt->memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
(void)lseek(rt->memf, (off_t)(sizeof(struct tcp_debug)*n1), SEEK_CUR);
for (i=n1; i < TCP_NDEBUG; i++) {
if (read(rt->memf, (char *)&rt->d[rt->n], sizeof(struct tcp_debug)) != sizeof(struct tcp_debug))
safe_exit(TCPDEBUG, "TCP_DEBUG2.read(kernel)", strerror(errno));
IF_ASSOSIATION {
if(((int)rt->d[rt->n].td_ti.ti_flags & (int)TH_FIN) != 0)
return;
else
rt->n++;
}
}
if (n2 > 0) {
(void)lseek(rt->memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
for (i=0; i < n2; i++) {
if (read(rt->memf, (char *)&rt->d[rt->n], sizeof(struct tcp_debug)) != sizeof(struct tcp_debug))
safe_exit(TCPDEBUG, "TCP_DEBUG2.read(kernel)", strerror(errno));
IF_ASSOSIATION {
if(((int)rt->d[rt->n].td_ti.ti_flags & (int)TH_FIN) != 0)
return;
else
rt->n++;
}
}
}
}
rt->p = now_p;
}
/*
* Initialization of TCP TRACE
*/
void init_so_debug(rt, a, act, flg)
struct tcp_trace *rt;
struct assosiation *a;
int act, flg;
{
char *system, *core;
off_t lseek();
int debx;
rt->n=0;
#ifdef _PATH_KMEM
core = _PATH_KMEM;
#else
core = "/dev/kmem";
#endif
#ifdef _PATH_KERNEL
system = _PATH_KERNEL;
#else
#ifdef _PATH_UNIX
system = _PATH_UNIX;
#else
system = "/kernel";
#endif
#endif
if (nlist(system, nl) < 0 || !nl[0].n_value) {
fprintf(stderr, "dbsd: {_tcp_debug}, {_tcp_debx} cannot found in %s\n", system);
safe_exit(TCPDEBUG, "dbsd: {_tcp_debug}, {_tcp_debx} cannot found in the kernel", "");
}
if ((rt->memf = open(core, O_RDONLY)) < 0)
safe_exit(TCPDEBUG, "TCP_DEBUG_INIT.open(kernel)", strerror(errno));
DEBUGMSG2(4, fprintf(stderr, "rt->memf=%d\n", rt->memf));
rt->p = debx = get_tcp_debx(rt->memf);
DEBUGMSG(5, "Search Syncronize\n");
rt->tcp_addr = search_syn(rt->memf, a, &(rt->p), act);
if (flg == BEFORE)
rt->p = debx;
DEBUGMSG2(3, fprintf(stderr, "rt->p=%d rt->tcp_addr=%lu\n", rt->p, (u_long)rt->tcp_addr));
}
/*
* search TCP_CB syn Packet
*/
caddr_t search_syn(memf, a, debx, act)
int memf;
struct assosiation *a;
int *debx;
int act;
{
int i, x;
x = *debx;
DEBUGMSG2(5, tcp_trace_debug2(a, act));
if (x < 0 || x > TCP_NDEBUG) {
fprintf(stderr, "debx=%d TCP_NDEBUG=%d: Internal Error!!! \n", x, TCP_NDEBUG);
safe_exit(INTERNALERROR, "TCP_DEBUG_SYN.x", "");
}
(void)lseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
(void)lseek(memf, (off_t)(sizeof(struct tcp_debug)*((x-1) % TCP_NDEBUG)), SEEK_CUR);
for (i=x-1; i >= 0; i--) {
if (read(memf, (char *)&my_tcp_debug, sizeof(struct tcp_debug)) != sizeof(struct tcp_debug))
safe_exit(TCPDEBUG, "TCP_DEBUG_SYN.read(kernel)", strerror(errno));
IF_ASSO {
*debx = i;
return my_tcp_debug.td_tcb;
}
(void)lseek(memf, (off_t)(sizeof(struct tcp_debug)*(-2)), SEEK_CUR);
}
(void)lseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
(void)lseek(memf, (off_t)(sizeof(struct tcp_debug)*(TCP_NDEBUG-1)), SEEK_CUR);
/* (void)lseek(memf, (off_t)(sizeof(struct tcp_debug)*(TCP_NDEBUG-2)), SEEK_CUR);*/
for (i=TCP_NDEBUG-1; i >= x; i--) {
if (read(memf, (char *)&my_tcp_debug, sizeof(struct tcp_debug)) != sizeof(struct tcp_debug))
safe_exit(TCPDEBUG, "TCP_DEBUG_SYN.read(kernel)", strerror(errno));
IF_ASSO {
*debx = i;
return my_tcp_debug.td_tcb;
}
(void)lseek(memf, (off_t)(sizeof(struct tcp_debug)*(-2)), SEEK_CUR);
}
return NULL;
}
/*
* Read tcp_debx from Kernel memory
*/
int get_tcp_debx(memf)
int memf;
{
off_t lseek();
(void)lseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET);
if (read(memf, (char *)&my_tcp_debx, sizeof(my_tcp_debx)) != sizeof(my_tcp_debx))
safe_exit(TCPDEBUG, "TCP_DEBUG_DEBX.read(kernel)", strerror(errno));
return my_tcp_debx; /* -1 */ /* XXX */
}
/*
* Debug Sub-Routine1
*/
void tcp_trace_debug(d, i, p)
struct tcp_debug *d;
int i, p;
{
int sp, dp, sa, da, th_flags;;
sa=(int)ntohl(d->td_ti.ti_src.s_addr);
da=(int)ntohl(d->td_ti.ti_dst.s_addr);
sp=(int)ntohs(d->td_ti.ti_sport);
dp=(int)ntohs(d->td_ti.ti_dport);
th_flags=(int)(d->td_ti.ti_flags);
fprintf(stderr,"[%3d](%4d)%1d(%3d.%3d.%3d.%3d, %3d.%3d.%3d.%3d)(%5d,%5d)%1u%1u%1u%1u%1u%1u(%lu)\n",
p,i, d->td_act,
GET_IP_ADDR(sa,4), GET_IP_ADDR(sa,3), GET_IP_ADDR(sa,2), GET_IP_ADDR(sa,1),
GET_IP_ADDR(da,4), GET_IP_ADDR(da,3), GET_IP_ADDR(da,2), GET_IP_ADDR(da,1),
sp, dp,
(int)(0x01 & (th_flags >>5)), /* URG */
(int)(0x01 & (th_flags >>4)), /* ACK */
(int)(0x01 & (th_flags >>3)), /* PSH */
(int)(0x01 & (th_flags >>2)), /* RST */
(int)(0x01 & (th_flags >>1)), /* SYN */
(int)(0x01 & (th_flags >>0)), /* FIN */
(long)d->td_tcb);
}
/*
* Debug Sub-Routine2
*/
void tcp_trace_debug2(a, act)
struct assosiation *a;
int act;
{
int sp, dp, sa, da, th_flags;
sa=(int)ntohl(a->source_address);
da=(int)ntohl(a->dest_address);
sp=(int)ntohs(a->source_port);
dp=(int)ntohs(a->dest_port);
th_flags=(int)(TH_SYN);
fprintf(stderr,"[%3d](%4d)%1u(%3d.%3d.%3d.%3d, %3d.%3d.%3d.%3d)(%5d,%5d)%1u%1u%1u%1u%1u%1u\n",
0,0,
act,
GET_IP_ADDR(sa,4), GET_IP_ADDR(sa,3), GET_IP_ADDR(sa,2), GET_IP_ADDR(sa,1),
GET_IP_ADDR(da,4), GET_IP_ADDR(da,3), GET_IP_ADDR(da,2), GET_IP_ADDR(da,1),
sp, dp,
(int)(0x01 & (th_flags >>5)), /* URG */
(int)(0x01 & (th_flags >>4)), /* ACK */
(int)(0x01 & (th_flags >>3)), /* PSH */
(int)(0x01 & (th_flags >>2)), /* RST */
(int)(0x01 & (th_flags >>1)), /* SYN */
(int)(0x01 & (th_flags >>0)) /* FIN */
);
}
#else /********** ELSE TCP_NDEBUG **********/
/*
* Dummy Functions for no tcp_debug OS
*/
void record_tcp_trace(rt, a, act)
struct tcp_trace *rt;
struct assosiation *a;
int act;
{
/* NULL */
}
void record_tcp_trace2(rt, a, flg)
struct tcp_trace *rt;
struct assosiation *a;
int flg;
{
/* NULL */
}
void init_so_debug(rt, a, act, flg)
struct tcp_trace *rt;
struct assosiation *a;
int act, flg;
{
/* NULL */
}
caddr_t search_syn(memf, a, debx, act)
int memf;
struct assosiation *a;
int *debx;
int act;
{
return NULL;
}
int get_tcp_debx(memf)
int memf;
{
return -1;
}
void tcp_trace_debug(d, i, p)
struct tcp_debug *d;
int i, p;
{
/* NULL */
}
void tcp_trace_debug2(a, act)
struct assosiation *a;
int act;
{
/* NULL */
}
#endif /********** ENDIF TCP_NDEBUG **********/
syntax highlighted by Code2HTML, v. 0.9.1