problem with sendto and raw sockets

Fernando Barsoba fbarsoba@verizon.net
Tue Oct 25 03:37:00 GMT 2005


Hi all,

I'm stuck trying to send an IP header through raw sockets. I'm using 
Eclipse and cygwin.. but I have been told that raw sockets should work 
with cygwin.. I got the definition for IP_HDRINCL from the last 
snapshot. I only got the socket.h header file from the snapshot... and 
not the whole thing. I have been able to build the program, but I am not 
sure if using only the socket.h could be the problem...

The error that I get back is: Cannot assign requested address.

Here's my code. I have been trying with this implementation using raw 
sockets and I have the same problem -> http://www.whitefang.com/rin/
(rawsock-05)

Any help appreciated.. i'm stuck with this thing..

FBM

ipsec_v4.c-------------

#include    "ipsec_v4.h"
#include    <stdio.h>
#include    <stdlib.h>

#define IP_VERSION 4
#define LEN    512

struct ip * build_ip_packet() {
    struct ip *iphdr;
    int packet_size;
    char *packet;
    struct in_addr ipsrc_addr, ipdst_addr;
    const char *host = "192.168.2.3";
    const char *dest = "192.168.2.2";
    
    packet_size = sizeof(struct ip);
    packet = malloc(packet_size);
    bzero(packet, packet_size);   
    iphdr = (struct ip *)packet;       

    inet_aton(host, &ipsrc_addr);
    inet_aton(dest, &ipdst_addr);
    
    iphdr->ip_v = 4;
    iphdr->ip_hl = 5;
    iphdr->ip_tos = 0;
    iphdr->ip_len = 0x1400;
    iphdr->ip_id = 0;
    iphdr->ip_off = 0;
    iphdr->ip_ttl = 64;
    iphdr->ip_p = 51;
    iphdr->ip_src = ipsrc_addr;
    iphdr->ip_dst = ipdst_addr;
    iphdr->ip_sum = 0;

    iphdr->ip_sum = in_cksum((u_short *) iphdr, (iphdr->ip_hl) << 2);

    return iphdr;
}

int main(int argc, char **argv) {
    int s, port;
    struct ip *ip_datagram;
    const int on = 1;
    struct sockaddr_in sin;
    char host[LEN];
    struct hostent *hp;

    hp = gethostbyname(argv[1]);
    if ( hp == NULL ) {
        fprintf(stderr, "%s: host not found (%s)\n", argv[0], host);
        exit(1);
    }
    port = atoi("5555");
    
    s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    memcpy(&sin.sin_addr, hp->h_addr_list[0], hp->h_length);

    ip_datagram = build_ip_packet();
    
    if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
        perror("setsockopt:");
        exit(s);
    }
    ssize_t returned;
    returned = sendto(s, ip_datagram, 20, 0, (struct sockaddr *) &sin, 
sizeof(sin));
    if (returned < 0) {
        perror("sendto");
        exit(1);
    }
    exit(0);   
}

checksum.c --------

#include <sys/types.h>
#include <netinet/in.h>

uint16_t in_cksum (uint16_t * addr, int len) {
     int nleft = len;
     uint32_t sum = 0;
     uint16_t *w = addr;
     uint16_t answer = 0;

    /*
     * Our algorithm is simple, using a 32 bit accumulator (sum), we add
    * sequential 16 bit words to it, and at the end, fold back all the
    * carry bits from the top 16 bits into the lower 16 bits.
    */
    while (nleft > 1) {
        sum += ntohs(*w++);
        nleft -= 2;
    }
    /* mop up an odd byte, if necessary */
    if (nleft == 1) {        /* ntohs shoudl be added here too.. to do!
        * (unsigned char *) (&answer) = * (unsigned char *) w;
        sum += answer;
    }

    /* add back carry outs from top 16 bits to low 16 bits */
    sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
    sum += (sum >> 16);     /* add carry */
    answer = ~sum;     /* truncate to 16 bits */
    return (answer);
}



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list