Commit 1c29d89d authored by Yann Garcia's avatar Yann Garcia
Browse files

Adding offline UDP layer

parent ee215a0f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
#sources := udp_layer.cc udp_pcap_layer.cc
sources := udp_layer.cc
sources := udp_layer.cc udp_offline_layer.cc
includes := .
+69 −0
Original line number Diff line number Diff line
#include "udp_offline_layer_factory.hh"

#include "loggers.hh"

udp_offline_layer::udp_offline_layer(const std::string& p_type, const std::string& p_param) : layer(p_type), _params() {
  loggers::get_instance().log(">>> udp_offline_layer::udp_offline_layer: '%s', %s", to_string().c_str(), p_param.c_str());
  params::convert(_params, p_param);
}

void udp_offline_layer::send_data(OCTETSTRING& p_data, params& p_params) {
  loggers::get_instance().log_msg(">>> udp_offline_layer::send_data: ", p_data);
  p_params.log();

  // FIXME FSCOM: To be done
  loggers::get_instance().warning("udp_offline_layer::send_data: Not implemented. Only for offline mode");

  params::const_iterator it = p_params.find("src_port");
  uint16_t src_port = (it != p_params.cend()) ? static_cast<uint16_t>(std::stoi(it->second)) : 2123;
  it = p_params.find("dst_port");
  uint16_t dst_port = (it != p_params.cend()) ? static_cast<uint16_t>(std::stoi(it->second)) : 2123;

  TTCN_Buffer udp;
  udp.put_c(static_cast<unsigned char>((src_port >> 8) & 0xFF));
  udp.put_c(static_cast<unsigned char>(src_port & 0xFF));
  udp.put_c(static_cast<unsigned char>((dst_port >> 8) & 0xFF));
  udp.put_c(static_cast<unsigned char>(dst_port & 0xFF));
  uint16_t length = static_cast<uint16_t>(8 + p_data.lengthof());
  udp.put_c(static_cast<unsigned char>((length >> 8) & 0xFF));
  udp.put_c(static_cast<unsigned char>(length & 0xFF));
  udp.put_c(0x00); // Checksum, not computed (optional in IPv4)
  udp.put_c(0x00);

  OCTETSTRING udp_pdu(udp.get_read_len(), udp.get_data());
  udp_pdu += p_data;

  send_to_all_layers(udp_pdu, p_params);
}

void udp_offline_layer::receive_data(OCTETSTRING& p_data, params& p_params) {
  loggers::get_instance().log_msg(">>> udp_offline_layer::receive_data: ", p_data);

  if (p_data.lengthof() < 8) {
    loggers::get_instance().warning("udp_offline_layer::receive_data: Truncated UDP header, discard %d bytes", p_data.lengthof());
    return;
  }

  const uint8_t* p = static_cast<const uint8_t*>(p_data);
  uint16_t src_port = static_cast<uint16_t>((p[0] << 8) | p[1]);
  uint16_t dst_port = static_cast<uint16_t>((p[2] << 8) | p[3]);
  loggers::get_instance().log("udp_offline_layer::receive_data: src_port=%d, dst_port=%d", src_port, dst_port);

  params::const_iterator it = _params.find("port");
  if (it != _params.cend()) {
    uint16_t port = static_cast<uint16_t>(std::stoi(it->second));
    if ((src_port != port) && (dst_port != port)) {
      loggers::get_instance().log("udp_offline_layer::receive_data: Datagram port doesn't match %d, discard it", port);
      return;
    }
  }

  OCTETSTRING data(p_data.lengthof() - 8, p + 8);

  p_params.insert(std::pair<std::string, std::string>("udp_src_port", std::to_string(src_port)));
  p_params.insert(std::pair<std::string, std::string>("udp_dst_port", std::to_string(dst_port)));

  receive_to_all_layers(data, p_params);
}

udp_offline_layer_factory udp_offline_layer_factory::_f;
+56 −0
Original line number Diff line number Diff line
/*!
 * \file      udp_offline_layer.hh
 * \brief     Header file for offline ITS UDP/IP protocol layer definition.
 * \author    ETSI TTF T059
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 */
#pragma once

#include "params.hh"
#include "t_layer.hh"

/*!
 * \class udp_offline_layer
 * \brief  This class provides description of the offline UDP/IP protocol layer.
 *         It parses the UDP header out of the raw IP payload (as delivered by \c ip_offline_layer)
 *         and forwards the UDP payload to the upper layers, mirroring what \c udp_layer delivers
 *         in online mode. This is the offline counterpart missing next to \c sctp_layer/sctp_offline_layer
 *         for protocols layered above UDP instead of SCTP (e.g. GTPv2-C).
 */
class udp_offline_layer : public layer {
  params _params; //! Layer parameters. \c port restricts delivery to datagrams with a matching source or destination port (default: any)

public: //! \publicsection
  /*!
   * \brief Specialised constructor
   *        Create a new instance of the udp_offline_layer class
   * \param[in] p_type \todo
   * \param[in] p_param \todo
   */
  udp_offline_layer(const std::string& p_type, const std::string& p_param);
  /*!
   * \brief Default destructor
   */
  virtual ~udp_offline_layer(){};

  /*!
   * \virtual
   * \fn void send_data(OCTETSTRING& data, params& p_params);
   * \brief Send bytes formated data to the lower layers
   * \param[in] p_data The data to be sent
   * \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
   */
  virtual void send_data(OCTETSTRING& p_data, params& p_params);
  /*!
   * \virtual
   * \fn void receive_data(OCTETSTRING& data, params& p_params);
   * \brief Receive bytes formated data from the lower layers
   * \param[in] p_data The bytes formated data received
   * \param[in] p_params Some lower layers parameters values when data was received
   */
  virtual void receive_data(OCTETSTRING& p_data, params& p_params);
}; // End of class udp_offline_layer
+42 −0
Original line number Diff line number Diff line
/*!
 * \file      udp_offline_layer_factory.hh
 * \brief     Header file for offline ITS UDP/IP protocol layer factory.
 * \author    ETSI TTF T059
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 */
#pragma once

#include "layer_stack_builder.hh"

#include "udp_offline_layer.hh"

/*!
 * \class udp_offline_layer_factory
 * \brief  This class provides a factory class to create an udp_offline_layer class instance
 */
class udp_offline_layer_factory : public layer_factory {
  static udp_offline_layer_factory _f; //! Reference to the unique instance of this class
public:                                //! \publicsection
  /*!
   * \brief Default constructor
   *        Create a new instance of the udp_offline_layer_factory class
   * \remark The offline UDP/IP layer identifier is UDP_FILE
   */
  udp_offline_layer_factory() {
    // register factory
    layer_stack_builder::register_layer_factory("UDP_FILE", this);
  };
  /*!
   * \fn layer* create_layer(const std::string&  type, const std::string&  param);
   * \brief  Create the layers stack based on the provided layers stack description
   * \param[in] p_type The provided layers stack description
   * \param[in] p_params Optional parameters
   * \return 0 on success, -1 otherwise
   * \inline
   */
  inline virtual layer *create_layer(const std::string& p_type, const std::string& p_param) { return new udp_offline_layer(p_type, p_param); };
}; // End of class udp_offline_layer_factory