問題:
約2GBのTCPDUMPのデータがあり、Python/Pandasを利用して各Tcpdumpのセッションから下記条件にマッチする2つの情報を抜き出しペアリングしデータの整形、更なる分析を行いたいのですが、欠損または破損したデータを含むためか2つの情報の数が一致せずペアリングした結果に不整合が生まれてしまいます。(それぞれ2つのデータを検索しカウントすると数にズレがあり、結果異なるセッションからの情報をペアリングしてしまっている)同様のデータ構成で少ないサンプリングデータでは2つの情報に欠損・破損がないため期待した結果を得る事ができております。
- 日付情報2018-01-31を含む一行目とペイロード情報から0x0050:から始まる行だけを抽出しペアリングする
- 上記2つの情報は一つのセッションの中に必ず存在する前提
- 日付情報2018-01-31を含む一行目をプライマリキーとして扱い、ペイロード情報から0x0050:から始まる行は付帯する情報としたい
プライマリキーとして扱いたい日付情報2018-01-31を含む一行目と付帯情報とする0x0050:から始まるペイロード情報をそれぞれ別のデータフレームを作り、それぞれ整形処理した上で2つのデータフレームを結合してするステップがコードとして良くないのではと考えておりますが、そもそもプライマリキーとするための明示的なコード記述が無い事と、プログラムは2つの情報の数が異なると判断されているため付帯情報となる0x0050:が何らかの理由で存在せずペアリングができなかった場合は、対象データが無い・失敗等の判断ができればと思います。アドバイス・ご教授頂けますと幸いです。
データ構成:
2018-01-31 17:01:36.900603 IP6 pgm1::54:1c:4400:5501:180.617 > pg00:0:0:XX::XXX.XXX: UDP, length 68
0x0000: 6e80 0000 004c 11f9 fda1 0000 0000 0054
0x0010: 001c 6400 3201 0180 fd00 0000 0000 0012
0x0020: 0000 0000 0000 0011 02cc 02cc 004c aaa7
0x0030: 0000 0044 0000 0005 0000 0000 0000 0000
0x0040: 000a 0000 0012 0000 fe80 0000 0000 0000
0x0050: 001c 8500 3901 2464 02cc 0000 000b 0000
0x0060: 0010 0000 0000 0010 0000 0001 0000 0000
0x0070: 0000 0000 0006 0000 0004 0000 0000 0005
0x0080: 0003 0000
コード実行結果:
Pandas データフレームを出力した結果。実際のペアリング結果と元の生Tcpdumpデータで比較した結果SourceIPと0x0050:列の情報がマッチせず異なるセッションの情報がペアリングされてしまっている。以下の正常例では3901:2464となっているが、異常例では3901:2464となるはずが別のセッションから異なる0x0050:の情報になってしまっている。
Date SourceIP 0x0050:
2018-01-30 21:32:19.576975 pgm1::54:1c:4400:5501:180 3901:2464
...
コード:
%matplotlib inline import sys, os, codecs, datetime, shutil, re, math, csv import pandas as pd import numpy as np import matplotlib.pyplot as plt #N行1列のデータフレームができる df = pd.read_table('tcpdump_sample', names="N") #2018-01または0x0050を含む行のみを抽出する df = df[df['N'].str.contains('2018-01|0x0050:')] df = df.reset_index(drop=True) #2018-01を含むデータのみで新データフレームdf1を作る df1 = df[df['N'].str.contains('2018-01')] df1 = df1.reset_index(drop=True) #0x0050:を含むデータのみで新データフレームdf2を作る df2 = df[df['N'].str.contains('0x0050:')] df2 = df2.reset_index(drop=True) #スペースで区切り不要な情報を消すための整形処理 df1 = df1.iloc[:,0].apply(lambda x: pd.Series(x.split())) df1 = df1.drop(df1.columns[[2,4,5,6,7,8]], axis=1) df1['Date'] = df1[[0,1]].apply(lambda x: '{} {}'.format(x[0],x[1]), axis=1) df1 = df1.drop(0, axis=1) df1 = df1.drop(1, axis=1) #スペースで区切り不要な列情報を消すための整形処理 df2 = df2.iloc[:,0].apply(lambda x: pd.Series(x.split())) df2 = df2.drop(df2.columns[[0,1,2,5,6,7,8,9]], axis=1) df2['0x0050:'] = df2[[3,4]].apply(lambda x: '{} {}'.format(x[3],x[4]), axis=1) df2 = df2.drop(3, axis=1) df2 = df2.drop(4, axis=1) #0x0050:列の各データの整形処理、スペースを:に置換 df2['0x0050:'] = df2['0x0050:'].str.replace(" ",":") #2つのデータフレームを結合し新df_newとする df_new = pd.concat([df1,df2], axis=1) #Date列をdatetimeに変更かつIndex化 df_new['Date'] = pd.to_datetime(df_new['Date']) df_new = df_new.set_index('Date') #列3で'pgm1'を含む行だけを抽出 df_new = df_new[df_new[3].str.contains('pgm1')] df_new.columns = ['SourceIP','0x0050:'] #列'SourceIP'で".617"不要なので消す df_new['SourceIP'] = df_new['SourceIP'].str.replace(".617","") #IPV6アドレスpgm1::54:1c:4400:5501:180で:440xから右側は不要なので消す df_new['SourceIP'] = df_new.iloc[:,0].apply(lambda x: pd.Series(x.rsplit("440"))) print(df_new)
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/02/10 15:03