Guest User

Untitled

a guest
Feb 20th, 2018
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.01 KB | None | 0 0
  1. %%%-------------------------------------------------------------------
  2. %% @copyright Geoff Cant
  3. %% @author Geoff Cant <nem@erlang.geek.nz>
  4. %% @version {@vsn}, {@date} {@time}
  5. %% @doc Experimental replacement for inet_dns
  6. %% @end
  7. %%%-------------------------------------------------------------------
  8. -module(ginet_dns2).
  9.  
  10. %% API
  11. -export([decode/1]).
  12.  
  13. -include_lib("kernel/src/inet_dns.hrl").
  14.  
  15. -compile(export_all).
  16.  
  17. %%====================================================================
  18. %% API
  19. %%====================================================================
  20.  
  21. decode(Msg = <<ID:16,
  22. QR:1,OPCODE:4,
  23. AA:1,TC:1,RD:1,RA:1,
  24. _Z:3,RCODE:4,
  25. QDCOUNT:16,ANCOUNT:16,
  26. NSCOUNT:16,ARCOUNT:16,
  27. Rest/binary>>) ->
  28. Header = #dns_header{id=ID,
  29. qr=QR,
  30. opcode=OPCODE,
  31. aa=AA,tc=TC,
  32. rd=RD,ra=RA,
  33. rcode=RCODE},
  34. {Queries,AnsRest} = decode_queries(Msg, QDCOUNT, Rest),
  35. {Answers,AuthRest} = decode_answers(Msg, ANCOUNT, AnsRest),
  36. {Authorities,AddRest} = decode_authority(Msg, NSCOUNT, AuthRest),
  37. {Additionals,_} = decode_additional(Msg, ARCOUNT, AddRest),
  38. [Header,Queries,Answers,Authorities,Additionals].
  39.  
  40. %%====================================================================
  41. %% Internal functions
  42. %%====================================================================
  43.  
  44. %% Query
  45.  
  46. decode_queries(Msg, Count, Rest) ->
  47. decode_queries(Msg, Count, Rest, []).
  48.  
  49. decode_queries(Msg, 0, Rest, Acc) -> {Acc,Rest};
  50. decode_queries(Msg, Count, Rest, Acc) ->
  51. {Name, <<QTYPE:16,QCLASS:16,QRest/binary>>} = decode_name(Msg, Rest),
  52. Q = #dns_query{domain=Name,
  53. type=decode_type(QTYPE),
  54. class=decode_class(QCLASS)},
  55. decode_queries(Msg, Count-1, QRest, Acc ++ [Q]).
  56.  
  57. %% Answers
  58.  
  59. decode_answers(Msg, Count, Rest) ->
  60. decode_answers(Msg, Count, Rest, []).
  61.  
  62. decode_answers(Msg, 0, Rest, Acc) -> {Acc,Rest};
  63. decode_answers(Msg, Count, Rest, Acc) ->
  64. {Name, <<Type:16,Class:16,TTL:32,
  65. RDLen:16,RD:RDLen/binary,
  66. RRest/binary>>} = decode_name(Msg, Rest),
  67. R = #dns_rr{domain=Name,
  68. type=decode_type(Type),
  69. class=decode_class(Class),
  70. ttl=TTL,
  71. data=RD},
  72. decode_answers(Msg, Count-1, RRest, Acc ++ [R]).
  73.  
  74. %% Authority
  75.  
  76. decode_authority(Msg, Count, Rest) ->
  77. decode_answers(Msg, Count, Rest).
  78.  
  79. %% Additional
  80.  
  81. decode_additional(Msg, Count, Rest) ->
  82. decode_answers(Msg, Count, Rest).
  83.  
  84. %% Name
  85.  
  86. decode_name(Msg, Data) ->
  87. decode_name(Msg, Data, []).
  88.  
  89. decode_name(Msg, <<0, Rest/binary>>, Acc) ->
  90. {lists:flatten(Acc), Rest};
  91. decode_name(Msg, <<1:1,1:1,Ptr:14,Rest/binary>>, Acc) ->
  92. <<_Skip:Ptr/binary,Name/binary>> = Msg,
  93. {CompName, _} = decode_name(Msg, Name, Acc),
  94. {case Acc of [] -> CompName; _ -> lists:flatten([Acc, ".", CompName]) end,
  95. Rest};
  96. decode_name(Msg, <<Len:8,Name:Len/binary,Rest/binary>>, Acc) ->
  97. StrName = binary_to_list(Name),
  98. decode_name(Msg, Rest, case Acc of [] -> StrName; _ -> [Acc, ".", StrName] end).
  99.  
  100. %%
  101. %% Resource types
  102. %%
  103. decode_type(Type) ->
  104. case Type of
  105. ?T_A -> ?S_A;
  106. ?T_NS -> ?S_NS;
  107. ?T_MD -> ?S_MD;
  108. ?T_MF -> ?S_MF;
  109. ?T_CNAME -> ?S_CNAME;
  110. ?T_SOA -> ?S_SOA;
  111. ?T_MB -> ?S_MB;
  112. ?T_MG -> ?S_MG;
  113. ?T_MR -> ?S_MR;
  114. ?T_NULL -> ?S_NULL;
  115. ?T_WKS -> ?S_WKS;
  116. ?T_PTR -> ?S_PTR;
  117. ?T_HINFO -> ?S_HINFO;
  118. ?T_MINFO -> ?S_MINFO;
  119. ?T_MX -> ?S_MX;
  120. ?T_TXT -> ?S_TXT;
  121. ?T_AAAA -> ?S_AAAA;
  122. ?T_SRV -> ?S_SRV;
  123. %% non standard
  124. ?T_UINFO -> ?S_UINFO;
  125. ?T_UID -> ?S_UID;
  126. ?T_GID -> ?S_GID;
  127. ?T_UNSPEC -> ?S_UNSPEC;
  128. %% Query type values which do not appear in resource records
  129. ?T_AXFR -> ?S_AXFR;
  130. ?T_MAILB -> ?S_MAILB;
  131. ?T_MAILA -> ?S_MAILA;
  132. ?T_ANY -> ?S_ANY;
  133. _ -> Type %% raw unknown type
  134. end.
  135.  
  136. %%
  137. %% Resource types
  138. %%
  139. encode_type(Type) ->
  140. case Type of
  141. ?S_A -> ?T_A;
  142. ?S_NS -> ?T_NS;
  143. ?S_MD -> ?T_MD;
  144. ?S_MF -> ?T_MF;
  145. ?S_CNAME -> ?T_CNAME;
  146. ?S_SOA -> ?T_SOA;
  147. ?S_MB -> ?T_MB;
  148. ?S_MG -> ?T_MG;
  149. ?S_MR -> ?T_MR;
  150. ?S_NULL -> ?T_NULL;
  151. ?S_WKS -> ?T_WKS;
  152. ?S_PTR -> ?T_PTR;
  153. ?S_HINFO -> ?T_HINFO;
  154. ?S_MINFO -> ?T_MINFO;
  155. ?S_MX -> ?T_MX;
  156. ?S_TXT -> ?T_TXT;
  157. ?S_AAAA -> ?T_AAAA;
  158. ?S_SRV -> ?T_SRV;
  159. %% non standard
  160. ?S_UINFO -> ?T_UINFO;
  161. ?S_UID -> ?T_UID;
  162. ?S_GID -> ?T_GID;
  163. ?S_UNSPEC -> ?T_UNSPEC;
  164. %% Query type values which do not appear in resource records
  165. ?S_AXFR -> ?T_AXFR;
  166. ?S_MAILB -> ?T_MAILB;
  167. ?S_MAILA -> ?T_MAILA;
  168. ?S_ANY -> ?T_ANY;
  169. Type when is_integer(Type) -> Type %% raw unknown type
  170. end.
  171.  
  172. %%
  173. %% Resource clases
  174. %%
  175.  
  176. decode_class(Class) ->
  177. case Class of
  178. ?C_IN -> in;
  179. ?C_CHAOS -> chaos;
  180. ?C_HS -> hs;
  181. ?C_ANY -> any;
  182. _ -> Class %% raw unknown class
  183. end.
  184.  
  185.  
  186. encode_class(Class) ->
  187. case Class of
  188. in -> ?C_IN;
  189. chaos -> ?C_CHAOS;
  190. hs -> ?C_HS;
  191. any -> ?C_ANY;
  192. Class when is_integer(Class) -> Class %% raw unknown class
  193. end.
Add Comment
Please, Sign In to add comment