On Sat, May 03, 2014 at 12:20:24PM +0200, Peter J. Philipp wrote:
> 
> 12:02:18.008513 48:01:09:03:04:07 ff:ff:ff:ff:ff:ff 8100 36: 802.1Q vid
> 10 pri 3 PPPoE-Discovery
>         code Initiation, version 1, type 1, id 0x0000, length 12
>         tag Service-Name, length 0
>         tag Host-Uniq, length 4 \005^\334G
>   0000: ffff ffff ffff 4801 0903 0407 8100 600a  ......H.......`.
>   0010: 8863 1109 0000 000c 0101 0000 0103 0004  .c..............
>   0020: 055e dc47                                .^.G
> 
> 
> vlan0:
> 
> 12:04:18.009041 48:01:09:03:04:07 60:0a:88:63:ff:ff 8863 32: PPPoE-Discovery
>         code Initiation, version 1, type 1, id 0x0000, length 12
>         tag Service-Name, length 0
>         tag Host-Uniq, length 4 \005^\334G
>   0000: 600a 8863 ffff 4801 0903 0407 8863 1109  `..c..H......c..
>   0010: 0000 000c 0101 0000 0103 0004 055e dc47  .............^.G
> ----
> 
> As you probably can see on the first glance is that the MAC address for
> the received changed.  It took 600a 8863, which is the vlan tag and the
> ethernet type, and overwrote the ethernet dest address with those 4
> bytes resulting in 60:0a:88:63:ff:ff.  My npppd that I had set up on
> vlan0 on the main host doesn't see it as a broadcast anymore and thus it
> can't offer a PADO.
> 
> Yours, Thorsten, is probably the same concept almost just it's reversed.
> 
> Now to my environment.
> 
> The mainhost is OpenBSD-current...
> 
> vether0 looks like this:
> 
> vether0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
>         lladdr fe:e1:ba:d0:65:cd
>         priority: 0
>         groups: vether
>         media: Ethernet autoselect
>         status: active
>         inet6 fe80::fce1:baff:fed0:65cd%vether0 prefixlen 64 scopeid 0x5
> ...
> 
> I'm sorry for being all over the place with the data.  And I have an
> inquiry to the vlan responsible person at OpenBSD:
> 
> 
> in /sys/net/if_vlan.c:  vlan_input() I see this:
> 
> ----
>         /*
>          * Having found a valid vlan interface corresponding to
>          * the given source interface and vlan tag, remove the
>          * encapsulation, and run the real packet through
>          * ether_input() a second time (it had better be
>          * reentrant!).
>          */
>         m->m_pkthdr.rcvif = &ifv->ifv_if;
>         if (m->m_flags & M_VLANTAG) {
>                 m->m_flags &= ~M_VLANTAG;
>         } else {
>                 eh->ether_type = mtod(m, u_int16_t *)[1];
>                 m->m_len -= EVL_ENCAPLEN;
>                 m->m_data += EVL_ENCAPLEN;
>                 m->m_pkthdr.len -= EVL_ENCAPLEN;
>         }
> ----
> 
> in the else statement, isn't the manipulation of the mbuf the same as an
> m_adj(m, EVL_ENCAPLEN); ?
> 
> If not, pardon my ignorance/newbishness.

Hi list,

I wrote many many debug printf's into net/if_vlan.c's vlan_input() and I can
pinpoint at what function it changes the value of struct ether_header *eh.
Here is what my debugs look like against a 5.5 source and against cat -n:

----
  272  
   273          printf("check 1: %s\n", ether_sprintf((unsigned char 
*)eh->ether_dhost));
   274          if (m->m_flags & M_VLANTAG) {
   275                  etype = ETHERTYPE_VLAN;
   276                  tagh = vlan_tagh;
   277          } else {
   278                  if (m->m_len < EVL_ENCAPLEN &&
   279                      (m = m_pullup(m, EVL_ENCAPLEN)) == NULL) {
   280                          ifp->if_ierrors++;
   281                          return (0);
   282                  }
   283                  printf("check 1a: %s\n", ether_sprintf((unsigned char 
*)eh->ether_dhost));
   284  
   285                  etype = ntohs(eh->ether_type);
   286                  printf("check 1b: %s\n", ether_sprintf((unsigned char 
*)eh->ether_dhost));
   287                  tagh = etype == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh;
   288                  printf("check 1c: %s\n", ether_sprintf((unsigned char 
*)eh->ether_dhost));
-----

The result is this:

check 1: ff:ff:ff:ff:ff:ff
check 1a: 60:0a:88:63:ff:ff
check 1b: 60:0a:88:63:ff:ff

so at the point between check 1 and check 1a is the offending function that 
changes *eh.  it's m_pullup().

Now then I'll leave it there as that's way over my head, but perhaps I've 
done the basic work for someone looking over this.

Good luck Thorsten!

-peter

Reply via email to