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

📄 jpcapsender.c

📁 JAVA 抓包系统~~~提取数据包分析。分离出TCP UDP ARP 等包
💻 C
字号:
#include<jni.h>
#include<pcap.h>

//#define DEBUG
//#define BSD_BUG

#include<sys/types.h>
#ifndef WIN32
#include<sys/param.h>
#include<sys/socket.h>
#define __FAVOR_BSD
#include<netinet/in.h>
#include<netdb.h>
#else
#include<winsock2.h>
#include<ws2tcpip.h>
//#include<packet32.h>
#endif
#include<netinet/in_systm.h>
#include<netinet/ip.h>
#include<netinet/tcp.h>
#include<netinet/udp.h>
#include<netinet/ip_icmp.h>

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

#ifdef WIN32
//LPADAPTER adapters[MAX_NUMBER_OF_INSTANCE];
SOCKET sockRaw=INVALID_SOCKET;
#else
int soc_num=-1;
#endif

unsigned short in_cksum(unsigned short *addr,int len);
int set_packet(JNIEnv *env, jobject packet,char *pointer,int include_datalink);

int set_ether(JNIEnv *env,jobject packet,char *pointer);
void set_ip(JNIEnv *env,jobject packet,char *pointer);
void set_tcp(JNIEnv *env,jobject packet,char *pointer,jbyteArray data,struct ip *ip);
void set_udp(JNIEnv *env,jobject packet,char *pointer,jbyteArray data,struct ip *ip);
int set_icmp(JNIEnv *env,jobject packet,char *pointer,jbyteArray data);
int set_arp(JNIEnv *env,jobject packet,u_char *pointer);

jclass JpcapSender=NULL;

int getJpcapSenderID(JNIEnv *env, jobject obj){
  if(JpcapSender==NULL)
    GlobalClassRef(JpcapSender,"jpcap/JpcapSender");
  return GetIntField(JpcapSender,obj,"ID");
}


/*
 * Class:     jpcap_JpcapSender
 * Method:    nativeOpenDevice
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT jstring JNICALL Java_jpcap_JpcapSender_nativeOpenDevice
(JNIEnv *env, jobject obj, jstring device){
	char *dev;
	jint id;
	
	set_Java_env(env);
	
	id=getJpcapSenderID(env,obj);


	jni_envs[id]=env;

	if(pcds[id]!=NULL){
		return NewString("Another Jpcap instance is being used.");
	}
	if(device==NULL){
		return NewString("Please specify device name.");
	}
	dev=(char *)GetStringChars(device);

	pcds[id]=pcap_open_live(dev,65535,0,1000,pcap_errbuf[id]);

	ReleaseStringChars(device,dev);

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

	return NULL;
}


/**
Open raw socket for sending IP packet
**/
JNIEXPORT void JNICALL
Java_jpcap_JpcapSender_nativeOpenRawSocket(JNIEnv *env,jobject obj){
  int on=1;
#ifdef WIN32
  WSADATA wsaData;
#endif

  set_Java_env(env);

#ifdef WIN32
  if(sockRaw!=INVALID_SOCKET){
#else
  if(soc_num>=0){
#endif
	  Throw(IOException,"Raw Socket is already opened.");
    return;
  }

#ifdef WIN32
  // Start Winsock up
  if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0) {
      Throw(IOException,"Failed to find Winsock 2.1 or better.");
      return;
  }

  sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, 0);
  if (sockRaw == INVALID_SOCKET) {
//	  printf("%d\n",WSAGetLastError());
      Throw(IOException,"Failed to create raw socket.");
      return;
  }
  setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on));
#else
  if((soc_num=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0){
    Throw(IOException,"can't initialize socket");
    return;
  }
  setsockopt(soc_num,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on));
#endif

//#endif
}




/**
Send packet via pcap
**/
JNIEXPORT void JNICALL
Java_jpcap_JpcapSender_nativeSendPacket(JNIEnv *env,jobject obj,jobject packet){
  char buf[MAX_PACKET_SIZE];
  int length;
  int id=getJpcapSenderID(env,obj);

  if(pcds[id]==NULL){
	Throw(IOException,"Another JpcapSender instance is being used.");
	return;
  }

#ifdef DEBUG
  puts("set packet.");
#endif
  length=set_packet(env,packet,buf,-1);
  if(length<60){ //include Ethernet trailer
	  memset(buf+length,0,60-length+1);
	  length=60;
  }

#ifdef DEBUG
  puts("send packet.");
#endif
  if(pcap_sendpacket(pcds[id],buf,length)<0){
		Throw(IOException,pcap_errbuf[id]);
    return;
  }
}

/**
Send IP Packet via Raw socket
**/
JNIEXPORT void JNICALL
Java_jpcap_JpcapSender_nativeSendPacketViaRawSocket(JNIEnv *env,jobject obj,jobject packet)
{
  char buf[MAX_PACKET_SIZE];
  struct ip *ip=(struct ip *)buf;
  int length;
  struct sockaddr_in dest;

  if(!IsInstanceOf(packet,IPPacket)){
    Throw(IOException,"not IPPacket object");
    return;
  }
#ifdef WIN32
  if(sockRaw==INVALID_SOCKET){
    Throw(IOException,"socket not initialized yet");
    return;
  }
#else
  if(soc_num<0){
    Throw(IOException,"socket not initialized yet");
    return;
  }
#endif
  length=set_packet(env,packet,buf,0);

  //set destination address
  memset((char *)&dest,0,sizeof(dest));
  dest.sin_family=AF_INET;
  //bug fix by Peter Martin
  dest.sin_addr=ip->ip_dst;

#ifdef WIN32
	if(sendto(sockRaw,buf,length,0,(struct sockaddr *)&dest,sizeof(dest))<0){
#else
	if(sendto(soc_num,buf,length,0,(struct sockaddr *)&dest,sizeof(dest))<0){
#endif
		Throw(IOException,"sendto error");
    return;
  }
}

int set_packet(JNIEnv *env, jobject packet,char *pointer,int include_datalink){
  int length=0,dthlen=0;
  jbyteArray data;

  if(include_datalink){
#ifdef DEBUG
	  puts("set datalink");
#endif
	dthlen=set_ether(env,packet,pointer);
    pointer+=dthlen;
  }

#ifdef DEBUG
	  puts("get packet data");
#endif
  data=GetObjectField(Packet,packet,"[B","data");
  if(data==NULL){
	length=0;
  }else{
	length=(*env)->GetArrayLength(env,data);
  }

  if(IsInstanceOf(packet,IPPacket)){
	struct ip *ip=(struct ip *)pointer;
#ifdef DEBUG
	  puts("set ip");
#endif
	if(GetByteField(IPPacket,packet,"version")!=4){
		Throw(IOException,"only IPv4 packet is supported");
		return 0;
	}
	set_ip(env,packet,pointer);
	length+=IPv4HDRLEN;
	pointer+=IPv4HDRLEN;

	if(IsInstanceOf(packet,TCPPacket)){
#ifdef DEBUG
	  puts("set tcp");
#endif
		length+=TCPHDRLEN;
		ip->ip_p=IPPROTO_TCP;
		ip->ip_len=length;

		set_tcp(env,packet,pointer,data,ip);
	  }else if(IsInstanceOf(packet,UDPPacket)){
#ifdef DEBUG
	  puts("set udp");
#endif
		length+=UDPHDRLEN;
		ip->ip_p=IPPROTO_UDP;
		ip->ip_len=length;

		set_udp(env,packet,pointer,data,ip);
	  }else if(IsInstanceOf(packet,ICMPPacket)){
#ifdef DEBUG
	  puts("set icmp");
#endif
		length+=set_icmp(env,packet,pointer,data);
		ip->ip_p=IPPROTO_ICMP;
		ip->ip_len=length;
	  }else{
#ifdef DEBUG
	  puts("set other type of ip");
#endif
		ip->ip_p=(unsigned char)GetShortField(IPPacket,packet,"protocol");
		ip->ip_len=length;
		//bug fix by Brad Dillmn
		(*env)->GetByteArrayRegion(env,data,0,
					   length-IPv4HDRLEN,pointer);
	  }

#ifndef BSD_BUG
      ip->ip_len=htons(ip->ip_len);
      ip->ip_off=htons(ip->ip_off);
#endif

	  ip->ip_sum=0;
	  ip->ip_sum=in_cksum((u_short *)ip,20);

  }else if(IsInstanceOf(packet,ARPPacket)){
#ifdef DEBUG
	  puts("set arp");
#endif
	length+=set_arp(env,packet,pointer);
  }else{ //unknown type
		(*env)->GetByteArrayRegion(env,data,0,
					   length,pointer);
  }

  return length+dthlen;
}

unsigned short in_cksum(unsigned short *data,int size){
        unsigned long sum = 0;

        while(size > 1){
                sum += *(data++);
                size -= 2;
        }

        if(size > 0) sum += (*data) & 0xff00;
        sum = (sum & 0xffff) + (sum >> 16);

        return ((~(unsigned short)((sum >> 16) + (sum & 0xffff))));
}

unsigned short in_cksum2(struct ip *ip,u_short len,unsigned short *data,int size){
        unsigned long sum = 0;
		u_short *p=(u_short *)&ip->ip_src;

		/*sum+=ip->ip_src.S_un.S_un_w.s_w1;
		sum+=ip->ip_src.S_un.S_un_w.s_w2;
		sum+=ip->ip_dst.S_un.S_un_w.s_w1;
		sum+=ip->ip_dst.S_un.S_un_w.s_w2;*/
		sum+=*(p++);
		sum+=*(p++);
		sum+=*(p++);
		sum+=*(p++);
		sum+=htons((u_short)(ip->ip_p&0x00ff));
		sum+=len;

        while(size > 1){
                sum += *(data++);
                size -= 2;
        }

		if(size > 0){
			sum += *(unsigned char *)data;
		}
        sum = (sum & 0xffff) + (sum >> 16);

        return ((~(unsigned short)((sum >> 16) + (sum & 0xffff))));
}



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

JNIEXPORT void JNICALL
Java_jpcap_JpcapSender_nativeCloseRawSocket(JNIEnv *env,jobject obj)
{
#ifdef WIN32
//  int id=getJpcapSenderID(env,obj);
//  PacketCloseAdapter(adapters[id]);
	closesocket(sockRaw);
  WSACleanup();
#else
  //bug fix by Peter Martin
  close(soc_num);
#endif
}

⌨️ 快捷键说明

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