]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/BonjourTop/source/BonjourTop.cpp
mDNSResponder-878.1.1.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / BonjourTop / source / BonjourTop.cpp
1 //
2 // BonjourTop.cpp
3 // TestTB
4 //
5 // Created by Terrin Eager on 9/26/12.
6 //
7 //
8
9 #include <stdio.h>
10 #include <errno.h>
11 #include <string.h>
12 #include <sys/socket.h>
13 #include <sys/types.h>
14 #include <netinet/in.h>
15 #include <unistd.h>
16 #include <stdlib.h>
17 #include <arpa/inet.h>
18 #include <ncurses.h>
19
20 #include "BonjourTop.h"
21 #include "DNSFrame.h"
22 #include "CaptureFile.h"
23 #include "bjsocket.h"
24 #include "bjstring.h"
25
26 #include <sys/sysctl.h>
27 #include <mach/mach.h>
28
29 #define SERVICE_IPV4 0
30 #define SERVICE_IPV6 1
31 #define APP_IPV4 2
32 #define APP_IPV6 3
33
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)
43
44 int CDeviceNode::nCreateCount = 0;
45 static integer_t Usage(void);
46
47 char CVSFileNameExample[] ="BonjourTop";
48 char DeviceNameExample[] ="BonjourTopDevice.csv";
49
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",
63
64 "_appletv._tcp.local.", "AppleTV", "?" , "t",
65 "_appletv-v2._tcp.local.", "AppleTV", "?" , "?",
66 "_appletv-pair._tcp.local.", "AppleTV", "?" , "?",
67
68 "A", "LinkLocal", "?" , "?",
69 "AAAA", "LinkLocal", "?" , "?",
70 "*.ip6.arpa.", "LinkLocal", "?" , "?",
71 "*.arpa.", "LinkLocal", "?" , "?",
72
73 "_airplay._tcp.local.", "AirPlay", "?" , "t",
74 "_airplayTXT", "AirPlay","?" , "t",
75 "_raop._tcp.local.", "AirPlay","?" , "?",
76
77 "_ubd._tcp.local.", "Ubiquity", "?" , "?",
78 "_ubiquity._tcp.local.", "Ubiquity", "?" , "?",
79 "_ubiquityV1._tcp.local.", "Ubiquity", "?" , "?",
80 "_ubiquityV2._tcp.local.", "Ubiquity", "?" , "?",
81
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", "?" , "?",
90
91 "_apple-mobdev._tcp.local.", "iTunes-WiFiSync","?" , "i",
92 "_daap._tcp.local.", "iTunes", "?" , "?",
93
94 "_sftp-ssh._tcp.local.", "Terminal", "?" , "X",
95 "_ssh._tcp.local.", "Terminal", "?" , "X",
96
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", "?" , "?",
102
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",
107
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",
117 ""
118 };
119
120 char DeviceInfo2DeviceOS[][50] = {
121 // deviceModel, deviceType
122 "MacBookAir", "X",
123 "MacBookPro", "X",
124 "Macmini", "X",
125 "iMac", "X",
126 "MacPro", "X",
127 "MacBook", "X",
128 "AAPLJ15", "X",
129 "AAPLJ41", "X",
130 "AAPLJ43", "X",
131 "AAPLJ45", "X",
132 "AAPLJ90", "X",
133 "AAPLJ17", "X",
134 "PowerMac", "X",
135
136
137 "J33AP", "t",
138 "J33iAP", "t",
139 "J71AP", "i",
140 "J72AP", "i",
141 "J75AP", "i",
142 "J85DEV", "i",
143 "K66AP", "t",
144 "N41AP", "i",
145 "N42AP", "i",
146 "N48AP", "i",
147 "N51AP", "i",
148 "N53AP", "i",
149 "N78AP", "i",
150 "P101AP", "i",
151 "P102AP", "i",
152 "P103AP", "i",
153 "P105AP", "i",
154 "P106AP", "i",
155 "P107AP", "i",
156 "AirPort", "b",
157 "TimeCapsule", "b",
158 ""
159 };
160
161 char Name2DeviceOS[][50] = {
162 // Name contains, osType
163 "iPhone", "i",
164 "phone", "i",
165 "Phone", "i",
166 "iPod", "i",
167 "iPad", "i",
168 "ipad", "i",
169 "Apple-TV", "t",
170 "AppleTV", "t",
171 "MacBook", "X",
172 "macbook", "X",
173 "iMac", "X",
174 "macmini", "X",
175 ""
176 };
177
178 BJ_UINT64 Hash(const char* pStr);
179 BJ_UINT64 Hash2(char* pStr);
180
181
182 CSocketStats::CSocketStats()
183 {
184 Init();
185
186 }
187 void CSocketStats::Init()
188 {
189 m_nFrameCount = 0;
190
191 m_nQuestionOnlyFrames = 0;
192 m_nAnswerOnlyFrames = 0;
193 m_nQandAFrames = 0;
194
195 m_SampleDay = 0;
196 }
197
198 void CSocketStats::Clear()
199 {
200 Init();
201 }
202
203 CBonjourTop::CBonjourTop()
204 {
205
206 m_bCursers = true;
207 m_pTcpDumpFileName = NULL;
208 m_pExportFileName = CVSFileNameExample;
209 m_DeviceFileName = DeviceNameExample;
210
211 m_nFrameCount = 0;
212 m_nTotalBytes = 0;
213
214 m_StartTime = m_EndTime = time(NULL);
215
216 m_SnapshotSeconds = 0;
217
218 m_MinAnswerCountForTruncatedFrames = 0;
219 m_AvgAnswerCountForTruncatedFrames = 0;
220 m_MaxAnswerCountForTruncatedFrames = 0;
221
222 window_size_changed = false;
223 m_bImportExportDeviceMap = false;
224
225 // loadup application mapping
226 for(int i=0; Service2App[i][0] != 0;)
227 {
228 BJString a(Service2App[i++]);
229
230 m_Service2AppMap.FindwithAddRecord(&a)->value = Service2App[i++];
231 m_Service2osBrowseMap.FindwithAddRecord(&a)->value = Service2App[i++];
232 m_Service2osRegisterMap.FindwithAddRecord(&a)->value = Service2App[i++];
233
234 }
235
236
237 m_CurrentDisplay = CBonjourTop::BJ_DISPLAY_APP;
238 // m_CurrentDisplay = CBonjourTop::BJ_DISPLAY_SERVICE;
239
240 Usage();
241
242 }
243
244 static int CbClearDataDevice(const void* pNode, const void*)
245 {
246 CDeviceNode* pDeviceRecord = (CDeviceNode*)pNode;
247
248 pDeviceRecord->ClearData();
249 return 0;
250 }
251
252 void CBonjourTop::Reset()
253 {
254 m_nFrameCount = 0;
255 m_nTotalBytes = 0;
256
257 m_MinAnswerCountForTruncatedFrames = 0;
258 m_AvgAnswerCountForTruncatedFrames = 0;
259 m_MaxAnswerCountForTruncatedFrames = 0;
260
261 m_StartTime = m_EndTime = time(NULL);
262
263 m_ServicePtrCache.ClearAll();
264 m_ApplPtrCache.ClearAll();
265
266 m_ServicePtrCacheIPv6.ClearAll();
267 m_ApplPtrCacheIPv6.ClearAll();
268
269 // Clear all data in the map
270 m_AppBreakdownIPv4OSX.clear();
271 m_AppBreakdownIPv4iOS.clear();
272 m_AppBreakdownIPv6OSX.clear();
273 m_AppBreakdownIPv6iOS.clear();
274
275 m_ServiceBreakdownIPv4OSX.clear();
276 m_ServiceBreakdownIPv4iOS.clear();
277 m_ServiceBreakdownIPv6OSX.clear();
278 m_ServiceBreakdownIPv6iOS.clear();
279
280 // Clear Socket Status
281 for (int i = 0; i < NUM_SOCKET_STATUS; i++)
282 {
283 m_SocketStatus[i].Clear();
284 }
285
286 for (int i = 0; i < HOURS_IN_DAY; i++)
287 {
288 for (int j = 0; j < MINUTES_IN_HOUR; j++)
289 {
290 m_MinSnapshot[i][j].Clear();
291 }
292 }
293
294 CDeviceNode* pDeviceNode = m_DeviceMap.GetRoot();
295 if (pDeviceNode)
296 {
297 pDeviceNode->CallBack(&CbClearDataDevice,NULL);
298 }
299
300 }
301
302 void CBonjourTop::SetIPAddr(const char* pStr)
303 {
304 m_IPv4Addr.Set(pStr);
305
306 }
307
308 void CBonjourTop::UpdateRecord(CStringTree& Cache,CDNSRecord* pDNSRecord,BJString& RecordName,BJString& ServiceName,BJ_UINT32 nBytes,bool bGoodbye)
309 {
310 BJ_UINT64 nHashValue = 0;
311 char deviceOS = '?';
312
313 nHashValue = Hash(RecordName.GetBuffer());
314 CStringNode* pRecord = Cache.Find(&nHashValue);
315 if (pRecord == NULL)
316 {
317 pRecord = (CStringNode*) Cache.FindwithAddRecord(&nHashValue);
318 strcpy(pRecord->m_Value, RecordName.GetBuffer());
319 }
320
321 if (pRecord == NULL)
322 return;
323 CDeviceNode dummyDevice;
324 CDeviceNode *device = &dummyDevice;
325 CIPDeviceNode *pipNode = m_IPtoNameMap.Find(&m_Frame.m_SourceIPAddress);
326
327 device = (pipNode)? pipNode->pDeviceNode : &dummyDevice;
328 pRecord->m_nBytes += 10 + nBytes;
329 deviceOS = device->GetDeviceOS();
330 device->frameTotal.Increment(m_nFrameCount);
331
332 if (pRecord->m_nLastFrameIndex != m_nFrameCount)
333 {
334 pRecord->m_nLastFrameIndex = m_nFrameCount;
335
336 pRecord->m_nFrames++;
337 if (deviceOS == 't' || deviceOS == 'i')
338 {
339 pRecord->m_nFramesiOS++;
340 }
341 else if (deviceOS == 'X')
342 {
343 pRecord->m_nFramesOSX++;
344 }
345 }
346
347 // Update Total Device Count
348 if (pRecord->m_DeviceTotalTree.Find(&m_Frame.m_SourceIPAddress) == NULL)
349 {
350 pRecord->m_nDeviceTotalCount++;
351 pRecord->m_DeviceTotalTree.FindwithAddRecord(&m_Frame.m_SourceIPAddress);
352 }
353
354 if (m_Frame.IsQueryFrame())
355 {
356 GetOSTypeFromQuery(pDNSRecord, ServiceName);
357 device->questionFrame.Increment(m_nFrameCount);
358 if (pRecord->m_nLastQueryFrameIndex != m_nFrameCount)
359 {
360 pRecord->m_nLastQueryFrameIndex = m_nFrameCount;
361
362 pRecord->m_nQuestionFrames++;
363
364 if (deviceOS == 't' || deviceOS == 'i')
365 {
366 pRecord->m_nQuestionFramesiOS++;
367 }
368 else if (deviceOS == 'X')
369 {
370 pRecord->m_nQuestionFramesOSX++;
371 }
372
373 if (pRecord->m_DeviceAskingTree.Find(&m_Frame.m_SourceIPAddress) == NULL)
374 {
375 pRecord->m_nDeviceAskingCount++;
376 pRecord->m_DeviceAskingTree.FindwithAddRecord(&m_Frame.m_SourceIPAddress);
377 }
378 }
379 }
380 else
381 {
382 GetOSTypeFromRegistration(pDNSRecord,ServiceName);
383
384 device->answerFrame.Increment(m_nFrameCount);
385 if (pRecord->m_nLastRespondsFrameIndex != m_nFrameCount)
386 {
387 pRecord->m_nLastRespondsFrameIndex = m_nFrameCount;
388
389 pRecord->m_nAnswerFrames++;
390 if (deviceOS == 't' || deviceOS == 'i')
391 {
392 pRecord->m_nAnswerFramesiOS++;
393 }
394 else if (deviceOS == 'X')
395 {
396 pRecord->m_nAnswerFramesOSX++;
397 }
398
399 if (bGoodbye)
400 {
401 pRecord->m_nGoodbyeFrames++;
402 }
403
404 if (pRecord->m_DeviceAnsweringTree.Find(&m_Frame.m_SourceIPAddress) == NULL)
405 {
406 pRecord->m_nDeviceAnsweringCount++;
407 pRecord->m_DeviceAnsweringTree.FindwithAddRecord(&m_Frame.m_SourceIPAddress);
408 }
409 }
410 }
411
412 if (m_Frame.IsWakeFrame())
413 {
414 if (pRecord->m_nLastWakeFrameIndex != m_nFrameCount)
415 {
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
418 {
419 pRecord->m_nWakeFrames++;
420 pRecord->m_lastQUFrameTime = m_Frame.GetTime();
421 device->QUFrame.Increment(m_nFrameCount);
422 }
423 pRecord->m_lastQUFrameTime = m_Frame.GetTime();
424 }
425 }
426
427
428 }
429
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)
431 {
432 bool isOSX = false;
433 BJString versionNumber = "mDNSResponder-";
434 const int version_max_length = 11; // largest number is 0xffffffff = 4294967295
435 char versionChar[version_max_length];
436
437 CStringShortTree *cache;
438 map<BJString, CStringShortTree*>* myMap;
439
440 if ((tracePlatform | 0x80) == tracePlatform)
441 {
442 versionNumber = "Discoveryd-";
443 }
444
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
447 {
448 if (deviceOS == 'i' || deviceOS == 't') // Pre iOS 7
449 {
450 isOSX = false;
451 }
452 else if (deviceOS == 'X') // Pre OSX 10.9
453 {
454 isOSX = true;
455 }
456 }
457 else if ((tracePlatform == TRACE_PLATFORM_OSX) || (tracePlatform == DISCOVERYD_TRACE_PLATFORM_OSX)) // >= OSX 10.9
458 {
459 isOSX = true;
460 snprintf(versionChar, sizeof(versionChar), "%u", traceVersion);
461 }
462 else if ((tracePlatform == TRACE_PLATFORM_iOS) || (tracePlatform == DISCOVERYD_TRACE_PLATFORM_iOS)) // >= iOS 7.x
463 {
464 isOSX = false;
465 snprintf(versionChar, sizeof(versionChar), "%u", traceVersion);
466 }
467 else if ((tracePlatform == TRACE_PLATFORM_APPLE_TV) || (tracePlatform == DISCOVERYD_TRACE_PLATFORM_APPLE_TV))
468 {
469 snprintf(versionChar, sizeof(versionChar), "%u", traceVersion);
470 }
471
472 versionNumber += (const char*)versionChar;
473
474 switch (cacheType) {
475 case SERVICE_IPV4:
476 if (isOSX)
477 {
478 myMap = &m_ServiceBreakdownIPv4OSX;
479 }
480 else
481 {
482 myMap = &m_ServiceBreakdownIPv4iOS;
483 }
484 break;
485 case SERVICE_IPV6:
486 if (isOSX)
487 {
488 myMap = &m_ServiceBreakdownIPv6OSX;
489 }
490 else
491 {
492 myMap = &m_ServiceBreakdownIPv6iOS;
493 }
494 break;
495 case APP_IPV4:
496 if (isOSX)
497 {
498 myMap = &m_AppBreakdownIPv4OSX;
499 }
500 else
501 {
502 myMap = &m_AppBreakdownIPv4iOS;
503 }
504 break;
505 case APP_IPV6:
506 if (isOSX)
507 {
508 myMap = &m_AppBreakdownIPv6OSX;
509 }
510 else
511 {
512 myMap = &m_AppBreakdownIPv6iOS;
513 }
514 break;
515
516 default:
517 return;
518 break;
519 }
520
521 if (myMap->find(versionNumber) == myMap->end()) // Version number not found. Create new record
522 {
523 myMap->insert(std::pair<BJString, CStringShortTree*>(versionNumber, new CStringShortTree()));
524 }
525 cache = (*myMap)[versionNumber];
526 UpdateShortRecord(cache, pDNSRecord, RecordName, ServiceName, nBytes, bGoodbye);
527 }
528
529 void CBonjourTop::UpdateShortRecord(CStringShortTree* Cache,CDNSRecord* pDNSRecord,BJString& RecordName,BJString& ServiceName,BJ_UINT32 nBytes,bool bGoodbye)
530 {
531 if (Cache == NULL)
532 {
533 return;
534 }
535
536 BJ_UINT64 nHashValue = 0;
537 char deviceOS = '?';
538
539 nHashValue = Hash(RecordName.GetBuffer());
540 CStringShortNode* pRecord = Cache->Find(&nHashValue);
541 if (pRecord == NULL)
542 {
543 pRecord = (CStringShortNode*) Cache->FindwithAddRecord(&nHashValue);
544 strcpy(pRecord->m_Value, RecordName.GetBuffer());
545 }
546
547 if (pRecord == NULL)
548 {
549 return;
550 }
551
552 CDeviceNode dummyDevice;
553 CDeviceNode *device = &dummyDevice;
554 CIPDeviceNode *pipNode = m_IPtoNameMap.Find(&m_Frame.m_SourceIPAddress);
555
556 device = (pipNode)? pipNode->pDeviceNode : &dummyDevice;
557 pRecord->m_nBytes += 10 + nBytes;
558 deviceOS = device->GetDeviceOS();
559 device->frameTotal.Increment(m_nFrameCount);
560
561 if (pRecord->m_nLastFrameIndex != m_nFrameCount)
562 {
563 pRecord->m_nLastFrameIndex = m_nFrameCount;
564 pRecord->m_nFrames++;
565 }
566
567 // Update Total Device Count
568 if (pRecord->m_DeviceTotalTree.Find(&m_Frame.m_SourceIPAddress) == NULL)
569 {
570 pRecord->m_nDeviceTotalCount++;
571 pRecord->m_DeviceTotalTree.FindwithAddRecord(&m_Frame.m_SourceIPAddress);
572 }
573
574 if (m_Frame.IsQueryFrame())
575 {
576 GetOSTypeFromQuery(pDNSRecord, ServiceName);
577 device->questionFrame.Increment(m_nFrameCount);
578 if (pRecord->m_nLastQueryFrameIndex != m_nFrameCount)
579 {
580 pRecord->m_nLastQueryFrameIndex = m_nFrameCount;
581
582 pRecord->m_nQuestionFrames++;
583
584 if (pRecord->m_DeviceAskingTree.Find(&m_Frame.m_SourceIPAddress) == NULL)
585 {
586 pRecord->m_nDeviceAskingCount++;
587 pRecord->m_DeviceAskingTree.FindwithAddRecord(&m_Frame.m_SourceIPAddress);
588 }
589
590 }
591 }
592 else
593 {
594 GetOSTypeFromRegistration(pDNSRecord,ServiceName);
595
596 device->answerFrame.Increment(m_nFrameCount);
597 if (pRecord->m_nLastRespondsFrameIndex != m_nFrameCount)
598 {
599 pRecord->m_nLastRespondsFrameIndex = m_nFrameCount;
600
601 pRecord->m_nAnswerFrames++;
602
603 if (bGoodbye)
604 {
605 pRecord->m_nGoodbyeFrames++;
606 }
607
608 if (pRecord->m_DeviceAnsweringTree.Find(&m_Frame.m_SourceIPAddress) == NULL)
609 {
610 pRecord->m_nDeviceAnsweringCount++;
611 pRecord->m_DeviceAnsweringTree.FindwithAddRecord(&m_Frame.m_SourceIPAddress);
612 }
613 }
614 }
615
616 if (m_Frame.IsWakeFrame())
617 {
618 if (pRecord->m_nLastWakeFrameIndex != m_nFrameCount)
619 {
620 pRecord->m_nLastWakeFrameIndex = m_nFrameCount;
621 if (pRecord->m_lastQUFrameTime +1000000ll < m_Frame.GetTime() || pRecord->m_lastQUFrameTime == 0) // last qu frame has been over 1 sec
622 {
623 pRecord->m_nWakeFrames++;
624 pRecord->m_lastQUFrameTime = m_Frame.GetTime();
625 device->QUFrame.Increment(m_nFrameCount);
626 }
627 pRecord->m_lastQUFrameTime = m_Frame.GetTime();
628 }
629 }
630
631
632 }
633
634 void CBonjourTop::GetOSTypeFromQuery(CDNSRecord *pDNSRecord,BJString& ServiceName)
635 {
636 if (pDNSRecord->m_RecType == DNS_TYPE_PTR)
637 {
638 StringMapNode* pStringNode = m_Service2osBrowseMap.Find(&ServiceName);
639 if (pStringNode && *pStringNode->value.GetBuffer() != '?')
640 {
641 CIPDeviceNode *ipNode = m_IPtoNameMap.FindwithAddRecord(&m_Frame.m_SourceIPAddress);
642 if (ipNode->pDeviceNode)
643 {
644 StringMapNode* pStringNode_temp = m_Service2osBrowseMap.Find(&ServiceName);
645 ipNode->pDeviceNode->SetDeviceOS(*pStringNode_temp->value.GetBuffer(),ServiceName.GetBuffer());
646 }
647 }
648 }
649 }
650
651 void CBonjourTop::GetOSTypeFromRegistration(CDNSRecord *pDNSRecord,BJString& ServiceName)
652 {
653 CDeviceNode* deviceNode = NULL;
654 BJString sDeviceName;
655
656 if (pDNSRecord->m_RecType == DNS_TYPE_PTR)
657 {
658 BJString sInstanceName;
659 pDNSRecord->GetRdata(sInstanceName,0,99);
660 CDNSRecord* pSRVRecord = m_Frame.FindAdditionRecord(sInstanceName, DNS_TYPE_SRV);
661 if (pSRVRecord)
662 {
663 pSRVRecord->GetRdata(sDeviceName,0,1);
664 }
665 else
666 {
667 sDeviceName = sInstanceName;
668 }
669 deviceNode = m_DeviceMap.Find(&sDeviceName);
670 }
671
672 // Name guess
673 if (Name2OSType(sDeviceName,deviceNode))
674 return;
675
676 StringMapNode* pStringNode = m_Service2osRegisterMap.Find(&ServiceName);
677
678 if (pStringNode == NULL || *pStringNode->value.GetBuffer() == '?')
679 return;
680
681
682
683 if (sDeviceName.GetLength() > 0)
684 {
685 // update global device table with os type
686 if (deviceNode)
687 {
688 deviceNode->SetDeviceOS(*pStringNode->value.GetBuffer(),ServiceName.GetBuffer());
689 }
690 }
691 }
692 bool CBonjourTop::Name2OSType(BJString name,CDeviceNode* device)
693 {
694 if (device == NULL)
695 return false;
696 // try to set device type from common names
697 for (int i=0; Name2DeviceOS[i][0] != 0; i +=2)
698 {
699 if (name.Contains(Name2DeviceOS[i]))
700 {
701 device->SetDeviceOS(Name2DeviceOS[i+1][0], "Name Mapping");
702 return true;
703 }
704 }
705 return false;
706 }
707 void CBonjourTop::ProcessFrame(BJ_UINT8* pBuffer,BJ_INT32 nLength,BJ_UINT64 nFrameTime)
708 {
709
710 m_Frame.ParseDNSFrame(pBuffer, nLength, nFrameTime);
711
712 if (m_Collection.IsValid())
713 {
714 // setup static collectby
715 CollectByPacketCount::nFrameIndex = m_nFrameCount;
716 CollectBySameSubnetDiffSubnet::bSameSubnet = m_Frame.m_SourceIPAddress.IsIPv6()? true: m_IPv4Addr.IsSameSubNet(&m_Frame.m_SourceIPAddress);
717 m_Collection.ProcessFrame(&m_Frame);
718 return;
719 }
720
721 if (m_Frame.IsTruncatedFrame())
722 {
723 if (m_Frame.GetAnswerCount() > 0)
724 {
725 if (m_AvgAnswerCountForTruncatedFrames)
726 {
727 m_AvgAnswerCountForTruncatedFrames += m_Frame.GetAnswerCount();
728 m_AvgAnswerCountForTruncatedFrames /=2;
729 }
730 else
731 m_AvgAnswerCountForTruncatedFrames += m_Frame.GetAnswerCount();
732
733 if (m_MinAnswerCountForTruncatedFrames > m_Frame.GetAnswerCount() || m_MinAnswerCountForTruncatedFrames == 0)
734 m_MinAnswerCountForTruncatedFrames = m_Frame.GetAnswerCount();
735 if (m_MaxAnswerCountForTruncatedFrames < m_Frame.GetAnswerCount())
736 m_MaxAnswerCountForTruncatedFrames = m_Frame.GetAnswerCount();
737
738 }
739 }
740
741 // find min snapshot bucket
742 time_t now = time(NULL);
743 struct tm* timeStruct = localtime(&now);
744 if (m_MinSnapshot[timeStruct->tm_hour][timeStruct->tm_min].m_SampleDay != timeStruct->tm_mday)
745 {
746 //Reset Snapshot 24 hour wrap around
747 m_MinSnapshot[timeStruct->tm_hour][timeStruct->tm_min].Init();
748 m_MinSnapshot[timeStruct->tm_hour][timeStruct->tm_min].m_SampleDay = timeStruct->tm_mday;
749
750 }
751 m_MinSnapshot[timeStruct->tm_hour][timeStruct->tm_min].m_nFrameCount++;
752
753 if (m_Frame.GetQuestionCount() == 0 && m_Frame.GetAnswerCount() > 0)
754 m_SocketStatus[0].m_nAnswerOnlyFrames++;
755 else if (m_Frame.GetQuestionCount() > 0 && m_Frame.GetAnswerCount() == 0)
756 m_SocketStatus[0].m_nQuestionOnlyFrames++;
757 else
758 m_SocketStatus[0].m_nQandAFrames++;
759
760 BJString InstanceName;
761 BJString RecordName;
762 BJString ApplRecordName;
763
764 /// first get the name to address
765 for (int dnsItemsIndex =m_Frame.GetQuestionCount(); dnsItemsIndex < m_Frame.GetMaxRecords();dnsItemsIndex++)
766 {
767 CDNSRecord* pDNSRecord = m_Frame.GetDnsRecord(dnsItemsIndex);
768 if (pDNSRecord == NULL)
769 continue;
770
771 if (pDNSRecord->m_RecType == DNS_TYPE_A)
772 {
773 BJString sName;
774 pDNSRecord->GetDnsRecordName(sName, 0, 1);
775 BJIPAddr ip;
776 ip.Setv4Raw(pDNSRecord->GetStartofRdata());
777
778 CDeviceNode* device = m_DeviceMap.FindwithAddRecord(&sName);
779 device->ipAddressv4 = ip;
780
781 // create ip to name mapping
782 CIPDeviceNode* pipNode = m_IPtoNameMap.FindwithAddRecord(&ip);
783
784 if (pipNode->pDeviceNode && pipNode->pDeviceNode->bIPName && pipNode->pDeviceNode->m_Key != device->m_Key)
785 {
786 pipNode->pDeviceNode->bDuplicate = true;
787 device->MergeData(pipNode->pDeviceNode);
788 pipNode->pDeviceNode->ClearData();
789 // remap IPv6
790 if (!pipNode->pDeviceNode->ipAddressv6.IsEmpty())
791 {
792 CIPDeviceNode* ipv6Node = m_IPtoNameMap.Find(&pipNode->pDeviceNode->ipAddressv6);
793 if (ipv6Node)
794 ipv6Node->pDeviceNode = device;
795 }
796 }
797
798 pipNode->pDeviceNode = device;
799 Name2OSType(sName,device);
800 }
801
802 if (pDNSRecord->m_RecType == DNS_TYPE_AAAA)
803 {
804 BJString sName;
805 pDNSRecord->GetDnsRecordName(sName, 0, 1);
806 BJIPAddr ip;
807 ip.Setv6Raw(pDNSRecord->GetStartofRdata());
808
809 if (ip.IsIPv6LinkLocal())
810 {
811 CDeviceNode* device = m_DeviceMap.FindwithAddRecord(&sName);
812 device->ipAddressv6 = ip;
813
814 // create ip to name mapping
815 CIPDeviceNode* pipNode = m_IPtoNameMap.FindwithAddRecord(&ip);
816
817 if (pipNode->pDeviceNode && pipNode->pDeviceNode->bIPName && pipNode->pDeviceNode->m_Key != device->m_Key)
818 {
819 pipNode->pDeviceNode->bDuplicate = true;
820 device->MergeData(pipNode->pDeviceNode);
821 pipNode->pDeviceNode->ClearData();
822 // remap IPv4
823 if (!pipNode->pDeviceNode->ipAddressv4.IsEmpty())
824 {
825 CIPDeviceNode* ipv4Node = m_IPtoNameMap.Find(&pipNode->pDeviceNode->ipAddressv4);
826 if (ipv4Node)
827 ipv4Node->pDeviceNode = device;
828 }
829 }
830
831 pipNode->pDeviceNode = device;
832 Name2OSType(sName,device);
833 }
834 }
835 if (pDNSRecord->m_RecType == DNS_TYPE_SRV)
836 { // Save SVR to Target
837 BJString sName;
838 pDNSRecord->GetDnsRecordName(sName, 0, 1);
839 StringMapNode *node = SVRtoDeviceName.FindwithAddRecord(&sName);
840 pDNSRecord->GetRdata(node->value, 0, 1);
841 }
842 }
843
844 CIPDeviceNode* pipNode = m_IPtoNameMap.FindwithAddRecord(&m_Frame.m_SourceIPAddress);
845 CDeviceNode* device = pipNode->pDeviceNode;
846 if (device == NULL)
847 {
848 // find the device by mac address
849 CMACAddrDeviceNode *macDevice = m_MACtoDevice.FindwithAddRecord(&m_Frame.m_SourceMACAddress);
850 device = macDevice->device;
851 if (device == NULL)
852 {
853 // auto create a device record
854 BJString name = m_Frame.m_SourceIPAddress.GetString();
855 device = m_DeviceMap.FindwithAddRecord(&name);
856 device->bIPName = true;
857 macDevice->device = device;
858 }
859
860 if (m_Frame.m_SourceIPAddress.IsIPv4())
861 device->ipAddressv4 = m_Frame.m_SourceIPAddress;
862 else
863 device->ipAddressv6 = m_Frame.m_SourceIPAddress;
864 if (device->macAddress.IsEmpty())
865 device->macAddress = m_Frame.m_SourceMACAddress;
866
867 pipNode->pDeviceNode = device;
868 }
869 device->bHasFrames = true;
870 // update mac address
871 if (m_Frame.IsQueryFrame() || device->GetDeviceOS() == 'i' ) // iOS don't use BSP so we can use SourceIP
872 {
873 if (m_Frame.m_SourceIPAddress.IsIPv4())
874 device->ipAddressv4 = m_Frame.m_SourceIPAddress;
875 if (m_Frame.m_SourceIPAddress.IsIPv6())
876 device->ipAddressv6 =m_Frame.m_SourceIPAddress;
877 device->macAddress = m_Frame.m_SourceMACAddress;
878 }
879
880 BJ_UINT8 traceplatform = TRACE_PLATFORM_UNKNOWN;
881 BJ_UINT32 traceversion = 0;
882 BJMACAddr traceMac;
883 if (device /*&& device->GetDeviceOS() == '?' */&& m_Frame.GetTracingInfo(traceplatform, traceversion, traceMac))
884 {
885 // printf("Tracing Data found platform=%d traceversion=%d\n",traceplatform,traceversion);
886 char platformMap[]= "?Xitw";
887 device->SetDeviceOS((traceplatform < 5) ? platformMap[traceplatform] : '?', "EDNS0 Trace");
888 if ((traceplatform == TRACE_PLATFORM_OSX) || (traceplatform == DISCOVERYD_TRACE_PLATFORM_OSX))
889 {
890 device->bOSXWithEDNSField = true;
891 }
892 else if ((traceplatform == TRACE_PLATFORM_iOS) || (traceplatform == DISCOVERYD_TRACE_PLATFORM_iOS))
893 {
894 device->biOSWithEDNSField = true;
895 }
896 }
897
898 for (int dnsItemsIndex =0; dnsItemsIndex < m_Frame.GetQuestionCount()+m_Frame.GetAnswerCount();dnsItemsIndex++)
899 {
900 RecordName = "";
901 ApplRecordName = "";
902 InstanceName = "";
903 // printf("Name = %s\n", GetDnsRecordName(&Frame,dnsItemsIndex,tempBuffer,sizeof(tempBuffer),0));
904
905 CDNSRecord* pDNSRecord = m_Frame.GetDnsRecord(dnsItemsIndex);
906 if (pDNSRecord == NULL)
907 continue;
908
909 pDNSRecord->GetDnsRecordName(RecordName,0,99);
910 InstanceName = RecordName;
911
912 if (RecordName.Contains("_kerberos."))
913 {
914 RecordName = "_kerberos.";
915 }
916 else
917 pDNSRecord->GetDnsRecordName(RecordName, (pDNSRecord->m_RecType == DNS_TYPE_PTR)?0:1,99);
918
919 if (pDNSRecord->m_RecType == DNS_TYPE_PTR)
920 {
921 if (RecordName.Contains(".ip6.arpa."))
922 RecordName = "*.ip6.arpa.";
923 else if (RecordName.Contains(".arpa."))
924 RecordName = "*.arpa.";
925 }
926 if (pDNSRecord->m_RecType == DNS_TYPE_A)
927 RecordName = "A";
928 if (pDNSRecord->m_RecType == DNS_TYPE_AAAA)
929 RecordName = "AAAA";
930 if (pDNSRecord->m_RecType == 255)
931 {
932 if (RecordName.Contains(".ip6.arpa."))
933 RecordName = "ANY *.ip6.arpa.";
934 else if (RecordName.Contains(".arpa."))
935 RecordName = "ANY *.arpa.";
936 else
937 RecordName = "Any";
938 }
939 if (RecordName.Contains("_sub."))
940 {
941 pDNSRecord->GetDnsRecordName(RecordName,2,99); /// skip first label and _sub. label
942 }
943
944 BJ_UINT32 nBytes = pDNSRecord->m_nNameLength + pDNSRecord->m_nRdataLen;
945
946 m_nTotalBytes += 10 + nBytes;
947
948 if (m_Frame.m_SourceIPAddress.IsIPv4())
949 {
950 UpdateRecord(m_ServicePtrCache,pDNSRecord,RecordName,RecordName, nBytes, (pDNSRecord->m_nTTL == 0));
951 UpdateShortRecordHelper(SERVICE_IPV4, traceplatform, traceversion, device->GetDeviceOS(), pDNSRecord, RecordName, RecordName, nBytes, (pDNSRecord->m_nTTL == 0));
952 }
953 else
954 {
955 UpdateRecord(m_ServicePtrCacheIPv6,pDNSRecord,RecordName,RecordName, nBytes, (pDNSRecord->m_nTTL == 0));
956 UpdateShortRecordHelper(SERVICE_IPV6, traceplatform, traceversion, device->GetDeviceOS(), pDNSRecord, RecordName, RecordName, nBytes, (pDNSRecord->m_nTTL == 0));
957 }
958
959 // Add application to cache
960 if (RecordName.GetLength() != 0)
961 {
962
963 ApplRecordName = RecordName;
964 StringMapNode* pNode;
965 pNode = m_Service2AppMap.Find(&ApplRecordName);
966 if (pNode && ApplRecordName.GetBuffer() != NULL)
967 {
968 ApplRecordName = pNode->value.GetBuffer();
969 if ( ApplRecordName == "Device-Info")
970 {
971 // find device record
972 BJString svrName;
973 pDNSRecord->GetDnsRecordName(svrName, 0, 1);
974 StringMapNode *nodeName = SVRtoDeviceName.Find(&svrName);
975
976 CDeviceNode* pDeviceNode = nodeName ? m_DeviceMap.Find(&nodeName->value) : NULL;
977
978 if (pDeviceNode)
979 {
980 BJString DeviceInfo;
981 DeviceInfo.Set((char*)pDNSRecord->GetStartofRdata(),MIN(pDNSRecord->m_nRdataLen,50));
982 char osType = '?';
983
984 for (int i=0; DeviceInfo2DeviceOS[i][0] != 0; i+=2)
985 {
986 if (DeviceInfo.Contains(DeviceInfo2DeviceOS[i]))
987 {
988 osType = *DeviceInfo2DeviceOS[i+1];
989 if (pDeviceNode->GetDeviceOS() != *DeviceInfo2DeviceOS[i])
990 {
991 pDeviceNode->SetDeviceOS(osType,"_device-info._tcp.local.");
992 pDeviceNode->SetModel(DeviceInfo2DeviceOS[i]);
993 }
994 break;
995 }
996 }
997
998
999 if (osType == 'X' || (pDeviceNode && pDeviceNode->GetDeviceOS() == 'X'))
1000 ApplRecordName = "Finder";
1001 if (osType == 't' || (pDeviceNode && pDeviceNode->GetDeviceOS() == 't'))
1002 ApplRecordName = "AirPlay";
1003
1004 if (pDeviceNode && pDeviceNode->GetDeviceOS() == '?' && pDNSRecord->m_nRdataLen > 0)
1005 {
1006 BJString DeviceInfo_temp;
1007 DeviceInfo_temp.Set((char*)pDNSRecord->GetStartofRdata(),MIN(pDNSRecord->m_nRdataLen,25));
1008 }
1009 }
1010 }
1011 }
1012 else
1013 {
1014 ApplRecordName = "Other";
1015 }
1016
1017 if (m_Frame.m_SourceIPAddress.IsIPv4())
1018 {
1019 UpdateRecord(m_ApplPtrCache,pDNSRecord,ApplRecordName,RecordName, nBytes, (pDNSRecord->m_nTTL == 0));
1020 UpdateShortRecordHelper(APP_IPV4, traceplatform, traceversion, device->GetDeviceOS(), pDNSRecord, ApplRecordName, RecordName, nBytes, (pDNSRecord->m_nTTL == 0));
1021
1022 }
1023 else
1024 {
1025 UpdateRecord(m_ApplPtrCacheIPv6,pDNSRecord,ApplRecordName,RecordName, nBytes, (pDNSRecord->m_nTTL == 0));
1026 UpdateShortRecordHelper(APP_IPV6, traceplatform, traceversion, device->GetDeviceOS(), pDNSRecord, ApplRecordName, RecordName, nBytes, (pDNSRecord->m_nTTL == 0));
1027 }
1028
1029 }
1030
1031 }
1032 }
1033
1034
1035 class CSortOptions
1036 {
1037
1038 public:
1039 CStringTree m_SortedCache;
1040 int m_nSortCol;
1041
1042 };
1043 static int CbPrintResults(const void* pNode, const void* pParam)
1044 {
1045 CStringNode* pRecord = (CStringNode*)pNode;
1046 CSortOptions* pSortedOption = (CSortOptions*)pParam;
1047
1048 CStringNode* pNewRecord;
1049
1050 BJ_UINT64 SortKey =0;
1051 switch (pSortedOption->m_nSortCol) {
1052 case 0:
1053 SortKey = Hash2(pRecord->m_Value); // cheat the sort to the first 8 char
1054 break;
1055 case 1:
1056 SortKey = pRecord->m_nBytes;
1057 break;
1058 case 2:
1059 SortKey = pRecord->m_nFrames;
1060 break;
1061 case 3:
1062 SortKey = pRecord->m_nQuestionFrames;
1063 break;
1064 case 4:
1065 SortKey = pRecord->m_nAnswerFrames;
1066 break;
1067 default:
1068 break;
1069 }
1070
1071
1072 pNewRecord = pSortedOption->m_SortedCache.AddRecord(&SortKey);
1073
1074 if (pNewRecord)
1075 {
1076 pNewRecord->CopyNode(pRecord);
1077
1078 }
1079
1080 return 0;
1081 }
1082
1083 #if 0 // Not used
1084 static int CbPrintUnknownDevice(const void* pNode, const void*)
1085 {
1086 CDeviceNode* pDeviceRecord = (CDeviceNode*)pNode;
1087
1088 if (pDeviceRecord->GetDeviceOS() != '?')
1089 return 0;
1090
1091 // printf("%s %s\n",pDeviceRecord->m_Key.GetBuffer(), pDeviceRecord->macAddress.GetString());
1092 return 0;
1093
1094 }
1095 #endif
1096
1097 static int CbBuildMacMap(const void* pNode, const void* pParam)
1098 {
1099 CDeviceNode* pDeviceNode = (CDeviceNode*)pNode;
1100 CMACAddrTree* pMacMap = (CMACAddrTree*)pParam;
1101
1102
1103 BJMACAddr vendorMac;
1104 vendorMac.CopyVendor(pDeviceNode->macAddress);
1105 if (vendorMac.IsEmpty())
1106 return 0;
1107
1108
1109
1110 if (pDeviceNode->GetDeviceOS() == '?')
1111 {
1112 // try to set device type from MAC address
1113 CMACAddrNode* pMacRecord = pMacMap->Find(&vendorMac);
1114 if (pMacRecord != NULL && pDeviceNode->GetDeviceOS() == '?')
1115 {
1116 pDeviceNode->SetDeviceOS(pMacRecord->deviceOS, "MAC Mapping");
1117 // printf("update device %s %c\n",vendorMac.GetStringVendor(),pMacRecord->deviceOS);
1118 }
1119
1120 if (pDeviceNode->GetDeviceOS() == '?')
1121 return 0;
1122 }
1123
1124
1125 CMACAddrNode* pMacRecord = pMacMap->Find(&vendorMac);
1126 if (pMacRecord == NULL)
1127 {
1128 pMacRecord = pMacMap->FindwithAddRecord(&vendorMac);
1129 pMacRecord->deviceOS = pDeviceNode->GetDeviceOS();
1130 pMacRecord->model = pDeviceNode->model;
1131 pMacRecord->method = pDeviceNode->settingService;
1132 }
1133 else
1134 {
1135 // Check mapping
1136 /// if (pMacRecord && pMacRecord->deviceOS != pDeviceNode->GetDeviceOS())
1137 // printf("Mac Mapping Bad deviceOS %c != %c %s %s %s\n", pMacRecord->deviceOS, pDeviceNode->GetDeviceOS(),pMacRecord->method.GetBuffer(), pDeviceNode->settingService.GetBuffer(),vendorMac.GetStringVendor());
1138 // if (pMacRecord && !(pMacRecord->model == pDeviceNode->model) && pMacRecord->model.GetLength() > 0 && pDeviceNode->model.GetLength() > 0)
1139 // printf("Mac Mapping Bad model %s != %s\n", pMacRecord->model.GetBuffer(), pDeviceNode->model.GetBuffer());
1140
1141 }
1142 return 0;
1143
1144 }
1145
1146 CStringNode* CBonjourTop::GetCurrentDisplayRoot(BJString &sTitle)
1147 {
1148 CStringNode* pRecord = NULL;
1149
1150 switch(m_CurrentDisplay)
1151 {
1152 case BJ_DISPLAY_APP:
1153 pRecord = m_ApplPtrCache.GetRoot();
1154 sTitle = "Application (IPv4)";
1155 break;
1156 case BJ_DISPLAY_APPv6:
1157 pRecord = m_ApplPtrCacheIPv6.GetRoot();
1158 sTitle = "Application (IPv6)";
1159 break;
1160 case BJ_DISPLAY_SERVICE:
1161 pRecord = m_ServicePtrCache.GetRoot();
1162 sTitle = "Services (IPv4)";
1163 break;
1164 case BJ_DISPLAY_SERVICEv6:
1165 pRecord = m_ServicePtrCacheIPv6.GetRoot();
1166 sTitle = "Services (IPv6)";
1167 break;
1168 case BJ_DISPLAY_24_MIN:
1169 printf("Error");
1170 break;
1171 }
1172 return pRecord;
1173 }
1174 void CBonjourTop::UpdateOSCounts()
1175 {
1176
1177
1178 CDeviceNode* pDeviceNode = m_DeviceMap.GetRoot();
1179 if (pDeviceNode)
1180 {
1181 pDeviceNode->CallBack(&CbBuildMacMap,&m_MacMap);
1182 // pDeviceNode->CallBack(&CbPrintUnknownDevice,NULL);
1183 }
1184
1185
1186 // Update Application Caches
1187 CStringNode* pCacheRoot = m_ApplPtrCache.GetRoot();
1188
1189 if (pCacheRoot)
1190 {
1191 pCacheRoot->UpdateOSTypeCounts(&m_DeviceMap,&m_IPtoNameMap);
1192 }
1193 pCacheRoot = m_ApplPtrCacheIPv6.GetRoot();
1194
1195 if (pCacheRoot)
1196 {
1197 pCacheRoot->UpdateOSTypeCounts(&m_DeviceMap,&m_IPtoNameMap);
1198 }
1199
1200 // Update Service caches
1201 pCacheRoot = m_ServicePtrCache.GetRoot();
1202
1203 if (pCacheRoot)
1204 {
1205 pCacheRoot->UpdateOSTypeCounts(&m_DeviceMap,&m_IPtoNameMap);
1206 }
1207 pCacheRoot = m_ServicePtrCacheIPv6.GetRoot();
1208
1209 if (pCacheRoot)
1210 {
1211 pCacheRoot->UpdateOSTypeCounts(&m_DeviceMap,&m_IPtoNameMap);
1212 }
1213
1214
1215 }
1216 void CBonjourTop::PrintResults(int nSortCol, bool bSortAsc)
1217 {
1218
1219 BJString sTitle;
1220 GetCurrentDisplayRoot(sTitle);
1221 device_count devCount;
1222 BJString sTableTitle;
1223
1224 UpdateOSCounts();
1225
1226 /////
1227 BJ_UINT64 nRate = 0;
1228 BJ_UINT64 nElapsedTime = m_EndTime-m_StartTime;
1229 if (nElapsedTime > 0)
1230 {
1231 nRate = (m_nFrameCount *3600) /nElapsedTime;
1232 }
1233 if (m_bCursers)
1234 {
1235 resizeterm(0,0);
1236 clear();
1237
1238 printw("While running the follow keys may be used:\n");
1239 printw("[p = sort by Packets (default)], [b = sort by Bytes], [n = sort by Name]\n");
1240 printw("[a = Display Application Names (default)], [s = Display Services Names], [t = Display 24 hour packet per min]\n");
1241 printw("[o = flip sort order], [e = export to BonjourTop.csv], [q = quit]\n\n");
1242
1243 printw("Total Packets: %llu, Total Bytes: %llu, Elapse Time: %lld sec, Rate: %llu packet/hr\n",m_nFrameCount,m_nTotalBytes,nElapsedTime,nRate);
1244 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);
1245 printw("IPv4 Wrong subnet: %llu, IPv6 Wrong subnet: %llu\n",m_SocketStatus[4].m_nFrameCount,m_SocketStatus[5].m_nFrameCount);
1246 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);
1247 printw("AnswerCount for truncated frames(min,avg,max): %llu,%llu,%llu\n\n",m_MinAnswerCountForTruncatedFrames,m_AvgAnswerCountForTruncatedFrames,m_MaxAnswerCountForTruncatedFrames);
1248
1249 bzero(&devCount, sizeof(devCount));
1250 m_DeviceMap.GetDeviceOSTypes(m_DeviceMap.GetRoot(),NULL, devCount);
1251 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);
1252 }
1253 else
1254 {
1255 printf("\nTotal Packets: %llu, Total Bytes: %llu, Elapse Time: %lld sec, Rate: %llu packet/hr\n",m_nFrameCount,m_nTotalBytes,nElapsedTime,nRate);
1256 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);
1257 printf("IPv4 Wrong subnet: %llu, IPv6 Wrong subnet: %llu\n",m_SocketStatus[4].m_nFrameCount,m_SocketStatus[5].m_nFrameCount);
1258 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
1260 bzero(&devCount, sizeof(devCount));
1261 m_DeviceMap.GetDeviceOSTypes(m_DeviceMap.GetRoot(),NULL, devCount);
1262
1263 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);
1264 printf("AnswerCount for truncated frames(min,avg,max): %llu,%llu,%llu\n\n",m_MinAnswerCountForTruncatedFrames,m_AvgAnswerCountForTruncatedFrames,m_MaxAnswerCountForTruncatedFrames);
1265 }
1266 PrintDetailResults(nSortCol, bSortAsc);
1267 if (m_bCursers)
1268 refresh();
1269 }
1270 void CBonjourTop::PrintDetailResults(int nSortCol, bool bSortAsc)
1271 {
1272 BJString sTitle;
1273 CStringNode* pCacheRoot = GetCurrentDisplayRoot(sTitle);
1274
1275 if (m_bCursers)
1276 {
1277 if(m_CurrentDisplay == CBonjourTop::BJ_DISPLAY_24_MIN)
1278 {
1279 printw(" ");
1280 for(int i=0;i<24;i++)
1281 printw(" %02d ",i);
1282 printw("\n");
1283 }
1284 else
1285 {
1286 printw("\n%s\n",sTitle.GetBuffer());
1287 printw(" %- 30s %10s %10s%24s%24s%24s%24s%24s\n","","","Total","Question","Answer","Asking","Answering", "Total");
1288 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");
1289 }
1290 }
1291 else
1292 {
1293 if(m_CurrentDisplay == CBonjourTop::BJ_DISPLAY_24_MIN)
1294 {
1295
1296 }
1297 else
1298 {
1299 printf("\n%s\n",sTitle.GetBuffer());
1300 printf(" %-30s %10s %10s%24s%24s%24s%24s%24s\n","","","Total","Question","Answer","Asking","Answering", "Total");
1301 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");
1302 }
1303 }
1304 if (m_CurrentDisplay == CBonjourTop::BJ_DISPLAY_24_MIN)
1305 {
1306
1307 for(int m=0;m<60;m++)
1308 {
1309 printw(" %02d ",m);
1310 for (int h=0;h<24;h++)
1311 printw("%5d ",m_MinSnapshot[h][m].m_nFrameCount);
1312 printw("\n");
1313 }
1314 }
1315 else
1316 {
1317 // sort list
1318 CSortOptions SortOptions;
1319 SortOptions.m_nSortCol = nSortCol;
1320
1321 if (pCacheRoot)
1322 pCacheRoot->UpdateOSTypeCounts(&m_DeviceMap,&m_IPtoNameMap);
1323
1324 if (pCacheRoot)
1325 pCacheRoot->CallBack(&CbPrintResults,&SortOptions);
1326
1327 // print list
1328
1329 CStringNode* pRecord = SortOptions.m_SortedCache.GetRoot();
1330 BJ_UINT32 nIndex = 1;
1331
1332 if (pRecord)
1333 pRecord->Print(m_bCursers,bSortAsc, nIndex,0,40);
1334 }
1335
1336
1337 }
1338
1339 void CBonjourTop::LiveCapture()
1340 {
1341 /// Live Capture
1342 const BJ_UINT16 BonjourPort = 5353;
1343 BJSocket Sockv4;
1344 BJSocket Sockv6;
1345 BJSelect SockSelect;
1346
1347 Sockv4.CreateListenerIPv4(interfaceName);
1348 Sockv6.CreateListenerIPv6(interfaceName);
1349
1350 SockSelect.Add(Sockv4);
1351 SockSelect.Add(Sockv6);
1352
1353
1354 m_StartTime = time(NULL);
1355
1356 bool bSortAsc = false;
1357 int nSortCol = 1;
1358
1359 while (1)
1360 {
1361 SockSelect.Add(Sockv4);
1362 SockSelect.Add(Sockv6);
1363
1364 int result = SockSelect.Wait(1);
1365 if (result < 0)
1366 {
1367 // if SockSelect.Wait failed due to an interrupt, then we want to continue processing the packets
1368 if (errno == EINTR)
1369 {
1370 continue;
1371 }
1372 printf("Error in Select\n");
1373 break;
1374 }
1375
1376 if (SockSelect.IsReady(Sockv4))
1377 {
1378
1379 int recvsize = Sockv4.Read();
1380
1381 if ((recvsize != 0) &&
1382 (Sockv4.GetSrcAddr()->GetPortNumber() == BonjourPort))
1383 {
1384 m_nFrameCount++;
1385 m_SocketStatus[Sockv4.IsMulticastPacket()? 0:2].m_nFrameCount++;
1386
1387 if (!m_IPv4Addr.IsSameSubNet(Sockv4.GetSrcAddr()))
1388 {
1389 m_SocketStatus[4].m_nFrameCount++;
1390 }
1391 m_Frame.m_SourceIPAddress = *Sockv4.GetSrcAddr();
1392 ProcessFrame(Sockv4.GetBuffer(),recvsize,Sockv4.m_CurrentFrame.GetTime());
1393 }
1394 }
1395
1396 if (SockSelect.IsReady(Sockv6))
1397 {
1398 int recvsize = Sockv6.Read();
1399 if ((recvsize != 0) &&
1400 (Sockv6.GetSrcAddr()->GetPortNumber() == BonjourPort))
1401 {
1402 m_nFrameCount++;
1403 m_SocketStatus[Sockv6.IsMulticastPacket()? 1:3].m_nFrameCount++;
1404 m_Frame.m_SourceIPAddress = *Sockv6.GetSrcAddr();
1405
1406 ProcessFrame(Sockv6.GetBuffer(),recvsize,Sockv6.m_CurrentFrame.GetTime());
1407 }
1408 }
1409
1410 if (m_bCursers)
1411 {
1412 int ch = getch();
1413 switch (ch)
1414 {
1415 case 'o':
1416 bSortAsc = !bSortAsc;
1417 result = 0; // force an update
1418 break;
1419 case 'n':
1420 nSortCol = 0;
1421 result = 0; // force an update
1422 break;
1423 case 'b':
1424 nSortCol = 1;
1425 result = 0; // force an update
1426 break;
1427 case 'p':
1428 if (nSortCol == 2)
1429 nSortCol = 3;
1430 else if (nSortCol == 3)
1431 nSortCol = 4;
1432 else
1433 nSortCol = 2;
1434 result = 0; // force an update
1435 break;
1436 case 'a':
1437 case 'A':
1438 if (m_CurrentDisplay == CBonjourTop::BJ_DISPLAY_APP)
1439 m_CurrentDisplay = CBonjourTop::BJ_DISPLAY_APPv6;
1440 else
1441 m_CurrentDisplay = CBonjourTop::BJ_DISPLAY_APP;
1442
1443 result = 0;
1444 break;
1445 case 's':
1446 case 'S':
1447 if (m_CurrentDisplay == CBonjourTop::BJ_DISPLAY_SERVICE)
1448 m_CurrentDisplay = CBonjourTop::BJ_DISPLAY_SERVICEv6;
1449 else
1450 m_CurrentDisplay = CBonjourTop::BJ_DISPLAY_SERVICE;
1451 result = 0;
1452 break;
1453 case 't':
1454 case 'T':
1455 m_CurrentDisplay = CBonjourTop::BJ_DISPLAY_24_MIN;
1456 result = 0;
1457 break;
1458 case 'q':
1459 return;
1460 case 'e':
1461 ExportResults();
1462 printf("\a");
1463 break;
1464 case KEY_RESIZE:
1465 endwin();
1466 initscr();
1467 result = 0; // force an update
1468 break;
1469 case KEY_DOWN:
1470 result = 0; // force an update
1471 break;
1472 }
1473 if (window_size_changed)
1474 {
1475 endwin();
1476 initscr();
1477 window_size_changed = false;
1478 }
1479 }
1480 if (m_EndTime != time(NULL) || result == 0)
1481 {
1482 m_EndTime = time(NULL);
1483 PrintResults(nSortCol,bSortAsc);
1484 if (m_SnapshotSeconds && (time(NULL) - m_StartTime) > m_SnapshotSeconds)
1485 {
1486 ExportResults();
1487 if (m_bImportExportDeviceMap)
1488 {
1489 WriteDeviceFile();
1490 WriteVendorFile();
1491 }
1492 Reset();
1493 }
1494 }
1495 }
1496 }
1497
1498
1499
1500 void CBonjourTop::CaptureFile()
1501 {
1502 CCaptureFile CaptureFile;
1503 BJIPAddr* pIPSrcAddr;
1504 BJIPAddr* pIPDestAddr;
1505
1506 CIPAddrMap LocalSubnetIPv6;
1507
1508
1509 CaptureFile.Open(m_pTcpDumpFileName);
1510
1511 m_StartTime = 0;
1512 int nFrameIndex = 0;
1513
1514 while (CaptureFile.NextFrame())
1515 {
1516 nFrameIndex++;
1517
1518 BJ_UINT8* pBonjourBuffer = (BJ_UINT8*)CaptureFile.m_CurrentFrame.GetBonjourStart();
1519 if (!pBonjourBuffer)
1520 continue;
1521
1522 m_nFrameCount++;
1523 m_nTotalBytes += CaptureFile.GetWiredLength();
1524
1525 pIPSrcAddr = CaptureFile.m_CurrentFrame.GetSrcIPAddr();
1526 pIPDestAddr = CaptureFile.m_CurrentFrame.GetDestIPAddr();
1527 m_Frame.m_SourceIPAddress = *CaptureFile.m_CurrentFrame.GetSrcIPAddr();;
1528 m_Frame.m_SourceMACAddress = *CaptureFile.m_CurrentFrame.GetSrcMACAddr();
1529
1530 if (pIPSrcAddr->IsIPv4())
1531 {
1532 // check fragment flag
1533 BJ_UINT8* pIP = CaptureFile.m_CurrentFrame.GetIPStart();
1534 BJ_UINT16 flags = * ((BJ_UINT16*)(pIP+6));
1535 if (flags)
1536 continue;
1537
1538 if (!m_IPv4Addr.IsEmptySubnet())
1539 {
1540 if (m_IPv4Addr.IsSameSubNet(pIPSrcAddr))
1541 {
1542 BJ_UINT8* pSourceMac = CaptureFile.m_CurrentFrame.GetEthernetStart()+6;
1543 BJIPAddr IPv6Addr;
1544 IPv6Addr.CreateLinkLocalIPv6(pSourceMac);
1545 LocalSubnetIPv6.FindwithAddRecord(&IPv6Addr);
1546
1547 }
1548 else
1549 {
1550 m_SocketStatus[4].m_nFrameCount++;
1551
1552 if (!m_Collection.IsValid())
1553 continue;
1554 }
1555 }
1556 m_SocketStatus[(pIPDestAddr->IsBonjourMulticast())?0:2].m_nFrameCount++;
1557 }
1558 if (pIPSrcAddr->IsIPv6())
1559 {
1560 if (!LocalSubnetIPv6.Find(pIPSrcAddr) && !m_IPv4Addr.IsEmptySubnet())
1561 {
1562 m_SocketStatus[5].m_nFrameCount++;
1563 if (!m_Collection.IsValid())
1564 continue;
1565 }
1566 m_SocketStatus[(pIPDestAddr->IsBonjourMulticast())?1:3].m_nFrameCount++;
1567 }
1568
1569 ProcessFrame(pBonjourBuffer,CaptureFile.GetBufferLen((pBonjourBuffer)),CaptureFile.m_CurrentFrame.GetTime());
1570
1571 }
1572 m_EndTime = CaptureFile.GetDeltaTime();
1573
1574 PrintResults(2,false);
1575 if ( m_CurrentDisplay == BJ_DISPLAY_APP)
1576 m_CurrentDisplay = BJ_DISPLAY_APPv6;
1577 else
1578 m_CurrentDisplay = BJ_DISPLAY_SERVICEv6;
1579
1580 PrintDetailResults(2,false);
1581
1582 }
1583
1584 void CBonjourTop::ExportPtrCache(FILE* hFile, BJString sTitle,CStringNode* pRoot)
1585 {
1586 fprintf(hFile,"%s\n",sTitle.GetBuffer());
1587 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");
1588
1589 if (pRoot)
1590 pRoot->Export(hFile);
1591 }
1592
1593 void CBonjourTop::ExportShortCacheHelper(FILE* hFile, BJString sTitle, CStringShortNode* pRoot)
1594 {
1595 fprintf(hFile,"%s\n",sTitle.GetBuffer());
1596 fprintf(hFile,"Name,Bytes,Total Packets,Question Packets,Answer Packets,Asking Devices,Answering Devices,Total Devices,QU Bit,Goodbye\n");
1597
1598 if (pRoot)
1599 {
1600 pRoot->Export(hFile);
1601 }
1602
1603 }
1604
1605 void CBonjourTop::ExportShortCache(FILE* hFile, BJString sTitle, map<BJString, CStringShortTree*>* myMap)
1606 {
1607 CStringShortTree* cache;
1608 BJString versionNumber;
1609
1610 fprintf(hFile,"%s\n",sTitle.GetBuffer());
1611
1612 for (map<BJString, CStringShortTree*>::iterator it = myMap->begin(); it != myMap->end(); ++it)
1613 {
1614 versionNumber = (*it).first;
1615 cache = (*it).second;
1616
1617 ExportShortCacheHelper(hFile, versionNumber, cache->GetRoot());
1618 }
1619 }
1620
1621 void CBonjourTop::ExportResults()
1622 {
1623
1624 BJString sTempFileName;
1625 device_count devCount;
1626 sTempFileName = m_pExportFileName;
1627
1628 if (m_SnapshotSeconds)
1629 {
1630 BJString sTimeStamp;
1631 sTimeStamp.Format(time(NULL), BJString::BJSS_TIME);
1632 sTempFileName += "_";
1633 sTempFileName += sTimeStamp;
1634 }
1635 sTempFileName += ".csv";
1636
1637 if (m_Collection.IsValid())
1638 {
1639 m_Collection.ExportCollection(sTempFileName);
1640 return;
1641 }
1642
1643 FILE* hFile = fopen(sTempFileName.GetBuffer(),"w");
1644
1645 if (hFile == NULL)
1646 {
1647 printf("file open failed %s\n",m_pExportFileName);
1648 return;
1649 }
1650
1651 fprintf(hFile,"Total Number of Frames, %llu\n",m_nFrameCount);
1652 fprintf(hFile,"Total Number of Bytes, %llu\n",m_nTotalBytes);
1653 fprintf(hFile,"Total Number of Sec, %llu\n",m_EndTime-m_StartTime);
1654
1655 bzero(&devCount, sizeof(devCount));
1656 m_DeviceMap.GetDeviceOSTypes(m_DeviceMap.GetRoot(),NULL, devCount);
1657 fprintf(hFile,"Total Number of Devices, %llu\n\n",devCount.iOS+devCount.OSX+devCount.unknownOS);
1658 fprintf(hFile,"Total Number of iOS Devices, %llu\n",devCount.iOS);
1659 fprintf(hFile,"Total Number of iOS Devices (>= iOS7), %llu\n", devCount.iOSWithEDNSField);
1660 fprintf(hFile,"Total Number of OSX Devices, %llu\n",devCount.OSX);
1661 fprintf(hFile,"Total Number of OSX Devices (>= OSX 10.9), %llu\n",devCount.OSXWithEDNSField);
1662
1663 fprintf(hFile,"IPv4 multicast, %llu\n",m_SocketStatus[0].m_nFrameCount);
1664 fprintf(hFile,"IPv6 multicast, %llu\n",m_SocketStatus[1].m_nFrameCount);
1665 fprintf(hFile,"IPv4 Unicast, %llu\n",m_SocketStatus[2].m_nFrameCount);
1666 fprintf(hFile,"IPv6 Unicast, %llu\n",m_SocketStatus[3].m_nFrameCount);
1667 fprintf(hFile,"IPv4 Wrong subnet, %llu\n",m_SocketStatus[4].m_nFrameCount);
1668 fprintf(hFile,"IPv6 Wrong subnet, %llu\n\n",m_SocketStatus[5].m_nFrameCount);
1669
1670 fprintf(hFile,"QuestionOnly Packets, %llu\n", m_SocketStatus[0].m_nQuestionOnlyFrames);
1671 fprintf(hFile,"AnswerOnly Packets, %llu\n", m_SocketStatus[0].m_nAnswerOnlyFrames);
1672 fprintf(hFile,"Q&A Packets, %llu\n\n", m_SocketStatus[0].m_nQandAFrames);
1673
1674 fprintf(hFile,"AnswerCount for truncated frames min, %llu\n", m_MinAnswerCountForTruncatedFrames);
1675 fprintf(hFile,"AnswerCount for truncated frames avg, %llu\n", m_AvgAnswerCountForTruncatedFrames);
1676 fprintf(hFile,"AnswerCount for truncated frames max, %llu\n\n", m_MaxAnswerCountForTruncatedFrames);
1677
1678 // Export Cache
1679 UpdateOSCounts();
1680 ExportPtrCache(hFile,"Application IPv4 Cache",m_ApplPtrCache.GetRoot());
1681 ExportShortCache(hFile, "OSX", &m_AppBreakdownIPv4OSX);
1682 ExportShortCache(hFile, "iOS", &m_AppBreakdownIPv4iOS);
1683
1684 ExportPtrCache(hFile,"Application IPv6 Cache",m_ApplPtrCacheIPv6.GetRoot());
1685 ExportShortCache(hFile, "OSX", &m_AppBreakdownIPv6OSX);
1686 ExportShortCache(hFile, "iOS", &m_AppBreakdownIPv6iOS);
1687
1688 ExportPtrCache(hFile,"Service IPv4 Cache",m_ServicePtrCache.GetRoot());
1689 ExportShortCache(hFile, "OSX", &m_ServiceBreakdownIPv4OSX);
1690 ExportShortCache(hFile, "iOS", &m_ServiceBreakdownIPv4iOS);
1691
1692 ExportPtrCache(hFile,"Service IPv6 Cache",m_ServicePtrCacheIPv6.GetRoot());
1693 ExportShortCache(hFile, "OSX", &m_ServiceBreakdownIPv6OSX);
1694 ExportShortCache(hFile, "iOS", &m_ServiceBreakdownIPv6iOS);
1695
1696 /// min snapshot table
1697
1698 fprintf(hFile,"Min Snapshot table\n");
1699
1700 for (int h=0;h<24;h++)
1701 {
1702 for(int m=0;m<60;m++)
1703 {
1704 if (m_MinSnapshot[h][m].m_nFrameCount)
1705 {
1706 fprintf(hFile,"%02d:%02d,%llu\n",h,m,m_MinSnapshot[h][m].m_nFrameCount);
1707 }
1708 }
1709
1710 }
1711
1712 fclose(hFile);
1713
1714 }
1715
1716 void CBonjourTop::WriteDeviceFile()
1717 {
1718 BJString sTempFileName;
1719 BJString sTimeStamp;
1720
1721 sTempFileName = m_DeviceFileName;
1722 sTimeStamp.Format(time(NULL), BJString::BJSS_TIME);
1723 sTempFileName += "_";
1724 sTempFileName += sTimeStamp;
1725 sTempFileName += ".csv";
1726
1727 FILE* hFile = fopen(sTempFileName.GetBuffer(),"w");
1728
1729 if (hFile == NULL)
1730 {
1731 printf("file open failed %s\n",sTempFileName.GetBuffer());
1732 return;
1733 }
1734
1735 fprintf(hFile,"\"Name\",\"IPv4Address\",\"IPv6Address\",\"MACAddress\",O,\"Model\",\"Method\",\"total frames\",\"question frames\",\"QU frames\",\"answer frames\"\n");
1736
1737 CDeviceNode *pDeviceNode = m_DeviceMap.GetRoot();
1738
1739 if (pDeviceNode)
1740 pDeviceNode->Export(hFile);
1741
1742 fclose(hFile);
1743
1744 printf("devicemap count %llu %d\n",m_DeviceMap.GetCount(),CDeviceNode::nCreateCount);
1745
1746 }
1747
1748 void CBonjourTop::WriteVendorFile()
1749 {
1750 BJString sTempFileName = "BonjourTopVendor";
1751 BJString sTimeStamp;
1752
1753 sTimeStamp.Format(time(NULL), BJString::BJSS_TIME);
1754 sTempFileName += "_";
1755 sTempFileName += sTimeStamp;
1756 sTempFileName += ".csv";
1757
1758 FILE* hFile = fopen(sTempFileName.GetBuffer(),"w");
1759
1760 if (hFile == NULL)
1761 {
1762 printf("file open failed %s\n",sTempFileName.GetBuffer());
1763 return;
1764 }
1765 fprintf(hFile,"\"MACAddress\",O,\"Model\",\"Method\"\n");
1766
1767 CMACAddrNode *node = m_MacMap.GetRoot();
1768
1769 if (node)
1770 node->Export(hFile);
1771
1772 fclose(hFile);
1773 }
1774
1775 void CBonjourTop::WindowSizeChanged()
1776 {
1777 window_size_changed = true;
1778 }
1779
1780 BJ_UINT64 Hash(const char* pStr)
1781 {
1782 // to fix
1783 BJ_UINT64 hash = 0;
1784 int c;
1785
1786 while ((c = *pStr++))
1787 hash += c;
1788
1789 return hash;
1790
1791
1792 }
1793
1794 BJ_UINT64 Hash2(char* pStr)
1795 {
1796 // to fix
1797 BJ_UINT64 hash = 0;
1798 int c;
1799 int i = 0;
1800
1801 while ((c = *pStr++) && i++ < 8)
1802 {
1803 hash = hash << 8;
1804 hash |= c;
1805 }
1806
1807 return hash;
1808
1809
1810 }
1811
1812 static integer_t Usage(void)
1813 {
1814 task_t targetTask = mach_task_self();
1815 struct task_basic_info ti;
1816 mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
1817
1818 kern_return_t kr = task_info(targetTask, TASK_BASIC_INFO_64,
1819 (task_info_t) &ti, &count);
1820 if (kr != KERN_SUCCESS)
1821 {
1822 printf("Kernel returned error during memory usage query");
1823 return 0;
1824 }
1825
1826 // On Mac OS X, the resident_size is in bytes, not pages!
1827 // (This differs from the GNU Mach kernel)
1828 // return ti.resident_size;
1829 return ti.user_time.seconds;
1830 }
1831
1832 ///////////////
1833
1834
1835 /* CStringNode */
1836
1837 void CStringNode::UpdateOSTypeCounts(CDeviceMap* pGlobalDeviceMap,CIPAddrMap *pIp2NameMap)
1838 {
1839 if (m_rbLeft)
1840 ((CStringNode*)m_rbLeft)->UpdateOSTypeCounts(pGlobalDeviceMap,pIp2NameMap);
1841 if (m_rbRight)
1842 ((CStringNode*)m_rbRight)->UpdateOSTypeCounts(pGlobalDeviceMap,pIp2NameMap);
1843
1844 BJ_UINT64 nDeviceUnknown = 0;
1845 m_nDeviceAskingiOSCount = 0;
1846 m_nDeviceAskingOSXCount = 0;
1847 m_nDeviceAnsweringiOSCount = 0;
1848 m_nDeviceAnsweringOSXCount = 0;
1849 m_nDeviceTotaliOSCount = 0;
1850 m_nDeviceTotalOSXCount = 0;
1851 m_DeviceAskingTree.GetDeviceOSTypes(m_DeviceAskingTree.GetRoot(),pIp2NameMap,m_nDeviceAskingiOSCount,m_nDeviceAskingOSXCount,nDeviceUnknown);
1852 if (m_DeviceAskingTree.GetCount() != m_nDeviceAskingiOSCount + m_nDeviceAskingOSXCount+nDeviceUnknown)
1853 {
1854 nDeviceUnknown = 0;
1855 }
1856 nDeviceUnknown = 0;
1857 m_DeviceAnsweringTree.GetDeviceOSTypes(m_DeviceAnsweringTree.GetRoot(),pIp2NameMap,m_nDeviceAnsweringiOSCount,m_nDeviceAnsweringOSXCount,nDeviceUnknown);
1858 if (m_DeviceAnsweringTree.GetCount() != m_nDeviceAnsweringiOSCount + m_nDeviceAnsweringOSXCount+nDeviceUnknown)
1859 {
1860 nDeviceUnknown = 0;
1861 }
1862 nDeviceUnknown = 0;
1863 m_DeviceTotalTree.GetDeviceOSTypes(m_DeviceTotalTree.GetRoot(), pIp2NameMap, m_nDeviceTotaliOSCount, m_nDeviceTotalOSXCount, nDeviceUnknown);
1864 if (m_DeviceTotalTree.GetCount() != m_nDeviceTotaliOSCount + m_nDeviceTotalOSXCount + nDeviceUnknown)
1865 {
1866 nDeviceUnknown = 0;
1867 }
1868 }
1869
1870 void CStringNode::Print(bool bCursers,bool bDescendingSort,BJ_UINT32 &nIndex, BJ_UINT32 nStartIndex,BJ_UINT32 nEndIndex)
1871 {
1872 if (bDescendingSort)
1873 {
1874 if (m_rbLeft)
1875 ((CStringNode*)m_rbLeft)->Print(bCursers,bDescendingSort,nIndex,nStartIndex,nEndIndex);
1876
1877 if (nIndex >= nStartIndex && nIndex <= nEndIndex)
1878 {
1879 if (bCursers)
1880 {
1881 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);
1882
1883 }
1884 else
1885 {
1886 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);
1887
1888 }
1889 }
1890 nIndex++;
1891 if (m_rbRight)
1892 ((CStringNode*)m_rbRight)->Print(bCursers,bDescendingSort,nIndex,nStartIndex,nEndIndex);
1893 }
1894 else
1895 {
1896 if (m_rbRight)
1897 ((CStringNode*)m_rbRight)->Print(bCursers,bDescendingSort,nIndex,nStartIndex,nEndIndex);
1898
1899 if (nIndex >= nStartIndex && nIndex <= nEndIndex)
1900 {
1901 if (bCursers)
1902 {
1903 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);
1904 }
1905 else
1906 {
1907 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);
1908 }
1909 }
1910 nIndex++;
1911 if (m_rbLeft)
1912 ((CStringNode*)m_rbLeft)->Print(bCursers,bDescendingSort,nIndex,nStartIndex,nEndIndex);
1913 }
1914
1915 }
1916 void CStringNode::Export(FILE* hFile)
1917 {
1918 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",
1919 (char*)&(m_Value),m_nBytes,
1920 m_nFrames, m_nFramesiOS, m_nFramesOSX,
1921 m_nQuestionFrames, m_nQuestionFramesiOS, m_nQuestionFramesOSX,
1922 m_nAnswerFrames, m_nAnswerFramesiOS, m_nAnswerFramesOSX,
1923 m_nDeviceAskingCount, m_nDeviceAskingiOSCount,m_nDeviceAskingOSXCount,
1924 m_nDeviceAnsweringCount,m_nDeviceAnsweringiOSCount,m_nDeviceAnsweringOSXCount,
1925 m_nDeviceTotalCount, m_nDeviceTotaliOSCount, m_nDeviceTotalOSXCount,
1926 m_nWakeFrames,m_nGoodbyeFrames);
1927
1928 if (m_rbLeft)
1929 ((CStringNode*)m_rbLeft)->Export(hFile);
1930 if (m_rbRight)
1931 ((CStringNode*)m_rbRight)->Export(hFile);
1932
1933 }
1934
1935 /* CStringShortNode */
1936
1937 void CStringShortNode::Export(FILE *hFile)
1938 {
1939 fprintf(hFile, "%s,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu\n",
1940 (char*)&(m_Value),m_nBytes,
1941 m_nFrames, m_nQuestionFrames, m_nAnswerFrames,
1942 m_nDeviceAskingCount, m_nDeviceAnsweringCount, m_nDeviceTotalCount,
1943 m_nWakeFrames,m_nGoodbyeFrames);
1944
1945
1946 if (m_rbLeft)
1947 {
1948 ((CStringShortNode*)m_rbLeft)->Export(hFile);
1949 }
1950 if (m_rbRight)
1951 {
1952 ((CStringShortNode*)m_rbRight)->Export(hFile);
1953 }
1954 }
1955
1956 /* CDeviceMap */
1957
1958 void CDeviceMap::GetDeviceOSTypes(CDeviceNode *node, CDeviceMap *pGlobalDeviceMap, device_count& dev_cnt)
1959 {
1960 if (node == NULL)
1961 return;
1962
1963 GetDeviceOSTypes(dynamic_cast<CDeviceNode*>(node->m_rbLeft),pGlobalDeviceMap, dev_cnt);
1964 GetDeviceOSTypes(dynamic_cast<CDeviceNode*>(node->m_rbRight),pGlobalDeviceMap, dev_cnt);
1965
1966 if (node->bDuplicate || !node->bHasFrames)
1967 return;
1968
1969 char deviceType = '?';
1970 if (pGlobalDeviceMap)
1971 {
1972 CDeviceNode* globalDevice = pGlobalDeviceMap->Find(&node->m_Key);
1973 if (globalDevice)
1974 {
1975 deviceType = globalDevice->GetDeviceOS();
1976
1977 if (globalDevice->bOSXWithEDNSField && deviceType == 'X')
1978 {
1979 dev_cnt.OSXWithEDNSField++;
1980 }
1981 else if (globalDevice->biOSWithEDNSField && (deviceType == 't' || deviceType == 'i'))
1982 {
1983 dev_cnt.iOSWithEDNSField++;
1984 }
1985 }
1986 }
1987 else
1988 {
1989 deviceType = node->GetDeviceOS();
1990 if (node->bOSXWithEDNSField && deviceType == 'X')
1991 {
1992 dev_cnt.OSXWithEDNSField++;
1993 }
1994 else if (node->biOSWithEDNSField && (deviceType == 't' || deviceType == 'i'))
1995 {
1996 dev_cnt.iOSWithEDNSField++;
1997 }
1998 }
1999 switch (deviceType)
2000 {
2001 case 'i':
2002 case 't':
2003 dev_cnt.iOS++;
2004 break;
2005 case 'X':
2006 dev_cnt.OSX++;
2007 break;
2008 default:
2009 dev_cnt.unknownOS++;
2010 break;
2011 }
2012 }
2013
2014 void CIPAddrMap::GetDeviceOSTypes(CIPDeviceNode* node, CIPAddrMap* pGobalMap, BJ_UINT64& iOS,BJ_UINT64& OSX,BJ_UINT64& unknowOS)
2015 {
2016 if (node == NULL)
2017 return;
2018
2019 GetDeviceOSTypes(dynamic_cast<CIPDeviceNode*>(node->m_rbLeft),pGobalMap, iOS, OSX, unknowOS);
2020 GetDeviceOSTypes(dynamic_cast<CIPDeviceNode*>(node->m_rbRight),pGobalMap,iOS, OSX, unknowOS);
2021
2022 char deviceType = '?';
2023 if (pGobalMap)
2024 {
2025 CIPDeviceNode *ipDevice = pGobalMap->Find(&node->m_Key);
2026
2027 if (ipDevice && ipDevice->pDeviceNode )
2028 deviceType = ipDevice->pDeviceNode->GetDeviceOS();
2029
2030 }
2031
2032 switch (deviceType)
2033 {
2034 case 'i':
2035 case 't':
2036 iOS++;
2037 break;
2038 case 'X':
2039 OSX++;
2040 break;
2041 default:
2042 unknowOS++;
2043 }
2044
2045 }
2046
2047
2048 ///////////
2049