Net-Connection-Sniffer
view release on metacpan or search on metacpan
dusr = newHV();
init_hv(dusr,len);
hv_store(stats,(char *)trgt.s,4,newRV_noinc((SV *)dusr),0);
}
if ((fetch_uv(dusr,"T")) < now) {
dnsRflag = 1;
av_push(dnsrequest,newSVpv((char *)trgt.s,4));
}
}
MODULE = Net::Connection::Sniffer PACKAGE = Net::Connection::Sniffer
PROTOTYPES: DISABLE
# run, now, next, start I32
# rate, bw NV
# SVt_NULL, /* 0 */
# SVt_IV, /* 1 */
# SVt_NV, /* 2 */
# SVt_RV, /* 3 */
# SVt_PV, /* 4 */
# SVt_PVIV, /* 5 */
# SVt_PVNV, /* 6 */
# SVt_PVMG, /* 7 */
# SVt_PVBM, /* 8 */
# SVt_PVLV, /* 9 */
# SVt_PVAV, /* 10 */
# SVt_PVHV, /* 11 */
# SVt_PVCV, /* 12 */
# SVt_PVGV, /* 13 */
# SVt_PVFM, /* 14 */
# SVt_PVIO /* 15 */
void
p2xs_gvars(pnow, pstart, prate, pbw)
SV * pnow
SV * pstart
SV * prate
SV * pbw
INIT:
if (items != 4)
croak("Usage: Net::Connection::Sniffer::p2xs_gvars(pnow, pstart, prate, pbw)");
CODE:
now = SvUV(pnow);
nextp = now;
nextrate= 300;
next = now + nextrate; /* first increment is 5 minutes, following are different */
start = SvUV(pstart);
rate = SvNV(prate);
bw = SvNV(pbw);
hup = 0;
ra = 0;
ba = 0;
PROTOTYPES: ENABLE
void
xs2p_gvars()
PPCODE:
EXTEND(SP,4);
PUSHs(sv_2mortal(newSVuv(now)));
PUSHs(sv_2mortal(newSVuv(start)));
PUSHs(sv_2mortal(newSVnv(rate)));
PUSHs(sv_2mortal(newSVnv(bw)));
XSRETURN(4);
void
xs_daemon_init(sniffer,hpref,dnsref,nhost,dnshost,port,listenon,bpfstr,dev,snaplen,promisc,to)
SV * sniffer
SV * hpref
SV * dnsref
SV * nhost
SV * dnshost
int port
SV * listenon
char * bpfstr
char * dev
int snaplen
int promisc
int to
PREINIT:
unsigned char * ip, * lip, * sniffp;
STRLEN len;
char errorbuf[PCAP_ERRBUF_SIZE+1];
struct bpf_program real_fp;
CODE:
pktlen = snaplen;
if (SvPOK(sniffer) == 0)
croak("sniffer is not a 'path' or 'STDERR'");
if (! SvROK(hpref))
croak("stats is not a REF");
if (SvTYPE(SvRV(hpref)) != SVt_PVHV)
croak("stats is not a hash REF");
if (! SvROK(dnsref))
croak("dnslookup is not REF");
if (SvTYPE(SvRV(dnsref)) != SVt_PVAV)
croak("dnslookup is not an array REF");
if (SvPOK(nhost) == 0)
croak("nhost is not a netaddr");
ip = (u_char *)SvPV(nhost,len);
if (len != 4)
croak("nhost length of netaddr length is %d, should be 4", len);
strncpy((char *)me.s,(char *)ip,4);
if (SvPOK(dnshost) == 0)
croak("dnshost is not a netaddr");
ip = (u_char *)SvPV(dnshost,len);
if (len != 4)
croak("dnshost length of netaddr length is %d, should be 4", len);
bzero(&dnsaddr.sa,socklen);
dnsaddr.si.sin_family = PF_INET;
dnsaddr.si.sin_addr.s_addr = *((unsigned long *)ip);
dnsaddr.si.sin_port = htons(53);
if ((dnsFD = socket(PF_INET,SOCK_DGRAM,0)) < 0)
croak("could not open name server socket");
#define PRINT_dumptxt 5
#define CLOSE_wFD 6
#define WAS_PURGE 7
#define TERMINATE 8
int
_enter_constants(...)
ALIAS:
Net::Connection::Sniffer::INITIALIZE = 0
Net::Connection::Sniffer::SEND_dns = 1
Net::Connection::Sniffer::SEND_listen = 2
Net::Connection::Sniffer::INIT_wFD = 3
Net::Connection::Sniffer::RECV_dns = 4
Net::Connection::Sniffer::PRINT_dumptxt = 5
Net::Connection::Sniffer::CLOSE_wFD = 6
Net::Connection::Sniffer::WAS_PURGE = 7
Net::Connection::Sniffer::TERMINATE = 8
CODE:
RETVAL = ix;
OUTPUT:
RETVAL
#
# first return value indicates args
# the requested perl run operation
# 0 end, run is zero
# 1 listen interrupt now, sender.naddr, message received
# 2 dnslookup
# 3 dump request hup, init
# 4 dns receive len, buffer
# 5 purge interrupt -- dns alarm is checked here in Perl
#
#define END_RUN 0
#define LISTEN_MSG 1
#define DNS_NEEDED 2
#define DUMP_REQUEST 3
#define DNS_RECEIVE 4
#define PURGE 5
int
_exit_constants()
ALIAS:
Net::Connection::Sniffer::END_RUN = 0
Net::Connection::Sniffer::LISTEN_MSG = 1
Net::Connection::Sniffer::DNS_NEEDED = 2
Net::Connection::Sniffer::DUMP_REQUEST = 3
Net::Connection::Sniffer::DNS_RECEIVE = 4
Net::Connection::Sniffer::PURGE = 5
CODE:
RETVAL = ix;
OUTPUT:
RETVAL
void
xs_while(vector,...)
int vector
PREINIT:
unsigned char * buf;
STRLEN len;
int dnslen, listenlen;
PPCODE:
switch(vector)
{
case SEND_dns :
if (av_len(dnsrequest) < 0) {
dnsRflag = 0;
av_undef(dnsrequest);
}
buf = (unsigned char *)SvPV(ST(1),len);
sendto(dnsFD,buf,len,0,&dnsaddr.sa,socklen);
break;
case WAS_PURGE :
break;
case PRINT_dumptxt :
buf = (unsigned char *)SvPV(ST(1),len);
my_dump((char *)buf,len);
break;
case SEND_listen :
if (SvPOK(ST(1)) == 0)
break;
buf = (unsigned char *)SvPV(ST(1),len);
sendto(lFD,buf,len,0,&sender.sa,socklen);
case INIT_wFD :
signal_dump = 0;
if (SvIOK(ST(2)) == 0)
croak("arg2 is not a boolean 0/1");
if (SvIV(ST(2)) != 0) {
if (dumptofile) {
WFD = fopen(tmp,"w");
}
wFD = fileno(WFD);
dump_head = 1;
nleft = 0;
}
break;
case CLOSE_wFD :
if (dumptofile != 0) {
# fsync(wFD);
while(1) {
if (close(wFD) < 0) {
if (errno == EINTR)
continue; /* try again */
break; /* else fatal */
} else
rename(tmp,filepath);
break;
}
}
wFD = 0;
break;
case INITIALIZE :
run = SvIV(ST(1));
ra = 0;
ba = 0;
maxfd = dnsFD + 1;
if (lFD != 0 && lFD >= maxfd)
maxfd = lFD +1;
if (pFD >= maxfd)
maxfd = pFD +1;
max = maxfd;
FD_ZERO(&rset);
}
DNSCHECK:
if (FD_ISSET(dnsFD,&rset)) {
dnslen = recv(dnsFD,out.s,512,0);
if (dnslen > 0) {
EXTEND(SP,3);
PUSHs(sv_2mortal(newSViv(DNS_RECEIVE)));
PUSHs(sv_2mortal(newSViv(dnslen)));
PUSHs(sv_2mortal(newSVpv((char *)out.s,dnslen)));
XSRETURN(3);
}
}
WFDCHECK:
if (wFD != 0 && FD_ISSET(wFD,&wset) && dumpmore() == 0) {
EXTEND(SP,3);
PUSHs(sv_2mortal(newSViv(DUMP_REQUEST)));
PUSHs(sv_2mortal(newSViv(hup)));
PUSHs(sv_2mortal(newSViv(dump_head)));
dump_head = 0;
XSRETURN(3);
}
TIMECHECK:
if (now > nextp) { /* purge once a second */
TIMEFORCE:
nextp = now;
if (run > 0)
run--;
if (wFD != 0)
signal_dump = 0;
EXTEND(SP,3);
PUSHs(sv_2mortal(newSViv(PURGE)));
PUSHs(sv_2mortal(newSViv(now)));
PUSHs(sv_2mortal(newSViv(signal_dump)));
XSRETURN(3);
}
}
closeMOST();
if (wFD != 0 && dumptofile != 0)
close(wFD);
pcap_close(pcap);
XPUSHs(sv_2mortal(newSViv(END_RUN)));
XSRETURN(1);
# ############## THIS STUFF IS FOR TESTING ONLY!
void
inc_sv(hpp,key)
SV * hpp
char * key
ALIAS:
Net::Connection::Sniffer::fetch_uv = 1
PREINIT:
HV * hp;
INIT:
if (SvTYPE(SvRV(hpp)) != SVt_PVHV)
croak("hp is not a hash REF");
hp = (HV *)SvRV(hpp);
PPCODE:
if (ix == 1) {
XPUSHs(sv_2mortal(newSVuv(fetch_uv(hp,key))));
XSRETURN(1);
} else
inc_sv(hp,key);
void
set_uv(hpp,key,vp)
SV * hpp
char * key
SV * vp
ALIAS:
Net::Connection::Sniffer::set_nv = 2
Net::Connection::Sniffer::add_nv = 1
PREINIT:
HV * hp;
u_int32_t val32;
double valnv;
INIT:
if (SvTYPE(SvRV(hpp)) != SVt_PVHV)
croak("hp is not a hash REF");
hp = (HV *)SvRV(hpp);
CODE:
if (ix == 2) {
valnv = SvNV(vp);
set_nv(hp,key,valnv);
} else {
val32 = SvUV(vp);
if (ix == 1)
add_nv(hp,key,val32);
else
set_uv(hp,key,val32);
}
void
aEQaPLUSbXm(hpp,key1,key2,multi)
SV * hpp
char * key1
char * key2
NV multi
PREINIT:
HV * hp;
INIT:
if (SvTYPE(SvRV(hpp)) != SVt_PVHV)
croak("hp is not a hash REF");
hp = (HV *)SvRV(hpp);
CODE:
aEQaPLUSbXm(hp,key1,key2,multi);
void
init_hv(hpp,len)
SV * hpp
I32 len
PREINIT:
HV * hp;
INIT:
if (SvTYPE(SvRV(hpp)) != SVt_PVHV)
croak("hp is not a hash REF");
hp = (HV *)SvRV(hpp);
CODE:
( run in 0.831 second using v1.01-cache-2.11-cpan-5511b514fd6 )