diff --git a/packet.cpp b/packet.cpp index cc6f922..25caefc 100644 --- a/packet.cpp +++ b/packet.cpp @@ -126,15 +126,17 @@ Packet * getPacket (const struct pcap_pkthdr * header, const u_char * packet) return new Packet (ip->ip_src, ntohs(tcp->th_sport), ip->ip_dst, ntohs(tcp->th_dport), header->len, header->ts); } -Packet::Packet (in_addr m_sip, unsigned short m_sport, in_addr m_dip, unsigned short m_dport, bpf_u_int32 m_len, timeval m_time) +Packet::Packet (in_addr m_sip, unsigned short m_sport, in_addr m_dip, unsigned short m_dport, bpf_u_int32 m_len, timeval m_time, direction m_dir) { sip = m_sip; sport = m_sport; dip = m_dip; dport = m_dport; len = m_len; time = m_time; + dir = m_dir; } Packet * Packet::newInverted () { - return new Packet (dip, dport, sip, sport, len, time); + /* TODO if this is a bottleneck, we can calculate the direction */ + return new Packet (dip, dport, sip, sport, len, time, dir_unknown); } /* constructs returns a new Packet() structure with the same contents as this one */ @@ -158,15 +160,35 @@ bool Packet::Outgoing () { if (DEBUG) assert (local_addrs != NULL); - return (local_addrs->contains(sip.s_addr)); + switch (dir) { + case dir_outgoing: + return true; + case dir_incoming: + return false; + case dir_unknown: + if (local_addrs->contains(sip.s_addr)) { + dir = dir_outgoing; + return true; + } else { + dir = dir_incoming; + return false; + } + } } +/* returns the packet in '1.2.3.4:5-1.2.3.4:5'-form, for use in the 'conninode' table */ +/* '1.2.3.4' should be the local address. */ char * Packet::gethashstring () { // TODO this needs to be bigger to support ipv6?! char * retval = (char *) malloc (92 * sizeof(char)); - snprintf(retval, 92 * sizeof(char), "%s:%d-", inet_ntoa(sip), sport); - snprintf(retval, 92 * sizeof(char), "%s%s:%d", retval, inet_ntoa(dip), dport); + if (Outgoing()) { + snprintf(retval, 92 * sizeof(char), "%s:%d-", inet_ntoa(sip), sport); + snprintf(retval, 92 * sizeof(char), "%s%s:%d", retval, inet_ntoa(dip), dport); + } else { + snprintf(retval, 92 * sizeof(char), "%s:%d-", inet_ntoa(dip), dport); + snprintf(retval, 92 * sizeof(char), "%s%s:%d", retval, inet_ntoa(sip), sport); + } //if (DEBUG) //cout << "hasshtring: " << retval << endl; return retval; diff --git a/packet.h b/packet.h index 6a39b83..375b323 100644 --- a/packet.h +++ b/packet.h @@ -13,6 +13,12 @@ extern "C" #include } +enum direction { + dir_unknown, + dir_incoming, + dir_outgoing +}; + /* To initialise this module, call getLocal with the currently * monitored device (e.g. "eth0:1") */ void getLocal (const char *device); @@ -27,7 +33,7 @@ public: bpf_u_int32 len; timeval time; - Packet (in_addr m_sip, unsigned short m_sport, in_addr m_dip, unsigned short m_dport, bpf_u_int32 m_len, timeval m_time); + Packet (in_addr m_sip, unsigned short m_sport, in_addr m_dip, unsigned short m_dport, bpf_u_int32 m_len, timeval m_time, direction dir = dir_unknown); /* using default copy constructor */ /* Packet (const Packet &old_packet); */ /* copy constructor that turns the packet around */ @@ -40,6 +46,8 @@ public: bool match (Packet * other); /* returns '1.2.3.4:5-1.2.3.4:6'-style string */ char * gethashstring(); +private: + direction dir; }; Packet * getPacket (const struct pcap_pkthdr * header, const u_char * packet); diff --git a/process.cpp b/process.cpp index 011ac34..1d5f413 100644 --- a/process.cpp +++ b/process.cpp @@ -18,17 +18,6 @@ extern timeval curtime; extern std::string * caption; -/*struct aftype inet6_aftype = -{ - "inet6", NULL, AF_INET6, sizeof(struct in6_addr), - INET6_print, INET6_sprint, INET6_input, INET6_reserror, - INET6_rprint, INET6_rinput, NULL, - - -1, - "/proc/net/if_inet6" -};*/ - - static int INET6_getsock(char *bufp, struct sockaddr *sap) { struct sockaddr_in6 *sin6; @@ -73,7 +62,14 @@ struct aftype { */ HashTable * conninode = new HashTable (256); -// TODO check what happens to the 'content' field of the hash!! +/* + * parses a /proc/net/tcp-line of the form: + * sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode + * 10: 020310AC:1770 9DD8A9C3:A525 01 00000000:00000000 00:00000000 00000000 0 0 2119 1 c0f4f0c0 206 40 10 3 -1 + * 11: 020310AC:0404 936B2ECF:0747 01 00000000:00000000 00:00000000 00000000 1000 0 2109 1 c0f4fc00 368 40 20 2 -1 + * + */ +// TODO check what happens to the 'content' field of the hash void addtoconninode (char * buffer) { char rem_addr[128], local_addr[128]; @@ -112,6 +108,107 @@ void addtoconninode (char * buffer) ((struct sockaddr *) &remaddr)->sa_family = AF_INET; } + /* Construct hash key and add inode to conninode table */ + char * hashkey = (char *) malloc (92 * sizeof(char)); + snprintf(hashkey, 92 * sizeof(char), "%s:%d-", inet_ntoa(((struct sockaddr_in *)&localaddr)->sin_addr), local_port); + snprintf(hashkey, 92 * sizeof(char), "%s%s:%d", hashkey, inet_ntoa(((struct sockaddr_in *)&remaddr)->sin_addr), rem_port); + conninode->add(hashkey, (void *)inode); + + // TODO maybe also add this inode for our other local addresses with that destination + + return; + + /* + * OLD CODE BELOW - dead now. + * + * + if (strcmp(inet_ntoa(((struct sockaddr_in *)&localaddr)->sin_addr), "172.16.3.1") == 0) + { + hashkey = (char *) malloc (92 * sizeof(char)); + snprintf(hashkey, 92 * sizeof(char), "%s:%d-", "195.169.216.157", local_port); + snprintf(hashkey, 92 * sizeof(char), "%s%s:%d", hashkey, inet_ntoa(((struct sockaddr_in *)&remaddr)->sin_addr), rem_port); + conninode->add(hashkey, (void *)inode); + } + if (strcmp(inet_ntoa(((struct sockaddr_in *)&remaddr)->sin_addr), "172.16.3.1") == 0) + { + hashkey = (char *) malloc (92 * sizeof(char)); + snprintf(hashkey, 92 * sizeof(char), "%s:%d-", inet_ntoa(((struct sockaddr_in *)&localaddr)->sin_addr), local_port); + snprintf(hashkey, 92 * sizeof(char), "%s%s:%d", hashkey, "195.169.216.157", rem_port); + conninode->add(hashkey, (void *)inode); + } + if (strcmp(inet_ntoa(((struct sockaddr_in *)&localaddr)->sin_addr), "195.169.216.157") == 0) + { + hashkey = (char *) malloc (92 * sizeof(char)); + snprintf(hashkey, 92 * sizeof(char), "%s:%d-", "172.16.3.1", local_port); + snprintf(hashkey, 92 * sizeof(char), "%s%s:%d", hashkey, inet_ntoa(((struct sockaddr_in *)&remaddr)->sin_addr), rem_port); + conninode->add(hashkey, (void *)inode); + + hashkey = (char *) malloc (92 * sizeof(char)); + snprintf(hashkey, 92 * sizeof(char), "%s:%d-", inet_ntoa(((struct sockaddr_in *)&remaddr)->sin_addr), rem_port); + snprintf(hashkey, 92 * sizeof(char), "%s%s:%d", hashkey, "172.16.3.1", local_port); + conninode->add(hashkey, (void *)inode); + } + if (strcmp(inet_ntoa(((struct sockaddr_in *)&remaddr)->sin_addr), "195.169.216.157") == 0) + { + hashkey = (char *) malloc (92 * sizeof(char)); + snprintf(hashkey, 92 * sizeof(char), "%s:%d-", inet_ntoa(((struct sockaddr_in *)&localaddr)->sin_addr), local_port); + snprintf(hashkey, 92 * sizeof(char), "%s%s:%d", hashkey, "172.16.3.1", rem_port); + conninode->add(hashkey, (void *)inode); + + hashkey = (char *) malloc (92 * sizeof(char)); + snprintf(hashkey, 92 * sizeof(char), "%s:%d-", "172.16.3.1", rem_port); + snprintf(hashkey, 92 * sizeof(char), "%s%s:%d", hashkey, inet_ntoa(((struct sockaddr_in *)&localaddr)->sin_addr), local_port); + conninode->add(hashkey, (void *)inode); + } + */ +} + +/* + * parses a /proc/net/tcp6-line of the form: + * sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode + * 2: 0000000000000000FFFF0000020310AC:0016 0000000000000000FFFF00009DD8A9C3:A526 01 00000000:00000000 02:000A7214 00000000 0 0 2525 2 c732eca0 201 40 1 2 -1 + * + */ +void addtoconninodev6 (char * buffer) +{ + /* TODO implement */ + + char rem_addr[128], local_addr[128]; + int local_port, rem_port; + struct sockaddr_in6 localaddr, remaddr; + char addr6[INET6_ADDRSTRLEN]; + struct in6_addr in6; + extern struct aftype inet6_aftype; + // the following line leaks memory. + unsigned long * inode = (unsigned long *) malloc (sizeof(unsigned long)); + // TODO check it matched + sscanf(buffer, "%*d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X %*lX:%*lX %*X:%*lX %*lX %*d %*d %ld %*512s\n", + local_addr, &local_port, rem_addr, &rem_port, inode); + + if (strlen(local_addr) > 8) + { + /* Demangle what the kernel gives us */ + sscanf(local_addr, "%08X%08X%08X%08X", + &in6.s6_addr32[0], &in6.s6_addr32[1], + &in6.s6_addr32[2], &in6.s6_addr32[3]); + inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6)); + INET6_getsock(addr6, (struct sockaddr *) &localaddr); + sscanf(rem_addr, "%08X%08X%08X%08X", + &in6.s6_addr32[0], &in6.s6_addr32[1], + &in6.s6_addr32[2], &in6.s6_addr32[3]); + inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6)); + INET6_getsock(addr6, (struct sockaddr *) &remaddr); + localaddr.sin6_family = AF_INET6; + remaddr.sin6_family = AF_INET6; + } + else + { + sscanf(local_addr, "%X", &((struct sockaddr_in *)&localaddr)->sin_addr.s_addr); + sscanf(rem_addr, "%X", &((struct sockaddr_in *)&remaddr)->sin_addr.s_addr); + ((struct sockaddr *) &localaddr)->sa_family = AF_INET; + ((struct sockaddr *) &remaddr)->sa_family = AF_INET; + } + char * hashkey = (char *) malloc (92 * sizeof(char)); snprintf(hashkey, 92 * sizeof(char), "%s:%d-", inet_ntoa(((struct sockaddr_in *)&localaddr)->sin_addr), local_port); snprintf(hashkey, 92 * sizeof(char), "%s%s:%d", hashkey, inet_ntoa(((struct sockaddr_in *)&remaddr)->sin_addr), rem_port); @@ -202,7 +299,7 @@ void refreshconninode () fgets(buffer, sizeof(buffer), procinfo); do { if (fgets(buffer, sizeof(buffer), procinfo)) - addtoconninode(buffer); + addtoconninodev6(buffer); } while (!feof(procinfo)); fclose (procinfo); }