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