On Tue, 2020-09-08 at 19:33 +0200, Denis Fondras wrote:
> On Sun, Sep 06, 2020 at 10:11:02PM +0200, Martijn van Duren wrote:
> > Moving towards individual transport mappings, it's becoming more
> > convenient to have the protocol directly after the listen on statement.
> > This gives me more flexibility in using mapping-specific APIs, also
> > when other transport mappings might become available in the future it
> > allows for easier mapping-specific features.
> >
> > While here I decided to also add port support for snmpe, which at this
> > point is rather trivial. Traphandler is not my point of focus at this
> > time.
> >
> > having udp|tcp at the last position is still supported, but generates a
> > pretty deprecated warning. Probably to be removed after release.
> >
> > OK?
> >
>
> OK denis@
>
> Can you check that port > 0 ? Because it prints "snmpd.conf:7: invalid
> address: ::1" which is not correct (though using 0 or -1 for port is a weird
> idea).
>
> > martijn@
> >
Sure
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.60
diff -u -p -r1.60 parse.y
--- parse.y 6 Sep 2020 15:51:28 -0000 1.60
+++ parse.y 9 Sep 2020 05:45:10 -0000
@@ -40,9 +40,11 @@
#include <err.h>
#include <errno.h>
#include <event.h>
+#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
@@ -92,6 +94,7 @@ char *symget(const char *);
struct snmpd *conf = NULL;
static int errors = 0;
static struct usmuser *user = NULL;
+static char *snmpd_port = SNMPD_PORT;
int host(const char *, const char *, int,
struct sockaddr_storage *, int);
@@ -122,11 +125,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 HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER
+%token HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER PORT
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.string> hostcmn
-%type <v.string> srcaddr
+%type <v.string> srcaddr port
%type <v.number> optwrite yesno seclevel proto
%type <v.data> objtype cmd
%type <v.oid> oid hostoid trapoid
@@ -193,28 +196,7 @@ yesno : STRING {
}
;
-main : LISTEN ON STRING proto {
- struct sockaddr_storage ss[16];
- int nhosts, i;
-
- nhosts = host($3, SNMPD_PORT, $4, ss, nitems(ss));
- if (nhosts < 1) {
- yyerror("invalid address: %s", $3);
- free($3);
- YYERROR;
- }
- if (nhosts > (int)nitems(ss))
- log_warn("%s resolves to more than %zu hosts",
- $3, nitems(ss));
- free($3);
-
- for (i = 0; i < nhosts; i++) {
- if (listen_add(&(ss[i]), $4) == -1) {
- yyerror("calloc");
- YYERROR;
- }
- }
- }
+main : LISTEN ON listenproto
| READONLY COMMUNITY STRING {
if (strlcpy(conf->sc_rdcommunity, $3,
sizeof(conf->sc_rdcommunity)) >=
@@ -295,6 +277,132 @@ main : LISTEN ON STRING proto {
}
;
+listenproto : UDP listen_udp
+ | TCP listen_tcp
+ | listen_empty
+
+listen_udp : STRING port {
+ struct sockaddr_storage ss[16];
+ int nhosts, i;
+
+ nhosts = host($1, $2, SOCK_DGRAM, ss, nitems(ss));
+ if (nhosts < 1) {
+ yyerror("invalid address: %s", $1);
+ free($1);
+ if ($2 != snmpd_port)
+ free($2);
+ YYERROR;
+ }
+ if (nhosts > (int)nitems(ss))
+ log_warn("%s:%s resolves to more than %zu
hosts",
+ $1, $2, nitems(ss));
+
+ free($1);
+ if ($2 != snmpd_port)
+ free($2);
+ for (i = 0; i < nhosts; i++) {
+ if (listen_add(&(ss[i]), SOCK_DGRAM) == -1) {
+ yyerror("calloc");
+ YYERROR;
+ }
+ }
+ }
+
+listen_tcp : STRING port {
+ struct sockaddr_storage ss[16];
+ int nhosts, i;
+
+ nhosts = host($1, $2, SOCK_STREAM, ss, nitems(ss));
+ if (nhosts < 1) {
+ yyerror("invalid address: %s", $1);
+ free($1);
+ if ($2 != snmpd_port)
+ free($2);
+ YYERROR;
+ }
+ if (nhosts > (int)nitems(ss))
+ log_warn("%s:%s resolves to more than %zu
hosts",
+ $1, $2, nitems(ss));
+
+ free($1);
+ if ($2 != snmpd_port)
+ free($2);
+ for (i = 0; i < nhosts; i++) {
+ if (listen_add(&(ss[i]), SOCK_STREAM) == -1) {
+ yyerror("calloc");
+ YYERROR;
+ }
+ }
+ }
+
+/* Remove after deprecation period and replace with listen_udp */
+listen_empty : STRING port proto {
+ struct sockaddr_storage ss[16];
+ int nhosts, i;
+
+ nhosts = host($1, $2, $3, ss, nitems(ss));
+ if (nhosts < 1) {
+ yyerror("invalid address: %s", $1);
+ free($1);
+ if ($2 != snmpd_port)
+ free($2);
+ YYERROR;
+ }
+ if (nhosts > (int)nitems(ss))
+ log_warn("%s:%s resolves to more than %zu
hosts",
+ $1, $2, nitems(ss));
+
+ free($1);
+ if ($2 != snmpd_port)
+ free($2);
+ for (i = 0; i < nhosts; i++) {
+ if (listen_add(&(ss[i]), $3) == -1) {
+ yyerror("calloc");
+ YYERROR;
+ }
+ }
+ }
+
+port : /* empty */ {
+ $$ = snmpd_port;
+ }
+ | PORT STRING {
+ $$ = $2;
+ }
+ | PORT NUMBER {
+ char *number;
+
+ if ($2 > UINT16_MAX) {
+ yyerror("port number too large");
+ YYERROR;
+ }
+ if ($2 < 1) {
+ yyerror("port number too small");
+ YYERROR;
+ }
+ if (asprintf(&number, "%"PRId64, $2) == -1) {
+ yyerror("malloc");
+ YYERROR;
+ }
+ $$ = number;
+ }
+ ;
+
+proto : /* empty */ {
+ $$ = SOCK_DGRAM;
+ }
+ | UDP {
+ log_warnx("udp as last keyword on listen on line is "
+ "deprecated");
+ $$ = SOCK_DGRAM;
+ }
+ | TCP {
+ log_warnx("tcp as last keyword on listen on line is "
+ "deprecated");
+ $$ = SOCK_STREAM;
+ }
+ ;
+
system : SYSTEM sysmib
;
@@ -541,11 +649,6 @@ enc : STRING {
}
;
-proto : /* empty */ { $$ = SOCK_DGRAM; }
- | TCP { $$ = SOCK_STREAM; }
- | UDP { $$ = SOCK_DGRAM; }
- ;
-
cmd : STRING {
struct trapcmd *cmd;
size_t span, limit;
@@ -646,6 +749,7 @@ lookup(char *s)
{ "none", NONE },
{ "oid", OBJECTID },
{ "on", ON },
+ { "port", PORT },
{ "read-only", READONLY },
{ "read-write", READWRITE },
{ "receiver", RECEIVER },
Index: snmpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.conf.5,v
retrieving revision 1.43
diff -u -p -r1.43 snmpd.conf.5
--- snmpd.conf.5 30 Jun 2020 17:11:49 -0000 1.43
+++ snmpd.conf.5 9 Sep 2020 05:45:10 -0000
@@ -95,7 +95,7 @@ Routing table information will not be av
reduced during bulk updates.
The default is
.Ic no .
-.It Ic listen on Ar address Op Ic tcp | udp
+.It Ic listen on Oo Ic tcp | udp Oc Ar address Op Ic port Ar port
Specify the local address
.Xr snmpd 8
should listen on for incoming SNMP messages.