5 // Created by Terrin Eager on 9/26/12.
12 #include <sys/socket.h>
13 #include <sys/types.h>
14 #include <netinet/in.h>
17 #include <arpa/inet.h>
20 #include "BonjourTop.h"
22 #include "CaptureFile.h"
26 #include <sys/sysctl.h>
27 #include <mach/mach.h>
29 #define SERVICE_IPV4 0
30 #define SERVICE_IPV6 1
34 #define TRACE_PLATFORM_UNKNOWN 0
35 #define TRACE_PLATFORM_OSX 1
36 #define TRACE_PLATFORM_iOS 2
37 #define TRACE_PLATFORM_APPLE_TV 3
38 #define TRACE_PLATFORM_NON_APPLE_PLATFORM 4
39 #define DISCOVERYD_TRACE_PLATFORM_OSX (1 | 0x80)
40 #define DISCOVERYD_TRACE_PLATFORM_iOS (2 | 0x80)
41 #define DISCOVERYD_TRACE_PLATFORM_APPLE_TV (3 | 0x80)
42 #define DISCOVERYD_TRACE_PLATFORM_NON_APPLE_PLATFORM (4 | 0x80)
44 int CDeviceNode::nCreateCount
= 0;
45 static integer_t
Usage(void);
47 char CVSFileNameExample
[] ="BonjourTop";
48 char DeviceNameExample
[] ="BonjourTopDevice.csv";
50 char Service2App
[][50] = {
51 // Service_Name, Application_Name, Browse_OS_Type, Register_OS_Type
52 "_device-info._tcp.local.", "Device-Info", "?" , "?",
53 "_rfb._tcp.local.", "Finder", "X" , "?",
54 "_afpovertcp._tcp.local.", "Finder", "?" , "X",
55 "_adisk._tcp.local.", "Finder", "?" , "X",
56 "_odisk._tcp.local.", "Finder", "?" , "X",
57 "_smb._tcp.local.", "Finder", "X" , "X",
58 "_smb2._tcp.local.", "Finder", "X" , "X",
59 "_workstation._tcp.local.", "Finder", "X" , "X",
60 "_kerberos.", "Finder", "X" , "X",
61 "_nfs._tcp.local.", "Finder", "X" , "X",
62 "_ftp._tcp.local.", "Finder", "X" , "X",
64 "_appletv._tcp.local.", "AppleTV", "?" , "t",
65 "_appletv-v2._tcp.local.", "AppleTV", "?" , "?",
66 "_appletv-pair._tcp.local.", "AppleTV", "?" , "?",
68 "A", "LinkLocal", "?" , "?",
69 "AAAA", "LinkLocal", "?" , "?",
70 "*.ip6.arpa.", "LinkLocal", "?" , "?",
71 "*.arpa.", "LinkLocal", "?" , "?",
73 "_airplay._tcp.local.", "AirPlay", "?" , "t",
74 "_airplayTXT", "AirPlay","?" , "t",
75 "_raop._tcp.local.", "AirPlay","?" , "?",
77 "_ubd._tcp.local.", "Ubiquity", "?" , "?",
78 "_ubiquity._tcp.local.", "Ubiquity", "?" , "?",
79 "_ubiquityV1._tcp.local.", "Ubiquity", "?" , "?",
80 "_ubiquityV2._tcp.local.", "Ubiquity", "?" , "?",
82 " _ipps._tcp.local.", "Printing", "?" , "?",
83 "_ipp._tcp.local.", "Printing", "?" , "?",
84 "_ipps._tcp.local.", "Printing", "?" , "?",
85 "_ipp-tls._tcp.local.", "Printing", "?" , "?",
86 "_printer._tcp.local.", "Printing", "?" , "?",
87 "_scanner._tcp.local.", "Printing", "?" , "?",
88 "_pdl-datastream._tcp.local.", "Printing", "?" , "?",
89 "_fax-ipp._tcp.local.", "Printing", "?" , "?",
91 "_apple-mobdev._tcp.local.", "iTunes-WiFiSync","?" , "i",
92 "_daap._tcp.local.", "iTunes", "?" , "?",
94 "_sftp-ssh._tcp.local.", "Terminal", "?" , "X",
95 "_ssh._tcp.local.", "Terminal", "?" , "X",
97 "_sleep-proxy._udp.local.", "Sleep Proxy", "?" , "?",
98 "_keepalive._dns-sd._udp.local.","Sleep Proxy", "X" , "?",
99 "_services._dns-sd._udp.local.", "Services", "?" , "?",
100 "ANY *.ip6.arpa.", "Sleep Proxy", "?" , "?",
101 "ANY *.arpa.", "Sleep Proxy", "?" , "?",
103 "AirPort_presence._tcp.local.", "AirPort", "?" , "?",
104 "_airport._tcp.local.", "AirPort", "?" , "?",
105 "_presence._tcp.local.", "iChat", "X" , "X",
106 "_home-sharing._tcp.local.", "HomeSharing", "?" , "X",
108 "_ptp._tcp.local.", "iPhoto", "?" , "X",
109 "_ica-networking2._tcp.local.", "iPhoto", "X" , "X",
110 "_mobileiphoto._udp.local.", "iPhoto", "?" , "?",
111 "_mobileiphoto2._udp.local.", "iPhoto", "?" , "?",
112 "_dpap._tcp.local.", "iPhoto", "?" , "X",
113 "_airdrop._tcp.local.", "AirDrop", "?" , "?",
114 "_http._tcp.local.", "Safari", "X" , "X",
115 "_net-assistant._udp.local.","Apple Remote Desktop","X" , "X",
116 "_servermgr._tcp.local.", "OSX Server", "X" , "X",
120 char DeviceInfo2DeviceOS
[][50] = {
121 // deviceModel, deviceType
161 char Name2DeviceOS
[][50] = {
162 // Name contains, osType
178 BJ_UINT64
Hash(const char* pStr
);
179 BJ_UINT64
Hash2(char* pStr
);
182 CSocketStats::CSocketStats()
187 void CSocketStats::Init()
191 m_nQuestionOnlyFrames
= 0;
192 m_nAnswerOnlyFrames
= 0;
198 void CSocketStats::Clear()
203 CBonjourTop::CBonjourTop()
207 m_pTcpDumpFileName
= NULL
;
208 m_pExportFileName
= CVSFileNameExample
;
209 m_DeviceFileName
= DeviceNameExample
;
214 m_StartTime
= m_EndTime
= time(NULL
);
216 m_SnapshotSeconds
= 0;
218 m_MinAnswerCountForTruncatedFrames
= 0;
219 m_AvgAnswerCountForTruncatedFrames
= 0;
220 m_MaxAnswerCountForTruncatedFrames
= 0;
222 window_size_changed
= false;
223 m_bImportExportDeviceMap
= false;
225 // loadup application mapping
226 for(int i
=0; Service2App
[i
][0] != 0;)
228 BJString
a(Service2App
[i
++]);
230 m_Service2AppMap
.FindwithAddRecord(&a
)->value
= Service2App
[i
++];
231 m_Service2osBrowseMap
.FindwithAddRecord(&a
)->value
= Service2App
[i
++];
232 m_Service2osRegisterMap
.FindwithAddRecord(&a
)->value
= Service2App
[i
++];
237 m_CurrentDisplay
= CBonjourTop::BJ_DISPLAY_APP
;
238 // m_CurrentDisplay = CBonjourTop::BJ_DISPLAY_SERVICE;
244 static int CbClearDataDevice(const void* pNode
, const void*)
246 CDeviceNode
* pDeviceRecord
= (CDeviceNode
*)pNode
;
248 pDeviceRecord
->ClearData();
252 void CBonjourTop::Reset()
257 m_MinAnswerCountForTruncatedFrames
= 0;
258 m_AvgAnswerCountForTruncatedFrames
= 0;
259 m_MaxAnswerCountForTruncatedFrames
= 0;
261 m_StartTime
= m_EndTime
= time(NULL
);
263 m_ServicePtrCache
.ClearAll();
264 m_ApplPtrCache
.ClearAll();
266 m_ServicePtrCacheIPv6
.ClearAll();
267 m_ApplPtrCacheIPv6
.ClearAll();
269 // Clear all data in the map
270 m_AppBreakdownIPv4OSX
.clear();
271 m_AppBreakdownIPv4iOS
.clear();
272 m_AppBreakdownIPv6OSX
.clear();
273 m_AppBreakdownIPv6iOS
.clear();
275 m_ServiceBreakdownIPv4OSX
.clear();
276 m_ServiceBreakdownIPv4iOS
.clear();
277 m_ServiceBreakdownIPv6OSX
.clear();
278 m_ServiceBreakdownIPv6iOS
.clear();
280 // Clear Socket Status
281 for (int i
= 0; i
< NUM_SOCKET_STATUS
; i
++)
283 m_SocketStatus
[i
].Clear();
286 for (int i
= 0; i
< HOURS_IN_DAY
; i
++)
288 for (int j
= 0; j
< MINUTES_IN_HOUR
; j
++)
290 m_MinSnapshot
[i
][j
].Clear();
294 CDeviceNode
* pDeviceNode
= m_DeviceMap
.GetRoot();
297 pDeviceNode
->CallBack(&CbClearDataDevice
,NULL
);
302 void CBonjourTop::SetIPAddr(const char* pStr
)
304 m_IPv4Addr
.Set(pStr
);
308 void CBonjourTop::UpdateRecord(CStringTree
& Cache
,CDNSRecord
* pDNSRecord
,BJString
& RecordName
,BJString
& ServiceName
,BJ_UINT32 nBytes
,bool bGoodbye
)
310 BJ_UINT64 nHashValue
= 0;
313 nHashValue
= Hash(RecordName
.GetBuffer());
314 CStringNode
* pRecord
= Cache
.Find(&nHashValue
);
317 pRecord
= (CStringNode
*) Cache
.FindwithAddRecord(&nHashValue
);
318 strlcpy(pRecord
->m_Value
, RecordName
.GetBuffer(), sizeof(pRecord
->m_Value
));
323 CDeviceNode dummyDevice
;
325 CIPDeviceNode
*pipNode
= m_IPtoNameMap
.Find(&m_Frame
.m_SourceIPAddress
);
327 device
= (pipNode
)? pipNode
->pDeviceNode
: &dummyDevice
;
328 pRecord
->m_nBytes
+= 10 + nBytes
;
329 deviceOS
= device
->GetDeviceOS();
330 device
->frameTotal
.Increment(m_nFrameCount
);
332 if (pRecord
->m_nLastFrameIndex
!= m_nFrameCount
)
334 pRecord
->m_nLastFrameIndex
= m_nFrameCount
;
336 pRecord
->m_nFrames
++;
337 if (deviceOS
== 't' || deviceOS
== 'i')
339 pRecord
->m_nFramesiOS
++;
341 else if (deviceOS
== 'X')
343 pRecord
->m_nFramesOSX
++;
347 // Update Total Device Count
348 if (pRecord
->m_DeviceTotalTree
.Find(&m_Frame
.m_SourceIPAddress
) == NULL
)
350 pRecord
->m_nDeviceTotalCount
++;
351 pRecord
->m_DeviceTotalTree
.FindwithAddRecord(&m_Frame
.m_SourceIPAddress
);
354 if (m_Frame
.IsQueryFrame())
356 GetOSTypeFromQuery(pDNSRecord
, ServiceName
);
357 device
->questionFrame
.Increment(m_nFrameCount
);
358 if (pRecord
->m_nLastQueryFrameIndex
!= m_nFrameCount
)
360 pRecord
->m_nLastQueryFrameIndex
= m_nFrameCount
;
362 pRecord
->m_nQuestionFrames
++;
364 if (deviceOS
== 't' || deviceOS
== 'i')
366 pRecord
->m_nQuestionFramesiOS
++;
368 else if (deviceOS
== 'X')
370 pRecord
->m_nQuestionFramesOSX
++;
373 if (pRecord
->m_DeviceAskingTree
.Find(&m_Frame
.m_SourceIPAddress
) == NULL
)
375 pRecord
->m_nDeviceAskingCount
++;
376 pRecord
->m_DeviceAskingTree
.FindwithAddRecord(&m_Frame
.m_SourceIPAddress
);
382 GetOSTypeFromRegistration(pDNSRecord
,ServiceName
);
384 device
->answerFrame
.Increment(m_nFrameCount
);
385 if (pRecord
->m_nLastRespondsFrameIndex
!= m_nFrameCount
)
387 pRecord
->m_nLastRespondsFrameIndex
= m_nFrameCount
;
389 pRecord
->m_nAnswerFrames
++;
390 if (deviceOS
== 't' || deviceOS
== 'i')
392 pRecord
->m_nAnswerFramesiOS
++;
394 else if (deviceOS
== 'X')
396 pRecord
->m_nAnswerFramesOSX
++;
401 pRecord
->m_nGoodbyeFrames
++;
404 if (pRecord
->m_DeviceAnsweringTree
.Find(&m_Frame
.m_SourceIPAddress
) == NULL
)
406 pRecord
->m_nDeviceAnsweringCount
++;
407 pRecord
->m_DeviceAnsweringTree
.FindwithAddRecord(&m_Frame
.m_SourceIPAddress
);
412 if (m_Frame
.IsWakeFrame())
414 if (pRecord
->m_nLastWakeFrameIndex
!= m_nFrameCount
)
416 pRecord
->m_nLastWakeFrameIndex
= m_nFrameCount
;
417 if (pRecord
->m_lastQUFrameTime
+1000000ll < m_Frame
.GetTime() || pRecord
->m_lastQUFrameTime
== 0) // last qu frame has been over 1 sec
419 pRecord
->m_nWakeFrames
++;
420 pRecord
->m_lastQUFrameTime
= m_Frame
.GetTime();
421 device
->QUFrame
.Increment(m_nFrameCount
);
423 pRecord
->m_lastQUFrameTime
= m_Frame
.GetTime();
430 void CBonjourTop::UpdateShortRecordHelper(BJ_UINT32 cacheType
, BJ_UINT32 tracePlatform
, BJ_UINT32 traceVersion
, char deviceOS
, CDNSRecord
* pDNSRecord
,BJString
& RecordName
,BJString
& ServiceName
,BJ_UINT32 nBytes
,bool bGoodbye
)
433 BJString versionNumber
= "mDNSResponder-";
434 const int version_max_length
= 11; // largest number is 0xffffffff = 4294967295
435 char versionChar
[version_max_length
];
437 CStringShortTree
*cache
;
438 map
<BJString
, CStringShortTree
*>* myMap
;
440 if ((tracePlatform
| 0x80) == tracePlatform
)
442 versionNumber
= "Discoveryd-";
445 snprintf(versionChar
, sizeof(versionChar
), "%u", 0); // Set versionChar to "0" by default
446 if (tracePlatform
== TRACE_PLATFORM_UNKNOWN
) // Pre iOS 7 or Pre OSX 10.9
448 if (deviceOS
== 'i' || deviceOS
== 't') // Pre iOS 7
452 else if (deviceOS
== 'X') // Pre OSX 10.9
457 else if ((tracePlatform
== TRACE_PLATFORM_OSX
) || (tracePlatform
== DISCOVERYD_TRACE_PLATFORM_OSX
)) // >= OSX 10.9
460 snprintf(versionChar
, sizeof(versionChar
), "%u", traceVersion
);
462 else if ((tracePlatform
== TRACE_PLATFORM_iOS
) || (tracePlatform
== DISCOVERYD_TRACE_PLATFORM_iOS
)) // >= iOS 7.x
465 snprintf(versionChar
, sizeof(versionChar
), "%u", traceVersion
);
467 else if ((tracePlatform
== TRACE_PLATFORM_APPLE_TV
) || (tracePlatform
== DISCOVERYD_TRACE_PLATFORM_APPLE_TV
))
469 snprintf(versionChar
, sizeof(versionChar
), "%u", traceVersion
);
472 versionNumber
+= (const char*)versionChar
;
478 myMap
= &m_ServiceBreakdownIPv4OSX
;
482 myMap
= &m_ServiceBreakdownIPv4iOS
;
488 myMap
= &m_ServiceBreakdownIPv6OSX
;
492 myMap
= &m_ServiceBreakdownIPv6iOS
;
498 myMap
= &m_AppBreakdownIPv4OSX
;
502 myMap
= &m_AppBreakdownIPv4iOS
;
508 myMap
= &m_AppBreakdownIPv6OSX
;
512 myMap
= &m_AppBreakdownIPv6iOS
;
521 if (myMap
->find(versionNumber
) == myMap
->end()) // Version number not found. Create new record
523 myMap
->insert(std::pair
<BJString
, CStringShortTree
*>(versionNumber
, new CStringShortTree()));
525 cache
= (*myMap
)[versionNumber
];
526 UpdateShortRecord(cache
, pDNSRecord
, RecordName
, ServiceName
, nBytes
, bGoodbye
);
529 void CBonjourTop::UpdateShortRecord(CStringShortTree
* Cache
,CDNSRecord
* pDNSRecord
,BJString
& RecordName
,BJString
& ServiceName
,BJ_UINT32 nBytes
,bool bGoodbye
)
536 BJ_UINT64 nHashValue
= 0;
538 nHashValue
= Hash(RecordName
.GetBuffer());
539 CStringShortNode
* pRecord
= Cache
->Find(&nHashValue
);
542 pRecord
= (CStringShortNode
*) Cache
->FindwithAddRecord(&nHashValue
);
544 strlcpy(pRecord
->m_Value
, RecordName
.GetBuffer(), sizeof(pRecord
->m_Value
));
552 CDeviceNode dummyDevice
;
554 CIPDeviceNode
*pipNode
= m_IPtoNameMap
.Find(&m_Frame
.m_SourceIPAddress
);
556 device
= (pipNode
)? pipNode
->pDeviceNode
: &dummyDevice
;
557 pRecord
->m_nBytes
+= 10 + nBytes
;
558 device
->frameTotal
.Increment(m_nFrameCount
);
560 if (pRecord
->m_nLastFrameIndex
!= m_nFrameCount
)
562 pRecord
->m_nLastFrameIndex
= m_nFrameCount
;
563 pRecord
->m_nFrames
++;
566 // Update Total Device Count
567 if (pRecord
->m_DeviceTotalTree
.Find(&m_Frame
.m_SourceIPAddress
) == NULL
)
569 pRecord
->m_nDeviceTotalCount
++;
570 pRecord
->m_DeviceTotalTree
.FindwithAddRecord(&m_Frame
.m_SourceIPAddress
);
573 if (m_Frame
.IsQueryFrame())
575 GetOSTypeFromQuery(pDNSRecord
, ServiceName
);
576 device
->questionFrame
.Increment(m_nFrameCount
);
577 if (pRecord
->m_nLastQueryFrameIndex
!= m_nFrameCount
)
579 pRecord
->m_nLastQueryFrameIndex
= m_nFrameCount
;
581 pRecord
->m_nQuestionFrames
++;
583 if (pRecord
->m_DeviceAskingTree
.Find(&m_Frame
.m_SourceIPAddress
) == NULL
)
585 pRecord
->m_nDeviceAskingCount
++;
586 pRecord
->m_DeviceAskingTree
.FindwithAddRecord(&m_Frame
.m_SourceIPAddress
);
593 GetOSTypeFromRegistration(pDNSRecord
,ServiceName
);
595 device
->answerFrame
.Increment(m_nFrameCount
);
596 if (pRecord
->m_nLastRespondsFrameIndex
!= m_nFrameCount
)
598 pRecord
->m_nLastRespondsFrameIndex
= m_nFrameCount
;
600 pRecord
->m_nAnswerFrames
++;
604 pRecord
->m_nGoodbyeFrames
++;
607 if (pRecord
->m_DeviceAnsweringTree
.Find(&m_Frame
.m_SourceIPAddress
) == NULL
)
609 pRecord
->m_nDeviceAnsweringCount
++;
610 pRecord
->m_DeviceAnsweringTree
.FindwithAddRecord(&m_Frame
.m_SourceIPAddress
);
615 if (m_Frame
.IsWakeFrame())
617 if (pRecord
->m_nLastWakeFrameIndex
!= m_nFrameCount
)
619 pRecord
->m_nLastWakeFrameIndex
= m_nFrameCount
;
620 if (pRecord
->m_lastQUFrameTime
+1000000ll < m_Frame
.GetTime() || pRecord
->m_lastQUFrameTime
== 0) // last qu frame has been over 1 sec
622 pRecord
->m_nWakeFrames
++;
623 pRecord
->m_lastQUFrameTime
= m_Frame
.GetTime();
624 device
->QUFrame
.Increment(m_nFrameCount
);
626 pRecord
->m_lastQUFrameTime
= m_Frame
.GetTime();
633 void CBonjourTop::GetOSTypeFromQuery(CDNSRecord
*pDNSRecord
,BJString
& ServiceName
)
635 if (pDNSRecord
->m_RecType
== DNS_TYPE_PTR
)
637 StringMapNode
* pStringNode
= m_Service2osBrowseMap
.Find(&ServiceName
);
638 if (pStringNode
&& *pStringNode
->value
.GetBuffer() != '?')
640 CIPDeviceNode
*ipNode
= m_IPtoNameMap
.FindwithAddRecord(&m_Frame
.m_SourceIPAddress
);
641 if (ipNode
->pDeviceNode
)
643 StringMapNode
* pStringNode_temp
= m_Service2osBrowseMap
.Find(&ServiceName
);
644 ipNode
->pDeviceNode
->SetDeviceOS(*pStringNode_temp
->value
.GetBuffer(),ServiceName
.GetBuffer());
650 void CBonjourTop::GetOSTypeFromRegistration(CDNSRecord
*pDNSRecord
,BJString
& ServiceName
)
652 CDeviceNode
* deviceNode
= NULL
;
653 BJString sDeviceName
;
655 if (pDNSRecord
->m_RecType
== DNS_TYPE_PTR
)
657 BJString sInstanceName
;
658 pDNSRecord
->GetRdata(sInstanceName
,0,99);
659 CDNSRecord
* pSRVRecord
= m_Frame
.FindAdditionRecord(sInstanceName
, DNS_TYPE_SRV
);
662 pSRVRecord
->GetRdata(sDeviceName
,0,1);
666 sDeviceName
= sInstanceName
;
668 deviceNode
= m_DeviceMap
.Find(&sDeviceName
);
672 if (Name2OSType(sDeviceName
,deviceNode
))
675 StringMapNode
* pStringNode
= m_Service2osRegisterMap
.Find(&ServiceName
);
677 if (pStringNode
== NULL
|| *pStringNode
->value
.GetBuffer() == '?')
682 if (sDeviceName
.GetLength() > 0)
684 // update global device table with os type
687 deviceNode
->SetDeviceOS(*pStringNode
->value
.GetBuffer(),ServiceName
.GetBuffer());
691 bool CBonjourTop::Name2OSType(BJString name
,CDeviceNode
* device
)
695 // try to set device type from common names
696 for (int i
=0; Name2DeviceOS
[i
][0] != 0; i
+=2)
698 if (name
.Contains(Name2DeviceOS
[i
]))
700 device
->SetDeviceOS(Name2DeviceOS
[i
+1][0], "Name Mapping");
706 void CBonjourTop::ProcessFrame(BJ_UINT8
* pBuffer
,BJ_INT32 nLength
,BJ_UINT64 nFrameTime
)
709 m_Frame
.ParseDNSFrame(pBuffer
, nLength
, nFrameTime
);
711 if (m_Collection
.IsValid())
713 // setup static collectby
714 CollectByPacketCount::nFrameIndex
= m_nFrameCount
;
715 CollectBySameSubnetDiffSubnet::bSameSubnet
= m_Frame
.m_SourceIPAddress
.IsIPv6()? true: m_IPv4Addr
.IsSameSubNet(&m_Frame
.m_SourceIPAddress
);
716 m_Collection
.ProcessFrame(&m_Frame
);
720 if (m_Frame
.IsTruncatedFrame())
722 if (m_Frame
.GetAnswerCount() > 0)
724 if (m_AvgAnswerCountForTruncatedFrames
)
726 m_AvgAnswerCountForTruncatedFrames
+= m_Frame
.GetAnswerCount();
727 m_AvgAnswerCountForTruncatedFrames
/=2;
730 m_AvgAnswerCountForTruncatedFrames
+= m_Frame
.GetAnswerCount();
732 if (m_MinAnswerCountForTruncatedFrames
> m_Frame
.GetAnswerCount() || m_MinAnswerCountForTruncatedFrames
== 0)
733 m_MinAnswerCountForTruncatedFrames
= m_Frame
.GetAnswerCount();
734 if (m_MaxAnswerCountForTruncatedFrames
< m_Frame
.GetAnswerCount())
735 m_MaxAnswerCountForTruncatedFrames
= m_Frame
.GetAnswerCount();
740 // find min snapshot bucket
741 time_t now
= time(NULL
);
742 struct tm
* timeStruct
= localtime(&now
);
743 if (m_MinSnapshot
[timeStruct
->tm_hour
][timeStruct
->tm_min
].m_SampleDay
!= timeStruct
->tm_mday
)
745 //Reset Snapshot 24 hour wrap around
746 m_MinSnapshot
[timeStruct
->tm_hour
][timeStruct
->tm_min
].Init();
747 m_MinSnapshot
[timeStruct
->tm_hour
][timeStruct
->tm_min
].m_SampleDay
= timeStruct
->tm_mday
;
750 m_MinSnapshot
[timeStruct
->tm_hour
][timeStruct
->tm_min
].m_nFrameCount
++;
752 if (m_Frame
.GetQuestionCount() == 0 && m_Frame
.GetAnswerCount() > 0)
753 m_SocketStatus
[0].m_nAnswerOnlyFrames
++;
754 else if (m_Frame
.GetQuestionCount() > 0 && m_Frame
.GetAnswerCount() == 0)
755 m_SocketStatus
[0].m_nQuestionOnlyFrames
++;
757 m_SocketStatus
[0].m_nQandAFrames
++;
759 BJString InstanceName
;
761 BJString ApplRecordName
;
763 /// first get the name to address
764 for (int dnsItemsIndex
=m_Frame
.GetQuestionCount(); dnsItemsIndex
< m_Frame
.GetMaxRecords();dnsItemsIndex
++)
766 CDNSRecord
* pDNSRecord
= m_Frame
.GetDnsRecord(dnsItemsIndex
);
767 if (pDNSRecord
== NULL
)
770 if (pDNSRecord
->m_RecType
== DNS_TYPE_A
)
773 pDNSRecord
->GetDnsRecordName(sName
, 0, 1);
775 ip
.Setv4Raw(pDNSRecord
->GetStartofRdata());
777 CDeviceNode
* device
= m_DeviceMap
.FindwithAddRecord(&sName
);
778 device
->ipAddressv4
= ip
;
780 // create ip to name mapping
781 CIPDeviceNode
* pipNode
= m_IPtoNameMap
.FindwithAddRecord(&ip
);
783 if (pipNode
->pDeviceNode
&& pipNode
->pDeviceNode
->bIPName
&& pipNode
->pDeviceNode
->m_Key
!= device
->m_Key
)
785 pipNode
->pDeviceNode
->bDuplicate
= true;
786 device
->MergeData(pipNode
->pDeviceNode
);
787 pipNode
->pDeviceNode
->ClearData();
789 if (!pipNode
->pDeviceNode
->ipAddressv6
.IsEmpty())
791 CIPDeviceNode
* ipv6Node
= m_IPtoNameMap
.Find(&pipNode
->pDeviceNode
->ipAddressv6
);
793 ipv6Node
->pDeviceNode
= device
;
797 pipNode
->pDeviceNode
= device
;
798 Name2OSType(sName
,device
);
801 if (pDNSRecord
->m_RecType
== DNS_TYPE_AAAA
)
804 pDNSRecord
->GetDnsRecordName(sName
, 0, 1);
806 ip
.Setv6Raw(pDNSRecord
->GetStartofRdata());
808 if (ip
.IsIPv6LinkLocal())
810 CDeviceNode
* device
= m_DeviceMap
.FindwithAddRecord(&sName
);
811 device
->ipAddressv6
= ip
;
813 // create ip to name mapping
814 CIPDeviceNode
* pipNode
= m_IPtoNameMap
.FindwithAddRecord(&ip
);
816 if (pipNode
->pDeviceNode
&& pipNode
->pDeviceNode
->bIPName
&& pipNode
->pDeviceNode
->m_Key
!= device
->m_Key
)
818 pipNode
->pDeviceNode
->bDuplicate
= true;
819 device
->MergeData(pipNode
->pDeviceNode
);
820 pipNode
->pDeviceNode
->ClearData();
822 if (!pipNode
->pDeviceNode
->ipAddressv4
.IsEmpty())
824 CIPDeviceNode
* ipv4Node
= m_IPtoNameMap
.Find(&pipNode
->pDeviceNode
->ipAddressv4
);
826 ipv4Node
->pDeviceNode
= device
;
830 pipNode
->pDeviceNode
= device
;
831 Name2OSType(sName
,device
);
834 if (pDNSRecord
->m_RecType
== DNS_TYPE_SRV
)
835 { // Save SVR to Target
837 pDNSRecord
->GetDnsRecordName(sName
, 0, 1);
838 StringMapNode
*node
= SVRtoDeviceName
.FindwithAddRecord(&sName
);
839 pDNSRecord
->GetRdata(node
->value
, 0, 1);
843 CIPDeviceNode
* pipNode
= m_IPtoNameMap
.FindwithAddRecord(&m_Frame
.m_SourceIPAddress
);
844 CDeviceNode
* device
= pipNode
->pDeviceNode
;
847 // find the device by mac address
848 CMACAddrDeviceNode
*macDevice
= m_MACtoDevice
.FindwithAddRecord(&m_Frame
.m_SourceMACAddress
);
849 device
= macDevice
->device
;
852 // auto create a device record
853 BJString name
= m_Frame
.m_SourceIPAddress
.GetString();
854 device
= m_DeviceMap
.FindwithAddRecord(&name
);
855 device
->bIPName
= true;
856 macDevice
->device
= device
;
859 if (m_Frame
.m_SourceIPAddress
.IsIPv4())
860 device
->ipAddressv4
= m_Frame
.m_SourceIPAddress
;
862 device
->ipAddressv6
= m_Frame
.m_SourceIPAddress
;
863 if (device
->macAddress
.IsEmpty())
864 device
->macAddress
= m_Frame
.m_SourceMACAddress
;
866 pipNode
->pDeviceNode
= device
;
868 device
->bHasFrames
= true;
869 // update mac address
870 if (m_Frame
.IsQueryFrame() || device
->GetDeviceOS() == 'i' ) // iOS don't use BSP so we can use SourceIP
872 if (m_Frame
.m_SourceIPAddress
.IsIPv4())
873 device
->ipAddressv4
= m_Frame
.m_SourceIPAddress
;
874 if (m_Frame
.m_SourceIPAddress
.IsIPv6())
875 device
->ipAddressv6
=m_Frame
.m_SourceIPAddress
;
876 device
->macAddress
= m_Frame
.m_SourceMACAddress
;
879 BJ_UINT8 traceplatform
= TRACE_PLATFORM_UNKNOWN
;
880 BJ_UINT32 traceversion
= 0;
882 if (device
/*&& device->GetDeviceOS() == '?' */&& m_Frame
.GetTracingInfo(traceplatform
, traceversion
, traceMac
))
884 // printf("Tracing Data found platform=%d traceversion=%d\n",traceplatform,traceversion);
885 char platformMap
[]= "?Xitw";
886 device
->SetDeviceOS((traceplatform
< 5) ? platformMap
[traceplatform
] : '?', "EDNS0 Trace");
887 if ((traceplatform
== TRACE_PLATFORM_OSX
) || (traceplatform
== DISCOVERYD_TRACE_PLATFORM_OSX
))
889 device
->bOSXWithEDNSField
= true;
891 else if ((traceplatform
== TRACE_PLATFORM_iOS
) || (traceplatform
== DISCOVERYD_TRACE_PLATFORM_iOS
))
893 device
->biOSWithEDNSField
= true;
897 for (int dnsItemsIndex
=0; dnsItemsIndex
< m_Frame
.GetQuestionCount()+m_Frame
.GetAnswerCount();dnsItemsIndex
++)
902 // printf("Name = %s\n", GetDnsRecordName(&Frame,dnsItemsIndex,tempBuffer,sizeof(tempBuffer),0));
904 CDNSRecord
* pDNSRecord
= m_Frame
.GetDnsRecord(dnsItemsIndex
);
905 if (pDNSRecord
== NULL
)
908 pDNSRecord
->GetDnsRecordName(RecordName
,0,99);
909 InstanceName
= RecordName
;
911 if (RecordName
.Contains("_kerberos."))
913 RecordName
= "_kerberos.";
916 pDNSRecord
->GetDnsRecordName(RecordName
, (pDNSRecord
->m_RecType
== DNS_TYPE_PTR
)?0:1,99);
918 if (pDNSRecord
->m_RecType
== DNS_TYPE_PTR
)
920 if (RecordName
.Contains(".ip6.arpa."))
921 RecordName
= "*.ip6.arpa.";
922 else if (RecordName
.Contains(".arpa."))
923 RecordName
= "*.arpa.";
925 if (pDNSRecord
->m_RecType
== DNS_TYPE_A
)
927 if (pDNSRecord
->m_RecType
== DNS_TYPE_AAAA
)
929 if (pDNSRecord
->m_RecType
== 255)
931 if (RecordName
.Contains(".ip6.arpa."))
932 RecordName
= "ANY *.ip6.arpa.";
933 else if (RecordName
.Contains(".arpa."))
934 RecordName
= "ANY *.arpa.";
938 if (RecordName
.Contains("_sub."))
940 pDNSRecord
->GetDnsRecordName(RecordName
,2,99); /// skip first label and _sub. label
943 BJ_UINT32 nBytes
= pDNSRecord
->m_nNameLength
+ pDNSRecord
->m_nRdataLen
;
945 m_nTotalBytes
+= 10 + nBytes
;
947 if (m_Frame
.m_SourceIPAddress
.IsIPv4())
949 UpdateRecord(m_ServicePtrCache
,pDNSRecord
,RecordName
,RecordName
, nBytes
, (pDNSRecord
->m_nTTL
== 0));
950 UpdateShortRecordHelper(SERVICE_IPV4
, traceplatform
, traceversion
, device
->GetDeviceOS(), pDNSRecord
, RecordName
, RecordName
, nBytes
, (pDNSRecord
->m_nTTL
== 0));
954 UpdateRecord(m_ServicePtrCacheIPv6
,pDNSRecord
,RecordName
,RecordName
, nBytes
, (pDNSRecord
->m_nTTL
== 0));
955 UpdateShortRecordHelper(SERVICE_IPV6
, traceplatform
, traceversion
, device
->GetDeviceOS(), pDNSRecord
, RecordName
, RecordName
, nBytes
, (pDNSRecord
->m_nTTL
== 0));
958 // Add application to cache
959 if (RecordName
.GetLength() != 0)
962 ApplRecordName
= RecordName
;
963 StringMapNode
* pNode
;
964 pNode
= m_Service2AppMap
.Find(&ApplRecordName
);
965 if (pNode
&& ApplRecordName
.GetBuffer() != NULL
)
967 ApplRecordName
= pNode
->value
.GetBuffer();
968 if ( ApplRecordName
== "Device-Info")
970 // find device record
972 pDNSRecord
->GetDnsRecordName(svrName
, 0, 1);
973 StringMapNode
*nodeName
= SVRtoDeviceName
.Find(&svrName
);
975 CDeviceNode
* pDeviceNode
= nodeName
? m_DeviceMap
.Find(&nodeName
->value
) : NULL
;
980 DeviceInfo
.Set((char*)pDNSRecord
->GetStartofRdata(),MIN(pDNSRecord
->m_nRdataLen
,50));
983 for (int i
=0; DeviceInfo2DeviceOS
[i
][0] != 0; i
+=2)
985 if (DeviceInfo
.Contains(DeviceInfo2DeviceOS
[i
]))
987 osType
= *DeviceInfo2DeviceOS
[i
+1];
988 if (pDeviceNode
->GetDeviceOS() != *DeviceInfo2DeviceOS
[i
])
990 pDeviceNode
->SetDeviceOS(osType
,"_device-info._tcp.local.");
991 pDeviceNode
->SetModel(DeviceInfo2DeviceOS
[i
]);
998 if (osType
== 'X' || (pDeviceNode
&& pDeviceNode
->GetDeviceOS() == 'X'))
999 ApplRecordName
= "Finder";
1000 if (osType
== 't' || (pDeviceNode
&& pDeviceNode
->GetDeviceOS() == 't'))
1001 ApplRecordName
= "AirPlay";
1003 if (pDeviceNode
&& pDeviceNode
->GetDeviceOS() == '?' && pDNSRecord
->m_nRdataLen
> 0)
1005 BJString DeviceInfo_temp
;
1006 DeviceInfo_temp
.Set((char*)pDNSRecord
->GetStartofRdata(),MIN(pDNSRecord
->m_nRdataLen
,25));
1013 ApplRecordName
= "Other";
1016 if (m_Frame
.m_SourceIPAddress
.IsIPv4())
1018 UpdateRecord(m_ApplPtrCache
,pDNSRecord
,ApplRecordName
,RecordName
, nBytes
, (pDNSRecord
->m_nTTL
== 0));
1019 UpdateShortRecordHelper(APP_IPV4
, traceplatform
, traceversion
, device
->GetDeviceOS(), pDNSRecord
, ApplRecordName
, RecordName
, nBytes
, (pDNSRecord
->m_nTTL
== 0));
1024 UpdateRecord(m_ApplPtrCacheIPv6
,pDNSRecord
,ApplRecordName
,RecordName
, nBytes
, (pDNSRecord
->m_nTTL
== 0));
1025 UpdateShortRecordHelper(APP_IPV6
, traceplatform
, traceversion
, device
->GetDeviceOS(), pDNSRecord
, ApplRecordName
, RecordName
, nBytes
, (pDNSRecord
->m_nTTL
== 0));
1038 CStringTree m_SortedCache
;
1042 static int CbPrintResults(const void* pNode
, const void* pParam
)
1044 CStringNode
* pRecord
= (CStringNode
*)pNode
;
1045 CSortOptions
* pSortedOption
= (CSortOptions
*)pParam
;
1047 CStringNode
* pNewRecord
;
1049 BJ_UINT64 SortKey
=0;
1050 switch (pSortedOption
->m_nSortCol
) {
1052 SortKey
= Hash2(pRecord
->m_Value
); // cheat the sort to the first 8 char
1055 SortKey
= pRecord
->m_nBytes
;
1058 SortKey
= pRecord
->m_nFrames
;
1061 SortKey
= pRecord
->m_nQuestionFrames
;
1064 SortKey
= pRecord
->m_nAnswerFrames
;
1071 pNewRecord
= pSortedOption
->m_SortedCache
.AddRecord(&SortKey
);
1075 pNewRecord
->CopyNode(pRecord
);
1083 static int CbPrintUnknownDevice(const void* pNode
, const void*)
1085 CDeviceNode
* pDeviceRecord
= (CDeviceNode
*)pNode
;
1087 if (pDeviceRecord
->GetDeviceOS() != '?')
1090 // printf("%s %s\n",pDeviceRecord->m_Key.GetBuffer(), pDeviceRecord->macAddress.GetString());
1096 static int CbBuildMacMap(const void* pNode
, const void* pParam
)
1098 CDeviceNode
* pDeviceNode
= (CDeviceNode
*)pNode
;
1099 CMACAddrTree
* pMacMap
= (CMACAddrTree
*)pParam
;
1102 BJMACAddr vendorMac
;
1103 vendorMac
.CopyVendor(pDeviceNode
->macAddress
);
1104 if (vendorMac
.IsEmpty())
1109 if (pDeviceNode
->GetDeviceOS() == '?')
1111 // try to set device type from MAC address
1112 CMACAddrNode
* pMacRecord
= pMacMap
->Find(&vendorMac
);
1113 if (pMacRecord
!= NULL
&& pDeviceNode
->GetDeviceOS() == '?')
1115 pDeviceNode
->SetDeviceOS(pMacRecord
->deviceOS
, "MAC Mapping");
1116 // printf("update device %s %c\n",vendorMac.GetStringVendor(),pMacRecord->deviceOS);
1119 if (pDeviceNode
->GetDeviceOS() == '?')
1124 CMACAddrNode
* pMacRecord
= pMacMap
->Find(&vendorMac
);
1125 if (pMacRecord
== NULL
)
1127 pMacRecord
= pMacMap
->FindwithAddRecord(&vendorMac
);
1128 pMacRecord
->deviceOS
= pDeviceNode
->GetDeviceOS();
1129 pMacRecord
->model
= pDeviceNode
->model
;
1130 pMacRecord
->method
= pDeviceNode
->settingService
;
1135 /// if (pMacRecord && pMacRecord->deviceOS != pDeviceNode->GetDeviceOS())
1136 // printf("Mac Mapping Bad deviceOS %c != %c %s %s %s\n", pMacRecord->deviceOS, pDeviceNode->GetDeviceOS(),pMacRecord->method.GetBuffer(), pDeviceNode->settingService.GetBuffer(),vendorMac.GetStringVendor());
1137 // if (pMacRecord && !(pMacRecord->model == pDeviceNode->model) && pMacRecord->model.GetLength() > 0 && pDeviceNode->model.GetLength() > 0)
1138 // printf("Mac Mapping Bad model %s != %s\n", pMacRecord->model.GetBuffer(), pDeviceNode->model.GetBuffer());
1145 CStringNode
* CBonjourTop::GetCurrentDisplayRoot(BJString
&sTitle
)
1147 CStringNode
* pRecord
= NULL
;
1149 switch(m_CurrentDisplay
)
1151 case BJ_DISPLAY_APP
:
1152 pRecord
= m_ApplPtrCache
.GetRoot();
1153 sTitle
= "Application (IPv4)";
1155 case BJ_DISPLAY_APPv6
:
1156 pRecord
= m_ApplPtrCacheIPv6
.GetRoot();
1157 sTitle
= "Application (IPv6)";
1159 case BJ_DISPLAY_SERVICE
:
1160 pRecord
= m_ServicePtrCache
.GetRoot();
1161 sTitle
= "Services (IPv4)";
1163 case BJ_DISPLAY_SERVICEv6
:
1164 pRecord
= m_ServicePtrCacheIPv6
.GetRoot();
1165 sTitle
= "Services (IPv6)";
1167 case BJ_DISPLAY_24_MIN
:
1173 void CBonjourTop::UpdateOSCounts()
1177 CDeviceNode
* pDeviceNode
= m_DeviceMap
.GetRoot();
1180 pDeviceNode
->CallBack(&CbBuildMacMap
,&m_MacMap
);
1181 // pDeviceNode->CallBack(&CbPrintUnknownDevice,NULL);
1185 // Update Application Caches
1186 CStringNode
* pCacheRoot
= m_ApplPtrCache
.GetRoot();
1190 pCacheRoot
->UpdateOSTypeCounts(&m_DeviceMap
,&m_IPtoNameMap
);
1192 pCacheRoot
= m_ApplPtrCacheIPv6
.GetRoot();
1196 pCacheRoot
->UpdateOSTypeCounts(&m_DeviceMap
,&m_IPtoNameMap
);
1199 // Update Service caches
1200 pCacheRoot
= m_ServicePtrCache
.GetRoot();
1204 pCacheRoot
->UpdateOSTypeCounts(&m_DeviceMap
,&m_IPtoNameMap
);
1206 pCacheRoot
= m_ServicePtrCacheIPv6
.GetRoot();
1210 pCacheRoot
->UpdateOSTypeCounts(&m_DeviceMap
,&m_IPtoNameMap
);
1215 void CBonjourTop::PrintResults(int nSortCol
, bool bSortAsc
)
1219 GetCurrentDisplayRoot(sTitle
);
1220 device_count devCount
;
1221 BJString sTableTitle
;
1226 BJ_UINT64 nRate
= 0;
1227 BJ_UINT64 nElapsedTime
= m_EndTime
-m_StartTime
;
1228 if (nElapsedTime
> 0)
1230 nRate
= (m_nFrameCount
*3600) /nElapsedTime
;
1237 printw("While running the follow keys may be used:\n");
1238 printw("[p = sort by Packets (default)], [b = sort by Bytes], [n = sort by Name]\n");
1239 printw("[a = Display Application Names (default)], [s = Display Services Names], [t = Display 24 hour packet per min]\n");
1240 printw("[o = flip sort order], [e = export to BonjourTop.csv], [q = quit]\n\n");
1242 printw("Total Packets: %llu, Total Bytes: %llu, Elapse Time: %lld sec, Rate: %llu packet/hr\n",m_nFrameCount
,m_nTotalBytes
,nElapsedTime
,nRate
);
1243 printw("IPv4 multicast: %llu, IPv6 multicast: %llu, IPv4 Unicast: %lld, IPv6 Unicast: %llu\n",m_SocketStatus
[0].m_nFrameCount
,m_SocketStatus
[1].m_nFrameCount
,m_SocketStatus
[2].m_nFrameCount
,m_SocketStatus
[3].m_nFrameCount
);
1244 printw("IPv4 Wrong subnet: %llu, IPv6 Wrong subnet: %llu\n",m_SocketStatus
[4].m_nFrameCount
,m_SocketStatus
[5].m_nFrameCount
);
1245 printw("QuestionOnly Packets: %llu, AnswerOnly Packets: %llu, Q&A Packets %llu\n",m_SocketStatus
[0].m_nQuestionOnlyFrames
,m_SocketStatus
[0].m_nAnswerOnlyFrames
,m_SocketStatus
[0].m_nQandAFrames
);
1246 printw("AnswerCount for truncated frames(min,avg,max): %llu,%llu,%llu\n\n",m_MinAnswerCountForTruncatedFrames
,m_AvgAnswerCountForTruncatedFrames
,m_MaxAnswerCountForTruncatedFrames
);
1248 bzero(&devCount
, sizeof(devCount
));
1249 m_DeviceMap
.GetDeviceOSTypes(m_DeviceMap
.GetRoot(),NULL
, devCount
);
1250 printw("Total Devices: %llu, iOS Devices: %llu(>= iOS7: %llu), OSX Devices %llu(>= OSX 10.9: %llu)\n",devCount
.iOS
+devCount
.OSX
+devCount
.unknownOS
,devCount
.iOS
, devCount
.iOSWithEDNSField
, devCount
.OSX
,devCount
.OSXWithEDNSField
);
1254 printf("\nTotal Packets: %llu, Total Bytes: %llu, Elapse Time: %lld sec, Rate: %llu packet/hr\n",m_nFrameCount
,m_nTotalBytes
,nElapsedTime
,nRate
);
1255 printf("IPv4 multicast: %llu, IPv6 multicast: %llu, IPv4 Unicast: %lld, IPv6 Unicast: %llu\n",m_SocketStatus
[0].m_nFrameCount
,m_SocketStatus
[1].m_nFrameCount
,m_SocketStatus
[2].m_nFrameCount
,m_SocketStatus
[3].m_nFrameCount
);
1256 printf("IPv4 Wrong subnet: %llu, IPv6 Wrong subnet: %llu\n",m_SocketStatus
[4].m_nFrameCount
,m_SocketStatus
[5].m_nFrameCount
);
1257 printf("QuestionOnly Packets: %llu, AnswerOnly Packets: %llu, Q&A Packets %llu\n",m_SocketStatus
[0].m_nQuestionOnlyFrames
,m_SocketStatus
[0].m_nAnswerOnlyFrames
,m_SocketStatus
[0].m_nQandAFrames
);
1259 bzero(&devCount
, sizeof(devCount
));
1260 m_DeviceMap
.GetDeviceOSTypes(m_DeviceMap
.GetRoot(),NULL
, devCount
);
1262 printf("Total Devices: %llu, iOS Devices: %llu(>= iOS7: %llu), OSX Devices %llu(>= OSX 10.9: %llu), unknown Devices %llu\n",devCount
.iOS
+devCount
.OSX
+devCount
.unknownOS
,devCount
.iOS
, devCount
.iOSWithEDNSField
,devCount
.OSX
,devCount
.OSXWithEDNSField
,devCount
.unknownOS
);
1263 printf("AnswerCount for truncated frames(min,avg,max): %llu,%llu,%llu\n\n",m_MinAnswerCountForTruncatedFrames
,m_AvgAnswerCountForTruncatedFrames
,m_MaxAnswerCountForTruncatedFrames
);
1265 PrintDetailResults(nSortCol
, bSortAsc
);
1269 void CBonjourTop::PrintDetailResults(int nSortCol
, bool bSortAsc
)
1272 CStringNode
* pCacheRoot
= GetCurrentDisplayRoot(sTitle
);
1276 if(m_CurrentDisplay
== CBonjourTop::BJ_DISPLAY_24_MIN
)
1279 for(int i
=0;i
<24;i
++)
1285 printw("\n%s\n",sTitle
.GetBuffer());
1286 printw(" %- 30s %10s %10s%24s%24s%24s%24s%24s\n","","","Total","Question","Answer","Asking","Answering", "Total");
1287 printw(" %- 30s %10s%24s%24s%24s %23s%24s%24s %11s %10s\n","Name","Bytes","Packets( iOS/ OSX)","Packets( iOS/ OSX)","Packets( iOS/ OSX)","Devices( iOS/ OSX)","Devices( iOS/ OSX)","Devices( iOS/ OSX)", "QU Bit","Goodbye");
1292 if(m_CurrentDisplay
== CBonjourTop::BJ_DISPLAY_24_MIN
)
1298 printf("\n%s\n",sTitle
.GetBuffer());
1299 printf(" %-30s %10s %10s%24s%24s%24s%24s%24s\n","","","Total","Question","Answer","Asking","Answering", "Total");
1300 printf(" %-30s %10s%24s%24s%24s %23s%24s%24s %11s %10s\n","Name","Bytes","Packets( iOS/ OSX)","Packets( iOS/ OSX)","Packets( iOS/ OSX)","Devices( iOS/ OSX)","Devices( iOS/ OSX)","Devices( iOS/ OSX)", "QU Bit","Goodbye");
1303 if (m_CurrentDisplay
== CBonjourTop::BJ_DISPLAY_24_MIN
)
1306 for(int m
=0;m
<60;m
++)
1309 for (int h
=0;h
<24;h
++)
1310 printw("%5d ",m_MinSnapshot
[h
][m
].m_nFrameCount
);
1317 CSortOptions SortOptions
;
1318 SortOptions
.m_nSortCol
= nSortCol
;
1321 pCacheRoot
->UpdateOSTypeCounts(&m_DeviceMap
,&m_IPtoNameMap
);
1324 pCacheRoot
->CallBack(&CbPrintResults
,&SortOptions
);
1328 CStringNode
* pRecord
= SortOptions
.m_SortedCache
.GetRoot();
1329 BJ_UINT32 nIndex
= 1;
1332 pRecord
->Print(m_bCursers
,bSortAsc
, nIndex
,0,40);
1338 void CBonjourTop::LiveCapture()
1341 const BJ_UINT16 BonjourPort
= 5353;
1344 BJSelect SockSelect
;
1346 Sockv4
.CreateListenerIPv4(interfaceName
);
1347 Sockv6
.CreateListenerIPv6(interfaceName
);
1349 SockSelect
.Add(Sockv4
);
1350 SockSelect
.Add(Sockv6
);
1353 m_StartTime
= time(NULL
);
1355 bool bSortAsc
= false;
1360 SockSelect
.Add(Sockv4
);
1361 SockSelect
.Add(Sockv6
);
1363 int result
= SockSelect
.Wait(1);
1366 // if SockSelect.Wait failed due to an interrupt, then we want to continue processing the packets
1371 printf("Error in Select\n");
1375 if (SockSelect
.IsReady(Sockv4
))
1378 int recvsize
= Sockv4
.Read();
1380 if ((recvsize
!= 0) &&
1381 (Sockv4
.GetSrcAddr()->GetPortNumber() == BonjourPort
))
1384 m_SocketStatus
[Sockv4
.IsMulticastPacket()? 0:2].m_nFrameCount
++;
1386 if (!m_IPv4Addr
.IsSameSubNet(Sockv4
.GetSrcAddr()))
1388 m_SocketStatus
[4].m_nFrameCount
++;
1390 m_Frame
.m_SourceIPAddress
= *Sockv4
.GetSrcAddr();
1391 ProcessFrame(Sockv4
.GetBuffer(),recvsize
,Sockv4
.m_CurrentFrame
.GetTime());
1395 if (SockSelect
.IsReady(Sockv6
))
1397 int recvsize
= Sockv6
.Read();
1398 if ((recvsize
!= 0) &&
1399 (Sockv6
.GetSrcAddr()->GetPortNumber() == BonjourPort
))
1402 m_SocketStatus
[Sockv6
.IsMulticastPacket()? 1:3].m_nFrameCount
++;
1403 m_Frame
.m_SourceIPAddress
= *Sockv6
.GetSrcAddr();
1405 ProcessFrame(Sockv6
.GetBuffer(),recvsize
,Sockv6
.m_CurrentFrame
.GetTime());
1415 bSortAsc
= !bSortAsc
;
1416 result
= 0; // force an update
1420 result
= 0; // force an update
1424 result
= 0; // force an update
1429 else if (nSortCol
== 3)
1433 result
= 0; // force an update
1437 if (m_CurrentDisplay
== CBonjourTop::BJ_DISPLAY_APP
)
1438 m_CurrentDisplay
= CBonjourTop::BJ_DISPLAY_APPv6
;
1440 m_CurrentDisplay
= CBonjourTop::BJ_DISPLAY_APP
;
1446 if (m_CurrentDisplay
== CBonjourTop::BJ_DISPLAY_SERVICE
)
1447 m_CurrentDisplay
= CBonjourTop::BJ_DISPLAY_SERVICEv6
;
1449 m_CurrentDisplay
= CBonjourTop::BJ_DISPLAY_SERVICE
;
1454 m_CurrentDisplay
= CBonjourTop::BJ_DISPLAY_24_MIN
;
1466 result
= 0; // force an update
1469 result
= 0; // force an update
1472 if (window_size_changed
)
1476 window_size_changed
= false;
1479 if (m_EndTime
!= time(NULL
) || result
== 0)
1481 m_EndTime
= time(NULL
);
1482 PrintResults(nSortCol
,bSortAsc
);
1483 if (m_SnapshotSeconds
&& (time(NULL
) - m_StartTime
) > m_SnapshotSeconds
)
1486 if (m_bImportExportDeviceMap
)
1499 void CBonjourTop::CaptureFile()
1501 CCaptureFile CaptureFile
;
1502 BJIPAddr
* pIPSrcAddr
;
1503 BJIPAddr
* pIPDestAddr
;
1505 CIPAddrMap LocalSubnetIPv6
;
1508 CaptureFile
.Open(m_pTcpDumpFileName
);
1511 int nFrameIndex
= 0;
1513 while (CaptureFile
.NextFrame())
1517 BJ_UINT8
* pBonjourBuffer
= (BJ_UINT8
*)CaptureFile
.m_CurrentFrame
.GetBonjourStart();
1518 if (!pBonjourBuffer
)
1522 m_nTotalBytes
+= CaptureFile
.GetWiredLength();
1524 pIPSrcAddr
= CaptureFile
.m_CurrentFrame
.GetSrcIPAddr();
1525 pIPDestAddr
= CaptureFile
.m_CurrentFrame
.GetDestIPAddr();
1526 m_Frame
.m_SourceIPAddress
= *CaptureFile
.m_CurrentFrame
.GetSrcIPAddr();;
1527 m_Frame
.m_SourceMACAddress
= *CaptureFile
.m_CurrentFrame
.GetSrcMACAddr();
1529 if (pIPSrcAddr
->IsIPv4())
1531 // check fragment flag
1532 BJ_UINT8
* pIP
= CaptureFile
.m_CurrentFrame
.GetIPStart();
1533 BJ_UINT16 flags
= * ((BJ_UINT16
*)(pIP
+6));
1537 if (!m_IPv4Addr
.IsEmptySubnet())
1539 if (m_IPv4Addr
.IsSameSubNet(pIPSrcAddr
))
1541 BJ_UINT8
* pSourceMac
= CaptureFile
.m_CurrentFrame
.GetEthernetStart()+6;
1543 IPv6Addr
.CreateLinkLocalIPv6(pSourceMac
);
1544 LocalSubnetIPv6
.FindwithAddRecord(&IPv6Addr
);
1549 m_SocketStatus
[4].m_nFrameCount
++;
1551 if (!m_Collection
.IsValid())
1555 m_SocketStatus
[(pIPDestAddr
->IsBonjourMulticast())?0:2].m_nFrameCount
++;
1557 if (pIPSrcAddr
->IsIPv6())
1559 if (!LocalSubnetIPv6
.Find(pIPSrcAddr
) && !m_IPv4Addr
.IsEmptySubnet())
1561 m_SocketStatus
[5].m_nFrameCount
++;
1562 if (!m_Collection
.IsValid())
1565 m_SocketStatus
[(pIPDestAddr
->IsBonjourMulticast())?1:3].m_nFrameCount
++;
1568 ProcessFrame(pBonjourBuffer
,CaptureFile
.GetBufferLen((pBonjourBuffer
)),CaptureFile
.m_CurrentFrame
.GetTime());
1571 m_EndTime
= CaptureFile
.GetDeltaTime();
1573 PrintResults(2,false);
1574 if ( m_CurrentDisplay
== BJ_DISPLAY_APP
)
1575 m_CurrentDisplay
= BJ_DISPLAY_APPv6
;
1577 m_CurrentDisplay
= BJ_DISPLAY_SERVICEv6
;
1579 PrintDetailResults(2,false);
1583 void CBonjourTop::ExportPtrCache(FILE* hFile
, BJString sTitle
,CStringNode
* pRoot
)
1585 fprintf(hFile
,"%s\n",sTitle
.GetBuffer());
1586 fprintf(hFile
,"Name,Bytes,Total Packets,Total Packets iOS,Total Packets OSX,Question Packets,Question Packets iOS,Question Packets OSX,Answer Packets,Answer Packets iOS,Answer Packets OSX,Asking Devices, Asking Devices iOS,Asking Devices OSX,Answering Devices,Answering Devices iOS,Answering Devices OSX,Total Devices,Total Devices iOS, Total Devices OSX,QU Bit,Goodbye\n");
1589 pRoot
->Export(hFile
);
1592 void CBonjourTop::ExportShortCacheHelper(FILE* hFile
, BJString sTitle
, CStringShortNode
* pRoot
)
1594 fprintf(hFile
,"%s\n",sTitle
.GetBuffer());
1595 fprintf(hFile
,"Name,Bytes,Total Packets,Question Packets,Answer Packets,Asking Devices,Answering Devices,Total Devices,QU Bit,Goodbye\n");
1599 pRoot
->Export(hFile
);
1604 void CBonjourTop::ExportShortCache(FILE* hFile
, BJString sTitle
, map
<BJString
, CStringShortTree
*>* myMap
)
1606 CStringShortTree
* cache
;
1607 BJString versionNumber
;
1609 fprintf(hFile
,"%s\n",sTitle
.GetBuffer());
1611 for (map
<BJString
, CStringShortTree
*>::iterator it
= myMap
->begin(); it
!= myMap
->end(); ++it
)
1613 versionNumber
= (*it
).first
;
1614 cache
= (*it
).second
;
1616 ExportShortCacheHelper(hFile
, versionNumber
, cache
->GetRoot());
1620 void CBonjourTop::ExportResults()
1623 BJString sTempFileName
;
1624 device_count devCount
;
1625 sTempFileName
= m_pExportFileName
;
1627 if (m_SnapshotSeconds
)
1629 BJString sTimeStamp
;
1630 sTimeStamp
.Format(time(NULL
), BJString::BJSS_TIME
);
1631 sTempFileName
+= "_";
1632 sTempFileName
+= sTimeStamp
;
1634 sTempFileName
+= ".csv";
1636 if (m_Collection
.IsValid())
1638 m_Collection
.ExportCollection(sTempFileName
);
1642 FILE* hFile
= fopen(sTempFileName
.GetBuffer(),"w");
1646 printf("file open failed %s\n",m_pExportFileName
);
1650 fprintf(hFile
,"Total Number of Frames, %llu\n",m_nFrameCount
);
1651 fprintf(hFile
,"Total Number of Bytes, %llu\n",m_nTotalBytes
);
1652 fprintf(hFile
,"Total Number of Sec, %llu\n",m_EndTime
-m_StartTime
);
1654 bzero(&devCount
, sizeof(devCount
));
1655 m_DeviceMap
.GetDeviceOSTypes(m_DeviceMap
.GetRoot(),NULL
, devCount
);
1656 fprintf(hFile
,"Total Number of Devices, %llu\n\n",devCount
.iOS
+devCount
.OSX
+devCount
.unknownOS
);
1657 fprintf(hFile
,"Total Number of iOS Devices, %llu\n",devCount
.iOS
);
1658 fprintf(hFile
,"Total Number of iOS Devices (>= iOS7), %llu\n", devCount
.iOSWithEDNSField
);
1659 fprintf(hFile
,"Total Number of OSX Devices, %llu\n",devCount
.OSX
);
1660 fprintf(hFile
,"Total Number of OSX Devices (>= OSX 10.9), %llu\n",devCount
.OSXWithEDNSField
);
1662 fprintf(hFile
,"IPv4 multicast, %llu\n",m_SocketStatus
[0].m_nFrameCount
);
1663 fprintf(hFile
,"IPv6 multicast, %llu\n",m_SocketStatus
[1].m_nFrameCount
);
1664 fprintf(hFile
,"IPv4 Unicast, %llu\n",m_SocketStatus
[2].m_nFrameCount
);
1665 fprintf(hFile
,"IPv6 Unicast, %llu\n",m_SocketStatus
[3].m_nFrameCount
);
1666 fprintf(hFile
,"IPv4 Wrong subnet, %llu\n",m_SocketStatus
[4].m_nFrameCount
);
1667 fprintf(hFile
,"IPv6 Wrong subnet, %llu\n\n",m_SocketStatus
[5].m_nFrameCount
);
1669 fprintf(hFile
,"QuestionOnly Packets, %llu\n", m_SocketStatus
[0].m_nQuestionOnlyFrames
);
1670 fprintf(hFile
,"AnswerOnly Packets, %llu\n", m_SocketStatus
[0].m_nAnswerOnlyFrames
);
1671 fprintf(hFile
,"Q&A Packets, %llu\n\n", m_SocketStatus
[0].m_nQandAFrames
);
1673 fprintf(hFile
,"AnswerCount for truncated frames min, %llu\n", m_MinAnswerCountForTruncatedFrames
);
1674 fprintf(hFile
,"AnswerCount for truncated frames avg, %llu\n", m_AvgAnswerCountForTruncatedFrames
);
1675 fprintf(hFile
,"AnswerCount for truncated frames max, %llu\n\n", m_MaxAnswerCountForTruncatedFrames
);
1679 ExportPtrCache(hFile
,"Application IPv4 Cache",m_ApplPtrCache
.GetRoot());
1680 ExportShortCache(hFile
, "OSX", &m_AppBreakdownIPv4OSX
);
1681 ExportShortCache(hFile
, "iOS", &m_AppBreakdownIPv4iOS
);
1683 ExportPtrCache(hFile
,"Application IPv6 Cache",m_ApplPtrCacheIPv6
.GetRoot());
1684 ExportShortCache(hFile
, "OSX", &m_AppBreakdownIPv6OSX
);
1685 ExportShortCache(hFile
, "iOS", &m_AppBreakdownIPv6iOS
);
1687 ExportPtrCache(hFile
,"Service IPv4 Cache",m_ServicePtrCache
.GetRoot());
1688 ExportShortCache(hFile
, "OSX", &m_ServiceBreakdownIPv4OSX
);
1689 ExportShortCache(hFile
, "iOS", &m_ServiceBreakdownIPv4iOS
);
1691 ExportPtrCache(hFile
,"Service IPv6 Cache",m_ServicePtrCacheIPv6
.GetRoot());
1692 ExportShortCache(hFile
, "OSX", &m_ServiceBreakdownIPv6OSX
);
1693 ExportShortCache(hFile
, "iOS", &m_ServiceBreakdownIPv6iOS
);
1695 /// min snapshot table
1697 fprintf(hFile
,"Min Snapshot table\n");
1699 for (int h
=0;h
<24;h
++)
1701 for(int m
=0;m
<60;m
++)
1703 if (m_MinSnapshot
[h
][m
].m_nFrameCount
)
1705 fprintf(hFile
,"%02d:%02d,%llu\n",h
,m
,m_MinSnapshot
[h
][m
].m_nFrameCount
);
1715 void CBonjourTop::WriteDeviceFile()
1717 BJString sTempFileName
;
1718 BJString sTimeStamp
;
1720 sTempFileName
= m_DeviceFileName
;
1721 sTimeStamp
.Format(time(NULL
), BJString::BJSS_TIME
);
1722 sTempFileName
+= "_";
1723 sTempFileName
+= sTimeStamp
;
1724 sTempFileName
+= ".csv";
1726 FILE* hFile
= fopen(sTempFileName
.GetBuffer(),"w");
1730 printf("file open failed %s\n",sTempFileName
.GetBuffer());
1734 fprintf(hFile
,"\"Name\",\"IPv4Address\",\"IPv6Address\",\"MACAddress\",O,\"Model\",\"Method\",\"total frames\",\"question frames\",\"QU frames\",\"answer frames\"\n");
1736 CDeviceNode
*pDeviceNode
= m_DeviceMap
.GetRoot();
1739 pDeviceNode
->Export(hFile
);
1743 printf("devicemap count %llu %d\n",m_DeviceMap
.GetCount(),CDeviceNode::nCreateCount
);
1747 void CBonjourTop::WriteVendorFile()
1749 BJString sTempFileName
= "BonjourTopVendor";
1750 BJString sTimeStamp
;
1752 sTimeStamp
.Format(time(NULL
), BJString::BJSS_TIME
);
1753 sTempFileName
+= "_";
1754 sTempFileName
+= sTimeStamp
;
1755 sTempFileName
+= ".csv";
1757 FILE* hFile
= fopen(sTempFileName
.GetBuffer(),"w");
1761 printf("file open failed %s\n",sTempFileName
.GetBuffer());
1764 fprintf(hFile
,"\"MACAddress\",O,\"Model\",\"Method\"\n");
1766 CMACAddrNode
*node
= m_MacMap
.GetRoot();
1769 node
->Export(hFile
);
1774 void CBonjourTop::WindowSizeChanged()
1776 window_size_changed
= true;
1779 BJ_UINT64
Hash(const char* pStr
)
1785 while ((c
= *pStr
++))
1793 BJ_UINT64
Hash2(char* pStr
)
1800 while ((c
= *pStr
++) && i
++ < 8)
1811 static integer_t
Usage(void)
1813 task_t targetTask
= mach_task_self();
1814 struct task_basic_info ti
;
1815 mach_msg_type_number_t count
= TASK_BASIC_INFO_64_COUNT
;
1817 kern_return_t kr
= task_info(targetTask
, TASK_BASIC_INFO_64
,
1818 (task_info_t
) &ti
, &count
);
1819 if (kr
!= KERN_SUCCESS
)
1821 printf("Kernel returned error during memory usage query");
1825 // On Mac OS X, the resident_size is in bytes, not pages!
1826 // (This differs from the GNU Mach kernel)
1827 // return ti.resident_size;
1828 return ti
.user_time
.seconds
;
1836 void CStringNode::UpdateOSTypeCounts(CDeviceMap
* pGlobalDeviceMap
,CIPAddrMap
*pIp2NameMap
)
1839 ((CStringNode
*)m_rbLeft
)->UpdateOSTypeCounts(pGlobalDeviceMap
,pIp2NameMap
);
1841 ((CStringNode
*)m_rbRight
)->UpdateOSTypeCounts(pGlobalDeviceMap
,pIp2NameMap
);
1843 BJ_UINT64 nDeviceUnknown
= 0;
1844 m_nDeviceAskingiOSCount
= 0;
1845 m_nDeviceAskingOSXCount
= 0;
1846 m_nDeviceAnsweringiOSCount
= 0;
1847 m_nDeviceAnsweringOSXCount
= 0;
1848 m_nDeviceTotaliOSCount
= 0;
1849 m_nDeviceTotalOSXCount
= 0;
1850 m_DeviceAskingTree
.GetDeviceOSTypes(m_DeviceAskingTree
.GetRoot(),pIp2NameMap
,m_nDeviceAskingiOSCount
,m_nDeviceAskingOSXCount
,nDeviceUnknown
);
1852 m_DeviceAnsweringTree
.GetDeviceOSTypes(m_DeviceAnsweringTree
.GetRoot(),pIp2NameMap
,m_nDeviceAnsweringiOSCount
,m_nDeviceAnsweringOSXCount
,nDeviceUnknown
);
1854 m_DeviceTotalTree
.GetDeviceOSTypes(m_DeviceTotalTree
.GetRoot(), pIp2NameMap
, m_nDeviceTotaliOSCount
, m_nDeviceTotalOSXCount
, nDeviceUnknown
);
1857 void CStringNode::Print(bool bCursers
,bool bDescendingSort
,BJ_UINT32
&nIndex
, BJ_UINT32 nStartIndex
,BJ_UINT32 nEndIndex
)
1859 if (bDescendingSort
)
1862 ((CStringNode
*)m_rbLeft
)->Print(bCursers
,bDescendingSort
,nIndex
,nStartIndex
,nEndIndex
);
1864 if (nIndex
>= nStartIndex
&& nIndex
<= nEndIndex
)
1868 printw("%3d. %-30s %10llu %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu %10llu\n",nIndex
,(char*)&(m_Value
),m_nBytes
,m_nFrames
, m_nFramesiOS
, m_nFramesOSX
, m_nQuestionFrames
, m_nQuestionFramesiOS
, m_nQuestionFramesOSX
, m_nAnswerFrames
,m_nAnswerFramesiOS
, m_nAnswerFramesOSX
, m_nDeviceAskingCount
,m_nDeviceAskingiOSCount
,m_nDeviceAskingOSXCount
, m_nDeviceAnsweringCount
,m_nDeviceAnsweringiOSCount
,m_nDeviceAnsweringOSXCount
, m_nDeviceTotalCount
, m_nDeviceTotaliOSCount
, m_nDeviceTotalOSXCount
, m_nWakeFrames
,m_nGoodbyeFrames
);
1873 printf("%3d. %-30s %10llu %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu %10llu\n",nIndex
,(char*)&(m_Value
),m_nBytes
,m_nFrames
, m_nFramesiOS
, m_nFramesOSX
, m_nQuestionFrames
, m_nQuestionFramesiOS
, m_nQuestionFramesOSX
, m_nAnswerFrames
,m_nAnswerFramesiOS
, m_nAnswerFramesOSX
, m_nDeviceAskingCount
,m_nDeviceAskingiOSCount
,m_nDeviceAskingOSXCount
, m_nDeviceAnsweringCount
,m_nDeviceAnsweringiOSCount
,m_nDeviceAnsweringOSXCount
, m_nDeviceTotalCount
, m_nDeviceTotaliOSCount
, m_nDeviceTotalOSXCount
, m_nWakeFrames
,m_nGoodbyeFrames
);
1879 ((CStringNode
*)m_rbRight
)->Print(bCursers
,bDescendingSort
,nIndex
,nStartIndex
,nEndIndex
);
1884 ((CStringNode
*)m_rbRight
)->Print(bCursers
,bDescendingSort
,nIndex
,nStartIndex
,nEndIndex
);
1886 if (nIndex
>= nStartIndex
&& nIndex
<= nEndIndex
)
1890 printw("%3d. %-30s %10llu %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu %10llu\n",nIndex
,(char*)&(m_Value
),m_nBytes
,m_nFrames
, m_nFramesiOS
, m_nFramesOSX
, m_nQuestionFrames
, m_nQuestionFramesiOS
, m_nQuestionFramesOSX
, m_nAnswerFrames
,m_nAnswerFramesiOS
, m_nAnswerFramesOSX
, m_nDeviceAskingCount
,m_nDeviceAskingiOSCount
,m_nDeviceAskingOSXCount
, m_nDeviceAnsweringCount
,m_nDeviceAnsweringiOSCount
,m_nDeviceAnsweringOSXCount
, m_nDeviceTotalCount
, m_nDeviceTotaliOSCount
, m_nDeviceTotalOSXCount
, m_nWakeFrames
,m_nGoodbyeFrames
);
1894 printf("%3d. %-30s %10llu %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu(%5llu/%5llu) %10llu %10llu\n",nIndex
,(char*)&(m_Value
),m_nBytes
,m_nFrames
, m_nFramesiOS
, m_nFramesOSX
, m_nQuestionFrames
, m_nQuestionFramesiOS
, m_nQuestionFramesOSX
, m_nAnswerFrames
,m_nAnswerFramesiOS
, m_nAnswerFramesOSX
, m_nDeviceAskingCount
,m_nDeviceAskingiOSCount
,m_nDeviceAskingOSXCount
, m_nDeviceAnsweringCount
,m_nDeviceAnsweringiOSCount
,m_nDeviceAnsweringOSXCount
, m_nDeviceTotalCount
, m_nDeviceTotaliOSCount
, m_nDeviceTotalOSXCount
, m_nWakeFrames
,m_nGoodbyeFrames
);
1899 ((CStringNode
*)m_rbLeft
)->Print(bCursers
,bDescendingSort
,nIndex
,nStartIndex
,nEndIndex
);
1903 void CStringNode::Export(FILE* hFile
)
1905 fprintf(hFile
, "%s,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu\n",
1906 (char*)&(m_Value
),m_nBytes
,
1907 m_nFrames
, m_nFramesiOS
, m_nFramesOSX
,
1908 m_nQuestionFrames
, m_nQuestionFramesiOS
, m_nQuestionFramesOSX
,
1909 m_nAnswerFrames
, m_nAnswerFramesiOS
, m_nAnswerFramesOSX
,
1910 m_nDeviceAskingCount
, m_nDeviceAskingiOSCount
,m_nDeviceAskingOSXCount
,
1911 m_nDeviceAnsweringCount
,m_nDeviceAnsweringiOSCount
,m_nDeviceAnsweringOSXCount
,
1912 m_nDeviceTotalCount
, m_nDeviceTotaliOSCount
, m_nDeviceTotalOSXCount
,
1913 m_nWakeFrames
,m_nGoodbyeFrames
);
1916 ((CStringNode
*)m_rbLeft
)->Export(hFile
);
1918 ((CStringNode
*)m_rbRight
)->Export(hFile
);
1922 /* CStringShortNode */
1924 void CStringShortNode::Export(FILE *hFile
)
1926 fprintf(hFile
, "%s,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu\n",
1927 (char*)&(m_Value
),m_nBytes
,
1928 m_nFrames
, m_nQuestionFrames
, m_nAnswerFrames
,
1929 m_nDeviceAskingCount
, m_nDeviceAnsweringCount
, m_nDeviceTotalCount
,
1930 m_nWakeFrames
,m_nGoodbyeFrames
);
1935 ((CStringShortNode
*)m_rbLeft
)->Export(hFile
);
1939 ((CStringShortNode
*)m_rbRight
)->Export(hFile
);
1945 void CDeviceMap::GetDeviceOSTypes(CDeviceNode
*node
, CDeviceMap
*pGlobalDeviceMap
, device_count
& dev_cnt
)
1950 GetDeviceOSTypes(dynamic_cast<CDeviceNode
*>(node
->m_rbLeft
),pGlobalDeviceMap
, dev_cnt
);
1951 GetDeviceOSTypes(dynamic_cast<CDeviceNode
*>(node
->m_rbRight
),pGlobalDeviceMap
, dev_cnt
);
1953 if (node
->bDuplicate
|| !node
->bHasFrames
)
1956 char deviceType
= '?';
1957 if (pGlobalDeviceMap
)
1959 CDeviceNode
* globalDevice
= pGlobalDeviceMap
->Find(&node
->m_Key
);
1962 deviceType
= globalDevice
->GetDeviceOS();
1964 if (globalDevice
->bOSXWithEDNSField
&& deviceType
== 'X')
1966 dev_cnt
.OSXWithEDNSField
++;
1968 else if (globalDevice
->biOSWithEDNSField
&& (deviceType
== 't' || deviceType
== 'i'))
1970 dev_cnt
.iOSWithEDNSField
++;
1976 deviceType
= node
->GetDeviceOS();
1977 if (node
->bOSXWithEDNSField
&& deviceType
== 'X')
1979 dev_cnt
.OSXWithEDNSField
++;
1981 else if (node
->biOSWithEDNSField
&& (deviceType
== 't' || deviceType
== 'i'))
1983 dev_cnt
.iOSWithEDNSField
++;
1996 dev_cnt
.unknownOS
++;
2001 void CIPAddrMap::GetDeviceOSTypes(CIPDeviceNode
* node
, CIPAddrMap
* pGobalMap
, BJ_UINT64
& iOS
,BJ_UINT64
& OSX
,BJ_UINT64
& unknowOS
)
2006 GetDeviceOSTypes(dynamic_cast<CIPDeviceNode
*>(node
->m_rbLeft
),pGobalMap
, iOS
, OSX
, unknowOS
);
2007 GetDeviceOSTypes(dynamic_cast<CIPDeviceNode
*>(node
->m_rbRight
),pGobalMap
,iOS
, OSX
, unknowOS
);
2009 char deviceType
= '?';
2012 CIPDeviceNode
*ipDevice
= pGobalMap
->Find(&node
->m_Key
);
2014 if (ipDevice
&& ipDevice
->pDeviceNode
)
2015 deviceType
= ipDevice
->pDeviceNode
->GetDeviceOS();