LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Networking
User Name
Password
Linux - Networking This forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.

Notices


Reply
  Search this Thread
Old 06-29-2015, 10:43 PM   #1
aniruddha.jagdale
LQ Newbie
 
Registered: Apr 2013
Posts: 19

Rep: Reputation: Disabled
I'm getting sendto error (Invalid Argument) in blow code, please assist


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<string.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<netinet/udp.h>
#include<sys/socket.h>
using namespace std;

/*UDP Pseudo Header*/

struct psd_udp
{
struct in_addr src;
struct in_addr dst;
unsigned char pad;
unsigned char proto;
unsigned short udp_len;
struct udphdr udp;
};

/*Checksum function*/

unsigned short in_cksum(unsigned short *addr, int len)
{
int nleft = len;
int sum = 0;
unsigned short *w = addr;
unsigned short answer = 0;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}

if (nleft == 1)
{
*(unsigned char *) (&answer) = *(unsigned char *) w;
sum += answer;
}

sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}

/*UDP Checksum*/

unsigned short in_cksum_udp(int src, int dst, unsigned short *addr, int len)
{
struct psd_udp buf;

memset(&buf, 0, sizeof(buf));
buf.src.s_addr = src;
buf.dst.s_addr = dst;
buf.pad = 0;
buf.proto = IPPROTO_UDP;
buf.udp_len = htons(len);
memcpy(&(buf.udp), addr, len);
return in_cksum((unsigned short *)&buf, 12 + len);
}


int main()
{
int udprawsock;
u_char *packet;
const int any=1;
char data[9]="Hello!!";

struct ip ip_hdr;
struct udphdr udp_hdr;
struct sockaddr_in info4kernel;

packet=(u_char*)malloc(sizeof(ip_hdr)+sizeof(udp_hdr)+sizeof(data));


ip_hdr.ip_hl=5;
ip_hdr.ip_v=4;
ip_hdr.ip_tos=0;
ip_hdr.ip_len=htons(sizeof(ip_hdr)+sizeof(udp_hdr)+sizeof(data));
ip_hdr.ip_id=htons(1000);
ip_hdr.ip_off=0;
ip_hdr.ip_ttl=64;
ip_hdr.ip_p=IPPROTO_UDP;
ip_hdr.ip_sum=0;
ip_hdr.ip_src.s_addr=inet_addr("192.168.32.128");
ip_hdr.ip_dst.s_addr=inet_addr("192.168.32.1");
ip_hdr.ip_sum=in_cksum((unsigned short *)&ip_hdr,sizeof(ip_hdr));

memcpy(packet,&ip_hdr,sizeof(ip_hdr));

udp_hdr.source=htons(1500);
udp_hdr.dest=htons(1501);
udp_hdr.len=sizeof(udp_hdr)+sizeof(data);
udp_hdr.check=0;
udp_hdr.check=in_cksum_udp(ip_hdr.ip_src.s_addr,ip_hdr.ip_dst.s_addr,(unsigned short*)&udp_hdr,sizeof(udp_hdr));

memcpy(packet+20,&udp_hdr,sizeof(udp_hdr));
memcpy(packet+28,&data,sizeof(data));


udprawsock=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);

if(udprawsock<0)
{
perror("Socket Error:");
exit(1);
}

if(setsockopt(udprawsock,IPPROTO_IP,IP_HDRINCL,&any,sizeof(any))<0)
{
perror("setsock error:");
exit(1);
}

info4kernel.sin_family=AF_INET;
info4kernel.sin_addr.s_addr=ip_hdr.ip_dst.s_addr;

if(sendto(udprawsock,packet,sizeof(packet),0,(struct sockaddr *)&info4kernel,sizeof(info4kernel))<0)
{
perror("sendto error");
exit(1);
}

return 0;
}
 
Old 07-01-2015, 12:48 PM   #2
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,914
Blog Entries: 13

Rep: Reputation: 4948Reputation: 4948Reputation: 4948Reputation: 4948Reputation: 4948Reputation: 4948Reputation: 4948Reputation: 4948Reputation: 4948Reputation: 4948Reputation: 4948
First: Check the link in my signature on how to use [code][/code] tags.

I compiled your program and see the same error. The manual page doesn't help much.

I went for a brief search for a sendto() example and found one here. Check that out because it is very simple.

One issue may be that you've chosen to do SOCK_RAW versus SOCK_DGRAM which is the normal socket type for UDP.

I don't think you need to fully create the packet unless you're modifying the content from a standard UDP data frame. You can see in the example that you can choose the port and then send a data stream via UDP without worrying about constructing the packet, nor setting any socket options.

I'd start with the equivalent of that example and then modify as you see fit.

Note also that I do NOT need to be root to run that example, but because (I believe) you're using SOCK_RAW, then you need to be sudo or root to run what you've coded.

Last edited by rtmistler; 07-01-2015 at 12:49 PM.
 
Old 07-01-2015, 06:46 PM   #3
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 792

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
Code:
sendto(udprawsock,packet,sizeof(packet),0,(struct sockaddr *)&info4kernel,sizeof(info4kernel))
Don't know if this related to your problem, but sizeof(packet) is equal to sizeof(u_char *), 8 bytes on my machine.
 
Old 07-02-2015, 06:33 AM   #4
aniruddha.jagdale
LQ Newbie
 
Registered: Apr 2013
Posts: 19

Original Poster
Rep: Reputation: Disabled
Thank you rtmistler for a very nice explanation. Very much appreciated.

@norobro your analysis is spot on, that's where the problem was. I gave the size of u_char * but not the size of packet which was the root cause. I changed that to sizeof(ip_hdr)+sizeof(udp_hdr)+sizeof(data) and it worked like charm.

Thank you both.
 
  


Reply

Tags
c++


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
sendto() returning -1 - Invalid argument gr1980 Programming 2 09-11-2010 11:13 AM
sendto failed -1 : Invalid argument gr1980 Linux - Newbie 1 09-11-2010 03:01 AM
Please Help me : Sendto: Invalid argument PF_PACKET SOCK_DGRAM htons(ETH_P_IP) tuxtuxtux Linux - Networking 3 03-24-2010 07:08 AM
sendto: Invalid argument netbsd quantt Programming 3 02-14-2009 03:29 AM
sendto: invalid argument Yury Programming 12 11-04-2006 07:06 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Networking

All times are GMT -5. The time now is 05:52 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration