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

📄 jpcap.c

📁 JAVA 抓包系统~~~提取数据包分析。分离出TCP UDP ARP 等包
💻 C
📖 第 1 页 / 共 2 页
字号:
  jint id=getJpcapID(env,obj);

  jni_envs[id]=env;
  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;
}


/*
 * Class:     jpcap_JpcapCaptor
 * Method:    setNonBlockingMode
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL Java_jpcap_JpcapCaptor_setNonBlockingMode
(JNIEnv *env, jobject obj, jboolean non_blocking){
	jint id=getJpcapID(env,obj);
	pcap_setnonblock(pcds[id],non_blocking,pcap_errbuf[id]);
}

/*
 * Class:     jpcap_JpcapCaptor
 * Method:    isNonBlockinMode
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_jpcap_JpcapCaptor_isNonBlockinMode
(JNIEnv *env, jobject obj){
	jint id=getJpcapID(env,obj);
	int nonblocking=pcap_getnonblock(pcds[id],pcap_errbuf[id]);
	return (nonblocking!=0?JNI_TRUE:JNI_FALSE);
}


/**
Set Filter
**/
JNIEXPORT void JNICALL
Java_jpcap_JpcapCaptor_setFilter(JNIEnv *env,jobject obj,jstring condition,
			   jboolean opt)
{
  char *cdt=(char *)GetStringChars(condition);
  struct bpf_program program;
  int id=getJpcapID(env,obj);
  char *err=NULL;

  if(pcap_compile(pcds[id],&program,cdt,(opt==JNI_TRUE?-1:0),netmasks[id])!=0){
    err = pcap_geterr(pcds[id]);
    if (err == NULL)
      err = "pcap_compile failed";
  } else if(pcap_setfilter(pcds[id],&program)!=0){
    err = pcap_geterr(pcds[id]);
    if (err == NULL)
      err = "pcap_setfilter failed";
  }

  ReleaseStringChars(condition,cdt);


  if (err != NULL) {
    char buf[2048];
    strcpy(buf, "Error occurred while compiling or setting filter: ");
    strncat(buf, err, 2047-strlen(buf));
    buf[2047] = 0;
    Throw(IOException, buf);
  }
}


/**
Break loop
**/
JNIEXPORT void JNICALL Java_jpcap_JpcapCaptor_breakLoop
(JNIEnv *env, jobject obj)
{
  int id=getJpcapID(env,obj);

  pcap_breakloop(pcds[id]);
}


/**
Update Statistics
**/
JNIEXPORT void JNICALL
Java_jpcap_JpcapCaptor_updateStat(JNIEnv *env,jobject obj)
{
  struct pcap_stat stat;
  jfieldID fid;
  int id=getJpcapID(env,obj);

  pcap_stats(pcds[id],&stat);

  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_JpcapCaptor_getErrorMessage(JNIEnv *env,jobject obj)
{
  int id=getJpcapID(env,obj);
  return NewString(pcap_errbuf[id]);
}

/**
Set Packet Read Timeout (UNIX only)
**/
JNIEXPORT jboolean JNICALL Java_jpcap_JpcapCaptor_setPacketReadTimeout
(JNIEnv *env, jobject obj, jint millis)
{
    jboolean success = JNI_FALSE;

#ifndef WIN32
    jint id = getJpcapID(env, obj);
    int fd = pcap_fileno(pcds[id]);
    int s;
    struct timeval tv;

    tv.tv_usec = (millis % 1000) * 1000;
    tv.tv_sec = millis / 1000;
    s = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval));
    success = (s==0?JNI_TRUE:JNI_FALSE);
#endif

    return success;
}

/**
Get Packet Read Timeout (UNIX only)
**/
JNIEXPORT jint JNICALL Java_jpcap_JpcapCaptor_getPacketReadTimeout
(JNIEnv *env, jobject obj)
{
    jint rval = -1;

#ifndef WIN32
    jint id = getJpcapID(env, obj);
    int fd = pcap_fileno(pcds[id]);
    int s;
    struct timeval tv;
    socklen_t len = sizeof(struct timeval);

    s = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &len);

    if (s == 0 && len == sizeof(struct timeval))
    {
        rval = (tv.tv_usec / 1000) + (tv.tv_sec * 1000);
    }
#endif

    return rval;
}

void dispatcher_handler(u_char *id,const struct pcap_pkthdr *header,
			const u_char *data)
{
  jobject packet;
  int ID=(int)id;

  JNIEnv *env=jni_envs[ID];

//  printf("enter:%d\n",ID);
  get_packet(*header,(u_char *)data,&packet,ID);
//  printf("got packet:%d\n",ID);
  (*env)->CallVoidMethod(env,jpcap_handlers[ID],handleMID,packet);
  DeleteLocalRef(packet);

//  printf("leave:%d\n",ID);
  YIELD();
}

void get_packet(struct pcap_pkthdr header,u_char *data,jobject *packet,int id){

  u_short nproto,tproto;
  u_short clen=header.caplen,hlen;
  u_char *orig_data=data;

  JNIEnv *env=jni_envs[id];

  // Analyze network protocol
  // patch from Kenta
  switch(linktypes[id]){
  case DLT_RAW:
    // based on the hack for Raw IP
    nproto=ETHERTYPE_IP;
    clen-=datalink_hlen(id);
    break;
  case DLT_IEEE802:
  case DLT_EN10MB:
    nproto=get_network_type(data,id);
    clen-=datalink_hlen(id);
    break;
  default:
    // get_network_type() macro does NOT work for non-ether packets
    // and can cause crash
    nproto=UNKNOWN_PROTO;
    break;
  }

  //printf("detect:%d\n",nproto);
  if(clen>0){
    switch(nproto){
    case ETHERTYPE_IP:
      clen-=((struct ip *)skip_datalink_header(data,id))->ip_hl<<2;
      if(clen>0 &&
	 !(ntohs(((struct ip *)skip_datalink_header(data,id))->ip_off)&IP_OFFMASK))
	tproto=((struct ip *)skip_datalink_header(data,id))->ip_p;
      else
	tproto=ETHERTYPE_IP;
      break;
#ifdef INET6
    case ETHERTYPE_IPV6:
      clen-=40;
      if(clen>0){
	u_char *dp=skip_datalink_header(data,id);
	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;
    case UNKNOWN_PROTO: //patch from Kenta
      tproto = UNKNOWN_PROTO;
      break;
    default:
      tproto=get_network_type(data,id);
    }
  }

  /** Check for truncated packet */
  if((tproto==IPPROTO_TCP && clen<TCPHDRLEN) ||
     (tproto==IPPROTO_UDP && clen<UDPHDRLEN) ||
     (tproto==IPPROTO_ICMP && clen<ICMPHDRLEN)){
    tproto=-1;
  }

  //printf("create:%d\n",tproto);
  /** 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;
    }
  }
  (*env)->CallVoidMethod(env,*packet,setPacketValueMID,
			     (jlong)header.ts.tv_sec,(jlong)header.ts.tv_usec,
			     (jint)header.caplen,(jint)header.len);

  //printf("datalink:%d\n",linktypes[id]);
  /** Analyze Datalink**/
  {
	jobject dlpacket=analyze_datalink(env,data,linktypes[id]);
    (*env)->CallVoidMethod(env,*packet,setDatalinkPacketMID,dlpacket);
	DeleteLocalRef(dlpacket);
  }

  //printf("network:%d\n",nproto);
  /** Analyze Network**/
  if(nproto != UNKNOWN_PROTO)
	data=skip_datalink_header(data,id);
  switch(nproto){
  case ETHERTYPE_IP:
    clen=ntohs(((struct ip *)data)->ip_len);
    hlen=analyze_ip(env,*packet,data);
    break;
#ifdef INET6
  case ETHERTYPE_IPV6:
    clen=ntohs(((struct ip6_hdr *)data)->ip6_plen);
	clen+=40; 
    hlen=analyze_ipv6(env,*packet,data);break;
#endif
  case ETHERTYPE_ARP:
    clen=hlen=analyze_arp(env,*packet,data);break;
  case UNKNOWN_PROTO:
    clen=header.caplen;
    hlen=0;
    break;
  default:
    clen=header.caplen-datalink_hlen(id);
	hlen=0;
    break;
  }
  if(nproto != UNKNOWN_PROTO &&
     tproto != UNKNOWN_PROTO &&
     clen>header.caplen-datalink_hlen(id)) 
    clen=header.caplen-datalink_hlen(id);
  data+=hlen;
  clen-=hlen;

  //printf("transport:%d\n",tproto);
  /** Analyze Transport **/
  switch(tproto){
  case IPPROTO_TCP:
    hlen=analyze_tcp(env,*packet,data); break;
  case IPPROTO_UDP:
	hlen=UDPHDRLEN;
    analyze_udp(env,*packet,data); break;
  case IPPROTO_ICMP:
    // updated by Damien Daspit 5/14/01
    //hlen=clen;
    hlen=ICMPHDRLEN;
	analyze_icmp(env,*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;
  }
  }
  if(hlen>clen) //if the header is cut off
	  hlen=clen; //cut off hlen
  clen-=hlen;
  data+=hlen;
  hlen=(u_short)(data-orig_data);
  //printf("set data: clen=%d, hlen=%d,total=%d/%d\n",clen,hlen,header.len,header.caplen);
  {
    jbyteArray dataArray=(*env)->NewByteArray(env,hlen);
	(*env)->SetByteArrayRegion(env,dataArray,0,hlen,orig_data);
	(*env)->CallVoidMethod(env,*packet,setPacketHeaderMID,dataArray);
	DeleteLocalRef(dataArray);

	if(clen>=0){
		dataArray=(*env)->NewByteArray(env,(jsize)clen);
		(*env)->SetByteArrayRegion(env,dataArray,0,(jsize)clen,data);
		(*env)->CallVoidMethod(env,*packet,setPacketDataMID,dataArray);
		DeleteLocalRef(dataArray);
	}
  }
}

void set_Java_env(JNIEnv *env){
  if(Jpcap!=NULL) return;
  GlobalClassRef(Jpcap,"jpcap/JpcapCaptor");
  GlobalClassRef(JpcapHandler,"jpcap/PacketReceiver");
  GlobalClassRef(Packet,"jpcap/packet/Packet");
  GlobalClassRef(DatalinkPacket,"jpcap/packet/DatalinkPacket");
  GlobalClassRef(EthernetPacket,"jpcap/packet/EthernetPacket");
  GlobalClassRef(IPPacket,"jpcap/packet/IPPacket");
  GlobalClassRef(TCPPacket,"jpcap/packet/TCPPacket");
  GlobalClassRef(UDPPacket,"jpcap/packet/UDPPacket");
  GlobalClassRef(ICMPPacket,"jpcap/packet/ICMPPacket");
  GlobalClassRef(IPv6Option,"jpcap/packet/IPv6Option");
  GlobalClassRef(ARPPacket,"jpcap/packet/ARPPacket");
  GlobalClassRef(String,"java/lang/String");
  GlobalClassRef(Thread,"java/lang/Thread");
  GlobalClassRef(UnknownHostException,"java/net/UnknownHostException");
  GlobalClassRef(IOException,"java/io/IOException");

  if((*env)->ExceptionCheck(env)==JNI_TRUE){
	  (*env)->ExceptionDescribe(env);
	  return;
  }

  handleMID=(*env)->GetMethodID(env,JpcapHandler,"receivePacket",
				"(Ljpcap/packet/Packet;)V");
  setPacketValueMID=(*env)->GetMethodID(env,Packet,"setPacketValue",
					"(JJII)V");
  setDatalinkPacketMID=(*env)->GetMethodID(env,Packet,"setDatalinkPacket",
					   "(Ljpcap/packet/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");
  // updated by Damien Daspit 5/7/01
  setIPValueMID=(*env)->GetMethodID(env,IPPacket,"setIPv4Value",
		 "(BBZZZBZZZSSSSS[B[B)V");
  setIPv4OptionMID=(*env)->GetMethodID(env,IPPacket,"setOption","([B)V");
  // *******************************
  setIPv6ValueMID=(*env)->GetMethodID(env,IPPacket,"setIPv6Value",
				      "(BBISBS[B[B)V");
  addIPv6OptHdrMID=(*env)->GetMethodID(env,IPPacket,"addOptionHeader",
				       "(Ljpcap/packet/IPv6Option;)V");
  // updated by Damien Daspit 5/7/01
  setTCPValueMID=(*env)->GetMethodID(env,TCPPacket,"setValue","(IIJJZZZZZZZZIS)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","(SS)V");
  setICMPTimestampMID=(*env)->GetMethodID(env,ICMPPacket,"setTimestampValue",
					  "(III)V");
  setICMPRedirectIPMID=(*env)->GetMethodID(env,ICMPPacket,"setRedirectIP",
				       "([B)V");
  getICMPRedirectIPMID=(*env)->GetMethodID(env,ICMPPacket,"getRedirectIP",
				       "()[B");
  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");
  jpcapID=(*env)->GetFieldID(env,Jpcap,"ID","I");

  if((*env)->ExceptionCheck(env)==JNI_TRUE){
	  (*env)->ExceptionDescribe(env);
	  return;
  }
}

⌨️ 快捷键说明

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