抓取飞信协议数据包的bash脚本
昨晚想写个抓飞信协议包的脚本,结果刚写了一点就去看电影了,今天把它给完善了一下贴出来,也顺便可以帮助大家更好地理解飞信协议,也为了更多的人能够加入到openfetion的开发中来。
其实不是我不懂“工欲善其事必先利其器”这个道理,只是之前在写openfetion的时候我只能跑到windows下去抓包,windows里面的什么vbs之类的脚本我也不会写,就用最笨的办法用wireshark把数据包抓出来然后复制到txt中,现在在linux下可以抓openfetion的数据包,它的包格式与官方飞信相同(这句是废话,要不然也不可能实现互联互通)。
简单地说一下这个脚本,其实不用说它也很简单,就这么几行,飞信在登录的时候需要向一台sipc服务器注册,随后主要的数据包都是与这台服务器之前交换的,而这台服务器我想肯定也是分布式架构了,不同的飞信号会对应于自己的sipc服务器,而服务器的地址是通过配置文件传递给客户端的,客户端在注册之前先向nav.fetion.com.cn这个地址POST一个http请求,随后服务器会响应一个大的xml,之前版本的openfeion并没有对这些数据做本地缓存,所以在每次登录的时候都需要获取这个配置文件,所以经常会有用户反应卡在“正在下载配置文件”这一步进行不下去了,现在的方法是在本地把需要用到的字段做了缓存,再次登录的时候用缓存版本号查询服务器,如果版本号是最新则会返回一个很小的xml结构,速度当然也会比完全下载快得多。
接着说这个脚本,请求到配置文件之后便会得到飞信号对应的sipc服务器地址,之后就用tcpdump来抓取通往这个地址的包和来自这个地址的包,然后就简单做了一下解析。
#!/bin/sh #written by @levin108 #This script is used to capture the packets of fetion client,and help to anlysis fetion protocol. #You need to have openfetion installed in your computer,or maybe libfetion,I don't know,whatever... if [ $UID -ne 0 ]; then echo "perminission denied,you must be root to run this script" exit 1 fi if [ $# == 0 ]; then echo -n "please input the mobile number:" read mobileno else mobileno=$1 fi if [ ${#mobileno} -ne 11 ];then echo "wrong mobile number" exit 1 fi protocol_version="4.0.2510" config_uri="http://nav.fetion.com.cn/nav/getsystemconfig.aspx" config_body="<config><user mobile-no=\"$mobileno\"/> \ <client type=\"PC\" version=\"$protocol_version\" \ platform=\"W5.1\"/><servers version=\"0\"/> \ <parameters version=\"0\"/><hints version=\"0\"/></config>" echo "Getting fetion sipc servr address..." config_xml=`curl -d "$config_body" -A "IIC2.0/PC $protocol_version" $config_uri 2> /dev/null` proxy_endpoint=`echo $config_xml | sed 's/.*<sipc-proxy>\([^<]*\).*/\1/'` proxy_ip=`echo $proxy_endpoint | sed 's/:[0-9]*$//'` proxy_port=`echo $proxy_endpoint | sed 's/.*://'` echo "Sipc server address : $proxy_ip:$proxy_port" echo "Start capturing,now start your fetion client and login." echo tcpdump -n -A -l -t -s 0 tcp and host $proxy_ip \ and port $proxy_port or host nav.fetion.com.cn 2>/dev/null | awk ' /^IP/{ if($NF == 0) { is_data_seg = 0; } else { printf("\n%s ----> %s\n", $2, $4) printf("-----------------------------------\n\n") # whether it is a data segment is_data_seg = 1; # eth/ip/tcp header length bytes_before_protocol = 52; } } !/^IP /{ if(is_data_seg) { if(length($0) < bytes_before_protocol) { bytes_before_protocol -= length($0) next; } if(length($0) >= bytes_before_protocol && bytes_before_protocol != 0) { $0 = substr($0, bytes_before_protocol); bytes_before_protocol = 0; } print $0 } } '
Recent Comments