00001
00002
00003
00014
00015
00016
00017
00018 #define MDNS_C
00019
00020
00022
00024
00025 #include "TCPIP.h"
00026 #include "mdns.h"
00027
00028
00030
00032
00033
00034
00035
00036 #define MAXREPEAT_INTERVAL (TICK_HOUR)
00037
00038
00039 #define DNS_DEFAULT_TTL 120ul // In seconds...
00040 #define DNS_RR_TTL 4500ul // In seconds...
00041
00042
00043 #define DNS_ROOT_LABEL (0xFF)
00044 #define DNS_UNSPECIFIED_LABEL (0xFF)
00045
00046
00047
00048 #define TCP_SERVICE_NAME_IDX (14)
00049 #define QUERY_SERVICE_NAME_IDX (15)
00050 #define QUERY_NAME_IDX (16)
00051
00052
00053
00054 #define DNS_ENTRIES (sizeof(_asDNSEntries)/sizeof(DNS_ENTRY))
00055 #define DNS_LABELS (sizeof(_asROMLabelList)/sizeof(ROM char *))
00056
00057
00058
00059
00060 #define DNS_PROBE_ENTRIES 2
00061
00062
00063
00064 #define DNS_GOODBYE_ENTRIES 1
00065
00066
00067
00068 #define MAX_DNS_NAME_LEN 100
00069
00070
00072
00074
00075
00076 typedef enum
00077 {
00078 MDNS_STOPPED = 0,
00079 MDNS_WAIT_FOR_PROBING,
00080 MDNS_SECOND_PROBE,
00081 MDNS_THIRD_PROBE,
00082 MDNS_FIRST_ANNOUNCING,
00083 MDNS_SECOND_ANNOUNCING,
00084 MDNS_THIRD_ANNOUNCING,
00085 MDNS_FOURTH_ANNOUNCING,
00086 MDNS_FIFTH_ANNOUNCING,
00087 MDNS_IDLE
00088 } SM_MDNS;
00089
00090
00091 typedef enum
00092 {
00093 MDNSR_STOPPED = 0,
00094 MDNSR_SERVICE,
00095 MDNSR_NAME,
00096 MDNSR_RESOLVED
00097 } SM_MDNSR;
00098
00099
00100
00101 typedef struct _DNS_HEADER
00102 {
00103 WORD_VAL TransactionID;
00104 WORD_VAL Flags;
00105 WORD_VAL Questions;
00106 WORD_VAL Answers;
00107 WORD_VAL AuthoritativeRecords;
00108 WORD_VAL AdditionalRecords;
00109 } DNS_HEADER;
00110
00111
00112 typedef struct
00113 {
00114 BYTE u8FirstLabelIdx;
00115 WORD_VAL u16Type;
00116 DWORD_VAL u32TTL;
00117 WORD_VAL u16DataLength;
00118 void * pData;
00119 BYTE u8DNSFirstLabelIdx;
00120 BYTE u8NumberOfAddRRs;
00121 ROM char * pAddRRList;
00122 BOOL bUnique;
00123 } DNS_ENTRY;
00124
00125
00126
00127 typedef struct
00128 {
00129 ROM char * pLabel;
00130 BYTE u8PrevIndex;
00131 } DNS_ROMLABEL;
00132
00133
00134
00135 typedef struct
00136 {
00137 char * pLabel;
00138 } DNS_RAMLABEL;
00139
00140
00141
00142 typedef struct
00143 {
00144 BYTE u8FirstLabelIdx;
00145 WORD_VAL u16Type;
00146 } DNS_QUERY;
00147
00148
00149 typedef struct
00150 {
00151 WORD_VAL u16Priority;
00152 WORD_VAL u16Weight;
00153 WORD_VAL u16Port;
00154 } SRV_ENTRY;
00155
00156
00157 typedef struct
00158 {
00159 BYTE bAnswer : 1;
00160 BYTE bUCAnswer : 1;
00161 BYTE bAdditional : 1;
00162 } DNS_CONTROL;
00163
00164
00166
00168
00169
00170 static SM_MDNS _eSM_MDNS = MDNS_STOPPED;
00171 static UDP_SOCKET _sMDNSMCSocket = INVALID_UDP_SOCKET;
00172 static DWORD _u32MdnsTimer;
00173
00174
00176
00177
00178 static BYTE _au8QuerySrvName[17];
00179 static SRV_ENTRY _sQuerySrv;
00180 static BYTE _au8QueryName[64];
00181 static BYTE _au8QueryIP[4];
00182 static DWORD _u32RetryTimer;
00183 static DWORD _u32IntervalTime;
00184 static SM_MDNSR _eSMResolver = MDNSR_STOPPED;
00185
00186
00187
00189
00190
00191
00192
00193
00194
00195
00196 ROM DNS_ROMLABEL _asROMLabelList[] =
00197 {
00198
00199 {HOSTNAME, 1},
00200
00201 {(ROM BYTE *) "local", DNS_ROOT_LABEL},
00202
00203 {(ROM BYTE *) "_http", 3},
00204
00205 {(ROM BYTE *) "_tcp", 1},
00206
00207 {(ROM BYTE *) "in-addr", 5},
00208
00209 {(ROM BYTE *) "arpa", DNS_ROOT_LABEL},
00210
00211 {(ROM BYTE *) "_services", 7},
00212
00213 {(ROM BYTE *) "_dns-sd", 8},
00214
00215 {(ROM BYTE *) "_udp", 1},
00216
00217 {(ROM BYTE *) "\x80", 4},
00218
00219 {(ROM BYTE *) "\x81", 9},
00220
00221 {(ROM BYTE *) "\x82", 10},
00222
00223 {(ROM BYTE *) "\x83", 11},
00224
00225 {HOSTNAME, 2},
00226
00227 {(ROM BYTE *) "\x84", 3},
00228
00229 {(ROM BYTE *) "\x85", 14},
00230
00231 {(ROM BYTE *) "\x85", 1},
00232 };
00233
00234
00235
00236
00237 static BYTE _u8IPbuf[16];
00238
00239
00240
00241
00242
00243
00244 ROM DNS_RAMLABEL _asRAMLabelList[] =
00245 {
00246 _u8IPbuf,
00247 &_u8IPbuf[4],
00248 &_u8IPbuf[8],
00249 &_u8IPbuf[12],
00250 _au8QuerySrvName,
00251 _au8QueryName,
00252 };
00253
00254
00256
00257
00258
00259
00260
00261 static BYTE _u8ZeroLength = 0;
00262
00263
00264
00265 static SRV_ENTRY _sHttpService = {0,0,0x5000};
00266
00267
00268 ROM DNS_ENTRY _asDNSEntries[] =
00269 {
00270
00271 {0, DNS_TYPE_A, DNS_DEFAULT_TTL, 4, (void *) &sIPConfig.MyIPAddr,
00272 DNS_UNSPECIFIED_LABEL, 0, 0, TRUE},
00273
00274
00275 {13, DNS_TYPE_SRV, DNS_DEFAULT_TTL, sizeof(SRV_ENTRY), &_sHttpService,
00276 0, 1, (ROM BYTE *) "\x000", TRUE},
00277
00278
00279 {12, DNS_TYPE_PTR, DNS_DEFAULT_TTL, 0, 0, 0, 0, 0, TRUE},
00280
00281
00282 {6, DNS_TYPE_PTR, DNS_RR_TTL, 0, 0, 2, 0, 0, FALSE},
00283
00284
00285 {13, DNS_TYPE_TXT, DNS_RR_TTL, 1, (void *) &_u8ZeroLength,
00286 DNS_UNSPECIFIED_LABEL, 1, (ROM BYTE *) "\x000", TRUE},
00287
00288
00289 {2, DNS_TYPE_PTR, DNS_RR_TTL, 0, 0,
00290 13, 3, (ROM BYTE *) "\x000\x001\x004", FALSE}
00291 };
00292
00293
00294
00296
00297
00298 static WORD_VAL _au16SendEntries[DNS_LABELS];
00299 static DNS_CONTROL _sControl[DNS_ENTRIES];
00300 static BYTE _u8UniqueEntries;
00301
00302
00303
00305
00307
00308 static void _PutQuery(BOOL bProbe, BOOL bQU, DNS_QUERY * pQuery);
00309 static BOOL _PrepareMulticast(BYTE nQueries, BYTE nAnswers,
00310 BYTE nAuthoritives, BYTE nAdditional);
00311 static void _SendRRList(BYTE nEntries, ROM DNS_ENTRY * pRRList, BOOL bGoodbye);
00312 static void _PutDNSName(BYTE u8StartIndex);
00313 static BYTE _u8GetDNSNameLength(BYTE u8LabelIndex);
00314 static void _GetQueryData(WORD_VAL * psType, WORD_VAL * psClass);
00315 static void _QueryLookUp(void);
00316 static void _AnswerLookUp(BOOL bQuery);
00317 BYTE _u8GetRRData(WORD_VAL * pType, WORD_VAL * pClass);
00318 BYTE _u8GetStartLabelFromFrame(void);
00319 void _CheckForQueryResponse(WORD_VAL u16Type, WORD_VAL * pu16Length,
00320 BYTE u8Startlabel);
00321
00323
00325
00330 BOOL bInitMDNSResponder(void)
00331 {
00332 BYTE i = 0;
00333 NODE_INFO nodeInfo;
00334
00335
00336 nodeInfo.MACAddr.v[0]= 0x01;
00337 nodeInfo.MACAddr.v[1]= 0x00;
00338 nodeInfo.MACAddr.v[2]= 0x5e;
00339 nodeInfo.MACAddr.v[3]= 0x00;
00340 nodeInfo.MACAddr.v[4]= 0x00;
00341 nodeInfo.MACAddr.v[5]= 0xfb;
00342 nodeInfo.IPAddr.v[0] = 224;
00343 nodeInfo.IPAddr.v[1] = 0;
00344 nodeInfo.IPAddr.v[2] = 0;
00345 nodeInfo.IPAddr.v[3] = 251;
00346
00347 _eSM_MDNS = MDNS_STOPPED;
00348
00349 _sMDNSMCSocket = UDPOpen(MDNS_PORT, &nodeInfo, MDNS_PORT);
00350
00351 if(_sMDNSMCSocket == INVALID_UDP_SOCKET)
00352 return FALSE;
00353
00354
00355 _u8UniqueEntries = 0;
00356 for (i=0; i < DNS_ENTRIES; i++)
00357 {
00358 if ((_asDNSEntries[i].u16Type.Val != DNS_TYPE_PTR)&&
00359 (_asDNSEntries[i].bUnique==TRUE))
00360 _u8UniqueEntries++;
00361 }
00362
00363 return TRUE;
00364 }
00365
00368
00369 void StartMDNSResponder(void)
00370 {
00371 BYTE i = 0;
00372
00373 MDNSStopResolving();
00374
00375
00376 for (i=0;i<4;i++)
00377 sprintf(&_u8IPbuf[i<<2], "%u", sIPConfig.MyIPAddr.v[i]);
00378
00379
00380
00381
00382 _u32MdnsTimer = TickGet() + (rand() % ((DWORD)(TICKS_PER_SECOND >> 2)));
00383 _eSM_MDNS = MDNS_WAIT_FOR_PROBING;
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 }
00396
00399
00400 void StopMDNSResponder(void)
00401 {
00402
00403 MDNSStopResolving();
00404
00405 if (_eSM_MDNS > MDNS_THIRD_PROBE)
00406 {
00407
00408
00409 _PrepareMulticast(0, DNS_GOODBYE_ENTRIES, 0, 0);
00410 _SendRRList(DNS_GOODBYE_ENTRIES,
00411 &_asDNSEntries[DNS_ENTRIES-DNS_GOODBYE_ENTRIES],
00412 TRUE);
00413 UDPFlush();
00414 }
00415
00416 _eSM_MDNS = MDNS_STOPPED;
00417 }
00418
00421
00422 MDNS_STATE eGetMDNSState(void)
00423 {
00424 if (_eSM_MDNS == MDNS_STOPPED)
00425 return MDNS_HAS_STOPPED;
00426 else if (_eSM_MDNS > MDNS_FIRST_ANNOUNCING)
00427 return MDNS_IS_RUNNING;
00428 else
00429 return MDNS_IS_STARTING_UP;
00430 }
00431
00434
00435 void MDNSResponder()
00436 {
00437 BOOL bSendUnicast = TRUE;
00438 BYTE i=0;
00439
00440 switch(_eSM_MDNS)
00441 {
00442 case MDNS_STOPPED:
00443 break;
00444
00445 case MDNS_THIRD_PROBE:
00446 bSendUnicast = FALSE;
00447 case MDNS_SECOND_PROBE:
00448 case MDNS_WAIT_FOR_PROBING:
00449 if (TickGet() > _u32MdnsTimer)
00450 {
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 _PrepareMulticast(DNS_PROBE_ENTRIES, 0, _u8UniqueEntries, 0);
00464
00465 for(i=0; i < DNS_PROBE_ENTRIES; i++)
00466 {
00467 DNS_QUERY query;
00468 query.u8FirstLabelIdx = _asDNSEntries[i].u8FirstLabelIdx;
00469 query.u16Type = _asDNSEntries[i].u16Type;
00470 _PutQuery(TRUE, bSendUnicast, &query);
00471 }
00472
00473
00474 for (i=0; i < DNS_ENTRIES; i++)
00475 {
00476 if((_asDNSEntries[i].bUnique==TRUE)&&
00477 (_asDNSEntries[i].u16Type.Val != DNS_TYPE_PTR))
00478 {
00479 _SendRRList(1, &_asDNSEntries[i], FALSE);
00480 }
00481 }
00482 UDPFlush();
00483
00484 _u32MdnsTimer += (DWORD)(TICKS_PER_SECOND >> 2);
00485 _eSM_MDNS++;
00486 }
00487 break;
00488
00489 case MDNS_FIRST_ANNOUNCING:
00490 case MDNS_SECOND_ANNOUNCING:
00491 case MDNS_THIRD_ANNOUNCING:
00492 case MDNS_FOURTH_ANNOUNCING:
00493 case MDNS_FIFTH_ANNOUNCING:
00494 if (TickGet() > _u32MdnsTimer)
00495 {
00496
00497
00498
00499
00500
00501
00502
00503 _PrepareMulticast(0, DNS_ENTRIES, 0, 0);
00504 _SendRRList(DNS_ENTRIES, _asDNSEntries, FALSE);
00505 UDPFlush();
00506
00507 _u32MdnsTimer += (TICKS_PER_SECOND)*
00508 (1<<(_eSM_MDNS-(MDNS_FIRST_ANNOUNCING)));
00509 _eSM_MDNS++;
00510 }
00511 break;
00512 }
00513
00514 if((_eSM_MDNS > MDNS_FIRST_ANNOUNCING)&&
00515 ((_eSMResolver == MDNSR_SERVICE) || (_eSMResolver == MDNSR_NAME)))
00516 {
00517 if (TickGet() > _u32RetryTimer)
00518 {
00519 if (_u32IntervalTime<MAXREPEAT_INTERVAL)
00520 _u32IntervalTime = _u32IntervalTime << 1;
00521
00522 _u32RetryTimer += _u32IntervalTime;
00523 if (_eSMResolver == MDNSR_SERVICE)
00524 MDNSResolveService(0, 0);
00525 else
00526 MDNSResolveName(0);
00527 }
00528 }
00529 }
00530
00533
00534 void MDNSProcessFrame(NODE_INFO *remoteNode, IP_ADDR *localIP)
00535 {
00536 DNS_HEADER head;
00537 BYTE i;
00538
00539
00540
00541 if ((localIP->Val != 0xFB0000E0ul) &&
00542 ((remoteNode->IPAddr.Val & sIPConfig.MyMask.Val) !=
00543 (sIPConfig.MyIPAddr.Val & sIPConfig.MyMask.Val)))
00544 {
00545 return;
00546 }
00547
00548
00549
00550 if (!UDPIsGetReady(_sMDNSMCSocket))
00551 return;
00552
00553
00554 memset(_sControl, 0, sizeof(_sControl));
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 UDPGet(&head.TransactionID.v[1]);
00569 UDPGet(&head.TransactionID.v[0]);
00570
00571 UDPGet(&head.Flags.v[1]);
00572 UDPGet(&head.Flags.v[0]);
00573
00574 UDPGet(&head.Questions.v[1]);
00575 UDPGet(&head.Questions.v[0]);
00576 UDPGet(&head.Answers.v[1]);
00577 UDPGet(&head.Answers.v[0]);
00578 UDPGet(&head.AuthoritativeRecords.v[1]);
00579 UDPGet(&head.AuthoritativeRecords.v[0]);
00580 UDPGet(&head.AdditionalRecords.v[1]);
00581 UDPGet(&head.AdditionalRecords.v[0]);
00582
00583
00584 if (head.Flags.Val == 0)
00585 {
00586
00587 BYTE j, answers = 0, additional = 0;
00588
00589
00590 if (_eSM_MDNS < MDNS_SECOND_ANNOUNCING)
00591 goto MDNSProcessEnd;
00592
00593
00594 if (head.Questions.Val == 0)
00595 goto MDNSProcessEnd;
00596
00597 while(head.Questions.Val--)
00598 {
00599
00600 _QueryLookUp();
00601 }
00602
00603 while(head.Answers.Val--)
00604 {
00605
00606 _AnswerLookUp(TRUE);
00607 }
00608
00609
00610 for(i = 0; i < DNS_ENTRIES; i++)
00611 {
00612 if (_sControl[i].bAnswer == TRUE)
00613 {
00614 answers++;
00615
00616
00617
00618 for(j = 0; j < _asDNSEntries[i].u8NumberOfAddRRs; j++)
00619 {
00620 BYTE add = _asDNSEntries[i].pAddRRList[j];
00621 if (_sControl[add].bAnswer == FALSE)
00622 _sControl[add].bAdditional = TRUE;
00623 }
00624 }
00625 }
00626
00627
00628 for(i = 0; i < DNS_ENTRIES; i++)
00629 {
00630 if (_sControl[i].bAdditional == TRUE)
00631 additional++;
00632 }
00633
00634 if (answers)
00635 {
00636
00637 _PrepareMulticast(0, answers, 0, additional);
00638
00639 for(i = 0; i < DNS_ENTRIES; i++)
00640 {
00641 if (_sControl[i].bAnswer == TRUE)
00642 _SendRRList(1, &_asDNSEntries[i], FALSE);
00643 }
00644
00645 if (additional)
00646 {
00647 for(i = 0; i < DNS_ENTRIES; i++)
00648 {
00649 if (_sControl[i].bAdditional == TRUE)
00650 _SendRRList(1, &_asDNSEntries[i], FALSE);
00651 }
00652 }
00653
00654 UDPFlush();
00655 }
00656 }
00657 else if (head.Flags.Val & 0x8000)
00658 {
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 while(head.Answers.Val--)
00669 _AnswerLookUp(FALSE);
00670
00671 while(head.AuthoritativeRecords.Val--)
00672 _AnswerLookUp(FALSE);
00673
00674 while(head.AdditionalRecords.Val--)
00675 _AnswerLookUp(FALSE);
00676
00677
00678 for(i = 0; i < DNS_ENTRIES; i++)
00679 {
00680 if (_sControl[i].bAnswer == TRUE)
00681 break;
00682 }
00683
00684
00685 if (i != DNS_ENTRIES)
00686 StopMDNSResponder();
00687
00688 }
00689
00690 MDNSProcessEnd:
00691 UDPDiscard();
00692 }
00693
00696
00697 BOOL bMDNSNameIsResolved(IP_ADDR * pIP)
00698 {
00699 if (_eSMResolver != MDNSR_RESOLVED)
00700 return FALSE;
00701 memcpy(pIP,(void *)_au8QueryIP, 4);
00702 return TRUE;
00703 }
00704
00707
00708 BOOL bMDNSServiceIsResolved(IP_ADDR * pIP, WORD_VAL * pu16Port)
00709 {
00710 if (bMDNSNameIsResolved(pIP) == TRUE)
00711 {
00712 *pu16Port = _sQuerySrv.u16Port;
00713 return TRUE;
00714 }
00715 return FALSE;
00716 }
00717
00720
00721 void MDNSStopResolving(void)
00722 {
00723 _eSMResolver = MDNSR_STOPPED;
00724 }
00725
00728
00729 void MDNSResolveName(char * pName)
00730 {
00731 DNS_QUERY query;
00732
00733
00734 if (pName)
00735 {
00736
00737 strcpy(_au8QueryName, pName);
00738 _u32RetryTimer = TickGet() + TICKS_PER_SECOND;
00739 _u32IntervalTime = TICKS_PER_SECOND;
00740 }
00741
00742 query.u16Type.Val = DNS_TYPE_A;
00743 query.u8FirstLabelIdx = QUERY_NAME_IDX;
00744
00745 _PrepareMulticast(1, 0, 0, 0);
00746 _PutQuery(FALSE, FALSE, &query);
00747
00748 UDPFlush();
00749
00750 _eSMResolver = MDNSR_NAME;
00751 }
00752
00755
00756 void MDNSResolveService(char * pName, ROM char * pServiceName)
00757 {
00758 DNS_QUERY query;
00759
00760
00761 if (pName)
00762 {
00763
00764 strcpypgm2ram(_au8QuerySrvName, pServiceName);
00765 strcpy(_au8QueryName, pName);
00766 _u32RetryTimer = TickGet() + TICKS_PER_SECOND;
00767 _u32IntervalTime = TICKS_PER_SECOND;
00768 }
00769
00770 query.u16Type.Val = DNS_TYPE_SRV;
00771 query.u8FirstLabelIdx = QUERY_SERVICE_NAME_IDX;
00772
00773 _PrepareMulticast(1, 0, 0, 0);
00774 _PutQuery(FALSE, FALSE, &query);
00775
00776 UDPFlush();
00777
00778 _eSMResolver = MDNSR_SERVICE;
00779 }
00780
00783
00784 static BYTE _u8GetDNSNameLength(BYTE u8LabelIndex)
00785 {
00786 BYTE i=0;
00787
00788 while(u8LabelIndex != DNS_ROOT_LABEL)
00789 {
00790 ROM BYTE * pRomLabel = _asROMLabelList[u8LabelIndex].pLabel;
00791
00792 if (_au16SendEntries[u8LabelIndex].Val)
00793 {
00794
00795 i+=2;
00796 return i;
00797 }
00798
00799
00800 i++;
00801 if (*pRomLabel & 0x80)
00802 {
00803
00804 BYTE ramidx = (*pRomLabel) & 0x7F;
00805 BYTE * pRamLabel = _asRAMLabelList[ramidx].pLabel;
00806
00807
00808 i += strlen(pRamLabel);
00809 }
00810 else
00811 i += strlenpgm(pRomLabel);
00812
00813 u8LabelIndex = _asROMLabelList[u8LabelIndex].u8PrevIndex;
00814 }
00815
00816
00817 return i++;
00818 }
00819
00822
00823 static void _PutDNSName(BYTE u8LabelIndex)
00824 {
00825 while(u8LabelIndex != DNS_ROOT_LABEL)
00826 {
00827 ROM BYTE * pRomLabel = _asROMLabelList[u8LabelIndex].pLabel;
00828
00829 if (_au16SendEntries[u8LabelIndex].Val)
00830 {
00831
00832 UDPPut(0xc0 | (_au16SendEntries[u8LabelIndex].v[1]));
00833
00834
00835 UDPPut(_au16SendEntries[u8LabelIndex].v[0]);
00836 return;
00837 }
00838 else
00839 {
00840
00841 _au16SendEntries[u8LabelIndex].Val = UDPGetPutOffset();
00842
00843 if (*pRomLabel & 0x80)
00844 {
00845
00846 BYTE ramidx = (*pRomLabel) & 0x7F;
00847 BYTE * pRamLabel = _asRAMLabelList[ramidx].pLabel;
00848
00849
00850 UDPPut(strlen(pRamLabel));
00851
00852 UDPPutString(pRamLabel);
00853 }
00854 else
00855 {
00856
00857
00858
00859 UDPPut(strlenpgm(pRomLabel));
00860
00861 UDPPutROMString(pRomLabel);
00862 }
00863
00864 u8LabelIndex = _asROMLabelList[u8LabelIndex].u8PrevIndex;
00865 }
00866 }
00867
00868
00869 UDPPut(0x00);
00870 }
00871
00874
00875 static void _GetQueryData(WORD_VAL * psType, WORD_VAL * psClass)
00876 {
00877
00878 UDPGet(&psType->v[1]);
00879 UDPGet(&psType->v[0]);
00880
00881
00882 UDPGet(&psClass->v[1]);
00883 UDPGet(&psClass->v[0]);
00884 }
00885
00888
00889 static void _AnswerLookUp(BOOL bQuery)
00890 {
00891 BYTE startlabel=0, i=0;
00892 WORD j=0;
00893 WORD_VAL type=0, class=0;
00894 WORD_VAL length, locallength;
00895 DWORD_VAL ttl = 0;
00896 BOOL bKeyMatch = FALSE;
00897 BOOL bEntryMatch = FALSE;
00898
00899
00900 startlabel = _u8GetRRData(&type, &class);
00901
00902
00903
00904 UDPGet(&ttl.v[3]);
00905 UDPGet(&ttl.v[2]);
00906 UDPGet(&ttl.v[1]);
00907 UDPGet(&ttl.v[0]);
00908
00909 UDPGet(&length.v[1]);
00910 UDPGet(&length.v[0]);
00911
00912
00913
00914 if (startlabel == DNS_UNSPECIFIED_LABEL)
00915 {
00916
00917 UDPGetArray(NULL, length.Val);
00918 return;
00919 }
00920
00921
00922
00923 for(i=0; i < DNS_ENTRIES; i++)
00924 {
00925 if ((_asDNSEntries[i].u8FirstLabelIdx == startlabel)&&
00926 (_asDNSEntries[i].u16Type.Val == type.Val))
00927 {
00928 bKeyMatch = TRUE;
00929 locallength.Val =
00930 _u8GetDNSNameLength(_asDNSEntries[i].u8DNSFirstLabelIdx);
00931
00932 if(length.Val != _asDNSEntries[i].u16DataLength.Val+locallength.Val)
00933 break;
00934
00935
00936 for (j=0; j<_asDNSEntries[i].u16DataLength.Val; j++)
00937 {
00938 BYTE tmp = 0;
00939 UDPGet(&tmp);
00940 length.Val--;
00941 if (tmp!=((BYTE *)(_asDNSEntries[i].pData))[j])
00942 break;
00943 }
00944
00945 if (j!=_asDNSEntries[i].u16DataLength.Val)
00946 break;
00947
00948 if ((_asDNSEntries[i].u8DNSFirstLabelIdx!=DNS_UNSPECIFIED_LABEL)&&
00949 (_u8GetStartLabelFromFrame() !=
00950 _asDNSEntries[i].u8DNSFirstLabelIdx))
00951 {
00952
00953
00954 length.Val = 0;
00955 break;
00956 }
00957
00958
00959
00960
00961 if ((_asDNSEntries[i].u32TTL.Val >> 1)<ttl.Val)
00962 {
00963
00964 _sControl[i].bAnswer = FALSE;
00965 }
00966
00967 bEntryMatch = TRUE;
00968 break;
00969 }
00970 }
00971
00972
00973 if ((bQuery==FALSE)&&(bKeyMatch==FALSE))
00974 _CheckForQueryResponse(type, &length, startlabel);
00975
00976
00977
00978 if (length.Val)
00979 UDPGetArray(NULL,length.Val);
00980
00981
00982 if ((bQuery==FALSE)&&(bKeyMatch==TRUE)&&(_asDNSEntries[i].bUnique==TRUE))
00983 {
00984
00985 _sControl[i].bAnswer = TRUE;
00986 }
00987 return;
00988 }
00989
00992
00993 static void _QueryLookUp(void)
00994 {
00995 BYTE labellen = 0;
00996 BYTE namelen = 0;
00997 BYTE startlabel = 0, j = 0;
00998 WORD_VAL type = 0, class = 0;
00999
01000
01001 startlabel = _u8GetRRData(&type, &class);
01002 if (startlabel == DNS_UNSPECIFIED_LABEL)
01003 return;
01004
01005
01006
01007 for(j=0; j < DNS_ENTRIES; j++)
01008 {
01009 if ((_asDNSEntries[j].u8FirstLabelIdx == startlabel)&&
01010 ((_asDNSEntries[j].u16Type.Val == type.Val) ||
01011 (type.Val == DNS_TYPE_ANY)))
01012 {
01013
01014 _sControl[j].bAnswer = TRUE;
01015
01016
01017 if (class.v[1] & 0x80)
01018 _sControl[j].bUCAnswer = TRUE;
01019 }
01020 }
01021
01022 return;
01023 }
01024
01027
01028 BYTE _u8GetRRData(WORD_VAL * pType, WORD_VAL * pClass)
01029 {
01030 BYTE label = _u8GetStartLabelFromFrame();
01031 _GetQueryData(pType, pClass);
01032
01033
01034 if ((pClass->Val & 0x7FFF) != 0x0001)
01035 return DNS_UNSPECIFIED_LABEL;
01036
01037 return label;
01038 }
01039
01042
01043 void _CheckForQueryResponse(WORD_VAL u16Type, WORD_VAL * pu16Length,
01044 BYTE u8Startlabel)
01045 {
01046 if ((u16Type.Val==DNS_TYPE_SRV)&&
01047 (_eSMResolver == MDNSR_SERVICE)&&
01048 (u8Startlabel == QUERY_SERVICE_NAME_IDX))
01049 {
01050
01051 BYTE labellen;
01052
01053
01054 UDPGet(&_sQuerySrv.u16Priority.v[1]);
01055 UDPGet(&_sQuerySrv.u16Priority.v[0]);
01056 UDPGet(&_sQuerySrv.u16Weight.v[1]);
01057 UDPGet(&_sQuerySrv.u16Weight.v[0]);
01058 UDPGet(&_sQuerySrv.u16Port.v[1]);
01059 UDPGet(&_sQuerySrv.u16Port.v[0]);
01060
01061 pu16Length->Val = pu16Length->Val - sizeof(SRV_ENTRY);
01062
01063 UDPGet(&labellen);
01064 if (labellen & 0xc0)
01065 {
01067
01068
01069
01070
01071
01072
01073 }
01074 else
01075 UDPGetArray(_au8QueryName, labellen);
01076
01077 _au8QueryName[labellen] = 0;
01078 pu16Length->Val-= labellen+1;
01079
01080
01081 _u32RetryTimer = TickGet() + TICKS_PER_SECOND;
01082 _u32IntervalTime = TICKS_PER_SECOND;
01083 _eSMResolver = MDNSR_NAME;
01084 strlwr(_au8QueryName);
01085 }
01086 else if ((u16Type.Val==DNS_TYPE_A)&&
01087 (_eSMResolver == MDNSR_NAME)&&
01088 (u8Startlabel == QUERY_NAME_IDX))
01089 {
01090
01091 UDPGetArray(_au8QueryIP, 4);
01092 pu16Length->Val = 0;
01093 _eSMResolver = MDNSR_RESOLVED;
01094 }
01095 }
01096
01099
01100 BYTE _u8GetStartLabelFromFrame(void)
01101 {
01102 BOOL bFound = FALSE;
01103 BOOL bNoSpaceLeft = FALSE;
01104 BYTE labellen = 0, namelen = 0, labelcount = 0, i, j;
01105 BYTE name[MAX_DNS_NAME_LEN];
01106 WORD_VAL udppos = u16MACGetCurrentReadPtrPos();
01107
01108 memset(name, 0, MAX_DNS_NAME_LEN);
01109
01110
01111 while(1)
01112 {
01113 labellen = MACGet();
01114
01115 if (labellen & 0xc0)
01116 {
01117
01118 WORD_VAL address;
01119 address.v[1] = labellen & 0x3F;
01120 address.v[0] = MACGet();
01121
01122
01123 MACSetReadPtrInRx(sizeof(IP_HEADER)+sizeof(UDP_HEADER)+address.Val);
01124 continue;
01125 }
01126
01127 if (labellen == 0)
01128
01129 break;
01130
01131
01132
01133 if ((namelen+labellen) > MAX_DNS_NAME_LEN)
01134 {
01135
01136 bNoSpaceLeft = TRUE;
01137 break;
01138 }
01139
01140 name[namelen++] = labellen;
01141
01142 MACGetArray(&name[namelen], labellen);
01143
01144
01145 strlwr(&name[namelen]);
01146
01147 namelen += labellen;
01148 }
01149
01150
01151 MACSetCurrentReadPtrPos(udppos);
01152
01153
01154
01155 while(UDPGet(&labellen) == TRUE)
01156 {
01157 if (labellen & 0xc0)
01158 {
01159 BYTE dummy;
01160 UDPGet(&dummy);
01161 break;
01162 }
01163 else if (labellen == 0)
01164 break;
01165
01166 UDPGetArray(NULL, labellen);
01167 }
01168
01169 if (bNoSpaceLeft == TRUE)
01170 return DNS_UNSPECIFIED_LABEL;
01171
01172
01173
01174 for(i=0; i<DNS_LABELS; i++)
01175 {
01176 BYTE index = i;
01177 namelen = 0;
01178
01179 while(1)
01180 {
01181 ROM BYTE * pRomLabel;
01182
01183 labellen = name[namelen++];
01184 if (labellen == 0)
01185 {
01186
01187 if (index == DNS_ROOT_LABEL)
01188 bFound = TRUE;
01189
01190 break;
01191 }
01192
01193 pRomLabel = _asROMLabelList[index].pLabel;
01194 if (*pRomLabel & 0x80)
01195 {
01196
01197 BYTE ramidx = (*pRomLabel) & 0x7F;
01198 BYTE * pRamLabel = _asRAMLabelList[ramidx].pLabel;
01199
01200 if (memcmp((void*)&name[namelen],(void*) pRamLabel, labellen)!=0)
01201 break;
01202 }
01203 else
01204 {
01205
01206 if (memcmppgm2ram(&name[namelen], pRomLabel, labellen)!=0)
01207 break;
01208 }
01209
01210 index = _asROMLabelList[index].u8PrevIndex;
01211 namelen += labellen;
01212 };
01213
01214
01215 if(bFound == TRUE)
01216 break;
01217 }
01218
01219
01220
01221
01222 if (bFound == FALSE)
01223 return DNS_UNSPECIFIED_LABEL;
01224
01225 return i;
01226 }
01227
01230
01231 static BOOL _PrepareMulticast(BYTE nQueries, BYTE nAnswers,
01232 BYTE nAuthoritives, BYTE nAdditional)
01233 {
01234 if(!UDPIsPutReady(_sMDNSMCSocket))
01235 return FALSE;
01236
01237
01238 memset(_au16SendEntries, 0, sizeof(_au16SendEntries));
01239
01240 UDPPut(0x00);
01241 UDPPut(0x00);
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 if (nQueries)
01258 UDPPut(0x00);
01259 else
01260 UDPPut(0x84);
01261 UDPPut(0x00);
01262
01263 UDPPut(0x00);
01264 UDPPut(nQueries);
01265
01266 UDPPut(0x00);
01267 UDPPut(nAnswers);
01268
01269 UDPPut(0x00);
01270 UDPPut(nAuthoritives);
01271 UDPPut(0x00);
01272 UDPPut(nAdditional);
01273
01274 return TRUE;
01275 }
01276
01279
01280 static void _SendRRList(BYTE nEntries, ROM DNS_ENTRY * pRRList, BOOL bGoodbye)
01281 {
01282 BYTE i = 0;
01283
01284 for(; i < nEntries; i++)
01285 {
01286 WORD_VAL len = 0;
01287
01288 _PutDNSName(pRRList[i].u8FirstLabelIdx);
01289
01290
01291 UDPPut(pRRList[i].u16Type.v[1]);
01292 UDPPut(pRRList[i].u16Type.v[0]);
01293
01294
01295 UDPPut(pRRList[i].bUnique<<7);
01296 UDPPut(0x01);
01297
01298
01299 if (bGoodbye == FALSE)
01300 {
01301 UDPPut(pRRList[i].u32TTL.v[3]);
01302 UDPPut(pRRList[i].u32TTL.v[2]);
01303 UDPPut(pRRList[i].u32TTL.v[1]);
01304 UDPPut(pRRList[i].u32TTL.v[0]);
01305 }
01306 else
01307 {
01308 UDPPut(0);
01309 UDPPut(0);
01310 UDPPut(0);
01311 UDPPut(0);
01312 }
01313
01314
01315 len.Val = pRRList[i].u16DataLength.Val +
01316 _u8GetDNSNameLength(pRRList[i].u8DNSFirstLabelIdx);
01317 UDPPut(len.v[1]);
01318 UDPPut(len.v[0]);
01319
01320
01321 if (pRRList[i].u16DataLength.Val)
01322 UDPPutArray(pRRList[i].pData, pRRList[i].u16DataLength.Val);
01323
01324
01325 if (pRRList[i].u8DNSFirstLabelIdx != DNS_ROOT_LABEL)
01326 _PutDNSName(pRRList[i].u8DNSFirstLabelIdx);
01327 }
01328 }
01329
01330
01333
01334 static void _PutQuery(BOOL bProbe, BOOL bQU, DNS_QUERY * pQuery)
01335 {
01336 BYTE i = 0;
01337 _PutDNSName(pQuery->u8FirstLabelIdx);
01338
01339
01340 if (bProbe==TRUE)
01341 {
01342 UDPPut(DNS_TYPE_ANY>>8);
01343 UDPPut(DNS_TYPE_ANY);
01344 }
01345 else
01346 {
01347 UDPPut(pQuery->u16Type.v[1]);
01348 UDPPut(pQuery->u16Type.v[0]);
01349 }
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361 UDPPut(bQU<<7);
01362 UDPPut(0x01);
01363 }