📄 jpcap.c
字号:
#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 + -