Sorry, but nope.  But I guess if you can post a complete source code

Again your right ;-)

There are two functions udp_raw_send and ip4_udp_raw_send. The first function which is called udp_raw_send has 6 arguments: source address, destination address, source port, destination port, payload and payload_length. This function does nothing else than determinig which protocol the address belongs to (IPv4 or IPv6) and call up the ip4_udp_raw_send function with the arguments like udp_raw_send except that the source and destination address are now in network byte order. The ip4_udp_raw_send function then calculates the checksum etc and sends then the udp packet out. Here are the two functions:

int udp_raw_send(const char *src_addr, const char *dst_addr,
                 const char *src_port, const char *dst_port,
                 const u_char *payload, const int payload_len) {

    struct addrinfo hints, *src_ai, *dst_ai;
    int result;
    int getaddrinfoError;

    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = 0;
    hints.ai_protocol = 0;
    hints.ai_addrlen = 0;
    hints.ai_canonname = NULL;
    hints.ai_addr = NULL;
    hints.ai_next = NULL;

if((getaddrinfoError = getaddrinfo(src_addr, src_port, &hints, &src_ai))
       != 0) {
        fprintf(stderr, "Error getaddrinfo (src address): %s\n",
                gai_strerror(getaddrinfoError));
        exit(EXIT_FAILURE);
    }

    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = 0;
    hints.ai_protocol = 0;
    hints.ai_addrlen = 0;
    hints.ai_canonname = NULL;
    hints.ai_addr = NULL;
    hints.ai_next = NULL;

if((getaddrinfoError = getaddrinfo(dst_addr, dst_port, &hints, &dst_ai))
       != 0) {
        fprintf(stderr, "Error getaddrinfo (dst address): %s\n",
                gai_strerror(getaddrinfoError));
        exit(EXIT_FAILURE);
    }

/* check if source and destination address are from the same ip family */
    if(src_ai->ai_family != dst_ai->ai_family) {
fprintf(stderr, "Error: source and destination address aren't from" \ " the same ip family. Maybe one is an IPv4 address" \
                        " and the other an IPv6 address\n");
        exit(EXIT_FAILURE);
    }

    if(src_ai->ai_family == AF_INET) {
        struct sockaddr_in *sin_src, *sin_dst;
        sin_src = (struct sockaddr_in *)src_ai->ai_addr;
        sin_dst = (struct sockaddr_in *)dst_ai->ai_addr;
        result = ip4_udp_raw_send(sin_src->sin_addr.s_addr,
                                  sin_dst->sin_addr.s_addr,
src_port, dst_port, payload, payload_len);
    } else if(src_ai->ai_family == AF_INET6) {
        struct sockaddr_in6 *sin6_src, *sin6_dst;
        sin6_src = (struct sockaddr_in6 *)src_ai->ai_addr;
        sin6_dst = (struct sockaddr_in6 *)dst_ai->ai_addr;
        result = ip6_udp_raw_send((char *)sin6_src->sin6_addr.s6_addr,
                                  (char *)sin6_dst->sin6_addr.s6_addr,
src_port, dst_port, payload, payload_len,
                                  dst_ai);
/*      result = ip6_udp_raw_send((char *)&(sin6_src->sin6_addr),
                                  (char *)&(sin6_dst->sin6_addr),
src_port, dst_port, payload, payload_len, (struct sockaddr_in6 *)(dst_ai- >ai_addr));*/
    } else {
        fprintf(stderr, "Error: please choose an address of" \
                        " AF_INET or AF_INET6\n");
        exit(EXIT_FAILURE);
    }

    freeaddrinfo(src_ai);
    freeaddrinfo(dst_ai);

    return(result);
}

int ip4_udp_raw_send(u_long src_addr, u_long dst_addr, const char *src_port,
                     const char *dst_port, const u_char *payload,
                     int payload_len) {
    struct sockaddr_in sin4;
    struct ip *iphdr;
    struct udphdr *udp;
    struct pseudo_udphdr *pseudo_udp;
    u_char *data;
unsigned char *packet = safe_zalloc(iphdr_len + udphdr_len + payload_len);
    int sockfd;
    const int on = 1;
    int result;

    iphdr = (struct ip *)packet;
    udp = (struct udphdr *)(packet + sizeof(struct ip));
    pseudo_udp = (struct pseudo_udphdr *) ((char *)udp - 12);
data = (u_char *)(packet + sizeof(struct ip) + sizeof(struct udphdr));

    memcpy(data, payload, payload_len);

    udp->uh_sport = htons(atoi(src_port));
    udp->uh_dport = htons(atoi(dst_port));
    udp->uh_ulen = htons(sizeof(struct udphdr) + payload_len);
    udp->uh_sum = 0;

    pseudo_udp->puh_src.s_addr = src_addr;
    pseudo_udp->puh_dst.s_addr = dst_addr;
    pseudo_udp->puh_p = IPPROTO_UDP;
    pseudo_udp->puh_ulen = htons(sizeof(struct udphdr) + payload_len);

    udp->uh_sum = in_cksum((unsigned short *)pseudo_udp,
sizeof(struct udphdr) + sizeof(struct pseudo_udphdr)
                           + payload_len);

/* "destroy" the pseudo udp header because the checksum is calculated
     *  and the space is know needed for the ip header */
    memset(pseudo_udp, '\0', sizeof(*pseudo_udp));

    iphdr->ip_v = 4;    /* header version */
    iphdr->ip_hl = 0x5; /* header length */
    iphdr->ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr)
                          + payload_len);   /* total length */
    iphdr->ip_ttl = 245;   /* time to live */
    iphdr->ip_p = IPPROTO_UDP;
    iphdr->ip_src.s_addr = src_addr;
    iphdr->ip_dst.s_addr = dst_addr;
    iphdr->ip_sum = 0;
    iphdr->ip_sum = in_cksum((u_int16_t *)&packet, sizeof(struct ip));

    sin4.sin_family = AF_INET;
    sin4.sin_addr.s_addr = dst_addr;
    sin4.sin_port = udp->uh_dport;

    sockfd = Socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

Setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof (on));

result = Sendto(sockfd, packet, (sizeof(struct ip) + sizeof (struct udphdr)
                    + payload_len), 0, (struct sockaddr *)&sin4,
                    (socklen_t)sizeof(struct sockaddr));

    return(result);
}

While using this functions I get this error on a FreeBSD system (RELENG_6_0):
sendto: Invalid argument

If you need the whole source code you can d/l here: http:// www.seekline.net/sile.tar.gz
After building via "make" you can execute the program like this:
./sile_send --src 192.168.0.1 --dst 192.168.0.2 --sport 53 --dport 53 --cmd echo
Then the error should occur.

Best regards, Stefan
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to