This is a very special method. using it to communicate without a port may bring some other advantages due to its particularity. However, this method also has a major disadvantage.
It may be named, for example, jiurl255. It does not use TCP, UDP, or ICMP. What protocol does it use? It uses the 255 protocol just like a messy name.
The above figure shows an IP header without IP options. There is an 8-bit protocol with a byte length. The system uses the value in this byte to distinguish what the upper-layer protocol is, the value of this Byte determines who should hand over the data for processing. TCP is decimal 6, UDP is decimal 17. That is to say, if this value is 6, it will be handed over to TCP for processing. If it is 17, it will be handed over to UDP for processing. What if the value is a value that nobody processes? For example, 222,255 (8bit, maximum 255 ). I think 255 is more beautiful. Let's just say 255. The values of others are the same. So what will happen? I guess I can get it. I did some small experiments later, which means I am right. (I watched the sky and found that you have the life to learn computer ). This item has nothing to do with TCP and UDP. Naturally, there will be no TCP or UDP port numbers.
Okay. If you are interested, try it first. Use jiurl255 to download the client program for simple communication and the server program.
The server is called rserver, and the client is called rclient.
Rserver first thesocket = socket (af_inet, sock_raw, 255); create an original socket using jiurl255, then bind the local address, and finally block in recvfrom, waiting for data sent to the 255 protocol. After receiving the message, the received data is printed.
Rclient first obtains the Server IP address, and then thesocket = socket (af_inet, sock_raw, 255); creates an original socket using jiurl255, then let you input some data from the keyboard and sendto send the input data to the server with protocol 255.
In the first test, when sending and receiving data, we can find that the data can be sent and received using the Protocol number that nobody uses. This is probably the case. After the system receives the IP packet, it will check whether the Protocol Number has any process to accept. If yes, it will send it to that process.
In the second test, run an rclient, run two rservers, and send data once. We can find that both rservers receive data from rclient. This indicates that the system sends the received data to each process that wants to accept the data on this Protocol Number.
In another experiment, when the server creates a socket, the Protocol Number is specified as 200, and the client creates a socket. When the IP header is filled, the Protocol Number is specified as 255, as a result, the server cannot receive the data sent by the client.
Notes after the test :"
Server collects data
Send data to the client
When the server creates a socket, the Protocol Number is 255,
When the client creates a socket and fills in the IP header, the Protocol Number is 255,
Result The server receives the data sent by the client.
When the server creates a socket, the Protocol Number is 200,
When the client creates a socket and fills in the IP header, the Protocol Number is 255,
As a result, the server cannot receive the data sent by the client.
The Protocol number 255 is used for multiple servers,
The client also sends data to the 255 protocol,
Multiple servers receive data.
"
In addition, if the program sends and receives messages and sends the messages to the local machine, the program will receive the messages it sends. It seems like, for example, after a program sends 255 of the data, it receives 255 of the data and sends the data to the local machine, then it will receive the data.
Rclient:
# Include <winsock2.h>
# Include <windows. h>
# Include <stdio. h>
# Include <ws2tcpip. h>
# Include <conio. h>
# Pragma comment (Lib, "ws2_32.lib ")
Typedef struct ip_hdr // defines the IP Header
{
Unsigned char h_verlen; // 4-bit header length, 4-bit IP version number
Unsigned char TOS; // an 8-bit service type TOS
Unsigned short total_len; // The total length of 16 bits (in bytes)
Unsigned short ident; // 16-bit ID
Unsigned short frag_and_flags; // 3-Bit Flag
Unsigned char TTL; // 8-bit TTL
Unsigned char proto; // 8-bit protocol (TCP, UDP, or other)
Unsigned short checksum; // 16-bit IP header checksum
Unsigned int sourceip; // 32-bit source IP address
Unsigned int destip; // 32-bit destination IP address
} Ip_header, * pip_header;
Ushort checksum (ushort * buffer, int size );
Void rawclient (char * szserver );
Void main ()
{
Wsadata;
Char serveraddr [256];
Printf ("server ADDR :");
Scanf ("% s", serveraddr );
Printf ("/N ");
Wsastartup (0x0202, & wsadata );
Rawclient (serveraddr );
Wsacleanup ();
}
//////////////////////////////////////// /////////
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 & 0 xFFFF );
Cksum + = (cksum> 16 );
Return (ushort )(~ Cksum );
}
//////////////////////////////////////// //////////////////
Void rawclient (char * szserver)
{
Lphostent lphostentry;
Lphostentry = gethostbyname (szserver );
If (lphostentry = NULL)
{
Printf ("gethostbyname () Error/N ");
Return;
}
Socket thesocket;
Thesocket = socket (af_inet, fig, 255 );
If (thesocket = invalid_socket)
{
Printf ("socket () Error/N ");
Return;
}
Int nret;
Bool optval;
Optval = true;
Nret = setsockopt (thesocket, ipproto_ip, ip_hdrincl, (char *) & optval, sizeof (optval ));
If (socket_error = nret)
{
Printf ("setsockopt error! % D/N ", wsagetlasterror ());
Return;
}
Sockaddr_in saserver;
Saserver. sin_family = af_inet;
Saserver. sin_addr = * (lpin_addr) * lphostentry-> h_addr_list); // Let Winsock assign address
Saserver. sin_port = 0; // use port passed from user
Char szbuf [1024];
//////////////////////////////////////// //////////////////////////
Memset (szbuf, 0, sizeof (szbuf ));
Int iphdrlen = 0;
Int datalen = 0;
Ip_header * piphdr = NULL;
Char * pdata = NULL;
Iphdrlen = sizeof (ip_header );
Piphdr = (ip_header *) szbuf;
Piphdr-> h_verlen = (4 <4) | (sizeof (ip_header)/sizeof (unsigned long ));
Piphdr-> TOS = 0;
Piphdr-> proto = 255;
Piphdr-> TTL = 128;
Piphdr-> ident = 0;
Piphdr-> checksum = 0;
Piphdr-> frag_and_flags = 0;
Piphdr-> sourceip = inet_addr ("1.1.1.1 ");
Piphdr-> destip = (unsigned INT) saserver. sin_addr.s_addr;
Pdata = (szbuf + iphdrlen );
Printf ("Type A String :");
Scanf ("% s", pdata );
Datalen = strlen (pdata );
Piphdr-> total_len = iphdrlen + datalen;
//////////////////////////////////////// //////////////////////////
Nret = sendto (thesocket, // socket
Szbuf, // data buffer
Iphdrlen + datalen, // length of data
0, // flags
(Lpsockaddr) & saserver, // server address
Sizeof (struct sockaddr); // length of address
If (nret! = Socket_error)
{
Printf ("client send: % s/n", pdata );
}
Getch ();
Closesocket (thesocket );
Return;
}
Rserver:
# Include <winsock2.h>
# Include <windows. h>
# Include <stdio. h>
# Include <ws2tcpip. h>
# Include <conio. h>
# Pragma comment (Lib, "ws2_32.lib ")
Void rawserver ();
Void main ()
{
Wsadata;
Wsastartup (0x0202, & wsadata );
Rawserver ();
Wsacleanup ();
}
//////////////////////////////////////// //////////////////
Void rawserver ()
{
Int nret;
Socket thesocket;
Thesocket = socket (af_inet, fig, 255 );
If (thesocket = invalid_socket)
{
Printf ("socket () Error/N ");
Return;
}
Sockaddr_in saserver;
Saserver. sin_family = af_inet;
Saserver. sin_addr.s_addr = inaddr_any; // Let Winsock assign address
Saserver. sin_port = 0; // use port passed from user
Nret = BIND (thesocket, // socket Descriptor
(Lpsockaddr) & saserver, // address to bind
Sizeof (struct sockaddr) // size of address
);
If (nret = socket_error)
{
Printf ("BIND () Error/N ");
Closesocket (thesocket );
Return;
}
//////////////////////////////////////// ///////////
Int nlen;
Nlen = sizeof (sockaddr );
Char szbuf [1024];
Nret = gethostname (szbuf, sizeof (szbuf ));
If (nret = socket_error)
{
Printf ("gethostname () Error/N ");
Closesocket (thesocket );
Return;
}
Lphostent lphostentry;
Lphostentry = gethostbyname (szbuf );
Printf ("server named % s ADDR % s/n ",
Szbuf, inet_ntoa (* (lpin_addr) lphostentry-> h_addr ));
//////////////////////////////////////// ///////////
Sockaddr_in saclient;
Memset (szbuf, 0, sizeof (szbuf ));
Nret = recvfrom (thesocket, // bound socket
Szbuf, // Receive Buffer
Sizeof (szbuf), // size of buffer in bytes
0, // flags
(Struct sockaddr *) & saclient, // buffer to receive client address
& Nlen); // length of client Address Buffer
If (nret! = Socket_error)
{
Printf ("server Recv: % s/n", szbuf + 20 );
}
Else
{
Printf ("Recv error: % d/N", wsagetlasterror ());
Closesocket (thesocket );
Return;
}
Getch ();
Closesocket (thesocket );
Return;
}
When jiurl255 is used for data transmission, it is obvious that there are no TCP and UDP ports, so that it will not be seen by commands such as netstat-. This is similar to using ICMP to transmit data, but I think jiurl255 is better than using ICMP to transmit data. It also has a major drawback: Because the IP address is used directly, the transmitted data may be lost. This is the note I wrote after my observation: "using IP address, in the IP header field, set the upper-layer protocol to 255, which is a protocol number that no one uses. Then, run the C, s programs and C on the two hosts in the network to send ip255 packets with the content Hello n. A total of 50 messages are sent and one message is sent per second. S receives the ip255 packet. In a test, 50 packets are received, and 49 are received. The IP address is indeed lost. It is feasible to try both directions. "
Therefore, it takes a lot of effort to hide the port using this method. In a program I write myself, some simple waiting Ack is used for transferring files, the mechanism of timeout and resend ensures that data is not lost or errors occur, and the command is sent. If you have time, write a sending and receiving function that ensures no loss and no error. For the mechanisms used for transferring files, refer to the TFTP protocol that uses UDP for reliable file transmission.
Final