Linux - Networking This forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
06-29-2015, 10:43 PM
|
#1
|
LQ Newbie
Registered: Apr 2013
Posts: 19
Rep:
|
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;
}
|
|
|
07-01-2015, 12:48 PM
|
#2
|
Moderator
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,914
|
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.
|
|
|
07-01-2015, 06:46 PM
|
#3
|
Member
Registered: Feb 2006
Distribution: Debian Sid
Posts: 792
|
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.
|
|
|
07-02-2015, 06:33 AM
|
#4
|
LQ Newbie
Registered: Apr 2013
Posts: 19
Original Poster
Rep:
|
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.
|
|
|
All times are GMT -5. The time now is 05:52 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|