/*************************************************************************** * 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: * URL: * 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 #if defined(__osf__) || defined(__bsdi__) #include #endif #if defined(__osf__) || defined(__bsdi__) #include #endif #include #include #include #include #include #include #include #include #include #if defined(__svr4__) #include #endif #include "dbs.h" #include "dbsd.h" #include "record.h" /*#include */ #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 **********/