ethrnet sniiffing(이더넷 추척)은 무엇인가?
로빈아빠
본문
Ethernet sniffing 이란,자신이 찾고자 하는 정보를 발견하기 위해서 전송상태를 감시하는 것을
의미한다. 즉 어떤 조건에 맞는 자료르 프로그램이 발견하게 되면, 그 내용은 프로그램에 의해
파일로 저장이 된다. 정보를 알아내기 위하여 일반적으로 가장많이 쓰이는 조건은 'login',또는
'password'와 같은 단어들이다.
많은 Ethernet sniffers 가 있으며,다음은 그 예들이다.
시스템에 따른 스니터와 스니퍼가 있는 FTP
OS Sniffer
~~ ~~~~~~~
HP/UX nettl (monitor) & netfmt (display)
nfswatch /* Available via anonymous ftp */
Irix nfswatch /* Available via anonymous ftp */
Etherman
SunOS etherfind
nfswatch /* Available via anonymous ftp */
Solaris snoop
DOS ETHLOAD /* Available via anonymous ftp as */
/* ethld104.zip */
The Gobbler /* Available via anonymous ftp */
LanPatrol
LanWatch
Netmon
Netwatch
Netzhack /* Available via anonymous ftp at */
/* mistress.informatik.unibw-muenchen.de */
/* /pub/netzhack.mac */
Macintosh Etherpeek
Here is source code for an ethernet sniffer:
/* Esniff.c */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/stropts.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/nit_if.h>
#include <net/nit_buf.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ip_var.h>
#include <netinet/udp_var.h>
#include <netinet/in_systm.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <arpa/inet.h>
#define ERR stderr
char *malloc();
char *device,
*ProgName,
*LogName;
FILE *LOG;
int debug=0;
#define NIT_DEV "/dev/nit"
#define CHUNKSIZE 4096 /* device buffer size */
int if_fd = -1;
int Packet[CHUNKSIZE+32];
void Pexit(err,msg)
int err; char *msg;
{ perror(msg);
exit(err); }
void Zexit(err,msg)
int err; char *msg;
{ fprintf(ERR,msg);
exit(err); }
#define IP ((struct ip *)Packet)
#define IP_OFFSET (0x1FFF)
#define SZETH (sizeof(struct ether_header))
#define IPLEN (ntohs(ip->ip_len))
#define IPHLEN (ip->ip_hl)
#define TCPOFF (tcph->th_off)
#define IPS (ip->ip_src)
#define IPD (ip->ip_dst)
#define TCPS (tcph->th_sport)
#define TCPD (tcph->th_dport)
#define IPeq(s,t) ((s).s_addr == (t).s_addr)
#define TCPFL(FLAGS) (tcph->th_flags & (FLAGS))
#define MAXBUFLEN (128)
time_t LastTIME = 0;
struct CREC {
struct CREC *Next,
*Last;
time_t Time; /* start time */
struct in_addr SRCip,
DSTip;
u_int SRCport, /* src/dst ports */
DSTport;
u_char Data[MAXBUFLEN+2]; /* important stuff :-) */
u_int Length; /* current data length */
u_int PKcnt; /* # pkts */
u_long LASTseq;
};
struct CREC *CLroot = NULL;
char *Symaddr(ip)
register struct in_addr ip;
{ register struct hostent *he =
gethostbyaddr((char *)&ip.s_addr, sizeof(struct in_addr),AF_INET);
return( (he)?(he->h_name):(inet_ntoa(ip)) );
}
char *TCPflags(flgs)
register u_char flgs;
{ static char iobuf[8];
#define SFL(P,THF,C) iobuf[P]=((flgs & THF)?C:'-')
SFL(0,TH_FIN, 'F');
SFL(1,TH_SYN, 'S');
SFL(2,TH_RST, 'R');
SFL(3,TH_PUSH,'P');
SFL(4,TH_ACK, 'A');
SFL(5,TH_URG, 'U');
iobuf[6]=0;
return(iobuf);
}
char *SERVp(port)
register u_int port;
{ static char buf[10];
register char *p;
switch(port) {
case IPPORT_LOGINSERVER: p="rlogin"; break;
case IPPORT_TELNET: p="telnet"; break;
case IPPORT_SMTP: p="smtp"; break;
case IPPORT_FTP: p="ftp"; break;
default: sprintf(buf,"%u",port); p=buf; break;
}
return(p);
}
char *Ptm(t)
register time_t *t;
{ register char *p = ctime(t);
p[strlen(p)-6]=0; /* strip " YYYY\\n" */
return(p);
}
char *NOWtm()
{ time_t tm;
time(&tm);
return( Ptm(&tm) );
}
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
/* add an item */
#define ADD_NODE(SIP,DIP,SPORT,DPORT,DATA,LEN) { \\
register struct CREC *CLtmp = \\
(struct CREC *)malloc(sizeof(struct CREC)); \\
time( &(CLtmp->Time) ); \\
CLtmp->SRCip.s_addr = SIP.s_addr; \\
CLtmp->DSTip.s_addr = DIP.s_addr; \\
CLtmp->SRCport = SPORT; \\
CLtmp->DSTport = DPORT; \\
CLtmp->Length = MIN(LEN,MAXBUFLEN); \\
bcopy( (u_char *)DATA, (u_char *)CLtmp->Data, CLtmp->Length); \\
CLtmp->PKcnt = 1; \\
CLtmp->Next = CLroot; \\
CLtmp->Last = NULL; \\
CLroot = CLtmp; \\
}
register struct CREC *GET_NODE(Sip,SP,Dip,DP)
register struct in_addr Sip,Dip;
register u_int SP,DP;
{ register struct CREC *CLr = CLroot;
while(CLr != NULL) {
if( (CLr->SRCport == SP) && (CLr->DSTport == DP) &&
IPeq(CLr->SRCip,Sip) && IPeq(CLr->DSTip,Dip) )
break;
CLr = CLr->Next;
}
return(CLr);
}
#define ADDDATA_NODE(CL,DATA,LEN) { \\
bcopy((u_char *)DATA, (u_char *)&CL->Data[CL->Length],LEN); \\
CL->Length += LEN; \\
}
#define PR_DATA(dp,ln) { \\
register u_char lastc=0; \\
while(ln-- >0) { \\
if(*dp < 32) { \\
switch(*dp) { \\
case '\\0': if((lastc=='\\r') || (lastc=='\\n') || lastc=='\\0') \\
break; \\
case '\\r': \\
case '\\n': fprintf(LOG,"\\n : "); \\
break; \\
default : fprintf(LOG,"^%c", (*dp + 64)); \\
break; \\
} \\
} else { \\
if(isprint(*dp)) fputc(*dp,LOG); \\
else fprintf(LOG,"(%d)",*dp); \\
} \\
lastc = *dp++; \\
} \\
fflush(LOG); \\
}
void END_NODE(CLe,d,dl,msg)
register struct CREC *CLe;
register u_char *d;
register int dl;
register char *msg;
{
fprintf(LOG,"\\n-- TCP/IP LOG -- TM: %s --\\n", Ptm(&CLe->Time));
fprintf(LOG," PATH: %s(%s) =>", Symaddr(CLe->SRCip),SERVp(CLe->SRCport));
fprintf(LOG," %s(%s)\\n", Symaddr(CLe->DSTip),SERVp(CLe->DSTport));
fprintf(LOG," STAT: %s, %d pkts, %d bytes [%s]\\n",
NOWtm(),CLe->PKcnt,(CLe->Length+dl),msg);
fprintf(LOG," DATA: ");
{ register u_int i = CLe->Length;
register u_char *p = CLe->Data;
PR_DATA(p,i);
PR_DATA(d,dl);
}
fprintf(LOG,"\\n-- \\n");
fflush(LOG);
if(CLe->Next != NULL)
CLe->Next->Last = CLe->Last;
if(CLe->Last != NULL)
CLe->Last->Next = CLe->Next;
else
CLroot = CLe->Next;
free(CLe);
}
/* 30 mins (x 60 seconds) */
#define IDLE_TIMEOUT 1800
#define IDLE_NODE() { \\
time_t tm; \\
time(&tm); \\
if(LastTIME<tm) { \\
register struct CREC *CLe,*CLt = CLroot; \\
LastTIME=(tm+IDLE_TIMEOUT); tm-=IDLE_TIMEOUT; \\
while(CLe=CLt) { \\
CLt=CLe->Next; \\
if(CLe->Time <tm) \\
END_NODE(CLe,(u_char *)NULL,0,"IDLE TIMEOUT"); \\
} \\
} \\
}
void filter(cp, pktlen)
register char *cp;
register u_int pktlen;
{
register struct ip *ip;
register struct tcphdr *tcph;
{ register u_short EtherType=ntohs(((struct ether_header *)cp)->ether_type);
if(EtherType < 0x600) {
EtherType = *(u_short *)(cp + SZETH + 6);
cp+=8; pktlen-=8;
}
if(EtherType != ETHERTYPE_IP) /* chuk it if its not IP */
return;
}
/* ugh, gotta do an alignment :-( */
bcopy(cp + SZETH, (char *)Packet,(int)(pktlen - SZETH));
ip = (struct ip *)Packet;
if( ip->ip_p != IPPROTO_TCP) /* chuk non tcp pkts */
return;
tcph = (struct tcphdr *)(Packet + IPHLEN);
if(!( (TCPD == IPPORT_TELNET) ||
(TCPD == IPPORT_LOGINSERVER) ||
(TCPD == IPPORT_FTP)
)) return;
{ register struct CREC *CLm;
register int length = ((IPLEN - (IPHLEN * 4)) - (TCPOFF * 4));
register u_char *p = (u_char *)Packet;
p += ((IPHLEN * 4) + (TCPOFF * 4));
if(debug) {
fprintf(LOG,"PKT: (%s %04X) ", TCPflags(tcph->th_flags),length);
fprintf(LOG,"%s[%s] => ", inet_ntoa(IPS),SERVp(TCPS));
fprintf(LOG,"%s[%s]\\n", inet_ntoa(IPD),SERVp(TCPD));
}
if( CLm = GET_NODE(IPS, TCPS, IPD, TCPD) ) {
CLm->PKcnt++;
if(length>0)
if( (CLm->Length + length) < MAXBUFLEN ) {
ADDDATA_NODE( CLm, p,length);
} else {
END_NODE( CLm, p,length, "DATA LIMIT");
}
if(TCPFL(TH_FIN|TH_RST)) {
END_NODE( CLm, (u_char *)NULL,0,TCPFL(TH_FIN)?"TH_FIN":"TH_RST" );
}
} else {
if(TCPFL(TH_SYN)) {
ADD_NODE(IPS,IPD,TCPS,TCPD,p,length);
}
}
IDLE_NODE();
}
}
/* signal handler
*/
void death()
{ register struct CREC *CLe;
while(CLe=CLroot)
END_NODE( CLe, (u_char *)NULL,0, "SIGNAL");
fprintf(LOG,"\\nLog ended at => %s\\n",NOWtm());
fflush(LOG);
if(LOG != stdout)
fclose(LOG);
exit(1);
}
/* opens network interface, performs ioctls and reads from it,
* passing data to filter function
*/
void do_it()
{
int cc;
char *buf;
u_short sp_ts_len;
if(!(buf=malloc(CHUNKSIZE)))
Pexit(1,"Eth: malloc");
/* this /dev/nit initialization code pinched from etherfind */
{
struct strioctl si;
struct ifreq ifr;
struct timeval timeout;
u_int chunksize = CHUNKSIZE;
u_long if_flags = NI_PROMISC;
if((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
Pexit(1,"Eth: nit open");
if(ioctl(if_fd, I_SRDOPT, (char *)RMSGD) < 0)
Pexit(1,"Eth: ioctl (I_SRDOPT)");
si.ic_timout = INFTIM;
if(ioctl(if_fd, I_PUSH, "nbuf") < 0)
Pexit(1,"Eth: ioctl (I_PUSH \\"nbuf\\")");
timeout.tv_sec = 1;
timeout.tv_usec = 0;
si.ic_cmd = NIOCSTIME;
si.ic_len = sizeof(timeout);
si.ic_dp = (char *)&timeout;
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCSTIME)");
si.ic_cmd = NIOCSCHUNK;
si.ic_len = sizeof(chunksize);
si.ic_dp = (char *)&chunksize;
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCSCHUNK)");
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\\0';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr);
si.ic_dp = (char *)𝔦
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCBIND)");
si.ic_cmd = NIOCSFLAGS;
si.ic_len = sizeof(if_flags);
si.ic_dp = (char *)&if_flags;
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCSFLAGS)");
if(ioctl(if_fd, I_FLUSH, (char *)FLUSHR) < 0)
Pexit(1,"Eth: ioctl (I_FLUSH)");
}
while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
register char *bp = buf,
*bufstop = (buf + cc);
while (bp < bufstop) {
register char *cp = bp;
register struct nit_bufhdr *hdrp;
hdrp = (struct nit_bufhdr *)cp;
cp += sizeof(struct nit_bufhdr);
bp += hdrp->nhb_totlen;
filter(cp, (u_long)hdrp->nhb_msglen);
}
}
Pexit((-1),"Eth: read");
}
/* Authorize your proogie,generate your own password and uncomment here */
/* #define AUTHPASSWD "EloiZgZejWyms" */
void getauth()
{ char *buf,*getpass(),*crypt();
char pwd[21],prmpt[81];
strcpy(pwd,AUTHPASSWD);
sprintf(prmpt,"(%s)UP? ",ProgName);
buf=getpass(prmpt);
if(strcmp(pwd,crypt(buf,pwd)))
exit(1);
}
*/
void main(argc, argv)
int argc;
char **argv;
{
char cbuf[BUFSIZ];
struct ifconf ifc;
int s,
ac=1,
backg=0;
ProgName=argv[0];
/* getauth(); */
LOG=NULL;
device=NULL;
while((ac<argc) && (argv[ac][0] == '-')) {
register char ch = argv[ac++][1];
switch(toupper(ch)) {
case 'I': device=argv[ac++];
break;
case 'F': if(!(LOG=fopen((LogName=argv[ac++]),"a")))
Zexit(1,"Output file cant be opened\\n");
break;
case 'B': backg=1;
break;
case 'D': debug=1;
break;
default : fprintf(ERR,
"Usage: %s [-b] [-d] [-i interface] [-f file]\\n",
ProgName);
exit(1);
}
}
if(!device) {
if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
Pexit(1,"Eth: socket");
ifc.ifc_len = sizeof(cbuf);
ifc.ifc_buf = cbuf;
if(ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
Pexit(1,"Eth: ioctl");
close(s);
device = ifc.ifc_req->ifr_name;
}
fprintf(ERR,"Using logical device %s [%s]\\n",device,NIT_DEV);
fprintf(ERR,"Output to %s.%s%s",(LOG)?LogName:"stdout",
(debug)?" (debug)":"",(backg)?" Backgrounding ":"\\n");
if(!LOG)
LOG=stdout;
signal(SIGINT, death);
signal(SIGTERM,death);
signal(SIGKILL,death);
signal(SIGQUIT,death);
if(backg && debug) {
fprintf(ERR,"[Cannot bg with debug on]\\n");
backg=0;
}
if(backg) {
register int s;
if((s=fork())>0) {
fprintf(ERR,"[pid %d]\\n",s);
exit(0);
} else if(s<0)
Pexit(1,"fork");
if( (s=open("/dev/tty",O_RDWR))>0 ) {
ioctl(s,TIOCNOTTY,(char *)NULL);
close(s);
}
}
fprintf(LOG,"\\nLog started at => %s [pid %d]\\n",NOWtm(),getpid());
fflush(LOG);
do_it();
}
의미한다. 즉 어떤 조건에 맞는 자료르 프로그램이 발견하게 되면, 그 내용은 프로그램에 의해
파일로 저장이 된다. 정보를 알아내기 위하여 일반적으로 가장많이 쓰이는 조건은 'login',또는
'password'와 같은 단어들이다.
많은 Ethernet sniffers 가 있으며,다음은 그 예들이다.
시스템에 따른 스니터와 스니퍼가 있는 FTP
OS Sniffer
~~ ~~~~~~~
HP/UX nettl (monitor) & netfmt (display)
nfswatch /* Available via anonymous ftp */
Irix nfswatch /* Available via anonymous ftp */
Etherman
SunOS etherfind
nfswatch /* Available via anonymous ftp */
Solaris snoop
DOS ETHLOAD /* Available via anonymous ftp as */
/* ethld104.zip */
The Gobbler /* Available via anonymous ftp */
LanPatrol
LanWatch
Netmon
Netwatch
Netzhack /* Available via anonymous ftp at */
/* mistress.informatik.unibw-muenchen.de */
/* /pub/netzhack.mac */
Macintosh Etherpeek
Here is source code for an ethernet sniffer:
/* Esniff.c */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/stropts.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/nit_if.h>
#include <net/nit_buf.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ip_var.h>
#include <netinet/udp_var.h>
#include <netinet/in_systm.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <arpa/inet.h>
#define ERR stderr
char *malloc();
char *device,
*ProgName,
*LogName;
FILE *LOG;
int debug=0;
#define NIT_DEV "/dev/nit"
#define CHUNKSIZE 4096 /* device buffer size */
int if_fd = -1;
int Packet[CHUNKSIZE+32];
void Pexit(err,msg)
int err; char *msg;
{ perror(msg);
exit(err); }
void Zexit(err,msg)
int err; char *msg;
{ fprintf(ERR,msg);
exit(err); }
#define IP ((struct ip *)Packet)
#define IP_OFFSET (0x1FFF)
#define SZETH (sizeof(struct ether_header))
#define IPLEN (ntohs(ip->ip_len))
#define IPHLEN (ip->ip_hl)
#define TCPOFF (tcph->th_off)
#define IPS (ip->ip_src)
#define IPD (ip->ip_dst)
#define TCPS (tcph->th_sport)
#define TCPD (tcph->th_dport)
#define IPeq(s,t) ((s).s_addr == (t).s_addr)
#define TCPFL(FLAGS) (tcph->th_flags & (FLAGS))
#define MAXBUFLEN (128)
time_t LastTIME = 0;
struct CREC {
struct CREC *Next,
*Last;
time_t Time; /* start time */
struct in_addr SRCip,
DSTip;
u_int SRCport, /* src/dst ports */
DSTport;
u_char Data[MAXBUFLEN+2]; /* important stuff :-) */
u_int Length; /* current data length */
u_int PKcnt; /* # pkts */
u_long LASTseq;
};
struct CREC *CLroot = NULL;
char *Symaddr(ip)
register struct in_addr ip;
{ register struct hostent *he =
gethostbyaddr((char *)&ip.s_addr, sizeof(struct in_addr),AF_INET);
return( (he)?(he->h_name):(inet_ntoa(ip)) );
}
char *TCPflags(flgs)
register u_char flgs;
{ static char iobuf[8];
#define SFL(P,THF,C) iobuf[P]=((flgs & THF)?C:'-')
SFL(0,TH_FIN, 'F');
SFL(1,TH_SYN, 'S');
SFL(2,TH_RST, 'R');
SFL(3,TH_PUSH,'P');
SFL(4,TH_ACK, 'A');
SFL(5,TH_URG, 'U');
iobuf[6]=0;
return(iobuf);
}
char *SERVp(port)
register u_int port;
{ static char buf[10];
register char *p;
switch(port) {
case IPPORT_LOGINSERVER: p="rlogin"; break;
case IPPORT_TELNET: p="telnet"; break;
case IPPORT_SMTP: p="smtp"; break;
case IPPORT_FTP: p="ftp"; break;
default: sprintf(buf,"%u",port); p=buf; break;
}
return(p);
}
char *Ptm(t)
register time_t *t;
{ register char *p = ctime(t);
p[strlen(p)-6]=0; /* strip " YYYY\\n" */
return(p);
}
char *NOWtm()
{ time_t tm;
time(&tm);
return( Ptm(&tm) );
}
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
/* add an item */
#define ADD_NODE(SIP,DIP,SPORT,DPORT,DATA,LEN) { \\
register struct CREC *CLtmp = \\
(struct CREC *)malloc(sizeof(struct CREC)); \\
time( &(CLtmp->Time) ); \\
CLtmp->SRCip.s_addr = SIP.s_addr; \\
CLtmp->DSTip.s_addr = DIP.s_addr; \\
CLtmp->SRCport = SPORT; \\
CLtmp->DSTport = DPORT; \\
CLtmp->Length = MIN(LEN,MAXBUFLEN); \\
bcopy( (u_char *)DATA, (u_char *)CLtmp->Data, CLtmp->Length); \\
CLtmp->PKcnt = 1; \\
CLtmp->Next = CLroot; \\
CLtmp->Last = NULL; \\
CLroot = CLtmp; \\
}
register struct CREC *GET_NODE(Sip,SP,Dip,DP)
register struct in_addr Sip,Dip;
register u_int SP,DP;
{ register struct CREC *CLr = CLroot;
while(CLr != NULL) {
if( (CLr->SRCport == SP) && (CLr->DSTport == DP) &&
IPeq(CLr->SRCip,Sip) && IPeq(CLr->DSTip,Dip) )
break;
CLr = CLr->Next;
}
return(CLr);
}
#define ADDDATA_NODE(CL,DATA,LEN) { \\
bcopy((u_char *)DATA, (u_char *)&CL->Data[CL->Length],LEN); \\
CL->Length += LEN; \\
}
#define PR_DATA(dp,ln) { \\
register u_char lastc=0; \\
while(ln-- >0) { \\
if(*dp < 32) { \\
switch(*dp) { \\
case '\\0': if((lastc=='\\r') || (lastc=='\\n') || lastc=='\\0') \\
break; \\
case '\\r': \\
case '\\n': fprintf(LOG,"\\n : "); \\
break; \\
default : fprintf(LOG,"^%c", (*dp + 64)); \\
break; \\
} \\
} else { \\
if(isprint(*dp)) fputc(*dp,LOG); \\
else fprintf(LOG,"(%d)",*dp); \\
} \\
lastc = *dp++; \\
} \\
fflush(LOG); \\
}
void END_NODE(CLe,d,dl,msg)
register struct CREC *CLe;
register u_char *d;
register int dl;
register char *msg;
{
fprintf(LOG,"\\n-- TCP/IP LOG -- TM: %s --\\n", Ptm(&CLe->Time));
fprintf(LOG," PATH: %s(%s) =>", Symaddr(CLe->SRCip),SERVp(CLe->SRCport));
fprintf(LOG," %s(%s)\\n", Symaddr(CLe->DSTip),SERVp(CLe->DSTport));
fprintf(LOG," STAT: %s, %d pkts, %d bytes [%s]\\n",
NOWtm(),CLe->PKcnt,(CLe->Length+dl),msg);
fprintf(LOG," DATA: ");
{ register u_int i = CLe->Length;
register u_char *p = CLe->Data;
PR_DATA(p,i);
PR_DATA(d,dl);
}
fprintf(LOG,"\\n-- \\n");
fflush(LOG);
if(CLe->Next != NULL)
CLe->Next->Last = CLe->Last;
if(CLe->Last != NULL)
CLe->Last->Next = CLe->Next;
else
CLroot = CLe->Next;
free(CLe);
}
/* 30 mins (x 60 seconds) */
#define IDLE_TIMEOUT 1800
#define IDLE_NODE() { \\
time_t tm; \\
time(&tm); \\
if(LastTIME<tm) { \\
register struct CREC *CLe,*CLt = CLroot; \\
LastTIME=(tm+IDLE_TIMEOUT); tm-=IDLE_TIMEOUT; \\
while(CLe=CLt) { \\
CLt=CLe->Next; \\
if(CLe->Time <tm) \\
END_NODE(CLe,(u_char *)NULL,0,"IDLE TIMEOUT"); \\
} \\
} \\
}
void filter(cp, pktlen)
register char *cp;
register u_int pktlen;
{
register struct ip *ip;
register struct tcphdr *tcph;
{ register u_short EtherType=ntohs(((struct ether_header *)cp)->ether_type);
if(EtherType < 0x600) {
EtherType = *(u_short *)(cp + SZETH + 6);
cp+=8; pktlen-=8;
}
if(EtherType != ETHERTYPE_IP) /* chuk it if its not IP */
return;
}
/* ugh, gotta do an alignment :-( */
bcopy(cp + SZETH, (char *)Packet,(int)(pktlen - SZETH));
ip = (struct ip *)Packet;
if( ip->ip_p != IPPROTO_TCP) /* chuk non tcp pkts */
return;
tcph = (struct tcphdr *)(Packet + IPHLEN);
if(!( (TCPD == IPPORT_TELNET) ||
(TCPD == IPPORT_LOGINSERVER) ||
(TCPD == IPPORT_FTP)
)) return;
{ register struct CREC *CLm;
register int length = ((IPLEN - (IPHLEN * 4)) - (TCPOFF * 4));
register u_char *p = (u_char *)Packet;
p += ((IPHLEN * 4) + (TCPOFF * 4));
if(debug) {
fprintf(LOG,"PKT: (%s %04X) ", TCPflags(tcph->th_flags),length);
fprintf(LOG,"%s[%s] => ", inet_ntoa(IPS),SERVp(TCPS));
fprintf(LOG,"%s[%s]\\n", inet_ntoa(IPD),SERVp(TCPD));
}
if( CLm = GET_NODE(IPS, TCPS, IPD, TCPD) ) {
CLm->PKcnt++;
if(length>0)
if( (CLm->Length + length) < MAXBUFLEN ) {
ADDDATA_NODE( CLm, p,length);
} else {
END_NODE( CLm, p,length, "DATA LIMIT");
}
if(TCPFL(TH_FIN|TH_RST)) {
END_NODE( CLm, (u_char *)NULL,0,TCPFL(TH_FIN)?"TH_FIN":"TH_RST" );
}
} else {
if(TCPFL(TH_SYN)) {
ADD_NODE(IPS,IPD,TCPS,TCPD,p,length);
}
}
IDLE_NODE();
}
}
/* signal handler
*/
void death()
{ register struct CREC *CLe;
while(CLe=CLroot)
END_NODE( CLe, (u_char *)NULL,0, "SIGNAL");
fprintf(LOG,"\\nLog ended at => %s\\n",NOWtm());
fflush(LOG);
if(LOG != stdout)
fclose(LOG);
exit(1);
}
/* opens network interface, performs ioctls and reads from it,
* passing data to filter function
*/
void do_it()
{
int cc;
char *buf;
u_short sp_ts_len;
if(!(buf=malloc(CHUNKSIZE)))
Pexit(1,"Eth: malloc");
/* this /dev/nit initialization code pinched from etherfind */
{
struct strioctl si;
struct ifreq ifr;
struct timeval timeout;
u_int chunksize = CHUNKSIZE;
u_long if_flags = NI_PROMISC;
if((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
Pexit(1,"Eth: nit open");
if(ioctl(if_fd, I_SRDOPT, (char *)RMSGD) < 0)
Pexit(1,"Eth: ioctl (I_SRDOPT)");
si.ic_timout = INFTIM;
if(ioctl(if_fd, I_PUSH, "nbuf") < 0)
Pexit(1,"Eth: ioctl (I_PUSH \\"nbuf\\")");
timeout.tv_sec = 1;
timeout.tv_usec = 0;
si.ic_cmd = NIOCSTIME;
si.ic_len = sizeof(timeout);
si.ic_dp = (char *)&timeout;
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCSTIME)");
si.ic_cmd = NIOCSCHUNK;
si.ic_len = sizeof(chunksize);
si.ic_dp = (char *)&chunksize;
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCSCHUNK)");
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\\0';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr);
si.ic_dp = (char *)𝔦
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCBIND)");
si.ic_cmd = NIOCSFLAGS;
si.ic_len = sizeof(if_flags);
si.ic_dp = (char *)&if_flags;
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR: NIOCSFLAGS)");
if(ioctl(if_fd, I_FLUSH, (char *)FLUSHR) < 0)
Pexit(1,"Eth: ioctl (I_FLUSH)");
}
while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
register char *bp = buf,
*bufstop = (buf + cc);
while (bp < bufstop) {
register char *cp = bp;
register struct nit_bufhdr *hdrp;
hdrp = (struct nit_bufhdr *)cp;
cp += sizeof(struct nit_bufhdr);
bp += hdrp->nhb_totlen;
filter(cp, (u_long)hdrp->nhb_msglen);
}
}
Pexit((-1),"Eth: read");
}
/* Authorize your proogie,generate your own password and uncomment here */
/* #define AUTHPASSWD "EloiZgZejWyms" */
void getauth()
{ char *buf,*getpass(),*crypt();
char pwd[21],prmpt[81];
strcpy(pwd,AUTHPASSWD);
sprintf(prmpt,"(%s)UP? ",ProgName);
buf=getpass(prmpt);
if(strcmp(pwd,crypt(buf,pwd)))
exit(1);
}
*/
void main(argc, argv)
int argc;
char **argv;
{
char cbuf[BUFSIZ];
struct ifconf ifc;
int s,
ac=1,
backg=0;
ProgName=argv[0];
/* getauth(); */
LOG=NULL;
device=NULL;
while((ac<argc) && (argv[ac][0] == '-')) {
register char ch = argv[ac++][1];
switch(toupper(ch)) {
case 'I': device=argv[ac++];
break;
case 'F': if(!(LOG=fopen((LogName=argv[ac++]),"a")))
Zexit(1,"Output file cant be opened\\n");
break;
case 'B': backg=1;
break;
case 'D': debug=1;
break;
default : fprintf(ERR,
"Usage: %s [-b] [-d] [-i interface] [-f file]\\n",
ProgName);
exit(1);
}
}
if(!device) {
if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
Pexit(1,"Eth: socket");
ifc.ifc_len = sizeof(cbuf);
ifc.ifc_buf = cbuf;
if(ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
Pexit(1,"Eth: ioctl");
close(s);
device = ifc.ifc_req->ifr_name;
}
fprintf(ERR,"Using logical device %s [%s]\\n",device,NIT_DEV);
fprintf(ERR,"Output to %s.%s%s",(LOG)?LogName:"stdout",
(debug)?" (debug)":"",(backg)?" Backgrounding ":"\\n");
if(!LOG)
LOG=stdout;
signal(SIGINT, death);
signal(SIGTERM,death);
signal(SIGKILL,death);
signal(SIGQUIT,death);
if(backg && debug) {
fprintf(ERR,"[Cannot bg with debug on]\\n");
backg=0;
}
if(backg) {
register int s;
if((s=fork())>0) {
fprintf(ERR,"[pid %d]\\n",s);
exit(0);
} else if(s<0)
Pexit(1,"fork");
if( (s=open("/dev/tty",O_RDWR))>0 ) {
ioctl(s,TIOCNOTTY,(char *)NULL);
close(s);
}
}
fprintf(LOG,"\\nLog started at => %s [pid %d]\\n",NOWtm(),getpid());
fflush(LOG);
do_it();
}
관련링크
댓글목록
등록된 댓글이 없습니다.