udp_xfer.c revision 1.1 1 /* $NetBSD: udp_xfer.c,v 1.1 2006/01/21 10:32:23 dsl Exp $ */
2
3 /*-
4 * Copyright (c) 2006 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by David Laight.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The NetBSD Foundation nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include <sys/cdefs.h>
36 __RCSID("$NetBSD: udp_xfer.c,v 1.1 2006/01/21 10:32:23 dsl Exp $");
37
38 #include <sys/types.h>
39 #include <unistd.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <sys/poll.h>
43 #include <netdb.h>
44 #include <err.h>
45
46 typedef uint32_t n_long;
47 #include <net.h>
48
49 void
50 set_port(struct sockaddr *sa, int port)
51 {
52
53 switch (sa->sa_family) {
54 case AF_INET:
55 ((struct sockaddr_in *)sa)->sin_port = port;
56 break;
57 #ifdef INET6
58 case AF_INET6:
59 ((struct sockaddr_in6 *)sa)->sin6_port = port;
60 break;
61 #endif
62 default:
63 errx(1, "Unsupported socket family %d",
64 sa->sa_family);
65 }
66 }
67
68 ssize_t
69 sendudp(struct iodesc *d, void *pkt, size_t len)
70 {
71 int sock;
72 int range = IP_PORTRANGE_LOW;
73
74 if (d->socket >= 0) {
75 close(d->socket);
76 d->socket = -1;
77 }
78
79 sock = socket(d->ai->ai_family, SOCK_DGRAM, IPPROTO_UDP);
80 if (sock < 0)
81 return -1;
82 d->socket = sock;
83 set_port(d->ai->ai_addr, d->destport);
84
85 setsockopt(sock, IPPROTO_IP, IP_PORTRANGE, &range, sizeof(range));
86
87 if (connect(sock, d->ai->ai_addr, d->ai->ai_addrlen) != 0)
88 return -1;
89
90 return send(sock, pkt, len, 0);
91 }
92
93 ssize_t
94 readudp(struct iodesc *d, void *pkt, size_t len, time_t tleft)
95 {
96 struct pollfd pfd = {d->socket, POLLIN, 0};
97
98 if (poll(&pfd, 1, tleft * 1000) != 1)
99 return -1;
100
101 return recv(d->socket, pkt, len, 0);
102 }
103