我已经工作了5天,试图在iPhone上学习和实现网络监视器。 我查看了来自苹果的netstat代码,我失去了25%的头发。
我找到了JB Devices的链接,但我需要它在非JB设备上执行。 (无论Apple是否在App Store上接受它)。
我找到了一些有用的链接:
how to get tcp udp opening port list on iPhone(我无法解析此问题中返回的数据:()
sysctlbyname buf return type(我不是网络人......不能理解这一点,也许你们可以帮助:))
我可以说我从第一个链接得到了一些东西。你能帮我解析数据吗? 有没有其他方法来实现这一目标?
答案 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代码。您只需要这些功能:
然后在这些函数中你会看到解析了数据的printf,你可以在字典中添加它。
Here是我的代码。您可以看到一个名为: DHInet 的类,其中有两个方法返回带有NSDictionary列表的NSArray以及连接信息。
我希望你发现它很有用,如果有人想帮我改进代码,那就这样吧,我需要清理代码,因为它有很多不必要的ifdef。