iPhone上的网络活动监控

时间:2013-11-14 12:32:30

标签: ios iphone ipad tcp netstat

我已经工作了5天,试图在iPhone上学习和实现网络监视器。 我查看了来自苹果的netstat代码,我失去了25%的头发。

我找到了JB Devices的链接,但我需要它在非JB设备上执行。 (无论Apple是否在App Store上接受它)。

我找到了一些有用的链接:

how to get tcp udp opening port list on iPhone(我无法解析此问题中返回的数据:()

Data Usage on iPhone

sysctlbyname buf return type(我不是网络人......不能理解这一点,也许你们可以帮助:))

TCP/UPD port list

我可以说我从第一个链接得到了一些东西。你能帮我解析数据吗? 有没有其他方法来实现这一目标?

1 个答案:

答案 0 :(得分:10)

好的,你可以在桌上找到所需的一切。

您可以查看问题Is there any private api to monitor network traffic on iPhone? 在这里,您可以找到来源code of inet。该代码具有解析how to get tcp udp opening port list on iPhone

返回的数据所需的全部内容
size_t len = 0;
if (sysctlbyname("net.inet.tcp.pcblist_n", 0, &len, 0, 0) < 0) {
    perror("sysctlbyname");
} else {
    char *buf = malloc(len);
    sysctlbyname("net.inet.tcp.pcblist_n", buf, &len, 0, 0);
    NSData *data = [NSData dataWithBytesNoCopy:buf length:len];
    NSLog(@"data = %@", data);
}

好的,是的,inet的源代码有点复杂。但是,你知道netstat打印净状态。因此,您只需要查看inet执行printf的时间,此时您将解析数据。

如果你尝试编译iOS的inet源代码,你会发现很多问题:ios sdk中没有一些头文件。好的,没有问题复制标题。

对于模拟器,您只需要复制netstat.h的标题。并添加一些私有的结构声明:

struct  xtcpcb_n {
    u_int32_t                      xt_len;
    u_int32_t                        xt_kind;                /* XSO_TCPCB */

    u_int64_t t_segq;
    int     t_dupacks;              /* consecutive dup acks recd */

    int t_timer[TCPT_NTIMERS_EXT];  /* tcp timers */

    int     t_state;                /* state of this connection */
    u_int   t_flags;

    int     t_force;                /* 1 if forcing out a byte */

    tcp_seq snd_una;                /* send unacknowledged */
    tcp_seq snd_max;                /* highest sequence number sent;
                                     * used to recognize retransmits
                                     */
    tcp_seq snd_nxt;                /* send next */
    tcp_seq snd_up;                 /* send urgent pointer */

    tcp_seq snd_wl1;                /* window update seg seq number */
    tcp_seq snd_wl2;                /* window update seg ack number */
    tcp_seq iss;                    /* initial send sequence number */
    tcp_seq irs;                    /* initial receive sequence number */

    tcp_seq rcv_nxt;                /* receive next */
    tcp_seq rcv_adv;                /* advertised window */
    u_int32_t rcv_wnd;              /* receive window */
    tcp_seq rcv_up;                 /* receive urgent pointer */

    u_int32_t snd_wnd;              /* send window */
    u_int32_t snd_cwnd;             /* congestion-controlled window */
    u_int32_t snd_ssthresh;         /* snd_cwnd size threshold for
                                     * for slow start exponential to
                                     * linear switch
                                     */
    u_int   t_maxopd;               /* mss plus options */

    u_int32_t t_rcvtime;            /* time at which a packet was received */
    u_int32_t t_starttime;          /* time connection was established */
    int     t_rtttime;              /* round trip time */
    tcp_seq t_rtseq;                /* sequence number being timed */

    int     t_rxtcur;               /* current retransmit value (ticks) */
    u_int   t_maxseg;               /* maximum segment size */
    int     t_srtt;                 /* smoothed round-trip time */
    int     t_rttvar;               /* variance in round-trip time */

    int     t_rxtshift;             /* log(2) of rexmt exp. backoff */
    u_int   t_rttmin;               /* minimum rtt allowed */
    u_int32_t t_rttupdated;         /* number of times rtt sampled */
    u_int32_t max_sndwnd;           /* largest window peer has offered */

    int     t_softerror;            /* possible error not yet reported */
    /* out-of-band data */
    char    t_oobflags;             /* have some */
    char    t_iobc;                 /* input character */
    /* RFC 1323 variables */
    u_char  snd_scale;              /* window scaling for send window */
    u_char  rcv_scale;              /* window scaling for recv window */
    u_char  request_r_scale;        /* pending window scaling */
    u_char  requested_s_scale;
    u_int32_t ts_recent;            /* timestamp echo data */

    u_int32_t ts_recent_age;        /* when last updated */
    tcp_seq last_ack_sent;
    /* RFC 1644 variables */
    tcp_cc  cc_send;                /* send connection count */
    tcp_cc  cc_recv;                /* receive connection count */
    tcp_seq snd_recover;            /* for use in fast recovery */
    /* experimental */
    u_int32_t snd_cwnd_prev;        /* cwnd prior to retransmit */
    u_int32_t snd_ssthresh_prev;    /* ssthresh prior to retransmit */
    u_int32_t t_badrxtwin;          /* window for retransmit recovery */
};


struct  xinpcb_n {
    u_int32_t               xi_len;         /* length of this structure */
    u_int32_t               xi_kind;                /* XSO_INPCB */
    u_int64_t               xi_inpp;
    u_short                 inp_fport;      /* foreign port */
    u_short                 inp_lport;      /* local port */
    u_int64_t               inp_ppcb;       /* pointer to per-protocol pcb */
    inp_gen_t               inp_gencnt;     /* generation count of this instance */
    int                             inp_flags;      /* generic IP/datagram flags */
    u_int32_t               inp_flow;
    u_char                  inp_vflag;
    u_char                  inp_ip_ttl;     /* time to live */
    u_char                  inp_ip_p;       /* protocol */
    union {                                 /* foreign host table entry */
        struct  in_addr_4in6    inp46_foreign;
        struct  in6_addr        inp6_foreign;
    }                               inp_dependfaddr;
    union {                                 /* local host table entry */
        struct  in_addr_4in6    inp46_local;
        struct  in6_addr        inp6_local;
    }                               inp_dependladdr;
    struct {
        u_char          inp4_ip_tos;    /* type of service */
    }                               inp_depend4;
    struct {
        u_int8_t        inp6_hlim;
        int                     inp6_cksum;
        u_short         inp6_ifindex;
        short           inp6_hops;
    }                               inp_depend6;
    u_int32_t               inp_flowhash;
};


#define SO_TC_STATS_MAX 4

struct data_stats {
    u_int64_t       rxpackets;
    u_int64_t       rxbytes;
    u_int64_t       txpackets;
    u_int64_t       txbytes;
};

struct xgen_n {
    u_int32_t   xgn_len;            /* length of this structure */
    u_int32_t   xgn_kind;       /* number of PCBs at this time */
};

#define XSO_SOCKET  0x001
#define XSO_RCVBUF  0x002
#define XSO_SNDBUF  0x004
#define XSO_STATS   0x008
#define XSO_INPCB   0x010
#define XSO_TCPCB   0x020

struct  xsocket_n {
    u_int32_t       xso_len;        /* length of this structure */
    u_int32_t       xso_kind;       /* XSO_SOCKET */
    u_int64_t       xso_so; /* makes a convenient handle */
    short           so_type;
    u_int32_t       so_options;
    short           so_linger;
    short           so_state;
    u_int64_t       so_pcb;     /* another convenient handle */
    int             xso_protocol;
    int             xso_family;
    short           so_qlen;
    short           so_incqlen;
    short           so_qlimit;
    short           so_timeo;
    u_short         so_error;
    pid_t           so_pgid;
    u_int32_t       so_oobmark;
    uid_t           so_uid;     /* XXX */
};

struct xsockbuf_n {
    u_int32_t       xsb_len;        /* length of this structure */
    u_int32_t       xsb_kind;       /* XSO_RCVBUF or XSO_SNDBUF */
    u_int32_t       sb_cc;
    u_int32_t       sb_hiwat;
    u_int32_t       sb_mbcnt;
    u_int32_t       sb_mbmax;
    int32_t         sb_lowat;
    short           sb_flags;
    short           sb_timeo;
};

struct xsockstat_n {
    u_int32_t       xst_len;        /* length of this structure */
    u_int32_t       xst_kind;       /* XSO_STATS */
    struct data_stats   xst_tc_stats[SO_TC_STATS_MAX];
};

但是对于设备你需要复制内核的其他标题,我不知道为什么标题不在设备sdk中(也许如果你使用它们Apple不会批准你的应用程序,我不知道,但那没关系)。

您可以将缺少的标头从模拟器SDK复制到您的项目中。或者您可以更改模拟器SDK的标头路径。 (我复制了标题) 如果您复制标题,则需要更改一些包含声明。

您不需要所有inet.c代码。您只需要这些功能:

  • protopr
  • inetprint
  • inetname

然后在这些函数中你会看到解析了数据的printf,你可以在字典中添加它。

Here是我的代码。您可以看到一个名为: DHInet 的类,其中有两个方法返回带有NSDictionary列表的NSArray以及连接信息。

我希望你发现它很有用,如果有人想帮我改进代码,那就这样吧,我需要清理代码,因为它有很多不必要的ifdef。