From: Janne J. <jan...@bi...> - 2002-04-02 15:09:35
|
Sorry for "spamming" so much with my porting issues. Now it seems that BSD (at least Free/OpenBSD) TUN devices send AF_INET as a u_int32_t in network byte order first, which Linux tun-devs dont. That's why my last mail contains sending of "00000002" as the first 32 bits, it's telling the other end which AF to use. When initiated from the Linux end, the BSD will say "unknown address family" or something very similar, which is true since it gets "45000054" as the first data. Is there two types of tun or is the BSD tuns just slightly different and incompatible by design? --=20 Janne Johansson jan...@bi... BioMat Systems AB Klarabergsg 37 3tr 111 21 Stockholm |
From: James Y. <ji...@nt...> - 2002-04-02 22:45:23
|
>Sorry for "spamming" so much with my porting issues. Hey, I think it's great you're trying to port it! Post as much as you want. >Now it seems that BSD (at least Free/OpenBSD) TUN devices send AF_INET as a u_int32_t in network byte order first, which Linux tun-devs dont. Interesting. We should post something about that on the TUN/TAP list. I would think that network byte order should be the correct behaviour. >That's why my last mail contains sending of "00000002" as the first 32 bits, it's telling the other end which AF to use. >When initiated from the Linux end, the BSD will say "unknown address family" or something very similar, which is true since it gets "45000054" as the first data. >Is there two types of tun or is the BSD tuns just slightly different and incompatible by design? Also sounds like a TUN/TAP list question. I know the TUN/TAP driver became an official part of the linux kernel as of the early 2.4 releases. A fix on the linux side to conform to network byte ordering would be dicey since it would break compatibility. My approach would be to do the fix on the linux side but add an extra check for compatibility and allow packets if the order is wrong. Since there aren't too many address families to worry about, the bad ordering test should't be terribly ambiguous. And since linux kernel changes take a long time to happen, it might be necessary to add a workaround in OpenVPN to deal with this. What do you think? James |
From: Janne J. <jan...@bi...> - 2002-04-03 07:27:05
|
On Wed, 2002-04-03 at 00:44, James Yonan wrote: > >Sorry for "spamming" so much with my porting issues. >=20 > Hey, I think it's great you're trying to port it! Post as much as you wa= nt. >=20 > >Now it seems that BSD (at least Free/OpenBSD) TUN devices send AF_INET > as a u_int32_t in network byte order first, which Linux tun-devs > dont. >=20 > Interesting. We should post something about that on the TUN/TAP list. I > would think that network byte order should be the correct behaviour. I'll get back to this further down, but to clarify, _each_ packet read from tun will have this u_int_32 prepended. > >That's why my last mail contains sending of "00000002" as the first > 32 bits, it's telling the other end which AF to use. >=20 > >When initiated from the Linux end, the BSD will say > "unknown address family" or something very similar, which is true > since it gets "45000054" as the first data. >=20 > >Is there two types of tun or is the BSD tuns just slightly different and > incompatible by design? >=20 > Also sounds like a TUN/TAP list question. I know the TUN/TAP driver beca= me > an official part of the linux kernel as of the early 2.4 releases. >=20 > A fix on the linux side to conform to network byte ordering would be dice= y > since it would break compatibility. Well, sooner or later Linux should do that too, to support big endian machines. But the issue was more to the fact that the BSD sends this: "00000002 45000054 ..blabla" whereas Linux sends this: "45000054 ..blabla". The manpage for tun on BSD says: "The first u_int32_t of data will always be the address family (eg, AF_INET) of the packet in network byte order. By default, the packet data follows immediately, but if the PREPADDR bit is set, the address to which the packet is to be sent is placed =20 after the address family u_int32_t and before the packet data." Now, I don't want to rant about OSes, but being able to just type "man tun" when you're dealing with tun interfaces and get serious info is quite nice. I googled a bit yesterday and could not find neither tun info for Linux nor the kernel source as cvsweb, so I could read the source at least. 8-/ > My approach would be to do the fix on the linux side but add an extra che= ck > for compatibility and allow packets if the order is wrong. Since there > aren't too many address families to worry about, the bad ordering test > should't be terribly ambiguous. >=20 > And since linux kernel changes take a long time to happen, it might be > necessary to add a workaround in OpenVPN to deal with this. >=20 > What do you think? I don't know the openvpn data format, but if 45000054 is some sort of openvtun identifier, you/we/I could add some code that checked for 00000002 followed by 45000054 and then strip the first u_int_32 from the packet and go on. Perhaps a --remote-is-bsd or something similar? The last bit of the manpage says: "NOTES Very old versions of the tunnel device did not include the address family at the start of the packet. More recent versions passed the address family as a single byte, but this caused problems with bpf, hence the current version passes a u_int32_t of address family. This was initially pass in host byte order, but the current version now uses network byte order." I checked the CVS for openbsd, and the native -> network byte order change was done 3 years ago, which is a really long time. I wonder if Vtun ever did work between linux-vs-bsd ? Or does it have code to handle this? --=20 Janne Johansson jan...@bi... BioMat Systems AB Klarabergsg 37 3tr 111 21 Stockholm |
From: James Y. <ji...@nt...> - 2002-04-04 08:46:08
|
>I don't know the openvpn data format, but if 45000054 is some sort of openvtun identifier, you/we/I could add some code that checked for 00000002 followed by 45000054 and then strip the first u_int_32 from the packet and go on. Perhaps a --remote-is-bsd or something similar? Openvpn doesn't look at the tunnel data... it just encrypts, decrypts, forwards etc. The 45000054 is the beginning of the IP header of the packets going over the tunnel. Yeah, an option might be right thing. So --remote-is-bsd would remove the AF_INET from incoming packets and add them to outgoing packets. A bit of a kludge. >I wonder if Vtun ever did work between linux-vs-bsd ? I doubt it. I did a grep on vtun sources for AF_INET and didn't find any usage other than the usual places. James |
From: Janne J. <jan...@bi...> - 2002-04-04 08:57:26
|
On Thu, 2002-04-04 at 10:46, James Yonan wrote: > >I don't know the openvpn data format, but if 45000054 is some sort of > openvtun identifier, you/we/I could add some code that checked for > 00000002 followed by 45000054 and then strip the first u_int_32 from > the packet and go on. Perhaps a --remote-is-bsd or something similar? >=20 > Openvpn doesn't look at the tunnel data... it just encrypts, decrypts, > forwards etc. The 45000054 is the beginning of the IP header of the pack= ets > going over the tunnel. Dang. =3D) (Sorry for mistyping it as openvtun) Still, it's just as well, since that data would look different when encrypted anyway. > Yeah, an option might be right thing. So --remote-is-bsd would remove th= e > AF_INET from incoming packets and add them to outgoing packets. A bit of= a > kludge. Yes, but since BSD wont let you choose if you want it or not, and the chance of changing Linux-TUN-drivers now is slim, I guess it has to be the application that takes care of this. I'll try to make a patch and test it, and send you the diff later. I'll also try to make a diff to let BSD tun devices ioctl away that particurlar u_int_32. BTW, is it just me or is the sourceforge lists slow? The turnaround time seems like hours to me. --=20 Janne Johansson jan...@bi... BioMat Systems AB Klarabergsg 37 3tr 111 21 Stockholm |
From: James Y. <ji...@nt...> - 2002-04-04 09:21:36
|
On Thu, 2002-04-04 at 10:46, James Yonan wrote: > >I don't know the openvpn data format, but if 45000054 is some sort of > openvtun identifier, you/we/I could add some code that checked for > 00000002 followed by 45000054 and then strip the first u_int_32 from > the packet and go on. Perhaps a --remote-is-bsd or something similar? > > Openvpn doesn't look at the tunnel data... it just encrypts, decrypts, > forwards etc. The 45000054 is the beginning of the IP header of the packets > going over the tunnel. Dang. =) (Sorry for mistyping it as openvtun) Still, it's just as well, since that data would look different when encrypted anyway. > Yeah, an option might be right thing. So --remote-is-bsd would remove the > AF_INET from incoming packets and add them to outgoing packets. A bit of a > kludge. >Yes, but since BSD wont let you choose if you want it or not, and the chance of changing Linux-TUN-drivers now is slim, I guess it has to be the application that takes care of this. I'll try to make a patch and test it, and send you the diff later. Some thoughts: * probably the best place to add/remove the AF_INET is by calling some routine in the main event loop in openvpn.c, conditional on --remote-is-bsd. * add and remove u_int_32 by manipulating struct buffer (see buf_prepend and buf_advance in particular). * remember that when you add a new buffer prepend item, you must modify the appropriate struct frame which will contain the MTU parms, so that everything gets sized right. For an example, see crypto_adjust_frame_parameters(). >I'll also try to make a diff to let BSD tun devices ioctl away that particurlar u_int_32. Good idea. >BTW, is it just me or is the sourceforge lists slow? The turnaround time seems like hours to me. Doesn't seem too bad to me. James |
From: Janne J. <jan...@bi...> - 2002-04-04 10:15:13
|
> >Yes, but since BSD wont let you choose if you want it or not, and the > chance of changing Linux-TUN-drivers now is slim, I guess it has to be > the application that takes care of this. I'll try to make a patch and > test it, and send you the diff later. >=20 > Some thoughts: >=20 > * probably the best place to add/remove the AF_INET is by calling some > routine in the main event loop in openvpn.c, conditional on --remote-is-b= sd. >=20 > * add and remove u_int_32 by manipulating struct buffer (see buf_prepend = and > buf_advance in particular). >=20 > * remember that when you add a new buffer prepend item, you must modify t= he > appropriate struct frame which will contain the MTU parms, so that > everything gets sized right. For an example, see > crypto_adjust_frame_parameters(). I have made an attempt but I must warn you, I'm no guru on pointers and stuff, so I'd like you to check my calls to see that I'm on the right track please: I will test this asap and tell you if it works. diff -ru openvpn-1.0.3/openvpn.c new_openvpn-1.0.3/openvpn.c --- openvpn-1.0.3/openvpn.c Fri Mar 29 01:43:12 2002 +++ new_openvpn-1.0.3/openvpn.c Thu Apr 4 12:09:32 2002 @@ -91,6 +91,8 @@ " : 8 -- show all debug info\n" "--gremlin : Simulate dropped & corrupted packets + network outage= s\n" " to test robustness of protocol (for debugging only).\= n" + "--remote-bsd : If the remote system is using BSD tun devices that ad= d\n" + " protocol info on each packet sent.\n" #ifdef USE_LZO "--comp-lzo : Use fast LZO compression -- may add up to 1 byte per\= n" " packet for uncompressible data.\n" @@ -210,6 +212,7 @@ o->verbosity =3D 1; o->bind_local =3D true; o->tun_mtu =3D DEFAULT_TUN_MTU; + o->remotebsd =3D false; #ifdef USE_LZO o->comp_lzo_adaptive =3D true; #endif @@ -262,6 +265,7 @@ SHOW_INT (nice); SHOW_INT (verbosity); SHOW_BOOL (gremlin); + SHOW_BOOL (remotebsd); =20 #ifdef USE_LZO SHOW_BOOL (comp_lzo); @@ -426,6 +430,11 @@ =20 static void frame_finalize(struct frame *frame, const struct options *opti= ons) { + if (options->remotebsd) + { + frame->extra_frame +=3D 4; + } + if (options->tun_mtu_defined) { frame->mtu =3D options->tun_mtu; @@ -872,6 +881,11 @@ check_status (buf.len, "read from tun"); if (buf.len > 0) { + if (options->remotebsd) + { + buf_advance(&buf, sizeof(u_int32_t)); + } + #ifdef USE_LZO if (options->comp_lzo) lzo_compress (&buf, lzo_compress_buf, &lzo_compwork, &frame, current= ); @@ -905,6 +919,13 @@ if (FD_ISSET (td, &writes)) { int size; + + if (options->remotebsd) + { + u_int32_t af =3D htonl(AF_INET); + buf_write_prepend(&to_tun, &af ,sizeof (u_int32_t)); + } + ASSERT (to_tun.len > 0 && to_tun.len <=3D MAX_RW_SIZE_TUN(&frame)); size =3D write (td, BPTR (&to_tun), BLEN (&to_tun)); check_status (size, "write to tun"); @@ -1155,6 +1176,10 @@ { options.bind_local =3D false; } + else if (streq (p1, "--remote-bsd")) + { + options.remotebsd =3D true; + } #ifdef USE_LZO else if (streq (p1, "--comp-lzo")) { diff -ru openvpn-1.0.3/openvpn.h new_openvpn-1.0.3/openvpn.h --- openvpn-1.0.3/openvpn.h Sat Mar 30 03:24:00 2002 +++ new_openvpn-1.0.3/openvpn.h Thu Apr 4 11:16:46 2002 @@ -53,6 +53,7 @@ int nice; int verbosity; bool gremlin; + bool remotebsd; =20 #ifdef USE_LZO bool comp_lzo; --=20 Janne Johansson jan...@bi... BioMat Systems AB Klarabergsg 37 3tr 111 21 Stockholm |
From: James Y. <ji...@nt...> - 2002-04-04 11:18:58
|
>I think the solution would be to have openvpn disable TUN_NO_IP for Linux tun devices and just not care about the actual value when the packets arrive. So if the linux side disables TUN_NO_PI, does the problem go away when connecting to BSD? James |