上篇文章搭建了一個UDP多播程式的基礎,所謂基礎,就是看著它,我可以寫簡單的多播程式了,可以在這個基礎上面開始工作了。
會多播了,多播的內容從哪裡來,播出什麼內容呢?呵呵,有個裝置,沒有通訊協議,用wireshark抓包,分析協議,編程實現之,這就是此次多播的任務。
啟動wireshark,抓取資料包,匯出為文字檔,三五十兆的檔案,ultraedit搜尋,觀察,眼睛都看直了,有裝置通訊資料,還有上網瀏覽的資料,有QQ的資料,有MSN的資料,還有些不知所以的資料,看了個暈頭轉向,感覺裝置的通訊資料的結構有點規律,有門兒。咱是程式員,有啥問題看看能不能編程解決呢,上python,提取資料,這樣子會讓分析資料方便一些,還能用提取的資料做測試。
看看wireshark匯出資料格式,每個資料區段都是“NO.”開頭的,接下來的一行是源IP和目標IP,後面還有一段“Data:”標識的資料區段,有規律,我用python提取這些資料沒問題。如果規律不明顯我就沒轍了。
Python程式要完成的功能:
l 提取指定ip地址的資料,把資料包部分儲存到一個檔案A中,這就方便觀察裝置發送的資料,定義出相關的結構
l 然後從檔案A中,提取出資料部分,儲存為檔案B,我在VC程式中讀取這個檔案B,嘗試解析這些資料,如果能夠成功解析,我的工作就基本完成了
看程式。
#coding=gb18030 </p><p>import fileinput<br /># 本程式的bug:因為匯出位元據時,字串匹配以"0000 "為<br /># 開始標誌,這與wireshark匯出檔案的第一個包的時間0.000000相<br /># 同,所以第一個你要手工把0.000000改為0.000001。<br /># 本程式就是為了匯出資料加以分析,不必為了修正上面的bug繞半天<br />#</p><p># 在介紹本程式功能之前,先瞭解一下wireshark檔案的格式。<br /># wireshark匯出檔案格式,"No."是開始標誌,開始標誌的<br /># 下一行是ip地址和協議資訊,接下來是它協議分析的一些輸出<br /># 最後是Data。<br />#<br />#No. Time Source Destination Protocol Info<br /># 16 58.5 192.168.0.66 234.5.6.7 UDP Source port: 1024 Destination port: synchronet-db<br />#<br /># 這中間是wireshark分析的輸出<br />#<br />#<br />#Data (40 bytes)<br />#<br />#0000 e9 24 00 00 ff ff 01 00 02 00 00 00 d2 04 00 00 .$..............<br />#0010 14 00 00 00 42 03 01 00 00 00 00 00 05 00 00 00 ....B...........<br />#0020 02 00 00 00 33 00 00 00 ....3...<br />#</p><p>#-------------------------------------------------------<br /># 本程式的功能是讀取wireshark的匯出檔案,過濾出指定ip的資料<br /># 1. Print_Data_Text匯出從一個"No."到下一個"No."之間的內容<br /># 2. Print_Data_bin 匯出"Data "部分的內容,格式如下:<br />#e9 24 00 00 ff ff 01 00 02 00 00 00 d2 04 00 00<br />#14 00 00 00 42 03 01 00 00 00 00 00 05 00 00 00<br />#02 00 00 00 33 00 00 00<br />#----<br />#e9 24 00 00 ff ff 01 00 02 00 00 00 d2 04 00 00<br />#14 00 00 00 42 03 01 00 00 00 00 00 05 00 00 00<br />#02 00 00 00 33 00 00 00<br />#在兩個資料包之間插入了一樣"----",</p><p># 3. Print_IP_Line 僅匯出包含ip的行,就是"No."下面的那行</p><p>#-------------------------------------------------------<br /># 如何設定匯出資料的條件:<br /># 匯出資料的條件<br /># and欄位的內容必須全部滿足<br /># or欄位的內容,至少滿足一個<br /># and 欄位和 or 欄位都滿足<br /># 如果and欄位不存在,則認為條件滿足<br /># 如果or欄位不存在,則認為條件滿足<br />#No. Time Source Destination Protocol Info<br />#14 9.949685 192.168.0.66 234.5.6.7 UDP Source port: onehome-remote Destination port: synchronet-db<br /># 舉例:<br /># 匯出滿足下麵條件的資料:<br /># No.下面一行的資料,包含"234.5.6.7"和"UDP",<br /># 並且包含"192.168.0.202"和"192.168.0.22"之一<br /># cond = []<br /># cond.append({<br /># "and":["234.5.6.7", "UDP"],<br /># "or":["192.168.0.202", "192.168.0.22"],<br /># })<br />#<br />#-------------------------------------------------------</p><p># 匯出滿足條件的資料, 為了在匯出的檔案中能看到資料是從<br /># 源檔案的那個地方來的,匯出的資料可以帶有行號資訊,行號<br /># 添加在每行資料的前面<br /># fileName: 未經處理資料檔案名稱<br /># saveto : 匯出資料儲存檔案名稱<br /># cond : 資料需要滿足的條件<br /># with_ln_number : 匯出資料時是否帶行號<br /># 只有帶行號的資料,才能被Print_Data_bin函數使用<br />def Print_Data_Text(fileName, saveto, cond, with_ln_number=True):<br /> f1 = open(saveto, 'w+')</p><p> ln = []<br /> myfile = fileinput.input(fileName)<br /> for x in myfile:<br /> ln.append(x)<br /> start_flag = 0<br /> start_ln = 0<br /> end_ln = 0<br /> end_flag = 0<br /> find_count = 0<br /> print " "<br /> for i in range(0,len(ln)):</p><p> if ln[i].find("No.") == 0 and start_flag == 1:<br /> start_flag = 0<br /> if ln[i].find("No.") == 0 and start_flag == 0:<br /> if Check_Expr(ln[i+1], cond)==True:<br /> start_ln = i<br /> start_flag = 1<br /> find_count = find_count + 1<br /> msg = ""<br /> msg = ("/b/b/b/b/b/b/b%02d")%(find_count)<br /> print msg,</p><p> if start_flag == 1:<br /> msg = ""<br /> if with_ln_number == True:<br /> msg = ("%08d:/t%s")%(i+1,ln[i])<br /> else:<br /> msg = ("%s")%(ln[i])</p><p> f1.write(msg)</p><p> f1.close()</p><p># 匯出資料包中的Data欄位的內容<br /># 通過,尋找 "0000 "作為開始標誌<br /># 尋找"Data:"作為結束標誌<br />def Print_Data_bin(fileName, saveto, data_start, data_end, with_ln_number=True):<br /> f1 = open(saveto, 'w+')<br /> ln = []<br /> myfile = fileinput.input(fileName)<br /> for x in myfile:<br /> ln.append(x)<br /> start_flag = 0<br /> start_ln = 0<br /> end_ln = 0<br /> end_flag = 0<br /> find_count = 0<br /> print " "<br /> for i in range(0,len(ln)):</p><p> if start_flag == 0 and Check_Expr(ln[i], data_start)==True:<br /> start_flag = 1<br /> msg = ("%s/n")%(ln[i][16:63])<br /> f1.write("----/n")<br /> if start_flag == 1 and Check_Expr(ln[i], data_end)==True:<br /> start_flag = 0</p><p> if start_flag == 1:<br /> msg = ""<br /> if with_ln_number == True:<br /> msg = ("%s/n")%(ln[i][16:63])<br /> else:<br /> msg = ("%s/n")%(ln[i][6:53])</p><p> f1.write(msg)<br /># if i > 100:<br /># break<br /> f1.close()</p><p>def Check_Expr(ln, expr):<br /> expr_flag = False<br /> for x in expr:<br /> and_flag = True<br /> or_flag = False<br /> if 'and' in x:<br /> for y in x["and"]:<br /> if ln.find(y) == -1:<br /> and_flag = False<br /> break</p><p> if 'or' in x:<br /> for y in x["or"]:<br /> if ln.find(y) != -1:<br /> or_flag = True<br /> break<br /> else:<br /> or_flag = True</p><p> if and_flag == True and or_flag == True:<br /> expr_flag = True<br /> break<br /> return expr_flag</p><p>#<br /># 為了方便查看資料網來,只<br /># 列印帶有IP地址的那行資料<br />#<br />def Print_IP_Line(fileName, saveto,cond):<br /> f1 = open(saveto, 'w+')<br /> ln = []<br /> myfile = fileinput.input(fileName)<br /> for x in myfile:<br /> ln.append(x)<br /> start_flag = 0<br /> start_ln = 0<br /> end_ln = 0<br /> end_flag = 0<br /> find_count = 0<br /> print " ",<br /> for i in range(0,len(ln)):</p><p> if ln[i].find("No.") == 0:<br /> if Check_Expr(ln[i+1], cond) == True:<br /> start_ln = i+1<br /> start_flag = 1<br /> find_count = find_count + 1<br /> msg = ""<br /> msg = ("/b/b/b/b/b/b/b/b%02d")%(find_count)<br /> print msg,</p><p> if start_flag == 1:<br /> msg = ""<br /> msg = ("%08d:/t%s")%(start_ln+1,ln[start_ln])<br /> f1.write(msg)<br /> start_flag = 0</p><p> f1.close()</p><p>if __name__ == '__main__': </p><p> src_data_file = "c://ws.txt"<br /> txt_data_file_11 = "d://RE_11.txt"<br /> bin_data_file_11 = "d://bin_11.txt"<br /> txt_data_file_66 = "d://RE_66.txt"<br /> bin_data_file_66 = "d://bin_66.txt"<br />#<br /># 匯出資料的條件<br /># and欄位的內容必須全部滿足<br /># or欄位的內容,至少滿足一個<br /># and 欄位和 or 欄位都滿足<br /># 如果and欄位不存在,則認為條件滿足<br /># 如果or欄位不存在,則認為條件滿足<br /># 舉例:<br />#No. Time Source Destination Protocol Info<br />#14 9.949685 192.168.0.202 234.5.6.7 UDP Source port: onehome-remote Destination port: synchronet-db<br /># 匯出滿足下麵條件的資料:<br /># No.下面一行的資料,包含"234.5.6.7"和"UDP",並且並且包含"192.168.0.202"和"192.168.0.22"之一<br /># cond = []<br /># cond.append({<br /># "and":["234.5.6.7", "UDP"],<br /># "or":["192.168.0.202", "192.168.0.22"],<br /># })<br /># </p><p> cond = []<br /> cond.append({<br /> "and":["234.5.6.7", "UDP"],<br /> "or":["192.168.0.202", "192.168.0.22"],<br /> })</p><p> getdata_start = []<br /> getdata_start.append({<br /> "and":["0000 "],<br /> })<br /> getdata_end = []<br /> getdata_end.append({<br /> "and":["Data: "],<br /> })</p><p># print getdata_start<br /># Print_IP_Line('c://RE.txt',cond)<br /> filter_data_11 = []<br /> filter_data_11.append({<br /> "and":["192.168.0.22", "234.5.6.7", "UDP"],<br /> })<br /> filter_data_66 = []<br /> filter_data_66.append({<br /> "and":["192.168.0.202", "234.5.6.7", "UDP"],<br /> })</p><p> Print_Data_Text(src_data_file, txt_data_file_11, filter_data_11)<br /> Print_Data_bin(txt_data_file_11, bin_data_file_11,getdata_start, getdata_end)<br /> Print_Data_Text(src_data_file, txt_data_file_66, filter_data_66)<br /> Print_Data_bin(txt_data_file_66, bin_data_file_66,getdata_start, getdata_end)<br /> Print_Data_bin(src_data_file, "d://ttxx1.txt",getdata_start, getdata_end, 0)<br /> Print_IP_Line(src_data_file,"d://ttxx2.txt", cond)<br />