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:
Mon Oct 27 11:21:29 2014 +0000
Revision:
101:5022828ace54
Parent:
98:6284ce9a0476
Child:
102:41a5e92e0a8e
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 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 37:fc4b4fd6a649 79 #define NyLPC_TDnsQuestion_QCLASS_IN 1
nyatla 37:fc4b4fd6a649 80 #define NyLPC_TDnsQuestion_QCLASS_CH 3
nyatla 37:fc4b4fd6a649 81 #define NyLPC_TDnsQuestion_QCLASS_HS 4
nyatla 37:fc4b4fd6a649 82 #define NyLPC_TDnsQuestion_QTYPR_SRV 33
nyatla 101:5022828ace54 83 #define NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH 0x8000
nyatla 101:5022828ace54 84
nyatla 37:fc4b4fd6a649 85
nyatla 37:fc4b4fd6a649 86 /**************************************************
nyatla 37:fc4b4fd6a649 87 * TLabelCache
nyatla 37:fc4b4fd6a649 88 **************************************************/
nyatla 98:6284ce9a0476 89 /**
nyatla 98:6284ce9a0476 90 * nameフィールドの文字列圧縮を解除して圧縮後のテキストポインタを返します。
nyatla 98:6284ce9a0476 91 */
nyatla 98:6284ce9a0476 92 static const char* getExtractNamePos(const char* i_packet_buf, const char* i_spos)
nyatla 37:fc4b4fd6a649 93 {
nyatla 98:6284ce9a0476 94 NyLPC_TUInt8 limit=0;
nyatla 98:6284ce9a0476 95 const char* s = i_spos;// question->buf + pos;//クエリの解析位置
nyatla 98:6284ce9a0476 96 for (;;){
nyatla 98:6284ce9a0476 97 switch (*(const NyLPC_TUInt8*)s){
nyatla 98:6284ce9a0476 98 case 0x00:
nyatla 98:6284ce9a0476 99 //queryが先に終了に到達するのはおかしい。
nyatla 98:6284ce9a0476 100 return NULL;
nyatla 98:6284ce9a0476 101 case 0xc0:
nyatla 98:6284ce9a0476 102 s = i_packet_buf + *((const NyLPC_TUInt8*)s + 1);//参照先にジャンプ
nyatla 98:6284ce9a0476 103 if (i_spos<=s){
nyatla 98:6284ce9a0476 104 //後方参照ならエラー
nyatla 98:6284ce9a0476 105 return NULL;
nyatla 98:6284ce9a0476 106 }
nyatla 98:6284ce9a0476 107 limit++;
nyatla 98:6284ce9a0476 108 if (limit > 32){
nyatla 98:6284ce9a0476 109 return NULL;
nyatla 98:6284ce9a0476 110 }
nyatla 98:6284ce9a0476 111 continue;
nyatla 98:6284ce9a0476 112 default:
nyatla 98:6284ce9a0476 113 break;
nyatla 98:6284ce9a0476 114 }
nyatla 98:6284ce9a0476 115 break;
nyatla 98:6284ce9a0476 116 }
nyatla 98:6284ce9a0476 117 return s;
nyatla 98:6284ce9a0476 118 }
nyatla 98:6284ce9a0476 119
nyatla 98:6284ce9a0476 120 /**
nyatla 98:6284ce9a0476 121 * 展開しない圧縮文字列の長さを返す
nyatla 98:6284ce9a0476 122 */
nyatla 101:5022828ace54 123 static NyLPC_TInt16 sizeofCompressName(const char* i_str)
nyatla 37:fc4b4fd6a649 124 {
nyatla 98:6284ce9a0476 125 NyLPC_TInt16 l = 0;
nyatla 98:6284ce9a0476 126 NyLPC_TUInt8 c;
nyatla 98:6284ce9a0476 127 for (;;){
nyatla 98:6284ce9a0476 128 c = (NyLPC_TUInt8)*(i_str + l);
nyatla 98:6284ce9a0476 129 switch (c){
nyatla 98:6284ce9a0476 130 case 0xc0:
nyatla 98:6284ce9a0476 131 return l + 2;
nyatla 98:6284ce9a0476 132 case 0x00:
nyatla 98:6284ce9a0476 133 return l + 1;
nyatla 98:6284ce9a0476 134 }
nyatla 98:6284ce9a0476 135 l += c + 1;
nyatla 98:6284ce9a0476 136 }
nyatla 37:fc4b4fd6a649 137 }
nyatla 98:6284ce9a0476 138 /**
nyatla 98:6284ce9a0476 139 * @return
nyatla 98:6284ce9a0476 140 * 圧縮するとtrue i_nameは2文字に圧縮される。
nyatla 98:6284ce9a0476 141 */
nyatla 98:6284ce9a0476 142 static NyLPC_TBool compressNameB(char* i_packet, NyLPC_TUInt16 i_spos, NyLPC_TUInt16 i_name_pos)
nyatla 37:fc4b4fd6a649 143 {
nyatla 98:6284ce9a0476 144 NyLPC_TUInt16 ret;
nyatla 98:6284ce9a0476 145 const char* p; //プロトコル文字列の解析開始位置
nyatla 98:6284ce9a0476 146 const char* s = i_packet + i_spos; //クエリの解析位置
nyatla 98:6284ce9a0476 147 const char* s2;
nyatla 98:6284ce9a0476 148
nyatla 98:6284ce9a0476 149 //Protocol
nyatla 98:6284ce9a0476 150 for (;;){
nyatla 98:6284ce9a0476 151 //0xc0参照の解決
nyatla 98:6284ce9a0476 152 s = getExtractNamePos(i_packet, s);
nyatla 98:6284ce9a0476 153 if (s == NULL){
nyatla 98:6284ce9a0476 154 //一致しない
nyatla 98:6284ce9a0476 155 return 0;
nyatla 98:6284ce9a0476 156 }
nyatla 98:6284ce9a0476 157 for (;;){
nyatla 98:6284ce9a0476 158 //検索位置のドメインを遡る
nyatla 98:6284ce9a0476 159 if (*s == *(i_packet+i_name_pos)){
nyatla 98:6284ce9a0476 160 //先頭一致
nyatla 98:6284ce9a0476 161 p = i_packet + i_name_pos;
nyatla 98:6284ce9a0476 162 s2 = getExtractNamePos(i_packet, s);
nyatla 98:6284ce9a0476 163 ret = (NyLPC_TUInt16)(s2 - i_packet);
nyatla 98:6284ce9a0476 164 for (;;){
nyatla 98:6284ce9a0476 165 //一致判定
nyatla 98:6284ce9a0476 166 if (s2 == NULL){
nyatla 98:6284ce9a0476 167 break;
nyatla 98:6284ce9a0476 168 }
nyatla 98:6284ce9a0476 169
nyatla 98:6284ce9a0476 170 if (memcmp(p, s2, (*(NyLPC_TUInt8*)s2 + 1)) != 0){
nyatla 98:6284ce9a0476 171 //不一致
nyatla 98:6284ce9a0476 172 break;
nyatla 98:6284ce9a0476 173 }
nyatla 98:6284ce9a0476 174 //検出位置の移動
nyatla 98:6284ce9a0476 175 p += (*(NyLPC_TUInt8*)s2) + 1;
nyatla 98:6284ce9a0476 176 s2 += (*(NyLPC_TUInt8*)s2) + 1;
nyatla 98:6284ce9a0476 177 if (*p == 0 && *s2 == 0){
nyatla 98:6284ce9a0476 178 //charで扱ってるクライアントのコケ防止
nyatla 98:6284ce9a0476 179 if(ret>0xff){
nyatla 98:6284ce9a0476 180 return 0;
nyatla 98:6284ce9a0476 181 }
nyatla 98:6284ce9a0476 182 *(i_packet + i_name_pos + 0) = 0xc0;
nyatla 98:6284ce9a0476 183 *(i_packet + i_name_pos + 1) = (NyLPC_TUInt8)ret;
nyatla 98:6284ce9a0476 184 return ret;
nyatla 98:6284ce9a0476 185 }
nyatla 98:6284ce9a0476 186 s2 = getExtractNamePos(i_packet, s2);
nyatla 37:fc4b4fd6a649 187 }
nyatla 98:6284ce9a0476 188 }
nyatla 98:6284ce9a0476 189 //一致しない->検索パターンの次のフラグメントを調べる
nyatla 98:6284ce9a0476 190 s += (*(NyLPC_TUInt8*)s) + 1;
nyatla 98:6284ce9a0476 191 break;
nyatla 98:6284ce9a0476 192 }
nyatla 37:fc4b4fd6a649 193 }
nyatla 98:6284ce9a0476 194 }
nyatla 98:6284ce9a0476 195 /**
nyatla 98:6284ce9a0476 196 * mDNSパケットからi_nameを検索する。
nyatla 98:6284ce9a0476 197 * i_targetはi_packetに含まれ、NULL終端されていること
nyatla 98:6284ce9a0476 198 * @return 0 圧縮失敗/その他:圧縮後のパケットサイズ
nyatla 98:6284ce9a0476 199 *
nyatla 98:6284ce9a0476 200 */
nyatla 98:6284ce9a0476 201 static NyLPC_TUInt16 compressNameA(char* i_packet, NyLPC_TUInt16 i_name_start,NyLPC_TUInt16 i_name_pos)
nyatla 98:6284ce9a0476 202 {
nyatla 98:6284ce9a0476 203 NyLPC_TUInt16 s = 12;
nyatla 98:6284ce9a0476 204 for (;;){
nyatla 98:6284ce9a0476 205 if (i_name_start <= s){
nyatla 98:6284ce9a0476 206 //圧縮対象文字列に到達
nyatla 98:6284ce9a0476 207 return 0;
nyatla 98:6284ce9a0476 208 }
nyatla 98:6284ce9a0476 209 //i_targetとAnswer文字列が等しいか確認
nyatla 98:6284ce9a0476 210 if (compressNameB(i_packet, s, i_name_pos)){
nyatla 98:6284ce9a0476 211 return i_name_pos + 2;
nyatla 98:6284ce9a0476 212 }
nyatla 98:6284ce9a0476 213 //
nyatla 98:6284ce9a0476 214 s += sizeofCompressName(i_packet+s);
nyatla 98:6284ce9a0476 215 //CLASS PTR/SRVの場合のみデータセクションも探す
nyatla 98:6284ce9a0476 216 switch (NyLPC_ntohs(*(NyLPC_TUInt16*)(i_packet+s))){
nyatla 98:6284ce9a0476 217 case NyLPC_TDnsQuestion_QTYPR_SRV:
nyatla 98:6284ce9a0476 218 s += 2+2+2;//PTRよりちょっと多い
nyatla 98:6284ce9a0476 219 case NyLPC_TDnsQuestion_QTYPR_PTR:
nyatla 98:6284ce9a0476 220 s += 2 + 2 + 4 + 2;
nyatla 98:6284ce9a0476 221 if (i_name_start <= s){
nyatla 98:6284ce9a0476 222 //圧縮対象文字列に到達
nyatla 98:6284ce9a0476 223 return 0;
nyatla 98:6284ce9a0476 224 }
nyatla 98:6284ce9a0476 225 // //データは圧縮ポインタにしない方がいいらしい。
nyatla 98:6284ce9a0476 226 // if (compressNameB(i_packet, s, i_name_pos)){
nyatla 98:6284ce9a0476 227 // return i_name_pos + 2;
nyatla 98:6284ce9a0476 228 // }
nyatla 98:6284ce9a0476 229 break;
nyatla 98:6284ce9a0476 230 default:
nyatla 98:6284ce9a0476 231 //ヘッダとデータサイズぶんだけ移動して終わり
nyatla 98:6284ce9a0476 232 s += 2 + 2 + 4 + 2;
nyatla 98:6284ce9a0476 233 break;
nyatla 98:6284ce9a0476 234 }
nyatla 98:6284ce9a0476 235 s += NyLPC_ntohs(*((NyLPC_TUInt16*)(i_packet+s - 2)));
nyatla 98:6284ce9a0476 236 }
nyatla 98:6284ce9a0476 237 }
nyatla 98:6284ce9a0476 238 /**
nyatla 98:6284ce9a0476 239 * @return
nyatla 98:6284ce9a0476 240 * 新しいi_packetの長さ
nyatla 98:6284ce9a0476 241 */
nyatla 98:6284ce9a0476 242 static NyLPC_TUInt16 compressName(char* i_packet, NyLPC_TUInt16 i_name_pos, NyLPC_TUInt16 i_name_len)
nyatla 98:6284ce9a0476 243 {
nyatla 98:6284ce9a0476 244 NyLPC_TUInt16 p;
nyatla 98:6284ce9a0476 245 NyLPC_TUInt16 s = i_name_pos;
nyatla 98:6284ce9a0476 246 for (;;){
nyatla 98:6284ce9a0476 247 p = compressNameA(i_packet, i_name_pos,s);
nyatla 98:6284ce9a0476 248 //i_targetとAnswer文字列が等しいか確認
nyatla 98:6284ce9a0476 249 if (p != 0){
nyatla 98:6284ce9a0476 250 return p;
nyatla 98:6284ce9a0476 251 }
nyatla 98:6284ce9a0476 252 s += (NyLPC_TUInt16)*(i_packet + s) + 1;
nyatla 98:6284ce9a0476 253 if (*(i_packet+s) == 0){
nyatla 98:6284ce9a0476 254 //圧縮対象文字列に到達
nyatla 98:6284ce9a0476 255 return (i_name_len + i_name_pos);
nyatla 98:6284ce9a0476 256 }
nyatla 98:6284ce9a0476 257 }
nyatla 37:fc4b4fd6a649 258 }
nyatla 37:fc4b4fd6a649 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 * 受領可能なQuestionか確認する
nyatla 37:fc4b4fd6a649 266 * @return
nyatla 37:fc4b4fd6a649 267 * 受領可能なQuestionの数
nyatla 37:fc4b4fd6a649 268 *
nyatla 37:fc4b4fd6a649 269 */
nyatla 98:6284ce9a0476 270 static NyLPC_TUInt16 getNumberOfQuestion(const void* i_packet, NyLPC_TUInt16 i_len)
nyatla 37:fc4b4fd6a649 271 {
nyatla 98:6284ce9a0476 272 struct NyLPC_TDnsHeader* ptr = (struct NyLPC_TDnsHeader*)i_packet;
nyatla 37:fc4b4fd6a649 273 NyLPC_TUInt16 t;
nyatla 98:6284ce9a0476 274 if (i_len<sizeof(struct NyLPC_TDnsHeader)){
nyatla 37:fc4b4fd6a649 275 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 276 }
nyatla 37:fc4b4fd6a649 277 //questrionの確認
nyatla 37:fc4b4fd6a649 278 //QR==0 && op==0 && tc=0
nyatla 98:6284ce9a0476 279 t = NyLPC_ntohs(ptr->flag);
nyatla 98:6284ce9a0476 280 if (((t & NyLPC_TDnsHeader_FLAG_MASK_QR) != 0) &&
nyatla 98:6284ce9a0476 281 ((t & NyLPC_TDnsHeader_FLAG_MASK_OPCODE) != 0) &&
nyatla 98:6284ce9a0476 282 ((t & NyLPC_TDnsHeader_FLAG_MASK_TC) != 0))
nyatla 37:fc4b4fd6a649 283 {
nyatla 37:fc4b4fd6a649 284 //this is response
nyatla 37:fc4b4fd6a649 285 return 0;
nyatla 37:fc4b4fd6a649 286 }
nyatla 37:fc4b4fd6a649 287 return NyLPC_ntohs(ptr->qd);
nyatla 37:fc4b4fd6a649 288 }
nyatla 37:fc4b4fd6a649 289
nyatla 98:6284ce9a0476 290 /**
nyatla 98:6284ce9a0476 291 * [i_name].[i_protocol].localをquestionと比較します。i_nameは省略ができます。
nyatla 101:5022828ace54 292 * i_nameはincasesensitiveです。
nyatla 98:6284ce9a0476 293 * @return 等しい場合true
nyatla 98:6284ce9a0476 294 */
nyatla 98:6284ce9a0476 295 static NyLPC_TBool NyLPC_TDnsQuestion_isEqualName(const struct NyLPC_TDnsQuestion* question, const char* i_name, const char* i_protocol)
nyatla 37:fc4b4fd6a649 296 {
nyatla 98:6284ce9a0476 297 NyLPC_TUInt8 tmp;
nyatla 98:6284ce9a0476 298 const char* p; //プロトコル文字列の解析開始位置
nyatla 98:6284ce9a0476 299 const char* s = question->buf + (NyLPC_TUInt8)question->qname_pos; //クエリの解析位置
nyatla 98:6284ce9a0476 300
nyatla 98:6284ce9a0476 301 //Domain
nyatla 98:6284ce9a0476 302 if (i_name != NULL){
nyatla 98:6284ce9a0476 303 //0xc0参照の解決
nyatla 98:6284ce9a0476 304 s = getExtractNamePos(question->buf, s);
nyatla 98:6284ce9a0476 305 if (s == NULL){
nyatla 98:6284ce9a0476 306 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 307 }
nyatla 98:6284ce9a0476 308 tmp = (NyLPC_TUInt8)strlen(i_name);
nyatla 101:5022828ace54 309 if (tmp != *s || NyLPC_strnicmp(s + 1, i_name, tmp) != 0){
nyatla 98:6284ce9a0476 310 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 311 }
nyatla 98:6284ce9a0476 312 s += (*s) + 1;
nyatla 98:6284ce9a0476 313 }else{
nyatla 98:6284ce9a0476 314 s = question->buf + (NyLPC_TUInt8)question->qname_pos;//クエリの解析位置
nyatla 98:6284ce9a0476 315 }
nyatla 98:6284ce9a0476 316 p = i_protocol;
nyatla 98:6284ce9a0476 317 //Protocol
nyatla 98:6284ce9a0476 318 for (;;){
nyatla 98:6284ce9a0476 319 //0xc0参照の解決
nyatla 98:6284ce9a0476 320 s = getExtractNamePos(question->buf, s);
nyatla 98:6284ce9a0476 321 if (s == NULL){
nyatla 98:6284ce9a0476 322 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 323 }
nyatla 98:6284ce9a0476 324 //SRVの末端到達
nyatla 98:6284ce9a0476 325 if (*p == 0){
nyatla 98:6284ce9a0476 326 if (question->buf + question->buf_len<s + 7 + 4){
nyatla 98:6284ce9a0476 327 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 328 }
nyatla 98:6284ce9a0476 329 return (memcmp("\5local\0", s, 7) == 0);
nyatla 98:6284ce9a0476 330 }
nyatla 98:6284ce9a0476 331 //有効サイズなら一致検出
nyatla 98:6284ce9a0476 332 if (question->buf + question->buf_len<s + 1 + (NyLPC_TUInt8)*s + 4){
nyatla 98:6284ce9a0476 333 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 334 }
nyatla 98:6284ce9a0476 335 if (memcmp(p, s + 1, (NyLPC_TUInt8)*s) != 0){
nyatla 98:6284ce9a0476 336 //不一致
nyatla 98:6284ce9a0476 337 return NyLPC_TBool_FALSE;
nyatla 98:6284ce9a0476 338 }
nyatla 98:6284ce9a0476 339 //検出位置の移動
nyatla 98:6284ce9a0476 340 p += (*s) + 1;
nyatla 98:6284ce9a0476 341 s += (*s) + 1;
nyatla 98:6284ce9a0476 342 }
nyatla 98:6284ce9a0476 343 }
nyatla 98:6284ce9a0476 344
nyatla 98:6284ce9a0476 345
nyatla 98:6284ce9a0476 346 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 347 {
nyatla 37:fc4b4fd6a649 348 NyLPC_TUInt16 i;
nyatla 98:6284ce9a0476 349 //解析開始位置を計算
nyatla 98:6284ce9a0476 350 NyLPC_TUInt16 qlen = 0;
nyatla 98:6284ce9a0476 351 for (i = i_parse_start; i<i_packet_len - 4; i++){
nyatla 98:6284ce9a0476 352 switch ((NyLPC_TUInt8)(*(i_packet + i))){
nyatla 98:6284ce9a0476 353 case 0x00:
nyatla 98:6284ce9a0476 354 qlen++;
nyatla 98:6284ce9a0476 355 break;
nyatla 98:6284ce9a0476 356 case 0xc0:
nyatla 98:6284ce9a0476 357 qlen+=2;
nyatla 98:6284ce9a0476 358 break;
nyatla 98:6284ce9a0476 359 default:
nyatla 98:6284ce9a0476 360 qlen++;
nyatla 98:6284ce9a0476 361 continue;
nyatla 37:fc4b4fd6a649 362 }
nyatla 98:6284ce9a0476 363 o_val->buf = i_packet;
nyatla 98:6284ce9a0476 364 o_val->buf_len = i_packet_len;
nyatla 98:6284ce9a0476 365 o_val->qname_pos = i_parse_start;
nyatla 98:6284ce9a0476 366 o_val->qtype = NyLPC_ntohs(*(NyLPC_TUInt16*)(i_packet+i_parse_start + qlen));
nyatla 98:6284ce9a0476 367 o_val->qclass = NyLPC_ntohs(*(NyLPC_TUInt16*)(i_packet+i_parse_start + qlen + sizeof(NyLPC_TUInt16)));
nyatla 98:6284ce9a0476 368 return qlen + 4;
nyatla 37:fc4b4fd6a649 369 }
nyatla 37:fc4b4fd6a649 370 return 0;
nyatla 37:fc4b4fd6a649 371 }
nyatla 37:fc4b4fd6a649 372
nyatla 37:fc4b4fd6a649 373 /**
nyatla 37:fc4b4fd6a649 374 * DNSレコードのPRTフィールドとDNSラベル文字列を比較する。
nyatla 37:fc4b4fd6a649 375 */
nyatla 98:6284ce9a0476 376 static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchPtrIdx(const struct NyLPC_TDnsRecord* i_struct,const struct NyLPC_TDnsQuestion* question)
nyatla 37:fc4b4fd6a649 377 {
nyatla 37:fc4b4fd6a649 378 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 379 for(i=0;i<i_struct->num_of_srv;i++){
nyatla 98:6284ce9a0476 380 if(NyLPC_TDnsQuestion_isEqualName(question,NULL,i_struct->srv[i].protocol)){
nyatla 37:fc4b4fd6a649 381 return i;
nyatla 37:fc4b4fd6a649 382 }
nyatla 37:fc4b4fd6a649 383 }
nyatla 37:fc4b4fd6a649 384 return -1;
nyatla 37:fc4b4fd6a649 385 }
nyatla 98:6284ce9a0476 386 static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchSrvIdx(const struct NyLPC_TDnsRecord* i_struct,const struct NyLPC_TDnsQuestion* question)
nyatla 37:fc4b4fd6a649 387 {
nyatla 37:fc4b4fd6a649 388 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 389 for(i=0;i<i_struct->num_of_srv;i++){
nyatla 98:6284ce9a0476 390 if(NyLPC_TDnsQuestion_isEqualName(question,i_struct->name,i_struct->srv[i].protocol)){
nyatla 37:fc4b4fd6a649 391 return i;
nyatla 37:fc4b4fd6a649 392 }
nyatla 37:fc4b4fd6a649 393 }
nyatla 37:fc4b4fd6a649 394 return -1;
nyatla 37:fc4b4fd6a649 395 }
nyatla 98:6284ce9a0476 396
nyatla 37:fc4b4fd6a649 397
nyatla 37:fc4b4fd6a649 398
nyatla 37:fc4b4fd6a649 399 /**
nyatla 37:fc4b4fd6a649 400 * '.'区切り文字列をDNS形式の[n]text[n]text\0へ変換する。
nyatla 37:fc4b4fd6a649 401 * @return
nyatla 37:fc4b4fd6a649 402 * 変換後のデータブロックの長さin byte
nyatla 37:fc4b4fd6a649 403 * 終端の\0の長さを含みます。
nyatla 37:fc4b4fd6a649 404 */
nyatla 37:fc4b4fd6a649 405 static NyLPC_TInt16 str2label(NyLPC_TChar* buf,const NyLPC_TChar* name)
nyatla 37:fc4b4fd6a649 406 {
nyatla 37:fc4b4fd6a649 407 //proto文字列の変換
nyatla 37:fc4b4fd6a649 408 NyLPC_TChar* lp;
nyatla 37:fc4b4fd6a649 409 const NyLPC_TChar* n=name;
nyatla 37:fc4b4fd6a649 410 NyLPC_TChar* b=buf;
nyatla 37:fc4b4fd6a649 411 while(*n!='\0'){
nyatla 37:fc4b4fd6a649 412 lp=b;
nyatla 37:fc4b4fd6a649 413 b++;
nyatla 37:fc4b4fd6a649 414 for(;strchr(".\0",*n)==NULL;){
nyatla 37:fc4b4fd6a649 415 *b=*n;
nyatla 37:fc4b4fd6a649 416 b++;
nyatla 37:fc4b4fd6a649 417 n++;
nyatla 37:fc4b4fd6a649 418 }
nyatla 37:fc4b4fd6a649 419 *lp=(char)(b-lp-1);
nyatla 37:fc4b4fd6a649 420 if(*n!='\0'){
nyatla 37:fc4b4fd6a649 421 n++;
nyatla 37:fc4b4fd6a649 422 }
nyatla 37:fc4b4fd6a649 423 }
nyatla 37:fc4b4fd6a649 424 *b='\0';
nyatla 37:fc4b4fd6a649 425 b++;
nyatla 37:fc4b4fd6a649 426 return b-buf;
nyatla 37:fc4b4fd6a649 427 }
nyatla 37:fc4b4fd6a649 428
nyatla 37:fc4b4fd6a649 429 /**
nyatla 37:fc4b4fd6a649 430 * ResourceHeaderのライタ
nyatla 101:5022828ace54 431 *//*
nyatla 98:6284ce9a0476 432 static NyLPC_TInt16 writeResourceHeader(char* i_packet,NyLPC_TInt16 i_spos,NyLPC_TInt16 buflen,const char* i_name,NyLPC_TUInt16 i_type,NyLPC_TUInt16 i_class)
nyatla 37:fc4b4fd6a649 433 {
nyatla 37:fc4b4fd6a649 434 NyLPC_TInt16 s;
nyatla 37:fc4b4fd6a649 435 NyLPC_TInt16 l=1+(NyLPC_TInt16)strlen(i_name)+1+5+1;
nyatla 98:6284ce9a0476 436 if(buflen<i_spos+l+4+4){
nyatla 37:fc4b4fd6a649 437 return 0;
nyatla 37:fc4b4fd6a649 438 }
nyatla 98:6284ce9a0476 439 s=str2label(i_packet+i_spos,i_name)-1;
nyatla 98:6284ce9a0476 440 s+=str2label(i_packet+i_spos+s,"local");
nyatla 98:6284ce9a0476 441 //レコード圧縮
nyatla 98:6284ce9a0476 442 l=compressName(i_packet,i_spos,s);
nyatla 98:6284ce9a0476 443 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(i_type);
nyatla 98:6284ce9a0476 444 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(i_class);
nyatla 98:6284ce9a0476 445 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 446 return l+2+2+4;
nyatla 101:5022828ace54 447 }*/
nyatla 37:fc4b4fd6a649 448
nyatla 98:6284ce9a0476 449 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 450 {
nyatla 98:6284ce9a0476 451 NyLPC_TInt16 s;
nyatla 37:fc4b4fd6a649 452 NyLPC_TInt16 l=(NyLPC_TInt16)(1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1);
nyatla 98:6284ce9a0476 453 if(buflen<i_spos+l+2+2+4){
nyatla 37:fc4b4fd6a649 454 return 0;
nyatla 37:fc4b4fd6a649 455 }
nyatla 98:6284ce9a0476 456 s=str2label(i_packet+i_spos,i_recode->name)-1;
nyatla 98:6284ce9a0476 457 s+=str2label(i_packet+i_spos+s,i_recode->srv[i_sid].protocol)-1;
nyatla 98:6284ce9a0476 458 s+=str2label(i_packet+i_spos+s,"local");
nyatla 98:6284ce9a0476 459 l=compressName(i_packet,i_spos,s);//圧縮
nyatla 98:6284ce9a0476 460 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(i_type);
nyatla 98:6284ce9a0476 461 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(i_class);
nyatla 98:6284ce9a0476 462 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 463 return l+2+2+4;
nyatla 37:fc4b4fd6a649 464 }
nyatla 37:fc4b4fd6a649 465
nyatla 98:6284ce9a0476 466 /**
nyatla 98:6284ce9a0476 467 * パケットヘッダを書き込みます。
nyatla 98:6284ce9a0476 468 * @return パケットサイズ
nyatla 98:6284ce9a0476 469 */
nyatla 98:6284ce9a0476 470 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 471 {
nyatla 98:6284ce9a0476 472 struct NyLPC_TDnsHeader* p=(struct NyLPC_TDnsHeader*)i_packet;
nyatla 37:fc4b4fd6a649 473 if(i_in_dns_header!=NULL){
nyatla 37:fc4b4fd6a649 474 memcpy(p,i_in_dns_header,sizeof(struct NyLPC_TDnsHeader));
nyatla 37:fc4b4fd6a649 475 p->flag=p->flag | NyLPC_HTONS(NyLPC_TDnsHeader_FLAG_MASK_QR|NyLPC_TDnsHeader_FLAG_MASK_AA);
nyatla 37:fc4b4fd6a649 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 }else{
nyatla 37:fc4b4fd6a649 478 p->flag=0;
nyatla 37:fc4b4fd6a649 479 p->id=0;
nyatla 37:fc4b4fd6a649 480 }
nyatla 37:fc4b4fd6a649 481 p->qd=0;
nyatla 37:fc4b4fd6a649 482 p->an=NyLPC_HTONS(i_an_count);
nyatla 37:fc4b4fd6a649 483 p->ns=NyLPC_HTONS(i_ns_count);
nyatla 37:fc4b4fd6a649 484 p->ar=NyLPC_HTONS(i_ar_count);
nyatla 37:fc4b4fd6a649 485 return sizeof(struct NyLPC_TDnsHeader);
nyatla 37:fc4b4fd6a649 486 }
nyatla 101:5022828ace54 487 /**
nyatla 101:5022828ace54 488 * ドメイン名からAレコードレスポンスを書きだす。
nyatla 101:5022828ace54 489 */
nyatla 101:5022828ace54 490 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 491 {
nyatla 98:6284ce9a0476 492 NyLPC_TInt16 s;
nyatla 37:fc4b4fd6a649 493 //AnswerはAレコードのみ
nyatla 101:5022828ace54 494 NyLPC_TInt16 l=1+(NyLPC_TInt16)strlen(i_name)+1+5+1;
nyatla 101:5022828ace54 495 if(obuflen<i_spos+l+4+4){
nyatla 101:5022828ace54 496 return 0;
nyatla 101:5022828ace54 497 }
nyatla 101:5022828ace54 498 s=str2label(i_packet+i_spos,i_name)-1;
nyatla 101:5022828ace54 499 s+=str2label(i_packet+i_spos+s,"local");
nyatla 101:5022828ace54 500 //レコード圧縮
nyatla 101:5022828ace54 501 l=compressName(i_packet,i_spos,s);
nyatla 101:5022828ace54 502 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_A);
nyatla 101:5022828ace54 503 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 101:5022828ace54 504 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 101:5022828ace54 505 l+=2+2+4;
nyatla 37:fc4b4fd6a649 506 //A record header
nyatla 101:5022828ace54 507 if(obuflen<l+6){
nyatla 37:fc4b4fd6a649 508 return 0;
nyatla 37:fc4b4fd6a649 509 }
nyatla 37:fc4b4fd6a649 510 //Aレコードを書く
nyatla 37:fc4b4fd6a649 511 //IPADDR
nyatla 101:5022828ace54 512 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(4);
nyatla 101:5022828ace54 513 (*(NyLPC_TUInt32*)(i_packet+l+2))=ip->v;
nyatla 101:5022828ace54 514 return l+6;
nyatla 37:fc4b4fd6a649 515 }
nyatla 101:5022828ace54 516 /**
nyatla 101:5022828ace54 517 * AレコードクエリからAレコードレスポンスを書きだす。
nyatla 101:5022828ace54 518 */
nyatla 101:5022828ace54 519 inline 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 520 {
nyatla 101:5022828ace54 521 const char* n;
nyatla 101:5022828ace54 522 NyLPC_TInt16 s;
nyatla 101:5022828ace54 523 //AnswerはAレコードのみ
nyatla 101:5022828ace54 524 NyLPC_TInt16 l;
nyatla 101:5022828ace54 525 s=0;
nyatla 101:5022828ace54 526 for(;;){
nyatla 101:5022828ace54 527 n=getExtractNamePos(i_query,i_query+s);
nyatla 101:5022828ace54 528 if(n==NULL){
nyatla 101:5022828ace54 529 *(i_packet+i_spos+s)=0;
nyatla 101:5022828ace54 530 s++;
nyatla 101:5022828ace54 531 break;
nyatla 101:5022828ace54 532 }else{
nyatla 101:5022828ace54 533 memcpy(i_packet+i_spos+s,i_query+s,((NyLPC_TUInt8)*n)+1);
nyatla 101:5022828ace54 534 s+=((NyLPC_TUInt8)*n)+1;
nyatla 101:5022828ace54 535 if(obuflen<i_spos+s+1+4+4){
nyatla 101:5022828ace54 536 return 0;
nyatla 101:5022828ace54 537 }
nyatla 101:5022828ace54 538 }
nyatla 101:5022828ace54 539 }
nyatla 101:5022828ace54 540 //レコード圧縮
nyatla 101:5022828ace54 541 l=compressName(i_packet,i_spos,s);
nyatla 101:5022828ace54 542 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_A);
nyatla 101:5022828ace54 543 (*(NyLPC_TUInt16*)(i_packet+l+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN|NyLPC_TDnsQuestion_QCLASS_CACHE_FLUSH);
nyatla 101:5022828ace54 544 (*(NyLPC_TUInt32*)(i_packet+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 101:5022828ace54 545 l+=2+2+4;
nyatla 101:5022828ace54 546 //A record header
nyatla 101:5022828ace54 547 if(obuflen<l+6){
nyatla 101:5022828ace54 548 return 0;
nyatla 101:5022828ace54 549 }
nyatla 101:5022828ace54 550 //Aレコードを書く
nyatla 101:5022828ace54 551 //IPADDR
nyatla 101:5022828ace54 552 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_HTONS(4);
nyatla 101:5022828ace54 553 (*(NyLPC_TUInt32*)(i_packet+l+2))=ip->v;
nyatla 101:5022828ace54 554 return l+6;
nyatla 101:5022828ace54 555 }
nyatla 98:6284ce9a0476 556
nyatla 98:6284ce9a0476 557 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 558 {
nyatla 37:fc4b4fd6a649 559 NyLPC_TInt16 l,s;
nyatla 37:fc4b4fd6a649 560 //Header
nyatla 98:6284ce9a0476 561 // s=(NyLPC_TInt16)*(i_question->buf+i_question->qname_pos);
nyatla 37:fc4b4fd6a649 562 //Headerの長さチェック
nyatla 98:6284ce9a0476 563 if(obuflen<i_spos+30+2+2+4){
nyatla 37:fc4b4fd6a649 564 return 0;
nyatla 37:fc4b4fd6a649 565 }
nyatla 37:fc4b4fd6a649 566 //Header書込み
nyatla 98:6284ce9a0476 567 memcpy(i_packet+i_spos,"\x09_services\x07_dns-sd\x04_udp\x05local\x00",30);
nyatla 98:6284ce9a0476 568 s=compressName(i_packet,i_spos,30);
nyatla 98:6284ce9a0476 569 (*(NyLPC_TUInt16*)(i_packet+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
nyatla 98:6284ce9a0476 570 (*(NyLPC_TUInt16*)(i_packet+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
nyatla 98:6284ce9a0476 571 (*(NyLPC_TUInt32*)(i_packet+s+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 572 l=s+2+2+4;
nyatla 37:fc4b4fd6a649 573
nyatla 37:fc4b4fd6a649 574 //Resourceの書込み
nyatla 37:fc4b4fd6a649 575 s=(NyLPC_TInt16)(1+strlen(i_srvlec->protocol)+1+5+1);//逆引き文字列の長さ(デリミタ×3+1)
nyatla 37:fc4b4fd6a649 576 if(obuflen<s+l+2){
nyatla 37:fc4b4fd6a649 577 return 0;
nyatla 37:fc4b4fd6a649 578 }
nyatla 98:6284ce9a0476 579 (*(NyLPC_TUInt16*)(i_packet+l))=NyLPC_ntohs(s);
nyatla 37:fc4b4fd6a649 580 l+=2;
nyatla 98:6284ce9a0476 581 s=str2label(i_packet+l,i_srvlec->protocol)-1;
nyatla 98:6284ce9a0476 582 s+=str2label(i_packet+l+s,"local");
nyatla 98:6284ce9a0476 583 s=compressName(i_packet,l,s);//圧縮
nyatla 98:6284ce9a0476 584 return s;
nyatla 37:fc4b4fd6a649 585 }
nyatla 98:6284ce9a0476 586 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 587 {
nyatla 37:fc4b4fd6a649 588 NyLPC_TInt16 l,s;
nyatla 37:fc4b4fd6a649 589 NyLPC_TUInt16* rlen;
nyatla 37:fc4b4fd6a649 590 //Header:開始文字数(1)+プレフィクス(n)+終端(1)+local(5)+1
nyatla 37:fc4b4fd6a649 591 s=(NyLPC_TInt16)(1+strlen(i_recode->srv[i_sid].protocol)+1+5+1);
nyatla 37:fc4b4fd6a649 592 //Headerの長さチェック
nyatla 98:6284ce9a0476 593 if(obuflen<i_spos+s+2+2+4){
nyatla 37:fc4b4fd6a649 594 return 0;
nyatla 37:fc4b4fd6a649 595 }
nyatla 37:fc4b4fd6a649 596 //Header書込み
nyatla 98:6284ce9a0476 597 s =str2label(i_packet+i_spos,i_recode->srv[i_sid].protocol)-1;
nyatla 98:6284ce9a0476 598 s+=str2label(i_packet+i_spos+s,"local");
nyatla 98:6284ce9a0476 599 s=compressName(i_packet,i_spos,s);
nyatla 98:6284ce9a0476 600 (*(NyLPC_TUInt16*)(i_packet+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
nyatla 98:6284ce9a0476 601 (*(NyLPC_TUInt16*)(i_packet+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
nyatla 98:6284ce9a0476 602 (*(NyLPC_TUInt32*)(i_packet+s+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 603 l=s+2+2+4;
nyatla 37:fc4b4fd6a649 604
nyatla 37:fc4b4fd6a649 605 //Resourceの書込み
nyatla 37:fc4b4fd6a649 606 s=1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1)
nyatla 37:fc4b4fd6a649 607 if(obuflen<s+l+2){
nyatla 37:fc4b4fd6a649 608 return 0;
nyatla 37:fc4b4fd6a649 609 }
nyatla 98:6284ce9a0476 610 rlen=(NyLPC_TUInt16*)(i_packet+l);
nyatla 37:fc4b4fd6a649 611 l+=2;
nyatla 98:6284ce9a0476 612 s =str2label(i_packet+l,i_recode->name)-1;
nyatla 98:6284ce9a0476 613 s+=str2label(i_packet+l+s,i_recode->srv[i_sid].protocol)-1;
nyatla 98:6284ce9a0476 614 s+=str2label(i_packet+l+s,"local");
nyatla 98:6284ce9a0476 615 s=compressName(i_packet,l,s);//圧縮
nyatla 98:6284ce9a0476 616 (*rlen)=NyLPC_ntohs(s-l);
nyatla 98:6284ce9a0476 617 return s;
nyatla 37:fc4b4fd6a649 618 }
nyatla 37:fc4b4fd6a649 619
nyatla 98:6284ce9a0476 620 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 621 {
nyatla 37:fc4b4fd6a649 622 NyLPC_TInt16 l,s;
nyatla 37:fc4b4fd6a649 623 NyLPC_TUInt16* rlen;
nyatla 37:fc4b4fd6a649 624
nyatla 37:fc4b4fd6a649 625 //SRV Record
nyatla 101:5022828ace54 626 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 627 if(s==0){
nyatla 37:fc4b4fd6a649 628 return 0;
nyatla 37:fc4b4fd6a649 629 }
nyatla 37:fc4b4fd6a649 630
nyatla 37:fc4b4fd6a649 631 l=1+strlen(i_inst->_ref_record->a)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1)
nyatla 98:6284ce9a0476 632 if(obuflen<s+8+l){
nyatla 37:fc4b4fd6a649 633 return 0;
nyatla 37:fc4b4fd6a649 634 }
nyatla 37:fc4b4fd6a649 635 //IPADDR
nyatla 98:6284ce9a0476 636 rlen=(NyLPC_TUInt16*)(i_packet+s);
nyatla 98:6284ce9a0476 637 (*(NyLPC_TUInt16*)(i_packet+s+2))=NyLPC_HTONS(0);//Priority
nyatla 98:6284ce9a0476 638 (*(NyLPC_TUInt16*)(i_packet+s+4))=NyLPC_HTONS(0);//Weight
nyatla 98:6284ce9a0476 639 (*(NyLPC_TUInt16*)(i_packet+s+6))=NyLPC_HTONS(i_inst->_ref_record->srv[i_sid].port);//PORT
nyatla 37:fc4b4fd6a649 640 l=4*2+s;
nyatla 98:6284ce9a0476 641 s=str2label(i_packet+l,i_inst->_ref_record->a)-1;
nyatla 98:6284ce9a0476 642 s+=str2label(i_packet+l+s,"local");
nyatla 98:6284ce9a0476 643 s=compressName(i_packet,l,s);//圧縮
nyatla 98:6284ce9a0476 644 (*rlen)=NyLPC_HTONS(2+2+2+(s-l));
nyatla 98:6284ce9a0476 645 return s;
nyatla 37:fc4b4fd6a649 646 }
nyatla 98:6284ce9a0476 647 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 648 {
nyatla 37:fc4b4fd6a649 649 NyLPC_TInt16 ret;
nyatla 37:fc4b4fd6a649 650 NyLPC_TInt16 l;
nyatla 37:fc4b4fd6a649 651 //Answer
nyatla 101:5022828ace54 652 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 653 if(ret==0){
nyatla 37:fc4b4fd6a649 654 return 0;
nyatla 37:fc4b4fd6a649 655 }
nyatla 37:fc4b4fd6a649 656 //name.proto.localを返す。
nyatla 98:6284ce9a0476 657 if(obuflen<ret+2){
nyatla 37:fc4b4fd6a649 658 return 0;
nyatla 37:fc4b4fd6a649 659 }
nyatla 98:6284ce9a0476 660 (*(NyLPC_TUInt16*)(i_packet+ret))=NyLPC_ntohs(0);
nyatla 37:fc4b4fd6a649 661 //proto.name.local.
nyatla 37:fc4b4fd6a649 662 l=ret+2;
nyatla 37:fc4b4fd6a649 663 return l;
nyatla 37:fc4b4fd6a649 664 }
nyatla 37:fc4b4fd6a649 665
nyatla 37:fc4b4fd6a649 666
nyatla 37:fc4b4fd6a649 667
nyatla 37:fc4b4fd6a649 668
nyatla 37:fc4b4fd6a649 669
nyatla 37:fc4b4fd6a649 670
nyatla 37:fc4b4fd6a649 671 static void sendAnnounse(NyLPC_TcMDnsServer_t* i_inst)
nyatla 37:fc4b4fd6a649 672 {
nyatla 37:fc4b4fd6a649 673 char* obuf;
nyatla 37:fc4b4fd6a649 674 NyLPC_TUInt16 obuflen;
nyatla 98:6284ce9a0476 675 NyLPC_TUInt16 l;
nyatla 37:fc4b4fd6a649 676 int i2;
nyatla 37:fc4b4fd6a649 677 for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
nyatla 37:fc4b4fd6a649 678 //Bufferの取得
nyatla 37:fc4b4fd6a649 679 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,TIMEOUT_IN_MS);
nyatla 37:fc4b4fd6a649 680 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 681 return;
nyatla 37:fc4b4fd6a649 682 }
nyatla 37:fc4b4fd6a649 683 l=setResponseHeader(obuf,NULL,1,0,3);
nyatla 98:6284ce9a0476 684 l=writePtrRecord(i_inst->_ref_record,i2,obuf,l,obuflen);
nyatla 98:6284ce9a0476 685 if(l<=0){
nyatla 37:fc4b4fd6a649 686 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 687 }
nyatla 98:6284ce9a0476 688 l=writeSRVRecord(i_inst,i2,obuf,l,obuflen);
nyatla 98:6284ce9a0476 689 if(l<=0){
nyatla 37:fc4b4fd6a649 690 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 691 }
nyatla 98:6284ce9a0476 692 l=writeTXTRecord(i_inst,i2,obuf,l,obuflen);
nyatla 98:6284ce9a0476 693 if(l<=0){
nyatla 37:fc4b4fd6a649 694 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 695 }
nyatla 37:fc4b4fd6a649 696 //Aレコード
nyatla 98:6284ce9a0476 697 l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 698 if(l<=0){
nyatla 37:fc4b4fd6a649 699 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 700 }
nyatla 37:fc4b4fd6a649 701 if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
nyatla 37:fc4b4fd6a649 702 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 703 }
nyatla 37:fc4b4fd6a649 704 }
nyatla 37:fc4b4fd6a649 705 return;
nyatla 37:fc4b4fd6a649 706 ERROR:
nyatla 37:fc4b4fd6a649 707 NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf);
nyatla 37:fc4b4fd6a649 708 return;
nyatla 37:fc4b4fd6a649 709 }
nyatla 37:fc4b4fd6a649 710
nyatla 37:fc4b4fd6a649 711
nyatla 98:6284ce9a0476 712
nyatla 37:fc4b4fd6a649 713 static void sendReply2(NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsHeader* i_dns_header,const struct NyLPC_TDnsQuestion* q)
nyatla 37:fc4b4fd6a649 714 {
nyatla 37:fc4b4fd6a649 715 NyLPC_TInt16 ptr_recode;
nyatla 37:fc4b4fd6a649 716 NyLPC_TInt16 i2;
nyatla 37:fc4b4fd6a649 717 char* obuf;
nyatla 37:fc4b4fd6a649 718 NyLPC_TUInt16 obuflen;
nyatla 98:6284ce9a0476 719 NyLPC_TUInt16 l;
nyatla 37:fc4b4fd6a649 720 //パケットヘッダの生成
nyatla 37:fc4b4fd6a649 721 switch(q->qtype){
nyatla 37:fc4b4fd6a649 722 case NyLPC_TDnsQuestion_QTYPR_SRV:
nyatla 37:fc4b4fd6a649 723 //SRV,A record
nyatla 98:6284ce9a0476 724 ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q);
nyatla 37:fc4b4fd6a649 725 if(ptr_recode<0){
nyatla 37:fc4b4fd6a649 726 goto DROP;
nyatla 37:fc4b4fd6a649 727 }
nyatla 37:fc4b4fd6a649 728 //Bufferの取得
nyatla 37:fc4b4fd6a649 729 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 730 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 731 goto DROP;
nyatla 37:fc4b4fd6a649 732 }
nyatla 37:fc4b4fd6a649 733 l=setResponseHeader(obuf,i_dns_header,1,0,2);
nyatla 98:6284ce9a0476 734 l=writeSRVRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 735 if(l<=0){
nyatla 37:fc4b4fd6a649 736 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 737 }
nyatla 98:6284ce9a0476 738 l=writeTXTRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 739 if(l<=0){
nyatla 37:fc4b4fd6a649 740 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 741 }
nyatla 37:fc4b4fd6a649 742 //Aレコード
nyatla 98:6284ce9a0476 743 l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 744 if(l<=0){
nyatla 37:fc4b4fd6a649 745 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 746 }
nyatla 37:fc4b4fd6a649 747 break;
nyatla 37:fc4b4fd6a649 748 case NyLPC_TDnsQuestion_QTYPR_A:
nyatla 37:fc4b4fd6a649 749 //自分宛?(name.local)
nyatla 98:6284ce9a0476 750 if(!NyLPC_TDnsQuestion_isEqualName(q,i_inst->_ref_record->a,"")){
nyatla 37:fc4b4fd6a649 751 goto DROP;
nyatla 37:fc4b4fd6a649 752 }
nyatla 37:fc4b4fd6a649 753 //Bufferの取得
nyatla 37:fc4b4fd6a649 754 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 755 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 756 goto DROP;
nyatla 37:fc4b4fd6a649 757 }
nyatla 37:fc4b4fd6a649 758 //Headerのコピー
nyatla 37:fc4b4fd6a649 759 l=setResponseHeader(obuf,i_dns_header,1,0,0);
nyatla 37:fc4b4fd6a649 760 //Aレコードのみ
nyatla 101:5022828ace54 761 l=writeARecordByQuery(obuf,l,obuflen,q->buf+q->qname_pos,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 762 if(l<=0){
nyatla 37:fc4b4fd6a649 763 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 764 }
nyatla 37:fc4b4fd6a649 765 break;
nyatla 37:fc4b4fd6a649 766 case NyLPC_TDnsQuestion_QTYPR_PTR:
nyatla 98:6284ce9a0476 767 //_service._dns-sd._udpかどうか
nyatla 98:6284ce9a0476 768 if(NyLPC_TDnsQuestion_isEqualName(q,NULL,"_services._dns-sd._udp")){
nyatla 37:fc4b4fd6a649 769 //Bufferの取得
nyatla 37:fc4b4fd6a649 770 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 771 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 772 goto DROP;
nyatla 37:fc4b4fd6a649 773 }
nyatla 37:fc4b4fd6a649 774 l=setResponseHeader(obuf,i_dns_header,i_inst->_ref_record->num_of_srv,0,0);
nyatla 37:fc4b4fd6a649 775 for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
nyatla 98:6284ce9a0476 776 l=writeSdPtrRecord(q,&(i_inst->_ref_record->srv[i2]),obuf,l,obuflen);
nyatla 98:6284ce9a0476 777 if(l<=0){
nyatla 37:fc4b4fd6a649 778 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 779 }
nyatla 37:fc4b4fd6a649 780 }
nyatla 37:fc4b4fd6a649 781 }else{
nyatla 37:fc4b4fd6a649 782 //自分宛?(proto.local)
nyatla 98:6284ce9a0476 783 ptr_recode=NyLPC_TDnsRecord_getMatchPtrIdx(i_inst->_ref_record,q);
nyatla 37:fc4b4fd6a649 784 if(ptr_recode<0){
nyatla 37:fc4b4fd6a649 785 goto DROP;
nyatla 37:fc4b4fd6a649 786 }
nyatla 37:fc4b4fd6a649 787 //Bufferの取得
nyatla 37:fc4b4fd6a649 788 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 789 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 790 goto DROP;
nyatla 37:fc4b4fd6a649 791 }
nyatla 37:fc4b4fd6a649 792 l=setResponseHeader(obuf,i_dns_header,1,0,3);
nyatla 98:6284ce9a0476 793 l=writePtrRecord(i_inst->_ref_record,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 794 if(l<=0){
nyatla 37:fc4b4fd6a649 795 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 796 }
nyatla 98:6284ce9a0476 797 l=writeSRVRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 798 if(l<=0){
nyatla 37:fc4b4fd6a649 799 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 800 }
nyatla 98:6284ce9a0476 801 l=writeTXTRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 802 if(l<=0){
nyatla 37:fc4b4fd6a649 803 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 804 }
nyatla 37:fc4b4fd6a649 805 //Aレコード
nyatla 98:6284ce9a0476 806 l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 807 if(l<=0){
nyatla 37:fc4b4fd6a649 808 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 809 }
nyatla 37:fc4b4fd6a649 810 }
nyatla 37:fc4b4fd6a649 811 break;
nyatla 37:fc4b4fd6a649 812 case NyLPC_TDnsQuestion_QTYPR_TXT:
nyatla 37:fc4b4fd6a649 813 //自分宛?(proto.local)
nyatla 98:6284ce9a0476 814 ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q);
nyatla 37:fc4b4fd6a649 815 if(ptr_recode<0){
nyatla 37:fc4b4fd6a649 816 goto DROP;
nyatla 37:fc4b4fd6a649 817 }
nyatla 37:fc4b4fd6a649 818 //Bufferの取得
nyatla 37:fc4b4fd6a649 819 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 820 l=setResponseHeader(obuf,i_dns_header,1,0,1);
nyatla 98:6284ce9a0476 821 l=writeTXTRecord(i_inst,ptr_recode,obuf,l,obuflen);
nyatla 98:6284ce9a0476 822 if(l<=0){
nyatla 37:fc4b4fd6a649 823 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 824 }
nyatla 98:6284ce9a0476 825 l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 98:6284ce9a0476 826 if(l<=0){
nyatla 37:fc4b4fd6a649 827 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 828 }
nyatla 37:fc4b4fd6a649 829 break;
nyatla 37:fc4b4fd6a649 830 default:
nyatla 37:fc4b4fd6a649 831 goto DROP;
nyatla 37:fc4b4fd6a649 832 }
nyatla 37:fc4b4fd6a649 833 if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
nyatla 37:fc4b4fd6a649 834 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 835 }
nyatla 37:fc4b4fd6a649 836 return;
nyatla 37:fc4b4fd6a649 837 ERROR:
nyatla 37:fc4b4fd6a649 838 NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf);
nyatla 37:fc4b4fd6a649 839 DROP:
nyatla 37:fc4b4fd6a649 840 return;
nyatla 37:fc4b4fd6a649 841 }
nyatla 37:fc4b4fd6a649 842 #define CTRL_FLAG_INIT 0x00
nyatla 37:fc4b4fd6a649 843 #define CTRL_FLAG_STARTED 0x80
nyatla 37:fc4b4fd6a649 844 #define CTRL_FLAG_STOP_REQUESTED 0x40
nyatla 37:fc4b4fd6a649 845 #define CTRL_FLAG_PROCESS_PACKET 0x20 //パケット処理中の間1
nyatla 37:fc4b4fd6a649 846
nyatla 37:fc4b4fd6a649 847 static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info)
nyatla 37:fc4b4fd6a649 848 {
nyatla 98:6284ce9a0476 849 NyLPC_TUInt16 in_len;
nyatla 37:fc4b4fd6a649 850 NyLPC_TUInt16 num_of_query;
nyatla 37:fc4b4fd6a649 851 struct NyLPC_TDnsQuestion q;
nyatla 37:fc4b4fd6a649 852 NyLPC_TUInt16 s;
nyatla 37:fc4b4fd6a649 853 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 854
nyatla 37:fc4b4fd6a649 855 if(i_info->peer_port!=MDNS_MCAST_PORT || !NyLPC_TIPv4Addr_isEqual(&MDNS_MCAST_IPADDR,&i_info->ip)){
nyatla 37:fc4b4fd6a649 856 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 857 }
nyatla 37:fc4b4fd6a649 858
nyatla 98:6284ce9a0476 859 num_of_query=getNumberOfQuestion(i_buf,i_info->size);
nyatla 37:fc4b4fd6a649 860 if(num_of_query==0){
nyatla 37:fc4b4fd6a649 861 goto DROP;
nyatla 37:fc4b4fd6a649 862 }
nyatla 98:6284ce9a0476 863 in_len=sizeof(struct NyLPC_TDnsHeader);
nyatla 37:fc4b4fd6a649 864 for(i=0;i<num_of_query;i++){
nyatla 37:fc4b4fd6a649 865 //Queryのパース
nyatla 98:6284ce9a0476 866
nyatla 98:6284ce9a0476 867 s=NyLPC_TDnsQuestion_parse(i_buf,i_info->size,in_len,&q);
nyatla 37:fc4b4fd6a649 868 if(s==0){
nyatla 37:fc4b4fd6a649 869 goto DROP;
nyatla 37:fc4b4fd6a649 870 }
nyatla 98:6284ce9a0476 871 in_len+=s;
nyatla 37:fc4b4fd6a649 872 sendReply2((NyLPC_TcMDnsServer_t*)i_inst,(const struct NyLPC_TDnsHeader*)i_buf,&q);
nyatla 37:fc4b4fd6a649 873 }
nyatla 37:fc4b4fd6a649 874 //パケット処理終了
nyatla 37:fc4b4fd6a649 875 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 876 DROP:
nyatla 37:fc4b4fd6a649 877 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 878 }
nyatla 37:fc4b4fd6a649 879
nyatla 37:fc4b4fd6a649 880 static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst)
nyatla 37:fc4b4fd6a649 881 {
nyatla 37:fc4b4fd6a649 882
nyatla 37:fc4b4fd6a649 883 if(NyLPC_cStopwatch_isExpired(&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw)){
nyatla 37:fc4b4fd6a649 884 //アナウンス
nyatla 37:fc4b4fd6a649 885 sendAnnounse(((NyLPC_TcMDnsServer_t*)i_inst));
nyatla 37:fc4b4fd6a649 886 //TTL(msec)*1000*80%
nyatla 101:5022828ace54 887 NyLPC_cStopwatch_startExpire((&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw),NyLPC_TcMDns_TTL*1000*4/5);
nyatla 37:fc4b4fd6a649 888 }
nyatla 37:fc4b4fd6a649 889 }
nyatla 37:fc4b4fd6a649 890
nyatla 37:fc4b4fd6a649 891 NyLPC_TBool NyLPC_cMDnsServer_initialize(
nyatla 48:00d211aac2ec 892 NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsRecord* i_ref_record)
nyatla 37:fc4b4fd6a649 893 {
nyatla 37:fc4b4fd6a649 894 NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw));
nyatla 37:fc4b4fd6a649 895 NyLPC_cStopwatch_startExpire(&(i_inst->_periodic_sw),1000);
nyatla 37:fc4b4fd6a649 896 NyLPC_cUdpSocket_initialize(&(i_inst->_super),MDNS_MCAST_PORT,NULL,0);
nyatla 37:fc4b4fd6a649 897 NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->_super),onPacket);
nyatla 48:00d211aac2ec 898 NyLPC_cUdpSocket_setOnPeriodicHandler(&(i_inst->_super),onPeriodic);
nyatla 37:fc4b4fd6a649 899 NyLPC_cUdpSocket_joinMulticast(&(i_inst->_super),&MDNS_MCAST_IPADDR);
nyatla 37:fc4b4fd6a649 900 i_inst->_ref_record=i_ref_record;
nyatla 37:fc4b4fd6a649 901 return NyLPC_TBool_TRUE;
nyatla 37:fc4b4fd6a649 902 }
nyatla 37:fc4b4fd6a649 903 void NyLPC_cMDnsServer_finalize(
nyatla 37:fc4b4fd6a649 904 NyLPC_TcMDnsServer_t* i_inst)
nyatla 37:fc4b4fd6a649 905 {
nyatla 37:fc4b4fd6a649 906 NyLPC_cUdpSocket_finalize(&(i_inst->_super));
nyatla 37:fc4b4fd6a649 907 NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw));
nyatla 37:fc4b4fd6a649 908 }
nyatla 37:fc4b4fd6a649 909
nyatla 37:fc4b4fd6a649 910
nyatla 37:fc4b4fd6a649 911