Поиск  Пользователи  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Войти
 
Страницы: 1
RSS
Сырые сокеты в WinXP
 
Необходимо из под WinXP программно формировать, отправлять и получать tcp-пакеты. Пробовал сделать по примеру как это делается в *nix - системах с попыткой адаптировать код по Windows, но, ничего не вышло. Очень буду признателен, если кто-нибудь подкинет статейку или какой-нибудь сорец.....
Может, кто программку подскажет под винду, работающую таким манером, к которой можно достать исходники? Очень нужно....
И ещё один вопросик: при попытке установить опции на сырой сокет с параметром IP_HDRINCL, борланд си 6-ой сказал, что он вообще не знает, что это такое, хотя в MSDN этот макрос описывается.... В хиадерах включена winsock2.h.... В чём может быть дело?
 
Посмотри вот сэмпл. Вроде достаточно доходчиво.

А на счет багланда и всяких-разных ссылок с MSDN обрати свой взор на последний Platform SDK -- ИМО багланд о последних веяниях девелоперовской мысли, идущей от MS ни слухом, ни духом.
 
Ок. Спасибо, TSS
Сейчас на вскидку глянул - вроде то что надо, дома поподробнее вчитаюсь....
 
могу кинуть на мыло адапитированные в свое время под маздай исходники создания и отправки icmp/udp/tcp пакетов. или класс позволяющий создавать icmp/udp/tcp пакеты (правда этот класс позволяет формировать только основные поля заголовка).
 
Вот такой получается код:

#include <vcl.h>
#include <winsock2.h> #include <ws2tcpip.h>
#include <stdio.h> #include <stdlib.h> #pragma hdrstop
#pragma pack(1)

#define WIN32_LEAN_AND_MEAN

#include "Unit1.h"
//---------------------------------------------------------- -----------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#define MAX_MESSAGE        4068
#define MAX_PACKET         4096

#define DEFAULT_MESSAGE    "This is a test"

struct tcpheader
{
unsigned short int th_sport;
unsigned short int th_dport;
unsigned int th_seq;
unsigned int th_ack;
unsigned char th_x2:4, th_off:4;
unsigned char th_flags;
unsigned short int th_win;
unsigned short int th_sum;
unsigned short int th_urp;

unsigned  char identity [4];
unsigned  char data [200];
} ; /* total tcp header length: 20 bytes (=160 bits) */

struct ipheader {
unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4 bits */
unsigned char ip_tos;
unsigned short int ip_len;
unsigned short int ip_id;
unsigned short int ip_off;
unsigned char ip_ttl;
unsigned char ip_p;
unsigned short int ip_sum;
unsigned int ip_src;
unsigned int ip_dst;
}; /* total ip header length: 20 bytes (=160 bits) */


typedef struct ps_hdr
{
    unsigned int   source_address;   //  Source   Address      ;     ;  ;  =>       4 Bytes
    unsigned  int   dest_address;    &n bsp;// Destination   Address      =>         4  Bytes
    unsigned  char   placeholder;    &n bsp;      //   Place   Holder     & nbsp;       => &n bsp;    & nbsp;1 Bytes
    unsigned   char   protocol;      ; ;   &nb sp; //  Protocol        &nbs p;  =>       1 Bytes
    unsigned short  tcp_length;        & nbsp; //  TCP   Length     &nb sp;       => &nbs p;  +   2  Bytes
                                  // &nbs p;  &nbs p;         &nbs p;         &nbs p;  = 12 Bytes
    struct tcpheader tcp;

}PS_HDR;


char         &n bsp; strMessage[MAX_MESSAGE]; // Message to send
TForm1 *Form1;
//---------------------------------------------------------- -----------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------- -----------------

USHORT checksum(USHORT *buffer, int size)
{
    unsigned long cksum=0;

    while (size > 1)
    {
        cksum += *buffer++;
        size  -= sizeof(USHORT);    
    }
    if (size)
    {
        cksum += *(UCHAR*)buffer;    
    }
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16);

    return (USHORT)(~cksum);
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   WSADATA       ;    ;   wsd;
   SOCKET                 s;   
   DWORD      & nbsp;     i;
   char      &n bsp;   *datagram="",  ident[] = "ScMX";
   hostent       ;      *h   = NULL;
   int      &nb sp;         bOpt = 1, y, len;
   char      &n bsp;      RecvBuf [200];

    struct ipheader *iph = (struct ipheader *) malloc(sizeof(struct ipheader));
    struct tcpheader *tcph = (struct tcpheader *) malloc( sizeof (struct tcpheader));
    struct ps_hdr *ps = (struct ps_hdr *) malloc( sizeof (struct ps_hdr));
    datagram = (char *) malloc(sizeof(struct ipheader) + sizeof(struct tcpheader));
    struct sockaddr_in sin, dest;


    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        ShowMessage("WSAStartup() failed: " + IntToStr(GetLastError()));
        return;
    }

    s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0,0);
    if (s == INVALID_SOCKET)
    {
        ShowMessage("WSASocket failed: " + IntToStr(GetLastError()));
        return;
    }


    iph= (struct ipheader *) datagram;
    tcph=(struct tcpheader *) (datagram+ sizeof(struct ipheader));

    sin.sin_family = AF_INET;
    sin.sin_port = htons (110);
    h = gethostbyname("localhost");
    if(h == NULL)
     ShowMessage("╬°шсър gethostbyname");

    sin.sin_addr.s_addr = inet_addr (inet_ntoa(*((struct in_addr *)h->h_addr)));

    iph->ip_hl = 5;
    iph->ip_v = 4;
    iph->ip_tos = 0;
    iph->ip_len = sizeof (struct ipheader) + sizeof (struct tcpheader);

    iph->ip_id = 1;
    iph->ip_off = 0;
    iph->ip_ttl = 255;
    iph->ip_p = IPPROTO_TCP;
    iph->ip_sum = 0;
    iph->ip_src = inet_addr ("127.0.0.1");
    iph->ip_dst = sin.sin_addr.s_addr;

    tcph->th_sport = htons (1999);
    tcph->th_dport = htons (135);
    tcph->th_seq = 666;
    tcph->th_ack = htons (6234);
    tcph->th_x2 = 0;
    tcph->th_off = 5;
    tcph->th_flags = 16; // SYN
    tcph->th_win = htons(65535);
    tcph->th_sum = 0;
    tcph->th_urp = 0;

    strncpy((char *)tcph->identity,ident,4);

    for(i = 0; i < strlen(strMessage); i++)
     tcph->data[I]=strMessage[I];

     ps->source_address  &nb sp;= inet_addr ("127.0.0.1");
    ps->dest_address  = sin.sin_addr.s_addr;
    ps->placeholder  = 0;
    ps->protocol  = IPPROTO_TCP;
    ps->tcp_length  = htons(sizeof(struct tcpheader));

    ps->tcp = *tcph;

    tcph->th_sum = checksum((unsigned short *)ps, sizeof(struct ps_hdr));
    iph->ip_sum  = checksum((unsigned short *)iph, sizeof(struct ipheader));

    setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));

    if (sendto(s, datagram, iph->ip_len, 0, (SOCKADDR *)&sin, sizeof(sin)) == SOCKET_ERROR)
    {
     ShowMessage("sendto() failed: " + IntToStr(WSAGetLastError()));
     return;
    }
     
      memset(datagram,0,strlen (datag ram));

    i = 0;
    len = sizeof(sin);

    i = recvfrom(s, RecvBuf, 200, 0,(sockaddr*)&sin, &len);
    if(i > 0)
       RichEdit1->Line s-> Add("& #9575;юыєўхэ яръхЄ.");
    /*while(i < 1)
    {
     memset(RecvBuf, 0, sizeof(RecvBuf));
     i = recv(s, RecvBuf, 200, 0);
    }
      RichEdit1->Lines-> Add("& #9575; юыєўхэ яръхЄ.");  */

    closesocket(s) ;
    WSACleanup() ;
}
//---------------------------------------------------------- -----------------

Никак не могу понять почему в ответ не приходит вообще никакого пакета (recivefrom), когда, по идее, должен прийти пакет с флагом ask.
Очень буду признателе за помощь.
Цель: получить tcp - пакет от удалённой машины, дабы в дальнейшем из tcp-заголовка достать размер окна....
Единственно, есть некототые сомнения, что 16 устанавливае SYN-флаг (это получается 00010000), а, если я не ошибаюсь,то SYN-флагу будет соответствовать 00000010, т.е. 2. Но замена 16 на два ровным счётом ничего не решает.
В чём может быть дело?
 
1.Ethereal почему-то тоже неловит пакеты с локалхоста на локолхост. Но он через WinPCap работает. Всё-таки тот с интерфейса ловит.
2.
...
unsigned int th_ack;
unsigned char th_x2:4, th_off:4;
unsigned char th_flags;
...
tcph->th_x2 = 0;
tcph->th_off = 5;
...
А не так ли?
...
unsigned int th_ack;
unsigned char th_SizeInDw:4, th_Reserved:4;
unsigned char th_flags;
...
tcph->th_SizeInDw = 5;
tcph->th_Reserved = 0;
...
 
А кто нибудь знает можно ли при помощи сырых сокетов отправлять и принимать пакеты произвольной структуры (то есть даже мак адреса отправителя и получателя изменить)
 
Спасибо, парни... Вроде разобрался: отправляю с установкой SYN флага, как 2. При помощи ф-ции WSAIoctl вешаю сокет на прослушку, т.е. приём всех пакетов. Кто-нибудь знает, как можно при помощи параметров WSAIoctl сделать так, что бы сокет принимал пакеты только с нужного хоста, т.е. с определённого ip?
 
дайте плиз рабочий исходник сырых сокетов , очень нужно ,весь инет облазил , везде нерабочий код =(
 
http://www.codeproject.com/KB/IP/rawsocket.aspx
ну вот неплохая статья по сокетам, так-же посоветовал бы скачать DRKB если интересует Delphi помнится там даже пример должен был быть по пингу...
http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedrawsocket11e.html
ярко расписанно
http://www.tenouk.com/Winsock/Winsock2example1.html
Страницы: 1
Читают тему