xref: /openbsd/regress/usr.sbin/snmpd/agentx.c (revision e024f79d)
1 #include <sys/socket.h>
2 #include <sys/types.h>
3 #include <sys/un.h>
4 
5 #include <endian.h>
6 #include <err.h>
7 #include <poll.h>
8 #include <stdarg.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 
15 #include "regress.h"
16 
17 #define AGENTX_SOCKET "/tmp/agentx"
18 
19 #define SUBAGENT_DESCR(name) name, strlen(name)
20 
21 #define AGENTX_OPEN_PDU 1
22 #define AGENTX_CLOSE_PDU 2
23 #define AGENTX_REGISTER_PDU 3
24 #define AGENTX_UNREGISTER_PDU 4
25 #define AGENTX_GET_PDU 5
26 #define AGENTX_GETNEXT_PDU 6
27 #define AGENTX_GETBULK_PDU 7
28 #define AGENTX_TESTSET_PDU 8
29 #define AGENTX_COMMITSET_PDU 9
30 #define AGENTX_UNDOSET_PDU 10
31 #define AGENTX_CLEANUPSET_PDU 11
32 #define AGENTX_NOTIFY_PDU 12
33 #define AGENTX_PING_PDU 13
34 #define AGENTX_INDEXALLOCATE_PDU 14
35 #define AGENTX_INDEXDEALLOCATE_PDU 15
36 #define AGENTX_ADDAGENTCAPS_PDU 16
37 #define AGENTX_REMOVEAGENTCAPS_PDU 17
38 #define AGENTX_RESPONSE_PDU 18
39 
40 #define NOAGENTXERROR 0
41 #define OPENFAILED 256
42 #define NOTOPEN 257
43 #define INDEXWRONGTYPE 258
44 #define INDEXALREADYALLOCATED 259
45 #define INDEXNONEAVAILABLE 260
46 #define INDEXNOTALLOCATED 261
47 #define UNSUPPORTEDCONTEXT 262
48 #define DUPLICATEREGISTRATION 263
49 #define UNKNOWNREGISTRATION 264
50 #define UNKNOWNAGENTCAPS 265
51 #define PARSEERROR 266
52 #define REQUESTDENIED 267
53 #define PROCESSINGERROR 268
54 
55 #define INSTANCE_REGISTRATION (1 << 0)
56 #define NEW_INDEX (1 << 1)
57 #define ANY_INDEX (1 << 2)
58 #define NON_DEFAULT_CONTEXT (1 << 3)
59 #define NETWORK_BYTE_ORDER (1 << 4)
60 
61 #define INTEGER 2
62 #define OCTETSTRING 4
63 #define AXNULL 5
64 #define OBJECTIDENTIFIER 6
65 #define IPADDRESS 64
66 #define COUNTER32 65
67 #define GAUGE32 66
68 #define TIMETICKS 67
69 #define OPAQUE 68
70 #define COUNTER64 70
71 #define NOSUCHOBJECT 128
72 #define NOSUCHINSTANCE 129
73 #define ENDOFMIBVIEW 130
74 
75 #define MESSAGE_NBO(msg) (((const char *)msg->buf)[2] & NETWORK_BYTE_ORDER)
76 
77 #define p16toh(header, value) (uint16_t)(header->flags & NETWORK_BYTE_ORDER ? \
78     be16toh(value) : le16toh(value))
79 #define p32toh(header, value) (uint32_t)(header->flags & NETWORK_BYTE_ORDER ? \
80     be32toh(value) : le32toh(value))
81 #define p64toh(header, value) (uint64_t)(header->flags & NETWORK_BYTE_ORDER ? \
82     be64toh(value) : le64toh(value))
83 
84 struct header {
85 	uint8_t		 version;
86 	uint8_t		 type;
87 	uint8_t		 flags;
88 	uint8_t		 reserved;
89 	uint32_t	 sessionid;
90 	uint32_t	 transactionid;
91 	uint32_t	 packetid;
92 	uint32_t	 payload_length;
93 } __attribute__ ((packed));
94 
95 struct message {
96 	void		*buf;
97 	size_t		 len;
98 	size_t		 size;
99 };
100 
101 void agentx_close_validate(const char *, const void *,
102     size_t, uint8_t, uint8_t);
103 static void agentx_response_validate(const char *, const void *, size_t,
104     uint8_t, uint32_t, enum error, uint16_t, struct varbind *, size_t);
105 static void message_add_uint8(struct message *, uint8_t);
106 static void message_add_uint16(struct message *, uint16_t);
107 static void message_add_uint32(struct message *, uint32_t);
108 static void message_add_uint64(struct message *, uint64_t);
109 static void message_add_nstring(struct message *, const void *, uint32_t);
110 static void message_add_oid(struct message *, const uint32_t[], uint8_t,
111     uint8_t);
112 static void message_add_varbind(struct message *, struct varbind *);
113 static void message_add_header(struct message *, uint8_t, uint8_t, uint8_t,
114     uint32_t, uint32_t, uint32_t);
115 static void message_add(struct message *, const void *, size_t);
116 static void message_release(struct message *);
117 static size_t poid(const char *, const struct header *, const uint8_t *, size_t,
118     struct oid *);
119 
120 void agentx_write(int, struct message *);
121 
122 void
agentx_open_nnbo(void)123 agentx_open_nnbo(void)
124 {
125 	int s;
126 	struct message msg = {};
127 	char zero[3] = {};
128 	char repl[1024];
129 	size_t n;
130 	uint32_t packetid = arc4random();
131 
132 	s = agentx_connect(axsocket);
133 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid);
134 	message_add_uint8(&msg, 0);
135 	message_add(&msg, zero, 3);
136 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 1), 0);
137 	message_add_nstring(&msg, SUBAGENT_DESCR(__func__));
138 
139 	agentx_write(s, &msg);
140 
141 	n = agentx_read(s, repl, sizeof(repl), 1000);
142 
143 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR,
144 	    0, NULL, 0);
145 	message_release(&msg);
146 	close(s);
147 }
148 
149 void
agentx_open_nbo(void)150 agentx_open_nbo(void)
151 {
152 	int s;
153 	struct message msg = {};
154 	char zero[3] = {};
155 	char repl[1024];
156 	size_t n;
157 	uint32_t packetid = arc4random();
158 
159 	s = agentx_connect(axsocket);
160 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, NETWORK_BYTE_ORDER, 0, 0,
161 	    packetid);
162 	message_add_uint8(&msg, 0);
163 	message_add(&msg, zero, 3);
164 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 2), 0);
165 	message_add_nstring(&msg, SUBAGENT_DESCR(__func__));
166 
167 	agentx_write(s, &msg);
168 
169 	n = agentx_read(s, repl, sizeof(repl), 1000);
170 
171 	agentx_response_validate(__func__, repl, n, NETWORK_BYTE_ORDER,
172 	    packetid, NOAGENTXERROR, 0, NULL, 0);
173 	message_release(&msg);
174 	close(s);
175 }
176 
177 /*
178  * The version byte is the only identifier we have to determine if we can
179  * "trust" the rest of the packet structure. If this doesn't match the server
180  * can't return a parseError message, because it doesn't know the packetid.
181  */
182 void
agentx_open_invalidversion(void)183 agentx_open_invalidversion(void)
184 {
185 	int s;
186 	struct message msg = {};
187 	char zero[3] = {};
188 	char repl[1024];
189 	size_t n;
190 	uint32_t packetid = arc4random();
191 
192 	s = agentx_connect(axsocket);
193 	message_add_header(&msg, 0xFF, AGENTX_OPEN_PDU, 0, 0, 0, packetid);
194 	message_add_uint8(&msg, 0);
195 	message_add(&msg, zero, 3);
196 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 3), 0);
197 	message_add_nstring(&msg, SUBAGENT_DESCR(__func__));
198 
199 	agentx_write(s, &msg);
200 
201 	if (agentx_read(s, repl, sizeof(repl), 1000) != 0)
202 		errx(1, "%s: Unexpected reply", __func__);
203 	close(s);
204 }
205 
206 void
agentx_open_ignore_sessionid(void)207 agentx_open_ignore_sessionid(void)
208 {
209 	int s1, s2;
210 	struct message msg = {};
211 	char zero[3] = {};
212 	char repl[1024];
213 	size_t n;
214 	uint32_t packetid = arc4random();
215 	uint32_t sessionid;
216 	struct header *header = (struct header *)repl;
217 
218 	s1 = agentx_connect(axsocket);
219 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid);
220 	message_add_uint8(&msg, 0);
221 	message_add(&msg, zero, 3);
222 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 4, 1), 0);
223 	message_add_nstring(&msg,
224 	    SUBAGENT_DESCR("agentx_open_ignore_sessionid.1"));
225 
226 	agentx_write(s1, &msg);
227 
228 	n = agentx_read(s1, repl, sizeof(repl), 1000);
229 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR,
230 	    0, NULL, 0);
231 
232 	sessionid = le32toh(header->sessionid);
233 
234 	s2 = agentx_connect(axsocket);
235 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, sessionid, 0, packetid);
236 	message_add_uint8(&msg, 0);
237 	message_add(&msg, zero, 3);
238 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 4, 2), 0);
239 	message_add_nstring(&msg,
240 	    SUBAGENT_DESCR("agentx_open_ignore_sessionid.2"));
241 
242 	agentx_write(s2, &msg);
243 
244 	n = agentx_read(s2, repl, sizeof(repl), 1000);
245 
246 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR,
247 	    0, NULL, 0);
248 	if (sessionid == le32toh(header->sessionid))
249 		errx(1, "%s: sessionid not ignored", __func__);
250 
251 	message_release(&msg);
252 	close(s1);
253 	close(s2);
254 }
255 
256 void
agentx_open_invalid_oid(void)257 agentx_open_invalid_oid(void)
258 {
259 	int s;
260 	struct message msg = {};
261 	char zero[3] = {};
262 	char repl[1024];
263 	size_t n;
264 	uint32_t packetid = arc4random();
265 	uint32_t oid[129];
266 
267 	s = agentx_connect(axsocket);
268 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid);
269 	message_add_uint8(&msg, 0);
270 	message_add(&msg, zero, 3);
271 	message_add_oid(&msg, oid, 129, 0);
272 	message_add_nstring(&msg, SUBAGENT_DESCR(__func__));
273 
274 	agentx_write(s, &msg);
275 
276 	if ((n = agentx_read(s, repl, sizeof(repl), 1000)) != 0)
277 		errx(1, "unexpected reply");
278 
279 	message_release(&msg);
280 	close(s);
281 }
282 
283 void
agentx_open_descr_too_long(void)284 agentx_open_descr_too_long(void)
285 {
286 	int s;
287 	struct message msg = {};
288 	char zero[3] = {};
289 	char repl[1024];
290 	size_t n;
291 	uint32_t packetid = arc4random();
292 	char descr[256];
293 
294 	s = agentx_connect(axsocket);
295 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid);
296 	message_add_uint8(&msg, 0);
297 	message_add(&msg, zero, 3);
298 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 6), 0);
299 	memset(descr, 'a', sizeof(descr));
300 	message_add_nstring(&msg, descr, sizeof(descr));
301 
302 	agentx_write(s, &msg);
303 
304 	n = agentx_read(s, repl, sizeof(repl), 1000);
305 
306 	agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0,
307 	    NULL, 0);
308 	message_release(&msg);
309 	close(s);
310 }
311 
312 void
agentx_open_descr_invalid(void)313 agentx_open_descr_invalid(void)
314 {
315 	int s;
316 	struct message msg = {};
317 	char zero[3] = {};
318 	char repl[1024];
319 	size_t n;
320 	uint32_t packetid = arc4random();
321 
322 	s = agentx_connect(axsocket);
323 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid);
324 	message_add_uint8(&msg, 0);
325 	message_add(&msg, zero, 3);
326 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 7), 0);
327 	/* Too long start-byte (5 ones instead of max 4) followed by ascii */
328 	message_add_nstring(&msg, SUBAGENT_DESCR("a\373a"));
329 
330 	agentx_write(s, &msg);
331 
332 	n = agentx_read(s, repl, sizeof(repl), 1000);
333 
334 	agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0,
335 	    NULL, 0);
336 	message_release(&msg);
337 	close(s);
338 }
339 
340 void
agentx_open_context(void)341 agentx_open_context(void)
342 {
343 	int s;
344 	struct message msg = {};
345 	char zero[3] = {};
346 	char repl[1024];
347 	size_t n;
348 	uint32_t packetid = arc4random();
349 
350 	s = agentx_connect(axsocket);
351 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, NON_DEFAULT_CONTEXT, 0, 0,
352 	    packetid);
353 	message_add_nstring(&msg, "ctx", 3);
354 	message_add_uint8(&msg, 0);
355 	message_add(&msg, zero, 3);
356 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 8), 0);
357 	message_add_nstring(&msg, SUBAGENT_DESCR(__func__));
358 
359 	agentx_write(s, &msg);
360 
361 	n = agentx_read(s, repl, sizeof(repl), 1000);
362 
363 	agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0,
364 	    NULL, 0);
365 	message_release(&msg);
366 	close(s);
367 }
368 
369 void
agentx_open_instance_registration(void)370 agentx_open_instance_registration(void)
371 {
372 	int s;
373 	struct message msg = {};
374 	char zero[3] = {};
375 	char repl[1024];
376 	size_t n;
377 	uint32_t packetid = arc4random();
378 
379 	s = agentx_connect(axsocket);
380 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, INSTANCE_REGISTRATION, 0,
381 	    0, packetid);
382 	message_add_uint8(&msg, 0);
383 	message_add(&msg, zero, 3);
384 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 9), 0);
385 	message_add_nstring(&msg, SUBAGENT_DESCR(__func__));
386 
387 	agentx_write(s, &msg);
388 
389 	n = agentx_read(s, repl, sizeof(repl), 1000);
390 
391 	agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0,
392 	    NULL, 0);
393 	message_release(&msg);
394 	close(s);
395 }
396 
397 void
agentx_open_new_index(void)398 agentx_open_new_index(void)
399 {
400 	int s;
401 	struct message msg = {};
402 	char zero[3] = {};
403 	char repl[1024];
404 	size_t n;
405 	uint32_t packetid = arc4random();
406 
407 	s = agentx_connect(axsocket);
408 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, NEW_INDEX, 0,
409 	    0, packetid);
410 	message_add_uint8(&msg, 0);
411 	message_add(&msg, zero, 3);
412 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 10), 0);
413 	message_add_nstring(&msg, SUBAGENT_DESCR(__func__));
414 
415 	agentx_write(s, &msg);
416 
417 	n = agentx_read(s, repl, sizeof(repl), 1000);
418 
419 	agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0,
420 	    NULL, 0);
421 	message_release(&msg);
422 	close(s);
423 }
424 
425 void
agentx_open_any_index(void)426 agentx_open_any_index(void)
427 {
428 	int s;
429 	struct message msg = {};
430 	char zero[3] = {};
431 	char repl[1024];
432 	size_t n;
433 	uint32_t packetid = arc4random();
434 
435 	s = agentx_connect(axsocket);
436 	message_add_header(&msg, 1, AGENTX_OPEN_PDU, ANY_INDEX, 0,
437 	    0, packetid);
438 	message_add_uint8(&msg, 0);
439 	message_add(&msg, zero, 3);
440 	message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 11), 0);
441 	message_add_nstring(&msg, SUBAGENT_DESCR(__func__));
442 
443 	agentx_write(s, &msg);
444 
445 	n = agentx_read(s, repl, sizeof(repl), 1000);
446 
447 	agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0,
448 	    NULL, 0);
449 	message_release(&msg);
450 	close(s);
451 }
452 
453 void
agentx_ping_notopen(void)454 agentx_ping_notopen(void)
455 {
456 	int s;
457 	struct message msg = {};
458 	char repl[1024];
459 	size_t n;
460 	uint32_t packetid = arc4random();
461 
462 	s = agentx_connect(axsocket);
463 	message_add_header(&msg, 1, AGENTX_PING_PDU, 0, 0, 0, packetid);
464 
465 	agentx_write(s, &msg);
466 
467 	n = agentx_read(s, repl, sizeof(repl), 1000);
468 
469 	agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0,
470 	    NULL, 0);
471 	message_release(&msg);
472 	close(s);
473 }
474 
475 void
agentx_ping_invalid_sessionid(void)476 agentx_ping_invalid_sessionid(void)
477 {
478 	int s;
479 	struct message msg = {};
480 	char repl[1024];
481 	size_t n;
482 	uint32_t packetid = arc4random();
483 	uint32_t sessionid;
484 
485 	s = agentx_connect(axsocket);
486 	sessionid = agentx_open(s, 0, 0,
487 	    OID_ARG(MIB_SUBAGENT_PING, 2), __func__);
488 	message_add_header(&msg, 1, AGENTX_PING_PDU, 0,
489 	    sessionid + 1, 0, packetid);
490 
491 	agentx_write(s, &msg);
492 
493 	n = agentx_read(s, repl, sizeof(repl), 1000);
494 
495 	agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0,
496 	    NULL, 0);
497 	message_release(&msg);
498 	close(s);
499 }
500 
501 void
agentx_ping_default(void)502 agentx_ping_default(void)
503 {
504 	int s;
505 	struct message msg = {};
506 	char repl[1024];
507 	size_t n;
508 	uint32_t packetid = arc4random();
509 	uint32_t sessionid;
510 
511 	s = agentx_connect(axsocket);
512 	sessionid = agentx_open(s, 0, 0,
513 	    OID_ARG(MIB_SUBAGENT_PING, 3), __func__);
514 	message_add_header(&msg, 1, AGENTX_PING_PDU, 0,
515 	    sessionid, 0, packetid);
516 
517 	agentx_write(s, &msg);
518 
519 	n = agentx_read(s, repl, sizeof(repl), 1000);
520 
521 	agentx_response_validate(__func__, repl, n, 0,
522 	    packetid, NOAGENTXERROR, 0, NULL, 0);
523 	message_release(&msg);
524 	close(s);
525 }
526 
527 void
agentx_ping_context(void)528 agentx_ping_context(void)
529 {
530 	int s;
531 	struct message msg = {};
532 	char repl[1024];
533 	size_t n;
534 	uint32_t packetid = arc4random();
535 	uint32_t sessionid;
536 
537 	s = agentx_connect(axsocket);
538 	sessionid = agentx_open(s, 0, 0,
539 	    OID_ARG(MIB_SUBAGENT_PING, 4), __func__);
540 	message_add_header(&msg, 1, AGENTX_PING_PDU, NON_DEFAULT_CONTEXT,
541 	    sessionid, 0, packetid);
542 	message_add_nstring(&msg, "ctx", 3);
543 
544 	agentx_write(s, &msg);
545 
546 	n = agentx_read(s, repl, sizeof(repl), 1000);
547 
548 	agentx_response_validate(__func__, repl, n, 0,
549 	    packetid, UNSUPPORTEDCONTEXT, 0, NULL, 0);
550 	message_release(&msg);
551 	close(s);
552 }
553 
554 void
agentx_ping_invalid_version(void)555 agentx_ping_invalid_version(void)
556 {
557 	int s;
558 	struct message msg = {};
559 	char repl[1024];
560 	size_t n;
561 	uint32_t packetid = arc4random();
562 	uint32_t sessionid;
563 
564 	s = agentx_connect(axsocket);
565 	sessionid = agentx_open(s, 0, 0,
566 	    OID_ARG(MIB_SUBAGENT_PING, 5), __func__);
567 	message_add_header(&msg, 0xFF, AGENTX_PING_PDU, INSTANCE_REGISTRATION,
568 	    sessionid, 0, packetid);
569 
570 	agentx_write(s, &msg);
571 
572 	n = agentx_read(s, repl, sizeof(repl), 1000);
573 
574 	agentx_close_validate(__func__, repl, n, 0, REASONPROTOCOLERROR);
575 	message_release(&msg);
576 	close(s);
577 }
578 
579 void
agentx_ping_instance_registration(void)580 agentx_ping_instance_registration(void)
581 {
582 	int s;
583 	struct message msg = {};
584 	char repl[1024];
585 	size_t n;
586 	uint32_t packetid = arc4random();
587 	uint32_t sessionid;
588 
589 	s = agentx_connect(axsocket);
590 	sessionid = agentx_open(s, 0, 0,
591 	    OID_ARG(MIB_SUBAGENT_PING, 6), __func__);
592 	message_add_header(&msg, 1, AGENTX_PING_PDU, INSTANCE_REGISTRATION,
593 	    sessionid, 0, packetid);
594 
595 	agentx_write(s, &msg);
596 
597 	n = agentx_read(s, repl, sizeof(repl), 1000);
598 
599 	agentx_response_validate(__func__, repl, n, 0,
600 	    packetid, PARSEERROR, 0, NULL, 0);
601 	message_release(&msg);
602 	close(s);
603 }
604 
605 void
agentx_ping_new_index(void)606 agentx_ping_new_index(void)
607 {
608 	int s;
609 	struct message msg = {};
610 	char repl[1024];
611 	size_t n;
612 	uint32_t packetid = arc4random();
613 	uint32_t sessionid;
614 
615 	s = agentx_connect(axsocket);
616 	sessionid = agentx_open(s, 0, 0,
617 	    OID_ARG(MIB_SUBAGENT_PING, 7), __func__);
618 	message_add_header(&msg, 1, AGENTX_PING_PDU, NEW_INDEX,
619 	    sessionid, 0, packetid);
620 
621 	agentx_write(s, &msg);
622 
623 	n = agentx_read(s, repl, sizeof(repl), 1000);
624 
625 	agentx_response_validate(__func__, repl, n, 0,
626 	    packetid, PARSEERROR, 0, NULL, 0);
627 	message_release(&msg);
628 	close(s);
629 }
630 
631 void
agentx_ping_any_index(void)632 agentx_ping_any_index(void)
633 {
634 	int s;
635 	struct message msg = {};
636 	char repl[1024];
637 	size_t n;
638 	uint32_t packetid = arc4random();
639 	uint32_t sessionid;
640 
641 	s = agentx_connect(axsocket);
642 	sessionid = agentx_open(s, 0, 0,
643 	    OID_ARG(MIB_SUBAGENT_PING, 8), __func__);
644 	message_add_header(&msg, 1, AGENTX_PING_PDU, ANY_INDEX,
645 	    sessionid, 0, packetid);
646 
647 	agentx_write(s, &msg);
648 
649 	n = agentx_read(s, repl, sizeof(repl), 1000);
650 
651 	agentx_response_validate(__func__, repl, n, 0,
652 	    packetid, PARSEERROR, 0, NULL, 0);
653 	message_release(&msg);
654 	close(s);
655 }
656 
657 void
agentx_ping_nbo_nnbo(void)658 agentx_ping_nbo_nnbo(void)
659 {
660 	int s;
661 	struct message msg = {};
662 	char repl[1024];
663 	size_t n;
664 	uint32_t packetid = arc4random();
665 	uint32_t sessionid;
666 
667 	s = agentx_connect(axsocket);
668 	sessionid = agentx_open(s, 0, 0,
669 	    OID_ARG(MIB_SUBAGENT_PING, 9), __func__);
670 	message_add_header(&msg, 1, AGENTX_PING_PDU, 0,
671 	    sessionid, 0, packetid);
672 
673 	agentx_write(s, &msg);
674 
675 	n = agentx_read(s, repl, sizeof(repl), 1000);
676 
677 	agentx_response_validate(__func__, repl, n, 0,
678 	    packetid, NOAGENTXERROR, 0, NULL, 0);
679 	message_release(&msg);
680 	close(s);
681 }
682 
683 void
agentx_ping_nnbo_nbo(void)684 agentx_ping_nnbo_nbo(void)
685 {
686 	int s;
687 	struct message msg = {};
688 	char repl[1024];
689 	size_t n;
690 	uint32_t packetid = arc4random();
691 	uint32_t sessionid;
692 
693 	s = agentx_connect(axsocket);
694 	sessionid = agentx_open(s, 0, 0,
695 	    OID_ARG(MIB_SUBAGENT_PING, 9), __func__);
696 	message_add_header(&msg, 1, AGENTX_PING_PDU, NETWORK_BYTE_ORDER,
697 	    sessionid, 0, packetid);
698 
699 	agentx_write(s, &msg);
700 
701 	n = agentx_read(s, repl, sizeof(repl), 1000);
702 
703 	agentx_response_validate(__func__, repl, n, NETWORK_BYTE_ORDER,
704 	    packetid, NOAGENTXERROR, 0, NULL, 0);
705 	message_release(&msg);
706 	close(s);
707 }
708 
709 /*
710  * Test that everything continues running in double exception condition
711  */
712 void
agentx_ping_invalid_version_close(void)713 agentx_ping_invalid_version_close(void)
714 {
715 	struct sockaddr_storage ss;
716 	struct message msg = {};
717 	struct sockaddr *sa = (struct sockaddr *)&ss;
718 	socklen_t salen;
719 	int snmp_s, ax_s;
720 	uint32_t sessionid, packetid;
721 	struct varbind varbind = {
722 		.type = TYPE_NULL,
723 		.name = OID_STRUCT(MIB_SUBAGENT_PING, 10, 0),
724 	};
725 	int32_t requestid;
726 	char buf[1024];
727 	size_t n;
728 
729 	ax_s = agentx_connect(axsocket);
730 	sessionid = agentx_open(ax_s, 0, 0,
731 	    OID_ARG(MIB_SUBAGENT_PING, 10), __func__);
732 	message_add_header(&msg, 0xFF, AGENTX_PING_PDU, INSTANCE_REGISTRATION,
733 	    sessionid, 0, packetid);
734 
735 	agentx_write(ax_s, &msg);
736 	close(ax_s);
737 
738 	salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa);
739 	snmp_s = snmp_connect(SOCK_DGRAM, sa, salen);
740 	requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1);
741 
742 	varbind.type = TYPE_NOSUCHOBJECT;
743 
744 	snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0,
745 	    &varbind, 1);
746 }
747 
748 void
agentx_close_notopen(void)749 agentx_close_notopen(void)
750 {
751 	int s;
752 	struct message msg = {};
753 	char repl[1024];
754 	size_t n;
755 	uint32_t packetid = arc4random();
756 	const uint8_t reason = REASONOTHER, zero[3] = {0};
757 
758 	s = agentx_connect(axsocket);
759 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, 0, 0, packetid);
760 	message_add(&msg, &reason, sizeof(reason));
761 	message_add(&msg, zero, sizeof(zero));
762 
763 	agentx_write(s, &msg);
764 
765 	n = agentx_read(s, repl, sizeof(repl), 1000);
766 
767 	agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0,
768 	    NULL, 0);
769 	message_release(&msg);
770 	close(s);
771 }
772 
773 void
agentx_close_reasonother(void)774 agentx_close_reasonother(void)
775 {
776 	int s;
777 	struct message msg = {};
778 	char repl[1024];
779 	size_t n;
780 	uint32_t packetid = arc4random();
781 	uint32_t sessionid;
782 	const uint8_t reason = REASONOTHER, zero[3] = {0};
783 
784 	s = agentx_connect(axsocket);
785 
786 	sessionid = agentx_open(s, 0, 0,
787 	    OID_ARG(MIB_SUBAGENT_CLOSE, 2), __func__);
788 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0,
789 	    packetid);
790 	message_add(&msg, &reason, sizeof(reason));
791 	message_add(&msg, zero, sizeof(zero));
792 
793 	agentx_write(s, &msg);
794 
795 	n = agentx_read(s, repl, sizeof(repl), 1000);
796 
797 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR,
798 	    0, NULL, 0);
799 	message_release(&msg);
800 	close(s);
801 }
802 
803 void
agentx_close_reasonparseerror(void)804 agentx_close_reasonparseerror(void)
805 {
806 	int s;
807 	struct message msg = {};
808 	char repl[1024];
809 	size_t n;
810 	uint32_t packetid = arc4random();
811 	uint32_t sessionid;
812 	const uint8_t reason = REASONPARSEERROR, zero[3] = {0};
813 
814 	s = agentx_connect(axsocket);
815 
816 	sessionid = agentx_open(s, 0, 0,
817 	    OID_ARG(MIB_SUBAGENT_CLOSE, 3), __func__);
818 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0,
819 	    packetid);
820 	message_add(&msg, &reason, sizeof(reason));
821 	message_add(&msg, zero, sizeof(zero));
822 
823 	agentx_write(s, &msg);
824 
825 	n = agentx_read(s, repl, sizeof(repl), 1000);
826 
827 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR,
828 	    0, NULL, 0);
829 	message_release(&msg);
830 	close(s);
831 }
832 
833 void
agentx_close_reasonprotocolerror(void)834 agentx_close_reasonprotocolerror(void)
835 {
836 	int s;
837 	struct message msg = {};
838 	char repl[1024];
839 	size_t n;
840 	uint32_t packetid = arc4random();
841 	uint32_t sessionid;
842 	const uint8_t reason = REASONPROTOCOLERROR, zero[3] = {0};
843 
844 	s = agentx_connect(axsocket);
845 
846 	sessionid = agentx_open(s, 0, 0,
847 	    OID_ARG(MIB_SUBAGENT_CLOSE, 4), __func__);
848 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0,
849 	    packetid);
850 	message_add(&msg, &reason, sizeof(reason));
851 	message_add(&msg, zero, sizeof(zero));
852 
853 	agentx_write(s, &msg);
854 
855 	n = agentx_read(s, repl, sizeof(repl), 1000);
856 
857 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR,
858 	    0, NULL, 0);
859 	message_release(&msg);
860 	close(s);
861 }
862 
863 void
agentx_close_reasontimouts(void)864 agentx_close_reasontimouts(void)
865 {
866 	int s;
867 	struct message msg = {};
868 	char repl[1024];
869 	size_t n;
870 	uint32_t packetid = arc4random();
871 	uint32_t sessionid;
872 	const uint8_t reason = REASONTIMEOUTS, zero[3] = {0};
873 
874 	s = agentx_connect(axsocket);
875 
876 	sessionid = agentx_open(s, 0, 0,
877 	    OID_ARG(MIB_SUBAGENT_CLOSE, 5), __func__);
878 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0,
879 	    packetid);
880 	message_add(&msg, &reason, sizeof(reason));
881 	message_add(&msg, zero, sizeof(zero));
882 
883 	agentx_write(s, &msg);
884 
885 	n = agentx_read(s, repl, sizeof(repl), 1000);
886 
887 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR,
888 	    0, NULL, 0);
889 	message_release(&msg);
890 	close(s);
891 }
892 
893 void
agentx_close_reasonshutdown(void)894 agentx_close_reasonshutdown(void)
895 {
896 	int s;
897 	struct message msg = {};
898 	char repl[1024];
899 	size_t n;
900 	uint32_t packetid = arc4random();
901 	uint32_t sessionid;
902 	const uint8_t reason = REASONSHUTDOWN, zero[3] = {0};
903 
904 	s = agentx_connect(axsocket);
905 
906 	sessionid = agentx_open(s, 0, 0,
907 	    OID_ARG(MIB_SUBAGENT_CLOSE, 6), __func__);
908 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0,
909 	    packetid);
910 	message_add(&msg, &reason, sizeof(reason));
911 	message_add(&msg, zero, sizeof(zero));
912 
913 	agentx_write(s, &msg);
914 
915 	n = agentx_read(s, repl, sizeof(repl), 1000);
916 
917 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR,
918 	    0, NULL, 0);
919 	message_release(&msg);
920 	close(s);
921 }
922 
923 void
agentx_close_reasonbymanager(void)924 agentx_close_reasonbymanager(void)
925 {
926 	int s;
927 	struct message msg = {};
928 	char repl[1024];
929 	size_t n;
930 	uint32_t packetid = arc4random();
931 	uint32_t sessionid;
932 	const uint8_t reason = REASONBYMANAGER, zero[3] = {0};
933 
934 	s = agentx_connect(axsocket);
935 
936 	sessionid = agentx_open(s, 0, 0,
937 	    OID_ARG(MIB_SUBAGENT_CLOSE, 7), __func__);
938 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0,
939 	    packetid);
940 	message_add(&msg, &reason, sizeof(reason));
941 	message_add(&msg, zero, sizeof(zero));
942 
943 	agentx_write(s, &msg);
944 
945 	n = agentx_read(s, repl, sizeof(repl), 1000);
946 
947 	agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR,
948 	    0, NULL, 0);
949 	message_release(&msg);
950 	close(s);
951 }
952 
953 void
agentx_close_reasoninvalid(void)954 agentx_close_reasoninvalid(void)
955 {
956 	int s;
957 	struct message msg = {};
958 	char repl[1024];
959 	size_t n;
960 	uint32_t packetid = arc4random();
961 	uint32_t sessionid;
962 	const uint8_t reason = 0xFF, zero[3] = {0};
963 
964 	s = agentx_connect(axsocket);
965 
966 	sessionid = agentx_open(s, 0, 0,
967 	    OID_ARG(MIB_SUBAGENT_CLOSE, 8), __func__);
968 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0,
969 	    packetid);
970 	message_add(&msg, &reason, sizeof(reason));
971 	message_add(&msg, zero, sizeof(zero));
972 
973 	agentx_write(s, &msg);
974 
975 	n = agentx_read(s, repl, sizeof(repl), 1000);
976 
977 	agentx_close_validate(__func__, repl, n, 0, REASONPROTOCOLERROR);
978 	message_release(&msg);
979 	close(s);
980 }
981 
982 void
agentx_close_single(void)983 agentx_close_single(void)
984 {
985 	int s;
986 	struct message msg = {};
987 	char repl[1024];
988 	size_t n;
989 	uint32_t packetid = arc4random();
990 	uint32_t sessionid1, sessionid2;
991 	const uint8_t reason = REASONOTHER, zero[3] = {0};
992 
993 	s = agentx_connect(axsocket);
994 
995 	sessionid1 = agentx_open(s, 0, 0,
996 	    OID_ARG(MIB_SUBAGENT_CLOSE, 9, 1), "agentx_close_single.1");
997 	sessionid2 = agentx_open(s, 0, 0,
998 	    OID_ARG(MIB_SUBAGENT_CLOSE, 9, 2), "agentx_close_single.2");
999 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid1, 0, packetid);
1000 	message_add(&msg, &reason, sizeof(reason));
1001 	message_add(&msg, zero, sizeof(zero));
1002 
1003 	agentx_write(s, &msg);
1004 
1005 	n = agentx_read(s, repl, sizeof(repl), 1000);
1006 
1007 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR,
1008 	    0, NULL, 0);
1009 
1010 	/* Test that only the second session is still open */
1011 	packetid = arc4random();
1012 	message_add_header(&msg, 1, AGENTX_PING_PDU, 0, sessionid2, 0, packetid);
1013 	agentx_write(s, &msg);
1014 	n = agentx_read(s, repl, sizeof(repl), 1000);
1015 	agentx_response_validate(__func__, repl, n, 0,
1016 	    packetid, NOAGENTXERROR, 0, NULL, 0);
1017 
1018 	packetid = arc4random();
1019 	message_add_header(&msg, 1, AGENTX_PING_PDU, 0, sessionid1, 0, packetid);
1020 	agentx_write(s, &msg);
1021 	n = agentx_read(s, repl, sizeof(repl), 1000);
1022 	agentx_response_validate(__func__, repl, n, 0,
1023 	    packetid, NOTOPEN, 0, NULL, 0);
1024 
1025 	message_release(&msg);
1026 	close(s);
1027 }
1028 
1029 void
agentx_close_notowned(void)1030 agentx_close_notowned(void)
1031 {
1032 	int s1, s2;
1033 	struct message msg = {};
1034 	char repl[1024];
1035 	size_t n;
1036 	uint32_t packetid = arc4random();
1037 	uint32_t sessionid1, sessionid2;
1038 	const uint8_t reason = REASONOTHER, zero[3] = {0};
1039 
1040 	s1 = agentx_connect(axsocket);
1041 	s2 = agentx_connect(axsocket);
1042 
1043 	sessionid1 = agentx_open(s1, 0, 0,
1044 	    OID_ARG(MIB_SUBAGENT_CLOSE, 10, 1), "agentx_close_notowned.1");
1045 	sessionid2 = agentx_open(s2, 0, 0,
1046 	    OID_ARG(MIB_SUBAGENT_CLOSE, 10, 2), "agentx_close_notowned.2");
1047 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid1, 0, packetid);
1048 	message_add(&msg, &reason, sizeof(reason));
1049 	message_add(&msg, zero, sizeof(zero));
1050 
1051 	agentx_write(s2, &msg);
1052 
1053 	n = agentx_read(s2, repl, sizeof(repl), 1000);
1054 
1055 	agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN,
1056 	    0, NULL, 0);
1057 
1058 	/* Test that both sessions are still open */
1059 	packetid = arc4random();
1060 	message_add_header(&msg, 1, AGENTX_PING_PDU, 0, sessionid1, 0, packetid);
1061 	agentx_write(s1, &msg);
1062 	n = agentx_read(s1, repl, sizeof(repl), 1000);
1063 	agentx_response_validate(__func__, repl, n, 0,
1064 	    packetid, NOAGENTXERROR, 0, NULL, 0);
1065 
1066 	packetid = arc4random();
1067 	message_add_header(&msg, 1, AGENTX_PING_PDU, 0, sessionid2, 0, packetid);
1068 	agentx_write(s2, &msg);
1069 	n = agentx_read(s2, repl, sizeof(repl), 1000);
1070 	agentx_response_validate(__func__, repl, n, 0,
1071 	    packetid, NOAGENTXERROR, 0, NULL, 0);
1072 
1073 	message_release(&msg);
1074 	close(s1);
1075 	close(s2);
1076 }
1077 
1078 void
agentx_close_invalid_sessionid(void)1079 agentx_close_invalid_sessionid(void)
1080 {
1081 	int s;
1082 	struct message msg = {};
1083 	char repl[1024];
1084 	size_t n;
1085 	uint32_t packetid = arc4random();
1086 	uint32_t sessionid;
1087 	const uint8_t reason = REASONOTHER, zero[3] = {0};
1088 
1089 	s = agentx_connect(axsocket);
1090 	sessionid = agentx_open(s, 0, 0,
1091 	    OID_ARG(MIB_SUBAGENT_CLOSE, 11), __func__);
1092 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid + 1, 0, packetid);
1093 	message_add(&msg, &reason, sizeof(reason));
1094 	message_add(&msg, zero, sizeof(zero));
1095 
1096 	agentx_write(s, &msg);
1097 
1098 	n = agentx_read(s, repl, sizeof(repl), 1000);
1099 
1100 	agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0,
1101 	    NULL, 0);
1102 	message_release(&msg);
1103 	close(s);
1104 }
1105 
1106 void
agentx_close_context(void)1107 agentx_close_context(void)
1108 {
1109 	int s;
1110 	struct message msg = {};
1111 	char repl[1024];
1112 	size_t n;
1113 	uint32_t packetid = arc4random();
1114 	uint32_t sessionid;
1115 	const uint8_t reason = REASONOTHER, zero[3] = {0};
1116 
1117 	s = agentx_connect(axsocket);
1118 	sessionid = agentx_open(s, 0, 0,
1119 	    OID_ARG(MIB_SUBAGENT_CLOSE, 12), __func__);
1120 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, NON_DEFAULT_CONTEXT,
1121 	    sessionid, 0, packetid);
1122 	message_add_nstring(&msg, "ctx", 3);
1123 	message_add(&msg, &reason, sizeof(reason));
1124 	message_add(&msg, zero, sizeof(zero));
1125 
1126 	agentx_write(s, &msg);
1127 
1128 	n = agentx_read(s, repl, sizeof(repl), 1000);
1129 
1130 	agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0,
1131 	    NULL, 0);
1132 	message_release(&msg);
1133 	close(s);
1134 }
1135 
1136 void
agentx_close_invalid_version(void)1137 agentx_close_invalid_version(void)
1138 {
1139 	int s;
1140 	struct message msg = {};
1141 	char repl[1024];
1142 	size_t n;
1143 	uint32_t packetid = arc4random();
1144 	uint32_t sessionid;
1145 	const uint8_t reason = REASONOTHER, zero[3] = {0};
1146 
1147 	s = agentx_connect(axsocket);
1148 	sessionid = agentx_open(s, 0, 0,
1149 	    OID_ARG(MIB_SUBAGENT_CLOSE, 13), __func__);
1150 	message_add_header(&msg, 0xFF, AGENTX_CLOSE_PDU, 0, sessionid, 0, packetid);
1151 	message_add(&msg, &reason, sizeof(reason));
1152 	message_add(&msg, zero, sizeof(zero));
1153 
1154 	agentx_write(s, &msg);
1155 
1156 	n = agentx_read(s, repl, sizeof(repl), 1000);
1157 	agentx_close_validate(__func__, repl, n, 0, REASONPROTOCOLERROR);
1158 
1159 	message_release(&msg);
1160 	close(s);
1161 }
1162 
1163 void
agentx_close_instance_registration(void)1164 agentx_close_instance_registration(void)
1165 {
1166 	int s;
1167 	struct message msg = {};
1168 	char repl[1024];
1169 	size_t n;
1170 	uint32_t packetid = arc4random();
1171 	uint32_t sessionid;
1172 	const uint8_t reason = REASONOTHER, zero[3] = {0};
1173 
1174 	s = agentx_connect(axsocket);
1175 	sessionid = agentx_open(s, 0, 0,
1176 	    OID_ARG(MIB_SUBAGENT_CLOSE, 14), __func__);
1177 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, INSTANCE_REGISTRATION,
1178 	    sessionid, 0, packetid);
1179 	message_add(&msg, &reason, sizeof(reason));
1180 	message_add(&msg, zero, sizeof(zero));
1181 
1182 	agentx_write(s, &msg);
1183 
1184 	n = agentx_read(s, repl, sizeof(repl), 1000);
1185 
1186 	agentx_response_validate(__func__, repl, n, 0,
1187 	    packetid, PARSEERROR, 0, NULL, 0);
1188 	message_release(&msg);
1189 	close(s);
1190 }
1191 
1192 void
agentx_close_new_index(void)1193 agentx_close_new_index(void)
1194 {
1195 	int s;
1196 	struct message msg = {};
1197 	char repl[1024];
1198 	size_t n;
1199 	uint32_t packetid = arc4random();
1200 	uint32_t sessionid;
1201 	const uint8_t reason = REASONOTHER, zero[3] = {0};
1202 
1203 	s = agentx_connect(axsocket);
1204 	sessionid = agentx_open(s, 0, 0,
1205 	    OID_ARG(MIB_SUBAGENT_CLOSE, 15), __func__);
1206 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, NEW_INDEX,
1207 	    sessionid, 0, packetid);
1208 	message_add(&msg, &reason, sizeof(reason));
1209 	message_add(&msg, zero, sizeof(zero));
1210 
1211 	agentx_write(s, &msg);
1212 
1213 	n = agentx_read(s, repl, sizeof(repl), 1000);
1214 
1215 	agentx_response_validate(__func__, repl, n, 0,
1216 	    packetid, PARSEERROR, 0, NULL, 0);
1217 	message_release(&msg);
1218 	close(s);
1219 }
1220 
1221 void
agentx_close_any_index(void)1222 agentx_close_any_index(void)
1223 {
1224 	int s;
1225 	struct message msg = {};
1226 	char repl[1024];
1227 	size_t n;
1228 	uint32_t packetid = arc4random();
1229 	uint32_t sessionid;
1230 	const uint8_t reason = REASONOTHER, zero[3] = {0};
1231 
1232 	s = agentx_connect(axsocket);
1233 	sessionid = agentx_open(s, 0, 0,
1234 	    OID_ARG(MIB_SUBAGENT_CLOSE, 16), __func__);
1235 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, ANY_INDEX,
1236 	    sessionid, 0, packetid);
1237 	message_add(&msg, &reason, sizeof(reason));
1238 	message_add(&msg, zero, sizeof(zero));
1239 
1240 	agentx_write(s, &msg);
1241 
1242 	n = agentx_read(s, repl, sizeof(repl), 1000);
1243 
1244 	agentx_response_validate(__func__, repl, n, 0,
1245 	    packetid, PARSEERROR, 0, NULL, 0);
1246 	message_release(&msg);
1247 	close(s);
1248 }
1249 
1250 void
agentx_close_nnbo_nbo(void)1251 agentx_close_nnbo_nbo(void)
1252 {
1253 	int s;
1254 	struct message msg = {};
1255 	char repl[1024];
1256 	size_t n;
1257 	uint32_t packetid = arc4random();
1258 	uint32_t sessionid;
1259 	const uint8_t reason = REASONOTHER, zero[3] = {0};
1260 
1261 	s = agentx_connect(axsocket);
1262 	sessionid = agentx_open(s, 0, 0,
1263 	    OID_ARG(MIB_SUBAGENT_CLOSE, 17), __func__);
1264 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, NETWORK_BYTE_ORDER,
1265 	    sessionid, 0, packetid);
1266 	message_add(&msg, &reason, sizeof(reason));
1267 	message_add(&msg, zero, sizeof(zero));
1268 
1269 	agentx_write(s, &msg);
1270 
1271 	n = agentx_read(s, repl, sizeof(repl), 1000);
1272 
1273 	agentx_response_validate(__func__, repl, n, NETWORK_BYTE_ORDER,
1274 	    packetid, NOAGENTXERROR, 0, NULL, 0);
1275 	message_release(&msg);
1276 	close(s);
1277 }
1278 
1279 void
agentx_register_notopen(void)1280 agentx_register_notopen(void)
1281 {
1282 	int s;
1283 	struct message msg = {};
1284 	char repl[1024];
1285 	size_t n;
1286 	uint32_t packetid = arc4random();
1287 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1288 
1289 	s = agentx_connect(axsocket);
1290 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, 0, 0, packetid);
1291 	message_add(&msg, &timeout, sizeof(timeout));
1292 	message_add(&msg, &priority, sizeof(priority));
1293 	message_add(&msg, &range_subid, sizeof(range_subid));
1294 	message_add(&msg, &reserved, sizeof(reserved));
1295 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 1, 0), 0);
1296 
1297 	agentx_write(s, &msg);
1298 
1299 	n = agentx_read(s, repl, sizeof(repl), 1000);
1300 
1301 	agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0,
1302 	    NULL, 0);
1303 	message_release(&msg);
1304 	close(s);
1305 }
1306 
1307 void
agentx_register_invalid_sessionid(void)1308 agentx_register_invalid_sessionid(void)
1309 {
1310 	int s;
1311 	struct message msg = {};
1312 	char repl[1024];
1313 	size_t n;
1314 	uint32_t packetid = arc4random();
1315 	uint32_t sessionid;
1316 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1317 
1318 	s = agentx_connect(axsocket);
1319 	sessionid = agentx_open(s, 0, 0,
1320 	    OID_ARG(MIB_SUBAGENT_REGISTER, 2), __func__);
1321 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid + 1, 0,
1322 	    packetid);
1323 	message_add(&msg, &timeout, sizeof(timeout));
1324 	message_add(&msg, &priority, sizeof(priority));
1325 	message_add(&msg, &range_subid, sizeof(range_subid));
1326 	message_add(&msg, &reserved, sizeof(reserved));
1327 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 2, 0), 0);
1328 
1329 	agentx_write(s, &msg);
1330 
1331 	n = agentx_read(s, repl, sizeof(repl), 1000);
1332 
1333 	agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0,
1334 	    NULL, 0);
1335 	message_release(&msg);
1336 	close(s);
1337 }
1338 
1339 void
agentx_register_default(void)1340 agentx_register_default(void)
1341 {
1342 	int s;
1343 	struct message msg = {};
1344 	char repl[1024];
1345 	size_t n;
1346 	uint32_t packetid = arc4random();
1347 	uint32_t sessionid;
1348 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1349 
1350 	s = agentx_connect(axsocket);
1351 	sessionid = agentx_open(s, 0, 0,
1352 	    OID_ARG(MIB_SUBAGENT_REGISTER, 3), __func__);
1353 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1354 	    packetid);
1355 	message_add(&msg, &timeout, sizeof(timeout));
1356 	message_add(&msg, &priority, sizeof(priority));
1357 	message_add(&msg, &range_subid, sizeof(range_subid));
1358 	message_add(&msg, &reserved, sizeof(reserved));
1359 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 3, 0), 0);
1360 
1361 	agentx_write(s, &msg);
1362 
1363 	n = agentx_read(s, repl, sizeof(repl), 1000);
1364 
1365 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, 0,
1366 	    NULL, 0);
1367 	message_release(&msg);
1368 	close(s);
1369 }
1370 
1371 void
agentx_register_context(void)1372 agentx_register_context(void)
1373 {
1374 	int s;
1375 	struct message msg = {};
1376 	char repl[1024];
1377 	size_t n;
1378 	uint32_t packetid = arc4random();
1379 	uint32_t sessionid;
1380 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1381 
1382 	s = agentx_connect(axsocket);
1383 	sessionid = agentx_open(s, 0, 0,
1384 	    OID_ARG(MIB_SUBAGENT_REGISTER, 4), __func__);
1385 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, NON_DEFAULT_CONTEXT,
1386 	    sessionid, 0, packetid);
1387 	message_add_nstring(&msg, "ctx", 3);
1388 	message_add(&msg, &timeout, sizeof(timeout));
1389 	message_add(&msg, &priority, sizeof(priority));
1390 	message_add(&msg, &range_subid, sizeof(range_subid));
1391 	message_add(&msg, &reserved, sizeof(reserved));
1392 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 4, 0), 0);
1393 
1394 	agentx_write(s, &msg);
1395 
1396 	n = agentx_read(s, repl, sizeof(repl), 1000);
1397 
1398 	agentx_response_validate(__func__, repl, n, 0, packetid,
1399 	    UNSUPPORTEDCONTEXT, 0, NULL, 0);
1400 	message_release(&msg);
1401 	close(s);
1402 }
1403 
1404 void
agentx_register_invalid_version(void)1405 agentx_register_invalid_version(void)
1406 {
1407 	int s;
1408 	struct message msg = {};
1409 	char repl[1024];
1410 	size_t n;
1411 	uint32_t packetid = arc4random();
1412 	uint32_t sessionid;
1413 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1414 
1415 	s = agentx_connect(axsocket);
1416 	sessionid = agentx_open(s, 0, 0,
1417 	    OID_ARG(MIB_SUBAGENT_REGISTER, 5), __func__);
1418 	message_add_header(&msg, 0xFF, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1419 	    packetid);
1420 	message_add(&msg, &timeout, sizeof(timeout));
1421 	message_add(&msg, &priority, sizeof(priority));
1422 	message_add(&msg, &range_subid, sizeof(range_subid));
1423 	message_add(&msg, &reserved, sizeof(reserved));
1424 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 5, 0), 0);
1425 
1426 	agentx_write(s, &msg);
1427 
1428 	n = agentx_read(s, repl, sizeof(repl), 1000);
1429 
1430 	agentx_close_validate(__func__, repl, n, 0, REASONPROTOCOLERROR);
1431 	message_release(&msg);
1432 	close(s);
1433 }
1434 
1435 void
agentx_register_instance_registration(void)1436 agentx_register_instance_registration(void)
1437 {
1438 	int s;
1439 	struct message msg = {};
1440 	char repl[1024];
1441 	size_t n;
1442 	uint32_t packetid = arc4random();
1443 	uint32_t sessionid;
1444 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1445 
1446 	s = agentx_connect(axsocket);
1447 	sessionid = agentx_open(s, 0, 0,
1448 	    OID_ARG(MIB_SUBAGENT_REGISTER, 6), __func__);
1449 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, INSTANCE_REGISTRATION,
1450 	    sessionid, 0, packetid);
1451 	message_add(&msg, &timeout, sizeof(timeout));
1452 	message_add(&msg, &priority, sizeof(priority));
1453 	message_add(&msg, &range_subid, sizeof(range_subid));
1454 	message_add(&msg, &reserved, sizeof(reserved));
1455 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 6, 0), 0);
1456 
1457 	agentx_write(s, &msg);
1458 
1459 	n = agentx_read(s, repl, sizeof(repl), 1000);
1460 
1461 	agentx_response_validate(__func__, repl, n, 0, packetid,
1462 	    NOAGENTXERROR, 0, NULL, 0);
1463 	message_release(&msg);
1464 	close(s);
1465 }
1466 
1467 void
agentx_register_new_index(void)1468 agentx_register_new_index(void)
1469 {
1470 	int s;
1471 	struct message msg = {};
1472 	char repl[1024];
1473 	size_t n;
1474 	uint32_t packetid = arc4random();
1475 	uint32_t sessionid;
1476 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1477 
1478 	s = agentx_connect(axsocket);
1479 	sessionid = agentx_open(s, 0, 0,
1480 	    OID_ARG(MIB_SUBAGENT_REGISTER, 7), __func__);
1481 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, NEW_INDEX,
1482 	    sessionid, 0, packetid);
1483 	message_add(&msg, &timeout, sizeof(timeout));
1484 	message_add(&msg, &priority, sizeof(priority));
1485 	message_add(&msg, &range_subid, sizeof(range_subid));
1486 	message_add(&msg, &reserved, sizeof(reserved));
1487 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 7, 0), 0);
1488 
1489 	agentx_write(s, &msg);
1490 
1491 	n = agentx_read(s, repl, sizeof(repl), 1000);
1492 
1493 	agentx_response_validate(__func__, repl, n, 0, packetid,
1494 	    PARSEERROR, 0, NULL, 0);
1495 	message_release(&msg);
1496 	close(s);
1497 }
1498 
1499 void
agentx_register_any_index(void)1500 agentx_register_any_index(void)
1501 {
1502 	int s;
1503 	struct message msg = {};
1504 	char repl[1024];
1505 	size_t n;
1506 	uint32_t packetid = arc4random();
1507 	uint32_t sessionid;
1508 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1509 
1510 	s = agentx_connect(axsocket);
1511 	sessionid = agentx_open(s, 0, 0,
1512 	    OID_ARG(MIB_SUBAGENT_REGISTER, 8), __func__);
1513 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, NEW_INDEX,
1514 	    sessionid, 0, packetid);
1515 	message_add(&msg, &timeout, sizeof(timeout));
1516 	message_add(&msg, &priority, sizeof(priority));
1517 	message_add(&msg, &range_subid, sizeof(range_subid));
1518 	message_add(&msg, &reserved, sizeof(reserved));
1519 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 8, 0), 0);
1520 
1521 	agentx_write(s, &msg);
1522 
1523 	n = agentx_read(s, repl, sizeof(repl), 1000);
1524 
1525 	agentx_response_validate(__func__, repl, n, 0, packetid,
1526 	    PARSEERROR, 0, NULL, 0);
1527 	message_release(&msg);
1528 	close(s);
1529 }
1530 
1531 void
agentx_register_duplicate_self(void)1532 agentx_register_duplicate_self(void)
1533 {
1534 	int s;
1535 	struct message msg = {};
1536 	char repl[1024];
1537 	size_t n;
1538 	uint32_t packetid = arc4random();
1539 	uint32_t sessionid;
1540 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1541 
1542 	s = agentx_connect(axsocket);
1543 	sessionid = agentx_open(s, 0, 0,
1544 	    OID_ARG(MIB_SUBAGENT_REGISTER, 9), __func__);
1545 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1546 	    packetid);
1547 	message_add(&msg, &timeout, sizeof(timeout));
1548 	message_add(&msg, &priority, sizeof(priority));
1549 	message_add(&msg, &range_subid, sizeof(range_subid));
1550 	message_add(&msg, &reserved, sizeof(reserved));
1551 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 9, 0), 0);
1552 	agentx_write(s, &msg);
1553 	n = agentx_read(s, repl, sizeof(repl), 1000);
1554 	agentx_response_validate(__func__, repl, n, 0, packetid,
1555 	    NOAGENTXERROR, 0, NULL, 0);
1556 
1557 	packetid = arc4random();
1558 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1559 	    packetid);
1560 	message_add(&msg, &timeout, sizeof(timeout));
1561 	message_add(&msg, &priority, sizeof(priority));
1562 	message_add(&msg, &range_subid, sizeof(range_subid));
1563 	message_add(&msg, &reserved, sizeof(reserved));
1564 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 9, 0), 0);
1565 	agentx_write(s, &msg);
1566 	n = agentx_read(s, repl, sizeof(repl), 1000);
1567 	agentx_response_validate(__func__, repl, n, 0, packetid,
1568 	    DUPLICATEREGISTRATION, 0, NULL, 0);
1569 
1570 	message_release(&msg);
1571 	close(s);
1572 }
1573 
1574 void
agentx_register_duplicate_twocon(void)1575 agentx_register_duplicate_twocon(void)
1576 {
1577 	int s1, s2;
1578 	struct message msg = {};
1579 	char repl[1024];
1580 	size_t n;
1581 	uint32_t packetid = arc4random();
1582 	uint32_t sessionid1, sessionid2;
1583 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1584 
1585 	s1 = agentx_connect(axsocket);
1586 	s2 = agentx_connect(axsocket);
1587 	sessionid1 = agentx_open(s1, 0, 0,
1588 	    OID_ARG(MIB_SUBAGENT_REGISTER, 10, 1),
1589 	    "agentx_register_duplicate_twocon.1");
1590 	sessionid2 = agentx_open(s2, 0, 0,
1591 	    OID_ARG(MIB_SUBAGENT_REGISTER, 10, 2),
1592 	    "agentx_register_duplicate_twocon.2");
1593 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid1, 0,
1594 	    packetid);
1595 	message_add(&msg, &timeout, sizeof(timeout));
1596 	message_add(&msg, &priority, sizeof(priority));
1597 	message_add(&msg, &range_subid, sizeof(range_subid));
1598 	message_add(&msg, &reserved, sizeof(reserved));
1599 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 10, 0), 0);
1600 	agentx_write(s1, &msg);
1601 	n = agentx_read(s1, repl, sizeof(repl), 1000);
1602 	agentx_response_validate(__func__, repl, n, 0, packetid,
1603 	    NOAGENTXERROR, 0, NULL, 0);
1604 
1605 	packetid = arc4random();
1606 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid2, 0,
1607 	    packetid);
1608 	message_add(&msg, &timeout, sizeof(timeout));
1609 	message_add(&msg, &priority, sizeof(priority));
1610 	message_add(&msg, &range_subid, sizeof(range_subid));
1611 	message_add(&msg, &reserved, sizeof(reserved));
1612 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 10, 0), 0);
1613 	agentx_write(s2, &msg);
1614 	n = agentx_read(s2, repl, sizeof(repl), 1000);
1615 	agentx_response_validate(__func__, repl, n, 0, packetid,
1616 	    DUPLICATEREGISTRATION, 0, NULL, 0);
1617 
1618 	message_release(&msg);
1619 	close(s1);
1620 	close(s2);
1621 }
1622 
1623 void
agentx_register_duplicate_priority(void)1624 agentx_register_duplicate_priority(void)
1625 {
1626 	int s;
1627 	struct message msg = {};
1628 	char repl[1024];
1629 	size_t n;
1630 	uint32_t packetid = arc4random();
1631 	uint32_t sessionid;
1632 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1633 
1634 	s = agentx_connect(axsocket);
1635 	sessionid = agentx_open(s, 0, 0,
1636 	    OID_ARG(MIB_SUBAGENT_REGISTER, 11), __func__);
1637 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1638 	    packetid);
1639 	message_add(&msg, &timeout, sizeof(timeout));
1640 	message_add(&msg, &priority, sizeof(priority));
1641 	message_add(&msg, &range_subid, sizeof(range_subid));
1642 	message_add(&msg, &reserved, sizeof(reserved));
1643 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 11, 0), 0);
1644 	agentx_write(s, &msg);
1645 	n = agentx_read(s, repl, sizeof(repl), 1000);
1646 	agentx_response_validate(__func__, repl, n, 0, packetid,
1647 	    NOAGENTXERROR, 0, NULL, 0);
1648 
1649 	packetid = arc4random();
1650 	priority = 1;
1651 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1652 	    packetid);
1653 	message_add(&msg, &timeout, sizeof(timeout));
1654 	message_add(&msg, &priority, sizeof(priority));
1655 	message_add(&msg, &range_subid, sizeof(range_subid));
1656 	message_add(&msg, &reserved, sizeof(reserved));
1657 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 11, 0), 0);
1658 	agentx_write(s, &msg);
1659 	n = agentx_read(s, repl, sizeof(repl), 1000);
1660 	agentx_response_validate(__func__, repl, n, 0, packetid,
1661 	    NOAGENTXERROR, 0, NULL, 0);
1662 
1663 	message_release(&msg);
1664 	close(s);
1665 }
1666 
1667 void
agentx_register_range(void)1668 agentx_register_range(void)
1669 {
1670 	int s;
1671 	struct message msg = {};
1672 	char repl[1024];
1673 	size_t n;
1674 	uint32_t packetid = arc4random();
1675 	uint32_t sessionid, upperbound = 10;
1676 	uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0;
1677 
1678 	s = agentx_connect(axsocket);
1679 	sessionid = agentx_open(s, 0, 0,
1680 	    OID_ARG(MIB_SUBAGENT_REGISTER, 12), __func__);
1681 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1682 	    packetid);
1683 	message_add(&msg, &timeout, sizeof(timeout));
1684 	message_add(&msg, &priority, sizeof(priority));
1685 	message_add(&msg, &range_subid, sizeof(range_subid));
1686 	message_add(&msg, &reserved, sizeof(reserved));
1687 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 12, 1), 0);
1688 	message_add_uint32(&msg, upperbound);
1689 	agentx_write(s, &msg);
1690 	n = agentx_read(s, repl, sizeof(repl), 1000);
1691 	agentx_response_validate(__func__, repl, n, 0, packetid,
1692 	    NOAGENTXERROR, 0, NULL, 0);
1693 
1694 	message_release(&msg);
1695 	close(s);
1696 }
1697 
1698 void
agentx_register_range_invalidupperbound(void)1699 agentx_register_range_invalidupperbound(void)
1700 {
1701 	int s;
1702 	struct message msg = {};
1703 	char repl[1024];
1704 	size_t n;
1705 	uint32_t packetid = arc4random();
1706 	uint32_t sessionid, upperbound = 1;
1707 	uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0;
1708 
1709 	s = agentx_connect(axsocket);
1710 	sessionid = agentx_open(s, 0, 0,
1711 	    OID_ARG(MIB_SUBAGENT_REGISTER, 13), __func__);
1712 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1713 	    packetid);
1714 	message_add(&msg, &timeout, sizeof(timeout));
1715 	message_add(&msg, &priority, sizeof(priority));
1716 	message_add(&msg, &range_subid, sizeof(range_subid));
1717 	message_add(&msg, &reserved, sizeof(reserved));
1718 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 13, 2), 0);
1719 	message_add_uint32(&msg, upperbound);
1720 	agentx_write(s, &msg);
1721 	n = agentx_read(s, repl, sizeof(repl), 1000);
1722 	agentx_response_validate(__func__, repl, n, 0, packetid,
1723 	    PARSEERROR, 0, NULL, 0);
1724 
1725 	message_release(&msg);
1726 	close(s);
1727 }
1728 
1729 void
agentx_register_range_single(void)1730 agentx_register_range_single(void)
1731 {
1732 	int s;
1733 	struct message msg = {};
1734 	char repl[1024];
1735 	size_t n;
1736 	uint32_t packetid = arc4random();
1737 	uint32_t sessionid, upperbound = 1;
1738 	uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0;
1739 
1740 	s = agentx_connect(axsocket);
1741 	sessionid = agentx_open(s, 0, 0,
1742 	    OID_ARG(MIB_SUBAGENT_REGISTER, 14), __func__);
1743 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1744 	    packetid);
1745 	message_add(&msg, &timeout, sizeof(timeout));
1746 	message_add(&msg, &priority, sizeof(priority));
1747 	message_add(&msg, &range_subid, sizeof(range_subid));
1748 	message_add(&msg, &reserved, sizeof(reserved));
1749 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 14, 1), 0);
1750 	message_add_uint32(&msg, upperbound);
1751 	agentx_write(s, &msg);
1752 	n = agentx_read(s, repl, sizeof(repl), 1000);
1753 	agentx_response_validate(__func__, repl, n, 0, packetid,
1754 	    NOAGENTXERROR, 0, NULL, 0);
1755 
1756 	message_release(&msg);
1757 	close(s);
1758 }
1759 
1760 void
agentx_register_range_overlap_single(void)1761 agentx_register_range_overlap_single(void)
1762 {
1763 	int s;
1764 	struct message msg = {};
1765 	char repl[1024];
1766 	size_t n;
1767 	uint32_t packetid = arc4random();
1768 	uint32_t sessionid, upperbound = 10;
1769 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1770 
1771 	s = agentx_connect(axsocket);
1772 	sessionid = agentx_open(s, 0, 0,
1773 	    OID_ARG(MIB_SUBAGENT_REGISTER, 15), __func__);
1774 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1775 	    packetid);
1776 	message_add(&msg, &timeout, sizeof(timeout));
1777 	message_add(&msg, &priority, sizeof(priority));
1778 	message_add(&msg, &range_subid, sizeof(range_subid));
1779 	message_add(&msg, &reserved, sizeof(reserved));
1780 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 15, 1), 0);
1781 	agentx_write(s, &msg);
1782 	n = agentx_read(s, repl, sizeof(repl), 1000);
1783 	agentx_response_validate(__func__, repl, n, 0, packetid,
1784 	    NOAGENTXERROR, 0, NULL, 0);
1785 
1786 	packetid = arc4random();
1787 	range_subid = 11;
1788 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1789 	    packetid);
1790 	message_add(&msg, &timeout, sizeof(timeout));
1791 	message_add(&msg, &priority, sizeof(priority));
1792 	message_add(&msg, &range_subid, sizeof(range_subid));
1793 	message_add(&msg, &reserved, sizeof(reserved));
1794 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 15, 1), 0);
1795 	message_add_uint32(&msg, upperbound);
1796 	agentx_write(s, &msg);
1797 	n = agentx_read(s, repl, sizeof(repl), 1000);
1798 	agentx_response_validate(__func__, repl, n, 0, packetid,
1799 	    DUPLICATEREGISTRATION, 0, NULL, 0);
1800 
1801 	message_release(&msg);
1802 	close(s);
1803 }
1804 
1805 void
agentx_register_single_overlap_range(void)1806 agentx_register_single_overlap_range(void)
1807 {
1808 	int s;
1809 	struct message msg = {};
1810 	char repl[1024];
1811 	size_t n;
1812 	uint32_t packetid = arc4random();
1813 	uint32_t sessionid, upperbound = 10;
1814 	uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0;
1815 
1816 	s = agentx_connect(axsocket);
1817 	sessionid = agentx_open(s, 0, 0,
1818 	    OID_ARG(MIB_SUBAGENT_REGISTER, 16), __func__);
1819 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1820 	    packetid);
1821 	message_add(&msg, &timeout, sizeof(timeout));
1822 	message_add(&msg, &priority, sizeof(priority));
1823 	message_add(&msg, &range_subid, sizeof(range_subid));
1824 	message_add(&msg, &reserved, sizeof(reserved));
1825 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 16, 1), 0);
1826 	message_add_uint32(&msg, upperbound);
1827 	agentx_write(s, &msg);
1828 	n = agentx_read(s, repl, sizeof(repl), 1000);
1829 	agentx_response_validate(__func__, repl, n, 0, packetid,
1830 	    NOAGENTXERROR, 0, NULL, 0);
1831 
1832 	packetid = arc4random();
1833 	range_subid = 0;
1834 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1835 	    packetid);
1836 	message_add(&msg, &timeout, sizeof(timeout));
1837 	message_add(&msg, &priority, sizeof(priority));
1838 	message_add(&msg, &range_subid, sizeof(range_subid));
1839 	message_add(&msg, &reserved, sizeof(reserved));
1840 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 16, 1), 0);
1841 	agentx_write(s, &msg);
1842 	n = agentx_read(s, repl, sizeof(repl), 1000);
1843 	agentx_response_validate(__func__, repl, n, 0, packetid,
1844 	    DUPLICATEREGISTRATION, 0, NULL, 0);
1845 
1846 	message_release(&msg);
1847 	close(s);
1848 }
1849 
1850 void
agentx_register_range_overlap_range(void)1851 agentx_register_range_overlap_range(void)
1852 {
1853 	int s;
1854 	struct message msg = {};
1855 	char repl[1024];
1856 	size_t n;
1857 	uint32_t packetid = arc4random();
1858 	uint32_t sessionid, upperbound = 10;
1859 	uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0;
1860 
1861 	s = agentx_connect(axsocket);
1862 	sessionid = agentx_open(s, 0, 0,
1863 	    OID_ARG(MIB_SUBAGENT_REGISTER, 17), __func__);
1864 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1865 	    packetid);
1866 	message_add(&msg, &timeout, sizeof(timeout));
1867 	message_add(&msg, &priority, sizeof(priority));
1868 	message_add(&msg, &range_subid, sizeof(range_subid));
1869 	message_add(&msg, &reserved, sizeof(reserved));
1870 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 17, 1), 0);
1871 	message_add_uint32(&msg, upperbound);
1872 	agentx_write(s, &msg);
1873 	n = agentx_read(s, repl, sizeof(repl), 1000);
1874 	agentx_response_validate(__func__, repl, n, 0, packetid,
1875 	    NOAGENTXERROR, 0, NULL, 0);
1876 
1877 	packetid = arc4random();
1878 	upperbound = 15;
1879 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1880 	    packetid);
1881 	message_add(&msg, &timeout, sizeof(timeout));
1882 	message_add(&msg, &priority, sizeof(priority));
1883 	message_add(&msg, &range_subid, sizeof(range_subid));
1884 	message_add(&msg, &reserved, sizeof(reserved));
1885 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 17, 6), 0);
1886 	message_add_uint32(&msg, upperbound);
1887 	agentx_write(s, &msg);
1888 	n = agentx_read(s, repl, sizeof(repl), 1000);
1889 	agentx_response_validate(__func__, repl, n, 0, packetid,
1890 	    DUPLICATEREGISTRATION, 0, NULL, 0);
1891 
1892 	message_release(&msg);
1893 	close(s);
1894 }
1895 
1896 void
agentx_register_below(void)1897 agentx_register_below(void)
1898 {
1899 	int s;
1900 	struct message msg = {};
1901 	char repl[1024];
1902 	size_t n;
1903 	uint32_t packetid = arc4random();
1904 	uint32_t sessionid;
1905 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1906 
1907 	s = agentx_connect(axsocket);
1908 	sessionid = agentx_open(s, 0, 0,
1909 	    OID_ARG(MIB_SUBAGENT_REGISTER, 18), __func__);
1910 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1911 	    packetid);
1912 	message_add(&msg, &timeout, sizeof(timeout));
1913 	message_add(&msg, &priority, sizeof(priority));
1914 	message_add(&msg, &range_subid, sizeof(range_subid));
1915 	message_add(&msg, &reserved, sizeof(reserved));
1916 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 18, 1), 0);
1917 	agentx_write(s, &msg);
1918 	n = agentx_read(s, repl, sizeof(repl), 1000);
1919 	agentx_response_validate(__func__, repl, n, 0, packetid,
1920 	    NOAGENTXERROR, 0, NULL, 0);
1921 
1922 	packetid = arc4random();
1923 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1924 	    packetid);
1925 	message_add(&msg, &timeout, sizeof(timeout));
1926 	message_add(&msg, &priority, sizeof(priority));
1927 	message_add(&msg, &range_subid, sizeof(range_subid));
1928 	message_add(&msg, &reserved, sizeof(reserved));
1929 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 18, 1, 0), 0);
1930 	agentx_write(s, &msg);
1931 	n = agentx_read(s, repl, sizeof(repl), 1000);
1932 	agentx_response_validate(__func__, repl, n, 0, packetid,
1933 	    NOAGENTXERROR, 0, NULL, 0);
1934 
1935 	message_release(&msg);
1936 	close(s);
1937 }
1938 
1939 void
agentx_register_above(void)1940 agentx_register_above(void)
1941 {
1942 	int s;
1943 	struct message msg = {};
1944 	char repl[1024];
1945 	size_t n;
1946 	uint32_t packetid = arc4random();
1947 	uint32_t sessionid;
1948 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1949 
1950 	s = agentx_connect(axsocket);
1951 	sessionid = agentx_open(s, 0, 0,
1952 	    OID_ARG(MIB_SUBAGENT_REGISTER, 19), __func__);
1953 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1954 	    packetid);
1955 	message_add(&msg, &timeout, sizeof(timeout));
1956 	message_add(&msg, &priority, sizeof(priority));
1957 	message_add(&msg, &range_subid, sizeof(range_subid));
1958 	message_add(&msg, &reserved, sizeof(reserved));
1959 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 19, 1, 1), 0);
1960 	agentx_write(s, &msg);
1961 	n = agentx_read(s, repl, sizeof(repl), 1000);
1962 	agentx_response_validate(__func__, repl, n, 0, packetid,
1963 	    NOAGENTXERROR, 0, NULL, 0);
1964 
1965 	packetid = arc4random();
1966 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1967 	    packetid);
1968 	message_add(&msg, &timeout, sizeof(timeout));
1969 	message_add(&msg, &priority, sizeof(priority));
1970 	message_add(&msg, &range_subid, sizeof(range_subid));
1971 	message_add(&msg, &reserved, sizeof(reserved));
1972 	message_add_oid(&msg, OID_ARG(MIB_REGISTER, 19, 1), 0);
1973 	agentx_write(s, &msg);
1974 	n = agentx_read(s, repl, sizeof(repl), 1000);
1975 	agentx_response_validate(__func__, repl, n, 0, packetid,
1976 	    NOAGENTXERROR, 0, NULL, 0);
1977 
1978 	message_release(&msg);
1979 	close(s);
1980 }
1981 
1982 void
agentx_register_restricted(void)1983 agentx_register_restricted(void)
1984 {
1985 	int s;
1986 	struct message msg = {};
1987 	char repl[1024];
1988 	size_t n;
1989 	uint32_t packetid = arc4random();
1990 	uint32_t sessionid;
1991 	uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0;
1992 
1993 	s = agentx_connect(axsocket);
1994 	sessionid = agentx_open(s, 0, 0,
1995 	    OID_ARG(MIB_SUBAGENT_REGISTER, 20), __func__);
1996 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0,
1997 	    packetid);
1998 	message_add(&msg, &timeout, sizeof(timeout));
1999 	message_add(&msg, &priority, sizeof(priority));
2000 	message_add(&msg, &range_subid, sizeof(range_subid));
2001 	message_add(&msg, &reserved, sizeof(reserved));
2002 	message_add_oid(&msg, OID_ARG(SYSORTABLE, 1, 1), 0);
2003 	agentx_write(s, &msg);
2004 	n = agentx_read(s, repl, sizeof(repl), 1000);
2005 	agentx_response_validate(__func__, repl, n, 0, packetid,
2006 	    REQUESTDENIED, 0, NULL, 0);
2007 
2008 	message_release(&msg);
2009 	close(s);
2010 }
2011 
2012 void
agentx_unregister_notopen(void)2013 agentx_unregister_notopen(void)
2014 {
2015 	int s;
2016 	struct message msg = {};
2017 	char repl[1024];
2018 	size_t n;
2019 	uint32_t packetid = arc4random();
2020 	uint8_t priority = 127, range_subid = 0, reserved = 0;
2021 
2022 	s = agentx_connect(axsocket);
2023 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, 0, 0, packetid);
2024 	message_add(&msg, &reserved, sizeof(reserved));
2025 	message_add(&msg, &priority, sizeof(priority));
2026 	message_add(&msg, &range_subid, sizeof(range_subid));
2027 	message_add(&msg, &reserved, sizeof(reserved));
2028 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 1, 0), 0);
2029 
2030 	agentx_write(s, &msg);
2031 
2032 	n = agentx_read(s, repl, sizeof(repl), 1000);
2033 
2034 	agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0,
2035 	    NULL, 0);
2036 	message_release(&msg);
2037 	close(s);
2038 }
2039 
2040 void
agentx_unregister_invalid_sessionid(void)2041 agentx_unregister_invalid_sessionid(void)
2042 {
2043 	int s;
2044 	struct message msg = {};
2045 	char repl[1024];
2046 	size_t n;
2047 	uint32_t packetid = arc4random();
2048 	uint32_t sessionid;
2049 	uint8_t priority = 127, range_subid = 0, reserved = 0;
2050 
2051 	s = agentx_connect(axsocket);
2052 	sessionid = agentx_open(s, 0, 0,
2053 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 2), __func__);
2054 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid + 1, 0,
2055 	    packetid);
2056 	message_add(&msg, &reserved, sizeof(reserved));
2057 	message_add(&msg, &priority, sizeof(priority));
2058 	message_add(&msg, &range_subid, sizeof(range_subid));
2059 	message_add(&msg, &reserved, sizeof(reserved));
2060 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 2, 0), 0);
2061 
2062 	agentx_write(s, &msg);
2063 
2064 	n = agentx_read(s, repl, sizeof(repl), 1000);
2065 
2066 	agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0,
2067 	    NULL, 0);
2068 	message_release(&msg);
2069 	close(s);
2070 }
2071 
2072 void
agentx_unregister_notregistered(void)2073 agentx_unregister_notregistered(void)
2074 {
2075 	int s;
2076 	struct message msg = {};
2077 	char repl[1024];
2078 	size_t n;
2079 	uint32_t packetid = arc4random();
2080 	uint32_t sessionid;
2081 	uint8_t priority = 127, range_subid = 0, reserved = 0;
2082 
2083 	s = agentx_connect(axsocket);
2084 	sessionid = agentx_open(s, 0, 0,
2085 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 3), __func__);
2086 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0,
2087 	    packetid);
2088 	message_add(&msg, &reserved, sizeof(reserved));
2089 	message_add(&msg, &priority, sizeof(priority));
2090 	message_add(&msg, &range_subid, sizeof(range_subid));
2091 	message_add(&msg, &reserved, sizeof(reserved));
2092 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 3), 0);
2093 
2094 	agentx_write(s, &msg);
2095 
2096 	n = agentx_read(s, repl, sizeof(repl), 1000);
2097 
2098 	agentx_response_validate(__func__, repl, n, 0, packetid,
2099 	    UNKNOWNREGISTRATION, 0, NULL, 0);
2100 	message_release(&msg);
2101 	close(s);
2102 }
2103 
2104 void
agentx_unregister_single(void)2105 agentx_unregister_single(void)
2106 {
2107 	int s;
2108 	struct message msg = {};
2109 	char repl[1024];
2110 	size_t n;
2111 	uint32_t packetid = arc4random();
2112 	uint32_t sessionid;
2113 	uint8_t priority = 127, range_subid = 0, reserved = 0;
2114 
2115 	s = agentx_connect(axsocket);
2116 	sessionid = agentx_open(s, 0, 0,
2117 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 4), __func__);
2118 	agentx_register(s, sessionid, 0, 0, 127, 0,
2119 	    OID_ARG(MIB_UNREGISTER, 4), 0);
2120 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0,
2121 	    packetid);
2122 	message_add(&msg, &reserved, sizeof(reserved));
2123 	message_add(&msg, &priority, sizeof(priority));
2124 	message_add(&msg, &range_subid, sizeof(range_subid));
2125 	message_add(&msg, &reserved, sizeof(reserved));
2126 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 4), 0);
2127 
2128 	agentx_write(s, &msg);
2129 
2130 	n = agentx_read(s, repl, sizeof(repl), 1000);
2131 
2132 	agentx_response_validate(__func__, repl, n, 0, packetid,
2133 	    NOAGENTXERROR, 0, NULL, 0);
2134 	message_release(&msg);
2135 	close(s);
2136 }
2137 
2138 void
agentx_unregister_single_notowned(void)2139 agentx_unregister_single_notowned(void)
2140 {
2141 	int s;
2142 	struct message msg = {};
2143 	char repl[1024];
2144 	size_t n;
2145 	uint32_t packetid = arc4random();
2146 	uint32_t sessionid1, sessionid2;
2147 	uint8_t priority = 127, range_subid = 0, reserved = 0;
2148 
2149 	s = agentx_connect(axsocket);
2150 	sessionid1 = agentx_open(s, 0, 0,
2151 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 5, 1),
2152 	    "agentx_unregister_single_notowned.1");
2153 	sessionid2 = agentx_open(s, 0, 0,
2154 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 5, 2),
2155 	    "agentx_unregister_single_notowned.2");
2156 	agentx_register(s, sessionid1, 0, 0, 127, 0,
2157 	    OID_ARG(MIB_UNREGISTER, 5, 1), 0);
2158 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid2, 0,
2159 	    packetid);
2160 	message_add(&msg, &reserved, sizeof(reserved));
2161 	message_add(&msg, &priority, sizeof(priority));
2162 	message_add(&msg, &range_subid, sizeof(range_subid));
2163 	message_add(&msg, &reserved, sizeof(reserved));
2164 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 5, 1), 0);
2165 
2166 	agentx_write(s, &msg);
2167 
2168 	n = agentx_read(s, repl, sizeof(repl), 1000);
2169 
2170 	agentx_response_validate(__func__, repl, n, 0, packetid,
2171 	    UNKNOWNREGISTRATION, 0, NULL, 0);
2172 	message_release(&msg);
2173 	close(s);
2174 }
2175 
2176 void
agentx_unregister_range(void)2177 agentx_unregister_range(void)
2178 {
2179 	int s;
2180 	struct message msg = {};
2181 	char repl[1024];
2182 	size_t n;
2183 	uint32_t packetid = arc4random();
2184 	uint32_t sessionid;
2185 	uint8_t priority = 127, range_subid = 11, reserved = 0;
2186 	uint32_t upperbound = 10;
2187 
2188 	s = agentx_connect(axsocket);
2189 	sessionid = agentx_open(s, 0, 0,
2190 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 6), __func__);
2191 	agentx_register(s, sessionid, 0, 0, 127, 11,
2192 	    OID_ARG(MIB_UNREGISTER, 6, 1), 10);
2193 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0,
2194 	    packetid);
2195 	message_add(&msg, &reserved, sizeof(reserved));
2196 	message_add(&msg, &priority, sizeof(priority));
2197 	message_add(&msg, &range_subid, sizeof(range_subid));
2198 	message_add(&msg, &reserved, sizeof(reserved));
2199 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 6, 1), 0);
2200 	message_add_uint32(&msg, upperbound);
2201 
2202 	agentx_write(s, &msg);
2203 
2204 	n = agentx_read(s, repl, sizeof(repl), 1000);
2205 
2206 	agentx_response_validate(__func__, repl, n, 0, packetid,
2207 	    NOAGENTXERROR, 0, NULL, 0);
2208 	message_release(&msg);
2209 	close(s);
2210 }
2211 
2212 void
agentx_unregister_range_single(void)2213 agentx_unregister_range_single(void)
2214 {
2215 	int s;
2216 	struct message msg = {};
2217 	char repl[1024];
2218 	size_t n;
2219 	uint32_t packetid = arc4random();
2220 	uint32_t sessionid;
2221 	uint8_t priority = 127, range_subid = 0, reserved = 0;
2222 
2223 	s = agentx_connect(axsocket);
2224 	sessionid = agentx_open(s, 0, 0,
2225 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 7), __func__);
2226 	agentx_register(s, sessionid, 0, 0, 127, 11,
2227 	    OID_ARG(MIB_UNREGISTER, 6, 1), 10);
2228 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0,
2229 	    packetid);
2230 	message_add(&msg, &reserved, sizeof(reserved));
2231 	message_add(&msg, &priority, sizeof(priority));
2232 	message_add(&msg, &range_subid, sizeof(range_subid));
2233 	message_add(&msg, &reserved, sizeof(reserved));
2234 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 7, 1), 0);
2235 
2236 	agentx_write(s, &msg);
2237 
2238 	n = agentx_read(s, repl, sizeof(repl), 1000);
2239 
2240 	agentx_response_validate(__func__, repl, n, 0, packetid,
2241 	    UNKNOWNREGISTRATION, 0, NULL, 0);
2242 	message_release(&msg);
2243 	close(s);
2244 }
2245 
2246 void
agentx_unregister_range_subset(void)2247 agentx_unregister_range_subset(void)
2248 {
2249 	int s;
2250 	struct message msg = {};
2251 	char repl[1024];
2252 	size_t n;
2253 	uint32_t packetid = arc4random();
2254 	uint32_t sessionid;
2255 	uint8_t priority = 127, range_subid = 11, reserved = 0;
2256 	uint32_t upperbound = 5;
2257 
2258 	s = agentx_connect(axsocket);
2259 	sessionid = agentx_open(s, 0, 0,
2260 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 8), __func__);
2261 	agentx_register(s, sessionid, 0, 0, 127, 11,
2262 	    OID_ARG(MIB_UNREGISTER, 8, 1), 10);
2263 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0,
2264 	    packetid);
2265 	message_add(&msg, &reserved, sizeof(reserved));
2266 	message_add(&msg, &priority, sizeof(priority));
2267 	message_add(&msg, &range_subid, sizeof(range_subid));
2268 	message_add(&msg, &reserved, sizeof(reserved));
2269 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 8, 1), 0);
2270 	message_add_uint32(&msg, upperbound);
2271 
2272 	agentx_write(s, &msg);
2273 
2274 	n = agentx_read(s, repl, sizeof(repl), 1000);
2275 
2276 	agentx_response_validate(__func__, repl, n, 0, packetid,
2277 	    UNKNOWNREGISTRATION, 0, NULL, 0);
2278 	message_release(&msg);
2279 	close(s);
2280 }
2281 
2282 void
agentx_unregister_range_extra(void)2283 agentx_unregister_range_extra(void)
2284 {
2285 	int s;
2286 	struct message msg = {};
2287 	char repl[1024];
2288 	size_t n;
2289 	uint32_t packetid = arc4random();
2290 	uint32_t sessionid;
2291 	uint8_t priority = 127, range_subid = 11, reserved = 0;
2292 	uint32_t upperbound = 10;
2293 
2294 	s = agentx_connect(axsocket);
2295 	sessionid = agentx_open(s, 0, 0,
2296 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 9), __func__);
2297 	agentx_register(s, sessionid, 0, 0, 127, 11,
2298 	    OID_ARG(MIB_UNREGISTER, 9, 1), upperbound);
2299 	upperbound = 15;
2300 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0,
2301 	    packetid);
2302 	message_add(&msg, &reserved, sizeof(reserved));
2303 	message_add(&msg, &priority, sizeof(priority));
2304 	message_add(&msg, &range_subid, sizeof(range_subid));
2305 	message_add(&msg, &reserved, sizeof(reserved));
2306 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 9, 1), 0);
2307 	message_add_uint32(&msg, upperbound);
2308 
2309 	agentx_write(s, &msg);
2310 
2311 	n = agentx_read(s, repl, sizeof(repl), 1000);
2312 
2313 	agentx_response_validate(__func__, repl, n, 0, packetid,
2314 	    UNKNOWNREGISTRATION, 0, NULL, 0);
2315 	message_release(&msg);
2316 	close(s);
2317 }
2318 
2319 void
agentx_unregister_range_priority(void)2320 agentx_unregister_range_priority(void)
2321 {
2322 	int s;
2323 	struct message msg = {};
2324 	char repl[1024];
2325 	size_t n;
2326 	uint32_t packetid = arc4random();
2327 	uint32_t sessionid;
2328 	uint8_t priority = 127, range_subid = 11, reserved = 0;
2329 	uint32_t upperbound = 10;
2330 
2331 	s = agentx_connect(axsocket);
2332 	sessionid = agentx_open(s, 0, 0,
2333 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 10), __func__);
2334 	agentx_register(s, sessionid, 0, 0, priority, 11,
2335 	    OID_ARG(MIB_UNREGISTER, 10, 1), upperbound);
2336 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0,
2337 	    packetid);
2338 	priority = 128;
2339 	message_add(&msg, &reserved, sizeof(reserved));
2340 	message_add(&msg, &priority, sizeof(priority));
2341 	message_add(&msg, &range_subid, sizeof(range_subid));
2342 	message_add(&msg, &reserved, sizeof(reserved));
2343 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 10, 1), 0);
2344 	message_add_uint32(&msg, upperbound);
2345 
2346 	agentx_write(s, &msg);
2347 
2348 	n = agentx_read(s, repl, sizeof(repl), 1000);
2349 
2350 	agentx_response_validate(__func__, repl, n, 0, packetid,
2351 	    UNKNOWNREGISTRATION, 0, NULL, 0);
2352 	message_release(&msg);
2353 	close(s);
2354 }
2355 
2356 void
agentx_unregister_range_notowned(void)2357 agentx_unregister_range_notowned(void)
2358 {
2359 	int s;
2360 	struct message msg = {};
2361 	char repl[1024];
2362 	size_t n;
2363 	uint32_t packetid = arc4random();
2364 	uint32_t sessionid1, sessionid2;
2365 	uint8_t priority = 127, range_subid = 11, reserved = 0;
2366 	uint32_t upperbound = 10;
2367 
2368 	s = agentx_connect(axsocket);
2369 	sessionid1 = agentx_open(s, 0, 0,
2370 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 11, 1),
2371 	    "agentx_unregister_range_notowned.1");
2372 	sessionid2 = agentx_open(s, 0, 0,
2373 	    OID_ARG(MIB_SUBAGENT_UNREGISTER, 11, 2),
2374 	    "agentx_unregister_range_notowned.2");
2375 	agentx_register(s, sessionid1, 0, 0, priority, 11,
2376 	    OID_ARG(MIB_UNREGISTER, 11, 1), upperbound);
2377 	message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid2, 0,
2378 	    packetid);
2379 	priority = 128;
2380 	message_add(&msg, &reserved, sizeof(reserved));
2381 	message_add(&msg, &priority, sizeof(priority));
2382 	message_add(&msg, &range_subid, sizeof(range_subid));
2383 	message_add(&msg, &reserved, sizeof(reserved));
2384 	message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 10, 1), 0);
2385 	message_add_uint32(&msg, upperbound);
2386 
2387 	agentx_write(s, &msg);
2388 
2389 	n = agentx_read(s, repl, sizeof(repl), 1000);
2390 
2391 	agentx_response_validate(__func__, repl, n, 0, packetid,
2392 	    UNKNOWNREGISTRATION, 0, NULL, 0);
2393 	message_release(&msg);
2394 	close(s);
2395 }
2396 
2397 void
agentx_get_handle(const char * test,const void * buf,size_t len,uint8_t flags,uint32_t sessionid,struct varbind * varbind,size_t nvarbind)2398 agentx_get_handle(const char *test, const void *buf, size_t len,
2399     uint8_t flags, uint32_t sessionid, struct varbind *varbind,
2400     size_t nvarbind)
2401 {
2402 	const struct header *header = buf;
2403 	struct oid start, end, zero = {0};
2404 	const uint8_t *u8;
2405 	uint32_t u32;
2406 	uint16_t u16;
2407 	size_t sublen, i, j;
2408 	char oid1[512], oid2[512];
2409 	struct varbind *pool;
2410 
2411 	if (len < sizeof(*header))
2412 		errx(1, "%s: unexpected pdu message size received: %zu", test, len);
2413 	if (header->version != 1)
2414 		errx(1, "%s: invalid pdu version", test);
2415 	if (header->type != AGENTX_GET_PDU)
2416 		errx(1, "%s: invalid pdu type received (%hhu/5)", test, header->type);
2417 	if (header->flags != flags)
2418 		errx(1, "%s: invalid get pdu flags received (%hhu/%hhu)",
2419 		    test, header->flags, flags);
2420 	if (header->reserved != 0)
2421 		errx(1, "%s: invalid get pdu reserved received", test);
2422 	if (p32toh(header, header->sessionid) != sessionid)
2423 		errx(1, "%s: unexpected get pdu sessionid (%u/%u)", test,
2424 		    p32toh(header, header->sessionid), sessionid);
2425 	if (p32toh(header, header->payload_length) > len - sizeof(*header))
2426 		errx(1, "%s: unexpected get pdu payload length received",
2427 		    test);
2428 
2429 	buf += sizeof(*header);
2430 	len = p32toh(header, header->payload_length);
2431 
2432 	if ((pool = calloc(nvarbind, sizeof(*pool))) == NULL)
2433 		err(1, NULL);
2434 	memcpy(pool, varbind, nvarbind * sizeof(*pool));
2435 
2436 	for (i = 0; len > 0; i++) {
2437 		sublen = poid(test, header, buf, len, &start);
2438 		buf += sublen;
2439 		len -= sublen;
2440 		sublen = poid(test, header, buf, len, &end);
2441 		buf += sublen;
2442 		len -= sublen;
2443 
2444 		if (oid_cmp(&end, &zero) != 0)
2445 			errx(1, "%s: unexpected searchrange end: (%s/%s)", test,
2446 			    oid_print(&end, oid1, sizeof(oid1)),
2447 			    oid_print(&zero, oid2, sizeof(oid2)));
2448 		if (start.include != 0 || end.include != 0)
2449 			errx(1, "%s: unexpected searchrange include: (%s)",
2450 			    test, oid_print(&start, oid1, sizeof(oid1)));
2451 		for (j = 0; j < nvarbind; j++) {
2452 			if (oid_cmp(&pool[j].name, &start) == 0)
2453 				break;
2454 		}
2455 		if (j == nvarbind)
2456 			warnx("%s: unexpected searchrange start: " "(%s)", test,
2457 			    oid_print(&start, oid1, sizeof(oid1)));
2458 
2459 		varbind[i] = pool[j];
2460 		pool[j].name.n_subid = 0;
2461 	}
2462 	free(pool);
2463 }
2464 
2465 void
agentx_getnext_handle(const char * test,const void * buf,size_t len,uint8_t flags,uint32_t sessionid,struct searchrange * searchrange,struct varbind * varbind,size_t nvarbind)2466 agentx_getnext_handle(const char *test, const void *buf, size_t len,
2467     uint8_t flags, uint32_t sessionid, struct searchrange *searchrange,
2468     struct varbind *varbind, size_t nvarbind)
2469 {
2470 	const struct header *header = buf;
2471 	struct oid start, end, zero = {0};
2472 	const uint8_t *u8;
2473 	uint32_t u32;
2474 	uint16_t u16;
2475 	size_t sublen, i, j, match;
2476 	char oid1[512], oid2[512], oid3[512], oid4[512];
2477 	struct varbind *pool;
2478 
2479 	if (len < sizeof(*header))
2480 		errx(1, "%s: unexpected pdu message size received: %zu", test, len);
2481 	if (header->version != 1)
2482 		errx(1, "%s: invalid pdu version", test);
2483 	if (header->type != AGENTX_GETNEXT_PDU)
2484 		errx(1, "%s: invalid pdu type received (%hhu/6)", test, header->type);
2485 	if (header->flags != flags)
2486 		errx(1, "%s: invalid get pdu flags received (%hhu/%hhu)",
2487 		    test, header->flags, flags);
2488 	if (header->reserved != 0)
2489 		errx(1, "%s: invalid get pdu reserved received", test);
2490 	if (p32toh(header, header->sessionid) != sessionid)
2491 		errx(1, "%s: unexpected get pdu sessionid (%u/%u)", test,
2492 		    p32toh(header, header->sessionid), sessionid);
2493 	if (p32toh(header, header->payload_length) > len - sizeof(*header))
2494 		errx(1, "%s: unexpected get pdu payload length received",
2495 		    test);
2496 
2497 	buf += sizeof(*header);
2498 	len = p32toh(header, header->payload_length);
2499 
2500 	if ((pool = calloc(nvarbind, sizeof(*pool))) == NULL)
2501 		err(1, NULL);
2502 	memcpy(pool, varbind, nvarbind * sizeof(*pool));
2503 
2504 	for (i = 0; len > 0; i++) {
2505 		sublen = poid(test, header, buf, len, &start);
2506 		buf += sublen;
2507 		len -= sublen;
2508 		sublen = poid(test, header, buf, len, &end);
2509 		buf += sublen;
2510 		len -= sublen;
2511 
2512 		if ((start.include != 1 && start.include != 0) ||
2513 		    end.include != 0)
2514 			errx(1, "%s: unexpected searchrange include: (%s-%s)",
2515 			    test, oid_print(&start, oid1, sizeof(oid1)),
2516 			    oid_print(&end, oid2, sizeof(oid2)));
2517 
2518 		match = (size_t)-1;
2519 		for (j = 0; j < nvarbind; j++) {
2520 			if (oid_cmp(&pool[j].name, &start) == 0 &&
2521 			    pool[j].type == TYPE_ENDOFMIBVIEW) {
2522 				match = j;
2523 			} else if (oid_cmp(&pool[j].name, &start) < 0 ||
2524 			    (!start.include &&
2525 			    oid_cmp(&pool[j].name, &start) == 0) ||
2526 			    oid_cmp(&pool[j].name, &end) >= 0)
2527 				continue;
2528 			if (match == (size_t)-1)
2529 				match = j;
2530 			else {
2531 				if (oid_cmp(&pool[j].name,
2532 				    &pool[match].name) < 0)
2533 					match = j;
2534 			}
2535 		}
2536 		if (match == (size_t)-1)
2537 			errx(1, "%s: unexpected searchrange start: " "(%s-%s)",
2538 			    test,
2539 			    oid_print(&start, oid1, sizeof(oid1)),
2540 			    oid_print(&end, oid2, sizeof(oid2)));
2541 		if (searchrange != NULL) {
2542 			if (oid_cmp(&searchrange[match].start, &start) != 0 ||
2543 			    oid_cmp(&searchrange[match].end, &end) != 0 ||
2544 			    searchrange[match].end.include != end.include ||
2545 			    searchrange[match].start.include != start.include)
2546 				errx(1, "%s: searchrange did not match "
2547 				    "(%s-%s/%s-%s)", test,
2548 				    oid_print(&start, oid1, sizeof(oid1)),
2549 				    oid_print(&end, oid2, sizeof(oid2)),
2550 				    oid_print(&searchrange[match].start, oid3,
2551 				    sizeof(oid3)),
2552 				    oid_print(&searchrange[match].end, oid4,
2553 				    sizeof(oid4)));
2554 		}
2555 
2556 		varbind[i] = pool[match];
2557 		pool[match].name.n_subid = 0;
2558 	}
2559 	free(pool);
2560 }
2561 
2562 /*
2563  * Don't assume a specific sequence of requests here so we can more easily
2564  * migrate to getbulk in agentx.
2565  */
2566 size_t
agentx_getbulk_handle(const char * test,const void * buf,size_t len,uint8_t flags,int32_t sessionid,struct varbind * varbind,size_t nvarbind,struct varbind * outvarbind)2567 agentx_getbulk_handle(const char *test, const void *buf, size_t len,
2568     uint8_t flags, int32_t sessionid, struct varbind *varbind, size_t nvarbind,
2569     struct varbind *outvarbind)
2570 {
2571 	const struct header *header = buf;
2572 	struct oid start, end, zero = {0};
2573 	const uint8_t *u8;
2574 	uint16_t nonrep, maxrep;
2575 	uint32_t u32;
2576 	uint16_t u16;
2577 	size_t sublen, i, j, match;
2578 	size_t nout = 0;
2579 	char oid1[512], oid2[512], oid3[512], oid4[512];
2580 
2581 	if (len < sizeof(*header))
2582 		errx(1, "%s: unexpected pdu message size received: %zu", test, len);
2583 	if (header->version != 1)
2584 		errx(1, "%s: invalid pdu version", test);
2585 	if (header->type != AGENTX_GETNEXT_PDU &&
2586 	    header->type != AGENTX_GETBULK_PDU)
2587 		errx(1, "%s: invalid pdu type received (%hhu/[67])",
2588 		    test, header->type);
2589 	if (header->flags != flags)
2590 		errx(1, "%s: invalid get pdu flags received (%hhu/%hhu)",
2591 		    test, header->flags, flags);
2592 	if (header->reserved != 0)
2593 		errx(1, "%s: invalid get pdu reserved received", test);
2594 	if (p32toh(header, header->sessionid) != sessionid)
2595 		errx(1, "%s: unexpected get pdu sessionid (%u/%u)", test,
2596 		    p32toh(header, header->sessionid), sessionid);
2597 	if (p32toh(header, header->payload_length) > len - sizeof(*header))
2598 		errx(1, "%s: unexpected get pdu payload length received",
2599 		    test);
2600 
2601 	buf += sizeof(*header);
2602 	len = p32toh(header, header->payload_length);
2603 
2604 	if (header->type == AGENTX_GETBULK_PDU) {
2605 		if (len < 4)
2606 			errx(1, "%s: missing non_repeaters/max_repititions",
2607 			    __func__);
2608 		memcpy(&u16, buf, sizeof(u16));
2609 		nonrep = p16toh(header, u16);
2610 		memcpy(&u16, buf + sizeof(u16), sizeof(u16));
2611 		maxrep = p16toh(header, u16);
2612 		buf += 4;
2613 	} else {
2614 		nonrep = 0;
2615 		maxrep = 1;
2616 	}
2617 	for (i = 0; len > 0; i++) {
2618 		sublen = poid(test, header, buf, len, &start);
2619 		buf += sublen;
2620 		len -= sublen;
2621 		sublen = poid(test, header, buf, len, &end);
2622 		buf += sublen;
2623 		len -= sublen;
2624 
2625 		if ((start.include != 1 && start.include != 0) ||
2626 		    end.include != 0)
2627 			errx(1, "%s: unexpected searchrange include: (%s-%s)",
2628 			    test, oid_print(&start, oid1, sizeof(oid1)),
2629 			    oid_print(&end, oid2, sizeof(oid2)));
2630 
2631 		match = (size_t)-1;
2632 		for (j = 0; j < nvarbind; j++) {
2633 			if (oid_cmp(&varbind[j].name, &start) == 0 &&
2634 			    varbind[j].type == TYPE_ENDOFMIBVIEW) {
2635 				match = j;
2636 			} else if (oid_cmp(&varbind[j].name, &start) < 0 ||
2637 			    (!start.include &&
2638 			    oid_cmp(&varbind[j].name, &start) == 0) ||
2639 			    oid_cmp(&varbind[j].name, &end) >= 0)
2640 				continue;
2641 			if (match == (size_t)-1)
2642 				match = j;
2643 			else {
2644 				if (oid_cmp(&varbind[j].name,
2645 				    &varbind[match].name) < 0)
2646 					match = j;
2647 			}
2648 		}
2649 		if (match == (size_t)-1)
2650 			errx(1, "%s: unexpected searchrange start: " "(%s-%s)",
2651 			    test,
2652 			    oid_print(&start, oid1, sizeof(oid1)),
2653 			    oid_print(&end, oid2, sizeof(oid2)));
2654 		outvarbind[nout++] = varbind[match];
2655 		varbind[match] = varbind[--nvarbind];
2656 		varbind[nvarbind] = (struct varbind){};
2657 	}
2658 	return nout;
2659 }
2660 
2661 void
agentx_close_validate(const char * test,const void * buf,size_t len,uint8_t flags,uint8_t reason)2662 agentx_close_validate(const char *test, const void *buf, size_t len,
2663     uint8_t flags, uint8_t reason)
2664 {
2665 	const struct header *header = buf;
2666 	const uint8_t *u8;
2667 	uint32_t u32;
2668 	uint16_t u16;
2669 
2670 	if (len != sizeof(*header) + 4)
2671 		errx(1, "%s: unexpected pdu message size received: %zu", test, len);
2672 	if (header->version != 1)
2673 		errx(1, "%s: invalid pdu version", test);
2674 	if (header->type != AGENTX_CLOSE_PDU)
2675 		errx(1, "%s: invalid pdu type received (%hhu/2)", test, header->type);
2676 	if (header->flags != flags)
2677 		errx(1, "%s: invalid close pdu flags received (%hhu/%hhu)",
2678 		    test, header->flags, flags);
2679 	if (header->reserved != 0)
2680 		errx(1, "%s: invalid close pdu reserved received", test);
2681 	if (p32toh(header, header->payload_length) != 4)
2682 		errx(1, "%s: unexpected response pdu payload length received",
2683 		    test);
2684 
2685 	u8 = buf + sizeof(*header);
2686 	if (u8[0] != reason)
2687 		errx(1, "%s: unexpected close reason (%hhu/%hhu)",
2688 		    test, u8[0], reason);
2689 	if (u8[1] != 0 || u8[2] != 0 || u8[3] != 0)
2690 		errx(1, "%s: invalid close pdu reserved received", test);
2691 }
2692 
2693 void
agentx_response_validate(const char * test,const void * buf,size_t len,uint8_t flags,uint32_t packetid,enum error error,uint16_t index,struct varbind * varbindlist,size_t nvarbind)2694 agentx_response_validate(const char *test, const void *buf, size_t len,
2695     uint8_t flags, uint32_t packetid, enum error error, uint16_t index,
2696     struct varbind *varbindlist, size_t nvarbind)
2697 {
2698 	const struct header *header = buf;
2699 	struct oid name, oid;
2700 	int32_t i32;
2701 	uint32_t u32;
2702 	uint16_t u16, type;
2703 	size_t i, sublen;
2704 
2705 	if (len < sizeof(*header) + 8)
2706 		errx(1, "%s: unexpected pdu message size received: %zu", test, len);
2707 	if (header->version != 1)
2708 		errx(1, "%s: invalid pdu version", test);
2709 	if (header->type != AGENTX_RESPONSE_PDU)
2710 		errx(1, "%s: invalid pdu type received (%hhu/18)", test, header->type);
2711 	if (header->flags != flags)
2712 		errx(1, "%s: invalid response pdu flags received (%hhu/%hhu)",
2713 		    test, header->flags, flags);
2714 	if (header->reserved != 0)
2715 		errx(1, "%s: invalid response pdu reserved received", test);
2716 	if (p32toh(header, header->packetid) != packetid)
2717 		errx(1, "%s: invalid response pdu packetid received", test);
2718 	/*
2719 	 * Needs to be changed once we start validating responses with varbinds.
2720 	 */
2721 	if (p32toh(header, header->payload_length) < 8 ||
2722 	    p32toh(header, header->payload_length) > len - sizeof(*header))
2723 		errx(1, "%s: unexpected response pdu payload length received",
2724 		    test);
2725 
2726 	buf += sizeof(*header);
2727 	len = p32toh(header, header->payload_length);
2728 	memcpy(&u32, buf, sizeof(u32));
2729 	if ((p32toh(header, u32) & 0xF0000000) != 0)
2730 		errx(1, "%s: unexpected response pdu sysUptime received",
2731 		    test);
2732 	buf += sizeof(u32);
2733 	memcpy(&u16, buf, sizeof(u16));
2734 	if (p16toh(header, u16) != error)
2735 		errx(1, "%s: unexpected response pdu error (%hu/%u)",
2736 		    test, p16toh(header, u16), error);
2737 	buf += sizeof(u16);
2738 	memcpy(&u16, buf, sizeof(u16));
2739 	if (p16toh(header, u16) != index)
2740 		errx(1, "%s: unexpected response pdu index (%hu/%hu)",
2741 		    test, p16toh(header, u16), index);
2742 	buf += sizeof(u16);
2743 	len -= 8;
2744 
2745 	for (i = 0; len > 0; i++) {
2746 		if (len < 4)
2747 			errx(1,
2748 			    "%s: invalid response pdu varbind length", test);
2749 		memcpy(&type, buf, sizeof(type));
2750 		type = p16toh(header, type);
2751 		if (i < nvarbind && type != varbindlist[i].type % 1000)
2752 			errx(1, "%s: invalid response pdu varbind type", test);
2753 		buf += sizeof(type);
2754 		len -= sizeof(type);
2755 		memcpy(&u16, buf, sizeof(u16));
2756 		if (u16 != 0)
2757 			errx(1, "%s: invalid response pdu varbind reserved",
2758 			    test);
2759 		buf += sizeof(u16);
2760 		len -= sizeof(u16);
2761 		sublen = poid(test, header, buf, len, &name);
2762 		if (i < nvarbind && oid_cmp(&varbindlist[i].name, &name) != 0)
2763 			errx(1, "%s: invalid response pdu varbind name", test);
2764 		buf += sublen;
2765 		len -= sublen;
2766 		switch (type % 1000) {
2767 		case TYPE_INTEGER:
2768 			if (len < sizeof(i32))
2769 				errx(1,
2770 				    "%s: invalid response pdu varbind length",
2771 				    test);
2772 			if (i < nvarbind && varbindlist[i].type / 1000 == 0) {
2773 				memcpy(&i32, buf, sizeof(i32));
2774 				i32 = p32toh(header, i32);
2775 				if (i32 != varbindlist[i].data.int32)
2776 					errx(1, "%s: invalid response pdu "
2777 					    "varbind integer", test);
2778 			}
2779 			break;
2780 		default:
2781 			errx(1, "%s: Regress test not implemented: %d", test, type);
2782 		}
2783 	}
2784 
2785 	if (i != nvarbind)
2786 		errx(1, "%s: unexpected response pdu nvarbind: (%zu/%zu)",
2787 		    test, i, nvarbind);
2788 }
2789 
2790 int
agentx_connect(const char * path)2791 agentx_connect(const char *path)
2792 {
2793 	struct sockaddr_un sun;
2794 	int s;
2795 
2796 	if (path == NULL)
2797 		path = AGENTX_SOCKET;
2798 
2799 	sun.sun_len = sizeof(sun);
2800 	sun.sun_family = AF_UNIX;
2801 	strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
2802 
2803 	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
2804 		err(1, "%s: socket", __func__);
2805 	if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) == -1)
2806 		err(1, "%s: connect", __func__);
2807 
2808 	return s;
2809 }
2810 
2811 uint32_t
agentx_open(int s,int nbo,uint8_t timeout,uint32_t oid[],size_t oidlen,const char * descr)2812 agentx_open(int s, int nbo, uint8_t timeout, uint32_t oid[], size_t oidlen,
2813      const char *descr)
2814 {
2815 	struct message msg ={};
2816 	char zero[3] = {};
2817 	char repl[1024];
2818 	size_t n;
2819 	uint32_t packetid = arc4random();
2820 	struct header *header = (struct header *)repl;
2821 
2822 	message_add_header(&msg, 1, AGENTX_OPEN_PDU,
2823 	    nbo ? NETWORK_BYTE_ORDER : 0, 0, 0, packetid);
2824 	message_add_uint8(&msg, timeout);
2825 	message_add(&msg, zero, 3);
2826 	message_add_oid(&msg, oid, oidlen, 0);
2827 	message_add_nstring(&msg, descr, strlen(descr));
2828 
2829 	agentx_write(s, &msg);
2830 	n = agentx_read(s, repl, sizeof(repl), 1000);
2831 
2832 	agentx_response_validate(__func__, repl, n,
2833 	    nbo ? NETWORK_BYTE_ORDER : 0, packetid, 0, 0, NULL, 0);
2834 
2835 	message_release(&msg);
2836 
2837 	return p32toh(header, header->sessionid);
2838 }
2839 
2840 void
agentx_close(int s,uint32_t sessionid,enum close_reason reason)2841 agentx_close(int s, uint32_t sessionid, enum close_reason reason)
2842 {
2843 	struct message msg ={};
2844 	char zero[3] = {};
2845 	char repl[1024];
2846 	size_t n;
2847 	uint32_t packetid = arc4random();
2848 	struct header *header = (struct header *)repl;
2849 
2850 	message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0,
2851 	    packetid);
2852 	message_add_uint8(&msg, reason);
2853 	message_add(&msg, zero, 3);
2854 
2855 	agentx_write(s, &msg);
2856 	n = agentx_read(s, repl, sizeof(repl), 1000);
2857 
2858 	agentx_response_validate(__func__, repl, n, 0, packetid, 0, 0, NULL, 0);
2859 
2860 	message_release(&msg);
2861 }
2862 
2863 void
agentx_register(int s,uint32_t sessionid,uint8_t instance,uint8_t timeout,uint8_t priority,uint8_t range_subid,uint32_t oid[],size_t oidlen,uint32_t upperbound)2864 agentx_register(int s, uint32_t sessionid, uint8_t instance, uint8_t timeout,
2865     uint8_t priority, uint8_t range_subid, uint32_t oid[], size_t oidlen,
2866     uint32_t upperbound)
2867 {
2868 	struct message msg = {};
2869 	char repl[1024];
2870 	size_t n;
2871 	uint32_t packetid = arc4random();
2872 	uint8_t reserved = 0;
2873 
2874 	message_add_header(&msg, 1, AGENTX_REGISTER_PDU,
2875 	    instance ? INSTANCE_REGISTRATION : 0, sessionid, 0, packetid);
2876 	message_add(&msg, &timeout, sizeof(timeout));
2877 	message_add(&msg, &priority, sizeof(priority));
2878 	message_add(&msg, &range_subid, sizeof(range_subid));
2879 	message_add(&msg, &reserved, sizeof(reserved));
2880 	message_add_oid(&msg, oid, oidlen, 0);
2881 	if (range_subid != 0)
2882 		message_add_uint32(&msg, upperbound);
2883 
2884 	agentx_write(s, &msg);
2885 
2886 	n = agentx_read(s, repl, sizeof(repl), 1000);
2887 
2888 	agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, 0,
2889 	    NULL, 0);
2890 	message_release(&msg);
2891 }
2892 
2893 void
agentx_response(int s,void * buf,enum error error,uint16_t index,struct varbind * varbindlist,size_t nvarbind)2894 agentx_response(int s, void *buf, enum error error, uint16_t index,
2895     struct varbind *varbindlist, size_t nvarbind)
2896 {
2897 	struct header *header = buf;
2898 	struct message msg = {};
2899 	char repl[1024];
2900 	size_t n;
2901 	uint32_t sysuptime = 0;
2902 	uint16_t reserved = 0;
2903 	size_t i;
2904 
2905 	message_add_header(&msg, 1, AGENTX_RESPONSE_PDU, 0,
2906 	    p32toh(header, header->sessionid),
2907 	    p32toh(header, header->transactionid),
2908 	    p32toh(header, header->packetid));
2909 	message_add_uint32(&msg, sysuptime);
2910 	message_add_uint16(&msg, error);
2911 	message_add_uint16(&msg, index);
2912 
2913 	for (i = 0; i < nvarbind; i++)
2914 		message_add_varbind(&msg, varbindlist + i);
2915 
2916 	agentx_write(s, &msg);
2917 	message_release(&msg);
2918 }
2919 
2920 static void
message_add_uint8(struct message * msg,uint8_t n)2921 message_add_uint8(struct message *msg, uint8_t n)
2922 {
2923 	message_add(msg, &n, 1);
2924 }
2925 
2926 static void
message_add_uint16(struct message * msg,uint16_t n)2927 message_add_uint16(struct message *msg, uint16_t n)
2928 {
2929 	if (MESSAGE_NBO(msg))
2930 		n = htobe16(n);
2931 	else
2932 		n = htole16(n);
2933 
2934 	message_add(msg, &n, sizeof(n));
2935 }
2936 
2937 static void
message_add_uint32(struct message * msg,uint32_t n)2938 message_add_uint32(struct message *msg, uint32_t n)
2939 {
2940 	if (MESSAGE_NBO(msg))
2941 		n = htobe32(n);
2942 	else
2943 		n = htole32(n);
2944 
2945 	message_add(msg, &n, sizeof(n));
2946 }
2947 
2948 static void
message_add_uint64(struct message * msg,uint64_t n)2949 message_add_uint64(struct message *msg, uint64_t n)
2950 {
2951 	if (MESSAGE_NBO(msg))
2952 		n = htobe64(n);
2953 	else
2954 		n = htole64(n);
2955 
2956 	message_add(msg, &n, sizeof(n));
2957 }
2958 
2959 static void
message_add_nstring(struct message * msg,const void * src,uint32_t len)2960 message_add_nstring(struct message *msg, const void *src, uint32_t len)
2961 {
2962 	char zero[3] = {};
2963 
2964 	message_add_uint32(msg, len);
2965 	if (len == 0)
2966 		return;
2967 	message_add(msg, src, len);
2968 	message_add(msg, zero, (4 - (len % 4)) % 4);
2969 }
2970 
2971 static void
message_add_oid(struct message * msg,const uint32_t oid[],uint8_t n_subid,uint8_t include)2972 message_add_oid(struct message *msg, const uint32_t oid[], uint8_t n_subid,
2973     uint8_t include)
2974 {
2975 	uint8_t prefix = 0;
2976 	uint8_t i;
2977 
2978 	if (n_subid > 5 && oid[0] == 1 && oid[1] == 3 && oid[2] == 6 &&
2979 	    oid[3] == 1 && oid[4] < UINT8_MAX) {
2980 		prefix = oid[4];
2981 		oid += 5;
2982 		n_subid -= 5;
2983 	}
2984 
2985 	message_add_uint8(msg, n_subid);
2986 	message_add_uint8(msg, prefix);
2987 	message_add_uint8(msg, include);
2988 	message_add_uint8(msg, 0);
2989 	for (i = 0; i < n_subid; i++)
2990 		message_add_uint32(msg, oid[i]);
2991 }
2992 
2993 static void
message_add_varbind(struct message * msg,struct varbind * varbind)2994 message_add_varbind(struct message *msg, struct varbind *varbind)
2995 {
2996 	uint64_t u64;
2997 	uint32_t u32;
2998 	size_t len;
2999 	va_list ap;
3000 
3001 	message_add_uint16(msg, varbind->type);
3002 	message_add_uint16(msg, 0);
3003 	message_add_oid(msg, varbind->name.subid, varbind->name.n_subid, 0);
3004 	switch (varbind->type) {
3005 	case INTEGER:
3006 		message_add_uint32(msg, varbind->data.int32);
3007 		break;
3008 	case COUNTER32:
3009 	case GAUGE32:
3010 	case TIMETICKS:
3011 		message_add_uint32(msg, varbind->data.uint32);
3012 		break;
3013 	case OCTETSTRING:
3014 	case IPADDRESS:
3015 	case OPAQUE:
3016 		message_add_nstring(msg, varbind->data.octetstring.string,
3017 		    varbind->data.octetstring.len);
3018 		break;
3019 	case OBJECTIDENTIFIER:
3020 		message_add_oid(msg, varbind->data.oid.subid,
3021 		    varbind->data.oid.n_subid, 0);
3022 		break;
3023 	case COUNTER64:
3024 		message_add_uint64(msg, varbind->data.uint64);
3025 		break;
3026 	case AXNULL:
3027 	case NOSUCHOBJECT:
3028 	case NOSUCHINSTANCE:
3029 	case ENDOFMIBVIEW:
3030 		break;
3031 	default:
3032 		errx(1, "%s: unsupported data type: %d", __func__,
3033 		    varbind->type);
3034 	}
3035 }
3036 
3037 static void
message_add_header(struct message * msg,uint8_t version,uint8_t type,uint8_t flags,uint32_t sessionid,uint32_t transactionid,uint32_t packetid)3038 message_add_header(struct message *msg, uint8_t version, uint8_t type,
3039     uint8_t flags, uint32_t sessionid, uint32_t transactionid,
3040     uint32_t packetid)
3041 {
3042 	if (msg->len != 0)
3043 		errx(1, "%s: message not new", __func__);
3044 	message_add_uint8(msg, version);
3045 	message_add_uint8(msg, type);
3046 	message_add_uint8(msg, flags);
3047 	message_add_uint8(msg, 0);
3048 	message_add_uint32(msg, sessionid);
3049 	message_add_uint32(msg, transactionid);
3050 	message_add_uint32(msg, packetid);
3051 	message_add_uint32(msg, 0); /* payload_length tbt */
3052 }
3053 
3054 static void
message_add(struct message * msg,const void * src,size_t len)3055 message_add(struct message *msg, const void *src, size_t len)
3056 {
3057 	if (len == 0)
3058 		return;
3059 	if (msg->len + len > msg->size) {
3060 		if ((msg->buf = recallocarray(msg->buf, msg->size,
3061 		    (((msg->len + len) % 4096) + 1) * 4096, 1)) == NULL)
3062 			err(1, NULL);
3063 		msg->size = (((msg->len + len) % 4096) + 1) * 4096;
3064 	}
3065 	memcpy(msg->buf + msg->len, src, len);
3066 	msg->len += len;
3067 }
3068 
3069 static void
message_release(struct message * msg)3070 message_release(struct message *msg)
3071 {
3072 	free(msg->buf);
3073 }
3074 
3075 static size_t
poid(const char * test,const struct header * header,const uint8_t * buf,size_t len,struct oid * oid)3076 poid(const char *test, const struct header *header, const uint8_t *buf, size_t len,
3077     struct oid *oid)
3078 {
3079 	uint8_t n_subid, i;
3080 	uint32_t subid;
3081 
3082 	if (len < 4)
3083 		errx(1, "%s: incomplete oid", test);
3084 	n_subid = buf[0];
3085 	if (buf[1] != 0) {
3086 		*oid = OID_STRUCT(1, 3, 6, 1, buf[1]);
3087 	} else
3088 		*oid = OID_STRUCT();
3089 	oid->include = buf[2];
3090 	if (buf[3] != 0)
3091 		errx(1, "%s: invalid oid reserved (%hhx)", test, buf[3]);
3092 	buf += 4;
3093 	len -= 4;
3094 	if (oid->n_subid + n_subid > 128)
3095 		errx(1, "%s: too many n_subid in oid", test);
3096 	if (len < n_subid * sizeof(oid->subid[0]))
3097 		errx(1, "%s: incomplete oid: (%zu/%zu)", test,
3098 		    n_subid * sizeof(oid->subid[0]), len);
3099 	for (i = 0; i < n_subid; i++) {
3100 		memcpy(&subid, buf, sizeof(subid));
3101 		buf += 4;
3102 		oid->subid[oid->n_subid++] = p32toh(header, subid);
3103 	}
3104 
3105 	return 4 * (n_subid + 1);
3106 }
3107 
3108 size_t
agentx_read(int s,void * buf,size_t len,int timeout)3109 agentx_read(int s, void *buf, size_t len, int timeout)
3110 {
3111 	ssize_t n;
3112 	size_t i;
3113 	int ret;
3114 	struct pollfd pfd = {
3115 		.fd = s,
3116 		.events = POLLIN
3117 	};
3118 
3119 	if ((ret = poll(&pfd, 1, timeout)) == -1)
3120 		err(1, "poll");
3121 	if (ret == 0)
3122 		errx(1, "%s: timeout", __func__);
3123 	if ((n = read(s, buf, len)) == -1)
3124 		err(1, "agentx read");
3125 
3126 	if (verbose && n != 0) {
3127 		printf("AgentX received(%d):\n", s);
3128 		for (i = 0; i < n; i++) {
3129 			printf("%s%02hhx", i % 4 == 0 ? "" : " ",
3130 			    ((char *)buf)[i]);
3131 			if (i % 4 == 3)
3132 				printf("\n");
3133 		}
3134 		if (i % 4 != 0)
3135 			printf("\n");
3136 	}
3137 	return n;
3138 }
3139 
3140 void
agentx_timeout(int s,int timeout)3141 agentx_timeout(int s, int timeout)
3142 {
3143 	int ret;
3144 	struct pollfd pfd = {
3145 		.fd = s,
3146 		.events = POLLIN
3147 	};
3148 
3149 	if ((ret = poll(&pfd, 1, timeout)) == -1)
3150 		err(1, "poll");
3151 	if (ret != 0)
3152 		errx(1, "%s: unexpected agentx data", __func__);
3153 }
3154 
3155 void
agentx_write(int s,struct message * msg)3156 agentx_write(int s, struct message *msg)
3157 {
3158 	ssize_t n;
3159 	char *buf = msg->buf;
3160 	size_t len = msg->len;
3161 	struct header *header = msg->buf;
3162 	size_t i;
3163 
3164 	msg->len = 16;
3165 	message_add_uint32(msg, len - sizeof(*header));
3166 
3167 	if (verbose) {
3168 		printf("AgentX sending(%d):\n", s);
3169 		for (i = 0; i < len; i++) {
3170 			printf("%s%02hhx", i % 4 == 0 ? "" : " ", buf[i]);
3171 			if (i % 4 == 3)
3172 				printf("\n");
3173 		}
3174 		if (i % 4 != 0)
3175 			printf("\n");
3176 	}
3177 
3178 	while (len > 0) {
3179 		if ((n = write(s, buf, len)) == -1)
3180 			err(1, "agentx write");
3181 		buf += n;
3182 		len -= n;
3183 	}
3184 	msg->len = 0;
3185 }
3186