+++ to secure your transactions use the Bitcoin Mixer Service +++

 

Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Parse and stores EDNS options
  • Loading branch information
bortzmeyer committed Jun 16, 2013
1 parent 6d2f16f commit 97c7ff1
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 53 deletions.
5 changes: 5 additions & 0 deletions DNSmezzo/packet-defs.h
Expand Up @@ -11,6 +11,9 @@
void
fatal(char *, ...);

/* Not in RFC 6891, it is an arbitrary limit we define */
#define MAX_EDNS_OPTIONS 10

struct dns_packet {
unsigned int rank;
struct timeval date;
Expand All @@ -30,6 +33,8 @@ struct dns_packet {
bool edns0;
unsigned int edns0_size; /* Undefined if edns0 is false */
bool do_dnssec; /* Undefined if edns0 is false */
unsigned int edns_options[MAX_EDNS_OPTIONS];
unsigned int num_edns_options;
unsigned int ancount, nscount, arcount;
};

Expand Down
130 changes: 80 additions & 50 deletions DNSmezzo/packets2postgresql.c
Expand Up @@ -95,7 +95,7 @@ escape(char *to, const char *from)
to[j++] = 't';
break;
case 92:
if (from[i+1] == '.') {
if (from[i + 1] == '.') {
to[j++] = '.';
i++;
}
Expand All @@ -116,34 +116,38 @@ escape(char *to, const char *from)
* http://coding.debuntu.org/c-implementing-str_replace-replace-all-occurrences-substring
* Licence: GPL v2+
*/
char *
str_replace ( const char *string, const char *substr, const char *replacement ){
char *tok = NULL;
char *newstr = NULL;
char *oldstr = NULL;
char *head = NULL;

/* if either substr or replacement is NULL, duplicate string a let caller handle it */
if ( substr == NULL || replacement == NULL ) return strdup (string);
newstr = strdup (string);
head = newstr;
while ( (tok = strstr ( head, substr ))){
oldstr = newstr;
newstr = malloc ( strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) + 1 );
/*failed to alloc mem, free old string and return NULL */
if ( newstr == NULL ){
free (oldstr);
return NULL;
char *
str_replace(const char *string, const char *substr, const char *replacement)
{
char *tok = NULL;
char *newstr = NULL;
char *oldstr = NULL;
char *head = NULL;

/* if either substr or replacement is NULL, duplicate string a let caller handle
* it */
if (substr == NULL || replacement == NULL)
return strdup(string);
newstr = strdup(string);
head = newstr;
while ((tok = strstr(head, substr))) {
oldstr = newstr;
newstr = malloc(strlen(oldstr) - strlen(substr) + strlen(replacement) + 1);
/* failed to alloc mem, free old string and return NULL */
if (newstr == NULL) {
free(oldstr);
return NULL;
}
memcpy(newstr, oldstr, tok - oldstr);
memcpy(newstr + (tok - oldstr), replacement, strlen(replacement));
memcpy(newstr + (tok - oldstr) + strlen(replacement), tok + strlen(substr),
strlen(oldstr) - strlen(substr) - (tok - oldstr));
memset(newstr + strlen(oldstr) - strlen(substr) + strlen(replacement), 0, 1);
/* move back head right after the last replacement */
head = newstr + (tok - oldstr) + strlen(replacement);
free(oldstr);
}
memcpy ( newstr, oldstr, tok - oldstr );
memcpy ( newstr + (tok - oldstr), replacement, strlen ( replacement ) );
memcpy ( newstr + (tok - oldstr) + strlen( replacement ), tok + strlen ( substr ), strlen ( oldstr ) - strlen ( substr ) - ( tok - oldstr ) );
memset ( newstr + strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) , 0, 1 );
/* move back head right after the last replacement */
head = newstr + (tok - oldstr) + strlen( replacement );
free (oldstr);
}
return newstr;
return newstr;
}

#define METADATA_INT 1
Expand Down Expand Up @@ -192,7 +196,7 @@ get_metadata(name, key, type)

#define SQL_PACKET_COMMAND "COPY DNS_Packets \
(file, rank, date, length, src_address, dst_address, protocol, src_port, dst_port, \
query, query_id, opcode, rcode, aa, tc, rd, ra, qname, qtype, qclass, edns0_size, do_dnssec, \
query, query_id, opcode, rcode, aa, tc, rd, ra, qname, qtype, qclass, edns0_size, do_dnssec, edns_options, \
ancount, nscount, arcount, registered_domain, lowercase_qname) FROM STDIN;"
#define PREPARED_PACKET_STMT "copy-data"
#define SQL_FILE_COMMAND "INSERT INTO Pcap_Files (hostname, filename, datalinktype, snaplength, filesize, filedate, stoppedat, samplingrate) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id;"
Expand Down Expand Up @@ -243,11 +247,13 @@ main(int argc, char *argv[])
PGresult *result;
struct tm file_creation, date_firstpacket, date_lastpacket;
int *sampling;
char *buffer, *bufptr, *tmp, *tmp2, *tmp3; /* SQL COPY input buffer */
char *buffer, *bufptr, *tmp, *tmp2, *tmp3; /* SQL COPY input
* buffer */
unsigned long copied;
const char *file_params[NUM_FILE_PARAMS];
const char *fileend_params[NUM_FILEEND_PARAMS];
unsigned int file_id = 0;
unsigned int i;

progname = argv[0];
while ((ch = getopt(argc, argv, "nvm:c:p")) != -1) {
Expand Down Expand Up @@ -301,9 +307,9 @@ main(int argc, char *argv[])
fatal(PQerrorMessage(conn));
}
/* We find lot of funny characters in domain names, not always UTF-8.
* Setting the client encoding to Latin-1 is arbitrary, but it is to
* be sure the program won't crash (because any string is valid
* Latin-1, unlike UTF-8). */
* Setting the client encoding to Latin-1 is arbitrary, but it is to be sure
* * the program won't crash (because any string is valid Latin-1, unlike
* UTF-8). */
result = PQexec(conn, "SET CLIENT_ENCODING TO 'LATIN-1';");
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
fatal("Cannot set encoding");
Expand Down Expand Up @@ -399,18 +405,18 @@ main(int argc, char *argv[])
fatal("Cannot malloc %i bytes for the COPY input buffer", BUFFER_SIZE);
}
bufptr = buffer;
if (! dry_run) {
PQclear(result);
result = PQexecPrepared(conn, PREPARED_PACKET_STMT, 0, NULL, NULL, NULL, 0);
if (PQresultStatus(result) == PGRES_COPY_IN) {
/* OK */
} else {
fatal("Result for '%s' is %s", SQL_PACKET_COMMAND,
PQresultErrorMessage(result));
if (!dry_run) {
PQclear(result);
result = PQexecPrepared(conn, PREPARED_PACKET_STMT, 0, NULL, NULL, NULL, 0);
if (PQresultStatus(result) == PGRES_COPY_IN) {
/* OK */
} else {
fatal("Result for '%s' is %s", SQL_PACKET_COMMAND,
PQresultErrorMessage(result));
}
}
}
// read TLDs only once at daemon startup
tldnode* tree = readTldTree(tldString);
tldnode *tree = readTldTree(tldString);

tmp = malloc(MAX_STRING);
tmp2 = malloc(MAX_STRING);
Expand Down Expand Up @@ -499,9 +505,27 @@ main(int argc, char *argv[])
bufptr += strlen(packet->do_dnssec ? "true" : "false");
*bufptr = '\t';
bufptr++;
if (packet->num_edns_options > 0) {
strcpy(bufptr, "{");
bufptr += strlen("{");
for (i = 0; i < packet->num_edns_options; i++) {
sprintf(tmp, "%i", packet->edns_options[i]);
strcpy(bufptr, tmp);
bufptr += strlen(tmp);
if (i < (packet->num_edns_options - 1)) {
strcpy(bufptr, ",");
bufptr++;
}
}
strcpy(bufptr, "}\t");
bufptr += strlen("}\t");
} else {
strcpy(bufptr, "\\N\t");
bufptr += strlen("\\N\t");
}
} else {
strcpy(bufptr, "\\N\t\\N\t");
bufptr += strlen("\\N\t\\N\t");
strcpy(bufptr, "\\N\t\\N\t\\N\t");
bufptr += strlen("\\N\t\\N\t\\N\t");
}
sprintf(tmp, "%i\t", packet->ancount);
strcpy(bufptr, tmp);
Expand All @@ -518,7 +542,7 @@ main(int argc, char *argv[])
} else {
tmp3 = NULL;
}
if (tmp3 == NULL) { /* this is already a TLD */
if (tmp3 == NULL) { /* this is already a TLD */
escape(tmp, tmp2);
} else {
escape(tmp, tmp3);
Expand Down Expand Up @@ -564,13 +588,17 @@ main(int argc, char *argv[])
if (copied != 1) {
fatal("Cannot end the data stream: %s", PQerrorMessage(conn));
}
result = PQgetResult(conn);
if (result != NULL && strcmp(PQerrorMessage(conn), "") != 0) {
fatal("COPY of data failed: %s.", PQerrorMessage(conn));
}
}
if (verbose) {
ct = current_time();
fprintf(stdout, "%s Done, %lu DNS packets stored%s\n",
ct, packetnum, (maxpackets > 0
&& packetnum >=
maxpackets) ?
&& packetnum >=
maxpackets) ?
" - interrupted before the end because max packets read" : "");
free(ct);
}
Expand Down Expand Up @@ -619,15 +647,17 @@ main(int argc, char *argv[])
result = PQexec(conn, tmp);
free(tmp);
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
fatal("Error while creating the UNIQUE(id) constraint: %s", PQresultErrorMessage(result));
fatal("Error while creating the UNIQUE(id) constraint: %s",
PQresultErrorMessage(result));
}
PQclear(result);

tmp = str_replace(SQL_CREATE_CONSTRAINT_REF_FILE, "TABLE_NAME", table_name);
result = PQexec(conn, tmp);
free(tmp);
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
fatal("Error while creating the foreign key (file) constraint: %s", PQresultErrorMessage(result));
fatal("Error while creating the foreign key (file) constraint: %s",
PQresultErrorMessage(result));
}
PQclear(result);

Expand Down
36 changes: 33 additions & 3 deletions DNSmezzo/pcap-parse.c
Expand Up @@ -108,6 +108,9 @@ get_next_packet(struct dns_packet *decoded, pcap_parser_file * input)
uint16_t edns_size;
uint16_t extended_rcode_and_version;
uint16_t zpart;
uint num_edns_options = 0;
uint16_t opt_len, option_code, option_length;
uint16_t option_codes[MAX_EDNS_OPTIONS];
const uint8_t *sectionptr;
const uint8_t *where_am_i; /* Cursor in packet */
bool end_of_name;
Expand Down Expand Up @@ -382,9 +385,36 @@ get_next_packet(struct dns_packet *decoded, pcap_parser_file * input)
DNS_DO_DNSSEC(zpart) ? true : false;
}
sectionptr += 2;
/* TODO: dissect the RDATA to find things like the
* option code (such as 3 for NSID)
* http://www.iana.org/assignments/dns-parameters */
CHECK_SECTIONPTR(2);
#ifdef PICKY_WITH_ALIGNMENT
opt_len = unaligned_uint16(sectionptr);
#else
opt_len = ntohs(*((uint16_t *) sectionptr));
#endif
sectionptr += 2;
while (opt_len > 0
&& num_edns_options < MAX_EDNS_OPTIONS) {
CHECK_SECTIONPTR(2);
#ifdef PICKY_WITH_ALIGNMENT
option_code = unaligned_uint16(sectionptr);
#else
option_code = ntohs(*((uint16_t *) sectionptr));
#endif
option_codes[num_edns_options] = option_code;
sectionptr += 2;
CHECK_SECTIONPTR(2);
#ifdef PICKY_WITH_ALIGNMENT
option_length = unaligned_uint16(sectionptr);
#else
option_length = ntohs(*((uint16_t *) sectionptr));
#endif
opt_len -= (option_length + 4);
num_edns_options++;
sectionptr += option_length;
}
memcpy(decoded->edns_options, option_codes,
num_edns_options * sizeof(option_code));
decoded->num_edns_options = num_edns_options;
}
}
}
Expand Down

0 comments on commit 97c7ff1

Please sign in to comment.