This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

libMiMic(MiMic library for mbed)は、WebService機能を提供するSDKです。 mbedでWebAPIに対応したネットワークデバイスを簡単に作ることが出来ます。

libMiMicはMiMic projectで開発しています。MiMic projectについてはこちらをご覧ください。 http://nyatla.jp/mimic/wp/

構成

libMiMicはmbedRTOS上で動作し、ユーザアプリケーションにAPIを提供します。コアAPIはC言語で記述されていますが、使用頻度の高いものについてはmbed向けのC++APIが準備されています。

/media/uploads/nyatla/libmimic-sdk.png

※libMiMicはmbedの標準イーサネットドライバをしようしていません。

標準イーサネットドライバと同時に使用することはできません。

  • MiMicIP - IPv4スタックです。レテンシとメモリ消費量を抑えたuipベースのライブラリです。
  • ARP/ICMP/UDP/TCP - 基礎的なソケットAPIを提供します。APIは独自です。
  • HTTP/1.1 Server - HTTP/1.1に対応したサーバです。マルチセッション・Chunked・持続性接続に対応しています。
  • HTTP Modules - HTTP/1.1の機能モジュールです。以下のモジュールがあります。
    • ROM file provider - ROMに格納したファイルイメージを公開します。
    • File system provider - mbedファイルシステムを公開します。
    • Onchip configuration - プログラムフラッシュを利用して設定を保存します。
    • MiMicVM processor - RPCリクエスト(MiMicVM)を処理します。
    • FileUpload - ファイルアップロードを受け取ります。
    • URL decoder - HTTPリクエストを解析します。
    • UPnP handler -UPnPメッセージを処理します。
    • WebSocket - Websocketサーバです。
  • mDNS - マルチキャストDNSサービスです。
  • UPnP - UPnP/1.0の機能を提供します。UPnP handlerと協調して動作します。(現在はデバイス探索(SSDP)・デスクリプション(Description)のみ実装してあります。)
  • DHCP/APIPA - ゼロコンフィギュレーション用のモジュールです。
  • HTTP/1.1 Client
  • mbed C++ class library - mbed向けのC++CPIです。C言語のものより簡単です。

対応機種

  • mbed(mbed LPC1768)
  • LPCXpresso1769

プログラム

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

サンプル

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

チュートリアル

English

libMiMic(MiMic library for mbed) is SDK which provides Webservice functions. It can be created networking device easily using mbed.

See more MiMic information, See MiMic project website. http://nyatla.jp/mimic/wp/

Structure

libMiMic run on mbed RTOS and provides networking API to user application. This library has C++ class API for the mbed, and low-level C language API.

/media/uploads/nyatla/libmimic-sdk.png

For WebService general, it can be written in a simple C + + API.

libMiMic does not have the standard Ethernet driver of mbed. It is not possible that will be used with the standard Ethernet driver.

  • MiMicIP - IPv4 protocol stack. This is based uip which is reduced memory and latency.
  • ARP / ICMP / UDP / TCP - Those are provide basic IP protocols.
  • HTTP/1.1 Server - The Http server compatible HTTP/1.1. It supports multi-session, chunked transport, persistent connection.
  • HTTP Modules - There are addon-module for HTTP server. The following modules.
    • ROM file module - Publish the file images in ROM.
    • File system module - Publish thefiles in mbed file system.
    • Onchip configuration module - To save the network settings to the program flash via REST.
    • MiMicVM module - To handle the (MiMicVM) RPC request.
    • FileUpload module - Accept a file via HTTP POST.
    • URL dedoce module - A versatility URL decoder.
    • UPnP handle module - To handle UPnP messages.
    • UPnP - This provides UPnP/1.0 device functions. It works together with UPnP handler.
    • Websocket - websocket (version13) server
  • mDNS Service - DNS-SD protocol server.
  • UPnP - This provides UPnP/1.0 device functions which works with UPnP handler. (You have been implemented (SSDP) ? description only (Description) device search now.) It is a module zero configuration for - DHCP / APIPA. mbed C + + class library - C of mbed for + + is the CPI. It is simple than that of the C language.
  • DHCP/APIPA - It support zero-cpnfigulation.
  • mbed C++ class library. Almost APIs for Web applications are available.
  • HTTP/1.1 Client

Supported target

  • mbed(mbed LPC1768)
  • LPCXpresso1769

Application

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

Sample

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

Tutorial

Committer:
nyatla
Date:
Thu Oct 30 14:03:31 2014 +0000
Revision:
103:853ddf4a1b81
Parent:
102:41a5e92e0a8e
Child:
104:4f4781ecdc79
bugfix; mDNS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nyatla 37:fc4b4fd6a649 1 /*********************************************************************************
nyatla 37:fc4b4fd6a649 2 * PROJECT: MiMic
nyatla 37:fc4b4fd6a649 3 * --------------------------------------------------------------------------------
nyatla 37:fc4b4fd6a649 4 *
nyatla 37:fc4b4fd6a649 5 * This file is part of MiMic
nyatla 37:fc4b4fd6a649 6 * Copyright (C)2011 Ryo Iizuka
nyatla 37:fc4b4fd6a649 7 *
nyatla 37:fc4b4fd6a649 8 * MiMic is free software: you can redistribute it and/or modify
nyatla 37:fc4b4fd6a649 9 * it under the terms of the GNU Lesser General Public License as published
nyatla 37:fc4b4fd6a649 10 * by the Free Software Foundation, either version 3 of the License, or
nyatla 37:fc4b4fd6a649 11 * (at your option) any later version.
nyatla 37:fc4b4fd6a649 12 *
nyatla 37:fc4b4fd6a649 13 * This program is distributed in the hope that it will be useful,
nyatla 37:fc4b4fd6a649 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nyatla 37:fc4b4fd6a649 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nyatla 37:fc4b4fd6a649 16 * GNU General Public License for more details.
nyatla 37:fc4b4fd6a649 17 *
nyatla 37:fc4b4fd6a649 18 * You should have received a copy of the GNU Lesser General Public License
nyatla 37:fc4b4fd6a649 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
nyatla 37:fc4b4fd6a649 20 *
nyatla 37:fc4b4fd6a649 21 * For further information please contact.
nyatla 37:fc4b4fd6a649 22 * http://nyatla.jp/
nyatla 37:fc4b4fd6a649 23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
nyatla 37:fc4b4fd6a649 24 *
nyatla 37:fc4b4fd6a649 25 *********************************************************************************/
nyatla 37:fc4b4fd6a649 26 #include "NyLPC_cMDnsServer.h"
nyatla 37:fc4b4fd6a649 27 #include "NyLPC_uipService.h"
nyatla 37:fc4b4fd6a649 28 #include "NyLPC_http.h"
nyatla 37:fc4b4fd6a649 29 #include "NyLPC_utils.h"
nyatla 37:fc4b4fd6a649 30 #include <stdio.h>
nyatla 37:fc4b4fd6a649 31 #include <string.h>
nyatla 37:fc4b4fd6a649 32
nyatla 37:fc4b4fd6a649 33
nyatla 37:fc4b4fd6a649 34 /**
nyatla 37:fc4b4fd6a649 35 * mDNSのポート番号
nyatla 37:fc4b4fd6a649 36 */
nyatla 37:fc4b4fd6a649 37 #define MDNS_MCAST_PORT 5353
nyatla 103:853ddf4a1b81 38 static const struct NyLPC_TIPv4Addr MDNS_MCAST_IPADDR = NyLPC_TIPv4Addr_pack(224, 0, 0, 251);
nyatla 37:fc4b4fd6a649 39 #define TIMEOUT_IN_MS 1000
nyatla 101:5022828ace54 40 #define NyLPC_TcMDns_TTL (120) //120
nyatla 37:fc4b4fd6a649 41
nyatla 37:fc4b4fd6a649 42
nyatla 37:fc4b4fd6a649 43 struct NyLPC_TDnsHeader
nyatla 37:fc4b4fd6a649 44 {
nyatla 37:fc4b4fd6a649 45 NyLPC_TUInt16 id;
nyatla 37:fc4b4fd6a649 46 NyLPC_TUInt16 flag;
nyatla 37:fc4b4fd6a649 47 NyLPC_TUInt16 qd;
nyatla 37:fc4b4fd6a649 48 NyLPC_TUInt16 an;
nyatla 37:fc4b4fd6a649 49 NyLPC_TUInt16 ns;
nyatla 37:fc4b4fd6a649 50 NyLPC_TUInt16 ar;
nyatla 37:fc4b4fd6a649 51 }PACK_STRUCT_END;
nyatla 37:fc4b4fd6a649 52
nyatla 37:fc4b4fd6a649 53 #define NyLPC_TDnsHeader_FLAG_MASK_QR 0x8000
nyatla 37:fc4b4fd6a649 54 #define NyLPC_TDnsHeader_FLAG_MASK_OPCODE 0x7800
nyatla 37:fc4b4fd6a649 55 #define NyLPC_TDnsHeader_FLAG_MASK_AA 0x0400
nyatla 37:fc4b4fd6a649 56 #define NyLPC_TDnsHeader_FLAG_MASK_TC 0x0200
nyatla 37:fc4b4fd6a649 57 #define NyLPC_TDnsHeader_FLAG_MASK_RD 0x0100
nyatla 37:fc4b4fd6a649 58 #define NyLPC_TDnsHeader_FLAG_MASK_RA 0x0080
nyatla 37:fc4b4fd6a649 59 #define NyLPC_TDnsHeader_FLAG_MASK_Z 0x0070
nyatla 37:fc4b4fd6a649 60 #define NyLPC_TDnsHeader_FLAG_MASK_RECODE 0x000F
nyatla 37:fc4b4fd6a649 61
nyatla 37:fc4b4fd6a649 62 struct NyLPC_TDnsQuestion
nyatla 37:fc4b4fd6a649 63 {
nyatla 98:6284ce9a0476 64 const char* buf; //Questionパケットの先頭
nyatla 98:6284ce9a0476 65 NyLPC_TUInt16 buf_len; //パケット長さ
nyatla 37:fc4b4fd6a649 66 NyLPC_TUInt16 qtype;
nyatla 37:fc4b4fd6a649 67 NyLPC_TUInt16 qclass;
nyatla 98:6284ce9a0476 68 NyLPC_TInt16 qname_pos;//Qnameの開始位置
nyatla 37:fc4b4fd6a649 69 };
nyatla 98:6284ce9a0476 70
nyatla 37:fc4b4fd6a649 71 #define NyLPC_TDnsQuestion_QTYPR_A 1
nyatla 37:fc4b4fd6a649 72 #define NyLPC_TDnsQuestion_QTYPR_NS 2
nyatla 37:fc4b4fd6a649 73 #define NyLPC_TDnsQuestion_QTYPR_CNAME 5
nyatla 37:fc4b4fd6a649 74 #define NyLPC_TDnsQuestion_QTYPR_SOA 6
nyatla 37:fc4b4fd6a649 75 #define NyLPC_TDnsQuestion_QTYPR_PTR 12
nyatla 37:fc4b4fd6a649 76 #define NyLPC_TDnsQuestion_QTYPR_MX 15
nyatla 37:fc4b4fd6a649 77 #define NyLPC_TDnsQuestion_QTYPR_TXT 16
nyatla 37:fc4b4fd6a649 78 #define NyLPC_TDnsQuestion_QTYPR_ANY 255
nyatla 102:41a5e92e0a8e 79 #define NyLPC_TDnsQuestion_QTYPR_AAAA 28
nyatla 102:41a5e92e0a8e 80 #define NyLPC_TDnsQuestion_QTYPR_NSEC 47
nyatla 37:fc4b4fd6a649 81 #define NyLPC_TDnsQuestion_QCLASS_IN 1
nyatla 37:fc4b4fd6a649 82 #define NyLPC_TDnsQuestion_QCLASS_CH 3
nyatla 37:fc4b4fd6a649 83 #define NyLPC_TDnsQuestion_QCLASS_HS 4
nyatla 37:fc4b4fd6a649 84 #define NyLPC_TDnsQuestion_QTYPR_SRV 33
nyatla 101:5022828ace54 85 #define NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH 0x8000
nyatla 101:5022828ace54 86
nyatla 37:fc4b4fd6a649 87
nyatla 37:fc4b4fd6a649 88 /**************************************************
nyatla 103:853ddf4a1b81 89 * TLabelCache
nyatla 103:853ddf4a1b81 90 **************************************************/
nyatla 98:6284ce9a0476 91 /**
nyatla 98:6284ce9a0476 92 * nameフィールドの文字列圧縮を解除して圧縮後のテキストポインタを返します。
nyatla 98:6284ce9a0476 93 */
nyatla 98:6284ce9a0476 94 static const char* getExtractNamePos(const char* i_packet_buf, const char* i_spos)
nyatla 37:fc4b4fd6a649 95 {
nyatla 103:853ddf4a1b81 96 NyLPC_TUInt8 limit = 0;
nyatla 98:6284ce9a0476 97 const char* s = i_spos;// question->buf + pos;//クエリの解析位置
nyatla 98:6284ce9a0476 98 for (;;){
nyatla 98:6284ce9a0476 99 switch (*(const NyLPC_TUInt8*)s){
nyatla 98:6284ce9a0476 100 case 0x00:
nyatla 98:6284ce9a0476 101 //queryが先に終了に到達するのはおかしい。
nyatla 98:6284ce9a0476 102 return NULL;
nyatla 98:6284ce9a0476 103 case 0xc0:
nyatla 98:6284ce9a0476 104 s = i_packet_buf + *((const NyLPC_TUInt8*)s + 1);//参照先にジャンプ
nyatla 103:853ddf4a1b81 105 if (i_spos <= s){
nyatla 98:6284ce9a0476 106 //後方参照ならエラー
nyatla 98:6284ce9a0476 107 return NULL;
nyatla 98:6284ce9a0476 108 }
nyatla 98:6284ce9a0476 109 limit++;
nyatla 98:6284ce9a0476 110 if (limit > 32){
nyatla 98:6284ce9a0476 111 return NULL;
nyatla 98:6284ce9a0476 112 }
nyatla 98:6284ce9a0476 113 continue;
nyatla 98:6284ce9a0476 114 default:
nyatla 98:6284ce9a0476 115 break;
nyatla 98:6284ce9a0476 116 }
nyatla 98:6284ce9a0476 117 break;
nyatla 98:6284ce9a0476 118 }
nyatla 98:6284ce9a0476 119 return s;
nyatla 98:6284ce9a0476 120 }
nyatla 98:6284ce9a0476 121
nyatla 98:6284ce9a0476 122 /**
nyatla 103:853ddf4a1b81 123 * 展開しない圧縮文字列の長さを返す
nyatla 103:853ddf4a1b81 124 */
nyatla 101:5022828ace54 125 static NyLPC_TInt16 sizeofCompressName(const char* i_str)
nyatla 37:fc4b4fd6a649 126 {
nyatla 98:6284ce9a0476 127 NyLPC_TInt16 l = 0;
nyatla 98:6284ce9a0476 128 NyLPC_TUInt8 c;
nyatla 98:6284ce9a0476 129 for (;;){
nyatla 98:6284ce9a0476 130 c = (NyLPC_TUInt8)*(i_str + l);
nyatla 98:6284ce9a0476 131 switch (c){
nyatla 98:6284ce9a0476 132 case 0xc0:
nyatla 98:6284ce9a0476 133 return l + 2;
nyatla 98:6284ce9a0476 134 case 0x00:
nyatla 98:6284ce9a0476 135 return l + 1;
nyatla 98:6284ce9a0476 136 }
nyatla 98:6284ce9a0476 137 l += c + 1;
nyatla 98:6284ce9a0476 138 }
nyatla 37:fc4b4fd6a649 139 }
nyatla 98:6284ce9a0476 140 /**
nyatla 103:853ddf4a1b81 141 * @return
nyatla 103:853ddf4a1b81 142 * 圧縮するとtrue i_nameは2文字に圧縮される。
nyatla 103:853ddf4a1b81 143 */
nyatla 98:6284ce9a0476 144 static NyLPC_TBool compressNameB(char* i_packet, NyLPC_TUInt16 i_spos, NyLPC_TUInt16 i_name_pos)
nyatla 37:fc4b4fd6a649 145 {
nyatla 98:6284ce9a0476 146 NyLPC_TUInt16 ret;
nyatla 98:6284ce9a0476 147 const char* p; //プロトコル文字列の解析開始位置
nyatla 98:6284ce9a0476 148 const char* s = i_packet + i_spos; //クエリの解析位置
nyatla 98:6284ce9a0476 149 const char* s2;
nyatla 98:6284ce9a0476 150
nyatla 98:6284ce9a0476 151 //Protocol
nyatla 98:6284ce9a0476 152 for (;;){
nyatla 98:6284ce9a0476 153 //0xc0参照の解決
nyatla 98:6284ce9a0476 154 s = getExtractNamePos(i_packet, s);
nyatla 98:6284ce9a0476 155 if (s == NULL){
nyatla 98:6284ce9a0476 156 //一致しない
nyatla 98:6284ce9a0476 157 return 0;
nyatla 98:6284ce9a0476 158 }
nyatla 98:6284ce9a0476 159 for (;;){
nyatla 98:6284ce9a0476 160 //検索位置のドメインを遡る
nyatla 103:853ddf4a1b81 161 if (*s == *(i_packet + i_name_pos)){
nyatla 98:6284ce9a0476 162 //先頭一致
nyatla 98:6284ce9a0476 163 p = i_packet + i_name_pos;
nyatla 98:6284ce9a0476 164 s2 = getExtractNamePos(i_packet, s);
nyatla 98:6284ce9a0476 165 ret = (NyLPC_TUInt16)(s2 - i_packet);
nyatla 98:6284ce9a0476 166 for (;;){
nyatla 98:6284ce9a0476 167 //一致判定
nyatla 98:6284ce9a0476 168 if (s2 == NULL){
nyatla 98:6284ce9a0476 169 break;
nyatla 98:6284ce9a0476 170 }
nyatla 98:6284ce9a0476 171
nyatla 98:6284ce9a0476 172 if (memcmp(p, s2, (*(NyLPC_TUInt8*)s2 + 1)) != 0){
nyatla 98:6284ce9a0476 173 //不一致
nyatla 98:6284ce9a0476 174 break;
nyatla 98:6284ce9a0476 175 }
nyatla 98:6284ce9a0476 176 //検出位置の移動
nyatla 98:6284ce9a0476 177 p += (*(NyLPC_TUInt8*)s2) + 1;
nyatla 98:6284ce9a0476 178 s2 += (*(NyLPC_TUInt8*)s2) + 1;
nyatla 98:6284ce9a0476 179 if (*p == 0 && *s2 == 0){
nyatla 98:6284ce9a0476 180 //charで扱ってるクライアントのコケ防止
nyatla 103:853ddf4a1b81 181 if (ret>0xff){
nyatla 98:6284ce9a0476 182 return 0;
nyatla 98:6284ce9a0476 183 }
nyatla 98:6284ce9a0476 184 *(i_packet + i_name_pos + 0) = 0xc0;
nyatla 98:6284ce9a0476 185 *(i_packet + i_name_pos + 1) = (NyLPC_TUInt8)ret;
nyatla 98:6284ce9a0476 186 return ret;
nyatla 98:6284ce9a0476 187 }
nyatla 98:6284ce9a0476 188 s2 = getExtractNamePos(i_packet, s2);
nyatla 37:fc4b4fd6a649 189 }
nyatla 98:6284ce9a0476 190 }
nyatla 98:6284ce9a0476 191 //一致しない->検索パターンの次のフラグメントを調べる
nyatla 98:6284ce9a0476 192 s += (*(NyLPC_TUInt8*)s) + 1;
nyatla 98:6284ce9a0476 193 break;
nyatla 98:6284ce9a0476 194 }
nyatla 37:fc4b4fd6a649 195 }
nyatla 98:6284ce9a0476 196 }
nyatla 98:6284ce9a0476 197 /**
nyatla 103:853ddf4a1b81 198 * mDNSパケットからi_nameを検索する。
nyatla 103:853ddf4a1b81 199 * i_targetはi_packetに含まれ、NULL終端されていること
nyatla 103:853ddf4a1b81 200 * @return 0 圧縮失敗/その他:圧縮後のパケットサイズ
nyatla 103:853ddf4a1b81 201 *
nyatla 103:853ddf4a1b81 202 */
nyatla 103:853ddf4a1b81 203 static NyLPC_TUInt16 compressNameA(char* i_packet, NyLPC_TUInt16 i_name_start, NyLPC_TUInt16 i_name_pos)
nyatla 98:6284ce9a0476 204 {
nyatla 98:6284ce9a0476 205 NyLPC_TUInt16 s = 12;
nyatla 98:6284ce9a0476 206 for (;;){
nyatla 98:6284ce9a0476 207 if (i_name_start <= s){
nyatla 98:6284ce9a0476 208 //圧縮対象文字列に到達
nyatla 98:6284ce9a0476 209 return 0;
nyatla 98:6284ce9a0476 210 }
nyatla 98:6284ce9a0476 211 //i_targetとAnswer文字列が等しいか確認
nyatla 98:6284ce9a0476 212 if (compressNameB(i_packet, s, i_name_pos)){
nyatla 98:6284ce9a0476 213 return i_name_pos + 2;
nyatla 98:6284ce9a0476 214 }
nyatla 98:6284ce9a0476 215 //
nyatla 103:853ddf4a1b81 216 s += sizeofCompressName(i_packet + s);
nyatla 103:853ddf4a1b81 217 s += 2 + 2 + 4 + 2;
nyatla 103:853ddf4a1b81 218 if (i_name_start <= s){
nyatla 103:853ddf4a1b81 219 //圧縮対象文字列に到達
nyatla 103:853ddf4a1b81 220 return 0;
nyatla 98:6284ce9a0476 221 }
nyatla 103:853ddf4a1b81 222 // //データは圧縮ポインタにしない方がいいらしい。
nyatla 103:853ddf4a1b81 223 // if (compressNameB(i_packet, s, i_name_pos)){
nyatla 103:853ddf4a1b81 224 // return i_name_pos + 2;
nyatla 103:853ddf4a1b81 225 // }
nyatla 103:853ddf4a1b81 226 s += NyLPC_ntohs(*((NyLPC_TUInt16*)(i_packet + s - 2)));
nyatla 98:6284ce9a0476 227 }
nyatla 98:6284ce9a0476 228 }
nyatla 98:6284ce9a0476 229 /**
nyatla 103:853ddf4a1b81 230 * @return
nyatla 103:853ddf4a1b81 231 * 新しいi_packetの長さ
nyatla 103:853ddf4a1b81 232 */
nyatla 98:6284ce9a0476 233 static NyLPC_TUInt16 compressName(char* i_packet, NyLPC_TUInt16 i_name_pos, NyLPC_TUInt16 i_name_len)
nyatla 98:6284ce9a0476 234 {
nyatla 98:6284ce9a0476 235 NyLPC_TUInt16 p;
nyatla 98:6284ce9a0476 236 NyLPC_TUInt16 s = i_name_pos;
nyatla 98:6284ce9a0476 237 for (;;){
nyatla 103:853ddf4a1b81 238 p = compressNameA(i_packet, i_name_pos, s);
nyatla 98:6284ce9a0476 239 //i_targetとAnswer文字列が等しいか確認
nyatla 98:6284ce9a0476 240 if (p != 0){
nyatla 98:6284ce9a0476 241 return p;
nyatla 98:6284ce9a0476 242 }
nyatla 98:6284ce9a0476 243 s += (NyLPC_TUInt16)*(i_packet + s) + 1;
nyatla 103:853ddf4a1b81 244 if (*(i_packet + s) == 0){
nyatla 98:6284ce9a0476 245 //圧縮対象文字列に到達
nyatla 98:6284ce9a0476 246 return (i_name_len + i_name_pos);
nyatla 98:6284ce9a0476 247 }
nyatla 98:6284ce9a0476 248 }
nyatla 37:fc4b4fd6a649 249 }
nyatla 37:fc4b4fd6a649 250
nyatla 37:fc4b4fd6a649 251
nyatla 37:fc4b4fd6a649 252
nyatla 37:fc4b4fd6a649 253
nyatla 37:fc4b4fd6a649 254
nyatla 37:fc4b4fd6a649 255 /**
nyatla 37:fc4b4fd6a649 256 * 受領可能なQuestionか確認する
nyatla 37:fc4b4fd6a649 257 * @return
nyatla 37:fc4b4fd6a649 258 * 受領可能なQuestionの数
nyatla 37:fc4b4fd6a649 259 *
nyatla 37:fc4b4fd6a649 260 */
nyatla 98:6284ce9a0476 261 static NyLPC_TUInt16 getNumberOfQuestion(const void* i_packet, NyLPC_TUInt16 i_len)
nyatla 37:fc4b4fd6a649 262 {
nyatla 98:6284ce9a0476 263 struct NyLPC_TDnsHeader* ptr = (struct NyLPC_TDnsHeader*)i_packet;
nyatla 37:fc4b4fd6a649 264 NyLPC_TUInt16 t;
nyatla 98:6284ce9a0476 265 if (i_len<sizeof(struct NyLPC_TDnsHeader)){
nyatla 37:fc4b4fd6a649 266 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 267 }
nyatla 37:fc4b4fd6a649 268 //questrionの確認
nyatla 37:fc4b4fd6a649 269 //QR==0 && op==0 && tc=0
nyatla 98:6284ce9a0476 270 t = NyLPC_ntohs(ptr->flag);
nyatla 98:6284ce9a0476 271 if (((t & NyLPC_TDnsHeader_FLAG_MASK_QR) != 0) &&
nyatla 98:6284ce9a0476 272 ((t & NyLPC_TDnsHeader_FLAG_MASK_OPCODE) != 0) &&
nyatla 98:6284ce9a0476 273 ((t & NyLPC_TDnsHeader_FLAG_MASK_TC) != 0))
nyatla 37:fc4b4fd6a649 274 {
nyatla 37:fc4b4fd6a649 275 //this is response
nyatla 37:fc4b4fd6a649 276 return 0;
nyatla 37:fc4b4fd6a649 277 }
nyatla 37:fc4b4fd6a649 278 return NyLPC_ntohs(ptr->qd);
nyatla 37:fc4b4fd6a649 279 }
nyatla 37:fc4b4fd6a649 280
nyatla 98:6284ce9a0476 281 /**
nyatla 98:6284ce9a0476 282 * [i_name].[i_protocol].localをquestionと比較します。i_nameは省略ができます。
nyatla 101:5022828ace54 283 * i_nameはincasesensitiveです。
nyatla 98:6284ce9a0476 284 * @return 等しい場合true
nyatla 98:6284ce9a0476 285 */
nyatla 98:6284ce9a0476 286 static NyLPC_TBool NyLPC_TDnsQuestion_isEqualName(const struct NyLPC_TDnsQuestion* question, const char* i_name, const char* i_protocol)
nyatla 37:fc4b4fd6a649 287 {
nyatla 98:6284ce9a0476 288 NyLPC_TUInt8 tmp;
nyatla 98:6284ce9a0476 289 const char* p; //プロトコル文字列の解析開始位置
nyatla 98:6284ce9a0476 290 const char* s = question->buf + (NyLPC_TUInt8)question->qname_pos; //クエリの解析位置
nyatla 98:6284ce9a0476 291
nyatla 98:6284ce9a0476 292 //Domain
nyatla 98:6284ce9a0476 293 if (i_name != NULL){
nyatla 98:6284ce9a0476 294 //0xc0参照の解決
nyatla 98:6284ce9a0476 295 s = getExtractNamePos(question->buf, s);
nyatla 98:6284ce9a0476 296 if (s == NULL){
nyatla 98:6284ce9a0476 297 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 298 }
nyatla 98:6284ce9a0476 299 tmp = (NyLPC_TUInt8)strlen(i_name);
nyatla 101:5022828ace54 300 if (tmp != *s || NyLPC_strnicmp(s + 1, i_name, tmp) != 0){
nyatla 98:6284ce9a0476 301 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 302 }
nyatla 98:6284ce9a0476 303 s += (*s) + 1;
nyatla 103:853ddf4a1b81 304 }
nyatla 103:853ddf4a1b81 305 else{
nyatla 98:6284ce9a0476 306 s = question->buf + (NyLPC_TUInt8)question->qname_pos;//クエリの解析位置
nyatla 98:6284ce9a0476 307 }
nyatla 98:6284ce9a0476 308 p = i_protocol;
nyatla 98:6284ce9a0476 309 //Protocol
nyatla 98:6284ce9a0476 310 for (;;){
nyatla 98:6284ce9a0476 311 //0xc0参照の解決
nyatla 98:6284ce9a0476 312 s = getExtractNamePos(question->buf, s);
nyatla 98:6284ce9a0476 313 if (s == NULL){
nyatla 98:6284ce9a0476 314 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 315 }
nyatla 98:6284ce9a0476 316 //SRVの末端到達
nyatla 98:6284ce9a0476 317 if (*p == 0){
nyatla 98:6284ce9a0476 318 if (question->buf + question->buf_len<s + 7 + 4){
nyatla 98:6284ce9a0476 319 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 320 }
nyatla 98:6284ce9a0476 321 return (memcmp("\5local\0", s, 7) == 0);
nyatla 98:6284ce9a0476 322 }
nyatla 98:6284ce9a0476 323 //有効サイズなら一致検出
nyatla 98:6284ce9a0476 324 if (question->buf + question->buf_len<s + 1 + (NyLPC_TUInt8)*s + 4){
nyatla 98:6284ce9a0476 325 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 326 }
nyatla 98:6284ce9a0476 327 if (memcmp(p, s + 1, (NyLPC_TUInt8)*s) != 0){
nyatla 98:6284ce9a0476 328 //不一致
nyatla 98:6284ce9a0476 329 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 330 }
nyatla 98:6284ce9a0476 331 //検出位置の移動
nyatla 98:6284ce9a0476 332 p += (*s) + 1;
nyatla 98:6284ce9a0476 333 s += (*s) + 1;
nyatla 98:6284ce9a0476 334 }
nyatla 98:6284ce9a0476 335 }
nyatla 98:6284ce9a0476 336
nyatla 98:6284ce9a0476 337
nyatla 98:6284ce9a0476 338 static NyLPC_TUInt16 NyLPC_TDnsQuestion_parse(const char* i_packet, NyLPC_TUInt16 i_packet_len, NyLPC_TInt16 i_parse_start, struct NyLPC_TDnsQuestion* o_val)
nyatla 98:6284ce9a0476 339 {
nyatla 37:fc4b4fd6a649 340 NyLPC_TUInt16 i;
nyatla 98:6284ce9a0476 341 //解析開始位置を計算
nyatla 98:6284ce9a0476 342 NyLPC_TUInt16 qlen = 0;
nyatla 98:6284ce9a0476 343 for (i = i_parse_start; i<i_packet_len - 4; i++){
nyatla 98:6284ce9a0476 344 switch ((NyLPC_TUInt8)(*(i_packet + i))){
nyatla 98:6284ce9a0476 345 case 0x00:
nyatla 98:6284ce9a0476 346 qlen++;
nyatla 98:6284ce9a0476 347 break;
nyatla 98:6284ce9a0476 348 case 0xc0:
nyatla 103:853ddf4a1b81 349 qlen += 2;
nyatla 98:6284ce9a0476 350 break;
nyatla 98:6284ce9a0476 351 default:
nyatla 98:6284ce9a0476 352 qlen++;
nyatla 98:6284ce9a0476 353 continue;
nyatla 37:fc4b4fd6a649 354 }
nyatla 98:6284ce9a0476 355 o_val->buf = i_packet;
nyatla 98:6284ce9a0476 356 o_val->buf_len = i_packet_len;
nyatla 98:6284ce9a0476 357 o_val->qname_pos = i_parse_start;
nyatla 103:853ddf4a1b81 358 o_val->qtype = NyLPC_ntohs(*(NyLPC_TUInt16*)(i_packet + i_parse_start + qlen));
nyatla 103:853ddf4a1b81 359 o_val->qclass = NyLPC_ntohs(*(NyLPC_TUInt16*)(i_packet + i_parse_start + qlen + sizeof(NyLPC_TUInt16)));
nyatla 98:6284ce9a0476 360 return qlen + 4;
nyatla 37:fc4b4fd6a649 361 }
nyatla 37:fc4b4fd6a649 362 return 0;
nyatla 37:fc4b4fd6a649 363 }
nyatla 37:fc4b4fd6a649 364
nyatla 37:fc4b4fd6a649 365 /**
nyatla 37:fc4b4fd6a649 366 * DNSレコードのPRTフィールドとDNSラベル文字列を比較する。
nyatla 37:fc4b4fd6a649 367 */
nyatla 103:853ddf4a1b81 368 static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchPtrIdx(const struct NyLPC_TDnsRecord* i_struct, const struct NyLPC_TDnsQuestion* question)
nyatla 37:fc4b4fd6a649 369 {
nyatla 37:fc4b4fd6a649 370 NyLPC_TInt16 i;
nyatla 103:853ddf4a1b81 371 for (i = 0; i<i_struct->num_of_srv; i++){
nyatla 103:853ddf4a1b81 372 if (NyLPC_TDnsQuestion_isEqualName(question, NULL, i_struct->srv[i].protocol)){
nyatla 37:fc4b4fd6a649 373 return i;
nyatla 37:fc4b4fd6a649 374 }
nyatla 37:fc4b4fd6a649 375 }
nyatla 37:fc4b4fd6a649 376 return -1;
nyatla 37:fc4b4fd6a649 377 }
nyatla 103:853ddf4a1b81 378 static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchSrvIdx(const struct NyLPC_TDnsRecord* i_struct, const struct NyLPC_TDnsQuestion* question)
nyatla 37:fc4b4fd6a649 379 {
nyatla 37:fc4b4fd6a649 380 NyLPC_TInt16 i;
nyatla 103:853ddf4a1b81 381 for (i = 0; i<i_struct->num_of_srv; i++){
nyatla 103:853ddf4a1b81 382 if (NyLPC_TDnsQuestion_isEqualName(question, i_struct->name, i_struct->srv[i].protocol)){
nyatla 37:fc4b4fd6a649 383 return i;
nyatla 37:fc4b4fd6a649 384 }
nyatla 37:fc4b4fd6a649 385 }
nyatla 37:fc4b4fd6a649 386 return -1;
nyatla 37:fc4b4fd6a649 387 }
nyatla 98:6284ce9a0476 388
nyatla 37:fc4b4fd6a649 389
nyatla 37:fc4b4fd6a649 390
nyatla 37:fc4b4fd6a649 391 /**
nyatla 37:fc4b4fd6a649 392 * '.'区切り文字列をDNS形式の[n]text[n]text\0へ変換する。
nyatla 37:fc4b4fd6a649 393 * @return
nyatla 37:fc4b4fd6a649 394 * 変換後のデータブロックの長さin byte
nyatla 37:fc4b4fd6a649 395 * 終端の\0の長さを含みます。
nyatla 37:fc4b4fd6a649 396 */
nyatla 103:853ddf4a1b81 397 static NyLPC_TInt16 str2label(NyLPC_TChar* buf, const NyLPC_TChar* name)
nyatla 37:fc4b4fd6a649 398 {
nyatla 37:fc4b4fd6a649 399 //proto文字列の変換
nyatla 37:fc4b4fd6a649 400 NyLPC_TChar* lp;
nyatla 103:853ddf4a1b81 401 const NyLPC_TChar* n = name;
nyatla 103:853ddf4a1b81 402 NyLPC_TChar* b = buf;
nyatla 103:853ddf4a1b81 403 while (*n != '\0'){
nyatla 103:853ddf4a1b81 404 lp = b;
nyatla 37:fc4b4fd6a649 405 b++;
nyatla 103:853ddf4a1b81 406 for (; strchr(".\0", *n) == NULL;){
nyatla 103:853ddf4a1b81 407 *b = *n;
nyatla 37:fc4b4fd6a649 408 b++;
nyatla 37:fc4b4fd6a649 409 n++;
nyatla 37:fc4b4fd6a649 410 }
nyatla 103:853ddf4a1b81 411 *lp = (char)(b - lp - 1);
nyatla 103:853ddf4a1b81 412 if (*n != '\0'){
nyatla 37:fc4b4fd6a649 413 n++;
nyatla 37:fc4b4fd6a649 414 }
nyatla 37:fc4b4fd6a649 415 }
nyatla 103:853ddf4a1b81 416 *b = '\0';
nyatla 37:fc4b4fd6a649 417 b++;
nyatla 103:853ddf4a1b81 418 return (NyLPC_TInt16)((int)b - (int)buf);
nyatla 37:fc4b4fd6a649 419 }
nyatla 37:fc4b4fd6a649 420 /**
nyatla 102:41a5e92e0a8e 421 * query文字列をパケットに追記します。
nyatla 102:41a5e92e0a8e 422 * @return 出力したバイト数
nyatla 102:41a5e92e0a8e 423 */
nyatla 103:853ddf4a1b81 424 static NyLPC_TInt16 query2label(char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen, const struct NyLPC_TDnsQuestion* i_query)
nyatla 37:fc4b4fd6a649 425 {
nyatla 102:41a5e92e0a8e 426 const char* n;
nyatla 103:853ddf4a1b81 427 NyLPC_TInt16 s = i_query->qname_pos;
nyatla 103:853ddf4a1b81 428 NyLPC_TInt16 l = 0;//出力した文字数
nyatla 103:853ddf4a1b81 429 for (;;){
nyatla 103:853ddf4a1b81 430 n = getExtractNamePos(i_query->buf, i_query->buf + s);
nyatla 103:853ddf4a1b81 431 if (n == NULL){
nyatla 103:853ddf4a1b81 432 *(i_packet + i_spos + l) = 0;
nyatla 103:853ddf4a1b81 433 l++;
nyatla 102:41a5e92e0a8e 434 break;
nyatla 103:853ddf4a1b81 435 }
nyatla 103:853ddf4a1b81 436 else{
nyatla 103:853ddf4a1b81 437 memcpy(i_packet + i_spos + l, n, ((NyLPC_TUInt8)*n) + 1);
nyatla 103:853ddf4a1b81 438 l += ((NyLPC_TUInt8)*n) + 1;
nyatla 103:853ddf4a1b81 439 s = (NyLPC_TInt16)((int)n - (int)i_query->buf + ((NyLPC_TUInt8)*n) + 1);
nyatla 103:853ddf4a1b81 440 if (obuflen<i_spos + l + 1){
nyatla 102:41a5e92e0a8e 441 return 0;
nyatla 102:41a5e92e0a8e 442 }
nyatla 102:41a5e92e0a8e 443 }
nyatla 37:fc4b4fd6a649 444 }
nyatla 103:853ddf4a1b81 445 return l;
nyatla 102:41a5e92e0a8e 446 }
nyatla 102:41a5e92e0a8e 447
nyatla 37:fc4b4fd6a649 448
nyatla 103:853ddf4a1b81 449 static NyLPC_TInt16 writeSrvResourceHeader(char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 buflen, const struct NyLPC_TDnsRecord* i_recode, int i_sid, NyLPC_TUInt16 i_type, NyLPC_TUInt16 i_class)
nyatla 37:fc4b4fd6a649 450 {
nyatla 98:6284ce9a0476 451 NyLPC_TInt16 s;
nyatla 103:853ddf4a1b81 452 NyLPC_TInt16 l = (NyLPC_TInt16)(1 + strlen(i_recode->name) + 1 + strlen(i_recode->srv[i_sid].protocol) + 1 + 5 + 1);
nyatla 103:853ddf4a1b81 453 if (buflen<i_spos + l + 2 + 2 + 4){
nyatla 37:fc4b4fd6a649 454 return 0;
nyatla 37:fc4b4fd6a649 455 }
nyatla 103:853ddf4a1b81 456 s = str2label(i_packet + i_spos, i_recode->name) - 1;
nyatla 103:853ddf4a1b81 457 s += str2label(i_packet + i_spos + s, i_recode->srv[i_sid].protocol) - 1;
nyatla 103:853ddf4a1b81 458 s += str2label(i_packet + i_spos + s, "local");
nyatla 103:853ddf4a1b81 459 l = compressName(i_packet, i_spos, s);//圧縮
nyatla 103:853ddf4a1b81 460 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(i_type);
nyatla 103:853ddf4a1b81 461 (*(NyLPC_TUInt16*)(i_packet + l + 2)) = NyLPC_HTONS(i_class);
nyatla 103:853ddf4a1b81 462 (*(NyLPC_TUInt32*)(i_packet + l + 4)) = NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 103:853ddf4a1b81 463 return l + 2 + 2 + 4;
nyatla 37:fc4b4fd6a649 464 }
nyatla 37:fc4b4fd6a649 465
nyatla 98:6284ce9a0476 466 /**
nyatla 103:853ddf4a1b81 467 * パケットヘッダを書き込みます。
nyatla 103:853ddf4a1b81 468 * @return パケットサイズ
nyatla 103:853ddf4a1b81 469 */
nyatla 103:853ddf4a1b81 470 static NyLPC_TUInt16 setResponseHeader(char* i_packet, const struct NyLPC_TDnsHeader* i_in_dns_header, NyLPC_TUInt16 i_an_count, NyLPC_TUInt16 i_ns_count, NyLPC_TUInt16 i_ar_count)
nyatla 37:fc4b4fd6a649 471 {
nyatla 103:853ddf4a1b81 472 struct NyLPC_TDnsHeader* p = (struct NyLPC_TDnsHeader*)i_packet;
nyatla 103:853ddf4a1b81 473 if (i_in_dns_header != NULL){
nyatla 103:853ddf4a1b81 474 memcpy(p, i_in_dns_header, sizeof(struct NyLPC_TDnsHeader));
nyatla 103:853ddf4a1b81 475 p->flag = p->flag | NyLPC_HTONS(NyLPC_TDnsHeader_FLAG_MASK_QR | NyLPC_TDnsHeader_FLAG_MASK_AA);
nyatla 103:853ddf4a1b81 476 p->flag = p->flag & NyLPC_HTONS(~(NyLPC_TDnsHeader_FLAG_MASK_RECODE | NyLPC_TDnsHeader_FLAG_MASK_TC | NyLPC_TDnsHeader_FLAG_MASK_RA));
nyatla 37:fc4b4fd6a649 477 }
nyatla 103:853ddf4a1b81 478 else{
nyatla 103:853ddf4a1b81 479 p->flag = 0;
nyatla 103:853ddf4a1b81 480 p->id = 0;
nyatla 103:853ddf4a1b81 481 }
nyatla 103:853ddf4a1b81 482 p->qd = 0;
nyatla 103:853ddf4a1b81 483 p->an = NyLPC_HTONS(i_an_count);
nyatla 103:853ddf4a1b81 484 p->ns = NyLPC_HTONS(i_ns_count);
nyatla 103:853ddf4a1b81 485 p->ar = NyLPC_HTONS(i_ar_count);
nyatla 37:fc4b4fd6a649 486 return sizeof(struct NyLPC_TDnsHeader);
nyatla 37:fc4b4fd6a649 487 }
nyatla 101:5022828ace54 488 /**
nyatla 103:853ddf4a1b81 489 * ドメイン名からAレコードレスポンスを書きだす。
nyatla 103:853ddf4a1b81 490 */
nyatla 103:853ddf4a1b81 491 static NyLPC_TInt16 writeARecord(char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen, const NyLPC_TChar* i_name, const struct NyLPC_TIPv4Addr* ip)
nyatla 37:fc4b4fd6a649 492 {
nyatla 98:6284ce9a0476 493 NyLPC_TInt16 s;
nyatla 37:fc4b4fd6a649 494 //AnswerはAレコードのみ
nyatla 103:853ddf4a1b81 495 NyLPC_TInt16 l = 1 + (NyLPC_TInt16)strlen(i_name) + 1 + 5 + 1;
nyatla 103:853ddf4a1b81 496 if (obuflen<i_spos + l + 4 + 4){
nyatla 101:5022828ace54 497 return 0;
nyatla 101:5022828ace54 498 }
nyatla 103:853ddf4a1b81 499 s = str2label(i_packet + i_spos, i_name) - 1;
nyatla 103:853ddf4a1b81 500 s += str2label(i_packet + i_spos + s, "local");
nyatla 101:5022828ace54 501 //レコード圧縮
nyatla 103:853ddf4a1b81 502 l = compressName(i_packet, i_spos, s);
nyatla 103:853ddf4a1b81 503 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_A);
nyatla 103:853ddf4a1b81 504 (*(NyLPC_TUInt16*)(i_packet + l + 2)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN | NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 103:853ddf4a1b81 505 (*(NyLPC_TUInt32*)(i_packet + l + 4)) = NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 103:853ddf4a1b81 506 l += 2 + 2 + 4;
nyatla 37:fc4b4fd6a649 507 //A record header
nyatla 103:853ddf4a1b81 508 if (obuflen<l + 6){
nyatla 37:fc4b4fd6a649 509 return 0;
nyatla 37:fc4b4fd6a649 510 }
nyatla 37:fc4b4fd6a649 511 //Aレコードを書く
nyatla 37:fc4b4fd6a649 512 //IPADDR
nyatla 103:853ddf4a1b81 513 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(4);
nyatla 103:853ddf4a1b81 514 (*(NyLPC_TUInt32*)(i_packet + l + 2)) = ip->v;
nyatla 103:853ddf4a1b81 515 return l + 6;
nyatla 37:fc4b4fd6a649 516 }
nyatla 102:41a5e92e0a8e 517
nyatla 101:5022828ace54 518 /**
nyatla 103:853ddf4a1b81 519 * AレコードクエリからAレコードレスポンスを書きだす。
nyatla 103:853ddf4a1b81 520 */
nyatla 103:853ddf4a1b81 521 static NyLPC_TInt16 writeARecordByQuery(char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen, const struct NyLPC_TDnsQuestion* i_query, const struct NyLPC_TIPv4Addr* ip)
nyatla 101:5022828ace54 522 {
nyatla 101:5022828ace54 523 NyLPC_TInt16 s;
nyatla 101:5022828ace54 524 //AnswerはAレコードのみ
nyatla 101:5022828ace54 525 NyLPC_TInt16 l;
nyatla 103:853ddf4a1b81 526 s = query2label(i_packet, i_spos, obuflen, i_query);
nyatla 103:853ddf4a1b81 527 if (s == 0){
nyatla 102:41a5e92e0a8e 528 return 0;
nyatla 101:5022828ace54 529 }
nyatla 102:41a5e92e0a8e 530
nyatla 101:5022828ace54 531 //レコード圧縮
nyatla 103:853ddf4a1b81 532 l = compressName(i_packet, i_spos, s);
nyatla 103:853ddf4a1b81 533 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_A);
nyatla 103:853ddf4a1b81 534 (*(NyLPC_TUInt16*)(i_packet + l + 2)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN | NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 103:853ddf4a1b81 535 (*(NyLPC_TUInt32*)(i_packet + l + 4)) = NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 103:853ddf4a1b81 536 l += 2 + 2 + 4;
nyatla 101:5022828ace54 537 //A record header
nyatla 103:853ddf4a1b81 538 if (obuflen<l + 6){
nyatla 101:5022828ace54 539 return 0;
nyatla 101:5022828ace54 540 }
nyatla 101:5022828ace54 541 //Aレコードを書く
nyatla 101:5022828ace54 542 //IPADDR
nyatla 103:853ddf4a1b81 543 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(4);
nyatla 103:853ddf4a1b81 544 (*(NyLPC_TUInt32*)(i_packet + l + 2)) = ip->v;
nyatla 103:853ddf4a1b81 545 return l + 6;
nyatla 101:5022828ace54 546 }
nyatla 98:6284ce9a0476 547
nyatla 102:41a5e92e0a8e 548 /**
nyatla 103:853ddf4a1b81 549 * AレコードクエリからAレコードレスポンスを書きだす。
nyatla 103:853ddf4a1b81 550 */
nyatla 103:853ddf4a1b81 551 static NyLPC_TInt16 writeAAAARecordByQuery(char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen, const struct NyLPC_TDnsQuestion* i_query, const struct NyLPC_TIPv4Addr* ip)
nyatla 102:41a5e92e0a8e 552 {
nyatla 102:41a5e92e0a8e 553 NyLPC_TInt16 s;
nyatla 102:41a5e92e0a8e 554 //AnswerはAレコードのみ
nyatla 102:41a5e92e0a8e 555 NyLPC_TInt16 l;
nyatla 103:853ddf4a1b81 556 s = query2label(i_packet, i_spos, obuflen, i_query);
nyatla 103:853ddf4a1b81 557 if (s == 0){
nyatla 102:41a5e92e0a8e 558 return 0;
nyatla 102:41a5e92e0a8e 559 }
nyatla 102:41a5e92e0a8e 560
nyatla 102:41a5e92e0a8e 561 //レコード圧縮
nyatla 103:853ddf4a1b81 562 l = compressName(i_packet, i_spos, s);
nyatla 103:853ddf4a1b81 563 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_AAAA);
nyatla 103:853ddf4a1b81 564 (*(NyLPC_TUInt16*)(i_packet + l + 2)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN | NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 103:853ddf4a1b81 565 (*(NyLPC_TUInt32*)(i_packet + l + 4)) = NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 103:853ddf4a1b81 566 l += 2 + 2 + 4;
nyatla 102:41a5e92e0a8e 567 //A record header
nyatla 103:853ddf4a1b81 568 if (obuflen<l + 2 + 16){
nyatla 103:853ddf4a1b81 569 return 0;
nyatla 103:853ddf4a1b81 570 }
nyatla 103:853ddf4a1b81 571 //AAAAレコードを書く
nyatla 103:853ddf4a1b81 572 //IPADDR
nyatla 103:853ddf4a1b81 573 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(16);
nyatla 103:853ddf4a1b81 574 memset(i_packet + l + 2, 0, 10);
nyatla 103:853ddf4a1b81 575 (*(NyLPC_TUInt16*)(i_packet + l + 2 + 10)) = 0xffff;
nyatla 103:853ddf4a1b81 576 (*(NyLPC_TUInt32*)(i_packet + l + 2 + 12)) = ip->v;
nyatla 103:853ddf4a1b81 577 return l + 2 + 16;
nyatla 103:853ddf4a1b81 578 }
nyatla 103:853ddf4a1b81 579 /**
nyatla 103:853ddf4a1b81 580 * AレコードクエリからAレコードレスポンスを書きだす。
nyatla 103:853ddf4a1b81 581 */
nyatla 103:853ddf4a1b81 582 static NyLPC_TInt16 writeAAAARecord(char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen, const NyLPC_TChar* i_name, const struct NyLPC_TIPv4Addr* ip)
nyatla 103:853ddf4a1b81 583 {
nyatla 103:853ddf4a1b81 584 NyLPC_TInt16 s;
nyatla 103:853ddf4a1b81 585 //AnswerはAレコードのみ
nyatla 103:853ddf4a1b81 586 NyLPC_TInt16 l = 1 + (NyLPC_TInt16)strlen(i_name) + 1 + 5 + 1;
nyatla 103:853ddf4a1b81 587 if (obuflen<i_spos + l + 4 + 4){
nyatla 103:853ddf4a1b81 588 return 0;
nyatla 103:853ddf4a1b81 589 }
nyatla 103:853ddf4a1b81 590 s = str2label(i_packet + i_spos, i_name) - 1;
nyatla 103:853ddf4a1b81 591 s += str2label(i_packet + i_spos + s, "local");
nyatla 103:853ddf4a1b81 592
nyatla 103:853ddf4a1b81 593 //レコード圧縮
nyatla 103:853ddf4a1b81 594 l = compressName(i_packet, i_spos, s);
nyatla 103:853ddf4a1b81 595 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_AAAA);
nyatla 103:853ddf4a1b81 596 (*(NyLPC_TUInt16*)(i_packet + l + 2)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN | NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 103:853ddf4a1b81 597 (*(NyLPC_TUInt32*)(i_packet + l + 4)) = NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 103:853ddf4a1b81 598 l += 2 + 2 + 4;
nyatla 103:853ddf4a1b81 599 //A record header
nyatla 103:853ddf4a1b81 600 if (obuflen<l + 2 + 16){
nyatla 102:41a5e92e0a8e 601 return 0;
nyatla 102:41a5e92e0a8e 602 }
nyatla 102:41a5e92e0a8e 603 //AAAAレコードを書く
nyatla 102:41a5e92e0a8e 604 //IPADDR
nyatla 103:853ddf4a1b81 605 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(16);
nyatla 103:853ddf4a1b81 606 memset(i_packet + l + 2, 0, 10);
nyatla 103:853ddf4a1b81 607 (*(NyLPC_TUInt16*)(i_packet + l + 2 + 10)) = 0xffff;
nyatla 103:853ddf4a1b81 608 (*(NyLPC_TUInt32*)(i_packet + l + 2 + 12)) = ip->v;
nyatla 103:853ddf4a1b81 609 return l + 2 + 16;
nyatla 102:41a5e92e0a8e 610 }
nyatla 102:41a5e92e0a8e 611 /**
nyatla 103:853ddf4a1b81 612 * NSECレコードレスポンスを書きだす。
nyatla 103:853ddf4a1b81 613 * IPv6わからんし。
nyatla 103:853ddf4a1b81 614 */
nyatla 103:853ddf4a1b81 615 static NyLPC_TInt16 writeNSECRecord(char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen, const NyLPC_TChar* i_name)
nyatla 102:41a5e92e0a8e 616 {
nyatla 102:41a5e92e0a8e 617 NyLPC_TInt16 s;
nyatla 102:41a5e92e0a8e 618 //AnswerはAレコードのみ
nyatla 103:853ddf4a1b81 619 NyLPC_TInt16 l = 1 + (NyLPC_TInt16)strlen(i_name) + 1 + 5 + 1;
nyatla 103:853ddf4a1b81 620 if (obuflen<i_spos + l + 4 + 4){
nyatla 102:41a5e92e0a8e 621 return 0;
nyatla 103:853ddf4a1b81 622 }
nyatla 103:853ddf4a1b81 623 s = str2label(i_packet + i_spos, i_name) - 1;
nyatla 103:853ddf4a1b81 624 s += str2label(i_packet + i_spos + s, "local");
nyatla 102:41a5e92e0a8e 625
nyatla 102:41a5e92e0a8e 626 //レコード圧縮
nyatla 103:853ddf4a1b81 627 l = i_spos + s;//compressName(i_packet,i_spos,s);
nyatla 103:853ddf4a1b81 628 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_NSEC);
nyatla 103:853ddf4a1b81 629 (*(NyLPC_TUInt16*)(i_packet + l + 2)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN | NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 103:853ddf4a1b81 630 (*(NyLPC_TUInt32*)(i_packet + l + 4)) = NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 103:853ddf4a1b81 631 l += 2 + 2 + 4;
nyatla 102:41a5e92e0a8e 632 //A record header
nyatla 103:853ddf4a1b81 633 if (obuflen<l + 2 + 2 + 6){
nyatla 102:41a5e92e0a8e 634 return 0;
nyatla 102:41a5e92e0a8e 635 }
nyatla 102:41a5e92e0a8e 636 //NSECレコードを書く
nyatla 103:853ddf4a1b81 637 *((NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(2 + 6);
nyatla 103:853ddf4a1b81 638 l += 2;
nyatla 103:853ddf4a1b81 639 *(i_packet + l) = 0xc0;
nyatla 103:853ddf4a1b81 640 *(i_packet + l + 1) = (NyLPC_TUInt8)i_spos;
nyatla 103:853ddf4a1b81 641 l += 2;
nyatla 103:853ddf4a1b81 642 memcpy(i_packet + l, "\x00\x04\x00\x00\x00\x08", 6);
nyatla 103:853ddf4a1b81 643 return l + 6;
nyatla 102:41a5e92e0a8e 644 }
nyatla 102:41a5e92e0a8e 645 /**
nyatla 103:853ddf4a1b81 646 * NSECレコードレスポンスを書きだす。
nyatla 103:853ddf4a1b81 647 * IPv6わからんし。
nyatla 103:853ddf4a1b81 648 */
nyatla 103:853ddf4a1b81 649 static NyLPC_TInt16 writeNSECRecordByQuery(char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen, const struct NyLPC_TDnsQuestion* i_query)
nyatla 102:41a5e92e0a8e 650 {
nyatla 102:41a5e92e0a8e 651 NyLPC_TInt16 s;
nyatla 102:41a5e92e0a8e 652 //AnswerはAレコードのみ
nyatla 102:41a5e92e0a8e 653 NyLPC_TInt16 l;
nyatla 103:853ddf4a1b81 654 s = query2label(i_packet, i_spos, obuflen, i_query);
nyatla 103:853ddf4a1b81 655 if (s == 0){
nyatla 102:41a5e92e0a8e 656 return 0;
nyatla 102:41a5e92e0a8e 657 }
nyatla 102:41a5e92e0a8e 658
nyatla 102:41a5e92e0a8e 659 //レコード圧縮
nyatla 103:853ddf4a1b81 660 l = i_spos + s;
nyatla 103:853ddf4a1b81 661 // l=compressName(i_packet,i_spos,s);
nyatla 103:853ddf4a1b81 662 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_NSEC);
nyatla 103:853ddf4a1b81 663 (*(NyLPC_TUInt16*)(i_packet + l + 2)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN | NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 103:853ddf4a1b81 664 (*(NyLPC_TUInt32*)(i_packet + l + 4)) = NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 103:853ddf4a1b81 665 l += 2 + 2 + 4;
nyatla 102:41a5e92e0a8e 666 //A record header
nyatla 103:853ddf4a1b81 667 if (obuflen<l + 2 + 2 + 6){
nyatla 102:41a5e92e0a8e 668 return 0;
nyatla 102:41a5e92e0a8e 669 }
nyatla 102:41a5e92e0a8e 670 //NSECレコードを書く
nyatla 103:853ddf4a1b81 671 *((NyLPC_TUInt16*)(i_packet + l)) = NyLPC_HTONS(2 + 6);
nyatla 103:853ddf4a1b81 672 l += 2;
nyatla 103:853ddf4a1b81 673 *(i_packet + l) = 0xc0;
nyatla 103:853ddf4a1b81 674 *(i_packet + l + 1) = (NyLPC_TUInt8)i_spos;
nyatla 103:853ddf4a1b81 675 l += 2;
nyatla 103:853ddf4a1b81 676 memcpy(i_packet + l, "\x00\x04\x00\x00\x00\x08", 6);
nyatla 103:853ddf4a1b81 677 return l + 6;
nyatla 102:41a5e92e0a8e 678 }
nyatla 103:853ddf4a1b81 679 static NyLPC_TInt16 writeSdPtrRecord(const struct NyLPC_TDnsQuestion* i_question, const struct NyLPC_TMDnsServiceRecord* i_srvlec, char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen)
nyatla 37:fc4b4fd6a649 680 {
nyatla 103:853ddf4a1b81 681 NyLPC_TInt16 l, s;
nyatla 37:fc4b4fd6a649 682 //Header
nyatla 103:853ddf4a1b81 683 // s=(NyLPC_TInt16)*(i_question->buf+i_question->qname_pos);
nyatla 37:fc4b4fd6a649 684 //Headerの長さチェック
nyatla 103:853ddf4a1b81 685 if (obuflen<i_spos + 30 + 2 + 2 + 4){
nyatla 37:fc4b4fd6a649 686 return 0;
nyatla 37:fc4b4fd6a649 687 }
nyatla 37:fc4b4fd6a649 688 //Header書込み
nyatla 103:853ddf4a1b81 689 memcpy(i_packet + i_spos, "\x09_services\x07_dns-sd\x04_udp\x05local\x00", 30);
nyatla 103:853ddf4a1b81 690 s = compressName(i_packet, i_spos, 30);
nyatla 103:853ddf4a1b81 691 (*(NyLPC_TUInt16*)(i_packet + s)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
nyatla 103:853ddf4a1b81 692 (*(NyLPC_TUInt16*)(i_packet + s + 2)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
nyatla 103:853ddf4a1b81 693 (*(NyLPC_TUInt32*)(i_packet + s + 4)) = NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 103:853ddf4a1b81 694 l = s + 2 + 2 + 4;
nyatla 37:fc4b4fd6a649 695
nyatla 37:fc4b4fd6a649 696 //Resourceの書込み
nyatla 103:853ddf4a1b81 697 s = (NyLPC_TInt16)(1 + strlen(i_srvlec->protocol) + 1 + 5 + 1);//逆引き文字列の長さ(デリミタ×3+1)
nyatla 103:853ddf4a1b81 698 if (obuflen<s + l + 2){
nyatla 37:fc4b4fd6a649 699 return 0;
nyatla 37:fc4b4fd6a649 700 }
nyatla 103:853ddf4a1b81 701 (*(NyLPC_TUInt16*)(i_packet + l)) = NyLPC_ntohs(s);
nyatla 103:853ddf4a1b81 702 l += 2;
nyatla 103:853ddf4a1b81 703 s = str2label(i_packet + l, i_srvlec->protocol) - 1;
nyatla 103:853ddf4a1b81 704 s += str2label(i_packet + l + s, "local");
nyatla 103:853ddf4a1b81 705 s = compressName(i_packet, l, s);//圧縮
nyatla 98:6284ce9a0476 706 return s;
nyatla 37:fc4b4fd6a649 707 }
nyatla 103:853ddf4a1b81 708 static NyLPC_TInt16 writePtrRecord(const struct NyLPC_TDnsRecord* i_recode, NyLPC_TInt16 i_sid, char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen)
nyatla 37:fc4b4fd6a649 709 {
nyatla 103:853ddf4a1b81 710 NyLPC_TInt16 l, s;
nyatla 37:fc4b4fd6a649 711 NyLPC_TUInt16* rlen;
nyatla 37:fc4b4fd6a649 712 //Header:開始文字数(1)+プレフィクス(n)+終端(1)+local(5)+1
nyatla 103:853ddf4a1b81 713 s = (NyLPC_TInt16)(1 + strlen(i_recode->srv[i_sid].protocol) + 1 + 5 + 1);
nyatla 37:fc4b4fd6a649 714 //Headerの長さチェック
nyatla 103:853ddf4a1b81 715 if (obuflen<i_spos + s + 2 + 2 + 4){
nyatla 37:fc4b4fd6a649 716 return 0;
nyatla 37:fc4b4fd6a649 717 }
nyatla 37:fc4b4fd6a649 718 //Header書込み
nyatla 103:853ddf4a1b81 719 s = str2label(i_packet + i_spos, i_recode->srv[i_sid].protocol) - 1;
nyatla 103:853ddf4a1b81 720 s += str2label(i_packet + i_spos + s, "local");
nyatla 103:853ddf4a1b81 721 s = compressName(i_packet, i_spos, s);
nyatla 103:853ddf4a1b81 722 (*(NyLPC_TUInt16*)(i_packet + s)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
nyatla 103:853ddf4a1b81 723 (*(NyLPC_TUInt16*)(i_packet + s + 2)) = NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
nyatla 103:853ddf4a1b81 724 (*(NyLPC_TUInt32*)(i_packet + s + 4)) = NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 103:853ddf4a1b81 725 l = s + 2 + 2 + 4;
nyatla 37:fc4b4fd6a649 726
nyatla 37:fc4b4fd6a649 727 //Resourceの書込み
nyatla 103:853ddf4a1b81 728 s = (NyLPC_TInt16)(1 + strlen(i_recode->name) + 1 + strlen(i_recode->srv[i_sid].protocol) + 1 + 5 + 1);//逆引き文字列の長さ(デリミタ×3+1)
nyatla 103:853ddf4a1b81 729 if (obuflen<s + l + 2){
nyatla 37:fc4b4fd6a649 730 return 0;
nyatla 37:fc4b4fd6a649 731 }
nyatla 103:853ddf4a1b81 732 rlen = (NyLPC_TUInt16*)(i_packet + l);
nyatla 103:853ddf4a1b81 733 l += 2;
nyatla 103:853ddf4a1b81 734 s = str2label(i_packet + l, i_recode->name) - 1;
nyatla 103:853ddf4a1b81 735 s += str2label(i_packet + l + s, i_recode->srv[i_sid].protocol) - 1;
nyatla 103:853ddf4a1b81 736 s += str2label(i_packet + l + s, "local");
nyatla 103:853ddf4a1b81 737 s = compressName(i_packet, l, s);//圧縮
nyatla 103:853ddf4a1b81 738 (*rlen) = NyLPC_ntohs(s - l);
nyatla 98:6284ce9a0476 739 return s;
nyatla 37:fc4b4fd6a649 740 }
nyatla 37:fc4b4fd6a649 741
nyatla 103:853ddf4a1b81 742 static NyLPC_TInt16 writeSRVRecord(NyLPC_TcMDnsServer_t* i_inst, NyLPC_TInt16 i_sid, char* i_packet, NyLPC_TUInt16 i_spos, NyLPC_TInt16 obuflen)
nyatla 37:fc4b4fd6a649 743 {
nyatla 103:853ddf4a1b81 744 NyLPC_TInt16 l, s;
nyatla 37:fc4b4fd6a649 745 NyLPC_TUInt16* rlen;
nyatla 37:fc4b4fd6a649 746
nyatla 37:fc4b4fd6a649 747 //SRV Record
nyatla 103:853ddf4a1b81 748 s = writeSrvResourceHeader(i_packet, i_spos, obuflen, i_inst->_ref_record, i_sid, NyLPC_TDnsQuestion_QTYPR_SRV, NyLPC_TDnsQuestion_QCLASS_IN | NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 103:853ddf4a1b81 749 if (s == 0){
nyatla 37:fc4b4fd6a649 750 return 0;
nyatla 37:fc4b4fd6a649 751 }
nyatla 37:fc4b4fd6a649 752
nyatla 103:853ddf4a1b81 753 l = (NyLPC_TInt16)(1 + strlen(i_inst->_ref_record->a) + 1 + 5 + 1);//逆引き文字列の長さ(デリミタ×3+1)
nyatla 103:853ddf4a1b81 754 if (obuflen<s + 8 + l){
nyatla 37:fc4b4fd6a649 755 return 0;
nyatla 37:fc4b4fd6a649 756 }
nyatla 37:fc4b4fd6a649 757 //IPADDR
nyatla 103:853ddf4a1b81 758 rlen = (NyLPC_TUInt16*)(i_packet + s);
nyatla 103:853ddf4a1b81 759 (*(NyLPC_TUInt16*)(i_packet + s + 2)) = NyLPC_HTONS(0);//Priority
nyatla 103:853ddf4a1b81 760 (*(NyLPC_TUInt16*)(i_packet + s + 4)) = NyLPC_HTONS(0);//Weight
nyatla 103:853ddf4a1b81 761 (*(NyLPC_TUInt16*)(i_packet + s + 6)) = NyLPC_HTONS(i_inst->_ref_record->srv[i_sid].port);//PORT
nyatla 103:853ddf4a1b81 762 l = 4 * 2 + s;
nyatla 103:853ddf4a1b81 763 s = str2label(i_packet + l, i_inst->_ref_record->a) - 1;
nyatla 103:853ddf4a1b81 764 s += str2label(i_packet + l + s, "local");
nyatla 103:853ddf4a1b81 765 s = compressName(i_packet, l, s);//圧縮
nyatla 103:853ddf4a1b81 766 (*rlen) = NyLPC_HTONS(2 + 2 + 2 + (s - l));
nyatla 98:6284ce9a0476 767 return s;
nyatla 37:fc4b4fd6a649 768 }
nyatla 103:853ddf4a1b81 769 static NyLPC_TInt16 writeTXTRecord(NyLPC_TcMDnsServer_t* i_inst, NyLPC_TInt16 i_sid, char* i_packet, NyLPC_TInt16 i_spos, NyLPC_TInt16 obuflen)
nyatla 37:fc4b4fd6a649 770 {
nyatla 37:fc4b4fd6a649 771 NyLPC_TInt16 ret;
nyatla 37:fc4b4fd6a649 772 NyLPC_TInt16 l;
nyatla 37:fc4b4fd6a649 773 //Answer
nyatla 103:853ddf4a1b81 774 ret = writeSrvResourceHeader(i_packet, i_spos, obuflen, i_inst->_ref_record, i_sid, NyLPC_TDnsQuestion_QTYPR_TXT, NyLPC_TDnsQuestion_QCLASS_IN | NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 103:853ddf4a1b81 775 if (ret == 0){
nyatla 37:fc4b4fd6a649 776 return 0;
nyatla 37:fc4b4fd6a649 777 }
nyatla 37:fc4b4fd6a649 778 //name.proto.localを返す。
nyatla 103:853ddf4a1b81 779 if (obuflen<ret + 2){
nyatla 37:fc4b4fd6a649 780 return 0;
nyatla 37:fc4b4fd6a649 781 }
nyatla 103:853ddf4a1b81 782 (*(NyLPC_TUInt16*)(i_packet + ret)) = NyLPC_ntohs(0);
nyatla 37:fc4b4fd6a649 783 //proto.name.local.
nyatla 103:853ddf4a1b81 784 l = ret + 2;
nyatla 37:fc4b4fd6a649 785 return l;
nyatla 37:fc4b4fd6a649 786 }
nyatla 37:fc4b4fd6a649 787
nyatla 37:fc4b4fd6a649 788
nyatla 37:fc4b4fd6a649 789
nyatla 37:fc4b4fd6a649 790
nyatla 37:fc4b4fd6a649 791
nyatla 37:fc4b4fd6a649 792
nyatla 37:fc4b4fd6a649 793 static void sendAnnounse(NyLPC_TcMDnsServer_t* i_inst)
nyatla 37:fc4b4fd6a649 794 {
nyatla 37:fc4b4fd6a649 795 char* obuf;
nyatla 37:fc4b4fd6a649 796 NyLPC_TUInt16 obuflen;
nyatla 98:6284ce9a0476 797 NyLPC_TUInt16 l;
nyatla 37:fc4b4fd6a649 798 int i2;
nyatla 37:fc4b4fd6a649 799 for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
nyatla 37:fc4b4fd6a649 800 //Bufferの取得
nyatla 37:fc4b4fd6a649 801 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,TIMEOUT_IN_MS);
nyatla 37:fc4b4fd6a649 802 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 803 return;
nyatla 37:fc4b4fd6a649 804 }
nyatla 103:853ddf4a1b81 805 l=setResponseHeader(obuf,NULL,1,0,5);
nyatla 98:6284ce9a0476 806 l=writePtrRecord(i_inst->_ref_record,i2,obuf,l,obuflen);
nyatla 98:6284ce9a0476 807 if(l<=0){
nyatla 37:fc4b4fd6a649 808 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 809 }
nyatla 102:41a5e92e0a8e 810 //SRV
nyatla 98:6284ce9a0476 811 l=writeSRVRecord(i_inst,i2,obuf,l,obuflen);
nyatla 98:6284ce9a0476 812 if(l<=0){
nyatla 37:fc4b4fd6a649 813 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 814 }
nyatla 102:41a5e92e0a8e 815 //TXT
nyatla 98:6284ce9a0476 816 l=writeTXTRecord(i_inst,i2,obuf,l,obuflen);
nyatla 98:6284ce9a0476 817 if(l<=0){
nyatla 37:fc4b4fd6a649 818 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 819 }
nyatla 37:fc4b4fd6a649 820 //Aレコード
nyatla 98:6284ce9a0476 821 l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 822 if(l<=0){
nyatla 37:fc4b4fd6a649 823 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 824 }
nyatla 103:853ddf4a1b81 825 //AAAAレコード
nyatla 103:853ddf4a1b81 826 l=writeAAAARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 827 if(l<=0){
nyatla 103:853ddf4a1b81 828 NyLPC_OnErrorGoto(ERROR);
nyatla 103:853ddf4a1b81 829 }
nyatla 102:41a5e92e0a8e 830 //NSEC
nyatla 102:41a5e92e0a8e 831 l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
nyatla 102:41a5e92e0a8e 832 if(l<=0){
nyatla 102:41a5e92e0a8e 833 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 834 }
nyatla 37:fc4b4fd6a649 835 if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
nyatla 37:fc4b4fd6a649 836 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 837 }
nyatla 37:fc4b4fd6a649 838 }
nyatla 37:fc4b4fd6a649 839 return;
nyatla 37:fc4b4fd6a649 840 ERROR:
nyatla 37:fc4b4fd6a649 841 NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf);
nyatla 37:fc4b4fd6a649 842 return;
nyatla 37:fc4b4fd6a649 843 }
nyatla 37:fc4b4fd6a649 844
nyatla 37:fc4b4fd6a649 845
nyatla 98:6284ce9a0476 846
nyatla 103:853ddf4a1b81 847 static void sendReply2(NyLPC_TcMDnsServer_t* i_inst, const struct NyLPC_TDnsHeader* i_dns_header, const struct NyLPC_TDnsQuestion* q)
nyatla 37:fc4b4fd6a649 848 {
nyatla 37:fc4b4fd6a649 849 NyLPC_TInt16 ptr_recode;
nyatla 37:fc4b4fd6a649 850 NyLPC_TInt16 i2;
nyatla 37:fc4b4fd6a649 851 char* obuf;
nyatla 37:fc4b4fd6a649 852 NyLPC_TUInt16 obuflen;
nyatla 98:6284ce9a0476 853 NyLPC_TUInt16 l;
nyatla 37:fc4b4fd6a649 854 //パケットヘッダの生成
nyatla 103:853ddf4a1b81 855 switch (q->qtype){
nyatla 37:fc4b4fd6a649 856 case NyLPC_TDnsQuestion_QTYPR_SRV:
nyatla 103:853ddf4a1b81 857 //
nyatla 103:853ddf4a1b81 858 ptr_recode = NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record, q);
nyatla 103:853ddf4a1b81 859 if (ptr_recode<0){
nyatla 37:fc4b4fd6a649 860 goto DROP;
nyatla 37:fc4b4fd6a649 861 }
nyatla 37:fc4b4fd6a649 862 //Bufferの取得
nyatla 103:853ddf4a1b81 863 obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0);
nyatla 103:853ddf4a1b81 864 if (obuf == NULL){
nyatla 37:fc4b4fd6a649 865 goto DROP;
nyatla 37:fc4b4fd6a649 866 }
nyatla 103:853ddf4a1b81 867 //SRV,(TXT,A,AAAA,NSEC)
nyatla 103:853ddf4a1b81 868 l = setResponseHeader(obuf, i_dns_header, 1, 0, 4);
nyatla 103:853ddf4a1b81 869 l = writeSRVRecord(i_inst, ptr_recode, obuf, l, obuflen);
nyatla 103:853ddf4a1b81 870 if (l <= 0){
nyatla 37:fc4b4fd6a649 871 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 872 }
nyatla 103:853ddf4a1b81 873 l = writeTXTRecord(i_inst, ptr_recode, obuf, l, obuflen);
nyatla 103:853ddf4a1b81 874 if (l <= 0){
nyatla 37:fc4b4fd6a649 875 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 876 }
nyatla 37:fc4b4fd6a649 877 //Aレコード
nyatla 103:853ddf4a1b81 878 l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 879 if (l <= 0){
nyatla 103:853ddf4a1b81 880 NyLPC_OnErrorGoto(ERROR);
nyatla 103:853ddf4a1b81 881 }
nyatla 103:853ddf4a1b81 882 //AAAAレコード
nyatla 103:853ddf4a1b81 883 l = writeAAAARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 884 if (l <= 0){
nyatla 37:fc4b4fd6a649 885 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 886 }
nyatla 102:41a5e92e0a8e 887 //NSEC
nyatla 103:853ddf4a1b81 888 l = writeNSECRecord(obuf, l, obuflen, i_inst->_ref_record->a);
nyatla 103:853ddf4a1b81 889 if (l <= 0){
nyatla 102:41a5e92e0a8e 890 NyLPC_OnErrorGoto(ERROR);
nyatla 103:853ddf4a1b81 891 }
nyatla 102:41a5e92e0a8e 892 break;
nyatla 102:41a5e92e0a8e 893 case NyLPC_TDnsQuestion_QTYPR_AAAA:
nyatla 102:41a5e92e0a8e 894 //自分宛?(name.local)
nyatla 103:853ddf4a1b81 895 if (!NyLPC_TDnsQuestion_isEqualName(q, i_inst->_ref_record->a, "")){
nyatla 102:41a5e92e0a8e 896 goto DROP;
nyatla 102:41a5e92e0a8e 897 }
nyatla 102:41a5e92e0a8e 898 //Bufferの取得
nyatla 103:853ddf4a1b81 899 obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0);
nyatla 103:853ddf4a1b81 900 if (obuf == NULL){
nyatla 102:41a5e92e0a8e 901 goto DROP;
nyatla 102:41a5e92e0a8e 902 }
nyatla 102:41a5e92e0a8e 903 //Headerのコピー
nyatla 103:853ddf4a1b81 904 //AAAA,(A,NSEC)
nyatla 103:853ddf4a1b81 905 l = setResponseHeader(obuf, i_dns_header, 1, 0, 2);
nyatla 102:41a5e92e0a8e 906 //AAAAレコード
nyatla 103:853ddf4a1b81 907 l = writeAAAARecordByQuery(obuf, l, obuflen, q, &(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 908 if (l <= 0){
nyatla 103:853ddf4a1b81 909 NyLPC_OnErrorGoto(ERROR);
nyatla 103:853ddf4a1b81 910 }
nyatla 103:853ddf4a1b81 911 //Aレコードのみ
nyatla 103:853ddf4a1b81 912 l = writeARecordByQuery(obuf, l, obuflen, q, &(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 913 if (l <= 0){
nyatla 102:41a5e92e0a8e 914 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 915 }
nyatla 102:41a5e92e0a8e 916 //NSEC
nyatla 103:853ddf4a1b81 917 l = writeNSECRecordByQuery(obuf, l, obuflen, q);
nyatla 103:853ddf4a1b81 918 if (l <= 0){
nyatla 102:41a5e92e0a8e 919 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 920 }
nyatla 37:fc4b4fd6a649 921 break;
nyatla 37:fc4b4fd6a649 922 case NyLPC_TDnsQuestion_QTYPR_A:
nyatla 37:fc4b4fd6a649 923 //自分宛?(name.local)
nyatla 103:853ddf4a1b81 924 if (!NyLPC_TDnsQuestion_isEqualName(q, i_inst->_ref_record->a, "")){
nyatla 37:fc4b4fd6a649 925 goto DROP;
nyatla 37:fc4b4fd6a649 926 }
nyatla 37:fc4b4fd6a649 927 //Bufferの取得
nyatla 103:853ddf4a1b81 928 obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0);
nyatla 103:853ddf4a1b81 929 if (obuf == NULL){
nyatla 37:fc4b4fd6a649 930 goto DROP;
nyatla 37:fc4b4fd6a649 931 }
nyatla 37:fc4b4fd6a649 932 //Headerのコピー
nyatla 103:853ddf4a1b81 933 l = setResponseHeader(obuf, i_dns_header, 1, 0, 1);
nyatla 103:853ddf4a1b81 934 //A、(NSEC
nyatla 103:853ddf4a1b81 935 l = writeARecordByQuery(obuf, l, obuflen, q, &(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 936 if (l <= 0){
nyatla 37:fc4b4fd6a649 937 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 938 }
nyatla 103:853ddf4a1b81 939 l = writeNSECRecordByQuery(obuf, l, obuflen, q);
nyatla 103:853ddf4a1b81 940 if (l <= 0){
nyatla 102:41a5e92e0a8e 941 NyLPC_OnErrorGoto(ERROR);
nyatla 103:853ddf4a1b81 942 }
nyatla 37:fc4b4fd6a649 943 break;
nyatla 37:fc4b4fd6a649 944 case NyLPC_TDnsQuestion_QTYPR_PTR:
nyatla 98:6284ce9a0476 945 //_service._dns-sd._udpかどうか
nyatla 103:853ddf4a1b81 946 if (NyLPC_TDnsQuestion_isEqualName(q, NULL, "_services._dns-sd._udp")){
nyatla 37:fc4b4fd6a649 947 //Bufferの取得
nyatla 103:853ddf4a1b81 948 obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0);
nyatla 103:853ddf4a1b81 949 if (obuf == NULL){
nyatla 37:fc4b4fd6a649 950 goto DROP;
nyatla 37:fc4b4fd6a649 951 }
nyatla 103:853ddf4a1b81 952 l = setResponseHeader(obuf, i_dns_header, i_inst->_ref_record->num_of_srv, 0, 0);
nyatla 103:853ddf4a1b81 953 for (i2 = 0; i2<i_inst->_ref_record->num_of_srv; i2++){
nyatla 103:853ddf4a1b81 954 l = writeSdPtrRecord(q, &(i_inst->_ref_record->srv[i2]), obuf, l, obuflen);
nyatla 103:853ddf4a1b81 955 if (l <= 0){
nyatla 37:fc4b4fd6a649 956 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 957 }
nyatla 37:fc4b4fd6a649 958 }
nyatla 103:853ddf4a1b81 959 }
nyatla 103:853ddf4a1b81 960 else{
nyatla 37:fc4b4fd6a649 961 //自分宛?(proto.local)
nyatla 103:853ddf4a1b81 962 ptr_recode = NyLPC_TDnsRecord_getMatchPtrIdx(i_inst->_ref_record, q);
nyatla 103:853ddf4a1b81 963 if (ptr_recode<0){
nyatla 37:fc4b4fd6a649 964 goto DROP;
nyatla 37:fc4b4fd6a649 965 }
nyatla 37:fc4b4fd6a649 966 //Bufferの取得
nyatla 103:853ddf4a1b81 967 obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0);
nyatla 103:853ddf4a1b81 968 if (obuf == NULL){
nyatla 37:fc4b4fd6a649 969 goto DROP;
nyatla 37:fc4b4fd6a649 970 }
nyatla 103:853ddf4a1b81 971 l = setResponseHeader(obuf, i_dns_header, 1, 0, 5);
nyatla 103:853ddf4a1b81 972 l = writePtrRecord(i_inst->_ref_record, ptr_recode, obuf, l, obuflen);
nyatla 103:853ddf4a1b81 973 if (l <= 0){
nyatla 37:fc4b4fd6a649 974 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 975 }
nyatla 103:853ddf4a1b81 976 //SRV
nyatla 103:853ddf4a1b81 977 l = writeSRVRecord(i_inst, ptr_recode, obuf, l, obuflen);
nyatla 103:853ddf4a1b81 978 if (l <= 0){
nyatla 37:fc4b4fd6a649 979 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 980 }
nyatla 103:853ddf4a1b81 981 //TXT
nyatla 103:853ddf4a1b81 982 l = writeTXTRecord(i_inst, ptr_recode, obuf, l, obuflen);
nyatla 103:853ddf4a1b81 983 if (l <= 0){
nyatla 37:fc4b4fd6a649 984 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 985 }
nyatla 37:fc4b4fd6a649 986 //Aレコード
nyatla 103:853ddf4a1b81 987 l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 988 if (l <= 0){
nyatla 37:fc4b4fd6a649 989 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 990 }
nyatla 103:853ddf4a1b81 991 //AAAAレコード
nyatla 103:853ddf4a1b81 992 l = writeAAAARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 993 if (l <= 0){
nyatla 103:853ddf4a1b81 994 NyLPC_OnErrorGoto(ERROR);
nyatla 103:853ddf4a1b81 995 }
nyatla 103:853ddf4a1b81 996 //NSEC
nyatla 103:853ddf4a1b81 997 l = writeNSECRecord(obuf, l, obuflen, i_inst->_ref_record->a);
nyatla 103:853ddf4a1b81 998 if (l <= 0){
nyatla 102:41a5e92e0a8e 999 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 1000 }
nyatla 37:fc4b4fd6a649 1001 }
nyatla 37:fc4b4fd6a649 1002 break;
nyatla 37:fc4b4fd6a649 1003 case NyLPC_TDnsQuestion_QTYPR_TXT:
nyatla 37:fc4b4fd6a649 1004 //自分宛?(proto.local)
nyatla 103:853ddf4a1b81 1005 ptr_recode = NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record, q);
nyatla 103:853ddf4a1b81 1006 if (ptr_recode<0){
nyatla 37:fc4b4fd6a649 1007 goto DROP;
nyatla 37:fc4b4fd6a649 1008 }
nyatla 37:fc4b4fd6a649 1009 //Bufferの取得
nyatla 103:853ddf4a1b81 1010 obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0);
nyatla 103:853ddf4a1b81 1011 l = setResponseHeader(obuf, i_dns_header, 1, 0, 3);
nyatla 103:853ddf4a1b81 1012 l = writeTXTRecord(i_inst, ptr_recode, obuf, l, obuflen);
nyatla 103:853ddf4a1b81 1013 if (l <= 0){
nyatla 37:fc4b4fd6a649 1014 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 1015 }
nyatla 103:853ddf4a1b81 1016 //A recoad
nyatla 103:853ddf4a1b81 1017 l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 1018 if (l <= 0){
nyatla 37:fc4b4fd6a649 1019 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 1020 }
nyatla 103:853ddf4a1b81 1021 //AAAAレコード
nyatla 103:853ddf4a1b81 1022 l = writeAAAARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 103:853ddf4a1b81 1023 if (l <= 0){
nyatla 103:853ddf4a1b81 1024 NyLPC_OnErrorGoto(ERROR);
nyatla 103:853ddf4a1b81 1025 }
nyatla 103:853ddf4a1b81 1026 //NSEC
nyatla 103:853ddf4a1b81 1027 l = writeNSECRecord(obuf, l, obuflen, i_inst->_ref_record->a);
nyatla 103:853ddf4a1b81 1028 if (l <= 0){
nyatla 102:41a5e92e0a8e 1029 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 1030 }
nyatla 37:fc4b4fd6a649 1031 break;
nyatla 37:fc4b4fd6a649 1032 default:
nyatla 37:fc4b4fd6a649 1033 goto DROP;
nyatla 37:fc4b4fd6a649 1034 }
nyatla 103:853ddf4a1b81 1035 if (!NyLPC_cUdpSocket_psend(&(i_inst->_super), &MDNS_MCAST_IPADDR, MDNS_MCAST_PORT, obuf, l)){
nyatla 37:fc4b4fd6a649 1036 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 1037 }
nyatla 37:fc4b4fd6a649 1038 return;
nyatla 37:fc4b4fd6a649 1039 ERROR:
nyatla 103:853ddf4a1b81 1040 NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super), obuf);
nyatla 37:fc4b4fd6a649 1041 DROP:
nyatla 37:fc4b4fd6a649 1042 return;
nyatla 37:fc4b4fd6a649 1043 }
nyatla 37:fc4b4fd6a649 1044 #define CTRL_FLAG_INIT 0x00
nyatla 37:fc4b4fd6a649 1045 #define CTRL_FLAG_STARTED 0x80
nyatla 37:fc4b4fd6a649 1046 #define CTRL_FLAG_STOP_REQUESTED 0x40
nyatla 37:fc4b4fd6a649 1047 #define CTRL_FLAG_PROCESS_PACKET 0x20 //パケット処理中の間1
nyatla 37:fc4b4fd6a649 1048
nyatla 37:fc4b4fd6a649 1049 static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info)
nyatla 37:fc4b4fd6a649 1050 {
nyatla 98:6284ce9a0476 1051 NyLPC_TUInt16 in_len;
nyatla 37:fc4b4fd6a649 1052 NyLPC_TUInt16 num_of_query;
nyatla 37:fc4b4fd6a649 1053 struct NyLPC_TDnsQuestion q;
nyatla 37:fc4b4fd6a649 1054 NyLPC_TUInt16 s;
nyatla 37:fc4b4fd6a649 1055 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 1056
nyatla 37:fc4b4fd6a649 1057 if(i_info->peer_port!=MDNS_MCAST_PORT || !NyLPC_TIPv4Addr_isEqual(&MDNS_MCAST_IPADDR,&i_info->ip)){
nyatla 37:fc4b4fd6a649 1058 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 1059 }
nyatla 37:fc4b4fd6a649 1060
nyatla 98:6284ce9a0476 1061 num_of_query=getNumberOfQuestion(i_buf,i_info->size);
nyatla 37:fc4b4fd6a649 1062 if(num_of_query==0){
nyatla 37:fc4b4fd6a649 1063 goto DROP;
nyatla 37:fc4b4fd6a649 1064 }
nyatla 98:6284ce9a0476 1065 in_len=sizeof(struct NyLPC_TDnsHeader);
nyatla 37:fc4b4fd6a649 1066 for(i=0;i<num_of_query;i++){
nyatla 37:fc4b4fd6a649 1067 //Queryのパース
nyatla 98:6284ce9a0476 1068
nyatla 98:6284ce9a0476 1069 s=NyLPC_TDnsQuestion_parse(i_buf,i_info->size,in_len,&q);
nyatla 37:fc4b4fd6a649 1070 if(s==0){
nyatla 37:fc4b4fd6a649 1071 goto DROP;
nyatla 37:fc4b4fd6a649 1072 }
nyatla 98:6284ce9a0476 1073 in_len+=s;
nyatla 37:fc4b4fd6a649 1074 sendReply2((NyLPC_TcMDnsServer_t*)i_inst,(const struct NyLPC_TDnsHeader*)i_buf,&q);
nyatla 37:fc4b4fd6a649 1075 }
nyatla 37:fc4b4fd6a649 1076 //パケット処理終了
nyatla 37:fc4b4fd6a649 1077 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 1078 DROP:
nyatla 37:fc4b4fd6a649 1079 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 1080 }
nyatla 37:fc4b4fd6a649 1081
nyatla 37:fc4b4fd6a649 1082 static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst)
nyatla 37:fc4b4fd6a649 1083 {
nyatla 37:fc4b4fd6a649 1084
nyatla 37:fc4b4fd6a649 1085 if(NyLPC_cStopwatch_isExpired(&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw)){
nyatla 37:fc4b4fd6a649 1086 //アナウンス
nyatla 37:fc4b4fd6a649 1087 sendAnnounse(((NyLPC_TcMDnsServer_t*)i_inst));
nyatla 37:fc4b4fd6a649 1088 //TTL(msec)*1000*80%
nyatla 101:5022828ace54 1089 NyLPC_cStopwatch_startExpire((&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw),NyLPC_TcMDns_TTL*1000*4/5);
nyatla 37:fc4b4fd6a649 1090 }
nyatla 37:fc4b4fd6a649 1091 }
nyatla 37:fc4b4fd6a649 1092
nyatla 37:fc4b4fd6a649 1093 NyLPC_TBool NyLPC_cMDnsServer_initialize(
nyatla 48:00d211aac2ec 1094 NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsRecord* i_ref_record)
nyatla 37:fc4b4fd6a649 1095 {
nyatla 37:fc4b4fd6a649 1096 NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw));
nyatla 37:fc4b4fd6a649 1097 NyLPC_cStopwatch_startExpire(&(i_inst->_periodic_sw),1000);
nyatla 37:fc4b4fd6a649 1098 NyLPC_cUdpSocket_initialize(&(i_inst->_super),MDNS_MCAST_PORT,NULL,0);
nyatla 37:fc4b4fd6a649 1099 NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->_super),onPacket);
nyatla 48:00d211aac2ec 1100 NyLPC_cUdpSocket_setOnPeriodicHandler(&(i_inst->_super),onPeriodic);
nyatla 37:fc4b4fd6a649 1101 NyLPC_cUdpSocket_joinMulticast(&(i_inst->_super),&MDNS_MCAST_IPADDR);
nyatla 37:fc4b4fd6a649 1102 i_inst->_ref_record=i_ref_record;
nyatla 37:fc4b4fd6a649 1103 return NyLPC_TBool_TRUE;
nyatla 37:fc4b4fd6a649 1104 }
nyatla 37:fc4b4fd6a649 1105 void NyLPC_cMDnsServer_finalize(
nyatla 37:fc4b4fd6a649 1106 NyLPC_TcMDnsServer_t* i_inst)
nyatla 37:fc4b4fd6a649 1107 {
nyatla 37:fc4b4fd6a649 1108 NyLPC_cUdpSocket_finalize(&(i_inst->_super));
nyatla 37:fc4b4fd6a649 1109 NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw));
nyatla 37:fc4b4fd6a649 1110 }
nyatla 37:fc4b4fd6a649 1111
nyatla 37:fc4b4fd6a649 1112
nyatla 37:fc4b4fd6a649 1113