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