I found a reference (
http://www.tenouk.com/Module43a.html
) for using raw sockets to send a simple UDP packet in Linux, but I cannot get it to work on macOS Sierra10.12.1. I've tried a number of different variations, but sendto() always returns
Invalid argument
.
I'd be grateful if you could point out my mistake.
Thanks!
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#define PCKT_LEN 8192
struct ipheader {
unsigned char iph_ihl:5, iph_ver:4;
unsigned char iph_tos;
unsigned short int iph_len;
unsigned short int iph_ident;
unsigned char iph_flag;
unsigned short int iph_offset;
unsigned char iph_ttl;
unsigned char iph_protocol;
unsigned short int iph_chksum;
unsigned int iph_sourceip;
unsigned int iph_destip;
struct udpheader {
unsigned short int udph_srcport;
unsigned short int udph_destport;
unsigned short int udph_len;
unsigned short int udph_chksum;
unsigned short csum(unsigned short *buf, int nwords)
unsigned long sum;
for(sum=0; nwords>0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum &0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
int main(int argc, char *argv[])
int sd;
char buffer[PCKT_LEN], *data;
struct ipheader *ip = (struct ipheader *) buffer;
struct udpheader *udp = (struct udpheader *) (buffer + sizeof(struct ipheader));
data = ((char *)udp + sizeof(struct udpheader));
struct sockaddr_in sin, din;
int one = 1;
const int *val = &one;
memset(buffer, 0, PCKT_LEN);
printf("*** start Debug ***\n");
printf("char: %lu\n", sizeof(char));
printf("short: %lu\n", sizeof(short));
printf("unsigned short: %lu\n", sizeof(unsigned short));
printf("int: %lu\n", sizeof(int));
printf("unsigned int: %lu\n", sizeof(unsigned int));
printf("long: %lu\n", sizeof(long));
printf("unsigned long: %lu\n", sizeof(unsigned long));
printf("*** end Debug ***\n");
if(argc != 5)
printf("- Invalid parameters!!!\n");
printf("- Usage %s <source hostname/IP> <source port> <target hostname/IP> <target port>\n", argv[0]);
exit(-1);
int srcPort = atoi(argv[2]);
int destPort = atoi(argv[4]);
char *str_srcIP = argv[1];
char *str_destIP = argv[3];
int srcPort = 23;
int destPort = 23;
char str_srcIP[] = "192.168.1.72";
char str_destIP[] = "192.168.1.73";
sd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
if(sd < 0)
perror("socket() error");
exit(-1);
printf("socket() - Using SOCK_RAW socket and UDP protocol is OK.\n");
sin.sin_len = sizeof(sin);
din.sin_len = sizeof(din);
sin.sin_family = AF_INET;
din.sin_family = AF_INET;
sin.sin_port = htons(srcPort);
din.sin_port = htons(destPort);
sin.sin_addr.s_addr = inet_addr(str_srcIP);
din.sin_addr.s_addr = inet_addr(str_destIP);
strcpy(data, "A");
unsigned long payloadSize = sizeof(struct ipheader) + sizeof(struct udpheader) + strlen(data);
ip->iph_ihl = 5;
ip->iph_ver = 4;
ip->iph_tos = 0;
ip->iph_len = payloadSize;
ip->iph_ident = htons(54321);
ip->iph_ttl = 64;
ip->iph_protocol = IPPROTO_UDP;
ip->iph_sourceip = inet_addr(str_srcIP);
ip->iph_destip = inet_addr(str_destIP);
udp->udph_srcport = htons(srcPort);
udp->udph_destport = htons(destPort);
udp->udph_len = htons(sizeof(struct udpheader));
ip->iph_chksum = csum((unsigned short *)buffer, sizeof(struct ipheader) + sizeof(struct udpheader));
if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)
perror("setsockopt() error");
exit(-1);
printf("setsockopt() is OK.\n");
printf("Trying...\n");
printf("Using raw socket and UDP protocol\n");
printf("Using Source IP: %s port: %u, Target IP: %s port: %u.\n", str_srcIP, srcPort, str_destIP, destPort);
std::cout<<"*** start Debug ***"<<std::endl;
std::cout<<"sd: "<<sd<<std::endl;
std::cout<<"Buffer: "<<buffer<<std::endl;
std::cout<<"iph_len: "<<ip->iph_len<<std::endl;
std::cout<<"sin: "<<(struct sockaddr *)&sin<<std::endl;
std::cout<<"sizeof(sin): "<<sizeof(sin)<<std::endl;
std::cout<<"*** end Debug ***"<<std::endl;
int count;
for(count = 1; count <=20; count++)
if(sendto(sd, buffer, ip->iph_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
perror("sendto() error");
exit(-1);
printf("Count #%u - sendto() is OK.\n", count);
sleep(2);
close(sd);
return 0;
What are you trying to do here? Most folks who want to send UDP use a UDP socket (that is,
AF_INET
or
AF_INET6
with
SOCK_DGRAM
). Why are you trying to send UDP using a raw socket?
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the
Apple Developer Forums Participation Agreement.
Forums
Apple Developer Program
Apple Developer Enterprise Program
App Store Small Business Program
MFi Program
News Partner Program
Video Partner Program
Security Bounty Program
Security Research Device Program