Re: undocumented (?) test -e behaviour with symbolic links

2016-09-30 Thread john slee
So it does. Not sure how I missed that, but I did. Oh well. Thanks :-/

John

On 1 October 2016 at 14:31, Theo Buehler  wrote:

> On Sat, Oct 01, 2016 at 01:38:49PM +1000, john slee wrote:
> > Not sure if folks are interested in this or not, but it sure caused me
> some
> > angst this morning. OSX has the same behaviour and also doesn't document
> > it. I assume it has been that way for a long, long time.
> >
> > My first patch. Thanks for all the cool stuff :-)
> >
> > Index: bin/test/test.1
> > ===
> > RCS file: /cvs/src/bin/test/test.1,v
> > retrieving revision 1.33
> > diff -u -p -r1.33 test.1
> > --- bin/test/test.1 16 Aug 2016 18:51:25 -  1.33
> > +++ bin/test/test.1 1 Oct 2016 03:37:23 -
> > @@ -92,7 +92,9 @@ exists and is a directory.
> >  .It Fl e Ar file
> >  True if
> >  .Ar file
> > -exists (regardless of type).
> > +exists, unless
> > +.Ar file
> > +is a dangling symbolic link.
>
> Thanks, but I think that we document it.  It seems unnecessary and
> inconsistent to add that caveat only to -e.  The manual says explicitly:
>
>  Symbolic links are followed for all primaries except -h and -L.
>
> So if your file is a dangling symbolic link, it is followed, and since
> the file it points to doesn't exist, the expression evaluates to false.
>
> POSIX is also unambiguous about this behavior:
>
>-e pathname
>  True if pathname resolves to an existing directory entry.
>  False if pathname cannot be resolved.
>
>[...]
>
>With the exception of the -h pathname and -L pathname primaries, if
> a
>pathname argument is a symbolic link, test shall evaluate the
>expression by resolving the symbolic link and using the file
> referenced
>by the link.
>
> >  .It Fl f Ar file
> >  True if
> >  .Ar file
>
>


Re: undocumented (?) test -e behaviour with symbolic links

2016-09-30 Thread Theo Buehler
On Sat, Oct 01, 2016 at 01:38:49PM +1000, john slee wrote:
> Not sure if folks are interested in this or not, but it sure caused me some
> angst this morning. OSX has the same behaviour and also doesn't document
> it. I assume it has been that way for a long, long time.
> 
> My first patch. Thanks for all the cool stuff :-)
>
> Index: bin/test/test.1
> ===
> RCS file: /cvs/src/bin/test/test.1,v
> retrieving revision 1.33
> diff -u -p -r1.33 test.1
> --- bin/test/test.1 16 Aug 2016 18:51:25 -  1.33
> +++ bin/test/test.1 1 Oct 2016 03:37:23 -
> @@ -92,7 +92,9 @@ exists and is a directory.
>  .It Fl e Ar file
>  True if
>  .Ar file
> -exists (regardless of type).
> +exists, unless
> +.Ar file
> +is a dangling symbolic link.

Thanks, but I think that we document it.  It seems unnecessary and
inconsistent to add that caveat only to -e.  The manual says explicitly:

 Symbolic links are followed for all primaries except -h and -L.

So if your file is a dangling symbolic link, it is followed, and since
the file it points to doesn't exist, the expression evaluates to false.

POSIX is also unambiguous about this behavior:

   -e pathname
 True if pathname resolves to an existing directory entry.
 False if pathname cannot be resolved.

   [...]

   With the exception of the -h pathname and -L pathname primaries, if a
   pathname argument is a symbolic link, test shall evaluate the
   expression by resolving the symbolic link and using the file referenced
   by the link.

>  .It Fl f Ar file
>  True if
>  .Ar file



undocumented (?) test -e behaviour with symbolic links

2016-09-30 Thread john slee
Not sure if folks are interested in this or not, but it sure caused me some
angst this morning. OSX has the same behaviour and also doesn't document
it. I assume it has been that way for a long, long time.

My first patch. Thanks for all the cool stuff :-)

Index: bin/test/test.1
===
RCS file: /cvs/src/bin/test/test.1,v
retrieving revision 1.33
diff -u -p -r1.33 test.1
--- bin/test/test.1 16 Aug 2016 18:51:25 -  1.33
+++ bin/test/test.1 1 Oct 2016 03:37:23 -
@@ -92,7 +92,9 @@ exists and is a directory.
 .It Fl e Ar file
 True if
 .Ar file
-exists (regardless of type).
+exists, unless
+.Ar file
+is a dangling symbolic link.
 .It Fl f Ar file
 True if
 .Ar file


let PF to send challenge ack

2016-09-30 Thread Alexandr Nedvedicky
Hello,

patch below makes life easier for clients, which always use same source port,
when talking to server (e.g. think of NFS). The scenario we are dealing with
is as follows:

- client mounts remote NFS share

- there is a PF sitting between client and NFS server. the mount
  operation in earlier step has created a state in PF

- client panics/loses power or whatever catastrophe happens preventing
  client to properly cease NFS sessions

- client boots up and attempts to mount same NFS share

- the SYN packet sent by client gets blocked by PF as it hits
  existing session, which is in established state.

The patch makes PF to send 'challenge ACK' for SYN packet, which matches
session in established state. Challenge ACK will have the last sequence numbers
firewall remembers for existing session. Client should response with RST to
challenge ACK. The RST will make firewall and remote server to kill old
session. Then client will retransmit SYN packet. The retransmitted SYN will
create a new state in PF and world will be nice and shiny again.

The challenge ACK sent by firewall essentially emulates behavior of NFS
server TCP stack. NFS server would also response with challenge ACK upon
reception of SYN, which matches existing connection.

The patch also comes with test case. I've just learned it's bit tricky
to use scapy for sending TCP packets. There are basically two pitfalls:

- the session established by scapy interferes with host's TCP stack,
where scapy is running. Host's TCP answers with RST to SYN-ACK,
which is sent as a response to scapy's SYN. Adding PF rule, which
blocks outbound RST solves the problem.

- the scapy's sr() function (send and receive) is very smart not
to receive a challenge_ack sent by remote PF. Test case uses
sniffer to verify remote PF answers with challenge ACK. If you
are not interested in further details stop reading here.

All packets (I should rather say protocol data units) are objects in scapy.
There is a method .answers(). Every protocol payload has its specific
answers() method. There is answers() method for IP, for UDP, for TCP, ...
Looking at answers() method for TCP we see something disappointing for
challenge ACK:

475def answers(self, other):
476if not isinstance(other, TCP):
477return 0
478if conf.checkIPsrc:
479if not ((self.sport == other.dport) and
480(self.dport == other.sport)):
481return 0
482if (abs(other.seq-self.ack) > 2+len(other.payload)):
483return 0
484return 1

there is a simple check for sequence number at line 482. The test prevents
sr() function to work for test case. The test sends SYN packet with
SeqNo 10, however PF answers with ACK 1000. I've tried to derive
TCP_OOW class (TCP out of window) with answers() method without check for
sequence numbers. Unfortunately I could not figure out a way to tell sr() to
use my TCP_OOW instead of default TCP class. I gave up and opted for poor man's
solution to use a sniffer instead.

thanks and
regards
sasha

8<---8<---8<--8<
diff -r a4cc143dcba1 src/sys/net/pf.c
--- a/src/sys/net/pf.c  Fri Sep 30 22:21:48 2016 +0200
+++ b/src/sys/net/pf.c  Fri Sep 30 22:22:49 2016 +0200
@@ -2815,6 +2815,25 @@ pf_send_tcp(const struct pf_rule *r, sa_
}
 }
 
+static void
+pf_send_challenge_ack(struct pf_pdesc *pd, struct pf_state *s,
+struct pf_state_peer *src, struct pf_state_peer *dst)
+{
+   /*
+* We are sending challenge ACK as a response to SYN packet, which
+* matches existing state (modulo TCP window check). Therefore packet
+* must be sent on behalf of destination.
+*
+* We expect sender to remain either silent, or send RST packet
+* so both, firewall and remote peer, can purge dead state from
+* memory.
+*/
+   pf_send_tcp(s->rule.ptr, pd->af, pd->dst, pd->src,
+   pd->hdr.tcp->th_dport, pd->hdr.tcp->th_sport, dst->seqlo,
+   src->seqlo, TH_ACK, 0, 0, s->rule.ptr->return_ttl, 1, 0,
+   pd->rdomain);
+}
+
 void
 pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
 struct pf_rule *r, u_int rdomain)
@@ -4637,20 +4656,34 @@ pf_test_state(struct pf_pdesc *pd, struc
case IPPROTO_TCP:
if ((action = pf_synproxy(pd, state, reason)) != PF_PASS)
return (action); 
-   if (((pd->hdr.tcp->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) &&
-   dst->state >= TCPS_FIN_WAIT_2 &&
-   src->state >= TCPS_FIN_WAIT_2) {
-   if (pf_status.debug >= LOG_NOTICE) {
-   log(LOG_NOTICE, "pf: state reuse ");
-  

Re: Fix kbd -l

2016-09-30 Thread Mark Kettenis
> From: Jeremie Courreges-Anglas 
> Date: Fri, 30 Sep 2016 17:00:45 +0200
> 
> Mark Kettenis  writes:
> 
> [...]
> 
> >> > -for (i = 0; kbdenc_tab[i].value; i++)
> >> > -printf("%s\n", kbdenc_tab[i].name);
> >> > +for (i = 0; i < encs->nencodings; i++) {
> >> > +n = _tab[0];
> >> > +found = 0;
> >> > +encoding = encs->encodings[i];
> >> > +while (n->value) {
> >> > +if (n->value == KB_ENCODING(encoding)) {
> >> > +printf("%s", n->name);
> >> > +found++;
> >> > +}
> >> > +n++;
> >> > +}
> >> 
> >> This looks a lot like a for loop.
> >
> > Right.  But there are some similar loops that are already written this
> > way.  So I left it the way I wrote^H^H^H^H^Hcopied it.  Feel free to
> > submite a separate patch that fixes this.
> 
> Ah, I see.  Here's the diff.

Thanks!  ok kettenis@

> Index: kbd_wscons.c
> ===
> RCS file: /cvs/src/sbin/kbd/kbd_wscons.c,v
> retrieving revision 1.31
> diff -u -p -p -u -r1.31 kbd_wscons.c
> --- kbd_wscons.c  30 Sep 2016 12:07:23 -  1.31
> +++ kbd_wscons.c  30 Sep 2016 14:55:03 -
> @@ -100,27 +100,23 @@ kbd_show_enc(struct wskbd_encoding_data 
>   kbtype_tab[idx]);
>  
>   for (i = 0; i < encs->nencodings; i++) {
> - n = _tab[0];
>   found = 0;
>   encoding = encs->encodings[i];
> - while (n->value) {
> + for (n = _tab[0]; n->value; n++) {
>   if (n->value == KB_ENCODING(encoding)) {
>   printf("%s", n->name);
>   found++;
>   }
> - n++;
>   }
>   if (found == 0)
>   printf("", KB_ENCODING(encoding));
> - n = _tab[0];
>   found = 0;
>   variant = KB_VARIANT(encoding);
> - while (n->value) {
> + for (n = _tab[0]; n->value; n++) {
>   if ((n->value & KB_VARIANT(encoding)) == n->value) {
>   printf(".%s", n->name);
>   variant &= ~n->value;
>   }
> - n++;
>   }
>   if (variant != 0)
>   printf(".", variant);
> @@ -248,11 +244,9 @@ kbd_set(char *name, int verbose)
>   *b++ = *c++;
>   *b = '\0';
>   v = 0;
> - n = _tab[0];
> - while (n->value) {
> + for (n = _tab[0]; n->value; n++) {
>   if (strcmp(n->name, buf) == 0)
>   v = n->value;
> - n++;
>   }
>   if (v == 0)
>   errx(1, "unknown variant %s", buf);
> 
> -- 
> jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE
> 



Re: Ignored .Pp in ksh.1

2016-09-30 Thread Jason McIntyre
On Fri, Sep 30, 2016 at 05:19:22PM +0200, Jan Stary wrote:
> The diff below removes a .Pp before an .It
> which mandoc complains about and ignores.
> 
>   Jan
> 

fixed, thanks.
jmc

> 
> Index: ksh.1
> ===
> RCS file: /cvs/src/bin/ksh/ksh.1,v
> retrieving revision 1.181
> diff -u -p -r1.181 ksh.1
> --- ksh.1 27 Sep 2016 23:58:38 -  1.181
> +++ ksh.1 30 Sep 2016 15:16:39 -
> @@ -4717,7 +4717,6 @@ offer a selection of signal names for th
>  .Xr kill 1 :
>  .Pp
>  .Dl set -A complete_kill_1 -- -9 -HUP -INFO -KILL -TERM
> -.Pp
>  .It complete-command: ^X^[
>  Automatically completes as much as is unique of the command name having the
>  partial word up to the cursor as its prefix, as in the
> 



Re: clang, stack limit and inlining

2016-09-30 Thread Theo de Raadt
> Diff below is a possible way to fix this.  But in a way we're cheating
> here since we'll still consume more than 2047 bytes of stack space
> when we descend into wskbd_initmute().  So perhaps we should rewrite
> this code to dynamically allocate the mixer_devinfo structs?

yes, it should be dynamically allocated.



Ignored .Pp in ksh.1

2016-09-30 Thread Jan Stary
The diff below removes a .Pp before an .It
which mandoc complains about and ignores.

Jan


Index: ksh.1
===
RCS file: /cvs/src/bin/ksh/ksh.1,v
retrieving revision 1.181
diff -u -p -r1.181 ksh.1
--- ksh.1   27 Sep 2016 23:58:38 -  1.181
+++ ksh.1   30 Sep 2016 15:16:39 -
@@ -4717,7 +4717,6 @@ offer a selection of signal names for th
 .Xr kill 1 :
 .Pp
 .Dl set -A complete_kill_1 -- -9 -HUP -INFO -KILL -TERM
-.Pp
 .It complete-command: ^X^[
 Automatically completes as much as is unique of the command name having the
 partial word up to the cursor as its prefix, as in the



Re: my final netinet6 bcopy->memcpy

2016-09-30 Thread David Hill
Ping.

On Mon, Sep 19, 2016 at 09:22:50PM -0400, David Hill wrote:
> Hello -
> 
> Here are the final bcopy->memcpy conversions in netinet6 that I am
> comfortable with.  There is also one (bcmp()) to (memcmp() != 0)
> conversion since the memory is not overlapping.
> 
> This, with the last netinet6 diff, has dropped the number of bcopy()
> calls from 62 to 29 in netinet6/
> 
> Index: icmp6.c
> ===
> RCS file: /cvs/src/sys/netinet6/icmp6.c,v
> retrieving revision 1.190
> diff -u -p -r1.190 icmp6.c
> --- icmp6.c   24 Aug 2016 09:38:29 -  1.190
> +++ icmp6.c   20 Sep 2016 01:00:36 -
> @@ -1401,7 +1401,7 @@ icmp6_redirect_input(struct mbuf *m, int
>   bzero(, sizeof(sin6));
>   sin6.sin6_family = AF_INET6;
>   sin6.sin6_len = sizeof(struct sockaddr_in6);
> - bcopy(, _addr, sizeof(reddst6));
> + memcpy(_addr, , sizeof(reddst6));
>   rt = rtalloc(sin6tosa(), 0, m->m_pkthdr.ph_rtableid);
>   if (rt) {
>   if (rt->rt_gateway == NULL ||
> @@ -1509,9 +1509,9 @@ icmp6_redirect_input(struct mbuf *m, int
>   sdst.sin6_family = sgw.sin6_family = ssrc.sin6_family = 
> AF_INET6;
>   sdst.sin6_len = sgw.sin6_len = ssrc.sin6_len =
>   sizeof(struct sockaddr_in6);
> - bcopy(, _addr, sizeof(struct in6_addr));
> - bcopy(, _addr, sizeof(struct in6_addr));
> - bcopy(, _addr, sizeof(struct in6_addr));
> + memcpy(_addr, , sizeof(struct in6_addr));
> + memcpy(_addr, , sizeof(struct in6_addr));
> + memcpy(_addr, , sizeof(struct in6_addr));
>   rtredirect(sin6tosa(), sin6tosa(), sin6tosa(),
>   , m->m_pkthdr.ph_rtableid);
>  
> @@ -1528,7 +1528,7 @@ icmp6_redirect_input(struct mbuf *m, int
>   bzero(, sizeof(sdst));
>   sdst.sin6_family = AF_INET6;
>   sdst.sin6_len = sizeof(struct sockaddr_in6);
> - bcopy(, _addr, sizeof(struct in6_addr));
> + memcpy(_addr, , sizeof(struct in6_addr));
>   pfctlinput(PRC_REDIRECT_HOST, sin6tosa());
>   }
>  
> Index: in6.c
> ===
> RCS file: /cvs/src/sys/netinet6/in6.c,v
> retrieving revision 1.192
> diff -u -p -r1.192 in6.c
> --- in6.c 4 Sep 2016 10:32:01 -   1.192
> +++ in6.c 20 Sep 2016 01:00:36 -
> @@ -1029,9 +1029,9 @@ in6_lifaddr_ioctl(u_long cmd, caddr_t da
>  
>   /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
>   bzero(, sizeof(ifra));
> - bcopy(iflr->iflr_name, ifra.ifra_name, sizeof(ifra.ifra_name));
> + memcpy(ifra.ifra_name, iflr->iflr_name, sizeof(ifra.ifra_name));
>  
> - bcopy(>addr, _addr,
> + memcpy(_addr, >addr,
>   ((struct sockaddr *)>addr)->sa_len);
>   if (hostid) {
>   /* fill in hostid part */
> @@ -1042,7 +1042,7 @@ in6_lifaddr_ioctl(u_long cmd, caddr_t da
>   }
>  
>   if (((struct sockaddr *)>dstaddr)->sa_family) {   /*XXX*/
> - bcopy(>dstaddr, _dstaddr,
> + memcpy(_dstaddr, >dstaddr,
>   ((struct sockaddr *)>dstaddr)->sa_len);
>   if (hostid) {
>   ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] =
> @@ -1073,14 +1073,14 @@ in6_lifaddr_ioctl(u_long cmd, caddr_t da
>   in6_prefixlen2mask(, iflr->prefixlen);
>  
>   sin6 = (struct sockaddr_in6 *)>addr;
> - bcopy(>sin6_addr, , sizeof(match));
> + memcpy(, >sin6_addr, sizeof(match));
>   match.s6_addr32[0] &= mask.s6_addr32[0];
>   match.s6_addr32[1] &= mask.s6_addr32[1];
>   match.s6_addr32[2] &= mask.s6_addr32[2];
>   match.s6_addr32[3] &= mask.s6_addr32[3];
>  
>   /* if you set extra bits, that's wrong */
> - if (bcmp(, >sin6_addr, sizeof(match)))
> + if (memcmp(, >sin6_addr, sizeof(match)) != 
> 0)
>   return EINVAL;
>  
>   cmp = 1;
> @@ -1092,7 +1092,7 @@ in6_lifaddr_ioctl(u_long cmd, caddr_t da
>   /* on deleting an address, do exact match */
>   in6_prefixlen2mask(, 128);
>   sin6 = (struct sockaddr_in6 *)>addr;
> - bcopy(>sin6_addr, , sizeof(match));
> + memcpy(, >sin6_addr, sizeof(match));
>  
>   cmp = 1;
>   }
> @@ -1104,7 +1104,7 @@ in6_lifaddr_ioctl(u_long cmd, caddr_t da
>   if (!cmp)
>   break;
>  
> - bcopy(IFA_IN6(ifa), 

Re: Fix kbd -l

2016-09-30 Thread Jeremie Courreges-Anglas
Mark Kettenis  writes:

[...]

>> > -  for (i = 0; kbdenc_tab[i].value; i++)
>> > -  printf("%s\n", kbdenc_tab[i].name);
>> > +  for (i = 0; i < encs->nencodings; i++) {
>> > +  n = _tab[0];
>> > +  found = 0;
>> > +  encoding = encs->encodings[i];
>> > +  while (n->value) {
>> > +  if (n->value == KB_ENCODING(encoding)) {
>> > +  printf("%s", n->name);
>> > +  found++;
>> > +  }
>> > +  n++;
>> > +  }
>> 
>> This looks a lot like a for loop.
>
> Right.  But there are some similar loops that are already written this
> way.  So I left it the way I wrote^H^H^H^H^Hcopied it.  Feel free to
> submite a separate patch that fixes this.

Ah, I see.  Here's the diff.


Index: kbd_wscons.c
===
RCS file: /cvs/src/sbin/kbd/kbd_wscons.c,v
retrieving revision 1.31
diff -u -p -p -u -r1.31 kbd_wscons.c
--- kbd_wscons.c30 Sep 2016 12:07:23 -  1.31
+++ kbd_wscons.c30 Sep 2016 14:55:03 -
@@ -100,27 +100,23 @@ kbd_show_enc(struct wskbd_encoding_data 
kbtype_tab[idx]);
 
for (i = 0; i < encs->nencodings; i++) {
-   n = _tab[0];
found = 0;
encoding = encs->encodings[i];
-   while (n->value) {
+   for (n = _tab[0]; n->value; n++) {
if (n->value == KB_ENCODING(encoding)) {
printf("%s", n->name);
found++;
}
-   n++;
}
if (found == 0)
printf("", KB_ENCODING(encoding));
-   n = _tab[0];
found = 0;
variant = KB_VARIANT(encoding);
-   while (n->value) {
+   for (n = _tab[0]; n->value; n++) {
if ((n->value & KB_VARIANT(encoding)) == n->value) {
printf(".%s", n->name);
variant &= ~n->value;
}
-   n++;
}
if (variant != 0)
printf(".", variant);
@@ -248,11 +244,9 @@ kbd_set(char *name, int verbose)
*b++ = *c++;
*b = '\0';
v = 0;
-   n = _tab[0];
-   while (n->value) {
+   for (n = _tab[0]; n->value; n++) {
if (strcmp(n->name, buf) == 0)
v = n->value;
-   n++;
}
if (v == 0)
errx(1, "unknown variant %s", buf);

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



Re: Fix kbd -l

2016-09-30 Thread Mark Kettenis
> From: Jeremie Courreges-Anglas 
> Date: Fri, 30 Sep 2016 13:32:57 +0200
> 
> Mark Kettenis  writes:
> 
> >> Date: Thu, 29 Sep 2016 14:19:43 +0200 (CEST)
> >> From: Mark Kettenis 
> >> 
> >> This diff adds a WSKBDIO_GETENCODINGS ioctl and uses it to print a
> >> list of supported encodings like the old kvm groveling code did.  The
> >> ioctl will clamp the number of entries that are returns to the number
> >> that was passed in.  This means that if the number returned is the
> >> same as the number passed in, there might be more entries and you
> >> probably want to retry with a larger buffer.  The new implementation
> >> does this.
> >
> > Thanks to tb@ for testing this on a ramdisk.  Here is a slightly
> > better diff that frees the allocated memory.
> >
> > ok?
> 
> Looks fine to me, ok jca@

Thanks,

> Nitpicking below,

I selectively applied those; see comments below.

> > Index: sbin/kbd/kbd_wscons.c
> > ===
> > RCS file: /cvs/src/sbin/kbd/kbd_wscons.c,v
> > retrieving revision 1.30
> > diff -u -p -r1.30 kbd_wscons.c
> > --- sbin/kbd/kbd_wscons.c   27 Sep 2016 22:03:49 -  1.30
> > +++ sbin/kbd/kbd_wscons.c   29 Sep 2016 18:12:48 -
> > @@ -34,6 +34,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  
> > @@ -82,31 +83,83 @@ struct nameint kbdvar_tab[] = {
> >  
> >  extern char *__progname;
> >  
> > -void   kbd_show_enc(int idx);
> > +void   kbd_show_enc(struct wskbd_encoding_data *encs, int idx);
> > +void   kbd_get_encs(int fd, struct wskbd_encoding_data *encs);
> >  void   kbd_list(void);
> >  void   kbd_set(char *name, int verbose);
> >  
> >  void
> > -kbd_show_enc(int idx)
> > +kbd_show_enc(struct wskbd_encoding_data *encs, int idx)
> >  {
> > +   int found;
> > +   kbd_t encoding, variant;
> > +   struct nameint *n;
> > int i;
> >  
> > printf("tables available for %s keyboard:\nencoding\n\n",
> > kbtype_tab[idx]);
> >  
> > -   for (i = 0; kbdenc_tab[i].value; i++)
> > -   printf("%s\n", kbdenc_tab[i].name);
> > +   for (i = 0; i < encs->nencodings; i++) {
> > +   n = _tab[0];
> > +   found = 0;
> > +   encoding = encs->encodings[i];
> > +   while (n->value) {
> > +   if (n->value == KB_ENCODING(encoding)) {
> > +   printf("%s", n->name);
> > +   found++;
> > +   }
> > +   n++;
> > +   }
> 
> This looks a lot like a for loop.

Right.  But there are some similar loops that are already written this
way.  So I left it the way I wrote^H^H^H^H^Hcopied it.  Feel free to
submite a separate patch that fixes this.



clang, stack limit and inlining

2016-09-30 Thread Mark Kettenis
We compile out kernel with -Wframe-larger-than=2047 to make sure we
don't write stupid code that blows the kernel stack.  Now clang thinks
it is clever and considers it a good idea to inline functions when the
function and the caller live in the same source file.  A particular
case where this happens is in audio.c, where wskbd_initmute() gets
inlined into wskbd_initvol().  And this inlining pushes things over
the stack limit, since struct mixer_devinfo is quite large and it now
needs three copies of that structure.

Diff below is a possible way to fix this.  But in a way we're cheating
here since we'll still consume more than 2047 bytes of stack space
when we descend into wskbd_initmute().  So perhaps we should rewrite
this code to dynamically allocate the mixer_devinfo structs?


Index: sys/cdefs.h
===
RCS file: /cvs/src/sys/sys/cdefs.h,v
retrieving revision 1.39
diff -u -p -r1.39 cdefs.h
--- sys/cdefs.h 18 Apr 2014 11:51:17 -  1.39
+++ sys/cdefs.h 30 Sep 2016 14:22:28 -
@@ -160,6 +160,12 @@
 #define __only_inline  static __inline
 #endif
 
+#if __GNUC_PREREQ__(3, 0)
+#define __noinline __attribute__((__noinline__))
+#else
+#define __noinline
+#endif
+
 /*
  * GNU C version 2.96 adds explicit branch prediction so that
  * the CPU back-end can hint the processor and also so that
Index: dev/audio.c
===
RCS file: /cvs/src/sys/dev/audio.c,v
retrieving revision 1.153
diff -u -p -r1.153 audio.c
--- dev/audio.c 19 Sep 2016 06:46:43 -  1.153
+++ dev/audio.c 30 Sep 2016 14:22:28 -
@@ -1783,7 +1783,7 @@ audiopoll(dev_t dev, int events, struct 
 }
 
 #if NWSKBD > 0
-int
+__noinline int
 wskbd_initmute(struct audio_softc *sc, struct mixer_devinfo *vol)
 {
struct mixer_devinfo mi;



Re: snmpd source address

2016-09-30 Thread Jeremie Courreges-Anglas
Jeremie Courreges-Anglas  writes:

> j...@wxcvbn.org (Jeremie Courreges-Anglas) writes:
>
>> SNMP uses UDP and snmpd listens on a single address.  This means that
>> you can have issues with the source address of the replies sent by
>> snmpd.  "listen on $loopback_address":
>>
>>   http://marc.info/?l=openbsd-misc=147445870822415=2
>>
>> seems to be unsufficient, but I don't understand why it would fail.
>>
>> The diff below should fix the source address selection for replies.
>> Configuring the source address for traps is a different problem and will
>> be implemented in a different diff.
>
> Updated diff that implements a "source-address" parameter for trap
> receivers, as discussed with Reyk.
>
>> WIP, only tested on a single box so far.  Thoughts / oks?
>
> source-address lightly tested with:
> trap receiver 127.0.0.1
> trap receiver 127.0.0.1 source-address 192.168.0.44
> trap receiver fe80::1%lo0 source-address ::1
>
> Comments and test reports welcome.

Notes regarding source-address:
- only try to handle an address, not a hostname.  I didn't want
  to handle the additional complexity as I'm not sure it's worth it.
- say we have "trap receiver somehostname source-address fd00::1".
  Should we try to filter out potential IPv4 addresses and find an
  appropriate IPv6 address?  The diff below would error out if the first
  record found is an IPv4.

>
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
> retrieving revision 1.39
> diff -u -p -r1.39 parse.y
> --- parse.y   21 Jun 2016 21:35:25 -  1.39
> +++ parse.y   30 Sep 2016 13:33:28 -
> @@ -98,9 +98,10 @@ static int  nctlsocks = 0;
>  struct address   *host_v4(const char *);
>  struct address   *host_v6(const char *);
>  int   host_dns(const char *, struct addresslist *,
> - int, in_port_t, struct ber_oid *, char *);
> + int, in_port_t, struct ber_oid *, char *,
> + struct address *);
>  int   host(const char *, struct addresslist *,
> - int, in_port_t, struct ber_oid *, char *);
> + int, in_port_t, struct ber_oid *, char *, char *);
>  
>  typedef struct {
>   union {
> @@ -127,10 +128,11 @@ typedef struct {
>  %token   SYSTEM CONTACT DESCR LOCATION NAME OBJECTID SERVICES RTFILTER
>  %token   READONLY READWRITE OCTETSTRING INTEGER COMMUNITY TRAP RECEIVER
>  %token   SECLEVEL NONE AUTH ENC USER AUTHKEY ENCKEY ERROR DISABLED
> -%token   SOCKET RESTRICTED AGENTX HANDLE DEFAULT
> +%token   SOCKET RESTRICTED AGENTX HANDLE DEFAULT SRCADDR
>  %token STRING
>  %token NUMBER
>  %type  hostcmn
> +%type  srcaddr
>  %type  optwrite yesno seclevel socktype
>  %typeobjtype cmd
>  %type oid hostoid trapoid
> @@ -200,7 +202,8 @@ main  : LISTEN ON STRING  {
>   struct address  *h;
>  
>   TAILQ_INIT();
> - if (host($3, , 1, SNMPD_PORT, NULL, NULL) <= 0) {
> + if (host($3, , 1, SNMPD_PORT, NULL, NULL, NULL)
> + <= 0) {
>   yyerror("invalid ip address: %s", $3);
>   free($3);
>   YYERROR;
> @@ -445,9 +448,13 @@ hostcmn  : /* empty */   
> { $$ = NULL; }
>   | COMMUNITY STRING  { $$ = $2; }
>   ;
>  
> -hostdef  : STRING hostoid hostcmn{
> +srcaddr  : /* empty */   { $$ = NULL; }
> + | SRCADDR STRING{ $$ = $2; }
> + ;
> +
> +hostdef  : STRING hostoid hostcmn srcaddr{
>   if (host($1, hlist, 1,
> - SNMPD_TRAPPORT, $2, $3) <= 0) {
> + SNMPD_TRAPPORT, $2, $3, $4) <= 0) {
>   yyerror("invalid host: %s", $1);
>   free($1);
>   YYERROR;
> @@ -636,6 +643,7 @@ lookup(char *s)
>   { "seclevel",   SECLEVEL },
>   { "services",   SERVICES },
>   { "socket", SOCKET },
> + { "source-address", SRCADDR },
>   { "string", OCTETSTRING },
>   { "system", SYSTEM },
>   { "trap",   TRAP },
> @@ -1151,7 +1159,7 @@ host_v6(const char *s)
>  
>  int
>  host_dns(const char *s, struct addresslist *al, int max,
> -  in_port_t port, struct ber_oid *oid, char *cmn)
> + in_port_t port, struct ber_oid *oid, char *cmn, struct address *src)
>  {
>   struct addrinfo  hints, *res0, *res;
>   int  error, cnt 

Re: snmpd source address

2016-09-30 Thread Jeremie Courreges-Anglas
j...@wxcvbn.org (Jeremie Courreges-Anglas) writes:

> SNMP uses UDP and snmpd listens on a single address.  This means that
> you can have issues with the source address of the replies sent by
> snmpd.  "listen on $loopback_address":
>
>   http://marc.info/?l=openbsd-misc=147445870822415=2
>
> seems to be unsufficient, but I don't understand why it would fail.
>
> The diff below should fix the source address selection for replies.
> Configuring the source address for traps is a different problem and will
> be implemented in a different diff.

Updated diff that implements a "source-address" parameter for trap
receivers, as discussed with Reyk.

> WIP, only tested on a single box so far.  Thoughts / oks?

source-address lightly tested with:
trap receiver 127.0.0.1
trap receiver 127.0.0.1 source-address 192.168.0.44
trap receiver fe80::1%lo0 source-address ::1

Comments and test reports welcome.


Index: parse.y
===
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.39
diff -u -p -r1.39 parse.y
--- parse.y 21 Jun 2016 21:35:25 -  1.39
+++ parse.y 30 Sep 2016 13:33:28 -
@@ -98,9 +98,10 @@ static intnctlsocks = 0;
 struct address *host_v4(const char *);
 struct address *host_v6(const char *);
 int host_dns(const char *, struct addresslist *,
-   int, in_port_t, struct ber_oid *, char *);
+   int, in_port_t, struct ber_oid *, char *,
+   struct address *);
 int host(const char *, struct addresslist *,
-   int, in_port_t, struct ber_oid *, char *);
+   int, in_port_t, struct ber_oid *, char *, char *);
 
 typedef struct {
union {
@@ -127,10 +128,11 @@ typedef struct {
 %token SYSTEM CONTACT DESCR LOCATION NAME OBJECTID SERVICES RTFILTER
 %token READONLY READWRITE OCTETSTRING INTEGER COMMUNITY TRAP RECEIVER
 %token SECLEVEL NONE AUTH ENC USER AUTHKEY ENCKEY ERROR DISABLED
-%token SOCKET RESTRICTED AGENTX HANDLE DEFAULT
+%token SOCKET RESTRICTED AGENTX HANDLE DEFAULT SRCADDR
 %token   STRING
 %token   NUMBER
 %typehostcmn
+%typesrcaddr
 %typeoptwrite yesno seclevel socktype
 %type  objtype cmd
 %type   oid hostoid trapoid
@@ -200,7 +202,8 @@ main: LISTEN ON STRING  {
struct address  *h;
 
TAILQ_INIT();
-   if (host($3, , 1, SNMPD_PORT, NULL, NULL) <= 0) {
+   if (host($3, , 1, SNMPD_PORT, NULL, NULL, NULL)
+   <= 0) {
yyerror("invalid ip address: %s", $3);
free($3);
YYERROR;
@@ -445,9 +448,13 @@ hostcmn: /* empty */   
{ $$ = NULL; }
| COMMUNITY STRING  { $$ = $2; }
;
 
-hostdef: STRING hostoid hostcmn{
+srcaddr: /* empty */   { $$ = NULL; }
+   | SRCADDR STRING{ $$ = $2; }
+   ;
+
+hostdef: STRING hostoid hostcmn srcaddr{
if (host($1, hlist, 1,
-   SNMPD_TRAPPORT, $2, $3) <= 0) {
+   SNMPD_TRAPPORT, $2, $3, $4) <= 0) {
yyerror("invalid host: %s", $1);
free($1);
YYERROR;
@@ -636,6 +643,7 @@ lookup(char *s)
{ "seclevel",   SECLEVEL },
{ "services",   SERVICES },
{ "socket", SOCKET },
+   { "source-address", SRCADDR },
{ "string", OCTETSTRING },
{ "system", SYSTEM },
{ "trap",   TRAP },
@@ -1151,7 +1159,7 @@ host_v6(const char *s)
 
 int
 host_dns(const char *s, struct addresslist *al, int max,
-in_port_t port, struct ber_oid *oid, char *cmn)
+   in_port_t port, struct ber_oid *oid, char *cmn, struct address *src)
 {
struct addrinfo  hints, *res0, *res;
int  error, cnt = 0;
@@ -1202,6 +1210,13 @@ host_dns(const char *s, struct addressli
memcpy(>sin6_addr, &((struct sockaddr_in6 *)
res->ai_addr)->sin6_addr, sizeof(struct in6_addr));
}
+   if (src != NULL) {
+   if (h->ss.ss_family != src->ss.ss_family) {
+   log_warnx("host and source-address family 
mismatch");
+   return (-1);
+   }
+   h->sa_srcaddr = src;
+   }
 
TAILQ_INSERT_HEAD(al, h, entry);

/etc/rc handling of kern.securelevel=2 (was: rc.securelevel example)

2016-09-30 Thread Jeremie Courreges-Anglas
j...@wxcvbn.org (Jeremie Courreges-Anglas) writes:

> Looks like it's not completely obvious how to set a custom securelevel,
> at least one user went the /etc/sysctl.conf way, which has the nasty
> side-effect of preventing the use of /etc/pf.conf.
>
> Should we add more belts and suspenders?

Dunno if adding an example is the right direction, but the /etc/rc part
would prevent people from shooting themselves in the foot.


Index: rc
===
RCS file: /cvs/src/etc/rc,v
retrieving revision 1.486
diff -u -p -r1.486 rc
--- rc  10 Jul 2016 09:08:18 -  1.486
+++ rc  24 Sep 2016 15:31:10 -
@@ -52,6 +52,12 @@ update_limit() {
 sysctl_conf() {
stripcom /etc/sysctl.conf |
while read _line; do
+   case $_line in
+   kern.securelevel=*)
+   echo "$_line ignored in /etc/sysctl.conf"
+   continue;;
+   esac
+
sysctl "$_line"
 
case $_line in


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



Re: Fix kbd -l

2016-09-30 Thread Jeremie Courreges-Anglas
Mark Kettenis  writes:

>> Date: Thu, 29 Sep 2016 14:19:43 +0200 (CEST)
>> From: Mark Kettenis 
>> 
>> This diff adds a WSKBDIO_GETENCODINGS ioctl and uses it to print a
>> list of supported encodings like the old kvm groveling code did.  The
>> ioctl will clamp the number of entries that are returns to the number
>> that was passed in.  This means that if the number returned is the
>> same as the number passed in, there might be more entries and you
>> probably want to retry with a larger buffer.  The new implementation
>> does this.
>
> Thanks to tb@ for testing this on a ramdisk.  Here is a slightly
> better diff that frees the allocated memory.
>
> ok?

Looks fine to me, ok jca@

Nitpicking below,

>
> Index: sys/dev/wscons/wsconsio.h
> ===
> RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v
> retrieving revision 1.75
> diff -u -p -r1.75 wsconsio.h
> --- sys/dev/wscons/wsconsio.h 14 Sep 2016 03:25:51 -  1.75
> +++ sys/dev/wscons/wsconsio.h 29 Sep 2016 18:12:48 -
> @@ -207,6 +207,12 @@ struct wskbd_backlight {
>  #define  WSKBD_TRANSLATED0
>  #define  WSKBD_RAW   1
>  
> +struct wskbd_encoding_data {
> + int nencodings;
> + kbd_t   *encodings;
> +};
> +#define WSKBDIO_GETENCODINGS _IOWR('W', 21, struct wskbd_encoding_data)
> +
>  /*
>   * Mouse ioctls (32 - 63)
>   */
> Index: sys/dev/wscons/wskbd.c
> ===
> RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v
> retrieving revision 1.83
> diff -u -p -r1.83 wskbd.c
> --- sys/dev/wscons/wskbd.c12 Dec 2015 12:30:18 -  1.83
> +++ sys/dev/wscons/wskbd.c29 Sep 2016 18:12:48 -
> @@ -1001,9 +1001,11 @@ wskbd_displayioctl(struct device *dev, u
>   struct wskbd_bell_data *ubdp, *kbdp;
>   struct wskbd_keyrepeat_data *ukdp, *kkdp;
>   struct wskbd_map_data *umdp;
> + struct wskbd_encoding_data *uedp;
>   kbd_t enc;
>   void *buf;
>   int len, error;
> + int count, i;

Maybe merge those two lines?

>  
>   switch (cmd) {
>   case WSKBDIO_BELL:
> @@ -1159,6 +1161,20 @@ getkeyrepeat:
>   wsmux_set_layout(sc->sc_base.me_parent, enc);
>  #endif
>   return (0);
> +
> + case WSKBDIO_GETENCODINGS:
> + uedp = (struct wskbd_encoding_data *)data;
> + for (count = 0; sc->id->t_keymap.keydesc[count].name; count++)
> + ;
> + if (uedp->nencodings > count)
> + uedp->nencodings = count;
> + for (i = 0; i < uedp->nencodings; i++) {
> + error = copyout(>id->t_keymap.keydesc[i].name,
> + >encodings[i], sizeof(kbd_t));
> + if (error)
> + return (error);
> + }
> + return(0);
+space^

>  
>   case WSKBDIO_GETBACKLIGHT:
>   if (wskbd_get_backlight != NULL)
> Index: sbin/kbd/kbd_wscons.c
> ===
> RCS file: /cvs/src/sbin/kbd/kbd_wscons.c,v
> retrieving revision 1.30
> diff -u -p -r1.30 kbd_wscons.c
> --- sbin/kbd/kbd_wscons.c 27 Sep 2016 22:03:49 -  1.30
> +++ sbin/kbd/kbd_wscons.c 29 Sep 2016 18:12:48 -
> @@ -34,6 +34,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  
> @@ -82,31 +83,83 @@ struct nameint kbdvar_tab[] = {
>  
>  extern char *__progname;
>  
> -void kbd_show_enc(int idx);
> +void kbd_show_enc(struct wskbd_encoding_data *encs, int idx);
> +void kbd_get_encs(int fd, struct wskbd_encoding_data *encs);
>  void kbd_list(void);
>  void kbd_set(char *name, int verbose);
>  
>  void
> -kbd_show_enc(int idx)
> +kbd_show_enc(struct wskbd_encoding_data *encs, int idx)
>  {
> + int found;
> + kbd_t encoding, variant;
> + struct nameint *n;
>   int i;
>  
>   printf("tables available for %s keyboard:\nencoding\n\n",
>   kbtype_tab[idx]);
>  
> - for (i = 0; kbdenc_tab[i].value; i++)
> - printf("%s\n", kbdenc_tab[i].name);
> + for (i = 0; i < encs->nencodings; i++) {
> + n = _tab[0];
> + found = 0;
> + encoding = encs->encodings[i];
> + while (n->value) {
> + if (n->value == KB_ENCODING(encoding)) {
> + printf("%s", n->name);
> + found++;
> + }
> + n++;
> + }

This looks a lot like a for loop.

> + if (found == 0)
> + printf("", KB_ENCODING(encoding));
> + n = _tab[0];
> + found = 0;
> + variant = KB_VARIANT(encoding);
> + while (n->value) {
> + if ((n->value & KB_VARIANT(encoding)) == n->value) {

Re: read(2) on directories

2016-09-30 Thread Jeremie Courreges-Anglas
"Theo de Raadt"  writes:

>> On 2016-09-26, Jeremie Courreges-Anglas  wrote:
>> 
>> >>> So I think that we agree that EISDIR is more useful, and seems safe from
>> >>> a portability POV.   I've built base and x sets on i386, and ajacoutot
>> >>> ran the ports bulk builds.  The two offenders in the ports tree were due
>> >>> to an unrelated glitch in base libtool which has since been fixed.
>> >
>> > I haven't received a single test report, which is far from sufficient
>> > for such a change.  Even though I'm convinced that such a change would
>> > be a benefit, I won't push this further.
>> 
>> I think your proposal came at a bad time when there was too much
>> other action in the tree.
>> 
>> I've run an amd64 package build with it (because I didn't read the
>> above that said that aja had already done so), which worked just
>> fine.  I don't think we're going to see more of a real-world test
>> unless the diff goes into snapshots.
>> 
>> FWIW, I'm in favor of this change.
>
> Indeed, and the timing is much better.  Let's do it, and keep an
> eye out for fallout.

Committed.  Please let me know if it produces unexpected, nasty side
effects.

Thanks folks,
-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



BFD: route get and route monitor

2016-09-30 Thread Peter Hessler
This diff makes route get and route monitor work.  sockaddr_bfd is so we
can play like the other RTAX_* indexes in rti_info of route messages.

OK?


$ route -n monitor
got message of size 128 on Wed Sep 28 21:35:32 2016
RTM_BFD: bidirectional forwarding detection: len 128
BFD mode async state down remotestate down laststate admindown error 0
localdiscr 4002401056 remotediscr 0 localdiag none remotediag none
uptime 04m46s lastuptime 00s mintx 100 minrx 1 minecho 0 multiplier 3

sockaddrs: 
 192.168.50.1 192.168.50.61

$ route -n get 192.168.50.1
   route to: 192.168.50.1
destination: 192.168.50.1
   mask: 255.255.255.255
  interface: vio0
 if address: 192.168.50.61
   priority: 4 (connected)
  flags: 
BFD mode async state down remotestate down laststate admindown error 0
localdiscr 4002401056 remotediscr 0 localdiag none remotediag none
uptime 05m13s lastuptime 00s mintx 100 minrx 1 minecho 0 multiplier 3
 use   mtuexpire
   8 0   879 
sockaddrs: 





Index: sbin/route/route.c
===
RCS file: /cvs/openbsd/src/sbin/route/route.c,v
retrieving revision 1.192
diff -u -p -u -p -r1.192 route.c
--- sbin/route/route.c  24 Sep 2016 19:36:49 -  1.192
+++ sbin/route/route.c  30 Sep 2016 08:09:48 -
@@ -100,6 +100,7 @@ const char *bfd_state(unsigned int);
 const char *bfd_diag(unsigned int);
 const char *bfd_calc_uptime(time_t);
 voidprint_bfdmsg(struct rt_msghdr *);
+voidprint_sabfd(struct sockaddr_bfd *);
 #endif
 const char *get_linkstate(int, int);
 voidprint_rtmsg(struct rt_msghdr *, int);
@@ -1439,6 +1440,9 @@ print_getmsg(struct rt_msghdr *rtm, int 
struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL;
struct sockaddr_dl *ifp = NULL;
struct sockaddr_rtlabel *sa_rl = NULL;
+#ifdef BFD
+   struct sockaddr_bfd *sa_bfd = NULL;
+#endif
struct sockaddr *mpls = NULL;
struct sockaddr *sa;
char *cp;
@@ -1487,6 +1491,11 @@ print_getmsg(struct rt_msghdr *rtm, int 
case RTA_LABEL:
sa_rl = (struct sockaddr_rtlabel *)sa;
break;
+#ifdef BFD
+   case RTA_BFD:
+   sa_bfd = (struct sockaddr_bfd *)sa;
+   break;
+#endif
}
ADVANCE(cp, sa);
}
@@ -1519,6 +1528,10 @@ print_getmsg(struct rt_msghdr *rtm, int 
printf("\n");
if (sa_rl != NULL)
printf("  label: %s\n", sa_rl->sr_label);
+#ifdef BFD
+   if (sa_bfd)
+   print_sabfd(sa_bfd);
+#endif
 
 #define lock(f)((rtm->rtm_rmx.rmx_locks & __CONCAT(RTV_,f)) ? 'L' : ' 
')
relative_expire = rtm->rtm_rmx.rmx_expire ?
@@ -1621,12 +1634,21 @@ void
 print_bfdmsg(struct rt_msghdr *rtm)
 {
struct bfd_msghdr *bfdm = (struct bfd_msghdr *)rtm;
+
+   printf("\n");
+   print_sabfd(>bm_sa);
+   pmsg_addrs(((char *)rtm + rtm->rtm_hdrlen), rtm->rtm_addrs);
+}
+
+void
+print_sabfd(struct sockaddr_bfd *sa_bfd)
+{
struct timeval tv;
 
gettimeofday(, NULL);
 
-   printf(" mode ");
-   switch (bfdm->bm_mode) {
+   printf("BFD mode ");
+   switch (sa_bfd->bs_mode) {
case BFD_MODE_ASYNC:
printf("async");
break;
@@ -1634,27 +1656,26 @@ print_bfdmsg(struct rt_msghdr *rtm)
printf("demand");
break;
default:
-   printf("unknown %u", bfdm->bm_mode);
+   printf("unknown %u", sa_bfd->bs_mode);
break;
}
-   printf(" state %s", bfd_state(bfdm->bm_state));
-   printf(" remotestate %s", bfd_state(bfdm->bm_remotestate));
-   printf(" laststate %s", bfd_state(bfdm->bm_laststate));
-
-   printf(" error %d", bfdm->bm_error);
-   printf(" localdiscr %u", bfdm->bm_localdiscr);
-   printf(" remotediscr %u", bfdm->bm_remotediscr);
-   printf(" localdiag %s", bfd_diag(bfdm->bm_localdiag));
-   printf(" remotediag %s", bfd_diag(bfdm->bm_remotediag));
-   printf(" uptime %s", bfd_calc_uptime(tv.tv_sec - bfdm->bm_uptime));
-   printf(" lastuptime %s", bfd_calc_uptime(bfdm->bm_lastuptime));
-
-   printf(" mintx %u", bfdm->bm_mintx);
-   printf(" minrx %u", bfdm->bm_minrx);
-   printf(" minecho %u", bfdm->bm_minecho);
-   printf(" multiplier %u", bfdm->bm_multiplier);
-
-   pmsg_addrs(((char *)rtm + rtm->rtm_hdrlen), rtm->rtm_addrs);
+   printf(" state %s", bfd_state(sa_bfd->bs_state));
+   printf(" remotestate %s", bfd_state(sa_bfd->bs_remotestate));
+   printf(" laststate %s", bfd_state(sa_bfd->bs_laststate));
+