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:
Tue Oct 28 12:38:10 2014 +0000
Revision:
102:41a5e92e0a8e
Parent:
101:5022828ace54
Child:
103:853ddf4a1b81
bugfix; AAAA/NSEC???????

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 37:fc4b4fd6a649 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 37:fc4b4fd6a649 89 * TLabelCache
nyatla 37:fc4b4fd6a649 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 98:6284ce9a0476 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 98:6284ce9a0476 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 98:6284ce9a0476 123 * 展開しない圧縮文字列の長さを返す
nyatla 98:6284ce9a0476 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 98:6284ce9a0476 141 * @return
nyatla 98:6284ce9a0476 142 * 圧縮するとtrue i_nameは2文字に圧縮される。
nyatla 98:6284ce9a0476 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 98:6284ce9a0476 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 98:6284ce9a0476 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 98:6284ce9a0476 198 * mDNSパケットからi_nameを検索する。
nyatla 98:6284ce9a0476 199 * i_targetはi_packetに含まれ、NULL終端されていること
nyatla 98:6284ce9a0476 200 * @return 0 圧縮失敗/その他:圧縮後のパケットサイズ
nyatla 98:6284ce9a0476 201 *
nyatla 98:6284ce9a0476 202 */
nyatla 98:6284ce9a0476 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 98:6284ce9a0476 216 s += sizeofCompressName(i_packet+s);
nyatla 98:6284ce9a0476 217 //CLASS PTR/SRVの場合のみデータセクションも探す
nyatla 98:6284ce9a0476 218 switch (NyLPC_ntohs(*(NyLPC_TUInt16*)(i_packet+s))){
nyatla 98:6284ce9a0476 219 case NyLPC_TDnsQuestion_QTYPR_SRV:
nyatla 98:6284ce9a0476 220 s += 2+2+2;//PTRよりちょっと多い
nyatla 98:6284ce9a0476 221 case NyLPC_TDnsQuestion_QTYPR_PTR:
nyatla 98:6284ce9a0476 222 s += 2 + 2 + 4 + 2;
nyatla 98:6284ce9a0476 223 if (i_name_start <= s){
nyatla 98:6284ce9a0476 224 //圧縮対象文字列に到達
nyatla 98:6284ce9a0476 225 return 0;
nyatla 98:6284ce9a0476 226 }
nyatla 98:6284ce9a0476 227 // //データは圧縮ポインタにしない方がいいらしい。
nyatla 98:6284ce9a0476 228 // if (compressNameB(i_packet, s, i_name_pos)){
nyatla 98:6284ce9a0476 229 // return i_name_pos + 2;
nyatla 98:6284ce9a0476 230 // }
nyatla 98:6284ce9a0476 231 break;
nyatla 98:6284ce9a0476 232 default:
nyatla 98:6284ce9a0476 233 //ヘッダとデータサイズぶんだけ移動して終わり
nyatla 98:6284ce9a0476 234 s += 2 + 2 + 4 + 2;
nyatla 98:6284ce9a0476 235 break;
nyatla 98:6284ce9a0476 236 }
nyatla 98:6284ce9a0476 237 s += NyLPC_ntohs(*((NyLPC_TUInt16*)(i_packet+s - 2)));
nyatla 98:6284ce9a0476 238 }
nyatla 98:6284ce9a0476 239 }
nyatla 98:6284ce9a0476 240 /**
nyatla 98:6284ce9a0476 241 * @return
nyatla 98:6284ce9a0476 242 * 新しいi_packetの長さ
nyatla 98:6284ce9a0476 243 */
nyatla 98:6284ce9a0476 244 static NyLPC_TUInt16 compressName(char* i_packet, NyLPC_TUInt16 i_name_pos, NyLPC_TUInt16 i_name_len)
nyatla 98:6284ce9a0476 245 {
nyatla 98:6284ce9a0476 246 NyLPC_TUInt16 p;
nyatla 98:6284ce9a0476 247 NyLPC_TUInt16 s = i_name_pos;
nyatla 98:6284ce9a0476 248 for (;;){
nyatla 98:6284ce9a0476 249 p = compressNameA(i_packet, i_name_pos,s);
nyatla 98:6284ce9a0476 250 //i_targetとAnswer文字列が等しいか確認
nyatla 98:6284ce9a0476 251 if (p != 0){
nyatla 98:6284ce9a0476 252 return p;
nyatla 98:6284ce9a0476 253 }
nyatla 98:6284ce9a0476 254 s += (NyLPC_TUInt16)*(i_packet + s) + 1;
nyatla 98:6284ce9a0476 255 if (*(i_packet+s) == 0){
nyatla 98:6284ce9a0476 256 //圧縮対象文字列に到達
nyatla 98:6284ce9a0476 257 return (i_name_len + i_name_pos);
nyatla 98:6284ce9a0476 258 }
nyatla 98:6284ce9a0476 259 }
nyatla 37:fc4b4fd6a649 260 }
nyatla 37:fc4b4fd6a649 261
nyatla 37:fc4b4fd6a649 262
nyatla 37:fc4b4fd6a649 263
nyatla 37:fc4b4fd6a649 264
nyatla 37:fc4b4fd6a649 265
nyatla 37:fc4b4fd6a649 266 /**
nyatla 37:fc4b4fd6a649 267 * 受領可能なQuestionか確認する
nyatla 37:fc4b4fd6a649 268 * @return
nyatla 37:fc4b4fd6a649 269 * 受領可能なQuestionの数
nyatla 37:fc4b4fd6a649 270 *
nyatla 37:fc4b4fd6a649 271 */
nyatla 98:6284ce9a0476 272 static NyLPC_TUInt16 getNumberOfQuestion(const void* i_packet, NyLPC_TUInt16 i_len)
nyatla 37:fc4b4fd6a649 273 {
nyatla 98:6284ce9a0476 274 struct NyLPC_TDnsHeader* ptr = (struct NyLPC_TDnsHeader*)i_packet;
nyatla 37:fc4b4fd6a649 275 NyLPC_TUInt16 t;
nyatla 98:6284ce9a0476 276 if (i_len<sizeof(struct NyLPC_TDnsHeader)){
nyatla 37:fc4b4fd6a649 277 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 278 }
nyatla 37:fc4b4fd6a649 279 //questrionの確認
nyatla 37:fc4b4fd6a649 280 //QR==0 && op==0 && tc=0
nyatla 98:6284ce9a0476 281 t = NyLPC_ntohs(ptr->flag);
nyatla 98:6284ce9a0476 282 if (((t & NyLPC_TDnsHeader_FLAG_MASK_QR) != 0) &&
nyatla 98:6284ce9a0476 283 ((t & NyLPC_TDnsHeader_FLAG_MASK_OPCODE) != 0) &&
nyatla 98:6284ce9a0476 284 ((t & NyLPC_TDnsHeader_FLAG_MASK_TC) != 0))
nyatla 37:fc4b4fd6a649 285 {
nyatla 37:fc4b4fd6a649 286 //this is response
nyatla 37:fc4b4fd6a649 287 return 0;
nyatla 37:fc4b4fd6a649 288 }
nyatla 37:fc4b4fd6a649 289 return NyLPC_ntohs(ptr->qd);
nyatla 37:fc4b4fd6a649 290 }
nyatla 37:fc4b4fd6a649 291
nyatla 98:6284ce9a0476 292 /**
nyatla 98:6284ce9a0476 293 * [i_name].[i_protocol].localをquestionと比較します。i_nameは省略ができます。
nyatla 101:5022828ace54 294 * i_nameはincasesensitiveです。
nyatla 98:6284ce9a0476 295 * @return 等しい場合true
nyatla 98:6284ce9a0476 296 */
nyatla 98:6284ce9a0476 297 static NyLPC_TBool NyLPC_TDnsQuestion_isEqualName(const struct NyLPC_TDnsQuestion* question, const char* i_name, const char* i_protocol)
nyatla 37:fc4b4fd6a649 298 {
nyatla 98:6284ce9a0476 299 NyLPC_TUInt8 tmp;
nyatla 98:6284ce9a0476 300 const char* p; //プロトコル文字列の解析開始位置
nyatla 98:6284ce9a0476 301 const char* s = question->buf + (NyLPC_TUInt8)question->qname_pos; //クエリの解析位置
nyatla 98:6284ce9a0476 302
nyatla 98:6284ce9a0476 303 //Domain
nyatla 98:6284ce9a0476 304 if (i_name != NULL){
nyatla 98:6284ce9a0476 305 //0xc0参照の解決
nyatla 98:6284ce9a0476 306 s = getExtractNamePos(question->buf, s);
nyatla 98:6284ce9a0476 307 if (s == NULL){
nyatla 98:6284ce9a0476 308 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 309 }
nyatla 98:6284ce9a0476 310 tmp = (NyLPC_TUInt8)strlen(i_name);
nyatla 101:5022828ace54 311 if (tmp != *s || NyLPC_strnicmp(s + 1, i_name, tmp) != 0){
nyatla 98:6284ce9a0476 312 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 313 }
nyatla 98:6284ce9a0476 314 s += (*s) + 1;
nyatla 98:6284ce9a0476 315 }else{
nyatla 98:6284ce9a0476 316 s = question->buf + (NyLPC_TUInt8)question->qname_pos;//クエリの解析位置
nyatla 98:6284ce9a0476 317 }
nyatla 98:6284ce9a0476 318 p = i_protocol;
nyatla 98:6284ce9a0476 319 //Protocol
nyatla 98:6284ce9a0476 320 for (;;){
nyatla 98:6284ce9a0476 321 //0xc0参照の解決
nyatla 98:6284ce9a0476 322 s = getExtractNamePos(question->buf, s);
nyatla 98:6284ce9a0476 323 if (s == NULL){
nyatla 98:6284ce9a0476 324 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 325 }
nyatla 98:6284ce9a0476 326 //SRVの末端到達
nyatla 98:6284ce9a0476 327 if (*p == 0){
nyatla 98:6284ce9a0476 328 if (question->buf + question->buf_len<s + 7 + 4){
nyatla 98:6284ce9a0476 329 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 330 }
nyatla 98:6284ce9a0476 331 return (memcmp("\5local\0", s, 7) == 0);
nyatla 98:6284ce9a0476 332 }
nyatla 98:6284ce9a0476 333 //有効サイズなら一致検出
nyatla 98:6284ce9a0476 334 if (question->buf + question->buf_len<s + 1 + (NyLPC_TUInt8)*s + 4){
nyatla 98:6284ce9a0476 335 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 336 }
nyatla 98:6284ce9a0476 337 if (memcmp(p, s + 1, (NyLPC_TUInt8)*s) != 0){
nyatla 98:6284ce9a0476 338 //不一致
nyatla 98:6284ce9a0476 339 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 340 }
nyatla 98:6284ce9a0476 341 //検出位置の移動
nyatla 98:6284ce9a0476 342 p += (*s) + 1;
nyatla 98:6284ce9a0476 343 s += (*s) + 1;
nyatla 98:6284ce9a0476 344 }
nyatla 98:6284ce9a0476 345 }
nyatla 98:6284ce9a0476 346
nyatla 98:6284ce9a0476 347
nyatla 98:6284ce9a0476 348 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 349 {
nyatla 37:fc4b4fd6a649 350 NyLPC_TUInt16 i;
nyatla 98:6284ce9a0476 351 //解析開始位置を計算
nyatla 98:6284ce9a0476 352 NyLPC_TUInt16 qlen = 0;
nyatla 98:6284ce9a0476 353 for (i = i_parse_start; i<i_packet_len - 4; i++){
nyatla 98:6284ce9a0476 354 switch ((NyLPC_TUInt8)(*(i_packet + i))){
nyatla 98:6284ce9a0476 355 case 0x00:
nyatla 98:6284ce9a0476 356 qlen++;
nyatla 98:6284ce9a0476 357 break;
nyatla 98:6284ce9a0476 358 case 0xc0:
nyatla 98:6284ce9a0476 359 qlen+=2;
nyatla 98:6284ce9a0476 360 break;
nyatla 98:6284ce9a0476 361 default:
nyatla 98:6284ce9a0476 362 qlen++;
nyatla 98:6284ce9a0476 363 continue;
nyatla 37:fc4b4fd6a649 364 }
nyatla 98:6284ce9a0476 365 o_val->buf = i_packet;
nyatla 98:6284ce9a0476 366 o_val->buf_len = i_packet_len;
nyatla 98:6284ce9a0476 367 o_val->qname_pos = i_parse_start;
nyatla 98:6284ce9a0476 368 o_val->qtype = NyLPC_ntohs(*(NyLPC_TUInt16*)(i_packet+i_parse_start + qlen));
nyatla 98:6284ce9a0476 369 o_val->qclass = NyLPC_ntohs(*(NyLPC_TUInt16*)(i_packet+i_parse_start + qlen + sizeof(NyLPC_TUInt16)));
nyatla 98:6284ce9a0476 370 return qlen + 4;
nyatla 37:fc4b4fd6a649 371 }
nyatla 37:fc4b4fd6a649 372 return 0;
nyatla 37:fc4b4fd6a649 373 }
nyatla 37:fc4b4fd6a649 374
nyatla 37:fc4b4fd6a649 375 /**
nyatla 37:fc4b4fd6a649 376 * DNSレコードのPRTフィールドとDNSラベル文字列を比較する。
nyatla 37:fc4b4fd6a649 377 */
nyatla 98:6284ce9a0476 378 static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchPtrIdx(const struct NyLPC_TDnsRecord* i_struct,const struct NyLPC_TDnsQuestion* question)
nyatla 37:fc4b4fd6a649 379 {
nyatla 37:fc4b4fd6a649 380 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 381 for(i=0;i<i_struct->num_of_srv;i++){
nyatla 98:6284ce9a0476 382 if(NyLPC_TDnsQuestion_isEqualName(question,NULL,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 static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchSrvIdx(const struct NyLPC_TDnsRecord* i_struct,const struct NyLPC_TDnsQuestion* question)
nyatla 37:fc4b4fd6a649 389 {
nyatla 37:fc4b4fd6a649 390 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 391 for(i=0;i<i_struct->num_of_srv;i++){
nyatla 98:6284ce9a0476 392 if(NyLPC_TDnsQuestion_isEqualName(question,i_struct->name,i_struct->srv[i].protocol)){
nyatla 37:fc4b4fd6a649 393 return i;
nyatla 37:fc4b4fd6a649 394 }
nyatla 37:fc4b4fd6a649 395 }
nyatla 37:fc4b4fd6a649 396 return -1;
nyatla 37:fc4b4fd6a649 397 }
nyatla 98:6284ce9a0476 398
nyatla 37:fc4b4fd6a649 399
nyatla 37:fc4b4fd6a649 400
nyatla 37:fc4b4fd6a649 401 /**
nyatla 37:fc4b4fd6a649 402 * '.'区切り文字列をDNS形式の[n]text[n]text\0へ変換する。
nyatla 37:fc4b4fd6a649 403 * @return
nyatla 37:fc4b4fd6a649 404 * 変換後のデータブロックの長さin byte
nyatla 37:fc4b4fd6a649 405 * 終端の\0の長さを含みます。
nyatla 37:fc4b4fd6a649 406 */
nyatla 37:fc4b4fd6a649 407 static NyLPC_TInt16 str2label(NyLPC_TChar* buf,const NyLPC_TChar* name)
nyatla 37:fc4b4fd6a649 408 {
nyatla 37:fc4b4fd6a649 409 //proto文字列の変換
nyatla 37:fc4b4fd6a649 410 NyLPC_TChar* lp;
nyatla 37:fc4b4fd6a649 411 const NyLPC_TChar* n=name;
nyatla 37:fc4b4fd6a649 412 NyLPC_TChar* b=buf;
nyatla 37:fc4b4fd6a649 413 while(*n!='\0'){
nyatla 37:fc4b4fd6a649 414 lp=b;
nyatla 37:fc4b4fd6a649 415 b++;
nyatla 37:fc4b4fd6a649 416 for(;strchr(".\0",*n)==NULL;){
nyatla 37:fc4b4fd6a649 417 *b=*n;
nyatla 37:fc4b4fd6a649 418 b++;
nyatla 37:fc4b4fd6a649 419 n++;
nyatla 37:fc4b4fd6a649 420 }
nyatla 37:fc4b4fd6a649 421 *lp=(char)(b-lp-1);
nyatla 37:fc4b4fd6a649 422 if(*n!='\0'){
nyatla 37:fc4b4fd6a649 423 n++;
nyatla 37:fc4b4fd6a649 424 }
nyatla 37:fc4b4fd6a649 425 }
nyatla 37:fc4b4fd6a649 426 *b='\0';
nyatla 37:fc4b4fd6a649 427 b++;
nyatla 37:fc4b4fd6a649 428 return b-buf;
nyatla 37:fc4b4fd6a649 429 }
nyatla 37:fc4b4fd6a649 430 /**
nyatla 102:41a5e92e0a8e 431 * query文字列をパケットに追記します。
nyatla 102:41a5e92e0a8e 432 * @return 出力したバイト数
nyatla 102:41a5e92e0a8e 433 */
nyatla 102:41a5e92e0a8e 434 static NyLPC_TInt16 query2label(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_query)
nyatla 37:fc4b4fd6a649 435 {
nyatla 102:41a5e92e0a8e 436 const char* n;
nyatla 102:41a5e92e0a8e 437 NyLPC_TInt16 s=0;
nyatla 102:41a5e92e0a8e 438 for(;;){
nyatla 102:41a5e92e0a8e 439 n=getExtractNamePos(i_query,i_query+s);
nyatla 102:41a5e92e0a8e 440 if(n==NULL){
nyatla 102:41a5e92e0a8e 441 *(i_packet+i_spos+s)=0;
nyatla 102:41a5e92e0a8e 442 s++;
nyatla 102:41a5e92e0a8e 443 break;
nyatla 102:41a5e92e0a8e 444 }else{
nyatla 102:41a5e92e0a8e 445 memcpy(i_packet+i_spos+s,i_query+s,((NyLPC_TUInt8)*n)+1);
nyatla 102:41a5e92e0a8e 446 s+=((NyLPC_TUInt8)*n)+1;
nyatla 102:41a5e92e0a8e 447 if(obuflen<i_spos+s+1+4+4){
nyatla 102:41a5e92e0a8e 448 return 0;
nyatla 102:41a5e92e0a8e 449 }
nyatla 102:41a5e92e0a8e 450 }
nyatla 37:fc4b4fd6a649 451 }
nyatla 102:41a5e92e0a8e 452 return s;
nyatla 102:41a5e92e0a8e 453 }
nyatla 102:41a5e92e0a8e 454
nyatla 37:fc4b4fd6a649 455
nyatla 98:6284ce9a0476 456 inline 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 457 {
nyatla 98:6284ce9a0476 458 NyLPC_TInt16 s;
nyatla 37:fc4b4fd6a649 459 NyLPC_TInt16 l=(NyLPC_TInt16)(1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1);
nyatla 98:6284ce9a0476 460 if(buflen<i_spos+l+2+2+4){
nyatla 37:fc4b4fd6a649 461 return 0;
nyatla 37:fc4b4fd6a649 462 }
nyatla 98:6284ce9a0476 463 s=str2label(i_packet+i_spos,i_recode->name)-1;
nyatla 98:6284ce9a0476 464 s+=str2label(i_packet+i_spos+s,i_recode->srv[i_sid].protocol)-1;
nyatla 98:6284ce9a0476 465 s+=str2label(i_packet+i_spos+s,"local");
nyatla 98:6284ce9a0476 466 l=compressName(i_packet,i_spos,s);//圧縮
nyatla 98:6284ce9a0476 467 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(i_type);
nyatla 98:6284ce9a0476 468 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(i_class);
nyatla 98:6284ce9a0476 469 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 470 return l+2+2+4;
nyatla 37:fc4b4fd6a649 471 }
nyatla 37:fc4b4fd6a649 472
nyatla 98:6284ce9a0476 473 /**
nyatla 98:6284ce9a0476 474 * パケットヘッダを書き込みます。
nyatla 98:6284ce9a0476 475 * @return パケットサイズ
nyatla 98:6284ce9a0476 476 */
nyatla 98:6284ce9a0476 477 inline 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 478 {
nyatla 98:6284ce9a0476 479 struct NyLPC_TDnsHeader* p=(struct NyLPC_TDnsHeader*)i_packet;
nyatla 37:fc4b4fd6a649 480 if(i_in_dns_header!=NULL){
nyatla 37:fc4b4fd6a649 481 memcpy(p,i_in_dns_header,sizeof(struct NyLPC_TDnsHeader));
nyatla 37:fc4b4fd6a649 482 p->flag=p->flag | NyLPC_HTONS(NyLPC_TDnsHeader_FLAG_MASK_QR|NyLPC_TDnsHeader_FLAG_MASK_AA);
nyatla 37:fc4b4fd6a649 483 p->flag=p->flag & NyLPC_HTONS(~(NyLPC_TDnsHeader_FLAG_MASK_RECODE|NyLPC_TDnsHeader_FLAG_MASK_TC|NyLPC_TDnsHeader_FLAG_MASK_RA));
nyatla 37:fc4b4fd6a649 484 }else{
nyatla 37:fc4b4fd6a649 485 p->flag=0;
nyatla 37:fc4b4fd6a649 486 p->id=0;
nyatla 37:fc4b4fd6a649 487 }
nyatla 37:fc4b4fd6a649 488 p->qd=0;
nyatla 37:fc4b4fd6a649 489 p->an=NyLPC_HTONS(i_an_count);
nyatla 37:fc4b4fd6a649 490 p->ns=NyLPC_HTONS(i_ns_count);
nyatla 37:fc4b4fd6a649 491 p->ar=NyLPC_HTONS(i_ar_count);
nyatla 37:fc4b4fd6a649 492 return sizeof(struct NyLPC_TDnsHeader);
nyatla 37:fc4b4fd6a649 493 }
nyatla 101:5022828ace54 494 /**
nyatla 101:5022828ace54 495 * ドメイン名からAレコードレスポンスを書きだす。
nyatla 101:5022828ace54 496 */
nyatla 101:5022828ace54 497 inline 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 498 {
nyatla 98:6284ce9a0476 499 NyLPC_TInt16 s;
nyatla 37:fc4b4fd6a649 500 //AnswerはAレコードのみ
nyatla 101:5022828ace54 501 NyLPC_TInt16 l=1+(NyLPC_TInt16)strlen(i_name)+1+5+1;
nyatla 101:5022828ace54 502 if(obuflen<i_spos+l+4+4){
nyatla 101:5022828ace54 503 return 0;
nyatla 101:5022828ace54 504 }
nyatla 101:5022828ace54 505 s=str2label(i_packet+i_spos,i_name)-1;
nyatla 101:5022828ace54 506 s+=str2label(i_packet+i_spos+s,"local");
nyatla 101:5022828ace54 507 //レコード圧縮
nyatla 101:5022828ace54 508 l=compressName(i_packet,i_spos,s);
nyatla 101:5022828ace54 509 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_A);
nyatla 101:5022828ace54 510 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 101:5022828ace54 511 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 101:5022828ace54 512 l+=2+2+4;
nyatla 37:fc4b4fd6a649 513 //A record header
nyatla 101:5022828ace54 514 if(obuflen<l+6){
nyatla 37:fc4b4fd6a649 515 return 0;
nyatla 37:fc4b4fd6a649 516 }
nyatla 37:fc4b4fd6a649 517 //Aレコードを書く
nyatla 37:fc4b4fd6a649 518 //IPADDR
nyatla 101:5022828ace54 519 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(4);
nyatla 101:5022828ace54 520 (*(NyLPC_TUInt32*)(i_packet+l+2))=ip->v;
nyatla 101:5022828ace54 521 return l+6;
nyatla 37:fc4b4fd6a649 522 }
nyatla 102:41a5e92e0a8e 523
nyatla 101:5022828ace54 524 /**
nyatla 101:5022828ace54 525 * AレコードクエリからAレコードレスポンスを書きだす。
nyatla 101:5022828ace54 526 */
nyatla 102:41a5e92e0a8e 527 static NyLPC_TInt16 writeARecordByQuery(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_query,const struct NyLPC_TIPv4Addr* ip)
nyatla 101:5022828ace54 528 {
nyatla 101:5022828ace54 529 NyLPC_TInt16 s;
nyatla 101:5022828ace54 530 //AnswerはAレコードのみ
nyatla 101:5022828ace54 531 NyLPC_TInt16 l;
nyatla 102:41a5e92e0a8e 532 s=query2label(i_packet,i_spos,obuflen,i_query);
nyatla 102:41a5e92e0a8e 533 if(s==0){
nyatla 102:41a5e92e0a8e 534 return 0;
nyatla 101:5022828ace54 535 }
nyatla 102:41a5e92e0a8e 536
nyatla 101:5022828ace54 537 //レコード圧縮
nyatla 101:5022828ace54 538 l=compressName(i_packet,i_spos,s);
nyatla 101:5022828ace54 539 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_A);
nyatla 101:5022828ace54 540 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 101:5022828ace54 541 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 101:5022828ace54 542 l+=2+2+4;
nyatla 101:5022828ace54 543 //A record header
nyatla 101:5022828ace54 544 if(obuflen<l+6){
nyatla 101:5022828ace54 545 return 0;
nyatla 101:5022828ace54 546 }
nyatla 101:5022828ace54 547 //Aレコードを書く
nyatla 101:5022828ace54 548 //IPADDR
nyatla 101:5022828ace54 549 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(4);
nyatla 101:5022828ace54 550 (*(NyLPC_TUInt32*)(i_packet+l+2))=ip->v;
nyatla 101:5022828ace54 551 return l+6;
nyatla 101:5022828ace54 552 }
nyatla 98:6284ce9a0476 553
nyatla 102:41a5e92e0a8e 554 /**
nyatla 102:41a5e92e0a8e 555 * AレコードクエリからAレコードレスポンスを書きだす。
nyatla 102:41a5e92e0a8e 556 */
nyatla 102:41a5e92e0a8e 557 static NyLPC_TInt16 writeAAAARecordByQuery(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_query,const struct NyLPC_TIPv4Addr* ip)
nyatla 102:41a5e92e0a8e 558 {
nyatla 102:41a5e92e0a8e 559 NyLPC_TInt16 s;
nyatla 102:41a5e92e0a8e 560 //AnswerはAレコードのみ
nyatla 102:41a5e92e0a8e 561 NyLPC_TInt16 l;
nyatla 102:41a5e92e0a8e 562 s=query2label(i_packet,i_spos,obuflen,i_query);
nyatla 102:41a5e92e0a8e 563 if(s==0){
nyatla 102:41a5e92e0a8e 564 return 0;
nyatla 102:41a5e92e0a8e 565 }
nyatla 102:41a5e92e0a8e 566
nyatla 102:41a5e92e0a8e 567 //レコード圧縮
nyatla 102:41a5e92e0a8e 568 l=compressName(i_packet,i_spos,s);
nyatla 102:41a5e92e0a8e 569 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_AAAA);
nyatla 102:41a5e92e0a8e 570 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 102:41a5e92e0a8e 571 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 102:41a5e92e0a8e 572 l+=2+2+4;
nyatla 102:41a5e92e0a8e 573 //A record header
nyatla 102:41a5e92e0a8e 574 if(obuflen<l+2+16){
nyatla 102:41a5e92e0a8e 575 return 0;
nyatla 102:41a5e92e0a8e 576 }
nyatla 102:41a5e92e0a8e 577 //AAAAレコードを書く
nyatla 102:41a5e92e0a8e 578 //IPADDR
nyatla 102:41a5e92e0a8e 579 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(16);
nyatla 102:41a5e92e0a8e 580 memset(i_packet+l+2,0,10);
nyatla 102:41a5e92e0a8e 581 (*(NyLPC_TUInt16*)(i_packet+l+2+10))=0xffff;
nyatla 102:41a5e92e0a8e 582 (*(NyLPC_TUInt32*)(i_packet+l+2+12))=ip->v;
nyatla 102:41a5e92e0a8e 583 return l+2+16;
nyatla 102:41a5e92e0a8e 584 }
nyatla 102:41a5e92e0a8e 585 /**
nyatla 102:41a5e92e0a8e 586 * NSECレコードレスポンスを書きだす。
nyatla 102:41a5e92e0a8e 587 * IPv6わからんし。
nyatla 102:41a5e92e0a8e 588 */
nyatla 102:41a5e92e0a8e 589 static NyLPC_TInt16 writeNSECRecord(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_name)
nyatla 102:41a5e92e0a8e 590 {
nyatla 102:41a5e92e0a8e 591 NyLPC_TInt16 s;
nyatla 102:41a5e92e0a8e 592 //AnswerはAレコードのみ
nyatla 102:41a5e92e0a8e 593 NyLPC_TInt16 l=1+(NyLPC_TInt16)strlen(i_name)+1+5+1;
nyatla 102:41a5e92e0a8e 594 if(obuflen<i_spos+l+4+4){
nyatla 102:41a5e92e0a8e 595 return 0;
nyatla 102:41a5e92e0a8e 596 }
nyatla 102:41a5e92e0a8e 597 s=str2label(i_packet+i_spos,i_name)-1;
nyatla 102:41a5e92e0a8e 598 s+=str2label(i_packet+i_spos+s,"local");
nyatla 102:41a5e92e0a8e 599
nyatla 102:41a5e92e0a8e 600 //レコード圧縮
nyatla 102:41a5e92e0a8e 601 l=i_spos+s;//compressName(i_packet,i_spos,s);
nyatla 102:41a5e92e0a8e 602 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_NSEC);
nyatla 102:41a5e92e0a8e 603 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 102:41a5e92e0a8e 604 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 102:41a5e92e0a8e 605 l+=2+2+4;
nyatla 102:41a5e92e0a8e 606 //A record header
nyatla 102:41a5e92e0a8e 607 if(obuflen<l+2+2+6){
nyatla 102:41a5e92e0a8e 608 return 0;
nyatla 102:41a5e92e0a8e 609 }
nyatla 102:41a5e92e0a8e 610 //NSECレコードを書く
nyatla 102:41a5e92e0a8e 611 *((NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(2+6);
nyatla 102:41a5e92e0a8e 612 l+=2;
nyatla 102:41a5e92e0a8e 613 *(i_packet+l)=0xc0;
nyatla 102:41a5e92e0a8e 614 *(i_packet+l+1)=(NyLPC_TUInt8)i_spos;
nyatla 102:41a5e92e0a8e 615 l+=2;
nyatla 102:41a5e92e0a8e 616 memcpy(i_packet+l,"\x00\x04\x00\x00\x00\x08",6);
nyatla 102:41a5e92e0a8e 617 return l+6;
nyatla 102:41a5e92e0a8e 618 }
nyatla 102:41a5e92e0a8e 619 /**
nyatla 102:41a5e92e0a8e 620 * NSECレコードレスポンスを書きだす。
nyatla 102:41a5e92e0a8e 621 * IPv6わからんし。
nyatla 102:41a5e92e0a8e 622 */
nyatla 102:41a5e92e0a8e 623 static NyLPC_TInt16 writeNSECRecordByQuery(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 obuflen,const NyLPC_TChar* i_query)
nyatla 102:41a5e92e0a8e 624 {
nyatla 102:41a5e92e0a8e 625 NyLPC_TInt16 s;
nyatla 102:41a5e92e0a8e 626 //AnswerはAレコードのみ
nyatla 102:41a5e92e0a8e 627 NyLPC_TInt16 l;
nyatla 102:41a5e92e0a8e 628 s=query2label(i_packet,i_spos,obuflen,i_query);
nyatla 102:41a5e92e0a8e 629 if(s==0){
nyatla 102:41a5e92e0a8e 630 return 0;
nyatla 102:41a5e92e0a8e 631 }
nyatla 102:41a5e92e0a8e 632
nyatla 102:41a5e92e0a8e 633 //レコード圧縮
nyatla 102:41a5e92e0a8e 634 l=i_spos+s;
nyatla 102:41a5e92e0a8e 635 // l=compressName(i_packet,i_spos,s);
nyatla 102:41a5e92e0a8e 636 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_NSEC);
nyatla 102:41a5e92e0a8e 637 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 102:41a5e92e0a8e 638 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 102:41a5e92e0a8e 639 l+=2+2+4;
nyatla 102:41a5e92e0a8e 640 //A record header
nyatla 102:41a5e92e0a8e 641 if(obuflen<l+2+2+6){
nyatla 102:41a5e92e0a8e 642 return 0;
nyatla 102:41a5e92e0a8e 643 }
nyatla 102:41a5e92e0a8e 644 //NSECレコードを書く
nyatla 102:41a5e92e0a8e 645 *((NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(2+6);
nyatla 102:41a5e92e0a8e 646 l+=2;
nyatla 102:41a5e92e0a8e 647 *(i_packet+l)=0xc0;
nyatla 102:41a5e92e0a8e 648 *(i_packet+l+1)=(NyLPC_TUInt8)i_spos;
nyatla 102:41a5e92e0a8e 649 l+=2;
nyatla 102:41a5e92e0a8e 650 memcpy(i_packet+l,"\x00\x04\x00\x00\x00\x08",6);
nyatla 102:41a5e92e0a8e 651 return l+6;
nyatla 102:41a5e92e0a8e 652 }
nyatla 98:6284ce9a0476 653 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 654 {
nyatla 37:fc4b4fd6a649 655 NyLPC_TInt16 l,s;
nyatla 37:fc4b4fd6a649 656 //Header
nyatla 98:6284ce9a0476 657 // s=(NyLPC_TInt16)*(i_question->buf+i_question->qname_pos);
nyatla 37:fc4b4fd6a649 658 //Headerの長さチェック
nyatla 98:6284ce9a0476 659 if(obuflen<i_spos+30+2+2+4){
nyatla 37:fc4b4fd6a649 660 return 0;
nyatla 37:fc4b4fd6a649 661 }
nyatla 37:fc4b4fd6a649 662 //Header書込み
nyatla 98:6284ce9a0476 663 memcpy(i_packet+i_spos,"\x09_services\x07_dns-sd\x04_udp\x05local\x00",30);
nyatla 98:6284ce9a0476 664 s=compressName(i_packet,i_spos,30);
nyatla 98:6284ce9a0476 665 (*(NyLPC_TUInt16*)(i_packet+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
nyatla 98:6284ce9a0476 666 (*(NyLPC_TUInt16*)(i_packet+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
nyatla 98:6284ce9a0476 667 (*(NyLPC_TUInt32*)(i_packet+s+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 668 l=s+2+2+4;
nyatla 37:fc4b4fd6a649 669
nyatla 37:fc4b4fd6a649 670 //Resourceの書込み
nyatla 37:fc4b4fd6a649 671 s=(NyLPC_TInt16)(1+strlen(i_srvlec->protocol)+1+5+1);//逆引き文字列の長さ(デリミタ×3+1)
nyatla 37:fc4b4fd6a649 672 if(obuflen<s+l+2){
nyatla 37:fc4b4fd6a649 673 return 0;
nyatla 37:fc4b4fd6a649 674 }
nyatla 98:6284ce9a0476 675 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_ntohs(s);
nyatla 37:fc4b4fd6a649 676 l+=2;
nyatla 98:6284ce9a0476 677 s=str2label(i_packet+l,i_srvlec->protocol)-1;
nyatla 98:6284ce9a0476 678 s+=str2label(i_packet+l+s,"local");
nyatla 98:6284ce9a0476 679 s=compressName(i_packet,l,s);//圧縮
nyatla 98:6284ce9a0476 680 return s;
nyatla 37:fc4b4fd6a649 681 }
nyatla 98:6284ce9a0476 682 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 683 {
nyatla 37:fc4b4fd6a649 684 NyLPC_TInt16 l,s;
nyatla 37:fc4b4fd6a649 685 NyLPC_TUInt16* rlen;
nyatla 37:fc4b4fd6a649 686 //Header:開始文字数(1)+プレフィクス(n)+終端(1)+local(5)+1
nyatla 37:fc4b4fd6a649 687 s=(NyLPC_TInt16)(1+strlen(i_recode->srv[i_sid].protocol)+1+5+1);
nyatla 37:fc4b4fd6a649 688 //Headerの長さチェック
nyatla 98:6284ce9a0476 689 if(obuflen<i_spos+s+2+2+4){
nyatla 37:fc4b4fd6a649 690 return 0;
nyatla 37:fc4b4fd6a649 691 }
nyatla 37:fc4b4fd6a649 692 //Header書込み
nyatla 98:6284ce9a0476 693 s =str2label(i_packet+i_spos,i_recode->srv[i_sid].protocol)-1;
nyatla 98:6284ce9a0476 694 s+=str2label(i_packet+i_spos+s,"local");
nyatla 98:6284ce9a0476 695 s=compressName(i_packet,i_spos,s);
nyatla 98:6284ce9a0476 696 (*(NyLPC_TUInt16*)(i_packet+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
nyatla 98:6284ce9a0476 697 (*(NyLPC_TUInt16*)(i_packet+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
nyatla 98:6284ce9a0476 698 (*(NyLPC_TUInt32*)(i_packet+s+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 699 l=s+2+2+4;
nyatla 37:fc4b4fd6a649 700
nyatla 37:fc4b4fd6a649 701 //Resourceの書込み
nyatla 37:fc4b4fd6a649 702 s=1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1)
nyatla 37:fc4b4fd6a649 703 if(obuflen<s+l+2){
nyatla 37:fc4b4fd6a649 704 return 0;
nyatla 37:fc4b4fd6a649 705 }
nyatla 98:6284ce9a0476 706 rlen=(NyLPC_TUInt16*)(i_packet+l);
nyatla 37:fc4b4fd6a649 707 l+=2;
nyatla 98:6284ce9a0476 708 s =str2label(i_packet+l,i_recode->name)-1;
nyatla 98:6284ce9a0476 709 s+=str2label(i_packet+l+s,i_recode->srv[i_sid].protocol)-1;
nyatla 98:6284ce9a0476 710 s+=str2label(i_packet+l+s,"local");
nyatla 98:6284ce9a0476 711 s=compressName(i_packet,l,s);//圧縮
nyatla 98:6284ce9a0476 712 (*rlen)=NyLPC_ntohs(s-l);
nyatla 98:6284ce9a0476 713 return s;
nyatla 37:fc4b4fd6a649 714 }
nyatla 37:fc4b4fd6a649 715
nyatla 98:6284ce9a0476 716 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 717 {
nyatla 37:fc4b4fd6a649 718 NyLPC_TInt16 l,s;
nyatla 37:fc4b4fd6a649 719 NyLPC_TUInt16* rlen;
nyatla 37:fc4b4fd6a649 720
nyatla 37:fc4b4fd6a649 721 //SRV Record
nyatla 101:5022828ace54 722 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 37:fc4b4fd6a649 723 if(s==0){
nyatla 37:fc4b4fd6a649 724 return 0;
nyatla 37:fc4b4fd6a649 725 }
nyatla 37:fc4b4fd6a649 726
nyatla 37:fc4b4fd6a649 727 l=1+strlen(i_inst->_ref_record->a)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1)
nyatla 98:6284ce9a0476 728 if(obuflen<s+8+l){
nyatla 37:fc4b4fd6a649 729 return 0;
nyatla 37:fc4b4fd6a649 730 }
nyatla 37:fc4b4fd6a649 731 //IPADDR
nyatla 98:6284ce9a0476 732 rlen=(NyLPC_TUInt16*)(i_packet+s);
nyatla 98:6284ce9a0476 733 (*(NyLPC_TUInt16*)(i_packet+s+2))=NyLPC_HTONS(0);//Priority
nyatla 98:6284ce9a0476 734 (*(NyLPC_TUInt16*)(i_packet+s+4))=NyLPC_HTONS(0);//Weight
nyatla 98:6284ce9a0476 735 (*(NyLPC_TUInt16*)(i_packet+s+6))=NyLPC_HTONS(i_inst->_ref_record->srv[i_sid].port);//PORT
nyatla 37:fc4b4fd6a649 736 l=4*2+s;
nyatla 98:6284ce9a0476 737 s=str2label(i_packet+l,i_inst->_ref_record->a)-1;
nyatla 98:6284ce9a0476 738 s+=str2label(i_packet+l+s,"local");
nyatla 98:6284ce9a0476 739 s=compressName(i_packet,l,s);//圧縮
nyatla 98:6284ce9a0476 740 (*rlen)=NyLPC_HTONS(2+2+2+(s-l));
nyatla 98:6284ce9a0476 741 return s;
nyatla 37:fc4b4fd6a649 742 }
nyatla 98:6284ce9a0476 743 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 744 {
nyatla 37:fc4b4fd6a649 745 NyLPC_TInt16 ret;
nyatla 37:fc4b4fd6a649 746 NyLPC_TInt16 l;
nyatla 37:fc4b4fd6a649 747 //Answer
nyatla 101:5022828ace54 748 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 37:fc4b4fd6a649 749 if(ret==0){
nyatla 37:fc4b4fd6a649 750 return 0;
nyatla 37:fc4b4fd6a649 751 }
nyatla 37:fc4b4fd6a649 752 //name.proto.localを返す。
nyatla 98:6284ce9a0476 753 if(obuflen<ret+2){
nyatla 37:fc4b4fd6a649 754 return 0;
nyatla 37:fc4b4fd6a649 755 }
nyatla 98:6284ce9a0476 756 (*(NyLPC_TUInt16*)(i_packet+ret))=NyLPC_ntohs(0);
nyatla 37:fc4b4fd6a649 757 //proto.name.local.
nyatla 37:fc4b4fd6a649 758 l=ret+2;
nyatla 37:fc4b4fd6a649 759 return l;
nyatla 37:fc4b4fd6a649 760 }
nyatla 37:fc4b4fd6a649 761
nyatla 37:fc4b4fd6a649 762
nyatla 37:fc4b4fd6a649 763
nyatla 37:fc4b4fd6a649 764
nyatla 37:fc4b4fd6a649 765
nyatla 37:fc4b4fd6a649 766
nyatla 37:fc4b4fd6a649 767 static void sendAnnounse(NyLPC_TcMDnsServer_t* i_inst)
nyatla 37:fc4b4fd6a649 768 {
nyatla 37:fc4b4fd6a649 769 char* obuf;
nyatla 37:fc4b4fd6a649 770 NyLPC_TUInt16 obuflen;
nyatla 98:6284ce9a0476 771 NyLPC_TUInt16 l;
nyatla 37:fc4b4fd6a649 772 int i2;
nyatla 37:fc4b4fd6a649 773 for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
nyatla 37:fc4b4fd6a649 774 //Bufferの取得
nyatla 37:fc4b4fd6a649 775 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,TIMEOUT_IN_MS);
nyatla 37:fc4b4fd6a649 776 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 777 return;
nyatla 37:fc4b4fd6a649 778 }
nyatla 102:41a5e92e0a8e 779 l=setResponseHeader(obuf,NULL,1,0,4);
nyatla 98:6284ce9a0476 780 l=writePtrRecord(i_inst->_ref_record,i2,obuf,l,obuflen);
nyatla 98:6284ce9a0476 781 if(l<=0){
nyatla 37:fc4b4fd6a649 782 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 783 }
nyatla 102:41a5e92e0a8e 784 //SRV
nyatla 98:6284ce9a0476 785 l=writeSRVRecord(i_inst,i2,obuf,l,obuflen);
nyatla 98:6284ce9a0476 786 if(l<=0){
nyatla 37:fc4b4fd6a649 787 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 788 }
nyatla 102:41a5e92e0a8e 789 //TXT
nyatla 98:6284ce9a0476 790 l=writeTXTRecord(i_inst,i2,obuf,l,obuflen);
nyatla 98:6284ce9a0476 791 if(l<=0){
nyatla 37:fc4b4fd6a649 792 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 793 }
nyatla 37:fc4b4fd6a649 794 //Aレコード
nyatla 98:6284ce9a0476 795 l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 796 if(l<=0){
nyatla 37:fc4b4fd6a649 797 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 798 }
nyatla 102:41a5e92e0a8e 799 //NSEC
nyatla 102:41a5e92e0a8e 800 l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
nyatla 102:41a5e92e0a8e 801 if(l<=0){
nyatla 102:41a5e92e0a8e 802 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 803 }
nyatla 37:fc4b4fd6a649 804 if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
nyatla 37:fc4b4fd6a649 805 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 806 }
nyatla 37:fc4b4fd6a649 807 }
nyatla 37:fc4b4fd6a649 808 return;
nyatla 37:fc4b4fd6a649 809 ERROR:
nyatla 37:fc4b4fd6a649 810 NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf);
nyatla 37:fc4b4fd6a649 811 return;
nyatla 37:fc4b4fd6a649 812 }
nyatla 37:fc4b4fd6a649 813
nyatla 37:fc4b4fd6a649 814
nyatla 98:6284ce9a0476 815
nyatla 37:fc4b4fd6a649 816 static void sendReply2(NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsHeader* i_dns_header,const struct NyLPC_TDnsQuestion* q)
nyatla 37:fc4b4fd6a649 817 {
nyatla 37:fc4b4fd6a649 818 NyLPC_TInt16 ptr_recode;
nyatla 37:fc4b4fd6a649 819 NyLPC_TInt16 i2;
nyatla 37:fc4b4fd6a649 820 char* obuf;
nyatla 37:fc4b4fd6a649 821 NyLPC_TUInt16 obuflen;
nyatla 98:6284ce9a0476 822 NyLPC_TUInt16 l;
nyatla 37:fc4b4fd6a649 823 //パケットヘッダの生成
nyatla 37:fc4b4fd6a649 824 switch(q->qtype){
nyatla 37:fc4b4fd6a649 825 case NyLPC_TDnsQuestion_QTYPR_SRV:
nyatla 37:fc4b4fd6a649 826 //SRV,A record
nyatla 98:6284ce9a0476 827 ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q);
nyatla 37:fc4b4fd6a649 828 if(ptr_recode<0){
nyatla 37:fc4b4fd6a649 829 goto DROP;
nyatla 37:fc4b4fd6a649 830 }
nyatla 37:fc4b4fd6a649 831 //Bufferの取得
nyatla 37:fc4b4fd6a649 832 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 833 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 834 goto DROP;
nyatla 37:fc4b4fd6a649 835 }
nyatla 37:fc4b4fd6a649 836 l=setResponseHeader(obuf,i_dns_header,1,0,2);
nyatla 98:6284ce9a0476 837 l=writeSRVRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 838 if(l<=0){
nyatla 37:fc4b4fd6a649 839 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 840 }
nyatla 98:6284ce9a0476 841 l=writeTXTRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 842 if(l<=0){
nyatla 37:fc4b4fd6a649 843 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 844 }
nyatla 37:fc4b4fd6a649 845 //Aレコード
nyatla 98:6284ce9a0476 846 l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 847 if(l<=0){
nyatla 37:fc4b4fd6a649 848 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 849 }
nyatla 102:41a5e92e0a8e 850 //NSEC
nyatla 102:41a5e92e0a8e 851 l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
nyatla 102:41a5e92e0a8e 852 if(l<=0){
nyatla 102:41a5e92e0a8e 853 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 854 }
nyatla 102:41a5e92e0a8e 855 break;
nyatla 102:41a5e92e0a8e 856 case NyLPC_TDnsQuestion_QTYPR_AAAA:
nyatla 102:41a5e92e0a8e 857 //自分宛?(name.local)
nyatla 102:41a5e92e0a8e 858 if(!NyLPC_TDnsQuestion_isEqualName(q,i_inst->_ref_record->a,"")){
nyatla 102:41a5e92e0a8e 859 goto DROP;
nyatla 102:41a5e92e0a8e 860 }
nyatla 102:41a5e92e0a8e 861 //Bufferの取得
nyatla 102:41a5e92e0a8e 862 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 102:41a5e92e0a8e 863 if(obuf==NULL){
nyatla 102:41a5e92e0a8e 864 goto DROP;
nyatla 102:41a5e92e0a8e 865 }
nyatla 102:41a5e92e0a8e 866 //Headerのコピー
nyatla 102:41a5e92e0a8e 867 l=setResponseHeader(obuf,i_dns_header,1,0,1);
nyatla 102:41a5e92e0a8e 868 //AAAAレコード
nyatla 102:41a5e92e0a8e 869 l=writeAAAARecordByQuery(obuf,l,obuflen,q->buf+q->qname_pos,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 102:41a5e92e0a8e 870 if(l<=0){
nyatla 102:41a5e92e0a8e 871 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 872 }
nyatla 102:41a5e92e0a8e 873 //NSEC
nyatla 102:41a5e92e0a8e 874 l=writeNSECRecordByQuery(obuf,l,obuflen,q->buf+q->qname_pos);
nyatla 102:41a5e92e0a8e 875 if(l<=0){
nyatla 102:41a5e92e0a8e 876 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 877 }
nyatla 37:fc4b4fd6a649 878 break;
nyatla 37:fc4b4fd6a649 879 case NyLPC_TDnsQuestion_QTYPR_A:
nyatla 37:fc4b4fd6a649 880 //自分宛?(name.local)
nyatla 98:6284ce9a0476 881 if(!NyLPC_TDnsQuestion_isEqualName(q,i_inst->_ref_record->a,"")){
nyatla 37:fc4b4fd6a649 882 goto DROP;
nyatla 37:fc4b4fd6a649 883 }
nyatla 37:fc4b4fd6a649 884 //Bufferの取得
nyatla 37:fc4b4fd6a649 885 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 886 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 887 goto DROP;
nyatla 37:fc4b4fd6a649 888 }
nyatla 37:fc4b4fd6a649 889 //Headerのコピー
nyatla 102:41a5e92e0a8e 890 l=setResponseHeader(obuf,i_dns_header,1,0,1);
nyatla 37:fc4b4fd6a649 891 //Aレコードのみ
nyatla 101:5022828ace54 892 l=writeARecordByQuery(obuf,l,obuflen,q->buf+q->qname_pos,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 893 if(l<=0){
nyatla 37:fc4b4fd6a649 894 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 895 }
nyatla 102:41a5e92e0a8e 896 l=writeNSECRecordByQuery(obuf,l,obuflen,q->buf+q->qname_pos);
nyatla 102:41a5e92e0a8e 897 if(l<=0){
nyatla 102:41a5e92e0a8e 898 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 899 }
nyatla 37:fc4b4fd6a649 900 break;
nyatla 37:fc4b4fd6a649 901 case NyLPC_TDnsQuestion_QTYPR_PTR:
nyatla 98:6284ce9a0476 902 //_service._dns-sd._udpかどうか
nyatla 98:6284ce9a0476 903 if(NyLPC_TDnsQuestion_isEqualName(q,NULL,"_services._dns-sd._udp")){
nyatla 37:fc4b4fd6a649 904 //Bufferの取得
nyatla 37:fc4b4fd6a649 905 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 906 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 907 goto DROP;
nyatla 37:fc4b4fd6a649 908 }
nyatla 37:fc4b4fd6a649 909 l=setResponseHeader(obuf,i_dns_header,i_inst->_ref_record->num_of_srv,0,0);
nyatla 37:fc4b4fd6a649 910 for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
nyatla 98:6284ce9a0476 911 l=writeSdPtrRecord(q,&(i_inst->_ref_record->srv[i2]),obuf,l,obuflen);
nyatla 98:6284ce9a0476 912 if(l<=0){
nyatla 37:fc4b4fd6a649 913 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 914 }
nyatla 37:fc4b4fd6a649 915 }
nyatla 37:fc4b4fd6a649 916 }else{
nyatla 37:fc4b4fd6a649 917 //自分宛?(proto.local)
nyatla 98:6284ce9a0476 918 ptr_recode=NyLPC_TDnsRecord_getMatchPtrIdx(i_inst->_ref_record,q);
nyatla 37:fc4b4fd6a649 919 if(ptr_recode<0){
nyatla 37:fc4b4fd6a649 920 goto DROP;
nyatla 37:fc4b4fd6a649 921 }
nyatla 37:fc4b4fd6a649 922 //Bufferの取得
nyatla 37:fc4b4fd6a649 923 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 924 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 925 goto DROP;
nyatla 37:fc4b4fd6a649 926 }
nyatla 102:41a5e92e0a8e 927 l=setResponseHeader(obuf,i_dns_header,1,0,4);
nyatla 98:6284ce9a0476 928 l=writePtrRecord(i_inst->_ref_record,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 929 if(l<=0){
nyatla 37:fc4b4fd6a649 930 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 931 }
nyatla 98:6284ce9a0476 932 l=writeSRVRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 933 if(l<=0){
nyatla 37:fc4b4fd6a649 934 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 935 }
nyatla 98:6284ce9a0476 936 l=writeTXTRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 937 if(l<=0){
nyatla 37:fc4b4fd6a649 938 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 939 }
nyatla 37:fc4b4fd6a649 940 //Aレコード
nyatla 98:6284ce9a0476 941 l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 942 if(l<=0){
nyatla 37:fc4b4fd6a649 943 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 944 }
nyatla 102:41a5e92e0a8e 945 l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
nyatla 102:41a5e92e0a8e 946 if(l<=0){
nyatla 102:41a5e92e0a8e 947 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 948 }
nyatla 37:fc4b4fd6a649 949 }
nyatla 37:fc4b4fd6a649 950 break;
nyatla 37:fc4b4fd6a649 951 case NyLPC_TDnsQuestion_QTYPR_TXT:
nyatla 37:fc4b4fd6a649 952 //自分宛?(proto.local)
nyatla 98:6284ce9a0476 953 ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q);
nyatla 37:fc4b4fd6a649 954 if(ptr_recode<0){
nyatla 37:fc4b4fd6a649 955 goto DROP;
nyatla 37:fc4b4fd6a649 956 }
nyatla 37:fc4b4fd6a649 957 //Bufferの取得
nyatla 37:fc4b4fd6a649 958 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 102:41a5e92e0a8e 959 l=setResponseHeader(obuf,i_dns_header,1,0,2);
nyatla 98:6284ce9a0476 960 l=writeTXTRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 961 if(l<=0){
nyatla 37:fc4b4fd6a649 962 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 963 }
nyatla 98:6284ce9a0476 964 l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 965 if(l<=0){
nyatla 37:fc4b4fd6a649 966 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 967 }
nyatla 102:41a5e92e0a8e 968 l=writeNSECRecord(obuf,l,obuflen,i_inst->_ref_record->a);
nyatla 102:41a5e92e0a8e 969 if(l<=0){
nyatla 102:41a5e92e0a8e 970 NyLPC_OnErrorGoto(ERROR);
nyatla 102:41a5e92e0a8e 971 }
nyatla 37:fc4b4fd6a649 972 break;
nyatla 37:fc4b4fd6a649 973 default:
nyatla 37:fc4b4fd6a649 974 goto DROP;
nyatla 37:fc4b4fd6a649 975 }
nyatla 37:fc4b4fd6a649 976 if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
nyatla 37:fc4b4fd6a649 977 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 978 }
nyatla 37:fc4b4fd6a649 979 return;
nyatla 37:fc4b4fd6a649 980 ERROR:
nyatla 37:fc4b4fd6a649 981 NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf);
nyatla 37:fc4b4fd6a649 982 DROP:
nyatla 37:fc4b4fd6a649 983 return;
nyatla 37:fc4b4fd6a649 984 }
nyatla 37:fc4b4fd6a649 985 #define CTRL_FLAG_INIT 0x00
nyatla 37:fc4b4fd6a649 986 #define CTRL_FLAG_STARTED 0x80
nyatla 37:fc4b4fd6a649 987 #define CTRL_FLAG_STOP_REQUESTED 0x40
nyatla 37:fc4b4fd6a649 988 #define CTRL_FLAG_PROCESS_PACKET 0x20 //パケット処理中の間1
nyatla 37:fc4b4fd6a649 989
nyatla 37:fc4b4fd6a649 990 static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info)
nyatla 37:fc4b4fd6a649 991 {
nyatla 98:6284ce9a0476 992 NyLPC_TUInt16 in_len;
nyatla 37:fc4b4fd6a649 993 NyLPC_TUInt16 num_of_query;
nyatla 37:fc4b4fd6a649 994 struct NyLPC_TDnsQuestion q;
nyatla 37:fc4b4fd6a649 995 NyLPC_TUInt16 s;
nyatla 37:fc4b4fd6a649 996 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 997
nyatla 37:fc4b4fd6a649 998 if(i_info->peer_port!=MDNS_MCAST_PORT || !NyLPC_TIPv4Addr_isEqual(&MDNS_MCAST_IPADDR,&i_info->ip)){
nyatla 37:fc4b4fd6a649 999 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 1000 }
nyatla 37:fc4b4fd6a649 1001
nyatla 98:6284ce9a0476 1002 num_of_query=getNumberOfQuestion(i_buf,i_info->size);
nyatla 37:fc4b4fd6a649 1003 if(num_of_query==0){
nyatla 37:fc4b4fd6a649 1004 goto DROP;
nyatla 37:fc4b4fd6a649 1005 }
nyatla 98:6284ce9a0476 1006 in_len=sizeof(struct NyLPC_TDnsHeader);
nyatla 37:fc4b4fd6a649 1007 for(i=0;i<num_of_query;i++){
nyatla 37:fc4b4fd6a649 1008 //Queryのパース
nyatla 98:6284ce9a0476 1009
nyatla 98:6284ce9a0476 1010 s=NyLPC_TDnsQuestion_parse(i_buf,i_info->size,in_len,&q);
nyatla 37:fc4b4fd6a649 1011 if(s==0){
nyatla 37:fc4b4fd6a649 1012 goto DROP;
nyatla 37:fc4b4fd6a649 1013 }
nyatla 98:6284ce9a0476 1014 in_len+=s;
nyatla 37:fc4b4fd6a649 1015 sendReply2((NyLPC_TcMDnsServer_t*)i_inst,(const struct NyLPC_TDnsHeader*)i_buf,&q);
nyatla 37:fc4b4fd6a649 1016 }
nyatla 37:fc4b4fd6a649 1017 //パケット処理終了
nyatla 37:fc4b4fd6a649 1018 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 1019 DROP:
nyatla 37:fc4b4fd6a649 1020 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 1021 }
nyatla 37:fc4b4fd6a649 1022
nyatla 37:fc4b4fd6a649 1023 static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst)
nyatla 37:fc4b4fd6a649 1024 {
nyatla 37:fc4b4fd6a649 1025
nyatla 37:fc4b4fd6a649 1026 if(NyLPC_cStopwatch_isExpired(&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw)){
nyatla 37:fc4b4fd6a649 1027 //アナウンス
nyatla 37:fc4b4fd6a649 1028 sendAnnounse(((NyLPC_TcMDnsServer_t*)i_inst));
nyatla 37:fc4b4fd6a649 1029 //TTL(msec)*1000*80%
nyatla 101:5022828ace54 1030 NyLPC_cStopwatch_startExpire((&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw),NyLPC_TcMDns_TTL*1000*4/5);
nyatla 37:fc4b4fd6a649 1031 }
nyatla 37:fc4b4fd6a649 1032 }
nyatla 37:fc4b4fd6a649 1033
nyatla 37:fc4b4fd6a649 1034 NyLPC_TBool NyLPC_cMDnsServer_initialize(
nyatla 48:00d211aac2ec 1035 NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsRecord* i_ref_record)
nyatla 37:fc4b4fd6a649 1036 {
nyatla 37:fc4b4fd6a649 1037 NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw));
nyatla 37:fc4b4fd6a649 1038 NyLPC_cStopwatch_startExpire(&(i_inst->_periodic_sw),1000);
nyatla 37:fc4b4fd6a649 1039 NyLPC_cUdpSocket_initialize(&(i_inst->_super),MDNS_MCAST_PORT,NULL,0);
nyatla 37:fc4b4fd6a649 1040 NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->_super),onPacket);
nyatla 48:00d211aac2ec 1041 NyLPC_cUdpSocket_setOnPeriodicHandler(&(i_inst->_super),onPeriodic);
nyatla 37:fc4b4fd6a649 1042 NyLPC_cUdpSocket_joinMulticast(&(i_inst->_super),&MDNS_MCAST_IPADDR);
nyatla 37:fc4b4fd6a649 1043 i_inst->_ref_record=i_ref_record;
nyatla 37:fc4b4fd6a649 1044 return NyLPC_TBool_TRUE;
nyatla 37:fc4b4fd6a649 1045 }
nyatla 37:fc4b4fd6a649 1046 void NyLPC_cMDnsServer_finalize(
nyatla 37:fc4b4fd6a649 1047 NyLPC_TcMDnsServer_t* i_inst)
nyatla 37:fc4b4fd6a649 1048 {
nyatla 37:fc4b4fd6a649 1049 NyLPC_cUdpSocket_finalize(&(i_inst->_super));
nyatla 37:fc4b4fd6a649 1050 NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw));
nyatla 37:fc4b4fd6a649 1051 }
nyatla 37:fc4b4fd6a649 1052
nyatla 37:fc4b4fd6a649 1053
nyatla 37:fc4b4fd6a649 1054