Download from tftp server on ubuntu ( boost::asio c++) - c++

I'm looking for an example of an TFTP client running on Linux platform. I'm trying do this problem using boost::asio here's the code:
void packi16 (char *buf, unsigned short int i){ //change the host order to network byte order (16bit)
i = htons(i);
memcpy(buf,&i,2);
}
int main()
{
boost::asio::io_service service;
boost::asio::ip::udp::socket sock(service);
sock.open(boost::asio::ip::udp::v4());
boost::asio::ip::udp::endpoint receiver_ep(boost::asio::ip::address::from_string("127.0.0.1"), 69);
char filename[] = "first";
char mode[] = "netascii";
int filename_size = (sizeof(filename)/sizeof(*filename));
int mode_size = (sizeof(mode)/sizeof(*mode));
char *packet;
packet = (char *)malloc((17)*sizeof(char));
packi16(packet,1); // 1 opcode for read request
memcpy(packet+2,filename,filename_size-1);
memset(packet+1+filename_size, '\0', 1);
memcpy(packet+2+filename_size, mode, mode_size-1);
memset(packet+1+filename_size+mode_size, '\0', 1);
sock.send_to(boost::asio::buffer(packet, 17), receiver_ep);
char buff[512];
boost::asio::ip::udp::endpoint sender_ep;
sock.receive_from(boost::asio::buffer(buff), sender_ep);
std::cout << buff;
return 0;
}
The problem is in program no error but code don't print anything although in the TFTP server i have this file : first. I use sniffer (wireshark) for see what's going on in my request packet, i capture packet made in tftp client in ubuntu then capture my program capture and it seems my program build correct packet.
Thanks m.s., Prabhu for your comments.

Related

C++ Creating multiple socket clients

I'm trying to build a simulation for multiple socket clients.
My server has the following code to listen to multiple clients
My socket are from a very simple class drive from CAsyncSocket and my environment is windows MFC.
m_server.Create(....); // with the correct values
if (m_server.Listen()==FALSE)
and later on the OnSocketAccept() function
if (m_server.Accept(tempSock))
{
CSocketThread* pThread = (CSocketThread*)AfxBeginThread(RUNTIME_CLASS(CSocketThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
...
My simulation apps has the following code:
for (int i = 0; i < numOfClients; i++)
{
m_sConnected[i].Create();
int rVal = m_sConnected[i].Connect(csIPAddress.GetString(), m_port);
That doesn't work.
In WireShark I can see that my (numOfClients = 10 for example) 10 clients are connected with different client source port.
But each new socket of m_sConnected[i] is becoming NULL after the second connection to all sockets including m_sConnected[0].
Closing the sockets or destroy the simulation app create socket close at the server side for all open threads for the listen sockets.
What is the problem?
Can I use the same process/thread for all my socket clients?
10x
UrAv.
your problem is that you are not using the CSocketThread object the right way.
as mentiend in microsoft documention
after the accept function you need to do the following :
CSockThread* pSockThread = (CSockThread*)AfxBeginThread( RUNTIME_CLASS(CSockThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
if (NULL != pSockThread) {
// Detach the newly accepted socket and save
//the SOCKET handle in our new thread object.
//After detaching it, it should no longer be
//used in the context of this thread.
pSockThread->m_hConnected = sConnected.Detach();
pSockThread->ResumeThread();
} }
when you attach your socket to the thread then it will run.
link to microsoft doc:
https://msdn.microsoft.com/en-us/library/wxzt95kb.aspx
your solution has worked for me. I have used multiple threads to stress test the server in c++ under linux. Pasting my code, it will be helpful to somebody...Experts can improve my code, if they find any flaws in my handling of code. I know, I am doing something wrong but no other go to test the server as no one has provided the solution for this till now. I am able to test the server for 100000 clients using this code. - Kranti.
include //for threading , link with lpthread
void *connection_handler(void *);
#define PORT 9998
#define SERVER_IP "127.0.0.1"
#define MAXSZ 100
#define MAXSOCK 70000
int main()
{
int sockfd[MAXSOCK];//to create socket
int socket_desc , new_socket[MAXSOCK], *new_sock;
struct sockaddr_in serverAddress;//client will connect on this
int n;
char msg1[MAXSZ];
char msg2[MAXSZ];
int NoOfClients = MAXSOCK;
memset(msg2,0,100);
void *ret;
for(int i=0;i<NoOfClients;i++){
//create socket
sockfd[i]=socket(AF_INET,SOCK_STREAM,0);
//initialize the socket addresses
memset(&serverAddress,0,sizeof(serverAddress));
serverAddress.sin_family=AF_INET;
serverAddress.sin_addr.s_addr=inet_addr(SERVER_IP);
serverAddress.sin_port=htons(PORT);
//client connect to server on port
new_socket[i] = connect(sockfd[i],(struct sockaddr *)&serverAddress,sizeof(serverAddress));
printf("new socket connected= %d",new_socket[i]);
pthread_t sniffer_thread[MAXSOCK];
new_sock = malloc(sizeof(int));
*new_sock = new_socket[i];
int p=-1;
if( p = pthread_create( &sniffer_thread[i] , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *message , client_message[50];
printf("we are in connection handler");
//Send some messages to the server
message = "Greetings! I am your connection handler\n";
int wlen = write(sock , message , strlen(message));
printf("write length is %d", wlen);
//Free the socket pointer
//close(sock);
free(sock);
return 0;
}

Bluetooth can receive data but cannot transmit it (socket programming in C++ to communicate Matlab)

I am using Raspberry Pi 3's internal bluetooth and I am writing a c++ code to connect the bluetooth of my windows PC. On the PC side, I use Matlab and I am able to send bytes to raspberry. However when I try to send bytes from raspberry to PC, I get the following error:
"Transport endpoint is not connected"
and Matlab says "Unsuccessful read: the specified amount of data was not returned within the timeout period".
Another interesting thing is that, when I try to send more than three bytes from Matlab, raspberry only receives the first three as if the rest did not exist. If I use two reads in a row, I am able to get 6 bytes and so on. Just pointing this odd fact since I thought it might be connected with my main problem and be a clue.
I have also tried to send a file manually, using the bluetooth symbol on menubar and it worked. So c++ code should be doing something different to cause this problem.
What is likely to be the cause of my problem? How can I send data from raspberry to my computer using c++?
My code is as follows:
(Referred website: http://people.csail.mit.edu/albert/bluez-intro/index.html)
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
int main(int argc, char **argv)
{
struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
char buf[1024] = { 0 };
int s, client, bytes_read;
socklen_t opt = sizeof(rem_addr);
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
bdaddr_t tempBDADDR = {0};
// bind socket to port 1 of the first available
// local bluetooth adapter
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_bdaddr = tempBDADDR;
loc_addr.rc_channel = (uint8_t) 1;
bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
// put socket into listening mode
listen(s, 1);
// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
ba2str( &rem_addr.rc_bdaddr, buf );
fprintf(stderr, "accepted connection from %s\n", buf);
memset(buf, 0, sizeof(buf));
// read data from the client
bytes_read = read(client, buf, sizeof(buf));
if( bytes_read > 0 ) {
printf("received [%s]\n", buf);
}
int status = 0;
// send a message
if( status == 0 ) {
status = write(s, "hello!", 6);
}
if( status < 0 ) perror("uh oh");
// close connection
close(client);
close(s);
return 0;
}
Matlab side is as straight forward as:
b = Bluetooth('raspberrypi', 1);
fopen(b);
fwrite(b, uint('1234'));
input = fread(b,6)
fclose(b);
clear('b');
EDIT:
Just figured that I do not get the "Transport endpoint is not connected" when I use the following line. However this only allows me to connect as client, whereas matlab only has a client type of connection. So now, I am able to send data to my computer from another socket without getting any errors, but cannot read it with matlab.
status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
Just figured it out. Leaving this here in case it helps someone else as well.
When a connection is accepted, a new descriptor is returned (along with a new socket). This is a significant difference from connect(). So I was wrong at the following line.
status = write(s, "hello!", 6);
changing it to
status = write(client, "hello!", 6);
worked like a charm.
(Reference: http://users.pja.edu.pl/~jms/qnx/help/tcpip_4.25_en/prog_guide/sock_advanced_tut.html)

WebRTC DTLS-SRTP OpenSSL Server Handshake Failure

Here is my procedure in OpenSSL Server Mode,
Initialization Part of SSL and BIO variables:
map<int, SSL> m_SSLMap;
map<int, BIO> m_BioWriteMap;
map<int, BIO> m_BioReadMap;
int InitializeServerNegotiationMode(int iFd)
{
SSL *pServSslFd;
BIO *pWb, *pRb;
pServSslFd = SSL_new(m_pCtx);
assert(pServSslFd);
if ( SSL_version(pServSslFd) == DTLS1_VERSION)
{
pWb = BIO_new(BIO_s_mem());
pRb = BIO_new(BIO_s_mem());
assert(pWb);
assert(pRb);
SSL_set_bio(pServSslFd, pRb, pWb);
SSL_set_accept_state(pServSslFd);
}
m_SSLMap[iFd] = *pServSslFd;
m_BioReadMap[iFd] = *pRb;
m_BioWriteMap[iFd] = *pWb;
return INITIALIZATION_SUCCESS;
}
Server Mode Negotiation Operations when DTLS data comes to the server:
int ServerModeDTLSNegotiation(int iChannel, const char *pBuff, const int iLen, int iFd)
{
SSL *pServSslFd;
BIO *pRbio;
BIO *pWbio;
pServSslFd = &m_SSLMap[iFd];
pRbio = &m_BioReadMap[iFd];
pWbio = &m_BioWriteMap[iFd];
char buff[4096];
memset(buff, 0, strlen(buff));
BIO_write(pRbio, pBuff, iLen);
if(!SSL_is_init_finished(pServSslFd))
{
int iRet = SSL_do_handshake(pServSslFd);
}
int iNewLen = BIO_read(pWbio, buff, 2048);
if(iNewLen>0)
{
char *pNewData = new char[iNewLen+1];
for(int i=0;i<iNewLen;i++)
pNewData[i] = buff[i];
m_pEventHandler->SendReply(iChannel, (unsigned char *)pNewData, iNewLen);
}
else
{
printf("[DTLS]:: HandShaking Response failed for this data,
return -1;
}
return NEGOTIATION_SUCCESS;
}
Here I am attaching Wireshark TCP-Dump for better monitoring about the issue.
https://www.dropbox.com/s/quidcs6gilnvt2o/WebRTC%20DTLS%20Handshake%20Failure.pcapng?dl=0
Now, I am confident about my initialization of SSL_CTX variable. Because, Sometimes Handshake successfully negotiate for every port. But sometimes Handshake fails for one or two port. I am working for 5 days to solve WebRTC DTLS Server Mode Negotiation for Google Chrome. But I haven't found the root cause for this problem.
The link for TCP-Dump is not working.
Anyway, it seems your solution should work.
As it's a server program, it's definitely multi threaded. But it's really dangerous to initialize SSL variables or to perform handshake procedure without locking. In that case so many things can happen if these two methods are processed by multiple thread.
My suggestion is to add locking mechanism for these methods.

Server won't connect to more than one client?

The problem is it only connects to one client instead of two. Can anyone help me figure out why?
Server:
#include <SFML/System.hpp>
#include <SFML/Network.hpp>
#include <iostream>
void sendInfo(void *UserData)
{
sf::IPAddress* ip = static_cast<sf::IPAddress*>(UserData);
// Print something...
while(true){
// Create the UDP socket
sf::SocketUDP Socket;
// Create bytes to send
char Buffer[] = "sending info.";
// Send data to "192.168.0.2" on port 4567
if (Socket.Send(Buffer, sizeof(Buffer), *ip, 4444) != sf::Socket::Done)
{
// Error...
}
}
}
void receiveInfo(void *userData)
{
// Print something...
while(true){
// Create the UDP socket
sf::SocketUDP Socket;
// Bind it (listen) to the port 4567
if (!Socket.Bind(4444))
{
// Error...
}
char Buffer[128];
std::size_t Received;
sf::IPAddress Sender;
unsigned short Port;
if (Socket.Receive(Buffer, sizeof(Buffer), Received, Sender, Port) != sf::Socket::Done)
{
// Error...
}
// Show the address / port of the sender
std::cout << Buffer << std::endl;
Socket.Close();
}
}
int main()
{
sf::IPAddress client[2];
int connected = 0;
while(connected < 2){
// Create the UDP socket
sf::SocketUDP Socket;
// Bind it (listen) to the port 4567
if (!Socket.Bind(4444))
{
// Error...
}
char Buffer[128];
std::size_t Received;
sf::IPAddress Sender;
unsigned short Port;
if (Socket.Receive(Buffer, sizeof(Buffer), Received, Sender, Port) != sf::Socket::Done)
{
// Error...
}
// Show the address / port of the sender
client[connected] = Sender;
Socket.Close();
sf::Thread* send = new sf::Thread(&sendInfo, &client[connected]);
sf::Thread* receive = new sf::Thread(&receiveInfo, &client[connected]);
// Start it !
send->Launch();
receive->Launch();
connected++;
}
while(true){
}
return EXIT_SUCCESS;
}
Client:
#include <SFML/System.hpp>
#include <SFML/Network.hpp>
#include <iostream>
void sendInfo(void *UserData)
{
// Print something...
while(true){
// Create the UDP socket
sf::SocketUDP Socket;
// Create bytes to send
char Buffer[] = "client sending info.";
// Send data to "192.168.0.2" on port 4567
if (Socket.Send(Buffer, sizeof(Buffer), "127.0.0.1", 4444) != sf::Socket::Done)
{
// Error...
}
}
}
void receiveInfo(void *userData)
{
// Print something...
while(true){
// Create the UDP socket
sf::SocketUDP Socket;
// Bind it (listen) to the port 4567
if (!Socket.Bind(4444))
{
// Error...
}
char Buffer[128];
std::size_t Received;
sf::IPAddress Sender;
unsigned short Port;
if (Socket.Receive(Buffer, sizeof(Buffer), Received, Sender, Port) != sf::Socket::Done)
{
// Error...
}
// Show the address / port of the sender
std::cout << Buffer << std::endl;
Socket.Close();
}
}
int main()
{
// Create the UDP socket
sf::SocketUDP Socket;
// Create bytes to send
char Buffer[] = "Client Joined.";
// Send data to "192.168.0.2" on port 4567
if (Socket.Send(Buffer, sizeof(Buffer), "127.0.0.1", 4444) != sf::Socket::Done)
{
// Error...
}
sf::Thread* send = new sf::Thread(&sendInfo);
sf::Thread* receive = new sf::Thread(&receiveInfo);
// Start it !
send->Launch();
receive->Launch();
while(true){
}
return EXIT_SUCCESS;
}
First things first: is this a chat server or a 'more typical' server?
If this is a chat server, then you either need to have a list of sockets that are connected to the clients (you can connect UDP sockets using the connect() call, very convenient, and it also helps reduce the chances of spoofed peers) or a list of all the client addresses that you can supply to sendto() or sendmsg().
More 'typical' servers won't try to send messages to any client except the one that most recently made a request: those servers typically don't save anything from the clients, and instead will use recvfrom() or recvmsg() to get the peer's address for use in later sendto() or sendmsg() calls.
Also, most protocols only rely on one well known port; the server uses one specific port by convention, but clients select whatever port is open and free. FTP relies heavily on well-known ports on the client-side as well, and as a result is a gigantic pain to tunnel through Network Address Translation firewalls.
It isn't just academic: both your client and your server are attempting to bind() to port 4444. This means you need at least two IP addresses on a single machine to test, or use virtualization software to run an entirely separate machine on the same hardware, or just have two machines available. It's more work than it needs to be, and there's no reason for the clients to care about their local port numbers:
Server:
// Bind it (listen) to the port 4567
if (!Socket.Bind(4444))
{
// Error...
}
Client:
// Bind it (listen) to the port 4567
if (!Socket.Bind(4444))
{
// Error...
}
Poof! These two will never run on the same host without significant tricks. I expect your "it connects to one" is probably just the server or the client connecting to itself, but without some code to fill in those // Error blocks, it'd be tough to tell for sure.
(And while we're here, I'd like to take an aside to talk about comments; comments that simply re-state what the code does aren't very useful. You'll note that most of your comments are in fact wrong, referring to wrong IPs or ports. Some just don't add any information:
// Create the UDP socket
sf::SocketUDP Socket;
I know we're taught to add comments, but sadly we're not always taught what kind of comments to add. The only comment in both programs that I'd recommend even keeping would be this one, slightly amended:
// udp doesn't require listen or accept
if (!Socket.Bind(4444))
It isn't obvious from reading the code, and won't be wrong when the port number is read out of an environment variable, command line parameter, configuration file, or registry. (It might be too redundant in a team of people familiar with the sockets API, but might be gold for a programmer not that familiar with the differences between UDP and TCP.)
Good function names, variable names, etc., will win over comments almost every time. End of aside. :)
And now, the more minor nit-picking: your thread handlers are doing some tasks like this:
while(1) {
socket s;
bind s;
r = recv s;
print r;
close s;
}
This needless creation, binding, and closing, is all wasted energy, both the computer's energy and (much more importantly) your energy. Consider the following two re-writings:
recv_thread() {
socket s;
bind s;
while (1) {
r = recv s;
print r;
}
close s;
}
or
recv_thread(s) {
while (1) {
r = recv s;
print r;
}
}
/* ... */
socket s;
bind s;
sf::Thread* rt = new sf::Thread(&recv_thread);
rt->Launch(s);
The first option is a simple refactoring of your existing code; it keeps the socket creation and destruction in the thread function, but moves the loop invariants out of the loop. The code inside the loop now does only what is necessary.
The second option is a more drastic reworking: it moves the socket creation to the main thread, where error-handling is probably much easier, and the thread function only does exactly what the remote peer needs that thread to do. (If you wanted to change from UDP to TCP, the second option would be by far the much easier easier one to change -- your threading code might not need any modifications at all.)
I hope this helps. :)

Problem with IP_HDRINCL?

I already asked this question on raw IP packet implementation. But I didn't get any solutions.
My code:
if((s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_TCP, 0, 0, 0))==SOCKET_ERROR) // Socket
{
printf("Creation of raw socket failed.");
return 0;
}
if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
{
printf("failed to set socket in raw mode.");
return 0;
}
if((sendto(s ,(char *) buf , sizeof(IPV4_HDR)+sizeof(TCP_HDR) + payload, 0,(SOCKADDR *)&dest, sizeof(dest)))==SOCKET_ERROR)
{
printf("Error sending Packet : %d",WSAGetLastError());
break;
}
Error:
WSAGetLastError() returns 10022:
Description:
An invalid argument (for example, an argument that specified an invalid level) was supplied to the setsockopt (Wsapiref_94aa.asp) function. Sometimes, it also refers to the current state of the sockets, for example, calling accept (Wsapiref_13aq.asp) on a socket that is not listening.
Commentary:
But I have set the correct option value and size.
What am I doing wrong? I am using Windows XP (SP3). In setsocketopt I tried IP_OPTIONS for that program it works fine and it sends IP Packets too. But in ethereal for every IP packet it generates ICMP packets from the destination.
How can I fix this?
Source code:
//raw tcp packet crafter
#include "stdio.h"
#include "winsock2.h"
#include "ws2tcpip.h" //IP_HDRINCL is here
#include "conio.h"
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;
int main()
{
char host[100],buf[1000],*data=NULL,source_ip[20]; //buf is the complete packet
SOCKET s;
int k=1;
IPV4_HDR *v4hdr=NULL;
TCP_HDR *tcphdr=NULL;
int payload=512 ;
int optval= 1;
SOCKADDR_IN dest;
hostent *server;
//Initialise Winsock
WSADATA wsock;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsock) != 0)
{
fprintf(stderr,"WSAStartup() failed");
exit(EXIT_FAILURE);
}
printf("Initialised successfully.");
////////////////////////////////////////////////
//Create Raw TCP Packet
printf("\nCreating Raw TCP Socket...");
if((s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_TCP, 0, 0, 0))==SOCKET_ERROR)
{
printf("Creation of raw socket failed.");
return 0;
}
printf("Raw TCP Socket Created successfully.");
////////////////////////////////////////////////
//Put Socket in RAW Mode.
printf("\nSetting the socket in RAW mode...");
if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
{
printf("failed to set socket in raw mode.");
return 0;
}
printf("Successful.");
////////////////////////////////////////////////
//Target Hostname
printf("\nEnter hostname : ");
gets(host);
printf("\nResolving Hostname...");
if((server=gethostbyname(host))==0)
{
printf("Unable to resolve.");
return 0;
}
dest.sin_family = AF_INET;
dest.sin_port = htons(8888); //your destination port
memcpy(&dest.sin_addr.s_addr,server->h_addr,server->h_length);
printf("Resolved.");
/////////////////////////////////////////////////
printf("\nEnter Source IP : ");
gets(source_ip);
v4hdr = (IPV4_HDR *)buf; //lets point to the ip header portion
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(source_ip);
v4hdr->ip_destaddr = inet_addr(inet_ntoa(dest.sin_addr));
v4hdr->ip_checksum = 0;
tcphdr = (TCP_HDR *)&buf[sizeof(IPV4_HDR)]; //get the pointer to the tcp header in the packet
tcphdr->source_port = htons(1234);
tcphdr->dest_port = htons(8888);
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;
// Initialize the TCP payload to some rubbish
data = &buf[sizeof(IPV4_HDR) + sizeof(TCP_HDR)];
memset(data, '^', payload);
printf("\nSending packet...\n");
while(!_kbhit())
{
printf(" %d packets send\r",k++);
if((sendto(s ,(char *) buf , sizeof(IPV4_HDR)+sizeof(TCP_HDR) + payload, 0,(SOCKADDR *)&dest, sizeof(dest)))==SOCKET_ERROR)
{
printf("Error sending Packet : %d",WSAGetLastError());
break;
}
}
return 0;
}
You can't send data on a raw tcp socket in windows.
From here:
"Limitations on Raw Sockets
On Windows 7, Windows Vista, Windows XP with Service Pack 2 (SP2), and Windows XP with Service Pack 3 (SP3), the ability to send traffic over raw sockets has been restricted in several ways:
TCP data cannot be sent over raw sockets.
UDP datagrams with an invalid source address cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. This change was made to limit the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets (TCP/IP packets with a forged source IP address).
A call to the bind function with a raw socket for the IPPROTO_TCP protocol is not allowed.
"
Well, seems you don't have a counterparty to send to.
You have created the socket and set its option, but then you need either listen for incoming connection (bind() + accept()) or connect() to other party.
Error description: Sometimes, it also refers to the current state of the sockets - I guess it's your case. Your socket is not in connected state so sendto() is invalid.
Btw, for reference, there is a discussion regarding 'optval', whether it is bool or int. Apparently 'int' is the better choice, but I've seen lots of examples with bool.
Set IP_HDRINCL to setsockopt function in win32
I had used 'bool' and my program worked fine on Windows XP. Now it doesn't work on Win 7, with the 10022 error code.