📄 trace.c
字号:
slen + TRACE_INDEX_MAPPING_SIZE, (char *)tim, file, line); dfree (tim, file, line); return status;}/* Stop all registered trace types from trying to trace. */void trace_stop (void){ int i; for (i = 0; i < trace_type_count; i++) if (trace_types [i] -> stop_tracing) (*(trace_types [i] -> stop_tracing)) (trace_types [i]); tracing_stopped = 1;}void trace_index_map_input (trace_type_t *ttype, unsigned length, char *buf){ trace_index_mapping_t *tmap; unsigned len; trace_type_t *tptr, **prev; if (length < TRACE_INDEX_MAPPING_SIZE) { log_error ("short trace index mapping"); return; } tmap = (trace_index_mapping_t *)buf; prev = &new_trace_types; for (tptr = new_trace_types; tptr; tptr = tptr -> next) { len = strlen (tptr -> name); if (len == length - TRACE_INDEX_MAPPING_SIZE && !memcmp (tptr -> name, tmap -> name, len)) { tptr -> index = ntohl (tmap -> index); trace_type_stash (tptr); *prev = tptr -> next; return; } prev = &tptr -> next; } log_error ("No registered trace type for type name %.*s", (int)length - TRACE_INDEX_MAPPING_SIZE, tmap -> name); return;}void trace_index_stop_tracing (trace_type_t *ttype) { }void trace_replay_init (void){ trace_playback_flag = 1;}void trace_file_replay (const char *filename){ tracepacket_t *tpkt = (tracepacket_t *)0; int status; char *buf = (char *)0; unsigned buflen; unsigned bufmax = 0; trace_type_t *ttype = (trace_type_t *)0; isc_result_t result; int len; traceinfile = fopen (filename, "r"); if (!traceinfile) { log_error ("Can't open tracefile %s: %m", filename); return; }#if defined (HAVE_SETFD) if (fcntl (fileno (traceinfile), F_SETFD, 1) < 0) log_error ("Can't set close-on-exec on %s: %m", filename);#endif status = fread (&tracefile_header, 1, sizeof tracefile_header, traceinfile); if (status < sizeof tracefile_header) { if (ferror (traceinfile)) log_error ("Error reading trace file header: %m"); else log_error ("Short read on trace file header: %d %ld.", status, (long)(sizeof tracefile_header)); goto out; } tracefile_header.magic = ntohl (tracefile_header.magic); tracefile_header.version = ntohl (tracefile_header.version); tracefile_header.hlen = ntohl (tracefile_header.hlen); tracefile_header.phlen = ntohl (tracefile_header.phlen); if (tracefile_header.magic != TRACEFILE_MAGIC) { log_error ("%s: not a dhcp trace file.", filename); goto out; } if (tracefile_header.version > TRACEFILE_VERSION) { log_error ("tracefile version %ld > current %ld.", (long int)tracefile_header.version, (long int)TRACEFILE_VERSION); goto out; } if (tracefile_header.phlen < sizeof *tpkt) { log_error ("tracefile packet size too small - %ld < %ld", (long int)tracefile_header.phlen, (long int)sizeof *tpkt); goto out; } len = (sizeof tracefile_header) - tracefile_header.hlen; if (len < 0) { log_error ("tracefile header size too small - %ld < %ld", (long int)tracefile_header.hlen, (long int)sizeof tracefile_header); goto out; } if (len > 0) { status = fseek (traceinfile, (long)len, SEEK_CUR); if (status < 0) { log_error ("can't seek past header: %m"); goto out; } } tpkt = dmalloc ((unsigned)tracefile_header.phlen, MDL); if (!tpkt) { log_error ("can't allocate trace packet header."); goto out; } while ((result = trace_get_next_packet (&ttype, tpkt, &buf, &buflen, &bufmax)) == ISC_R_SUCCESS) { (*ttype -> have_packet) (ttype, tpkt -> length, buf); ttype = (trace_type_t *)0; } out: fclose (traceinfile); if (buf) dfree (buf, MDL); if (tpkt) dfree (tpkt, MDL);}/* Get the next packet from the file. If ttp points to a nonzero pointer to a trace type structure, check the next packet to see if it's of the expected type, and back off if not. */isc_result_t trace_get_next_packet (trace_type_t **ttp, tracepacket_t *tpkt, char **buf, unsigned *buflen, unsigned *bufmax){ trace_type_t *ttype; unsigned paylen; int status; int len; fpos_t curpos; status = fgetpos (traceinfile, &curpos); if (status < 0) log_error ("Can't save tracefile position: %m"); status = fread (tpkt, 1, (size_t)tracefile_header.phlen, traceinfile); if (status < tracefile_header.phlen) { if (ferror (traceinfile)) log_error ("Error reading trace packet header: %m"); else if (status == 0) return ISC_R_EOF; else log_error ("Short read on trace packet header: " "%ld %ld.", (long int)status, (long int)tracefile_header.phlen); return ISC_R_PROTOCOLERROR; } /* Swap the packet. */ tpkt -> type_index = ntohl (tpkt -> type_index); tpkt -> length = ntohl (tpkt -> length); tpkt -> when = ntohl (tpkt -> when); /* See if there's a handler for this packet type. */ if (tpkt -> type_index < trace_type_count && trace_types [tpkt -> type_index]) ttype = trace_types [tpkt -> type_index]; else { log_error ("Trace packet with unknown index %ld", (long int)tpkt -> type_index); return ISC_R_PROTOCOLERROR; } /* If we were just hunting for the time marker, we've found it, so back up to the beginning of the packet and return its type. */ if (ttp && *ttp == &trace_time_marker) { *ttp = ttype; status = fsetpos (traceinfile, &curpos); if (status < 0) { log_error ("fsetpos in tracefile failed: %m"); return ISC_R_PROTOCOLERROR; } return ISC_R_EXISTS; } /* If we were supposed to get a particular kind of packet, check to see that we got the right kind. */ if (ttp && *ttp && ttype != *ttp) { log_error ("Read packet type %s when expecting %s", ttype -> name, (*ttp) -> name); status = fsetpos (traceinfile, &curpos); if (status < 0) { log_error ("fsetpos in tracefile failed: %m"); return ISC_R_PROTOCOLERROR; } return ISC_R_UNEXPECTEDTOKEN; } paylen = tpkt -> length; if (paylen % 8) paylen += 8 - (tpkt -> length % 8); if (paylen > (*bufmax)) { if ((*buf)) dfree ((*buf), MDL); (*bufmax) = ((paylen + 1023) & ~1023U); (*buf) = dmalloc ((*bufmax), MDL); if (!(*buf)) { log_error ("Can't allocate input buffer sized %d", (*bufmax)); return ISC_R_NOMEMORY; } } status = fread ((*buf), 1, paylen, traceinfile); if (status < paylen) { if (ferror (traceinfile)) log_error ("Error reading trace payload: %m"); else log_error ("Short read on trace payload: %d %d.", status, paylen); return ISC_R_PROTOCOLERROR; } /* Store the actual length of the payload. */ *buflen = tpkt -> length; if (trace_set_time_hook) (*trace_set_time_hook) (tpkt -> when); if (ttp) *ttp = ttype; return ISC_R_SUCCESS;}isc_result_t trace_get_packet (trace_type_t **ttp, unsigned *buflen, char **buf){ tracepacket_t *tpkt; unsigned bufmax = 0; isc_result_t status; if (!buf || *buf) return ISC_R_INVALIDARG; tpkt = dmalloc ((unsigned)tracefile_header.phlen, MDL); if (!tpkt) { log_error ("can't allocate trace packet header."); return ISC_R_NOMEMORY; } status = trace_get_next_packet (ttp, tpkt, buf, buflen, &bufmax); dfree (tpkt, MDL); return status;}time_t trace_snoop_time (trace_type_t **ptp){ tracepacket_t *tpkt; unsigned bufmax = 0; unsigned buflen = 0; char *buf = (char *)0; isc_result_t status; time_t result; trace_type_t *ttp; if (!ptp) ptp = &ttp; tpkt = dmalloc ((unsigned)tracefile_header.phlen, MDL); if (!tpkt) { log_error ("can't allocate trace packet header."); return ISC_R_NOMEMORY; } *ptp = &trace_time_marker; trace_get_next_packet (ptp, tpkt, &buf, &buflen, &bufmax); result = tpkt -> when; dfree (tpkt, MDL); return result;}/* Get a packet from the trace input file that contains a file with the specified name. We don't hunt for the packet - it should be the next packet in the tracefile. If it's not, or something else bad happens, return an error code. */isc_result_t trace_get_file (trace_type_t *ttype, const char *filename, unsigned *len, char **buf){ fpos_t curpos; unsigned max = 0; tracepacket_t *tpkt; int status; isc_result_t result; /* Disallow some obvious bogosities. */ if (!buf || !len || *buf) return ISC_R_INVALIDARG; /* Save file position in case of filename mismatch. */ status = fgetpos (traceinfile, &curpos); if (status < 0) log_error ("Can't save tracefile position: %m"); tpkt = dmalloc ((unsigned)tracefile_header.phlen, MDL); if (!tpkt) { log_error ("can't allocate trace packet header."); return ISC_R_NOMEMORY; } result = trace_get_next_packet (&ttype, tpkt, buf, len, &max); if (result != ISC_R_SUCCESS) { dfree (tpkt, MDL); if (*buf) dfree (*buf, MDL); return result; } /* Make sure the filename is right. */ if (strcmp (filename, *buf)) { log_error ("Read file %s when expecting %s", *buf, filename); status = fsetpos (traceinfile, &curpos); if (status < 0) { log_error ("fsetpos in tracefile failed: %m"); dfree (tpkt, MDL); dfree (*buf, MDL); return ISC_R_PROTOCOLERROR; } return ISC_R_UNEXPECTEDTOKEN; } dfree (tpkt, MDL); return ISC_R_SUCCESS;}#endif /* TRACING */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -