sock.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. /*++
  2. Copyright (c) 2014 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. sock.c
  9. Abstract:
  10. This module contains socket support for Unix-like platforms.
  11. Author:
  12. Evan Green 27-Aug-2014
  13. Environment:
  14. Win32
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <arpa/inet.h>
  20. #include <netinet/in.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <sys/socket.h>
  24. #include <unistd.h>
  25. #include "sock.h"
  26. //
  27. // ---------------------------------------------------------------- Definitions
  28. //
  29. //
  30. // ------------------------------------------------------ Data Type Definitions
  31. //
  32. //
  33. // ----------------------------------------------- Internal Function Prototypes
  34. //
  35. //
  36. // -------------------------------------------------------------------- Globals
  37. //
  38. //
  39. // ------------------------------------------------------------------ Functions
  40. //
  41. int
  42. DbgrSocketInitializeLibrary (
  43. void
  44. )
  45. /*++
  46. Routine Description:
  47. This routine initializes socket support in the application.
  48. Arguments:
  49. None.
  50. Return Value:
  51. 0 on success.
  52. Non-zero on failure.
  53. --*/
  54. {
  55. return 0;
  56. }
  57. void
  58. DbgrSocketDestroyLibrary (
  59. void
  60. )
  61. /*++
  62. Routine Description:
  63. This routine tears down socket support in the application.
  64. Arguments:
  65. None.
  66. Return Value:
  67. None.
  68. --*/
  69. {
  70. return;
  71. }
  72. int
  73. DbgrSocketCreateStreamSocket (
  74. void
  75. )
  76. /*++
  77. Routine Description:
  78. This routine creates an IPv4 TCP socket.
  79. Arguments:
  80. None.
  81. Return Value:
  82. Returns the socket on success.
  83. Returns a value less than zero on failure.
  84. --*/
  85. {
  86. return socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  87. }
  88. int
  89. DbgrSocketBind (
  90. int Socket,
  91. char *Host,
  92. int Port
  93. )
  94. /*++
  95. Routine Description:
  96. This routine binds the given socket to the given address and port.
  97. Arguments:
  98. Socket - Supplies the socket to bind.
  99. Host - Supplies a pointer to the host string. Supply NULL to use any
  100. address.
  101. Port - Supplies the port to bind on.
  102. Return Value:
  103. 0 on success.
  104. Non-zero on failure.
  105. --*/
  106. {
  107. struct sockaddr_in Address;
  108. int Result;
  109. Address.sin_family = AF_INET;
  110. Address.sin_port = htons(Port);
  111. Address.sin_addr.s_addr = INADDR_ANY;
  112. if ((Host != NULL) && (*Host != '\0')) {
  113. Result = inet_pton(AF_INET, Host, &(Address.sin_addr));
  114. if (Result == 0) {
  115. return 1;
  116. }
  117. }
  118. Result = bind(Socket,
  119. (struct sockaddr *)&Address,
  120. sizeof(struct sockaddr_in));
  121. return Result;
  122. }
  123. int
  124. DbgrSocketConnect (
  125. int Socket,
  126. char *Host,
  127. int Port
  128. )
  129. /*++
  130. Routine Description:
  131. This routine connects to a remote server.
  132. Arguments:
  133. Socket - Supplies the socket to connect.
  134. Host - Supplies a pointer to the host string to connect to.
  135. Port - Supplies the port to bind on.
  136. Return Value:
  137. 0 on success.
  138. Non-zero on failure.
  139. --*/
  140. {
  141. struct sockaddr_in Address;
  142. int Result;
  143. Address.sin_family = AF_INET;
  144. Address.sin_port = htons(Port);
  145. Result = inet_pton(AF_INET, Host, &(Address.sin_addr));
  146. if (Result == 0) {
  147. return 1;
  148. }
  149. Result = connect(Socket,
  150. (struct sockaddr *)&Address,
  151. sizeof(struct sockaddr_in));
  152. return Result;
  153. }
  154. int
  155. DbgrSocketListen (
  156. int Socket
  157. )
  158. /*++
  159. Routine Description:
  160. This routine starts a server socket listening for connections.
  161. Arguments:
  162. Socket - Supplies the socket to listen on.
  163. Return Value:
  164. 0 on success.
  165. Non-zero on failure.
  166. --*/
  167. {
  168. return listen(Socket, 5);
  169. }
  170. int
  171. DbgrSocketAccept (
  172. int Socket,
  173. char **Host,
  174. int *Port
  175. )
  176. /*++
  177. Routine Description:
  178. This routine accepts a new incoming connection from the given listening
  179. socket.
  180. Arguments:
  181. Socket - Supplies the socket to accept an incoming connection from.
  182. Host - Supplies an optional pointer where a string describing the host will
  183. be returned on success. The caller is responsible for freeing this
  184. string.
  185. Port - Supplies an optional pointer where the port number will be returned
  186. on success.
  187. Return Value:
  188. Returns the newly connected client socket on success.
  189. Returns a negative value on failure.
  190. --*/
  191. {
  192. struct sockaddr_in Address;
  193. int Result;
  194. socklen_t Size;
  195. char StringBuffer[100];
  196. if (Host != NULL) {
  197. *Host = NULL;
  198. }
  199. if (Port != NULL) {
  200. *Port = 0;
  201. }
  202. Size = sizeof(struct sockaddr_in);
  203. Result = accept(Socket, (struct sockaddr *)&Address, &Size);
  204. if (Result < 0) {
  205. return Result;
  206. }
  207. if (Host != NULL) {
  208. StringBuffer[0] = '\0';
  209. inet_ntop(Address.sin_family,
  210. &(Address.sin_addr),
  211. StringBuffer,
  212. sizeof(StringBuffer));
  213. *Host = strdup(StringBuffer);
  214. }
  215. if (Port != NULL) {
  216. *Port = ntohs(Address.sin_port);
  217. }
  218. return Result;
  219. }
  220. int
  221. DbgrSocketGetName (
  222. int Socket,
  223. char **Host,
  224. int *Port
  225. )
  226. /*++
  227. Routine Description:
  228. This routine gets the current local host and port for the given socket.
  229. Arguments:
  230. Socket - Supplies the socket to query.
  231. Host - Supplies an optional pointer where a string describing the host will
  232. be returned on success. The caller is responsible for freeing this
  233. string.
  234. Port - Supplies an optional pointer where the port number will be returned
  235. on success.
  236. Return Value:
  237. 0 on success.
  238. Returns a non-zero value on failure.
  239. --*/
  240. {
  241. struct sockaddr_in Address;
  242. int Result;
  243. socklen_t Size;
  244. if (Host != NULL) {
  245. *Host = NULL;
  246. }
  247. if (Port != NULL) {
  248. *Port = 0;
  249. }
  250. Size = sizeof(Address);
  251. Result = getsockname(Socket, (struct sockaddr *)&Address, &Size);
  252. if (Result != 0) {
  253. return Result;
  254. }
  255. if (Host != NULL) {
  256. *Host = strdup(inet_ntoa(Address.sin_addr));
  257. }
  258. if (Port != NULL) {
  259. *Port = ntohs(Address.sin_port);
  260. }
  261. return 0;
  262. }
  263. int
  264. DbgrSocketShutdown (
  265. int Socket
  266. )
  267. /*++
  268. Routine Description:
  269. This routine shuts down a socket. It shuts down both the read and write
  270. sides of the connection.
  271. Arguments:
  272. Socket - Supplies the socket to shut down.
  273. Return Value:
  274. 0 on success.
  275. Non-zero on failure.
  276. --*/
  277. {
  278. return shutdown(Socket, SHUT_RDWR);
  279. }
  280. void
  281. DbgrSocketClose (
  282. int Socket
  283. )
  284. /*++
  285. Routine Description:
  286. This routine closes a socket.
  287. Arguments:
  288. Socket - Supplies the socket to destroy.
  289. Return Value:
  290. None.
  291. --*/
  292. {
  293. close(Socket);
  294. return;
  295. }
  296. int
  297. DbgrSocketSend (
  298. int Socket,
  299. const void *Data,
  300. int Length
  301. )
  302. /*++
  303. Routine Description:
  304. This routine sends data out of a connected socket.
  305. Arguments:
  306. Socket - Supplies the file descriptor of the socket to send data out of.
  307. Data - Supplies the buffer of data to send.
  308. Length - Supplies the length of the data buffer, in bytes.
  309. Return Value:
  310. Returns the number of bytes sent on success.
  311. -1 on error, and the errno variable will be set to contain more information.
  312. --*/
  313. {
  314. return send(Socket, Data, Length, 0);
  315. }
  316. int
  317. DbgrSocketReceive (
  318. int Socket,
  319. void *Buffer,
  320. int Length
  321. )
  322. /*++
  323. Routine Description:
  324. This routine receives data from a connected socket.
  325. Arguments:
  326. Socket - Supplies the file descriptor of the socket to receive data from.
  327. Buffer - Supplies a pointer to a buffer where the received data will be
  328. returned.
  329. Length - Supplies the length of the data buffer, in bytes.
  330. Return Value:
  331. Returns the number of bytes received on success.
  332. -1 on error, and the errno variable will be set to contain more information.
  333. --*/
  334. {
  335. return recv(Socket, Buffer, Length, 0);
  336. }
  337. int
  338. DbgrSocketPeek (
  339. int Socket,
  340. void *Buffer,
  341. int Length
  342. )
  343. /*++
  344. Routine Description:
  345. This routine peeks at data from a received socket, but does not remove it
  346. from the queue.
  347. Arguments:
  348. Socket - Supplies the file descriptor of the socket to receive data from.
  349. Buffer - Supplies a pointer to a buffer where the peeked data will be
  350. returned.
  351. Length - Supplies the length of the data buffer, in bytes.
  352. Return Value:
  353. Returns the number of bytes received on success.
  354. -1 on error, and the errno variable will be set to contain more information.
  355. --*/
  356. {
  357. return recvfrom(Socket, Buffer, Length, MSG_PEEK, NULL, NULL);
  358. }
  359. //
  360. // --------------------------------------------------------- Internal Functions
  361. //