zoukankan      html  css  js  c++  java
  • ndk编译libpcap 1.7.4

    android完全菜鸟,绝对的第一次接触,想做手机抓包,在网上搜又是NDK 又是JNI 又是JNETPCAP 完全蒙了,让我这种android和java都弄不明白什么关系的人情何以堪!

    静下心想一想,无非是编译一个库,好在C和LINUX都有10年的经验,就直接下最新的libpcap 1.7.4 一步步编译,成功了,写个测试也OK。现将过程写出,以做备忘。

    下载安装 android studio、android-ndk-r10d、jdk、libpcap 1.7.4 我这面是全下的WIN7 64对应版本  

    1. 把libpcap的gz包托到VMWare上的ARCHLINUX里,tar xzf xxxxxx 然后

    ./configure --disable-ipv6 --disable-usb --disable-bluetooth --disable-canusb --disable-can --disable-dbus
    make > res.txt

    生成文件如下

    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./pcap-linux.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./pcap-netfilter-linux.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./fad-getad.c
    if grep GIT ./VERSION >/dev/null; then 
        read ver <./VERSION; 
        echo $ver | tr -d '12'; 
        date +_%Y_%m_%d; 
    else 
        cat ./VERSION; 
    fi | sed -e 's/.*/static const char pcap_version_string[] = "libpcap version &";/' > version.h
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./pcap.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./inet.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./gencode.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./optimize.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./nametoaddr.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./etherent.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./savefile.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./sf-pcap.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./sf-pcap-ng.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./pcap-common.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./bpf_image.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c ./bpf_dump.c
    ./runlex.sh flex -Ppcap_ -oscanner.c scanner.l
    mv scanner.c scanner.c.bottom
    cat ./scanner.c.top scanner.c.bottom > scanner.c
    bison -y -p pcap_ -d grammar.y
    mv y.tab.c grammar.c
    mv y.tab.h tokdefs.h
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c scanner.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -Dyylval=pcap_lval -c grammar.c
    rm -f bpf_filter.c
    ln -s ./bpf/net/bpf_filter.c bpf_filter.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c bpf_filter.c
    if grep GIT ./VERSION >/dev/null; then 
        read ver <./VERSION; 
        echo $ver | tr -d '12'; 
        date +_%Y_%m_%d; 
    else 
        cat ./VERSION; 
    fi | sed -e 's/.*/char pcap_version[] = "&";/' > version.c
    gcc -fpic -I.  -I/usr/include/libnl3 -DHAVE_CONFIG_H  -D_U_="__attribute__((unused))" -g -O2    -c version.c
    ar rc libpcap.a pcap-linux.o pcap-netfilter-linux.o fad-getad.o pcap.o inet.o gencode.o optimize.o nametoaddr.o etherent.o savefile.o sf-pcap.o sf-pcap-ng.o pcap-common.o bpf_image.o bpf_dump.o  scanner.o grammar.o bpf_filter.o version.o  
    ranlib libpcap.a
    VER=`cat ./VERSION`; 
    MAJOR_VER=`sed 's/([0-9][0-9]*)..*/1/' ./VERSION`; 
    gcc -shared -Wl,-soname,libpcap.so.$MAJOR_VER  
        -o libpcap.so.$VER pcap-linux.o pcap-netfilter-linux.o fad-getad.o pcap.o inet.o gencode.o optimize.o nametoaddr.o etherent.o savefile.o sf-pcap.o sf-pcap-ng.o pcap-common.o bpf_image.o bpf_dump.o  scanner.o grammar.o bpf_filter.o version.o   -lnl-genl-3 -lnl-3 
    ./config.status --file=pcap-config.tmp:./pcap-config.in
    config.status: creating pcap-config.tmp
    mv pcap-config.tmp pcap-config
    chmod a+x pcap-config

    编译过程非常简单,但有五个文件是生成的(scanner.c grammar.c tokdefs.h version.c version.h),全部托到WINDOWS下,放到LIBPCAP源码目录。

    另外,还有一个bpf_filter.c在子目录里,LINUX 建了一个软链接,WINDOWS里干脆直接COPY到源码里。

    此时已经可以开始编译了,但出错是肯定的。。一个个来

    完全不用什么SHELL之类的,就在源码目录里编译以下文件

    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./pcap-linux.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./pcap-netfilter-linux.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./fad-getad.c                          
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./pcap.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./inet.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./gencode.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./optimize.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./nametoaddr.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./etherent.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./savefile.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./sf-pcap.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./sf-pcap-ng.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./pcap-common.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./bpf_image.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./bpf_dump.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./scanner.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./bpf_filter.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./version.c
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -Dyylval=pcap_lval -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c grammar.c

    1. pcap-netfilter-linux.c 编译出错 

    D:libpcap-1.7.4>D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -D_U_="__attribute__((unused))" -O2 -fomit-frame-pointer -Wall -pipe -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -c ./pcap-netfilter-linux.c
    In file included from D:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude/stdlib.h:40:0,
                     from ./pcap-netfilter-linux.c:42:
    D:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude/string.h:76:15: error: expected declaration specifiers or '...' before '(' token
    D:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude/string.h:76:15: error: expected declaration specifiers or '...' before '(' token
    D:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude/string.h:76:15: error: expected declaration specifiers or '...' before '(' token
    D:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude/string.h:76:15: error: expected ')' before ',' token

    这需要在pcap-int.h中进行修改

    1 #define HAVE_STRLCPY 1 //加这一句
    2 #ifndef HAVE_STRLCPY
    3 #define strlcpy(x, y, z) 
    4     (strncpy((x), (y), (z)), 
    5      ((z) <= 0 ? 0 : ((x)[(z) - 1] = '')), 
    6      strlen((y)))
    7 #endif

    2. fad-getad.c 编译出错

    ./fad-getad.c:50:21: fatal error: ifaddrs.h: No such file or directory
    compilation terminated.

    这个用的接口是getifaddrs 本来就释放不了问题很多,连原来代码里都有提到代码会报错,我看了下里面无非就是列举网卡,就重写了该文件,如下

      1 /* -*- Mode: c; tab- 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
      2 /*
      3  * Copyright (c) 1994, 1995, 1996, 1997, 1998
      4  *    The Regents of the University of California.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. All advertising materials mentioning features or use of this software
     15  *    must display the following acknowledgement:
     16  *    This product includes software developed by the Computer Systems
     17  *    Engineering Group at Lawrence Berkeley Laboratory.
     18  * 4. Neither the name of the University nor of the Laboratory may be used
     19  *    to endorse or promote products derived from this software without
     20  *    specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  */
     34 
     35 #ifdef HAVE_CONFIG_H
     36 #include "config.h"
     37 #endif
     38 
     39 #include <sys/types.h>
     40 #include <sys/socket.h>
     41 #include <netinet/in.h>
     42 
     43 #include <net/if.h>
     44 
     45 #include <ctype.h>
     46 #include <errno.h>
     47 #include <stdio.h>
     48 #include <stdlib.h>
     49 #include <string.h>
     50 #include <unistd.h>
     51 //#include <linux/if.h>
     52 //#include <ifaddrs.h>
     53 
     54 #include "pcap-int.h"
     55 
     56 #ifdef HAVE_OS_PROTO_H
     57 #include "os-proto.h"
     58 #endif
     59 
     60 /*
     61  * We don't do this on Solaris 11 and later, as it appears there aren't
     62  * any AF_PACKET addresses on interfaces, so we don't need this, and
     63  * we end up including both the OS's <net/bpf.h> and our <pcap/bpf.h>,
     64  * and their definitions of some data structures collide.
     65  */
     66 #if (defined(linux) || defined(__Lynx__)) && defined(AF_PACKET)
     67 # ifdef HAVE_NETPACKET_PACKET_H
     68 /* Linux distributions with newer glibc */
     69 #  include <netpacket/packet.h>
     70 # else /* HAVE_NETPACKET_PACKET_H */
     71 /* LynxOS, Linux distributions with older glibc */
     72 # ifdef __Lynx__
     73 /* LynxOS */
     74 #  include <netpacket/if_packet.h>
     75 # else /* __Lynx__ */
     76 /* Linux */
     77 #  include <linux/types.h>
     78 #  include <linux/if_packet.h>
     79 # endif /* __Lynx__ */
     80 # endif /* HAVE_NETPACKET_PACKET_H */
     81 #endif /* (defined(linux) || defined(__Lynx__)) && defined(AF_PACKET) */
     82 
     83 /*
     84  * This is fun.
     85  *
     86  * In older BSD systems, socket addresses were fixed-length, and
     87  * "sizeof (struct sockaddr)" gave the size of the structure.
     88  * All addresses fit within a "struct sockaddr".
     89  *
     90  * In newer BSD systems, the socket address is variable-length, and
     91  * there's an "sa_len" field giving the length of the structure;
     92  * this allows socket addresses to be longer than 2 bytes of family
     93  * and 14 bytes of data.
     94  *
     95  * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553
     96  * variant of the old BSD scheme (with "struct sockaddr_storage" rather
     97  * than "struct sockaddr"), and some use the new BSD scheme.
     98  *
     99  * Some versions of GNU libc use neither scheme, but has an "SA_LEN()"
    100  * macro that determines the size based on the address family.  Other
    101  * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553
    102  * but not in the final version).  On the latter systems, we explicitly
    103  * check the AF_ type to determine the length; we assume that on
    104  * all those systems we have "struct sockaddr_storage".
    105  */
    106 #ifndef SA_LEN
    107 #ifdef HAVE_SOCKADDR_SA_LEN
    108 #define SA_LEN(addr)    ((addr)->sa_len)
    109 #else /* HAVE_SOCKADDR_SA_LEN */
    110 #ifdef HAVE_SOCKADDR_STORAGE
    111 static size_t
    112 get_sa_len( struct sockaddr* addr )
    113 {
    114     switch ( addr->sa_family )
    115     {
    116 
    117 #ifdef AF_INET
    118         case AF_INET:
    119             return ( sizeof ( struct sockaddr_in ) );
    120 #endif
    121 
    122 #ifdef AF_INET6
    123         case AF_INET6:
    124             return ( sizeof ( struct sockaddr_in6 ) );
    125 #endif
    126 
    127 #if (defined(linux) || defined(__Lynx__)) && defined(AF_PACKET)
    128         case AF_PACKET:
    129             return ( sizeof ( struct sockaddr_ll ) );
    130 #endif
    131 
    132         default:
    133             return ( sizeof ( struct sockaddr ) );
    134     }
    135 }
    136 #define SA_LEN(addr)    (get_sa_len(addr))
    137 #else /* HAVE_SOCKADDR_STORAGE */
    138 #define SA_LEN(addr)    (sizeof (struct sockaddr))
    139 #endif /* HAVE_SOCKADDR_STORAGE */
    140 #endif /* HAVE_SOCKADDR_SA_LEN */
    141 #endif /* SA_LEN */
    142 
    143 /*
    144  * Get a list of all interfaces that are up and that we can open.
    145  * Returns -1 on error, 0 otherwise.
    146  * The list, as returned through "alldevsp", may be null if no interfaces
    147  * could be opened.
    148  */
    149 
    150 #define MAX_INTERFACE 32
    151 struct ifreq ifr[MAX_INTERFACE];
    152 
    153 
    154 int pcap_findalldevs_interfaces( pcap_if_t** alldevsp, char* errbuf )
    155 {
    156     pcap_if_t* devlist;
    157     int i, rc, sock, ifnum;
    158     char ifname[IFNAMSIZ];
    159     
    160     struct sockaddr* addr, *netmask, *broadaddr, *dstaddr;
    161     size_t addr_size, broadaddr_size, dstaddr_size;
    162     struct ifconf ifc;
    163     char* p;
    164 
    165     devlist = NULL;
    166 
    167     sock = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
    168     if ( sock == -1 )
    169     {
    170         ( void )snprintf( errbuf, PCAP_ERRBUF_SIZE, "sock: %s", pcap_strerror( errno ) );
    171         return -1;
    172     }
    173 
    174 
    175     ifc.ifc_len = sizeof( ifr );
    176     ifc.ifc_buf = ( caddr_t ) ifr;
    177     rc = ioctl( sock, SIOCGIFCONF, &ifc );
    178     if ( rc == -1 )
    179     {
    180         ( void )snprintf( errbuf, PCAP_ERRBUF_SIZE, "ioctl: %s", pcap_strerror( errno ) );
    181         close( sock );
    182         return -1;
    183     }
    184 
    185     ifnum = ifc.ifc_len / sizeof ( struct ifreq );
    186     if ( ifnum > MAX_INTERFACE )
    187     {
    188         ifnum = MAX_INTERFACE;
    189     }
    190 
    191     for ( i = 0; i < ifnum; i ++ )
    192     {
    193         rc = ioctl( sock, SIOCGIFFLAGS, ifr + i );
    194         if ( rc == -1 )
    195         {
    196             ( void )snprintf( errbuf, PCAP_ERRBUF_SIZE, "ioctl: %s", pcap_strerror( errno ) );
    197             break;
    198         }
    199 
    200         //ip netmask
    201         rc = ioctl ( sock, SIOCGIFADDR, ifr + i );
    202         if ( rc != -1 )
    203         {
    204             addr = &ifr[i].ifr_addr;
    205             addr_size = SA_LEN( addr );
    206 
    207             ioctl ( sock, SIOCGIFNETMASK, ifr + i );
    208             netmask = &ifr[i].ifr_netmask;
    209         }
    210         else
    211         {
    212             continue;
    213         }
    214 
    215         // broadcast
    216         if ( ( ifr[i].ifr_flags & IFF_BROADCAST ) && ( rc = ioctl ( sock, SIOCGIFBRDADDR, ifr + i ) ) != -1 )
    217         {
    218             broadaddr = &ifr[i].ifr_broadaddr;
    219             broadaddr_size = SA_LEN( broadaddr );
    220         }
    221         else
    222         {
    223             broadaddr = NULL;
    224             broadaddr_size = 0;
    225         }
    226 
    227         // p2p
    228         if ( ( ifr[i].ifr_flags & IFF_POINTOPOINT ) && ( rc = ioctl ( sock, SIOCGIFDSTADDR, ifr + i ) ) != -1 )
    229         {
    230             dstaddr = &ifr[i].ifr_dstaddr;
    231             dstaddr_size = SA_LEN( dstaddr );
    232         }
    233         else
    234         {
    235             dstaddr = NULL;
    236             dstaddr_size = 0;
    237         }
    238 
    239         // ifname
    240         memset( ifname, 0, sizeof( ifname ) );
    241         strcpy( ifname, ifr[i].ifr_name );
    242 
    243         /*p = strchr( ifname, ':' );
    244         if ( p != NULL )
    245         {
    246             *p = 0;
    247         }*/
    248 
    249         printf("add [%d][%s]
    ", i, ifname);
    250         if ( add_addr_to_iflist( &devlist, ifname,
    251                                  ifr[i].ifr_flags, addr, addr_size, netmask, addr_size,
    252                                  broadaddr, broadaddr_size, dstaddr, dstaddr_size,
    253                                  errbuf ) < 0 )
    254         {
    255             rc = -1;
    256             break;
    257         }
    258     }
    259 
    260     if ( rc == -1 )
    261     {
    262         if ( devlist != NULL )
    263         {
    264             pcap_freealldevs( devlist );
    265             devlist = NULL;
    266         }
    267     }
    268 
    269     *alldevsp = devlist;
    270     close( sock );
    271     return 0;
    272 }

    3. pcap.c报错

    D:libpcap-1.7.4pcap.c: In function 'pcap_strerror':
    D:libpcap-1.7.4pcap.c:1591:27: error: conflicting types for 'sys_errlist'
    D:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude/stdio.h:239:14: note: previous declaration of 'sys_errlist' was here

    修改该函数

     1 const char *
     2 pcap_strerror(int errnum)
     3 {
     4 #define HAVE_STRERROR 1//加这一句
     5 #ifdef HAVE_STRERROR
     6     return (strerror(errnum));
     7 #else
     8     extern int sys_nerr;
     9     extern const char *const sys_errlist[];
    10     static char ebuf[15+10+1];
    11 
    12     if ((unsigned int)errnum < sys_nerr)
    13         return ((char *)sys_errlist[errnum]);
    14     (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
    15     return(ebuf);
    16 #endif
    17 }

    4. inet.c警告

    ---------- ndk-gcc ----------
    D:libpcap-1.7.4inet.c:71:0: warning: "INT_MAX" redefined [enabled by default]
    D:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude/sys/limits.h:68:0: note: this is the location of the previous definition

    修改为

    #define HAVE_LIMITS_H 1 //加这一句
    #ifdef HAVE_LIMITS_H
    #include <limits.h>
    #else
    #define INT_MAX        2147483647
    #endif

    5. gencode.c警告

    一大堆,分支可能无法RETURN 变量可能未初始化之类的,不影响,不作修改!

    然后开始链接,这里恶心了好久.后来想想也明白了,这个就是嵌入式板子上的一个LINUX系统,没有标准C库。一定要加-nostdlib

    还有就是体现出菜鸟本色的东西了,crtend_android.o crtbegin_dynamic.o 这两个东西不知道干什么的,在网上看了下,好像都要,应该是启动代码类的,本来可能是后缀S的汇编。。所以直接COPY到源码文件夹。至于为什么用dynamic,只是因为我要编译SO。不过后缀有SO的可能更好,纠结了半天用的是crtend_so.o crtbegin_so.o。后面测试程序再用上面的两个好了。

    然后执行

    D:Androidandroid-ndk-r10d oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -nostdlib -Bdynamic -shared -Wl,-soname,libpcap.so -o libpcap.so pcap-linux.o pcap-netfilter-linux.o fad-getad.o pcap.o inet.o gencode.o optimize.o nametoaddr.o etherent.o savefile.o sf-pcap.o sf-pcap-ng.o pcap-common.o bpf_image.o bpf_dump.o scanner.o grammar.o bpf_filter.o version.o crtend_so.o crtbegin_so.o -LD:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrlib -lc -ldl -llog -lgcc -lm -landroid -lz

    顺利生成libpcap.so

    然后写个程序测下

     1 //netpkghdr.h
     2 #ifndef _NET_PKG_HDR_H_
     3 #define _NET_PKG_HDR_H_
     4 
     5 
     6 
     7 #define ETHERTYPE_IP 0x0008        // IP协议  (0x0800的网络序)
     8 #define TCP_PROTOCAL 0x0006        // TCP协议 (0x0600的网络序)
     9 #define BUFF_MAX_LEN 0x10000       // 最大包长
    10 
    11 
    12 #pragma pack(push, 1)
    13 
    14 // ethernet header
    15 typedef struct ether_header
    16 {
    17     unsigned char  dst[6];         // 目标MAC
    18     unsigned char  src[6];         // 源MAC
    19     unsigned short type;           // 上层协议标识
    20 } eth_hdr;
    21 
    22 // ipv4 address
    23 typedef struct ip_address
    24 {
    25     unsigned char b1, b2, b3, b4;
    26 } ip_addr;
    27 
    28 // ipv4 header
    29 typedef struct ip_header
    30 {
    31     unsigned char  ver_ihl;        // 版本信息(4)头长度(4)
    32     unsigned char  tos;            // 服务类型
    33     unsigned short len;            // 数据包长度
    34     unsigned short id;             // 数据包标识
    35     unsigned short slice;          // 片偏移
    36     unsigned char  ttl;            // ttl
    37     unsigned char  proto;          // 协议
    38     unsigned short sum;            // 校验和
    39     ip_addr        saddr;          // 源IP
    40     ip_addr        daddr;          // 目标IP
    41 } ip_hdr;
    42 
    43 // tcp header
    44 typedef struct tcp_header
    45 {
    46     unsigned short sport;          // 源端口
    47     unsigned short dport;          // 目标端口
    48     unsigned int   seq;            // 序列号
    49     unsigned int   ack;            // 应答
    50     unsigned short len_code;       // TCP头长度(4)保留(6)标志(6)
    51     unsigned short window;         // 窗口大小
    52     unsigned short sum;            // 校验和
    53     unsigned short urp;            // 紧急数据偏移
    54 } tcp_hdr;
    55 
    56 // udp header
    57 typedef struct udp_header
    58 {
    59     unsigned short sport;          // 源端口
    60     unsigned short dport;          // 目标端口
    61     unsigned short len;            // 包长
    62     unsigned short sum;            // 校验和
    63 } udp_hdr;
    64 
    65 #pragma pack(pop)
    66 
    67 
    68 #endif /* _NET_PKG_HDR_H_ */
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <pcap.h>
      5 #include "netpkghdr.h"
      6 
      7 
      8 unsigned char g_buffer[BUFF_MAX_LEN] = {0};
      9 
     10 
     11 pcap_t* get_pcap( const char* name )
     12 {
     13     pcap_if_t* ifs;
     14     pcap_if_t* d;
     15     pcap_t* pcap;
     16     char errbuff[PCAP_ERRBUF_SIZE];
     17 
     18     if ( pcap_findalldevs( &ifs, errbuff ) == -1 )
     19     {
     20         fprintf( stderr, "pcap_findalldevs [%s]
    ", errbuff );
     21         return NULL;
     22     }
     23 
     24     for ( d = ifs; d; d = d->next )
     25     {
     26         if ( memcmp( d->name, name, strlen( name ) ) == 0 )
     27         {
     28             break;
     29         }
     30     }
     31 
     32     pcap = pcap_open_live( d->name, 
     33                            BUFF_MAX_LEN, 
     34                            0, 
     35                            3000, 
     36                            errbuff );
     37 
     38     pcap_freealldevs( ifs );
     39 
     40     if ( pcap == NULL )
     41     {
     42         fprintf( stderr, "pcap_open_live [%s]
    ", errbuff );
     43         return NULL;
     44     }
     45 
     46     return pcap;
     47 }
     48 
     49 int main()
     50 {
     51     int rc;
     52     pcap_t* pcap;
     53     struct bpf_program bpf;
     54 
     55     struct pcap_pkthdr* header;
     56     const unsigned char* pkt_data;
     57 
     58 
     59     eth_hdr* eth;
     60 
     61     ip_hdr* ip;
     62     unsigned short ip_hdr_len;
     63 
     64     tcp_hdr* tcp;
     65     unsigned short tcp_hdr_len;
     66     unsigned short tcp_data_len;
     67     unsigned char* tcp_pkt_data;
     68 
     69 
     70     if ( ( pcap = get_pcap( "wlan" ) ) == NULL )
     71     {
     72         return -1;
     73     }
     74 
     75 
     76     if ( pcap_compile( pcap, &bpf, "tcp port 80", 1, 0 ) < 0 )
     77     {
     78         fprintf( stderr, "pcap_compile error
    " );
     79         return -1;
     80     }
     81 
     82     if ( pcap_setfilter( pcap, &bpf ) < 0 )
     83     {
     84         fprintf( stderr, "pcap_setfilter
    " );
     85         return -1;
     86     }
     87 
     88 
     89     while ( ( rc = pcap_next_ex( pcap, &header, &pkt_data ) ) >= 0 )
     90     {
     91         if ( rc == 0 )
     92         {
     93             continue;
     94         }
     95 
     96         eth = ( eth_hdr* )pkt_data;
     97 
     98         ip = ( ip_hdr* )( eth + 1 );
     99         ip_hdr_len = ( ( ip->ver_ihl & 0x0F ) << 2 );
    100 
    101         tcp = ( tcp_hdr* )( pkt_data + sizeof( eth_hdr ) + ip_hdr_len );
    102         tcp_hdr_len = ( ( tcp->len_code & 0x00F0 ) >> 2 );
    103         tcp_data_len = header->len - sizeof( eth_hdr ) - ip_hdr_len - tcp_hdr_len;
    104         tcp_pkt_data = ( unsigned char* )tcp + tcp_hdr_len;
    105 
    106 
    107         if ( tcp_data_len < 3 || 
    108                 ( strncmp( ( char* )tcp_pkt_data, "GET", 3 ) && 
    109                   strncmp( ( char* )tcp_pkt_data, "POST", 4 ) && 
    110                   strncmp( ( char* )tcp_pkt_data, "HTTP/1.1", 8 ) ) )
    111         {
    112             continue;
    113         }
    114 
    115         memcpy( g_buffer, tcp_pkt_data, tcp_data_len );
    116         g_buffer[tcp_data_len] = 0;
    117 
    118 
    119         printf( "==============================================
    " );
    120         printf( "%s
    ", ( char* )g_buffer );
    121         printf( "**********************************************
    
    " );
    122     }
    123 
    124 
    125     pcap_close( pcap );
    126 
    127 
    128     return 0;
    129 }

    编译之

    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -DNDEBUG -O2 -fomit-frame-pointer -Wall -pipe -c main.c -I. -ID:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrinclude -I./pcap
    D:Androidandroid-ndk-r10d	oolchainsarm-linux-androideabi-4.6prebuiltwindows-x86_64inarm-linux-androideabi-gcc.exe -nostdlib -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -o hello main.o D:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrlibcrtend_android.o D:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrlibcrtbegin_dynamic.o -L. -LD:Androidandroid-ndk-r10dplatformsandroid-19arch-armusrlib -lc -ldl -llog -lgcc -lm -landroid -lz -lpcap

    报错!!!

    d:/android/android-ndk-r10d/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./libpcap.so: error: undefined reference to 'pcap_snprintf'
    d:/android/android-ndk-r10d/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./libpcap.so: error: undefined reference to 'pcap_vsnprintf'
    collect2: ld returned 1 exit status

    明显是PCAP源码里这两个函数有问题,回头再去改源码

    同样是修改pcap-int.h

    #define HAVE_SNPRINTF 1 //添加这一句
    #if !defined(HAVE_SNPRINTF)
    #define snprintf pcap_snprintf
    extern int snprintf (char *, size_t, const char *, ...);
    #endif
    
    #define HAVE_VSNPRINTF 1 //添加这一句
    #if !defined(HAVE_VSNPRINTF)
    #define vsnprintf pcap_vsnprintf
    extern int vsnprintf (char *, size_t, const char *, va_list ap);
    #endif

    重新生成SO,并编译程序 ...顺利生成hello

    然后用传说中的adb push到里面(这个查了半小时,不知道ADB是什么)

    用RE把so放/system/lib 改权限

    用RE修改hello权限

    adb shell,发现和LINUX一样一样的。。。

    执行之

    明天再写几个JNI的东西,把这一堆PCAP的函数包成我想要的,然后写JAVA。。。再然后就OK了。。

    闲扯几句,开始看了眼JNI吓一跳,后来用和上面一要最土的方法,试了下,发现和C与LUA交互非常像,只是更智能点。

  • 相关阅读:
    ref和out的区别
    final、finally、finalize的区别
    get和post的区别
    什么是事务
    锁的详细
    什么是游标
    什么是存储过程
    委托的来由
    多线程的秘密
    String str=null; 和String str=""的区别
  • 原文地址:https://www.cnblogs.com/javado/p/4716844.html
Copyright © 2011-2022 走看看