添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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
  • Terms of Use Privacy Policy License Agreements