📄 jpcap.c
字号:
return devices;
#else
return NULL;
#endif
}
/**
Process Packets
**/
JNIEXPORT jint JNICALL
Java_jpcap_Jpcap_processPacket(JNIEnv *env,jobject obj,
jint cnt,jobject handler)
{
jint pkt_cnt;
jni_env=env;
jpcap_handler=(*env)->NewGlobalRef(env,handler);
pkt_cnt=pcap_dispatch(pcd,cnt,dispatcher_handler,tmp_buffer);
(*env)->DeleteGlobalRef(env,jpcap_handler);
return pkt_cnt;
}
/**
Loop Packets
**/
JNIEXPORT jint JNICALL
Java_jpcap_Jpcap_loopPacket(JNIEnv *env,jobject obj,
jint cnt,jobject handler)
{
jint pkt_cnt;
jni_env=env;
jpcap_handler=(*env)->NewGlobalRef(env,handler);
pkt_cnt=pcap_loop(pcd,cnt,dispatcher_handler,tmp_buffer);
(*env)->DeleteGlobalRef(env,jpcap_handler);
return pkt_cnt;
}
/**
Get One Packet
**/
JNIEXPORT jobject JNICALL
Java_jpcap_Jpcap_getPacket(JNIEnv *env,jobject obj)
{
struct pcap_pkthdr header;
jobject packet;
u_char *data=(u_char *)pcap_next(pcd,&header);
jni_env=env;
get_packet(header,data,&packet);
return packet;
}
/**
Set Filter
**/
JNIEXPORT void JNICALL
Java_jpcap_Jpcap_setFilter(JNIEnv *env,jobject obj,jstring condition,
jboolean opt)
{
char *cdt=(char *)(*env)->GetStringUTFChars(env,condition,0);
struct bpf_program program;
if(pcap_compile(pcd,&program,cdt,(opt==JNI_TRUE?-1:0),netmask)!=0){
/**error**/
}
if(pcap_setfilter(pcd,&program)!=0){
/**error**/
}
(*env)->ReleaseStringUTFChars(env,condition,cdt);
}
/**
Update Statistics
**/
JNIEXPORT void JNICALL
Java_jpcap_Jpcap_updateStat(JNIEnv *env,jobject obj)
{
struct pcap_stat stat;
jclass Jpcap;
jfieldID fid;
pcap_stats(pcd,&stat);
Jpcap=(*env)->FindClass(env,"Jpcap");
fid=(*env)->GetFieldID(env,Jpcap,"received_packets","I");
(*env)->SetIntField(env,obj,fid,(jint)stat.ps_recv);
fid=(*env)->GetFieldID(env,Jpcap,"dropped_packets","I");
(*env)->SetIntField(env,obj,fid,(jint)stat.ps_drop);
}
/**
Get Error Message
**/
JNIEXPORT jstring JNICALL
Java_jpcap_Jpcap_getErrorMessage(JNIEnv *env,jobject obj)
{
return (*env)->NewStringUTF(env,pcap_errbuf);
}
void dispatcher_handler(u_char *tmp,const struct pcap_pkthdr *header,
const u_char *data)
{
jobject packet;
get_packet(*header,(u_char *)data,&packet);
(*jni_env)->CallVoidMethod(jni_env,jpcap_handler,handleMID,packet);
DeleteLocalRef(packet);
YIELD();
}
void get_packet(struct pcap_pkthdr header,u_char *data,jobject *packet){
u_short nproto,tproto;
u_short clen=header.caplen,hlen;
u_char *orig_data=data;
/**Analyze type of packet **/
nproto=get_network_type(data);
clen-=datalink_hlen;
if(clen>0){
switch(nproto){
case ETHERTYPE_IP:
clen-=((struct ip *)skip_datalink_header(data))->ip_hl<<2;
if(clen>0 &&
!(ntohs(((struct ip *)skip_datalink_header(data))->ip_off)&IP_OFFMASK))
tproto=((struct ip *)skip_datalink_header(data))->ip_p;
else
tproto=ETHERTYPE_IP;
break;
#ifdef INET6
case ETHERTYPE_IPV6:
clen-=40;
if(clen>0){
u_char *dp=skip_datalink_header(data);
struct ip6_ext *ip6_ext;
tproto=((struct ip6_hdr *)dp)->ip6_nxt;
while((tproto==IPPROTO_HOPOPTS || tproto==IPPROTO_DSTOPTS ||
tproto==IPPROTO_ROUTING || tproto==IPPROTO_AH ||
tproto==IPPROTO_FRAGMENT) && clen>0){
switch(tproto){
case IPPROTO_HOPOPTS: /* Hop-by-Hop option */
case IPPROTO_DSTOPTS: /* Destination option */
case IPPROTO_ROUTING: /* Routing option */
case IPPROTO_AH: /* AH option */
ip6_ext=(struct ip6_ext *)dp;
tproto=ip6_ext->ip6e_nxt;
dp+=ip6_ext->ip6e_len;
clen-=ip6_ext->ip6e_len;
break;
case IPPROTO_FRAGMENT: /* Fragment option */
ip6_ext=(struct ip6_ext *)dp;
tproto=ip6_ext->ip6e_nxt;
dp+=16;
clen-=16;
break;
}
if(tproto==IPPROTO_ESP || tproto==IPPROTO_NONE)
tproto=-1;
}
}
break;
#endif
case ETHERTYPE_ARP:
/** XXX - assume that ARP is for Ethernet<->IPv4 **/
clen-=28;
if(clen>0) tproto=ETHERTYPE_ARP;
break;
default:
tproto=get_network_type(data);
}
}
/** Check for truncated packet */
if((tproto==IPPROTO_TCP && clen<TCPHDRLEN) ||
(tproto==IPPROTO_UDP && clen<UDPHDRLEN) ||
(tproto==IPPROTO_ICMP && clen<ICMPHDRLEN)){
tproto=-1;
}
/** Create packet object **/
switch(tproto){
case IPPROTO_TCP:
*packet=AllocObject(TCPPacket);break;
case IPPROTO_UDP:
*packet=AllocObject(UDPPacket);break;
case IPPROTO_ICMP:
*packet=AllocObject(ICMPPacket);break;
default:
switch(nproto){
case ETHERTYPE_IP:
*packet=AllocObject(IPPacket);break;
#ifdef INET6
case ETHERTYPE_IPV6:
*packet=AllocObject(IPPacket);break;
#endif
case ETHERTYPE_ARP:
case ETHERTYPE_REVARP:
*packet=AllocObject(ARPPacket);break;
default:
*packet=AllocObject(Packet);break;
}
}
(*jni_env)->CallVoidMethod(jni_env,*packet,setPacketValueMID,
(jlong)header.ts.tv_sec,(jlong)header.ts.tv_usec,
(jint)header.caplen,(jint)header.len);
/** Analyze Datalink**/
{
jobject dlpacket=analyze_datalink(data);
(*jni_env)->CallVoidMethod(jni_env,*packet,setDatalinkPacketMID,dlpacket);
}
/** Analyze Network**/
data=skip_datalink_header(data);
switch(nproto){
case ETHERTYPE_IP:
clen=ntohs(((struct ip *)data)->ip_len);
hlen=analyze_ip(*packet,data);
break;
#ifdef INET6
case ETHERTYPE_IPV6:
clen=ntohs(((struct ip6_hdr *)data)->ip6_plen);
hlen=analyze_ipv6(*packet,data);break;
#endif
case ETHERTYPE_ARP:
clen=hlen=analyze_arp(*packet,data);break;
default:
clen=header.caplen-datalink_hlen;
hlen=0;
break;
}
if(hlen>header.caplen-datalink_hlen) hlen=header.caplen-datalink_hlen;
data+=hlen;
clen-=hlen;
/** Analyze Transport **/
switch(tproto){
case IPPROTO_TCP:
hlen=analyze_tcp(*packet,data); break;
case IPPROTO_UDP:
hlen=UDPHDRLEN;
analyze_udp(*packet,data); break;
case IPPROTO_ICMP:
hlen=clen;
analyze_icmp(*packet,data,clen);break;
default:
{
/*jbyteArray dataArray=(*jni_env)->NewByteArray(jni_env,clen);
(*jni_env)->SetByteArrayRegion(jni_env,dataArray,0,clen,data);
(*jni_env)->CallVoidMethod(jni_env,*packet,setPacketDataMID,dataArray);*/
hlen=0;
break;
}
}
clen-=hlen;
data+=hlen;
hlen=data-orig_data;
{
jbyteArray dataArray=(*jni_env)->NewByteArray(jni_env,hlen);
(*jni_env)->SetByteArrayRegion(jni_env,dataArray,0,hlen,orig_data);
(*jni_env)->CallVoidMethod(jni_env,*packet,setPacketHeaderMID,dataArray);
DeleteLocalRef(dataArray);
if(clen>0){
dataArray=(*jni_env)->NewByteArray(jni_env,clen);
(*jni_env)->SetByteArrayRegion(jni_env,dataArray,0,clen,data);
(*jni_env)->CallVoidMethod(jni_env,*packet,setPacketDataMID,dataArray);
DeleteLocalRef(dataArray);
}else{
(*jni_env)->CallVoidMethod(jni_env,*packet,setPacketDataMID,
(*jni_env)->NewByteArray(jni_env,0));
}
}
}
void set_info(JNIEnv *env,jobject obj){
struct pcap_info *info=(struct pcap_info *)pcd;
jmethodID mid=(*env)->GetMethodID(env,
(*env)->FindClass(env,"jpcap/Jpcap"),
"setInfo","(III)V");
(*env)->CallVoidMethod(env,obj,mid,info->linktype,info->tzoff,info->snapshot);
}
void set_Java_env(JNIEnv *env){
if(linktype!=-1) //already done
return;
linktype=pcap_datalink(pcd);
GlobalClassRef(JpcapHandler,"jpcap/JpcapHandler");
GlobalClassRef(Packet,"jpcap/Packet");
GlobalClassRef(DatalinkPacket,"jpcap/DatalinkPacket");
GlobalClassRef(EthernetPacket,"jpcap/EthernetPacket");
GlobalClassRef(IPPacket,"jpcap/IPPacket");
GlobalClassRef(TCPPacket,"jpcap/TCPPacket");
GlobalClassRef(UDPPacket,"jpcap/UDPPacket");
GlobalClassRef(ICMPPacket,"jpcap/ICMPPacket");
GlobalClassRef(IPv6Option,"jpcap/IPv6Option");
GlobalClassRef(ARPPacket,"jpcap/ARPPacket");
GlobalClassRef(String,"java/lang/String");
GlobalClassRef(Thread,"java/lang/Thread");
GlobalClassRef(UnknownHostException,"java/net/UnknownHostException");
GlobalClassRef(IOException,"java/io/IOException");
handleMID=(*env)->GetMethodID(env,JpcapHandler,"handlePacket",
"(Ljpcap/Packet;)V");
setPacketValueMID=(*env)->GetMethodID(env,Packet,"setPacketValue",
"(JJII)V");
setDatalinkPacketMID=(*env)->GetMethodID(env,Packet,"setDatalinkPacket",
"(Ljpcap/DatalinkPacket;)V");
setPacketHeaderMID=(*env)->GetMethodID(env,Packet,"setPacketHeader","([B)V");
setPacketDataMID=(*env)->GetMethodID(env,Packet,"setPacketData",
"([B)V");
setEthernetValueMID=(*env)->GetMethodID(env,EthernetPacket,"setValue",
"([B[BS)V");
setIPValueMID=(*env)->GetMethodID(env,IPPacket,"setIPv4Value",
"(BBZZZZZZSSSSS[B[B)V");
setIPv6ValueMID=(*env)->GetMethodID(env,IPPacket,"setIPv6Value",
"(BBISBS[B[B)V");
addIPv6OptHdrMID=(*env)->GetMethodID(env,IPPacket,"addOptionHeader",
"(Ljpcap/IPv6Option;)V");
setTCPValueMID=(*env)->GetMethodID(env,TCPPacket,"setValue","(IIJJZZZZZZIS)V");
setTCPOptionMID=(*env)->GetMethodID(env,TCPPacket,"setOption","([B)V");
setUDPValueMID=(*env)->GetMethodID(env,UDPPacket,"setValue","(III)V");
setICMPValueMID=(*env)->GetMethodID(env,ICMPPacket,"setValue","(BBSSS)V");
setICMPIDMID=(*env)->GetMethodID(env,ICMPPacket,"setID","(II)V");
setICMPTimestampMID=(*env)->GetMethodID(env,ICMPPacket,"setTimestampValue",
"(JJJ)V");
setICMPRedirectIPMID=(*env)->GetMethodID(env,ICMPPacket,"setRedirectIP",
"([B)V");
setICMPRouterAdMID=(*env)->GetMethodID(env,ICMPPacket,"setRouterAdValue",
"(BBS[Ljava/lang/String;[I)V");
setV6OptValueMID=(*env)->GetMethodID(env,IPv6Option,"setValue",
"(BBB)V");
setV6OptOptionMID=(*env)->GetMethodID(env,IPv6Option,"setOptionData",
"([B)V");
setV6OptRoutingMID=(*env)->GetMethodID(env,IPv6Option,"setRoutingOption",
"(BB[Ljava/lang/String;)V");
setV6OptFragmentMID=(*env)->GetMethodID(env,IPv6Option,"setFragmentOption",
"(SZI)V");
setV6OptAHMID=(*env)->GetMethodID(env,IPv6Option,"setAHOption",
"(II)V");
getSourceAddressMID=(*env)->GetMethodID(env,IPPacket,"getSourceAddress",
"()[B");
getDestinationAddressMID=(*env)->GetMethodID(env,IPPacket,
"getDestinationAddress",
"()[B");
setARPValueMID=(*env)->GetMethodID(env,ARPPacket,"setValue",
"(SSSSS[B[B[B[B)V");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -