Deleted Added
full compact
relay.c (145554) relay.c (153881)
1/* $FreeBSD: head/contrib/ipfilter/samples/relay.c 145554 2005-04-26 15:18:45Z darrenr $ */
1/* $FreeBSD: head/contrib/ipfilter/samples/relay.c 153881 2005-12-30 11:52:26Z guido $ */
2
3/*
4 * Sample program to be used as a transparent proxy.
5 *
6 * Must be executed with permission enough to do an ioctl on /dev/ipl
7 * or equivalent. This is just a sample and is only alpha quality.
8 * - Darren Reed (8 April 1996)
9 */
10#include <unistd.h>
11#include <stdio.h>
12#include <fcntl.h>
13#include <errno.h>
14#include <sys/types.h>
15#include <sys/time.h>
16#include <sys/syslog.h>
17#include <sys/socket.h>
18#include <sys/ioctl.h>
19#include <netinet/in.h>
20#include <net/if.h>
2
3/*
4 * Sample program to be used as a transparent proxy.
5 *
6 * Must be executed with permission enough to do an ioctl on /dev/ipl
7 * or equivalent. This is just a sample and is only alpha quality.
8 * - Darren Reed (8 April 1996)
9 */
10#include <unistd.h>
11#include <stdio.h>
12#include <fcntl.h>
13#include <errno.h>
14#include <sys/types.h>
15#include <sys/time.h>
16#include <sys/syslog.h>
17#include <sys/socket.h>
18#include <sys/ioctl.h>
19#include <netinet/in.h>
20#include <net/if.h>
21#include "ip_compat.h"
22#include "ip_fil.h"
23#include "ip_nat.h"
21#include "netinet/ip_compat.h"
22#include "netinet/ip_fil.h"
23#include "netinet/ip_nat.h"
24#include "netinet/ipl.h"
25
26#define RELAY_BUFSZ 8192
27
28char ibuff[RELAY_BUFSZ];
29char obuff[RELAY_BUFSZ];
30
31int relay(ifd, ofd, rfd)
32int ifd, ofd, rfd;
33{
34 fd_set rfds, wfds;
35 char *irh, *irt, *rrh, *rrt;
36 char *iwh, *iwt, *rwh, *rwt;
37 int nfd, n, rw;
38
39 irh = irt = ibuff;
40 iwh = iwt = obuff;
41 nfd = ifd;
42 if (nfd < ofd)
43 nfd = ofd;
44 if (nfd < rfd)
45 nfd = rfd;
46
47 while (1) {
48 FD_ZERO(&rfds);
49 FD_ZERO(&wfds);
50 if (irh > irt)
51 FD_SET(rfd, &wfds);
52 if (irh < (ibuff + RELAY_BUFSZ))
53 FD_SET(ifd, &rfds);
54 if (iwh > iwt)
55 FD_SET(ofd, &wfds);
56 if (iwh < (obuff + RELAY_BUFSZ))
57 FD_SET(rfd, &rfds);
58
59 switch ((n = select(nfd + 1, &rfds, &wfds, NULL, NULL)))
60 {
61 case -1 :
62 case 0 :
63 return -1;
64 default :
65 if (FD_ISSET(ifd, &rfds)) {
66 rw = read(ifd, irh, ibuff + RELAY_BUFSZ - irh);
67 if (rw == -1)
68 return -1;
69 if (rw == 0)
70 return 0;
71 irh += rw;
72 n--;
73 }
74 if (n && FD_ISSET(ofd, &wfds)) {
75 rw = write(ofd, iwt, iwh - iwt);
76 if (rw == -1)
77 return -1;
78 iwt += rw;
79 n--;
80 }
81 if (n && FD_ISSET(rfd, &rfds)) {
82 rw = read(rfd, iwh, obuff + RELAY_BUFSZ - iwh);
83 if (rw == -1)
84 return -1;
85 if (rw == 0)
86 return 0;
87 iwh += rw;
88 n--;
89 }
90 if (n && FD_ISSET(rfd, &wfds)) {
91 rw = write(rfd, irt, irh - irt);
92 if (rw == -1)
93 return -1;
94 irt += rw;
95 n--;
96 }
97 if (irh == irt)
98 irh = irt = ibuff;
99 if (iwh == iwt)
100 iwh = iwt = obuff;
101 }
102 }
103}
104
105main(argc, argv)
106int argc;
107char *argv[];
108{
109 struct sockaddr_in sin;
110 ipfobj_t obj;
111 natlookup_t nl;
112 natlookup_t *nlp = &nl;
113 int fd, sl = sizeof(sl), se;
114
115 openlog(argv[0], LOG_PID|LOG_NDELAY, LOG_DAEMON);
116 if ((fd = open(IPNAT_NAME, O_RDONLY)) == -1) {
117 se = errno;
118 perror("open");
119 errno = se;
120 syslog(LOG_ERR, "open: %m\n");
121 exit(-1);
122 }
123
124 bzero(&obj, sizeof(obj));
125 obj.ipfo_rev = IPFILTER_VERSION;
126 obj.ipfo_size = sizeof(nl);
127 obj.ipfo_ptr = &nl;
128 obj.ipfo_type = IPFOBJ_NATLOOKUP;
129
130 bzero(&nl, sizeof(nl));
131 nl.nl_flags = IPN_TCP;
132
133 bzero(&sin, sizeof(sin));
134 sin.sin_family = AF_INET;
135 sl = sizeof(sin);
136 if (getsockname(0, (struct sockaddr *)&sin, &sl) == -1) {
137 se = errno;
138 perror("getsockname");
139 errno = se;
140 syslog(LOG_ERR, "getsockname: %m\n");
141 exit(-1);
142 } else {
143 nl.nl_inip.s_addr = sin.sin_addr.s_addr;
144 nl.nl_inport = sin.sin_port;
145 }
146
147 bzero(&sin, sizeof(sin));
148 sin.sin_family = AF_INET;
149 sl = sizeof(sin);
150 if (getpeername(0, (struct sockaddr *)&sin, &sl) == -1) {
151 se = errno;
152 perror("getpeername");
153 errno = se;
154 syslog(LOG_ERR, "getpeername: %m\n");
155 exit(-1);
156 } else {
157 nl.nl_outip.s_addr = sin.sin_addr.s_addr;
158 nl.nl_outport = sin.sin_port;
159 }
160
161 if (ioctl(fd, SIOCGNATL, &obj) == -1) {
162 se = errno;
163 perror("ioctl");
164 errno = se;
165 syslog(LOG_ERR, "ioctl: %m\n");
166 exit(-1);
167 }
168
169 sin.sin_port = nl.nl_realport;
170 sin.sin_addr = nl.nl_realip;
171 sl = sizeof(sin);
172
173 fd = socket(AF_INET, SOCK_STREAM, 0);
174 if (connect(fd, (struct sockaddr *)&sin, sl) == -1) {
175 se = errno;
176 perror("connect");
177 errno = se;
178 syslog(LOG_ERR, "connect: %m\n");
179 exit(-1);
180 }
181
182 (void) ioctl(fd, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK);
183 (void) ioctl(0, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK);
184 (void) ioctl(1, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK);
185
186 syslog(LOG_NOTICE, "connected to %s,%d\n", inet_ntoa(sin.sin_addr),
187 ntohs(sin.sin_port));
188 if (relay(0, 1, fd) == -1) {
189 se = errno;
190 perror("relay");
191 errno = se;
192 syslog(LOG_ERR, "relay: %m\n");
193 exit(-1);
194 }
195 exit(0);
196}
24#include "netinet/ipl.h"
25
26#define RELAY_BUFSZ 8192
27
28char ibuff[RELAY_BUFSZ];
29char obuff[RELAY_BUFSZ];
30
31int relay(ifd, ofd, rfd)
32int ifd, ofd, rfd;
33{
34 fd_set rfds, wfds;
35 char *irh, *irt, *rrh, *rrt;
36 char *iwh, *iwt, *rwh, *rwt;
37 int nfd, n, rw;
38
39 irh = irt = ibuff;
40 iwh = iwt = obuff;
41 nfd = ifd;
42 if (nfd < ofd)
43 nfd = ofd;
44 if (nfd < rfd)
45 nfd = rfd;
46
47 while (1) {
48 FD_ZERO(&rfds);
49 FD_ZERO(&wfds);
50 if (irh > irt)
51 FD_SET(rfd, &wfds);
52 if (irh < (ibuff + RELAY_BUFSZ))
53 FD_SET(ifd, &rfds);
54 if (iwh > iwt)
55 FD_SET(ofd, &wfds);
56 if (iwh < (obuff + RELAY_BUFSZ))
57 FD_SET(rfd, &rfds);
58
59 switch ((n = select(nfd + 1, &rfds, &wfds, NULL, NULL)))
60 {
61 case -1 :
62 case 0 :
63 return -1;
64 default :
65 if (FD_ISSET(ifd, &rfds)) {
66 rw = read(ifd, irh, ibuff + RELAY_BUFSZ - irh);
67 if (rw == -1)
68 return -1;
69 if (rw == 0)
70 return 0;
71 irh += rw;
72 n--;
73 }
74 if (n && FD_ISSET(ofd, &wfds)) {
75 rw = write(ofd, iwt, iwh - iwt);
76 if (rw == -1)
77 return -1;
78 iwt += rw;
79 n--;
80 }
81 if (n && FD_ISSET(rfd, &rfds)) {
82 rw = read(rfd, iwh, obuff + RELAY_BUFSZ - iwh);
83 if (rw == -1)
84 return -1;
85 if (rw == 0)
86 return 0;
87 iwh += rw;
88 n--;
89 }
90 if (n && FD_ISSET(rfd, &wfds)) {
91 rw = write(rfd, irt, irh - irt);
92 if (rw == -1)
93 return -1;
94 irt += rw;
95 n--;
96 }
97 if (irh == irt)
98 irh = irt = ibuff;
99 if (iwh == iwt)
100 iwh = iwt = obuff;
101 }
102 }
103}
104
105main(argc, argv)
106int argc;
107char *argv[];
108{
109 struct sockaddr_in sin;
110 ipfobj_t obj;
111 natlookup_t nl;
112 natlookup_t *nlp = &nl;
113 int fd, sl = sizeof(sl), se;
114
115 openlog(argv[0], LOG_PID|LOG_NDELAY, LOG_DAEMON);
116 if ((fd = open(IPNAT_NAME, O_RDONLY)) == -1) {
117 se = errno;
118 perror("open");
119 errno = se;
120 syslog(LOG_ERR, "open: %m\n");
121 exit(-1);
122 }
123
124 bzero(&obj, sizeof(obj));
125 obj.ipfo_rev = IPFILTER_VERSION;
126 obj.ipfo_size = sizeof(nl);
127 obj.ipfo_ptr = &nl;
128 obj.ipfo_type = IPFOBJ_NATLOOKUP;
129
130 bzero(&nl, sizeof(nl));
131 nl.nl_flags = IPN_TCP;
132
133 bzero(&sin, sizeof(sin));
134 sin.sin_family = AF_INET;
135 sl = sizeof(sin);
136 if (getsockname(0, (struct sockaddr *)&sin, &sl) == -1) {
137 se = errno;
138 perror("getsockname");
139 errno = se;
140 syslog(LOG_ERR, "getsockname: %m\n");
141 exit(-1);
142 } else {
143 nl.nl_inip.s_addr = sin.sin_addr.s_addr;
144 nl.nl_inport = sin.sin_port;
145 }
146
147 bzero(&sin, sizeof(sin));
148 sin.sin_family = AF_INET;
149 sl = sizeof(sin);
150 if (getpeername(0, (struct sockaddr *)&sin, &sl) == -1) {
151 se = errno;
152 perror("getpeername");
153 errno = se;
154 syslog(LOG_ERR, "getpeername: %m\n");
155 exit(-1);
156 } else {
157 nl.nl_outip.s_addr = sin.sin_addr.s_addr;
158 nl.nl_outport = sin.sin_port;
159 }
160
161 if (ioctl(fd, SIOCGNATL, &obj) == -1) {
162 se = errno;
163 perror("ioctl");
164 errno = se;
165 syslog(LOG_ERR, "ioctl: %m\n");
166 exit(-1);
167 }
168
169 sin.sin_port = nl.nl_realport;
170 sin.sin_addr = nl.nl_realip;
171 sl = sizeof(sin);
172
173 fd = socket(AF_INET, SOCK_STREAM, 0);
174 if (connect(fd, (struct sockaddr *)&sin, sl) == -1) {
175 se = errno;
176 perror("connect");
177 errno = se;
178 syslog(LOG_ERR, "connect: %m\n");
179 exit(-1);
180 }
181
182 (void) ioctl(fd, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK);
183 (void) ioctl(0, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK);
184 (void) ioctl(1, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK);
185
186 syslog(LOG_NOTICE, "connected to %s,%d\n", inet_ntoa(sin.sin_addr),
187 ntohs(sin.sin_port));
188 if (relay(0, 1, fd) == -1) {
189 se = errno;
190 perror("relay");
191 errno = se;
192 syslog(LOG_ERR, "relay: %m\n");
193 exit(-1);
194 }
195 exit(0);
196}