zoukankan      html  css  js  c++  java
  • 利 用jnetpcap 封装libpcap

    我是参照http://aswang.iteye.com/blog/1036305 编译出来的。但是我用的libpcap源码是android自带的源码,jnetpcap用的是1.2版本。利用javah时因为要一个一个生成,所以我写了一个比较笨拙的脚本,还好vim比较智能,呵呵,大大减少我写脚本的时间,对于vim还得继续学习。使用下面这个脚本的时候记得把#号去掉。在org一级执行。

    #javah path . -jni org.jnetpcap.ByteBufferHandler
    #javah path . -jni org.jnetpcap.JBufferHandler
    #javah path . -jni org.jnetpcap.JCaptureHeader
    #javah path . -jni org.jnetpcap.PcapAddr
    #javah path . -jni org.jnetpcap.PcapBpfProgram
    #javah path . -jni org.jnetpcap.Pcap
    #javah path . -jni org.jnetpcap.PcapClosedException
    #javah path . -jni org.jnetpcap.PcapDLT
    #javah path . -jni org.jnetpcap.PcapDumper
    #javah path . -jni org.jnetpcap.PcapExtensionNotAvailableException
    #javah path . -jni org.jnetpcap.PcapHandler
    #javah path . -jni org.jnetpcap.PcapHeader
    #javah path . -jni org.jnetpcap.PcapIf
    #javah path . -jni org.jnetpcap.PcapInteger
    #javah path . -jni org.jnetpcap.PcapPktBuffer
    #javah path . -jni org.jnetpcap.PcapPktHdr
    #javah path . -jni org.jnetpcap.PcapSockAddr
    #javah path . -jni org.jnetpcap.PcapStat
    ##javah path . -jni org.jnetpcap.PcapTasK
    #javah path . -jni org.jnetpcap.PcapUtils$1
    #javah path . -jni org.jnetpcap.PcapUtils$2
    #javah path . -jni org.jnetpcap.PcapUtils$3
    #javah path . -jni org.jnetpcap.PcapUtils$4
    #javah path . -jni org.jnetpcap.PcapUtils
    #javah -classpath . -jni org.jnetpcap.packet.JBinding
    #javah -classpath . -jni org.jnetpcap.packet.JBinding$DefaultJBinding
    #javah -classpath . -jni org.jnetpcap.packet.JDependency
    #javah -classpath . -jni org.jnetpcap.packet.JHeader$1
    #javah -classpath . -jni org.jnetpcap.packet.JHeader
    #javah -classpath . -jni org.jnetpcap.packet.JHeaderPool$1
    #javah -classpath . -jni org.jnetpcap.packet.JHeaderPool
    #javah -classpath . -jni org.jnetpcap.packet.JHeaderScanner
    #javah -classpath . -jni org.jnetpcap.packet.JHeader$State#javah -classpath . -jni org.jnetpcap.packet.JProtocol
    #javah -classpath . -jni org.jnetpcap.packet.JRegistry
    #javah -classpath . -jni org.jnetpcap.packet.JRegistry$Entry
    #javah -classpath . -jni org.jnetpcap.packet.JScan
    #javah -classpath . -jni org.jnetpcap.packet.JScanner$1
    #javah -classpath . -jni org.jnetpcap.packet.JScanner
    #javah -classpath . -jni org.jnetpcap.packet.PcapPacket
    #javah -classpath . -jni org.jnetpcap.packet.UnregisteredHeaderException
    #javah -classpath . -jni org.jnetpcap.packet.UnregisteredScannerException
    #javah -classpath . -jni org.jnetpcap.nio.JBuffer
    #javah -classpath . -jni org.jnetpcap.nio.JFunction
    #javah -classpath . -jni org.jnetpcap.nio.JMemory
    #javah -classpath . -jni org.jnetpcap.nio.JMemoryPool$Block
    #javah -classpath . -jni org.jnetpcap.nio.JMemoryPool
    #javah -classpath . -jni org.jnetpcap.nio.JMemory$Type
    #javah -classpath . -jni org.jnetpcap.nio.JNumber
    #javah -classpath . -jni org.jnetpcap.nio.JNumber$Type
    #javah -classpath . -jni org.jnetpcap.nio.JStruct
    javah -classpath . -jni org.jnetpcap.winpcap.WinPcap$1
    javah -classpath . -jni org.jnetpcap.winpcap.WinPcap
    javah -classpath . -jni org.jnetpcap.winpcap.WinPcapRmtAuth
    javah -classpath . -jni org.jnetpcap.winpcap.WinPcapSamp
    javah -classpath . -jni org.jnetpcap.winpcap.WinPcapSendQueue
    javah -classpath . -jni org.jnetpcap.winpcap.WinPcapStat
    #javah -classpath . -jni org.jnetpcap.packet.JPacket
    #javah -classpath . -jni org.jnetpcap.packet.JPacketHandler
    #javah -classpath . -jni org.jnetpcap.packet.JPacket$State

    1、下载源代码

    $git clone git://android.git.kernel.org/platform/external/libpcap.git

    (从android官方源码站点下载libpcap代码,版本为0.9.8)

    之前在网上查到jnetpcap1.2版本支持libpcap-0.9.8,所以下载jnetpcap-1.2.rc1.zip

    http://sourceforge.net/projects/jnetpcap/files/jnetpcap/1.2/stable/

    $wget http://ncu.dl.sourceforge.net/project/jnetpcap/jnetpcap/1.2/stable/jnetpcap-1.2.rc1.zip

    2、在android的ndk目录下,新建一个目录jnetpcap1.2,其中包括子目录jni

    将libpcap的源文件和jnetpcap-1.2.rc1.zip里面的c源文件拷贝到jni目录(即将所有源文件放在同一个目录下)。

    3、打开jni目录下的Android.mk文件(这个文件是libpcap源码里面带的),将其修改为如下内容:

    LOCAL_PATH:= $(call my-dir)

    include $(CLEAR_VARS)

     

    LOCAL_SRC_FILES:=\

    bpf_dump.c\

    bpf/net/bpf_filter.c\

    bpf_image.c\

    etherent.c\

    fad-gifc.c\

    gencode.c\

    grammar.c\

    inet.c\

    nametoaddr.c\

    optimize.c\

    pcap.c\

    pcap-linux.c\

    savefile.c\

    scanner.c\

    version.c

     

    LOCAL_CFLAGS:=-O2 -g

    LOCAL_CFLAGS+=-DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -Dlinux -D__GLIBC__ -D_GNU_SOURCE

     

    LOCAL_MODULE:= libpcap

    include $(BUILD_STATIC_LIBRARY)

     

    #LOCAL_PATH:= $(call my-dir)

    include $(CLEAR_VARS)

     

    LOCAL_SRC_FILES:=\

    jnetpcap.cpp\

    jnetpcap_beta.cpp\

    jnetpcap_bpf.cpp\

    jnetpcap_dumper.cpp\

    jnetpcap_ids.cpp\

    jnetpcap_pcap_header.cpp\

    jnetpcap_utils.cpp\

    nio_jbuffer.cpp\

    nio_jmemory.cpp\

    nio_jnumber.cpp\

    packet_jheader.cpp\

    packet_jheader_scanner.cpp\

    packet_jpacket.cpp\

    packet_jscan.cpp\

    packet_jsmall_scanner.cpp\

    packet_protocol.cpp\

    winpcap_ext.cpp\

    winpcap_ids.cpp\

    winpcap_send_queue.cpp\

    winpcap_stat_ex.cpp

     

    LOCAL_MODULE:= libjnetpcap

    LOCAL_STATIC_LIBRARIES := libpcap

    include $(BUILD_SHARED_LIBRARY)

     

    4、切换到jni目录下,执行如下命令:

    $ndk-build V=1 -B NDK_LOG=1

    (后面加参数是为里输出日志信息,便于挑错,-B是重新编译)

    编译报错:



     意思是找不到对应的头文件。

     

    因为jnetpcap 是通过jni对libpcap的封装,所以我们需要为jnetpcap里面的native方法生成头文件。

    接下来,首先编译jnetpcap1.2源码中的java源码,得到对应的class文件;

    然后,在class目录下,通过javah -classpath . -jni org.jnetpcap.Pcap命令 来为class生成对应的.h头文件

    最后,将生成的.h文件全部拷贝到jni目录下,重新编译。编译过程中会出现很多警告,影响不大。

    但是结果还是报错了:



    上面这个问题,最后是google 解决的,在此谢过:http://comments.gmane.org/gmane.comp.handhelds.android.ndk/4066

     

    在 grammar.y 和 grammar.c文件中,注释掉以下内容:

    //#ifndef YYBISON
    int yyparse(void);

    int
    pcap_parse()
    {
        return (yyparse());
    }
    //#endif

     

    同时在scanner.c和scanner.l中注释掉以下内容:

    //#define yylval pcap_lval

     

    然后重新运行,$NDK/ndk-build V=1 -B NDK_LOG=1

    如果能够看到如下输出信息,则说明编译成功。


     

    编译成功后,会在jnetpcap1.2目录下自动创建一个libs目录,在该目录下包含一个子目录armeabi,在这个目录下包含编译生成的共享库:libjnetpcap.so

    在java代码中就可以如下来加载这个共享库:

     

    Java代码  收藏代码
    1. System.loadLibrary("jnetpcap");  

    至此,编译工作已完成。

     

    使用类似的方法,可以编译成功jnetpcap1.2.r5,但是在编译jnetpcap1.3.0-1会出问题,后面会将编译jnetpcap1.3.0-1的过程写下来。

     

     

     

     

    android.mk

     

    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_C_INCLUDES += $(LOCAL_PATH)
    LOCAL_MODULE    := **
    LOCAL_SRC_FILES := **.c
    LOCAL_LDLIBS :=$(LOCAL_PATH)/**.a
    include $(BUILD_EXECUTABLE)

  • 相关阅读:
    MyBatis 缓存机制
    MyBatis 动态SQL
    SpringMVC的简介与使用
    捕获组和前后查找
    正则表达式:( ) 小括号、[ ] 中括号、{ } 大括号的区别
    343.整数拆分
    74. 搜索二维矩阵
    数的划分
    213.打家劫舍||
    整数划分为k份
  • 原文地址:https://www.cnblogs.com/wenjie2008888/p/2595185.html
Copyright © 2011-2022 走看看