To be more precise the sendmsg() in the following fails on
        certian platforms.

        Mark

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/uio.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

int
main(int argc, char **argv) {
        struct sockaddr_in6 sa;
        int fd;
        int res;
        int on = 1;

        fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
        if (fd == -1) {
                perror("socket");
                exit(1);
        }

        fprintf(stderr, "socket options");
#ifdef SO_BSDCOMPAT
        fprintf(stderr, " SO_BSDCOMPAT");
        res = setsockopt(fd, SOL_SOCKET, SO_BSDCOMPAT, (void *)&on, sizeof(on));
        if (res == -1)
                perror("setsockopt(SO_BSDCOMPAT)");
#endif

#ifdef SO_TIMESTAMP
        fprintf(stderr, " SO_TIMESTAMP");
        res = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, (void *)&on, sizeof(on));
        if (res == -1)
                perror("setsockopt(SO_TIMESTAMP)");
#endif

#ifdef IPV6_RECVPKTINFO
        fprintf(stderr, " IPV6_RECVPKTINFO");
        res = setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
                         (void *)&on, sizeof(on));
        if (res == -1)
                perror("setsockopt(IPV6_RECVPKTINFO)");
#else
        fprintf(stderr, " IPV6_PKTINFO");
        res = setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO,
                         (void *)&on, sizeof(on));
        if (res == -1)
                perror("setsockopt(IPV6_PKTINFO)");
#endif
        fprintf(stderr, "\n");

        memset(&sa, 0, sizeof(sa));
        sa.sin6_addr = in6addr_any;
        sa.sin6_family = PF_INET6;
        sa.sin6_port = htons(0);
#ifdef SIN6_LEN
        sa.sin6_len = sizeof(sa);
#endif

        res = bind(fd, (struct sockaddr *)&sa, sizeof(sa));
        if (res == -1) {
                perror("bind");
                exit(1);
        }
                
        while (*++argv != NULL) {
                struct msghdr msg;
                struct iovec io;

                memset(&sa, 0, sizeof(sa));
                if (inet_pton(PF_INET6, *argv, &sa.sin6_addr) != 1)
                        continue;
                sa.sin6_family = PF_INET6;
                sa.sin6_port = htons(9);        /* discard */
#ifdef SIN6_LEN
                sa.sin6_len = sizeof(sa);
#endif

                /* some data */
                io.iov_base = "1234";
                io.iov_len = 4;

                msg.msg_name = &sa;
                msg.msg_namelen = sizeof(sa);
                msg.msg_iov = &io;
                msg.msg_iovlen = 1;
                msg.msg_control = NULL;
                msg.msg_controllen = 0;
                msg.msg_flags = 0;

                fprintf(stderr, "trying %s#9 ... ", *argv);

                errno = 0;
                res = sendmsg(fd, &msg, 0);
                if (res != 4)
                        perror("sendto");
                else
                        fprintf(stderr, "success\n");
                
        }
        close(fd);
        return (0);
}
--
Mark Andrews, Internet Software Consortium
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: [EMAIL PROTECTED]

Reply via email to