⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpcap.c

📁 Java抓包必备
💻 C
📖 第 1 页 / 共 2 页
字号:
#include<jni.h>
#include<pcap.h>

#include<net/bpf.h>

#ifndef WIN32
#include<sys/param.h>
#include<sys/socket.h>
#include<sys/ioctl.h>
#include<net/if.h>
#include<errno.h>
#define __FAVOR_BSD
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
#ifndef SIOCGIFCONF
#include<sys/sockio.h>
#endif
#else
#include<winsock.h>
#include<stdlib.h>
#endif

#include<netinet/in_systm.h>
#include<netinet/ip.h>

#include"jpcap_Jpcap.h"
#include"jpcap_IPAddress.h"

#include"Jpcap_sub.h"
#include"Jpcap_ether.h"

#ifdef INET6
#define COMPAT_RFC2292
#include<netinet/ip6.h>
#include<netinet6/ah.h>
#endif

const int offset_type[]={0,12,-1,-1,-1,-1,20,-1,-1,2,
#ifdef PCAP_FDDIPAD
			  19+PCAP_FDDIPAD,
#else
			  19,
#endif
			  6,-1,-1,5};

const int offset_data[]={4,14,-1,-1,-1,-1,22,-1,16,4,
#ifdef PCAP_FDDIPAD
			   21+PCAP_FDDIPAD,
#else
			   21,
#endif
			   8,0,24,24};

#define get_network_type(data) ntohs(*(u_short *)(data+offset_type[linktype]))

#define skip_datalink_header(data)  (data+offset_data[linktype])

#define datalink_hlen offset_data[linktype]


pcap_t *pcd=NULL;
int linktype=-1;
bpf_u_int32 netnum,netmask;

struct pcap_info {
        int fd;
        int snapshot;
        int linktype;
        int tzoff;
        int offset;
};

jclass JpcapHandler,Packet,DatalinkPacket,EthernetPacket,IPPacket,TCPPacket,UDPPacket,ICMPPacket,IPv6Option,ARPPacket,String,Thread,UnknownHostException,IOException;
jmethodID handleMID,setPacketValueMID,setDatalinkPacketMID,
  setPacketHeaderMID,setPacketDataMID,
  setEthernetValueMID,setIPValueMID,setIPv6ValueMID,addIPv6OptHdrMID,
  setTCPValueMID,setTCPOptionMID,setUDPValueMID,
  setICMPValueMID,setICMPIDMID,setICMPTimestampMID,setICMPRedirectIPMID,
  setICMPRouterAdMID,setV6OptValueMID,setV6OptOptionMID,setV6OptFragmentMID,
  setV6OptRoutingMID,setV6OptAHMID,
  setARPValueMID,
  getSourceAddressMID,getDestinationAddressMID;

jobject jpcap_handler;
JNIEnv *jni_env=NULL;

static char pcap_errbuf[PCAP_ERRBUF_SIZE];
static char buffer[256];
static char tmp_buffer[256];

void set_info(JNIEnv *env,jobject obj);
void set_Java_env(JNIEnv *);
void get_packet(struct pcap_pkthdr,u_char *,jobject *);
void dispatcher_handler(u_char *,const struct pcap_pkthdr *,const u_char *);

struct ip_packet *getIP(char *payload);

u_short analyze_ip(jobject packet,u_char *data);
u_short analyze_tcp(jobject packet,u_char *data);
void analyze_udp(jobject packet,u_char *data);
void analyze_icmp(jobject packet,u_char *data,u_short len);
#ifdef INET6
u_short analyze_ipv6(jobject packet,u_char *data);
#endif
int analyze_arp(jobject packet,u_char *data);
jobject analyze_datalink(u_char *data);


/**
Open Device for Live Capture
**/
JNIEXPORT jstring JNICALL
Java_jpcap_Jpcap_nativeOpenLive(JNIEnv *env,jobject obj,jstring device,jint snaplen,
			  jint promisc,jint to_ms)
{
  char *dev;
  jni_env=env;

  if(pcd!=NULL){
	return (*env)->NewStringUTF(env,"Another Jpcap instance is being used.");
  }
  
  if(device==NULL){
    return (*env)->NewStringUTF(env,"Please specify device name.");
  }
  dev=(char *)(*env)->GetStringUTFChars(env,device,0);

  pcd=pcap_open_live(dev,snaplen,promisc,to_ms,pcap_errbuf);
  if(pcap_lookupnet(dev,&netnum,&netmask,pcap_errbuf)==-1){
    strcpy(pcap_errbuf,"Can't get net number and netmask.");
	pcd=NULL;
  }

  (*env)->ReleaseStringUTFChars(env,device,dev);

  if(pcd==NULL) return (*env)->NewStringUTF(env,pcap_errbuf);

  set_info(env,obj);
  set_Java_env(env);
  return NULL;
} 

/**
Open Dumped File
**/
JNIEXPORT jstring JNICALL
Java_jpcap_Jpcap_nativeOpenOffline(JNIEnv *env,jobject obj,jstring filename)
{
  char *file;
  jni_env=env;

  if(pcd!=NULL){
	return (*env)->NewStringUTF(env,"Another Jpcap instance is being used.");
  }

  file=(char *)(*env)->GetStringUTFChars(env,filename,0);
  
  pcd=pcap_open_offline(file,pcap_errbuf);

  (*env)->ReleaseStringUTFChars(env,filename,file);

  if(pcd==NULL) return (*env)->NewStringUTF(env,pcap_errbuf);

  set_info(env,obj);
  set_Java_env(env);
  return NULL;
}

/**
Close Live Capture Device
**/
JNIEXPORT void JNICALL
Java_jpcap_Jpcap_close(JNIEnv *env,jobject obj)
{
  if(pcd!=NULL) pcap_close(pcd);
  pcd=NULL;
}

/**
Look up device 
**/
JNIEXPORT jstring JNICALL
Java_jpcap_Jpcap_lookupDevice(JNIEnv *env,jobject obj)
{
  char *dev=pcap_lookupdev(pcap_errbuf);
  if(dev==NULL){
    return NULL;
  }else
    return (*env)->NewStringUTF(env,dev);
}

/**
Get Interface List
**/
JNIEXPORT jobjectArray JNICALL
Java_jpcap_Jpcap_getDeviceList(JNIEnv *env,jobject obj)
{
#ifndef WIN32
  int sock=socket(AF_INET,SOCK_DGRAM,0);
  struct ifconf ifc;
  struct ifreq *ifr,*last;
  struct ifreq ifrflags;
  pcap_t *pch;

  char names[100][100];
  int total=0,i=0;
  jobjectArray devices=NULL;
  
  if(sock<0){
    /* error opening socket*/
    return NULL;
  }

  ifc.ifc_len = 1024*sizeof(struct ifreq);
  ifc.ifc_buf=malloc(ifc.ifc_len);

  if(ioctl(sock,SIOCGIFCONF,&ifc)<0 ||
     ifc.ifc_len<sizeof(struct ifreq)){
    /* SIOCGIFCONF error */
    goto FAIL;
  }

  ifr=(struct ifreq *)ifc.ifc_req;
  last=(struct ifreq *)((char *)ifr+ifc.ifc_len);

  while(ifr<last){
    //puts(ifr->ifr_name);
    /* Skip "dummy" and a ":" */
    if(strncmp(ifr->ifr_name,"dummy",5)==0 ||
       strchr(ifr->ifr_name,':')!=NULL)
      goto NEXT;

    for(i=0;i<total;i++){
      if(strcmp(names[i],ifr->ifr_name)==0) goto NEXT;
    }
    /* Check flags */
    memset(&ifrflags,0,sizeof ifrflags);
    strncpy(ifrflags.ifr_name,ifr->ifr_name,sizeof ifrflags.ifr_name);
    if(ioctl(sock,SIOCGIFFLAGS,(char *)&ifrflags)<0){
      if(errno == ENXIO) goto NEXT;
      else goto FAIL;
    }

    if(!(ifrflags.ifr_flags & IFF_UP)) goto NEXT;

    pch=pcap_open_live(ifr->ifr_name,68,0,0,pcap_errbuf);
    if(pch==NULL) goto NEXT;
    pcap_close(pch);

    strcpy(names[total++],ifr->ifr_name);

  NEXT:
#ifdef HAVE_SA_LEN
    ifr=(struct ifreq *)((char *)ifr+ifr->ifr_addr.sa_len+IFNAMSIZ);
#else
    ifr=(struct ifreq *)((char *)ifr+sizeof(struct ifreq));
#endif
  }

  if(total==0) return NULL;
  devices=(*env)->NewObjectArray(env,(jsize)total,
			  (*env)->FindClass(env,"java/lang/String"),NULL);
  for(i=0;i<total;i++){
    (*env)->SetObjectArrayElement(env,devices,i,(*env)->NewStringUTF(env,names[i]));
  }

  free(ifc.ifc_buf);
  close(sock);
  return devices;

FAIL:
  free(ifc.ifc_buf);
  close(sock);
  return NULL;

#else
	wchar_t *dev;
	int i=0,c=0,j=0;
	char buf[256];
	jobjectArray devices=NULL;

	if(dev=(wchar_t *)pcap_lookupdev(pcap_errbuf)){
		if(dev[0]<256) { /*NT/2000*/
			if(dev[0]==0 && dev[1]==0) return NULL; /* no device */
			while(!(dev[i]==0 && dev[i-1]==0)){
				if(dev[i]==0) c++;
				i++;
			}
			devices=(*env)->NewObjectArray(env,(jsize)c,(*env)->FindClass(env,"java/lang/String"),NULL);
			i=0;
			for(j=0;j<c;j++){
				wcstombs(buf,(wchar_t *)(dev+i),255);
				(*env)->SetObjectArrayElement(env,devices,j,(*env)->NewStringUTF(env,buf));
				while(dev[i]!=0) i++;
				i++;
			}
		}else{ /*9x*/
			char *dev9x=(char *)dev;
			
			if(dev9x[0]==0 && dev9x[1]==0) return NULL; /* no device */
			while(!(dev9x[i]==0 && dev9x[i-1]==0)){
				if(dev9x[i]==0) c++;
				i++;
			}
			devices=(*env)->NewObjectArray(env,(jsize)c,(*env)->FindClass(env,"java/lang/String"),NULL);
			i=0;
			for(j=0;j<c;j++){
				(*env)->SetObjectArrayElement(env,devices,j,(*env)->NewStringUTF(env,(char *)(dev9x+i)));
				while(dev9x[i]!=0) i++;
				i++;
			}
		}
	}
	
	return devices;
#endif
}

/**
Get Interface Description (for Windows)
**/
JNIEXPORT jobjectArray JNICALL
Java_jpcap_Jpcap_getDeviceDescription(JNIEnv *env,jobject obj)
{
#ifdef WIN32
	wchar_t *dev;
	char *dscr;
	int i=0,c=0,j=0;
	jobjectArray devices=NULL;

	if(dev=(wchar_t *)pcap_lookupdev(pcap_errbuf)){
		if(dev[0]<256) { /*NT/2000*/
			if(dev[0]==0 && dev[1]==0) return NULL; /* no device */
			while(!(dev[i]==0 && dev[i-1]==0)){
				if(dev[i]==0) c++;
				i++;
			}
			devices=(*env)->NewObjectArray(env,(jsize)c,(*env)->FindClass(env,"java/lang/String"),NULL);
			i++;
			dscr=(char *)dev+(i<<1);
			for(j=0;j<c;j++){
				(*env)->SetObjectArrayElement(env,devices,j,(*env)->NewStringUTF(env,dscr));
				while(*dscr++!=0);
			}
		}else{ /*9x*/
			char *dev9x=(char *)dev;
			
			if(dev9x[0]==0 && dev9x[1]==0) return NULL; /* no device */
			while(!(*dev9x==0 && *(dev9x-1)==0)){
				if(*dev9x==0) c++;
				dev9x++;
			}
			devices=(*env)->NewObjectArray(env,(jsize)c,(*env)->FindClass(env,"java/lang/String"),NULL);
			dev9x++;
			for(j=0;j<c;j++){
				(*env)->SetObjectArrayElement(env,devices,j,(*env)->NewStringUTF(env,dev9x));
				while(*dev9x++!=0);
			}
		}
	}
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -