147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* -*- Mode: C; tab-width: 4 -*- 247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved. 447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * you may not use this file except in compliance with the License. 747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * You may obtain a copy of the License at 847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 1047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 1147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Unless required by applicable law or agreed to in writing, software 1247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 1347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * See the License for the specific language governing permissions and 1547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * limitations under the License. 1647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 1747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Formatting notes: 1847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * This code follows the "Whitesmiths style" C indentation rules. Plenty of discussion 1947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * on C indentation can be found on the web, such as <http://www.kafejo.com/komp/1tbs.htm>, 2047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * but for the sake of brevity here I will say just this: Curly braces are not syntactially 2147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * part of an "if" statement; they are the beginning and ending markers of a compound statement; 2247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * therefore common sense dictates that if they are part of a compound statement then they 2347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * should be indented to the same level as everything else in that compound statement. 2447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Indenting curly braces at the same level as the "if" implies that curly braces are 2547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * part of the "if", which is false. (This is as misleading as people who write "char* x,y;" 2647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * thinking that variables x and y are both of type "char*" -- and anyone who doesn't 2747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * understand why variable y is not of type "char*" just proves the point that poor code 2847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * layout leads people to unfortunate misunderstandings about how the C language really works.) 2947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 3047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 3147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//************************************************************************************************************* 3247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Incorporate mDNS.c functionality 3347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 3447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// We want to use much of the functionality provided by "mDNS.c", 3547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// except we'll steal the packets that would be sent to normal mDNSCoreReceive() routine 3647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define mDNSCoreReceive __NOT__mDNSCoreReceive__NOT__ 3747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "mDNS.c" 3847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#undef mDNSCoreReceive 3947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 4047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//************************************************************************************************************* 4147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Headers 4247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 4347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <stdio.h> // For printf() 4447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <stdlib.h> // For malloc() 4547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <string.h> // For strrchr(), strcmp() 4647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <time.h> // For "struct tm" etc. 4747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <signal.h> // For SIGINT, SIGTERM 4847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined(WIN32) 4947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Both mDNS.c and mDNSWin32.h declare UDPSocket_struct type resulting in a compile-time error, so 5047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// trick the compiler when including mDNSWin32.h 5147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# define UDPSocket_struct _UDPSocket_struct 5247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# include <mDNSEmbeddedAPI.h> 5347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# include <mDNSWin32.h> 5447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# include <PosixCompat.h> 5547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# define IFNAMSIZ 256 5647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic HANDLE gStopEvent = INVALID_HANDLE_VALUE; 5747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent ) { SetEvent( gStopEvent ); return TRUE; } 5847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid setlinebuf( FILE * fp ) {} 5947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#else 6047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# include <netdb.h> // For gethostbyname() 6147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# include <sys/socket.h> // For AF_INET, AF_INET6, etc. 6247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# include <net/if.h> // For IF_NAMESIZE 6347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# include <netinet/in.h> // For INADDR_NONE 6447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# include <arpa/inet.h> // For inet_addr() 6547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# include "mDNSPosix.h" // Defines the specific types needed to run mDNS on this platform 6647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 6747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "ExampleClientApp.h" 6847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 6947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//************************************************************************************************************* 7047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Types and structures 7147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 7247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltenum 7347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 7447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Primitive operations 7547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_probe = 0, 7647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_goodbye = 1, 7747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 7847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // These are meta-categories; 7947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Query and Answer operations are actually subdivided into two classes: 8047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Browse query/answer and 8147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Resolve query/answer 8247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_query = 2, 8347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_answer = 3, 8447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 8547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // The "Browse" variants of query/answer 8647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_browsegroup = 2, 8747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_browseq = 2, 8847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_browsea = 3, 8947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 9047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // The "Resolve" variants of query/answer 9147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_resolvegroup = 4, 9247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_resolveq = 4, 9347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_resolvea = 5, 9447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 9547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt OP_NumTypes = 6 9647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt }; 9747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 9847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct ActivityStat_struct ActivityStat; 9947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstruct ActivityStat_struct 10047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 10147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ActivityStat *next; 10247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domainname srvtype; 10347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int printed; 10447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int totalops; 10547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int stat[OP_NumTypes]; 10647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt }; 10747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 10847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct FilterList_struct FilterList; 10947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstruct FilterList_struct 11047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 11147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt FilterList *next; 11247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSAddr FilterAddr; 11347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt }; 11447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 11547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//************************************************************************************************************* 11647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Constants 11747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 11847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define kReportTopServices 15 11947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define kReportTopHosts 15 12047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 12147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//************************************************************************************************************* 12247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Globals 12347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 12447e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNS mDNSStorage; // mDNS core uses this to store its globals 12547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic mDNS_PlatformSupport PlatformStorage; // Stores this platform's globals 12647e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport const char ProgramName[] = "mDNSNetMonitor"; 12747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 12847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstruct timeval tv_start, tv_end, tv_interval; 12947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int FilterInterface = 0; 13047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic FilterList *Filters; 13147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define ExactlyOneFilter (Filters && !Filters->next) 13247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 13347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int NumPktQ, NumPktL, NumPktR, NumPktB; // Query/Legacy/Response/Bad 13447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int NumProbes, NumGoodbyes, NumQuestions, NumLegacy, NumAnswers, NumAdditionals; 13547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 13647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic ActivityStat *stats; 13747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 13847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define OPBanner "Total Ops Probe Goodbye BrowseQ BrowseA ResolveQ ResolveA" 13947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 14047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//************************************************************************************************************* 14147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Utilities 14247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 14347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Special version of printf that knows how to print IP addresses, DNS-format name strings, etc. 14447e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal mDNSu32 mprintf(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2); 14547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal mDNSu32 mprintf(const char *format, ...) 14647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 14747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu32 length; 14847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt unsigned char buffer[512]; 14947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt va_list ptr; 15047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt va_start(ptr,format); 15147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt length = mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr); 15247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt va_end(ptr); 15347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt printf("%s", buffer); 15447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return(length); 15547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 15647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 15747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//************************************************************************************************************* 15847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Host Address List 15947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// 16047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Would benefit from a hash 16147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 16247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef enum 16347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 16447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostPkt_Q = 0, // Query 16547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostPkt_L = 1, // Legacy Query 16647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostPkt_R = 2, // Response 16747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostPkt_B = 3, // Bad 16847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostPkt_NumTypes = 4 16947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } HostPkt_Type; 17047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 17147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct 17247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 17347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSAddr addr; 17447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt unsigned long pkts[HostPkt_NumTypes]; 17547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt unsigned long totalops; 17647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt unsigned long stat[OP_NumTypes]; 17747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domainname hostname; 17847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domainname revname; 17947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt UTF8str255 HIHardware; 18047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt UTF8str255 HISoftware; 18147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu32 NumQueries; 18247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSs32 LastQuery; 18347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } HostEntry; 18447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 18547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HostEntryTotalPackets(H) ((H)->pkts[HostPkt_Q] + (H)->pkts[HostPkt_L] + (H)->pkts[HostPkt_R] + (H)->pkts[HostPkt_B]) 18647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 18747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct 18847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 18947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt long num; 19047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt long max; 19147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntry *hosts; 19247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } HostList; 19347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 19447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic HostList IPv4HostList = { 0, 0, 0 }; 19547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic HostList IPv6HostList = { 0, 0, 0 }; 19647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 19747e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal HostEntry *FindHost(const mDNSAddr *addr, HostList *list) 19847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 19947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt long i; 20047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 20147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i = 0; i < list->num; i++) 20247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 20347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntry *entry = list->hosts + i; 20447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (mDNSSameAddress(addr, &entry->addr)) 20547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return entry; 20647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 20747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 20847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 20947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 21047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 21147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal HostEntry *AddHost(const mDNSAddr *addr, HostList *list) 21247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 21347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 21447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntry *entry; 21547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (list->num >= list->max) 21647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 21747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt long newMax = list->max + 64; 21847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntry *newHosts = realloc(list->hosts, newMax * sizeof(HostEntry)); 21947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (newHosts == NULL) 22047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 22147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt list->max = newMax; 22247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt list->hosts = newHosts; 22347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 22447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 22547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry = list->hosts + list->num++; 22647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 22747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->addr = *addr; 22847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<HostPkt_NumTypes; i++) entry->pkts[i] = 0; 22947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->totalops = 0; 23047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<OP_NumTypes; i++) entry->stat[i] = 0; 23147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->hostname.c[0] = 0; 23247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->revname.c[0] = 0; 23347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->HIHardware.c[0] = 0; 23447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->HISoftware.c[0] = 0; 23547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->NumQueries = 0; 23647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 23747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry->addr.type == mDNSAddrType_IPv4) 23847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 23947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSv4Addr ip = entry->addr.ip.v4; 24047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char buffer[32]; 24147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code 24247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNS_snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.in-addr.arpa.", ip.b[3], ip.b[2], ip.b[1], ip.b[0]); 24347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt MakeDomainNameFromDNSNameString(&entry->revname, buffer); 24447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 24547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 24647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return(entry); 24747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 24847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 24947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal HostEntry *GotPacketFromHost(const mDNSAddr *addr, HostPkt_Type t, mDNSOpaque16 id) 25047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 25147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (ExactlyOneFilter) return(NULL); 25247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 25347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 25447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostList *list = (addr->type == mDNSAddrType_IPv4) ? &IPv4HostList : &IPv6HostList; 25547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntry *entry = FindHost(addr, list); 25647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!entry) entry = AddHost(addr, list); 25747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!entry) return(NULL); 25847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Don't count our own interrogation packets 25947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (id.NotAnInteger != 0xFFFF) entry->pkts[t]++; 26047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return(entry); 26147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 26247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 26347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 26447e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void RecordHostInfo(HostEntry *entry, const ResourceRecord *const pktrr) 26547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 26647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!entry->hostname.c[0]) 26747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 26847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (pktrr->rrtype == kDNSType_A || pktrr->rrtype == kDNSType_AAAA) 26947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 27047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Should really check that the rdata in the address record matches the source address of this packet 27147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->NumQueries = 0; 27247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt AssignDomainName(&entry->hostname, pktrr->name); 27347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 27447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 27547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (pktrr->rrtype == kDNSType_PTR) 27647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (SameDomainName(&entry->revname, pktrr->name)) 27747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 27847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->NumQueries = 0; 27947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt AssignDomainName(&entry->hostname, &pktrr->rdata->u.name); 28047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 28147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 28247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (pktrr->rrtype == kDNSType_HINFO) 28347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 28447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt RDataBody *rd = &pktrr->rdata->u; 28547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *rdend = (mDNSu8 *)rd + pktrr->rdlength; 28647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *hw = rd->txt.c; 28747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *sw = hw + 1 + (mDNSu32)hw[0]; 28847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (sw + 1 + sw[0] <= rdend) 28947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 29047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt AssignDomainName(&entry->hostname, pktrr->name); 29147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSPlatformMemCopy(entry->HIHardware.c, hw, 1 + (mDNSu32)hw[0]); 29247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSPlatformMemCopy(entry->HISoftware.c, sw, 1 + (mDNSu32)sw[0]); 29347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 29447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 29547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 29647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 29747e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void SendUnicastQuery(mDNS *const m, HostEntry *entry, domainname *name, mDNSu16 rrtype, mDNSInterfaceID InterfaceID) 29847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 29947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSOpaque16 id = { { 0xFF, 0xFF } }; 30047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSMessage query; 30147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *qptr = query.data; 30247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *const limit = query.data + sizeof(query.data); 30347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSAddr *target = &entry->addr; 30447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt InitializeDNSMessage(&query.h, id, QueryFlags); 30547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt qptr = putQuestion(&query, qptr, limit, name, rrtype, kDNSClass_IN); 30647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->LastQuery = m->timenow; 30747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->NumQueries++; 30847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 30947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Note: When there are multiple mDNSResponder agents running on a single machine 31047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // (e.g. Apple mDNSResponder plus a SliMP3 server with embedded mDNSResponder) 31147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // it is possible that unicast queries may not go to the primary system responder. 31247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // We try the first query using unicast, but if that doesn't work we try again via multicast. 31347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry->NumQueries > 2) 31447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 31547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt target = &AllDNSLinkGroup_v4; 31647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 31747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 31847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 31947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt //mprintf("%#a Q\n", target); 32047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt InterfaceID = mDNSInterface_Any; // Send query from our unicast reply socket 32147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 32247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 32347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSSendDNSMessage(&mDNSStorage, &query, qptr, InterfaceID, mDNSNULL, target, MulticastDNSPort, mDNSNULL, mDNSNULL); 32447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 32547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 32647e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void AnalyseHost(mDNS *const m, HostEntry *entry, const mDNSInterfaceID InterfaceID) 32747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 32847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // If we've done four queries without answer, give up 32947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry->NumQueries >= 4) return; 33047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 33147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // If we've done a query in the last second, give the host a chance to reply before trying again 33247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry->NumQueries && m->timenow - entry->LastQuery < mDNSPlatformOneSecond) return; 33347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 33447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // If we don't know the host name, try to find that first 33547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!entry->hostname.c[0]) 33647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 33747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry->revname.c[0]) 33847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 33947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt SendUnicastQuery(m, entry, &entry->revname, kDNSType_PTR, InterfaceID); 34047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt //mprintf("%##s PTR %d\n", entry->revname.c, entry->NumQueries); 34147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 34247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 34347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // If we have the host name but no HINFO, now ask for that 34447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (!entry->HIHardware.c[0]) 34547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 34647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt SendUnicastQuery(m, entry, &entry->hostname, kDNSType_HINFO, InterfaceID); 34747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt //mprintf("%##s HINFO %d\n", entry->hostname.c, entry->NumQueries); 34847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 34947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 35047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 35147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal int CompareHosts(const void *p1, const void *p2) 35247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 35347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return (int)(HostEntryTotalPackets((HostEntry *)p2) - HostEntryTotalPackets((HostEntry *)p1)); 35447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 35547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 35647e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void ShowSortedHostList(HostList *list, int max) 35747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 35847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntry *e, *end = &list->hosts[(max < list->num) ? max : list->num]; 35947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt qsort(list->hosts, list->num, sizeof(HostEntry), CompareHosts); 36047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (list->num) mprintf("\n%-25s%s%s\n", "Source Address", OPBanner, " Pkts Query LegacyQ Response"); 36147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (e = &list->hosts[0]; e < end; e++) 36247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 36347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int len = mprintf("%#-25a", &e->addr); 36447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (len > 25) mprintf("\n%25s", ""); 36547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("%8lu %8lu %8lu %8lu %8lu %8lu %8lu", e->totalops, 36647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt e->stat[OP_probe], e->stat[OP_goodbye], 36747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt e->stat[OP_browseq], e->stat[OP_browsea], 36847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt e->stat[OP_resolveq], e->stat[OP_resolvea]); 36947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf(" %8lu %8lu %8lu %8lu", 37047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntryTotalPackets(e), e->pkts[HostPkt_Q], e->pkts[HostPkt_L], e->pkts[HostPkt_R]); 37147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (e->pkts[HostPkt_B]) mprintf("Bad: %8lu", e->pkts[HostPkt_B]); 37247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n"); 37347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!e->HISoftware.c[0] && e->NumQueries > 2) 37447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSPlatformMemCopy(&e->HISoftware, "\x27*** Unknown (Jaguar, Windows, etc.) ***", 0x28); 37547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (e->hostname.c[0] || e->HIHardware.c[0] || e->HISoftware.c[0]) 37647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("%##-45s %#-14s %#s\n", e->hostname.c, e->HIHardware.c, e->HISoftware.c); 37747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 37847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 37947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 38047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//************************************************************************************************************* 38147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Receive and process packets 38247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 38347e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport mDNSBool ExtractServiceType(const domainname *const fqdn, domainname *const srvtype) 38447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 38547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i, len; 38647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *src = fqdn->c; 38747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *dst = srvtype->c; 38847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 38947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len = *src; 39047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (len == 0 || len >= 0x40) return(mDNSfalse); 39147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (src[1] != '_') src += 1 + len; 39247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 39347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len = *src; 39447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (len == 0 || len >= 0x40 || src[1] != '_') return(mDNSfalse); 39547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<=len; i++) *dst++ = *src++; 39647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 39747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len = *src; 39847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (len == 0 || len >= 0x40 || src[1] != '_') return(mDNSfalse); 39947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<=len; i++) *dst++ = *src++; 40047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 40147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *dst++ = 0; // Put the null root label on the end of the service type 40247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 40347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return(mDNStrue); 40447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 40547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 40647e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void recordstat(HostEntry *entry, const domainname *fqdn, int op, mDNSu16 rrtype) 40747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 40847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ActivityStat **s = &stats; 40947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domainname srvtype; 41047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 41147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (op != OP_probe) 41247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 41347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (rrtype == kDNSType_SRV || rrtype == kDNSType_TXT) op = op - OP_browsegroup + OP_resolvegroup; 41447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (rrtype != kDNSType_PTR) return; 41547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 41647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 41747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ExtractServiceType(fqdn, &srvtype)) return; 41847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 41947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (*s && !SameDomainName(&(*s)->srvtype, &srvtype)) s = &(*s)->next; 42047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!*s) 42147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 42247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 42347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *s = malloc(sizeof(ActivityStat)); 42447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!*s) exit(-1); 42547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (*s)->next = NULL; 42647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (*s)->srvtype = srvtype; 42747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (*s)->printed = 0; 42847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (*s)->totalops = 0; 42947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<OP_NumTypes; i++) (*s)->stat[i] = 0; 43047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 43147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 43247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (*s)->totalops++; 43347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (*s)->stat[op]++; 43447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry) 43547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 43647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->totalops++; 43747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt entry->stat[op]++; 43847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 43947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 44047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 44147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void printstats(int max) 44247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 44347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 44447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!stats) return; 44547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<max; i++) 44647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 44747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int max = 0; 44847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ActivityStat *s, *m = NULL; 44947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (s = stats; s; s=s->next) 45047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!s->printed && max < s->totalops) 45147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { m = s; max = s->totalops; } 45247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!m) return; 45347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt m->printed = mDNStrue; 45447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (i==0) mprintf("%-25s%s\n", "Service Type", OPBanner); 45547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("%##-25s%8d %8d %8d %8d %8d %8d %8d\n", m->srvtype.c, m->totalops, m->stat[OP_probe], 45647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt m->stat[OP_goodbye], m->stat[OP_browseq], m->stat[OP_browsea], m->stat[OP_resolveq], m->stat[OP_resolvea]); 45747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 45847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 45947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 46047e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal const mDNSu8 *FindUpdate(mDNS *const m, const DNSMessage *const query, const mDNSu8 *ptr, const mDNSu8 *const end, 46147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSQuestion *q, LargeCacheRecord *pkt) 46247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 46347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 46447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i = 0; i < query->h.numAuthorities; i++) 46547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 46647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *p2 = ptr; 46747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = GetLargeResourceRecord(m, query, ptr, end, q->InterfaceID, kDNSRecordTypePacketAuth, pkt); 46847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ptr) break; 46947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && ResourceRecordAnswersQuestion(&pkt->r.resrec, q)) return(p2); 47047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 47147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return(mDNSNULL); 47247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 47347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 47447e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void DisplayPacketHeader(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *srcaddr, mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSInterfaceID InterfaceID) 47547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 47647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *const ptype = (msg->h.flags.b[0] & kDNSFlag0_QR_Response) ? "-R- " : 47747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (srcport.NotAnInteger == MulticastDNSPort.NotAnInteger) ? "-Q- " : "-LQ-"; 47847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 47947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt struct timeval tv; 48047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt struct tm tm; 48147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu32 index = mDNSPlatformInterfaceIndexfromInterfaceID(m, InterfaceID, mDNSfalse); 48247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char if_name[IFNAMSIZ]; // Older Linux distributions don't define IF_NAMESIZE 48347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if_indextoname(index, if_name); 48447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt gettimeofday(&tv, NULL); 48547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt localtime_r((time_t*)&tv.tv_sec, &tm); 48647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n%d:%02d:%02d.%06d Interface %d/%s\n", tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec, index, if_name); 48747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 48847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("%#-16a %s Q:%3d Ans:%3d Auth:%3d Add:%3d Size:%5d bytes", 48947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt srcaddr, ptype, msg->h.numQuestions, msg->h.numAnswers, msg->h.numAuthorities, msg->h.numAdditionals, end - (mDNSu8 *)msg); 49047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 49147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (msg->h.id.NotAnInteger) mprintf(" ID:%u", mDNSVal16(msg->h.id)); 49247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 49347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!mDNSAddrIsDNSMulticast(dstaddr)) mprintf(" To: %#a", dstaddr); 49447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 49547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (msg->h.flags.b[0] & kDNSFlag0_TC) 49647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 49747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (msg->h.flags.b[0] & kDNSFlag0_QR_Response) mprintf(" Truncated"); 49847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else mprintf(" Truncated (KA list continues in next packet)"); 49947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 50047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n"); 50147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 50247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 50347e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void DisplayResourceRecord(const mDNSAddr *const srcaddr, const char *const op, const ResourceRecord *const pktrr) 50447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 50547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt static const char hexchars[16] = "0123456789ABCDEF"; 50647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt #define MaxWidth 132 50747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char buffer[MaxWidth+8]; 50847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char *p = buffer; 50947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 51047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt RDataBody *rd = &pktrr->rdata->u; 51147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *rdend = (mDNSu8 *)rd + pktrr->rdlength; 51247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int n = mprintf("%#-16a %-5s %-5s%5lu %##s -> ", srcaddr, op, DNSTypeName(pktrr->rrtype), pktrr->rroriginalttl, pktrr->name->c); 51347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 51447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (pktrr->RecordType == kDNSRecordTypePacketNegative) { mprintf("**** ERROR: FAILED TO READ RDATA ****\n"); return; } 51547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 51647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // The kDNSType_OPT case below just calls GetRRDisplayString_rdb 51747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Perhaps more (or all?) of the cases should do that? 51847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt switch(pktrr->rrtype) 51947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 52047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSType_A: n += mprintf("%.4a", &rd->ipv4); break; 52147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSType_PTR: n += mprintf("%##.*s", MaxWidth - n, rd->name.c); break; 52247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSType_HINFO:// same as kDNSType_TXT below 52347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSType_TXT: { 52447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *t = rd->txt.c; 52547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (t < rdend && t[0] && p < buffer+MaxWidth) 52647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 52747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 52847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=1; i<=t[0] && p < buffer+MaxWidth; i++) 52947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 53047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (t[i] == '\\') *p++ = '\\'; 53147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (t[i] >= ' ') *p++ = t[i]; 53247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 53347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 53447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = '\\'; 53547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = '0'; 53647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = 'x'; 53747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = hexchars[t[i] >> 4]; 53847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = hexchars[t[i] & 0xF]; 53947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 54047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 54147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt t += 1+t[0]; 54247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (t < rdend && t[0]) { *p++ = '\\'; *p++ = ' '; } 54347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 54447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = 0; 54547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt n += mprintf("%.*s", MaxWidth - n, buffer); 54647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } break; 54747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSType_AAAA: n += mprintf("%.16a", &rd->ipv6); break; 54847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSType_SRV: n += mprintf("%##s:%d", rd->srv.target.c, mDNSVal16(rd->srv.port)); break; 54947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSType_OPT: { 55047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char b[MaxMsg]; 55147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Quick hack: we don't want the prefix that GetRRDisplayString_rdb puts at the start of its 55247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // string, because it duplicates the name and rrtype we already display, so we compute the 55347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // length of that prefix and strip that many bytes off the beginning of the string we display. 55447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu32 striplen = mDNS_snprintf(b, MaxMsg-1, "%4d %##s %s ", pktrr->rdlength, pktrr->name->c, DNSTypeName(pktrr->rrtype)); 55547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt GetRRDisplayString_rdb(pktrr, &pktrr->rdata->u, b); 55647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt n += mprintf("%.*s", MaxWidth - n, b + striplen); 55747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } break; 55847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSType_NSEC: { 55947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 56047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<255; i++) 56147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (rd->nsec.bitmap[i>>3] & (128 >> (i&7))) 56247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt n += mprintf("%s ", DNSTypeName(i)); 56347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } break; 56447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt default: { 56547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *s = rd->data; 56647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (s < rdend && p < buffer+MaxWidth) 56747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 56847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*s == '\\') *p++ = '\\'; 56947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*s >= ' ') *p++ = *s; 57047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 57147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 57247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = '\\'; 57347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = '0'; 57447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = 'x'; 57547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = hexchars[*s >> 4]; 57647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = hexchars[*s & 0xF]; 57747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 57847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt s++; 57947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 58047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *p++ = 0; 58147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt n += mprintf("%.*s", MaxWidth - n, buffer); 58247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } break; 58347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 58447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 58547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n"); 58647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 58747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 58847e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void HexDump(const mDNSu8 *ptr, const mDNSu8 *const end) 58947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 59047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (ptr < end) 59147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 59247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 59347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<16; i++) 59447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (&ptr[i] < end) mprintf("%02X ", ptr[i]); 59547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else mprintf(" "); 59647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<16; i++) 59747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (&ptr[i] < end) mprintf("%c", ptr[i] <= ' ' || ptr[i] >= 126 ? '.' : ptr[i]); 59847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr += 16; 59947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n"); 60047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 60147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 60247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 60347e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void DisplayError(const mDNSAddr *srcaddr, const mDNSu8 *ptr, const mDNSu8 *const end, char *msg) 60447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 60547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("%#-16a **** ERROR: FAILED TO READ %s **** \n", srcaddr, msg); 60647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HexDump(ptr, end); 60747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 60847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 60947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void DisplayQuery(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, 61047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSAddr *srcaddr, mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSInterfaceID InterfaceID) 61147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 61247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 61347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ptr = msg->data; 61447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *auth = LocateAuthorities(msg, end); 61547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSBool MQ = (srcport.NotAnInteger == MulticastDNSPort.NotAnInteger); 61647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntry *entry = GotPacketFromHost(srcaddr, MQ ? HostPkt_Q : HostPkt_L, msg->h.id); 61747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt LargeCacheRecord pkt; 61847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 61947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DisplayPacketHeader(m, msg, end, srcaddr, srcport, dstaddr, InterfaceID); 62047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (msg->h.id.NotAnInteger != 0xFFFF) 62147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 62247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MQ) NumPktQ++; else NumPktL++; 62347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 62447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 62547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<msg->h.numQuestions; i++) 62647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 62747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSQuestion q; 62847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *p2 = (mDNSu8 *)getQuestion(msg, ptr, end, InterfaceID, &q); 62947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu16 ucbit = q.qclass & kDNSQClass_UnicastResponse; 63047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt q.qclass &= ~kDNSQClass_UnicastResponse; 63147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!p2) { DisplayError(srcaddr, ptr, end, "QUESTION"); return; } 63247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = p2; 63347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt p2 = (mDNSu8 *)FindUpdate(m, msg, auth, end, &q, &pkt); 63447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (p2) 63547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 63647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NumProbes++; 63747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DisplayResourceRecord(srcaddr, ucbit ? "(PU)" : "(PM)", &pkt.r.resrec); 63847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt recordstat(entry, &q.qname, OP_probe, q.qtype); 63947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt p2 = (mDNSu8 *)skipDomainName(msg, p2, end); 64047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Having displayed this update record, clear type and class so we don't display the same one again. 64147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt p2[0] = p2[1] = p2[2] = p2[3] = 0; 64247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 64347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 64447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 64547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *ptype = ucbit ? "(QU)" : "(QM)"; 64647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (srcport.NotAnInteger == MulticastDNSPort.NotAnInteger) NumQuestions++; 64747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else { NumLegacy++; ptype = "(LQ)"; } 64847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("%#-16a %-5s %-5s %##s\n", srcaddr, ptype, DNSTypeName(q.qtype), q.qname.c); 64947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (msg->h.id.NotAnInteger != 0xFFFF) recordstat(entry, &q.qname, OP_query, q.qtype); 65047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 65147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 65247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 65347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<msg->h.numAnswers; i++) 65447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 65547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ep = ptr; 65647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAns, &pkt); 65747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ptr) { DisplayError(srcaddr, ep, end, "KNOWN ANSWER"); return; } 65847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DisplayResourceRecord(srcaddr, "(KA)", &pkt.r.resrec); 65947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 66047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // In the case of queries with long multi-packet KA lists, we count each subsequent KA packet 66147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // the same as a single query, to more accurately reflect the burden on the network 66247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // (A query with a six-packet KA list is *at least* six times the burden on the network as a single-packet query.) 66347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (msg->h.numQuestions == 0 && i == 0) 66447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt recordstat(entry, pkt.r.resrec.name, OP_query, pkt.r.resrec.rrtype); 66547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 66647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 66747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<msg->h.numAuthorities; i++) 66847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 66947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ep = ptr; 67047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &pkt); 67147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ptr) { DisplayError(srcaddr, ep, end, "AUTHORITY"); return; } 67247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // After we display an Update record with its matching question (above) we zero out its type and class 67347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // If any remain that haven't been zero'd out, display them here 67447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (pkt.r.resrec.rrtype || pkt.r.resrec.rrclass) DisplayResourceRecord(srcaddr, "(AU)", &pkt.r.resrec); 67547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 67647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 67747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<msg->h.numAdditionals; i++) 67847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 67947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ep = ptr; 68047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAdd, &pkt); 68147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ptr) { DisplayError(srcaddr, ep, end, "ADDITIONAL"); return; } 68247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DisplayResourceRecord(srcaddr, pkt.r.resrec.rrtype == kDNSType_OPT ? "(OP)" : "(AD)", &pkt.r.resrec); 68347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 68447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 68547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry) AnalyseHost(m, entry, InterfaceID); 68647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 68747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 68847e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void DisplayResponse(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *end, 68947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSAddr *srcaddr, mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSInterfaceID InterfaceID) 69047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 69147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 69247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ptr = msg->data; 69347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntry *entry = GotPacketFromHost(srcaddr, HostPkt_R, msg->h.id); 69447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt LargeCacheRecord pkt; 69547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 69647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DisplayPacketHeader(m, msg, end, srcaddr, srcport, dstaddr, InterfaceID); 69747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (msg->h.id.NotAnInteger != 0xFFFF) NumPktR++; 69847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 69947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<msg->h.numQuestions; i++) 70047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 70147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSQuestion q; 70247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ep = ptr; 70347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = getQuestion(msg, ptr, end, InterfaceID, &q); 70447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ptr) { DisplayError(srcaddr, ep, end, "QUESTION"); return; } 70547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (mDNSAddrIsDNSMulticast(dstaddr)) 70647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("%#-16a (?) **** ERROR: SHOULD NOT HAVE Q IN mDNS RESPONSE **** %-5s %##s\n", srcaddr, DNSTypeName(q.qtype), q.qname.c); 70747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 70847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("%#-16a (Q) %-5s %##s\n", srcaddr, DNSTypeName(q.qtype), q.qname.c); 70947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 71047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 71147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<msg->h.numAnswers; i++) 71247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 71347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ep = ptr; 71447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAns, &pkt); 71547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ptr) { DisplayError(srcaddr, ep, end, "ANSWER"); return; } 71647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (pkt.r.resrec.rroriginalttl) 71747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 71847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NumAnswers++; 71947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DisplayResourceRecord(srcaddr, (pkt.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? "(AN)" : "(AN+)", &pkt.r.resrec); 72047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (msg->h.id.NotAnInteger != 0xFFFF) recordstat(entry, pkt.r.resrec.name, OP_answer, pkt.r.resrec.rrtype); 72147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry) RecordHostInfo(entry, &pkt.r.resrec); 72247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 72347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 72447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 72547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NumGoodbyes++; 72647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DisplayResourceRecord(srcaddr, "(DE)", &pkt.r.resrec); 72747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt recordstat(entry, pkt.r.resrec.name, OP_goodbye, pkt.r.resrec.rrtype); 72847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 72947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 73047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 73147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<msg->h.numAuthorities; i++) 73247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 73347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ep = ptr; 73447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &pkt); 73547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ptr) { DisplayError(srcaddr, ep, end, "AUTHORITY"); return; } 73647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("%#-16a (?) **** ERROR: SHOULD NOT HAVE AUTHORITY IN mDNS RESPONSE **** %-5s %##s\n", 73747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt srcaddr, DNSTypeName(pkt.r.resrec.rrtype), pkt.r.resrec.name->c); 73847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 73947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 74047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<msg->h.numAdditionals; i++) 74147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 74247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ep = ptr; 74347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAdd, &pkt); 74447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ptr) { DisplayError(srcaddr, ep, end, "ADDITIONAL"); return; } 74547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NumAdditionals++; 74647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DisplayResourceRecord(srcaddr, 74747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt pkt.r.resrec.rrtype == kDNSType_OPT ? "(OP)" : (pkt.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? "(AD)" : "(AD+)", 74847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt &pkt.r.resrec); 74947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry) RecordHostInfo(entry, &pkt.r.resrec); 75047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 75147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 75247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (entry) AnalyseHost(m, entry, InterfaceID); 75347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 75447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 75547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void ProcessUnicastResponse(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *end, const mDNSAddr *srcaddr, const mDNSInterfaceID InterfaceID) 75647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 75747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 75847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 *ptr = LocateAnswers(msg, end); 75947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HostEntry *entry = GotPacketFromHost(srcaddr, HostPkt_R, msg->h.id); 76047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt //mprintf("%#a R\n", srcaddr); 76147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 76247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=0; i<msg->h.numAnswers + msg->h.numAuthorities + msg->h.numAdditionals; i++) 76347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 76447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt LargeCacheRecord pkt; 76547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAns, &pkt); 76647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (ptr && pkt.r.resrec.rroriginalttl && entry) RecordHostInfo(entry, &pkt.r.resrec); 76747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 76847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 76947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 77047e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal mDNSBool AddressMatchesFilterList(const mDNSAddr *srcaddr) 77147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 77247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt FilterList *f; 77347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!Filters) return(srcaddr->type == mDNSAddrType_IPv4); 77447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (f=Filters; f; f=f->next) if (mDNSSameAddress(srcaddr, &f->FilterAddr)) return(mDNStrue); 77547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return(mDNSfalse); 77647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 77747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 77847e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end, 77947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSAddr *srcaddr, mDNSIPPort srcport, const mDNSAddr *dstaddr, mDNSIPPort dstport, const mDNSInterfaceID InterfaceID) 78047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 78147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 StdQ = kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery; 78247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 StdR = kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery; 78347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const mDNSu8 QR_OP = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask); 78447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSu8 *ptr = (mDNSu8 *)&msg->h.numQuestions; 78547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int goodinterface = (FilterInterface == 0); 78647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 78747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (void)dstaddr; // Unused 78847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (void)dstport; // Unused 78947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 79047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Read the integer parts which are in IETF byte-order (MSB first, LSB second) 79147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt msg->h.numQuestions = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]); 79247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt msg->h.numAnswers = (mDNSu16)((mDNSu16)ptr[2] << 8 | ptr[3]); 79347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt msg->h.numAuthorities = (mDNSu16)((mDNSu16)ptr[4] << 8 | ptr[5]); 79447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt msg->h.numAdditionals = (mDNSu16)((mDNSu16)ptr[6] << 8 | ptr[7]); 79547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 79647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // For now we're only interested in monitoring IPv4 traffic. 79747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // All IPv6 packets should just be duplicates of the v4 packets. 79847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!goodinterface) goodinterface = (FilterInterface == (int)mDNSPlatformInterfaceIndexfromInterfaceID(m, InterfaceID, mDNSfalse)); 79947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (goodinterface && AddressMatchesFilterList(srcaddr)) 80047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 80147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNS_Lock(m); 80247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!mDNSAddrIsDNSMulticast(dstaddr)) 80347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 80447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (QR_OP == StdQ) mprintf("Unicast query from %#a\n", srcaddr); 80547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (QR_OP == StdR) ProcessUnicastResponse(m, msg, end, srcaddr, InterfaceID); 80647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 80747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 80847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 80947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (QR_OP == StdQ) DisplayQuery (m, msg, end, srcaddr, srcport, dstaddr, InterfaceID); 81047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (QR_OP == StdR) DisplayResponse (m, msg, end, srcaddr, srcport, dstaddr, InterfaceID); 81147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 81247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 81347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt debugf("Unknown DNS packet type %02X%02X (ignored)", msg->h.flags.b[0], msg->h.flags.b[1]); 81447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt GotPacketFromHost(srcaddr, HostPkt_B, msg->h.id); 81547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NumPktB++; 81647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 81747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 81847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNS_Unlock(m); 81947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 82047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 82147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 82247e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal mStatus mDNSNetMonitor(void) 82347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 82447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt struct tm tm; 82547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int h, m, s, mul, div, TotPkt; 82647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !defined(WIN32) 82747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt sigset_t signals; 82847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 82947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 83047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mStatus status = mDNS_Init(&mDNSStorage, &PlatformStorage, 83147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize, 83247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNS_Init_DontAdvertiseLocalAddresses, 83347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext); 83447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (status) return(status); 83547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 83647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt gettimeofday(&tv_start, NULL); 83747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 83847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined( WIN32 ) 83947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt status = SetupInterfaceList(&mDNSStorage); 84047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (status) return(status); 84147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt gStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 84247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (gStopEvent == INVALID_HANDLE_VALUE) return mStatus_UnknownErr; 84347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!SetConsoleCtrlHandler(ConsoleControlHandler, TRUE)) return mStatus_UnknownErr; 84447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (WaitForSingleObjectEx(gStopEvent, INFINITE, TRUE) == WAIT_IO_COMPLETION) 84547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DispatchSocketEvents(&mDNSStorage); 84647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!SetConsoleCtrlHandler(ConsoleControlHandler, FALSE)) return mStatus_UnknownErr; 84747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt CloseHandle(gStopEvent); 84847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#else 84947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSPosixListenForSignalInEventLoop(SIGINT); 85047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSPosixListenForSignalInEventLoop(SIGTERM); 85147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 85247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt do 85347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 85447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt struct timeval timeout = { 0x3FFFFFFF, 0 }; // wait until SIGINT or SIGTERM 85547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSBool gotSomething; 85647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSPosixRunEventLoopOnce(&mDNSStorage, &timeout, &signals, &gotSomething); 85747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 85847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while ( !( sigismember( &signals, SIGINT) || sigismember( &signals, SIGTERM))); 85947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 86047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 86147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Now display final summary 86247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt TotPkt = NumPktQ + NumPktL + NumPktR; 86347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt gettimeofday(&tv_end, NULL); 86447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt tv_interval = tv_end; 86547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (tv_start.tv_usec > tv_interval.tv_usec) 86647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { tv_interval.tv_usec += 1000000; tv_interval.tv_sec--; } 86747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt tv_interval.tv_sec -= tv_start.tv_sec; 86847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt tv_interval.tv_usec -= tv_start.tv_usec; 86947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt h = (tv_interval.tv_sec / 3600); 87047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt m = (tv_interval.tv_sec % 3600) / 60; 87147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt s = (tv_interval.tv_sec % 60); 87247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (tv_interval.tv_sec > 10) 87347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 87447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mul = 60; 87547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt div = tv_interval.tv_sec; 87647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 87747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 87847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 87947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mul = 60000; 88047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt div = tv_interval.tv_sec * 1000 + tv_interval.tv_usec / 1000; 88147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (div == 0) div=1; 88247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 88347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 88447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n\n"); 88547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt localtime_r((time_t*)&tv_start.tv_sec, &tm); 88647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Started %3d:%02d:%02d.%06d\n", tm.tm_hour, tm.tm_min, tm.tm_sec, tv_start.tv_usec); 88747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt localtime_r((time_t*)&tv_end.tv_sec, &tm); 88847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("End %3d:%02d:%02d.%06d\n", tm.tm_hour, tm.tm_min, tm.tm_sec, tv_end.tv_usec); 88947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Captured for %3d:%02d:%02d.%06d\n", h, m, s, tv_interval.tv_usec); 89047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!Filters) 89147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 89247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Unique source addresses seen on network:"); 89347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (IPv4HostList.num) mprintf(" %ld (IPv4)", IPv4HostList.num); 89447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (IPv6HostList.num) mprintf(" %ld (IPv6)", IPv6HostList.num); 89547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!IPv4HostList.num && !IPv6HostList.num) mprintf(" None"); 89647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n"); 89747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 89847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n"); 89947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Modern Query Packets: %7d (avg%5d/min)\n", NumPktQ, NumPktQ * mul / div); 90047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Legacy Query Packets: %7d (avg%5d/min)\n", NumPktL, NumPktL * mul / div); 90147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Multicast Response Packets: %7d (avg%5d/min)\n", NumPktR, NumPktR * mul / div); 90247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Total Multicast Packets: %7d (avg%5d/min)\n", TotPkt, TotPkt * mul / div); 90347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n"); 90447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Total New Service Probes: %7d (avg%5d/min)\n", NumProbes, NumProbes * mul / div); 90547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Total Goodbye Announcements: %7d (avg%5d/min)\n", NumGoodbyes, NumGoodbyes * mul / div); 90647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Total Query Questions: %7d (avg%5d/min)\n", NumQuestions, NumQuestions * mul / div); 90747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Total Queries from Legacy Clients:%7d (avg%5d/min)\n", NumLegacy, NumLegacy * mul / div); 90847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Total Answers/Announcements: %7d (avg%5d/min)\n", NumAnswers, NumAnswers * mul / div); 90947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("Total Additional Records: %7d (avg%5d/min)\n", NumAdditionals, NumAdditionals * mul / div); 91047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mprintf("\n"); 91147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt printstats(kReportTopServices); 91247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 91347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!ExactlyOneFilter) 91447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 91547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ShowSortedHostList(&IPv4HostList, kReportTopHosts); 91647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ShowSortedHostList(&IPv6HostList, kReportTopHosts); 91747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 91847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 91947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNS_Close(&mDNSStorage); 92047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return(0); 92147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 92247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 92347e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport int main(int argc, char **argv) 92447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 92547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *progname = strrchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0]; 92647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 92747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mStatus status; 92847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 92947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined(WIN32) 93047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); 93147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 93247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 93347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt setlinebuf(stdout); // Want to see lines as they appear, not block buffered 93447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 93547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i=1; i<argc; i++) 93647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 93747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (i+1 < argc && !strcmp(argv[i], "-i") && atoi(argv[i+1])) 93847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 93947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt FilterInterface = atoi(argv[i+1]); 94047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i += 2; 94147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt printf("Monitoring interface %d\n", FilterInterface); 94247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 94347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 94447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 94547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt struct in_addr s4; 94647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt struct in6_addr s6; 94747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt FilterList *f; 94847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSAddr a; 94947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt a.type = mDNSAddrType_IPv4; 95047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 95147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (inet_pton(AF_INET, argv[i], &s4) == 1) 95247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt a.ip.v4.NotAnInteger = s4.s_addr; 95347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (inet_pton(AF_INET6, argv[i], &s6) == 1) 95447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 95547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt a.type = mDNSAddrType_IPv6; 95647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSPlatformMemCopy(&a.ip.v6, &s6, sizeof(a.ip.v6)); 95747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 95847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 95947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 96047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt struct hostent *h = gethostbyname(argv[i]); 96147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (h) a.ip.v4.NotAnInteger = *(long*)h->h_addr; 96247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else goto usage; 96347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 96447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 96547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt f = malloc(sizeof(*f)); 96647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt f->FilterAddr = a; 96747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt f->next = Filters; 96847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Filters = f; 96947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 97047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 97147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 97247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt status = mDNSNetMonitor(); 97347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (status) { fprintf(stderr, "%s: mDNSNetMonitor failed %d\n", progname, (int)status); return(status); } 97447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return(0); 97547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 97647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltusage: 97747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "\nmDNS traffic monitor\n"); 97847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "Usage: %s [-i index] [host]\n", progname); 97947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "Optional [-i index] parameter displays only packets from that interface index\n"); 98047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "Optional [host] parameter displays only packets from that host\n"); 98147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 98247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "\nPer-packet header output:\n"); 98347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "-Q- Multicast Query from mDNS client that accepts multicast responses\n"); 98447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "-R- Multicast Response packet containing answers/announcements\n"); 98547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "-LQ- Multicast Query from legacy client that does *not* listen for multicast responses\n"); 98647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "Q/Ans/Auth/Add Number of questions, answers, authority records and additional records in packet\n"); 98747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 98847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "\nPer-record display:\n"); 98947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(PM) Probe Question (new service starting), requesting multicast response\n"); 99047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(PU) Probe Question (new service starting), requesting unicast response\n"); 99147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(DE) Deletion/Goodbye (service going away)\n"); 99247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(LQ) Legacy Query Question\n"); 99347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(QM) Query Question, requesting multicast response\n"); 99447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(QU) Query Question, requesting unicast response\n"); 99547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(KA) Known Answer (information querier already knows)\n"); 99647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(AN) Unique Answer to question (or periodic announcment) (entire RR Set)\n"); 99747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(AN+) Answer to question (or periodic announcment) (add to existing RR Set members)\n"); 99847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(AD) Unique Additional Record Set (entire RR Set)\n"); 99947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "(AD+) Additional records (add to existing RR Set members)\n"); 100047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 100147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "\nFinal summary, sorted by service type:\n"); 100247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "Probe Probes for this service type starting up\n"); 100347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "Goodbye Goodbye (deletion) packets for this service type shutting down\n"); 100447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "BrowseQ Browse questions from clients browsing to find a list of instances of this service\n"); 100547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "BrowseA Browse answers/announcments advertising instances of this service\n"); 100647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "ResolveQ Resolve questions from clients actively connecting to an instance of this service\n"); 100747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "ResolveA Resolve answers/announcments giving connection information for an instance of this service\n"); 100847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "\n"); 100947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return(-1); 101047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 1011