From nobody Sat Jan 08 05:47:25 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 9332E1946718; Sat, 8 Jan 2022 05:47:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JW8Hd2B6Fz3kTs; Sat, 8 Jan 2022 05:47:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 2B6E6196A2; Sat, 8 Jan 2022 05:47:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 2085lPBP028996; Sat, 8 Jan 2022 05:47:25 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2085lPx4028995; Sat, 8 Jan 2022 05:47:25 GMT (envelope-from git) Date: Sat, 8 Jan 2022 05:47:25 GMT Message-Id: <202201080547.2085lPx4028995@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Cy Schubert Subject: git: 08ab34a06a9b - main - ipfilter: Restore ipfsync List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: cy X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 08ab34a06a9b0a84e979ff43f2d6f2d60fb37ed9 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1641620845; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cdH3MPhQAskWi1XZ9v0494L36QjOzaBtGItIze622/0=; b=cnLcizh+jpLPSFXdE2f2Ni5H9yBe5AD9c8MH1j0yMmZ2JMKzgS0GJFVRInTVTQasXfnYBF zSTnTziIYpD9cw96yHcH5YhEdlXShnNP6J8YEB1WjfEb7Bw4J/a5nUfOL93+cSRbaMrz8x HPYaeVi6B2PFHqnAFedPPPHt1juKQFw5kKcwwIiTQ0eqv0JjBM6Pi/jOTvGyh8e69Er7Ni LCRNLqwsfU5ogERLmW5CKDm9hzs2BGcbDHBakkBxnKKegWt2q2u1C2tDXj3fXriXkXFbrc ZmcsRNJmSx2SBF/vJT11sZYJUe2tDQUIwjZpmf9jgC5xvLkrqs+jt8gU7M/JaA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1641620845; a=rsa-sha256; cv=none; b=HGDS0u6hCFCaCrkJUYUOqZm9uimU4mvJcxlszeC0JjTtGxF4HGmX383lXrcN/FeaZ07YHY 7NM2giHQra6ZnwYpte+RvyY5wYbJGqyU4PC8wF8KgVzKWNEHEvFrTZ+gd56O53Hxg6VGNz mKWBzXEZSNdE0R9+sQo+tN5gE8XShpARxb41jrfIIlIhxCZ24dZBcGvP+x00Xh7FmhlGyN jy5ZWKE2EDRIrXTyksMjdEGbs6YzJeSwnpU1hcK60hAxzQS+fU8SeOAqD5ucImQcAfT1yw 4PA4YTzZXMG0e1dl7vxu4DkMTQrjlUfUOIJ89amBck6JcEQb1INbxOAbcoH7Mg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by cy: URL: https://cgit.FreeBSD.org/src/commit/?id=08ab34a06a9b0a84e979ff43f2d6f2d60fb37ed9 commit 08ab34a06a9b0a84e979ff43f2d6f2d60fb37ed9 Author: Cy Schubert AuthorDate: 2022-01-08 04:12:50 +0000 Commit: Cy Schubert CommitDate: 2022-01-08 05:46:53 +0000 ipfilter: Restore ipfsync ipfsync is a WIP sync daemon designed to be used in a failover scenario. It was removed by 5ee61c7daa511927aae8652d6a3ea78866a50ef8. This commit restores its three files. ipfsync is in my work queue. MFC after: 10 days X-MFC with: 5ee61c7daa511927aae8652d6a3ea78866a50ef8 --- sbin/ipf/ipfsync/ipfsyncd.c | 671 ++++++++++++++++++++++++++++++++++++++++++++ sbin/ipf/ipfsync/ipsyncm.c | 256 +++++++++++++++++ sbin/ipf/ipfsync/ipsyncs.c | 274 ++++++++++++++++++ 3 files changed, 1201 insertions(+) diff --git a/sbin/ipf/ipfsync/ipfsyncd.c b/sbin/ipf/ipfsync/ipfsyncd.c new file mode 100644 index 000000000000..ead92b70371c --- /dev/null +++ b/sbin/ipf/ipfsync/ipfsyncd.c @@ -0,0 +1,671 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)$Id: ipfsyncd.c,v 1.1.2.2 2012/07/22 08:04:24 darren_r Exp $"; +#endif +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ipf.h" +#include "opts.h" + + +#define R_IO_ERROR -1 +#define R_OKAY 0 +#define R_MORE 1 +#define R_SKIP 2 +#if defined(sun) && !defined(SOLARIS2) +# define STRERROR(x) sys_errlist[x] +extern char *sys_errlist[]; +#else +# define STRERROR(x) strerror(x) +#endif + + +int main(int, char *[]); +void usage(char *); +void printsynchdr(synchdr_t *); +void printtable(int); +void printsmcproto(char *); +void printcommand(int); +int do_kbuff(int, char *, int *); +int do_packet(int, char *); +int buildsocket(char *, struct sockaddr_in *); +void do_io(void); +void handleterm(int); + +int terminate = 0; +int igmpfd = -1; +int nfd = -1; +int lfd = -1; +int opts = 0; + +void +usage(progname) + char *progname; +{ + fprintf(stderr, + "Usage: %s [-d] [-p port] [-i address] -I \n", + progname); +} + +void +handleterm(sig) + int sig; +{ + terminate = sig; +} + + +/* should be large enough to hold header + any datatype */ +#define BUFFERLEN 1400 + +int +main(argc, argv) + int argc; + char *argv[]; +{ + struct sockaddr_in sin; + char *interface; + char *progname; + int opt, tries; + + progname = strrchr(argv[0], '/'); + if (progname) { + progname++; + } else { + progname = argv[0]; + } + + opts = 0; + tries = 0; + interface = NULL; + + bzero((char *)&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(0xaf6c); + sin.sin_addr.s_addr = htonl(INADDR_UNSPEC_GROUP | 0x697066); + + while ((opt = getopt(argc, argv, "di:I:p:")) != -1) + switch (opt) + { + case 'd' : + debuglevel++; + break; + case 'I' : + interface = optarg; + break; + case 'i' : + sin.sin_addr.s_addr = inet_addr(optarg); + break; + case 'p' : + sin.sin_port = htons(atoi(optarg)); + break; + } + + if (interface == NULL) { + usage(progname); + exit(1); + } + + if (!debuglevel) { + +#ifdef BSD + daemon(0, 0); +#else + int fd = open("/dev/null", O_RDWR); + + switch (fork()) + { + case 0 : + break; + + case -1 : + fprintf(stderr, "%s: fork() failed: %s\n", + argv[0], STRERROR(errno)); + exit(1); + /* NOTREACHED */ + + default : + exit(0); + /* NOTREACHED */ + } + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + + setsid(); +#endif + } + + signal(SIGHUP, handleterm); + signal(SIGINT, handleterm); + signal(SIGTERM, handleterm); + + openlog(progname, LOG_PID, LOG_SECURITY); + + while (!terminate) { + if (lfd != -1) { + close(lfd); + lfd = -1; + } + if (nfd != -1) { + close(nfd); + nfd = -1; + } + if (igmpfd != -1) { + close(igmpfd); + igmpfd = -1; + } + + if (buildsocket(interface, &sin) == -1) + goto tryagain; + + lfd = open(IPSYNC_NAME, O_RDWR); + if (lfd == -1) { + syslog(LOG_ERR, "open(%s):%m", IPSYNC_NAME); + debug(1, "open(%s): %s\n", IPSYNC_NAME, + STRERROR(errno)); + goto tryagain; + } + + tries = -1; + do_io(); +tryagain: + tries++; + syslog(LOG_INFO, "retry in %d seconds", 1 << tries); + debug(1, "wait %d seconds\n", 1 << tries); + sleep(1 << tries); + } + + + /* terminate */ + if (lfd != -1) + close(lfd); + if (nfd != -1) + close(nfd); + + syslog(LOG_ERR, "signal %d received, exiting...", terminate); + debug(1, "signal %d received, exiting...", terminate); + + exit(1); +} + + +void +do_io() +{ + char nbuff[BUFFERLEN]; + char buff[BUFFERLEN]; + fd_set mrd, rd; + int maxfd; + int inbuf; + int n1; + int left; + + FD_ZERO(&mrd); + FD_SET(lfd, &mrd); + FD_SET(nfd, &mrd); + maxfd = nfd; + if (lfd > maxfd) + maxfd = lfd; + debug(2, "nfd %d lfd %d maxfd %d\n", nfd, lfd, maxfd); + + inbuf = 0; + /* + * A threaded approach to this loop would have one thread + * work on reading lfd (only) all the time and another thread + * working on reading nfd all the time. + */ + while (!terminate) { + int n; + + rd = mrd; + + n = select(maxfd + 1, &rd, NULL, NULL, NULL); + if (n < 0) { + switch (errno) + { + case EINTR : + continue; + default : + syslog(LOG_ERR, "select error: %m"); + debug(1, "select error: %s\n", STRERROR(errno)); + return; + } + } + + if (FD_ISSET(lfd, &rd)) { + n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf); + + debug(3, "read(K):%d\n", n1); + + if (n1 <= 0) { + syslog(LOG_ERR, "read error (k-header): %m"); + debug(1, "read error (k-header): %s\n", + STRERROR(errno)); + return; + } + + left = 0; + + switch (do_kbuff(n1, buff, &left)) + { + case R_IO_ERROR : + return; + case R_MORE : + inbuf += left; + break; + default : + inbuf = 0; + break; + } + } + + if (FD_ISSET(nfd, &rd)) { + n1 = recv(nfd, nbuff, sizeof(nbuff), 0); + + debug(3, "read(N):%d\n", n1); + + if (n1 <= 0) { + syslog(LOG_ERR, "read error (n-header): %m"); + debug(1, "read error (n-header): %s\n", + STRERROR(errno)); + return; + } + + switch (do_packet(n1, nbuff)) + { + case R_IO_ERROR : + return; + default : + break; + } + } + } +} + + +int +buildsocket(nicname, sinp) + char *nicname; + struct sockaddr_in *sinp; +{ + struct sockaddr_in *reqip; + struct ifreq req; + char opt; + + debug(2, "binding to %s:%s\n", nicname, inet_ntoa(sinp->sin_addr)); + + if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) { + struct in_addr addr; + struct ip_mreq mreq; + + igmpfd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP); + if (igmpfd == -1) { + syslog(LOG_ERR, "socket:%m"); + debug(1, "socket:%s\n", STRERROR(errno)); + return -1; + } + + bzero((char *)&req, sizeof(req)); + strncpy(req.ifr_name, nicname, sizeof(req.ifr_name)); + req.ifr_name[sizeof(req.ifr_name) - 1] = '\0'; + if (ioctl(igmpfd, SIOCGIFADDR, &req) == -1) { + syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m"); + debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + reqip = (struct sockaddr_in *)&req.ifr_addr; + + addr = reqip->sin_addr; + if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_IF, + (char *)&addr, sizeof(addr)) == -1) { + syslog(LOG_ERR, "setsockopt(IP_MULTICAST_IF(%s)):%m", + inet_ntoa(addr)); + debug(1, "setsockopt(IP_MULTICAST_IF(%s)):%s\n", + inet_ntoa(addr), STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + + opt = 0; + if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_LOOP, + (char *)&opt, sizeof(opt)) == -1) { + syslog(LOG_ERR, "setsockopt(IP_MULTICAST_LOOP=0):%m"); + debug(1, "setsockopt(IP_MULTICAST_LOOP=0):%s\n", + STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + + opt = 63; + if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_TTL, + (char *)&opt, sizeof(opt)) == -1) { + syslog(LOG_ERR, "setsockopt(IP_MULTICAST_TTL=%d):%m", + opt); + debug(1, "setsockopt(IP_MULTICAST_TTL=%d):%s\n", opt, + STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + + mreq.imr_multiaddr.s_addr = sinp->sin_addr.s_addr; + mreq.imr_interface.s_addr = reqip->sin_addr.s_addr; + + if (setsockopt(igmpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + (char *)&mreq, sizeof(mreq)) == -1) { + char buffer[80]; + + snprintf(buffer, sizeof(buffer), "%s,", inet_ntoa(sinp->sin_addr)); + strcat(buffer, inet_ntoa(reqip->sin_addr)); + + syslog(LOG_ERR, + "setsockpt(IP_ADD_MEMBERSHIP,%s):%m", buffer); + debug(1, "setsockpt(IP_ADD_MEMBERSHIP,%s):%s\n", + buffer, STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + } + nfd = socket(AF_INET, SOCK_DGRAM, 0); + if (nfd == -1) { + syslog(LOG_ERR, "socket:%m"); + if (igmpfd != -1) { + close(igmpfd); + igmpfd = -1; + } + return -1; + } + bzero((char *)&req, sizeof(req)); + strncpy(req.ifr_name, nicname, sizeof(req.ifr_name)); + req.ifr_name[sizeof(req.ifr_name) - 1] = '\0'; + if (ioctl(nfd, SIOCGIFADDR, &req) == -1) { + syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m"); + debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + + if (bind(nfd, (struct sockaddr *)&req.ifr_addr, + sizeof(req.ifr_addr)) == -1) { + syslog(LOG_ERR, "bind:%m"); + debug(1, "bind:%s\n", STRERROR(errno)); + close(nfd); + if (igmpfd != -1) { + close(igmpfd); + igmpfd = -1; + } + nfd = -1; + return -1; + } + + if (connect(nfd, (struct sockaddr *)sinp, sizeof(*sinp)) == -1) { + syslog(LOG_ERR, "connect:%m"); + debug(1, "connect:%s\n", STRERROR(errno)); + close(nfd); + if (igmpfd != -1) { + close(igmpfd); + igmpfd = -1; + } + nfd = -1; + return -1; + } + syslog(LOG_INFO, "Sending data to %s", inet_ntoa(sinp->sin_addr)); + debug(3, "Sending data to %s\n", inet_ntoa(sinp->sin_addr)); + + return nfd; +} + + +int +do_packet(pklen, buff) + int pklen; + char *buff; +{ + synchdr_t *sh; + u_32_t magic; + int len; + int n2; + int n3; + + while (pklen > 0) { + if (pklen < sizeof(*sh)) { + syslog(LOG_ERR, "packet length too short:%d", pklen); + debug(2, "packet length too short:%d\n", pklen); + return R_SKIP; + } + + sh = (synchdr_t *)buff; + len = ntohl(sh->sm_len); + magic = ntohl(sh->sm_magic); + + if (magic != SYNHDRMAGIC) { + syslog(LOG_ERR, "invalid header magic %x", magic); + debug(2, "invalid header magic %x\n", magic); + return R_SKIP; + } + + if (pklen < len + sizeof(*sh)) { + syslog(LOG_ERR, "packet length too short:%d", pklen); + debug(2, "packet length too short:%d\n", pklen); + return R_SKIP; + } + + if (debuglevel > 3) { + printsynchdr(sh); + printcommand(sh->sm_cmd); + printtable(sh->sm_table); + printsmcproto(buff); + } + + n2 = sizeof(*sh) + len; + + do { + n3 = write(lfd, buff, n2); + if (n3 <= 0) { + syslog(LOG_ERR, "write error: %m"); + debug(1, "write error: %s\n", STRERROR(errno)); + return R_IO_ERROR; + } + + n2 -= n3; + buff += n3; + pklen -= n3; + } while (n3 != 0); + } + + return R_OKAY; +} + + + +int +do_kbuff(inbuf, buf, left) + int inbuf, *left; + char *buf; +{ + synchdr_t *sh; + u_32_t magic; + int complete; + int sendlen; + int error; + int bytes; + int len; + int n2; + int n3; + + sendlen = 0; + bytes = inbuf; + error = R_OKAY; + sh = (synchdr_t *)buf; + + for (complete = 0; bytes > 0; complete++) { + len = ntohl(sh->sm_len); + magic = ntohl(sh->sm_magic); + + if (magic != SYNHDRMAGIC) { + syslog(LOG_ERR, + "read invalid header magic 0x%x, flushing", + magic); + debug(2, "read invalid header magic 0x%x, flushing\n", + magic); + n2 = SMC_RLOG; + (void) ioctl(lfd, SIOCIPFFL, &n2); + break; + } + + if (debuglevel > 3) { + printsynchdr(sh); + printcommand(sh->sm_cmd); + printtable(sh->sm_table); + putchar('\n'); + } + + if (bytes < sizeof(*sh) + len) { + debug(3, "Not enough bytes %d < %d\n", bytes, + sizeof(*sh) + len); + error = R_MORE; + break; + } + + if (debuglevel > 3) { + printsmcproto(buf); + } + + sendlen += len + sizeof(*sh); + sh = (synchdr_t *)(buf + sendlen); + bytes -= sendlen; + } + + if (complete) { + n3 = send(nfd, buf, sendlen, 0); + if (n3 <= 0) { + syslog(LOG_ERR, "write error: %m"); + debug(1, "write error: %s\n", STRERROR(errno)); + return R_IO_ERROR; + } + debug(3, "send on %d len %d = %d\n", nfd, sendlen, n3); + error = R_OKAY; + } + + /* move buffer to the front,we might need to make + * this more efficient, by using a rolling pointer + * over the buffer and only copying it, when + * we are reaching the end + */ + if (bytes > 0) { + bcopy(buf + bytes, buf, bytes); + error = R_MORE; + } + debug(4, "complete %d bytes %d error %d\n", complete, bytes, error); + + *left = bytes; + + return error; +} + + +void +printcommand(cmd) + int cmd; +{ + + switch (cmd) + { + case SMC_CREATE : + printf(" cmd:CREATE"); + break; + case SMC_UPDATE : + printf(" cmd:UPDATE"); + break; + default : + printf(" cmd:Unknown(%d)", cmd); + break; + } +} + + +void +printtable(table) + int table; +{ + switch (table) + { + case SMC_NAT : + printf(" table:NAT"); + break; + case SMC_STATE : + printf(" table:STATE"); + break; + default : + printf(" table:Unknown(%d)", table); + break; + } +} + + +void +printsmcproto(buff) + char *buff; +{ + syncupdent_t *su; + synchdr_t *sh; + + sh = (synchdr_t *)buff; + + if (sh->sm_cmd == SMC_CREATE) { + ; + + } else if (sh->sm_cmd == SMC_UPDATE) { + su = (syncupdent_t *)buff; + if (sh->sm_p == IPPROTO_TCP) { + printf(" TCP Update: age %lu state %d/%d\n", + su->sup_tcp.stu_age, + su->sup_tcp.stu_state[0], + su->sup_tcp.stu_state[1]); + } + } else { + printf("Unknown command\n"); + } +} + + +void +printsynchdr(sh) + synchdr_t *sh; +{ + + printf("v:%d p:%d num:%d len:%d magic:%x", sh->sm_v, sh->sm_p, + ntohl(sh->sm_num), ntohl(sh->sm_len), ntohl(sh->sm_magic)); +} diff --git a/sbin/ipf/ipfsync/ipsyncm.c b/sbin/ipf/ipfsync/ipsyncm.c new file mode 100644 index 000000000000..d57196379210 --- /dev/null +++ b/sbin/ipf/ipfsync/ipsyncm.c @@ -0,0 +1,256 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)$Id$"; +#endif +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_state.h" +#include "netinet/ip_sync.h" + + +int main(int, char *[]); +void usage(const char *); + +int terminate = 0; + +void usage(const char *progname) { + fprintf(stderr, "Usage: %s \n", progname); +} + +#if 0 +static void handleterm(int sig) +{ + terminate = sig; +} +#endif + + +/* should be large enough to hold header + any datatype */ +#define BUFFERLEN 1400 + +int main(argc, argv) + int argc; + char *argv[]; +{ + struct sockaddr_in sin; + char buff[BUFFERLEN]; + synclogent_t *sl; + syncupdent_t *su; + int nfd = -1, lfd = -1, n1, n2, n3, len; + int inbuf; + u_32_t magic; + synchdr_t *sh; + char *progname; + + progname = strrchr(argv[0], '/'); + if (progname) { + progname++; + } else { + progname = argv[0]; + } + + + if (argc < 2) { + usage(progname); + exit(1); + } + +#if 0 + signal(SIGHUP, handleterm); + signal(SIGINT, handleterm); + signal(SIGTERM, handleterm); +#endif + + openlog(progname, LOG_PID, LOG_SECURITY); + + bzero((char *)&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = inet_addr(argv[1]); + if (argc > 2) + sin.sin_port = htons(atoi(argv[2])); + else + sin.sin_port = htons(43434); + + while (1) { + + if (lfd != -1) + close(lfd); + if (nfd != -1) + close(nfd); + + lfd = open(IPSYNC_NAME, O_RDONLY); + if (lfd == -1) { + syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME); + goto tryagain; + } + + nfd = socket(AF_INET, SOCK_DGRAM, 0); + if (nfd == -1) { + syslog(LOG_ERR, "Socket :%m"); + goto tryagain; + } + + if (connect(nfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + syslog(LOG_ERR, "Connect: %m"); + goto tryagain; + } + + syslog(LOG_INFO, "Sending data to %s", + inet_ntoa(sin.sin_addr)); + + inbuf = 0; + while (1) { + + n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf); + + printf("header : %d bytes read (header = %d bytes)\n", + n1, (int) sizeof(*sh)); + + if (n1 < 0) { + syslog(LOG_ERR, "Read error (header): %m"); + goto tryagain; + } + + if (n1 == 0) { + /* XXX can this happen??? */ + syslog(LOG_ERR, + "Read error (header) : No data"); + sleep(1); + continue; + } + + inbuf += n1; + +moreinbuf: + if (inbuf < sizeof(*sh)) { + continue; /* need more data */ + } + + sh = (synchdr_t *)buff; + len = ntohl(sh->sm_len); + magic = ntohl(sh->sm_magic); + + if (magic != SYNHDRMAGIC) { + syslog(LOG_ERR, + "Invalid header magic %x", magic); + goto tryagain; + } + +#define IPSYNC_DEBUG +#ifdef IPSYNC_DEBUG + printf("v:%d p:%d len:%d magic:%x", sh->sm_v, + sh->sm_p, len, magic); + + if (sh->sm_cmd == SMC_CREATE) + printf(" cmd:CREATE"); + else if (sh->sm_cmd == SMC_UPDATE) + printf(" cmd:UPDATE"); + else + printf(" cmd:Unknown(%d)", sh->sm_cmd); + + if (sh->sm_table == SMC_NAT) + printf(" table:NAT"); + else if (sh->sm_table == SMC_STATE) + printf(" table:STATE"); + else + printf(" table:Unknown(%d)", sh->sm_table); + + printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num)); +#endif + + if (inbuf < sizeof(*sh) + len) { + continue; /* need more data */ + goto tryagain; + } + +#ifdef IPSYNC_DEBUG + if (sh->sm_cmd == SMC_CREATE) { + sl = (synclogent_t *)buff; + + } else if (sh->sm_cmd == SMC_UPDATE) { + su = (syncupdent_t *)buff; + if (sh->sm_p == IPPROTO_TCP) { + printf(" TCP Update: age %lu state %d/%d\n", + su->sup_tcp.stu_age, + su->sup_tcp.stu_state[0], + su->sup_tcp.stu_state[1]); + } + } else { + printf("Unknown command\n"); + } +#endif + + n2 = sizeof(*sh) + len; + n3 = write(nfd, buff, n2); + if (n3 <= 0) { + syslog(LOG_ERR, "Write error: %m"); + goto tryagain; + } + + + if (n3 != n2) { + syslog(LOG_ERR, "Incomplete write (%d/%d)", + n3, n2); + goto tryagain; + } + + /* signal received? */ + if (terminate) + break; + + /* move buffer to the front,we might need to make + * this more efficient, by using a rolling pointer + * over the buffer and only copying it, when + * we are reaching the end + */ + inbuf -= n2; + if (inbuf) { + bcopy(buff+n2, buff, inbuf); + printf("More data in buffer\n"); + goto moreinbuf; + } + } + + if (terminate) + break; +tryagain: + sleep(1); + } + + + /* terminate */ + if (lfd != -1) + close(lfd); + if (nfd != -1) + close(nfd); + + syslog(LOG_ERR, "signal %d received, exiting...", terminate); + + exit(1); +} + diff --git a/sbin/ipf/ipfsync/ipsyncs.c b/sbin/ipf/ipfsync/ipsyncs.c new file mode 100644 index 000000000000..a53cfb8c9508 --- /dev/null +++ b/sbin/ipf/ipfsync/ipsyncs.c @@ -0,0 +1,274 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)$Id$"; +#endif +#include +#include +#include + +#include +#include + *** 256 LINES SKIPPED ***