static void udp_callback(struct tuple4 *addr, u_char *udp_data, int udp_data_len, struct rfc_ip *ip) { struct session *elt; unsigned int udp_data_offset = IPHDRLEN + UDPHDRLEN; if (NULL == (elt = sessions_find(first_session, TYPE_UDP, 0, addr))) { if (bonus_time) return; if (addr->source == 1719 || addr->dest == 1719) elt = sessions_add(TYPE_UDP | TYPE_H225_RAS, addr, NULL); else if (addr->source == 5060 || addr->dest == 5060) elt = sessions_add(TYPE_UDP | TYPE_SIP, addr, NULL); } if (NULL == elt) return; elt->bytes += udp_data_len; elt->lastseen = nids_last_pcap_header->ts; if (NULL != elt->callback) elt = elt->callback(elt, udp_data, udp_data_len); /* * We can dump the frame only after the data is processed because * a new session object (`elt') might be created by the callback, * with a pointer to a different PCAP file. */ if ((ip->ihl > 5) && ((ip->ihl * 4) < (udp_data_offset + udp_data_len))) udp_data_offset = ip->ihl * 4 + UDPHDRLEN; dump_frame((u_char *)ip, udp_data_offset + udp_data_len, elt->dumper); }
static struct session *h225_cs_callback(struct session *cs, u_char *data, uint32_t len) { char callToken[20]; OOH323CallData *call; Q931Message q931; DListNode *node; H245OpenLogicalChannel *olc; H245H2250LogicalChannelParameters *lcp; struct tuple4 addr; ooGenerateCallToken(callToken, 20); call = ooCreateCall("incoming", callToken); call->pH225Channel = (OOH323Channel*) memAllocZ (call->pctxt, sizeof (OOH323Channel)); if (OO_OK == ooQ931Decode(call, &q931, ntohs(*((u_short *)(data + 2))) - 4, data + 4)) { if (OO_OK == ooHandleH2250Message(call, &q931)) { if (!bonus_time && (q931.messageType == Q931CallProceedingMsg)) { for (node = call->remoteFastStartOLCs.head; NULL != node; node = node->next) { olc = node->data; if (4 == olc->forwardLogicalChannelParameters.multiplexParameters.t) { lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters; if (lcp->m.mediaChannelPresent && (1 == lcp->mediaChannel.t) && (1 == lcp->mediaChannel.u.unicastAddress->t)) { addr.source = 0; addr.saddr = 0; addr.dest = lcp->mediaChannel.u.unicastAddress->u.iPAddress->tsapIdentifier; addr.daddr = *((u_int *)lcp->mediaChannel.u.unicastAddress->u.iPAddress->network.data); sessions_add(TYPE_UDP | TYPE_RTP, &addr, cs); if (lcp->m.mediaControlChannelPresent && (2 == lcp->mediaControlChannel.t) && (1 == lcp->mediaControlChannel.u.multicastAddress->t)) { addr.source = 0; addr.saddr = 0; addr.dest = lcp->mediaControlChannel.u.unicastAddress->u.iPAddress->tsapIdentifier; addr.daddr = *((u_int *)lcp->mediaControlChannel.u.unicastAddress->u.iPAddress->network.data); sessions_add(TYPE_UDP | TYPE_RTCP, &addr, cs); } /* break; */ } } } } } } ooCleanCall(call); return cs; }
/* * This function is called upon reception of all IPv4 packets, which * means some packets will be processed by both ip_callback and * {udp,tcp}_callback. It is necessary for TCP packets though because * tcp_callback is only called once a connection is established (i.e. * after the first SYN, SYN+ACK and ACK packets have passed) and only * when data is available (PSH packets). * Since we don't want failed TCP connections (portscans etc) to * mobilize resources, we give TCP sessions 60 seconds to complete * the TCP handshake or else they are considered to be closed. */ static void ip_callback(struct rfc_ip *ip, int len) { struct tuple4 addr; struct rfc_tcp *tcp; struct session *elt; struct session *elt_next; unsigned int ip_data_offset = IPHDRLEN; for (elt = first_session; NULL != elt; elt = elt_next) { elt_next = elt->next; if (elt->timeout && (nids_last_pcap_header->ts.tv_sec >= elt->timeout)) sessions_del(elt); } if ((ip->ihl > 5) && ((ip->ihl * 4) <= len)) ip_data_offset = ip->ihl * 4; if ((ip->protocol != 6) || (len < (ip_data_offset + TCPHDRLEN))) return; /* not TCP or too short */ tcp = (struct rfc_tcp *)((char *)ip + ip_data_offset); addr.saddr = *((u_int *)&ip->saddr); addr.daddr = *((u_int *)&ip->daddr); addr.source = ntohs(tcp->sport); addr.dest = ntohs(tcp->dport); if (NULL != (elt = sessions_find(first_session, TYPE_TCP, 0, &addr))) { dump_frame((u_char *)ip, len, elt->dumper); if (sessions_expiration_delay) elt->timeout = nids_last_pcap_header->ts.tv_sec + sessions_expiration_delay; elt->lastseen = nids_last_pcap_header->ts; return; } if (!tcp->syn || bonus_time) return; if (addr.source == 5060 || addr.dest == 5060) elt = sessions_add(TYPE_TCP | TYPE_SIP, &addr, NULL); else elt = sessions_add(TYPE_TCP, &addr, NULL); if (NULL == elt) return; dump_frame((u_char *)ip, len, elt->dumper); elt->timeout = nids_last_pcap_header->ts.tv_sec + 60; /* 60 seconds to complete TCP handshake */ }
SaErrorT ohc_sess_open( SaHpiDomainIdT did, SaHpiSessionIdT& sid ) { ohc_init(); // TODO investigate cSession * session = new cSession; SaErrorT rv = session->RpcOpen( did ); if ( rv == SA_OK ) { sid = sessions_add( session ); } else { delete session; } return rv; }
EXPORTNOT session_t *remote_session_add(const char *uid, const char *plugin) { session_t *s; plugin_t *pl; if (!(pl = plugin_find(plugin))) { debug_error("remote_session_add() plugin == NULL\n"); return NULL; } s = xmalloc(sizeof(session_t)); s->uid = xstrdup(uid); s->status = EKG_STATUS_NA; s->plugin = pl; sessions_add(s); /* XXX, session_var_default() */ query_emit_id(NULL, SESSION_ADDED, &(s->uid)); return s; }
static struct session *h225_ras_callback(struct session *ras, u_char *data, uint32_t len) { OOCTXT ctxt; H225RasMessage *pRasMsg; struct session *cs; struct session *rasbkp; initContext(&ctxt); if (ASN_OK != setPERBuffer(&ctxt, data, len, TRUE)) return ras; rasbkp = ras; pRasMsg = (H225RasMessage *)memAlloc(&ctxt, sizeof (H225RasMessage)); if (ASN_OK == asn1PD_H225RasMessage(&ctxt, pRasMsg)) switch (pRasMsg->t) { case T_H225RasMessage_admissionRequest: if (bonus_time) break; if ('\0' != ras->u.ras_params.call_id[0]) ras = sessions_add(TYPE_UDP | TYPE_H225_RAS, &ras->addr, NULL); memcpy(ras->u.ras_params.call_id, pRasMsg->u.admissionRequest->conferenceID.data, 16); ras->u.ras_params.seqnum = pRasMsg->u.admissionRequest->requestSeqNum; ras->timeout = nids_last_pcap_header->ts.tv_sec + 60; /* 60 seconds for the gatekeeper to confirm admission */ break; case T_H225RasMessage_admissionConfirm: if (bonus_time) break; while ((NULL != ras) && (ras->u.ras_params.seqnum != pRasMsg->u.admissionConfirm->requestSeqNum)) ras = sessions_find(ras->next, TYPE_UDP | TYPE_H225_RAS, 0, &ras->addr); if (NULL == ras) { ras = rasbkp; break; } if (pRasMsg->u.admissionConfirm->destCallSignalAddress.t != T_H225TransportAddress_ipAddress) { ras->timeout = nids_last_pcap_header->ts.tv_sec; /* delete after dumping frame */ break; } ras->u.ras_params.cs_addr.dest = pRasMsg->u.admissionConfirm->destCallSignalAddress.u.ipAddress->port; ras->u.ras_params.cs_addr.daddr = *((u_int *)pRasMsg->u.admissionConfirm->destCallSignalAddress.u.ipAddress->ip.data); if (NULL != (cs = sessions_add(TYPE_TCP | TYPE_H225_CS, &ras->u.ras_params.cs_addr, ras))) cs->timeout = nids_last_pcap_header->ts.tv_sec + 60; /* 60 seconds to establish the Call Signaling stream */ break; case T_H225RasMessage_admissionReject: while ((NULL != ras) && (ras->u.ras_params.seqnum != pRasMsg->u.admissionReject->requestSeqNum)) ras = sessions_find(ras->next, TYPE_UDP | TYPE_H225_RAS, 0, &ras->addr); if (NULL == ras) { ras = rasbkp; break; } ras->timeout = nids_last_pcap_header->ts.tv_sec; /* delete after dumping frame */ break; case T_H225RasMessage_disengageRequest: while ((NULL != ras) && memcmp(ras->u.ras_params.call_id, pRasMsg->u.disengageRequest->conferenceID.data, 16)) ras = sessions_find(ras->next, TYPE_UDP | TYPE_H225_RAS, 0, &ras->addr); if (NULL == ras) { ras = rasbkp; break; } ras->u.ras_params.seqnum = pRasMsg->u.disengageRequest->requestSeqNum; break; case T_H225RasMessage_disengageConfirm: while ((NULL != ras) && (ras->u.ras_params.seqnum != pRasMsg->u.disengageConfirm->requestSeqNum)) ras = sessions_find(ras->next, TYPE_UDP | TYPE_H225_RAS, 0, &ras->addr); if (NULL == ras) { ras = rasbkp; break; } ras->timeout = nids_last_pcap_header->ts.tv_sec; /* delete after dumping frame */ } memFreePtr(&ctxt, pRasMsg); freeContext(&ctxt); return ras; }
static struct session *sip_callback(struct session *sip, u_char *data, uint32_t len) { osip_message_t *msg; struct tuple4 addr; struct session *start; struct session *rtp; osip_call_id_t *call_id; osip_message_init(&msg); if (!osip_message_parse(msg, (char *)data, len)) { if (NULL == sip->u.sip_params.call_id) { /* * If the session object was created by udp_callback * we need to fill in the call_id field here because * udp_callback doesn't know anything about SIP */ if (NULL != (call_id = osip_message_get_call_id(msg))) osip_call_id_clone(call_id, &sip->u.sip_params.call_id); } else { /* * Otherwise check if the session object passed to this * function call was really the one corresponding to the * call ID in the SIP packet, in case several SIP calls * are passed upon the same transport layer protocol, * source and destination IPv4 address & port combination. * udp_callback has no way of knowing how to distinguish * SIP session objects based on call ID, so we have to do * it here. We just continue searching in the list of all * tracked sessions for similar SIP objects until we find * one that has the same call ID, or else we create a new * SIP session object that corresponds to the new call. */ start = sip; do { if (NULL == (call_id = osip_message_get_call_id(msg))) continue; if (!osip_call_id_match(sip->u.sip_params.call_id, call_id)) break; } while ((sip = sessions_find(sip->next, TYPE_SIP, 0, &sip->addr))); if (NULL == sip) { if (bonus_time) { osip_message_free(msg); return start; } sip = sessions_add(start->type, &start->addr, NULL); if (NULL != (call_id = osip_message_get_call_id(msg))) osip_call_id_clone(call_id, &sip->u.sip_params.call_id); } } /* * If the current SIP packet is an INVITE message, store the * advertised source port and IPv4 address. It is not very * important, since we can do only with the destination part * (useful in case the capture missed the INVITE packet), but * it helps discriminating from unrelated packets. * * Unfortunately, some SIP implementations such as the one in * Audiocodes Mediant 1000 SIP gateways actually use a source * port different from the one they advertised in the INVITE * message parameters - how outrageous! - so we have to make * our sessions search engine ignore the source port part by * zeroing it :-/ */ if (MSG_IS_INVITE(msg)) { if (!bonus_time) { sip_get_address(msg, &sip->u.sip_params.rtp_addr.saddr, &sip->u.sip_params.rtp_addr.source); #ifndef USING_NON_STUPID_SIP_IMPLEMENTATIONS sip->u.sip_params.rtp_addr.source = 0; #endif } } else if (MSG_TEST_CODE(msg, 200)) { if (MSG_IS_RESPONSE_FOR(msg, "INVITE")) { if (!bonus_time && sip_get_address(msg, &sip->u.sip_params.rtp_addr.daddr, &sip->u.sip_params.rtp_addr.dest)) { sessions_add(TYPE_UDP | TYPE_RTP, &sip->u.sip_params.rtp_addr, sip); sip->u.sip_params.picked_up = 1; } } else if (MSG_IS_RESPONSE_FOR(msg, "BYE") || MSG_IS_RESPONSE_FOR(msg, "CANCEL")) { start = first_session; while (NULL != (rtp = sessions_find(start, TYPE_RTP, sip->id, NULL))) { sessions_del(rtp); start = rtp->next; } /* * Mark for deletion in 2 seconds, in order to give some * time to the extra ACK packets that might be exchanged */ if (sip->type & TYPE_UDP) sip->timeout = nids_last_pcap_header->ts.tv_sec + 2; } } } osip_message_free(msg); return sip; }