Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проблема с сокетом для сервера 
:(
    Опции темы
tymrfik
  Дата 14.6.2014, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.1.2011

Репутация: нет
Всего: нет



Для низкоуровневого сокета, по протоколу ICMP.
Адрес источника должен быть 192.168.1.100
а Адрес получателя 192.168.1.107
Вместо этого программа выдает:
 Пункт отправки 112.255.39.0
 Пункт приема 200.0.0.0
Межу сервером и клиентом локальная сеть через маршрутизатор. 
Код

#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#define SIO_RCVALL 0x98000001 //äëÿ íåðàçáîð÷èâîãî ðåæèìà
#define MAX_PACKET_SIZE 0x10000

#pragma comment(lib, "Ws2_32.lib")
 
#include <winsock2.h>
#include <windows.h>

using namespace std;

struct icmp_header 
{
unsigned char type; // òèï ICMP- ïàêåòà
unsigned char code; // êîä ICMP- ïàêåòà 
unsigned short crc ; // êîíòðîëüíàÿ ñóììà 
unsigned long orig_timestamp; // äîïîëíèòåëüíûå ïîëÿ 
unsigned long recv_timestamp; // óòî÷íÿþùèé òèï
unsigned long trns_timestamp; //ICMP-ïàêåòà
};
struct ip_header
{
unsigned char version; // íîìåð âåðñèè ïðîòîêîëà 
unsigned char tos; // òèï ñåðâèñà 
unsigned short length; // îáùàÿ äëèíà ïàêåòà 
unsigned short id ; // èäåíòèôèêàòîð ïàêåòà
unsigned short flags; // ôëàãè 
unsigned char ttl ; // Âðåìÿ æèçíè ïàêåòà 
unsigned char proto; // Ïðîòîêîë âåðõíåãî óðîâíÿ 
unsigned short crc; // CRC çàãîëîâêà 
unsigned int src_addr; // IP- àäðåñ îòïðàâèòåëÿ 
unsigned int dst_addr; // IP- àäðåñ ïîëó÷àòåëÿ 
}; 
//ïîäñ÷åò êîíòðëüíîé ñóììû
unsigned short rs_crc (unsigned short * buffer, int length)

unsigned long crc = 0;
// Âû÷èñëåíèå CRC 
while (length > 1)
 { 
 crc += *buffer++; 
 length -= sizeof (unsigned short); 
 } 
if (length) crc += *(unsigned char*) buffer;
// Çàêîí÷èòü âû÷èñëåíèÿ 
crc = (crc >> 16) + (crc & 0xffff);
crc += (crc >> 16);
//Ñìåùåíèå CRC , åñëè íåîáõîäèìî
if (1) crc = crc << 1; 
// Âîçâðàùàåì èíâåðòèðîâàííîå çíà÷åíèå 
return (unsigned short)(~crc); 


int main(int argc, char *argv[])
{
{
    struct ip_header iph;
    struct icmp_header icmph;
    icmph.type = 8; // oei ICMP- iaeaoa
    icmph.code= 0; // eia ICMP- iaeaoa 
    icmph.crc=0; // eiio?ieuiay noiia 
    icmph.orig_timestamp; // aiiieieoaeuiua iiey 
    icmph.recv_timestamp; // ooi?iy?uee oei
    icmph.trns_timestamp; //ICMP-iaeaoa
    iph.version=0x4; // iiia? aa?nee i?ioieiea 
   iph.tos= 0; // oei na?aena (ii?iaeuiue)
   iph.length= 10; // iauay aeeia iaeaoa 
   iph.id= htonl(54321) ; // eaaioeoeeaoi? iaeaoa
   iph.flags= htons(0); // oeaae 
   iph.ttl=255 ; // A?aiy ?ecie iaeaoa 
   iph.proto = IPPROTO_ICMP; // I?ioieie aa?oiaai o?iaiy 
   iph.crc=0; // CRC caaieiaea 
  SOCKET s, s_new, client;// nieaou
  char Buffer[MAX_PACKET_SIZE]; // aoooa? aey i?eaia aaiiuo 64 Kb
    //Eieoeaeece?oai aeaeeioaeo WinSock
    WSADATA wsaData;
        int errcod;
        errcod = WSAStartup(MAKEWORD(2, 2), &wsaData);
            if(errcod!=0)
            {
             cout<<"WinSock not found!";
             return 0;
            }
   s = socket (AF_INET,SOCK_RAW, IPPROTO_ICMP);
    if(s == INVALID_SOCKET)
    {
        cout<<"Error create socket";
    }
    else cout<<"Create socket succesfull";
    cout<<endl;
   struct sockaddr_in server, client_addr, saddr;
    //ZeroMemory(&server,sizeof(server));// îáíóëÿåì
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("192.168.1.107");
    server.sin_port = 0;
    bind (s, (struct sockaddr*)&server, sizeof(server));
    unsigned long flag = 1;
    ioctlsocket(s,SIO_RCVALL,&flag);
    int cnt ;
    char buf[7000];
    int l = 10; //êîë-âî ïàêåòîâ
    int len =sizeof(client_addr);
  while (l>0)
    {
    cnt = recv(s,buf,sizeof(buf),0);// ïðèåì
     if (cnt>=sizeof(iph)+sizeof(icmph))//  åñëè ïðèíÿòà IP- äàòàãðàììà
     { 
    client_addr.sin_addr.S_un.S_addr = iph.src_addr;//  èçâëåêàåì àäðåñ èñòî÷íèêà 
    cout<<"___Punkt otpravki__";
    cout<< inet_ntoa(client_addr.sin_addr);
    //server.sin_addr.S_un.S_addr = iph.receiver;// ecaeaeaai aa?an
        // iieo?aoaey
   saddr.sin_addr.S_un.S_addr = iph.dst_addr;// èçâëåêàåì àäðåñ ïîëó÷àòåëÿ
   cout<<"___Punkt naznachenia__";
   cout<< inet_ntoa(saddr.sin_addr);
    l--;
    } 
   // cout<<endl;
   } 
  }
    system("PAUSE");
    return EXIT_SUCCESS;
}

PM MAIL   Вверх
feodorv
Дата 15.6.2014, 02:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Ну, для начала нужно упаковать структуры:
Код

#pragma pack(push,1)
struct icmp_header 
{
  ...
};

struct ip_header
{
  ...
};
#pragma pack(pop)



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
tymrfik
Дата 15.6.2014, 08:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.1.2011

Репутация: нет
Всего: нет



feodorv, не знал про такое спасибо. Ааа насчет глюка с адресами подсказать можете? 
PM MAIL   Вверх
feodorv
Дата 15.6.2014, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(tymrfik @  15.6.2014,  09:22 Найти цитируемый пост)
Ааа насчет глюка с адресами подсказать можете?  

Не помогло?

У Вас совершенно оторван iph от buf при приеме пакета. Какие значения iph.src_addr и iph.dst_addr изначально в структуре iph были, такие и выводятся. Без относительно того, что там принято в buf.

Это сообщение отредактировал(а) feodorv - 15.6.2014, 14:41


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
tymrfik
Дата 15.6.2014, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.1.2011

Репутация: нет
Всего: нет



СРОЧНО ПОМОГИТЕ! ПОЧЕМУ ПРИЕМ НЕ ПРОХОДИТ, ХОТЯ ОТПРАВКА С КЛИЕНТА ТОЧНО ИДЕТ.
Код

#include <cstdlib>
#include <iostream>
#define REQ_DATASIZE 27
#define ICMP_ECHOREPLY    0
#define ICMP_ECHOREQ    8
#define SM_EVENT        WM_USER+192

#include <winsock2.h>
#include <Ws2tcpip.h>

#pragma pack(1)

typedef struct tagIPHDR
{
    u_char  version;     // version number
    u_char    TOS;            // Type Of Service
    u_short    TotLen;            // Total Length
    u_short    ID;                // Identification
    u_short    FlagOff;        // Flags and Fragment Offset
    u_char    TTL;            // Time To Live
    u_char    Protocol;        // Protocol
    u_short    Checksum;        // Checksum
    struct    in_addr iaSrc;    // Internet Address - Source
    struct    in_addr iaDst;    // Internet Address - Destination    
}IPHDR, *PIPHDR;

// ICMP Header - RFC 792
typedef struct tagICMPHDR
{
    u_char    Type;            // Type
    u_char    Code;            // Code
    u_short    Checksum;        // Checksum
    u_short    ID;                // Identification
    u_short    Seq;            // Sequence
    char    Data;            // Data
}ICMPHDR, *PICMPHDR;

#define REQ_DATASIZE 27        // Echo Request Data size

// ICMP Echo Reply..
typedef struct tagECHOREPLY
{
    IPHDR ipHdr;    
                IPHDR ipReplyHdr;
    ICMPHDR icmpHdr;
    DWORD    dwTime;
    char    cData[REQ_DATASIZE];    
    char cFiller[256];
}ECHOREPLY,*PECHOREPLY;

//ICMP Echo Request...
typedef struct tagECHOREQUEST
{
    ICMPHDR icmpHdr;
    DWORD    dwTime;
    char    cData[REQ_DATASIZE];    
}ECHOREQUEST, *PECHOREQUEST;

//Here it is object client address...
sockaddr_in objClientAddress;
sockaddr_in objServAddress;    
//Here it initializes the socket..
int OnInitializeSocketENV();    
//Here it creates the socket..
int OnCreateSocket(SOCKET& rawSocket);
//Here it binds the socket..
int BindSocket(SOCKET& rawSocket);
//Here it receives the echo message
int RecvEchoMessage(SOCKET& rawSocket);


#pragma pack()

u_short in_cksum(u_short *addr, int len);
using namespace std;

int main(int argc, char *argv[])
{
    //Here it is a instance os a socket.. 
    SOCKET rawSocket;
/*    //Here it initializes the socket environment..
    if(!OnInitializeSocketENV()) return 0;
    //Here it creates the socket..    
    if(!OnCreateSocket(rawSocket)) return 0 ;
    //Here it binds the socket..
    if(!BindSocket(rawSocket)) return 0;
    if(!RecvEchoMessage(rawSocket)) return 0;*/
    
    OnInitializeSocketENV();
    //Here it creates the socket..    
   OnCreateSocket(rawSocket);
    //Here it binds the socket..
    BindSocket(rawSocket);
    
    printf("Socket is listening..\n");    
    //Here it receives the echo response..
    RecvEchoMessage(rawSocket); 
    
    closesocket(rawSocket);
    WSACleanup();
    getchar();
    
    return 0;
}
//Here it initializes the socket environment...
int OnInitializeSocketENV()
{
     WSADATA wsaData;
        int errcod;
        errcod = WSAStartup(MAKEWORD(2, 2), &wsaData);
            if(errcod!=0)
            {
             cout<<"WinSock not found!";
             return 0;}
    }    
    //Here it is checking for version requested...
    /*if(wsaData.wVersion != wVersionRequested)
    {
        printf("Error winsock version not supported\n");        
        return false;
    }
    return true;
}*/
//Here it creates the socket object...
int OnCreateSocket(SOCKET& rawSocket)
{
    rawSocket = socket(AF_INET, SOCK_RAW,IPPROTO_ICMP);
     if(rawSocket == INVALID_SOCKET)
    {
        cout<<"Error create socket";
    }
    else cout<<"Create socket succesfull";
    cout<<endl;
}

//Here it binds the socket..
int BindSocket(SOCKET& rawSocket)
{
    //Here preparation is done to bind the socket.
    objServAddress.sin_addr.s_addr =  INADDR_ANY;//inet_addr("192.168.1.107");
    objServAddress.sin_family = AF_INET;
    objServAddress.sin_port = 0;
    //Here it binds the socket...
    int nRetValue = bind(rawSocket,(struct sockaddr*)&objServAddress,sizeof(objServAddress));
    if(nRetValue == SOCKET_ERROR)
    {
        printf("Socket binding is failed\n");                
        closesocket(rawSocket);
        rawSocket = 1;    
        return false;
    }
    return(true);
}

//Here it receives the echo message
int RecvEchoMessage(SOCKET& rawSocket)
{
    ECHOREPLY echoReply;
    
    int nAddrLen = sizeof(struct sockaddr_in);
    int nRet;            
   
    //char on=1;
    //setsockopt(rawSocket,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));
    if((nRet = recvfrom(rawSocket,(LPSTR)&echoReply,sizeof(ECHOREPLY),0,(struct sockaddr *)&objClientAddress,
            &nAddrLen)) > 0)
    {        
        printf("\nEcho is received from..: %s\n",inet_ntoa(objClientAddress.sin_addr));
        printf("\n..............IPHEADER INFO.........................\n");
        printf("size of IPHeder=%d\n",sizeof(echoReply.ipHdr));
        printf("IP Header Version :%d\n",echoReply.ipHdr.version);
        printf("Type of service   :%d\n",echoReply.ipHdr.TOS);
        printf("TTL   :%d\n",echoReply.ipHdr.TTL);

        //Here it sends the echo request..
        if(echoReply.ipHdr.Protocol ==  IPPROTO_ICMP)
            printf("It is a ICMP protocol %d\n",echoReply.ipHdr.Protocol);
        else
            printf("It is not a ICMP protocol:%d\n",echoReply.ipHdr.Protocol);
                
        printf("Here is source address :%s\n",inet_ntoa(echoReply.ipHdr.iaSrc));
        printf("Here is destination address:%s\n",inet_ntoa(echoReply.ipHdr.iaDst));
    
        printf("\n\n..............ICMP HEADER INFO.........................\n");                
        printf("Message Type...: %d\n",echoReply.icmpHdr.Type);
        printf("Message Code...: %d\n",echoReply.icmpHdr.Code);    
        printf("ID.............: %d\n",echoReply.icmpHdr.ID);    
        printf("SEQ............: %d\n",echoReply.icmpHdr.Seq);    
        printf("CHECKSUM.......: %d\n",echoReply.icmpHdr.Checksum);    
        printf("DATA sent......: %s\n",echoReply.cData);    
        
        //Here it constructs the echo reply and sends the same back to the client
        ECHOREQUEST echoReq;
        int nId  = 1;
        int nSeq = 1;
        int nRet,nIndex;
        
        //Fill in echo request..    
        echoReq.icmpHdr.Type     = ICMP_ECHOREPLY;
        echoReq.icmpHdr.Code     = 0;
        echoReq.icmpHdr.Checksum = 0;
        echoReq.icmpHdr.ID         = nId++;
        echoReq.icmpHdr.Seq         = nSeq++;    
        //Fill in some data to send..        
        for(nIndex = 0; nIndex < REQ_DATASIZE-1; nIndex++)
        {
            echoReq.cData[nIndex] = 'a'+nIndex;
        }
        //save tick count when sent..
        echoReq.dwTime = GetTickCount();
        //Put data in packet and compute checksum 
        echoReq.icmpHdr.Checksum = in_cksum((u_short*)&echoReq,sizeof(ECHOREQUEST));
      
        if((nRet = sendto(rawSocket,(LPSTR)&echoReq,sizeof(ECHOREQUEST),0,(struct sockaddr *)&objClientAddress,
            nAddrLen)) > 0)        
        {        
            printf("\nReply is sent to...:%s\n",inet_ntoa(objClientAddress.sin_addr));            
        }    
    }
    if(nRet == SOCKET_ERROR)
    {   
        int nError = WSAGetLastError();
        printf("Failure while sending and receiving data, Error:%d\n",nError);
        return false;
    }
    printf("Received value is...:%d",nRet);        
    return true;
}
//Check sum is done for ICMP Request..
u_short in_cksum(u_short *addr, int len)
{
    register int nleft = len;
    register u_short *w = addr;
    register u_short answer;
    register int sum = 0;

    /*
     *  Our algorithm is simple, using a 32 bit accumulator (sum),
     *  we add sequential 16 bit words to it, and at the end, fold
     *  back all the carry bits from the top 16 bits into the lower
     *  16 bits.
     */
    while( nleft > 1 )  {
        sum += *w++;
        nleft -= 2;
    }

    /* mop up an odd byte, if necessary */
    if( nleft == 1 ) {
        u_short    u = 0;

        *(u_char *)(&u) = *(u_char *)w ;
        sum += u;
    }

    /*
     * add back carry outs from top 16 bits to low 16 bits
     */
    sum = (sum >> 16) + (sum & 0xffff);    /* add hi 16 to low 16 */
    sum += (sum >> 16);            /* add carry */
    answer = ~sum;                /* truncate to 16 bits */

    return (answer);
}




//Here it waits for echo reply.
int WaitForEchoReply(SOCKET& objRawsocket);

//Here it waits for echo reply...
int WaitForEchoReply(SOCKET& objRawsocket)
{
    struct timeval Timeout;
    fd_set readfds;
    
    readfds.fd_count = 1;
    readfds.fd_array[0] = objRawsocket;
    
    Timeout.tv_sec = 5;
    Timeout.tv_usec = 0;
    
    int nSelect = select(0, &readfds, NULL, NULL, NULL);    
    int nErrorCode = WSAGetLastError();
    printf("Select Error Code:\n",nErrorCode);
    
    return(select(1, &readfds, NULL, NULL, NULL));
}

PM MAIL   Вверх
feodorv
Дата 15.6.2014, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(tymrfik @  15.6.2014,  15:03 Найти цитируемый пост)
СРОЧНО ПОМОГИТЕ! ПОЧЕМУ ПРИЕМ НЕ ПРОХОДИТ, ХОТЯ ОТПРАВКА С КЛИЕНТА ТОЧНО ИДЕТ.

Может, поможет smile 



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 15.6.2014, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(feodorv @  15.6.2014,  15:25 Найти цитируемый пост)
Может, поможет

Имею в виду следующее:
Цитата(feodorv @  18.5.2012,  13:36 Найти цитируемый пост)
Пока по сокету что-нибудь не пошлёшь, он как будто запечатанный. Стоит что-то послать, и он начинает ловить ICMP...



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
tymrfik
Дата 15.6.2014, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 20.1.2011

Репутация: нет
Всего: нет



на клиент не реагирует. а ping - ом не вариант проверить? (хотя тоже не принимает от пинга простого)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1333 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.