Beispiel #1
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("*** -> Received packet of length %d \n",len);
  /* Error handling */
  if (len < sizeof(sr_ethernet_hdr_t))
  {
    printf("Invalid packet, insufficient length.\n");
    return;
  }

  struct sr_if* iface = sr_get_interface(sr, interface);
  if (iface == 0)
  {
    printf("Invalid interface, interface not found.\n");
  }

  /* Handle ARP packet */
  if (ethertype(packet) == ethertype_arp)
  {
    sr_handle_arp_packet(sr, packet, len, interface, iface);
  }
  /* Handle IP packet */
  else if (ethertype(packet) == ethertype_ip)
  {
    sr_handle_ip_packet(sr, packet, len, interface, iface);
  }
}/* end sr_ForwardPacket */
Beispiel #2
0
/*---------------------------------------------------------------------
 * Method: sr_handlepacket(uint8_t* p,char* interface)
 * Scope:  Global
 *
 * This method is called each time the router receives a packet on the
 * interface.  The packet buffer, the packet length and the receiving
 * interface are passed in as parameters. The packet is complete with
 * ethernet headers.
 *
 * Note: Both the packet buffer and the character's memory are handled
 * by sr_vns_comm.c that means do NOT delete either.  Make a copy of the
 * packet instead if you intend to keep it around beyond the scope of
 * the method call.
 *
 *---------------------------------------------------------------------*/
void sr_handlepacket(struct sr_instance* sr, 
		     uint8_t* packet, /*lent*/
		     unsigned int len, 
		     char* interface){
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);
  
  printf("*** -> Received packet of length %d \n",len);

  /*Initializers*/
  //for ICMP
  uint16_t ethtype = ethertype(packet);//either ARP or IP
  
  if (ethtype == ethertype_ip){
    int iRet = handle_IP_packet(sr,packet,len, interface);
    if (iRet != 1){
      fprintf(stderr, "Didn't process IP packet properly\n");
    }
  }else if (ethtype == ethertype_arp){/*ARP*/
    int aRet =  handle_ARP_packet(sr,packet,len, interface);
    if (aRet != 1){
      fprintf(stderr, "Didn't process ARP packet properly\n");
    }
  }else{
    fprintf(stderr, "Unrecognized Ethernet Type, while processing\n");
  }
}/* end sr_handlePacket */
Beispiel #3
0
/*---------------------------------------------------------------------
 * Method: sr_handlepacket(uint8_t* p,char* interface)
 * Scope:  Global
 *
 * This method is called each time the router receives a packet on the
 * interface.  The packet buffer, the packet length and the receiving
 * interface are passed in as parameters. The packet is complete with
 * ethernet headers.
 *
 * Note: Both the packet buffer and the character's memory are handled
 * by sr_vns_comm.c that means do NOT delete either.  Make a copy of the
 * packet instead if you intend to keep it around beyond the scope of
 * the method call.
 *
 *---------------------------------------------------------------------*/
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{

  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("*** -> Received packet of length %d \n",len);
	
	/* Ensure that the length is at least enough for an ethernet header */
	if (len < sizeof(struct sr_ethernet_hdr))
		return;

  /* Handle ARP packet */
	if (ethertype(packet) == ethertype_arp) {
		process_arp(sr, packet, len, interface);

	/* Handle IP packet */	
	} else {
		process_ip(sr, packet, len, interface);
	}
}/* end sr_ForwardPacket */
Beispiel #4
0
 void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
    unsigned int len,
        char* interface/* lent */) {
    /* REQUIRES */
    assert(sr);
    assert(packet);
    assert(interface);
    int res;
 

    /* Ethernet */
    int minlength = sizeof(sr_ethernet_hdr_t);
    if (len < minlength) {
        fprintf(stderr, "Failed to parse ETHERNET header, insufficient length\n");
        return;
    }

    uint16_t ethtype = ethertype(packet);

    /* IP */
    if (ethtype == ethertype_ip) { 

        minlength += sizeof(sr_ip_hdr_t);
        if (len < minlength) {
            fprintf(stderr, "Failed to parse IP header, insufficient length\n");
            return;
        } 
        res = handle_ip_packet(sr, packet, len );

        if (res == -1){
            fprintf(stderr, "bad handle_ip_packet\n");
            return;
        }
        
        /* end IP */
    } else if (ethtype == ethertype_arp) { 
        /* begin ARP */

        minlength += sizeof(sr_arp_hdr_t);

        if (len < minlength){
            fprintf(stderr, "Failed to parse ARP header, insufficient length\n");
        }
        res = handle_arp_packet(sr, packet, len );

        if (res == -1){
            fprintf(stderr, "bad handle_arp_packet\n");
            return;
        }
        /* end ARP */
    } else {
        fprintf(stderr, "Unrecognized Ethernet Type: %d\n", ethtype);
    }
    /* TODO: fill in code here */
    return;

}
Beispiel #5
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("*** -> Received packet of length %d \n",len);

  /* fill in code here */
  
  /* check if header has the correct size */
  if (len < sizeof(sr_ethernet_hdr_t)) {
	fprintf(stderr, "Error: invalid packet length (ether_hdr)\n");
	return;
  }
  
  if (len > 1500) {
	  fprintf(stderr, "Error: packet length longer than MTU(ether_hdr)");
	  return;
  }
  
  switch (ethertype(packet)) {
  
	/* -------------       Handling ARP     -------------------- */
	case ethertype_arp:
		sr_handlearp(sr, packet, len, interface);
		break;

	/* -------------       Handling IP      -------------------- */
	case ethertype_ip:
		sr_handleip(sr, packet, len, interface);
		break;

	default:
		fprintf(stderr, "Unknown ether_type: %d\n", ethertype(packet));
		break;

  }/* -- switch -- */
  

}/* end sr_ForwardPacket */
Beispiel #6
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("*** -> Received packet of length %d \n",len);

	if (ethertype(packet) == ethertype_arp) {			/* ARP packet */
		struct sr_arp_hdr *arpHeader = (struct sr_arp_hdr *) (packet + sizeof(struct sr_ethernet_hdr));
		if (is_broadcast_mac(packet) || we_are_dest(sr, arpHeader->ar_tip)) {
			/* Process only broadcasted packets or packets meant for me */
			processArp(sr, packet, len, interface);
		}

	} else if (ethertype(packet) == ethertype_ip) { 	/* IP packet */
		struct sr_ip_hdr *ipHeader = (struct sr_ip_hdr *) (packet + sizeof(struct sr_ethernet_hdr));
		
		/* Ignore invalid packets */
		if (!is_sane_ip_packet(packet, len)) {
			return;
		}

		/* If NAT is enabled, do an address translation */
		if (sr->natEnable) {
			int failed = sr_nat_translate_packet(sr, packet, len, interface);
			if (failed) {
				/* packet could not be translated. Drop it */
				return;
			}
		}

		if (we_are_dest(sr, ipHeader->ip_dst)) {
			/* We are destination */
			processIP(sr, packet, len, interface);
		} else {
			/* We are not destination. Forward it. */
			processForward(sr, packet, len, interface);
		}
	}
}
Beispiel #7
0
static void
dissect_vntag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint16     encap_proto;
	proto_tree *vntag_tree = NULL;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "VNTAG");
	col_clear(pinfo->cinfo, COL_INFO);

	if (tree) {
		proto_item *ti = proto_tree_add_item(tree, proto_vntag, tvb, 0, 4, ENC_NA);

		vntag_tree = proto_item_add_subtree(ti, ett_vntag);

		/* XXX, 4 bytes of data */

		/* from scapy (http://hg.secdev.org/scapy-com/rev/37acec891993) GPLv2:

		   BitField("dir",     0, 1),
		   BitField("ptr",     0, 1),
		   BitField("dst",     0, 14),
		   BitField("looped",  0, 1),
		   BitField("r",       0, 1),
		   BitField("version", 0, 2),
		   BitField("src",     0, 12) ]
		*/
		/* another: http://www.definethecloud.net/access-layer-network-virtualization-vn-tag-and-vepa */
	}

	encap_proto = tvb_get_ntohs(tvb, 4);

	/* copied from packet-vlan.c do we need it also for VNTAG? */
#if 0
	if (encap_proto <= IEEE_802_3_MAX_LEN) {
		gboolean is_802_2;

		/* Is there an 802.2 layer? I can tell by looking at the first 2
		   bytes after the VLAN header. If they are 0xffff, then what
		   follows the VLAN header is an IPX payload, meaning no 802.2.
		   (IPX/SPX is they only thing that can be contained inside a
		   straight 802.3 packet, so presumably the same applies for
		   Ethernet VLAN packets). A non-0xffff value means that there's an
		   802.2 layer inside the VLAN layer */
		is_802_2 = TRUE;

		/* Don't throw an exception for this check (even a BoundsError) */
		if (tvb_length_remaining(tvb, 4) >= 2) {
			if (tvb_get_ntohs(tvb, 4) == 0xffff)
				is_802_2 = FALSE;
		}

		dissect_802_3(encap_proto, is_802_2, tvb, 4, pinfo, tree, vntag_tree, hf_vntag_len, hf_vntag_trailer, 0);
	} else
#endif
		ethertype(encap_proto, tvb, 6, pinfo, tree, vntag_tree, hf_vntag_etype, hf_vntag_trailer, 0);
}
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("\n--ROUTER RECEIVED A NEW PACKET--\n");
 /* print_hdr_eth(packet);*/

  /* Sanity checks */

  if (len > 1514)
  {
    fprintf(stderr, "Error: EthHeader 1514 check not met");
    return;
  }  

  if (len < sizeof(sr_ethernet_hdr_t)) 
  {
    fprintf(stderr, "Error: Packet size < EthHeader size");
    return;
  } 

  /* IP/ICMP/ARP */
  uint16_t ether_type = ethertype(packet); 

  switch (ether_type)
  {
    /* IP */
    case 0x0800: 
        process_ether_type_ip(sr, packet, len, interface);
        break;

    /* ARP */
    case 0x0806:
        process_ether_type_arp(sr, packet, len, interface);
        break;

    /* Garbage ethernet type */
    default:
        fprintf(stderr, "Error: Garbage ether_type %d", ether_type);
        return;
  }
return;   
}
Beispiel #9
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
    /* REQUIRES */	/*struct sr_if *sr_iface = sr_get_router_if(sr, arp_hdr->ar_tip);*/
    assert(sr);
    assert(packet);
    assert(interface);


    /* copy into a new packet for better handling :) */
    uint8_t *packet1 = packet;

    printf("*** -> Received packet of length %d \n",len);

    /* sanity-check the packet (meets min length) */
    if (!check_min_length(len, ETHER_PACKET_LEN)) {
        fprintf(stderr, "packet length is smaller the ethernet size. Drop it!\n");
        return;
    }

    uint16_t eth_type = ethertype(packet1);

    /* ARP REQUEST & REPLY */
    if (eth_type == ethertype_arp) {
        sr_handle_arppacket(sr, packet1, len, interface);
        return;
    }
    /* IP REQUEST & REPLY */
    else if (eth_type == ethertype_ip) {
        sr_handle_ippacket(sr, packet1, len, interface);
        return;
    }
    /* OTHERWISE, DROP!!! */
    else {
        fprintf(stderr, "Invalid ethernet type, drop the packet!\n");
        return;
    }

    return;

}/* end sr_ForwardPacket */
Beispiel #10
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  printf("Router Accessed\n");
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);
  struct sr_if * iface = sr_get_interface(sr, interface);
  printf("*** -> Received packet of length %d \n",len);
  
  /* Ethernet Protocol */
  if(len>=34){
    uint8_t* ether_packet = malloc(len+28);
    memcpy(ether_packet,packet,len);
    print_hdrs(packet,len);

    uint16_t package_type = ethertype(ether_packet);
    enum sr_ethertype arp = ethertype_arp;
    enum sr_ethertype ip = ethertype_ip;

    if (strcmp(iface->name,interface) == 0){ 
      printf("Right interface\n"); 
      if(package_type==arp){
        /* ARP protocol */
        sr_handleARPpacket(sr, ether_packet, len, iface);
      }else if(package_type==ip){
        /* IP protocol */
        if (sr->mode == 1){
          sr_natHandleIP(sr,ether_packet,len,iface);
        } else{
          sr_handleIPpacket(sr, ether_packet,len, iface);
        }
      }else{
        /* drop package */
        printf("bad protocol! BOO! \n");
      }
    }
    free(ether_packet);
  }
}/* end sr_ForwardPacket */
Beispiel #11
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("*** -> Received packet of length %d \n",len);

  /* Check packet type */
  uint16_t ethtype = ethertype(packet);
  unsigned int minlen = sizeof(sr_ethernet_hdr_t);

  if (len < minlen) {
	  fprintf(stderr, "Invalid Ethernet frame size");
	  return;
  }

  switch(ethtype) {
  	  case ethertype_arp:
  		 Debug("Receive an ARP packet sent to interface %s\n", interface);
  		 sr_handle_arp(sr, packet , len, interface);
  		 break;

  	  case ethertype_ip:
  		  Debug("Get an IP header sent to interface: %s\n", interface);
  		  sr_handle_ip(sr, packet, len, interface);
  		  break;

  	  default:
  		  fprintf(stderr, "Unrecognized Ethernet Type: %d\n", ethtype);
  		  break;
  }


}/* end sr_ForwardPacket */
Beispiel #12
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("*** -> Received packet of length %d \n",len);

  /*print_hdrs(packet, len);*/

  struct sr_if* iface = sr_get_interface(sr, interface);
  assert(iface);

  if (len < sizeof(sr_ethernet_hdr_t)) {
    fprintf(stderr, "ERROR: Packet too small.\n");
    return;
  }

  uint16_t ethtype = ethertype(packet);
  switch (ethtype) {

  case ethertype_arp:
    sr_handlearp(sr, packet, len, iface);
    break;

  case ethertype_ip:
    sr_handleip(sr, packet, len, iface);
    break;

  default:
    fprintf(stderr, "ERROR: Unrecognized Ethernet Type: %d\n", ethtype);
  }

}
Beispiel #13
0
void sr_handlepacket(struct sr_instance *sr,
        uint8_t *packet/* lent */,
        unsigned int len,
        char *interface/* lent */)
{
    /* REQUIRES */
    assert(sr);
    assert(packet);
    assert(interface);

    printf("** -> Received packet of length %d \n",len);
   
    /* Ensure the packet is long enough */
    if (len < sizeof(struct sr_ethernet_hdr)){
      return;
    }

    if (ethertype(packet) == ethertype_arp){
      arp_handlepacket(sr, packet, len, interface);
    } else {
      ip_handlepacket(sr, packet, len, interface);
    }

}/* end sr_ForwardPacket */
Beispiel #14
0
static void
dissect_fw1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  /* Set up structures needed to add the protocol subtree and manage it */
  proto_item    *ti;
  proto_tree    *volatile fh_tree = NULL;
  char          direction;
  char  chain;
  char          *interface_name;
  guint32       iface_len = 10;
  guint16       etype;
  wmem_strbuf_t *header;
  int           i;
  gboolean      found;
  static const char     fw1_header[] = "FW1 Monitor";

  header = wmem_strbuf_new_label(wmem_epan_scope());
  wmem_strbuf_append(header, fw1_header);

  /* Make entries in Protocol column and Info column on summary display */
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "FW1");
  col_clear(pinfo->cinfo, COL_INFO);


  /* g_snprintf(header, sizeof(header), fw1_header); */

  /* fetch info to local variable */
  direction = tvb_get_guint8(tvb, 0);

  if (!fw1_iflist_with_chain)
    chain = ' ';
  else
    chain = tvb_get_guint8(tvb, 1);

  if (fw1_with_uuid)
    iface_len = 6;

  interface_name=(char *)wmem_alloc(wmem_packet_scope(), iface_len+1);
  tvb_get_nstringz0(tvb, 2, iface_len+1, interface_name);

  /* Known interface name - if not, remember it */
  found=FALSE;
  for (i=0; i<interface_anzahl; i++) {
    if ( strcmp(p_interfaces[i], interface_name) == 0 ) {
      found=TRUE;
      break;
    }
  }
  if (!found && interface_anzahl < MAX_INTERFACES) {
    p_interfaces[interface_anzahl] = wmem_strdup(wmem_file_scope(), interface_name);
    interface_anzahl++;
  }

  /* display all interfaces always in the same order */
  for (i=0; i<interface_anzahl; i++) {
    if ( strcmp(p_interfaces[i], interface_name) == 0 ) {
      wmem_strbuf_append_printf(header, "  %c%c %s %c%c",
                                direction == 'i' ? 'i' : (direction == 'O' ? 'O' : ' '),
                                (direction == 'i' || direction == 'O') ? chain : ' ',
                                p_interfaces[i],
                                direction == 'I' ? 'I' : (direction == 'o' ? 'o' : ' '),
                                (direction == 'I' || direction == 'o') ? chain : ' '
        );
    } else {
      wmem_strbuf_append_printf(header, "    %s  ", p_interfaces[i]);
    }
  }

  col_add_str(pinfo->cinfo, COL_IF_DIR, wmem_strbuf_get_str(header) + sizeof(fw1_header) + 1);

  if (tree) {
    if (!fw1_summary_in_tree)
      /* Do not show the summary in Protocol Tree */
      ti = proto_tree_add_protocol_format(tree, proto_fw1, tvb, 0, ETH_HEADER_SIZE, "%s", fw1_header);
    else
      ti = proto_tree_add_protocol_format(tree, proto_fw1, tvb, 0, ETH_HEADER_SIZE, "%s", wmem_strbuf_get_str(header));

    /* create display subtree for the protocol */
    fh_tree = proto_item_add_subtree(ti, ett_fw1);

    proto_tree_add_item(fh_tree, hf_fw1_direction, tvb, 0, 1, ENC_ASCII|ENC_NA);

    if (fw1_iflist_with_chain)
      proto_tree_add_item(fh_tree, hf_fw1_chain, tvb, 1, 1, ENC_ASCII|ENC_NA);

    proto_tree_add_item(fh_tree, hf_fw1_interface, tvb, 2, iface_len, ENC_ASCII|ENC_NA);

    if (fw1_with_uuid)
      proto_tree_add_item(fh_tree, hf_fw1_uuid, tvb, 8, 4, ENC_BIG_ENDIAN);
  }

  etype = tvb_get_ntohs(tvb, 12);
  ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree, hf_fw1_type, hf_fw1_trailer, 0);
}
Beispiel #15
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("Received packet of length %d \n",len);

  /* fill in code here */
 
  /*initializing key variables*/
  uint8_t* packet_buffer; /*packet buffer*/
  /*struct sr_if* iface;*/ /*interface struct*/
  uint16_t checksum,ether_type; /*checksum bit*/
  unsigned int packet_len,minlength; /*packet length*/
  int ipLen,etherLen,arpLen;
 
  packet_buffer = packet;
  packet_len = len;
  minlength = sizeof(sr_ethernet_hdr_t);
  etherLen = sizeof(sr_ethernet_hdr_t); /*ethernet header size*/
  ipLen = sizeof(sr_ip_hdr_t); /*ip header length*/
  arpLen  = sizeof(sr_arp_hdr_t); /*arp header length*/

  if (len > IP_MAXPACKET)
  {
    	perror("Error: invalid packet size");
	exit(1);
  }
  if (len < minlength)
  {
        perror("Error: packet size too small");
	exit(1);
  }
  /*obtain interface information*/
  /*iface = sr_get_interface(sr,interface);*/

  
  /*examining each layer of header*/  
  
  /*examine ethernet header*/
  sr_ethernet_hdr_t* ether_header = (sr_ethernet_hdr_t*) packet_buffer;  
  ether_type = ethertype(packet_buffer); 
 
  if (ether_type == ethertype_ip) /*IP*/
  {
	if (process_ip_packet(sr, packet, len, interface)  < 0) {
      fprintf(stderr, "Error processing IP datagram\n");
    }
  }

  else if (ether_type == ethertype_arp) /*ARP*/
  {
	if (process_arp_packet(sr, packet, len, interface)  <0) {
      fprintf(stderr, "Error processing ARP packet\n");
    }
  }
  else {
    fprintf(stderr, "Error: Unrecognized Ethernet Type: %d\n", ether_type);
  }
  
}/* end sr_ForwardPacket */
static void
dissect_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint16 encap_proto;

    proto_tree *cmd_tree = NULL;
    gint offset = 0;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "CMD");
    col_clear(pinfo->cinfo, COL_INFO);

    if (tree) {
        proto_item *ti = proto_tree_add_item(tree, proto_cmd, tvb, 0, 6, ENC_NA);

        cmd_tree = proto_item_add_subtree(ti, ett_cmd);
        proto_tree_add_item(cmd_tree, hf_cmd_version, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
        proto_tree_add_item(cmd_tree, hf_cmd_length, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
        proto_tree_add_item(cmd_tree, hf_cmd_options, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
        proto_tree_add_item(cmd_tree, hf_cmd_sgt, tvb, offset, 2, ENC_BIG_ENDIAN);
        /*offset += 2;*/
    }

    encap_proto = tvb_get_ntohs(tvb, 6);

/* This Logic to identify and decode IEEE 802.3 frames is not working correctly. Carry over code from packet-vlan.c
 * Commenting it out for now will display as Unknown for L2 control frames instead of showing a wrong decode.
 */
#if 0
    if (encap_proto <= IEEE_802_3_MAX_LEN) {
        gboolean is_802_2 = TRUE;

        /* Don't throw an exception for this check (even a BoundsError) */
        if (tvb_length_remaining(tvb, 4) >= 2) {
            if (tvb_get_ntohs(tvb, 4) == 0xffff)
                is_802_2 = FALSE;
        }

        dissect_802_3(encap_proto, is_802_2, tvb, 4, pinfo, tree, cmd_tree, hf_eth_type, hf_cmd_trailer, 0);
    } else {
#endif

    ethertype(encap_proto, tvb, 8, pinfo, tree, cmd_tree,
          hf_eth_type, hf_cmd_trailer, 0);
}

void
proto_register_cmd(void)
{
    static hf_register_info hf[] = {
        { &hf_cmd_version,
            { "Version", "cmd.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
        },
        { &hf_cmd_length,
            { "Length", "cmd.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
        },
        { &hf_cmd_options,
            { "Options", "cmd.options", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
        },
        { &hf_cmd_sgt,
            { "SGT", "cmd.sgt", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
        },
        { &hf_eth_type,
            { "Type", "cmd.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0, NULL, HFILL }
        },
        { &hf_cmd_trailer,
            { "Trailer", "cmd.trailer", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
        },
    };

    static gint *ett[] = {
        &ett_cmd
    };

    proto_cmd = proto_register_protocol("Cisco MetaData", "Cisco MetaData", "cmd");
    proto_register_field_array(proto_cmd, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));
}

void
proto_reg_handoff_cmd(void)
{
    dissector_handle_t cmd_handle;

    cmd_handle = create_dissector_handle(dissect_cmd, proto_cmd);
    dissector_add_uint("ethertype", ETHERTYPE_CMD, cmd_handle);
}
Beispiel #17
0
    BOOST_AUTO_TEST_CASE(multicast_test)
    {
        auto const sut = actions::pop_mpls::multicast();

        BOOST_TEST(sut.ethertype() == 0x8848);
    }

    BOOST_DATA_TEST_CASE(
            create_test
            , bdata::make(std::vector<std::uint16_t>{0x0800, 0x8847, 0x8848})
            , ethertype)
    {
        auto const sut = actions::pop_mpls::create(ethertype);

        BOOST_TEST(sut.ethertype() == ethertype);
    }

    BOOST_AUTO_TEST_SUITE(equality)
      BOOST_AUTO_TEST_CASE(true_if_same_object)
      {
        auto const sut = actions::pop_mpls{0x0800};

        BOOST_TEST((sut == sut));
      }
      BOOST_AUTO_TEST_CASE(true_if_ethertype_and_pad_are_equal)
      {
        auto const sut1 = actions::pop_mpls{0x8847};
        auto const sut2 = actions::pop_mpls{0x8847};

        BOOST_TEST((sut1 == sut2));
Beispiel #18
0
static void
dissect_eth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
    int fcs_len)
{
  proto_item        *ti = NULL;
  eth_hdr           *ehdr;
  gboolean          is_802_2;
  proto_tree        *fh_tree = NULL;
  const guint8      *src_addr, *dst_addr;
  static eth_hdr    ehdrs[4];
  static int        ehdr_num=0;
  proto_tree        *tree;
  proto_item        *addr_item;
  proto_tree        *addr_tree=NULL;

  ehdr_num++;
  if(ehdr_num>=4){
     ehdr_num=0;
  }
  ehdr=&ehdrs[ehdr_num];

  tree=parent_tree;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Ethernet");

  src_addr=tvb_get_ptr(tvb, 6, 6);
  SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src_addr);
  SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src_addr);
  SET_ADDRESS(&ehdr->src, AT_ETHER, 6, src_addr);
  dst_addr=tvb_get_ptr(tvb, 0, 6);
  SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst_addr);
  SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst_addr);
  SET_ADDRESS(&ehdr->dst, AT_ETHER, 6, dst_addr);

  ehdr->type = tvb_get_ntohs(tvb, 12);

  tap_queue_packet(eth_tap, pinfo, ehdr);

  /*
   * In case the packet is a non-Ethernet packet inside
   * Ethernet framing, allow heuristic dissectors to take
   * a first look before we assume that it's actually an
   * Ethernet packet.
   */
  if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, parent_tree, NULL))
    return;

  if (ehdr->type <= IEEE_802_3_MAX_LEN) {
    /* Oh, yuck.  Cisco ISL frames require special interpretation of the
       destination address field; fortunately, they can be recognized by
       checking the first 5 octets of the destination address, which are
       01-00-0C-00-00 for ISL frames. */
    if ((tvb_get_guint8(tvb, 0) == 0x01 ||
      tvb_get_guint8(tvb, 0) == 0x0C) &&
      tvb_get_guint8(tvb, 1) == 0x00 &&
      tvb_get_guint8(tvb, 2) == 0x0C &&
      tvb_get_guint8(tvb, 3) == 0x00 &&
      tvb_get_guint8(tvb, 4) == 0x00) {
      dissect_isl(tvb, pinfo, parent_tree, fcs_len);
      return;
    }
  }

  /*
   * If the type/length field is <= the maximum 802.3 length,
   * and is not zero, this is an 802.3 frame, and it's a length
   * field; it might be an Novell "raw 802.3" frame, with no
   * 802.2 LLC header, or it might be a frame with an 802.2 LLC
   * header.
   *
   * If the type/length field is >= the minimum Ethernet II length,
   * this is an Ethernet II frame, and it's a type field.
   *
   * If the type/length field is > maximum 802.3 length and < minimum
   * Ethernet II length, then this is an invalid packet.
   *
   * If the type/length field is zero (ETHERTYPE_UNK), this is
   * a frame used internally by the Cisco MDS switch to contain
   * Fibre Channel ("Vegas").  We treat that as an Ethernet II
   * frame; the dissector for those frames registers itself with
   * an ethernet type of ETHERTYPE_UNK.
   */
  if (ehdr->type > IEEE_802_3_MAX_LEN && ehdr->type < ETHERNET_II_MIN_LEN) {
    tvbuff_t *next_tvb;

    col_add_fstr(pinfo->cinfo, COL_INFO,
        "Ethernet Unknown: Invalid length/type: 0x%04x (%d)",
        ehdr->type, ehdr->type);
    ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
        "Ethernet Unknown, Src: %s (%s), Dst: %s (%s)",
        get_ether_name(src_addr), ether_to_str(src_addr),
        get_ether_name(dst_addr), ether_to_str(dst_addr));
    fh_tree = proto_item_add_subtree(ti, ett_ether);
    addr_item = proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst_addr);
    if (addr_item)
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 0, 6, dst_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 0, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 0, 3, ENC_BIG_ENDIAN);

    addr_item = proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src_addr);
    if (addr_item)
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 6, 6, src_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 6, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 6, 3, ENC_BIG_ENDIAN);

    ti = proto_tree_add_item(fh_tree, hf_eth_invalid_lentype, tvb, 12, 2, ENC_BIG_ENDIAN);
    expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
        "Invalid length/type: 0x%04x (%d)", ehdr->type, ehdr->type);
    next_tvb = tvb_new_subset_remaining(tvb, 14);
    call_dissector(data_handle, next_tvb, pinfo, parent_tree);
    return;
  }

  if (ehdr->type <= IEEE_802_3_MAX_LEN && ehdr->type != ETHERTYPE_UNK) {

    is_802_2 = check_is_802_2(tvb, fcs_len);

     col_add_fstr(pinfo->cinfo, COL_INFO, "IEEE 802.3 Ethernet %s",
        (is_802_2 ? "" : "Raw "));
    if (tree) {
      ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
        "IEEE 802.3 Ethernet %s", (is_802_2 ? "" : "Raw "));

      fh_tree = proto_item_add_subtree(ti, ett_ieee8023);
    }

    /* if IP is not referenced from any filters we dont need to worry about
       generating any tree items.  We must do this after we created the actual
       protocol above so that proto hier stat still works though.
    */
    if(!proto_field_is_referenced(parent_tree, proto_eth)){
      tree=NULL;
      fh_tree=NULL;
    }

    addr_item=proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst_addr);
    if(addr_item){
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    }
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 0, 6, dst_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 0, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 0, 3, ENC_BIG_ENDIAN);

    addr_item=proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src_addr);
    if(addr_item){
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    }
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 6, 6, src_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 6, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 6, 3, ENC_BIG_ENDIAN);

    dissect_802_3(ehdr->type, is_802_2, tvb, ETH_HEADER_SIZE, pinfo,
        parent_tree, fh_tree, hf_eth_len, hf_eth_trailer, fcs_len);
  } else {
    if (eth_interpret_as_fw1_monitor) {
        if ((dst_addr[0] == 'i') || (dst_addr[0] == 'I') ||
            (dst_addr[0] == 'o') || (dst_addr[0] == 'O')) {
            call_dissector(fw1_handle, tvb, pinfo, parent_tree);
            return;
        }
    }

    col_set_str(pinfo->cinfo, COL_INFO, "Ethernet II");
    if (parent_tree) {
        if (PTREE_DATA(parent_tree)->visible) {
            ti = proto_tree_add_protocol_format(parent_tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
                "Ethernet II, Src: %s (%s), Dst: %s (%s)",
                get_ether_name(src_addr), ether_to_str(src_addr),
                get_ether_name(dst_addr), ether_to_str(dst_addr));
      }
      else {
            ti = proto_tree_add_item(parent_tree, proto_eth, tvb, 0, ETH_HEADER_SIZE, ENC_NA);
      }
      fh_tree = proto_item_add_subtree(ti, ett_ether2);
    }

    addr_item=proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst_addr);
    if(addr_item){
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    }
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 0, 6, dst_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 0, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 0, 3, ENC_BIG_ENDIAN);

    addr_item=proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src_addr);
    if(addr_item){
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
        if (tvb_get_guint8(tvb, 6) & 0x01) {
            expert_add_info_format(pinfo, addr_item, PI_PROTOCOL, PI_WARN,
                "Source MAC must not be a group address: IEEE 802.3-2002, Section 3.2.3(b)");
        }
    }
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 6, 6, src_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 6, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 6, 3, ENC_BIG_ENDIAN);

    ethertype(ehdr->type, tvb, ETH_HEADER_SIZE, pinfo, parent_tree, fh_tree, hf_eth_type,
          hf_eth_trailer, fcs_len);
  }
}
Beispiel #19
0
void display_packet(GtkWidget *widget) {
  GtkTreeSelection *selection;		/* tree selection */
  GtkTreeModel     *model;		/* tree model */
  GtkTreeIter       iter;		/* tree iterator */
  pcap_t *handler;			/* pcap file handler */
  char errbuf[PCAP_ERRBUF_SIZE];	/* pcap error buffer */
  struct pcap_pkthdr *header;		/* the header from libpcap */
  const u_char *packet;			/* current packet pointer */
  unsigned int packetnumber;		/* currently secected packet number */
  struct ether_header *eth = NULL;
  struct sll_header *sll = NULL;	/* sll header (linux cooked) */
  struct arphdr *arp = NULL;
  struct iphdr *ipv4 = NULL;		/* ipv4_header pointer */
  struct ip6_hdr *ipv6 = NULL;
  struct icmphdr *icmp = NULL;
  struct icmp6_hdr *icmpv6 = NULL;
  struct tcphdr *tcp = NULL;
  struct udphdr *udp = NULL;
  unsigned int i = 1;			/* loop counter to track packet */
  unsigned short nextproto = 0;
  char *nextptr = NULL;
  int pos;

  if (filename == NULL) return;

  /* open pcap to find packet */
  handler = pcap_open_offline(filename, errbuf);
  if (handler == NULL) return;

  /* get currently selected packet */
  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
  if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
    gtk_tree_model_get(model, &iter, 0, &packetnumber, -1);
  }

  /* iterate through packets until selected packet is found
     this might also be done by preloading of this technique is too slow */
  while (i++ <= packetnumber) pcap_next_ex(handler, &header, &packet);

  /* remember tab position and hide all tabs */
  pos = gtk_notebook_get_current_page(protocolheadernotebook);

  /* clear grids */
  while (gtk_notebook_get_n_pages(protocolheadernotebook) > 0) {
    gtk_notebook_remove_page(protocolheadernotebook, 0);
  }

  switch (pcap_datalink(handler)) {

    case DLT_EN10MB:
      /* set pointer to ethernet header */
      eth = (struct ether_header*)(packet);

      /* display ethernet tab */
      gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(ethernet_grid(eth)), gtk_label_new(hardwaretype(pcap_datalink(handler))));

      nextproto = htons(eth->ether_type);
      nextptr = (void*)(packet + sizeof(struct ether_header));

      break;
    case LINKTYPE_LINUX_SLL:
      /* LINUX COOKED */
      sll = (struct sll_header*)(packet);

      /* display sll tab */
      gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(sll_grid(sll)), gtk_label_new(hardwaretype(pcap_datalink(handler))));

      nextproto = htons(sll->sll_protocol);
      nextptr = (void*)(packet + sizeof(struct sll_header));

      break;
    default:
      /* display not supported tab */
      gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(not_supported_grid(hardwaretype(pcap_datalink(handler)))), gtk_label_new(hardwaretype(pcap_datalink(handler))));

      return;
  }

  switch (nextproto) {
    case ETHERTYPE_ARP:
      /* ARP */
      arp = (struct arphdr*)nextptr;
      nextptr += sizeof(struct arphdr);

      /* display arp tab */
      gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(arp_grid(arp, ((u_char*)nextptr))), gtk_label_new(ethertype(nextproto)));
      nextproto = 0xffff;

      break;
    case ETHERTYPE_IP:
      /* IPV4 */
      ipv4 = (struct iphdr*)nextptr;
      nextptr += sizeof(struct iphdr);

      /* display ipv4 tab */
      gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(ipv4_grid(ipv4, ((u_char*)nextptr))), gtk_label_new(ethertype(nextproto)));

      nextproto = ipv4->protocol;

      break;
    case ETHERTYPE_IPV6:
      /* IPV6 */
      ipv6 = (struct ip6_hdr*)nextptr;
      nextptr += sizeof(struct ip6_hdr);

      /* display ipv4 tab */
      gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(ipv6_grid(ipv6, ((u_char*)nextptr))), gtk_label_new(ethertype(nextproto)));

      nextproto = ipv6->ip6_ctlun.ip6_un1.ip6_un1_nxt;

      while (nextproto == IPPROTO_HOPOPTS) {
        /* next header */
        nextproto = ((u_char*)nextptr)[0];

        nextptr += (((u_char*)nextptr)[1]+1) * 8;
      }

      break;
    default:
      /* display not supported tab */
      gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(not_supported_grid(ethertype(nextproto))), gtk_label_new(ethertype(nextproto)));

      nextproto = 0xffff;

      break;
  }

  if (nextproto != 0xffff) {
    switch (nextproto) {
      case IPPROTO_ICMP:
        icmp = (struct icmphdr*)nextptr;
        nextptr += sizeof(struct icmphdr);

        gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(icmp_grid(icmp, ((u_char*)nextptr), htons(ipv4->tot_len)-(ipv4->ihl*4))), gtk_label_new(ipprotocol(nextproto)));

        break;
      case IPPROTO_ICMPV6:
        icmpv6 = (struct icmp6_hdr*)nextptr;

        /* skip 4 bytes of unused / reserved fields of header struct and pass to next protocol pointer */
        nextptr += sizeof(struct icmp6_hdr)-4;

        gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(icmpv6_grid(icmpv6, ((u_char*)nextptr), htons(ipv6->ip6_ctlun.ip6_un1.ip6_un1_plen))), gtk_label_new(ipprotocol(nextproto)));

        break;
      case IPPROTO_TCP:
        tcp = (struct tcphdr*)nextptr;
        nextptr += sizeof(struct tcphdr);

        gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(tcp_grid(tcp, ((u_char*)nextptr))), gtk_label_new(ipprotocol(nextproto)));

        break;
      case IPPROTO_UDP:
        udp = (struct udphdr*)nextptr;

        gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(udp_grid(udp)), gtk_label_new(ipprotocol(nextproto)));

        break;
      default:

        /* display not supported tab */
        gtk_notebook_append_page(protocolheadernotebook, GTK_WIDGET(not_supported_grid(ipprotocol(nextproto))), gtk_label_new(ipprotocol(nextproto)));

        nextproto = 0xffff;

        break;
    }
  }

  /* switch to tab that was former selected */
  if ((pos >= 0) && (pos < gtk_notebook_get_n_pages(protocolheadernotebook))) {
    gtk_notebook_set_current_page(protocolheadernotebook, pos);
  }

  /* close pcap handler */
  pcap_close(handler);
}
Beispiel #20
0
void getinfo(pcap_t *handler, const u_char *packet, char **protocol, char **flags, char **source, char **sport, char **destination, char **dport) {
  struct ether_header *eth;
  struct iphdr *ipv4;                   /* ipv4_header pointer */
  struct tcphdr *tcp;
  struct udphdr *udp;
  struct ip6_hdr *ipv6;
  struct sll_header *sll;               /* sll header (linux cooked) */
  unsigned short nextproto;
  char *nextptr = NULL;

  *protocol = malloc(100);
  *source = malloc(100);
  *sport = malloc(100);
  *destination = malloc(100);
  *dport = malloc(100);
  *flags = malloc(100);
  memset(*protocol, 0, 100);
  memset(*source, 0, 100);
  memset(*sport, 0, 100);
  memset(*destination, 0, 100);
  memset(*dport, 0, 100);
  memset(*flags, 0, 100);

  sprintf(*protocol, "%s", hardwaretype(pcap_datalink(handler)));

  switch (pcap_datalink(handler)) {

    case DLT_EN10MB:
      /* set pointer to ethernet header */
      eth = (struct ether_header*)(packet);

      sprintf(*source, "%02x:%02x:%02x:%02x:%02x:%02x", eth->ether_shost[0], eth->ether_shost[1], eth->ether_shost[2], eth->ether_shost[3], eth->ether_shost[4], eth->ether_shost[5]);
      sprintf(*destination, "%02x:%02x:%02x:%02x:%02x:%02x", eth->ether_dhost[0], eth->ether_dhost[1], eth->ether_dhost[2], eth->ether_dhost[3], eth->ether_dhost[4], eth->ether_dhost[5]);

      nextproto = htons(eth->ether_type);
      nextptr = (void*)(packet + sizeof(struct ether_header));

      break;
    case LINKTYPE_LINUX_SLL:
      /* LINUX COOKED */
      sll = (struct sll_header*)(packet);

      /* TODO: need to check sll->halen to get REAL size (6 chosen here) */
      sprintf(*source, "%02x:%02x:%02x:%02x:%02x:%02x", sll->sll_addr[0], sll->sll_addr[1], sll->sll_addr[2], sll->sll_addr[3], sll->sll_addr[4], sll->sll_addr[5]);
      /* destination is unknown in SLL */

      nextproto = htons(sll->sll_protocol);
      nextptr = (void*)(packet + sizeof(struct sll_header));

      break;
    default:
      nextproto = 0xffff;
      break;
  }

  if (nextproto != 0xffff) {

    sprintf(*protocol, "%s", ethertype(nextproto));

    switch (nextproto) {

      case ETHERTYPE_ARP:
        /* ARP */
  /*      arp = (struct arphdr*)nextptr;*/
        nextproto = 0xffff;

        break;

      case ETHERTYPE_IP:
        /* IPV4 */
        ipv4 = (struct iphdr*)nextptr;
        nextptr += sizeof(struct iphdr);
        nextproto = ipv4->protocol;

        sprintf(*source, "%u.%u.%u.%u", ipv4->saddr & 0xff, (ipv4->saddr >> 8) & 0xff, (ipv4->saddr >> 16) & 0xff, (ipv4->saddr >> 24) & 0xff);
        sprintf(*destination, "%u.%u.%u.%u", ipv4->daddr & 0xff, (ipv4->daddr >> 8) & 0xff, (ipv4->daddr >> 16) & 0xff, (ipv4->daddr >> 24) & 0xff);

        /* reserved flag */
        if (ipv4->frag_off & htons(IP_RF)) strcat(*flags, "RF ");

        /* dont fragment flag */
        if (ipv4->frag_off & htons(IP_DF)) strcat(*flags, "DF ");

        /* more fragments flag */
        if (ipv4->frag_off & htons(IP_MF)) strcat(*flags, "MF ");

        break;
      case ETHERTYPE_IPV6:
        ipv6 = (struct ip6_hdr*)nextptr;
        nextptr += sizeof(struct ip6_hdr);

        sprintf(*source, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", htons(ipv6->ip6_src.__in6_u.__u6_addr16[0]), htons(ipv6->ip6_src.__in6_u.__u6_addr16[1]), htons(ipv6->ip6_src.__in6_u.__u6_addr16[2]), htons(ipv6->ip6_src.__in6_u.__u6_addr16[3]), htons(ipv6->ip6_src.__in6_u.__u6_addr16[4]), htons(ipv6->ip6_src.__in6_u.__u6_addr16[5]), htons(ipv6->ip6_src.__in6_u.__u6_addr16[6]), htons(ipv6->ip6_src.__in6_u.__u6_addr16[7]));
        sprintf(*destination, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", htons(ipv6->ip6_dst.__in6_u.__u6_addr16[0]), htons(ipv6->ip6_dst.__in6_u.__u6_addr16[1]), htons(ipv6->ip6_dst.__in6_u.__u6_addr16[2]), htons(ipv6->ip6_dst.__in6_u.__u6_addr16[3]), htons(ipv6->ip6_dst.__in6_u.__u6_addr16[4]), htons(ipv6->ip6_dst.__in6_u.__u6_addr16[5]), htons(ipv6->ip6_dst.__in6_u.__u6_addr16[6]), htons(ipv6->ip6_dst.__in6_u.__u6_addr16[7]));

        nextproto = ipv6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
        while (nextproto == IPPROTO_HOPOPTS) {
          /* next header */
          nextproto = ((u_char*)nextptr)[0];

          nextptr += (((u_char*)nextptr)[1]+1) * 8;
        }
        break;
      default:
        nextproto = 0xffff;
        break;
    }
  }
Beispiel #21
0
static void
dissect_btbnep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item   *pi;
    proto_tree   *btbnep_tree;
    gint          offset = 0;
    guint         bnep_type;
    guint         extension_flag;
    guint         type = 0;
    proto_item   *addr_item;
    proto_tree   *addr_tree = NULL;
    const guint8 *src_addr;
    const guint8 *dst_addr;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "BNEP");
    col_clear(pinfo->cinfo, COL_INFO);

    switch (pinfo->p2p_dir) {
        case P2P_DIR_SENT:
            col_add_str(pinfo->cinfo, COL_INFO, "Sent ");
            break;
        case P2P_DIR_RECV:
            col_add_str(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;
        default:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
                pinfo->p2p_dir);
            break;
    }

    pi = proto_tree_add_item(tree, proto_btbnep, tvb, offset, -1, ENC_NA);
    btbnep_tree = proto_item_add_subtree(pi, ett_btbnep);

    proto_tree_add_item(btbnep_tree, hf_btbnep_extension_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(btbnep_tree, hf_btbnep_bnep_type, tvb, offset, 1, ENC_BIG_ENDIAN);
    bnep_type = tvb_get_guint8(tvb, offset);
    extension_flag = bnep_type & 0x80;
    bnep_type = bnep_type & 0x7F;
    offset += 1;

    col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_const(bnep_type, bnep_type_vals,  "Unknown type"));
    if (extension_flag) col_append_fstr(pinfo->cinfo, COL_INFO, "+E");

    if (bnep_type == BNEP_TYPE_GENERAL_ETHERNET || bnep_type == BNEP_TYPE_COMPRESSED_ETHERNET_DESTINATION_ONLY) {
        dst_addr = tvb_get_ptr(tvb, offset, 6);
        SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst_addr);
        SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst_addr);

        addr_item = proto_tree_add_ether(btbnep_tree, hf_btbnep_dst, tvb, offset, 6, dst_addr);
        if (addr_item) addr_tree = proto_item_add_subtree(addr_item, ett_addr);
        proto_tree_add_ether(addr_tree, hf_btbnep_addr, tvb, offset, 6, dst_addr);
        proto_tree_add_item(addr_tree, hf_btbnep_lg, tvb, offset, 3, ENC_BIG_ENDIAN);
        proto_tree_add_item(addr_tree, hf_btbnep_ig, tvb, offset, 3, ENC_BIG_ENDIAN);
        offset += 6;
    }

    if (bnep_type == BNEP_TYPE_GENERAL_ETHERNET || bnep_type == BNEP_TYPE_COMPRESSED_ETHERNET_SOURCE_ONLY) {
        src_addr = tvb_get_ptr(tvb, offset, 6);
        SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src_addr);
        SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src_addr);


        addr_item = proto_tree_add_ether(btbnep_tree, hf_btbnep_src, tvb, offset, 6, src_addr);
        if (addr_item) {
            addr_tree = proto_item_add_subtree(addr_item, ett_addr);
            if (tvb_get_guint8(tvb, offset) & 0x01) {
                expert_add_info_format(pinfo, addr_item, PI_PROTOCOL, PI_WARN,
                        "Source MAC must not be a group address: IEEE 802.3-2002, Section 3.2.3(b)");
            }
        }
        proto_tree_add_ether(addr_tree, hf_btbnep_addr, tvb, offset, 6, src_addr);
        proto_tree_add_item(addr_tree, hf_btbnep_lg, tvb, offset, 3, ENC_BIG_ENDIAN);
        proto_tree_add_item(addr_tree, hf_btbnep_ig, tvb, offset, 3, ENC_BIG_ENDIAN);
        offset += 6;
    }

    if (bnep_type != BNEP_TYPE_CONTROL) {
        type = tvb_get_ntohs(tvb, offset);
        if (!top_dissect) {
            proto_tree_add_item(btbnep_tree, hf_btbnep_type, tvb, offset, 2, ENC_BIG_ENDIAN);
            col_append_fstr(pinfo->cinfo, COL_INFO, " - Type: %s", val_to_str_const(type, etype_vals, "unknown"));
        }
        offset += 2;
    } else {
        offset = dissect_control(tvb, pinfo, btbnep_tree, offset);
    }

    if (extension_flag) {
        offset = dissect_extension(tvb, pinfo, btbnep_tree, offset);
    }

    if (bnep_type != BNEP_TYPE_CONTROL) {
        /* dissect normal network */
       if (top_dissect) {
            ethertype(type, tvb, offset, pinfo, tree, btbnep_tree,
                    hf_btbnep_type, 0, 0);
       } else {
            tvbuff_t  *next_tvb;

            next_tvb = tvb_new_subset_remaining(tvb, offset);
            call_dissector(data_handle, next_tvb, pinfo, tree);
       }
    }
}
static void
dissect_vmlab(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

    proto_tree*     volatile vmlab_tree;
    proto_item*     ti;
    
    guint32         offset=0;

    const guint8*   src_addr;
    const guint8*   dst_addr;
    const guint8*   eth_addr;
    guint8          attributes;
    guint8          portgroup;

    volatile guint16 encap_proto;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "VMLAB");
    col_clear(pinfo->cinfo, COL_INFO);

    ti = proto_tree_add_item(tree, proto_vmlab, tvb, 0, 24, FALSE);
    vmlab_tree = proto_item_add_subtree(ti, ett_vmlab);
   
    /* Flags*/
    attributes = tvb_get_guint8(tvb, offset);
    proto_tree_add_item(vmlab_tree, hf_vmlab_flags_part1,    tvb, offset, 1, FALSE);
    proto_tree_add_item(vmlab_tree, hf_vmlab_flags_fragment, tvb, offset, 1, FALSE);
    proto_tree_add_item(vmlab_tree, hf_vmlab_flags_part2,    tvb, offset, 1, FALSE);
    if (attributes & 0x04) {
        proto_item_append_text(ti, ", Fragment");
    }
    offset += 1;
        
    /* Portgroup*/
    portgroup = tvb_get_guint8(tvb, offset);
    proto_tree_add_uint(vmlab_tree, hf_vmlab_portgroup, tvb, offset, 1, portgroup);
    proto_item_append_text(ti, ", Portgroup: %d", portgroup);
    offset += 1;

    /* The next two bytes were always 0x0000 as far as I could tell*/
    offset += 2;

    /* Not really clear, what the difference between this and the next MAC address is
       Both are usually equal*/
    eth_addr=tvb_get_ptr(tvb, offset, 6);
    proto_tree_add_ether(vmlab_tree, hf_vmlab_eth_addr, tvb, offset, 6, eth_addr);
    offset += 6;

    dst_addr=tvb_get_ptr(tvb, offset, 6);
    proto_tree_add_ether(vmlab_tree, hf_vmlab_eth_dst, tvb, offset, 6, dst_addr);
    offset += 6;

    /* Source MAC*/
    src_addr=tvb_get_ptr(tvb, offset, 6);
    proto_tree_add_ether(vmlab_tree, hf_vmlab_eth_src, tvb, offset, 6, src_addr);
    offset += 6;

    proto_item_append_text(ti, ", Src: %s (%s), Dst: %s (%s)", 
                           get_ether_name(src_addr), ether_to_str(src_addr), get_ether_name(dst_addr), ether_to_str(dst_addr));
        
    /* Encapsulated Ethertype is also part of the block*/
    encap_proto = tvb_get_ntohs(tvb, offset);
    offset += 2;

    /* Now call whatever was encapsulated*/
    ethertype(encap_proto, tvb, offset, pinfo, tree, vmlab_tree, hf_vmlab_etype, hf_vmlab_trailer, 0);

}
Beispiel #23
0
static void
dissect_sll(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint16 pkttype;
	guint16 protocol;
	guint16 hatype, halen;
	const guint8 *src;
	proto_item *ti;
	tvbuff_t *next_tvb;
	proto_tree *fh_tree = NULL;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SLL");
	col_clear(pinfo->cinfo, COL_INFO);

	pkttype = tvb_get_ntohs(tvb, 0);

	/*
	 * Set "pinfo->p2p_dir" if the packet wasn't received
	 * promiscuously.
	 */
	switch (pkttype) {

	case LINUX_SLL_HOST:
	case LINUX_SLL_BROADCAST:
	case LINUX_SLL_MULTICAST:
		pinfo->p2p_dir = P2P_DIR_RECV;
		break;

	case LINUX_SLL_OUTGOING:
		pinfo->p2p_dir = P2P_DIR_SENT;
		break;
	}

	col_add_str(pinfo->cinfo, COL_INFO,
		    val_to_str(pkttype, packet_type_vals, "Unknown (%u)"));

	if (tree) {
		ti = proto_tree_add_protocol_format(tree, proto_sll, tvb, 0,
		    SLL_HEADER_SIZE, "Linux cooked capture");
		fh_tree = proto_item_add_subtree(ti, ett_sll);
		proto_tree_add_item(fh_tree, hf_sll_pkttype, tvb, 0, 2, ENC_BIG_ENDIAN);
	}

	/*
	 * XXX - check the link-layer address type value?
	 * For now, we just assume 6 means Ethernet.
	 */
	hatype = tvb_get_ntohs(tvb, 2);
	halen = tvb_get_ntohs(tvb, 4);
	if (tree) {
		proto_tree_add_uint(fh_tree, hf_sll_hatype, tvb, 2, 2, hatype);
		proto_tree_add_uint(fh_tree, hf_sll_halen, tvb, 4, 2, halen);
	}
	switch (halen) {
	case 4:
		src = tvb_get_ptr(tvb, 6, 4);
		SET_ADDRESS(&pinfo->dl_src, AT_IPv4, 4, src);
		SET_ADDRESS(&pinfo->src, AT_IPv4, 4, src);
		if (tree) {
			proto_tree_add_item(fh_tree, hf_sll_src_ipv4, tvb,
			    6, 4, ENC_BIG_ENDIAN);
		}
		break;
	case 6:
		src = tvb_get_ptr(tvb, 6, 6);
		SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
		SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
		if (tree) {
			proto_tree_add_ether(fh_tree, hf_sll_src_eth, tvb,
			    6, 6, src);
		}
		break;
	case 0:
		break;
	default:
		if (tree) {
			proto_tree_add_item(fh_tree, hf_sll_src_other, tvb,
			    6, halen > 8 ? 8 : halen, ENC_NA);
		}
		break;
	}

	protocol = tvb_get_ntohs(tvb, 14);
	next_tvb = tvb_new_subset_remaining(tvb, SLL_HEADER_SIZE);
	if (protocol <= 1536) {	/* yes, 1536 - that's how Linux does it */
		/*
		 * "proto" is *not* a length field, it's a Linux internal
		 * protocol type.
		 * We therefore cannot say how much of the packet will
		 * be trailer data.
		 * XXX - do the same thing we do for packets with Ethertypes?
		 */
		proto_tree_add_uint(fh_tree, hf_sll_ltype, tvb, 14, 2,
		    protocol);

		if(!dissector_try_uint(sll_linux_dissector_table, protocol,
			next_tvb, pinfo, tree)) {
			call_dissector(data_handle, next_tvb, pinfo, tree);
		}
	} else {
		switch (hatype) {
		case ARPHRD_IPGRE:
			proto_tree_add_uint(fh_tree, hf_sll_gretype, tvb, 14, 2,
			    protocol);
			dissector_try_uint(gre_dissector_table,
					   protocol, next_tvb, pinfo, tree);
			break;
		default:
			ethertype(protocol, tvb, SLL_HEADER_SIZE, pinfo, tree,
				  fh_tree, hf_sll_etype, hf_sll_trailer, 0);
			break;
		}
	}
}
Beispiel #24
0
/* Code to actually dissect the packets */
static int
dissect_tte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    tvbuff_t* tvb_next;
    int is_frame_pcf;

    /* Set up structures needed to add the protocol subtree and manage it */
    proto_item *tte_root_item, *tte_macdest_item, *tte_macsrc_item;
    proto_tree *tte_tree, *tte_macdest_tree/*, *tte_macsrc_tree*/;

    /* Check that there's enough data */
    if (tvb_length(tvb) < TTE_HEADER_LENGTH)
        return 0;

    /* check if data of pcf frame */
    is_frame_pcf = 
       (tvb_get_ntohs(tvb, TTE_MAC_LENGTH * 2) == ETHERTYPE_TTE_PCF);

    /* return if no valid cosntant field is found */
    if (!is_frame_pcf)
    {
        if ( (tvb_get_ntohl(tvb, 0) & tte_pref_ct_mask) != tte_pref_ct_marker)
            return 0;
    }

    /* Make entries in Protocol column and Info column on summary display */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "TTE ");

    col_set_str(pinfo->cinfo, COL_INFO, "Bogus TTEthernet Frame");

    if (tree) {

        /* create display subtree for the protocol */
        tte_root_item = proto_tree_add_item(tree, proto_tte, tvb, 0,
            TTE_HEADER_LENGTH, FALSE);

        tte_tree = proto_item_add_subtree(tte_root_item, ett_tte);

        tte_macdest_item = proto_tree_add_item(tte_tree,
            hf_eth_dst, tvb, 0, TTE_MAC_LENGTH, FALSE);

        tte_macsrc_item = proto_tree_add_item(tte_tree,
            hf_eth_src, tvb, TTE_MAC_LENGTH, TTE_MAC_LENGTH, FALSE);

        proto_tree_add_item(tte_tree,
            hf_eth_type, tvb, TTE_MAC_LENGTH*2, TTE_ETHERTYPE_LENGTH,
            FALSE);

        tte_macdest_tree = proto_item_add_subtree(tte_macdest_item,
            ett_tte_macdest);

        proto_tree_add_item(tte_macdest_tree,
            hf_tte_dst_cf, tvb, 0, TTE_MACDEST_CF_LENGTH, FALSE);

        proto_tree_add_item(tte_macdest_tree,
            hf_tte_ctid, tvb, TTE_MACDEST_CF_LENGTH,
            TTE_MACDEST_CTID_LENGTH, FALSE);
    }

    tvb_next = tvb_new_subset_remaining(tvb, TTE_HEADER_LENGTH);

    /* prevent the Columns to be cleared...appending cannot be prevented */
    col_set_fence(pinfo->cinfo, COL_PROTOCOL);

    /* call std Ethernet dissector */
    ethertype (tvb_get_ntohs(tvb, TTE_MAC_LENGTH * 2), tvb
        , 14, pinfo, tree, NULL, hf_eth_type, 0, 0 );

    return tvb_length(tvb);
}
Beispiel #25
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  uint8_t buf[len];
  int cksumtemp = 0;
  int cksumcalculated = 0;
  struct sr_arpentry *entry;
  struct sr_arpreq *req;
  struct sr_arpcache *arp_cache = &(sr->cache);
  struct sr_if *sr_interface;
  struct sr_rt *rt_walker = 0;
  char *temp_if;

  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("\n*** -> Received packet of length %d \n",len);

  /* fill in code here */
  sr_ethernet_hdr_t *ethhdr = (sr_ethernet_hdr_t *)packet;
  sr_arp_hdr_t *arphdr = (sr_arp_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t));
  sr_ip_hdr_t *iphdr = (sr_ip_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t));
  sr_icmp_hdr_t *icmphdr = (sr_icmp_hdr_t *)(packet + sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t));

  sr_ethernet_hdr_t *arpreply_ethhdr = (sr_ethernet_hdr_t *)buf;
  sr_arp_hdr_t *arpreply_arphdr = (sr_arp_hdr_t *)(buf + sizeof(sr_ethernet_hdr_t));

  sr_ethernet_hdr_t *tempreq;

  if (len < sizeof(sr_ethernet_hdr_t)) {
    fprintf(stderr, "ETHERNET header is insufficient length\n");
    return;
  }

  if(ethertype(packet) == ethertype_arp) { /* ARP */
    if (len < (sizeof(sr_ethernet_hdr_t) + sizeof(sr_arp_hdr_t))) {
      /* todo: call sr_arp_req_not_for_us, maybe later */
      fprintf(stderr, "ARP header is insufficient length\n");
      return;
    }
    else {
      printf("ARP packet received\n");
      if(ntohs(arphdr->ar_op) == arp_op_request) { /* ARP request */
	printf("\tARP request\n");
	/* send ARP reply */
	sr_interface = sr_get_interface(sr,interface);
	memcpy(buf,packet,len);

	memset(arpreply_ethhdr->ether_dhost,0xff,6);
	memcpy(arpreply_ethhdr->ether_shost,sr_interface->addr,6);
	arpreply_ethhdr->ether_type = htons(ethertype_arp);

	arpreply_arphdr->ar_op = htons(arp_op_reply);
	memcpy(arpreply_arphdr->ar_sha,sr_interface->addr,6);
	arpreply_arphdr->ar_sip = arphdr->ar_tip;
	memcpy(arpreply_arphdr->ar_tha,arphdr->ar_sha,6);
	arpreply_arphdr->ar_tip = arphdr->ar_sip;
	sr_send_packet(sr,buf,len,interface);

	printf("\tARP reply sent\n");
		/* sr_arpcache_dump(arp_cache); */
      }
      else if(ntohs(arphdr->ar_op) == arp_op_reply) { /* ARP reply */
	printf("\tARP reply\n");
	/* cache IP->MAC mapping and check if arp req in queue */
	req = sr_arpcache_insert(arp_cache,arphdr->ar_sha,ntohs(arphdr->ar_sip));
	tempreq = (sr_ethernet_hdr_t *)req->packets->buf;
	memcpy(tempreq->ether_dhost,ethhdr->ether_shost,6);
	if(req != NULL) {
	  /* send outstanding packets by call */
	  printf("\tARP req in queue\n");
	  sr_send_packet(sr,req->packets->buf,req->packets->len,interface);
	  sr_arpreq_destroy(arp_cache,req);
	}
	else
	  printf("\tARP req not in queue\n");
      }
      else /* not ARP request or reply */
	fprintf(stderr, "Unknown ARP opcode\n");
    }
  }

  else if(ethertype(packet) == ethertype_ip) { /* IP */
    if (len < (sizeof(sr_ethernet_hdr_t) + sizeof(sr_ip_hdr_t))) {
      fprintf(stderr, "IP header is insufficient length\n");
      return;
    }
    else {
      printf("IP packet received\n");
      /* check checksum */
      cksumtemp = iphdr->ip_sum;
      iphdr->ip_sum = 0;
      cksumcalculated = cksum((void *)iphdr,4*iphdr->ip_hl);

      if(cksumtemp == cksumcalculated) {
	printf("\tChecksum good!\n");

	/* this part should not be here, it should be called though */
	if(iphdr->ip_ttl <= 1) {
	  fprintf(stderr, "ICMP time exceeded\n"); /* ICMP time exceeded */
	  return;
	}
	else
	  iphdr->ip_ttl -= 1; 
	
	/* update checksum */
	iphdr->ip_sum = cksum((void *)iphdr,4*iphdr->ip_hl);

	/* todo: LPM and find next hop ip, if no match ICMP net unreachable  */

	/* check routing table, save interface */
	rt_walker = sr->routing_table;
	while(rt_walker != NULL) {
	  if(iphdr->ip_dst == (uint32_t)rt_walker->dest.s_addr) { /* checks for dest IP addr, should be LPM ip not ip_dst */
	    temp_if = rt_walker->interface;
	  }
	  rt_walker = rt_walker->next;
	}
	sr_interface = sr_get_interface(sr,temp_if);

	/* check cache to avoid unnecessary arp req */
	entry = sr_arpcache_lookup(arp_cache,ntohs(iphdr->ip_dst)); /* should be LPM ip not ip_dst, but since next hop is destination... */

	if(entry != NULL) { /* cache hit, just send ip packet to next hop*/
	  printf("\tIP->MAC hit\n");
	  sr_send_packet(sr,packet,len,sr_interface);
	  free(entry);
	}
	else { /* cache miss, send ARP req and wait for reply */
	  printf("\tIP->MAC miss\n");
	  if(sr_interface == 0) { /* no match in routing table */
	    fprintf(stderr, "ICMP host unreachable\n");
	    return;
	  }
	  else { /* match in routing table */
	    /* construct arp req with new interface */
	    memset(arpreply_ethhdr->ether_dhost,0xff,6);
	    memcpy(arpreply_ethhdr->ether_shost,sr_interface->addr,6);
	    arpreply_ethhdr->ether_type = htons(ethertype_arp);

	    arpreply_arphdr->ar_hrd = htons(arp_hrd_ethernet);
	    arpreply_arphdr->ar_pro = htons(ethertype_ip);
	    arpreply_arphdr->ar_hln = 0x6;
	    arpreply_arphdr->ar_pln = 0x4;
	    arpreply_arphdr->ar_op = htons(arp_op_request);
	    memcpy(arpreply_arphdr->ar_sha,sr_interface->addr,6);
	    arpreply_arphdr->ar_sip = sr_interface->ip;
	    memset(arpreply_arphdr->ar_tha,0x00,6);
	    arpreply_arphdr->ar_tip = iphdr->ip_dst;

	    memcpy(ethhdr->ether_shost,sr_interface->addr,6);

	    printf("\tARP request sent\n");
	    /* add packet to queue list */
	    req = sr_arpcache_queuereq(arp_cache,ntohs(iphdr->ip_dst),packet,len,sr_interface);
	    handle_arpreq(arp_cache,sr,req,buf,sr_interface);
	  }
	}
      }
      else {
	/* drop packet */
	fprintf(stderr, "\tChecksum bad!\n");
	return;
      }
    }
  }

  else /* not IP or ARP */
    printf("Unrecognized Ethernet Type 0x%X\n",ethertype(packet));
}