Eth p all windows

from socket import socket, AF_PACKET, SOCK_RAW

ETH_P_ALL = 0x0003

print(«Starting»)

interface = «enx7cc2c65485c0»

# interface_mac = 7c:c2:c6:54:85:c0

# Note: When sending ethernet frames, only the following data is actually supplied at this level:

# — Destination MAC

# — Source MAC

# — EtherType

# — Payload data

arp_packet = bytearray([

# Ethernet frame data exposed at this level (missing Preamble / Start of frame delimiter from hardware level)

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # Destination MAC (broadcast)

0x7c, 0xc2, 0xc6, 0x54, 0x85, 0xc0, # Source MAC

0x08, 0x06, # EtherType (0x0806 for ARP)

# ARP packet data starts here

0x00, 0x01, # Hardware type (Ethernet)

0x08, 0x00, # Protocol type (IPv4)

0x06, # Hardware size

0x04, # Protocol size

0x00, 0x01, # Opcode (request)

0x7c, 0xc2, 0xc6, 0x54, 0x85, 0xc0, # Sender MAC address

0xC0, 0xA8, 0x01, 0x02, # Sender IP address

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Target MAC address (unknown)

0xC0, 0xA8, 0x01, 0x01, # Target IP address

# No padding or frame check sequence CRC is added here either

])

ethernet_frame = bytearray([

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # Destination MAC (broadcast)

0x00, 0x11, 0x22, 0x33, 0x44, 0x55, # Source MAC

0x12, 0x34, # Custom EtherType (0x1234)

# Payload (just some test data)

0xde, 0xad, 0xbe, 0xef # Example payload

])

# AF_PACKET is a low-level interface to network devices

# SOCK_RAW, when combined with AF_PACKET, refers to raw ethernet packets

with socket(AF_PACKET, SOCK_RAW) as raw_socket:

print(raw_socket)

print(f»Binding to interface: {interface}«)

raw_socket.bind((interface, ETH_P_ALL))

print(«Sending raw ARP packet»)

bytes_sent = raw_socket.send(arp_packet)

# bytes_sent = raw_socket.send(ethernet_frame)

print(f»Sent {bytes_sent} bytes to the interface»)

Сразу скажу: то, чем мы с вами будем здесь заниматься, не претендует, скажем, на какую-то промышленную применимость. Более того, я признаю, что мой код в данном примере может быть ужасен, страшен и ненужен. И тем не менее — почему бы не поперехватывать пакеты посреди недели? Так, слегка.

Итак, сегодня мы вот что наколдуем:

1. Реализуем простейший пассивный перехватчик пакетов для TCP и UDP
2. Засунем его в C-библиотеку в виде расширения для Python
3. Приделаем ко всему этому интерфейс итератора, дабы байты сыпались, как из рога изобилия
4.…
5. PROFIT!

Зачем все это нужно?

Зачем нужны снифферы? Чтобы нюхать сетевой трафик. Нет, я не шучу, с английского глагол «to sniff» так и переводится — «нюхать». Ладно-ладно, будем более научны — с их помощью можно и нужно анализировать сетевые пакеты, проходящие через сетевую карту компьютера.

Снифферы бывают пассивные и активные. Пассивный сниффер делает именно и только то, что от него требуется — перехватывает для анализа трафик, проходящий сквозь сетевую карту компьютера, на котором он установлен. Казалось бы, куда уж круче? Однако же, активный сниффер не только мониторит сетевую карту, но и всячески пытается добраться до трафика, который гуляет по локальной сети и не предназначен для чужих глаз. Делает он это, например, с использованием ARP-Spoofing и всяких прочих грязных трюков. Кстати, в некоммутируемых сетях (основанных на репитерах и хабах) пассивный сниффер может внезапно обнаружить в себе суперсилы, ибо при отсутствии коммутации все пакеты в таких сетях рассылаются по всем хостам. Принимать их, конечно, должны только адресаты, но… :)

А вот чтобы их принимать — надо перво-наперво заставить сетевую карту уволить ее личного секретаря, который фильтрует корреспонденцию, и начать читать все и сразу. Научно это называется «Promiscuous mode», то есть «Неразборчивый режим». И тут есть засада:

Да, для перевода карты в неразборчивый режим требуются права root. Поэтому и наш скрипт попросит их для запуска. Такие дела.

Ну и чо?

Как говорил один известный киношный персонаж, «We need to go deeper». То есть, нырнуть поглубже в уровни OSI, на канальный уровень. Для этого при создании сокета необходимо указать константу PF_PACKET вместо PF_INET:

    int s_sock;
    struct ifreq ifr;
    strcpy(ifr.ifr_name, IFACE);

    if ( (s_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
        perror("Error creating socket");
        exit(-1);
    }

    ifr.ifr_flags |= IFF_PROMISC;
    if (ioctl(s_sock, SIOCGIFFLAGS, &ifr) < 0) {
      perror("Unable to set promiscious mode for device");
      close(s_sock);
      exit(-1);
    }

Обычно при открытии подобного сокета указывается конкретный протокол, по которому идет перехват. Если же указать константу ETH_P_ALL — будут перехватываться все. Структура ifreq используется в Linux для руления сетевым интерфейсом на низком уровне через ioctl(), а IFACE в данном случае — просто строка с именем смотрящего в сеть интерфейса, например, «eth0».

Собственно, теперь все, что нам остается — читать данные из сокета в цикле и смотреть, что из этого получится:

    int n = 0;
    char buf[MTU];
    n = recvfrom(s_sock, buf, sizeof(buf), 0, 0, 0);

MTU здесь проще всего поставить равным 1500 — это определенный стандартом максимальный размер пакета в сетях Ethernet. Для сетей, построенных по другому стандарту, например, FDDI, значение может быть другим.

Поскольку мы работаем с Ethernet, данные о заголовках полученных пакетов проще всего записывать в специально предназначенную для этого структуру ядра — ethhdr. Для разных базовых протоколов вплоть до транспортного уровня существуют похожие структуры, которые, как ни сложно в это поверить, носят названия наподобие iphdr, tcphdr или даже udphdr (как говорится, «знаю отличную шутку про UDP, но не факт, что она до вас дойдет»). Как и полагается в старом добром C, это делается как-то так:

  struct ethhdr eth;
  memcpy((char *) &eth, data, sizeof(struct ethhdr));
Мда… И как же засунуть это в Python?

Всем известно, что в питоне у нас все есть объект. В случае с генератором/итератором исключения так же не будет — мы должны создать объект, имеющий метод __iter__() и умеющий next(). У объекта есть куча полей, большинство из которых нам не нужны, поэтому осторожно — впереди куча нулей.

PyTypeObject PyPacketGenerator_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "packgen",                       /* tp_name */
    sizeof(PacketGeneratorState),            /* tp_basicsize */
    0,                              /* tp_itemsize */
    (destructor)packgen_dealloc,     /* tp_dealloc */
    0,                              /* tp_print */
    0,                              /* tp_getattr */
    0,                              /* tp_setattr */
    0,                              /* tp_reserved */
    0,                              /* tp_repr */
    0,                              /* tp_as_number */
    0,                              /* tp_as_sequence */
    0,                              /* tp_as_mapping */
    0,                              /* tp_hash */
    0,                              /* tp_call */
    0,                              /* tp_str */
    0,                              /* tp_getattro */
    0,                              /* tp_setattro */
    0,                              /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,             /* tp_flags */
    0,                              /* tp_doc */
    0,                              /* tp_traverse */
    0,                              /* tp_clear */
    0,                              /* tp_richcompare */
    0,                              /* tp_weaklistoffset */
    PyObject_SelfIter,              /* tp_iter */
    (iternextfunc)packgen_next,      /* tp_iternext */
    0,                              /* tp_methods */
    0,                              /* tp_members */
    0,                              /* tp_getset */
    0,                              /* tp_base */
    0,                              /* tp_dict */
    0,                              /* tp_descr_get */
    0,                              /* tp_descr_set */
    0,                              /* tp_dictoffset */
    0,                              /* tp_init */
    PyType_GenericAlloc,            /* tp_alloc */
    packgen_new,                     /* tp_new */
};

Из этого объявления видно, что рабочие методы нашего будущего объекта — это packgen_new(), packgen_next() и packgen_dealloc(). Последний является деструктором и в общем и целом без него можно обойтись, если очень хочется и нет лишних данных в памяти. Кроме того, нам потребуется структура, в которой мы будем хранить данные о состоянии объекта на текущей итерации. Поскольку единственное, что нам необходимо хранить — это сокет, его и объявим:

typedef struct {
    PyObject_HEAD
    int s_sock;
} PacketGeneratorState;

Как я сказал выше, нужно открыть сокет и настроить сетевую карту в режим шпиёнства. Проще всего это сделать прямо в методе инициализации объекта.

static PyObject *
packgen_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
    int s_sock;
    struct ifreq ifr;

    strcpy(ifr.ifr_name, IFACE);
    if ( (s_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
        perror("Error creating socket");
        exit(-1);
    }

    ifr.ifr_flags |= IFF_PROMISC;
    if (ioctl(s_sock, SIOCGIFFLAGS, &ifr) < 0) {
      perror("Unable to set promiscious mode for device");
      close(s_sock);
      exit(-1);
    }

    PacketGeneratorState *pkstate = (PacketGeneratorState *)type->tp_alloc(type, 0);
    if (!pkstate)
        return NULL;

    pkstate->s_sock = s_sock;

    return (PyObject *)pkstate;
}

В принципе, вполне реально было бы сделать возвращение пакетов из модуля в виде классов, но

мне было лень

я решил сделать проще и возвращать словарь (а если кто переделает по-своему — будет молодец). Все, что остается сделать — это определить, что у нас IP на сетевом уровне, а по IP-заголовку, в свою очередь, определить вышележащий протокол (если кто не помнит, протоколы обозначаются циферками и прописаны в /etc/protocols). Это все работает потому, что пакеты у нас похожи на творения поваров Burger King — каждый вышестоящий уровень дописывает свой заголовок к нижестоящему. Возьмем старых добрых братьев — TCP и UDP.

PyObject *packet;
packet = PyDict_New();
if (!packet)
      return NULL;
if (ntohs(eth.h_proto) == ETH_P_IP) {
      ip = (struct iphdr *)(data + sizeof(struct ethhdr));
      PyDict_SetItemString(packet, "ip_source", PyString_FromFormat("%s", inet_ntoa(ip->saddr)));
      ...
      if ((ip->protocol) == IPPROTO_TCP) {
            tcp = (struct tcphdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
            PyDict_SetItemString(packet, "tcp_source_port", PyString_FromFormat("%d", ntohs(tcp->source)));
            ...
      }
      if ((ip->protocol) == IPPROTO_UDP) {  
        udp = (struct udphdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
        PyDict_SetItemString(packet, "udp_source_port", PyString_FromFormat("%d", ntohs(udp->source)));
        ...
      }
} 
return packet;
Вуаля!

Выглядит все в итоге примерно вот так:
Python 2.7.3 (default, Apr 20 2012, 22:44:07)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pysniff
>>> for i in pysniff.packgen():
... print i
...
{'ip_destination': '192.168.1.111', 'tcp_seq': '10972', 'ip_source': '173.194.32.53', 'tcp_offset': '8', 'tcp_source_port': '443', 'tcp_dest_port': '44021'}
{'ip_destination': '173.194.32.53', 'tcp_seq': '47475', 'ip_source': '192.168.1.111', 'tcp_offset': '8', 'tcp_source_port': '44021', 'tcp_dest_port': '443'}
{'ip_destination': '192.168.1.111', 'tcp_seq': '10972', 'ip_source': '173.194.32.53', 'tcp_offset': '8', 'tcp_source_port': '443', 'tcp_dest_port': '44021'}
{'ip_destination': '173.194.32.53', 'tcp_seq': '47475', 'ip_source': '192.168.1.111', 'tcp_offset': '8', 'tcp_source_port': '44021', 'tcp_dest_port': '443'}

Ради смеха создал репозиторий на github, вдруг захочется развить идею? Удачного вам сниффинга, не попадайтесь!

1. Original socket usage scenario

The network programming we usually use is to send and receive data at the application layer. Each program can only receive data sent to itself, that is, each program can only receive data from the bound port of the program. The received data usually includes only application-layer data, and the original header information is hidden in the transmission process. In some cases, we need to perform more low-level operations, such as listening to all data sent and received by the native machine, modifying headers, etc., whereas SOCK_STREAM and SOCK_DGRAMZ are usually used in the application layer and cannot meet this requirement.

With raw sockets, we can capture all IP packets sent to the local machine (including IP headers and TCP/UDP/ICMP headers) and all frames received by the local machine (including data link layer protocol headers). A common socket cannot process network packets such as ICMP and IGMP, but SOCK_RAW can. With raw sockets, we can construct our own IP headers.

2. Introduction to primitive socket classification and socket functions

There are two types of raw sockets: one handles data at the IP layer and above it by specifying the socket as the first parameter

AF_INET

To create this socket. The other is to process the data link layer and the data on it by specifying the socket as the first parameter

PF_PACKET

To create this socket.

Socket function:

int socket(int domain, int type, int proto)

#include <sys/types.h>

#include <sys/socket.h>

parameter

options

role

note

domain

AF_INET

Get data starting with the network layer (complete IP packets)

PF_PACKET

Get data from the start of the data link layer (link layer header +IP packet)

. .

Other domain options are not in use

type

SOCK_STREAM

Connection-oriented streaming sockets

SOCK_DGRAM

Connectionless packet socket

SOCK_RAW

The raw socket that receives the underlying data message

SOCK_PACKET

An outdated type is not recommended for the latest version

. .

Other type options are not used for the time being

proto

0

The default value is 0

ETH_P_IP

ETH_P_IP 0x800 Only IP data frames sent to the local MAC are received

ETH_P_ARP

ETH_P_ARP 0x806 Only arp data frames sent to the local MAC are accepted

ETH_P_RARP

ETH_P_RARP 0x8035 Only RARP frames sent to the local MAC are accepted

ETH_P_ALL

ETH_P_ALL 0x3 Receives all types of IP ARP Data frames sent to the local MAC address and all types of data frames sent from the local MAC address.(If promiscuous mode is enabled, non-local FRAMES are received.)

3. Socket usage and application scenarios

Creating a socket and its application scenario

Create a way

Work domain

Send a message

Receive a message

note

socket(AF_INET,SOCK_STREAM, 0)

The network layer

Receiving and sending are corresponding

port

Application layer data of

Received the packet destined for the local IP address

socket(AF_INET, SOCK_DGRAM, 0)

socket(AF_INET, SOCK_RAW, 0)

Only packets containing TCP or UDP headers or other transport protocols can be sent. IP headers and Ethernet frame headers are automatically sealed by the kernel

The user gets the complete IP packet containing the IP header

socket(PF_PACKET, SOCK_DGRAM, 0)

The link layer

Get IPV4 data link layer frames, excluding Ethernet frames (6 source MAC + 6 Destination MAC + 2)

Received the packet destined for the local MAC address. Procedure It is mainly used to obtain underlying data

socket(PF_PACKET, SOCK_RAW, 0)

Get an IPV4 data link layer frame, i.e. data containing Ethernet frame headers (14+20+(8: UDP or 20: TCP))

4. Comparison of two sockets

In the table above we know socket(AF_INET, SOCK_RAW…) Socket (PF_PACKET, SOCK_DGRAM,0) and **socket(PF_PACKET, SOCK_DGRAM,0)** can receive complete IP packets, but what is the difference between the received sockets? Next, a brief explanation:

Knot up is: socket (AF_INET SOCK_RAW, IPPROTO_TCP | IPPROTO_UDP | IPPROTO_ICMP) to send and receive IP packets can * * : ** This socket can receive IP packets destined for the local IP address of the protocol type (TCP UDP ICMP, etc.) ** Cannot: ** Received packets not destined for the local IP address (IP soft filtering discards these packets not destined for the local IP address) ** Cannot: ** You need to organize TCP, UDP, and ICMP headers when receiving packets sent from the host. You can use setsockopt to wrap your own IP header. This socket is suitable for writing a ping program.

The socket (PF_PACKET, SOCK_RAW | SOCK_DGRAM, htons (ETH_P_IP | ETH_P_ARP | ETH_P_ALL)) to send and receive Ethernet data frame. This socket is relatively powerful and can listen for all data frames on the network card

Yes: Receives frames sent to the local MAC address Yes: Receives frames sent from the local PC (the third parameter must be set to ETH_P_ALL) Yes: Receives frames sent from the local PC. ETH_P_IP 0x800 Accepts only IP frames sent to the local MAC address. ETH_P_ARP 0x806 Accepts only ARP frames sent to the local MAC address ETH_P_RARP 0x8035 Accepts only RARP frames sent to the local MAC ETH_P_ALL 0x3 Receives all TYPES of IP ARP data frames sent to the local MAC. Receives all types of data frames sent from the local machine (when promiscuous mode is enabled, non-local MAC data frames will be received)

5. Application example: Grab all IP packets (code reproduced)

#include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <linux/if_packet.h> #include <netinet/if_ether.h> #include <netinet/in.h> typedef Struct _iphdr {unsigned char h_verlen; // 4-bit header length + 4-bit IP version number unsigned char tos; // 8-bit service type TOS unsigned short total_len; //16 bits total length (bytes) unsigned short ident; // unsigned short frag_and_flags; //3 bits unsigned char TTL; //8 bits TTL unsigned char proto; //8 bit protocol (TCP, UDP or other) unsigned short checksum; // 16-bit IP header checksum unsigned int sourceIP; // 32-bit source IP address unsigned int destIP; // 32-bit destination IP address}IP_HEADER; Typedef struct _udphdr // define UDP header {unsigned short uh_sport; // 16-bit source port unsigned short uh_dport; // 16-bit destination port unsigned short uh_len; // 16-bit UDP packet length unsigned short uh_sum; // 16-bit checksum}UDP_HEADER; Typedef struct _tcphdr // define TCP header {unsigned short th_sport; // 16-bit source port unsigned short th_dport; // 16-bit destination port unsigned int th_seq; // Unsigned int th_ack; // Unsigned char th_lenres; //4 bit header length /6 bit reserved word unsigned char th_flag; // unsigned short th_win; // Unsigned short th_sum; // 16-bit checksum unsigned short th_urp; // 16-bit emergency data offset}TCP_HEADER; typedef struct _icmphdr { unsigned char icmp_type; unsigned char icmp_code; /* type sub code */ unsigned short icmp_cksum; unsigned short icmp_id; unsigned short icmp_seq; /* This is not the std header, but we reserve space for time */ unsigned short icmp_timestamp; }ICMP_HEADER; void analyseIP(IP_HEADER *ip); void analyseTCP(TCP_HEADER *tcp); void analyseUDP(UDP_HEADER *udp); void analyseICMP(ICMP_HEADER *icmp); int main(void) { int sockfd; IP_HEADER *ip; char buf[10240]; ssize_t n; /* capture ip datagram without ethernet header */ if ((sockfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)))== -1) { printf("socket error! \n"); return 1; } while (1) { n = recv(sockfd, buf, sizeof(buf), 0); if (n == -1) { printf("recv error! \n"); break; } else if (n==0) continue; // The received data does not include the data link frame header IP = (IP_HEADER *)(buf); analyseIP(ip); size_t iplen = (ip->h_verlen&0x0f)*4; TCP_HEADER *tcp = (TCP_HEADER *)(buf +iplen); if (ip->proto == IPPROTO_TCP) { TCP_HEADER *tcp = (TCP_HEADER *)(buf +iplen); analyseTCP(tcp); } else if (ip->proto == IPPROTO_UDP) { UDP_HEADER *udp = (UDP_HEADER *)(buf + iplen); analyseUDP(udp); } else if (ip->proto == IPPROTO_ICMP) { ICMP_HEADER *icmp = (ICMP_HEADER *)(buf + iplen); analyseICMP(icmp); } else if (ip->proto == IPPROTO_IGMP) { printf("IGMP----\n"); } else { printf("other protocol! \n"); } printf("\n\n"); } close(sockfd); return 0; } void analyseIP(IP_HEADER *ip) { unsigned char* p = (unsigned char*)&ip->sourceIP; printf("Source IP\t: %u.%u.%u.%u\n",p[0],p[1],p[2],p[3]); p = (unsigned char*)&ip->destIP; printf("Destination IP\t: %u.%u.%u.%u\n",p[0],p[1],p[2],p[3]); } void analyseTCP(TCP_HEADER *tcp) { printf("TCP -----\n"); printf("Source port: %u\n", ntohs(tcp->th_sport)); printf("Dest port: %u\n", ntohs(tcp->th_dport)); } void analyseUDP(UDP_HEADER *udp) { printf("UDP -----\n"); printf("Source port: %u\n", ntohs(udp->uh_sport)); printf("Dest port: %u\n", ntohs(udp->uh_dport)); } void analyseICMP(ICMP_HEADER *icmp) { printf("ICMP -----\n"); printf("type: %u\n", icmp->icmp_type); printf("sub code: %u\n", icmp->icmp_code); }Copy the code


Ethernet на самом низком уровне

  • Подписаться на тему
  • Сообщить другу
  • Скачать/распечатать тему



Сообщ.
#1

,

    Кто-нибудь, помогите! :
    Нужно обмениваться по сети компьютерам, которые работают под самодельной ОС (www.multex.nm.ru)
    Ну, нашел я описание REALTEK — адаптера, получил доступ к его регистрам, а как организовывать пакеты и вообще, как сеть то работает с ними ??? Подскажите, где найти какую-нибудь документацию об этом. У меня ведь даже NETBIOS-a нет, значит все протоколы нужно вручную наворачивать.
    Буду благодарен за любую информацию.


    Olej



    Сообщ.
    #2

    ,

      Senior Member

      Рейтинг (т): 8

      Цитата klotho, 23.04.03, 15:03:59

      Кто-нибудь, помогите! :

      Тут никто не поможет, это — к психиатру… :-(

      Цитата

      Нужно обмениваться по сети компьютерам, которые работают под самодельной ОС (www.multex.nm.ru)
      Ну, нашел я описание REALTEK — адаптера, получил доступ к его регистрам, а как организовывать пакеты и вообще, как сеть то работает с ними ??? Подскажите, где найти какую-нибудь документацию об этом. У меня ведь даже NETBIOS-a нет, значит все протоколы нужно вручную наворачивать.

      Это уже начинаются настоящие «наступания на грабли» … когда говорят: «не лепите самопалки OS — не дело это!»… Всё далеко не так просто, и только начинается (вам ещё IPC предстоит!!! :-(). Что предстоит сделать с сетью:

      1. Прописать стек TCP/IP в полном соответствии с RFC (в Linux, помнится передача TCP — 8000 стр. кода, а приём — 23000, кажется — это когда уже транспорт IP сделан). Почему TCP/IP (там выше фраза про NETBEUI…)? Потому, сто TCP/IP postfactum стандарт общеупотребимый, а NETBEUI etc. — это частная фирменная херня никому, кроме MS не нужная. Т.е. п.1 — прописать «транспортный уровень» 7-уровневой модели OSI.

      2. Для каждого типа сетевой карты — написать драйвер, т.е. реализацию MAC-уровня для каждого типа железа (канальный уровень OSI). Это — вниз…

      3. А вверх … Для минимально полноценной OS:
      — ppp и инкапсуляция через сериальные каналы;
      — всю технику маршрутизации и разрешения имён: DNS, arp — rarp ….
      — весь прикладной уровень: telnet, ssl/ssh, ftp, http ….. даже перечислять скучно.

      … и вот только после всего этого … можно подумать об том, чтоб с этой OS начинать выползать в сетевое окружение…

      «Я скорблю вместе с вами» (с).

      P.S. В качестве бонуса: для попыток обмена MAC-уровня нужно начинать со стандарта NE-2000 совместимых Ethernet карт — с этого все начинают — он масово реализован и достаточно описан. Кстати, выше сказано — REALTEC карта… это кто? «Имя им легион» (с) — если RTL8029 — это и есть NE-2000, RTL8139 … всё гораздо хуже …

      Сообщение отредактировано: Olej


      klotho



      Сообщ.
      #3

      ,

        Спасибо за ответ! Это, действительно, RTL8139, но все не так уж страшно…
        После того, как я написал драйверы для звука чипсетов i815 и VIA, да навернул на них MP3-декодер, это уже меня не пугает.
        А где посмотреть структуру MAC-заголовка? Я просто с сетями возился до сих пор только на уровне сокетов в Delphi…


        Olej



        Сообщ.
        #4

        ,

          Senior Member

          Рейтинг (т): 8

          Цитата klotho, 23.04.03, 15:50:08

          А где посмотреть структуру MAC-заголовка?

          MAC пакет — для вашей платы — это Ethernet кадр.
          Смотреть всё нужно в RFC (MAC, IP, ICMP/IGMP, UDP/TCP, ARP/RARP…) — номера я не помню, но это и несложно: поисковиком ищем справочники по RFC, есть хорошие русскоязычные, где-то в Новосибирске… Только RFC! — это основополагающие документы, всё остальное — их перепевки…

          Цитата

          Я просто с сетями возился до сих пор только на уровне сокетов в Delphi…

          А первое с чего нужно начать — уровень абстракции сокетов, особенно Delphi — забыть: это всё уже использование надстроек, которые только предстоит построить.

          P.S. А если уже и вправду — невмоготу … я бы сделал так:
          1. поставить небольшую «эталонную» OS, лучше из UNIX, я бы лично взял QNX 6.2.
          2. установить в нём BPF + libcap — Берклиевский пакетный фильтр.
          3. запустить над ним сетевой снифер tcpdump.

          Вот теперь можно с tcpdump:
          1. смотреть детально структуру всех пакетов: MAC, ARP, IP-UDP-TCP, …. NETBEUI и др.
          2. видеть структуру пакетов «мусора», который отсылается из новой OS в процессе доводки и отладки.


          klotho



          Сообщ.
          #5

          ,

            Я написал драйвер RTL8139, мне нужно теперь передавать пакеты из Windows в мои вычислители. А можно ли под Win98 выдавать «сырые» пакеты на уровне MAC-адресов?
            Собственно, большего мне и не надо…
            Я почитал Windows-SDK, там про RAW-Socket что-то невразумительное написано…


            Oksiv



            Сообщ.
            #6

            ,

              2klotho — могу сказать одно, когда я писал драйвер USB устройства + USB host
              controllera под DOS то лучше чем исходники ядра Linux быть не может, там и смотри всё что тебе надо особенно по сетям.

              P.S почитал про MULTEX, интересно, а драйвер для USB хоста не думали написать, в принципе могу поучаствовать?


              Olej



              Сообщ.
              #7

              ,

                Senior Member

                Рейтинг (т): 8

                Цитата klotho, 28.04.03, 13:13:34

                Я написал драйвер RTL8139, мне нужно теперь передавать пакеты из Windows в мои вычислители. А можно ли под Win98 выдавать «сырые» пакеты на уровне MAC-адресов?
                Я почитал Windows-SDK, там про RAW-Socket что-то невразумительное написано…

                RAW-сокет — это уже сокет IP, но … незаполненный. Т.е. для его использования уже нужен (полноценный!) транспортный уровень IP!

                Сокет MAC-уровня есть пока реализованный только в Linux — тип SOCK_PACKET (так, кажется). Может там, в кодах смотреть надо.

                Если уж совсем не ймётся туда лезть — смотрите книгу У.Стивенса, вот здесь об ней:
                http://qnx.org.ru/forum/viewtopic.php?topic=1350&forum=12&10
                — книга только что вышла в издательстве «Питер» — 1080 стр. детального текста с кодами по использованию техники сокетов. Ничего другого подобного нет!


                Oksiv



                Сообщ.
                #8

                ,

                  Цитата Olej, 30.04.03, 12:18:04

                  RAW-сокет — это уже сокет IP, но … незаполненный. Т.е. для его использования уже нужен (полноценный!) транспортный уровень IP!

                  Сокет MAC-уровня есть пока реализованный только в Linux — тип SOCK_PACKET (так, кажется). Может там, в кодах смотреть надо.

                  Если уж совсем не ймётся туда лезть — смотрите книгу У.Стивенса, вот здесь об ней:
                  http://qnx.org.ru/forum/viewtopic.php?topic=1350&forum=12&10
                  — книга только что вышла в издательстве «Питер» — 1080 стр. детального текста с кодами по использованию техники сокетов. Ничего другого подобного нет!

                  RAW сокеты есть и в Windows 2000.
                  Сокет MAC уровня звучит интересно в Linux сокет уровня IP если ты имел ввиду не одно и тоже.


                  Olej



                  Сообщ.
                  #9

                  ,

                    Senior Member

                    Рейтинг (т): 8

                    Цитата ViSko, 30.04.03, 14:01:08

                    RAW сокеты есть и в Windows 2000.
                    Сокет MAC уровня звучит интересно в Linux сокет уровня IP если ты имел ввиду не одно и тоже.

                    Нет, я имел в виду именно сокет MAC-уровня, т.е. сокет Ethernet-кадра (или другой среды…), именно AF-PACKET в Linux его и определяет. То-же, с чем оперирует перехват пакетов в BPF (Berkley Packet Filter) & tcpdump.
                    У Стивенса есть…


                    Oksiv



                    Сообщ.
                    #10

                    ,

                        У Стивенса есть… <br>

                      до этого я ещё не дочитал   :)


                      Olej



                      Сообщ.
                      #11

                      ,

                        Senior Member

                        Рейтинг (т): 8

                        Цитата ViSko, 05.05.03, 17:02:40

                          У Стивенса есть… <br>

                        до этого я ещё не дочитал љ:)

                        fd = socket( AF_INET, SOCK_PACKET, htons( ETH_P_ALL ) );

                        — странно мне только (но в Linux многое «по-быстренькому») — почему сокет для MAC-уровня должен определяться в семейсиве адресов IP?


                        Balamut



                        Сообщ.
                        #12

                        ,

                          Junior

                          Рейтинг (т): 0

                          сырцы для Ethernet&TCP/IP  смотреть на
                          http://www.opentcp.org


                          Olej



                          Сообщ.
                          #13

                          ,

                            Senior Member

                            Рейтинг (т): 8

                            Кстати, то, что я писал:

                            Цитата

                            fd = socket( AF_INET, SOCK_PACKET, htons( ETH_P_ALL ) );

                            — это специфика Linux, и никого более. А вот в хэдерах стандартной BSD реализации стека TCP/IP определено ещё такое адресное семейство как AF_LINK — т.е. судя по всему — это MAC-уровень, и они его сами в реализации для этого используют. Нельзя ли этой штукой попользоваться с пользовательского уровня?

                            И ещё одна штука, общеупотребимая (портированная) — это BPF (Berkley Packet Filter). Обычно, его знают в связи с снифером tcpdump, но это гораздо большее — он имеет описанный пользовательский интерфейс, вполне достаточный для манипулирования с сетью минуя стек TCP/IP (или параллельно — потому он и «фильтр»), в том числе и на MAC-уровне, что мы и видим по tcpdump.


                            Andy_user



                            Сообщ.
                            #14

                            ,

                              Member

                              Рейтинг (т): 3

                              Обычно использую в Linux (2.4.3-20mdk):
                              packet_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

                              По поводу BPF:
                              если не ошибаюсь, BPF позволяет только получит данные канального уровня, минуя стек TCP/IP. Отправить пакет нельзя (ИМХО).

                              Сообщение отредактировано: Andy_user


                              Olej



                              Сообщ.
                              #15

                              ,

                                Senior Member

                                Рейтинг (т): 8

                                Цитата Andy_user, 21.05.03, 16:58:21

                                Обычно использую в Linux (2.4.3-20mdk):
                                packet_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

                                По поводу BPF:
                                если не ошибаюсь, BPF позволяет только получит данные канального уровня, минуя стек TCP/IP. Отправить пакет нельзя (ИМХО).

                                Засомневался … и специально проверил:
                                — BPF позволяет как принимать, так и отправлять пакеты канального уровня. Выглядит это как-то примерно так:
                                open( «/dev/bf0», … ); // там любопытно: bf0, bf1 … — первый свободный
                                ioctl(…); // несколько раз — устанавливабтся параметры, фильтр…
                                read()/write(); // — всё, поехали читать/писать…

                                — запись в канальный уровень через BPF используется очень редко: UDP/TCP пишутся через IP-сокет, ICMP/IGMP — через RAW … почти ничего не остаётся… Поэтому запись в BPF менее известна и освещена. Но — напр. демон RARP-разрешителя во многих OS не сделан в ядре (см. ниже), а как пользовательский процесс пишет в BPF. Запись в BPF — незаменимая штука, когда нужно отправлять «хитрые» UDP/TCP сегменты — если вы помните, там такая штука: UDP/TCP пакеты не доходят (!) до RAW-сокета — они известны ядру, оно их принимает, и не передаёт RAW…

                                — почему я и засомневался, что есть такая известная библиотека libcap — интерфейс к … чуть не сказал BPF — это «»обобщённый» интерфейс, который использует «то что есть»: BPF, пакетный  сокет Linux, что-то ещё из TLI SVR4….

                                — BPF — считается много эффективнее, чем пакетный сокет Linux, и тем-более всякая самопальная фича, типа «сниферов»:
                                1. BPF много лет вылизан, стандартный интерфейс, всё время совершенствуется;
                                2. выполняется в режиме ядра с двойной (обменной) буферизацией и намного реже требует переключения в контекст пользовательского процесса и копирования буферов;
                                3. в отличие от пакетного сокета — выполняет фильтрацию в режиме ядра, и сыпет на пользовательский уровень только то, что запросили, а не «всё», а это на порядки меньше переключений контекстов!

                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                                0 пользователей:

                                • Предыдущая тема
                                • Сетевые Технологии
                                • Следующая тема

                                [ Script execution time: 0,0383 ]   [ 15 queries used ]   [ Generated: 14.05.25, 07:57 GMT ]  

                                Понравилась статья? Поделить с друзьями:
                                0 0 голоса
                                Рейтинг статьи
                                Подписаться
                                Уведомить о
                                guest

                                0 комментариев
                                Старые
                                Новые Популярные
                                Межтекстовые Отзывы
                                Посмотреть все комментарии
                              • Восстановление реестра windows server 2003
                              • Как подключить наушники к компьютеру проводные с микрофоном windows 10
                              • Аналог appstore для windows
                              • Windows 7 не видит флешку 256 гб
                              • Видеоредактор онлайн для windows 10