1 Востаннє редагувалося cheappi386 (20.02.2017 20:19:33)

Тема: Сирі сокети, як правильно отримати відповідь ?

#pragma pack(push)
#pragma pack(1) 
typedef struct ip_hdr
{
    unsigned char ip_header_len : 4; // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
    unsigned char ip_version : 4; // 4-bit IPv4 version
    unsigned char ip_tos; // IP type of service
    unsigned short ip_total_length; // Total length
    unsigned short ip_id; // Unique identifier

    unsigned char ip_frag_offset : 5; // Fragment offset field

    unsigned char ip_more_fragment : 1;
    unsigned char ip_dont_fragment : 1;
    unsigned char ip_reserved_zero : 1;

    unsigned char ip_frag_offset1; //fragment offset

    unsigned char ip_ttl; // Time to live
    unsigned char ip_protocol; // Protocol(TCP,UDP etc)
    unsigned short ip_checksum; // IP checksum
    unsigned int ip_srcaddr; // Source address
    unsigned int ip_destaddr; // Source address
} IPV4_HDR, *PIPV4_HDR, FAR * LPIPV4_HDR;

// TCP header
typedef struct tcp_header
{
    unsigned short source_port; // source port
    unsigned short dest_port; // destination port
    unsigned int sequence; // sequence number - 32 bits
    unsigned int acknowledge; // acknowledgement number - 32 bits

    unsigned char ns : 1; //Nonce Sum Flag Added in RFC 3540.
    unsigned char reserved_part1 : 3; //according to rfc
    unsigned char data_offset : 4; /*The number of 32-bit words in the TCP header.
                                   This indicates where the data begins.
                                   The length of the TCP header is always a multiple
                                   of 32 bits.*/

    unsigned char fin : 1; //Finish Flag
    unsigned char syn : 1; //Synchronise Flag
    unsigned char rst : 1; //Reset Flag
    unsigned char psh : 1; //Push Flag
    unsigned char ack : 1; //Acknowledgement Flag
    unsigned char urg : 1; //Urgent Flag

    unsigned char ecn : 1; //ECN-Echo Flag
    unsigned char cwr : 1; //Congestion Window Reduced Flag

                           ////////////////////////////////

    unsigned short window; // window
    unsigned short checksum; // checksum
    unsigned short urgent_pointer; // urgent pointer
} TCP_HDR, *PTCP_HDR, /*FAR *LPTCP_HDR,*/ TCPHeader, TCP_HEADER;
#pragma pack(pop)
#pragma warning(disable : 4996)

char test_host[] = "google.com.ua";
int main()
{
    unsigned char *buf = new unsigned char[1024];
    unsigned char *recbuf = new unsigned char[1024];

    SOCKADDR_IN dest;
    hostent *server;
    SOCKET s;
    int payload = 512, optval,reclen=0;
    WSADATA wsock = { 0 };
    WSAStartup(MAKEWORD(2, 2), &wsock);
    s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    if (s == INVALID_SOCKET)
    {
        printf("socket error: %d\n", WSAGetLastError());
        _getch();
    }
    if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval)) == SOCKET_ERROR)
    {
        printf("setsockopt error: %d\n",WSAGetLastError());
        _getch();
    }
    server = gethostbyname(test_host);
    dest.sin_family = AF_INET;
    dest.sin_port = htons(80); 
    memcpy(&dest.sin_addr.s_addr, server->h_addr, server->h_length);
    printf("%s : %s\n", test_host, inet_ntoa(dest.sin_addr));
    IPV4_HDR *v4hdr = NULL;
    v4hdr = (IPV4_HDR *)buf; 
    v4hdr->ip_version = 4;
    v4hdr->ip_header_len = 5;
    v4hdr->ip_tos = 0;
    v4hdr->ip_total_length = htons(sizeof(IPV4_HDR) + sizeof(TCP_HDR) + payload);
    v4hdr->ip_id = htons(2);
    v4hdr->ip_frag_offset = 0;
    v4hdr->ip_frag_offset1 = 0;
    v4hdr->ip_reserved_zero = 0;
    v4hdr->ip_dont_fragment = 1;
    v4hdr->ip_more_fragment = 0;
    v4hdr->ip_ttl = 8;
    v4hdr->ip_protocol = IPPROTO_TCP;
    v4hdr->ip_srcaddr = inet_addr("192.168.0.104");
    v4hdr->ip_destaddr = inet_addr(inet_ntoa(dest.sin_addr));
    v4hdr->ip_checksum = 0;

    TCP_HDR *tcphdr = (TCP_HDR *)( ((DWORD)v4hdr) + sizeof(IPV4_HDR) );
    tcphdr->source_port = htons(1234);
    tcphdr->dest_port = htons(80);
    tcphdr->cwr = 0;
    tcphdr->ecn = 1;
    tcphdr->urg = 0;
    tcphdr->ack = 0;
    tcphdr->psh = 0;
    tcphdr->rst = 1;
    tcphdr->syn = 0;
    tcphdr->fin = 0;
    tcphdr->ns = 1;
    tcphdr->checksum = 0;

    unsigned char *data = (unsigned char *) ( ((DWORD)buf) + sizeof(IPV4_HDR) + sizeof(TCP_HDR) );
    memset(data, '^', payload);

    if ((sendto(s,(const char*)buf, sizeof(IPV4_HDR) + sizeof(TCP_HDR) + payload, 0, (SOCKADDR *)&dest, sizeof(dest))) == SOCKET_ERROR)
    {
        printf("sendto error: %d\n", WSAGetLastError());
    }
    else
    {
        reclen = sizeof(dest);
        if (recvfrom(s, (char*)recbuf, sizeof(IPV4_HDR) + sizeof(TCP_HDR), 0, (SOCKADDR *)&dest, &reclen) == SOCKET_ERROR)
        {
            printf("recvfrom error: %d\n", WSAGetLastError());
        }
        else
        {
            printf("received!\n");
        }
    }
    _getch();
    closesocket(s);
    delete[]buf;
    delete[]recbuf;
    return 0;
}

Висне на recvfrom, що не так у коді?Якийсь флаг у пакеті, не так стоїть, чи я просто не правильно намагаюся прийняти відповідь?

2

Re: Сирі сокети, як правильно отримати відповідь ?

Я пригадую, що сирі сокети погано роблять у вінді (залежить від версії системи/увімкненого брандмауеру та ін.), взагалі вінда не зовсім посікс сумісна і сокетів це теж стосується. Тож перед як питати що не так в коді- скомпілюйте його в нормальну систему а потім танцюйте з віносозалежними хвункціями та брендмауерами.

Подякували: 0x9111A1

3

Re: Сирі сокети, як правильно отримати відповідь ?

nmap якось жеж працює під віндовс ?

4

Re: Сирі сокети, як правильно отримати відповідь ?

Багато чого працює під вінду, але не з юзермоду ;) Мені з ХР вдавалося якось працювати з сирими сокетами, але вже не пам'ятаю як.

5

Re: Сирі сокети, як правильно отримати відповідь ?

cheappi386
В усіх нормальних Ос, включаючи останні Вінди, з сирими сокетами можна працювати лише з-під адміна.

6

Re: Сирі сокети, як правильно отримати відповідь ?

до 1001 порта треба права адміна, а вище здається ні

7

Re: Сирі сокети, як правильно отримати відповідь ?

cheappi386 написав:

nmap якось жеж працює під віндовс ?

Хіба він не використовує Рсар?