/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation,
* YDC Corporation, IPA (Information-technology Promotion Agency, Japan).
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* conditions and disclaimer are agreed and accepted by the user:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the names of the copyrighters, the name of the project which
* is related to this software (hereinafter referred to as "project") nor
* the names of the contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. No merchantable use may be permitted without prior written
* notification to the copyrighters. However, using this software for the
* purpose of testing or evaluating any products including merchantable
* products may be permitted without any notification to the copyrighters.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTERS, THE PROJECT AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING
* BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHTERS, THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT,STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $TAHI: v6eval/lib/pkt/PktCtlClient.cc,v 1.15 2003/04/17 02:22:20 akisada Exp $
*/
#include "PktCtlClient.h"
#include "timeval.h"
#include "RunEnv.h"
#include "bufStat.h"
#include "PvOctets.h"
#include "ItPosition.h"
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <net/bpf.h>
PktCtlClient::PktCtlClient(StringList pos):PktClient(),
command_(pos),parsed_(0) {}
PktCtlClient::~PktCtlClient() {}
int PktCtlClient::readIndication() {
tcpHead h(eRead_);
timeval tv;
timeval *timeout=RunEnv::tvtimeout();
uint32_t size=0;
if(timeout!=0){
tv.tv_sec=htonl(timeout->tv_sec);
tv.tv_usec=htonl(timeout->tv_usec);
size=sizeof(tv);}
if(sendPacket(h,size,(char*)&tv)==sizeof(tv))
return 0;
else
return 1;}
int PktCtlClient::writeIndication(STR s,uint32_t l) {
tcpHead h(eWrite_);
sendPacket(h,l,s); /* todo: error check */
return 0;}
int PktCtlClient::dumpIndication(uint32_t l) {
uint32_t dp=htonl(l);
tcpHead h(eDump_);
sendPacket(h,sizeof(dp),(char *)&dp); /* todo: error check */
return 0;}
int PktCtlClient::Indication(uint32_t req){
tcpHead con(req);
if(sendPacket(con,0,0)==sizeof(con))
return 0;
else
return 1;}
int PktCtlClient::sendConnect(CSTR) {
return PktClient::sendConnect("pktctl");}
int PktCtlClient::writeConfirmation() {
int rc=result();
if(rc!=0) {
printf("err:pktbuf result=%d\n",rc);
terminate(); exit(1);}
timeval& tv=*(timeval*)buffer();
printf("std: %ld.%06ld\n",(u_long)ntohl(tv.tv_sec),(u_long)ntohl(tv.tv_usec));
return command();}
int PktCtlClient::statusConfirmation() {
int rc=result();
if(rc!=0) {
printf("err:pktbuf result=%d\n",rc);
terminate(); exit(1);}
bufStat& stat=*(bufStat*)buffer();
stat.print();
return command();}
int PktCtlClient::Confirmation(STR msg) {
int rc=result();
if(rc!=0) {
printf("err:pktbuf %s result=%d\n",msg,rc);
terminate(); exit(1);}
return command();}
int PktCtlClient::captureConfirmation() {
return Confirmation("capture start");}
int PktCtlClient::clearConfirmation() {
return Confirmation("clear buffer");}
int PktCtlClient::stopConfirmation() {
return Confirmation("capture stop");}
int PktCtlClient::wrapConfirmation() {
return Confirmation("wrap mode");}
int PktCtlClient::nowrapConfirmation() {
return Confirmation("nowrap mode");}
int PktCtlClient::connectConfirmation() {
return Confirmation("Connected");}
int PktCtlClient::readConfirmation() {
int rc=result();
STR s=buffer();
uint32_t l=bodyLength();
if(rc==2) {
printf("log:pktbuf timeout\n");
exit(1);}
if(rc!=0||s==0||l==0) {
printf("err:pktbuf result=%d length=%d\n",rc,l);
terminate(); exit(3);}
bpf_hdr* hdr=(bpf_hdr*)s;
hdr->bh_tstamp.tv_sec=ntohl(hdr->bh_tstamp.tv_sec);
hdr->bh_tstamp.tv_usec=ntohl(hdr->bh_tstamp.tv_usec);
hdr->bh_hdrlen=ntohs(hdr->bh_hdrlen);
hdr->bh_caplen=ntohl(hdr->bh_caplen);
hdr->bh_datalen=ntohl(hdr->bh_datalen);
timeval *tv=&(hdr->bh_tstamp);
if(*tv<RunEnv::seek())
printf("-- skip --\n");
else
printf("-- eval --\n");
printf("std: %ld.%06ld\n",tv->tv_sec,tv->tv_usec);
uint32_t hlen=hdr->bh_hdrlen;
uint32_t caplen=hdr->bh_caplen;
PvOctets rcv(caplen,(OCTSTR)s+hlen);
rcv.print();
return command();}
int PktCtlClient::dumpConfirmation() {
int rc=result();
STR s=buffer();
uint32_t l=bodyLength();
if(rc==0&&l==0) {
printf("std:buffer empty\n");
terminate(); exit(0);}
if(s==0||l==0) {
printf("err:pktctl result=%d length=%d\n",rc,l);
terminate(); exit(3);}
bpf_hdr* hdr=(bpf_hdr*)s;
hdr->bh_tstamp.tv_sec=ntohl(hdr->bh_tstamp.tv_sec);
hdr->bh_tstamp.tv_usec=ntohl(hdr->bh_tstamp.tv_usec);
timeval *tv=&(hdr->bh_tstamp);
printf("std: %ld.%06ld\n",tv->tv_sec,tv->tv_usec);
uint32_t hlen=ntohs(hdr->bh_hdrlen);
uint32_t caplen=ntohl(hdr->bh_caplen);
PvOctets rcv(caplen,(OCTSTR)s+hlen);
rcv.print();
printf("\n");
if(rc) return dumpIndication(rc);
else return command();}
int PktCtlClient::command(int) {
int rc=0;
if(parsed_ >= command_.size())
exit (0); // all command has paesed.
CmString & cmdstr=*command_[parsed_++];
if(cmdstr=="send") {
if(parsed_ >= command_.size()){
fprintf(stderr,"err: less argument\n");
exit (1);}
CSTR filename=(*command_[parsed_++]).string();
const uint32_t MAX_PKTSIZE=1500;
char buf[MAX_PKTSIZE];
int fd;
ssize_t size;
fd = open(filename,O_RDONLY,0);
if(fd == -1) {
printf("err:can't open send data file\n");
rc=1;}
else { size = read(fd,buf,MAX_PKTSIZE);
if (size <= 0) rc=1;
else rc=writeIndication(buf,size);}}
else if(cmdstr=="recv") {
rc=readIndication();}
else if(cmdstr=="dump") {
rc=dumpIndication(0);}
else if(cmdstr=="capture") {
rc=Indication(eCapture_);}
else if(cmdstr=="clear") {
rc=Indication(eClear_);}
else if(cmdstr=="dump") {
rc=Indication(eDump_);}
else if(cmdstr=="stop") {
rc=Indication(eStop_);}
else if(cmdstr=="wrap") {
rc=Indication(eWrap_);}
else if(cmdstr=="nowrap") {
rc=Indication(eNowrap_);}
else if(cmdstr=="status") {
rc=Indication(eStatus_);}
else { printf("err:unknown command \"%s\"\n",cmdstr.string());
usage();
rc=1;}
if(rc){ exit (rc);}
return 0;}
void PktCtlClient::usage() {
printf("usage:\n");
printf(" status: report current status of pakcet buffer.\n");
printf(" capture: flush and start receive packet from bpf.\n");
printf(" clear: set pointer at the top of buffer.\n");
printf(" wrap: use buffer as wrap buffer.\n");
printf(" nowrap: stop receive packet from bpf pointer comes end.\n");
printf(" stop: stop receiving packet from bpf.\n");
printf(" dump: dump packet buffer.\n");
printf(" send: send packet.\n");
printf(" recv: recv packet.\n");}
syntax highlighted by Code2HTML, v. 0.9.1