1145519Sdarrenr/* $FreeBSD: releng/10.2/contrib/ipfilter/tools/ipsyncm.c 255332 2013-09-06 23:11:19Z cy $ */ 2145510Sdarrenr 3145510Sdarrenr/* 4255332Scy * Copyright (C) 2012 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"; 10255332Scystatic const char rcsid[] = "@(#)$Id$"; 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> 25161357Sguido#include <string.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 *[])); 37161357Sguidovoid usage __P((const char *)); 38145510Sdarrenr 39145510Sdarrenrint terminate = 0; 40145510Sdarrenr 41145510Sdarrenrvoid usage(const char *progname) { 42145510Sdarrenr fprintf(stderr, "Usage: %s <destination IP> <destination port>\n", progname); 43145510Sdarrenr} 44145510Sdarrenr 45161357Sguido#if 0 46145510Sdarrenrstatic void handleterm(int sig) 47145510Sdarrenr{ 48145510Sdarrenr terminate = sig; 49145510Sdarrenr} 50161357Sguido#endif 51145510Sdarrenr 52255332Scy 53145510Sdarrenr/* should be large enough to hold header + any datatype */ 54145510Sdarrenr#define BUFFERLEN 1400 55145510Sdarrenr 56145510Sdarrenrint main(argc, argv) 57255332Scy int argc; 58255332Scy char *argv[]; 59145510Sdarrenr{ 60145510Sdarrenr struct sockaddr_in sin; 61145510Sdarrenr char buff[BUFFERLEN]; 62145510Sdarrenr synclogent_t *sl; 63145510Sdarrenr syncupdent_t *su; 64145510Sdarrenr int nfd = -1, lfd = -1, n1, n2, n3, len; 65145510Sdarrenr int inbuf; 66145510Sdarrenr u_32_t magic; 67145510Sdarrenr synchdr_t *sh; 68145510Sdarrenr char *progname; 69255332Scy 70145510Sdarrenr progname = strrchr(argv[0], '/'); 71145510Sdarrenr if (progname) { 72145510Sdarrenr progname++; 73145510Sdarrenr } else { 74145510Sdarrenr progname = argv[0]; 75145510Sdarrenr } 76145510Sdarrenr 77255332Scy 78145510Sdarrenr if (argc < 2) { 79145510Sdarrenr usage(progname); 80145510Sdarrenr exit(1); 81145510Sdarrenr } 82145510Sdarrenr 83145510Sdarrenr#if 0 84145510Sdarrenr signal(SIGHUP, handleterm); 85145510Sdarrenr signal(SIGINT, handleterm); 86145510Sdarrenr signal(SIGTERM, handleterm); 87145510Sdarrenr#endif 88145510Sdarrenr 89145510Sdarrenr openlog(progname, LOG_PID, LOG_SECURITY); 90145510Sdarrenr 91145510Sdarrenr bzero((char *)&sin, sizeof(sin)); 92145510Sdarrenr sin.sin_family = AF_INET; 93145510Sdarrenr sin.sin_addr.s_addr = inet_addr(argv[1]); 94145510Sdarrenr if (argc > 2) 95145510Sdarrenr sin.sin_port = htons(atoi(argv[2])); 96145510Sdarrenr else 97145510Sdarrenr sin.sin_port = htons(43434); 98145510Sdarrenr 99145510Sdarrenr while (1) { 100145510Sdarrenr 101145510Sdarrenr if (lfd != -1) 102145510Sdarrenr close(lfd); 103145510Sdarrenr if (nfd != -1) 104145510Sdarrenr close(nfd); 105145510Sdarrenr 106145510Sdarrenr lfd = open(IPSYNC_NAME, O_RDONLY); 107145510Sdarrenr if (lfd == -1) { 108145510Sdarrenr syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME); 109145510Sdarrenr goto tryagain; 110145510Sdarrenr } 111255332Scy 112145510Sdarrenr nfd = socket(AF_INET, SOCK_DGRAM, 0); 113145510Sdarrenr if (nfd == -1) { 114145510Sdarrenr syslog(LOG_ERR, "Socket :%m"); 115145510Sdarrenr goto tryagain; 116145510Sdarrenr } 117255332Scy 118145510Sdarrenr if (connect(nfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { 119145510Sdarrenr syslog(LOG_ERR, "Connect: %m"); 120145510Sdarrenr goto tryagain; 121145510Sdarrenr } 122145510Sdarrenr 123161357Sguido syslog(LOG_INFO, "Sending data to %s", 124145510Sdarrenr inet_ntoa(sin.sin_addr)); 125255332Scy 126255332Scy inbuf = 0; 127145510Sdarrenr while (1) { 128145510Sdarrenr 129145510Sdarrenr n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf); 130255332Scy 131145510Sdarrenr printf("header : %d bytes read (header = %d bytes)\n", 132255332Scy n1, (int) sizeof(*sh)); 133255332Scy 134145510Sdarrenr if (n1 < 0) { 135145510Sdarrenr syslog(LOG_ERR, "Read error (header): %m"); 136145510Sdarrenr goto tryagain; 137145510Sdarrenr } 138145510Sdarrenr 139145510Sdarrenr if (n1 == 0) { 140145510Sdarrenr /* XXX can this happen??? */ 141145510Sdarrenr syslog(LOG_ERR, 142145510Sdarrenr "Read error (header) : No data"); 143145510Sdarrenr sleep(1); 144145510Sdarrenr continue; 145145510Sdarrenr } 146145510Sdarrenr 147255332Scy inbuf += n1; 148255332Scy 149145510Sdarrenrmoreinbuf: 150145510Sdarrenr if (inbuf < sizeof(*sh)) { 151145510Sdarrenr continue; /* need more data */ 152145510Sdarrenr } 153145510Sdarrenr 154145510Sdarrenr sh = (synchdr_t *)buff; 155145510Sdarrenr len = ntohl(sh->sm_len); 156255332Scy magic = ntohl(sh->sm_magic); 157145510Sdarrenr 158145510Sdarrenr if (magic != SYNHDRMAGIC) { 159145510Sdarrenr syslog(LOG_ERR, 160145510Sdarrenr "Invalid header magic %x", magic); 161145510Sdarrenr goto tryagain; 162145510Sdarrenr } 163145510Sdarrenr 164145510Sdarrenr#define IPSYNC_DEBUG 165145510Sdarrenr#ifdef IPSYNC_DEBUG 166145510Sdarrenr printf("v:%d p:%d len:%d magic:%x", sh->sm_v, 167145510Sdarrenr sh->sm_p, len, magic); 168145510Sdarrenr 169145510Sdarrenr if (sh->sm_cmd == SMC_CREATE) 170145510Sdarrenr printf(" cmd:CREATE"); 171145510Sdarrenr else if (sh->sm_cmd == SMC_UPDATE) 172145510Sdarrenr printf(" cmd:UPDATE"); 173145510Sdarrenr else 174145510Sdarrenr printf(" cmd:Unknown(%d)", sh->sm_cmd); 175145510Sdarrenr 176145510Sdarrenr if (sh->sm_table == SMC_NAT) 177145510Sdarrenr printf(" table:NAT"); 178145510Sdarrenr else if (sh->sm_table == SMC_STATE) 179145510Sdarrenr printf(" table:STATE"); 180145510Sdarrenr else 181145510Sdarrenr printf(" table:Unknown(%d)", sh->sm_table); 182145510Sdarrenr 183145510Sdarrenr printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num)); 184255332Scy#endif 185255332Scy 186145510Sdarrenr if (inbuf < sizeof(*sh) + len) { 187145510Sdarrenr continue; /* need more data */ 188145510Sdarrenr goto tryagain; 189145510Sdarrenr } 190145510Sdarrenr 191145510Sdarrenr#ifdef IPSYNC_DEBUG 192145510Sdarrenr if (sh->sm_cmd == SMC_CREATE) { 193145510Sdarrenr sl = (synclogent_t *)buff; 194145510Sdarrenr 195145510Sdarrenr } else if (sh->sm_cmd == SMC_UPDATE) { 196145510Sdarrenr su = (syncupdent_t *)buff; 197145510Sdarrenr if (sh->sm_p == IPPROTO_TCP) { 198255332Scy printf(" TCP Update: age %lu state %d/%d\n", 199145510Sdarrenr su->sup_tcp.stu_age, 200255332Scy su->sup_tcp.stu_state[0], 201145510Sdarrenr su->sup_tcp.stu_state[1]); 202145510Sdarrenr } 203145510Sdarrenr } else { 204145510Sdarrenr printf("Unknown command\n"); 205145510Sdarrenr } 206145510Sdarrenr#endif 207145510Sdarrenr 208145510Sdarrenr n2 = sizeof(*sh) + len; 209145510Sdarrenr n3 = write(nfd, buff, n2); 210145510Sdarrenr if (n3 <= 0) { 211145510Sdarrenr syslog(LOG_ERR, "Write error: %m"); 212145510Sdarrenr goto tryagain; 213145510Sdarrenr } 214145510Sdarrenr 215255332Scy 216145510Sdarrenr if (n3 != n2) { 217145510Sdarrenr syslog(LOG_ERR, "Incomplete write (%d/%d)", 218145510Sdarrenr n3, n2); 219145510Sdarrenr goto tryagain; 220145510Sdarrenr } 221145510Sdarrenr 222145510Sdarrenr /* signal received? */ 223145510Sdarrenr if (terminate) 224145510Sdarrenr break; 225145510Sdarrenr 226145510Sdarrenr /* move buffer to the front,we might need to make 227145510Sdarrenr * this more efficient, by using a rolling pointer 228145510Sdarrenr * over the buffer and only copying it, when 229255332Scy * we are reaching the end 230145510Sdarrenr */ 231145510Sdarrenr inbuf -= n2; 232145510Sdarrenr if (inbuf) { 233145510Sdarrenr bcopy(buff+n2, buff, inbuf); 234145510Sdarrenr printf("More data in buffer\n"); 235145510Sdarrenr goto moreinbuf; 236145510Sdarrenr } 237145510Sdarrenr } 238145510Sdarrenr 239145510Sdarrenr if (terminate) 240145510Sdarrenr break; 241145510Sdarrenrtryagain: 242145510Sdarrenr sleep(1); 243145510Sdarrenr } 244145510Sdarrenr 245145510Sdarrenr 246145510Sdarrenr /* terminate */ 247145510Sdarrenr if (lfd != -1) 248145510Sdarrenr close(lfd); 249145510Sdarrenr if (nfd != -1) 250145510Sdarrenr close(nfd); 251145510Sdarrenr 252145510Sdarrenr syslog(LOG_ERR, "signal %d received, exiting...", terminate); 253145510Sdarrenr 254145510Sdarrenr exit(1); 255145510Sdarrenr} 256145510Sdarrenr 257