4 * Copyright (C) 2001-2006 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
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";
12 #include <sys/types.h>
14 #include <sys/socket.h>
16 #include <netinet/in.h>
19 #include <arpa/inet.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
));
41 void usage(const char *progname
) {
43 "Usage: %s <destination IP> <destination port> [remote IP]\n",
48 static void handleterm(int sig
)
54 #define BUFFERLEN 1400
60 int nfd
= -1 , lfd
= -1;
61 int n1
, n2
, n3
, magic
, len
, inbuf
;
62 struct sockaddr_in sin
;
63 struct sockaddr_in in
;
70 progname
= strrchr(argv
[0], '/');
83 signal(SIGHUP
, handleterm
);
84 signal(SIGINT
, handleterm
);
85 signal(SIGTERM
, handleterm
);
88 openlog(progname
, LOG_PID
, LOG_SECURITY
);
90 lfd
= open(IPSYNC_NAME
, O_WRONLY
);
92 syslog(LOG_ERR
, "Opening %s :%m", IPSYNC_NAME
);
96 bzero((char *)&sin
, sizeof(sin
));
97 sin
.sin_family
= AF_INET
;
99 sin
.sin_addr
.s_addr
= inet_addr(argv
[1]);
101 sin
.sin_port
= htons(atoi(argv
[2]));
103 sin
.sin_port
= htons(43434);
105 in
.sin_addr
.s_addr
= inet_addr(argv
[3]);
107 in
.sin_addr
.s_addr
= 0;
117 lfd
= open(IPSYNC_NAME
, O_WRONLY
);
119 syslog(LOG_ERR
, "Opening %s :%m", IPSYNC_NAME
);
123 nfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
125 syslog(LOG_ERR
, "Socket :%m");
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");
137 syslog(LOG_INFO
, "Listening to %s", inet_ntoa(sin
.sin_addr
));
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
));
153 syslog(LOG_ERR
, "Read error (header): %m");
158 /* XXX can this happen??? */
160 "Read error (header) : No data");
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",
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");
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");
199 printf(" table:Unknown(%d)", sh
->sm_table
);
201 printf(" num:%d\n", (u_32_t
)ntohl(sh
->sm_num
));
204 if (inbuf
< sizeof(*sh
) + len
) {
205 continue; /* need more data */
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",
218 su
->sup_tcp
.stu_state
[0],
219 su
->sup_tcp
.stu_state
[1]);
222 printf("Unknown command\n");
226 n2
= sizeof(*sh
) + len
;
227 n3
= write(lfd
, buff
, n2
);
229 syslog(LOG_ERR
, "%s: Write error: %m",
236 syslog(LOG_ERR
, "%s: Incomplete write (%d/%d)",
237 IPSYNC_NAME
, n3
, n2
);
241 /* signal received? */
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
252 bcopy(buff
+n2
, buff
, inbuf
);
253 printf("More data in buffer\n");
271 syslog(LOG_ERR
, "signal %d received, exiting...", terminate
);