Uninitialized vector entry?
[minix3.git] / lib / ip / sendto.c
blob6c805ffce97d243f87297fe494f764bbd0d542b1
1 #undef NDEBUG
3 #include <assert.h>
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <sys/ioctl.h>
10 #include <sys/socket.h>
11 #include <netinet/in.h>
13 #include <net/gen/in.h>
14 #include <net/gen/udp.h>
15 #include <net/gen/udp_hdr.h>
16 #include <net/gen/udp_io.h>
18 #define DEBUG 0
20 static ssize_t _udp_sendto(int socket, const void *message, size_t length,
21 int flags, const struct sockaddr *dest_addr, socklen_t dest_len,
22 nwio_udpopt_t *udpoptp);
24 ssize_t sendto(int socket, const void *message, size_t length, int flags,
25 const struct sockaddr *dest_addr, socklen_t dest_len)
27 int r;
28 nwio_udpopt_t udpopt;
30 r= ioctl(socket, NWIOGUDPOPT, &udpopt);
31 if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
33 if (r == -1)
34 return r;
35 return _udp_sendto(socket, message, length, flags,
36 dest_addr, dest_len, &udpopt);
39 #if DEBUG
40 fprintf(stderr, "sendto: not implemented for fd %d\n", socket);
41 #endif
42 errno= ENOSYS;
43 return -1;
46 static ssize_t _udp_sendto(int socket, const void *message, size_t length,
47 int flags, const struct sockaddr *dest_addr, socklen_t dest_len,
48 nwio_udpopt_t *udpoptp)
50 int r, t_errno;
51 size_t buflen;
52 void *buf;
53 struct sockaddr_in *sinp;
54 udp_io_hdr_t *io_hdrp;
56 if (flags)
58 #if DEBUG
59 fprintf(stderr, "sendto(udp): flags not implemented\n");
60 #endif
61 errno= ENOSYS;
62 return -1;
65 if (udpoptp->nwuo_flags & NWUO_RWDATONLY)
66 return write(socket, message, length);
68 if ((udpoptp->nwuo_flags & NWUO_RP_ANY) ||
69 (udpoptp->nwuo_flags & NWUO_RA_ANY))
71 if (!dest_addr)
73 errno= ENOTCONN;
74 return -1;
77 /* Check destination address */
78 if (dest_len < sizeof(*sinp))
80 errno= EINVAL;
81 return -1;
83 sinp= (struct sockaddr_in *)dest_addr;
84 if (sinp->sin_family != AF_INET)
86 errno= EAFNOSUPPORT;
87 return -1;
91 buflen= sizeof(*io_hdrp) + length;
92 if (buflen < length)
94 /* Overflow */
95 errno= EMSGSIZE;
96 return -1;
98 buf= malloc(buflen);
99 if (buf == NULL)
100 return -1;
102 io_hdrp= buf;
103 io_hdrp->uih_src_addr= 0; /* Unused */
104 io_hdrp->uih_src_port= 0; /* Will cause error if NWUO_LP_ANY */
105 if (udpoptp->nwuo_flags & NWUO_RA_ANY)
106 io_hdrp->uih_dst_addr= sinp->sin_addr.s_addr;
107 else
108 io_hdrp->uih_dst_addr= 0;
109 if (udpoptp->nwuo_flags & NWUO_RP_ANY)
110 io_hdrp->uih_dst_port= sinp->sin_port;
111 else
112 io_hdrp->uih_dst_port= 0;
113 io_hdrp->uih_ip_opt_len= 0;
114 io_hdrp->uih_data_len= 0;
116 memcpy(&io_hdrp[1], message, length);
117 r= write(socket, buf, buflen);
118 if (r == -1)
120 t_errno= errno;
121 free(buf);
122 errno= t_errno;
123 return -1;
125 assert(r == buflen);
126 free(buf);
127 return length;