ipsyncm.c revision 145519
1/* $FreeBSD: head/contrib/ipfilter/tools/ipsyncm.c 145519 2005-04-25 18:20:15Z darrenr $ */ 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) 9static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 10static 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 36int main __P((int, char *[])); 37 38int terminate = 0; 39 40void usage(const char *progname) { 41 fprintf(stderr, "Usage: %s <destination IP> <destination port>\n", progname); 42} 43 44static 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 53int main(argc, argv) 54int argc; 55char *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 146moreinbuf: 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; 238tryagain: 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 254