質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

517閲覧

Python/Pandas:Tcpdumpデータ効率的な抽出、データマッチング不整合の解消方法

minhouse10

総合スコア41

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2018/02/10 07:41

編集2018/02/10 07:53

問題:
約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)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Pythonなど不要。そう、シェル芸ならね!

bash

1$ cat tcpdump_sample|awk '/^2018-01-31/{r=$1" "$2" "$4}r!=""&&/^0x0050/{r=r" "$4":"$5;print r;r=""}'

投稿2018/02/10 13:37

hichon

総合スコア5737

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

minhouse10

2018/02/10 15:03

hichon様、ご回答頂き、誠にありがとうございました! Linuxサーバーで早速実行した所、以下のように期待する結果が得られました。さらになぜPythonで期待する結果が得られなかったのか、Shellで実行した結果との差異を検証してみたいと思います。またこちらアップデートさせて頂きます。改めてありがとうございました。 2018-01-31 16:46:28.095476 pgm1::22:1o:2450:3203:19a3 2302:63ss
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問