rpcap-protocol.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
  3. * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the Politecnico di Torino, CACE Technologies
  16. * nor the names of its contributors may be used to endorse or promote
  17. * products derived from this software without specific prior written
  18. * permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. */
  33. #ifdef HAVE_CONFIG_H
  34. #include <config.h>
  35. #endif
  36. #include <string.h> /* for strlen(), ... */
  37. #include <stdlib.h> /* for malloc(), free(), ... */
  38. #include <stdarg.h> /* for functions with variable number of arguments */
  39. #include <errno.h> /* for the errno variable */
  40. #include "sockutils.h"
  41. #include "portability.h"
  42. #include "rpcap-protocol.h"
  43. #include <pcap/pcap.h>
  44. /*
  45. * This file contains functions used both by the rpcap client and the
  46. * rpcap daemon.
  47. */
  48. /*
  49. * This function sends a RPCAP error to our peer.
  50. *
  51. * It has to be called when the main program detects an error.
  52. * It will send to our peer the 'buffer' specified by the user.
  53. * This function *does not* request a RPCAP CLOSE connection. A CLOSE
  54. * command must be sent explicitly by the program, since we do not know
  55. * whether the error can be recovered in some way or if it is a
  56. * non-recoverable one.
  57. *
  58. * \param sock: the socket we are currently using.
  59. *
  60. * \param ver: the protocol version we want to put in the reply.
  61. *
  62. * \param errcode: a integer which tells the other party the type of error
  63. * we had.
  64. *
  65. * \param error: an user-allocated (and '0' terminated) buffer that contains
  66. * the error description that has to be transmitted to our peer. The
  67. * error message cannot be longer than PCAP_ERRBUF_SIZE.
  68. *
  69. * \param errbuf: a pointer to a user-allocated buffer (of size
  70. * PCAP_ERRBUF_SIZE) that will contain the error message (in case there
  71. * is one). It could be network problem.
  72. *
  73. * \return '0' if everything is fine, '-1' if some errors occurred. The
  74. * error message is returned in the 'errbuf' variable.
  75. */
  76. int
  77. rpcap_senderror(SOCKET sock, uint8 ver, unsigned short errcode, const char *error, char *errbuf)
  78. {
  79. char sendbuf[RPCAP_NETBUF_SIZE]; /* temporary buffer in which data to be sent is buffered */
  80. int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
  81. uint16 length;
  82. length = (uint16)strlen(error);
  83. if (length > PCAP_ERRBUF_SIZE)
  84. length = PCAP_ERRBUF_SIZE;
  85. rpcap_createhdr((struct rpcap_header *) sendbuf, ver, RPCAP_MSG_ERROR, errcode, length);
  86. if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
  87. RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE))
  88. return -1;
  89. if (sock_bufferize(error, length, sendbuf, &sendbufidx,
  90. RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE))
  91. return -1;
  92. if (sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) < 0)
  93. return -1;
  94. return 0;
  95. }
  96. /*
  97. * This function fills in a structure of type rpcap_header.
  98. *
  99. * It is provided just because the creation of an rpcap header is a common
  100. * task. It accepts all the values that appears into an rpcap_header, and
  101. * it puts them in place using the proper hton() calls.
  102. *
  103. * \param header: a pointer to a user-allocated buffer which will contain
  104. * the serialized header, ready to be sent on the network.
  105. *
  106. * \param ver: a value (in the host byte order) which will be placed into the
  107. * header.ver field and that represents the protocol version number of the
  108. * current message.
  109. *
  110. * \param type: a value (in the host byte order) which will be placed into the
  111. * header.type field and that represents the type of the current message.
  112. *
  113. * \param value: a value (in the host byte order) which will be placed into
  114. * the header.value field and that has a message-dependent meaning.
  115. *
  116. * \param length: a value (in the host by order) which will be placed into
  117. * the header.length field, representing the payload length of the message.
  118. *
  119. * \return Nothing. The serialized header is returned into the 'header'
  120. * variable.
  121. */
  122. void
  123. rpcap_createhdr(struct rpcap_header *header, uint8 ver, uint8 type, uint16 value, uint32 length)
  124. {
  125. memset(header, 0, sizeof(struct rpcap_header));
  126. header->ver = ver;
  127. header->type = type;
  128. header->value = htons(value);
  129. header->plen = htonl(length);
  130. }
  131. /*
  132. * Convert a message type to a string containing the type name.
  133. */
  134. static const char *requests[] =
  135. {
  136. NULL, /* not a valid message type */
  137. "RPCAP_MSG_ERROR",
  138. "RPCAP_MSG_FINDALLIF_REQ",
  139. "RPCAP_MSG_OPEN_REQ",
  140. "RPCAP_MSG_STARTCAP_REQ",
  141. "RPCAP_MSG_UPDATEFILTER_REQ",
  142. "RPCAP_MSG_CLOSE",
  143. "RPCAP_MSG_PACKET",
  144. "RPCAP_MSG_AUTH_REQ",
  145. "RPCAP_MSG_STATS_REQ",
  146. "RPCAP_MSG_ENDCAP_REQ",
  147. "RPCAP_MSG_SETSAMPLING_REQ",
  148. };
  149. #define NUM_REQ_TYPES (sizeof requests / sizeof requests[0])
  150. static const char *replies[] =
  151. {
  152. NULL,
  153. NULL, /* this would be a reply to RPCAP_MSG_ERROR */
  154. "RPCAP_MSG_FINDALLIF_REPLY",
  155. "RPCAP_MSG_OPEN_REPLY",
  156. "RPCAP_MSG_STARTCAP_REPLY",
  157. "RPCAP_MSG_UPDATEFILTER_REPLY",
  158. NULL, /* this would be a reply to RPCAP_MSG_CLOSE */
  159. NULL, /* this would be a reply to RPCAP_MSG_PACKET */
  160. "RPCAP_MSG_AUTH_REPLY",
  161. "RPCAP_MSG_STATS_REPLY",
  162. "RPCAP_MSG_ENDCAP_REPLY",
  163. "RPCAP_MSG_SETSAMPLING_REPLY",
  164. };
  165. #define NUM_REPLY_TYPES (sizeof replies / sizeof replies[0])
  166. const char *
  167. rpcap_msg_type_string(uint8 type)
  168. {
  169. if (type & RPCAP_MSG_IS_REPLY) {
  170. type &= ~RPCAP_MSG_IS_REPLY;
  171. if (type >= NUM_REPLY_TYPES)
  172. return NULL;
  173. return replies[type];
  174. } else {
  175. if (type >= NUM_REQ_TYPES)
  176. return NULL;
  177. return requests[type];
  178. }
  179. }