]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ipfilter/tools/ipsyncm.c
Import IP Filter 4.1.13
[FreeBSD/FreeBSD.git] / contrib / ipfilter / tools / ipsyncm.c
1 /*
2  * Copyright (C) 1993-2001 by Darren Reed.
3  *
4  * See the IPFILTER.LICENCE file for details on licencing.
5  */
6 #if !defined(lint)
7 static const char sccsid[] = "@(#)ip_fil.c      2.41 6/5/96 (C) 1993-2000 Darren Reed";
8 static const char rcsid[] = "@(#)$Id: ipsyncm.c,v 1.4.2.4 2006/03/27 02:09:46 darrenr Exp $";
9 #endif
10 #include <sys/types.h>
11 #include <sys/time.h>
12 #include <sys/socket.h>
13
14 #include <netinet/in.h>
15 #include <net/if.h>
16
17 #include <arpa/inet.h>
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <syslog.h>
25 #include <signal.h>
26
27 #include "netinet/ip_compat.h"
28 #include "netinet/ip_fil.h"
29 #include "netinet/ip_nat.h"
30 #include "netinet/ip_state.h"
31 #include "netinet/ip_sync.h"
32
33
34 int     main __P((int, char *[]));
35 void    usage __P((const char *));
36
37 int     terminate = 0;
38
39 void usage(const char *progname) {
40         fprintf(stderr, "Usage: %s <destination IP> <destination port>\n", progname);
41 }
42
43 #if 0
44 static void handleterm(int sig)
45 {
46         terminate = sig;
47 }
48 #endif
49
50  
51 /* should be large enough to hold header + any datatype */
52 #define BUFFERLEN 1400
53
54 int main(argc, argv)
55 int argc;
56 char *argv[];
57 {
58         struct sockaddr_in sin;
59         char buff[BUFFERLEN];
60         synclogent_t *sl;
61         syncupdent_t *su;
62         int nfd = -1, lfd = -1, n1, n2, n3, len;
63         int inbuf;
64         u_32_t magic;
65         synchdr_t *sh;
66         char *progname;
67         
68         progname = strrchr(argv[0], '/');
69         if (progname) {
70                 progname++;
71         } else {
72                 progname = argv[0];
73         }
74         
75
76         if (argc < 2) {
77                 usage(progname);
78                 exit(1);
79         }
80
81 #if 0
82         signal(SIGHUP, handleterm);
83         signal(SIGINT, handleterm);
84         signal(SIGTERM, handleterm);
85 #endif
86
87         openlog(progname, LOG_PID, LOG_SECURITY);
88
89         bzero((char *)&sin, sizeof(sin));
90         sin.sin_family = AF_INET;
91         sin.sin_addr.s_addr = inet_addr(argv[1]);
92         if (argc > 2)
93                 sin.sin_port = htons(atoi(argv[2]));
94         else
95                 sin.sin_port = htons(43434);
96
97         while (1) {
98
99                 if (lfd != -1)
100                         close(lfd);
101                 if (nfd != -1)
102                         close(nfd);
103
104                 lfd = open(IPSYNC_NAME, O_RDONLY);
105                 if (lfd == -1) {
106                         syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME);
107                         goto tryagain;
108                 }
109                 
110                 nfd = socket(AF_INET, SOCK_DGRAM, 0);
111                 if (nfd == -1) {
112                         syslog(LOG_ERR, "Socket :%m");
113                         goto tryagain;
114                 }
115         
116                 if (connect(nfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
117                         syslog(LOG_ERR, "Connect: %m");
118                         goto tryagain;
119                 }
120
121                 syslog(LOG_INFO, "Sending data to %s",
122                        inet_ntoa(sin.sin_addr));
123         
124                 inbuf = 0;      
125                 while (1) {
126
127                         n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf);
128                 
129                         printf("header : %d bytes read (header = %d bytes)\n",
130                                n1, sizeof(*sh));
131         
132                         if (n1 < 0) {
133                                 syslog(LOG_ERR, "Read error (header): %m");
134                                 goto tryagain;
135                         }
136
137                         if (n1 == 0) {
138                                 /* XXX can this happen??? */
139                                 syslog(LOG_ERR,
140                                        "Read error (header) : No data");
141                                 sleep(1);
142                                 continue;
143                         }
144                         
145                         inbuf += n1;            
146
147 moreinbuf:
148                         if (inbuf < sizeof(*sh)) {
149                                 continue; /* need more data */
150                         }
151
152                         sh = (synchdr_t *)buff;
153                         len = ntohl(sh->sm_len);
154                         magic = ntohl(sh->sm_magic);            
155
156                         if (magic != SYNHDRMAGIC) {
157                                 syslog(LOG_ERR,
158                                        "Invalid header magic %x", magic);
159                                 goto tryagain;
160                         }
161
162 #define IPSYNC_DEBUG
163 #ifdef IPSYNC_DEBUG
164                         printf("v:%d p:%d len:%d magic:%x", sh->sm_v,
165                                sh->sm_p, len, magic);
166
167                         if (sh->sm_cmd == SMC_CREATE)
168                                 printf(" cmd:CREATE");
169                         else if (sh->sm_cmd == SMC_UPDATE)
170                                 printf(" cmd:UPDATE");
171                         else
172                                 printf(" cmd:Unknown(%d)", sh->sm_cmd);
173
174                         if (sh->sm_table == SMC_NAT)
175                                 printf(" table:NAT");
176                         else if (sh->sm_table == SMC_STATE)
177                                 printf(" table:STATE");
178                         else
179                                 printf(" table:Unknown(%d)", sh->sm_table);
180
181                         printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num));
182 #endif                  
183                         
184                         if (inbuf < sizeof(*sh) + len) {
185                                 continue; /* need more data */
186                                 goto tryagain;
187                         }
188
189 #ifdef IPSYNC_DEBUG
190                         if (sh->sm_cmd == SMC_CREATE) {
191                                 sl = (synclogent_t *)buff;
192
193                         } else if (sh->sm_cmd == SMC_UPDATE) {
194                                 su = (syncupdent_t *)buff;
195                                 if (sh->sm_p == IPPROTO_TCP) {
196                                         printf(" TCP Update: age %lu state %d/%d\n", 
197                                                 su->sup_tcp.stu_age,
198                                                 su->sup_tcp.stu_state[0], 
199                                                 su->sup_tcp.stu_state[1]);
200                                 }
201                         } else {
202                                 printf("Unknown command\n");
203                         }
204 #endif
205
206                         n2 = sizeof(*sh) + len;
207                         n3 = write(nfd, buff, n2);
208                         if (n3 <= 0) {
209                                 syslog(LOG_ERR, "Write error: %m");
210                                 goto tryagain;
211                         }
212
213                         
214                         if (n3 != n2) {
215                                 syslog(LOG_ERR, "Incomplete write (%d/%d)",
216                                        n3, n2);
217                                 goto tryagain;
218                         }
219
220                         /* signal received? */
221                         if (terminate)
222                                 break;
223
224                         /* move buffer to the front,we might need to make
225                          * this more efficient, by using a rolling pointer
226                          * over the buffer and only copying it, when
227                          * we are reaching the end 
228                          */
229                         inbuf -= n2;
230                         if (inbuf) {
231                                 bcopy(buff+n2, buff, inbuf);
232                                 printf("More data in buffer\n");
233                                 goto moreinbuf;
234                         }
235                 }
236
237                 if (terminate)
238                         break;
239 tryagain:
240                 sleep(1);
241         }
242
243
244         /* terminate */
245         if (lfd != -1)
246                 close(lfd);
247         if (nfd != -1)
248                 close(nfd);
249
250         syslog(LOG_ERR, "signal %d received, exiting...", terminate);
251
252         exit(1);
253 }
254