224
u_short clientPort, serverPort;
226
int sport_idx = mapGlobalToLocalIdx(sport);
227
int dport_idx = mapGlobalToLocalIdx(dport);
229
/* Now let's update the list of ports recently used by the hosts */
230
if((sport > dport) || broadcastHost(dstHost)) {
231
clientPort = sport, serverPort = dport;
233
if(sport_idx == -1) addPortToList(srcHost, srcHost->otherIpPortsSent, sport);
234
if(dport_idx == -1) addPortToList(dstHost, dstHost->otherIpPortsRcvd, dport);
236
if(srcHost != myGlobals.otherHostEntry)
237
updatePortList(srcHost, clientPort, -1);
238
if(dstHost != myGlobals.otherHostEntry)
239
updatePortList(dstHost, -1, serverPort);
241
clientPort = dport, serverPort = sport;
243
if(srcHost != myGlobals.otherHostEntry)
244
updatePortList(srcHost, -1, serverPort);
245
if(dstHost != myGlobals.otherHostEntry)
246
updatePortList(dstHost, clientPort, -1);
249
/* **************** */
251
if(/* (srcHost == dstHost) || */
252
broadcastHost(srcHost) || broadcastHost(dstHost))
255
if(sport < MAX_ASSIGNED_IP_PORTS) {
256
ports = getPortsUsage(srcHost, sport, 1);
259
traceEvent(CONST_TRACE_INFO, "DEBUG: Adding svr peer %u", dstHost->hostTrafficBucket);
262
incrementTrafficCounter(&ports->serverTraffic, length);
263
ports->serverUses++, ports->serverUsesLastPeer = dstHost->hostSerial;
265
ports = getPortsUsage(dstHost, sport, 1);
268
traceEvent(CONST_TRACE_INFO, "DEBUG: Adding client peer %u", dstHost->hostTrafficBucket);
271
incrementTrafficCounter(&ports->clientTraffic, length);
272
ports->clientUses++, ports->clientUsesLastPeer = srcHost->hostSerial;
275
if(dport < MAX_ASSIGNED_IP_PORTS) {
276
ports = getPortsUsage(srcHost, dport, 1);
279
traceEvent(CONST_TRACE_INFO, "DEBUG: Adding client peer %u", dstHost->hostTrafficBucket);
282
incrementTrafficCounter(&ports->clientTraffic, length);
283
ports->clientUses++, ports->clientUsesLastPeer = dstHost->hostSerial;
285
ports = getPortsUsage(dstHost, dport, 1);
288
traceEvent(CONST_TRACE_INFO, "DEBUG: Adding svr peer %u", srcHost->hostTrafficBucket);
291
incrementTrafficCounter(&ports->serverTraffic, length);
292
ports->serverUses++, ports->serverUsesLastPeer = srcHost->hostSerial;
176
u_short clientPort, serverPort;
178
int sport_idx = mapGlobalToLocalIdx(sport);
179
int dport_idx = mapGlobalToLocalIdx(dport);
181
/* Now let's update the list of ports recently used by the hosts */
182
if((sport > dport) || broadcastHost(dstHost)) {
183
clientPort = sport, serverPort = dport;
185
if(sport_idx == -1) addPortToList(srcHost, srcHost->otherIpPortsSent, sport);
186
if(dport_idx == -1) addPortToList(dstHost, dstHost->otherIpPortsRcvd, dport);
188
if(srcHost != myGlobals.otherHostEntry)
189
updatePortList(srcHost, clientPort, -1);
190
if(dstHost != myGlobals.otherHostEntry)
191
updatePortList(dstHost, -1, serverPort);
193
clientPort = dport, serverPort = sport;
195
if(srcHost != myGlobals.otherHostEntry)
196
updatePortList(srcHost, -1, serverPort);
197
if(dstHost != myGlobals.otherHostEntry)
198
updatePortList(dstHost, clientPort, -1);
201
/* **************** */
203
if(/* (srcHost == dstHost) || */
204
broadcastHost(srcHost) || broadcastHost(dstHost))
207
if(sport < MAX_ASSIGNED_IP_PORTS) {
208
ports = getPortsUsage(srcHost, sport, 1);
211
traceEvent(CONST_TRACE_INFO, "DEBUG: Adding svr peer %u", dstHost->hostTrafficBucket);
214
incrementTrafficCounter(&ports->serverTraffic, length);
215
ports->serverUses++, ports->serverUsesLastPeer = dstHost->hostSerial;
217
ports = getPortsUsage(dstHost, sport, 1);
220
traceEvent(CONST_TRACE_INFO, "DEBUG: Adding client peer %u", dstHost->hostTrafficBucket);
223
incrementTrafficCounter(&ports->clientTraffic, length);
224
ports->clientUses++, ports->clientUsesLastPeer = srcHost->hostSerial;
227
if(dport < MAX_ASSIGNED_IP_PORTS) {
228
ports = getPortsUsage(srcHost, dport, 1);
231
traceEvent(CONST_TRACE_INFO, "DEBUG: Adding client peer %u", dstHost->hostTrafficBucket);
234
incrementTrafficCounter(&ports->clientTraffic, length);
235
ports->clientUses++, ports->clientUsesLastPeer = dstHost->hostSerial;
237
ports = getPortsUsage(dstHost, dport, 1);
240
traceEvent(CONST_TRACE_INFO, "DEBUG: Adding svr peer %u", srcHost->hostTrafficBucket);
243
incrementTrafficCounter(&ports->serverTraffic, length);
244
ports->serverUses++, ports->serverUsesLastPeer = srcHost->hostSerial;
1099
1054
/* *********************************** */
1101
static void handleWinMxSession (const struct pcap_pkthdr *h,
1102
HostTraffic *srcHost, u_short sport,
1103
HostTraffic *dstHost, u_short dport,
1104
u_int packetDataLength, u_char* packetData,
1105
IPSession *theSession, int actualDeviceId) {
1108
if (((theSession->bytesProtoSent.value == 3 /* GET */) &&
1109
(theSession->bytesProtoRcvd.value <= 1 /* 1 */))
1110
|| ((theSession->bytesProtoSent.value == 4 /* SEND */) &&
1111
(theSession->bytesProtoRcvd.value <= 1 /* 1 */))) {
1112
char *user, *strtokState, *strtokState1, *row, *file;
1115
theSession->isP2P = FLAG_P2P_WINMX;
1117
if ((rcStr = (u_char*)malloc(packetDataLength+1)) == NULL) {
1118
traceEvent (CONST_TRACE_WARNING, "handleWinMxSession: Unable to "
1119
"allocate memory, WINMX Session handling incomplete\n");
1122
memcpy(rcStr, packetData, packetDataLength);
1123
rcStr[packetDataLength] = '\0';
1125
row = strtok_r((char*)rcStr, "\"", &strtokState);
1128
user = strtok_r(row, "_", &strtokState1);
1129
file = strtok_r(NULL, "\"", &strtokState);
1131
if((user != NULL) && (file != NULL)) {
1132
for(i=0; file[i] != '\0'; i++) {
1133
if(file[i] == '\\') begin = i;
1137
file = &file[begin];
1138
if(strlen(file) > 64) file[strlen(file)-64] = '\0';
1141
traceEvent(CONST_TRACE_INFO, "WinMX: %s->%s [%s][%s]",
1142
srcHost->hostNumIpAddress,
1143
dstHost->hostNumIpAddress,
1147
if(theSession->bytesProtoSent.value == 3) {
1149
updateFileList(file, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
1150
updateFileList(file, BITFLAG_P2P_UPLOAD_MODE, dstHost);
1151
updateHostUsers(user, BITFLAG_P2P_USER, srcHost);
1154
updateFileList(file, BITFLAG_P2P_UPLOAD_MODE, srcHost);
1155
updateFileList(file, BITFLAG_P2P_DOWNLOAD_MODE, dstHost);
1156
updateHostUsers(user, BITFLAG_P2P_USER, dstHost);
1165
/* *********************************** */
1167
static void handleGnutellaSession(const struct pcap_pkthdr *h,
1168
HostTraffic *srcHost, u_short sport,
1169
HostTraffic *dstHost, u_short dport,
1170
u_int packetDataLength, u_char* packetData,
1171
IPSession *theSession, int actualDeviceId) {
1172
u_char *rcStr, tmpStr[256];
1174
if(theSession->bytesProtoSent.value == 0) {
1175
char *strtokState, *row;
1176
char *theStr = "GET /get/";
1178
if ((rcStr = (u_char*)malloc(packetDataLength+1)) == NULL) {
1179
traceEvent (CONST_TRACE_WARNING, "handleGnutellaSession: Unable to "
1180
"allocate memory, Gnutella Session handling incomplete\n");
1183
memcpy(rcStr, packetData, packetDataLength);
1184
rcStr[packetDataLength] = '\0';
1186
if(strncmp((char*)rcStr, theStr, strlen(theStr)) == 0) {
1190
row = strtok_r((char*)rcStr, "\n", &strtokState);
1191
file = &row[strlen(theStr)+1];
1192
if(strlen(file) > 10) file[strlen(file)-10] = '\0';
1194
for(i=0; file[i] != '\0'; i++) {
1195
if(file[i] == '/') begin = i;
1200
unescape((char*)tmpStr, sizeof(tmpStr), &file[begin]);
1203
traceEvent(CONST_TRACE_INFO, "Gnutella: %s->%s [%s]",
1204
srcHost->hostNumIpAddress,
1205
dstHost->hostNumIpAddress,
1208
updateFileList((char*)tmpStr, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
1209
updateFileList((char*)tmpStr, BITFLAG_P2P_UPLOAD_MODE, dstHost);
1210
theSession->isP2P = FLAG_P2P_GNUTELLA;
1216
/* *********************************** */
1218
static void handleKazaaSession(const struct pcap_pkthdr *h,
1219
HostTraffic *srcHost, u_short sport,
1220
HostTraffic *dstHost, u_short dport,
1221
u_int packetDataLength, u_char* packetData,
1222
IPSession *theSession, int actualDeviceId) {
1226
if(theSession->bytesProtoSent.value == 0) {
1227
char *strtokState, *row;
1229
if ((rcStr = (char*)malloc(packetDataLength+1)) == NULL) {
1230
traceEvent (CONST_TRACE_WARNING, "handleKazaaSession: Unable to "
1231
"allocate memory, Kazaa Session handling incomplete\n");
1234
memcpy(rcStr, packetData, packetDataLength);
1235
rcStr[packetDataLength] = '\0';
1237
if(strncmp(rcStr, "GET ", 4) == 0) {
1238
row = strtok_r(rcStr, "\n", &strtokState);
1240
while(row != NULL) {
1241
if(strncmp(row, "GET /", 4) == 0) {
1242
char *theStr = "GET /.hash=";
1243
if(strncmp(row, theStr, strlen(theStr)) != 0) {
1244
char *strtokState1, *file = strtok_r(&row[4], " ", &strtokState1);
1248
for(i=0; file[i] != '\0'; i++) {
1249
if(file[i] == '/') begin = i;
1254
unescape(tmpStr, sizeof(tmpStr), &file[begin]);
1257
traceEvent(CONST_TRACE_INFO, "Kazaa: %s->%s [%s]",
1258
srcHost->hostNumIpAddress,
1259
dstHost->hostNumIpAddress,
1262
updateFileList(tmpStr, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
1263
updateFileList(tmpStr, BITFLAG_P2P_UPLOAD_MODE, dstHost);
1264
theSession->isP2P = FLAG_P2P_KAZAA;
1267
} else if(strncmp(row, "X-Kazaa-Username", 15) == 0) {
1270
row[strlen(row)-1] = '\0';
1273
if(strlen(user) > 48)
1276
/* traceEvent(CONST_TRACE_INFO, "DEBUG: USER='%s'", user); */
1278
updateHostUsers(user, BITFLAG_P2P_USER, srcHost);
1279
theSession->isP2P = FLAG_P2P_KAZAA;
1282
row = strtok_r(NULL, "\n", &strtokState);
1285
/* printf("==>\n\n%s\n\n", rcStr); */
1289
} else if (((theSession->bytesProtoSent.value > 0)
1290
|| (theSession->bytesProtoSent.value < 32))) {
1291
char *strtokState, *row;
1293
if ((rcStr = (char*)malloc(packetDataLength+1)) == NULL) {
1294
traceEvent (CONST_TRACE_WARNING, "handleKazaaSession: Unable to "
1295
"allocate memory, Kazaa Session handling incomplete\n");
1298
memcpy(rcStr, packetData, packetDataLength);
1299
rcStr[packetDataLength] = '\0';
1301
if(strncmp(rcStr, "HTTP", 4) == 0) {
1302
row = strtok_r(rcStr, "\n", &strtokState);
1304
while(row != NULL) {
1305
char *str = "X-KazaaTag: 4=";
1307
if(strncmp(row, str, strlen(str)) == 0) {
1308
char *file = &row[strlen(str)];
1310
file[strlen(file)-1] = '\0';
1312
traceEvent(CONST_TRACE_INFO, "Uploading '%s'", file);
1314
updateFileList(file, BITFLAG_P2P_UPLOAD_MODE, srcHost);
1315
updateFileList(file, BITFLAG_P2P_DOWNLOAD_MODE, dstHost);
1316
theSession->isP2P = FLAG_P2P_KAZAA;
1319
row = strtok_r(NULL, "\n", &strtokState);
1326
/* *********************************** */
1328
1056
static void handleHTTPSession(const struct pcap_pkthdr *h,
1329
1057
HostTraffic *srcHost, u_short sport,
1330
1058
HostTraffic *dstHost, u_short dport,
1331
1059
u_int packetDataLength, u_char* packetData,
1332
1060
IPSession *theSession, int actualDeviceId) {
1333
char *rcStr, tmpStr[256];
1061
char *rcStr, tmpStr[256] = { '\0' };
1334
1062
struct timeval tvstrct;
1336
if (sport == IP_TCP_PORT_HTTP) FD_SET(FLAG_HOST_TYPE_SVC_HTTP, &srcHost->flags);
1337
if (dport == IP_TCP_PORT_HTTP) FD_SET(FLAG_HOST_TYPE_SVC_HTTP, &dstHost->flags);
1064
if (sport == IP_TCP_PORT_HTTP) setHostFlag(FLAG_HOST_TYPE_SVC_HTTP, srcHost);
1065
if (dport == IP_TCP_PORT_HTTP) setHostFlag(FLAG_HOST_TYPE_SVC_HTTP, dstHost);
1339
1067
if ((sport == IP_TCP_PORT_HTTP)
1340
1068
&& (theSession->bytesProtoRcvd.value == 0)) {
1448
1170
if(srcHost->protocolInfo == NULL) srcHost->protocolInfo = calloc(1, sizeof(ProtocolInfo));
1449
1171
if(dstHost->protocolInfo == NULL) dstHost->protocolInfo = calloc(1, sizeof(ProtocolInfo));
1451
if(srcHost->protocolInfo->httpStats == NULL) {
1452
srcHost->protocolInfo->httpStats = (ServiceStats*)malloc(sizeof(ServiceStats));
1453
memset(srcHost->protocolInfo->httpStats, 0, sizeof(ServiceStats));
1455
if(dstHost->protocolInfo->httpStats == NULL) {
1456
dstHost->protocolInfo->httpStats = (ServiceStats*)malloc(sizeof(ServiceStats));
1457
memset(dstHost->protocolInfo->httpStats, 0, sizeof(ServiceStats));
1460
if(subnetLocalHost(dstHost))
1461
incrementTrafficCounter(&srcHost->protocolInfo->httpStats->numLocalReqSent, 1);
1463
incrementTrafficCounter(&srcHost->protocolInfo->httpStats->numRemReqSent, 1);
1465
if(subnetLocalHost(srcHost))
1466
incrementTrafficCounter(&dstHost->protocolInfo->httpStats->numLocalReqRcvd, 1);
1468
incrementTrafficCounter(&dstHost->protocolInfo->httpStats->numRemReqRcvd, 1);
1173
/* Fix courtesy of Ronald Roskens <ronr@econet.com> */
1174
allocHostTrafficCounterMemory(srcHost, protocolInfo->httpStats, sizeof(ServiceStats));
1175
allocHostTrafficCounterMemory(dstHost, protocolInfo->httpStats, sizeof(ServiceStats));
1177
if(subnetLocalHost(dstHost)) {
1178
incrementHostTrafficCounter(srcHost, protocolInfo->httpStats->numLocalReqSent, 1);
1180
incrementHostTrafficCounter(srcHost, protocolInfo->httpStats->numRemReqSent, 1);
1183
if(subnetLocalHost(srcHost)) {
1184
incrementHostTrafficCounter(dstHost, protocolInfo->httpStats->numLocalReqRcvd, 1);
1186
incrementHostTrafficCounter(dstHost, protocolInfo->httpStats->numRemReqRcvd, 1);
1470
1189
row = strtok_r(rcStr, "\n", &strtokState);
1860
1579
|| ((dport >= minPort) && (dport <= maxPort)));
1582
/* ****************************************************** */
1584
static void timeval_diff(struct timeval *begin,
1585
struct timeval *end, struct timeval *result) {
1586
if(end->tv_sec >= begin->tv_sec) {
1587
result->tv_sec = end->tv_sec-begin->tv_sec;
1589
if((end->tv_usec - begin->tv_usec) < 0) {
1590
result->tv_usec = 1000000 + end->tv_usec - begin->tv_usec;
1591
if(result->tv_usec > 1000000) begin->tv_usec = 1000000;
1594
result->tv_usec = end->tv_usec-begin->tv_usec;
1596
result->tv_sec /= 2, result->tv_usec /= 2;
1598
result->tv_sec = 0, result->tv_usec = 0;
1601
/* *********************************** */
1603
static void updateNetworkDelay(NetworkDelay *delayStats,
1604
HostSerial *peer, u_int16_t peer_port,
1605
struct timeval *delay,
1606
struct timeval *when,
1611
traceEvent(CONST_TRACE_WARNING,
1612
"updateNetworkDelay(port=%d [idx=%d], delay=%.2f ms)",
1613
peer_port, port_idx, (float)int_delay/1000);
1615
if(port_idx == -1) return;
1617
int_delay = delay->tv_sec * 1000000 + delay->tv_usec;
1618
if((when->tv_sec == 0) && (when->tv_usec == 0)) gettimeofday(when, NULL);
1619
memcpy(&delayStats[port_idx].last_update, when, sizeof(struct timeval));
1621
if(delayStats[port_idx].min_nw_delay == 0)
1622
delayStats[port_idx].min_nw_delay = int_delay;
1624
delayStats[port_idx].min_nw_delay = min(delayStats[port_idx].min_nw_delay, int_delay);
1626
if(delayStats[port_idx].max_nw_delay == 0)
1627
delayStats[port_idx].max_nw_delay = int_delay;
1629
delayStats[port_idx].max_nw_delay = max(delayStats[port_idx].max_nw_delay, int_delay);
1631
delayStats[port_idx].total_delay += int_delay, delayStats[port_idx].num_samples++;
1632
delayStats[port_idx].peer_port = peer_port;
1633
memcpy(&delayStats[port_idx].last_peer, peer, sizeof(HostSerial));
1636
/* *********************************** */
1638
void updatePeersDelayStats(HostTraffic *peer_a,
1639
HostSerial *peer_b_serial,
1641
struct timeval *nwDelay,
1642
struct timeval *synAckTime,
1643
struct timeval *ackTime,
1644
u_char is_client_delay,
1646
/* traceEvent(CONST_TRACE_WARNING, "----------> updateSessionDelayStats()"); */
1648
if((!subnetPseudoLocalHost(peer_a)) || (port_idx == -1)) return;
1650
if(is_client_delay) {
1651
if((nwDelay->tv_sec > 0) || (nwDelay->tv_usec > 0)) {
1652
if(peer_a->clientDelay == NULL)
1653
peer_a->clientDelay = (NetworkDelay*)calloc(sizeof(NetworkDelay),
1654
myGlobals.ipPortMapper.numSlots);
1656
if(peer_a->clientDelay == NULL) {
1657
traceEvent(CONST_TRACE_ERROR, "Sanity check failed [Low memory?]");
1661
updateNetworkDelay(peer_a->clientDelay,
1669
if((nwDelay->tv_sec > 0) || (nwDelay->tv_usec > 0)) {
1670
if(peer_a->serverDelay == NULL)
1671
peer_a->serverDelay = (NetworkDelay*)calloc(sizeof(NetworkDelay),
1672
myGlobals.ipPortMapper.numSlots);
1673
if(peer_a->serverDelay == NULL) {
1674
traceEvent(CONST_TRACE_ERROR, "Sanity check failed [Low memory?]");
1678
updateNetworkDelay(peer_a->serverDelay,
1688
/* *********************************** */
1690
void updateSessionDelayStats(IPSession* session) {
1693
/* traceEvent(CONST_TRACE_WARNING, "----------> updateSessionDelayStats()"); */
1695
port = session->dport;
1696
if((port_idx = mapGlobalToLocalIdx(port)) == -1) {
1697
port = session->sport;
1698
if((port_idx = mapGlobalToLocalIdx(port)) == -1) {
1703
if(subnetPseudoLocalHost(session->initiator))
1704
updatePeersDelayStats(session->initiator,
1705
&session->remotePeer->hostSerial,
1707
&session->clientNwDelay,
1708
&session->synAckTime,
1709
NULL, 1 /* client */, port_idx);
1711
if(subnetPseudoLocalHost(session->remotePeer))
1712
updatePeersDelayStats(session->remotePeer,
1713
&session->initiator->hostSerial,
1715
&session->serverNwDelay,
1718
0 /* server */, port_idx);
1863
1721
/* *********************************** */
1865
1723
static IPSession* handleTCPSession(const struct pcap_pkthdr *h,
1866
1724
u_short fragmentedData, u_int tcpWin,
1867
1725
HostTraffic *srcHost, u_short sport,
1868
1726
HostTraffic *dstHost, u_short dport,
1869
u_int length, struct tcphdr *tp,
1727
u_int sent_length, u_int rcvd_length /* Always 0 except for NetFlow v9 */,
1870
1729
u_int packetDataLength, u_char* packetData,
1871
1730
int actualDeviceId, u_short *newSession) {
1872
1731
IPSession *prevSession;
2016
1880
theSession->firstSeen = myGlobals.actTime;
2017
1881
flowDirection = FLAG_CLIENT_TO_SERVER;
1883
notifyEvent(sessionCreation, NULL, theSession, 0);
1884
} /* End of new session branch */
1886
/* traceEvent(CONST_TRACE_ERROR, "--> DEBUG: [state=%d][flags=%d]", theSession->sessionState, tp->th_flags); */
1888
&& (theSession->sessionState == FLAG_STATE_SYN)
1889
&& (tp->th_flags == (TH_SYN | TH_ACK))) {
1890
theSession->synAckTime.tv_sec = h->ts.tv_sec;
1891
theSession->synAckTime.tv_usec = h->ts.tv_usec;
1892
timeval_diff(&theSession->synTime, (struct timeval*)&h->ts, &theSession->serverNwDelay);
1894
if(theSession->serverNwDelay.tv_sec > 1000) {
1896
This value seems to be wrong so it's better to ignore it
1897
rather than showing a false/wrong/dummy value
1899
theSession->serverNwDelay.tv_usec = theSession->serverNwDelay.tv_sec = 0;
1902
theSession->sessionState = FLAG_STATE_SYN_ACK;
1903
/* traceEvent(CONST_TRACE_ERROR, "DEBUG: SYN_ACK [%d.%d]", h->ts.tv_sec, h->ts.tv_usec); */
1905
&& (theSession->sessionState == FLAG_STATE_SYN_ACK)
1906
&& (tp->th_flags == TH_ACK)) {
1907
theSession->ackTime.tv_sec = h->ts.tv_sec;
1908
theSession->ackTime.tv_usec = h->ts.tv_usec;
1910
/* traceEvent(CONST_TRACE_ERROR, "DEBUG: ACK [%d.%d]", h->ts.tv_sec, h->ts.tv_usec); */
1912
if(theSession->synTime.tv_sec > 0) {
1913
timeval_diff(&theSession->synAckTime, (struct timeval*)&h->ts, &theSession->clientNwDelay);
1915
if(theSession->clientNwDelay.tv_sec > 1000) {
1917
This value seems to be wrong so it's better to ignore it
1918
rather than showing a false/wrong/dummy value
1920
theSession->clientNwDelay.tv_usec = theSession->clientNwDelay.tv_sec = 0;
1923
updateSessionDelayStats(theSession);
1927
traceEvent(CONST_TRACE_ERROR, "DEBUG: ** FLAG_STATE_ACTIVE ** [client=%d.%d][server=%d.%d]",
1928
theSession->clientNwDelay.tv_sec, theSession->clientNwDelay.tv_usec,
1929
theSession->serverNwDelay.tv_sec, theSession->serverNwDelay.tv_usec);
1932
theSession->sessionState = FLAG_STATE_ACTIVE;
2047
1957
packetDataLength, packetData, theSession,
2048
1958
actualDeviceId);
2049
1959
} else if((dport == IP_TCP_PORT_KAZAA) && (packetDataLength > 0)) {
2050
handleKazaaSession(h, srcHost, sport, dstHost, dport,
2051
packetDataLength, packetData, theSession,
1960
theSession->isP2P = FLAG_P2P_KAZAA;
2053
1961
} else if (((dport == IP_TCP_PORT_GNUTELLA1) ||
2054
1962
(dport == IP_TCP_PORT_GNUTELLA2) ||
2055
1963
(dport == IP_TCP_PORT_GNUTELLA3))
2056
1964
&& (packetDataLength > 0)) {
2057
handleGnutellaSession(h, srcHost, sport, dstHost, dport,
2058
packetDataLength, packetData, theSession,
2060
} else if((dport == IP_TCP_PORT_WINMX) && (packetDataLength > 0)) {
2061
handleWinMxSession(h, srcHost, sport, dstHost, dport,
2062
packetDataLength, packetData, theSession,
1965
theSession->isP2P = FLAG_P2P_GNUTELLA;
2064
1966
} else if (((sport == IP_TCP_PORT_MSMSGR) ||
2065
1967
(dport == IP_TCP_PORT_MSMSGR))
2066
1968
&& (packetDataLength > 0)) {
2067
1969
handleMsnMsgrSession(h, srcHost, sport, dstHost, dport,
2068
1970
packetDataLength, packetData, theSession,
2069
1971
actualDeviceId);
2070
} else if(((sport == IP_TCP_PORT_SMTP) ||
2071
(dport == IP_TCP_PORT_SMTP))
1972
} else if(((sport == IP_TCP_PORT_SMTP) || (dport == IP_TCP_PORT_SMTP))
2072
1973
&& (theSession->sessionState == FLAG_STATE_ACTIVE)) {
2073
1974
handleSMTPSession(h, srcHost, sport, dstHost, dport,
2074
1975
packetDataLength, packetData, theSession,
2075
1976
actualDeviceId);
2076
} else if(((sport == IP_TCP_PORT_FTP) ||
2077
(dport == IP_TCP_PORT_FTP))
1977
} else if(((sport == IP_TCP_PORT_FTP) || (dport == IP_TCP_PORT_FTP))
2078
1978
&& (theSession->sessionState == FLAG_STATE_ACTIVE)) {
2079
1979
handleFTPSession(h, srcHost, sport, dstHost, dport,
2080
1980
packetDataLength, packetData, theSession,
2107
2007
/* Further decoders */
2108
2008
if((!theSession->isP2P)
2109
2009
&& (packetDataLength > 0)
2110
&& ((theSession->bytesProtoSent.value > 0) && (theSession->bytesProtoSent.value < 1400))) {
2010
&& ((theSession->bytesProtoSent.value > 0)
2011
&& (theSession->bytesProtoSent.value < 1400))) {
2111
2012
rcStr = (u_char*)malloc(len+1);
2112
2013
memcpy(rcStr, packetData, len);
2113
2014
rcStr[len-1] = '\0';
2115
/* See dcplusplus.sourceforge.net */
2116
if(portRange(sport, dport, 411, 412)
2117
|| (!strncmp((char*)rcStr, "$Connect", 8))
2118
|| (!strncmp((char*)rcStr, "$Direction", 10))
2119
|| (!strncmp((char*)rcStr, "$Hello", 6))
2120
|| (!strncmp((char*)rcStr, "$Key", 4))
2121
|| (!strncmp((char*)rcStr, "$Lock", 5))
2122
|| (!strncmp((char*)rcStr, "$MyInfo", 7))
2123
|| (!strncmp((char*)rcStr, "$Pin", 4))
2124
|| (!strncmp((char*)rcStr, "$Quit", 5))
2125
|| (!strncmp((char*)rcStr, "$Send", 5))
2126
|| (!strncmp((char*)rcStr, "$SR", 3))
2127
|| (!strncmp((char*)rcStr, "$Search", 7))) {
2128
theSession->isP2P = FLAG_P2P_DIRECTCONNECT;
2129
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
2130
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_UPLOAD_MODE, dstHost);
2131
} else if(!strncmp((char*)rcStr, "$MyNick", 7)) {
2132
theSession->isP2P = FLAG_P2P_DIRECTCONNECT;
2133
updateHostUsers(strtok((char*)&rcStr[8], "|"), BITFLAG_P2P_USER, srcHost);
2134
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
2135
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_UPLOAD_MODE, dstHost);
2136
} else if(!strncmp((char*)rcStr, "$Get", 4)) {
2137
char *file = strtok((char*)&rcStr[5], "$");
2138
theSession->isP2P = FLAG_P2P_DIRECTCONNECT;
2139
updateFileList(file, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
2140
updateFileList(file, BITFLAG_P2P_UPLOAD_MODE, dstHost);
2141
} else if(portRange(sport, dport, 4661, 4665)
2016
if(portRange(sport, dport, 4661, 4665)
2142
2017
|| (rcStr[0] == 0xE3) || (rcStr[0] == 0xC5)) {
2143
2018
/* Skype uses the eDonkey protocol so we must male sure that
2144
2019
we don't mix them */
2159
2032
|| (strstr((char*)rcStr, "GET TrackPak") != NULL)
2160
2033
|| (strstr((char*)rcStr, "BitTorrent") != NULL)) {
2161
2034
theSession->isP2P = FLAG_P2P_BITTORRENT;
2162
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
2163
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_UPLOAD_MODE, dstHost);
2164
2035
} else if(portRange(sport, dport, 6346, 6347)
2165
2036
|| (!strncmp((char*)rcStr, "GNUTELLA", 8))
2166
2037
|| (!strncmp((char*)rcStr, "GIV", 3))
2167
2038
|| (!strncmp((char*)rcStr, "GET /uri-res/", 13))) {
2168
2039
theSession->isP2P = FLAG_P2P_GNUTELLA;
2169
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
2170
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_UPLOAD_MODE, dstHost);
2171
2040
} else if((!strncmp((char*)rcStr, "GET hash:", 9))
2172
2041
|| (!strncmp((char*)rcStr, "PUSH", 4))
2173
2042
|| (!strncmp((char*)rcStr, "GET /uri-res/", 12))) {
2175
2044
theSession->isP2P = FLAG_P2P_OTHER_PROTOCOL;
2176
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
2177
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_UPLOAD_MODE, dstHost);
2178
2045
} else if((!strncmp((char*)rcStr, "GET /$$$$$$$$$/", 15))) {
2179
2046
/* EarthStation5 */
2180
2047
theSession->isP2P = FLAG_P2P_OTHER_PROTOCOL;
2181
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_DOWNLOAD_MODE, srcHost);
2182
updateFileList(UNKNOWN_P2P_FILE, BITFLAG_P2P_UPLOAD_MODE, dstHost);
2191
2056
switch(sport) {
2192
2057
case IP_TCP_PORT_FTP:
2193
FD_SET(FLAG_HOST_TYPE_SVC_FTP, &srcHost->flags);
2058
setHostFlag(FLAG_HOST_TYPE_SVC_FTP, srcHost);
2195
2060
case IP_TCP_PORT_SMTP:
2196
FD_SET(FLAG_HOST_TYPE_SVC_SMTP, &srcHost->flags);
2061
setHostFlag(FLAG_HOST_TYPE_SVC_SMTP, srcHost);
2198
2063
case IP_TCP_PORT_HTTP:
2199
2064
case IP_TCP_PORT_HTTPS:
2200
FD_SET(FLAG_HOST_TYPE_SVC_HTTP, &srcHost->flags);
2065
setHostFlag(FLAG_HOST_TYPE_SVC_HTTP, srcHost);
2202
2067
case IP_TCP_PORT_POP2:
2203
2068
case IP_TCP_PORT_POP3:
2204
FD_SET(FLAG_HOST_TYPE_SVC_POP, &srcHost->flags);
2069
setHostFlag(FLAG_HOST_TYPE_SVC_POP, srcHost);
2206
2071
case IP_TCP_PORT_IMAP:
2207
FD_SET(FLAG_HOST_TYPE_SVC_IMAP, &srcHost->flags);
2072
setHostFlag(FLAG_HOST_TYPE_SVC_IMAP, srcHost);
2209
2074
case IP_TCP_PORT_PRINTER:
2210
2075
case IP_TCP_PORT_JETDIRECT:
2211
FD_SET(FLAG_HOST_TYPE_PRINTER, &srcHost->flags);
2076
setHostFlag(FLAG_HOST_TYPE_PRINTER, srcHost);
2215
2080
switch(dport) {
2216
2081
case IP_TCP_PORT_FTP:
2217
FD_SET(FLAG_HOST_TYPE_SVC_FTP, &dstHost->flags);
2082
setHostFlag(FLAG_HOST_TYPE_SVC_FTP, dstHost);
2219
2084
case IP_TCP_PORT_SMTP:
2220
FD_SET(FLAG_HOST_TYPE_SVC_SMTP, &dstHost->flags);
2085
setHostFlag(FLAG_HOST_TYPE_SVC_SMTP, dstHost);
2222
2087
case IP_TCP_PORT_HTTP:
2223
2088
case IP_TCP_PORT_HTTPS:
2224
FD_SET(FLAG_HOST_TYPE_SVC_HTTP, &dstHost->flags);
2089
setHostFlag(FLAG_HOST_TYPE_SVC_HTTP, dstHost);
2226
2091
case IP_TCP_PORT_POP2:
2227
2092
case IP_TCP_PORT_POP3:
2228
FD_SET(FLAG_HOST_TYPE_SVC_POP, &dstHost->flags);
2093
setHostFlag(FLAG_HOST_TYPE_SVC_POP, dstHost);
2230
2095
case IP_TCP_PORT_IMAP:
2231
FD_SET(FLAG_HOST_TYPE_SVC_IMAP, &dstHost->flags);
2096
setHostFlag(FLAG_HOST_TYPE_SVC_IMAP, dstHost);
2233
2098
case IP_TCP_PORT_PRINTER:
2234
2099
case IP_TCP_PORT_JETDIRECT:
2235
FD_SET(FLAG_HOST_TYPE_PRINTER, &dstHost->flags);
2100
setHostFlag(FLAG_HOST_TYPE_PRINTER, dstHost);
2295
2160
if((theSession->maxWindow < tcpWin) || (theSession->maxWindow == 0))
2296
2161
theSession->maxWindow = tcpWin;
2299
printf("DEBUG: sessionsState=%d\n", theSession->sessionState);
2302
2163
if((theSession->lastFlags == (TH_SYN|TH_ACK)) && (theSession->sessionState == FLAG_STATE_SYN)) {
2303
theSession->sessionState = FLAG_FLAG_STATE_SYN_ACK;
2304
} else if((theSession->lastFlags == TH_ACK) && (theSession->sessionState == FLAG_FLAG_STATE_SYN_ACK)) {
2305
if(h->ts.tv_sec >= theSession->nwLatency.tv_sec) {
2306
theSession->nwLatency.tv_sec = h->ts.tv_sec-theSession->nwLatency.tv_sec;
2308
if((h->ts.tv_usec - theSession->nwLatency.tv_usec) < 0) {
2309
theSession->nwLatency.tv_usec = 1000000 + h->ts.tv_usec - theSession->nwLatency.tv_usec;
2310
if(theSession->nwLatency.tv_usec > 1000000) theSession->nwLatency.tv_usec = 1000000;
2311
theSession->nwLatency.tv_sec--;
2313
theSession->nwLatency.tv_usec = h->ts.tv_usec-theSession->nwLatency.tv_usec;
2315
theSession->nwLatency.tv_sec /= 2;
2316
theSession->nwLatency.tv_usec /= 2;
2319
if(theSession->nwLatency.tv_sec > 1000) {
2321
This value seems to be wrong so it's better to ignore it
2322
rather than showing a false/wrong/dummy value
2324
theSession->nwLatency.tv_usec = theSession->nwLatency.tv_sec = 0;
2325
#ifdef LATENCY_DEBUG
2326
traceEvent(CONST_TRACE_NOISY, "LATENCY: %s:%d->%s:%d invalid (too big), ignored",
2327
_addrtostr(&theSession->initiatorRealIp, buf, sizeof(buf)),
2329
_addrtostr(&theSession->remotePeerRealIp, buf1, sizeof(buf1)),
2334
traceEvent(CONST_TRACE_NOISY, "LATENCY: %s:%d->%s:%d is %d us",
2335
_addrtostr(&theSession->initiatorRealIp, buf, sizeof(buf)),
2337
_addrtostr(&theSession->remotePeerRealIp, buf1, sizeof(buf1)),
2339
(int)(theSession->nwLatency.tv_sec * 1000000 + theSession->nwLatency.tv_usec));
2342
theSession->sessionState = FLAG_STATE_ACTIVE;
2344
/* The latency value is negative. There's something wrong so let's drop it */
2345
theSession->nwLatency.tv_usec = theSession->nwLatency.tv_sec = 0;
2346
#ifdef LATENCY_DEBUG
2347
traceEvent(CONST_TRACE_NOISY, "LATENCY: %s:%d->%s:%d invalid (negative), ignored",
2348
_addrtostr(&theSession->initiatorRealIp, buf, sizeof(buf)),
2350
_addrtostr(&theSession->remotePeerRealIp, buf1, sizeof(buf1)),
2164
theSession->sessionState = FLAG_STATE_SYN_ACK;
2165
} else if((theSession->lastFlags == TH_ACK) && (theSession->sessionState == FLAG_STATE_SYN_ACK)) {
2167
traceEvent(CONST_TRACE_NOISY, "LATENCY: %s:%d->%s:%d [CND: %d us][SND: %d us]",
2168
_addrtostr(&theSession->initiatorRealIp, buf, sizeof(buf)),
2170
_addrtostr(&theSession->remotePeerRealIp, buf1, sizeof(buf1)),
2172
(int)(theSession->clientNwDelay.tv_sec * 1000000 + theSession->clientNwDelay.tv_usec),
2173
(int)(theSession->serverNwDelay.tv_sec * 1000000 + theSession->serverNwDelay.tv_usec)
2176
theSession->sessionState = FLAG_STATE_ACTIVE;
2180
traceEvent(CONST_TRACE_WARNING, "DEBUG: sessionsState=%d\n", theSession->sessionState);
2355
2183
if(subnetLocalHost(srcHost)) {
2356
2184
hostToUpdate = dstHost;
2357
2185
} else if(subnetLocalHost(dstHost)) {