/**************************************************************************** ** File: ns_labels.c ** ** Author: Mike Borella ** ** Comments: Encapsulation for ugly NS label manipulation ** ** $Id: ns_labels.c,v 1.3 2000/08/29 21:59:02 mborella Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU Library General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** *****************************************************************************/ #include "ns_labels.h" #define NUM_LABELS 128 int current_label = -1; ns_label_t nslabels[NUM_LABELS]; /*---------------------------------------------------------------------------- ** ** reset_nslabels() ** ** Initialize the NS labels structures ** **---------------------------------------------------------------------------- */ void reset_nslabels(void) { int i; current_label = -1; for (i=0; i= 0) { strcat(s, "."); get_nslabel(nslabels[nslabels[i].next].offset, s+strlen(s)); } strcat(s, "\0"); break; } } /*---------------------------------------------------------------------------- ** ** parse_ns_labels() ** ** Recursively parse a label entry in a DNS packet. We assume that the ** current byte of the packet points to the first label count. Store ** the DNS name in the string passed in, and let's assume that this string ** is big enough. ** **---------------------------------------------------------------------------- */ void parse_ns_labels(packet_t *pkt, char *name) { u_int8_t count; u_int16_t offset; int read_a_label = 0; char label[MAX_LABEL_SIZE]; int first_offset = 0; while(1) { if (get_packet_bytes((u_int8_t *) &count, pkt, 1) == 0) return; /* * A count of 0 indicates an "end of string", so quit */ if (count == 0) break; /* * Make sure that we don't run past the ned of label space in * our structure - this should NOT be an issue, but if for some * reason it is, it will cause *nasty* bugs... */ if (count > MAX_LABEL_SIZE && count < 192) count = MAX_LABEL_SIZE; /* * This is a new label, so let's mark it as such */ if (read_a_label) set_nslabel_next(); new_nslabel(); if (!first_offset) { first_offset = get_packet_markdistance(pkt)-1; } set_nslabel_offset(get_packet_markdistance(pkt)-1); /* * A count > 192 indicates a pointer. What an ugly way of * saving a few bytes */ if (count >= 192) { /* * There's a pointer in this label. Sigh. Let's grab the * 14 low-order bits and run with them... */ offset = count - 192; offset = offset << 8; if (get_packet_bytes((u_int8_t *) &count, pkt, 1) == 0) return; offset = offset + count; get_nslabel(offset, name); set_nslabel_label(name); return; } /* * This is normal behavior, if anything is "normal" for DNS. * Grab count bytes and stick them in the label string, follow it * up with a "." to separate the hierarchy */ if (get_packet_bytes((u_int8_t *) &label, pkt, count ) == 0) return; label[count] = '\0'; set_nslabel_label(label); read_a_label = 1; } get_nslabel(first_offset, name); return; }