0

これがプログラムのコードで、単純な「ping」を送信する必要があります。IcmpSendEcho2()関数を使用できることは知っていますが、次のようにすることにしました。

struct ICMPh
{
unsigned char typ;
unsigned char kod;
unsigned short suma_spr;
unsigned short id;
unsigned short seq;
};
unsigned short CalcChecksum (char *pBuffer, int nLen)
 { 
  ////Checksum for ICMP is calculated in the same way as for IP header
  //This code was taken from: http://www.netfor2.com/ipsum.htm

  unsigned short nWord;
  unsigned int nSum = 0;
  int i;


  for (i = 0; i < nLen; i = i + 2)
  {
      nWord =((pBuffer [i] << 8)& 0xFF00) + (pBuffer [i + 1] & 0xFF);
      nSum = nSum + (unsigned int)nWord;  
  }


 while (nSum >> 16)
  {
      nSum = (nSum & 0xFFFF) + (nSum >> 16);
  }

  //One's complement the result
  nSum = ~nSum;

  return ((unsigned short) nSum);
 }
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)==SOCKET_ERROR)
{
    cout<<"ERROR at startup:\n";
    cout<<WSAGetLastError()<<"\n";
    system("pause");
    WSACleanup();
    return -1;
}
SOCKET soc;
int seq=0;

soc=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(soc==INVALID_SOCKET)
{
    cout<<"ERROR: INVALID SOCKET\n";
    cout<<WSAGetLastError()<<"\n";
    system("pause");
    WSACleanup();
    return -1;
}
char* addres=new char;
cin>>addres;

SOCKADDR_IN adr;
adr.sin_addr.S_un.S_addr=inet_addr(addres);
adr.sin_family=AF_INET;
adr.sin_port=rand();

ICMPh icmp;
icmp.kod=0;
icmp.seq=htons(seq++);
icmp.typ=8;
icmp.suma_spr=0;
icmp.id=htons(rand());

int size=32;
char *buffer;

buffer=new char[sizeof(ICMPh)+size];
memcpy_s(buffer,sizeof(ICMPh),&icmp,sizeof(ICMPh));
memset(buffer+sizeof(ICMPh),'x',size);

icmp.suma_spr=htons(CalcChecksum(buffer,sizeof(ICMPh)+size));

memcpy_s(buffer,sizeof(ICMPh),&icmp,sizeof(ICMPh));

if(sendto(soc,buffer,sizeof(ICMPh)+size,0,(SOCKADDR*)&adr,sizeof(SOCKADDR_IN))==SOCKET_ERROR)
{
    cout<<"FAIL at 'sendto':\n";
    cout<<WSAGetLastError()<<"\n";
    system("pause");
    WSACleanup();
    delete []buffer;
    return -1;
}
else
    cout<<"FINE";
WSACleanup();
system("pause");
delete []buffer;
return 0;
} 

そしてここに問題があります。機能するまで、すべてが正常にsendto()機能しています。10013エラーコードフォームが表示されます。これは 、このアプリケーションのwitch admin特権を開始しWSAGetLastError()たことを意味します。そのため、このソケット構成を使用してデータを送信できない理由がわかりません。WSAEACCES Permission denied

4

1 に答える 1

3

の場合sendto()WSAEACCESユーザー権限とは関係ありません。socket()RAWソケットを使用するための十分な権限がない場合は、代わりに エラーが発生します。ドキュメントを読んでくださいsendto()レポートの場合、構造体が正しく入力されていないWSAEACCESことを意味します。sockaddr_inこれに関連するコードに3つのバグがあります。

sockaddr_in1)使用する前にゼロにしないでください。そうすることが重要です。

2)ユーザーからターゲットアドレスを受け取るために1文字のバッファーを割り当てています。IPv4アドレス(ヌルターミネータを含む)の代わりに、バッファは16文字である必要があります。したがって、バッファオーバーフローが発生します。

3)フィールドhtons()を割り当てるときに呼び出していません。sin_port

于 2012-06-11T00:19:03.840 に答える