Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

471 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. addr.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. IP address routines
  8. Author:
  9. Jim Gilroy (jamesg) June 2000
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. #include "ws2atm.h" // ATM addressing
  14. //
  15. // Address info table
  16. //
  17. FAMILY_INFO AddrFamilyTable[] =
  18. {
  19. AF_INET,
  20. DNS_TYPE_A,
  21. sizeof(IP4_ADDRESS),
  22. sizeof(SOCKADDR_IN),
  23. (DWORD) FIELD_OFFSET( SOCKADDR_IN, sin_addr ),
  24. AF_INET6,
  25. DNS_TYPE_AAAA,
  26. sizeof(IP6_ADDRESS),
  27. sizeof(SOCKADDR_IN6),
  28. (DWORD) FIELD_OFFSET( SOCKADDR_IN6, sin6_addr ),
  29. AF_ATM,
  30. DNS_TYPE_ATMA,
  31. sizeof(ATM_ADDRESS),
  32. sizeof(SOCKADDR_ATM),
  33. sizeof(DWORD),
  34. (DWORD) FIELD_OFFSET( SOCKADDR_ATM, satm_number ),
  35. };
  36. PFAMILY_INFO
  37. FamilyInfo_GetForFamily(
  38. IN DWORD Family
  39. )
  40. /*++
  41. Routine Description:
  42. Get address family info for family.
  43. Arguments:
  44. Family -- address family
  45. Return Value:
  46. Ptr to address family info for family.
  47. NULL if family is unknown.
  48. --*/
  49. {
  50. PFAMILY_INFO pinfo = NULL;
  51. // switch on type
  52. if ( Family == AF_INET )
  53. {
  54. pinfo = pFamilyInfoIp4;
  55. }
  56. else if ( Family == AF_INET6 )
  57. {
  58. pinfo = pFamilyInfoIp6;
  59. }
  60. else if ( Family == AF_ATM )
  61. {
  62. pinfo = pFamilyInfoAtm;
  63. }
  64. return pinfo;
  65. }
  66. DWORD
  67. Family_SockaddrLength(
  68. IN WORD Family
  69. )
  70. /*++
  71. Routine Description:
  72. Extract info for family.
  73. Arguments:
  74. Family -- address family
  75. Return Value:
  76. Length of sockaddr for address family.
  77. Zero if unknown family.
  78. --*/
  79. {
  80. PFAMILY_INFO pinfo;
  81. // get family -- extract info
  82. pinfo = FamilyInfo_GetForFamily( Family );
  83. if ( pinfo )
  84. {
  85. return pinfo->LengthSockaddr;
  86. }
  87. return 0;
  88. }
  89. WORD
  90. Family_DnsType(
  91. IN WORD Family
  92. )
  93. /*++
  94. Routine Description:
  95. Extract info for family.
  96. Arguments:
  97. Family -- address family
  98. Return Value:
  99. Length of sockaddr for address family.
  100. Zero if unknown family.
  101. --*/
  102. {
  103. PFAMILY_INFO pinfo;
  104. // get family -- extract info
  105. pinfo = FamilyInfo_GetForFamily( Family );
  106. if ( pinfo )
  107. {
  108. return pinfo->DnsType;
  109. }
  110. return 0;
  111. }
  112. DWORD
  113. Family_GetFromDnsType(
  114. IN WORD wType
  115. )
  116. /*++
  117. Routine Description:
  118. Get address family for a given DNS type.
  119. Arguments:
  120. wType -- DNS type
  121. Return Value:
  122. Address family if found.
  123. Zero if wType doesn't map to known family.
  124. --*/
  125. {
  126. // switch on type
  127. if ( wType == DNS_TYPE_A )
  128. {
  129. return AF_INET;
  130. }
  131. if ( wType == DNS_TYPE_AAAA )
  132. {
  133. return AF_INET6;
  134. }
  135. if ( wType == DNS_TYPE_ATMA )
  136. {
  137. return AF_ATM;
  138. }
  139. return 0;
  140. }
  141. //
  142. // Sockaddr
  143. //
  144. DWORD
  145. Sockaddr_Length(
  146. IN PSOCKADDR pSockaddr
  147. )
  148. /*++
  149. Routine Description:
  150. Get length of sockaddr.
  151. Arguments:
  152. pSockaddr -- sockaddr buffer to recv address
  153. Return Value:
  154. Length of sockaddr for address family.
  155. Zero if unknown family.
  156. --*/
  157. {
  158. return Family_SockaddrLength( pSockaddr->sa_family );
  159. }
  160. IP6_ADDRESS
  161. Sockaddr_GetIp6(
  162. IN PSOCKADDR pSockaddr
  163. )
  164. /*++
  165. Routine Description:
  166. Get IP6 address from sockaddr.
  167. If IP4 sockaddr, IP6 address is mapped.
  168. Arguments:
  169. pSockaddr -- any kind of sockaddr
  170. must have actual length for sockaddr family
  171. Return Value:
  172. IP6 address corresponding to sockaddr.
  173. If IP4 sockaddr it's IP4_MAPPED address.
  174. If not IP4 or IP6 sockaddr IP6 addresss is zero.
  175. --*/
  176. {
  177. IP6_ADDRESS ip6;
  178. //
  179. // switch on family
  180. // - IP6 gets copy
  181. // - IP4 gets IP4_MAPPED
  182. // - bogus gets zero
  183. //
  184. switch ( pSockaddr->sa_family )
  185. {
  186. case AF_INET:
  187. IP6_SET_ADDR_V4MAPPED(
  188. & ip6,
  189. ((PSOCKADDR_IN)pSockaddr)->sin_addr.s_addr );
  190. break;
  191. case AF_INET6:
  192. RtlCopyMemory(
  193. &ip6,
  194. & ((PSOCKADDR_IN6)pSockaddr)->sin6_addr,
  195. sizeof(IP6_ADDRESS) );
  196. break;
  197. default:
  198. RtlZeroMemory(
  199. &ip6,
  200. sizeof(IP6_ADDRESS) );
  201. break;
  202. }
  203. return ip6;
  204. }
  205. VOID
  206. Sockaddr_BuildFromIp6(
  207. OUT PSOCKADDR pSockaddr,
  208. IN IP6_ADDRESS Ip6Addr,
  209. IN WORD Port
  210. )
  211. /*++
  212. Routine Description:
  213. Write IP6 address (straight 6 or v4 mapped) to sockaddr.
  214. Arguments:
  215. pSockaddr -- ptr to sockaddr to write to;
  216. must be at least size of SOCKADDR_IN6
  217. Ip6Addr -- IP6 addresss being written
  218. Port -- port in net byte order
  219. Return Value:
  220. None
  221. --*/
  222. {
  223. // zero
  224. RtlZeroMemory(
  225. pSockaddr,
  226. sizeof(SOCKADDR_IN6) );
  227. //
  228. // determine whether IP6 or IP4
  229. //
  230. if ( IP6_IS_ADDR_V4MAPPED( &Ip6Addr ) )
  231. {
  232. PSOCKADDR_IN psa = (PSOCKADDR_IN) pSockaddr;
  233. psa->sin_family = AF_INET;
  234. psa->sin_port = Port;
  235. psa->sin_addr.s_addr = IP6_GET_V4_ADDR( &Ip6Addr );
  236. }
  237. else // IP6
  238. {
  239. PSOCKADDR_IN6 psa = (PSOCKADDR_IN6) pSockaddr;
  240. psa->sin6_family = AF_INET6;
  241. psa->sin6_port = Port;
  242. RtlCopyMemory(
  243. &psa->sin6_addr,
  244. &Ip6Addr,
  245. sizeof(IP6_ADDRESS) );
  246. }
  247. }
  248. DNS_STATUS
  249. Sockaddr_BuildFromFlatAddr(
  250. OUT PSOCKADDR pSockaddr,
  251. IN OUT PDWORD pSockaddrLength,
  252. IN BOOL fClearSockaddr,
  253. IN PBYTE pAddr,
  254. IN DWORD AddrLength,
  255. IN DWORD AddrFamily
  256. )
  257. /*++
  258. Routine Description:
  259. Convert address in ptr\family\length to sockaddr.
  260. Arguments:
  261. pSockaddr -- sockaddr buffer to recv address
  262. pSockaddrLength -- addr with length of sockaddr buffer
  263. receives the actual sockaddr length
  264. fClearSockaddr -- start with zero buffer
  265. pAddr -- ptr to address
  266. AddrLength -- address length
  267. AddrFamily -- address family (AF_INET, AF_INET6)
  268. Return Value:
  269. NO_ERROR if successful.
  270. ERROR_INSUFFICIENT_BUFFER -- if buffer too small
  271. WSAEAFNOSUPPORT -- if invalid family
  272. --*/
  273. {
  274. PFAMILY_INFO pinfo;
  275. DWORD lengthIn = *pSockaddrLength;
  276. DWORD lengthSockAddr;
  277. // clear to start
  278. if ( fClearSockaddr )
  279. {
  280. RtlZeroMemory(
  281. pSockaddr,
  282. lengthIn );
  283. }
  284. // switch on type
  285. if ( AddrFamily == AF_INET )
  286. {
  287. pinfo = pFamilyInfoIp4;
  288. }
  289. else if ( AddrFamily == AF_INET6 )
  290. {
  291. pinfo = pFamilyInfoIp6;
  292. }
  293. else if ( AddrFamily == AF_ATM )
  294. {
  295. pinfo = pFamilyInfoAtm;
  296. }
  297. else
  298. {
  299. return WSAEAFNOSUPPORT;
  300. }
  301. // validate lengths
  302. if ( AddrLength != pinfo->LengthAddr )
  303. {
  304. return DNS_ERROR_INVALID_IP_ADDRESS;
  305. }
  306. lengthSockAddr = pinfo->LengthSockaddr;
  307. *pSockaddrLength = lengthSockAddr;
  308. if ( lengthIn < lengthSockAddr )
  309. {
  310. return ERROR_INSUFFICIENT_BUFFER;
  311. }
  312. //
  313. // fill out sockaddr
  314. // - set family
  315. // - copy address to sockaddr
  316. // - return length was set above
  317. //
  318. RtlCopyMemory(
  319. (PBYTE)pSockaddr + pinfo->OffsetToAddrInSockaddr,
  320. pAddr,
  321. AddrLength );
  322. pSockaddr->sa_family = (WORD)AddrFamily;
  323. return NO_ERROR;
  324. }
  325. //
  326. // End addr.c
  327. //