コード例 #1
0
ファイル: dlep_writer.c プロジェクト: OLSR/OONF
/**
 * Add a TLV to a DLEP writer buffer
 * @param writer dlep writer
 * @param type TLV type
 * @param data1 first part of TLV value
 * @param len1 length of first value
 * @param data2 second part of TLV value
 * @param len2 length of second value
 */
void
dlep_writer_add_tlv2(
  struct dlep_writer *writer, uint16_t type, const void *data1, uint16_t len1, const void *data2, uint16_t len2) {
  abuf_append_uint16(writer->out, htons(type));
  abuf_append_uint16(writer->out, htons(len1 + len2));
  abuf_memcpy(writer->out, data1, len1);
  abuf_memcpy(writer->out, data2, len2);
}
コード例 #2
0
ファイル: dlep_writer.c プロジェクト: gabri94/OONF
/**
 * Add a TLV to a DLEP writer buffer
 * @param writer dlep writer
 * @param type TLV type
 * @param data pointer to TLV value
 * @param len length of value, can be 0
 */
void
dlep_writer_add_tlv(struct dlep_writer *writer,
    uint16_t type, const void *data, uint16_t len) {
  abuf_append_uint16(writer->out, htons(type));
  abuf_append_uint16(writer->out, htons(len));
  abuf_memcpy(writer->out, data, len);
}
コード例 #3
0
ファイル: autobuf.c プロジェクト: brabander/olsr
/**
 * Append the result of a template engine into an autobuffer.
 * Each usage of a key will be replaced with the corresponding
 * value.
 * @param autobuf pointer to autobuf object
 * @param file code file where this function was called (supplied by macro)
 * @param line line number in file where this function was called (supplied by macro)
 * @param format format string (as supplied to abuf_template_init()
 * @param values array of values (same number as keys)
 * @param table pointer to index table initialized by abuf_template_init()
 * @param indexCount length of index table as returned by abuf_template_init()
 * @return -1 if an out-of-memory error happened, 0 otherwise
 */
int
abuf_templatef (struct autobuf *autobuf,
    const char *format, char **values, size_t *table, size_t indexCount) {
  size_t i, last = 0;

  if (autobuf == NULL) return 0;

  for (i=0; i<indexCount; i+=3) {
    /* copy prefix text */
    if (last < table[i+1]) {
      if (abuf_memcpy(autobuf, &format[last], table[i+1] - last) < 0) {
        return -1;
      }
    }
    if (abuf_puts(autobuf, values[table[i]]) < 0) {
      return -1;
    }
    last = table[i+2];
  }

  if (last < strlen(format)) {
    if (abuf_puts(autobuf, &format[last]) < 0) {
      return -1;
    }
  }
  return 0;
}
コード例 #4
0
ファイル: dlep_interface.c プロジェクト: treba123/OONF
/**
 * Callback to send multicast over interface
 * @param session dlep session
 * @param af_family address family for multicast
 */
static void
_cb_send_multicast(struct dlep_session *session, int af_family) {
  struct dlep_if *interf;

  if (abuf_getlen(session->writer.out) <= sizeof(_DLEP_PREFIX) - 1
      || !netaddr_socket_is_unspec(&session->remote_socket)) {
    return;
  }

  /* get pointer to radio interface */
  interf = container_of(session, struct dlep_if, session);

  if (interf->session_tree.count > 0
      && interf->single_session) {
    /* do not produce UDP traffic as long as we are connected */
    return;
  }

  OONF_DEBUG(session->log_source, "Send multicast %"
      PRINTF_SIZE_T_SPECIFIER " bytes",
      abuf_getlen(session->writer.out));

  oonf_packet_send_managed_multicast(&interf->udp,
      abuf_getptr(session->writer.out), abuf_getlen(session->writer.out),
      af_family);

  abuf_clear(session->writer.out);

  /* add dlep prefix to buffer */
  abuf_memcpy(session->writer.out, _DLEP_PREFIX, sizeof(_DLEP_PREFIX) - 1);
}
コード例 #5
0
ファイル: template.c プロジェクト: benpicco/oonf_api
/**
 * Append the result of a template engine into an autobuffer.
 * Each usage of a key will be replaced with the corresponding
 * value.
 * @param out pointer to autobuf object
 * @param format format string (as supplied to abuf_template_init()
 * @param storage pointer to template storage object, which will be filled by
 *   this function
 * @return -1 if an out-of-memory error happened, 0 otherwise
 */
int
abuf_add_template(struct autobuf *out, const char *format,
    struct abuf_template_storage *storage) {
  struct abuf_template_storage_entry *entry;
  size_t i, last = 0;

  if (out == NULL) return 0;

  for (i=0; i<storage->count; i++) {
    entry = &storage->indices[i];

    /* copy prefix text */
    if (last < entry->start) {
      if (abuf_memcpy(out, &format[last], entry->start - last) < 0) {
        return -1;
      }
    }

    if (entry->data->value) {
      if (abuf_puts(out, entry->data->value) < 0) {
        return -1;
      }
    }
    last = entry->end;
  }

  if (last < strlen(format)) {
    if (abuf_puts(out, &format[last]) < 0) {
      return -1;
    }
  }
  return 0;
}
コード例 #6
0
ファイル: dlep_interface.c プロジェクト: treba123/OONF
/**
 * Add a new interface to this dlep instance
 * @param interf pointer to interface
 * @param ifname name of interface
 * @param l2_origin layer2 originator that shall be used
 * @param log_src logging source that shall be used
 * @param radio true if it is a radio interface, false for router
 * @return -1 if an error happened, 0 otherwise
 */
int
dlep_if_add(struct dlep_if *interf, const char *ifname,
    uint32_t l2_origin, enum oonf_log_source log_src, bool radio) {
  struct dlep_extension *ext;

  /* initialize key */
  strscpy(interf->l2_ifname, ifname,
      sizeof(interf->l2_ifname));
  interf->_node.key = interf->l2_ifname;

  if (abuf_init(&interf->udp_out)) {
    return -1;
  }

  /* add dlep prefix to buffer */
  abuf_memcpy(&interf->udp_out,
      _DLEP_PREFIX, sizeof(_DLEP_PREFIX) - 1);

  if (dlep_session_add(&interf->session,
      interf->l2_ifname, l2_origin,
      &interf->udp_out,
      radio, log_src)) {
    abuf_free(&interf->udp_out);
    return -1;
  }

  /* initialize stream list */
  avl_init(&interf->session_tree, avl_comp_netaddr_socket, false);

  /* initialize discovery socket */
  interf->udp.config.user = interf;
  interf->udp.config.receive_data = _cb_receive_udp;
  oonf_packet_add_managed(&interf->udp);

  /* initialize session */
  interf->session.cb_send_buffer = _cb_send_multicast;
  interf->session.cb_end_session = NULL;
  interf->session.restrict_signal =
      radio ? DLEP_PEER_DISCOVERY : DLEP_PEER_OFFER;
  interf->session.writer.out = &interf->udp_out;

  /* inform all extension */
  avl_for_each_element(dlep_extension_get_tree(), ext, _node) {
    if (radio) {
      if (ext->cb_session_init_radio) {
        ext->cb_session_init_radio(&interf->session);
      }
    }
    else {
      if (ext->cb_session_init_router) {
        ext->cb_session_init_router(&interf->session);
      }
    }
  }
  return 0;
}
コード例 #7
0
ファイル: template.c プロジェクト: benpicco/oonf_api
/**
 * Prints a string to an autobuffer, using JSON escape rules
 * @param out pointer to output buffer
 * @param txt string to print
 * @param delimiter true if string must be enclosed in quotation marks
 * @return -1 if an error happened, 0 otherwise
 */
static int
_json_printvalue(struct autobuf *out, const char *txt, bool delimiter) {
  const char *ptr;
  bool unprintable;

  if (delimiter) {
    if (abuf_puts(out, "\"") < 0) {
      return -1;
    }
  }
  else if (*txt == 0) {
    abuf_puts(out, "0");
  }

  ptr = txt;
  while (*ptr) {
    unprintable = !str_char_is_printable(*ptr);
    if (unprintable || *ptr == '\\' || *ptr == '\"') {
      if (ptr != txt) {
        if (abuf_memcpy(out, txt, ptr - txt) < 0) {
          return -1;
        }
      }

      if (unprintable) {
        if (abuf_appendf(out, "\\u00%02x", (unsigned char)(*ptr++)) < 0) {
          return -1;
        }
      }
      else {
        if (abuf_appendf(out, "\\%c", *ptr++) < 0) {
          return -1;
        }
      }
      txt = ptr;
    }
    else {
      ptr++;
    }
  }

  if (abuf_puts(out, txt) < 0) {
    return -1;
  }
  if (delimiter) {
    if (abuf_puts(out, "\"") < 0) {
      return -1;
    }
  }

  return 0;
}
コード例 #8
0
ファイル: oonf_packet_socket.c プロジェクト: gabri94/OONF
/**
 * Send a data packet through a packet socket. The transmission might not
 * be happen synchronously if the socket would block.
 * @param pktsocket pointer to packet socket
 * @param remote ip/address to send packet to
 * @param data pointer to data to be sent
 * @param length length of data
 * @return -1 if an error happened, 0 otherwise
 */
int
oonf_packet_send(struct oonf_packet_socket *pktsocket, union netaddr_socket *remote,
    const void *data, size_t length) {
  int result;
  struct netaddr_str buf;

  if (abuf_getlen(&pktsocket->out) == 0) {
    /* no backlog of outgoing packets, try to send directly */
    result = os_fd_sendto(&pktsocket->scheduler_entry.fd, data, length, remote,
        pktsocket->config.dont_route);
    if (result > 0) {
      /* successful */
      OONF_DEBUG(LOG_PACKET, "Sent %d bytes to %s %s",
          result, netaddr_socket_to_string(&buf, remote),
          pktsocket->os_if != NULL ? pktsocket->os_if->name : "");
      return 0;
    }

    if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) {
      OONF_WARN(LOG_PACKET, "Cannot send UDP packet to %s: %s (%d)",
          netaddr_socket_to_string(&buf, remote), strerror(errno), errno);
      return -1;
    }
  }

  /* append destination */
  abuf_memcpy(&pktsocket->out, remote, sizeof(*remote));

  /* append data length */
  abuf_append_uint16(&pktsocket->out, length);

  /* append data */
  abuf_memcpy(&pktsocket->out, data, length);

  /* activate outgoing socket scheduler */
  oonf_socket_set_write(&pktsocket->scheduler_entry, true);
  return 0;
}
コード例 #9
0
ファイル: dlep_interface.c プロジェクト: treba123/OONF
/**
 * Callback to receive UDP data through oonf_packet_managed API
 * @param pkt packet socket
 * @param from network socket the packet was received from
 * @param ptr pointer to packet data
 * @param length length of packet data
 */
static void
_cb_receive_udp(struct oonf_packet_socket *pkt,
    union netaddr_socket *from, void *ptr, size_t length) {
  struct dlep_if *interf;
  uint8_t *buffer;
  ssize_t processed;
  struct netaddr_str nbuf;

  interf = pkt->config.user;
  buffer = ptr;

  if (interf->session_tree.count > 0
      && interf->single_session) {
    /* ignore UDP traffic as long as we have a connection */
    return;
  }

  if (length < sizeof(_DLEP_PREFIX) - 1) {
    /* ignore unknown prefix */
    return;
  }

  if (memcmp(buffer, _DLEP_PREFIX, sizeof(_DLEP_PREFIX)-1) != 0) {
    OONF_WARN(interf->session.log_source,
        "Incoming UDP packet with unknown signature");
    return;
  }

  /* advance pointer and fix length */
  buffer += (sizeof(_DLEP_PREFIX) - 1);
  length -= (sizeof(_DLEP_PREFIX) - 1);

  /* copy socket information */
  memcpy(&interf->session.remote_socket, from,
      sizeof(interf->session.remote_socket));

  processed = dlep_session_process_buffer(&interf->session, buffer, length);
  if (processed < 0) {
    return ;
  }

  if ((size_t)processed < length) {
    OONF_WARN(interf->session.log_source,
        "Received malformed or too short UDP packet from %s",
        netaddr_socket_to_string(&nbuf, from));
    /* incomplete or bad packet, just ignore it */
    return;
  }

  if (abuf_getlen(interf->session.writer.out) > sizeof(_DLEP_PREFIX) - 1) {
    /* send an unicast response */
    oonf_packet_send_managed(&interf->udp, from,
        abuf_getptr(interf->session.writer.out),
        abuf_getlen(interf->session.writer.out));
    abuf_clear(interf->session.writer.out);

    /* add dlep prefix to buffer */
    abuf_memcpy(interf->session.writer.out,
        _DLEP_PREFIX, sizeof(_DLEP_PREFIX) - 1);
  }

  netaddr_socket_invalidate(&interf->session.remote_socket);
}