TMXR: Add Access Control List (ACL) support for incoming network connections

This commit is contained in:
Mark Pizzolato 2022-02-04 07:59:08 -08:00
parent 10e561767f
commit 35503f4765
4 changed files with 226 additions and 81 deletions

Binary file not shown.

View file

@ -1898,8 +1898,16 @@ static t_stat sim_set_rem_telnet (int32 flag, CONST char *cptr)
t_stat r; t_stat r;
if (flag) { if (flag) {
r = sim_parse_addr (cptr, NULL, 0, NULL, NULL, 0, NULL, NULL); char gbuf[CBUFSIZE];
char *cp;
strlcpy (gbuf, cptr, sizeof (gbuf));
if ((cp = strchr (gbuf, ';')))
*cp = '\0';
r = sim_parse_addr (gbuf, NULL, 0, NULL, NULL, 0, NULL, NULL);
if (r == SCPE_OK) { if (r == SCPE_OK) {
if (cp != NULL)
*cp = ';';
if (sim_rem_con_tmxr.master) /* already open? */ if (sim_rem_con_tmxr.master) /* already open? */
sim_set_rem_telnet (0, NULL); /* close first */ sim_set_rem_telnet (0, NULL); /* close first */
if (sim_rem_con_tmxr.lines == 0) /* if no connection limit set */ if (sim_rem_con_tmxr.lines == 0) /* if no connection limit set */
@ -2473,6 +2481,8 @@ while (*cptr != 0) { /* do all mods */
return r; return r;
} }
else { else {
if (cvptr) /* if we removed a = sign */
*(--cvptr) = '='; /* restore it */
if (sim_con_tmxr.master) /* already open? */ if (sim_con_tmxr.master) /* already open? */
sim_set_notelnet (0, NULL); /* close first */ sim_set_notelnet (0, NULL); /* close first */
r = tmxr_attach (&sim_con_tmxr, &sim_con_unit, gbuf);/* open master socket */ r = tmxr_attach (&sim_con_tmxr, &sim_con_unit, gbuf);/* open master socket */

View file

@ -916,11 +916,21 @@ tptr = (char *) calloc (1, 1);
if (tptr == NULL) /* no more mem? */ if (tptr == NULL) /* no more mem? */
return tptr; return tptr;
if (mp->port) /* copy port */ if (mp->port) { /* copy port */
sprintf (growstring(&tptr, 33 + strlen (mp->port)), "%s%s", mp->port, sprintf (growstring(&tptr, 33 + strlen (mp->port)), "%s%s", mp->port,
mp->notelnet ? ";notelnet" : mp->notelnet ? ";notelnet" :
(mp->nomessage ? ";nomessage" : (mp->nomessage ? ";nomessage" :
"")); ""));
if (mp->acl) { /* copy acl in pieces */
char gbuf[CBUFSIZE];
const char *c = mp->acl;
while (*c != '\0') {
c = get_glyph_nc (c, gbuf, ',');
sprintf (growstring(&tptr, 9 + strlen (gbuf)), ";%s=%s", (gbuf[0] == '+') ? "Accept" : "Reject", gbuf + 1);
}
}
}
if (mp->logfiletmpl[0]) /* logfile info */ if (mp->logfiletmpl[0]) /* logfile info */
sprintf (growstring(&tptr, 7 + strlen (mp->logfiletmpl)), ",Log=%s", mp->logfiletmpl); sprintf (growstring(&tptr, 7 + strlen (mp->logfiletmpl)), ",Log=%s", mp->logfiletmpl);
if (mp->buffered) if (mp->buffered)
@ -989,10 +999,20 @@ if (lp->destination || lp->port || lp->txlogname || (lp->conn == TMXR_LINE_DISAB
sprintf (growstring(&tptr, 8), ",%s", lp->datagram ? "UDP" : "TCP"); sprintf (growstring(&tptr, 8), ",%s", lp->datagram ? "UDP" : "TCP");
if (lp->mp->packet != lp->packet) if (lp->mp->packet != lp->packet)
sprintf (growstring(&tptr, 8), ",Packet"); sprintf (growstring(&tptr, 8), ",Packet");
if (lp->port) if (lp->port) {
sprintf (growstring(&tptr, 32 + strlen (lp->port)), ",%s%s%s", lp->port, sprintf (growstring(&tptr, 32 + strlen (lp->port)), ",%s%s%s", lp->port,
((lp->mp->notelnet != lp->notelnet) && (!lp->datagram)) ? (lp->notelnet ? ";notelnet" : ";telnet") : "", ((lp->mp->notelnet != lp->notelnet) && (!lp->datagram)) ? (lp->notelnet ? ";notelnet" : ";telnet") : "",
((lp->mp->nomessage != lp->nomessage) && (!lp->datagram)) ? (lp->nomessage ? ";nomessage" : ";message") : ""); ((lp->mp->nomessage != lp->nomessage) && (!lp->datagram)) ? (lp->nomessage ? ";nomessage" : ";message") : "");
if (lp->acl) { /* copy acl in pieces */
char gbuf[CBUFSIZE];
const char *c = lp->acl;
while (*c != '\0') {
c = get_glyph_nc (c, gbuf, ',');
sprintf (growstring(&tptr, 9 + strlen (gbuf)), ";%s=%s", (gbuf[0] == '+') ? "Accept" : "Reject", gbuf + 1);
}
}
}
if (lp->destination) { if (lp->destination) {
if (lp->serport) { if (lp->serport) {
char portname[CBUFSIZE]; char portname[CBUFSIZE];
@ -1120,6 +1140,17 @@ if (mp->master) {
i = mp->lines; /* play it safe in case lines == 0 */ i = mp->lines; /* play it safe in case lines == 0 */
++mp->sessions; /* count the new session */ ++mp->sessions; /* count the new session */
if (mp->acl) {
if (sim_addr_acl_check (address, mp->acl) != 0) {
tmxr_debug_connect (mp, "tmxr_poll_conn() - Connection Specifically rejected by ACL");
sim_close_sock (newsock);
free (address);
++mp->acl_rejected_sessions;
}
else
++mp->acl_accepted_sessions;
}
else {
for (j = 0; j < mp->lines; j++, i++) { /* find next avail line */ for (j = 0; j < mp->lines; j++, i++) { /* find next avail line */
if (op && (*op >= 0) && (*op < mp->lines)) /* order list present and valid? */ if (op && (*op >= 0) && (*op < mp->lines)) /* order list present and valid? */
i = *op++; /* get next line in list to try */ i = *op++; /* get next line in list to try */
@ -1208,6 +1239,7 @@ if (mp->master) {
lp->cnms = sim_os_msec (); /* time of connection */ lp->cnms = sim_os_msec (); /* time of connection */
return i; return i;
} }
}
} /* end if newsock */ } /* end if newsock */
} }
@ -1296,6 +1328,18 @@ for (i = 0; i < mp->lines; i++) { /* check each line in se
free (peername); free (peername);
++mp->sessions; /* count the new session */ ++mp->sessions; /* count the new session */
if (lp->acl) { /* Restrict connection with ACL rules? */
if (sim_addr_acl_check (address, lp->acl) != 0) {
snprintf (msg, sizeof (msg) -1, "tmxr_poll_conn() - ACL Rejecting line connection from: %s", address);
tmxr_debug_connect_line (lp, msg);
sim_close_sock (newsock);
free (address);
++lp->acl_rejected_sessions;
continue; /* Go back for another connection */
}
else
++lp->acl_accepted_sessions;
}
if (lp->destination) { /* Virtual Null Modem Cable? */ if (lp->destination) { /* Virtual Null Modem Cable? */
char host[sizeof(msg) - 64]; char host[sizeof(msg) - 64];
@ -2858,7 +2902,8 @@ t_stat tmxr_open_master (TMXR *mp, CONST char *cptr)
int32 i, line, nextline = -1; int32 i, line, nextline = -1;
char tbuf[CBUFSIZE], listen[CBUFSIZE], destination[CBUFSIZE], char tbuf[CBUFSIZE], listen[CBUFSIZE], destination[CBUFSIZE],
logfiletmpl[CBUFSIZE], buffered[CBUFSIZE], hostport[CBUFSIZE], logfiletmpl[CBUFSIZE], buffered[CBUFSIZE], hostport[CBUFSIZE],
port[CBUFSIZE], option[CBUFSIZE], speed[CBUFSIZE], dev_name[CBUFSIZE]; port[CBUFSIZE], option[CBUFSIZE], speed[CBUFSIZE], dev_name[CBUFSIZE],
acl[CBUFSIZE];
char framer[CBUFSIZE],fr_eth[CBUFSIZE]; char framer[CBUFSIZE],fr_eth[CBUFSIZE];
int num; int num;
int8 fr_mode; int8 fr_mode;
@ -2896,6 +2941,7 @@ while (*tptr) {
memset(destination, '\0', sizeof(destination)); memset(destination, '\0', sizeof(destination));
memset(buffered, '\0', sizeof(buffered)); memset(buffered, '\0', sizeof(buffered));
memset(port, '\0', sizeof(port)); memset(port, '\0', sizeof(port));
memset(acl, '\0', sizeof(acl));
memset(option, '\0', sizeof(option)); memset(option, '\0', sizeof(option));
memset(speed, '\0', sizeof(speed)); memset(speed, '\0', sizeof(speed));
memset(framer, '\0', sizeof(framer)); memset(framer, '\0', sizeof(framer));
@ -3026,6 +3072,7 @@ while (*tptr) {
cptr = get_glyph (gbuf, port, ';'); cptr = get_glyph (gbuf, port, ';');
if (sim_parse_addr (port, NULL, 0, NULL, NULL, 0, NULL, NULL)) if (sim_parse_addr (port, NULL, 0, NULL, NULL, 0, NULL, NULL))
return sim_messagef (SCPE_ARG, "Invalid Port Specifier: %s\n", port); return sim_messagef (SCPE_ARG, "Invalid Port Specifier: %s\n", port);
memset (acl, '\0', sizeof (acl));
while (cptr && *cptr) { while (cptr && *cptr) {
char *tptr = gbuf + (cptr - gbuf); char *tptr = gbuf + (cptr - gbuf);
@ -3041,6 +3088,24 @@ while (*tptr) {
else else
if (0 == MATCH_CMD (tptr, "MESSAGE")) if (0 == MATCH_CMD (tptr, "MESSAGE"))
listennomessage = FALSE; listennomessage = FALSE;
else
if (0 == memcmp (option, "ACCEPT=", 7)) {
if (sim_addr_acl_check (option + 7, NULL))
return sim_messagef (SCPE_ARG, "Invalid Accept Criteria: %s\n", option + 7);
if (acl[0] != '\0')
strlcat (acl, ",", sizeof (acl));
strlcat (acl, "+", sizeof (acl)); /* Tag as Accept rule */
strlcat (acl, option + 7, sizeof (acl));
}
else
if (0 == memcmp (option, "REJECT=", 7)) {
if (sim_addr_acl_check (option + 7, NULL))
return sim_messagef (SCPE_ARG, "Invalid Reject Criteria: %s\n", option + 7);
if (acl[0] != '\0')
strlcat (acl, ",", sizeof (acl));
strlcat (acl, "-", sizeof (acl)); /* Tag as Reject rule */
strlcat (acl, option + 7, sizeof (acl));
}
else { else {
if (*tptr) if (*tptr)
return sim_messagef (SCPE_ARG, "Invalid Specifier: %s\n", tptr); return sim_messagef (SCPE_ARG, "Invalid Specifier: %s\n", tptr);
@ -3057,6 +3122,7 @@ while (*tptr) {
sim_close_sock (sock); sim_close_sock (sock);
sim_os_ms_sleep (2); /* let the close finish (required on some platforms) */ sim_os_ms_sleep (2); /* let the close finish (required on some platforms) */
strcpy (listen, port); strcpy (listen, port);
memset (acl, '\0', sizeof (acl));
cptr = get_glyph (cptr, option, ';'); cptr = get_glyph (cptr, option, ';');
while (option[0]) { while (option[0]) {
if (0 == MATCH_CMD (option, "NOTELNET")) if (0 == MATCH_CMD (option, "NOTELNET"))
@ -3070,6 +3136,24 @@ while (*tptr) {
else else
if (0 == MATCH_CMD (option, "MESSAGE")) if (0 == MATCH_CMD (option, "MESSAGE"))
listennomessage = FALSE; listennomessage = FALSE;
else
if (0 == memcmp (option, "ACCEPT=", 7)) {
if (sim_addr_acl_check (option + 7, NULL))
return sim_messagef (SCPE_ARG, "Invalid Accept Criteria: %s\n", option + 7);
if (acl[0] != '\0')
strlcat (acl, ",", sizeof (acl));
strlcat (acl, "+", sizeof (acl)); /* Tag as Accept rule */
strlcat (acl, option + 7, sizeof (acl));
}
else
if (0 == memcmp (option, "REJECT=", 7)) {
if (sim_addr_acl_check (option + 7, NULL))
return sim_messagef (SCPE_ARG, "Invalid Reject Criteria: %s\n", option + 7);
if (acl[0] != '\0')
strlcat (acl, ",", sizeof (acl));
strlcat (acl, "-", sizeof (acl)); /* Tag as Reject rule */
strlcat (acl, option + 7, sizeof (acl));
}
else else
return sim_messagef (SCPE_ARG, "Invalid Specifier: %s\n", option); return sim_messagef (SCPE_ARG, "Invalid Specifier: %s\n", option);
cptr = get_glyph (cptr, option, ';'); cptr = get_glyph (cptr, option, ';');
@ -3249,6 +3333,8 @@ while (*tptr) {
mp->ring_start_time = 0; mp->ring_start_time = 0;
mp->notelnet = listennotelnet; /* save desired telnet behavior flag */ mp->notelnet = listennotelnet; /* save desired telnet behavior flag */
mp->nomessage = listennomessage; /* save desired telnet behavior flag */ mp->nomessage = listennomessage; /* save desired telnet behavior flag */
if (acl[0])
mp->acl = strdup (acl); /* save specified access control list */
for (i = 0; i < mp->lines; i++) { /* initialize lines */ for (i = 0; i < mp->lines; i++) { /* initialize lines */
lp = mp->ldsc + i; lp = mp->ldsc + i;
lp->mp = mp; /* set the back pointer */ lp->mp = mp; /* set the back pointer */
@ -3463,6 +3549,8 @@ while (*tptr) {
lp->nomessage = listennomessage; lp->nomessage = listennomessage;
else else
lp->nomessage = mp->nomessage; lp->nomessage = mp->nomessage;
if (acl[0])
lp->acl = strdup (acl);
} }
if (destination[0]) { if (destination[0]) {
serport = sim_open_serial (destination, lp, &r); serport = sim_open_serial (destination, lp, &r);
@ -4455,6 +4543,10 @@ if (attach)
free (attach); free (attach);
tmxr_show_summ(st, NULL, 0, mp); tmxr_show_summ(st, NULL, 0, mp);
fprintf(st, ", sessions=%d", mp->sessions); fprintf(st, ", sessions=%d", mp->sessions);
if (mp->acl_accepted_sessions)
fprintf(st, ", accepted=%d", mp->acl_accepted_sessions);
if (mp->acl_rejected_sessions)
fprintf(st, ", rejected=%d", mp->acl_rejected_sessions);
if (mp->lines == 1) { if (mp->lines == 1) {
if (mp->ldsc->rxbps) { if (mp->ldsc->rxbps) {
fprintf(st, ", Speed=%d", mp->ldsc->rxbps); fprintf(st, ", Speed=%d", mp->ldsc->rxbps);
@ -4497,6 +4589,13 @@ for (j = 0; j < mp->lines; j++) {
if (lp->bpsfactor != 1.0) if (lp->bpsfactor != 1.0)
fprintf(st, ", Speed=*%.0f bps", lp->bpsfactor); fprintf(st, ", Speed=*%.0f bps", lp->bpsfactor);
} }
if (lp->sessions) {
fprintf(st, ", Sessions=%d", lp->sessions);
if (lp->acl_accepted_sessions)
fprintf(st, ", Accepted=%d", lp->acl_accepted_sessions);
if (lp->acl_rejected_sessions)
fprintf(st, ", Rejected=%d", lp->acl_rejected_sessions);
}
fprintf (st, "\n"); fprintf (st, "\n");
} }
if ((!lp->sock) && (!lp->connecting) && (!lp->serport) && (!lp->master)) { if ((!lp->sock) && (!lp->connecting) && (!lp->serport) && (!lp->master)) {
@ -4584,6 +4683,8 @@ for (i = 0; i < mp->lines; i++) { /* loop thru conn */
} }
free (lp->destination); free (lp->destination);
lp->destination = NULL; lp->destination = NULL;
free (lp->acl);
lp->acl = NULL;
if (lp->connecting) { if (lp->connecting) {
lp->sock = lp->connecting; lp->sock = lp->connecting;
lp->connecting = 0; lp->connecting = 0;
@ -4845,6 +4946,15 @@ if (single_line) { /* Single Line Multiplexer */
} }
fprintf (st, "A Telnet listening port can be configured with:\n\n"); fprintf (st, "A Telnet listening port can be configured with:\n\n");
fprintf (st, " sim> ATTACH %s {interface:}port\n\n", dptr->name); fprintf (st, " sim> ATTACH %s {interface:}port\n\n", dptr->name);
fprintf (st, "Connections to the specified port, by default, will be unrestricted.\n");
fprintf (st, "Connections from particular IPv4 or IPv6 addresses can be restricted\n");
fprintf (st, "or allowed based on rules you can add to the \"{interface:}port\"\n");
fprintf (st, "specifier on the attach command. You can add as many rules as you need\n");
fprintf (st, "to the attach command specified with \";ACCEPT=rule-detail\" or\n");
fprintf (st, "\";REJECT=rule-detail\" where rule-detail can be an IP address, hostname\n");
fprintf (st, "or network block in CIDR form. Rules are interpreted in order and if,\n");
fprintf (st, "while processing the list, the end is reached the connection will be\n");
fprintf (st, "rejected.\n\n");
fprintf (st, "The -U switch can be specified on the attach command that specifies\n"); fprintf (st, "The -U switch can be specified on the attach command that specifies\n");
fprintf (st, "a listening port. This will allow a listening port to be reused if\n"); fprintf (st, "a listening port. This will allow a listening port to be reused if\n");
fprintf (st, "some prior connections haven't completely shutdown.\n\n"); fprintf (st, "some prior connections haven't completely shutdown.\n\n");
@ -5012,6 +5122,15 @@ else {
fprintf (st, "Line specific tcp listening ports are supported. These are configured\n"); fprintf (st, "Line specific tcp listening ports are supported. These are configured\n");
fprintf (st, "using commands of the form:\n\n"); fprintf (st, "using commands of the form:\n\n");
fprintf (st, " sim> ATTACH %s Line=n,{interface:}port{;notelnet}|{;nomessage}\n\n", dptr->name); fprintf (st, " sim> ATTACH %s Line=n,{interface:}port{;notelnet}|{;nomessage}\n\n", dptr->name);
fprintf (st, "Connections to the specified port, by default, will be unrestricted.\n");
fprintf (st, "Connections from particular IPv4 or IPv6 addresses can be restricted\n");
fprintf (st, "or allowed based on rules you can add to the \"{interface:}port\"\n");
fprintf (st, "specifier on the attach command. You can add as many rules as you need\n");
fprintf (st, "to the attach command specified with \";ACCEPT=rule-detail\" or\n");
fprintf (st, "\";REJECT=rule-detail\" where rule-detail can be an IP address, hostname\n");
fprintf (st, "or network block in CIDR form. Rules are interpreted in order and if,\n");
fprintf (st, "while processing the list, the end is reached the connection will be\n");
fprintf (st, "rejected.\n\n");
} }
fprintf (st, "Direct computer to computer connections (Virutal Null Modem cables) may\n"); fprintf (st, "Direct computer to computer connections (Virutal Null Modem cables) may\n");
fprintf (st, "be established using the telnet protocol or via raw tcp sockets.\n\n"); fprintf (st, "be established using the telnet protocol or via raw tcp sockets.\n\n");
@ -5194,8 +5313,11 @@ if (lp->sock) {
free (peername); free (peername);
} }
if ((lp->port) && (!lp->datagram)) if ((lp->port) && (!lp->datagram)) {
fprintf (st, "Listening on port %s\n", lp->port); /* print port name */ fprintf (st, "Listening on port %s\n", lp->port); /* print port name */
if (lp->acl)
fprintf (st, "Connections will be accepted/rejected based on: %s\n", lp->acl);
}
if (lp->serport) /* serial connection? */ if (lp->serport) /* serial connection? */
fprintf (st, "Connected to serial port %s\n", lp->destination); /* print port name */ fprintf (st, "Connected to serial port %s\n", lp->destination); /* print port name */
@ -6036,6 +6158,13 @@ SIM_TEST(sim_parse_addr ("", NULL, 0, "localhost", NULL, 0, "1234", NULL) != -1)
SIM_TEST(sim_parse_addr ("", host, 0, "localhost", NULL, 0, "1234", NULL) != -1); SIM_TEST(sim_parse_addr ("", host, 0, "localhost", NULL, 0, "1234", NULL) != -1);
SIM_TEST(sim_parse_addr ("", host, sizeof(host), "localhost", port, 0, "1234", NULL) != -1); SIM_TEST(sim_parse_addr ("", host, sizeof(host), "localhost", port, 0, "1234", NULL) != -1);
SIM_TEST((sim_parse_addr ("", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"1234"))); SIM_TEST((sim_parse_addr ("", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"1234")));
SIM_TEST(sim_addr_acl_check ("127.0.0.1", NULL) == -1);
SIM_TEST(sim_addr_acl_check ("127.0.0.1/0", NULL) != -1);
SIM_TEST(sim_addr_acl_check ("127.0.0.1/32", NULL) == -1);
SIM_TEST(sim_addr_acl_check ("127.0.0.1/64", NULL) != -1);
SIM_TEST(sim_addr_acl_check ("127.0.0.6", "+127.0.0.1/32,-127.0.0.2") != -1);
SIM_TEST(sim_addr_acl_check ("127.0.0.2", "+127.0.0.1,-127.0.0.2/32,+127.0.0.3") != -1);
SIM_TEST(sim_parse_addr ("", host, sizeof(host), "localhost", port, sizeof(port), "1234", "127.0.0.1") == -1);
SIM_TEST((sim_parse_addr ("localhost:6666", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"6666"))); SIM_TEST((sim_parse_addr ("localhost:6666", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"6666")));
SIM_TEST(sim_parse_addr ("localhost:66666", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) != -1); SIM_TEST(sim_parse_addr ("localhost:66666", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) != -1);
SIM_TEST((sim_parse_addr ("localhost:telnet", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"telnet"))); SIM_TEST((sim_parse_addr ("localhost:telnet", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"telnet")));

View file

@ -141,6 +141,9 @@ struct tmln {
char *ipad; /* IP address */ char *ipad; /* IP address */
SOCKET master; /* line specific master socket */ SOCKET master; /* line specific master socket */
char *port; /* line specific listening port */ char *port; /* line specific listening port */
char *acl; /* Access control list (CIDR) to accept or reject connects from */
int32 acl_accepted_sessions; /* count of ACL accepted tcp connections */
int32 acl_rejected_sessions; /* count of ACL rejected tcp connections */
int32 sessions; /* count of tcp connections received */ int32 sessions; /* count of tcp connections received */
uint32 cnms; /* conn time */ uint32 cnms; /* conn time */
int32 tsta; /* Telnet state */ int32 tsta; /* Telnet state */
@ -218,6 +221,9 @@ struct tmxr {
TMLN *ldsc; /* line descriptors */ TMLN *ldsc; /* line descriptors */
int32 *lnorder; /* line connection order */ int32 *lnorder; /* line connection order */
DEVICE *dptr; /* multiplexer device */ DEVICE *dptr; /* multiplexer device */
char *acl; /* Access control list (CIDR) to accept or reject connects from */
int32 acl_accepted_sessions; /* count of ACL accepted tcp connections */
int32 acl_rejected_sessions; /* count of ACL rejected tcp connections */
UNIT *uptr; /* polling unit (connection) */ UNIT *uptr; /* polling unit (connection) */
char logfiletmpl[FILENAME_MAX]; /* template logfile name */ char logfiletmpl[FILENAME_MAX]; /* template logfile name */
int32 txcount; /* count of transmit bytes */ int32 txcount; /* count of transmit bytes */