16

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

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

我发现了一些有用的链接:

如何在 iPhone 上获取 tcp udp 开放端口列表(我无法解析此问题中返回的数据:()

iPhone 上的数据使用情况

sysctlbyname buf 返回类型(我不是网络人..无法理解这个,也许你们可以帮忙:))

TCP/UPD 端口列表

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

4

1 回答 1

11

好的,你有你需要的一切。

您可以查看问题Is there any private api to monitor network traffic on iPhone? 在这里你可以找到inet 的源代码。该代码具有解析如何在 iPhone 上获取 tcp udp 开放端口列表返回的数据所需的一切

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];
};

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

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

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

  • 原型
  • 网印
  • 网名

然后在这些函数中,您将看到解析数据的 printf,您可以将其添加到字典中。

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

我希望你觉得它有用,如果有人想帮助我改进代码,那么我需要清理代码,因为它有很多不必要的 ifdef。

于 2013-11-20T22:33:25.393 回答