#pragma hdrstop
#include <vcl.h>
#include "raw_socket.h"
#include "main.h"
#include "data.h"
#include <ws2tcpip.h>
////////////////////////////////////////////////////////////////////////////////
int rs_exit (void)
{
// 囝蜥襯徹 菊萄慘鋼蒐 Winsock
WSACleanup ();
return 0;
}
//////////////////////////////////////////////////////////////////////////////
int rs_init (int v_major, int v_minor)
{
WSADATA wsadata;
// 位摟廓鞅頑甕� 菊萄慘鋼蒐 WinSock 頑滓瘩蝗 閑曇態�
if (WSAStartup(MAKEWORD(v_major, v_minor), &wsadata))
{
ShowMessage("疝廖蒙 慚摟廓鞅頑甕� WinSock");
return 1;
}
// 俏蝴綑蒙 閑曇態 WinSock
if (LOBYTE(wsadata.wVersion) != v_minor || HIBYTE(wsadata.wVersion) != v_major)
{
rs_exit ();
ShowMessage ("押 閑曆�� 閑曇�� WinSock");
return 1;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
int rs_set_raw (SOCKET s)
{
unsigned int use_own_header = 1;
// 降錶瘟階� 複甕� RAW 溫� 縝蒸錶, 餾� 廈隆撿� � 錙�
//餾� 撲 陲檣磋� 蛭滇� 縴整截蝴痞� 頑蝓蝴蒐 鋒蒸錙�
if ( setsockopt (s, IPPROTO_IP, 2, (char*)&use_own_header, sizeof(use_own_header))== SOCKET_ERROR)
{
ShowMessage ("疝廖蒙 檀錶瘟階� 複甕� RAW 溫� 縝蒸錶");
return 1;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
int rs_set_tos (SOCKET s, unsigned char new_tos)
{
int tos = new_tos;
int tos_len = sizeof (tos);
int per=setsockopt(s, IPPROTO_IP, 3, (char *)&tos, tos_len);
if (per == SOCKET_ERROR)
{
ShowMessage("疝廖蒙 檀錶瘟階� 複甕� TOS");
return 1;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
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;
// �頊擋麴粳 慚閑暸截蝴痢獗 鳩皓粵徹.
if (Fdata->crash_crc)
return (unsigned short)(crc); //綁鞅 CRC 撇頡橫粵� 錙 獗 慚閑暸截擘� 稞�
else return (unsigned short)(~crc);
}
////////////////////////////////////////////////////////////////////////////////
unsigned short rs_pseudo_crc (char * data, int data_length, unsigned int src_addr, unsigned int dst_addr, int packet_length, unsigned char proto)
{
char * buffer;
unsigned int full_length;
unsigned char header_length;
struct pseudo_header ph;
unsigned short p_crc = 0;
// 夏整痞 滓瘩贖 颳稟溜鋒蒸錶.
ph.src_addr = src_addr;
ph.dst_addr = dst_addr;
ph.zero = 0;
ph.proto = proto;
ph.length = htons (packet_length);
header_length = sizeof (struct pseudo_header);
full_length = header_length + data_length;
// 順滇雒璃� 鋒��錚.
buffer =(char *) calloc (full_length, sizeof (char));
// �獗擋甕� 颳稟溜鋒蒸錶.
memcpy (buffer, &ph, header_length);
memcpy (buffer + header_length, data, data_length);
// 順鞣縛粵徹 CRC.
p_crc = rs_crc ((unsigned short*) buffer, full_length);
free (buffer);
return p_crc;
}
////////////////////////////////////////////////////////////////////////////////
int rs_send_ip (SOCKET s, struct ip_header iph, unsigned char * data, int data_length, unsigned short dst_port_raw)
{
char * buffer;
int result;
sockaddr_in target;
unsigned char header_length;
unsigned int packet_length;
memset (&target, 0, sizeof (target));
target.sin_family = AF_INET;
target.sin_addr.s_addr = iph.dst_addr;
target.sin_port = dst_port_raw;
// �鞣縛粵徹 溫慚� 鋒蒸錶 � 頑廈餃階� 鋒蒸錶.
header_length = sizeof (struct ip_header); // !!! If IP_OPTIONS, increase...
packet_length = header_length + data_length;
// 降錶瘟階� CRC.
iph.crc = 0;
// 囝頡颱粵徹 獗蜻錙橢� 頡雒� 頑廈餃階� IP.
iph.version = header_length / 4 + (unsigned char) atoi ("4") * 16;
// 仞鞅 溫慚� 鋒蒸錶 獗 頑滓熱 , 錙
//溫慚� 鋒蒸錶 擋隅� 溫慚� 頑廈餃階�
if (!iph.length) iph.length = htons (packet_length);
// �滇雒璃� 鋒��錚 頡� 瘟順� 鋒蒸�
buffer =(char *) calloc (packet_length, sizeof (char));
// 決震曉鈇璃� 頑廈餃階� � 蛭繆� (CRC 擋隅� 0).
memcpy (buffer, &iph, sizeof (struct ip_header));
// 決震曉鈇璃� 滓瘩贖
if (data) memcpy (buffer + header_length, data, data_length);
// �鞣縛粵徹 CRC.
iph.crc = rs_crc ((unsigned short *) buffer, packet_length);
// 蜻震曉鈇璃� 頑廈餃階� 鋒蒸錶 (CRC 頡膳摘痢�).
memcpy (buffer, &iph, sizeof (struct ip_header));
// 俠興頗� 頑蜻瞇粵瘟廈 IP 鋒蒸錶.
result = sendto (s, buffer, packet_length, 0,(struct sockaddr *)&target, sizeof (target));
if (result==SOCKET_ERROR)
{
int SockErr;
result = GetLastError();
switch (result)
{
case WSANOTINITIALISED : {SockErr=1;break;};// A successful WSAStartup must occur before using this function.
case WSAENETDOWN :{SockErr=2;break;}; // The network subsystem has failed.
case WSAEACCES : {SockErr=3;break;}; // The requested address is a broadcast address, but the appropriate flag was not set.
case WSAEINVAL: {SockErr=4;break;}; // An unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.
case WSAEINTR :{SockErr=5;break;}; // The (blocking) call was canceled through WSACancelBlockingCall.
case WSAEINPROGRESS:{SockErr=6;break;}; // A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
case WSAEFAULT: {SockErr=7;break;}; // The buf or to parameters are not part of the user address space, or the tolen argument is too small.
case WSAENETRESET :{SockErr=8;break;}; // The connection has been broken due to the remote host resetting.
case WSAENOBUFS :{SockErr=9;break;}; // No buffer space is available.
case WSAENOTCONN :{SockErr=10;break;}; // The socket is not connected (connection-oriented sockets only)
case WSAENOTSOCK: {SockErr=11;break;}; // The descriptor is not a socket.
case WSAEOPNOTSUPP:{SockErr=12;break;}; // MSG_OOB was specified, but the socket is not stream style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.
case WSAESHUTDOWN :{SockErr=13;break;}; // The socket has been shut down; it is not possible to sendto on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
case WSAEWOULDBLOCK :{SockErr=14;break;}; // The socket is marked as nonblocking and the requested operation would block.
case WSAEMSGSIZE :{SockErr=15;break;}; // The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
case WSAEHOSTUNREACH :{SockErr=16;break;}; // The remote host cannot be reached from this host at this time.
case WSAECONNABORTED :{SockErr=17;break;}; // The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.
case WSAECONNRESET :{SockErr=18;break;}; // The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. For UPD sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the socket as it is no longer usable.
case WSAEADDRNOTAVAIL: {SockErr=19;break;}; // The specified address is not available from the local machine.
cas
gen_packet_src.zip_gen_packet_src
版权申诉
111 浏览量
2022-09-14
17:07:09
上传
评论
收藏 18KB ZIP 举报
周楷雯
- 粉丝: 78
- 资源: 1万+