static void AnalyzeArrival(Item *ip_addresses, long iteration, char *arrival, double *cf_this) { char src[CF_BUFSIZE], dest[CF_BUFSIZE], flag = '.', *arr; int isme_dest, isme_src; src[0] = dest[0] = '\0'; if (strstr(arrival, "listening")) { return; } if (Chop(arrival, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } /* Most hosts have only a few dominant services, so anomalies will show up even in the traffic without looking too closely. This will apply only to the main interface .. not multifaces New format in tcpdump IP (tos 0x10, ttl 64, id 14587, offset 0, flags [DF], proto TCP (6), length 692) 128.39.89.232.22 > 84.215.40.125.48022: P 1546432:1547072(640) ack 1969 win 1593 <nop,nop,timestamp 25662737 1631360> IP (tos 0x0, ttl 251, id 14109, offset 0, flags [DF], proto UDP (17), length 115) 84.208.20.110.53 > 192.168.1.103.32769: 45266 NXDomain 0/1/0 (87) arp who-has 192.168.1.1 tell 192.168.1.103 arp reply 192.168.1.1 is-at 00:1d:7e:28:22:c6 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84) 192.168.1.103 > 128.39.89.10: ICMP echo request, id 48474, seq 1, length 64 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84) 192.168.1.103 > 128.39.89.10: ICMP echo request, id 48474, seq 2, length 64 */ for (arr = strstr(arrival, "length"); (arr != NULL) && (*arr != ')'); arr++) { } if (arr == NULL) { arr = arrival; } else { arr++; } if ((strstr(arrival, "proto TCP")) || (strstr(arrival, "ack"))) { sscanf(arr, "%s %*c %s %c ", src, dest, &flag); DePort(src); DePort(dest); isme_dest = IsInterfaceAddress(ip_addresses, dest); isme_src = IsInterfaceAddress(ip_addresses, src); switch (flag) { case 'S': Log(LOG_LEVEL_DEBUG, "%ld: TCP new connection from '%s' to '%s' - i am '%s'", iteration, src, dest, VIPADDRESS); if (isme_dest) { cf_this[ob_tcpsyn_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_TCP_SYN]), src); } else if (isme_src) { cf_this[ob_tcpsyn_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_TCP_SYN]), dest); } break; case 'F': Log(LOG_LEVEL_DEBUG, "%ld: TCP end connection from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_tcpfin_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_TCP_FIN]), src); } else if (isme_src) { cf_this[ob_tcpfin_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_TCP_FIN]), dest); } break; default: Log(LOG_LEVEL_DEBUG, "%ld: TCP established from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_tcpack_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_TCP_ACK]), src); } else if (isme_src) { cf_this[ob_tcpack_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_TCP_ACK]), dest); } break; } } else if (strstr(arrival, ".53")) { sscanf(arr, "%s %*c %s %c ", src, dest, &flag); DePort(src); DePort(dest); isme_dest = IsInterfaceAddress(ip_addresses, dest); isme_src = IsInterfaceAddress(ip_addresses, src); Log(LOG_LEVEL_DEBUG, "%ld: DNS packet from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_dns_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_DNS]), src); } else if (isme_src) { cf_this[ob_dns_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_TCP_ACK]), dest); } } else if (strstr(arrival, "proto UDP")) { sscanf(arr, "%s %*c %s %c ", src, dest, &flag); DePort(src); DePort(dest); isme_dest = IsInterfaceAddress(ip_addresses, dest); isme_src = IsInterfaceAddress(ip_addresses, src); Log(LOG_LEVEL_DEBUG, "%ld: UDP packet from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_udp_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_UDP]), src); } else if (isme_src) { cf_this[ob_udp_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_UDP]), dest); } } else if (strstr(arrival, "proto ICMP")) { sscanf(arr, "%s %*c %s %c ", src, dest, &flag); DePort(src); DePort(dest); isme_dest = IsInterfaceAddress(ip_addresses, dest); isme_src = IsInterfaceAddress(ip_addresses, src); Log(LOG_LEVEL_DEBUG, "%ld: ICMP packet from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_icmp_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_ICMP]), src); } else if (isme_src) { cf_this[ob_icmp_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_ICMP]), src); } } else { Log(LOG_LEVEL_DEBUG, "%ld: Miscellaneous undirected packet (%.100s)", iteration, arrival); cf_this[ob_tcpmisc_in]++; /* Here we don't know what source will be, but .... */ sscanf(arrival, "%s", src); if (!isdigit((int) *src)) { Log(LOG_LEVEL_DEBUG, "Assuming continuation line..."); return; } DePort(src); if (strstr(arrival, ".138")) { snprintf(dest, CF_BUFSIZE - 1, "%s NETBIOS", src); } else if (strstr(arrival, ".2049")) { snprintf(dest, CF_BUFSIZE - 1, "%s NFS", src); } else { strncpy(dest, src, 60); dest[60] = '\0'; } IncrementCounter(&(NETIN_DIST[IP_TYPES_TCP_MISC]), dest); } }
static void ShowState(char *type) { struct stat statbuf; char buffer[CF_BUFSIZE], vbuff[CF_BUFSIZE], assemble[CF_BUFSIZE]; Item *addresses = NULL, *saddresses = NULL, *ip; int i = 0, tot = 0, min_signal_diversity = 1, conns = 1; int maxlen = 0, count; double *dist = NULL, S = 0.0; char *offset = NULL; FILE *fp; CfDebug("ShowState(%s)\n", type); snprintf(buffer, CF_BUFSIZE - 1, "%s/state/cf_%s", CFWORKDIR, type); if (cfstat(buffer, &statbuf) == 0) { if ((fp = fopen(buffer, "r")) == NULL) { CfOut(cf_inform, "fopen", "Could not open state memory %s\n", buffer); return; } while (!feof(fp)) { char local[CF_BUFSIZE], remote[CF_BUFSIZE]; buffer[0] = local[0] = remote[0] = '\0'; memset(vbuff, 0, CF_BUFSIZE); fgets(buffer, CF_BUFSIZE, fp); if (strlen(buffer) > 0) { CfOut(cf_verbose, "", "(%2d) %s", conns, buffer); if (IsSocketType(type)) { if (strncmp(type, "incoming", 8) == 0 || strncmp(type, "outgoing", 8) == 0) { if (strncmp(buffer, "tcp", 3) == 0) { sscanf(buffer, "%*s %*s %*s %s %s", local, remote); /* linux-like */ } else { sscanf(buffer, "%s %s", local, remote); /* solaris-like */ } strncpy(vbuff, remote, CF_BUFSIZE - 1); DePort(vbuff); } } else if (IsTCPType(type)) { count = 1; sscanf(buffer, "%d %[^\n]", &count, remote); AppendItem(&addresses, remote, ""); SetItemListCounter(addresses, remote, count); conns += count; continue; } else { /* If we get here this is a process thing */ if (offset == NULL) { if ((offset = strstr(buffer, "CMD"))) { } else if ((offset = strstr(buffer, "COMMAND"))) { } if (offset == NULL) { continue; } } strncpy(vbuff, offset, CF_BUFSIZE - 1); Chop(vbuff); } if (!IsItemIn(addresses, vbuff)) { conns++; AppendItem(&addresses, vbuff, ""); IncrementItemListCounter(addresses, vbuff); } else { conns++; IncrementItemListCounter(addresses, vbuff); } } } fclose(fp); conns--; CfOut(cf_error, "", "\n"); CfOut(cf_error, "", "R: The peak measured state was q = %d:\n", conns); if (IsSocketType(type) || IsTCPType(type)) { for (ip = addresses; ip != NULL; ip = ip->next) { tot += ip->counter; buffer[0] = '\0'; sscanf(ip->name, "%s", buffer); if (!IsIPV4Address(buffer) && !IsIPV6Address(buffer)) { CfOut(cf_verbose, "", "Rejecting address %s\n", ip->name); continue; } CfOut(cf_error, "", "R: DNS key: %s = %s (%d/%d)\n", buffer, IPString2Hostname(buffer), ip->counter, conns); if (strlen(ip->name) > maxlen) { maxlen = strlen(ip->name); } } if (addresses != NULL) { printf("R: -\n"); } } else { for (ip = addresses; ip != NULL; ip = ip->next) { tot += ip->counter; } } addresses = SortItemListCounters(addresses); saddresses = addresses; for (ip = saddresses; ip != NULL; ip = ip->next) { int s; if (maxlen > 17) /* ipv6 */ { snprintf(assemble, CF_BUFSIZE, "Frequency: %-40s|", ip->name); } else { snprintf(assemble, CF_BUFSIZE, "Frequency: %-17s|", ip->name); } for (s = 0; (s < ip->counter) && (s < 50); s++) { if (s < 48) { strcat(assemble, "*"); } else { strcat(assemble, "+"); } } CfOut(cf_error, "", "R: %s \t(%d/%d)\n", assemble, ip->counter, conns); } dist = xmalloc((tot + 1) * sizeof(double)); if (conns > min_signal_diversity) { for (i = 0, ip = addresses; ip != NULL; i++, ip = ip->next) { dist[i] = ((double) (ip->counter)) / ((double) tot); S -= dist[i] * log(dist[i]); } CfOut(cf_error, "", "R: Variability/entropy of addresses = %.1f %%\n", S / log((double) tot) * 100.0); CfOut(cf_error, "", "R: (Entropy = 0 for single source, 100 for flatly distributed source)\n -\n"); } CfOut(cf_error, "", "\n"); CfOut(cf_error, "", "R: State of %s peaked at %s\n", type, cf_ctime(&statbuf.st_mtime)); } else { CfOut(cf_inform, "", "R: State parameter %s is not known or recorded\n", type); } DeleteItemList(addresses); if (dist) { free((char *) dist); } }