ipsyncm.c revision 145510
1145510Sdarrenr/* $NetBSD$ */ 2145510Sdarrenr 3145510Sdarrenr/* 4145510Sdarrenr * Copyright (C) 1993-2001 by Darren Reed. 5145510Sdarrenr * 6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7145510Sdarrenr */ 8145510Sdarrenr#if !defined(lint) 9145510Sdarrenrstatic const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 10145510Sdarrenrstatic const char rcsid[] = "@(#)Id: ipsyncm.c,v 1.4.2.2 2005/01/08 14:31:46 darrenr Exp"; 11145510Sdarrenr#endif 12145510Sdarrenr#include <sys/types.h> 13145510Sdarrenr#include <sys/time.h> 14145510Sdarrenr#include <sys/socket.h> 15145510Sdarrenr 16145510Sdarrenr#include <netinet/in.h> 17145510Sdarrenr#include <net/if.h> 18145510Sdarrenr 19145510Sdarrenr#include <arpa/inet.h> 20145510Sdarrenr 21145510Sdarrenr#include <stdio.h> 22145510Sdarrenr#include <stdlib.h> 23145510Sdarrenr#include <fcntl.h> 24145510Sdarrenr#include <unistd.h> 25145510Sdarrenr#include <strings.h> 26145510Sdarrenr#include <syslog.h> 27145510Sdarrenr#include <signal.h> 28145510Sdarrenr 29145510Sdarrenr#include "netinet/ip_compat.h" 30145510Sdarrenr#include "netinet/ip_fil.h" 31145510Sdarrenr#include "netinet/ip_nat.h" 32145510Sdarrenr#include "netinet/ip_state.h" 33145510Sdarrenr#include "netinet/ip_sync.h" 34145510Sdarrenr 35145510Sdarrenr 36145510Sdarrenrint main __P((int, char *[])); 37145510Sdarrenr 38145510Sdarrenrint terminate = 0; 39145510Sdarrenr 40145510Sdarrenrvoid usage(const char *progname) { 41145510Sdarrenr fprintf(stderr, "Usage: %s <destination IP> <destination port>\n", progname); 42145510Sdarrenr} 43145510Sdarrenr 44145510Sdarrenrstatic void handleterm(int sig) 45145510Sdarrenr{ 46145510Sdarrenr terminate = sig; 47145510Sdarrenr} 48145510Sdarrenr 49145510Sdarrenr 50145510Sdarrenr/* should be large enough to hold header + any datatype */ 51145510Sdarrenr#define BUFFERLEN 1400 52145510Sdarrenr 53145510Sdarrenrint main(argc, argv) 54145510Sdarrenrint argc; 55145510Sdarrenrchar *argv[]; 56145510Sdarrenr{ 57145510Sdarrenr struct sockaddr_in sin; 58145510Sdarrenr char buff[BUFFERLEN]; 59145510Sdarrenr synclogent_t *sl; 60145510Sdarrenr syncupdent_t *su; 61145510Sdarrenr int nfd = -1, lfd = -1, n1, n2, n3, len; 62145510Sdarrenr int inbuf; 63145510Sdarrenr u_32_t magic; 64145510Sdarrenr synchdr_t *sh; 65145510Sdarrenr char *progname; 66145510Sdarrenr 67145510Sdarrenr progname = strrchr(argv[0], '/'); 68145510Sdarrenr if (progname) { 69145510Sdarrenr progname++; 70145510Sdarrenr } else { 71145510Sdarrenr progname = argv[0]; 72145510Sdarrenr } 73145510Sdarrenr 74145510Sdarrenr 75145510Sdarrenr if (argc < 2) { 76145510Sdarrenr usage(progname); 77145510Sdarrenr exit(1); 78145510Sdarrenr } 79145510Sdarrenr 80145510Sdarrenr#if 0 81145510Sdarrenr signal(SIGHUP, handleterm); 82145510Sdarrenr signal(SIGINT, handleterm); 83145510Sdarrenr signal(SIGTERM, handleterm); 84145510Sdarrenr#endif 85145510Sdarrenr 86145510Sdarrenr openlog(progname, LOG_PID, LOG_SECURITY); 87145510Sdarrenr 88145510Sdarrenr bzero((char *)&sin, sizeof(sin)); 89145510Sdarrenr sin.sin_family = AF_INET; 90145510Sdarrenr sin.sin_addr.s_addr = inet_addr(argv[1]); 91145510Sdarrenr if (argc > 2) 92145510Sdarrenr sin.sin_port = htons(atoi(argv[2])); 93145510Sdarrenr else 94145510Sdarrenr sin.sin_port = htons(43434); 95145510Sdarrenr 96145510Sdarrenr while (1) { 97145510Sdarrenr 98145510Sdarrenr if (lfd != -1) 99145510Sdarrenr close(lfd); 100145510Sdarrenr if (nfd != -1) 101145510Sdarrenr close(nfd); 102145510Sdarrenr 103145510Sdarrenr lfd = open(IPSYNC_NAME, O_RDONLY); 104145510Sdarrenr if (lfd == -1) { 105145510Sdarrenr syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME); 106145510Sdarrenr goto tryagain; 107145510Sdarrenr } 108145510Sdarrenr 109145510Sdarrenr nfd = socket(AF_INET, SOCK_DGRAM, 0); 110145510Sdarrenr if (nfd == -1) { 111145510Sdarrenr syslog(LOG_ERR, "Socket :%m"); 112145510Sdarrenr goto tryagain; 113145510Sdarrenr } 114145510Sdarrenr 115145510Sdarrenr if (connect(nfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { 116145510Sdarrenr syslog(LOG_ERR, "Connect: %m"); 117145510Sdarrenr goto tryagain; 118145510Sdarrenr } 119145510Sdarrenr 120145510Sdarrenr syslog(LOG_INFO, "Established connection to %s", 121145510Sdarrenr inet_ntoa(sin.sin_addr)); 122145510Sdarrenr 123145510Sdarrenr inbuf = 0; 124145510Sdarrenr while (1) { 125145510Sdarrenr 126145510Sdarrenr n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf); 127145510Sdarrenr 128145510Sdarrenr printf("header : %d bytes read (header = %d bytes)\n", 129145510Sdarrenr n1, sizeof(*sh)); 130145510Sdarrenr 131145510Sdarrenr if (n1 < 0) { 132145510Sdarrenr syslog(LOG_ERR, "Read error (header): %m"); 133145510Sdarrenr goto tryagain; 134145510Sdarrenr } 135145510Sdarrenr 136145510Sdarrenr if (n1 == 0) { 137145510Sdarrenr /* XXX can this happen??? */ 138145510Sdarrenr syslog(LOG_ERR, 139145510Sdarrenr "Read error (header) : No data"); 140145510Sdarrenr sleep(1); 141145510Sdarrenr continue; 142145510Sdarrenr } 143145510Sdarrenr 144145510Sdarrenr inbuf += n1; 145145510Sdarrenr 146145510Sdarrenrmoreinbuf: 147145510Sdarrenr if (inbuf < sizeof(*sh)) { 148145510Sdarrenr continue; /* need more data */ 149145510Sdarrenr } 150145510Sdarrenr 151145510Sdarrenr sh = (synchdr_t *)buff; 152145510Sdarrenr len = ntohl(sh->sm_len); 153145510Sdarrenr magic = ntohl(sh->sm_magic); 154145510Sdarrenr 155145510Sdarrenr if (magic != SYNHDRMAGIC) { 156145510Sdarrenr syslog(LOG_ERR, 157145510Sdarrenr "Invalid header magic %x", magic); 158145510Sdarrenr goto tryagain; 159145510Sdarrenr } 160145510Sdarrenr 161145510Sdarrenr#define IPSYNC_DEBUG 162145510Sdarrenr#ifdef IPSYNC_DEBUG 163145510Sdarrenr printf("v:%d p:%d len:%d magic:%x", sh->sm_v, 164145510Sdarrenr sh->sm_p, len, magic); 165145510Sdarrenr 166145510Sdarrenr if (sh->sm_cmd == SMC_CREATE) 167145510Sdarrenr printf(" cmd:CREATE"); 168145510Sdarrenr else if (sh->sm_cmd == SMC_UPDATE) 169145510Sdarrenr printf(" cmd:UPDATE"); 170145510Sdarrenr else 171145510Sdarrenr printf(" cmd:Unknown(%d)", sh->sm_cmd); 172145510Sdarrenr 173145510Sdarrenr if (sh->sm_table == SMC_NAT) 174145510Sdarrenr printf(" table:NAT"); 175145510Sdarrenr else if (sh->sm_table == SMC_STATE) 176145510Sdarrenr printf(" table:STATE"); 177145510Sdarrenr else 178145510Sdarrenr printf(" table:Unknown(%d)", sh->sm_table); 179145510Sdarrenr 180145510Sdarrenr printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num)); 181145510Sdarrenr#endif 182145510Sdarrenr 183145510Sdarrenr if (inbuf < sizeof(*sh) + len) { 184145510Sdarrenr continue; /* need more data */ 185145510Sdarrenr goto tryagain; 186145510Sdarrenr } 187145510Sdarrenr 188145510Sdarrenr#ifdef IPSYNC_DEBUG 189145510Sdarrenr if (sh->sm_cmd == SMC_CREATE) { 190145510Sdarrenr sl = (synclogent_t *)buff; 191145510Sdarrenr 192145510Sdarrenr } else if (sh->sm_cmd == SMC_UPDATE) { 193145510Sdarrenr su = (syncupdent_t *)buff; 194145510Sdarrenr if (sh->sm_p == IPPROTO_TCP) { 195145510Sdarrenr printf(" TCP Update: age %lu state %d/%d\n", 196145510Sdarrenr su->sup_tcp.stu_age, 197145510Sdarrenr su->sup_tcp.stu_state[0], 198145510Sdarrenr su->sup_tcp.stu_state[1]); 199145510Sdarrenr } 200145510Sdarrenr } else { 201145510Sdarrenr printf("Unknown command\n"); 202145510Sdarrenr } 203145510Sdarrenr#endif 204145510Sdarrenr 205145510Sdarrenr n2 = sizeof(*sh) + len; 206145510Sdarrenr n3 = write(nfd, buff, n2); 207145510Sdarrenr if (n3 <= 0) { 208145510Sdarrenr syslog(LOG_ERR, "Write error: %m"); 209145510Sdarrenr goto tryagain; 210145510Sdarrenr } 211145510Sdarrenr 212145510Sdarrenr 213145510Sdarrenr if (n3 != n2) { 214145510Sdarrenr syslog(LOG_ERR, "Incomplete write (%d/%d)", 215145510Sdarrenr n3, n2); 216145510Sdarrenr goto tryagain; 217145510Sdarrenr } 218145510Sdarrenr 219145510Sdarrenr /* signal received? */ 220145510Sdarrenr if (terminate) 221145510Sdarrenr break; 222145510Sdarrenr 223145510Sdarrenr /* move buffer to the front,we might need to make 224145510Sdarrenr * this more efficient, by using a rolling pointer 225145510Sdarrenr * over the buffer and only copying it, when 226145510Sdarrenr * we are reaching the end 227145510Sdarrenr */ 228145510Sdarrenr inbuf -= n2; 229145510Sdarrenr if (inbuf) { 230145510Sdarrenr bcopy(buff+n2, buff, inbuf); 231145510Sdarrenr printf("More data in buffer\n"); 232145510Sdarrenr goto moreinbuf; 233145510Sdarrenr } 234145510Sdarrenr } 235145510Sdarrenr 236145510Sdarrenr if (terminate) 237145510Sdarrenr break; 238145510Sdarrenrtryagain: 239145510Sdarrenr sleep(1); 240145510Sdarrenr } 241145510Sdarrenr 242145510Sdarrenr 243145510Sdarrenr /* terminate */ 244145510Sdarrenr if (lfd != -1) 245145510Sdarrenr close(lfd); 246145510Sdarrenr if (nfd != -1) 247145510Sdarrenr close(nfd); 248145510Sdarrenr 249145510Sdarrenr syslog(LOG_ERR, "signal %d received, exiting...", terminate); 250145510Sdarrenr 251145510Sdarrenr exit(1); 252145510Sdarrenr} 253145510Sdarrenr 254