Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / ipf / tools / ipsyncs.c
blob92b8f36e9bd9aecc93ca1992905f17de1380a25e
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2001-2006 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8 #if !defined(lint)
9 static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
10 static const char rcsid[] = "@(#)Id: ipsyncs.c,v 1.5.2.5 2009/03/29 01:17:53 darrenr Exp";
11 #endif
12 #include <sys/types.h>
13 #include <sys/time.h>
14 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <net/if.h>
19 #include <arpa/inet.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <fcntl.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <syslog.h>
27 #include <errno.h>
28 #include <signal.h>
30 #include "netinet/ip_compat.h"
31 #include "netinet/ip_fil.h"
32 #include "netinet/ip_state.h"
33 #include "netinet/ip_nat.h"
34 #include "netinet/ip_sync.h"
36 int main __P((int, char *[]));
37 void usage __P((const char *progname));
39 int terminate = 0;
41 void usage(const char *progname) {
42 fprintf(stderr,
43 "Usage: %s <destination IP> <destination port> [remote IP]\n",
44 progname);
47 #if 0
48 static void handleterm(int sig)
50 terminate = sig;
52 #endif
54 #define BUFFERLEN 1400
56 int main(argc, argv)
57 int argc;
58 char *argv[];
60 int nfd = -1 , lfd = -1;
61 int n1, n2, n3, magic, len, inbuf;
62 struct sockaddr_in sin;
63 struct sockaddr_in in;
64 char buff[BUFFERLEN];
65 synclogent_t *sl;
66 syncupdent_t *su;
67 synchdr_t *sh;
68 char *progname;
70 progname = strrchr(argv[0], '/');
71 if (progname) {
72 progname++;
73 } else {
74 progname = argv[0];
77 if (argc < 2) {
78 usage(progname);
79 exit(1);
82 #if 0
83 signal(SIGHUP, handleterm);
84 signal(SIGINT, handleterm);
85 signal(SIGTERM, handleterm);
86 #endif
88 openlog(progname, LOG_PID, LOG_SECURITY);
90 lfd = open(IPSYNC_NAME, O_WRONLY);
91 if (lfd == -1) {
92 syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME);
93 exit(1);
96 bzero((char *)&sin, sizeof(sin));
97 sin.sin_family = AF_INET;
98 if (argc > 1)
99 sin.sin_addr.s_addr = inet_addr(argv[1]);
100 if (argc > 2)
101 sin.sin_port = htons(atoi(argv[2]));
102 else
103 sin.sin_port = htons(43434);
104 if (argc > 3)
105 in.sin_addr.s_addr = inet_addr(argv[3]);
106 else
107 in.sin_addr.s_addr = 0;
108 in.sin_port = 0;
110 while(1) {
112 if (lfd != -1)
113 close(lfd);
114 if (nfd != -1)
115 close(nfd);
117 lfd = open(IPSYNC_NAME, O_WRONLY);
118 if (lfd == -1) {
119 syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME);
120 goto tryagain;
123 nfd = socket(AF_INET, SOCK_DGRAM, 0);
124 if (nfd == -1) {
125 syslog(LOG_ERR, "Socket :%m");
126 goto tryagain;
129 n1 = 1;
130 setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &n1, sizeof(n1));
132 if (bind(nfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
133 syslog(LOG_ERR, "Bind: %m");
134 goto tryagain;
137 syslog(LOG_INFO, "Listening to %s", inet_ntoa(sin.sin_addr));
139 inbuf = 0;
140 while (1) {
144 * XXX currently we do not check the source address
145 * of a datagram, this can be a security risk
147 n1 = read(nfd, buff+inbuf, BUFFERLEN-inbuf);
149 printf("header : %d bytes read (header = %d bytes)\n",
150 n1, (int) sizeof(*sh));
152 if (n1 < 0) {
153 syslog(LOG_ERR, "Read error (header): %m");
154 goto tryagain;
157 if (n1 == 0) {
158 /* XXX can this happen??? */
159 syslog(LOG_ERR,
160 "Read error (header) : No data");
161 sleep(1);
162 continue;
165 inbuf += n1;
167 moreinbuf:
168 if (inbuf < sizeof(*sh)) {
169 continue; /* need more data */
172 sh = (synchdr_t *)buff;
173 len = ntohl(sh->sm_len);
174 magic = ntohl(sh->sm_magic);
176 if (magic != SYNHDRMAGIC) {
177 syslog(LOG_ERR, "Invalid header magic %x",
178 magic);
179 goto tryagain;
182 #define IPSYNC_DEBUG
183 #ifdef IPSYNC_DEBUG
184 printf("v:%d p:%d len:%d magic:%x", sh->sm_v,
185 sh->sm_p, len, magic);
187 if (sh->sm_cmd == SMC_CREATE)
188 printf(" cmd:CREATE");
189 else if (sh->sm_cmd == SMC_UPDATE)
190 printf(" cmd:UPDATE");
191 else
192 printf(" cmd:Unknown(%d)", sh->sm_cmd);
194 if (sh->sm_table == SMC_NAT)
195 printf(" table:NAT");
196 else if (sh->sm_table == SMC_STATE)
197 printf(" table:STATE");
198 else
199 printf(" table:Unknown(%d)", sh->sm_table);
201 printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num));
202 #endif
204 if (inbuf < sizeof(*sh) + len) {
205 continue; /* need more data */
206 goto tryagain;
209 #ifdef IPSYNC_DEBUG
210 if (sh->sm_cmd == SMC_CREATE) {
211 sl = (synclogent_t *)buff;
213 } else if (sh->sm_cmd == SMC_UPDATE) {
214 su = (syncupdent_t *)buff;
215 if (sh->sm_p == IPPROTO_TCP) {
216 printf(" TCP Update: age %lu state %d/%d\n",
217 su->sup_tcp.stu_age,
218 su->sup_tcp.stu_state[0],
219 su->sup_tcp.stu_state[1]);
221 } else {
222 printf("Unknown command\n");
224 #endif
226 n2 = sizeof(*sh) + len;
227 n3 = write(lfd, buff, n2);
228 if (n3 <= 0) {
229 syslog(LOG_ERR, "%s: Write error: %m",
230 IPSYNC_NAME);
231 goto tryagain;
235 if (n3 != n2) {
236 syslog(LOG_ERR, "%s: Incomplete write (%d/%d)",
237 IPSYNC_NAME, n3, n2);
238 goto tryagain;
241 /* signal received? */
242 if (terminate)
243 break;
245 /* move buffer to the front,we might need to make
246 * this more efficient, by using a rolling pointer
247 * over the buffer and only copying it, when
248 * we are reaching the end
250 inbuf -= n2;
251 if (inbuf) {
252 bcopy(buff+n2, buff, inbuf);
253 printf("More data in buffer\n");
254 goto moreinbuf;
258 if (terminate)
259 break;
260 tryagain:
261 sleep(1);
265 /* terminate */
266 if (lfd != -1)
267 close(lfd);
268 if (nfd != -1)
269 close(nfd);
271 syslog(LOG_ERR, "signal %d received, exiting...", terminate);
273 exit(1);