3 * $Id: forward.c,v 1.1 1999/07/01 08:56:23 mdw Exp $
7 * (c) 1999 Mark Wooding
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of the `fw' port forwarder.
14 * `fw' is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * `fw' is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with `fw'; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Revision history --------------------------------------------------*
32 * Revision 1.1 1999/07/01 08:56:23 mdw
37 /*----- Header files ------------------------------------------------------*/
46 #include <sys/types.h>
50 #include <sys/socket.h>
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
54 #include <mLib/alloc.h>
55 #include <mLib/conn.h>
62 /*----- Data structures ---------------------------------------------------*/
64 /* --- Port forwarding data --- */
67 int fd_a; /* Client's file descriptor */
68 int fd_b; /* Server's file descriptor */
69 unsigned state; /* Current state of the world */
70 conn c; /* Nonblocking connect to server */
71 chan ab; /* Channel from @a@ to @b@ */
72 chan ba; /* Channel from @b@ to @a@ */
75 #define S_AB 1u /* Channel from @a@ to @b@ open */
76 #define S_BA 2u /* Channel from @b@ to @a@ open */
77 #define S_NOTCONN 4u /* Not connected to @b@ yet */
78 #define S_NOTID 8u /* Not finished identification */
80 /*----- Main code ---------------------------------------------------------*/
84 * Arguments: @fw *f@ = pointer to forwarder
88 * Use: Tidies up a forwarder that nobody wants any more.
91 static void done(fw *f)
100 * Arguments: @void *vp@ = pointer to forwarder
104 * Use: Handles completion of client identification.
107 static void ident(void *vp)
110 f->state &= ~S_NOTID;
115 /* --- @closeba@ --- *
117 * Arguments: @void *vp@ = pointer to forwarder
121 * Use: Handles the closing of the %$b \rightarrow a$% channel.
124 static void closeba(void *vp)
132 /* --- @closeab@ --- *
134 * Arguments: @void *vp@ = pointer to forwarder
138 * Use: Handles the closing of the %$a \rightarrow b$% channel.
141 static void closeab(void *vp)
151 * Arguments: @int fd@ = newly connected socket
152 * @void *vp@ = pointer to forwarder
156 * Use: Completes the forwarder once the outbound connection is set
160 static void go(int fd, void *vp)
164 /* --- If it all went tits-up, deal with that --- */
173 /* --- OK, finish configuring the forwarder --- */
176 chan_dest(&f->ab, fd);
177 chan_open(&f->ba, fd, f->fd_a, closeba, f);
179 f->state &= ~S_NOTCONN;
182 /* --- @forward@ --- *
184 * Arguments: @int fd@ = file descriptor attached to client
185 * @struct sockaddr_in *sin@ = pointer to destination address
186 * @const id_req *q@ = pointer to identification request block
190 * Use: Start a port forwarding job.
193 void forward(int fd, struct sockaddr_in *sin, const id_req *q)
198 /* --- Set up the new socket --- */
200 if ((nfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
205 setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
206 setsockopt(nfd, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
209 /* --- Initialize the easy bits --- */
211 f = xmalloc(sizeof(*f));
214 f->state = S_NOTCONN | S_AB | S_NOTID;
216 /* --- Open the %$a \rightarrow b$% channel --- */
218 chan_open(&f->ab, fd, -1, closeab, f);
219 conn_init(&f->c, sel, nfd, (struct sockaddr *)sin, sizeof(*sin), go, f);
220 identify(q, ident, f);
223 /*----- That's all, folks -------------------------------------------------*/