lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Mon, 11 Feb 2008 14:18:34 +0100
From:	Jesper Dangaard Brouer <jdb@...x.dk>
To:	"netdev@...r.kernel.org" <netdev@...r.kernel.org>
Cc:	"David S. Miller" <davem@...emloft.net>
Subject: Re: Protocol handler for Marvell DSA EtherType packets

Hi NetDev and Google,

The answer to my question was:
 Aha, you are trying to use tcpdump to see the "encapsulated" packets,
then you also need to adjust skb->mac.raw.

I have attached the code (and inlined the receive func, for easier
commenting), as I have another question:

I use dev_get_by_index() which calls dev_hold() (via my function
m88e_get_netdevice()).

The question is: 
  Should I use dev_put() before or after calling netif_rx(skb).

-- 
Med venlig hilsen / Best regards
  Jesper Brouer
  ComX Networks A/S
  Linux Network developer
  Cand. Scient Datalog / MSc.
  Author of http://adsl-optimizer.dk
  LinkedIn: http://www.linkedin.com/in/brouer


On Fri, 2008-02-01 at 14:28 +0100, Jesper Dangaard Brouer wrote:
> Hi Netdev
> 
> I writing a new protocol handler using dev_add_pack().  (For a Marvell
> switch chip handling DSA (Distributed Switch Architecture) Ethertype
> packets).
> 
> My protocol handler works and I get the skb. But I want to remove the
> DSA Headers and send the packet back for normal processing on a
> device. (I actually just want to be able to tcpdump these packets on
> the device).
> 
> I'm removing the headers by:
>   skb_pull(skb, sizeof(struct dsa_header));
> 
> I'm trying to retransmit it by:
>   netif_rx(skb);
> 
> But it seems that I just retransmit the same packet without removing
> the DSA headers.
> 
> Any hints about which functions I should use the remove the DSA header?



/*
 * 	Main DSA Receive routine.
 */
int dsa_receive(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
{
	int res = NET_RX_SUCCESS;
	struct dsa_header   *dsa_hdr;
	struct proto_header *proto_hdr;
	struct net_device   *port_dev; /* the port associated net_device*/
	struct ethhdr       *eth_hdr;

	/*
	if      (skb->pkt_type == PACKET_OTHERHOST) VERBOSE("PACKET_OTHERHOST");
	else if (skb->pkt_type == PACKET_BROADCAST) VERBOSE("PACKET_BROADCAST");
	else if (skb->pkt_type == PACKET_MULTICAST) VERBOSE("PACKET_MULTICAST");
	else if (skb->pkt_type == PACKET_HOST)      VERBOSE("PACKET_HOST");
	else VERBOSE("PACKET_TYPE UNKNOWN");
	*/

	// Access to the real mac header
	eth_hdr = (struct ethhdr *)skb->mac.raw; // Same as eth_hdr(skb)

	// At this point the Ethernet header has been removed, but the
	// DSA EtherType header contains two extra reserved bytes,
	// move the pointer past these.
	//
	// DEBUGOUT("Removing 2 reserved bytes from DSA EtherType tag");
	skb_pull(skb, 2);

	// Access to the DSA packet information
	dsa_hdr = (struct dsa_header *) skb->data;

	if (net_ratelimit()) {
		printk(KERN_INFO);
		printk("Dev:%s ",      skb->dev->name);
		printk("Type 0x%x ",   dsa_hdr->type);
		printk("Tagged 0x%x ", dsa_hdr->tagged);
//		printk("Dev 0x%x ",    dsa_hdr->dev);
		printk("Port 0x%x ",   dsa_hdr->port);
		printk("Info 0x%x ",   dsa_hdr->info);
		printk("Prio 0x%x ",   dsa_hdr->pri);
		printk("Res 0x%x ",    dsa_hdr->res);
		printk("VLAN ID 0x%x ",dsa_hdr->vid);
		printk("\n");
	}

	// Decoding the DSA type
	switch(dsa_hdr->type) {
	case DSA_TO_CPU:
	{
		int code = ((dsa_hdr->info)&0x06)|dsa_hdr->res;

		if(IGMP_TRAP == code) {
			printk("IGMP Trap\n");
		} else {
			printk("Unsupported code %d\n",code);
		}
		break;
	}
	case DSA_FROM_CPU:
		/*Fall through*/
	case DSA_TO_SNIFFER:
		/*Fall through*/
		if (net_ratelimit())
			DEBUGOUT("Sniffer packet");
		break;
	case DSA_FORWARD:
		/*Fall through*/
	default:

		break;
	}

	// Find the device associated with the switch port.
	//
	// Q: m88e_get_netdevice() calls dev_get_by_index(), which it calls dev_hold()
	port_dev = m88e_get_netdevice(dsa_hdr->port);
	skb->dev = port_dev;

	// Move past the DSA header
	skb_pull(skb, sizeof(struct dsa_header));

	// TEST: if it possible to change some skb data and see it in tcpdump
	// eth_hdr->h_proto = 0x9111;

	/* Extract the ethertype of the encapsulated packet, and
	   indicate the protocol to the next layer. */
	proto_hdr     = (struct proto_header*) skb->data;
	skb->protocol = proto_hdr->h_proto;

	if (net_ratelimit())
		printk(KERN_ERR "Encapsulated packet Protocol 0x%x\n",skb->protocol);

	// HACK, shift the mac header, this allows packet sniffers to
	// decode the packet as a normal ethernet packet, but the mac
	// address will not be correct.
	skb->mac.raw = skb->data - (6+6);

	// Q: Is it allowed to modify the skb data, I would like to
	// correct the MAC headers, but is that allowed? Do I need to
	// skb_copy the packet?

	// Move past the EtherType of the encapsulated packet
	skb_pull(skb, sizeof(struct proto_header));

	// FIXME: Perhaps we need to change skb->pkt_type to
	// PACKET_HOST, to make the next protocol handlers
	// accept/process the data???
	//skb->pkt_type = PACKET_HOST;

	// Retransmit it on a virtual switch port device... this will
	// e.g. send it to the IGMP protocol handler.
	res = netif_rx(skb);

	// Release the device pointer
	if (port_dev)
		dev_put(port_dev);

	return res;

 drop:
        kfree_skb(skb);
 out:
        return NET_RX_DROP;
}


static struct packet_type dsa_packet_type =
{
	.type = __constant_htons(ETHERTYPE_DSA),
	.dev  = NULL, /* NULL is wildcarded interfaces */
	.func = dsa_receive,
	.data = NULL,
	//.data = (void*)1, /* Set here '(void *)1' when this code can SHARE SKBs */
	.next = NULL
};


View attachment "ethertype_dsa.c" of type "text/x-csrc" (6773 bytes)

View attachment "ethertype_dsa.h" of type "text/x-chdr" (2018 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ