Re: MBIM Patch (Round 2)

2016-06-08 Thread Gerhard Roth
On Tue, 7 Jun 2016 16:31:21 +0100 Stuart Henderson <s...@spacehopper.org> wrote:
> On 2016/06/07 14:39, Gerhard Roth wrote:
> > > > Now I get an IP address from my provider, I want something like this:
> > > > 
> > > > inet 10.75.178.41 --> 10.75.178.42 netmask 0xfffc
> > > > 
> > > > But if I used SIOCAIFADDR I would get this instead:
> > > > 
> > > > inet 0.0.0.1 --> 0.0.0.2 netmask 0xff00
> > > > inet 10.75.178.41 --> 10.75.178.42 netmask 0xfffc
> > > > 
> > > > And deleting the old one first seems more racy.
> > > 
> > > Why?
> > 
> > Because either there is a time without any IP address or there
> > is one with two addresses. Neither seems right.
> 
> Is there a problem to have no address? That is what happens with
> gif(4), tun(4) etc, even with ethernet interfaces, when they don't
> have a particular address configured on them.
> 
> There doesn't seem a particular problem with dhclient removing
> the old address before it adds a new one..
> 
> > See above. That's the current OpenBSD model for PPP.
> 
> There are several models :-)
> 
> The 0.0.0.1 thing is a specific hack for sppp/pppoe which has
> "magic" values of 0.0.0.0 and 0.0.0.1 and a way to request a
> specific hardcoded address. This is because *both* sides
> propose addresses via IPCP (they are "equal" peers as far
> as configuration is concerned), they have to agree and can
> NAK each other.
> 
> It's not the only way though, even for PPP; ppp(4) doesn't use
> this mechanism, it has separate configuration for pppd instead.
> When we had ppp(8), that didn't, either.
> 
> As far as I understand MBIM addressing is driven from the "mobile
> network" side, we just set the address they are telling us to use
> without a way to propose our own address. If that's correct then
> we don't need a way to set "our side's" address at all, or have
> a way to tie down the remote side's address, so address
> configuration can be a lot simpler than any PPP interface.

I not sure if it is possible to send packets from an interface
that has no addresses assigned to it.

And then, the MBIM standard says nothing about the network segment.
My provider just gives me some non-routable 10.x.x.x IP, but I
think that it would be totally legal to assign some public IPv4
address to me. In that case it is mandatory that we assign this
address to our local interface.


> 
> > > But when you lose the connection with the network or you manually set
> > > the interface down, this IP address once given to you by the provider
> > > is no longer yours and must not be used anymore.
> 
> The same can apply in other cases (wifi, wired ethernet etc) too,
> but we don't do anything to remove it from those interfaces (though
> it's easy enough to remove using ifstated if needed).

For WiFi and Ethernet it is dhclient that will remove the old
addresses.



Re: MBIM Patch (Round 2)

2016-06-07 Thread Gerhard Roth
On Tue, 7 Jun 2016 13:08:49 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> On 07/06/16(Tue) 11:53, Gerhard Roth wrote:
> > On Mon, 6 Jun 2016 10:30:11 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> > > On 01/06/16(Wed) 17:20, Gerhard Roth wrote:
> > > Any reason for using a different license in documentation an code?
> > 
> > Different in what sense? Which paragraph do you mean?
> 
> This is a BSD 2-clauses the code is ISC.
> 
> > I just copied it from some other man page in share/man/man4. Can't
> > remember which one it was. But they all say pretty much the same thing.
> 
> Well if you don't mind, please use /usr/share/misc/license.template :)

Seriously, you don't mean that!
Did you take a look at that file?


> 
> > > > +/*
> > > > + * Some devices are picky about too frequent control messages.
> > > > + * Query device state not more often than every 0.5 secs.
> > > > + */
> > > > +struct timeval umbim_update_rate = { 0, 50 };
> > > ^
> > > This variable seems unused.  What it is for?
> > 
> > Some remnant from an earlier version.
> > 
> > 
> > > 
> > > > +int umbim_delay = 4000;
> > > 
> > > What is this supposed to be?
> > 
> > A value?
> > 
> > A litte delay in between the requests sent to the device.
> > Using a global variable helps to tune the value via DDB in the
> > development stage.
> 
> You're paraphrasing your code :)  My unclear question was just why
> do you need such delay? ;)

Well, ask the firmware writer. I don't know.


> 
> > > > +   break;
> > > > +   case SIOCSIFFLAGS:
> > > > +   usb_add_task(sc->sc_udev, >sc_umbim_task);
> > > 
> > > I guess you want to wait for the task to complete here.  You're not
> > > respecting  the API by returning directly.  But why using a task?  To
> > > serialize up/down operations?
> > 
> > No, waiting here is not an option. In order to get a complete configuration
> > of the device you need a mobile connection with the next base station.
> > Would you really want "ifconfig up" to block indefinitely when you're in
> > the basement without network access?
> > 
> > The task is there, because going "up" needs a lot of steps with
> > requests being sent to device and then waiting for the device to
> > respond to them.
> 
> I understand you point.  My concern is just that SIOCSIFFLAGS indicates
> that the interface is down/up once the ioclt(2) is finished.  It doesn't
> seem to be the case in your driver, I just hope this is not a problem.

How about WiFi? AFAIK it only starts scanning for an access point
but doesn't block until it finished association. So why should it
be a problem here?


> 
> > > > +   if (ifr->ifr_mtu > ifp->if_hardmtu) {
> > > > +   error = EINVAL;
> > > > +   break;
> > > > +   }
> > > > +   ifp->if_mtu = ifr->ifr_mtu;
> > > > +   break;
> > > > +   case SIOCGIFMTU:
> > > > +   ifr->ifr_mtu = ifp->if_mtu;
> > > > +   break;
> > > > +   case SIOCGIFHARDMTU:
> > > > +   ifr->ifr_hardmtu = ifp->if_hardmtu;
> > > > +   break;
> > > > +   case SIOCAIFADDR:
> > > 
> > > It is accepted that this ioctl(2) implicitly bring the interface up.
> > 
> > But this is a point-to-point interface and behaves a little bit
> > different from regular Ethernet interfaces. You're not supposed to
> > add IP destination addresses manually. Your provider will tell them to you.
> > And in case you do try to add them manually, that will not get a
> > working network interface.
> 
> I'm not saying it makes sense.  I'm just explaining how it is.
> 
> > > What about routing domains?  Did you try your device in a rdomain != 0?
> > 
> > No I didn't try them. But what could happen? This is a point-to-point
> > interface. No more routing decisions should be necessary on that level.
> 
> What could happen?  Good question.  I don't know.
> 
> > > > +void
> > > > +umbim_linkstate(struct umbim_softc *sc, int state)
> > > > +{
> > > > +   struct ifnet *ifp = GET_IFP(sc);
> > > > +   int  s;
> > > > +
> > > > +   s = splnet();
> > > > +

Re: MBIM Patch (Round 2)

2016-06-07 Thread Gerhard Roth
On Mon, 6 Jun 2016 10:30:11 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> On 01/06/16(Wed) 17:20, Gerhard Roth wrote:
> > [...] 
> > Thanks for all the feedback.
> 
> More comments inline.

Replies too.


> 
> > Index: sbin/ifconfig/ifconfig.c
> > ===
> > RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
> > retrieving revision 1.322
> > diff -u -p -u -p -r1.322 ifconfig.c
> > --- sbin/ifconfig/ifconfig.c3 May 2016 17:52:33 -   1.322
> > +++ sbin/ifconfig/ifconfig.c1 Jun 2016 14:32:18 -
> > @@ -107,6 +107,8 @@
> >  #include 
> >  
> >  #include "brconfig.h"
> > +#include 
> > +#include 
> 
> Does USB mobile broadband interfaces share a spec with non-USB devices?
> In other words would it make sense to move (some of) the defines in net/
> rather than usb/?

No, the MBIM spec is pure USB stuff that was schemed by usb.org.
 

> In any case these two include lines should be before the standard ones
> and under #ifndef SMALL.

That's right.


> [...]
> > Index: share/man/man4/umbim.4
> > ===
> > RCS file: share/man/man4/umbim.4
> > diff -N share/man/man4/umbim.4
> > --- /dev/null   1 Jan 1970 00:00:00 -
> > +++ share/man/man4/umbim.4  1 Jun 2016 14:32:18 -
> > @@ -0,0 +1,95 @@
> > +.\" Copyright (c) 2016 genua mbH
> > +.\" All rights reserved.
> > +.\"
> > +.\" Redistribution and use in source and binary forms, with or without
> > +.\" modification, are permitted provided that the following conditions
> > +.\" are met:
> > +.\"
> > +.\"- Redistributions of source code must retain the above copyright
> > +.\"  notice, this list of conditions and the following disclaimer.
> > +.\"- Redistributions in binary form must reproduce the above
> > +.\"  copyright notice, this list of conditions and the following
> > +.\"  disclaimer in the documentation and/or other materials provided
> > +.\"  with the distribution.
> > +.\"
> > +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > +.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > +.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> > +.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> > +.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> > +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
> > +.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> > +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> > +.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> > +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
> > +.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> > +.\" POSSIBILITY OF SUCH DAMAGE.
> 
> Any reason for using a different license in documentation an code?

Different in what sense? Which paragraph do you mean?

I just copied it from some other man page in share/man/man4. Can't
remember which one it was. But they all say pretty much the same thing.


> 
> > +.Sh CAVEATS
> > +The
> > +.Nm
> > +driver currently does not support IPv6 addresses.
> > +.Pp
> > +Roaming can be prevented by the driver. This feature hasn't been tested.
> > +Please don't kill me in case your phone bills rack up sky high.
> 
> I wouldn't put the last sentence in this manual.  The license already
> say that.

Ok, it's gone.


> 
> > Index: sys/dev/usb/if_umbim.c
> > ===
> > RCS file: sys/dev/usb/if_umbim.c
> > diff -N sys/dev/usb/if_umbim.c
> > --- /dev/null   1 Jan 1970 00:00:00 -
> > +++ sys/dev/usb/if_umbim.c  1 Jun 2016 14:32:19 -
> > @@ -0,0 +1,2441 @@
> > +/* $OpenBSD$ */
> > +
> > +/*
> > + * Copyright (c) 2016 genua mbH
> > + * All rights reserved.
> > + *
> > + * Permission to use, copy, modify, and distribute this software for any
> > + * purpose with or without fee is hereby granted, provided that the above
> > + * copyright notice and this permission notice appear in all copies.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIE

Re: MBIM Patch (Round 2)

2016-06-01 Thread Gerhard Roth

On 01.06.2016 20:28, Theo de Raadt wrote:

As I said, we could still change the name of the interface to 'ubm'
while keeping 'umbim' as the name of the driver.


No, I don't understand the proposal.  I think it should be ubm
throughout, or I am threatening to rename ix(4) to a 8 character
name.



Changing the name from 'mbim' to 'umbim' already took me serveral
hours because a simple sed(1) can't do the job. Don't have that
much lifetime left to go through this boredom once again.

BTW: if "ifconfig umbim0" is annoyingly long, we could just replace
ifconfig(8) with ip(8). That would save even more keystrokes ;)



Re: MBIM Patch (Round 2)

2016-06-01 Thread Gerhard Roth

On 01.06.2016 17:32, Theo de Raadt wrote:

- renamed it from 'mbim' to 'umbim'
I tried 'ubm' as proposed by Theo but that felt weird. Esp.
when changing the prefixes of macros whose names were
   derived from the MBIM standard.


I suggested that because

  ifconfig umbim0 ...

Is annoyingly long.



As I said, we could still change the name of the interface to 'ubm'
while keeping 'umbim' as the name of the driver.

Should I?



Re: MBIM Patch - Part 2 of 4

2016-05-31 Thread Gerhard Roth
On Mon, 23 May 2016 17:47:28 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> On 23/05/16(Mon) 16:51, Gerhard Roth wrote:
> > On Mon, 23 May 2016 16:18:29 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> > > On 23/05/16(Mon) 15:38, Gerhard Roth wrote:
> > > 
> > > This is crazy :)   No driver should ever modify `ia' directly.  This
> > > code should call in_control() via the ioctl path.
> > 
> > As mentioned in a previous mail: this was mostly copied from
> > if_spppsubr.c:sppp_set_ip_addrs(). But doing an SIOCSIFADDR
> > ioctl() from inside the kernel seems weird, too.
> 
> SIOCAIFADDR/SIOCDIFADDR It is the way to go.  The driver should not
> manipulate addresses or route entry.

Not manipulating the route entries is simple to fix. Will do that.

But using SIOCAIFADDR/SIOCDIFADDR seems rather awkward since in_control()
requires a 'struct socket *so' argument (even though it does nothing with
it, except checking 'so->so_state & SS_PRIV'). Creating a socket inside
the driver for this sole purpose seems just as weird as setting up a
fake struct socket.

Are you really sure, this is the better way to go?



Re: MBIM Patch - Part 2 of 4

2016-05-31 Thread Gerhard Roth
On Mon, 23 May 2016 17:47:28 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> On 23/05/16(Mon) 16:51, Gerhard Roth wrote:
> > On Mon, 23 May 2016 16:18:29 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> > > On 23/05/16(Mon) 15:38, Gerhard Roth wrote:
> > > > This is part 2 of the MBIM patch. It adds the mbim driver to i386
> > > > +/*
> > > > + * Some devices are picky about too frequent control messages.
> > > > + * Query device state not more often than every 0.5 secs.
> > > > + */
> > > > +struct timeval mbim_update_rate = { 0, 50 };
> > > > +int mbim_delay = 4000;
> > > > +
> > > > +/*
> > > > + * Normally, MBIM devices are detected by their interface class and 
> > > > subclass.
> > > > + * But for some models that have multiple configurations, it is better 
> > > > to
> > > > + * match by vendor and product id so that we can select the desired
> > > > + * configuration ourselves.
> > > > + *
> > > > + * OTOH, some devices identifiy themself als an MBIM device but fail 
> > > > to speak
> > > > + * the MBIM protocol.
> > > > + */
> > > 
> > > Why is it better?  This is just working around usb_probe_and_attach()
> > > and require developer to add an entry for every device we need to
> > > support.
> > 
> > I just thought that some modules that are already in use say with a
> > umsm config would otherwise change to mbim and break the setup. The idea
> > was to keep existing modules first as they are now and start adding
> > new one to the list.
> 
> Well the rule is first match win.  Since umsm(4) uses a vendor/product
> table as long as you don't add your device to this table it should be
> ok.
> 

Now I remember why I needed to match on VID/PID, too. I have one
MBIM module (Sierra Wireless MC8305) that shows some strange behaviour:

If you read the configuration descriptor #1 and then set
configuration #2, the device resets itself and shortly disapears
from the USB bus.

When matching VID/PID, I can prevent usbd_probe_and_attach() from reading
configuration #1.

Without matching VID/PID, usbd_probe_and_attach() will read configuration #1
to try matching all the interfaces provided by the device. But then I not
able to switch to configuration #2 anymore.

I'm quite sure this is a firmware bug and the only workaround I have
is the match by VID/PID. That still allows to match other MBIM devices
not listed in the table to be matched by Class/SubClass.

Any suggestions?

Gerhard





Re: MBIM Patch - Part 1 of 4

2016-05-30 Thread Gerhard Roth
On Sat, 28 May 2016 09:18:13 +0200 Stefan Sperling <s...@stsp.name> wrote:
> On Mon, May 23, 2016 at 03:37:32PM +0200, Gerhard Roth wrote:
> > I have this stuff around quite a while now, but since patrick@ asked
> > me repeatedly, I think it is time to share this now.
> > 
> > This is a patch that adds support for the "Mobile Broadband Interface
> > Model" (MBIM) from http://www.usb.org/. It allows to attach UMTS/LTE
> > USB devices as a network interface.
> > 
> > I'm not asking for OKs at this time, but hope that some people will
> > give it test. I tested with two different Sierra Wireless modules
> > (EM8805, MC8305) and each one behaved a little bit different.
> > 
> > In order to configure the network interface, this is what you do:
> > 
> > # ifconfig mbim0 pin 1234 apn internet.t-mobile
> > # ifconfig mbim0 inet 0.0.0.1 0.0.0.2
> > # route delete default
> > # route add -ifp mbim0 default 0.0.0.2
> > # ifconfig mbim0 up
> > 
> > The mbim interface is a point-to-point type interface and will
> > update the default route, once it is registered in the network.
> 
> As others have already said, I think the problem with these diffs
> is that you're trying to solve too many problems at once.
> 
> I believe the problems this driver should solve first and foremost are getting
> a network link and getting an IP assigned to the interface so people can use
> that IP to set up whatever routing they want.
> 
> Could mbim in theory support IPv6? We don't need to do anything about
> this now. But the design shouldn't assume it will only support IPv4.

Yes mbim does support IPv6, but the code is still missing.
I just don't have a SIM card for a provider that gives me an IPv6
address. So I could only implement it without testing.


> 
> Don't worry about breaking existing umsm(4) setups.
> Since this driver provides a much simpler user interface than umsm coupled
> with pppd(8) I'd suggest to eventually prefer attaching mbim instead of umsm
> where possible. I hate having to copy pppd config files around for umsm.
> If I lost those files I'd have to spend a day or so to get the setup working
> again because I don't remember (and don't want to remember) all the AT and
> up/down scripts I used to get umsm to work. That's why I think mbim is 
> promising.
> 
> > To get extended information on the interface use:
> > 
> > # ifconfig mbim0 devinfo
> 
> I don't see the need to add a new subcommand for this.
> If this information is important why is it not shown as part of the
> default 'ifconfig mbim0' output? If it is not important, why show it?
> 
> I agree with Theo that the ifconfig diff is too large. And it seems you're
> exposing too many details at this layer. How much of it can be removed while
> still solving the problem of getting a network link and an IP assigned?
> Can you compress status information on the 'status:' line, instead of printing
> seperate lines for data items such as pin, error state, rssi, ber and so on?
> How much of this information do users really need?

Already removed the 'devinfo' part and compressed the information onto
fewer lines. That will come with the next update of the patch.



Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Gerhard Roth

On 23.05.2016 17:47, Martin Pieuchot wrote:

On 23/05/16(Mon) 16:51, Gerhard Roth wrote:

Why do you need to set a default route in the first place?


Just like PPP this was designed as a point-to-point interface. The idea
is that once you get an uplink, all traffic should be routed through it.


Sure, my point is can you add the route *once* you get an uplink?



Ok, all of this was meant to be an intermediate solution ;)

The idea was that once the MBIM driver was accepted into the OpenBSD
kernel, the information provided by the MBIM_CID_IP_CONFIGURATION msg
would generate an extended version of the RTM_IFINFO routing message.
This message would pass the DNS server and the default gateway that
was reported by the provider up to any listeners as RTAX_DNS1,
RTAX_DNS2, and RTAX_GATEWAY.

Then I would write a daemon sitting there and listening for this kind
of routing messages and once it receives them, perform the required
actions, i.e. updating /etc/resolv.conf and/or setting the default
route.

But that was planned as a second step. The first step would be the
simple solution we have there right now. And because it would go
away later on, I didn't give it too much thought.


Gerhard



Re: MBIM Patch - Part 2 of 4

2016-05-23 Thread Gerhard Roth
On Mon, 23 May 2016 16:18:29 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> On 23/05/16(Mon) 15:38, Gerhard Roth wrote:
> > This is part 2 of the MBIM patch. It adds the mbim driver to i386
> 
> Comments inline.

Replies too.


> 
> > Index: sys/dev/usb/if_mbim.c
> > ===
> > RCS file: sys/dev/usb/if_mbim.c
> > diff -N sys/dev/usb/if_mbim.c
> > --- /dev/null   1 Jan 1970 00:00:00 -
> > +++ sys/dev/usb/if_mbim.c   23 May 2016 09:50:08 -
> > +
> > +struct cfdriver mbim_cd = {
> > +   NULL, "mbim", DV_DULL
> > +};
> > +
> > +struct cfattach mbim_ca = {
> > +   sizeof (struct mbim_softc),
> > +   mbim_match,
> > +   mbim_attach,
> > +   mbim_detach,
> > +   mbim_activate,
> > +};
> 
> This struct can be const.

Will do


> 
> > +/*
> > + * Some devices are picky about too frequent control messages.
> > + * Query device state not more often than every 0.5 secs.
> > + */
> > +struct timeval mbim_update_rate = { 0, 50 };
> > +int mbim_delay = 4000;
> > +
> > +/*
> > + * Normally, MBIM devices are detected by their interface class and 
> > subclass.
> > + * But for some models that have multiple configurations, it is better to
> > + * match by vendor and product id so that we can select the desired
> > + * configuration ourselves.
> > + *
> > + * OTOH, some devices identifiy themself als an MBIM device but fail to 
> > speak
> > + * the MBIM protocol.
> > + */
> 
> Why is it better?  This is just working around usb_probe_and_attach()
> and require developer to add an entry for every device we need to
> support.

I just thought that some modules that are already in use say with a
umsm config would otherwise change to mbim and break the setup. The idea
was to keep existing modules first as they are now and start adding
new one to the list.


> 
> > +int
> > +mbim_match(struct device *parent, void *match, void *aux)
> > +{
> > +   struct usb_attach_arg *uaa = aux;
> > +   usb_interface_descriptor_t *id;
> > +
> > +   if (usb_lookup(mbim_blacklist, uaa->vendor, uaa->product) != NULL)
> > +   return UMATCH_NONE;
> > +   if (mbim_lookup(uaa->vendor, uaa->product) != NULL)
> > +   return UMATCH_VENDOR_PRODUCT;
> > +   if (!uaa->iface)
> > +   return UMATCH_NONE;
> > +   if (!uaa->iface ||
> > +   (id = usbd_get_interface_descriptor(uaa->iface)) == NULL)
> > +   return UMATCH_NONE;
> > +   if (id->bInterfaceClass != UICLASS_CDC ||
> > +   id->bInterfaceSubClass !=
> > +   UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL ||
> > +   id->bNumEndpoints != 1)
> > +   return UMATCH_NONE;
> > +
> > +   return UMATCH_DEVCLASS_DEVSUBCLASS;
> > +}
> > +
> > +void
> > +mbim_attach(struct device *parent, struct device *self, void *aux)
> > +{
> > +   struct mbim_softc *sc = (struct mbim_softc *)self;
> > +   struct usb_attach_arg *uaa = aux;
> > +   usbd_status status;
> > +   struct usbd_desc_iter iter;
> > +   const usb_descriptor_t *desc;
> > +   int  v;
> > +   struct mbim_descriptor *md;
> > +   int  i;
> > +   struct usbd_interface *ctrl_iface = NULL;
> > +   int  ctrl_ep;
> > +   uint8_t  data_ifaceno;
> > +   usb_interface_descriptor_t *id;
> > +   usb_config_descriptor_t *cd;
> > +   usb_endpoint_descriptor_t *ed;
> > +   int  s;
> > +   struct ifnet *ifp;
> > +   int  hard_mtu;
> > +
> > +   sc->sc_udev = uaa->device;
> > +
> > +   if (uaa->configno < 0) {
> > +   uaa->configno = mbim_lookup(uaa->vendor, uaa->product)->confno;
> > +   DPRINTF("%s: switching to config #%d\n", DEVNAM(sc),
> > +   uaa->configno);
> > +   status = usbd_set_config_no(sc->sc_udev, uaa->configno, 1);
> > +   if (status) {
> > +   printf("%s: failed to switch to config #%d: %s\n",
> > +   DEVNAM(sc), uaa->configno, usbd_errstr(status));
> > +   goto fail;
> > +   }
> > +   }
> > +
> > +   sc->sc_ver_maj = sc->sc_ver_min = -1;
> > +   usbd_desc_iter_init(sc->sc_udev, );
> > +   hard_mtu = MBIM_MAXSEGSZ_MINVAL;
> > +   while ((desc = usbd_desc_iter_next())) {
> > +   if (desc->bDescriptorType != UDESC_CS_INTERFACE)
> > +  

Re: MBIM Patch - Part 1 of 4

2016-05-23 Thread Gerhard Roth
On Mon, 23 May 2016 15:54:36 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> On 23/05/16(Mon) 15:37, Gerhard Roth wrote:
> > I have this stuff around quite a while now, but since patrick@ asked
> > me repeatedly, I think it is time to share this now.
> > 
> > This is a patch that adds support for the "Mobile Broadband Interface
> > Model" (MBIM) from http://www.usb.org/. It allows to attach UMTS/LTE
> > USB devices as a network interface.
> 
> That's great!
> 
> > I'm not asking for OKs at this time, but hope that some people will
> > give it test. I tested with two different Sierra Wireless modules
> > (EM8805, MC8305) and each one behaved a little bit different.
> > 
> > In order to configure the network interface, this is what you do:
> > 
> > # ifconfig mbim0 pin 1234 apn internet.t-mobile
> 
> I'd like to bikeshed early, we're trying to prefix all new USB driver
> name with 'u'.  So I'd suggest a rename when this goes in tree.

Of course no problem. Will fix that with the next version of the patch.


> 
> > # ifconfig mbim0 inet 0.0.0.1 0.0.0.2
> > # route delete default
> > # route add -ifp mbim0 default 0.0.0.2
> > # ifconfig mbim0 up
> >
> > The mbim interface is a point-to-point type interface and will
> > update the default route, once it is registered in the network.
> 
> Can't you insert the route later instead of updating it?

Have to try. I fact this part of the code is more or less copied from
sppp_update_gw() in if_spppsubr.c


> 
> > [...] uhub.c may be needed: some modules appear at the usb bus just
> > to detach themselves again and then reappear shortly after.
> 
> Do you know why?  On which controller?

Oh, I don't think this is a problem of the controller. It's the device
itself that just detaches and re-attaches again. Guess the firmware has
a bug. Here's an example:

usbd_fill_iface_data: bad max packet size
usbd_fill_iface_data: bad max packet size
ugen2 at uhub4 port 2 "Sierra Wireless, Incorporated EM8805" rev 2.00/0.00 addr 
3
ugen2: setting configuration index 0 failed
ugen2 detached
mbim1 at uhub4 port 2 "Sierra Wireless, Incorporated EM8805" rev 2.00/0.06 addr 
3


Gerhard



MBIM Patch - Part 1 of 4

2016-05-23 Thread Gerhard Roth
I have this stuff around quite a while now, but since patrick@ asked
me repeatedly, I think it is time to share this now.

This is a patch that adds support for the "Mobile Broadband Interface
Model" (MBIM) from http://www.usb.org/. It allows to attach UMTS/LTE
USB devices as a network interface.

I'm not asking for OKs at this time, but hope that some people will
give it test. I tested with two different Sierra Wireless modules
(EM8805, MC8305) and each one behaved a little bit different.

In order to configure the network interface, this is what you do:

# ifconfig mbim0 pin 1234 apn internet.t-mobile
# ifconfig mbim0 inet 0.0.0.1 0.0.0.2
# route delete default
# route add -ifp mbim0 default 0.0.0.2
# ifconfig mbim0 up

The mbim interface is a point-to-point type interface and will
update the default route, once it is registered in the network.

To get extended information on the interface use:

# ifconfig mbim0 devinfo


The patch comes in 4 parts. This is the first part that provides
some changes required to the rest of the kernel. Esp. the change
in uhub.c may be needed: some modules appear at the usb bus just
to detach themselves again and then reappear shortly after.

After patching, please do a

# cd /sys/dev/usb
# make

to rebuild usbdevs.h and usbdevs_data.h.

In case of problems, please add

option MBIM_DEBUG

to generic and set the variable 'mbim_debug'.

Have fun,

Gerhard


Index: sys/dev/usb/uhub.c
===
RCS file: /cvs/src/sys/dev/usb/uhub.c,v
retrieving revision 1.88
diff -u -p -u -p -r1.88 uhub.c
--- sys/dev/usb/uhub.c  29 Nov 2015 16:30:48 -  1.88
+++ sys/dev/usb/uhub.c  23 May 2016 09:50:08 -
@@ -523,7 +523,9 @@ uhub_port_connect(struct uhub_softc *sc,
 {
struct usbd_port *up = >sc_hub->hub->ports[port-1];
int speed;
+   int retry = 1;
 
+again:
/* We have a connect status change, handle it. */
usbd_clear_port_feature(sc->sc_hub, port, UHF_C_PORT_CONNECTION);
 
@@ -613,6 +615,11 @@ uhub_port_connect(struct uhub_softc *sc,
 * some other serious problem.  Since we cannot leave
 * at 0 we have to disable the port instead.
 */
+   if (retry--) {
+   printf("%s: port %d: retrying\n", DEVNAME(sc), port);
+   goto again;
+   }
+
printf("%s: device problem, disabling port %d\n", DEVNAME(sc),
port);
usbd_clear_port_feature(sc->sc_hub, port, UHF_PORT_ENABLE);
Index: sys/dev/usb/usb.h
===
RCS file: /cvs/src/sys/dev/usb/usb.h,v
retrieving revision 1.54
diff -u -p -u -p -r1.54 usb.h
--- sys/dev/usb/usb.h   28 Feb 2016 17:57:50 -  1.54
+++ sys/dev/usb/usb.h   23 May 2016 09:50:08 -
@@ -508,6 +508,7 @@ typedef struct usb_port_status usb_port_
 #define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
 #define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
 #define UISUBCLASS_MOBILE_DIRECT_LINE_MODEL10
+#define UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL 14
 #define   UIPROTO_CDC_AT   1
 
 #define UICLASS_HID0x03
@@ -545,6 +546,7 @@ typedef struct usb_port_status usb_port_
 
 #define UICLASS_CDC_DATA   0x0a
 #define  UISUBCLASS_DATA   0
+#define   UIPROTO_DATA_MBIM0x02/* MBIM */
 #define   UIPROTO_DATA_ISDNBRI 0x30/* Physical iface */
 #define   UIPROTO_DATA_HDLC0x31/* HDLC */
 #define   UIPROTO_DATA_TRANSPARENT 0x32/* Transparent */
Index: sys/dev/usb/usbdevs
===
RCS file: /cvs/src/sys/dev/usb/usbdevs,v
retrieving revision 1.664
diff -u -p -u -p -r1.664 usbdevs
--- sys/dev/usb/usbdevs 20 May 2016 02:04:24 -  1.664
+++ sys/dev/usb/usbdevs 23 May 2016 09:50:08 -
@@ -3832,7 +3832,9 @@ product SIERRA AC881U 0x6856  881U
 product SIERRA AC885U  0x6880  885U
 product SIERRA C01SW   0x6890  C01SW
 product SIERRA USB305  0x68a3  USB305
+product SIERRA MC8305  0x9011  MC8305
 product SIERRA MC8355  0x9013  MC8355
+product SIERRA EM8805  0x9041  EM8805
 product SIERRA AIRCARD_770S0x9053  Aircard 770S
 
 /* Sigmatel products */
Index: sys/net/if_types.h
===
RCS file: /cvs/src/sys/net/if_types.h,v
retrieving revision 1.20
diff -u -p -u -p -r1.20 if_types.h
--- sys/net/if_types.h  7 Mar 2016 19:33:26 -   1.20
+++ sys/net/if_types.h  23 May 2016 09:50:09 -
@@ -268,5 +268,6 @@
 #defineIFT_CARP0xf7/* Common Address Redundancy 
Protocol */
 #define IFT_BLUETOOTH  0xf8/* Bluetooth */
 #define IFT_PFLOW  0xf9/* 

MBIM Patch - Part 4 of 4

2016-05-23 Thread Gerhard Roth
This is the final patch for MBIM which adds a manual page for
mbim(4).


Index: share/man/man4/Makefile
===
RCS file: /cvs/src/share/man/man4/Makefile,v
retrieving revision 1.621
diff -u -p -u -p -r1.621 Makefile
--- share/man/man4/Makefile 11 May 2016 21:52:49 -  1.621
+++ share/man/man4/Makefile 23 May 2016 09:50:08 -
@@ -33,9 +33,9 @@ MAN=  aac.4 ac97.4 acphy.4 \
ix.4 ixgb.4 jmb.4 jme.4 jmphy.4 \
kate.4 km.4 ksyms.4 kue.4 lc.4 lge.4 lii.4 lisa.4 lm.4 \
lmenv.4 lmn.4 lmtemp.4 lo.4 lpt.4 lxtphy.4 luphy.4 \
-   maestro.4 mainbus.4 malo.4 maxds.4 maxtmp.4 mbg.4 midi.4 mii.4 mfi.4 \
-   mfii.4 mlphy.4 moscom.4 mos.4 mpe.4 mpath.4 mpi.4 mpii.4 mpu.4 msk.4 \
-   mpw.4 msts.4 mtd.4 mtdphy.4 multicast.4 mtio.4 myx.4 \
+   maestro.4 mainbus.4 malo.4 maxds.4 maxtmp.4 mbg.4 mbim.4 midi.4 mii.4 \
+   mfi.4 mfii.4 mlphy.4 moscom.4 mos.4 mpe.4 mpath.4 mpi.4 mpii.4 mpu.4 \
+   msk.4 mpw.4 msts.4 mtd.4 mtdphy.4 multicast.4 mtio.4 myx.4 \
ne.4 neo.4 nep.4 netintro.4 nfe.4 nge.4 nmea.4 \
nsclpcsio.4 nsgphy.4 nsphy.4 nsphyter.4 null.4 nviic.4 nvme.4 nvt.4 \
oce.4 ohci.4 options.4 onewire.4 oosiop.4 osiop.4 otus.4 \
Index: share/man/man4/mbim.4
===
RCS file: share/man/man4/mbim.4
diff -N share/man/man4/mbim.4
--- /dev/null   1 Jan 1970 00:00:00 -
+++ share/man/man4/mbim.4   23 May 2016 09:50:08 -
@@ -0,0 +1,95 @@
+.\" Copyright (c) 2016 genua mbH
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\"- Redistributions of source code must retain the above copyright
+.\"  notice, this list of conditions and the following disclaimer.
+.\"- Redistributions in binary form must reproduce the above
+.\"  copyright notice, this list of conditions and the following
+.\"  disclaimer in the documentation and/or other materials provided
+.\"  with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $OpenBSD$
+.\"
+.Dd $Mdocdate$
+.Dt MBIM 4
+.Os
+.Sh NAME
+.Nm mbim
+.Nd USB Mobile Broadband Interface Model
+.Sh SYNOPSIS
+.Cd "mbim*  at uhub?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for USB MBIM devices. Those devices allow to
+establish connections via celluar networks such as GPRS, UMTS, LTE, etc.
+.Pp
+The
+.Nm
+device appears as a regular point-to-point network interface,
+transporting raw IP frames.
+.Pp
+Required configuration parameters like PIN and APN have to be set
+via
+.Xr ifconfig 8 .
+Once the SIM card has has been unlocked with the correct PIN, it
+will remain in this state until the device is power-cycled.
+In case the device is connected to an "always-on" USB port,
+it is possible to connect to a provider without entering the
+PIN again even afer a reboot of the system.
+.Pp
+If a default gateway route is configured for the
+.Nm
+network interface, the driver will modify the destination IP address
+dynamically, according to the information sent by the network provider.
+.Sh HARDWARE
+The following devices are known to be supported by the
+.Nm
+driver:
+.Pp
+.Bl -tag -width Ds -offset indent -compact
+.It Tn Sierra Wireless MC8305
+.It Tn Sierra Wireless EM8805
+.El
+.Pp
+There are probably a lot more devices that also work flawlessly.
+If some devices fail to provide a confirming MBIM implementation,
+their vendor and product IDs should be added to the driver's blacklist
+manually.  Since most device offer multiple interfaces, blacklisted ones
+will probably be attached by some other driver, e.g.
+.Xr umsm 4 .
+.Sh SEE ALSO
+.Xr intro 4 ,
+.Xr netintro 4 ,
+.Xr usb 4 ,
+.Xr hostname.if 5 ,
+.Xr ifconfig 8
+.Xr route 8
+.Rs
+.%T "Universal Serial Bus Communications Class Subclass Specification for 
Mobile Broadband Interface Model"
+.%U http://www.usb.org/developers/docs/devclass_docs/MBIM10Errata1_073013.zip
+.Re
+.Sh CAVEATS
+The
+.Nm
+driver currently does not support IPv6 addresses.
+.Pp
+Roaming can be prevented by the driver. 

MBIM Patch - Part 3 of 4

2016-05-23 Thread Gerhard Roth
Part 3 of the MBIM patch updates ifconfig(8).


Index: sbin/ifconfig/ifconfig.8
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.267
diff -u -p -u -p -r1.267 ifconfig.8
--- sbin/ifconfig/ifconfig.86 Apr 2016 10:07:14 -   1.267
+++ sbin/ifconfig/ifconfig.823 May 2016 09:50:08 -
@@ -519,6 +519,8 @@ tunnel
 .Xr vxlan 4 )
 .It
 .Xr vlan 4
+.It
+.Xr mbim 4
 .El
 .\" BRIDGE
 .Sh BRIDGE
@@ -1645,6 +1647,71 @@ will be assigned 802.1Q tag 5.
 Disassociate from the parent interface.
 This breaks the link between the vlan interface and its parent,
 clears its vlan tag, flags, and link address, and shuts the interface down.
+.El
+.\" MBIM
+.Sh MBIM
+.nr nS 1
+.Bk -words
+.Nm ifconfig
+.Ar mbim-interface
+.Op Cm pin Ar pin
+.Op Cm chgpin Ar oldpin Ar newpin
+.Op Cm puk Ar puk Ar newpin
+.Op Oo Fl Oc Ns Cm apn Ar apn
+.Op Oo Fl Oc Ns Cm class Ar class,class,...
+.Op Oo Fl Oc Ns Cm roaming
+.Ek
+.nr nS 0
+.Pp
+The following options are available for an
+.Xr mbim 4
+interface:
+.Bl -tag -width Ds
+.It Cm pin Ar pin
+Enter the PIN required to unlock the SIM card. Most SIM cards will not
+allow to establish a network association without providing a PIN.
+.It Cm chgpin Ar oldpin Ar newpin
+Permanently changes the PIN of the SIM card from the current value
+.Ar oldpin
+to
+.Ar newpin .
+.It Cm puk Ar puk Ar newpin
+Sets the PIN of the SIM card to
+.Ar newpin
+using the PUK
+.Ar puk
+to validate the request.
+.It Cm apn Ar apn
+Set the "Access Point Name" required by your network provider.
+.It Fl apn
+Clear the current "Access Point Name" value.
+.It Cm class
+List all available cell classes.
+.It Cm class Ar class,class,...
+Set the preferred cell classes. Apart from those listed by
+.Nm Cm class
+the following aliases can be used:
+.Ar 4G,
+.Ar 3G,
+and
+.Ar 2G.
+.It Fl class
+Clear any cell class preferences.
+.It Cm roaming
+Enable data roaming.
+.It Fl roaming
+Disable data roaming.
+.It Cm up
+As soon as the interface is marked as "up", the
+.Xr mbim 4
+device will try to establish a data connection with the service provider.
+.It Cm down
+Marking the interface as "down" will terminate any existing data connection
+and deregister with the service provider.
+.It Cm devinfo
+Provides some additional information about the
+.Xr mbim 4
+device, e.g. the IMEI number.
 .El
 .Sh EXAMPLES
 Assign the
Index: sbin/ifconfig/ifconfig.c
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.322
diff -u -p -u -p -r1.322 ifconfig.c
--- sbin/ifconfig/ifconfig.c3 May 2016 17:52:33 -   1.322
+++ sbin/ifconfig/ifconfig.c23 May 2016 09:50:08 -
@@ -107,6 +107,8 @@
 #include 
 
 #include "brconfig.h"
+#include 
+#include 
 
 #define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
 #define MAXIMUM(a, b)  (((a) > (b)) ? (a) : (b))
@@ -143,8 +145,10 @@ intLflag = 1;
 
 intshowmediaflag;
 intshowcapsflag;
+intshowdevinfoflag;
 intshownet80211chans;
 intshownet80211nodes;
+intshowclasses;
 
 void   notealias(const char *, int);
 void   setifaddr(const char *, int);
@@ -275,6 +279,19 @@ void   unsetifdesc(const char *, int);
 void   printifhwfeatures(const char *, int);
 void   setpair(const char *, int);
 void   unsetpair(const char *, int);
+void   mbim_status(void);
+void   mbim_devinfo(const char *, int);
+void   mbim_printclasses(char *, int);
+intmbim_parse_classes(const char *);
+void   mbim_setpin(const char *, int);
+void   mbim_chgpin(const char *, const char *);
+void   mbim_puk(const char *, const char *);
+void   mbim_pinop(int, int, const char *, const char *);
+void   mbim_apn(const char *, int);
+void   mbim_setclass(const char *, int);
+void   mbim_roaming(const char *, int);
+void   utf16_to_char(uint16_t *, int, char *, size_t);
+intchar_to_utf16(const char *, uint16_t *, size_t);
 #else
 void   setignore(const char *, int);
 #endif
@@ -486,6 +503,16 @@ const struct   cmd {
{ "-descr", 1,  0,  unsetifdesc },
{ "wol",IFXF_WOL,   0,  setifxflags },
{ "-wol",   -IFXF_WOL,  0,  setifxflags },
+   { "devinfo",NEXTARG0,   0,  mbim_devinfo },
+   { "pin",NEXTARG,0,  mbim_setpin },
+   { "chgpin", NEXTARG2,   0,  NULL, mbim_chgpin },
+   { "puk",NEXTARG2,   0,  NULL, mbim_puk },
+   { "apn",NEXTARG,0,  mbim_apn },
+   { "-apn",   -1, 0,  mbim_apn },
+   { "class",  NEXTARG0,   0,  mbim_setclass },
+   { "-class", -1, 0,  mbim_setclass },
+   { "roaming",1,  0,  mbim_roaming },
+   { "-roaming",   0,  0,  

MBIM Patch - Part 2 of 4

2016-05-23 Thread Gerhard Roth
This is part 2 of the MBIM patch. It adds the mbim driver to i386
and amd64 kernels.


Index: sys/arch/amd64/conf/GENERIC
===
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.418
diff -u -p -u -p -r1.418 GENERIC
--- sys/arch/amd64/conf/GENERIC 7 May 2016 23:10:50 -   1.418
+++ sys/arch/amd64/conf/GENERIC 23 May 2016 09:50:08 -
@@ -279,6 +279,7 @@ urtw*   at uhub?# Realtek 8187
 rsu*   at uhub?# Realtek RTL8188SU/RTL8191SU/RTL8192SU
 urtwn* at uhub?# Realtek RTL8188CU/RTL8192CU
 udcf*  at uhub?# Gude Expert mouseCLOCK
+mbim*  at uhub?# Mobile Broadband Interface Model
 uthum* at uhidev?  # TEMPerHUM sensor
 ugold* at uhidev?  # gold TEMPer sensor
 utrh*  at uhidev?  # USBRH sensor
Index: sys/arch/i386/conf/GENERIC
===
RCS file: /cvs/src/sys/arch/i386/conf/GENERIC,v
retrieving revision 1.814
diff -u -p -u -p -r1.814 GENERIC
--- sys/arch/i386/conf/GENERIC  24 Apr 2016 17:30:31 -  1.814
+++ sys/arch/i386/conf/GENERIC  23 May 2016 09:50:08 -
@@ -14,6 +14,9 @@ include   "../../../conf/GENERIC"
 maxusers   80  # estimated number of users
 
 option USER_PCICONF# user-space PCI configuration
+option USB_DEBUG
+#optionUHUB_DEBUG
+option EHCI_DEBUG
 
 #optionVM86# Virtual 8086 emulation
 option KVM86   # Kernel Virtual 8086 emulation
@@ -314,6 +317,7 @@ rsu*at uhub?# Realtek 
RTL8188SU/RTL81
 urtwn* at uhub?# Realtek RTL8188CU/RTL8192CU
 udcf*  at uhub?# Gude Expert mouseCLOCK
 umbg*  at uhub?# Meinberg Funkuhren USB5131
+mbim*  at uhub?# Mobile Broadband Interface Model
 uthum* at uhidev?  # TEMPerHUM sensor
 ugold* at uhidev?  # gold TEMPer sensor
 utrh*  at uhidev?  # USBRH sensor
Index: sys/dev/usb/files.usb
===
RCS file: /cvs/src/sys/dev/usb/files.usb,v
retrieving revision 1.126
diff -u -p -u -p -r1.126 files.usb
--- sys/dev/usb/files.usb   8 Jan 2016 15:54:13 -   1.126
+++ sys/dev/usb/files.usb   23 May 2016 09:50:08 -
@@ -397,6 +397,11 @@ device otus: ether, ifnet, ifmedia, wlan
 attach otus at uhub
 file   dev/usb/if_otus.c   otus
 
+# Mobile Broadband Interface Model
+device mbim: ifnet, ifmedia
+attach mbim at uhub
+file   dev/usb/if_mbim.c   mbim
+
 # USB logical device
 device usbf {}
 attach usbf at usbdev
Index: sys/dev/usb/if_mbim.c
===
RCS file: sys/dev/usb/if_mbim.c
diff -N sys/dev/usb/if_mbim.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ sys/dev/usb/if_mbim.c   23 May 2016 09:50:08 -
@@ -0,0 +1,2487 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2016 genua mbH
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Mobile Broadband Interface Model
+ * http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf
+ */
+#include "bpfilter.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#if NBPFILTER > 0
+#include 
+#endif
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#ifdef MBIM_DEBUG
+#define DPRINTF(x...)  \
+   do { if (mbim_debug) log(LOG_DEBUG, x); } while (0)
+
+#define DPRINTFN(n, x...)  \
+   do { if (mbim_debug >= (n)) log(LOG_DEBUG, x); } while (0)
+
+#define DDUMPN(n, b, l)
\
+   do {\
+   if (mbim_debug >= (n))  \
+   

snmpd: some values need casting

2016-01-28 Thread Gerhard Roth
Hi,

ber_add_integer() can ASN.1 encode integers of up to 64 bit. Yet for
some types (e.g. SNMP_T_TIMETICKS, SNMP_T_GAUGE32, ..) the MIB says that
the value must no exceed 2^32-1. We should cast the value to u_int32_t
to avoid that e.g. Gauge32 carries a value larger than 32 bit.

One special thing is the interface baud rate, where the MIB in RFC 2863
states that the value should be truncated to 4,294,967,295 in case it is
"greater than the maximum value reportable by this object".


Gerhard


Index: usr.sbin/snmpd/mib.c
===
RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.80
diff -u -p -u -p -r1.80 mib.c
--- usr.sbin/snmpd/mib.c17 Nov 2015 12:30:23 -  1.80
+++ usr.sbin/snmpd/mib.c28 Jan 2016 12:19:01 -
@@ -155,7 +155,7 @@ mib_getsys(struct oid *oid, struct ber_o
break;
case 3:
ticks = smi_getticks();
-   *elm = ber_add_integer(*elm, ticks);
+   *elm = ber_add_integer(*elm, (u_int32_t)ticks);
ber_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
break;
case 4:
@@ -463,7 +463,8 @@ mib_hrsystemuptime(struct oid *oid, stru
if (sysctl(mib, 2, , , NULL, 0) == -1)
return (-1);
 
-   *elm = ber_add_integer(*elm, (now - boottime.tv_sec) * 100);
+   *elm = ber_add_integer(*elm,
+   (u_int32_t)((now - boottime.tv_sec) * 100));
ber_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
 
return (0);
@@ -1079,6 +1080,7 @@ mib_iftable(struct oid *oid, struct ber_
size_t   len;
int  ifq;
int  mib[] = { CTL_NET, PF_INET, IPPROTO_IP, 0, 0 };
+   u_int32_tbaudrate;
 
/* Get and verify the current row index */
idx = o->bo_id[OIDIDX_ifEntry];
@@ -1115,7 +1117,11 @@ mib_iftable(struct oid *oid, struct ber_
ber = ber_add_integer(ber, kif->if_mtu);
break;
case 5:
-   ber = ber_add_integer(ber, kif->if_baudrate);
+   if (kif->if_baudrate <= UINT32_MAX)
+   baudrate = kif->if_baudrate;
+   else
+   baudrate = UINT32_MAX;
+   ber = ber_add_integer(ber, baudrate);
ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
break;
case 6:
@@ -1145,7 +1151,7 @@ mib_iftable(struct oid *oid, struct ber_
ber = ber_add_integer(ber, i);
break;
case 9:
-   ber = ber_add_integer(ber, kif->if_ticks);
+   ber = ber_add_integer(ber, (u_int32_t)kif->if_ticks);
ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
break;
case 10:
@@ -1328,7 +1334,7 @@ int
 mib_ifstacklast(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
 {
struct ber_element  *ber = *elm;
-   ber = ber_add_integer(ber, kr_iflastchange());
+   ber = ber_add_integer(ber, (u_int32_t)kr_iflastchange());
ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
return (0);
 }
@@ -1667,7 +1673,7 @@ mib_pfinfo(struct oid *oid, struct ber_o
else
runtime = 0;
runtime *= 100;
-   *elm = ber_add_integer(*elm, runtime);
+   *elm = ber_add_integer(*elm, (u_int32_t)runtime);
ber_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
break;
case 3:
@@ -2168,7 +2174,7 @@ mib_pftables(struct oid *oid, struct ber
break;
case 20:
tzero = (time(NULL) - ts.pfrts_tzero) * 100;
-   ber = ber_add_integer(ber, tzero);
+   ber = ber_add_integer(ber, (u_int32_t)tzero);
ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
break;
case 21:
@@ -2224,7 +2230,8 @@ mib_pftableaddrs(struct oid *oid, struct
ber = ber_add_integer(ber, as.pfras_a.pfra_net);
break;
case 4:
-   ber = ber_add_integer(ber, (time(NULL) - as.pfras_tzero) * 100);
+   ber = ber_add_integer(ber,
+   (u_int32_t)((time(NULL) - as.pfras_tzero) * 100));
ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
break;
case 5:
@@ -3044,7 +3051,8 @@ mib_ipstat(struct oid *oid, struct ber_o
for (i = 0;
(u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
if (oid->o_oid[OIDIDX_ip] == mapping[i].m_id) {
-   *elm = ber_add_integer(*elm, *mapping[i].m_ptr);
+   *elm = ber_add_integer(*elm,
+   (u_int32_t)*mapping[i].m_ptr);
ber_set_header(*elm,
 

Exclude invalid sensors from the sensors MIB

2015-11-17 Thread Gerhard Roth
Sensors marked as invalid should be excluded by snmpd(8) from the sensors
MIB just as sysctl(8) excludes them from the 'hw.sensors' tree.

Gerhard


Index: usr.sbin/snmpd/mib.c
===
RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.79
diff -u -p -u -p -r1.79 mib.c
--- usr.sbin/snmpd/mib.c8 Oct 2015 08:29:21 -   1.79
+++ usr.sbin/snmpd/mib.c17 Nov 2015 10:39:31 -
@@ -2556,7 +2556,7 @@ mib_sensors(struct oid *oid, struct ber_
}
for (j = 0; j < SENSOR_MAX_TYPES; j++) {
mib[3] = j;
-   for (k = 0; k < sensordev.maxnumt[j]; k++, n++) {
+   for (k = 0; k < sensordev.maxnumt[j]; k++) {
mib[4] = k;
if (sysctl(mib, 5,
, , NULL, 0) == -1) {
@@ -2566,8 +2566,11 @@ mib_sensors(struct oid *oid, struct ber_
break;
return (-1);
}
+   if (sensor.flags & SENSOR_FINVALID)
+   continue;
if (n == idx)
goto found;
+   n++;
}
}
}



snmpd loses ARP table information

2015-11-02 Thread Gerhard Roth
Hi,

snmpd pernanently loses its ARP table information:

# snmpctl walk 127.0.0.1 oid ipNetToMediaPhysAddress
ipNetToMediaPhysAddress.2.192.168.16.1="xx:xx:xx:xx:xx:xx"
ipNetToMediaPhysAddress.2.192.168.16.126="xx:xx:xx:xx:xx:xx"
ipNetToMediaPhysAddress.2.192.168.19.132="xx:xx:xx:xx:xx:xx"

Query the whole tree and this information is gone:

# snmpctl walk 127.0.0.1 oid iso.org>/dev/null
# snmpctl walk 127.0.0.1 oid ipNetToMediaPhysAddress
0=6

The reason is that several OIDs in mib.c call kr_updateif()
and this function deletes the kif_node and the restores it
via fetchifs(). But then the ARP information held by the
old kif_node is gone.

There is no need to delete the kif_node prior to calling
fetchifs() since it only calls rtmsg_process() which is
also called during normal processing of messages from the
routing socket.

And while here, also handle RTM_DESYNC messages.

Gerhard


Index: usr.sbin/snmpd/kroute.c
===
RCS file: /cvs/src/usr.sbin/snmpd/kroute.c,v
retrieving revision 1.31
diff -u -p -u -p -r1.31 kroute.c
--- usr.sbin/snmpd/kroute.c 18 Jul 2015 00:27:32 -  1.31
+++ usr.sbin/snmpd/kroute.c 2 Nov 2015 11:41:51 -
@@ -365,12 +365,6 @@ kr_iflastchange(void)
 int
 kr_updateif(u_int if_index)
 {
-   struct kif_node *kn;
-
-   if ((kn = kif_find(if_index)) != NULL)
-   kif_remove(kn);
-
-   /* Do not update the interface address list */
return (fetchifs(if_index));
 }
 
@@ -1380,6 +1374,12 @@ rtmsg_process(char *buf, int len)
break;
case RTM_IFANNOUNCE:
if_announce(next);
+   break;
+   case RTM_DESYNC:
+   kr_shutdown();
+   if (fetchifs(0) == -1)
+   fatalx("rtmsg_process: fetchifs");
+   ktable_init();
break;
default:
/* ignore for now */



Fix for handling SNMP GETBULK Requests

2015-06-08 Thread Gerhard Roth
Hi,

there's a bug in snmpd that breaks GETBULK requests for multiple OIDs.

Example:

   # OID1=1.3.6.1.2.1.1.1
   # OID2=1.3.6.1.2.1.31.1.1.1.1
   # snmpbulkget -Cr3 -c public -v2c localhost $OID1
   SNMPv2-MIB::sysDescr.0 = STRING: OpenBSD null 5.7 GENERIC#123 i386
   SNMPv2-MIB::sysObjectID.0 = OID: OPENBSD-BASE-MIB::openBSDDefaultObjectID
   SNMPv2-MIB::sysUpTime.0 = Timeticks: (68096) 0:11:20.96
   # snmpbulkget -Cr3 -c public -v2c localhost $OID2
   IF-MIB::ifName.1 = STRING: em0
   IF-MIB::ifName.2 = STRING: iwi0
   IF-MIB::ifName.3 = STRING: enc0
   # snmpbulkget -Cr3 -c public -v2c localhost $OID1 $OID2
   SNMPv2-MIB::sysDescr.0 = STRING: OpenBSD null 5.7 GENERIC#123 i386
   IF-MIB::ifName.1 = STRING: em0
   IF-MIB::ifName.2 = STRING: iwi0
   IF-MIB::ifName.3 = STRING: enc0


Each query for a single OID delivers three repetitions (as requested by
-Cr3). But the query for two OIDs skips the repetitions for the first
one. If we add more OIDs, only the last OID of the query will have
repetitions in the reply.

The reason is that we must link the result of each mps_getbulkreq()
to the end of the previous list and not the start of it.

With the patch below, we get the desired result:

   # snmpbulkget -Cr3 -c public -v2c localhost $OID1 $OID2
   SNMPv2-MIB::sysDescr.0 = STRING: OpenBSD null 5.7 GENERIC#123 i386
   SNMPv2-MIB::sysObjectID.0 = OID: OPENBSD-BASE-MIB::openBSDDefaultObjectID
   SNMPv2-MIB::sysUpTime.0 = Timeticks: (239) 0:00:02.39
   IF-MIB::ifName.1 = STRING: em0
   IF-MIB::ifName.2 = STRING: iwi0
   IF-MIB::ifName.3 = STRING: enc0


Gerhard



Index: mps.c
===
RCS file: /cvs/src/usr.sbin/snmpd/mps.c,v
retrieving revision 1.20
diff -u -p -u -p -r1.20 mps.c
--- mps.c   16 Jan 2015 00:05:13 -  1.20
+++ mps.c   3 Jun 2015 08:48:42 -
@@ -289,7 +289,7 @@ mps_getnextreq(struct snmp_message *msg,
 
 int
 mps_getbulkreq(struct snmp_message *msg, struct ber_element **root,
-struct ber_oid *o, int max)
+struct ber_element **end, struct ber_oid *o, int max)
 {
struct ber_element *c, *d, *e;
size_t len;
@@ -297,14 +297,17 @@ mps_getbulkreq(struct snmp_message *msg,
 
j = max;
c = *root;
+   *end = NULL;
 
for (d = NULL, len = 0; j  0; j--) {
e = ber_add_sequence(NULL);
if (c == NULL)
c = e;
ret = mps_getnextreq(msg, e, o);
-   if (ret == 1)
+   if (ret == 1) {
+   *root = c;
return (1);
+   }
if (ret == -1) {
ber_free_elements(e);
if (d == NULL)
@@ -319,6 +322,7 @@ mps_getbulkreq(struct snmp_message *msg,
if (d != NULL)
ber_link_elements(d, e);
d = e;
+   *end = d;
}
 
*root = c;
Index: snmpd.h
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
retrieving revision 1.59
diff -u -p -u -p -r1.59 snmpd.h
--- snmpd.h 16 Jan 2015 00:05:13 -  1.59
+++ snmpd.h 3 Jun 2015 09:02:38 -
@@ -396,6 +396,7 @@ struct snmp_message {
struct ber_element  *sm_c;
struct ber_element  *sm_next;
struct ber_element  *sm_last;
+   struct ber_element  *sm_end;
 
u_int8_t sm_data[READ_BUF_SIZE];
size_t   sm_datalen;
@@ -638,7 +639,7 @@ int  mps_getreq(struct snmp_message *, 
 int mps_getnextreq(struct snmp_message *, struct ber_element *,
struct ber_oid *);
 int mps_getbulkreq(struct snmp_message *, struct ber_element **,
-   struct ber_oid *, int);
+   struct ber_element **, struct ber_oid *, int);
 int mps_setreq(struct snmp_message *, struct ber_element *,
struct ber_oid *);
 int mps_set(struct ber_oid *, void *, long long);
Index: snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.40
diff -u -p -u -p -r1.40 snmpe.c
--- snmpe.c 16 Jan 2015 00:05:13 -  1.40
+++ snmpe.c 3 Jun 2015 09:06:31 -
@@ -374,6 +374,7 @@ snmpe_parsevarbinds(struct snmp_message 
break;
case 1:
msg-sm_c = NULL;
+   msg-sm_end = NULL;
 
switch (msg-sm_context) {
 
@@ -409,7 +410,8 @@ snmpe_parsevarbinds(struct snmp_message 
 
case SNMP_C_GETBULKREQ:
ret = mps_getbulkreq(msg, msg-sm_c,
-   o, msg-sm_maxrepetitions);
+   msg-sm_end, 

Re: cdce(4) and MBIM

2015-01-21 Thread Gerhard Roth
Hi Ingo,

sorry to disappoint you, but that won't work. First of all, if_cdce.c doesn't
do NCM encoding and second, even if it did this still wouldn't work because
it just describes how data packets are encapsulated. But to talk to an MBIM
device, you need a different set of control messages (e.g. to set the PIN,
to tell the device to connect to the network, etc.)

I'm currently working on an MBIM driver for OpenBSD, but it will take some
more time until it's ready for sending out patches.

Gerhard


On Tue, 20 Jan 2015 23:31:17 +0100 Ingo Feinerer feine...@logic.at wrote:
 Has anyone experiences with USB devices (e.g. UMTS modem) offering
 Mobile Broadband Interface Model (MBIM) interfaces?
 
 According to
 www.usb.org/developers/docs/devclass_docs/MBIM10Errata1_073013.zip MBIM
 is comparable to NCM (The largest deviation from NCM 1.0 is that
 devices transfer raw IP packets instead of packets with 802.3 headers.)
 which is supported by cdce(4).
 
 By hardcoding vendor and device ID in sys/dev/usb/if_cdce.c I managed to
 have a modem with MBIM interface attach via cdce:
 
 cdce0 at uhub0 port 4 configuration 1 interface 0 MediaTek Inc Product rev 
 2.00/3.00 addr 2
 cdce0: address XX:XX:XX:XX:XX:XX
 
 ifconfig appears to work as well
 
 cdce0: flags=8802BROADCAST,SIMPLEX,MULTICAST mtu 1500
 lladdr XX:XX:XX:XX:XX:XX
 priority: 0
 
 but dhclient gets no response. /var/log/messages contains
 
 cdce0: watchdog timeout
 cdce0: usb error on tx: TIMEOUT
 
 Any ideas?
 
 Best regards,
 Ingo
 



Re: run(4) firmware update; please test

2014-05-16 Thread Gerhard Roth
On Fri, 16 May 2014 13:07:24 +0200 Stefan Sperling s...@openbsd.org wrote:
 On Fri, May 16, 2014 at 02:44:10PM +0400, Dinar Talypov wrote:
  Hi,
  
  I have tested with D-Link  DWA-140 rev B2G:
  
  run0 at uhub0 port 1 Ralink 11n Adapter rev 1.10/1.01 addr 2
  run0: MAC/BBP RT3071 (rev 0x021C), RF RT3022 (MIMO 2T2R), address
  14:d6:4d:49:73:4e
  
  with this diff nothing works. It doesn't find any access point.
 
 Are you able to help me debug this by providing more details?
 
 Are you really sure it's the firmware update that's causing the problem?
 
 Are you able to try your run(4) device with FreeBSD-current (10 isn't
 new enough)? They claim to support your device and use the updated firmware.
 


He's using a model that requires a firmware-blob different from the one
of all other testers (run-rt2870 vs. run-rt3071). That might explain,
why he's the only one who got troubles with the new FW.

On topic: new FW works fine on a SparkLAN WPER-150GN:

   run0 at uhub1 port 3 Ralink 802.11 n WLAN rev 2.00/1.01 addr 3
   run0: MAC/BBP RT3070 (rev 0x0201), RF RT3020 (MIMO 1T1R), address 
00:0e:8e:xx:xx:xx



pf dropping window updates and acks

2013-10-11 Thread Gerhard Roth
In January bluhm@ introduced 'data_end' to pf.c:tcp_track_full().
Now this breaks the handling of non-data packets. They may be rejected
because the SEQ_GEQ(src-seqhi, data_end) check fails.

The patch below should fix this.

Gerhard



Index: sys/net/pf.c
===
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.841
diff -u -p -u -p -r1.841 pf.c
--- sys/net/pf.c9 Oct 2013 09:32:01 -   1.841
+++ sys/net/pf.c11 Oct 2013 09:57:20 -
@@ -3940,7 +3940,7 @@ pf_tcp_track_full(struct pf_pdesc *pd, s
if (seq == end) {
/* Ease sequencing restrictions on no data packets */
seq = src-seqlo;
-   end = seq;
+   data_end = end = seq;
}
 
ackskew = dst-seqlo - ack;



Fw: SNMPv3 engine id discovery

2013-09-09 Thread Gerhard Roth
Anybody willing to ok that patch?

Gerhard


Begin forwarded message:

Date: Fri, 16 Aug 2013 10:24:02 +0200
From: Gerhard Roth gr...@genua.de
To: tech@openbsd.org
Subject: SNMPv3 engine id discovery


Hi,

in SNMPv3 engine id discovery is done by sending a noAuthNoPriv request
to the SNMP agent. The agent should reply with a usmStatsUnknownEngineIDs
report containing the authoritative engine id.

In case snmpd was configured with a minimum seclevel higher than none,
a usmStatsUnsupportedSecLevels report was generated instead.

The fix below delays checking the required seclevel until after engine
id discovery has been handled.

Ok?

Gerhard



Index: usr.sbin/snmpd/snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.33
diff -u -p -u -p -r1.33 snmpe.c
--- usr.sbin/snmpd/snmpe.c  29 Mar 2013 12:53:41 -  1.33
+++ usr.sbin/snmpd/snmpe.c  16 Aug 2013 08:05:19 -
@@ -530,8 +530,7 @@ snmpe_parse(struct sockaddr_storage *ss,
goto parsefail;
 
msg-sm_flags = *flagstr;
-   if (MSG_SECLEVEL(msg)  env-sc_min_seclevel ||
-   msg-sm_secmodel != SNMP_SEC_USM) {
+   if (msg-sm_secmodel != SNMP_SEC_USM) {
/* XXX currently only USM supported */
errstr = unsupported security model;
stats-snmp_usmbadseclevel++;
Index: usr.sbin/snmpd/usm.c
===
RCS file: /cvs/src/usr.sbin/snmpd/usm.c,v
retrieving revision 1.6
diff -u -p -u -p -r1.6 usm.c
--- usr.sbin/snmpd/usm.c24 Jan 2013 09:30:27 -  1.6
+++ usr.sbin/snmpd/usm.c16 Aug 2013 08:05:19 -
@@ -287,6 +287,13 @@ usm_decode(struct snmp_message *msg, str
msg-sm_engine_boots = (u_int32_t)engine_boots;
msg-sm_engine_time = (u_int32_t)engine_time;
 
+   if (MSG_SECLEVEL(msg)  env-sc_min_seclevel) {
+   *errp = security level too low;
+   msg-sm_usmerr = OIDVAL_usmErrSecLevel;
+   stats-snmp_usmbadseclevel++;
+   goto done;
+   }
+
memcpy(msg-sm_username, user, userlen);
msg-sm_username[userlen] = '\0';
msg-sm_user = usm_finduser(msg-sm_username);



SNMPv3 engine id discovery

2013-08-16 Thread Gerhard Roth
Hi,

in SNMPv3 engine id discovery is done by sending a noAuthNoPriv request
to the SNMP agent. The agent should reply with a usmStatsUnknownEngineIDs
report containing the authoritative engine id.

In case snmpd was configured with a minimum seclevel higher than none,
a usmStatsUnsupportedSecLevels report was generated instead.

The fix below delays checking the required seclevel until after engine
id discovery has been handled.

Ok?

Gerhard



Index: usr.sbin/snmpd/snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.33
diff -u -p -u -p -r1.33 snmpe.c
--- usr.sbin/snmpd/snmpe.c  29 Mar 2013 12:53:41 -  1.33
+++ usr.sbin/snmpd/snmpe.c  16 Aug 2013 08:05:19 -
@@ -530,8 +530,7 @@ snmpe_parse(struct sockaddr_storage *ss,
goto parsefail;
 
msg-sm_flags = *flagstr;
-   if (MSG_SECLEVEL(msg)  env-sc_min_seclevel ||
-   msg-sm_secmodel != SNMP_SEC_USM) {
+   if (msg-sm_secmodel != SNMP_SEC_USM) {
/* XXX currently only USM supported */
errstr = unsupported security model;
stats-snmp_usmbadseclevel++;
Index: usr.sbin/snmpd/usm.c
===
RCS file: /cvs/src/usr.sbin/snmpd/usm.c,v
retrieving revision 1.6
diff -u -p -u -p -r1.6 usm.c
--- usr.sbin/snmpd/usm.c24 Jan 2013 09:30:27 -  1.6
+++ usr.sbin/snmpd/usm.c16 Aug 2013 08:05:19 -
@@ -287,6 +287,13 @@ usm_decode(struct snmp_message *msg, str
msg-sm_engine_boots = (u_int32_t)engine_boots;
msg-sm_engine_time = (u_int32_t)engine_time;
 
+   if (MSG_SECLEVEL(msg)  env-sc_min_seclevel) {
+   *errp = security level too low;
+   msg-sm_usmerr = OIDVAL_usmErrSecLevel;
+   stats-snmp_usmbadseclevel++;
+   goto done;
+   }
+
memcpy(msg-sm_username, user, userlen);
msg-sm_username[userlen] = '\0';
msg-sm_user = usm_finduser(msg-sm_username);



dhcpd uses bad current time

2013-05-15 Thread Gerhard Roth
In dhcpd, variable cur_time is set only once per dispatch loop.
Unfortunately, this is done before the poll(2) call. Since poll(2)
may sleep for an arbitrary amount of time, the value of cur_time
might refer to some long ago point in time. When message dispatching
is done, timeouts and lease ends are calculated based on this
outdated cur_time value that was set before the call to poll(2).

It's fine to set cur_time only once per loop, but we should do it after
the blocking poll(2) syscall so that its value is more accurate.

ok?

Gerhard



Index: usr.sbin/dhcpd/dispatch.c
===
RCS file: /cvs/src/usr.sbin/dhcpd/dispatch.c,v
retrieving revision 1.30
diff -u -p -r1.30 dispatch.c
--- usr.sbin/dhcpd/dispatch.c   19 Apr 2013 21:25:39 -  1.30
+++ usr.sbin/dhcpd/dispatch.c   15 May 2013 08:09:17 -
@@ -306,8 +306,6 @@ dispatch(void)
 * still a timeout registered, time out the poll
 * call then.
 */
-   time(cur_time);
-another:
if (timeouts) {
if (timeouts-when = cur_time) {
struct dhcpd_timeout *t = timeouts;
@@ -315,7 +313,7 @@ another:
(*(t-func))(t-what);
t-next = free_timeouts;
free_timeouts = t;
-   goto another;
+   continue;
}
 
/*
@@ -360,6 +358,7 @@ another:
case 0:
continue;   /* no packets */
}
+   time(cur_time);
 
for (i = 0, l = protocols; l; l = l-next) {
struct interface_info *ip = l-local;



Re: dhcpd uses bad current time

2013-05-15 Thread Gerhard Roth
On Wed, 15 May 2013 10:15:54 +0200
Gerhard Roth gr...@genua.de wrote:

 In dhcpd, variable cur_time is set only once per dispatch loop.
 Unfortunately, this is done before the poll(2) call. Since poll(2)
 may sleep for an arbitrary amount of time, the value of cur_time
 might refer to some long ago point in time. When message dispatching
 is done, timeouts and lease ends are calculated based on this
 outdated cur_time value that was set before the call to poll(2).
 
 It's fine to set cur_time only once per loop, but we should do it after
 the blocking poll(2) syscall so that its value is more accurate.
 
 ok?
 
 Gerhard
 


Sorry, the previous version will break timeout handling when there
are no incoming packets. I notice the moment that I sent the mail.

So let's keep all the old code and just add another update of cur_time
after poll(2).

Gerhard


Index: usr.sbin/dhcpd/dispatch.c
===
RCS file: /cvs/src/usr.sbin/dhcpd/dispatch.c,v
retrieving revision 1.30
diff -u -p -r1.30 dispatch.c
--- usr.sbin/dhcpd/dispatch.c   19 Apr 2013 21:25:39 -  1.30
+++ usr.sbin/dhcpd/dispatch.c   15 May 2013 08:26:49 -
@@ -360,6 +360,7 @@ another:
case 0:
continue;   /* no packets */
}
+   time(cur_time);
 
for (i = 0, l = protocols; l; l = l-next) {
struct interface_info *ip = l-local;



Re: dhcpd uses bad current time

2013-05-15 Thread Gerhard Roth
On Wed, 15 May 2013 10:24:22 +0200 Otto Moerbeek o...@drijf.net wrote:
 On Wed, May 15, 2013 at 10:15:54AM +0200, Gerhard Roth wrote:
 
  In dhcpd, variable cur_time is set only once per dispatch loop.
  Unfortunately, this is done before the poll(2) call. Since poll(2)
  may sleep for an arbitrary amount of time, the value of cur_time
  might refer to some long ago point in time. When message dispatching
  is done, timeouts and lease ends are calculated based on this
  outdated cur_time value that was set before the call to poll(2).
  
  It's fine to set cur_time only once per loop, but we should do it after
  the blocking poll(2) syscall so that its value is more accurate.
  
  ok?
  
  Gerhard
 
 I don't think the first call to time() should be left out. cur_time is
 potentially used in the first iteration of the loop. 
 

Well, it is set in main(), so it is initialized. But nevertheless you're
that we should keep it because it is required for correct timeout
handling if there are no incoming packets.

Just sent out a second diff that keeps the time(2) call at the top
of the loop.

Gerhard



Re: check for device_lookup result in vscsi

2013-05-10 Thread Gerhard Roth
Mike,

but it does check in vscsiopen(). Hence no userland program should be
able to call vscsiioctl() for a non-existant device because the open()
already failed. At least that's true as long as vscsi devices can't
disappear during run-time.

Gerhard


On Fri, 10 May 2013 14:44:39 +0200 Mike Belopuhov m...@belopuhov.com wrote:
 On Fri, May 03, 2013 at 16:19 +0200, Mike Belopuhov wrote:
  hi,
  
  while looking for the device_unref bugs, i found that
  vscsi doesn't check if device_lookup has returned a
  valid return value.
  
  ok?
  
 
 anyone?
 
  diff --git sys/dev/vscsi.c sys/dev/vscsi.c
  index 3da371c..db65642 100644
  --- sys/dev/vscsi.c
  +++ sys/dev/vscsi.c
  @@ -296,6 +296,9 @@ vscsiioctl(dev_t dev, u_long cmd, caddr_t addr, int 
  flags, struct proc *p)
  int read = 0;
  int err = 0;
   
  +   if (sc == NULL)
  +   return (ENXIO);
  +
  rw_enter_write(sc-sc_ioc_lock);
   
  switch (cmd) {
  @@ -476,6 +479,9 @@ vscsipoll(dev_t dev, int events, struct proc *p)
  struct vscsi_softc  *sc = DEV2SC(dev);
  int revents = 0;
   
  +   if (sc == NULL)
  +   return (ENXIO);
  +
  if (events  (POLLIN | POLLRDNORM)) {
  mtx_enter(sc-sc_state_mtx);
  if (!TAILQ_EMPTY(sc-sc_ccb_i2t))
  @@ -494,9 +500,14 @@ vscsipoll(dev_t dev, int events, struct proc *p)
   
   int
   vscsikqfilter(dev_t dev, struct knote *kn)
  -{ 
  +{
  struct vscsi_softc *sc = DEV2SC(dev);
  -   struct klist *klist = sc-sc_sel.si_note;
  +   struct klist *klist;
  +
  +   if (sc == NULL)
  +   return (ENXIO);
  +
  +   klist = sc-sc_sel.si_note;
   
  switch (kn-kn_filter) {
  case EVFILT_READ:
 




Re: Add Soekris comBIOS detection to bios(4) on i386/amd64

2013-03-04 Thread Gerhard Roth
On Mon, 4 Mar 2013 06:02:19 -0500 Matt Dainty m...@bodgit-n-scarper.com wrote:
 * Matt Dainty m...@bodgit-n-scarper.com [2013-02-20 19:30:43]:
  Attached are two patches for bios(4) on i386  amd64 that add support
  for detecting the comBIOS on Soekris hardware, which then fills in the
  hw.vendor  hw.product sysctl variables as this hardware lacks any
  SMBIOS to provide them. The idea is then these can be used in the
  GPIO/LED driver for the net6501 I posted a while ago to simplify the
  match logic.
  
  I've tested this with a net6501  amd64 so I would appreciate testing
  on any other Soekris hardware under i386; net4501, net4801  net5501.
 
 I'm lacking a test report for a net4801, however as I've had reports
 of success for all other Soekris board types, I'd be surprised if it
 didn't work.

Hi,

I can confirm that your patch works for i386 on net4501:

# sysctl hw
hw.machine=i386
hw.model=Geode(TM) Integrated Processor by National Semi (Geode by NSC 
586-class)
hw.ncpu=1
hw.byteorder=1234
hw.pagesize=4096
...
hw.cpuspeed=267
hw.vendor=Soekris Engineering
hw.product=net4801
hw.version=1
hw.physmem=133754880
hw.usermem=133742592
hw.ncpufound=1
hw.allowpowerdown=1

Gerhard

 
  Also any other hardware that lacks SMBIOS and in the case of i386
  doesn't need to disable probing of SMBIOS with flags 0x0008.
 
 I would still appreciate some testing on other systems that lack any
 SMBIOS, just to make sure it doesn't cause problems there. However as
 this code walks over the same area of memory, I would again be
 surprised if this caused problems when the SMBIOS probe didn't.
 
 Matt
 
  --- sys/arch/amd64/amd64/bios.c.origTue Feb 19 01:56:56 2013
  +++ sys/arch/amd64/amd64/bios.c Wed Feb 20 08:37:12 2013
  @@ -95,6 +95,7 @@
  vaddr_t va;
  paddr_t pa, end;
  u_int8_t *p;
  +   int smbiosrev = 0;
   
  /* see if we have SMBIOS extentions */
  for (p = ISA_HOLE_VADDR(SMBIOS_START);
  @@ -137,6 +138,10 @@
  printf(: SMBIOS rev. %d.%d @ 0x%lx (%d entries),
  hdr-majrev, hdr-minrev, hdr-addr, hdr-count);
   
  +   smbiosrev = hdr-majrev * 100 + hdr-minrev;
  +   if (hdr-minrev  10)
  +   smbiosrev = hdr-majrev * 100 + hdr-minrev * 10;
  +
  bios.cookie = 0;
  if (smbios_find_table(SMBIOS_TYPE_BIOS, bios)) {
  sb = bios.tblhdr;
  @@ -158,6 +163,39 @@
  break;
  }
  printf(\n);
  +
  +   /* No SMBIOS extensions, go looking for Soekris comBIOS */
  +   if (!smbiosrev) {
  +   const char *signature = Soekris Engineering;
  +
  +   for (p = ISA_HOLE_VADDR(SMBIOS_START);
  +   p = (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END -
  +   (strlen(signature) - 1)); p++)
  +   if (!memcmp(p, signature, strlen(signature))) {
  +   hw_vendor = malloc(strlen(signature) + 1,
  +   M_DEVBUF, M_NOWAIT);
  +   if (hw_vendor)
  +   strlcpy(hw_vendor, signature,
  +   strlen(signature) + 1);
  +   p += strlen(signature);
  +   break;
  +   }
  +
  +   for (; hw_vendor 
  +   p = (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END - 6); p++)
  +   /*
  +* Search only for net6501 in the comBIOS as that's
  +* the only Soekris platform that can run amd64
  +*/
  +   if (!memcmp(p, net6501, 7)) {
  +   hw_prod = malloc(8, M_DEVBUF, M_NOWAIT);
  +   if (hw_prod) {
  +   memcpy(hw_prod, p, 7);
  +   hw_prod[7] = '\0';
  +   }
  +   break;
  +   }
  +   }
   
   #if NACPI  0
  {
  --- sys/arch/i386/i386/bios.c.orig  Tue Feb 19 06:36:42 2013
  +++ sys/arch/i386/i386/bios.c   Wed Feb 20 08:58:17 2013
  @@ -330,6 +330,43 @@
   
  printf(\n);
   
  +   /* No SMBIOS extensions, go looking for Soekris comBIOS */
  +   if (!(flags  BIOSF_SMBIOS)  !smbiosrev) {
  +   const char *signature = Soekris Engineering;
  +
  +   for (va = ISA_HOLE_VADDR(SMBIOS_START);
  +   va = (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END -
  +   (strlen(signature) - 1)); va++)
  +   if (!memcmp((u_int8_t *)va, signature,
  +   strlen(signature))) {
  +   hw_vendor = malloc(strlen(signature) + 1,
  +   M_DEVBUF, M_NOWAIT);
  +   if (hw_vendor)
  +   strlcpy(hw_vendor, signature,
  +   strlen(signature) + 1);
  +   va += strlen(signature);
  +  

Re: Add Soekris comBIOS detection to bios(4) on i386/amd64

2013-03-04 Thread Gerhard Roth
On Mon, 4 Mar 2013 15:18:45 +0100 Gerhard Roth gerhard_r...@genua.de wrote:
 On Mon, 4 Mar 2013 06:02:19 -0500 Matt Dainty m...@bodgit-n-scarper.com 
 wrote:
  * Matt Dainty m...@bodgit-n-scarper.com [2013-02-20 19:30:43]:
   Attached are two patches for bios(4) on i386  amd64 that add support
   for detecting the comBIOS on Soekris hardware, which then fills in the
   hw.vendor  hw.product sysctl variables as this hardware lacks any
   SMBIOS to provide them. The idea is then these can be used in the
   GPIO/LED driver for the net6501 I posted a while ago to simplify the
   match logic.
   
   I've tested this with a net6501  amd64 so I would appreciate testing
   on any other Soekris hardware under i386; net4501, net4801  net5501.
  
  I'm lacking a test report for a net4801, however as I've had reports
  of success for all other Soekris board types, I'd be surprised if it
  didn't work.
 
 Hi,
 
 I can confirm that your patch works for i386 on net4501:
 
 # sysctl hw
 hw.machine=i386
 hw.model=Geode(TM) Integrated Processor by National Semi (Geode by NSC 
 586-class)
 hw.ncpu=1
 hw.byteorder=1234
 hw.pagesize=4096
 ...
 hw.cpuspeed=267
 hw.vendor=Soekris Engineering
 hw.product=net4801
 hw.version=1
 hw.physmem=133754880
 hw.usermem=133742592
 hw.ncpufound=1
 hw.allowpowerdown=1
 
 Gerhard


Sorry,

stupid me mixed up 4801 and 4501 :(

But as you see from the sysctl output, I tested on 4801. So this should
fill up your gap.

Gerhard

 
  
   Also any other hardware that lacks SMBIOS and in the case of i386
   doesn't need to disable probing of SMBIOS with flags 0x0008.
  
  I would still appreciate some testing on other systems that lack any
  SMBIOS, just to make sure it doesn't cause problems there. However as
  this code walks over the same area of memory, I would again be
  surprised if this caused problems when the SMBIOS probe didn't.
  
  Matt
  
   --- sys/arch/amd64/amd64/bios.c.orig  Tue Feb 19 01:56:56 2013
   +++ sys/arch/amd64/amd64/bios.c   Wed Feb 20 08:37:12 2013
   @@ -95,6 +95,7 @@
 vaddr_t va;
 paddr_t pa, end;
 u_int8_t *p;
   + int smbiosrev = 0;

 /* see if we have SMBIOS extentions */
 for (p = ISA_HOLE_VADDR(SMBIOS_START);
   @@ -137,6 +138,10 @@
 printf(: SMBIOS rev. %d.%d @ 0x%lx (%d entries),
 hdr-majrev, hdr-minrev, hdr-addr, hdr-count);

   + smbiosrev = hdr-majrev * 100 + hdr-minrev;
   + if (hdr-minrev  10)
   + smbiosrev = hdr-majrev * 100 + hdr-minrev * 10;
   +
 bios.cookie = 0;
 if (smbios_find_table(SMBIOS_TYPE_BIOS, bios)) {
 sb = bios.tblhdr;
   @@ -158,6 +163,39 @@
 break;
 }
 printf(\n);
   +
   + /* No SMBIOS extensions, go looking for Soekris comBIOS */
   + if (!smbiosrev) {
   + const char *signature = Soekris Engineering;
   +
   + for (p = ISA_HOLE_VADDR(SMBIOS_START);
   + p = (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END -
   + (strlen(signature) - 1)); p++)
   + if (!memcmp(p, signature, strlen(signature))) {
   + hw_vendor = malloc(strlen(signature) + 1,
   + M_DEVBUF, M_NOWAIT);
   + if (hw_vendor)
   + strlcpy(hw_vendor, signature,
   + strlen(signature) + 1);
   + p += strlen(signature);
   + break;
   + }
   +
   + for (; hw_vendor 
   + p = (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END - 6); p++)
   + /*
   +  * Search only for net6501 in the comBIOS as that's
   +  * the only Soekris platform that can run amd64
   +  */
   + if (!memcmp(p, net6501, 7)) {
   + hw_prod = malloc(8, M_DEVBUF, M_NOWAIT);
   + if (hw_prod) {
   + memcpy(hw_prod, p, 7);
   + hw_prod[7] = '\0';
   + }
   + break;
   + }
   + }

#if NACPI  0
 {
   --- sys/arch/i386/i386/bios.c.origTue Feb 19 06:36:42 2013
   +++ sys/arch/i386/i386/bios.c Wed Feb 20 08:58:17 2013
   @@ -330,6 +330,43 @@

 printf(\n);

   + /* No SMBIOS extensions, go looking for Soekris comBIOS */
   + if (!(flags  BIOSF_SMBIOS)  !smbiosrev) {
   + const char *signature = Soekris Engineering;
   +
   + for (va = ISA_HOLE_VADDR(SMBIOS_START);
   + va = (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END -
   + (strlen(signature) - 1)); va++)
   + if (!memcmp((u_int8_t *)va, signature,
   + strlen(signature))) {
   + hw_vendor = malloc(strlen(signature) + 1,
   + M_DEVBUF, M_NOWAIT

Re: [PATCH] snmpd readonly mode

2013-03-04 Thread Gerhard Roth
On Mon, 4 Mar 2013 15:56:36 +0100 Ilya Bakulin ilya_baku...@genua.de wrote:
 Hi list,
 We have a small issue with snmpd daemon in OpenBSD.
 If people use SNMPv2c, they should explicitly set read-write community name 
 to some [probably random-generated] string, because otherwise everybody is 
 able to alter values of some SNMP nodes (the default value for read-write 
 community is private, which is not very secure, probably).
 
 Attached is the patch that adds new configuration file parameter,
 nowrite, with values yes and no, that disallows any write 
 attempts to any SNMP node regardless of specified read-write community string.
 
 $ snmpset -c private -v2c 127.0.0.1 system.sysContact.0 s SOME_CRAP
 Error in packet.
 Reason: (readOnly) The two parties used do not have access to use the
 specified SNMP PDU.
 Failed object: SNMPv2-MIB::sysContact.0
 
 Hope you will find it useful.
 
 // Ilya
 
 

Just a little bike-shedding:

- The term readonly seems more common to me than nowrite.

- All members of struct snmpd have a 'sc_' prefix. You should stick to
  that style.

Gerhard



Re: [PATCH] snmpd readonly mode

2013-03-04 Thread Gerhard Roth
On Mon, 4 Mar 2013 17:28:17 +0100 Ilya Bakulin ilya_baku...@genua.de wrote:
 On Monday 04 March 2013 16:13:09 Gerhard Roth wrote:
  Just a little bike-shedding:
 
  - The term readonly seems more common to me than nowrite.
 I didn't use readonly because there is already a keyword read-only with 
 the token name READONLY, and I didn't want to introduce yet another readonly* 
 variable :-)

Hi Ilya,

how about using the existing 'read-write' keyword?

read-write [no | community string]

Gerhard

 
 
  - All members of struct snmpd have a 'sc_' prefix. You should stick to
that style.
 
  Gerhard
 Agree, not using sc_ is bad.
 
 // Ilya



Re: cloneable tun

2012-11-29 Thread Gerhard Roth
On 11/29/2012 01:33 PM, Reyk Floeter wrote:
 On Thu, Nov 29, 2012 at 10:59 AM, Mike Belopuhov m...@belopuhov.com wrote:
 But currently /dev/tunN is usable from any programming language that
 that can do reads and writes.  With Reyk's changes you need to do an
 ioctl even for basic usage, which is at best quirky in languages other
 than C/C++.  That feels like a step backward to me.

 sure, we can totally leave tun for legacy use in the shell scripts.
 so i guess reyk should go ahead and implement a dynamic tun interface
 (dun?) with whatever semantics we need and want.
 
 Or even better duh? ;-) I wrote this diff because I wanted to
 experiment with clonable device nodes, I still don't like the fact
 that you have to MAKEDEV a device per dynamic interface, and because
 it adds some extra flexibility. But it doesn't have to go anywhere, I
 didn't even waste much time with writing it yesterday in the
 afternoon.
 
 btw., I like C and it is still my favorite language (sorry, CS
 people). But it shouldn't be a problem to do simple ioctls with most
 other languages except shell scripts.
 
 #!/usr/bin/perl
 require sys/ioctl.ph;
 $TUNSIFUNIT = _IOC(IOC_INOUT, ord('t'), 90, 4);
 open(TUN0, +/dev/tun0) or die open;
 ioctl(TUN0, $TUNSIFUNIT, $unit = pack(i, -1)) or die ioctl $!;
 print Returned: tun.unpack(i, $unit).\n;
 close(TUN0);
 
 reyk
 

I like cloning devices. But instead of needing an ioclt(2), wouldn't
it be simpler to adapt the SVR4 API where the first parameter of
cdevsw open() functions is an 'dev_t *dev'. Thus the open() routine
can automatically do the cloning (or maybe not if minor is  0) by
returning the device-Id of the cloned instance. and there is no need
for using additional ioctl(2)s.

Of course it requires a one-time API change with large impact.

Gerhard



Re: [PATCH] mlockall() problem in OpenBSD 5.2

2012-11-09 Thread Gerhard Roth
On Thu, 08 Nov 2012 16:22:41 -0500
Ted Unangst t...@tedunangst.com wrote:
 On Thu, Nov 08, 2012 at 13:34, Ilya Bakulin wrote:
 
  The problem seems to be in uvm_map_pageable_all() function
  (sys/uvm/uvm_map.c). This function is a special case of uvm_map_pageable,
  which tries to mlockall() all mapped memory regions.
  Prior to calling uvm_map_pageable_wire(), which actually does locking, it
  tries to count how many memory bytes will be locked, and compares this
  number
  with uvmexp.wiredmax, which is set by RLIMIT_MEMLOCK.
  The problem is that counting algorithm doesn't take into account that some
  pages have VM_PROT_NONE flag set and hence won't be locked anyway.
  Later in uvm_map_pageable_wire() these pages are skipped when doing actual
  job.
 
 I don't know if this is right.  Should prot_none pages not be wired?
 
 I think the opposite should happen.  prot_none pages should be locked
 as well.  The app may be using prot_none as a way to protect its super
 secret secrets from itself.  It certainly wouldn't want them being
 swapped out.
 

As long as they have VM_PROT_NONE, they can't be accessed and wiring them
is just a waste of resources.

If your scenario applies then uvm_map_protect() kicks in. It takes care of
wiring pages if the protection changes from VM_PROT_NONE to some different
value, though I have to admit that this happens only in case the
VM_MAP_WIREFUTURE flag was specified. But that looks acceptable to me.

Gerhard



Re: [PATCH] mlockall() problem in OpenBSD 5.2

2012-11-08 Thread Gerhard Roth
I did a similar change recently
(http://marc.info/?l=openbsd-cvsm=135055003602935w=2). Therefore I
think that Ilya's patch is valid and should be applied.

If anyone is willing to ok, I can commit it.

Gerhard


On 11/08/2012 01:34 PM, Ilya Bakulin wrote:
 Hi list,
 after upgrade on OpenBSD 5.2 we observe the following message from ntpd:
 
 Oct 22 17:20:13 gg74 ntpd[2918]: ntpd 4.2.6p2@1.2194-o Tue Oct 16 20:26:47 
 UTC 
 2012 (1)
 Oct 22 17:20:13 gg74 ntpd[10103]: mlockall(): Cannot allocate memory
 Oct 22 17:20:13 gg74 ntpd[10103]: signal_no_reset: signal 13 had flags 12
 Oct 22 17:20:13 gg74 ntpd[10103]: proto: precision = 6.390 usec
 ...
 This doesn't prevent ntpd from starting, however.
 We tried to debug this problem. This occurs when an application tries to set 
 resource limits (more precisely, RLIMIT_MEMLOCK) to some relatively low value 
 and then does mlockall().
 
 The problem seems to be in uvm_map_pageable_all() function 
 (sys/uvm/uvm_map.c). This function is a special case of uvm_map_pageable, 
 which tries to mlockall() all mapped memory regions.
 Prior to calling uvm_map_pageable_wire(), which actually does locking, it 
 tries to count how many memory bytes will be locked, and compares this number 
 with uvmexp.wiredmax, which is set by RLIMIT_MEMLOCK.
 The problem is that counting algorithm doesn't take into account that some 
 pages have VM_PROT_NONE flag set and hence won't be locked anyway.
 Later in uvm_map_pageable_wire() these pages are skipped when doing actual 
 job.
 
 Attached patch fixes the problem on OpenBSD 5.2.
 
 I'm also attaching a simple test application, that can be used to reproduce 
 the bug. Just compile and run as root (otherwise mlockall() doesn't work 
 anyway). On OpenBSD 5.2 the RLIMIT_MEMLOCK limit will be significantly higher 
 than on OpenBSD 5.1. After applying my patch they will be almost the same.
 
 Thank you for your attention.
 
 // Ilya



Re: [PATCH] mlockall() problem in OpenBSD 5.2

2012-11-08 Thread Gerhard Roth
On 11/08/2012 02:08 PM, Stuart Henderson wrote:
 Oh talking of RLIMIT reminds me...can someone who knows this area take
 a look at http://thread.gmane.org/gmane.os.aeriebsd.general/100 please?
 

To me the fix looks reasonable. Limiting the stack size below
the current usage shouldn't be allowed. And returning EINVAL is the
right error code according to SUS (The limit specified cannot be
lowered because current usage is already higher than the limit.).

However, the EINVAL error should then be added to the man page
(lib/libc/sys/getrlimit.2). That's missing in Mickey's patch.

Gerhard



Re: DNS options for sppp(4)

2012-10-25 Thread Gerhard Roth
On 10/25/2012 10:44 AM, LEVAI Daniel wrote:
 On p, okt 05, 2012 at 13:46:19 +0200, Gerhard Roth wrote:
 Hi,

 I trying to revive part of an old patch that was submitted by mpf
 in 2007. If adds support for DNS server negotiation to the IPCP
 part of sppp(4). If the PPP server provides IP addresses for
 DNS servers, they will appear in the ifconfig(8) output.

 A simple ifstated(8) script could then be used to re-write resolv.conf,
 e.g.

  # ifconfig pppoe | sed -n 's/^[[:space:]]*dns.:/nameserver/p'
 [...]
 
 Works for me.
 Cool feature, I like it :)
 Thanks!
 
 
 Daniel
 

So anybody out there willing to give me an ok?



DNS options for sppp(4)

2012-10-05 Thread Gerhard Roth
Hi,

I trying to revive part of an old patch that was submitted by mpf
in 2007. If adds support for DNS server negotiation to the IPCP
part of sppp(4). If the PPP server provides IP addresses for
DNS servers, they will appear in the ifconfig(8) output.

A simple ifstated(8) script could then be used to re-write resolv.conf,
e.g.

# ifconfig pppoe | sed -n 's/^[[:space:]]*dns.:/nameserver/p'


Gerhard


Index: sbin/ifconfig/ifconfig.c
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.257
diff -u -p -r1.257 ifconfig.c
--- sbin/ifconfig/ifconfig.c6 Sep 2012 19:41:59 -   1.257
+++ sbin/ifconfig/ifconfig.c5 Oct 2012 11:19:36 -
@@ -4265,6 +4265,12 @@ sppp_status(void)
if (spa.flags  AUTHFLAG_NORECHALLENGE)
printf(norechallenge );
putchar('\n');
+   if (spr.defs.dns_addrs[0] != INADDR_ANY)
+   printf(\tdns1: %s\n,
+   inet_ntoa(*(struct in_addr *)spr.defs.dns_addrs[0]));
+   if (spr.defs.dns_addrs[1] != INADDR_ANY)
+   printf(\tdns2: %s\n,
+   inet_ntoa(*(struct in_addr *)spr.defs.dns_addrs[1]));
 }
 
 void
Index: sys/net/if_sppp.h
===
RCS file: /cvs/src/sys/net/if_sppp.h,v
retrieving revision 1.17
diff -u -p -r1.17 if_sppp.h
--- sys/net/if_sppp.h   29 Jan 2012 10:21:54 -  1.17
+++ sys/net/if_sppp.h   5 Oct 2012 11:19:45 -
@@ -118,6 +118,7 @@ struct sppp {
time_t  pp_last_receive;/* peer's last sign of life */
time_t  pp_last_activity;   /* second of last payload data s/r */
enum ppp_phase pp_phase;/* phase we're currently in */
+   u_int32_t  dns_addrs[2];/* primary and secondary DNS server */
int state[IDX_COUNT];   /* state machine */
u_char  confid[IDX_COUNT];  /* id of last configuration request */
int rst_counter[IDX_COUNT]; /* restart counter */
Index: sys/net/if_spppsubr.c
===
RCS file: /cvs/src/sys/net/if_spppsubr.c,v
retrieving revision 1.98
diff -u -p -r1.98 if_spppsubr.c
--- sys/net/if_spppsubr.c   24 Jul 2012 15:16:20 -  1.98
+++ sys/net/if_spppsubr.c   5 Oct 2012 11:19:45 -
@@ -167,6 +167,8 @@
 #define IPCP_OPT_ADDRESSES 1   /* both IP addresses; deprecated */
 #define IPCP_OPT_COMPRESSION   2   /* IP compression protocol (VJ) */
 #define IPCP_OPT_ADDRESS   3   /* local IP address */
+#define IPCP_OPT_PRIMDNS   129 /* primary remote dns address */
+#define IPCP_OPT_SECDNS131 /* secondary remote dns address 
*/
 
 #define IPV6CP_OPT_IFID1   /* interface identifier */
 #define IPV6CP_OPT_COMPRESSION 2   /* IPv6 compression protocol */
@@ -2687,6 +2689,7 @@ sppp_ipcp_init(struct sppp *sp)
sp-ipcp.flags = 0;
sp-state[IDX_IPCP] = STATE_INITIAL;
sp-fail_counter[IDX_IPCP] = 0;
+   bzero(sp-dns_addrs, sizeof(sp-dns_addrs));
 #if defined (__FreeBSD__)
callout_handle_init(sp-ch[IDX_IPCP]);
 #endif
@@ -2954,6 +2957,9 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struc
struct ifnet *ifp = sp-pp_if;
int debug = ifp-if_flags  IFF_DEBUG;
u_int32_t wantaddr;
+   u_int32_t dns;
+   int dnsix;
+   int dns_changed = 0;
 
len -= 4;
 
@@ -2995,6 +3001,17 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struc
}
}
break;
+   case IPCP_OPT_PRIMDNS:
+   case IPCP_OPT_SECDNS:
+   if (len = 6  p[1] == 6) {
+   dnsix = (*p == IPCP_OPT_PRIMDNS) ? 0 : 1;
+   bcopy(p + 2, dns, sizeof dns);
+   if (sp-dns_addrs[dnsix] != dns) {
+   sp-dns_addrs[dnsix] = dns;
+   dns_changed = 1;
+   }
+   }
+   break;
 #ifdef notyet
case IPCP_OPT_COMPRESS:
/*
@@ -3004,6 +3021,8 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struc
 #endif
}
}
+   if ((ifp-if_flags  IFF_UP)  dns_changed)
+   rt_ifmsg(ifp);
if (debug)
addlog(\n);
 }
@@ -3109,12 +3128,13 @@ sppp_ipcp_tlf(struct sppp *sp)
/* we no longer need LCP */
sp-lcp.protos = ~(1  IDX_IPCP);
sppp_lcp_check_and_close(sp);
+   bzero(sp-dns_addrs, sizeof(sp-dns_addrs));
 }
 
 HIDE void
 sppp_ipcp_scr(struct sppp *sp)
 {
-   char opt[6 /* compression */ + 6 /* address */];
+   char opt[6 /* compression */ + 6 /* address */ + 12 /* dns addresses 
*/];
u_int32_t ouraddr;
int i = 0;
 
@@ -3143,6 +3163,16 @@ sppp_ipcp_scr(struct 

Problem in vr_stop()

2012-09-18 Thread Gerhard Roth
Hi,

we observed mysterious panics while stopping vr interfaces. This was due
to vr_stop() trying to stop the transfers but then not waiting for them
to really finish but rather remove their DMA buffer mappings immediately.

The patch below uses a loop that was copied from vr_setcfg() (!IFM_ACTIVE)
to wait for transfers to finish.

Gerhard


Index: sys/dev/pci/if_vr.c
===
RCS file: /cvs/src/sys/dev/pci/if_vr.c,v
retrieving revision 1.114
diff -u -p -r1.114 if_vr.c
--- sys/dev/pci/if_vr.c 30 Jan 2012 09:11:30 -  1.114
+++ sys/dev/pci/if_vr.c 18 Sep 2012 10:48:24 -
@@ -1542,6 +1542,17 @@ vr_stop(struct vr_softc *sc)
 
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_STOP);
VR_CLRBIT16(sc, VR_COMMAND, (VR_CMD_RX_ON|VR_CMD_TX_ON));
+
+   /* wait for xfers to shutdown */
+   for (i = VR_TIMEOUT; i  0; i--) {
+   DELAY(10);
+   if (!(CSR_READ_2(sc, VR_COMMAND)  (VR_CMD_TX_ON|VR_CMD_RX_ON)))
+   break;
+   }
+#ifdef VR_DEBUG
+   if (i == 0)
+   printf(%s: rx shutdown error!\n, sc-sc_dev.dv_xname);
+#endif
CSR_WRITE_2(sc, VR_IMR, 0x);
CSR_WRITE_4(sc, VR_TXADDR, 0x);
CSR_WRITE_4(sc, VR_RXADDR, 0x);



Bug in calibration of local APIC timer

2012-09-17 Thread Gerhard Roth
Hi,

I spotted a problem with the calibration of the local APIC clock. For
the second CPU you sometimes see impossibly high clock rates like
in the following example:

 cpu0: Intel(R) Core(TM) i3-2100 CPU @ 3.10GHz (GenuineIntel 686-class) 3.10 
 GHz
 cpu0: 
 FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,SBF,SSE3,PCLMUL,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,XSAVE,AVX
 real mem  = 2124333056 (2025MB)
 avail mem = 2033119232 (1938MB)
 mainbus0 at root
 bios0 at mainbus0: AT/286+ BIOS, date 10/20/10, SMBIOS rev. 2.7 @ 0xeadc0 
 (105 entries)
 bios0: vendor American Megatrends Inc. version 1.1a date 09/28/2011
 bios0: Supermicro GS0300
 acpi at bios0 function 0x0 not configured
 pcibios at bios0 function 0x1a not configured
 bios0: ROM list: 0xc/0x8000
 mainbus0: Intel MP Specification (Version 1.4)
 cpu0 at mainbus0: apid 0 (boot processor)
 cpu0: apic clock running at 249MHz
 cpu1 at mainbus0: apid 2 (application processor)
 cpu1: Intel(R) Core(TM) i3-2100 CPU @ 3.10GHz (GenuineIntel 686-class) 7.73 
 GHz

The primary cause for this is the wrong speed detected for the APIC
clock. Above it claims to be 249 MHz, when in fact it is 100 MHz.
The main trouble with that error is that now all delay(9) calls are
wrong by the same factor.

In order to calibrate the local APIC timer the i8254 timer is used for
reference. This timer is initialized with TIMER_FREQ / hz and then
counts down to one within 1/hz seconds after which it starts another
cycle. So this kinda looks like a saw-tooth.

The code picks an arbitrary value of the counter and stores it in
'starttick'. Then it loops hz times (which should take a total of one
second). The first inner do-while loop waits for the current counter
to become larger than 'starttick', i.e. for a new timer cycle to
start. The second do-while loop waits for the counter to be decreased
to the same value as 'starttick'. Both do-while loops together are
expected to take 1/hz seconds. To visualize this, imagine a time-
diagram with the saw-tooth counter value and a horizontal line at the
height of 'starttick'.

Now if the value of 'starttick' by chance is very large, the code might
miss the small time window where the counter in fact is larger than it.
The chance of a miss is even larger due to the call to i8254_delay()
where we're blind to the counter values. In the extreme case where
starttick is set to the counters initial value (TIMER_FREQ / hz), this
would be an endless loop cause the counter will never carry a value
larger than this. Same problem happens if the value of 'starttick' is
rather small.

In both cases (very large or very small 'starttick') some cycles of the
i8254 counter may be missed and we have to run longer until hz cycles
are detected. Once we leave the for-loop which is expected to run for
one second, the local APIC timer will have made a much larger progress
than expected and the code assumes that it's running faster than fact
it is.


The patch below fixes the problem:

- Neither call i8254_delay() nor lapic_gettick() inside the calibration
  loop. Only keep an eye on the i8254 counter. We don't need these calls
  and permanently reading the counter reduces the possibility of missing
  cycles.

- Because comparison against an arbitrary start value is problematic,
  we first wait for the current cycle to finish. Then inside the
  calibration loop, we just wait until hz complete cycles have passed.


Gerhard


Index: sys/arch/amd64/amd64/lapic.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/lapic.c,v
retrieving revision 1.27
diff -u -p -r1.27 lapic.c
--- sys/arch/amd64/amd64/lapic.c20 Sep 2010 06:33:46 -  1.27
+++ sys/arch/amd64/amd64/lapic.c17 Sep 2012 17:55:48 -
@@ -305,6 +305,20 @@ lapic_initclocks(void)
 extern int gettick(void);  /* XXX put in header file */
 extern u_long rtclock_tval; /* XXX put in header file */
 
+static __inline void
+wait_next_cycle(void)
+{
+   unsigned int tick, tlast;
+
+   tlast = (1  16);  /* i8254 counter has 16 bits at most */
+   for (;;) {
+   tick = gettick();
+   if (tick  tlast)
+   return;
+   tlast = tick;
+   }
+}
+
 /*
  * Calibrate the local apic count-down timer (which is running at
  * bus-clock speed) vs. the i8254 counter/timer (which is running at
@@ -319,8 +333,7 @@ extern u_long rtclock_tval; /* XXX put i
 void
 lapic_calibrate_timer(struct cpu_info *ci)
 {
-   unsigned int starttick, tick1, tick2, endtick;
-   unsigned int startapic, apic1, apic2, endapic;
+   unsigned int startapic, endapic;
u_int64_t dtick, dapic, tmp;
long rf = read_rflags();
int i;
@@ -337,27 +350,20 @@ lapic_calibrate_timer(struct cpu_info *c
i82489_writereg(LAPIC_ICR_TIMER, 0x8000);
 
disable_intr();
-   

Re: SNMPv3 Support

2012-07-19 Thread Gerhard Roth

Hi Reyk,

On Wed, 18 Jul 2012 21:42:34 +0200, Reyk Floeter r...@openbsd.org wrote:

How about:
noAuthNoPriv- none
authNoPriv  - auth
authPriv- encr



Is there a better alternative for encr? Maybe just enc (I know it
would complicate the grammar because it's a reserved keyword) or
something more abstract like high or all?


the yacc grammar was exactly why I chose encr instead of enc. ;)

I changed it to enc now. But now none, auth and enc are
reserved words. Hope nobody uses them as community string or
elsewhere.

Also noticed that you wanted me to keep the auth keyword in front
of hmac-*. Fixed this one, too.

Find the updated patch below.

Gerhard


Index: usr.sbin/snmpd/Makefile
===
RCS file: /cvs/src/usr.sbin/snmpd/Makefile,v
retrieving revision 1.8
diff -u -p -r1.8 Makefile
--- usr.sbin/snmpd/Makefile 20 Mar 2012 03:01:26 -  1.8
+++ usr.sbin/snmpd/Makefile 18 Jul 2012 14:03:06 -
@@ -4,9 +4,9 @@ PROG=   snmpd
 MAN=   snmpd.8 snmpd.conf.5
 SRCS=  parse.y ber.c log.c control.c snmpe.c \
mps.c trap.c mib.c smi.c kroute.c snmpd.c timer.c \
-   pf.c
+   pf.c usm.c

-LDADD= -levent -lutil -lkvm
+LDADD= -levent -lutil -lkvm -lcrypto
 DPADD= ${LIBEVENT} ${LIBUTIL}
 CFLAGS+=   -Wall -I${.CURDIR}
 CFLAGS+=   -Wstrict-prototypes -Wmissing-prototypes
Index: usr.sbin/snmpd/ber.3
===
RCS file: /cvs/src/usr.sbin/snmpd/ber.3,v
retrieving revision 1.9
diff -u -p -r1.9 ber.3
--- usr.sbin/snmpd/ber.325 Feb 2010 09:59:55 -  1.9
+++ usr.sbin/snmpd/ber.318 Jul 2012 14:03:06 -
@@ -50,9 +50,11 @@
 .Nm ber_write_elements ,
 .Nm ber_set_readbuf ,
 .Nm ber_read_elements ,
+.Nm ber_getpos ,
 .Nm ber_free_elements ,
 .Nm ber_calc_len ,
 .Nm ber_set_application ,
+.Nm ber_set_writecallback
 .Nm ber_free
 .Nd parse ASN.1 with Basic Encoding Rules
 .Sh SYNOPSIS
@@ -121,6 +123,8 @@
 .Fn ber_set_readbuf struct ber *ber void *buf size_t len
 .Ft struct
 .Fn ber_element *ber_read_elements struct ber *ber struct ber_element 
*root
+.Ft off_t
+.Fn ber_getpos struct ber_element *elm
 .Ft void
 .Fn ber_free_elements struct ber_element *root
 .Ft size_t
@@ -128,6 +132,8 @@
 .Ft void
 .Fn ber_set_application struct ber *ber unsigned long (*cb)(struct ber_element 
*)
 .Ft void
+.Fn ber_set_writecallback struct ber_element *elm void (*cb)(void *arg, size_t 
offs) void *arg
+.Ft void
 .Fn ber_free struct ber *ber
 .Sh DESCRIPTION
 The
@@ -188,8 +194,10 @@ struct ber_oid {
 .Fn ber_write_elements ,
 .Fn ber_set_readbuf ,
 .Fn ber_read_elements ,
+.Fn ber_getpos ,
 .Fn ber_free_elements ,
 .Fn ber_set_application ,
+.Fn ber_set_writecallback ,
 .Fn ber_free
 .Sh RETURN VALUES
 Upon successful completion
Index: usr.sbin/snmpd/ber.c
===
RCS file: /cvs/src/usr.sbin/snmpd/ber.c,v
retrieving revision 1.23
diff -u -p -r1.23 ber.c
--- usr.sbin/snmpd/ber.c20 Sep 2010 08:30:13 -  1.23
+++ usr.sbin/snmpd/ber.c18 Jul 2012 14:03:06 -
@@ -618,6 +618,7 @@ ber_scanf_elements(struct ber_element *b
void**ptr;
size_t  *len, ret = 0, n = strlen(fmt);
char**s;
+   off_t   *pos;
struct ber_oid  *o;
struct ber_element  *parent[_MAX_SEQ], **e;

@@ -695,6 +696,11 @@ ber_scanf_elements(struct ber_element *b
goto fail;
ret++;
break;
+   case 'p':
+   pos = va_arg(ap, off_t *);
+   *pos = ber_getpos(ber);
+   ret++;
+   continue;
case '{':
case '(':
if (ber-be_encoding != BER_TYPE_SEQUENCE 
@@ -712,7 +718,7 @@ ber_scanf_elements(struct ber_element *b
goto fail;
ber = parent[level--];
ret++;
-   continue;
+   break;
default:
goto fail;
}
@@ -808,6 +814,12 @@ ber_read_elements(struct ber *ber, struc
return root;
 }

+off_t
+ber_getpos(struct ber_element *elm)
+{
+   return elm-be_offs;
+}
+
 void
 ber_free_elements(struct ber_element *root)
 {
@@ -867,6 +879,8 @@ ber_dump_element(struct ber *ber, struct
uint8_t u;

ber_dump_header(ber, root);
+   if (root-be_cb)
+   root-be_cb(root-be_cbarg, ber-br_wptr - ber-br_wbuf);

switch (root-be_encoding) {
case BER_TYPE_BOOLEAN:
@@ -1068,6 +1082,7 @@ ber_read_element(struct ber *ber, struct

elm-be_type = type;
elm-be_len = len;

Re: SNMPv3 Support

2012-07-18 Thread Gerhard Roth

On Wed, 18 Jul 2012 16:51:27 +0200, Mike Belopuhov m...@crypt.org.ru wrote:

On Wed, Jul 18, 2012 at 4:16 PM, Gerhard Roth wrote:

same here, wouldn't it be possible to match the ipsec.conf grammar and
ignore the SNMPv3 naming a bit?

auth hmac-sha1 authkey fooobar enc aes enckey dkjdkj
- instead of -
hmac sha authpass foobar cipher aes privpass dkjdkj

or maybe authpass and encpass, but what does priv mean.




So instead of

user name [authpass pass hmac [MD5|SHA]] \
[privpass pass cipher [DES|AES]]

let's use

user name [hmac-[md5|sha1] authkey key] \
[enc [des|aes] enckey key]

Is that ipsec.conf like enough?



why weren't all the other _priv instances renamed to _encr?
is there any value in keeping SNMP_MSGFLAG_PRIV and such around?
uu_privkey looks a bif of an alien alongside uu_authkey.



I agree with Reyk that the configuration of snmpd should be possible
to anyone who has not read all the SNMPv3 RFCs.

OTOH, shouldn't the code somehow reflect which part of the RFCs
it implements? Otherwise its hard to understand whats happening.
And unfortunately the RFCs use the word priv or privacy consistenly
instead of encryption.

Gerhard



SNMPv3 Support

2012-07-17 Thread Gerhard Roth
Hi all,

below you'll find a patch that adds basic SNMPv3 support to OpenBSD's
snmpd(8). When I say basic that's because of some limitations:

- Traps are still sent via SNMPv2 protocol. They can neither be
 authenticated nor encrypted.

- Transport mode is still UDP. Not additional transport subsystems
 were added.

- Only the User-based Security Model (USM, RFC3414) is supported.
 View-Based Access Control (VACM, RFC3415) is not included.


Just to provide you a little background, I'll explain some details
below.

Three security levels are defined in RFC3411:

1) noAuthNoPriv: no authentication, no encryption
2) authNoPriv: with authentication, without encryption
3) authPriv: with authentication, with encryption

There is a new keyword 'seclevel' in snmpd.conf(5) that allows to
define the minimum security level required by snmpd(8). Any requirement
higher than noAuthNoPriv will disable SNMPv2 support.


The USM offers:

- Verification of message contents and authentication of the sender

 USM adds a HMAC to the SNMP message. The HMAC is calculated over
 the whole message with the HMAC portion set to zeroes.
 According to RFC3414 the defined HMAC algorithms are HMAC-MD5-96
 and HMAC-SHA-96. The key is derived from an authentication
 passphrase.


- Encryption of the PDU

 USM encypts only a part of the message, the scoped PDU while the
 SNMP header remains plaintext. RFC3414 defines only CBC DES but
 RFC3826 adds CFB128 AES 128 encryption (although this is not
 part of STD62). The IV is derived from an encryption passphrase.


- Protection agains replay attacks

 The non-authoritative SNMP engines have to synchronize their
 clocks with the authoritative SNMP engine. RFC3414 demands
 to reject any SNMPv3 message that has a timestamp that differs
 more than 150 seconds from the local clock.


The USM users together with their HMAC and encryption passphrases
have to be defined in snmpd.conf(5). The code already supports multiple
users, though without VACM there's not much sense to it.


Gerhard

[demime 1.01d removed an attachment of type application/octet-stream which had 
a name of snmpv3.patch]



Re: SNMPv3 Support

2012-07-17 Thread Gerhard Roth

On Tue, 17 Jul 2012 11:21:04 +0200, Gerhard Roth gerhard_r...@genua.de wrote:

Hi all,

below you'll find a patch that adds basic SNMPv3 support to OpenBSD's
snmpd(8). When I say basic that's because of some limitations:

- Traps are still sent via SNMPv2 protocol. They can neither be
 authenticated nor encrypted.

- Transport mode is still UDP. Not additional transport subsystems
 were added.

- Only the User-based Security Model (USM, RFC3414) is supported.
 View-Based Access Control (VACM, RFC3415) is not included.


Just to provide you a little background, I'll explain some details
below.

Three security levels are defined in RFC3411:

1) noAuthNoPriv: no authentication, no encryption
2) authNoPriv: with authentication, without encryption
3) authPriv: with authentication, with encryption

There is a new keyword 'seclevel' in snmpd.conf(5) that allows to
define the minimum security level required by snmpd(8). Any requirement
higher than noAuthNoPriv will disable SNMPv2 support.


The USM offers:

- Verification of message contents and authentication of the sender

 USM adds a HMAC to the SNMP message. The HMAC is calculated over
 the whole message with the HMAC portion set to zeroes.
 According to RFC3414 the defined HMAC algorithms are HMAC-MD5-96
 and HMAC-SHA-96. The key is derived from an authentication
 passphrase.


- Encryption of the PDU

 USM encypts only a part of the message, the scoped PDU while the
 SNMP header remains plaintext. RFC3414 defines only CBC DES but
 RFC3826 adds CFB128 AES 128 encryption (although this is not
 part of STD62). The IV is derived from an encryption passphrase.


- Protection agains replay attacks

 The non-authoritative SNMP engines have to synchronize their
 clocks with the authoritative SNMP engine. RFC3414 demands
 to reject any SNMPv3 message that has a timestamp that differs
 more than 150 seconds from the local clock.


The USM users together with their HMAC and encryption passphrases
have to be defined in snmpd.conf(5). The code already supports multiple
users, though without VACM there's not much sense to it.


Gerhard

[demime 1.01d removed an attachment of type application/octet-stream which had 
a name of snmpv3.patch]




Sorry for using an attachment. Here's the patch inlined:


Index: Makefile
===
RCS file: /cvs/src/usr.sbin/snmpd/Makefile,v
retrieving revision 1.8
diff -u -p -r1.8 Makefile
--- Makefile20 Mar 2012 03:01:26 -  1.8
+++ Makefile17 Jul 2012 06:49:17 -
@@ -4,9 +4,9 @@ PROG=   snmpd
 MAN=   snmpd.8 snmpd.conf.5
 SRCS=  parse.y ber.c log.c control.c snmpe.c \
mps.c trap.c mib.c smi.c kroute.c snmpd.c timer.c \
-   pf.c
+   pf.c usm.c

-LDADD= -levent -lutil -lkvm
+LDADD= -levent -lutil -lkvm -lcrypto
 DPADD= ${LIBEVENT} ${LIBUTIL}
 CFLAGS+=   -Wall -I${.CURDIR}
 CFLAGS+=   -Wstrict-prototypes -Wmissing-prototypes
Index: ber.3
===
RCS file: /cvs/src/usr.sbin/snmpd/ber.3,v
retrieving revision 1.9
diff -u -p -r1.9 ber.3
--- ber.3   25 Feb 2010 09:59:55 -  1.9
+++ ber.3   17 Jul 2012 06:44:44 -
@@ -50,9 +50,11 @@
 .Nm ber_write_elements ,
 .Nm ber_set_readbuf ,
 .Nm ber_read_elements ,
+.Nm ber_getpos ,
 .Nm ber_free_elements ,
 .Nm ber_calc_len ,
 .Nm ber_set_application ,
+.Nm ber_set_callback
 .Nm ber_free
 .Nd parse ASN.1 with Basic Encoding Rules
 .Sh SYNOPSIS
@@ -121,6 +123,8 @@
 .Fn ber_set_readbuf struct ber *ber void *buf size_t len
 .Ft struct
 .Fn ber_element *ber_read_elements struct ber *ber struct ber_element 
*root
+.Ft off_t
+.Fn ber_getpos struct ber_element *elm
 .Ft void
 .Fn ber_free_elements struct ber_element *root
 .Ft size_t
@@ -128,6 +132,8 @@
 .Ft void
 .Fn ber_set_application struct ber *ber unsigned long (*cb)(struct ber_element 
*)
 .Ft void
+.Fn ber_set_callback struct ber_element *elm void (*cb)(void *arg, size_t offs) 
void *arg
+.Ft void
 .Fn ber_free struct ber *ber
 .Sh DESCRIPTION
 The
@@ -188,8 +194,10 @@ struct ber_oid {
 .Fn ber_write_elements ,
 .Fn ber_set_readbuf ,
 .Fn ber_read_elements ,
+.Fn ber_getpos ,
 .Fn ber_free_elements ,
 .Fn ber_set_application ,
+.Fn ber_set_callback ,
 .Fn ber_free
 .Sh RETURN VALUES
 Upon successful completion
Index: ber.c
===
RCS file: /cvs/src/usr.sbin/snmpd/ber.c,v
retrieving revision 1.23
diff -u -p -r1.23 ber.c
--- ber.c   20 Sep 2010 08:30:13 -  1.23
+++ ber.c   17 Jul 2012 06:44:44 -
@@ -618,6 +618,7 @@ ber_scanf_elements(struct ber_element *b
void**ptr;
size_t  *len, ret = 0, n = strlen(fmt);
char**s

mkdep(1) misses compilation errors

2012-06-25 Thread Gerhard Roth

Hi,

the exit status of a shell pipeline is the exit status of the last
command in the pipeline. Since mkdep(1) pipes the output of ${CC} into
sed(1), the following check of '$?' checks the exit status of sed(1)
and not the of of cc(1).

This is nasty if some modification broke the compilation of a particular
source file. It cannot be compiled, but mkdep(1) exits with zero and
'make depend' completes without error. Since the source couldn't be
compiled, the resulting depend file will not list this source. Without
having any dependencies, make(1) will not try to rebuild the derived
targets. Unless I do a 'make clean', I won't even notice that my
build is broken.

Below is a possible patch to fix this.

Gerhard


--- usr.bin/mkdep/mkdep.gcc.sh  2008/08/28 09:39:44 1.15
+++ usr.bin/mkdep/mkdep.gcc.sh  2012/06/25 10:47:29
@@ -89,14 +89,9 @@ TMP=`mktemp /tmp/mkdep.XX` || exit 1
 trap 'rm -f $TMP ; trap 2 ; kill -2 $$' 1 2 3 13 15

 if [ x$file = x ]; then
-   ${CC:-cc} -M $@
+   ${CC:-cc} -M $@  $TMP
 else
-   ${CC:-cc} -M $@  cat $file
-fi |
-if [ x$pflag = x ]; then
-   sed -e 's; \./; ;g'  $TMP
-else
-   sed -e 's;\.o[ ]*:; :;' -e 's; \./; ;g'  $TMP
+   ${CC:-cc} -M $@  cat $file  $TMP
 fi

 if [ $? != 0 ]; then
@@ -105,15 +100,24 @@ if [ $? != 0 ]; then
exit 1
 fi

+postproc() {
+   in=$1
+   if [ x$pflag = x ]; then
+   sed -e 's; \./; ;g' $in
+   else
+   sed -e 's;\.o[ ]*:; :;' -e 's; \./; ;g' $in
+   fi
+}
+
 if [ $append = 1 ]; then
-   cat $TMP  $D
+   postproc $TMP  $D
if [ $? != 0 ]; then
echo 'mkdep: append failed.'
rm -f $TMP
exit 1
fi
 else
-   mv -f $TMP $D
+   postproc $TMP  $D
if [ $? != 0 ]; then
echo 'mkdep: rename failed.'
rm -f $TMP


Gerhard
--
genua
Gesellschaft fuer Netzwerk- und Unix-Administration mbH
Domagkstrasse 7, 85551 Kirchheim bei Muenchen
tel +49 89 991950-0, fax -999, www.genua.de
Geschaeftsfuehrer: Dr. Magnus Harlander, Dr. Michaela Harlander,
Bernhard Schneck. Amtsgericht Muenchen HRB 98238



IP Routing Fix

2012-06-22 Thread Gerhard Roth

Hi everybody,

there is code in ether_output() that handles the case that we have to
use a gateway to send the packet. This code does a lookup for the route
required to reach the gateway.

In case there is a gateway for which no direct route exists (surely a
stupid thing, but possible during reconfiguration), rtalloc1() will
return the same gateway routing entry as the one we're trying to resolve
in ether_output(). Hence this would set 'rt-rt_gwroute' to point to
'rt'.

This can later lead to a panic when rtrequest1() is processing the
RTM_DELETE request. RTFREE() of the 'rt-rt_gwroute' would return the
memory to the pool if RTF_UP flag is not set. Back in rtrequest1(),
dereferencing 'rt' would access freed memory.


There should always exist a direct route to the gateway or else it is
unreachable. There is no such concept as a gateway to reach a gateway.
We can only route for the one next hop and never beyond. If this
requirement is fulfilled, a gateway routing entry can never reference
another gateway routing entry and hence there are no more self
references.

The patch below adds a check to ether_output(). The same modification
is also required for atm_output(), fddi_output(), and nd6_output(),
but the code is so much identical that I omitted the patches to them.

Regards,

Gerhard


RCS file: src/sys/net/if_ethersubr.c,v
retrieving revision 1.151
diff -u -p -r1.151 src/sys/net/if_ethersubr.c
--- src/sys/net/if_ethersubr.c  2011/07/09 01:47:18 1.151
+++ src/sys/net/if_ethersubr.c  2012/06/22 09:40:03
@@ -270,8 +270,19 @@ ether_output(ifp0, m0, dst, rt0)
lookup:
rt-rt_gwroute = rtalloc1(rt-rt_gateway,
RT_REPORT, ifp-if_rdomain);
-   if ((rt = rt-rt_gwroute) == NULL)
+   if (rt-rt_gwroute == NULL)
senderr(EHOSTUNREACH);
+
+   /*
+* There should be an immediate route to  
the

+* gateway.
+*/
+   if (rt-rt_gwroute-rt_flags   
RTF_GATEWAY) {

+   rtfree(rt-rt_gwroute);
+   rt-rt_gwroute = NULL;
+   senderr(EHOSTUNREACH);
+   }
+   rt = rt-rt_gwroute;
}
}
if (rt-rt_flags  RTF_REJECT)

--
genua
Gesellschaft fuer Netzwerk- und Unix-Administration mbH
Domagkstrasse 7, 85551 Kirchheim bei Muenchen
tel +49 89 991950-0, fax -999, www.genua.de
Geschaeftsfuehrer: Dr. Magnus Harlander, Dr. Michaela Harlander,
Bernhard Schneck. Amtsgericht Muenchen HRB 98238



Memory leak in snmpd(8)

2012-05-24 Thread Gerhard Roth

Hi,

with the OPENBSD-CARP-MIB a memory leak was introduced to snmpd(8):

RCS file: mib.c,v
retrieving revision 1.52
diff -u -p -r1.52 mib.c
--- mib.c   2012/03/20 03:01:26 1.52
+++ mib.c   2012/05/24 12:53:35
@@ -2713,7 +2713,7 @@ mib_carpiftable(struct oid *oid, struct ber_oid *o,
st
/* Get and verify the current row index */
idx = o-bo_id[OIDIDX_carpIfEntry];

-   if ((cif = mib_carpifget(cif, idx)) == NULL) {
+   if (mib_carpifget(cif, idx) == NULL) {
free(cif);
return (1);
}


Gerhard

--
GeNUA, Gesellschaft fCr Netzwerk- und Unix-Administration mbH
Domagkstrasse 7, 85551 Kirchheim bei Muenchen
tel +49 89 991950-0, fax -999, www.genua.de
Geschaeftsfuehrer: Dr. Magnus Harlander, Dr. Michaela Harlander,
Bernhard Schneck. Amtsgericht Muenchen HRB 98238



Re: Memory leak in snmpd(8)

2012-05-24 Thread Gerhard Roth

On Thu, 24 May 2012 16:16:02 +0200, Kenneth R Westerback
kwesterb...@rogers.com wrote:

On Thu, May 24, 2012 at 01:54:36PM +0200, Gerhard Roth wrote:

Hi,

with the OPENBSD-CARP-MIB a memory leak was introduced to snmpd(8):

RCS file: mib.c,v
retrieving revision 1.52
diff -u -p -r1.52 mib.c
--- mib.c   2012/03/20 03:01:26 1.52
+++ mib.c   2012/05/24 12:53:35
@@ -2713,7 +2713,7 @@ mib_carpiftable(struct oid *oid, struct ber_oid
*o,
st
/* Get and verify the current row index */
idx = o-bo_id[OIDIDX_carpIfEntry];

-   if ((cif = mib_carpifget(cif, idx)) == NULL) {
+   if (mib_carpifget(cif, idx) == NULL) {
free(cif);
return (1);
}


Gerhard



Calling mib_carpget() seems a tad over complex. Wouldn't the diff
below make it cleaner? Untested except by gcc.

And doesn't the socket 's' leak too, or does SIOCGVH returning -1
mean 's' was closed?

 Ken

Index: mib.c
===
RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.52
diff -u -p -r1.52 mib.c
--- mib.c   20 Mar 2012 03:01:26 -  1.52
+++ mib.c   24 May 2012 14:11:22 -
@@ -1360,7 +1360,7 @@ intmib_carpstats(struct oid *, struct
 int mib_carpiftable(struct oid *, struct ber_oid *, struct ber_element
**);
 int mib_carpifnum(struct oid *, struct ber_oid *, struct ber_element
**);
 struct carpif
-   *mib_carpifget(struct carpif *, u_int);
+   *mib_carpifget(u_int);
 int mib_memiftable(struct oid *, struct ber_oid *, struct ber_element
**);
static struct oid openbsd_mib[] = {
@@ -2647,9 +2647,10 @@ mib_carpifnum(struct oid *oid, struct be
 }
struct carpif *
-mib_carpifget(struct carpif *cif, u_int idx)
+mib_carpifget(u_int idx)
 {
struct kif  *kif;
+   struct carpif   *cif;
int  s;
struct ifreq ifr;
struct carpreq   carpr;
@@ -2692,9 +2693,12 @@ mib_carpifget(struct carpif *cif, u_int
if (ioctl(s, SIOCGVH, (caddr_t)ifr) == -1)
return (NULL);
-   memset(cif, 0, sizeof(struct carpif));
-   memcpy(cif-carpr, carpr, sizeof(struct carpreq));
-   memcpy(cif-kif, kif, sizeof(struct kif));
+   cif = malloc(sizeof(struct carpif));
+   if (cif != NULL) {
+   memset(cif, 0, sizeof(struct carpif));
+   memcpy(cif-carpr, carpr, sizeof(struct carpreq));
+   memcpy(cif-kif, kif, sizeof(struct kif));
+   }
close(s);
@@ -2707,16 +2711,11 @@ mib_carpiftable(struct oid *oid, struct
u_int32_tidx;
struct carpif   *cif;
-   if ((cif = malloc(sizeof(struct carpif))) == NULL)
-   return (1);
-
/* Get and verify the current row index */
idx = o-bo_id[OIDIDX_carpIfEntry];
-   if ((cif = mib_carpifget(cif, idx)) == NULL) {
-   free(cif);
+   if ((cif = mib_carpifget(idx)) == NULL)
return (1);
-   }
/* Tables need to prepend the OID on their own */
o-bo_id[OIDIDX_carpIfEntry] = cif-kif.if_index;



Hi Ken,

I like your patch; it's better than mine.

And you are right about the socket fd leak. If an ioctl()
would close the filedes passed in that would be a very
awkward API.

Gerhard

--
GeNUA, Gesellschaft fCr Netzwerk- und Unix-Administration mbH
Domagkstrasse 7, 85551 Kirchheim bei Muenchen
tel +49 89 991950-0, fax -999, www.genua.de
Geschaeftsfuehrer: Dr. Magnus Harlander, Dr. Michaela Harlander,
Bernhard Schneck. Amtsgericht Muenchen HRB 98238



<    1   2