📄 spp_dns.c
字号:
*/ dnsSessionData = _dpd.streamAPI->get_application_data( p->stream_session_ptr, PP_DNS ); if ( !dnsSessionData ) { dnsSessionData = calloc( 1, sizeof( DNSSessionData )); if ( !dnsSessionData ) return NULL; /*Register the new DNS data block in the stream session. */ _dpd.streamAPI->set_application_data( p->stream_session_ptr, PP_DNS, dnsSessionData, FreeDNSSessionData ); } return dnsSessionData;}/* Registered as a callback with the DNS data when they are * added to the stream session. Called by stream when a * session is about to be destroyed to free that data. * * PARAMETERS: * * application_data: Pointer to the DNS data * * RETURNS: Nothing. */static void FreeDNSSessionData( void* application_data ){ DNSSessionData* dnsSessionData = (DNSSessionData*)application_data; if ( dnsSessionData ) { free( dnsSessionData ); }}/* Validates given port as an DNS server port. * * PARAMETERS: * * port: Port to validate. * * RETURNS: DNS_TRUE, if the port is indeed an DNS server port. * DNS_FALSE, otherwise. */static inline int CheckDNSPort( u_int16_t port ){ if ( dns_config.ports[ PORT_INDEX(port) ] & CONV_PORT( port ) ) { return 1; } return 0;}static u_int16_t ParseDNSHeader(const unsigned char *data, u_int16_t bytes_unused, DNSSessionData *dnsSessionData){ if (bytes_unused == 0) { return bytes_unused; } switch (dnsSessionData->state) { case DNS_RESP_STATE_LENGTH: /* First two bytes are length in TCP */ dnsSessionData->length = ((u_int8_t)*data) << 8; dnsSessionData->state = DNS_RESP_STATE_LENGTH_PART; data++; bytes_unused--; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_LENGTH_PART: dnsSessionData->length |= ((u_int8_t)*data); dnsSessionData->state = DNS_RESP_STATE_HDR_ID; data++; bytes_unused--; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_ID: dnsSessionData->hdr.id = (u_int8_t)*data << 8; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_ID_PART; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_ID_PART: dnsSessionData->hdr.id |= (u_int8_t)*data; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_FLAGS; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_FLAGS: dnsSessionData->hdr.flags = (u_int8_t)*data << 8; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_FLAGS_PART; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_FLAGS_PART: dnsSessionData->hdr.flags |= (u_int8_t)*data; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_QS; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_QS: dnsSessionData->hdr.questions = (u_int8_t)*data << 8; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_QS_PART; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_QS_PART: dnsSessionData->hdr.questions |= (u_int8_t)*data; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_ANSS; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_ANSS: dnsSessionData->hdr.answers = (u_int8_t)*data << 8; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_ANSS_PART; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_ANSS_PART: dnsSessionData->hdr.answers |= (u_int8_t)*data; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_AUTHS; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_AUTHS: dnsSessionData->hdr.authorities = (u_int8_t)*data << 8; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_AUTHS_PART; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_AUTHS_PART: dnsSessionData->hdr.authorities |= (u_int8_t)*data; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_ADDS; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_ADDS: dnsSessionData->hdr.additionals = (u_int8_t)*data << 8; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_HDR_ADDS_PART; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_HDR_ADDS_PART: dnsSessionData->hdr.additionals |= (u_int8_t)*data; data++; bytes_unused--; dnsSessionData->state = DNS_RESP_STATE_QUESTION; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ default: /* Continue -- we're beyond the header */ break; } return bytes_unused;}u_int16_t ParseDNSName(const unsigned char *data, u_int16_t bytes_unused, DNSSessionData *dnsSessionData){ u_int16_t bytes_required = dnsSessionData->curr_txt.txt_len - dnsSessionData->curr_txt.txt_bytes_seen; while (dnsSessionData->curr_txt.name_state != DNS_RESP_STATE_NAME_COMPLETE) { if (bytes_unused == 0) { return bytes_unused; } switch (dnsSessionData->curr_txt.name_state) { case DNS_RESP_STATE_NAME_SIZE: dnsSessionData->curr_txt.txt_len = (u_int8_t)*data; data++; bytes_unused--; dnsSessionData->bytes_seen_curr_rec++; if (dnsSessionData->curr_txt.txt_len == 0) { dnsSessionData->curr_txt.name_state = DNS_RESP_STATE_NAME_COMPLETE; return bytes_unused; } dnsSessionData->curr_txt.name_state = DNS_RESP_STATE_NAME; dnsSessionData->curr_txt.txt_bytes_seen = 0; if ((dnsSessionData->curr_txt.txt_len & DNS_RR_PTR) == DNS_RR_PTR) { /* A reference to another location... */ /* This is an offset */ dnsSessionData->curr_txt.offset = (dnsSessionData->curr_txt.txt_len & ~0xC0) << 8; bytes_required = dnsSessionData->curr_txt.txt_len = 1; dnsSessionData->curr_txt.relative = 1; /* Setup to read 2nd Byte of Location */ } else { bytes_required = dnsSessionData->curr_txt.txt_len; dnsSessionData->curr_txt.offset = 0; dnsSessionData->curr_txt.relative = 0; } if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_NAME: if (bytes_required <= bytes_unused) { bytes_unused -= bytes_required; if (dnsSessionData->curr_txt.relative) { /* If this one is a relative offset, read that extra byte */ dnsSessionData->curr_txt.offset |= *data; } data += bytes_required; dnsSessionData->bytes_seen_curr_rec += bytes_required; dnsSessionData->curr_txt.txt_bytes_seen += bytes_required; if (bytes_unused == 0) { return bytes_unused; } } else { dnsSessionData->bytes_seen_curr_rec+= bytes_unused; dnsSessionData->curr_txt.txt_bytes_seen += bytes_unused; return 0; } if (dnsSessionData->curr_txt.relative) { /* And since its relative, we're done */ dnsSessionData->curr_txt.name_state = DNS_RESP_STATE_NAME_COMPLETE; return bytes_unused; } break; } /* Go to the next portion of the name */ dnsSessionData->curr_txt.name_state = DNS_RESP_STATE_NAME_SIZE; } return bytes_unused;}static u_int16_t ParseDNSQuestion(const unsigned char *data, u_int16_t data_size, u_int16_t bytes_unused, DNSSessionData *dnsSessionData){ u_int16_t bytes_used = 0; u_int16_t new_bytes_unused = 0; if (bytes_unused == 0) { return bytes_unused; } if (dnsSessionData->curr_rec_state < DNS_RESP_STATE_Q_NAME_COMPLETE) { new_bytes_unused = ParseDNSName(data, bytes_unused, dnsSessionData); bytes_used = bytes_unused - new_bytes_unused; if (dnsSessionData->curr_txt.name_state == DNS_RESP_STATE_NAME_COMPLETE) { dnsSessionData->curr_rec_state = DNS_RESP_STATE_Q_TYPE; bzero(&dnsSessionData->curr_txt, sizeof(DNSNameState)); data = data + bytes_used; bytes_unused = new_bytes_unused; if (bytes_unused == 0) { /* ran out of data */ return bytes_unused; } } else { /* Should be 0 -- ran out of data */ return new_bytes_unused; } } switch (dnsSessionData->curr_rec_state) { case DNS_RESP_STATE_Q_TYPE: dnsSessionData->curr_q.type = (u_int8_t)*data << 8; data++; bytes_unused--; dnsSessionData->curr_rec_state = DNS_RESP_STATE_Q_TYPE_PART; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_Q_TYPE_PART: dnsSessionData->curr_q.type |= (u_int8_t)*data; data++; bytes_unused--; dnsSessionData->curr_rec_state = DNS_RESP_STATE_Q_CLASS; if (bytes_unused == 0) { return bytes_unused; } /* Fall through */ case DNS_RESP_STATE_Q_CLASS: dnsSessionData->curr_q.dns_class = (u_int8_t)*data << 8; data++; bytes_unused--; dnsSessionData->curr_rec_state = DNS_RESP_STATE_Q_CLASS_PART; if (bytes_unused == 0) { return bytes_unused; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -