1254219Scy/* 2254219Scy * Copyright (C) 2012 by Darren Reed. 3254219Scy * 4254219Scy * See the IPFILTER.LICENCE file for details on licencing. 5254219Scy */ 6254219Scy#if !defined(lint) 7254219Scystatic const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 8254219Scystatic const char rcsid[] = "@(#)$Id: ipfsyncd.c,v 1.1.2.2 2012/07/22 08:04:24 darren_r Exp $"; 9254219Scy#endif 10254219Scy#include <sys/types.h> 11254219Scy#include <sys/time.h> 12254219Scy#include <sys/socket.h> 13254219Scy#include <sys/ioctl.h> 14254219Scy#include <sys/sockio.h> 15254219Scy#include <sys/errno.h> 16254219Scy 17254219Scy#include <netinet/in.h> 18254219Scy#include <net/if.h> 19254219Scy 20254219Scy#include <arpa/inet.h> 21254219Scy 22254219Scy#include <stdio.h> 23254219Scy#include <stdlib.h> 24254219Scy#include <fcntl.h> 25254219Scy#include <unistd.h> 26254219Scy#include <string.h> 27254219Scy#include <syslog.h> 28254219Scy#include <signal.h> 29254219Scy 30254219Scy#include "ipf.h" 31254219Scy#include "opts.h" 32254219Scy 33254219Scy 34254219Scy#define R_IO_ERROR -1 35254219Scy#define R_OKAY 0 36254219Scy#define R_MORE 1 37254219Scy#define R_SKIP 2 38254219Scy#if defined(sun) && !defined(SOLARIS2) 39254219Scy# define STRERROR(x) sys_errlist[x] 40254219Scyextern char *sys_errlist[]; 41254219Scy#else 42254219Scy# define STRERROR(x) strerror(x) 43254219Scy#endif 44254219Scy 45254219Scy 46369245Sgit2svnint main(int, char *[]); 47369245Sgit2svnvoid usage(char *); 48369245Sgit2svnvoid printsynchdr(synchdr_t *); 49369245Sgit2svnvoid printtable(int); 50369245Sgit2svnvoid printsmcproto(char *); 51369245Sgit2svnvoid printcommand(int); 52369245Sgit2svnint do_kbuff(int, char *, int *); 53369245Sgit2svnint do_packet(int, char *); 54369245Sgit2svnint buildsocket(char *, struct sockaddr_in *); 55369245Sgit2svnvoid do_io(void); 56369245Sgit2svnvoid handleterm(int); 57254219Scy 58254219Scyint terminate = 0; 59254219Scyint igmpfd = -1; 60254219Scyint nfd = -1; 61254219Scyint lfd = -1; 62254219Scyint opts = 0; 63254219Scy 64254219Scyvoid 65254219Scyusage(progname) 66254219Scy char *progname; 67254219Scy{ 68254219Scy fprintf(stderr, 69254219Scy "Usage: %s [-d] [-p port] [-i address] -I <interface>\n", 70254219Scy progname); 71254219Scy} 72254219Scy 73254219Scyvoid 74254219Scyhandleterm(sig) 75254219Scy int sig; 76254219Scy{ 77254219Scy terminate = sig; 78254219Scy} 79254219Scy 80254219Scy 81254219Scy/* should be large enough to hold header + any datatype */ 82254219Scy#define BUFFERLEN 1400 83254219Scy 84254219Scyint 85254219Scymain(argc, argv) 86254219Scy int argc; 87254219Scy char *argv[]; 88254219Scy{ 89254219Scy struct sockaddr_in sin; 90254219Scy char *interface; 91254219Scy char *progname; 92254219Scy int opt, tries; 93254219Scy 94254219Scy progname = strrchr(argv[0], '/'); 95254219Scy if (progname) { 96254219Scy progname++; 97254219Scy } else { 98254219Scy progname = argv[0]; 99254219Scy } 100254219Scy 101254219Scy opts = 0; 102254219Scy tries = 0; 103254219Scy interface = NULL; 104254219Scy 105254219Scy bzero((char *)&sin, sizeof(sin)); 106254219Scy sin.sin_family = AF_INET; 107254219Scy sin.sin_port = htons(0xaf6c); 108254219Scy sin.sin_addr.s_addr = htonl(INADDR_UNSPEC_GROUP | 0x697066); 109254219Scy 110254219Scy while ((opt = getopt(argc, argv, "di:I:p:")) != -1) 111254219Scy switch (opt) 112254219Scy { 113254219Scy case 'd' : 114254219Scy debuglevel++; 115254219Scy break; 116254219Scy case 'I' : 117254219Scy interface = optarg; 118254219Scy break; 119254219Scy case 'i' : 120254219Scy sin.sin_addr.s_addr = inet_addr(optarg); 121254219Scy break; 122254219Scy case 'p' : 123254219Scy sin.sin_port = htons(atoi(optarg)); 124254219Scy break; 125254219Scy } 126254219Scy 127254219Scy if (interface == NULL) { 128254219Scy usage(progname); 129254219Scy exit(1); 130254219Scy } 131254219Scy 132254219Scy if (!debuglevel) { 133254219Scy 134369273Scy#ifdef BSD 135254219Scy daemon(0, 0); 136254219Scy#else 137254219Scy int fd = open("/dev/null", O_RDWR); 138254219Scy 139254219Scy switch (fork()) 140254219Scy { 141254219Scy case 0 : 142254219Scy break; 143254219Scy 144254219Scy case -1 : 145254219Scy fprintf(stderr, "%s: fork() failed: %s\n", 146254219Scy argv[0], STRERROR(errno)); 147254219Scy exit(1); 148254219Scy /* NOTREACHED */ 149254219Scy 150254219Scy default : 151254219Scy exit(0); 152254219Scy /* NOTREACHED */ 153254219Scy } 154254219Scy 155254219Scy dup2(fd, 0); 156254219Scy dup2(fd, 1); 157254219Scy dup2(fd, 2); 158254219Scy close(fd); 159254219Scy 160254219Scy setsid(); 161254219Scy#endif 162254219Scy } 163254219Scy 164254219Scy signal(SIGHUP, handleterm); 165254219Scy signal(SIGINT, handleterm); 166254219Scy signal(SIGTERM, handleterm); 167254219Scy 168254219Scy openlog(progname, LOG_PID, LOG_SECURITY); 169254219Scy 170254219Scy while (!terminate) { 171254219Scy if (lfd != -1) { 172254219Scy close(lfd); 173254219Scy lfd = -1; 174254219Scy } 175254219Scy if (nfd != -1) { 176254219Scy close(nfd); 177254219Scy nfd = -1; 178254219Scy } 179254219Scy if (igmpfd != -1) { 180254219Scy close(igmpfd); 181254219Scy igmpfd = -1; 182254219Scy } 183254219Scy 184254219Scy if (buildsocket(interface, &sin) == -1) 185254219Scy goto tryagain; 186254219Scy 187254219Scy lfd = open(IPSYNC_NAME, O_RDWR); 188254219Scy if (lfd == -1) { 189254219Scy syslog(LOG_ERR, "open(%s):%m", IPSYNC_NAME); 190254219Scy debug(1, "open(%s): %s\n", IPSYNC_NAME, 191254219Scy STRERROR(errno)); 192254219Scy goto tryagain; 193254219Scy } 194254219Scy 195254219Scy tries = -1; 196254219Scy do_io(); 197254219Scytryagain: 198254219Scy tries++; 199254219Scy syslog(LOG_INFO, "retry in %d seconds", 1 << tries); 200254219Scy debug(1, "wait %d seconds\n", 1 << tries); 201254219Scy sleep(1 << tries); 202254219Scy } 203254219Scy 204254219Scy 205254219Scy /* terminate */ 206254219Scy if (lfd != -1) 207254219Scy close(lfd); 208254219Scy if (nfd != -1) 209254219Scy close(nfd); 210254219Scy 211254219Scy syslog(LOG_ERR, "signal %d received, exiting...", terminate); 212254219Scy debug(1, "signal %d received, exiting...", terminate); 213254219Scy 214254219Scy exit(1); 215254219Scy} 216254219Scy 217254219Scy 218254219Scyvoid 219254219Scydo_io() 220254219Scy{ 221254219Scy char nbuff[BUFFERLEN]; 222254219Scy char buff[BUFFERLEN]; 223254219Scy fd_set mrd, rd; 224254219Scy int maxfd; 225254219Scy int inbuf; 226254219Scy int n1; 227254219Scy int left; 228254219Scy 229254219Scy FD_ZERO(&mrd); 230254219Scy FD_SET(lfd, &mrd); 231254219Scy FD_SET(nfd, &mrd); 232254219Scy maxfd = nfd; 233254219Scy if (lfd > maxfd) 234254219Scy maxfd = lfd; 235254219Scy debug(2, "nfd %d lfd %d maxfd %d\n", nfd, lfd, maxfd); 236254219Scy 237254219Scy inbuf = 0; 238254219Scy /* 239254219Scy * A threaded approach to this loop would have one thread 240254219Scy * work on reading lfd (only) all the time and another thread 241254219Scy * working on reading nfd all the time. 242254219Scy */ 243254219Scy while (!terminate) { 244254219Scy int n; 245254219Scy 246254219Scy rd = mrd; 247254219Scy 248254219Scy n = select(maxfd + 1, &rd, NULL, NULL, NULL); 249254219Scy if (n < 0) { 250254219Scy switch (errno) 251254219Scy { 252254219Scy case EINTR : 253254219Scy continue; 254254219Scy default : 255254219Scy syslog(LOG_ERR, "select error: %m"); 256254219Scy debug(1, "select error: %s\n", STRERROR(errno)); 257254219Scy return; 258254219Scy } 259254219Scy } 260254219Scy 261254219Scy if (FD_ISSET(lfd, &rd)) { 262254219Scy n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf); 263254219Scy 264254219Scy debug(3, "read(K):%d\n", n1); 265254219Scy 266254219Scy if (n1 <= 0) { 267254219Scy syslog(LOG_ERR, "read error (k-header): %m"); 268254219Scy debug(1, "read error (k-header): %s\n", 269254219Scy STRERROR(errno)); 270254219Scy return; 271254219Scy } 272254219Scy 273254219Scy left = 0; 274254219Scy 275254219Scy switch (do_kbuff(n1, buff, &left)) 276254219Scy { 277254219Scy case R_IO_ERROR : 278254219Scy return; 279254219Scy case R_MORE : 280254219Scy inbuf += left; 281254219Scy break; 282254219Scy default : 283254219Scy inbuf = 0; 284254219Scy break; 285254219Scy } 286254219Scy } 287254219Scy 288254219Scy if (FD_ISSET(nfd, &rd)) { 289254219Scy n1 = recv(nfd, nbuff, sizeof(nbuff), 0); 290254219Scy 291254219Scy debug(3, "read(N):%d\n", n1); 292254219Scy 293254219Scy if (n1 <= 0) { 294254219Scy syslog(LOG_ERR, "read error (n-header): %m"); 295254219Scy debug(1, "read error (n-header): %s\n", 296254219Scy STRERROR(errno)); 297254219Scy return; 298254219Scy } 299254219Scy 300254219Scy switch (do_packet(n1, nbuff)) 301254219Scy { 302254219Scy case R_IO_ERROR : 303254219Scy return; 304254219Scy default : 305254219Scy break; 306254219Scy } 307254219Scy } 308254219Scy } 309254219Scy} 310254219Scy 311254219Scy 312254219Scyint 313254219Scybuildsocket(nicname, sinp) 314254219Scy char *nicname; 315254219Scy struct sockaddr_in *sinp; 316254219Scy{ 317254219Scy struct sockaddr_in *reqip; 318254219Scy struct ifreq req; 319254219Scy char opt; 320254219Scy 321254219Scy debug(2, "binding to %s:%s\n", nicname, inet_ntoa(sinp->sin_addr)); 322254219Scy 323254219Scy if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) { 324254219Scy struct in_addr addr; 325254219Scy struct ip_mreq mreq; 326254219Scy 327254219Scy igmpfd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP); 328254219Scy if (igmpfd == -1) { 329254219Scy syslog(LOG_ERR, "socket:%m"); 330254219Scy debug(1, "socket:%s\n", STRERROR(errno)); 331254219Scy return -1; 332254219Scy } 333254219Scy 334254219Scy bzero((char *)&req, sizeof(req)); 335254219Scy strncpy(req.ifr_name, nicname, sizeof(req.ifr_name)); 336254219Scy req.ifr_name[sizeof(req.ifr_name) - 1] = '\0'; 337254219Scy if (ioctl(igmpfd, SIOCGIFADDR, &req) == -1) { 338254219Scy syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m"); 339254219Scy debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno)); 340254219Scy close(igmpfd); 341254219Scy igmpfd = -1; 342254219Scy return -1; 343254219Scy } 344254219Scy reqip = (struct sockaddr_in *)&req.ifr_addr; 345254219Scy 346254219Scy addr = reqip->sin_addr; 347254219Scy if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_IF, 348254219Scy (char *)&addr, sizeof(addr)) == -1) { 349254219Scy syslog(LOG_ERR, "setsockopt(IP_MULTICAST_IF(%s)):%m", 350254219Scy inet_ntoa(addr)); 351254219Scy debug(1, "setsockopt(IP_MULTICAST_IF(%s)):%s\n", 352254219Scy inet_ntoa(addr), STRERROR(errno)); 353254219Scy close(igmpfd); 354254219Scy igmpfd = -1; 355254219Scy return -1; 356254219Scy } 357254219Scy 358254219Scy opt = 0; 359254219Scy if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_LOOP, 360254219Scy (char *)&opt, sizeof(opt)) == -1) { 361254219Scy syslog(LOG_ERR, "setsockopt(IP_MULTICAST_LOOP=0):%m"); 362254219Scy debug(1, "setsockopt(IP_MULTICAST_LOOP=0):%s\n", 363254219Scy STRERROR(errno)); 364254219Scy close(igmpfd); 365254219Scy igmpfd = -1; 366254219Scy return -1; 367254219Scy } 368254219Scy 369254219Scy opt = 63; 370254219Scy if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_TTL, 371254219Scy (char *)&opt, sizeof(opt)) == -1) { 372254219Scy syslog(LOG_ERR, "setsockopt(IP_MULTICAST_TTL=%d):%m", 373254219Scy opt); 374254219Scy debug(1, "setsockopt(IP_MULTICAST_TTL=%d):%s\n", opt, 375254219Scy STRERROR(errno)); 376254219Scy close(igmpfd); 377254219Scy igmpfd = -1; 378254219Scy return -1; 379254219Scy } 380254219Scy 381254219Scy mreq.imr_multiaddr.s_addr = sinp->sin_addr.s_addr; 382254219Scy mreq.imr_interface.s_addr = reqip->sin_addr.s_addr; 383254219Scy 384254219Scy if (setsockopt(igmpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 385254219Scy (char *)&mreq, sizeof(mreq)) == -1) { 386254219Scy char buffer[80]; 387254219Scy 388254219Scy sprintf(buffer, "%s,", inet_ntoa(sinp->sin_addr)); 389254219Scy strcat(buffer, inet_ntoa(reqip->sin_addr)); 390254219Scy 391254219Scy syslog(LOG_ERR, 392254219Scy "setsockpt(IP_ADD_MEMBERSHIP,%s):%m", buffer); 393254219Scy debug(1, "setsockpt(IP_ADD_MEMBERSHIP,%s):%s\n", 394254219Scy buffer, STRERROR(errno)); 395254219Scy close(igmpfd); 396254219Scy igmpfd = -1; 397254219Scy return -1; 398254219Scy } 399254219Scy } 400254219Scy nfd = socket(AF_INET, SOCK_DGRAM, 0); 401254219Scy if (nfd == -1) { 402254219Scy syslog(LOG_ERR, "socket:%m"); 403254219Scy if (igmpfd != -1) { 404254219Scy close(igmpfd); 405254219Scy igmpfd = -1; 406254219Scy } 407254219Scy return -1; 408254219Scy } 409254219Scy bzero((char *)&req, sizeof(req)); 410254219Scy strncpy(req.ifr_name, nicname, sizeof(req.ifr_name)); 411254219Scy req.ifr_name[sizeof(req.ifr_name) - 1] = '\0'; 412254219Scy if (ioctl(nfd, SIOCGIFADDR, &req) == -1) { 413254219Scy syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m"); 414254219Scy debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno)); 415254219Scy close(igmpfd); 416254219Scy igmpfd = -1; 417254219Scy return -1; 418254219Scy } 419254219Scy 420254219Scy if (bind(nfd, (struct sockaddr *)&req.ifr_addr, 421254219Scy sizeof(req.ifr_addr)) == -1) { 422254219Scy syslog(LOG_ERR, "bind:%m"); 423254219Scy debug(1, "bind:%s\n", STRERROR(errno)); 424254219Scy close(nfd); 425254219Scy if (igmpfd != -1) { 426254219Scy close(igmpfd); 427254219Scy igmpfd = -1; 428254219Scy } 429254219Scy nfd = -1; 430254219Scy return -1; 431254219Scy } 432254219Scy 433254219Scy if (connect(nfd, (struct sockaddr *)sinp, sizeof(*sinp)) == -1) { 434254219Scy syslog(LOG_ERR, "connect:%m"); 435254219Scy debug(1, "connect:%s\n", STRERROR(errno)); 436254219Scy close(nfd); 437254219Scy if (igmpfd != -1) { 438254219Scy close(igmpfd); 439254219Scy igmpfd = -1; 440254219Scy } 441254219Scy nfd = -1; 442254219Scy return -1; 443254219Scy } 444254219Scy syslog(LOG_INFO, "Sending data to %s", inet_ntoa(sinp->sin_addr)); 445254219Scy debug(3, "Sending data to %s\n", inet_ntoa(sinp->sin_addr)); 446254219Scy 447254219Scy return nfd; 448254219Scy} 449254219Scy 450254219Scy 451254219Scyint 452254219Scydo_packet(pklen, buff) 453254219Scy int pklen; 454254219Scy char *buff; 455254219Scy{ 456254219Scy synchdr_t *sh; 457254219Scy u_32_t magic; 458254219Scy int len; 459254219Scy int n2; 460254219Scy int n3; 461254219Scy 462254219Scy while (pklen > 0) { 463254219Scy if (pklen < sizeof(*sh)) { 464254219Scy syslog(LOG_ERR, "packet length too short:%d", pklen); 465254219Scy debug(2, "packet length too short:%d\n", pklen); 466254219Scy return R_SKIP; 467254219Scy } 468254219Scy 469254219Scy sh = (synchdr_t *)buff; 470254219Scy len = ntohl(sh->sm_len); 471254219Scy magic = ntohl(sh->sm_magic); 472254219Scy 473254219Scy if (magic != SYNHDRMAGIC) { 474254219Scy syslog(LOG_ERR, "invalid header magic %x", magic); 475254219Scy debug(2, "invalid header magic %x\n", magic); 476254219Scy return R_SKIP; 477254219Scy } 478254219Scy 479254219Scy if (pklen < len + sizeof(*sh)) { 480254219Scy syslog(LOG_ERR, "packet length too short:%d", pklen); 481254219Scy debug(2, "packet length too short:%d\n", pklen); 482254219Scy return R_SKIP; 483254219Scy } 484254219Scy 485254219Scy if (debuglevel > 3) { 486254219Scy printsynchdr(sh); 487254219Scy printcommand(sh->sm_cmd); 488254219Scy printtable(sh->sm_table); 489254219Scy printsmcproto(buff); 490254219Scy } 491254219Scy 492254219Scy n2 = sizeof(*sh) + len; 493254219Scy 494254219Scy do { 495254219Scy n3 = write(lfd, buff, n2); 496254219Scy if (n3 <= 0) { 497254219Scy syslog(LOG_ERR, "write error: %m"); 498254219Scy debug(1, "write error: %s\n", STRERROR(errno)); 499254219Scy return R_IO_ERROR; 500254219Scy } 501254219Scy 502254219Scy n2 -= n3; 503254219Scy buff += n3; 504254219Scy pklen -= n3; 505254219Scy } while (n3 != 0); 506254219Scy } 507254219Scy 508254219Scy return R_OKAY; 509254219Scy} 510254219Scy 511254219Scy 512254219Scy 513254219Scyint 514254219Scydo_kbuff(inbuf, buf, left) 515254219Scy int inbuf, *left; 516254219Scy char *buf; 517254219Scy{ 518254219Scy synchdr_t *sh; 519254219Scy u_32_t magic; 520254219Scy int complete; 521254219Scy int sendlen; 522254219Scy int error; 523254219Scy int bytes; 524254219Scy int len; 525254219Scy int n2; 526254219Scy int n3; 527254219Scy 528254219Scy sendlen = 0; 529254219Scy bytes = inbuf; 530254219Scy error = R_OKAY; 531254219Scy sh = (synchdr_t *)buf; 532254219Scy 533254219Scy for (complete = 0; bytes > 0; complete++) { 534254219Scy len = ntohl(sh->sm_len); 535254219Scy magic = ntohl(sh->sm_magic); 536254219Scy 537254219Scy if (magic != SYNHDRMAGIC) { 538254219Scy syslog(LOG_ERR, 539254219Scy "read invalid header magic 0x%x, flushing", 540254219Scy magic); 541254219Scy debug(2, "read invalid header magic 0x%x, flushing\n", 542254219Scy magic); 543254219Scy n2 = SMC_RLOG; 544254219Scy (void) ioctl(lfd, SIOCIPFFL, &n2); 545254219Scy break; 546254219Scy } 547254219Scy 548254219Scy if (debuglevel > 3) { 549254219Scy printsynchdr(sh); 550254219Scy printcommand(sh->sm_cmd); 551254219Scy printtable(sh->sm_table); 552254219Scy putchar('\n'); 553254219Scy } 554254219Scy 555254219Scy if (bytes < sizeof(*sh) + len) { 556254219Scy debug(3, "Not enough bytes %d < %d\n", bytes, 557254219Scy sizeof(*sh) + len); 558254219Scy error = R_MORE; 559254219Scy break; 560254219Scy } 561254219Scy 562254219Scy if (debuglevel > 3) { 563254219Scy printsmcproto(buf); 564254219Scy } 565254219Scy 566254219Scy sendlen += len + sizeof(*sh); 567254219Scy sh = (synchdr_t *)(buf + sendlen); 568254219Scy bytes -= sendlen; 569254219Scy } 570254219Scy 571254219Scy if (complete) { 572254219Scy n3 = send(nfd, buf, sendlen, 0); 573254219Scy if (n3 <= 0) { 574254219Scy syslog(LOG_ERR, "write error: %m"); 575254219Scy debug(1, "write error: %s\n", STRERROR(errno)); 576254219Scy return R_IO_ERROR; 577254219Scy } 578254219Scy debug(3, "send on %d len %d = %d\n", nfd, sendlen, n3); 579254219Scy error = R_OKAY; 580254219Scy } 581254219Scy 582254219Scy /* move buffer to the front,we might need to make 583254219Scy * this more efficient, by using a rolling pointer 584254219Scy * over the buffer and only copying it, when 585254219Scy * we are reaching the end 586254219Scy */ 587254219Scy if (bytes > 0) { 588254219Scy bcopy(buf + bytes, buf, bytes); 589254219Scy error = R_MORE; 590254219Scy } 591254219Scy debug(4, "complete %d bytes %d error %d\n", complete, bytes, error); 592254219Scy 593254219Scy *left = bytes; 594254219Scy 595254219Scy return error; 596254219Scy} 597254219Scy 598254219Scy 599254219Scyvoid 600254219Scyprintcommand(cmd) 601254219Scy int cmd; 602254219Scy{ 603254219Scy 604254219Scy switch (cmd) 605254219Scy { 606254219Scy case SMC_CREATE : 607254219Scy printf(" cmd:CREATE"); 608254219Scy break; 609254219Scy case SMC_UPDATE : 610254219Scy printf(" cmd:UPDATE"); 611254219Scy break; 612254219Scy default : 613254219Scy printf(" cmd:Unknown(%d)", cmd); 614254219Scy break; 615254219Scy } 616254219Scy} 617254219Scy 618254219Scy 619254219Scyvoid 620254219Scyprinttable(table) 621254219Scy int table; 622254219Scy{ 623254219Scy switch (table) 624254219Scy { 625254219Scy case SMC_NAT : 626254219Scy printf(" table:NAT"); 627254219Scy break; 628254219Scy case SMC_STATE : 629254219Scy printf(" table:STATE"); 630254219Scy break; 631254219Scy default : 632254219Scy printf(" table:Unknown(%d)", table); 633254219Scy break; 634254219Scy } 635254219Scy} 636254219Scy 637254219Scy 638254219Scyvoid 639254219Scyprintsmcproto(buff) 640254219Scy char *buff; 641254219Scy{ 642254219Scy syncupdent_t *su; 643254219Scy synchdr_t *sh; 644254219Scy 645254219Scy sh = (synchdr_t *)buff; 646254219Scy 647254219Scy if (sh->sm_cmd == SMC_CREATE) { 648254219Scy ; 649254219Scy 650254219Scy } else if (sh->sm_cmd == SMC_UPDATE) { 651254219Scy su = (syncupdent_t *)buff; 652254219Scy if (sh->sm_p == IPPROTO_TCP) { 653254219Scy printf(" TCP Update: age %lu state %d/%d\n", 654254219Scy su->sup_tcp.stu_age, 655254219Scy su->sup_tcp.stu_state[0], 656254219Scy su->sup_tcp.stu_state[1]); 657254219Scy } 658254219Scy } else { 659254219Scy printf("Unknown command\n"); 660254219Scy } 661254219Scy} 662254219Scy 663254219Scy 664254219Scyvoid 665254219Scyprintsynchdr(sh) 666254219Scy synchdr_t *sh; 667254219Scy{ 668254219Scy 669254219Scy printf("v:%d p:%d num:%d len:%d magic:%x", sh->sm_v, sh->sm_p, 670254219Scy ntohl(sh->sm_num), ntohl(sh->sm_len), ntohl(sh->sm_magic)); 671254219Scy} 672