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

📄 jpcap.c

📁 JAVA 抓包系统~~~提取数据包分析。分离出TCP UDP ARP 等包
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef WIN32
#include<winsock2.h>
#include<iphlpapi.h>
#endif /* for WIN32 */

#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
#endif

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

#ifdef INET6
#ifndef WIN32
#define COMPAT_RFC2292
#include<netinet/ip6.h>
#include<netinet6/ah.h>
#else
typedef unsigned char  u_int8_t;
typedef unsigned short u_int16_t;
typedef unsigned int   u_int32_t;
typedef int            pid_t;
#define IPPROTO_HOPOPTS        0 /* IPv6 Hop-by-Hop options */
#define IPPROTO_IPV6          41 /* IPv6 header */
#define IPPROTO_ROUTING       43 /* IPv6 Routing header */
#define IPPROTO_FRAGMENT      44 /* IPv6 fragmentation header */
#define IPPROTO_ESP           50 /* encapsulating security payload */
#define IPPROTO_AH            51 /* authentication header */
#define IPPROTO_ICMPV6        58 /* ICMPv6 */
#define IPPROTO_NONE          59 /* IPv6 no next header */
#define IPPROTO_DSTOPTS       60 /* IPv6 Destination options */
#include<ws2tcpip.h>
#include<tpipv6.h>
#include<netinet/ip6.h>
#include<netinet6/ah.h>
#endif
#endif

#include"jpcap_JpcapCaptor.h"

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


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,id) ntohs(*(u_short *)(data+offset_type[linktypes[id]]))

#define skip_datalink_header(data,id)  (data+offset_data[linktypes[id]])

#define datalink_hlen(id) offset_data[linktypes[id]]

#define UNKNOWN_PROTO 0xffff

pcap_t *pcds[MAX_NUMBER_OF_INSTANCE];
JNIEnv *jni_envs[MAX_NUMBER_OF_INSTANCE];
char pcap_errbuf[PCAP_ERRBUF_SIZE][MAX_NUMBER_OF_INSTANCE];

jclass Jpcap=NULL,JpcapHandler,Interface,IAddress,Packet,DatalinkPacket,EthernetPacket,IPPacket,TCPPacket,UDPPacket,ICMPPacket,IPv6Option,ARPPacket,String,Thread,UnknownHostException,IOException;
jmethodID deviceConstMID,addressConstMID,handleMID,setPacketValueMID,setDatalinkPacketMID,
  setPacketHeaderMID,setPacketDataMID,
  setEthernetValueMID,setIPValueMID,setIPv4OptionMID,setIPv6ValueMID,addIPv6OptHdrMID,
  setTCPValueMID,setTCPOptionMID,setUDPValueMID,
  setICMPValueMID,setICMPIDMID,setICMPTimestampMID,setICMPRedirectIPMID,getICMPRedirectIPMID,
  setICMPRouterAdMID,setV6OptValueMID,setV6OptOptionMID,setV6OptFragmentMID,
  setV6OptRoutingMID,setV6OptAHMID,
  setARPValueMID,
  getSourceAddressMID,getDestinationAddressMID;
jfieldID jpcapID;

int linktypes[MAX_NUMBER_OF_INSTANCE];
bpf_u_int32 netnums[MAX_NUMBER_OF_INSTANCE],netmasks[MAX_NUMBER_OF_INSTANCE];
jobject jpcap_handlers[MAX_NUMBER_OF_INSTANCE];
char pcap_errbuf[PCAP_ERRBUF_SIZE][MAX_NUMBER_OF_INSTANCE];

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

struct ip_packet *getIP(char *payload);

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


int getJpcapID(JNIEnv *env,jobject obj)
{
	return GetIntField(Jpcap,obj,"ID");
}

jbyteArray getAddressByteArray(JNIEnv *env,struct sockaddr *addr)
{
	jbyteArray array;
	if(addr==NULL) return NULL;

	switch(addr->sa_family){
		case AF_INET:
			array=(*env)->NewByteArray(env,4);
			(*env)->SetByteArrayRegion(env,array,0,4,(jbyte *)&((struct sockaddr_in *)addr)->sin_addr);
			break;
		case AF_INET6:
			array=(*env)->NewByteArray(env,16);
			(*env)->SetByteArrayRegion(env,array,0,16,(jbyte *)&((struct sockaddr_in6 *)addr)->sin6_addr);
			break;
		default:
			//printf("AF:%d\n",addr->sa_family);
			return NULL;
			break;
	}
	return array;
}

/**
Get Interface List
**/
JNIEXPORT jobjectArray JNICALL Java_jpcap_JpcapCaptor_getDeviceList
  (JNIEnv *env, jclass cl)
{
	pcap_if_t *alldevs;
	pcap_if_t *d;
	pcap_addr_t *a;
	pcap_t *tmp_pcap;
	char errbuf[PCAP_ERRBUF_SIZE];
	int i=0,j=0,k=0;
	jobjectArray devices=NULL;
	jobjectArray addresses=NULL;
	jobject device=NULL;
	jobject address=NULL;
	int linktype;
	jstring lname,ldesc;
#ifdef WIN32
    u_long size=0;
	PIP_INTERFACE_INFO pInfo = NULL;
	MIB_IFROW MibIfRow;
	char **devnames;
	char *p1,*p2,*p3;
#else
    int sd;
    struct ifreq ifr;
	u_char buf[6];
#endif

	Interface=FindClass("jpcap/NetworkInterface");
	deviceConstMID=(*env)->GetMethodID(env,Interface,"<init>","(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;[B[Ljpcap/NetworkInterfaceAddress;)V");
	IAddress=FindClass("jpcap/NetworkInterfaceAddress");
	addressConstMID=(*env)->GetMethodID(env,IAddress,"<init>","([B[B[B[B)V");

	(*env)->ExceptionDescribe(env);

	/* Retrieve the device list */
    if (pcap_findalldevs(&alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        return NULL;
    }

	//count # of devices
	for(i=0,d=alldevs;d;d=d->next,i++);

	//create array
	devices=(*env)->NewObjectArray(env,(jsize)i,Interface,NULL);

#ifdef WIN32
	//obtain necessary size
	GetInterfaceInfo(NULL, &size);
	//allocate memory
	pInfo = (PIP_INTERFACE_INFO) malloc (size);
	if(GetInterfaceInfo(pInfo, &size)!=NO_ERROR){
		Throw(IOException,"GetInterfaceInfo failed.");
		return NULL;
	}
#endif

	/* Set Interface data */
    for(i=0,d=alldevs;d;d=d->next)
    {
		jbyteArray mac=(*env)->NewByteArray(env,6);
		//set mac
#ifdef WIN32
		// compare the device names obtained from Pcap and from IP Helper
		// in order to identify MAC address
		// since device name differs in 9x and NT/XP, compare name
		// from the end (not sure if this works in every case. I hope it does..)
		p1=d->name;
		while(*p1!=0) p1++;  //find the end

		//convert wchar to char
		devnames=(char **)malloc(sizeof(char *)*pInfo->NumAdapters);
		for(j=0;j<pInfo->NumAdapters;j++){
			size=WideCharToMultiByte(0,0,pInfo->Adapter[j].Name,-1,NULL,0,NULL,NULL);
			devnames[j]=(char *)malloc(size);
			WideCharToMultiByte(0,0,pInfo->Adapter[j].Name,-1,devnames[j],size,NULL,NULL);
			//printf("%s\n",devnames[j]);
		}

		for(j=0;j<pInfo->NumAdapters;j++){
			p2=p1;
			p3=devnames[j];
			while(*p3!=0) p3++; //find the end
			k=0;
			//printf("%s,%s:%d\n",d->name,devnames[j],j);
			while(*p2==*p3){
				p2--; p3--; k++;
				//printf("%c,%c,%d\n",*p2,*p3,k);
			}
			if(k<30) continue;

			//found! set MAC address
			MibIfRow.dwIndex=pInfo->Adapter[j].Index;
			GetIfEntry(&MibIfRow);
			(*env)->SetByteArrayRegion(env,mac,0,MibIfRow.dwPhysAddrLen,MibIfRow.bPhysAddr);
		}

#else
    /* make socket */
    sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sd < 0) {
		Throw(IOException,"cannot open socket.");
        return NULL; // error: can't create socket.
    }

    /* set interface name (lo, eth0, eth1,..) */
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_ifrn.ifrn_name,d->name, IFNAMSIZ);

    /* get a Get Interface Hardware Address */
    ioctl(sd, SIOCGIFHWADDR, &ifr);

    close(sd);

	(*env)->SetByteArrayRegion(env,mac,0,6,ifr.ifr_ifru.ifru_hwaddr.sa_data);
#endif

		//count # of addresses
		for(j=0,a=d->addresses;a;a=a->next)
			if(getAddressByteArray(env,a->addr)) j++;

		//create array of addresses
		addresses=(*env)->NewObjectArray(env,(jsize)j,IAddress,NULL);

		//set address data
		for(j=0,a=d->addresses;a;a=a->next)
		{
			jbyteArray addr=getAddressByteArray(env,a->addr);
			if(addr){
				address=(*env)->NewObject(env,IAddress,addressConstMID,
					addr,getAddressByteArray(env,a->netmask),
					getAddressByteArray(env,a->broadaddr),getAddressByteArray(env,a->dstaddr));
				(*env)->SetObjectArrayElement(env,addresses,j++,address);
			}
		}

		//get datalink name
		tmp_pcap=pcap_open_live(d->name,0,0,1000,errbuf);
		if(tmp_pcap!=NULL){
			linktype=pcap_datalink(tmp_pcap);
			lname=NewString(pcap_datalink_val_to_name(linktype));
			ldesc=NewString(pcap_datalink_val_to_description(linktype));
			pcap_close(tmp_pcap);
		}else{
			lname=NewString("Unknown");
			ldesc=NewString("Unknown");
		}

		device=(*env)->NewObject(env,Interface,deviceConstMID,NewString(d->name),
			NewString(d->description),(d->flags&PCAP_IF_LOOPBACK?JNI_TRUE:JNI_FALSE),lname,ldesc,mac,addresses);
		(*env)->SetObjectArrayElement(env,devices,i++,device);

		DeleteLocalRef(device);
		DeleteLocalRef(mac);
    }
    
    /* We don't need any more the device list. Free it */
    pcap_freealldevs(alldevs);

	(*env)->ExceptionDescribe(env);

	return devices;
}

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

  set_Java_env(env);

  id=getJpcapID(env,obj);

  if(pcds[id]!=NULL){
	return NewString("Another Jpcap instance is being used.");
  }

  jni_envs[id]=env;

  if(device==NULL){
    return NewString("Please specify device name.");
  }
  dev=(char *)GetStringChars(device);

  pcds[id]=pcap_open_live(dev,snaplen,promisc,to_ms,pcap_errbuf[id]);
  if(pcap_lookupnet(dev,&netnums[id],&netmasks[id],pcap_errbuf[id])==-1){
	netmasks[id] = 0; 
  }

  ReleaseStringChars(device,dev);

  if(pcds[id]==NULL) return NewString(pcap_errbuf[id]);

  //set_info(env,obj,pcds[id]);
  linktypes[id]=pcap_datalink(pcds[id]);
  return NULL;
}

/**
Open Dumped File
**/
JNIEXPORT jstring JNICALL
Java_jpcap_JpcapCaptor_nativeOpenOffline(JNIEnv *env,jobject obj,jstring filename)
{
  char *file;
  jint id;
  
  set_Java_env(env);

  id=getJpcapID(env,obj);

  if(pcds[id]!=NULL){
	return NewString("Another Jpcap instance is being used.");
  }
  jni_envs[id]=env;

  file=(char *)GetStringChars(filename);

  pcds[id]=pcap_open_offline(file,pcap_errbuf[id]);

  ReleaseStringChars(filename,file);

  if(pcds[id]==NULL) return NewString(pcap_errbuf[id]);

  //set_info(env,obj,pcds[id]);
  linktypes[id]=pcap_datalink(pcds[id]);
  set_Java_env(env);
  return NULL;
}

/**
Close Live Capture Device
**/
JNIEXPORT void JNICALL
Java_jpcap_JpcapCaptor_nativeClose(JNIEnv *env,jobject obj)
{
  int id=getJpcapID(env,obj);
  if(pcds[id]!=NULL) pcap_close(pcds[id]);
  pcds[id]=NULL;
}


/**
Process Packets
**/
JNIEXPORT jint JNICALL
Java_jpcap_JpcapCaptor_processPacket(JNIEnv *env,jobject obj,
			       jint cnt,jobject handler)
{
  jint pkt_cnt;
  jint id=getJpcapID(env,obj);

  jni_envs[id]=env;
//  printf("%d\n",id);
  jpcap_handlers[id]=(*env)->NewGlobalRef(env,handler);

  pkt_cnt=pcap_dispatch(pcds[id],cnt,dispatcher_handler,(u_char *)id);

  (*env)->DeleteGlobalRef(env,jpcap_handlers[id]);
  return pkt_cnt;
}

/**
Loop Packets
**/
JNIEXPORT jint JNICALL
Java_jpcap_JpcapCaptor_loopPacket(JNIEnv *env,jobject obj,
			    jint cnt,jobject handler)
{
  jint pkt_cnt;
  jint id=getJpcapID(env,obj);

  jni_envs[id]=env;
  jpcap_handlers[id]=(*env)->NewGlobalRef(env,handler);

  pkt_cnt=pcap_loop(pcds[id],cnt,dispatcher_handler,(u_char *)id);

  (*env)->DeleteGlobalRef(env,jpcap_handlers[id]);
  return pkt_cnt;
}


/**
Get One Packet
**/
JNIEXPORT jobject JNICALL
Java_jpcap_JpcapCaptor_getPacket(JNIEnv *env,jobject obj)
{
  struct pcap_pkthdr header;
  jobject packet;
  int id=getJpcapID(env,obj);
  u_char *data=(u_char *)pcap_next(pcds[id],&header);

  jni_envs[id]=env;
  if(data==NULL) return NULL;
  get_packet(header,data,&packet,id);
  return packet;
}

/*
 * Class:     jpcap_JpcapCaptor
 * Method:    dispatchPacket
 * Signature: (ILjpcap/PacketReceiver;)I
 */
JNIEXPORT jint JNICALL Java_jpcap_JpcapCaptor_dispatchPacket
(JNIEnv *env,jobject obj, jint cnt,jobject handler)
{
  jint pkt_cnt;

⌨️ 快捷键说明

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