diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2012-08-30 01:09:22 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2012-08-30 01:09:22 +0000 |
commit | 1dbb4f86570541f2aab1fe65e7b6d16f69605259 (patch) | |
tree | c5ee143900aaaf2c7fa47a9c3366316c4fd46a1c /libexec | |
parent | 7c2016e04b7360510ca31791e9cb94a974dc12dc (diff) |
remove libexec/tftp-proxy now we have usr.sbin/tftp-proxy
ok deraadt@
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/tftp-proxy/Makefile | 7 | ||||
-rw-r--r-- | libexec/tftp-proxy/filter.c | 192 | ||||
-rw-r--r-- | libexec/tftp-proxy/filter.h | 28 | ||||
-rw-r--r-- | libexec/tftp-proxy/tftp-proxy.8 | 121 | ||||
-rw-r--r-- | libexec/tftp-proxy/tftp-proxy.c | 335 |
5 files changed, 0 insertions, 683 deletions
diff --git a/libexec/tftp-proxy/Makefile b/libexec/tftp-proxy/Makefile deleted file mode 100644 index b5f4eefc089..00000000000 --- a/libexec/tftp-proxy/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# $OpenBSD: Makefile,v 1.1 2005/12/28 19:07:07 jcs Exp $ - -PROG= tftp-proxy -SRCS= tftp-proxy.c filter.c -MAN= tftp-proxy.8 - -.include <bsd.prog.mk> diff --git a/libexec/tftp-proxy/filter.c b/libexec/tftp-proxy/filter.c deleted file mode 100644 index 90a80d367f3..00000000000 --- a/libexec/tftp-proxy/filter.c +++ /dev/null @@ -1,192 +0,0 @@ -/* $OpenBSD: filter.c,v 1.13 2012/07/08 11:57:08 sthen Exp $ */ - -/* - * Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <syslog.h> - -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/socket.h> - -#include <net/if.h> -#include <net/pfvar.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> - -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "filter.h" - -/* From netinet/in.h, but only _KERNEL_ gets them. */ -#define satosin(sa) ((struct sockaddr_in *)(sa)) -#define satosin6(sa) ((struct sockaddr_in6 *)(sa)) - -enum { TRANS_FILTER = 0, TRANS_NAT, TRANS_RDR, TRANS_SIZE }; - -int prepare_rule(u_int32_t, struct sockaddr *, struct sockaddr *, - u_int16_t, u_int8_t); - -static struct pfioc_rule pfr; -static struct pfioc_trans pft; -static struct pfioc_trans_e pfte; -static int dev, rule_log; -static char *qname; - -int -add_filter(u_int32_t id, u_int8_t dir, struct sockaddr *src, - struct sockaddr *dst, u_int16_t d_port, u_int8_t proto) -{ - if (!src || !dst || !d_port || !proto) { - errno = EINVAL; - return (-1); - } - - if (prepare_rule(id, src, dst, d_port, proto) == -1) - return (-1); - - pfr.rule.direction = dir; - if (ioctl(dev, DIOCADDRULE, &pfr) == -1) - return (-1); - - return (0); -} - -int -do_commit(void) -{ - if (ioctl(dev, DIOCXCOMMIT, &pft) == -1) - return (-1); - - return (0); -} - -void -init_filter(char *opt_qname, int opt_verbose) -{ - struct pf_status status; - - qname = opt_qname; - - if (opt_verbose == 1) - rule_log = PF_LOG; - else if (opt_verbose == 2) - rule_log = PF_LOG_ALL; - - dev = open("/dev/pf", O_RDWR); - if (dev == -1) { - syslog(LOG_ERR, "can't open /dev/pf"); - exit(1); - } - if (ioctl(dev, DIOCGETSTATUS, &status) == -1) { - syslog(LOG_ERR, "DIOCGETSTATUS"); - exit(1); - } - if (!status.running) { - syslog(LOG_ERR, "pf is disabled"); - exit(1); - } -} - -int -prepare_commit(u_int32_t id) -{ - char an[PF_ANCHOR_NAME_SIZE]; - - memset(&pft, 0, sizeof pft); - memset(&pfte, 0, sizeof pfte); - pft.size = 1; - pft.esize = sizeof pfte; - pft.array = &pfte; - - snprintf(an, PF_ANCHOR_NAME_SIZE, "%s/%d.%d", FTP_PROXY_ANCHOR, - getpid(), id); - strlcpy(pfte.anchor, an, PF_ANCHOR_NAME_SIZE); - pfte.type = PF_TRANS_RULESET; - - if (ioctl(dev, DIOCXBEGIN, &pft) == -1) - return (-1); - - return (0); -} - -int -prepare_rule(u_int32_t id, struct sockaddr *src, - struct sockaddr *dst, u_int16_t d_port, u_int8_t proto) -{ - char an[PF_ANCHOR_NAME_SIZE]; - - if ((src->sa_family != AF_INET && src->sa_family != AF_INET6) || - (src->sa_family != dst->sa_family)) { - errno = EPROTONOSUPPORT; - return (-1); - } - - memset(&pfr, 0, sizeof pfr); - snprintf(an, PF_ANCHOR_NAME_SIZE, "%s/%d.%d", FTP_PROXY_ANCHOR, - getpid(), id); - strlcpy(pfr.anchor, an, PF_ANCHOR_NAME_SIZE); - - pfr.ticket = pfte.ticket; - - /* Generic for all rule types. */ - pfr.rule.af = src->sa_family; - pfr.rule.proto = proto; - pfr.rule.src.addr.type = PF_ADDR_ADDRMASK; - pfr.rule.dst.addr.type = PF_ADDR_ADDRMASK; - pfr.rule.rdr.addr.type = PF_ADDR_NONE; - pfr.rule.nat.addr.type = PF_ADDR_NONE; - - if (src->sa_family == AF_INET) { - memcpy(&pfr.rule.src.addr.v.a.addr.v4, - &satosin(src)->sin_addr.s_addr, 4); - memset(&pfr.rule.src.addr.v.a.mask.addr8, 255, 4); - memcpy(&pfr.rule.dst.addr.v.a.addr.v4, - &satosin(dst)->sin_addr.s_addr, 4); - memset(&pfr.rule.dst.addr.v.a.mask.addr8, 255, 4); - } else { - memcpy(&pfr.rule.src.addr.v.a.addr.v6, - &satosin6(src)->sin6_addr.s6_addr, 16); - memset(&pfr.rule.src.addr.v.a.mask.addr8, 255, 16); - memcpy(&pfr.rule.dst.addr.v.a.addr.v6, - &satosin6(dst)->sin6_addr.s6_addr, 16); - memset(&pfr.rule.dst.addr.v.a.mask.addr8, 255, 16); - } - pfr.rule.dst.port_op = PF_OP_EQ; - pfr.rule.dst.port[0] = htons(d_port); - pfr.rule.rtableid = -1; - pfr.rule.onrdomain = -1; - pfr.rule.set_prio[0] = pfr.rule.set_prio[1] = PF_PRIO_NOTSET; - pfr.rule.action = PF_PASS; - pfr.rule.quick = 1; - pfr.rule.log = rule_log; - pfr.rule.keep_state = 1; - pfr.rule.flags = (proto == IPPROTO_TCP ? TH_SYN : 0); - pfr.rule.flagset = (proto == IPPROTO_TCP ? - (TH_SYN|TH_ACK|TH_FIN|TH_RST) : 0); - pfr.rule.max_states = 1; - if (qname != NULL) - strlcpy(pfr.rule.qname, qname, sizeof pfr.rule.qname); - - return (0); -} diff --git a/libexec/tftp-proxy/filter.h b/libexec/tftp-proxy/filter.h deleted file mode 100644 index 0214b76fe0c..00000000000 --- a/libexec/tftp-proxy/filter.h +++ /dev/null @@ -1,28 +0,0 @@ -/* $OpenBSD: filter.h,v 1.3 2011/05/05 12:25:51 sthen Exp $ */ - -/* - * Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define FTP_PROXY_ANCHOR "tftp-proxy" - -int add_filter(u_int32_t, u_int8_t, struct sockaddr *, struct sockaddr *, - u_int16_t, u_int8_t); -int add_rdr(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t, - struct sockaddr *, u_int16_t, u_int8_t); -int do_commit(void); -int do_rollback(void); -void init_filter(char *, int); -int prepare_commit(u_int32_t); diff --git a/libexec/tftp-proxy/tftp-proxy.8 b/libexec/tftp-proxy/tftp-proxy.8 deleted file mode 100644 index 0a79653fd1e..00000000000 --- a/libexec/tftp-proxy/tftp-proxy.8 +++ /dev/null @@ -1,121 +0,0 @@ -.\" $OpenBSD: tftp-proxy.8,v 1.7 2011/09/28 13:25:24 jmc Exp $ -.\" -.\" Copyright (c) 2005 joshua stein <jcs@openbsd.org> -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd $Mdocdate: September 28 2011 $ -.Dt TFTP-PROXY 8 -.Os -.Sh NAME -.Nm tftp-proxy -.Nd Internet Trivial File Transfer Protocol proxy -.Sh SYNOPSIS -.Nm tftp-proxy -.Op Fl v -.Op Fl w Ar transwait -.Sh DESCRIPTION -.Nm -is a proxy for the Internet Trivial File Transfer Protocol invoked by -the -.Xr inetd 8 -internet server. -TFTP connections should be redirected to the proxy using a -.Xr pf 4 -rule using the -.Ar divert-to -option, after which the proxy connects to the server on behalf of -the client. -The connection from the proxy to the server needs to be passed by -a rule with divert-reply set. -.Pp -The proxy inserts -.Xr pf 4 -pass rules using the -.Ar anchor -facility to allow payload packets between the client and the server. -Once the rules are inserted, -.Nm -forwards the initial request from the client to the server to begin the -transfer. -After -.Ar transwait -seconds, the states are assumed to have been established and the -.Xr pf 4 -rules are deleted and the program exits. -Once the transfer between the client and the server is completed the -states will naturally expire. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl v -Log the connection and request information to -.Xr syslogd 8 . -.It Fl w Ar transwait -Number of seconds to wait for the data transmission to begin before -removing the -.Xr pf 4 -rule. -The default is 2 seconds. -.El -.Sh CONFIGURATION -To make use of the proxy, -.Xr pf.conf 5 -needs the following rules. -The anchor is mandatory. -Adjust the rule as needed for your configuration. -.Bd -literal -offset indent -anchor "tftp-proxy/*" -pass in quick on $int_if inet proto udp from $lan to port tftp \e - divert-to 127.0.0.1 port 6969 -pass out quick on $ext_if inet proto udp from $lan to port tftp \e - group proxy divert-reply -.Ed -.Pp -.Xr inetd 8 -must be configured to spawn the proxy on the port that packets are -being forwarded to by -.Xr pf 4 . -An example -.Xr inetd.conf 5 -entry follows: -.Bd -literal -offset indent -127.0.0.1:6969 dgram udp wait root:proxy \e - /usr/libexec/tftp-proxy tftp-proxy -.Ed -.Sh SEE ALSO -.Xr tftp 1 , -.Xr pf 4 , -.Xr pf.conf 5 , -.Xr ftp-proxy 8 , -.Xr inetd 8 , -.Xr syslogd 8 , -.Xr tftpd 8 -.Sh CAVEATS -.Nm -chroots to -.Pa /var/empty -and changes to user -.Dq proxy -to drop privileges. diff --git a/libexec/tftp-proxy/tftp-proxy.c b/libexec/tftp-proxy/tftp-proxy.c deleted file mode 100644 index ad9c48ca65e..00000000000 --- a/libexec/tftp-proxy/tftp-proxy.c +++ /dev/null @@ -1,335 +0,0 @@ -/* $OpenBSD: tftp-proxy.c,v 1.8 2011/09/28 12:38:59 dlg Exp $ - * - * Copyright (c) 2005 DLS Internet Services - * Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/uio.h> -#include <unistd.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/tftp.h> -#include <sys/socket.h> -#include <net/if.h> -#include <net/pfvar.h> - -#include <errno.h> -#include <pwd.h> -#include <stdio.h> -#include <syslog.h> -#include <string.h> -#include <stdlib.h> - -#include "filter.h" - -#define CHROOT_DIR "/var/empty" -#define NOPRIV_USER "proxy" - -#define PF_NAT_PROXY_PORT_LOW 50001 -#define PF_NAT_PROXY_PORT_HIGH 65535 - -#define DEFTRANSWAIT 2 -#define NTOP_BUFS 4 -#define PKTSIZE SEGSIZE+4 - -const char *opcode(int); -const char *sock_ntop(struct sockaddr *); -static void usage(void); - -extern char *__progname; -char ntop_buf[NTOP_BUFS][INET6_ADDRSTRLEN]; -int verbose = 0; - -int -main(int argc, char *argv[]) -{ - int c, fd = 0, on = 1, out_fd = 0, reqsize = 0; - int transwait = DEFTRANSWAIT; - char *p; - struct tftphdr *tp; - struct passwd *pw; - union { - struct cmsghdr hdr; - char buf[CMSG_SPACE(sizeof(struct sockaddr_storage)) + - CMSG_SPACE(sizeof(in_port_t))]; - } cmsgbuf; - char req[PKTSIZE]; - struct cmsghdr *cmsg; - struct msghdr msg; - struct iovec iov; - - struct sockaddr_storage from, server; - - openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); - - while ((c = getopt(argc, argv, "vw:")) != -1) { - switch (c) { - case 'v': - verbose++; - break; - case 'w': - transwait = strtoll(optarg, &p, 10); - if (transwait < 1) { - syslog(LOG_ERR, "invalid -w value"); - exit(1); - } - break; - default: - usage(); - break; - } - } - - /* non-blocking io */ - if (ioctl(fd, FIONBIO, &on) < 0) { - syslog(LOG_ERR, "ioctl(FIONBIO): %m"); - exit(1); - } - - if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) == -1) { - syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m"); - exit(1); - } - - if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTPORT, &on, sizeof(on)) == -1) { - syslog(LOG_ERR, "setsockopt(IP_RECVDSTPORT): %m"); - exit(1); - } - - bzero(&msg, sizeof(msg)); - iov.iov_base = req; - iov.iov_len = sizeof(req); - msg.msg_name = &from; - msg.msg_namelen = sizeof(from); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = &cmsgbuf.buf; - msg.msg_controllen = sizeof(cmsgbuf.buf); - - if ((reqsize = recvmsg(fd, &msg, 0)) < 0) { - syslog(LOG_ERR, "recvmsg: %m"); - exit(1); - } - - memset(&server, 0, sizeof(server)); - server.ss_family = from.ss_family; - server.ss_len = from.ss_len; - - close(fd); - close(1); - - switch (fork()) { - case -1: - syslog(LOG_ERR, "couldn't fork"); - case 0: - break; - default: - exit(0); - } - - /* establish a new outbound connection to the remote server */ - if ((out_fd = socket(((struct sockaddr *)&from)->sa_family, - SOCK_DGRAM, IPPROTO_UDP)) < 0) { - syslog(LOG_ERR, "couldn't create new socket"); - exit(1); - } - - if (setsockopt(out_fd, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)) == -1) { - syslog(LOG_ERR, "couldn't enable BINDANY"); - exit(1); - } - - /* open /dev/pf */ - init_filter(NULL, verbose); - - tzset(); - - /* revoke privs */ - pw = getpwnam(NOPRIV_USER); - if (!pw) { - syslog(LOG_ERR, "no such user %s: %m", NOPRIV_USER); - exit(1); - } - if (chroot(CHROOT_DIR) || chdir("/")) { - syslog(LOG_ERR, "chroot %s: %m", CHROOT_DIR); - exit(1); - } - if (setgroups(1, &pw->pw_gid) || - setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || - setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) { - syslog(LOG_ERR, "can't revoke privs: %m"); - exit(1); - } - - /* get server address and port */ - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == IPPROTO_IP && - cmsg->cmsg_type == IP_RECVDSTADDR) { - memcpy(&((struct sockaddr_in *)&server)->sin_addr, - CMSG_DATA(cmsg), sizeof(struct in_addr)); - } - if (cmsg->cmsg_level == IPPROTO_IP && - cmsg->cmsg_type == IP_RECVDSTPORT) { - memcpy(&((struct sockaddr_in *)&server)->sin_port, - CMSG_DATA(cmsg), sizeof(in_port_t)); - } - } - - tp = (struct tftphdr *)req; - if (!(ntohs(tp->th_opcode) == RRQ || ntohs(tp->th_opcode) == WRQ)) { - /* not a tftp request, bail */ - if (verbose) { - syslog(LOG_WARNING, "not a valid tftp request"); - exit(1); - } else - /* exit 0 so inetd doesn't log anything */ - exit(0); - } - - /* bind ourselves to the clients IP for the connection to the server */ - if (bind(out_fd, (struct sockaddr *)&from, from.ss_len) == -1) { - syslog(LOG_ERR, "couldn't bind to client address: %m"); - exit(1); - } - - if (connect(out_fd, (struct sockaddr *)&server, - ((struct sockaddr *)&server)->sa_len) < 0 && errno != EINPROGRESS) { - syslog(LOG_ERR, "couldn't connect to remote server: %m"); - exit(1); - } - - if (verbose) { - syslog(LOG_INFO, "%s:%d -> %s:%d \"%s %s\"", - sock_ntop((struct sockaddr *)&from), - ntohs(((struct sockaddr_in *)&from)->sin_port), - sock_ntop((struct sockaddr *)&server), - ntohs(((struct sockaddr_in *)&server)->sin_port), - opcode(ntohs(tp->th_opcode)), - tp->th_stuff); - } - - /* get ready to add rdr and pass rules */ - if (prepare_commit(1) == -1) { - syslog(LOG_ERR, "couldn't prepare pf commit"); - exit(1); - } - - /* explicitly allow the packets to return back to the client (which pf - * will see post-rdr) */ - if (add_filter(1, PF_IN, (struct sockaddr *)&server, - (struct sockaddr *)&from, - ntohs(((struct sockaddr_in *)&from)->sin_port), - IPPROTO_UDP) == -1) { - syslog(LOG_ERR, "couldn't add pass in"); - exit(1); - } - if (add_filter(1, PF_OUT, (struct sockaddr *)&server, - (struct sockaddr *)&from, - ntohs(((struct sockaddr_in *)&from)->sin_port), - IPPROTO_UDP) == -1) { - syslog(LOG_ERR, "couldn't add pass out"); - exit(1); - } - - if (do_commit() == -1) { - syslog(LOG_ERR, "couldn't commit pf rules"); - exit(1); - } - - /* forward the initial tftp request and start the insanity */ - if (send(out_fd, tp, reqsize, 0) < 0) { - syslog(LOG_ERR, "couldn't forward tftp packet: %m"); - exit(1); - } - - close(out_fd); - - /* allow the transfer to start to establish a state */ - sleep(transwait); - - /* delete our rdr rule and clean up */ - prepare_commit(1); - do_commit(); - - return(0); -} - -const char * -opcode(int code) -{ - static char str[6]; - - switch (code) { - case 1: - (void)snprintf(str, sizeof(str), "RRQ"); - break; - case 2: - (void)snprintf(str, sizeof(str), "WRQ"); - break; - default: - (void)snprintf(str, sizeof(str), "(%d)", code); - break; - } - - return (str); -} - -const char * -sock_ntop(struct sockaddr *sa) -{ - static int n = 0; - - /* Cycle to next buffer. */ - n = (n + 1) % NTOP_BUFS; - ntop_buf[n][0] = '\0'; - - if (sa->sa_family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - - return (inet_ntop(AF_INET, &sin->sin_addr, ntop_buf[n], - sizeof ntop_buf[0])); - } - - if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - - return (inet_ntop(AF_INET6, &sin6->sin6_addr, ntop_buf[n], - sizeof ntop_buf[0])); - } - - return (NULL); -} - -static void -usage(void) -{ - syslog(LOG_ERR, "usage: %s [-v] [-w transwait]", __progname); - exit(1); -} |