종종 통신의 패킷 데이터를 따와서 프로그램을 해야 할때가 있습니다.
그래서 공부 하는김에 적어 둡니다.
일단 라이브리는 Pcap 이 패킷을 후킹해주는 라이브러리인데 C# 으로 wrap 해준 라이브러리가 있습니다.
SharpPcap 이라는 라이브러리 입니다.
사용 법은 비교적 간단하고 강력 합니다 .
예제가 마음에 듭니다.
값을 DB에 저장 하는 예제 입니다.
using PacketDotNet;
using SharpPcap;
using SharpPcap.LibPcap;
using SharpPcap.AirPcap;
using SharpPcap.WinPcap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
namespace pcappro
{
class Program
{
public static string EquipmentCode = "";
static string strConn = "Server=127.0.0.1;Database=test;Uid=test;Pwd=test!;";
public static MySqlConnection conn;
public static MySqlCommand query_cmd;
static void Main(string[] args)
{
// Print SharpPcap version
conn = new MySqlConnection(strConn);
conn = new MySqlConnection(strConn);
conn.Open();
query_cmd = new MySqlCommand("", conn);
string ver = SharpPcap.Version.VersionString;
Console.WriteLine("Chapcturing System");
// If no devices were found print an error
if (CaptureDeviceList.Instance.Count < 1)
{
Console.WriteLine("No devices were found on this machine");
return;
}
Console.WriteLine();
Console.WriteLine("사용중인 렌카드:");
Console.WriteLine("----------------------------------------------------");
Console.WriteLine();
int i = 0;
// Print out the devices
foreach (var dev in CaptureDeviceList.Instance)
{
/* Description */
Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description);
i++;
}
Console.WriteLine();
Console.Write("-- 렌카드를 선택해주세요: ");
i = int.Parse(Console.ReadLine());
Console.WriteLine();
Console.Write("-- 설비 코드를 입력해주세요: ");
EquipmentCode = Console.ReadLine();
int readTimeoutMilliseconds = 1000;
var PM1 = CaptureDeviceList.Instance[i];
var PM2 = CaptureDeviceList.New()[i]; // NOTE: the call to New()
// Register our handler function to the 'packet arrival' event
PM1.OnPacketArrival +=
new PacketArrivalEventHandler(PM1_OnPacketArrival);
PM2.OnPacketArrival +=
new PacketArrivalEventHandler(PM2_OnPacketArrival);
PM1.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
PM2.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
//필터 수정 필요
PM1.Filter = "tcp[tcpflags] == 24 and dst port 1000 and src host 10.0.0.1";
PM2.Filter = "tcp[tcpflags] == 24 and dst port 1000 and src host 10.0.0.3";
Console.WriteLine("device1.Filter {0}, device2.Filter {1}",
PM1.Filter, PM2.Filter);
Console.WriteLine();
Console.WriteLine("-- Listening on {0} {1}, hit 'Enter' to stop...",
PM1.Name, PM1.Description);
// Start the capturing process
PM1.StartCapture();
PM2.StartCapture();
// Wait for 'Enter' from the user.
var input = "";
while (!(input=="Exit"))
{
input = Console.ReadLine();
}
// Stop the capturing process
PM1.StopCapture();
PM2.StopCapture();
Console.WriteLine("-- Capture stopped.");
// Print out the device statistics
Console.WriteLine("device1 {0}", PM1.Statistics.ToString());
Console.WriteLine("device2 {0}", PM2.Statistics.ToString());
// Close the pcap device
PM1.Close();
PM2.Close();
}
private static void PM1_OnPacketArrival(object sender, CaptureEventArgs e)
{
byte[] buffbyte = new byte[e.Packet.Data.Length - 54];
Buffer.BlockCopy(e.Packet.Data, 54, buffbyte,0, e.Packet.Data.Length - 54);
string paravalue = System.Text.Encoding.UTF8.GetString(buffbyte);
paravalue= paravalue.Replace(">","");
paravalue= paravalue.Replace("\r\n", "");
string[] paravalues = paravalue.Split(' ');
Console.WriteLine("{0} {1}:{2}", "PM1",paravalues[1], paravalues[2]);
query_cmd.CommandText = String.Format("call trimmersave ('{0}','{1} {2}',{3})", EquipmentCode,"PM1", paravalues[1], paravalues[2]);
query_cmd.ExecuteNonQuery();
}
private static void PM2_OnPacketArrival(object sender, CaptureEventArgs e)
{
byte[] buffbyte = new byte[e.Packet.Data.Length - 54];
Buffer.BlockCopy(e.Packet.Data, 54, buffbyte, 0, e.Packet.Data.Length - 54);
string paravalue = System.Text.Encoding.UTF8.GetString(buffbyte);
paravalue = paravalue.Replace(">", "");
paravalue = paravalue.Replace("\r\n", "");
string[] paravalues = paravalue.Split(' ');
Console.WriteLine("{0} {1}:{2}", "PM3", paravalues[1], paravalues[2]);
query_cmd.CommandText = String.Format("call trimmersave ('{0}','{1} {2}',{3})", EquipmentCode, "PM3", paravalues[1], paravalues[2]);
query_cmd.ExecuteNonQuery();
}
}
}