source: trunk/minix/lib/ip/sendto.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 2.5 KB
Line 
1#undef NDEBUG
2
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>
12
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>
17
18#define DEBUG 0
19
20static 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);
23
24ssize_t sendto(int socket, const void *message, size_t length, int flags,
25 const struct sockaddr *dest_addr, socklen_t dest_len)
26{
27 int r;
28 nwio_udpopt_t udpopt;
29
30 r= ioctl(socket, NWIOGUDPOPT, &udpopt);
31 if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
32 {
33 if (r == -1)
34 return r;
35 return _udp_sendto(socket, message, length, flags,
36 dest_addr, dest_len, &udpopt);
37 }
38
39#if DEBUG
40 fprintf(stderr, "sendto: not implemented for fd %d\n", socket);
41#endif
42 errno= ENOSYS;
43 return -1;
44}
45
46static 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)
49{
50 int r, t_errno;
51 size_t buflen;
52 void *buf;
53 struct sockaddr_in *sinp;
54 udp_io_hdr_t *io_hdrp;
55
56 if (flags)
57 {
58#if DEBUG
59 fprintf(stderr, "sendto(udp): flags not implemented\n");
60#endif
61 errno= ENOSYS;
62 return -1;
63 }
64
65 if (udpoptp->nwuo_flags & NWUO_RWDATONLY)
66 return write(socket, message, length);
67
68 if ((udpoptp->nwuo_flags & NWUO_RP_ANY) ||
69 (udpoptp->nwuo_flags & NWUO_RA_ANY))
70 {
71 /* Check destination address */
72 if (dest_len < sizeof(*sinp))
73 {
74 errno= EINVAL;
75 return -1;
76 }
77 sinp= (struct sockaddr_in *)dest_addr;
78 if (sinp->sin_family != AF_INET)
79 {
80 errno= EAFNOSUPPORT;
81 return -1;
82 }
83 }
84
85 buflen= sizeof(*io_hdrp) + length;
86 if (buflen < length)
87 {
88 /* Overflow */
89 errno= EMSGSIZE;
90 return -1;
91 }
92 buf= malloc(buflen);
93 if (buf == NULL)
94 return -1;
95
96 io_hdrp= buf;
97 io_hdrp->uih_src_addr= 0; /* Unused */
98 io_hdrp->uih_src_port= 0; /* Will cause error if NWUO_LP_ANY */
99 if (udpoptp->nwuo_flags & NWUO_RA_ANY)
100 io_hdrp->uih_dst_addr= sinp->sin_addr.s_addr;
101 else
102 io_hdrp->uih_dst_addr= 0;
103 if (udpoptp->nwuo_flags & NWUO_RP_ANY)
104 io_hdrp->uih_dst_port= sinp->sin_port;
105 else
106 io_hdrp->uih_dst_port= 0;
107 io_hdrp->uih_ip_opt_len= 0;
108 io_hdrp->uih_data_len= 0;
109
110 memcpy(&io_hdrp[1], message, length);
111 r= write(socket, buf, buflen);
112 if (r == -1)
113 {
114 t_errno= errno;
115 free(buf);
116 errno= t_errno;
117 return -1;
118 }
119 assert(r == buflen);
120 free(buf);
121 return length;
122}
123
Note: See TracBrowser for help on using the repository browser.