Beispiel #1
0
static void
read_stdin( int fd, void *data ) {
  UNUSED( data );

  char buf[ 1024 ];
  memset( buf, '\0', sizeof( buf ) );
  ssize_t ret = read( fd, buf, sizeof( buf ) );
  if ( ret < 0 ) {
    if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ) {
      return;
    }

    set_readable( fd, false );

    error( "Read error ( errno = %s [%d] ).", strerror( errno ), errno );
    return;
  }
  else if ( ret == 0 ) {
    return;
  }

  if ( stdin_read_buffer == NULL ) {
    set_readable( fd, false );

    error( "Read buffer is not allocated yet" );
    return;
  }

  char *p = append_back_buffer( stdin_read_buffer, ( size_t ) ret );
  memcpy( p, buf, ( size_t ) ret );
  char *lf = find_character( stdin_read_buffer->data, stdin_read_buffer->length, '\n' );
  while ( lf != NULL ) {
    size_t length = ( size_t ) ( lf - ( char * ) stdin_read_buffer->data );
    if ( length > 0 ) {
      buffer *string = alloc_buffer_with_length( length );
      p = append_back_buffer( string, length );
      memcpy( p, stdin_read_buffer->data, length );
      relay_string( string );
      free_buffer( string );
      remove_front_buffer( stdin_read_buffer, length + 1 );
    }
    else {
      if ( stdin_read_buffer->length > 0 ) {
        remove_front_buffer( stdin_read_buffer, 1 );
      }
    }
    if ( stdin_read_buffer->length == 0 ) {
      break;
    }
    lf = find_character( stdin_read_buffer->data, stdin_read_buffer->length, '\n' );
  }

  // truncate head room manually
  buffer *truncated = duplicate_buffer( stdin_read_buffer );
  free_buffer( stdin_read_buffer );
  stdin_read_buffer = truncated;
}
static void
send_packet( uint32_t destination_port, packet_in packet_in, uint32_t in_port ) {
  openflow_actions *actions = create_actions();
  append_action_output( actions, destination_port, OFPCML_NO_BUFFER );

  openflow_instructions *insts = create_instructions();
  append_instructions_apply_actions( insts, actions );

  oxm_matches *match = create_oxm_matches();
  set_match_from_packet( match, in_port, NULL, packet_in.data );

  buffer *flow_mod = create_flow_mod(
    get_transaction_id(),
    get_cookie(),
    0,
    0,
    OFPFC_ADD,
    60,
    0,
    OFP_HIGH_PRIORITY,
    packet_in.buffer_id,
    0,
    0,
    OFPFF_SEND_FLOW_REM,
    match,
    insts
  );
  send_openflow_message( packet_in.datapath_id, flow_mod );
  free_buffer( flow_mod );
  delete_oxm_matches( match );
  delete_instructions( insts );

  if ( packet_in.buffer_id == OFP_NO_BUFFER ) {
    buffer *frame = duplicate_buffer( packet_in.data );
    fill_ether_padding( frame );
    buffer *packet_out = create_packet_out(
      get_transaction_id(),
      packet_in.buffer_id,
      in_port,
      actions,
      frame
    );
    send_openflow_message( packet_in.datapath_id, packet_out );
    free_buffer( packet_out );
    free_buffer( frame );
  }

  delete_actions( actions );
}
Beispiel #3
0
static void
send_packet_out( packet_in packet_in, openflow_actions *actions ) {
  buffer *frame = duplicate_buffer( packet_in.data );
  fill_ether_padding( frame );

  buffer *packet_out = create_packet_out(
    get_transaction_id(),
    UINT32_MAX,
    packet_in.in_port,
    actions,
    frame
  );

  free_buffer( frame );
  send_openflow_message( packet_in.datapath_id, packet_out );
  free_buffer( packet_out );
}
Beispiel #4
0
static VALUE
packet_in_init_copy( VALUE self, VALUE orig ) {
  if ( self == orig ) {
    return self;
  }

  rb_packet_in *self_pin, *orig_pin;
  Data_Get_Struct( self, rb_packet_in, self_pin );
  Data_Get_Struct( self, rb_packet_in, orig_pin );

  memcpy( &self_pin->packet_in, &orig_pin->packet_in, sizeof( packet_in ) );
  free_buffer( self_pin->data );
  self_pin->data = duplicate_buffer( orig_pin->data );
  parse_packet( self_pin->data );
  self_pin->packet_in.data = self_pin->data;

  return self;
}
Beispiel #5
0
/*
 * Handler called when +OFPT_PACKET_IN+ message is received.
 */
void
handle_packet_in( uint64_t datapath_id, packet_in message ) {
  VALUE controller = ( VALUE ) message.user_data;
  if ( rb_respond_to( controller, rb_intern( "packet_in" ) ) == Qfalse ) {
    return;
  }

  VALUE r_message = rb_funcall( cPacketIn, rb_intern( "new" ), 0 );
  rb_packet_in *tmp = NULL;
  Data_Get_Struct( r_message, rb_packet_in, tmp );
  memcpy( &tmp->packet_in, &message, sizeof( packet_in ) );
  free_buffer( tmp->data );
  tmp->data = duplicate_buffer( message.data );
  parse_packet( tmp->data );
  tmp->packet_in.data = tmp->data;

  rb_funcall( controller, rb_intern( "packet_in" ), 2, ULL2NUM( datapath_id ), r_message );
}
Beispiel #6
0
static void
init_channel_duplicates(CHANNEL *c, CHANNEL *source)
{
    c->source = source;

    if (c->duplicates != NULL) {
        c->free_waiting = c->num_duplicates;

        for (uint32_t i = 0; i < c->num_duplicates; i++) {
            CHANNEL *d = &c->duplicates[i];

            duplicate_buffer(&d->buf, &source->buf);
            d->used_bytes = 0;
            d->free_bytes = 0;

            init_channel_duplicates(d, source);
        }
    }
}
Beispiel #7
0
bool
send_message_to_secure_channel( buffer *message ) {
  assert( send_queue != NULL );
  assert( message != NULL );
  assert( message->length > 0 );
  assert( connection.state == CONNECTED );
  assert( connection.fd >= 0 );

  debug( "Enqueuing a message to send queue ( queue length = %u, message length = %zu ).",
        send_queue->length, message->length );

  if ( send_queue->length == 0 ) {
    set_writable( connection.fd, true );
  }

  buffer *duplicated = duplicate_buffer( message );
  enqueue_message( send_queue, duplicated );

  return true;
}
static void
handle_ovs_vendor_error( uint64_t datapath_id, uint32_t transaction_id, const buffer *data ) {
  assert( data != NULL );
  assert( data->length > 0 );

  buffer *ovs_data = duplicate_buffer( data );
  remove_front_buffer( ovs_data, sizeof( ovs_vendor_error ) );
  ovs_vendor_error *err = data->data;

  debug( "An Open vSwitch vendor error message received ( datapath_id = %#" PRIx64 ", transaction_id = %#x, "
         "type = %#x, code = %#x, ovs_data = %p ).",
         datapath_id, transaction_id, ntohs( err->type ), ntohs( err->code ), ovs_data );

  if ( event_handlers.ovs_error_callback != NULL ) {
    event_handlers.ovs_error_callback( datapath_id, transaction_id, ntohs( err->type ), ntohs( err->code ),
                                      ovs_data, event_handlers.ovs_error_user_data );
  }

  free_buffer( ovs_data );
}
static void
send_packet( uint16_t destination_port, packet_in packet_in ) {
  openflow_actions *actions = create_actions();
  append_action_output( actions, destination_port, UINT16_MAX );

  struct ofp_match match;
  set_match_from_packet( &match, packet_in.in_port, 0, packet_in.data );

  buffer *flow_mod = create_flow_mod(
    get_transaction_id(),
    match,
    get_cookie(),
    OFPFC_ADD,
    60,
    0,
    UINT16_MAX,
    packet_in.buffer_id,
    OFPP_NONE,
    OFPFF_SEND_FLOW_REM,
    actions
  );
  send_openflow_message( packet_in.datapath_id, flow_mod );
  free_buffer( flow_mod );

  if ( packet_in.buffer_id == UINT32_MAX ) {
    buffer *frame = duplicate_buffer( packet_in.data );
    fill_ether_padding( frame );
    buffer *packet_out = create_packet_out(
      get_transaction_id(),
      packet_in.buffer_id,
      packet_in.in_port,
      actions,
      frame
    );
    send_openflow_message( packet_in.datapath_id, packet_out );
    free_buffer( packet_out );
    free_buffer( frame );
  }

  delete_actions( actions );
}
static void
handle_port_desc_reply( uint64_t datapath_id, uint32_t transaction_id,
                        uint16_t type, uint16_t flags, const buffer *data,
                       void *user_data ) {
  UNUSED( transaction_id );
  UNUSED( type );
  UNUSED( flags );
  show_desc *show_desc = user_data;

  desc_entry *desc = lookup_hash_entry( show_desc->db, &datapath_id );
  if ( desc == NULL ) {
    return;
  }
  append_to_tail( &desc->port_desc, duplicate_buffer( data ) );

  if ( more_requests( flags ) ) {
    return;
  }

  display_desc( &desc->desc_stats );
  display_datapath_id( datapath_id );
  for ( list_element *e = desc->port_desc; e != NULL; e = e->next ) {
    buffer *data = e->data;
    struct ofp_port *port = ( struct ofp_port  * ) data->data;
    size_t length = data->length;
    while ( length >= sizeof( struct ofp_port ) ) {
      display_port( port );
      length -= ( uint16_t ) sizeof( struct ofp_port );
      port++;
    }
    free_buffer( e->data );
  }
  delete_list( desc->port_desc );
  delete_hash_entry( show_desc->db, &datapath_id );
  show_desc->count--;
  xfree( desc );

  if ( show_desc->count == 0 ) {
    stop_trema();
  }
}
Beispiel #11
0
static void
send_packet_out( uint64_t datapath_id, openflow_actions *actions, const buffer *original ) {
  const uint32_t transaction_id = get_transaction_id();
  const uint32_t buffer_id = UINT32_MAX;
  const uint16_t in_port = OFPP_NONE;
  buffer *copy = NULL;
  const buffer *packet = original;

  if ( original->length + ETH_FCS_LENGTH < ETH_MINIMUM_LENGTH ) {
    copy = duplicate_buffer( original );
    fill_ether_padding( copy );
    packet = copy;
  }
  buffer *packet_out = create_packet_out( transaction_id, buffer_id, in_port,
                                          actions, packet );

  send_openflow_message( datapath_id, packet_out );

  free_buffer( packet_out );
  if ( copy != NULL ) {
    free_buffer( copy );
  }
}
Beispiel #12
0
static void
handle_packet_in( uint64_t datapath_id, uint32_t transaction_id,
                  uint32_t buffer_id, uint16_t total_len,
                  uint16_t in_port, uint8_t reason, const buffer *data,
                  void *user_data ) {
  assert( in_port != 0 );
  assert( data != NULL );
  assert( user_data != NULL );

  routing_switch *routing_switch = user_data;

  debug( "Packet-In received ( datapath_id = %#" PRIx64 ", transaction_id = %#lx, "
         "buffer_id = %#lx, total_len = %u, in_port = %u, reason = %#x, "
         "data_len = %u ).", datapath_id, transaction_id, buffer_id,
         total_len, in_port, reason, data->length );

  const port_info *port = lookup_outbound_port( routing_switch->switches, datapath_id, in_port );

  const uint8_t *src = packet_info( data )->l2_data.eth->macsa;
  const uint8_t *dst = packet_info( data )->l2_data.eth->macda;

  if ( in_port <= OFPP_MAX || in_port == OFPP_LOCAL ) {
    if ( port == NULL && !lookup_fdb( routing_switch->fdb, src, &datapath_id, &in_port ) ) {
      debug( "Ignoring Packet-In from switch-to-switch link" );
      return;
    }
  }
  else {
    error( "Packet-In from invalid port ( in_port = %#u ).", in_port );
    return;
  }

  if ( !update_fdb( routing_switch->fdb, src, datapath_id, in_port ) ) {
    return;
  }

  buffer *original_packet = duplicate_buffer( data );
  uint16_t out_port;
  uint64_t out_datapath_id;

  if ( lookup_fdb( routing_switch->fdb, dst, &out_datapath_id, &out_port ) ) {
    // Host is located, so resolve path and send flowmod
    if ( ( datapath_id == out_datapath_id ) && ( in_port == out_port ) ) {
      // in and out are same
      free_buffer( original_packet );
      return;
    }

    // Ask path resolver service to lookup a path
    // resolve_path_replied() will be called later
    resolve_path_replied_params *param = xmalloc( sizeof( *param ) );
    param->routing_switch = routing_switch;
    param->original_packet = original_packet;

    resolve_path( datapath_id, in_port, out_datapath_id, out_port,
                  param, resolve_path_replied );
  } else {
    // Host's location is unknown, so flood packet
    flood_packet( datapath_id, in_port, original_packet, routing_switch->switches );
  }
}
static void
make_path( sliceable_switch *sliceable_switch, uint64_t in_datapath_id, uint16_t in_port, uint16_t in_vid,
           uint64_t out_datapath_id, uint16_t out_port, uint16_t out_vid, const buffer *packet ) {
  dlist_element *hops = resolve_path( sliceable_switch->pathresolver, in_datapath_id, in_port, out_datapath_id, out_port );
  if ( hops == NULL ) {
    warn( "No available path found ( %#" PRIx64 ":%u -> %#" PRIx64 ":%u ).",
          in_datapath_id, in_port, out_datapath_id, out_port );
    discard_packet_in( in_datapath_id, in_port, packet, DISCARD_DURATION_NO_PATH );
    return;
  }

  // check if the packet is ARP or not
  if ( sliceable_switch->handle_arp_with_packetout && packet_type_arp( packet ) ) {
    // send packet out for tail switch
    free_hop_list( hops );
    output_packet( packet, out_datapath_id, out_port, out_vid );
    return;
  }

  const uint32_t wildcards = 0;
  struct ofp_match match;
  set_match_from_packet( &match, in_port, wildcards, packet );

  if ( lookup_path( in_datapath_id, match, PRIORITY ) != NULL ) {
    warn( "Duplicated path found." );
    output_packet( packet, out_datapath_id, out_port, out_vid );
    return;
  }

  const uint16_t hard_timeout = 0;
  path *p = create_path( match, PRIORITY, sliceable_switch->idle_timeout, hard_timeout );
  assert( p != NULL );
  openflow_actions *vlan_actions = create_openflow_actions_to_update_vid( in_vid, out_vid );
  for ( dlist_element *e = get_first_element( hops ); e != NULL; e = e->next ) {
    pathresolver_hop *rh = e->data;
    openflow_actions *actions = NULL;
    if ( e->next == NULL ) {
      actions = vlan_actions;
    }
    hop *h = create_hop( rh->dpid, rh->in_port_no, rh->out_port_no, actions );
    assert( h != NULL );
    append_hop_to_path( p, h );
  } // for(;;)
  if ( vlan_actions ) {
    delete_actions( vlan_actions );
  }

  dlist_element *e = get_last_element( hops );
  pathresolver_hop *last_hop = e->data;
  packet_out_params *params = xmalloc( sizeof( struct packet_out_params ) );
  params->packet = duplicate_buffer( packet );
  params->out_datapath_id = last_hop->dpid;
  params->out_port_no = last_hop->out_port_no;
  params->out_vid = out_vid;
  params->in_vid = in_vid;

  bool ret;
  if ( sliceable_switch->setup_reverse_flow && packet_to_set_reverse_path( packet ) ) {
    ret = setup_path( p, setup_reverse_path, params, NULL, NULL );
  }
  else {
    ret = setup_path( p, handle_setup, params, NULL, NULL );
  }
  if ( ret != true ) {
    error( "Failed to set up path." );
    output_packet( packet, out_datapath_id, out_port, out_vid );
    free_buffer( params->packet );
    xfree( params );
  }

  delete_path( p );

  // free them
  free_hop_list( hops );
}
static VALUE
send_packet_out( int argc, VALUE *argv, VALUE self ) {
  VALUE datapath_id = Qnil;
  VALUE options = Qnil;
  rb_scan_args( argc, argv, "11", &datapath_id, &options );

  uint32_t buffer_id = OFP_NO_BUFFER;
  buffer *data = NULL;
  openflow_actions *actions = NULL;
  uint32_t in_port = OFPP_ANY;
  if ( !NIL_P( options ) ) {
    VALUE r_opt_action = HASH_REF( options, actions );
    if ( !NIL_P( r_opt_action ) ) {
      actions = pack_basic_action( r_opt_action );
    }

    VALUE r_opt_message = HASH_REF( options, packet_in );
    VALUE r_opt_data = HASH_REF( options, data );
    if ( !NIL_P( r_opt_message ) ) {

      if ( datapath_id == rb_iv_get( r_opt_message, "@datapath_id" ) ) {
        buffer_id = NUM2UINT( rb_iv_get( r_opt_message, "@buffer_id" ) );
        VALUE match = rb_iv_get( r_opt_message, "@match" );
        in_port = NUM2UINT( rb_iv_get( match, "@in_port" ) );
      }
       
      VALUE r_data = rb_iv_get( r_opt_message, "@data" );
      data = r_array_to_buffer( r_data );
    }
    else if ( !NIL_P( r_opt_data ) ) {
      data = r_array_to_buffer( r_opt_data );
    }

    buffer *packet_out;
    if ( buffer_id == OFP_NO_BUFFER &&
         ( !NIL_P( r_opt_message ) || !NIL_P( r_opt_data ) )) {
      buffer *frame = duplicate_buffer( data );
      fill_ether_padding( frame );

      packet_out = create_packet_out(
        get_transaction_id(),
        buffer_id, 
        in_port,
        actions,
        frame
      );
      free_buffer( data );
      free_buffer( frame );
    } 
    else {
      packet_out = create_packet_out(
        get_transaction_id(),
        buffer_id, 
        in_port,
        actions,
        NULL
      );
    }
    send_openflow_message( NUM2ULL( datapath_id ), packet_out );

    free_buffer( packet_out );
    delete_actions( actions );
  }
  return self;
}
Beispiel #15
0
/*
 * @overload send_packet_out(datapath_id, options={})
 *   Sends a packet_out message to have a packet processed by the datapath.
 *
 *   @example
 *     send_packet_out(
 *       datapath_id,
 *       :packet_in => message,
 *       :actions => Trema::SendOutPort.new(port_no)
 *     )
 *
 *
 *   @param [Number] datapath_id
 *     the datapath to which a message is sent.
 *
 *   @param [Hash] options
 *     the options to create a message with.
 *
 *
 *   @option options [PacketIn] :packet_in (nil)
 *     The {PacketIn} object received by packet_in handler. If this
 *     option is not nil, :buffer_id, :data, and :in_port option is
 *     set automatically according to the value of :packet_in.
 *
 *   @option options [Number] :in_port (OFPP_NONE)
 *     The port from which the frame is to be sent. OFPP_NONE if
 *     none. OFPP_TABLE to perform the actions defined in the flow
 *     table.
 *
 *   @option options [Number] :buffer_id (0xffffffff)
 *     The buffer ID assigned by the datapath. If 0xffffffff, the
 *     frame is not buffered, and the entire frame must be passed in
 *     :data.
 *
 *   @option options [String, nil] :data (nil)
 *     The entire Ethernet frame. Should be of length 0 if buffer_id
 *     is 0xffffffff, and should be of length >0 otherwise.
 *
 *   @option options [Action, Array<Action>, nil] :actions (nil)
 *     The sequence of actions specifying the actions to perform on
 *     the frame.
 *
 *   @option options [Boolean] :zero_padding (false)
 *     If true, fill up to minimum ethernet frame size.
 */
static VALUE
controller_send_packet_out( int argc, VALUE *argv, VALUE self ) {
  VALUE datapath_id = Qnil;
  VALUE options = Qnil;
  rb_scan_args( argc, argv, "11", &datapath_id, &options );

  // Defaults.
  uint32_t buffer_id = UINT32_MAX;
  uint16_t in_port = OFPP_NONE;
  openflow_actions *actions = create_actions();
  const buffer *data = NULL;
  buffer *allocated_data = NULL;
  VALUE opt_zero_padding = Qnil;

  if ( options != Qnil ) {
    VALUE opt_message = rb_hash_aref( options, ID2SYM( rb_intern( "packet_in" ) ) );
    if ( opt_message != Qnil ) {
      packet_in *message;
      Data_Get_Struct( opt_message, packet_in, message );

      if ( NUM2ULL( datapath_id ) == message->datapath_id ) {
        buffer_id = message->buffer_id;
        in_port = message->in_port;
      }
      data = ( buffer_id == UINT32_MAX ? message->data : NULL );
    }

    VALUE opt_buffer_id = rb_hash_aref( options, ID2SYM( rb_intern( "buffer_id" ) ) );
    if ( opt_buffer_id != Qnil ) {
      buffer_id = ( uint32_t ) NUM2ULONG( opt_buffer_id );
    }

    VALUE opt_in_port = rb_hash_aref( options, ID2SYM( rb_intern( "in_port" ) ) );
    if ( opt_in_port != Qnil ) {
      in_port = ( uint16_t ) NUM2UINT( opt_in_port );
    }

    VALUE opt_action = rb_hash_aref( options, ID2SYM( rb_intern( "actions" ) ) );
    if ( opt_action != Qnil ) {
      form_actions( opt_action, actions );
    }

    VALUE opt_data = rb_hash_aref( options, ID2SYM( rb_intern( "data" ) ) );
    if ( opt_data != Qnil ) {
      Check_Type( opt_data, T_STRING );
      uint16_t length = ( uint16_t ) RSTRING_LEN( opt_data );
      allocated_data = alloc_buffer_with_length( length );
      memcpy( append_back_buffer( allocated_data, length ), RSTRING_PTR( opt_data ), length );
      data = allocated_data;
    }

    opt_zero_padding = rb_hash_aref( options, ID2SYM( rb_intern( "zero_padding" ) ) );
    if ( opt_zero_padding != Qnil ) {
      if ( TYPE( opt_zero_padding ) != T_TRUE && TYPE( opt_zero_padding ) != T_FALSE ) {
        rb_raise( rb_eTypeError, ":zero_padding must be true or false" );
      }
    }
  }

  if ( data != NULL && data->length + ETH_FCS_LENGTH < ETH_MINIMUM_LENGTH &&
       opt_zero_padding != Qnil && TYPE( opt_zero_padding ) == T_TRUE ) {
    if ( allocated_data == NULL ) {
      allocated_data = duplicate_buffer( data );
      data = allocated_data;
    }
    fill_ether_padding( allocated_data );
  }

  buffer *packet_out = create_packet_out(
    get_transaction_id(),
    buffer_id,
    in_port,
    actions,
    data
  );
  send_openflow_message( NUM2ULL( datapath_id ), packet_out );

  if ( allocated_data != NULL ) {
    free_buffer( allocated_data );
  }
  free_buffer( packet_out );
  delete_actions( actions );
  return self;
}
Beispiel #16
0
static void
test_parse_packet_lldp_over_ip_succeeds() {
  const char filename[] = "./unittests/lib/test_packets/lldp_over_ip.cap";
  buffer *copy;
  buffer *buffer = store_packet_to_buffer( filename );

  assert_true( parse_packet( buffer ) );

  packet_info *packet_info = buffer->user_data;

  assert_int_equal( packet_info->format, ETH_IPV4_ETHERIP );

  u_char macda[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  u_char macsa[] = { 0xfe, 0xab, 0x7e, 0x15, 0x3f, 0xc6 };
  assert_memory_equal( packet_info->eth_macda, macda, ETH_ADDRLEN );
  assert_memory_equal( packet_info->eth_macsa, macsa, ETH_ADDRLEN );

  assert_int_equal( packet_info->ipv4_version, 4 );
  assert_int_equal( packet_info->ipv4_ihl, 5 );
  assert_int_equal( packet_info->ipv4_tos, 0 );
  assert_int_equal( packet_info->ipv4_tot_len, 51 );
  assert_int_equal( packet_info->ipv4_id, 0 );
  assert_int_equal( packet_info->ipv4_frag_off, 0 );
  assert_int_equal( packet_info->ipv4_ttl, 1 );
  assert_int_equal( packet_info->ipv4_protocol, 97 );
  assert_int_equal( packet_info->ipv4_checksum, 0 );
  assert_int_equal( packet_info->ipv4_saddr, 0x0a2a7aca );
  assert_int_equal( packet_info->ipv4_daddr, 0x0a2a7ad4 );

  uint16_t sample = ntohs( *( uint16_t * ) packet_info->l4_payload );
  assert_int_equal( sample, 0x0180 );
  assert_int_equal( packet_info->l4_payload_length, 31 );

  assert_int_equal( packet_info->etherip_version, ETHERIP_VERSION );
  assert_int_equal( packet_info->etherip_offset, 36 );

  copy = duplicate_buffer( buffer );
  assert_true ( copy != NULL );
  assert_true( copy->length == buffer->length );
  copy->user_data = NULL;
  remove_front_buffer( copy, packet_info->etherip_offset );

  assert_true( parse_packet( copy ) );

  packet_info = copy->user_data;

  assert_int_equal( packet_info->format, ETH_LLDP );

  u_char lldp_macda[] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e };
  u_char lldp_macsa[] = { 0xfe, 0xab, 0x7e, 0x15, 0x3f, 0xc6 };

  assert_memory_equal( packet_info->eth_macda, lldp_macda, ETH_ADDRLEN );
  assert_memory_equal( packet_info->eth_macsa, lldp_macsa, ETH_ADDRLEN );

  sample = ntohs( *( uint16_t * ) packet_info->l3_payload );
  assert_int_equal( sample, 0x0205 );
  assert_int_equal( packet_info->l3_payload_length, 17 );

  free_buffer( copy );

  free_buffer( buffer );
}
Beispiel #17
0
/*!	Clones the buffer by grabbing another reference to the underlying data.
	If that data changes, it will be changed in the clone as well.

	If \a shareFreeSpace is \c true, the cloned buffer may claim the free
	space in the original buffer as the original buffer can still do. If you
	are using this, it's your responsibility that only one of the buffers
	will do this.
*/
static net_buffer *
clone_buffer(net_buffer *_buffer, bool shareFreeSpace)
{
	return duplicate_buffer(_buffer);
}