static void sipPlugin_delete(HashBucket* bkt, void *pluginData) { if(pluginData != NULL) { struct plugin_info *info = (struct plugin_info*)pluginData; #ifdef SIP_DEBUG char buf[256], buf1[256]; traceEvent(TRACE_INFO, "SIP: '%s'->'%s'", info->sip_calling_party, info->sip_called_party); traceEvent(TRACE_INFO, "RTP '%s:%d'->'%s:%d'", _intoa(bkt->src, buf, sizeof(buf)), info->rtp_src_port, _intoa(bkt->dst, buf1, sizeof(buf1)), info->rtp_dst_port); #endif free(info); } }
static void dumpPlugin_delete(HashBucket* bkt, void *pluginData) { #ifdef DEBUG traceEvent(TRACE_INFO, "dumpPlugin_delete called.\n"); #endif if(pluginData != NULL) { struct plugin_info *info = (struct plugin_info*)pluginData; #ifdef DEBUG char buf[256], buf1[256]; traceEvent(TRACE_INFO, "Flow [%s:%d -> %s:%d] terminated.\n", _intoa(bkt->src, buf, sizeof(buf)), (int)bkt->sport, _intoa(bkt->dst, buf1, sizeof(buf1)), (int)bkt->dport); #endif fclose(info->fd); if(info->file_path != NULL) free(info->file_path); free(info); } }
char* IpAddress::print(char *str, u_int str_len) { return(_intoa(str, str_len)); }
static void sipPlugin_packet(u_char new_bucket, void *pluginData, HashBucket* bkt, u_short proto, u_char isFragment, u_short numPkts, u_char tos, u_short vlanId, struct ether_header *ehdr, IpAddress *src, u_short sport, IpAddress *dst, u_short dport, u_int len, u_int8_t flags, u_int8_t icmpType, u_short numMplsLabels, u_char mplsLabels[MAX_NUM_MPLS_LABELS][MPLS_LABEL_LEN], char *fingerprint, const struct pcap_pkthdr *h, const u_char *p, u_char *payload, int payloadLen) { if((payload == NULL) || (payloadLen == 0)) return; if(new_bucket /* This bucket has been created recently */) { /* Check whether this is an RTP or SIP flow */ if((bkt->proto == 17 /* UDP */) && (bkt->sport == DEFAULT_SIP_PORT) && (bkt->dport == DEFAULT_SIP_PORT) /* SIP */ ) { PluginInformation *info; info = (PluginInformation*)malloc(sizeof(PluginInformation)); if(info == NULL) { traceEvent(TRACE_ERROR, "Not enough memory?"); return; /* Not enough memory */ } info->pluginPtr = (void*)&sipPlugin; pluginData = info->pluginData = (struct plugin_info*)malloc(sizeof(struct plugin_info)); if(info->pluginData == NULL) { traceEvent(TRACE_ERROR, "Not enough memory?"); free(info); return; /* Not enough memory */ } else { /* Set defaults */ struct plugin_info *infos = (struct plugin_info*)pluginData; info->next = bkt->plugin; bkt->plugin = info; memset(infos, 0, sizeof(struct plugin_info)); } } } if(pluginData != NULL) { char *my_payload, *strtokState, *row; #ifdef SIP_DEBUG char buf[32]; #endif char *from = NULL, *to = NULL, *server = NULL, *audio = NULL, *video = NULL; struct plugin_info *info = (struct plugin_info*)pluginData; /* Handle your Sip packet here */ my_payload = malloc(payloadLen+1); if(my_payload != NULL) { char *rtpmap; memcpy(my_payload, payload, payloadLen); my_payload[payloadLen] = '\0'; row = strtok_r((char*)my_payload, "\r\n", &strtokState); if(row != NULL) { if(strstr(row, "INVITE")) info->sip_invite_time.tv_sec = h->ts.tv_sec, info->sip_invite_time.tv_usec = h->ts.tv_usec; else if(strstr(row, "Trying")) info->sip_trying_time.tv_sec = h->ts.tv_sec, info->sip_trying_time.tv_usec = h->ts.tv_usec; else if(strstr(row, "Ringing")) info->sip_ringing_time.tv_sec = h->ts.tv_sec, info->sip_ringing_time.tv_usec = h->ts.tv_usec; else if(strstr(row, "OK")) info->sip_ok_time.tv_sec = h->ts.tv_sec, info->sip_ok_time.tv_usec = h->ts.tv_usec; else if(strstr(row, "ACK")) info->sip_ack_time.tv_sec = h->ts.tv_sec, info->sip_ack_time.tv_usec = h->ts.tv_usec; row = strtok_r(NULL, "\r\n", &strtokState); while(row != NULL) { #ifdef SIP_DEBUG traceEvent(TRACE_INFO, "==> SIP [%d] '%s'", strlen(row), row); #endif if((from == NULL) && ((!strncmp(row, "From: ", 6)) || (!strncmp(row, "f: ", 3)))) { from = row; } else if((to == NULL) && ((!strncmp(row, "To: ", 4)) || (!strncmp(row, "t: ", 3)))) { to = row; } else if(!strncmp(row, "Call-ID: ", 8)) { strncpy(info->sip_call_id, &row[9], MAX_SIP_STR_LEN); } else if((server == NULL) && (!strncmp(row, "Server: ", 8))) { server = row; } else if((audio == NULL) && (!strncmp(row, "m=audio ", 8))) { audio = row; } else if((video == NULL) && (!strncmp(row, "m=video ", 8))) { video = row; } else if((rtpmap = strstr(row, "=rtpmap:")) != NULL) { char *codec; int i; if(rtpmap[10] == ' ') codec = &rtpmap[11]; else codec = &rtpmap[10]; for(i=0; codec[i] != '\0'; i++) if(codec[i] == '/') { codec[i] = '\0'; break; } if(info->rtp_codecs[0] == '\0') { snprintf(info->rtp_codecs, sizeof(info->rtp_codecs)-1, "%s", codec); } else { if(strstr(info->rtp_codecs, codec) == NULL) { char tmpStr[SIP_CODECS_STR_LEN]; snprintf(tmpStr, sizeof(tmpStr)-1, "%s;%s", info->rtp_codecs, codec); strcpy(info->rtp_codecs, tmpStr); } } } row = strtok_r(NULL, "\r\n", &strtokState); } } if(server) { strtok_r(server, ":", &strtokState); server = strtok_r(NULL, ":", &strtokState); #ifdef SIP_DEBUG /* traceEvent(TRACE_INFO, "Server '%s'", server); */ #endif } if(from && to && (!strncasecmp((char*)my_payload, SIP_INVITE, strlen(SIP_INVITE)))) { strtok_r(from, ":", &strtokState); strtok_r(NULL, ":\"", &strtokState); from = strtok_r(NULL, "\"@>", &strtokState); strtok_r(to, ":", &strtokState); strtok_r(NULL, "\":", &strtokState); to = strtok_r(NULL, "\"@>", &strtokState); #ifdef SIP_DEBUG traceEvent(TRACE_INFO, "'%s'->'%s'", from, to); #endif strncpy(info->sip_calling_party, from, MAX_SIP_STR_LEN); strncpy(info->sip_called_party, to, MAX_SIP_STR_LEN); } if(audio) { strtok_r(audio, " ", &strtokState); audio = strtok_r(NULL, " ", &strtokState); #ifdef SIP_DEBUG traceEvent(TRACE_INFO, "RTP '%s:%s'", _intoa(*src, buf, sizeof(buf)), audio); #endif if(cmpIpAddress(bkt->src, *src)) { /* Direction: src -> dst */ if(audio) info->rtp_src_port = atoi(audio); } else { /* Direction: dst -> src */ if(audio) info->rtp_dst_port = atoi(audio); } } if(video) { strtok_r(video, " ", &strtokState); video = strtok_r(NULL, " ", &strtokState); #ifdef SIP_DEBUG traceEvent(TRACE_INFO, "RTP '%s:%s'", _intoa(*src, buf, sizeof(buf)), video); #endif } free(my_payload); } else traceEvent(TRACE_ERROR, "Not enough memory?"); } }
static void dumpPlugin_packet(u_char new_bucket, void* pluginData, HashBucket* bkt, u_short proto, u_char isFragment, u_short numPkts, u_char tos, u_short vlanId, struct ether_header *ehdr, IpAddress *src, u_short sport, IpAddress *dst, u_short dport, u_int len, u_int8_t flags, u_int8_t icmpType, u_short numMplsLabels, u_char mplsLabels[MAX_NUM_MPLS_LABELS][MPLS_LABEL_LEN], char *fingerprint, const struct pcap_pkthdr *h, const u_char *p, u_char *payload, int payloadLen) { if(new_bucket) { PluginInformation *info; /* The file has not yet been created */ char buf[32], buf1[32], filePath[PATH_LEN], dirPath[PATH_LEN]; time_t now = time(NULL); FILE *fd; struct tm t; char *prefix; info = (PluginInformation*)malloc(sizeof(PluginInformation)); if(info == NULL) { traceEvent(TRACE_ERROR, "Not enough memory?"); return; /* Not enough memory */ } info->pluginPtr = (void*)&dumpPlugin; pluginData = info->pluginData = malloc(sizeof(struct plugin_info)); if(info->pluginData == NULL) { traceEvent(TRACE_ERROR, "Not enough memory?"); free(info); return; /* Not enough memory */ } info->next = bkt->plugin; bkt->plugin = info; #ifdef DEBUG traceEvent(TRACE_INFO, "dumpPlugin_create called.\n"); #endif strftime(dirPath, sizeof(dirPath), "/%G/%b/%e/%H/%M/", localtime_r(&now, &t)); if( (bkt->sport == 25) || (bkt->dport == 25)) prefix = "smtp"; else if((bkt->sport == 110) || (bkt->dport == 110)) prefix = "pop"; else if((bkt->sport == 143) || (bkt->dport == 143)) prefix = "imap"; else if((bkt->sport == 220) || (bkt->dport == 220)) prefix = "imap3"; else prefix = "data"; snprintf(filePath, sizeof(filePath), "%s/%s/%s:%d_%s:%d-%u.%s", BASE_PATH, dirPath, _intoa(bkt->src, buf, sizeof(buf)), (int)bkt->sport, _intoa(bkt->dst, buf1, sizeof(buf1)), (int)bkt->dport, (unsigned int)now, prefix); fd = fopen(filePath, "w+"); if(fd == NULL) { char fullPath[256]; /* Maybe the directory has not been created yet */ snprintf(fullPath, sizeof(fullPath), "%s/%s", BASE_PATH, dirPath); mkdir_p(fullPath); fd = fopen(filePath, "w+"); } if(fd != NULL) { struct plugin_info* infos = (struct plugin_info*)pluginData; #ifdef DEBUG traceEvent(TRACE_INFO, "Saving flow into %s", filePath); #endif infos->fd = fd; infos->file_path = strdup(filePath); } } if((payload == NULL) || (payloadLen == 0)) return; /* Nothing to save */ if(pluginData != NULL) (void)fwrite(payload, payloadLen, 1, ((struct plugin_info *)pluginData)->fd); }