WinPcap 2.3
Пользователи, просматривающие топик: none
|
Зашли как: Guest
|
Имя |
Сообщение |
<< Старые топики Новые топики >> |
|
|
WinPcap 2.3 - 2009-10-01 19:06:25.750000
|
|
|
ArtAdmin
Сообщений: 11556
Оценки: 14
Присоединился: 2007-01-17 16:55:01.430000
|
Обсуждение статьи "WinPcap 2.3"
|
|
|
SeyCom; e-mail: za@chem.vam - 2009-10-01 19:06:26.020000
|
|
|
Guest
Сообщений: 83368
Оценки: 51
Присоединился: None
|
Народ, это ВЕЩЬ. Автор не точен, с помощью этой вещи можно еще без проблем реализовать IP-спуфинг под виндами! Заголовочные файлы там конечно на Си, но дельфятники, в инете кое-где есть и заголовочные файлы для Дельфи… ищите и обрящете! :)
|
|
|
SharpPcap - 2009-10-01 19:06:26.256666
|
|
|
Guest
Сообщений: 83368
Оценки: 51
Присоединился: None
|
лучше использовать SharpPcap для разработки сетевых приложений в MS Visual Studio
|
|
|
отправка пакета из SharpPcap - 2009-10-02 15:08:34.670000
|
|
|
79084195O6O
Сообщений: 321
Оценки: 0
Присоединился: 2009-09-25 14:44:51.560000
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Timers;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Threading;
using SharpPcap;
using SharpPcap.Packets;
using SharpPcap.Protocols;
using SharpPcap.Packets.Util;
using SharpPcap.Util;
using SharpPcap.Containers;
using System.Net.NetworkInformation;
using System.ComponentModel;
namespace RIP
{
/// <summary>
/// Класс является хранилищем инфомрации о
/// IP и MAC адресе сетевого устройства.
/// </summary>
class Adresses
{
/// <summary>
/// В переменной хранится IP адрес сетевого устройства
/// </summary>
public IPAddress ip;
/// <summary>
/// В переменной хранится MAC адрес сетевого устройства
/// </summary>
public PhysicalAddress mac;
}
/// <summary>
/// Класс является хранилищем информации о принятом или переданном
/// пакете.
/// </summary>
class PacketInfo
{
/// <summary>
/// Переменная хранит IP адрес отправителя пакета
/// </summary>
private IPAddress sourceIP;
/// <summary>
/// Переменная хранит IP адрес получателя пакета
/// </summary>
private IPAddress destIP;
/// <summary>
/// Переменная хранит информацию о типе пакета (входящий\исходящий)
/// </summary>
private TypeOfPacket type;
/// <summary>
/// Перечисление типов пакета (входящий\исходящий)
/// </summary>
public enum TypeOfPacket : byte
{
input,
output
}
/// <summary>
/// Время получения\отправки пакета
/// </summary>
private DateTime time;
/// <summary>
/// Конструктор создающий экземпляр класса PacketInfo. Все поля заполняются в конструкторе.
/// </summary>
/// <param name="sourceIP_">IP адрес отправителя пакета</param>
/// <param name="destIP_">IP адрес получателя пакета</param>
/// <param name="type_">Тип пакета</param>
public PacketInfo(IPAddress sourceIP_, IPAddress destIP_, TypeOfPacket type_)
{
sourceIP = sourceIP_;
destIP = destIP_;
type = type_;
time = DateTime.Now;
}
/// <summary>
/// Представляет экземпляр класса PacketInfo в виде строки вида:
/// "тип пакета" From: "адрес отправителя" To: "адрес получателя" | время |
/// </summary>
/// <returns></returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(type);
sb.Append(" From:");
sb.Append(sourceIP);
sb.Append(" To:");
sb.Append(destIP);
sb.Append(" | ");
sb.Append(time.ToString("HH:mm:ss,ffff"));
sb.Append(" |");
return sb.ToString();
}
}
/// <summary>
/// Класс RipRouter осуществляет работу части логики маршрутизатора, работающего
/// по протоколу RIPv1
/// </summary>
class RipRouter
{
/// <summary>
/// Хранилище всех поддерживаемых устройств, устройство должно иметь IPv4.
/// Ограничено 48 устройствами.
/// </summary>
public List<PcapDevice> networkInterfaces = new List<PcapDevice>(48);
/// <summary>
/// Хранилище IP и MAC адресов поддерживаемых устройств.
/// Ограничено 48 устройствами.
/// </summary>
public List<Adresses> networkInterfacesAddr = new List<Adresses>(48);
/// <summary>
/// Таймер отправки все таблицы маршрутизации.
/// </summary>
private System.Windows.Forms.Timer rtSendingTimer = new System.Windows.Forms.Timer();
/// <summary>
/// Таблица маршрутизации класса "RIP машрутизатора".
/// </summary>
public RoutingTable<RoutingElement> routingTable = new RoutingTable<RoutingElement>();
/// <summary>
/// Хранилище всех переданных\полученных пакетов.
/// </summary>
public BindingList<PacketInfo> packets = new BindingList<PacketInfo>();
/// <summary>
/// Хранилище информации об активных маршутизаторах.
/// </summary>
public BindingList<IPAddress> activeRouter = new BindingList<IPAddress>();
/// <summary>
/// Хранилище содержимого всех полученных\переданных пакетов(Ограничено 100000 пакетов).
/// </summary>
public List<RIPPacket> ripPacketsInfo = new List<RIPPacket>(100000);
/// <summary>
/// Переменная хранит состояние "маршрутизатора"
/// </summary>
private bool started;
/// <summary>
/// Свойство, возвращает состояние "маршрутизатора"
/// </summary>
public bool Started
{
get
{
return started;
}
}
/// <summary>
/// Метод обновляет список всех поддерживаемых устройств в объекте класса RipRouter.
/// </summary>
public void UpdateNetworkInterfaces()
{
//Список всех сетевых устройств в системе
List<PcapDevice> devicesList = Pcap.GetAllDevices();
//Цикл перебора всех устройств
for (int i = 0; i < devicesList.Count; i++)
{
//Цикл перебора всех адресов устройства
for (int k = 0; k < devicesList[i].Addresses.Count; k++)
{
//Если у устройтсва IP адрес не пустой и не равен 0.0.0.0
if ((devicesList[i].Addresses[k].Addr.ipAddress != null)&&
(devicesList[i].Addresses[k].Addr.ipAddress.ToString() != "0.0.0.0" ))
{
//Если IP адрес принадлежит к семейству IPv4
if (devicesList[i].Addresses[k].Addr.ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
//Добавляем устройство в список поддерживаемых
networkInterfaces.Add(devicesList[i]);
Adresses addr = new Adresses();
//Записываем IP адрес устройства в промежуточную переменную
addr.ip = devicesList[i].Addresses[k].Addr.ipAddress;
//Записываем MAC адрес устройства в промежуточную переменную
addr.mac =
devicesList[i].Addresses[devicesList[i].Addresses.Count - 1].Addr.hardwareAddress;
//Добавляем адрес устройства в список адресов поддерживаемых устройств
networkInterfacesAddr.Add(addr);
}
}
}
}
}
/// <summary>
/// Метод сопоставляет таблицу маршрутизации объекта класса RipRouter
/// с передаваемой в метод таблицей. Добавляет или модифицирует поля "своей" таблицы,
/// если это необходимо.
/// </summary>
/// <param name="recieveRoutingTable">Таблица маршрутизации с которой будут сравнивать
/// "свою" таблицу.
/// </param>
private void UpdateRoutingTable(RoutingTable<RoutingElement> recieveRoutingTable)
{
//Перебор всех элементов полученной
for (int i = 0; i < recieveRoutingTable.Count; i++)
{
//Если в "своей" таблице нету элемента с IP адресом, который есть в
//полученной таблице
if (routingTable.IndexOf(recieveRoutingTable[i].IpAddress) == -1)
{
//Если этому адреса присвоена метрика не больше 14
if (recieveRoutingTable[i].Metric < 15)
{
//Добавить к метрике единицу
RoutingElement re = new RoutingElement(recieveRoutingTable[i].IpAddress,2,
(byte)(recieveRoutingTable[i].Metric+1),recieveRoutingTable[i].NetworkPort);
//Добавить этот элемент к "своей" таблице
routingTable.Add(re);
}
}
//Если элемент уже есть в "своей" таблице
else
{
//Если у существующего элемента метрика больше, чем полученная метрика + 1
if (routingTable[routingTable.IndexOf(recieveRoutingTable[i].IpAddress)].Metric >
recieveRoutingTable[i].Metric + 1)
{
//Изменить существующую запись в таблице
routingTable[routingTable.IndexOf(recieveRoutingTable[i].IpAddress)] =
recieveRoutingTable[i];
//Добавить к метрике единицу
routingTable[routingTable.IndexOf(recieveRoutingTable[i].IpAddress)].Metric++;
}
}
}
}
/// <summary>
/// Метод создает минимальную таблицу маршрутизации
/// </summary>
public void CreateMinRoutingTable()
{
byte[] buff = new byte[4];
for (int i = 0; i < networkInterfacesAddr.Count; i++)
{
//Записываем в промежуточный массив байт, адрес IPv4 поддерживаемого устройства
buff = networkInterfacesAddr[i].ip.GetAddressBytes();
//Последний байт обнуляем, т.е. получаем адрес сети
buff[3] = 0;
// Если в таблице еще нету сети с таким адресом
if (routingTable.IndexOf(new IPAddress(buff)) == -1)
{
//Добавляем элемент в табилцу маршрутизации с метрикой 1 и портом, через который
//эта сеть достижима равняется индексу в списке поддерживаемых устройств
routingTable.Add(new RoutingElement(new IPAddress(buff), 2, 1, i));
}
}
}
/// <summary>
/// Констурктор, создает экземпляр класса RipRouter
/// </summary>
public RipRouter()
{
//Обновляем список поддерживаем устройств
UpdateNetworkInterfaces();
//Создаем минимальную таблицу маршрутизации
CreateMinRoutingTable();
//Устанавливаем таймер в нерабочее состояние
rtSendingTimer.Enabled = false;
//Интервав таймера 30 секунд
rtSendingTimer.Interval = 30000;
rtSendingTimer.Tick += new EventHandler(rtSendingTimer_Tick);
started = false;
}
/// <summary>
/// Метод добавляет в хранилице пактов информацию о пакете, и в хранилице содержимого пакетов
/// добавляет элемент содержащий сам пакет.
/// </summary>
/// <param name="sourceIP">Отправитель пакета</param>
/// <param name="destIP">Получатель пакета</param>
/// <param name="type">Тип пакета</param>
/// <param name="ripPacket">Содержимое пакета</param>
private void AddPacket(IPAddress sourceIP, IPAddress destIP, PacketInfo.TypeOfPacket type, RIPPacket ripPacket)
{
packets.Add(new PacketInfo(sourceIP, destIP, type));
ripPacketsInfo.Add(ripPacket);
}
/// <summary>
/// Метод передает всю свою таблицу маршрутизации по протоклу RIP
/// </summary>
private void SendAllRoutingTable()
{
//В RIP пакете может содержатсья не более 25 элементов
//маршрутной инфомрации, поэтому определяем необходимое количество
//RIP пакетов для передачи всей таблицы маршрутизации
// (int) - будет округялть в меньшую сторону.
int numOfRipPacket = (int)routingTable.Count / 25;
//Если число пакетов равно 0
if (numOfRipPacket == 0)
{
//Отправляем через все поддерживаемые устройства "свою" таблицу маршрутизации
for (int i = 0; i < networkInterfaces.Count; i++)
{
Send(networkInterfaces[i], new RIPPacket(RIPPacket.CommandType.Response, routingTable));
}
}
else
{
//Создаем новую промежуточную таблицу маршрутизации
RoutingTable<RoutingElement> rTable = new RoutingTable<RoutingElement>();
for (int i = 0; i < networkInterfaces.Count; i++)
{
//Осущесвляем перебор всех пакетов необходимых для отправки
for (int numOfRipPacket_ = 0; numOfRipPacket_ < numOfRipPacket; numOfRipPacket_++)
{
//Перебор каждого элемента в таблице для отправки
for (int j = 0; j < 25; j++)
{
//Добавляем в новую таблицу соответсвующий элемент из своей
rTable.Add(routingTable[numOfRipPacket_ * 25 + j]);
}
//Отправка таблицы
Send(networkInterfaces[i], new RIPPacket(RIPPacket.CommandType.Response, rTable));
//Очистка таблицы для последующие записи
rTable.Clear();
}
//Если число элементов в своей таблице не кратно 25
if (routingTable.Count % 25 != 0)
{
//Осуществляем перебор всех оставшихся элементов
for (int j = 0; j < routingTable.Count % 25; j++)
{
//Записывем в таблицу для отправки
rTable.Add(routingTable[numOfRipPacket * 25 + j]);
}
Send(networkInterfaces[i], new RIPPacket(RIPPacket.CommandType.Response, rTable));
}
}
}
}
/// <summary>
/// Обработчик события истечения времени таймера
/// </summary>
/// <param name="sender">Источник</param>
/// <param name="e">Параметр</param>
private void rtSendingTimer_Tick(object sender, EventArgs e)
{
SendAllRoutingTable();
}
/// <summary>
/// Метод отправки пакета через сетевое устройство
/// </summary>
/// <param name="device">Устройство, через которое будет осуществляться
/// отправка
/// </param>
/// <param name="ripPacket">Rip пакет, который необходимо передать</param>
private void Send(PcapDevice device, RIPPacket ripPacket)
{
//Массив байт заголвка Ethernet
byte[] ethernet = new byte[54];
//Общая длина сообщения, со всемии заголовками
int packetLenght = ripPacket.Lenght + EthernetFields_Fields.ETH_HEADER_LEN +
IPv4Fields_Fields.IP_HEADER_LEN + UDPFields_Fields.UDP_HEADER_LEN;
UDPPacket udpPacket = new UDPPacket(EthernetFields_Fields.ETH_HEADER_LEN, ethernet);
//MAC - адрес назначения (устанвливаем широковещательный)
udpPacket.DestinationHwAddress = PhysicalAddress.Parse("FFFFFFFFFFFF");
//МАС - адрес источника
try
{
//Береться из списка адресов поддерживаемых устройств
udpPacket.SourceHwAddress = networkInterfacesAddr[networkInterfaces.IndexOf(device)].mac;
}
catch
{
udpPacket.SourceHwAddress = new PhysicalAddress(PhysicalAddress.Parse("0ABCDEF").GetAddressBytes());
}
//Какой протокл переносит свою информацию в Ethernet пакете
udpPacket.EthernetProtocol = EthernetPacket.EtherType.IP;
// -----------IP------------
udpPacket.IPVersion = IPPacket.IPVersions.IPv4;
udpPacket.DestinationAddress = IPAddress.Parse("255.255.255.255");
udpPacket.SourceAddress = networkInterfacesAddr[networkInterfaces.IndexOf(device)].ip;
udpPacket.IPProtocol = IPProtocol.IPProtocolType.UDP;
udpPacket.TimeToLive = 1;
udpPacket.IPTotalLength = packetLenght - EthernetFields_Fields.ETH_HEADER_LEN;
udpPacket.IPHeaderLength = IPv4Fields_Fields.IP_HEADER_LEN;
// -----------UDP------------
udpPacket.SourcePort = 520;
udpPacket.DestinationPort = 520;
udpPacket.SetData(ripPacket.GetBytes());
udpPacket.ComputeIPChecksum();
udpPacket.ComputeUDPChecksum();
//Добавляем пакет в список переданных\полученных пакетов
AddPacket(udpPacket.SourceAddress, udpPacket.DestinationAddress,
PacketInfo.TypeOfPacket.output, ripPacket);
try
{
device.SendPacket(udpPacket.Bytes);
}
catch (PcapDeviceNotReadyException ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// Метод отправляет RIP пакет формата "запрос на передачу всей таблицы маршрутизации"
/// </summary>
/// <param name="device">Устройство через которое будет передаваться пакет</param>
public void SendRequest(PcapDevice device)
{
Send(device, RIPPacket.RequestRIPPacket());
}
/// <summary>
/// Метод начала работы маршрутизатора
/// </summary>
/// <param name="rtSending">
/// Если true маршуртизатор включает таймер отправки всей таблицы маршрутизации через каждые 30 секунд
/// </param>
public void Start(bool rtSending)
{
for (int i = 0; i < networkInterfaces.Count; i++)
{
try
{
//Добавляем обработчик события принятого\переданного пакет для каждого устройства
networkInterfaces[i].OnPacketArrival += new Pcap.PacketArrivalEvent(RipRouter_OnPacketArrival);
//Открывает устройство
networkInterfaces[i].Open(true);
//Создаем фильтр - "захват только udp пакетов"
string filter = "udp";
//Устанавливаем созданный фильтр устройству
networkInterfaces[i].SetFilter(filter);
//Начинаем захват пакетов
networkInterfaces[i].StartCapture();
//Посылаем соседям запрос на передачу всей таблицы маршрутизации
SendRequest(networkInterfaces[i]);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
started = true;
rtSendingTimer.Enabled = rtSending;
}
/// <summary>
/// Обработчик события захвата пакетов
/// </summary>
/// <param name="sender">источник</param>
/// <param name="e">параметр</param>
private void RipRouter_OnPacketArrival(object sender, PcapCaptureEventArgs e)
{
Packet packet = e.Packet;
PcapDevice device = e.Device;
//Если принятый\переданный пакет IP
if (packet is IPPacket)
{
IPPacket ip = (IPPacket)packet;
//Если контрольная сумма верна и IP пакет переносит UDP пакет
if ((ip.ValidIPChecksum == true) && (packet is UDPPacket))
{
UDPPacket udpPacket = (UDPPacket)ip;
//Если UDP пакет отправляется из 520 порта в 520
if ((udpPacket.SourcePort == 520) && (udpPacket.DestinationPort == 520) &&
//и у UDP пакета верная контрольная сумма
(udpPacket.ValidUDPChecksum == true) &&
//в UDP пакете данные соответсвуют структуре RIP пакета
(RIPPacket.IsRip(udpPacket.Data) == true) &&
//IP адрес источника не соответсвуют IP адресу устроства
//Это сделано, чтобы не обрабатывать передаваемые пакеты
(networkInterfacesAddr[networkInterfaces.IndexOf(device)].ip.ToString()) != udpPacket.SourceAddress.ToString())
{
RIPPacket ripPacket = new RIPPacket(udpPacket.Data, networkInterfaces.IndexOf(device));
AddPacket(udpPacket.SourceAddress, udpPacket.DestinationAddress,
PacketInfo.TypeOfPacket.input, ripPacket);
//Добавляем IP адрес источника пакета в список активных маршрутизаторов
if (activeRouter.IndexOf(udpPacket.SourceAddress) == -1)
{
activeRouter.Add(udpPacket.SourceAddress);
}
//Обработка принятых RIP пакетов, согласно типу комманды
switch (ripPacket.Command)
{
//Если комманда - запрос
case 1:
//Если версия RIPv1
if ((ripPacket.Version == 1) &&
//Число элементов маршрутнйо инфомрации в пакете равно одному
(ripPacket.routingTable.Count == 1) &&
//Элемент маршрутной инфомрации имеет адрес 0.0.0.0
(ripPacket.routingTable[0].IpAddress.ToString() == "0.0.0.0") &&
//Метрику 16
(ripPacket.routingTable[0].Metric == 16) &&
//Семейство адресов 0х00
(udpPacket.Data[5] == 0x00))
{
//Отправить всю таблицу маршрутизации
SendAllRoutingTable();
}
return;
// Если комманда - ответ
case 2:
// Если версия RIPv1
if (ripPacket.Version == 1)
{
//Обновить таблицу маршутизации
UpdateRoutingTable(ripPacket.routingTable);
}
return;
}
}
}
}
}
/// <summary>
/// Статический метод, который представляет списко поддерживаемых адресов
/// в текстовом виде
/// </summary>
/// <param name="networkInterfacesAddr_">
/// Список адресов поддерживаемых устройств
/// </param>
/// <returns></returns>
public static string GetNetworkInterfacesNames(List<Adresses> networkInterfacesAddr_)
{
StringBuilder sb = new StringBuilder();
for(int i=0; i< networkInterfacesAddr_.Count; i++)
{
sb.Append("Порт ");
sb.Append(i.ToString());
sb.Append(":\n");
sb.Append("IP-адрес: ");
sb.Append(networkInterfacesAddr_[i].ip.ToString());
sb.Append("\n");
sb.Append("MAC-адрес: ");
sb.Append(networkInterfacesAddr_[i].mac.ToString());
sb.Append("\n");
}
return sb.ToString();
}
/// <summary>
/// Метод останавливает работу маршрутизатора
/// </summary>
public void Stop()
{
for (int i = 0; i < networkInterfaces.Count; i++)
{
//Если устровства открыты
if (networkInterfaces[i].Opened)
{
try
{
//Если устроство осуществляет захват пакетов
if (networkInterfaces[i].Started)
//Остановить захват
networkInterfaces[i].StopCapture();
//Закрыть устройство
networkInterfaces[i].Close();
}
catch(PcapException ex)
{
MessageBox.Show(ex.Message);
}
}
rtSendingTimer.Enabled = false;
started = false;
}
}
}
}
это точно… второй день ковыряю SharpPcap и все никак не пойму, как там собрать нужный пакет самому ручками… может у кого уже есть готовое решение?
|
|
|
Please pay attantion - 2010-05-24 13:00:29.076666
|
|
|
Guest
Сообщений: 83368
Оценки: 51
Присоединился: None
|
WinPCAP не работает через соединение PPPoE
|
|
|
attantion - 2010-06-11 09:34:54.850000
|
|
|
79084195O6O
Сообщений: 321
Оценки: 0
Присоединился: 2009-09-25 14:44:51.560000
|
up
|
|
|
|
|