Bug Summary

File:src/usr.sbin/snmpd/application_agentx.c
Warning:line 262, column 4
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name application_agentx.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/snmpd/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/usr.sbin/snmpd -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/snmpd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/snmpd/application_agentx.c
1/* $OpenBSD: application_agentx.c,v 1.15 2023/12/21 12:43:30 martijn Exp $ */
2/*
3 * Copyright (c) 2022 Martijn van Duren <martijn@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/queue.h>
19#include <sys/socket.h>
20#include <sys/stat.h>
21#include <sys/tree.h>
22#include <sys/un.h>
23
24#include <ber.h>
25#include <errno(*__errno()).h>
26#include <event.h>
27#include <inttypes.h>
28#include <stdint.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33
34#include "application.h"
35#include "ax.h"
36#include "log.h"
37#include "smi.h"
38#include "snmp.h"
39#include "snmpd.h"
40
41#define AGENTX_DEFAULTTIMEOUT5 5
42
43struct appl_agentx_connection {
44 uint32_t conn_id;
45 /*
46 * A backend has several overruling properties:
47 * - If it exits, snmpd crashes
48 * - All registrations are priority 1
49 * - All registrations own the subtree.
50 */
51 int conn_backend;
52 struct ax *conn_ax;
53 struct event conn_rev;
54 struct event conn_wev;
55
56 TAILQ_HEAD(, appl_agentx_session)struct { struct appl_agentx_session *tqh_first; struct appl_agentx_session
**tqh_last; }
conn_sessions;
57 RB_ENTRY(appl_agentx_connection)struct { struct appl_agentx_connection *rbe_left; struct appl_agentx_connection
*rbe_right; struct appl_agentx_connection *rbe_parent; int rbe_color
; }
conn_entry;
58};
59
60struct appl_agentx_session {
61 uint32_t sess_id;
62 struct appl_agentx_connection *sess_conn;
63 /*
64 * RFC 2741 section 7.1.1:
65 * All subsequent AgentX protocol operations initiated by the master
66 * agent for this session must use this byte ordering and set this bit
67 * accordingly.
68 */
69 enum ax_byte_order sess_byteorder;
70 uint8_t sess_timeout;
71 struct ax_oid sess_oid;
72 struct ax_ostring sess_descr;
73 struct appl_backend sess_backend;
74
75 RB_ENTRY(appl_agentx_session)struct { struct appl_agentx_session *rbe_left; struct appl_agentx_session
*rbe_right; struct appl_agentx_session *rbe_parent; int rbe_color
; }
sess_entry;
76 TAILQ_ENTRY(appl_agentx_session)struct { struct appl_agentx_session *tqe_next; struct appl_agentx_session
**tqe_prev; }
sess_conn_entry;
77};
78
79void appl_agentx_listen(struct agentx_master *);
80void appl_agentx_accept(int, short, void *);
81void appl_agentx_free(struct appl_agentx_connection *, enum appl_close_reason);
82void appl_agentx_recv(int, short, void *);
83void appl_agentx_open(struct appl_agentx_connection *, struct ax_pdu *);
84void appl_agentx_close(struct appl_agentx_session *, struct ax_pdu *);
85void appl_agentx_forceclose(struct appl_backend *, enum appl_close_reason);
86void appl_agentx_session_free(struct appl_agentx_session *);
87void appl_agentx_register(struct appl_agentx_session *, struct ax_pdu *);
88void appl_agentx_unregister(struct appl_agentx_session *, struct ax_pdu *);
89void appl_agentx_get(struct appl_backend *, int32_t, int32_t, const char *,
90 struct appl_varbind *);
91void appl_agentx_getnext(struct appl_backend *, int32_t, int32_t, const char *,
92 struct appl_varbind *);
93void appl_agentx_addagentcaps(struct appl_agentx_session *, struct ax_pdu *);
94void appl_agentx_removeagentcaps(struct appl_agentx_session *, struct ax_pdu *);
95void appl_agentx_response(struct appl_agentx_session *, struct ax_pdu *);
96void appl_agentx_send(int, short, void *);
97struct ber_oid *appl_agentx_oid2ber_oid(struct ax_oid *, struct ber_oid *);
98struct ber_element *appl_agentx_value2ber_element(struct ax_varbind *);
99struct ax_ostring *appl_agentx_string2ostring(const char *,
100 struct ax_ostring *);
101int appl_agentx_cmp(struct appl_agentx_connection *,
102 struct appl_agentx_connection *);
103int appl_agentx_session_cmp(struct appl_agentx_session *,
104 struct appl_agentx_session *);
105
106struct appl_backend_functions appl_agentx_functions = {
107 .ab_close = appl_agentx_forceclose,
108 .ab_get = appl_agentx_get,
109 .ab_getnext = appl_agentx_getnext,
110 .ab_getbulk = NULL((void *)0), /* not properly supported in application.c and libagentx */
111};
112
113RB_HEAD(appl_agentx_conns, appl_agentx_connection)struct appl_agentx_conns { struct appl_agentx_connection *rbh_root
; }
appl_agentx_conns =
114 RB_INITIALIZER(&appl_agentx_conns){ ((void *)0) };
115RB_HEAD(appl_agentx_sessions, appl_agentx_session)struct appl_agentx_sessions { struct appl_agentx_session *rbh_root
; }
appl_agentx_sessions =
116 RB_INITIALIZER(&appl_agentx_sessions){ ((void *)0) };
117
118RB_PROTOTYPE_STATIC(appl_agentx_conns, appl_agentx_connection, conn_entry,__attribute__((__unused__)) static void appl_agentx_conns_RB_INSERT_COLOR
(struct appl_agentx_conns *, struct appl_agentx_connection *)
; __attribute__((__unused__)) static void appl_agentx_conns_RB_REMOVE_COLOR
(struct appl_agentx_conns *, struct appl_agentx_connection *,
struct appl_agentx_connection *);__attribute__((__unused__))
static struct appl_agentx_connection *appl_agentx_conns_RB_REMOVE
(struct appl_agentx_conns *, struct appl_agentx_connection *)
; __attribute__((__unused__)) static struct appl_agentx_connection
*appl_agentx_conns_RB_INSERT(struct appl_agentx_conns *, struct
appl_agentx_connection *); __attribute__((__unused__)) static
struct appl_agentx_connection *appl_agentx_conns_RB_FIND(struct
appl_agentx_conns *, struct appl_agentx_connection *); __attribute__
((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_NFIND
(struct appl_agentx_conns *, struct appl_agentx_connection *)
; __attribute__((__unused__)) static struct appl_agentx_connection
*appl_agentx_conns_RB_NEXT(struct appl_agentx_connection *);
__attribute__((__unused__)) static struct appl_agentx_connection
*appl_agentx_conns_RB_PREV(struct appl_agentx_connection *);
__attribute__((__unused__)) static struct appl_agentx_connection
*appl_agentx_conns_RB_MINMAX(struct appl_agentx_conns *, int
);
119 appl_agentx_cmp)__attribute__((__unused__)) static void appl_agentx_conns_RB_INSERT_COLOR
(struct appl_agentx_conns *, struct appl_agentx_connection *)
; __attribute__((__unused__)) static void appl_agentx_conns_RB_REMOVE_COLOR
(struct appl_agentx_conns *, struct appl_agentx_connection *,
struct appl_agentx_connection *);__attribute__((__unused__))
static struct appl_agentx_connection *appl_agentx_conns_RB_REMOVE
(struct appl_agentx_conns *, struct appl_agentx_connection *)
; __attribute__((__unused__)) static struct appl_agentx_connection
*appl_agentx_conns_RB_INSERT(struct appl_agentx_conns *, struct
appl_agentx_connection *); __attribute__((__unused__)) static
struct appl_agentx_connection *appl_agentx_conns_RB_FIND(struct
appl_agentx_conns *, struct appl_agentx_connection *); __attribute__
((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_NFIND
(struct appl_agentx_conns *, struct appl_agentx_connection *)
; __attribute__((__unused__)) static struct appl_agentx_connection
*appl_agentx_conns_RB_NEXT(struct appl_agentx_connection *);
__attribute__((__unused__)) static struct appl_agentx_connection
*appl_agentx_conns_RB_PREV(struct appl_agentx_connection *);
__attribute__((__unused__)) static struct appl_agentx_connection
*appl_agentx_conns_RB_MINMAX(struct appl_agentx_conns *, int
);
;
120RB_PROTOTYPE_STATIC(appl_agentx_sessions, appl_agentx_session, sess_entry,__attribute__((__unused__)) static void appl_agentx_sessions_RB_INSERT_COLOR
(struct appl_agentx_sessions *, struct appl_agentx_session *)
; __attribute__((__unused__)) static void appl_agentx_sessions_RB_REMOVE_COLOR
(struct appl_agentx_sessions *, struct appl_agentx_session *,
struct appl_agentx_session *);__attribute__((__unused__)) static
struct appl_agentx_session *appl_agentx_sessions_RB_REMOVE(struct
appl_agentx_sessions *, struct appl_agentx_session *); __attribute__
((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_INSERT
(struct appl_agentx_sessions *, struct appl_agentx_session *)
; __attribute__((__unused__)) static struct appl_agentx_session
*appl_agentx_sessions_RB_FIND(struct appl_agentx_sessions *,
struct appl_agentx_session *); __attribute__((__unused__)) static
struct appl_agentx_session *appl_agentx_sessions_RB_NFIND(struct
appl_agentx_sessions *, struct appl_agentx_session *); __attribute__
((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_NEXT
(struct appl_agentx_session *); __attribute__((__unused__)) static
struct appl_agentx_session *appl_agentx_sessions_RB_PREV(struct
appl_agentx_session *); __attribute__((__unused__)) static struct
appl_agentx_session *appl_agentx_sessions_RB_MINMAX(struct appl_agentx_sessions
*, int);
121 appl_agentx_session_cmp)__attribute__((__unused__)) static void appl_agentx_sessions_RB_INSERT_COLOR
(struct appl_agentx_sessions *, struct appl_agentx_session *)
; __attribute__((__unused__)) static void appl_agentx_sessions_RB_REMOVE_COLOR
(struct appl_agentx_sessions *, struct appl_agentx_session *,
struct appl_agentx_session *);__attribute__((__unused__)) static
struct appl_agentx_session *appl_agentx_sessions_RB_REMOVE(struct
appl_agentx_sessions *, struct appl_agentx_session *); __attribute__
((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_INSERT
(struct appl_agentx_sessions *, struct appl_agentx_session *)
; __attribute__((__unused__)) static struct appl_agentx_session
*appl_agentx_sessions_RB_FIND(struct appl_agentx_sessions *,
struct appl_agentx_session *); __attribute__((__unused__)) static
struct appl_agentx_session *appl_agentx_sessions_RB_NFIND(struct
appl_agentx_sessions *, struct appl_agentx_session *); __attribute__
((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_NEXT
(struct appl_agentx_session *); __attribute__((__unused__)) static
struct appl_agentx_session *appl_agentx_sessions_RB_PREV(struct
appl_agentx_session *); __attribute__((__unused__)) static struct
appl_agentx_session *appl_agentx_sessions_RB_MINMAX(struct appl_agentx_sessions
*, int);
;
122
123void
124appl_agentx(void)
125{
126 struct agentx_master *master;
127
128 TAILQ_FOREACH(master, &(snmpd_env->sc_agentx_masters), axm_entry)for((master) = ((&(snmpd_env->sc_agentx_masters))->
tqh_first); (master) != ((void *)0); (master) = ((master)->
axm_entry.tqe_next))
129 appl_agentx_listen(master);
130}
131
132void
133appl_agentx_init(void)
134{
135 struct agentx_master *master;
136
137 TAILQ_FOREACH(master, &(snmpd_env->sc_agentx_masters), axm_entry)for((master) = ((&(snmpd_env->sc_agentx_masters))->
tqh_first); (master) != ((void *)0); (master) = ((master)->
axm_entry.tqe_next))
{
138 if (master->axm_fd == -1)
139 continue;
140 event_set(&(master->axm_ev), master->axm_fd,
141 EV_READ0x02 | EV_PERSIST0x10, appl_agentx_accept, master);
142 event_add(&(master->axm_ev), NULL((void *)0));
143 log_info("AgentX: listening on %s", master->axm_sun.sun_path);
144 }
145}
146void
147appl_agentx_listen(struct agentx_master *master)
148{
149 mode_t mask;
150
151 unlink(master->axm_sun.sun_path);
152
153 mask = umask(0777);
154 if ((master->axm_fd = socket(AF_UNIX1, SOCK_STREAM1, 0)) == -1 ||
155 bind(master->axm_fd, (struct sockaddr *)&(master->axm_sun),
156 sizeof(master->axm_sun)) == -1 ||
157 listen(master->axm_fd, 5)) {
158 log_warn("AgentX: listen %s", master->axm_sun.sun_path);
159 umask(mask);
160 return;
161 }
162 umask(mask);
163 if (chown(master->axm_sun.sun_path, master->axm_owner,
164 master->axm_group) == -1) {
165 log_warn("AgentX: chown %s", master->axm_sun.sun_path);
166 goto fail;
167 }
168 if (chmod(master->axm_sun.sun_path, master->axm_mode) == -1) {
169 log_warn("AgentX: chmod %s", master->axm_sun.sun_path);
170 goto fail;
171 }
172 return;
173 fail:
174 close(master->axm_fd);
175 master->axm_fd = -1;
176}
177
178void
179appl_agentx_shutdown(void)
180{
181 struct appl_agentx_connection *conn, *tconn;
182
183 RB_FOREACH_SAFE(conn, appl_agentx_conns, &appl_agentx_conns, tconn)for ((conn) = appl_agentx_conns_RB_MINMAX(&appl_agentx_conns
, -1); ((conn) != ((void *)0)) && ((tconn) = appl_agentx_conns_RB_NEXT
(conn), 1); (conn) = (tconn))
1
Assuming 'conn' is not equal to null
2
Loop condition is true. Entering loop body
184 appl_agentx_free(conn, APPL_CLOSE_REASONSHUTDOWN);
3
Calling 'appl_agentx_free'
185}
186
187void
188appl_agentx_accept(int masterfd, short event, void *cookie)
189{
190 int fd;
191 struct agentx_master *master = cookie;
192 struct sockaddr_un sun;
193 socklen_t sunlen = sizeof(sun);
194 struct appl_agentx_connection *conn = NULL((void *)0);
195
196 if ((fd = accept(masterfd, (struct sockaddr *)&sun, &sunlen)) == -1) {
197 log_warn("AgentX: accept %s", master->axm_sun.sun_path);
198 return;
199 }
200
201 if ((conn = malloc(sizeof(*conn))) == NULL((void *)0)) {
202 log_warn(NULL((void *)0));
203 goto fail;
204 }
205
206 conn->conn_backend = 0;
207 TAILQ_INIT(&(conn->conn_sessions))do { (&(conn->conn_sessions))->tqh_first = ((void *
)0); (&(conn->conn_sessions))->tqh_last = &(&
(conn->conn_sessions))->tqh_first; } while (0)
;
208 if ((conn->conn_ax = ax_new(fd)) == NULL((void *)0)) {
209 log_warn(NULL((void *)0));
210 goto fail;
211 }
212
213 do {
214 conn->conn_id = arc4random();
215 } while (RB_INSERT(appl_agentx_conns,appl_agentx_conns_RB_INSERT(&appl_agentx_conns, conn)
216 &appl_agentx_conns, conn)appl_agentx_conns_RB_INSERT(&appl_agentx_conns, conn) != NULL((void *)0));
217
218 event_set(&(conn->conn_rev), fd, EV_READ0x02 | EV_PERSIST0x10,
219 appl_agentx_recv, conn);
220 event_add(&(conn->conn_rev), NULL((void *)0));
221 event_set(&(conn->conn_wev), fd, EV_WRITE0x04, appl_agentx_send, conn);
222 log_info("AgentX(%"PRIu32"u""): new connection", conn->conn_id);
223
224 return;
225 fail:
226 close(fd);
227 free(conn);
228}
229
230void
231appl_agentx_backend(int fd)
232{
233 struct appl_agentx_connection *conn;
234
235 if ((conn = malloc(sizeof(*conn))) == NULL((void *)0))
236 fatal(NULL((void *)0));
237
238 conn->conn_backend = 1;
239 TAILQ_INIT(&(conn->conn_sessions))do { (&(conn->conn_sessions))->tqh_first = ((void *
)0); (&(conn->conn_sessions))->tqh_last = &(&
(conn->conn_sessions))->tqh_first; } while (0)
;
240 if ((conn->conn_ax = ax_new(fd)) == NULL((void *)0))
241 fatal("ax_new");
242
243 do {
244 conn->conn_id = arc4random();
245 } while (RB_INSERT(appl_agentx_conns,appl_agentx_conns_RB_INSERT(&appl_agentx_conns, conn)
246 &appl_agentx_conns, conn)appl_agentx_conns_RB_INSERT(&appl_agentx_conns, conn) != NULL((void *)0));
247
248 event_set(&(conn->conn_rev), fd, EV_READ0x02 | EV_PERSIST0x10,
249 appl_agentx_recv, conn);
250 event_add(&(conn->conn_rev), NULL((void *)0));
251 event_set(&(conn->conn_wev), fd, EV_WRITE0x04, appl_agentx_send, conn);
252}
253
254void
255appl_agentx_free(struct appl_agentx_connection *conn,
256 enum appl_close_reason reason)
257{
258 struct appl_agentx_session *session;
259
260 while ((session = TAILQ_FIRST(&(conn->conn_sessions))((&(conn->conn_sessions))->tqh_first)) != NULL((void *)0)) {
4
Assuming the condition is true
5
Loop condition is true. Entering loop body
14
Loop condition is true. Entering loop body
261 if (conn->conn_ax
14.1
Field 'conn_ax' is equal to NULL
== NULL((void *)0)
)
6
Assuming field 'conn_ax' is equal to NULL
7
Taking true branch
15
Taking true branch
262 appl_agentx_session_free(session);
8
Calling 'appl_agentx_session_free'
13
Returning; memory was released via 1st parameter
16
Use of memory after it is freed
263 else
264 appl_agentx_forceclose(&(session->sess_backend),
265 reason);
266 }
267
268 event_del(&(conn->conn_rev));
269 event_del(&(conn->conn_wev));
270
271 RB_REMOVE(appl_agentx_conns, &appl_agentx_conns, conn)appl_agentx_conns_RB_REMOVE(&appl_agentx_conns, conn);
272 if (conn->conn_ax != NULL((void *)0))
273 (void)ax_send(conn->conn_ax);
274 ax_free(conn->conn_ax);
275 if (conn->conn_backend)
276 fatalx("AgentX(%"PRIu32"u""): disappeared unexpected",
277 conn->conn_id);
278 free(conn);
279}
280
281void
282appl_agentx_recv(int fd, short event, void *cookie)
283{
284 struct appl_agentx_connection *conn = cookie;
285 struct appl_agentx_session *session = NULL((void *)0);
286 struct ax_pdu *pdu;
287 enum appl_error error;
288 char name[100];
289
290 snprintf(name, sizeof(name), "AgentX(%"PRIu32"u"")", conn->conn_id);
291 if ((pdu = ax_recv(conn->conn_ax)) == NULL((void *)0)) {
292 if (errno(*__errno()) == EAGAIN35)
293 return;
294 log_warn("%s", name);
295 /*
296 * Either the connection is dead, or we had garbage on the line.
297 * Both make sure we can't continue on this stream.
298 */
299 if (errno(*__errno()) == ECONNRESET54) {
300 ax_free(conn->conn_ax);
301 conn->conn_ax = NULL((void *)0);
302 }
303 appl_agentx_free(conn, errno(*__errno()) == EPROTO95 ?
304 APPL_CLOSE_REASONPROTOCOLERROR : APPL_CLOSE_REASONOTHER);
305 return;
306 }
307
308 conn->conn_ax->ax_byteorder = pdu->ap_header.aph_flags &
309 AX_PDU_FLAG_NETWORK_BYTE_ORDER(1 << 4) ?
310 AX_BYTE_ORDER_BE : AX_BYTE_ORDER_LE;
311 if (pdu->ap_header.aph_type != AX_PDU_TYPE_OPEN) {
312 /* Make sure we only look for connection-local sessions */
313 TAILQ_FOREACH(session, &(conn->conn_sessions),for((session) = ((&(conn->conn_sessions))->tqh_first
); (session) != ((void *)0); (session) = ((session)->sess_conn_entry
.tqe_next))
314 sess_conn_entry)for((session) = ((&(conn->conn_sessions))->tqh_first
); (session) != ((void *)0); (session) = ((session)->sess_conn_entry
.tqe_next))
{
315 if (session->sess_id == pdu->ap_header.aph_sessionid)
316 break;
317 }
318 if (session == NULL((void *)0)) {
319 log_warnx("%s: Session %"PRIu32"u"" not found for request",
320 name, pdu->ap_header.aph_sessionid);
321 error = APPL_ERROR_NOTOPEN;
322 goto fail;
323 }
324 strlcpy(name, session->sess_backend.ab_name, sizeof(name));
325 /*
326 * RFC2741 section 7.1.1 bullet 4 is unclear on what byte order
327 * the response should be. My best guess is that it makes more
328 * sense that replies are in the same byte-order as what was
329 * requested.
330 * In practice we always have the same byte order as when we
331 * opened the session, so it's likely a non-issue, however, we
332 * can change to session byte order here.
333 */
334 }
335
336 if (pdu->ap_header.aph_flags & AX_PDU_FLAG_INSTANCE_REGISTRATION(1 << 0)) {
337 if (pdu->ap_header.aph_type != AX_PDU_TYPE_REGISTER) {
338 log_warnx("%s: %s: Invalid INSTANCE_REGISTRATION flag",
339 name, ax_pdutype2string(pdu->ap_header.aph_flags));
340 error = APPL_ERROR_PARSEERROR;
341 goto fail;
342 }
343 }
344 if (pdu->ap_header.aph_flags & AX_PDU_FLAG_NEW_INDEX(1 << 1)) {
345 if (pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXALLOCATE &&
346 pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXDEALLOCATE) {
347 log_warnx("%s: %s: Invalid NEW_INDEX flag", name,
348 ax_pdutype2string(pdu->ap_header.aph_flags));
349 error = APPL_ERROR_PARSEERROR;
350 goto fail;
351 }
352 }
353 if (pdu->ap_header.aph_flags & AX_PDU_FLAG_ANY_INDEX(1 << 2)) {
354 if (pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXALLOCATE &&
355 pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXDEALLOCATE) {
356 log_warnx("%s: %s: Invalid ANY_INDEX flag", name,
357 ax_pdutype2string(pdu->ap_header.aph_flags));
358 error = APPL_ERROR_PARSEERROR;
359 goto fail;
360 }
361 }
362 if (pdu->ap_header.aph_flags & AX_PDU_FLAG_NON_DEFAULT_CONTEXT(1 << 3)) {
363 if (pdu->ap_header.aph_type != AX_PDU_TYPE_REGISTER &&
364 pdu->ap_header.aph_type != AX_PDU_TYPE_UNREGISTER &&
365 pdu->ap_header.aph_type != AX_PDU_TYPE_ADDAGENTCAPS &&
366 pdu->ap_header.aph_type != AX_PDU_TYPE_REMOVEAGENTCAPS &&
367 pdu->ap_header.aph_type != AX_PDU_TYPE_GET &&
368 pdu->ap_header.aph_type != AX_PDU_TYPE_GETNEXT &&
369 pdu->ap_header.aph_type != AX_PDU_TYPE_GETBULK &&
370 pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXALLOCATE &&
371 pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXDEALLOCATE &&
372 pdu->ap_header.aph_type != AX_PDU_TYPE_NOTIFY &&
373 pdu->ap_header.aph_type != AX_PDU_TYPE_TESTSET &&
374 pdu->ap_header.aph_type != AX_PDU_TYPE_PING) {
375 log_warnx("%s: %s: Invalid NON_DEFAULT_CONTEXT flag",
376 name, ax_pdutype2string(pdu->ap_header.aph_flags));
377 error = APPL_ERROR_PARSEERROR;
378 goto fail;
379 }
380 if (appl_context(pdu->ap_context.aos_string, 0) == NULL((void *)0)) {
381 log_warnx("%s: %s: Unsupported context",
382 name, ax_pdutype2string(pdu->ap_header.aph_flags));
383 error = APPL_ERROR_UNSUPPORTEDCONTEXT;
384 goto fail;
385 }
386 }
387 switch (pdu->ap_header.aph_type) {
388 case AX_PDU_TYPE_OPEN:
389 appl_agentx_open(conn, pdu);
390 break;
391 case AX_PDU_TYPE_CLOSE:
392 appl_agentx_close(session, pdu);
393 break;
394 case AX_PDU_TYPE_REGISTER:
395 appl_agentx_register(session, pdu);
396 break;
397 case AX_PDU_TYPE_UNREGISTER:
398 appl_agentx_unregister(session, pdu);
399 break;
400 case AX_PDU_TYPE_GET:
401 case AX_PDU_TYPE_GETNEXT:
402 case AX_PDU_TYPE_GETBULK:
403 case AX_PDU_TYPE_TESTSET:
404 case AX_PDU_TYPE_COMMITSET:
405 case AX_PDU_TYPE_UNDOSET:
406 case AX_PDU_TYPE_CLEANUPSET:
407 log_warnx("%s: %s: Not an adminsitrative message", name,
408 ax_pdutype2string(pdu->ap_header.aph_type));
409 error = APPL_ERROR_PARSEERROR;
410 goto fail;
411 case AX_PDU_TYPE_NOTIFY:
412 log_warnx("%s: %s: not supported", name,
413 ax_pdutype2string(pdu->ap_header.aph_type));
414 /*
415 * RFC 2741 section 7.1.10:
416 * Note that the master agent's successful response indicates
417 * the agentx-Notify-PDU was received and validated. It does
418 * not indicate that any particular notifications were actually
419 * generated or received by notification targets
420 */
421 /* XXX Not yet - FALLTHROUGH */
422 case AX_PDU_TYPE_PING:
423 ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid,
424 pdu->ap_header.aph_transactionid,
425 pdu->ap_header.aph_packetid, smi_getticks(),
426 APPL_ERROR_NOERROR, 0, NULL((void *)0), 0);
427 event_add(&(conn->conn_wev), NULL((void *)0));
428 break;
429 case AX_PDU_TYPE_INDEXALLOCATE:
430 case AX_PDU_TYPE_INDEXDEALLOCATE:
431 log_warnx("%s: %s: not supported", name,
432 ax_pdutype2string(pdu->ap_header.aph_type));
433 ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid,
434 pdu->ap_header.aph_transactionid,
435 pdu->ap_header.aph_packetid, smi_getticks(),
436 APPL_ERROR_PROCESSINGERROR, 1,
437 pdu->ap_payload.ap_vbl.ap_varbind,
438 pdu->ap_payload.ap_vbl.ap_nvarbind);
439 event_add(&(conn->conn_wev), NULL((void *)0));
440 break;
441 case AX_PDU_TYPE_ADDAGENTCAPS:
442 appl_agentx_addagentcaps(session, pdu);
443 break;
444 case AX_PDU_TYPE_REMOVEAGENTCAPS:
445 appl_agentx_removeagentcaps(session, pdu);
446 break;
447 case AX_PDU_TYPE_RESPONSE:
448 appl_agentx_response(session, pdu);
449 break;
450 }
451
452 ax_pdu_free(pdu);
453 return;
454 fail:
455 ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid,
456 pdu->ap_header.aph_transactionid,
457 pdu->ap_header.aph_packetid, smi_getticks(),
458 error, 0, NULL((void *)0), 0);
459 event_add(&(conn->conn_wev), NULL((void *)0));
460 ax_pdu_free(pdu);
461
462 if (session == NULL((void *)0) || error != APPL_ERROR_PARSEERROR)
463 return;
464
465 appl_agentx_forceclose(&(session->sess_backend),
466 APPL_CLOSE_REASONPARSEERROR);
467 if (TAILQ_EMPTY(&(conn->conn_sessions))(((&(conn->conn_sessions))->tqh_first) == ((void *)
0))
)
468 appl_agentx_free(conn, APPL_CLOSE_REASONOTHER);
469}
470
471void
472appl_agentx_open(struct appl_agentx_connection *conn, struct ax_pdu *pdu)
473{
474 struct appl_agentx_session *session;
475 struct ber_oid oid;
476 char oidbuf[1024];
477 enum appl_error error = APPL_ERROR_NOERROR;
478
479 if ((session = malloc(sizeof(*session))) == NULL((void *)0)) {
480 log_warn(NULL((void *)0));
481 error = APPL_ERROR_OPENFAILED;
482 goto fail;
483 }
484 session->sess_descr.aos_string = NULL((void *)0);
485
486 session->sess_conn = conn;
487 if (pdu->ap_header.aph_flags & AX_PDU_FLAG_NETWORK_BYTE_ORDER(1 << 4))
488 session->sess_byteorder = AX_BYTE_ORDER_BE;
489 else
490 session->sess_byteorder = AX_BYTE_ORDER_LE;
491
492 /* RFC 2742 agentxSessionObjectID */
493 if (pdu->ap_payload.ap_open.ap_oid.aoi_idlen == 0) {
494 pdu->ap_payload.ap_open.ap_oid.aoi_id[0] = 0;
495 pdu->ap_payload.ap_open.ap_oid.aoi_id[1] = 0;
496 pdu->ap_payload.ap_open.ap_oid.aoi_idlen = 2;
497 } else if (pdu->ap_payload.ap_open.ap_oid.aoi_idlen == 1) {
498 log_warnx("AgentX(%"PRIu32"u""): Invalid oid: Open Failed",
499 conn->conn_id);
500 error = APPL_ERROR_PARSEERROR;
501 goto fail;
502 }
503 /* RFC 2742 agentxSessionDescr */
504 if (pdu->ap_payload.ap_open.ap_descr.aos_slen > 255) {
505 log_warnx("AgentX(%"PRIu32"u""): Invalid descr (too long): Open "
506 "Failed", conn->conn_id);
507 error = APPL_ERROR_PARSEERROR;
508 goto fail;
509 }
510 /*
511 * ax_ostring is always NUL-terminated, but doesn't scan for internal
512 * NUL-bytes. However, mbstowcs stops at NUL, which might be in the
513 * middle of the string.
514 */
515 if (strlen(pdu->ap_payload.ap_open.ap_descr.aos_string) !=
516 pdu->ap_payload.ap_open.ap_descr.aos_slen ||
517 mbstowcs(NULL((void *)0),
518 pdu->ap_payload.ap_open.ap_descr.aos_string, 0) == (size_t)-1) {
519 log_warnx("AgentX(%"PRIu32"u""): Invalid descr (not UTF-8): "
520 "Open Failed", conn->conn_id);
521 error = APPL_ERROR_PARSEERROR;
522 goto fail;
523 }
524
525 session->sess_timeout = pdu->ap_payload.ap_open.ap_timeout;
526 session->sess_oid = pdu->ap_payload.ap_open.ap_oid;
527 session->sess_descr.aos_slen = pdu->ap_payload.ap_open.ap_descr.aos_slen;
528 if (pdu->ap_payload.ap_open.ap_descr.aos_string != NULL((void *)0)) {
529 session->sess_descr.aos_string =
530 strdup(pdu->ap_payload.ap_open.ap_descr.aos_string);
531 if (session->sess_descr.aos_string == NULL((void *)0)) {
532 log_warn("AgentX(%"PRIu32"u""): strdup: Open Failed",
533 conn->conn_id);
534 error = APPL_ERROR_OPENFAILED;
535 goto fail;
536 }
537 }
538
539 /* RFC 2742 agentxSessionIndex: chances of reuse, slim to none */
540 do {
541 session->sess_id = arc4random();
542 } while (RB_INSERT(appl_agentx_sessions,appl_agentx_sessions_RB_INSERT(&appl_agentx_sessions, session
)
543 &appl_agentx_sessions, session)appl_agentx_sessions_RB_INSERT(&appl_agentx_sessions, session
)
!= NULL((void *)0));
544
545 if (asprintf(&(session->sess_backend.ab_name),
546 "AgentX(%"PRIu32"u""/%"PRIu32"u"")",
547 conn->conn_id, session->sess_id) == -1) {
548 log_warn("AgentX(%"PRIu32"u""): asprintf: Open Failed",
549 conn->conn_id);
550 error = APPL_ERROR_OPENFAILED;
551 goto fail;
552 }
553 session->sess_backend.ab_cookie = session;
554 session->sess_backend.ab_retries = 0;
555 session->sess_backend.ab_fn = &appl_agentx_functions;
556 session->sess_backend.ab_range = 1;
557 RB_INIT(&(session->sess_backend.ab_requests))do { (&(session->sess_backend.ab_requests))->rbh_root
= ((void *)0); } while (0)
;
558 TAILQ_INSERT_TAIL(&(conn->conn_sessions), session, sess_conn_entry)do { (session)->sess_conn_entry.tqe_next = ((void *)0); (session
)->sess_conn_entry.tqe_prev = (&(conn->conn_sessions
))->tqh_last; *(&(conn->conn_sessions))->tqh_last
= (session); (&(conn->conn_sessions))->tqh_last = &
(session)->sess_conn_entry.tqe_next; } while (0)
;
559
560 appl_agentx_oid2ber_oid(&(session->sess_oid), &oid);
561 smi_oid2string(&oid, oidbuf, sizeof(oidbuf), 0);
562 log_info("%s: %s %s: Open", session->sess_backend.ab_name, oidbuf,
563 session->sess_descr.aos_string);
564
565 ax_response(conn->conn_ax, session->sess_id,
566 pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
567 smi_getticks(), APPL_ERROR_NOERROR, 0, NULL((void *)0), 0);
568 event_add(&(conn->conn_wev), NULL((void *)0));
569
570 return;
571 fail:
572 ax_response(conn->conn_ax, 0, pdu->ap_header.aph_transactionid,
573 pdu->ap_header.aph_packetid, 0, error, 0, NULL((void *)0), 0);
574 event_add(&(conn->conn_wev), NULL((void *)0));
575 if (session != NULL((void *)0))
576 free(session->sess_descr.aos_string);
577 free(session);
578}
579
580void
581appl_agentx_close(struct appl_agentx_session *session, struct ax_pdu *pdu)
582{
583 struct appl_agentx_connection *conn = session->sess_conn;
584 char name[100];
585 enum appl_error error = APPL_ERROR_NOERROR;
586
587 strlcpy(name, session->sess_backend.ab_name, sizeof(name));
588 if (pdu->ap_payload.ap_close.ap_reason == AX_CLOSE_BYMANAGER) {
589 log_warnx("%s: Invalid close reason", name);
590 error = APPL_ERROR_PARSEERROR;
591 } else {
592 appl_agentx_session_free(session);
593 log_info("%s: Closed by subagent (%s)", name,
594 ax_closereason2string(pdu->ap_payload.ap_close.ap_reason));
595 }
596
597 ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid,
598 pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
599 smi_getticks(), error, 0, NULL((void *)0), 0);
600 event_add(&(conn->conn_wev), NULL((void *)0));
601 if (error == APPL_ERROR_NOERROR)
602 return;
603
604 appl_agentx_forceclose(&(session->sess_backend),
605 APPL_CLOSE_REASONPARSEERROR);
606 if (TAILQ_EMPTY(&(conn->conn_sessions))(((&(conn->conn_sessions))->tqh_first) == ((void *)
0))
)
607 appl_agentx_free(conn, APPL_CLOSE_REASONOTHER);
608}
609
610void
611appl_agentx_forceclose(struct appl_backend *backend,
612 enum appl_close_reason reason)
613{
614 struct appl_agentx_session *session = backend->ab_cookie;
615 char name[100];
616
617 session->sess_conn->conn_ax->ax_byteorder = session->sess_byteorder;
618 ax_close(session->sess_conn->conn_ax, session->sess_id,
619 (enum ax_close_reason) reason);
620 event_add(&(session->sess_conn->conn_wev), NULL((void *)0));
621
622 strlcpy(name, session->sess_backend.ab_name, sizeof(name));
623 appl_agentx_session_free(session);
624 log_info("%s: Closed by snmpd (%s)", name,
625 ax_closereason2string((enum ax_close_reason)reason));
626}
627
628void
629appl_agentx_session_free(struct appl_agentx_session *session)
630{
631 struct appl_agentx_connection *conn = session->sess_conn;
632
633 appl_close(&(session->sess_backend));
634
635 RB_REMOVE(appl_agentx_sessions, &appl_agentx_sessions, session)appl_agentx_sessions_RB_REMOVE(&appl_agentx_sessions, session
)
;
636 TAILQ_REMOVE(&(conn->conn_sessions), session, sess_conn_entry)do { if (((session)->sess_conn_entry.tqe_next) != ((void *
)0)) (session)->sess_conn_entry.tqe_next->sess_conn_entry
.tqe_prev = (session)->sess_conn_entry.tqe_prev; else (&
(conn->conn_sessions))->tqh_last = (session)->sess_conn_entry
.tqe_prev; *(session)->sess_conn_entry.tqe_prev = (session
)->sess_conn_entry.tqe_next; ; ; } while (0)
;
9
Assuming field 'tqe_next' is equal to null
10
Taking false branch
11
Loop condition is false. Exiting loop
637
638 free(session->sess_backend.ab_name);
639 free(session->sess_descr.aos_string);
640 free(session);
12
Memory is released
641}
642
643void
644appl_agentx_register(struct appl_agentx_session *session, struct ax_pdu *pdu)
645{
646 uint32_t timeout;
647 struct ber_oid oid;
648 enum appl_error error;
649 int subtree = 0;
650
651 timeout = pdu->ap_payload.ap_register.ap_timeout;
652 timeout = timeout != 0 ? timeout : session->sess_timeout != 0 ?
653 session->sess_timeout : AGENTX_DEFAULTTIMEOUT5;
654 timeout *= 100;
655
656 if (session->sess_conn->conn_backend) {
657 pdu->ap_payload.ap_register.ap_priority = 1;
658 subtree = 1;
659 }
660 if (appl_agentx_oid2ber_oid(
661 &(pdu->ap_payload.ap_register.ap_subtree), &oid) == NULL((void *)0)) {
662 log_warnx("%s: Failed to register: oid too small",
663 session->sess_backend.ab_name);
664 error = APPL_ERROR_PROCESSINGERROR;
665 goto fail;
666 }
667
668 error = appl_register(pdu->ap_context.aos_string, timeout,
669 pdu->ap_payload.ap_register.ap_priority, &oid,
670 pdu->ap_header.aph_flags & AX_PDU_FLAG_INSTANCE_REGISTRATION(1 << 0),
671 subtree, pdu->ap_payload.ap_register.ap_range_subid,
672 pdu->ap_payload.ap_register.ap_upper_bound,
673 &(session->sess_backend));
674
675 fail:
676 ax_response(session->sess_conn->conn_ax, session->sess_id,
677 pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
678 smi_getticks(), error, 0, NULL((void *)0), 0);
679 event_add(&(session->sess_conn->conn_wev), NULL((void *)0));
680}
681
682void
683appl_agentx_unregister(struct appl_agentx_session *session, struct ax_pdu *pdu)
684{
685 struct ber_oid oid;
686 enum appl_error error;
687
688 if (appl_agentx_oid2ber_oid(
689 &(pdu->ap_payload.ap_unregister.ap_subtree), &oid) == NULL((void *)0)) {
690 log_warnx("%s: Failed to unregister: oid too small",
691 session->sess_backend.ab_name);
692 error = APPL_ERROR_PROCESSINGERROR;
693 goto fail;
694 }
695
696 error = appl_unregister(pdu->ap_context.aos_string,
697 pdu->ap_payload.ap_unregister.ap_priority, &oid,
698 pdu->ap_payload.ap_unregister.ap_range_subid,
699 pdu->ap_payload.ap_unregister.ap_upper_bound,
700 &(session->sess_backend));
701
702 fail:
703 ax_response(session->sess_conn->conn_ax, session->sess_id,
704 pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
705 smi_getticks(), error, 0, NULL((void *)0), 0);
706 event_add(&(session->sess_conn->conn_wev), NULL((void *)0));
707}
708
709#define AX_PDU_FLAG_INDEX((1 << 1) | (1 << 2)) (AX_PDU_FLAG_NEW_INDEX(1 << 1) | AX_PDU_FLAG_ANY_INDEX(1 << 2))
710
711void
712appl_agentx_get(struct appl_backend *backend, int32_t transactionid,
713 int32_t requestid, const char *ctx, struct appl_varbind *vblist)
714{
715 struct appl_agentx_session *session = backend->ab_cookie;
716 struct ax_ostring *context, string;
717 struct appl_varbind *vb;
718 struct ax_searchrange *srl;
719 size_t i, j, nsr;
720
721 if (session->sess_conn->conn_ax == NULL((void *)0))
722 return;
723
724 for (nsr = 0, vb = vblist; vb != NULL((void *)0); vb = vb->av_next)
725 nsr++;
726
727 if ((srl = calloc(nsr, sizeof(*srl))) == NULL((void *)0)) {
728 log_warn(NULL((void *)0));
729 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist);
730 return;
731 }
732
733 for (i = 0, vb = vblist; i < nsr; i++, vb = vb->av_next) {
734 srl[i].asr_start.aoi_include = vb->av_include;
735 srl[i].asr_start.aoi_idlen = vb->av_oid.bo_n;
736 for (j = 0; j < vb->av_oid.bo_n; j++)
737 srl[i].asr_start.aoi_id[j] = vb->av_oid.bo_id[j];
738 srl[i].asr_stop.aoi_include = 0;
739 srl[i].asr_stop.aoi_idlen = 0;
740 }
741 if ((context = appl_agentx_string2ostring(ctx, &string)) == NULL((void *)0)) {
742 if (errno(*__errno()) != 0) {
743 log_warn("Failed to convert context");
744 appl_response(backend, requestid,
745 APPL_ERROR_GENERR, 1, vblist);
746 free(srl);
747 return;
748 }
749 }
750
751 session->sess_conn->conn_ax->ax_byteorder = session->sess_byteorder;
752 if (ax_get(session->sess_conn->conn_ax, session->sess_id, transactionid,
753 requestid, context, srl, nsr) == -1)
754 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist);
755 else
756 event_add(&(session->sess_conn->conn_wev), NULL((void *)0));
757 free(srl);
758 if (context != NULL((void *)0))
759 free(context->aos_string);
760}
761
762void
763appl_agentx_getnext(struct appl_backend *backend, int32_t transactionid,
764 int32_t requestid, const char *ctx, struct appl_varbind *vblist)
765{
766 struct appl_agentx_session *session = backend->ab_cookie;
767 struct ax_ostring *context, string;
768 struct appl_varbind *vb;
769 struct ax_searchrange *srl;
770 size_t i, j, nsr;
771
772 if (session->sess_conn->conn_ax == NULL((void *)0))
773 return;
774
775 for (nsr = 0, vb = vblist; vb != NULL((void *)0); vb = vb->av_next)
776 nsr++;
777
778 if ((srl = calloc(nsr, sizeof(*srl))) == NULL((void *)0)) {
779 log_warn(NULL((void *)0));
780 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist);
781 return;
782 }
783
784 for (i = 0, vb = vblist; i < nsr; i++, vb = vb->av_next) {
785 srl[i].asr_start.aoi_include = vb->av_include;
786 srl[i].asr_start.aoi_idlen = vb->av_oid.bo_n;
787 for (j = 0; j < vb->av_oid.bo_n; j++)
788 srl[i].asr_start.aoi_id[j] = vb->av_oid.bo_id[j];
789 srl[i].asr_stop.aoi_include = 0;
790 srl[i].asr_stop.aoi_idlen = vb->av_oid_end.bo_n;
791 for (j = 0; j < vb->av_oid_end.bo_n; j++)
792 srl[i].asr_stop.aoi_id[j] = vb->av_oid_end.bo_id[j];
793 }
794 if ((context = appl_agentx_string2ostring(ctx, &string)) == NULL((void *)0)) {
795 if (errno(*__errno()) != 0) {
796 log_warn("Failed to convert context");
797 appl_response(backend, requestid,
798 APPL_ERROR_GENERR, 1, vblist);
799 free(srl);
800 return;
801 }
802 }
803
804 session->sess_conn->conn_ax->ax_byteorder = session->sess_byteorder;
805 if (ax_getnext(session->sess_conn->conn_ax, session->sess_id, transactionid,
806 requestid, context, srl, nsr) == -1)
807 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist);
808 else
809 event_add(&(session->sess_conn->conn_wev), NULL((void *)0));
810 free(srl);
811 if (context != NULL((void *)0))
812 free(context->aos_string);
813}
814
815void
816appl_agentx_addagentcaps(struct appl_agentx_session *session,
817 struct ax_pdu *pdu)
818{
819 struct ber_oid oid;
820 enum appl_error error;
821
822 if (appl_agentx_oid2ber_oid(&(pdu->ap_payload.ap_addagentcaps.ap_oid),
823 &oid) == NULL((void *)0)) {
824 log_warnx("%s: Failed to add agent capabilities: oid too small",
825 session->sess_backend.ab_name);
826 error = APPL_ERROR_PARSEERROR;
827 goto fail;
828 }
829
830 error = appl_addagentcaps(pdu->ap_context.aos_string, &oid,
831 pdu->ap_payload.ap_addagentcaps.ap_descr.aos_string,
832 &(session->sess_backend));
833
834 fail:
835 ax_response(session->sess_conn->conn_ax, session->sess_id,
836 pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
837 smi_getticks(), error, 0, NULL((void *)0), 0);
838 event_add(&(session->sess_conn->conn_wev), NULL((void *)0));
839}
840
841void
842appl_agentx_removeagentcaps(struct appl_agentx_session *session,
843 struct ax_pdu *pdu)
844{
845 struct ber_oid oid;
846 enum appl_error error;
847
848 if (appl_agentx_oid2ber_oid(&(pdu->ap_payload.ap_addagentcaps.ap_oid),
849 &oid) == NULL((void *)0)) {
850 log_warnx("%s: Failed to remove agent capabilities: "
851 "oid too small", session->sess_backend.ab_name);
852 error = APPL_ERROR_PARSEERROR;
853 goto fail;
854 }
855
856 error = appl_removeagentcaps(pdu->ap_context.aos_string, &oid,
857 &(session->sess_backend));
858
859 fail:
860 ax_response(session->sess_conn->conn_ax, session->sess_id,
861 pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
862 smi_getticks(), error, 0, NULL((void *)0), 0);
863 event_add(&(session->sess_conn->conn_wev), NULL((void *)0));
864}
865
866void
867appl_agentx_response(struct appl_agentx_session *session, struct ax_pdu *pdu)
868{
869 struct appl_varbind *response = NULL((void *)0);
870 struct ax_varbind *vb;
871 enum appl_error error;
872 uint16_t index;
873 size_t i, nvarbind;
874
875 nvarbind = pdu->ap_payload.ap_response.ap_nvarbind;
876 if ((response = calloc(nvarbind, sizeof(*response))) == NULL((void *)0)) {
877 log_warn(NULL((void *)0));
878 appl_response(&(session->sess_backend),
879 pdu->ap_header.aph_packetid,
880 APPL_ERROR_GENERR, 1, NULL((void *)0));
881 return;
882 }
883
884 error = (enum appl_error)pdu->ap_payload.ap_response.ap_error;
885 index = pdu->ap_payload.ap_response.ap_index;
886 for (i = 0; i < nvarbind; i++) {
887 response[i].av_next = i + 1 == nvarbind ?
888 NULL((void *)0) : &(response[i + 1]);
889 vb = &(pdu->ap_payload.ap_response.ap_varbindlist[i]);
890
891 if (appl_agentx_oid2ber_oid(&(vb->avb_oid),
892 &(response[i].av_oid)) == NULL((void *)0)) {
893 log_warnx("%s: invalid oid",
894 session->sess_backend.ab_name);
895 if (error != APPL_ERROR_NOERROR) {
896 error = APPL_ERROR_GENERR;
897 index = i + 1;
898 }
899 continue;
900 }
901 response[i].av_value = appl_agentx_value2ber_element(vb);
902 if (response[i].av_value == NULL((void *)0)) {
903 log_warn("%s: Failed to parse response value",
904 session->sess_backend.ab_name);
905 if (error != APPL_ERROR_NOERROR) {
906 error = APPL_ERROR_GENERR;
907 index = i + 1;
908 }
909 }
910 }
911 appl_response(&(session->sess_backend), pdu->ap_header.aph_packetid,
912 error, index, response);
913 free(response);
914}
915
916void
917appl_agentx_send(int fd, short event, void *cookie)
918{
919 struct appl_agentx_connection *conn = cookie;
920
921 switch (ax_send(conn->conn_ax)) {
922 case -1:
923 if (errno(*__errno()) == EAGAIN35)
924 break;
925 log_warn("AgentX(%"PRIu32"u"")", conn->conn_id);
926 ax_free(conn->conn_ax);
927 conn->conn_ax = NULL((void *)0);
928 appl_agentx_free(conn, APPL_CLOSE_REASONOTHER);
929 return;
930 case 0:
931 return;
932 default:
933 break;
934 }
935 event_add(&(conn->conn_wev), NULL((void *)0));
936}
937
938struct ber_oid *
939appl_agentx_oid2ber_oid(struct ax_oid *aoid, struct ber_oid *boid)
940{
941 size_t i;
942
943 if (aoid->aoi_idlen < BER_MIN_OID_LEN2 ||
944 aoid->aoi_idlen > BER_MAX_OID_LEN128) {
945 errno(*__errno()) = EINVAL22;
946 return NULL((void *)0);
947 }
948
949
950 boid->bo_n = aoid->aoi_idlen;
951 for (i = 0; i < boid->bo_n; i++)
952 boid->bo_id[i] = aoid->aoi_id[i];
953 return boid;
954}
955
956struct ber_element *
957appl_agentx_value2ber_element(struct ax_varbind *vb)
958{
959 struct ber_oid oid;
960 struct ber_element *elm;
961
962 switch (vb->avb_type) {
963 case AX_DATA_TYPE_INTEGER:
964 return ober_add_integer(NULL((void *)0), vb->avb_data.avb_int32);
965 case AX_DATA_TYPE_OCTETSTRING:
966 return ober_add_nstring(NULL((void *)0),
967 vb->avb_data.avb_ostring.aos_string,
968 vb->avb_data.avb_ostring.aos_slen);
969 case AX_DATA_TYPE_NULL:
970 return ober_add_null(NULL((void *)0));
971 case AX_DATA_TYPE_OID:
972 if (appl_agentx_oid2ber_oid(
973 &(vb->avb_data.avb_oid), &oid) == NULL((void *)0))
974 return NULL((void *)0);
975 return ober_add_oid(NULL((void *)0), &oid);
976 case AX_DATA_TYPE_IPADDRESS:
977 if ((elm = ober_add_nstring(NULL((void *)0),
978 vb->avb_data.avb_ostring.aos_string,
979 vb->avb_data.avb_ostring.aos_slen)) == NULL((void *)0))
980 return NULL((void *)0);
981 ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_IPADDR);
982 return elm;
983 case AX_DATA_TYPE_COUNTER32:
984 elm = ober_add_integer(NULL((void *)0), vb->avb_data.avb_uint32);
985 if (elm == NULL((void *)0))
986 return NULL((void *)0);
987 ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_COUNTER32);
988 return elm;
989 case AX_DATA_TYPE_GAUGE32:
990 elm = ober_add_integer(NULL((void *)0), vb->avb_data.avb_uint32);
991 if (elm == NULL((void *)0))
992 return NULL((void *)0);
993 ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_GAUGE32);
994 return elm;
995 case AX_DATA_TYPE_TIMETICKS:
996 elm = ober_add_integer(NULL((void *)0), vb->avb_data.avb_uint32);
997 if (elm == NULL((void *)0))
998 return NULL((void *)0);
999 ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_TIMETICKS);
1000 return elm;
1001 case AX_DATA_TYPE_OPAQUE:
1002 if ((elm = ober_add_nstring(NULL((void *)0),
1003 vb->avb_data.avb_ostring.aos_string,
1004 vb->avb_data.avb_ostring.aos_slen)) == NULL((void *)0))
1005 return NULL((void *)0);
1006 ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_OPAQUE);
1007 return elm;
1008 case AX_DATA_TYPE_COUNTER64:
1009 elm = ober_add_integer(NULL((void *)0), vb->avb_data.avb_uint64);
1010 if (elm == NULL((void *)0))
1011 return NULL((void *)0);
1012 ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_COUNTER64);
1013 return elm;
1014 case AX_DATA_TYPE_NOSUCHOBJECT:
1015 return appl_exception(APPL_EXC_NOSUCHOBJECT);
1016 case AX_DATA_TYPE_NOSUCHINSTANCE:
1017 return appl_exception(APPL_EXC_NOSUCHINSTANCE);
1018 case AX_DATA_TYPE_ENDOFMIBVIEW:
1019 return appl_exception(APPL_EXC_ENDOFMIBVIEW);
1020 default:
1021 errno(*__errno()) = EINVAL22;
1022 return NULL((void *)0);
1023 }
1024}
1025
1026struct ax_ostring *
1027appl_agentx_string2ostring(const char *str, struct ax_ostring *ostring)
1028{
1029 if (str == NULL((void *)0)) {
1030 errno(*__errno()) = 0;
1031 return NULL((void *)0);
1032 }
1033
1034 ostring->aos_slen = strlen(str);
1035 if ((ostring->aos_string = strdup(str)) == NULL((void *)0))
1036 return NULL((void *)0);
1037 return ostring;
1038}
1039
1040int
1041appl_agentx_cmp(struct appl_agentx_connection *conn1,
1042 struct appl_agentx_connection *conn2)
1043{
1044 return conn1->conn_id < conn2->conn_id ? -1 :
1045 conn1->conn_id > conn2->conn_id;
1046}
1047
1048int
1049appl_agentx_session_cmp(struct appl_agentx_session *sess1,
1050 struct appl_agentx_session *sess2)
1051{
1052 return sess1->sess_id < sess2->sess_id ? -1 : sess1->sess_id > sess2->sess_id;
1053}
1054
1055RB_GENERATE_STATIC(appl_agentx_conns, appl_agentx_connection, conn_entry,__attribute__((__unused__)) static void appl_agentx_conns_RB_INSERT_COLOR
(struct appl_agentx_conns *head, struct appl_agentx_connection
*elm) { struct appl_agentx_connection *parent, *gparent, *tmp
; while ((parent = (elm)->conn_entry.rbe_parent) &&
(parent)->conn_entry.rbe_color == 1) { gparent = (parent)
->conn_entry.rbe_parent; if (parent == (gparent)->conn_entry
.rbe_left) { tmp = (gparent)->conn_entry.rbe_right; if (tmp
&& (tmp)->conn_entry.rbe_color == 1) { (tmp)->
conn_entry.rbe_color = 0; do { (parent)->conn_entry.rbe_color
= 0; (gparent)->conn_entry.rbe_color = 1; } while (0); elm
= gparent; continue; } if ((parent)->conn_entry.rbe_right
== elm) { do { (tmp) = (parent)->conn_entry.rbe_right; if
(((parent)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left
)) { ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent
= (parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent
= (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp
); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do
{} while (0); } while (0); tmp = parent; parent = elm; elm =
tmp; } do { (parent)->conn_entry.rbe_color = 0; (gparent)
->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent
)->conn_entry.rbe_left; if (((gparent)->conn_entry.rbe_left
= (tmp)->conn_entry.rbe_right)) { ((tmp)->conn_entry.rbe_right
)->conn_entry.rbe_parent = (gparent); } do {} while (0); if
(((tmp)->conn_entry.rbe_parent = (gparent)->conn_entry
.rbe_parent)) { if ((gparent) == ((gparent)->conn_entry.rbe_parent
)->conn_entry.rbe_left) ((gparent)->conn_entry.rbe_parent
)->conn_entry.rbe_left = (tmp); else ((gparent)->conn_entry
.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->conn_entry.rbe_right = (gparent);
(gparent)->conn_entry.rbe_parent = (tmp); do {} while (0)
; if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while
(0); } else { tmp = (gparent)->conn_entry.rbe_left; if (tmp
&& (tmp)->conn_entry.rbe_color == 1) { (tmp)->
conn_entry.rbe_color = 0; do { (parent)->conn_entry.rbe_color
= 0; (gparent)->conn_entry.rbe_color = 1; } while (0); elm
= gparent; continue; } if ((parent)->conn_entry.rbe_left ==
elm) { do { (tmp) = (parent)->conn_entry.rbe_left; if (((
parent)->conn_entry.rbe_left = (tmp)->conn_entry.rbe_right
)) { ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_parent
= (parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent
= (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_right = (parent); (parent)->conn_entry.rbe_parent = (
tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent))
do {} while (0); } while (0); tmp = parent; parent = elm; elm
= tmp; } do { (parent)->conn_entry.rbe_color = 0; (gparent
)->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent
)->conn_entry.rbe_right; if (((gparent)->conn_entry.rbe_right
= (tmp)->conn_entry.rbe_left)) { ((tmp)->conn_entry.rbe_left
)->conn_entry.rbe_parent = (gparent); } do {} while (0); if
(((tmp)->conn_entry.rbe_parent = (gparent)->conn_entry
.rbe_parent)) { if ((gparent) == ((gparent)->conn_entry.rbe_parent
)->conn_entry.rbe_left) ((gparent)->conn_entry.rbe_parent
)->conn_entry.rbe_left = (tmp); else ((gparent)->conn_entry
.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->conn_entry.rbe_left = (gparent); (
gparent)->conn_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->conn_entry.rbe_parent)) do {} while (0); } while
(0); } } (head->rbh_root)->conn_entry.rbe_color = 0; }
__attribute__((__unused__)) static void appl_agentx_conns_RB_REMOVE_COLOR
(struct appl_agentx_conns *head, struct appl_agentx_connection
*parent, struct appl_agentx_connection *elm) { struct appl_agentx_connection
*tmp; while ((elm == ((void *)0) || (elm)->conn_entry.rbe_color
== 0) && elm != (head)->rbh_root) { if ((parent)->
conn_entry.rbe_left == elm) { tmp = (parent)->conn_entry.rbe_right
; if ((tmp)->conn_entry.rbe_color == 1) { do { (tmp)->conn_entry
.rbe_color = 0; (parent)->conn_entry.rbe_color = 1; } while
(0); do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent
)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) {
((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = (
parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent
= (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp
); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do
{} while (0); } while (0); tmp = (parent)->conn_entry.rbe_right
; } if (((tmp)->conn_entry.rbe_left == ((void *)0) || ((tmp
)->conn_entry.rbe_left)->conn_entry.rbe_color == 0) &&
((tmp)->conn_entry.rbe_right == ((void *)0) || ((tmp)->
conn_entry.rbe_right)->conn_entry.rbe_color == 0)) { (tmp)
->conn_entry.rbe_color = 1; elm = parent; parent = (elm)->
conn_entry.rbe_parent; } else { if ((tmp)->conn_entry.rbe_right
== ((void *)0) || ((tmp)->conn_entry.rbe_right)->conn_entry
.rbe_color == 0) { struct appl_agentx_connection *oleft; if (
(oleft = (tmp)->conn_entry.rbe_left)) (oleft)->conn_entry
.rbe_color = 0; (tmp)->conn_entry.rbe_color = 1; do { (oleft
) = (tmp)->conn_entry.rbe_left; if (((tmp)->conn_entry.
rbe_left = (oleft)->conn_entry.rbe_right)) { ((oleft)->
conn_entry.rbe_right)->conn_entry.rbe_parent = (tmp); } do
{} while (0); if (((oleft)->conn_entry.rbe_parent = (tmp)
->conn_entry.rbe_parent)) { if ((tmp) == ((tmp)->conn_entry
.rbe_parent)->conn_entry.rbe_left) ((tmp)->conn_entry.rbe_parent
)->conn_entry.rbe_left = (oleft); else ((tmp)->conn_entry
.rbe_parent)->conn_entry.rbe_right = (oleft); } else (head
)->rbh_root = (oleft); (oleft)->conn_entry.rbe_right = (
tmp); (tmp)->conn_entry.rbe_parent = (oleft); do {} while (
0); if (((oleft)->conn_entry.rbe_parent)) do {} while (0);
} while (0); tmp = (parent)->conn_entry.rbe_right; } (tmp
)->conn_entry.rbe_color = (parent)->conn_entry.rbe_color
; (parent)->conn_entry.rbe_color = 0; if ((tmp)->conn_entry
.rbe_right) ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_color
= 0; do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent
)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) {
((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = (
parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent
= (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp
); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do
{} while (0); } while (0); elm = (head)->rbh_root; break;
} } else { tmp = (parent)->conn_entry.rbe_left; if ((tmp)
->conn_entry.rbe_color == 1) { do { (tmp)->conn_entry.rbe_color
= 0; (parent)->conn_entry.rbe_color = 1; } while (0); do {
(tmp) = (parent)->conn_entry.rbe_left; if (((parent)->
conn_entry.rbe_left = (tmp)->conn_entry.rbe_right)) { ((tmp
)->conn_entry.rbe_right)->conn_entry.rbe_parent = (parent
); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (
parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_right = (parent); (parent)->conn_entry.rbe_parent = (
tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent))
do {} while (0); } while (0); tmp = (parent)->conn_entry.
rbe_left; } if (((tmp)->conn_entry.rbe_left == ((void *)0)
|| ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_color ==
0) && ((tmp)->conn_entry.rbe_right == ((void *)0)
|| ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_color
== 0)) { (tmp)->conn_entry.rbe_color = 1; elm = parent; parent
= (elm)->conn_entry.rbe_parent; } else { if ((tmp)->conn_entry
.rbe_left == ((void *)0) || ((tmp)->conn_entry.rbe_left)->
conn_entry.rbe_color == 0) { struct appl_agentx_connection *oright
; if ((oright = (tmp)->conn_entry.rbe_right)) (oright)->
conn_entry.rbe_color = 0; (tmp)->conn_entry.rbe_color = 1;
do { (oright) = (tmp)->conn_entry.rbe_right; if (((tmp)->
conn_entry.rbe_right = (oright)->conn_entry.rbe_left)) { (
(oright)->conn_entry.rbe_left)->conn_entry.rbe_parent =
(tmp); } do {} while (0); if (((oright)->conn_entry.rbe_parent
= (tmp)->conn_entry.rbe_parent)) { if ((tmp) == ((tmp)->
conn_entry.rbe_parent)->conn_entry.rbe_left) ((tmp)->conn_entry
.rbe_parent)->conn_entry.rbe_left = (oright); else ((tmp)->
conn_entry.rbe_parent)->conn_entry.rbe_right = (oright); }
else (head)->rbh_root = (oright); (oright)->conn_entry
.rbe_left = (tmp); (tmp)->conn_entry.rbe_parent = (oright)
; do {} while (0); if (((oright)->conn_entry.rbe_parent)) do
{} while (0); } while (0); tmp = (parent)->conn_entry.rbe_left
; } (tmp)->conn_entry.rbe_color = (parent)->conn_entry.
rbe_color; (parent)->conn_entry.rbe_color = 0; if ((tmp)->
conn_entry.rbe_left) ((tmp)->conn_entry.rbe_left)->conn_entry
.rbe_color = 0; do { (tmp) = (parent)->conn_entry.rbe_left
; if (((parent)->conn_entry.rbe_left = (tmp)->conn_entry
.rbe_right)) { ((tmp)->conn_entry.rbe_right)->conn_entry
.rbe_parent = (parent); } do {} while (0); if (((tmp)->conn_entry
.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent
) == ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_left
) ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_left
= (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry
.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)
->conn_entry.rbe_right = (parent); (parent)->conn_entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->conn_entry
.rbe_parent)) do {} while (0); } while (0); elm = (head)->
rbh_root; break; } } } if (elm) (elm)->conn_entry.rbe_color
= 0; } __attribute__((__unused__)) static struct appl_agentx_connection
* appl_agentx_conns_RB_REMOVE(struct appl_agentx_conns *head
, struct appl_agentx_connection *elm) { struct appl_agentx_connection
*child, *parent, *old = elm; int color; if ((elm)->conn_entry
.rbe_left == ((void *)0)) child = (elm)->conn_entry.rbe_right
; else if ((elm)->conn_entry.rbe_right == ((void *)0)) child
= (elm)->conn_entry.rbe_left; else { struct appl_agentx_connection
*left; elm = (elm)->conn_entry.rbe_right; while ((left = (
elm)->conn_entry.rbe_left)) elm = left; child = (elm)->
conn_entry.rbe_right; parent = (elm)->conn_entry.rbe_parent
; color = (elm)->conn_entry.rbe_color; if (child) (child)->
conn_entry.rbe_parent = parent; if (parent) { if ((parent)->
conn_entry.rbe_left == elm) (parent)->conn_entry.rbe_left =
child; else (parent)->conn_entry.rbe_right = child; do {}
while (0); } else (head)->rbh_root = child; if ((elm)->
conn_entry.rbe_parent == old) parent = elm; (elm)->conn_entry
= (old)->conn_entry; if ((old)->conn_entry.rbe_parent)
{ if (((old)->conn_entry.rbe_parent)->conn_entry.rbe_left
== old) ((old)->conn_entry.rbe_parent)->conn_entry.rbe_left
= elm; else ((old)->conn_entry.rbe_parent)->conn_entry
.rbe_right = elm; do {} while (0); } else (head)->rbh_root
= elm; ((old)->conn_entry.rbe_left)->conn_entry.rbe_parent
= elm; if ((old)->conn_entry.rbe_right) ((old)->conn_entry
.rbe_right)->conn_entry.rbe_parent = elm; if (parent) { left
= parent; do { do {} while (0); } while ((left = (left)->
conn_entry.rbe_parent)); } goto color; } parent = (elm)->conn_entry
.rbe_parent; color = (elm)->conn_entry.rbe_color; if (child
) (child)->conn_entry.rbe_parent = parent; if (parent) { if
((parent)->conn_entry.rbe_left == elm) (parent)->conn_entry
.rbe_left = child; else (parent)->conn_entry.rbe_right = child
; do {} while (0); } else (head)->rbh_root = child; color:
if (color == 0) appl_agentx_conns_RB_REMOVE_COLOR(head, parent
, child); return (old); } __attribute__((__unused__)) static struct
appl_agentx_connection * appl_agentx_conns_RB_INSERT(struct appl_agentx_conns
*head, struct appl_agentx_connection *elm) { struct appl_agentx_connection
*tmp; struct appl_agentx_connection *parent = ((void *)0); int
comp = 0; tmp = (head)->rbh_root; while (tmp) { parent = tmp
; comp = (appl_agentx_cmp)(elm, parent); if (comp < 0) tmp
= (tmp)->conn_entry.rbe_left; else if (comp > 0) tmp =
(tmp)->conn_entry.rbe_right; else return (tmp); } do { (elm
)->conn_entry.rbe_parent = parent; (elm)->conn_entry.rbe_left
= (elm)->conn_entry.rbe_right = ((void *)0); (elm)->conn_entry
.rbe_color = 1; } while (0); if (parent != ((void *)0)) { if (
comp < 0) (parent)->conn_entry.rbe_left = elm; else (parent
)->conn_entry.rbe_right = elm; do {} while (0); } else (head
)->rbh_root = elm; appl_agentx_conns_RB_INSERT_COLOR(head,
elm); return (((void *)0)); } __attribute__((__unused__)) static
struct appl_agentx_connection * appl_agentx_conns_RB_FIND(struct
appl_agentx_conns *head, struct appl_agentx_connection *elm)
{ struct appl_agentx_connection *tmp = (head)->rbh_root; int
comp; while (tmp) { comp = appl_agentx_cmp(elm, tmp); if (comp
< 0) tmp = (tmp)->conn_entry.rbe_left; else if (comp >
0) tmp = (tmp)->conn_entry.rbe_right; else return (tmp); }
return (((void *)0)); } __attribute__((__unused__)) static struct
appl_agentx_connection * appl_agentx_conns_RB_NFIND(struct appl_agentx_conns
*head, struct appl_agentx_connection *elm) { struct appl_agentx_connection
*tmp = (head)->rbh_root; struct appl_agentx_connection *res
= ((void *)0); int comp; while (tmp) { comp = appl_agentx_cmp
(elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->conn_entry
.rbe_left; } else if (comp > 0) tmp = (tmp)->conn_entry
.rbe_right; else return (tmp); } return (res); } __attribute__
((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_NEXT
(struct appl_agentx_connection *elm) { if ((elm)->conn_entry
.rbe_right) { elm = (elm)->conn_entry.rbe_right; while ((elm
)->conn_entry.rbe_left) elm = (elm)->conn_entry.rbe_left
; } else { if ((elm)->conn_entry.rbe_parent && (elm
== ((elm)->conn_entry.rbe_parent)->conn_entry.rbe_left
)) elm = (elm)->conn_entry.rbe_parent; else { while ((elm)
->conn_entry.rbe_parent && (elm == ((elm)->conn_entry
.rbe_parent)->conn_entry.rbe_right)) elm = (elm)->conn_entry
.rbe_parent; elm = (elm)->conn_entry.rbe_parent; } } return
(elm); } __attribute__((__unused__)) static struct appl_agentx_connection
* appl_agentx_conns_RB_PREV(struct appl_agentx_connection *elm
) { if ((elm)->conn_entry.rbe_left) { elm = (elm)->conn_entry
.rbe_left; while ((elm)->conn_entry.rbe_right) elm = (elm)
->conn_entry.rbe_right; } else { if ((elm)->conn_entry.
rbe_parent && (elm == ((elm)->conn_entry.rbe_parent
)->conn_entry.rbe_right)) elm = (elm)->conn_entry.rbe_parent
; else { while ((elm)->conn_entry.rbe_parent && (elm
== ((elm)->conn_entry.rbe_parent)->conn_entry.rbe_left
)) elm = (elm)->conn_entry.rbe_parent; elm = (elm)->conn_entry
.rbe_parent; } } return (elm); } __attribute__((__unused__)) static
struct appl_agentx_connection * appl_agentx_conns_RB_MINMAX(
struct appl_agentx_conns *head, int val) { struct appl_agentx_connection
*tmp = (head)->rbh_root; struct appl_agentx_connection *parent
= ((void *)0); while (tmp) { parent = tmp; if (val < 0) tmp
= (tmp)->conn_entry.rbe_left; else tmp = (tmp)->conn_entry
.rbe_right; } return (parent); }
1056 appl_agentx_cmp)__attribute__((__unused__)) static void appl_agentx_conns_RB_INSERT_COLOR
(struct appl_agentx_conns *head, struct appl_agentx_connection
*elm) { struct appl_agentx_connection *parent, *gparent, *tmp
; while ((parent = (elm)->conn_entry.rbe_parent) &&
(parent)->conn_entry.rbe_color == 1) { gparent = (parent)
->conn_entry.rbe_parent; if (parent == (gparent)->conn_entry
.rbe_left) { tmp = (gparent)->conn_entry.rbe_right; if (tmp
&& (tmp)->conn_entry.rbe_color == 1) { (tmp)->
conn_entry.rbe_color = 0; do { (parent)->conn_entry.rbe_color
= 0; (gparent)->conn_entry.rbe_color = 1; } while (0); elm
= gparent; continue; } if ((parent)->conn_entry.rbe_right
== elm) { do { (tmp) = (parent)->conn_entry.rbe_right; if
(((parent)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left
)) { ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent
= (parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent
= (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp
); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do
{} while (0); } while (0); tmp = parent; parent = elm; elm =
tmp; } do { (parent)->conn_entry.rbe_color = 0; (gparent)
->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent
)->conn_entry.rbe_left; if (((gparent)->conn_entry.rbe_left
= (tmp)->conn_entry.rbe_right)) { ((tmp)->conn_entry.rbe_right
)->conn_entry.rbe_parent = (gparent); } do {} while (0); if
(((tmp)->conn_entry.rbe_parent = (gparent)->conn_entry
.rbe_parent)) { if ((gparent) == ((gparent)->conn_entry.rbe_parent
)->conn_entry.rbe_left) ((gparent)->conn_entry.rbe_parent
)->conn_entry.rbe_left = (tmp); else ((gparent)->conn_entry
.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->conn_entry.rbe_right = (gparent);
(gparent)->conn_entry.rbe_parent = (tmp); do {} while (0)
; if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while
(0); } else { tmp = (gparent)->conn_entry.rbe_left; if (tmp
&& (tmp)->conn_entry.rbe_color == 1) { (tmp)->
conn_entry.rbe_color = 0; do { (parent)->conn_entry.rbe_color
= 0; (gparent)->conn_entry.rbe_color = 1; } while (0); elm
= gparent; continue; } if ((parent)->conn_entry.rbe_left ==
elm) { do { (tmp) = (parent)->conn_entry.rbe_left; if (((
parent)->conn_entry.rbe_left = (tmp)->conn_entry.rbe_right
)) { ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_parent
= (parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent
= (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_right = (parent); (parent)->conn_entry.rbe_parent = (
tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent))
do {} while (0); } while (0); tmp = parent; parent = elm; elm
= tmp; } do { (parent)->conn_entry.rbe_color = 0; (gparent
)->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent
)->conn_entry.rbe_right; if (((gparent)->conn_entry.rbe_right
= (tmp)->conn_entry.rbe_left)) { ((tmp)->conn_entry.rbe_left
)->conn_entry.rbe_parent = (gparent); } do {} while (0); if
(((tmp)->conn_entry.rbe_parent = (gparent)->conn_entry
.rbe_parent)) { if ((gparent) == ((gparent)->conn_entry.rbe_parent
)->conn_entry.rbe_left) ((gparent)->conn_entry.rbe_parent
)->conn_entry.rbe_left = (tmp); else ((gparent)->conn_entry
.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->conn_entry.rbe_left = (gparent); (
gparent)->conn_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->conn_entry.rbe_parent)) do {} while (0); } while
(0); } } (head->rbh_root)->conn_entry.rbe_color = 0; }
__attribute__((__unused__)) static void appl_agentx_conns_RB_REMOVE_COLOR
(struct appl_agentx_conns *head, struct appl_agentx_connection
*parent, struct appl_agentx_connection *elm) { struct appl_agentx_connection
*tmp; while ((elm == ((void *)0) || (elm)->conn_entry.rbe_color
== 0) && elm != (head)->rbh_root) { if ((parent)->
conn_entry.rbe_left == elm) { tmp = (parent)->conn_entry.rbe_right
; if ((tmp)->conn_entry.rbe_color == 1) { do { (tmp)->conn_entry
.rbe_color = 0; (parent)->conn_entry.rbe_color = 1; } while
(0); do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent
)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) {
((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = (
parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent
= (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp
); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do
{} while (0); } while (0); tmp = (parent)->conn_entry.rbe_right
; } if (((tmp)->conn_entry.rbe_left == ((void *)0) || ((tmp
)->conn_entry.rbe_left)->conn_entry.rbe_color == 0) &&
((tmp)->conn_entry.rbe_right == ((void *)0) || ((tmp)->
conn_entry.rbe_right)->conn_entry.rbe_color == 0)) { (tmp)
->conn_entry.rbe_color = 1; elm = parent; parent = (elm)->
conn_entry.rbe_parent; } else { if ((tmp)->conn_entry.rbe_right
== ((void *)0) || ((tmp)->conn_entry.rbe_right)->conn_entry
.rbe_color == 0) { struct appl_agentx_connection *oleft; if (
(oleft = (tmp)->conn_entry.rbe_left)) (oleft)->conn_entry
.rbe_color = 0; (tmp)->conn_entry.rbe_color = 1; do { (oleft
) = (tmp)->conn_entry.rbe_left; if (((tmp)->conn_entry.
rbe_left = (oleft)->conn_entry.rbe_right)) { ((oleft)->
conn_entry.rbe_right)->conn_entry.rbe_parent = (tmp); } do
{} while (0); if (((oleft)->conn_entry.rbe_parent = (tmp)
->conn_entry.rbe_parent)) { if ((tmp) == ((tmp)->conn_entry
.rbe_parent)->conn_entry.rbe_left) ((tmp)->conn_entry.rbe_parent
)->conn_entry.rbe_left = (oleft); else ((tmp)->conn_entry
.rbe_parent)->conn_entry.rbe_right = (oleft); } else (head
)->rbh_root = (oleft); (oleft)->conn_entry.rbe_right = (
tmp); (tmp)->conn_entry.rbe_parent = (oleft); do {} while (
0); if (((oleft)->conn_entry.rbe_parent)) do {} while (0);
} while (0); tmp = (parent)->conn_entry.rbe_right; } (tmp
)->conn_entry.rbe_color = (parent)->conn_entry.rbe_color
; (parent)->conn_entry.rbe_color = 0; if ((tmp)->conn_entry
.rbe_right) ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_color
= 0; do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent
)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) {
((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = (
parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent
= (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp
); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do
{} while (0); } while (0); elm = (head)->rbh_root; break;
} } else { tmp = (parent)->conn_entry.rbe_left; if ((tmp)
->conn_entry.rbe_color == 1) { do { (tmp)->conn_entry.rbe_color
= 0; (parent)->conn_entry.rbe_color = 1; } while (0); do {
(tmp) = (parent)->conn_entry.rbe_left; if (((parent)->
conn_entry.rbe_left = (tmp)->conn_entry.rbe_right)) { ((tmp
)->conn_entry.rbe_right)->conn_entry.rbe_parent = (parent
); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (
parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent
)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp);
else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry
.rbe_right = (parent); (parent)->conn_entry.rbe_parent = (
tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent))
do {} while (0); } while (0); tmp = (parent)->conn_entry.
rbe_left; } if (((tmp)->conn_entry.rbe_left == ((void *)0)
|| ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_color ==
0) && ((tmp)->conn_entry.rbe_right == ((void *)0)
|| ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_color
== 0)) { (tmp)->conn_entry.rbe_color = 1; elm = parent; parent
= (elm)->conn_entry.rbe_parent; } else { if ((tmp)->conn_entry
.rbe_left == ((void *)0) || ((tmp)->conn_entry.rbe_left)->
conn_entry.rbe_color == 0) { struct appl_agentx_connection *oright
; if ((oright = (tmp)->conn_entry.rbe_right)) (oright)->
conn_entry.rbe_color = 0; (tmp)->conn_entry.rbe_color = 1;
do { (oright) = (tmp)->conn_entry.rbe_right; if (((tmp)->
conn_entry.rbe_right = (oright)->conn_entry.rbe_left)) { (
(oright)->conn_entry.rbe_left)->conn_entry.rbe_parent =
(tmp); } do {} while (0); if (((oright)->conn_entry.rbe_parent
= (tmp)->conn_entry.rbe_parent)) { if ((tmp) == ((tmp)->
conn_entry.rbe_parent)->conn_entry.rbe_left) ((tmp)->conn_entry
.rbe_parent)->conn_entry.rbe_left = (oright); else ((tmp)->
conn_entry.rbe_parent)->conn_entry.rbe_right = (oright); }
else (head)->rbh_root = (oright); (oright)->conn_entry
.rbe_left = (tmp); (tmp)->conn_entry.rbe_parent = (oright)
; do {} while (0); if (((oright)->conn_entry.rbe_parent)) do
{} while (0); } while (0); tmp = (parent)->conn_entry.rbe_left
; } (tmp)->conn_entry.rbe_color = (parent)->conn_entry.
rbe_color; (parent)->conn_entry.rbe_color = 0; if ((tmp)->
conn_entry.rbe_left) ((tmp)->conn_entry.rbe_left)->conn_entry
.rbe_color = 0; do { (tmp) = (parent)->conn_entry.rbe_left
; if (((parent)->conn_entry.rbe_left = (tmp)->conn_entry
.rbe_right)) { ((tmp)->conn_entry.rbe_right)->conn_entry
.rbe_parent = (parent); } do {} while (0); if (((tmp)->conn_entry
.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent
) == ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_left
) ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_left
= (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry
.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)
->conn_entry.rbe_right = (parent); (parent)->conn_entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->conn_entry
.rbe_parent)) do {} while (0); } while (0); elm = (head)->
rbh_root; break; } } } if (elm) (elm)->conn_entry.rbe_color
= 0; } __attribute__((__unused__)) static struct appl_agentx_connection
* appl_agentx_conns_RB_REMOVE(struct appl_agentx_conns *head
, struct appl_agentx_connection *elm) { struct appl_agentx_connection
*child, *parent, *old = elm; int color; if ((elm)->conn_entry
.rbe_left == ((void *)0)) child = (elm)->conn_entry.rbe_right
; else if ((elm)->conn_entry.rbe_right == ((void *)0)) child
= (elm)->conn_entry.rbe_left; else { struct appl_agentx_connection
*left; elm = (elm)->conn_entry.rbe_right; while ((left = (
elm)->conn_entry.rbe_left)) elm = left; child = (elm)->
conn_entry.rbe_right; parent = (elm)->conn_entry.rbe_parent
; color = (elm)->conn_entry.rbe_color; if (child) (child)->
conn_entry.rbe_parent = parent; if (parent) { if ((parent)->
conn_entry.rbe_left == elm) (parent)->conn_entry.rbe_left =
child; else (parent)->conn_entry.rbe_right = child; do {}
while (0); } else (head)->rbh_root = child; if ((elm)->
conn_entry.rbe_parent == old) parent = elm; (elm)->conn_entry
= (old)->conn_entry; if ((old)->conn_entry.rbe_parent)
{ if (((old)->conn_entry.rbe_parent)->conn_entry.rbe_left
== old) ((old)->conn_entry.rbe_parent)->conn_entry.rbe_left
= elm; else ((old)->conn_entry.rbe_parent)->conn_entry
.rbe_right = elm; do {} while (0); } else (head)->rbh_root
= elm; ((old)->conn_entry.rbe_left)->conn_entry.rbe_parent
= elm; if ((old)->conn_entry.rbe_right) ((old)->conn_entry
.rbe_right)->conn_entry.rbe_parent = elm; if (parent) { left
= parent; do { do {} while (0); } while ((left = (left)->
conn_entry.rbe_parent)); } goto color; } parent = (elm)->conn_entry
.rbe_parent; color = (elm)->conn_entry.rbe_color; if (child
) (child)->conn_entry.rbe_parent = parent; if (parent) { if
((parent)->conn_entry.rbe_left == elm) (parent)->conn_entry
.rbe_left = child; else (parent)->conn_entry.rbe_right = child
; do {} while (0); } else (head)->rbh_root = child; color:
if (color == 0) appl_agentx_conns_RB_REMOVE_COLOR(head, parent
, child); return (old); } __attribute__((__unused__)) static struct
appl_agentx_connection * appl_agentx_conns_RB_INSERT(struct appl_agentx_conns
*head, struct appl_agentx_connection *elm) { struct appl_agentx_connection
*tmp; struct appl_agentx_connection *parent = ((void *)0); int
comp = 0; tmp = (head)->rbh_root; while (tmp) { parent = tmp
; comp = (appl_agentx_cmp)(elm, parent); if (comp < 0) tmp
= (tmp)->conn_entry.rbe_left; else if (comp > 0) tmp =
(tmp)->conn_entry.rbe_right; else return (tmp); } do { (elm
)->conn_entry.rbe_parent = parent; (elm)->conn_entry.rbe_left
= (elm)->conn_entry.rbe_right = ((void *)0); (elm)->conn_entry
.rbe_color = 1; } while (0); if (parent != ((void *)0)) { if (
comp < 0) (parent)->conn_entry.rbe_left = elm; else (parent
)->conn_entry.rbe_right = elm; do {} while (0); } else (head
)->rbh_root = elm; appl_agentx_conns_RB_INSERT_COLOR(head,
elm); return (((void *)0)); } __attribute__((__unused__)) static
struct appl_agentx_connection * appl_agentx_conns_RB_FIND(struct
appl_agentx_conns *head, struct appl_agentx_connection *elm)
{ struct appl_agentx_connection *tmp = (head)->rbh_root; int
comp; while (tmp) { comp = appl_agentx_cmp(elm, tmp); if (comp
< 0) tmp = (tmp)->conn_entry.rbe_left; else if (comp >
0) tmp = (tmp)->conn_entry.rbe_right; else return (tmp); }
return (((void *)0)); } __attribute__((__unused__)) static struct
appl_agentx_connection * appl_agentx_conns_RB_NFIND(struct appl_agentx_conns
*head, struct appl_agentx_connection *elm) { struct appl_agentx_connection
*tmp = (head)->rbh_root; struct appl_agentx_connection *res
= ((void *)0); int comp; while (tmp) { comp = appl_agentx_cmp
(elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->conn_entry
.rbe_left; } else if (comp > 0) tmp = (tmp)->conn_entry
.rbe_right; else return (tmp); } return (res); } __attribute__
((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_NEXT
(struct appl_agentx_connection *elm) { if ((elm)->conn_entry
.rbe_right) { elm = (elm)->conn_entry.rbe_right; while ((elm
)->conn_entry.rbe_left) elm = (elm)->conn_entry.rbe_left
; } else { if ((elm)->conn_entry.rbe_parent && (elm
== ((elm)->conn_entry.rbe_parent)->conn_entry.rbe_left
)) elm = (elm)->conn_entry.rbe_parent; else { while ((elm)
->conn_entry.rbe_parent && (elm == ((elm)->conn_entry
.rbe_parent)->conn_entry.rbe_right)) elm = (elm)->conn_entry
.rbe_parent; elm = (elm)->conn_entry.rbe_parent; } } return
(elm); } __attribute__((__unused__)) static struct appl_agentx_connection
* appl_agentx_conns_RB_PREV(struct appl_agentx_connection *elm
) { if ((elm)->conn_entry.rbe_left) { elm = (elm)->conn_entry
.rbe_left; while ((elm)->conn_entry.rbe_right) elm = (elm)
->conn_entry.rbe_right; } else { if ((elm)->conn_entry.
rbe_parent && (elm == ((elm)->conn_entry.rbe_parent
)->conn_entry.rbe_right)) elm = (elm)->conn_entry.rbe_parent
; else { while ((elm)->conn_entry.rbe_parent && (elm
== ((elm)->conn_entry.rbe_parent)->conn_entry.rbe_left
)) elm = (elm)->conn_entry.rbe_parent; elm = (elm)->conn_entry
.rbe_parent; } } return (elm); } __attribute__((__unused__)) static
struct appl_agentx_connection * appl_agentx_conns_RB_MINMAX(
struct appl_agentx_conns *head, int val) { struct appl_agentx_connection
*tmp = (head)->rbh_root; struct appl_agentx_connection *parent
= ((void *)0); while (tmp) { parent = tmp; if (val < 0) tmp
= (tmp)->conn_entry.rbe_left; else tmp = (tmp)->conn_entry
.rbe_right; } return (parent); }
;
1057RB_GENERATE_STATIC(appl_agentx_sessions, appl_agentx_session, sess_entry,__attribute__((__unused__)) static void appl_agentx_sessions_RB_INSERT_COLOR
(struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *parent, *gparent, *tmp; while
((parent = (elm)->sess_entry.rbe_parent) && (parent
)->sess_entry.rbe_color == 1) { gparent = (parent)->sess_entry
.rbe_parent; if (parent == (gparent)->sess_entry.rbe_left)
{ tmp = (gparent)->sess_entry.rbe_right; if (tmp &&
(tmp)->sess_entry.rbe_color == 1) { (tmp)->sess_entry.
rbe_color = 0; do { (parent)->sess_entry.rbe_color = 0; (gparent
)->sess_entry.rbe_color = 1; } while (0); elm = gparent; continue
; } if ((parent)->sess_entry.rbe_right == elm) { do { (tmp
) = (parent)->sess_entry.rbe_right; if (((parent)->sess_entry
.rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp)->sess_entry
.rbe_left)->sess_entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry
.rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_left = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->
sess_entry.rbe_color = 0; (gparent)->sess_entry.rbe_color =
1; } while (0); do { (tmp) = (gparent)->sess_entry.rbe_left
; if (((gparent)->sess_entry.rbe_left = (tmp)->sess_entry
.rbe_right)) { ((tmp)->sess_entry.rbe_right)->sess_entry
.rbe_parent = (gparent); } do {} while (0); if (((tmp)->sess_entry
.rbe_parent = (gparent)->sess_entry.rbe_parent)) { if ((gparent
) == ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left
) ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left
= (tmp); else ((gparent)->sess_entry.rbe_parent)->sess_entry
.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)
->sess_entry.rbe_right = (gparent); (gparent)->sess_entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry
.rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent
)->sess_entry.rbe_left; if (tmp && (tmp)->sess_entry
.rbe_color == 1) { (tmp)->sess_entry.rbe_color = 0; do { (
parent)->sess_entry.rbe_color = 0; (gparent)->sess_entry
.rbe_color = 1; } while (0); elm = gparent; continue; } if ((
parent)->sess_entry.rbe_left == elm) { do { (tmp) = (parent
)->sess_entry.rbe_left; if (((parent)->sess_entry.rbe_left
= (tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry.rbe_right
)->sess_entry.rbe_parent = (parent); } do {} while (0); if
(((tmp)->sess_entry.rbe_parent = (parent)->sess_entry.
rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->
sess_entry.rbe_color = 0; (gparent)->sess_entry.rbe_color =
1; } while (0); do { (tmp) = (gparent)->sess_entry.rbe_right
; if (((gparent)->sess_entry.rbe_right = (tmp)->sess_entry
.rbe_left)) { ((tmp)->sess_entry.rbe_left)->sess_entry.
rbe_parent = (gparent); } do {} while (0); if (((tmp)->sess_entry
.rbe_parent = (gparent)->sess_entry.rbe_parent)) { if ((gparent
) == ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left
) ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left
= (tmp); else ((gparent)->sess_entry.rbe_parent)->sess_entry
.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)
->sess_entry.rbe_left = (gparent); (gparent)->sess_entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry
.rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root
)->sess_entry.rbe_color = 0; } __attribute__((__unused__))
static void appl_agentx_sessions_RB_REMOVE_COLOR(struct appl_agentx_sessions
*head, struct appl_agentx_session *parent, struct appl_agentx_session
*elm) { struct appl_agentx_session *tmp; while ((elm == ((void
*)0) || (elm)->sess_entry.rbe_color == 0) && elm !=
(head)->rbh_root) { if ((parent)->sess_entry.rbe_left ==
elm) { tmp = (parent)->sess_entry.rbe_right; if ((tmp)->
sess_entry.rbe_color == 1) { do { (tmp)->sess_entry.rbe_color
= 0; (parent)->sess_entry.rbe_color = 1; } while (0); do {
(tmp) = (parent)->sess_entry.rbe_right; if (((parent)->
sess_entry.rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp
)->sess_entry.rbe_left)->sess_entry.rbe_parent = (parent
); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (
parent)->sess_entry.rbe_parent)) { if ((parent) == ((parent
)->sess_entry.rbe_parent)->sess_entry.rbe_left) ((parent
)->sess_entry.rbe_parent)->sess_entry.rbe_left = (tmp);
else ((parent)->sess_entry.rbe_parent)->sess_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->sess_entry
.rbe_left = (parent); (parent)->sess_entry.rbe_parent = (tmp
); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do
{} while (0); } while (0); tmp = (parent)->sess_entry.rbe_right
; } if (((tmp)->sess_entry.rbe_left == ((void *)0) || ((tmp
)->sess_entry.rbe_left)->sess_entry.rbe_color == 0) &&
((tmp)->sess_entry.rbe_right == ((void *)0) || ((tmp)->
sess_entry.rbe_right)->sess_entry.rbe_color == 0)) { (tmp)
->sess_entry.rbe_color = 1; elm = parent; parent = (elm)->
sess_entry.rbe_parent; } else { if ((tmp)->sess_entry.rbe_right
== ((void *)0) || ((tmp)->sess_entry.rbe_right)->sess_entry
.rbe_color == 0) { struct appl_agentx_session *oleft; if ((oleft
= (tmp)->sess_entry.rbe_left)) (oleft)->sess_entry.rbe_color
= 0; (tmp)->sess_entry.rbe_color = 1; do { (oleft) = (tmp
)->sess_entry.rbe_left; if (((tmp)->sess_entry.rbe_left
= (oleft)->sess_entry.rbe_right)) { ((oleft)->sess_entry
.rbe_right)->sess_entry.rbe_parent = (tmp); } do {} while (
0); if (((oleft)->sess_entry.rbe_parent = (tmp)->sess_entry
.rbe_parent)) { if ((tmp) == ((tmp)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((tmp)->sess_entry.rbe_parent)->
sess_entry.rbe_left = (oleft); else ((tmp)->sess_entry.rbe_parent
)->sess_entry.rbe_right = (oleft); } else (head)->rbh_root
= (oleft); (oleft)->sess_entry.rbe_right = (tmp); (tmp)->
sess_entry.rbe_parent = (oleft); do {} while (0); if (((oleft
)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp
= (parent)->sess_entry.rbe_right; } (tmp)->sess_entry.
rbe_color = (parent)->sess_entry.rbe_color; (parent)->sess_entry
.rbe_color = 0; if ((tmp)->sess_entry.rbe_right) ((tmp)->
sess_entry.rbe_right)->sess_entry.rbe_color = 0; do { (tmp
) = (parent)->sess_entry.rbe_right; if (((parent)->sess_entry
.rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp)->sess_entry
.rbe_left)->sess_entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry
.rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_left = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); elm = (head)->rbh_root; break; } } else { tmp = (parent
)->sess_entry.rbe_left; if ((tmp)->sess_entry.rbe_color
== 1) { do { (tmp)->sess_entry.rbe_color = 0; (parent)->
sess_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)->
sess_entry.rbe_left; if (((parent)->sess_entry.rbe_left = (
tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry.rbe_right
)->sess_entry.rbe_parent = (parent); } do {} while (0); if
(((tmp)->sess_entry.rbe_parent = (parent)->sess_entry.
rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); tmp = (parent)->sess_entry.rbe_left; } if (((tmp)->
sess_entry.rbe_left == ((void *)0) || ((tmp)->sess_entry.rbe_left
)->sess_entry.rbe_color == 0) && ((tmp)->sess_entry
.rbe_right == ((void *)0) || ((tmp)->sess_entry.rbe_right)
->sess_entry.rbe_color == 0)) { (tmp)->sess_entry.rbe_color
= 1; elm = parent; parent = (elm)->sess_entry.rbe_parent;
} else { if ((tmp)->sess_entry.rbe_left == ((void *)0) ||
((tmp)->sess_entry.rbe_left)->sess_entry.rbe_color == 0
) { struct appl_agentx_session *oright; if ((oright = (tmp)->
sess_entry.rbe_right)) (oright)->sess_entry.rbe_color = 0;
(tmp)->sess_entry.rbe_color = 1; do { (oright) = (tmp)->
sess_entry.rbe_right; if (((tmp)->sess_entry.rbe_right = (
oright)->sess_entry.rbe_left)) { ((oright)->sess_entry.
rbe_left)->sess_entry.rbe_parent = (tmp); } do {} while (0
); if (((oright)->sess_entry.rbe_parent = (tmp)->sess_entry
.rbe_parent)) { if ((tmp) == ((tmp)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((tmp)->sess_entry.rbe_parent)->
sess_entry.rbe_left = (oright); else ((tmp)->sess_entry.rbe_parent
)->sess_entry.rbe_right = (oright); } else (head)->rbh_root
= (oright); (oright)->sess_entry.rbe_left = (tmp); (tmp)->
sess_entry.rbe_parent = (oright); do {} while (0); if (((oright
)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp
= (parent)->sess_entry.rbe_left; } (tmp)->sess_entry.rbe_color
= (parent)->sess_entry.rbe_color; (parent)->sess_entry
.rbe_color = 0; if ((tmp)->sess_entry.rbe_left) ((tmp)->
sess_entry.rbe_left)->sess_entry.rbe_color = 0; do { (tmp)
= (parent)->sess_entry.rbe_left; if (((parent)->sess_entry
.rbe_left = (tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry
.rbe_right)->sess_entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry
.rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); elm = (head)->rbh_root; break; } } } if (elm) (elm)->
sess_entry.rbe_color = 0; } __attribute__((__unused__)) static
struct appl_agentx_session * appl_agentx_sessions_RB_REMOVE(
struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *child, *parent, *old = elm
; int color; if ((elm)->sess_entry.rbe_left == ((void *)0)
) child = (elm)->sess_entry.rbe_right; else if ((elm)->
sess_entry.rbe_right == ((void *)0)) child = (elm)->sess_entry
.rbe_left; else { struct appl_agentx_session *left; elm = (elm
)->sess_entry.rbe_right; while ((left = (elm)->sess_entry
.rbe_left)) elm = left; child = (elm)->sess_entry.rbe_right
; parent = (elm)->sess_entry.rbe_parent; color = (elm)->
sess_entry.rbe_color; if (child) (child)->sess_entry.rbe_parent
= parent; if (parent) { if ((parent)->sess_entry.rbe_left
== elm) (parent)->sess_entry.rbe_left = child; else (parent
)->sess_entry.rbe_right = child; do {} while (0); } else (
head)->rbh_root = child; if ((elm)->sess_entry.rbe_parent
== old) parent = elm; (elm)->sess_entry = (old)->sess_entry
; if ((old)->sess_entry.rbe_parent) { if (((old)->sess_entry
.rbe_parent)->sess_entry.rbe_left == old) ((old)->sess_entry
.rbe_parent)->sess_entry.rbe_left = elm; else ((old)->sess_entry
.rbe_parent)->sess_entry.rbe_right = elm; do {} while (0);
} else (head)->rbh_root = elm; ((old)->sess_entry.rbe_left
)->sess_entry.rbe_parent = elm; if ((old)->sess_entry.rbe_right
) ((old)->sess_entry.rbe_right)->sess_entry.rbe_parent =
elm; if (parent) { left = parent; do { do {} while (0); } while
((left = (left)->sess_entry.rbe_parent)); } goto color; }
parent = (elm)->sess_entry.rbe_parent; color = (elm)->
sess_entry.rbe_color; if (child) (child)->sess_entry.rbe_parent
= parent; if (parent) { if ((parent)->sess_entry.rbe_left
== elm) (parent)->sess_entry.rbe_left = child; else (parent
)->sess_entry.rbe_right = child; do {} while (0); } else (
head)->rbh_root = child; color: if (color == 0) appl_agentx_sessions_RB_REMOVE_COLOR
(head, parent, child); return (old); } __attribute__((__unused__
)) static struct appl_agentx_session * appl_agentx_sessions_RB_INSERT
(struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *tmp; struct appl_agentx_session
*parent = ((void *)0); int comp = 0; tmp = (head)->rbh_root
; while (tmp) { parent = tmp; comp = (appl_agentx_session_cmp
)(elm, parent); if (comp < 0) tmp = (tmp)->sess_entry.rbe_left
; else if (comp > 0) tmp = (tmp)->sess_entry.rbe_right;
else return (tmp); } do { (elm)->sess_entry.rbe_parent = parent
; (elm)->sess_entry.rbe_left = (elm)->sess_entry.rbe_right
= ((void *)0); (elm)->sess_entry.rbe_color = 1; } while (
0); if (parent != ((void *)0)) { if (comp < 0) (parent)->
sess_entry.rbe_left = elm; else (parent)->sess_entry.rbe_right
= elm; do {} while (0); } else (head)->rbh_root = elm; appl_agentx_sessions_RB_INSERT_COLOR
(head, elm); return (((void *)0)); } __attribute__((__unused__
)) static struct appl_agentx_session * appl_agentx_sessions_RB_FIND
(struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *tmp = (head)->rbh_root
; int comp; while (tmp) { comp = appl_agentx_session_cmp(elm,
tmp); if (comp < 0) tmp = (tmp)->sess_entry.rbe_left; else
if (comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return
(tmp); } return (((void *)0)); } __attribute__((__unused__))
static struct appl_agentx_session * appl_agentx_sessions_RB_NFIND
(struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *tmp = (head)->rbh_root
; struct appl_agentx_session *res = ((void *)0); int comp; while
(tmp) { comp = appl_agentx_session_cmp(elm, tmp); if (comp <
0) { res = tmp; tmp = (tmp)->sess_entry.rbe_left; } else if
(comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return
(tmp); } return (res); } __attribute__((__unused__)) static struct
appl_agentx_session * appl_agentx_sessions_RB_NEXT(struct appl_agentx_session
*elm) { if ((elm)->sess_entry.rbe_right) { elm = (elm)->
sess_entry.rbe_right; while ((elm)->sess_entry.rbe_left) elm
= (elm)->sess_entry.rbe_left; } else { if ((elm)->sess_entry
.rbe_parent && (elm == ((elm)->sess_entry.rbe_parent
)->sess_entry.rbe_left)) elm = (elm)->sess_entry.rbe_parent
; else { while ((elm)->sess_entry.rbe_parent && (elm
== ((elm)->sess_entry.rbe_parent)->sess_entry.rbe_right
)) elm = (elm)->sess_entry.rbe_parent; elm = (elm)->sess_entry
.rbe_parent; } } return (elm); } __attribute__((__unused__)) static
struct appl_agentx_session * appl_agentx_sessions_RB_PREV(struct
appl_agentx_session *elm) { if ((elm)->sess_entry.rbe_left
) { elm = (elm)->sess_entry.rbe_left; while ((elm)->sess_entry
.rbe_right) elm = (elm)->sess_entry.rbe_right; } else { if
((elm)->sess_entry.rbe_parent && (elm == ((elm)->
sess_entry.rbe_parent)->sess_entry.rbe_right)) elm = (elm)
->sess_entry.rbe_parent; else { while ((elm)->sess_entry
.rbe_parent && (elm == ((elm)->sess_entry.rbe_parent
)->sess_entry.rbe_left)) elm = (elm)->sess_entry.rbe_parent
; elm = (elm)->sess_entry.rbe_parent; } } return (elm); } __attribute__
((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_MINMAX
(struct appl_agentx_sessions *head, int val) { struct appl_agentx_session
*tmp = (head)->rbh_root; struct appl_agentx_session *parent
= ((void *)0); while (tmp) { parent = tmp; if (val < 0) tmp
= (tmp)->sess_entry.rbe_left; else tmp = (tmp)->sess_entry
.rbe_right; } return (parent); }
1058 appl_agentx_session_cmp)__attribute__((__unused__)) static void appl_agentx_sessions_RB_INSERT_COLOR
(struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *parent, *gparent, *tmp; while
((parent = (elm)->sess_entry.rbe_parent) && (parent
)->sess_entry.rbe_color == 1) { gparent = (parent)->sess_entry
.rbe_parent; if (parent == (gparent)->sess_entry.rbe_left)
{ tmp = (gparent)->sess_entry.rbe_right; if (tmp &&
(tmp)->sess_entry.rbe_color == 1) { (tmp)->sess_entry.
rbe_color = 0; do { (parent)->sess_entry.rbe_color = 0; (gparent
)->sess_entry.rbe_color = 1; } while (0); elm = gparent; continue
; } if ((parent)->sess_entry.rbe_right == elm) { do { (tmp
) = (parent)->sess_entry.rbe_right; if (((parent)->sess_entry
.rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp)->sess_entry
.rbe_left)->sess_entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry
.rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_left = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->
sess_entry.rbe_color = 0; (gparent)->sess_entry.rbe_color =
1; } while (0); do { (tmp) = (gparent)->sess_entry.rbe_left
; if (((gparent)->sess_entry.rbe_left = (tmp)->sess_entry
.rbe_right)) { ((tmp)->sess_entry.rbe_right)->sess_entry
.rbe_parent = (gparent); } do {} while (0); if (((tmp)->sess_entry
.rbe_parent = (gparent)->sess_entry.rbe_parent)) { if ((gparent
) == ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left
) ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left
= (tmp); else ((gparent)->sess_entry.rbe_parent)->sess_entry
.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)
->sess_entry.rbe_right = (gparent); (gparent)->sess_entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry
.rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent
)->sess_entry.rbe_left; if (tmp && (tmp)->sess_entry
.rbe_color == 1) { (tmp)->sess_entry.rbe_color = 0; do { (
parent)->sess_entry.rbe_color = 0; (gparent)->sess_entry
.rbe_color = 1; } while (0); elm = gparent; continue; } if ((
parent)->sess_entry.rbe_left == elm) { do { (tmp) = (parent
)->sess_entry.rbe_left; if (((parent)->sess_entry.rbe_left
= (tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry.rbe_right
)->sess_entry.rbe_parent = (parent); } do {} while (0); if
(((tmp)->sess_entry.rbe_parent = (parent)->sess_entry.
rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->
sess_entry.rbe_color = 0; (gparent)->sess_entry.rbe_color =
1; } while (0); do { (tmp) = (gparent)->sess_entry.rbe_right
; if (((gparent)->sess_entry.rbe_right = (tmp)->sess_entry
.rbe_left)) { ((tmp)->sess_entry.rbe_left)->sess_entry.
rbe_parent = (gparent); } do {} while (0); if (((tmp)->sess_entry
.rbe_parent = (gparent)->sess_entry.rbe_parent)) { if ((gparent
) == ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left
) ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left
= (tmp); else ((gparent)->sess_entry.rbe_parent)->sess_entry
.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)
->sess_entry.rbe_left = (gparent); (gparent)->sess_entry
.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry
.rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root
)->sess_entry.rbe_color = 0; } __attribute__((__unused__))
static void appl_agentx_sessions_RB_REMOVE_COLOR(struct appl_agentx_sessions
*head, struct appl_agentx_session *parent, struct appl_agentx_session
*elm) { struct appl_agentx_session *tmp; while ((elm == ((void
*)0) || (elm)->sess_entry.rbe_color == 0) && elm !=
(head)->rbh_root) { if ((parent)->sess_entry.rbe_left ==
elm) { tmp = (parent)->sess_entry.rbe_right; if ((tmp)->
sess_entry.rbe_color == 1) { do { (tmp)->sess_entry.rbe_color
= 0; (parent)->sess_entry.rbe_color = 1; } while (0); do {
(tmp) = (parent)->sess_entry.rbe_right; if (((parent)->
sess_entry.rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp
)->sess_entry.rbe_left)->sess_entry.rbe_parent = (parent
); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (
parent)->sess_entry.rbe_parent)) { if ((parent) == ((parent
)->sess_entry.rbe_parent)->sess_entry.rbe_left) ((parent
)->sess_entry.rbe_parent)->sess_entry.rbe_left = (tmp);
else ((parent)->sess_entry.rbe_parent)->sess_entry.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->sess_entry
.rbe_left = (parent); (parent)->sess_entry.rbe_parent = (tmp
); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do
{} while (0); } while (0); tmp = (parent)->sess_entry.rbe_right
; } if (((tmp)->sess_entry.rbe_left == ((void *)0) || ((tmp
)->sess_entry.rbe_left)->sess_entry.rbe_color == 0) &&
((tmp)->sess_entry.rbe_right == ((void *)0) || ((tmp)->
sess_entry.rbe_right)->sess_entry.rbe_color == 0)) { (tmp)
->sess_entry.rbe_color = 1; elm = parent; parent = (elm)->
sess_entry.rbe_parent; } else { if ((tmp)->sess_entry.rbe_right
== ((void *)0) || ((tmp)->sess_entry.rbe_right)->sess_entry
.rbe_color == 0) { struct appl_agentx_session *oleft; if ((oleft
= (tmp)->sess_entry.rbe_left)) (oleft)->sess_entry.rbe_color
= 0; (tmp)->sess_entry.rbe_color = 1; do { (oleft) = (tmp
)->sess_entry.rbe_left; if (((tmp)->sess_entry.rbe_left
= (oleft)->sess_entry.rbe_right)) { ((oleft)->sess_entry
.rbe_right)->sess_entry.rbe_parent = (tmp); } do {} while (
0); if (((oleft)->sess_entry.rbe_parent = (tmp)->sess_entry
.rbe_parent)) { if ((tmp) == ((tmp)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((tmp)->sess_entry.rbe_parent)->
sess_entry.rbe_left = (oleft); else ((tmp)->sess_entry.rbe_parent
)->sess_entry.rbe_right = (oleft); } else (head)->rbh_root
= (oleft); (oleft)->sess_entry.rbe_right = (tmp); (tmp)->
sess_entry.rbe_parent = (oleft); do {} while (0); if (((oleft
)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp
= (parent)->sess_entry.rbe_right; } (tmp)->sess_entry.
rbe_color = (parent)->sess_entry.rbe_color; (parent)->sess_entry
.rbe_color = 0; if ((tmp)->sess_entry.rbe_right) ((tmp)->
sess_entry.rbe_right)->sess_entry.rbe_color = 0; do { (tmp
) = (parent)->sess_entry.rbe_right; if (((parent)->sess_entry
.rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp)->sess_entry
.rbe_left)->sess_entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry
.rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_left = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); elm = (head)->rbh_root; break; } } else { tmp = (parent
)->sess_entry.rbe_left; if ((tmp)->sess_entry.rbe_color
== 1) { do { (tmp)->sess_entry.rbe_color = 0; (parent)->
sess_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)->
sess_entry.rbe_left; if (((parent)->sess_entry.rbe_left = (
tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry.rbe_right
)->sess_entry.rbe_parent = (parent); } do {} while (0); if
(((tmp)->sess_entry.rbe_parent = (parent)->sess_entry.
rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); tmp = (parent)->sess_entry.rbe_left; } if (((tmp)->
sess_entry.rbe_left == ((void *)0) || ((tmp)->sess_entry.rbe_left
)->sess_entry.rbe_color == 0) && ((tmp)->sess_entry
.rbe_right == ((void *)0) || ((tmp)->sess_entry.rbe_right)
->sess_entry.rbe_color == 0)) { (tmp)->sess_entry.rbe_color
= 1; elm = parent; parent = (elm)->sess_entry.rbe_parent;
} else { if ((tmp)->sess_entry.rbe_left == ((void *)0) ||
((tmp)->sess_entry.rbe_left)->sess_entry.rbe_color == 0
) { struct appl_agentx_session *oright; if ((oright = (tmp)->
sess_entry.rbe_right)) (oright)->sess_entry.rbe_color = 0;
(tmp)->sess_entry.rbe_color = 1; do { (oright) = (tmp)->
sess_entry.rbe_right; if (((tmp)->sess_entry.rbe_right = (
oright)->sess_entry.rbe_left)) { ((oright)->sess_entry.
rbe_left)->sess_entry.rbe_parent = (tmp); } do {} while (0
); if (((oright)->sess_entry.rbe_parent = (tmp)->sess_entry
.rbe_parent)) { if ((tmp) == ((tmp)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((tmp)->sess_entry.rbe_parent)->
sess_entry.rbe_left = (oright); else ((tmp)->sess_entry.rbe_parent
)->sess_entry.rbe_right = (oright); } else (head)->rbh_root
= (oright); (oright)->sess_entry.rbe_left = (tmp); (tmp)->
sess_entry.rbe_parent = (oright); do {} while (0); if (((oright
)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp
= (parent)->sess_entry.rbe_left; } (tmp)->sess_entry.rbe_color
= (parent)->sess_entry.rbe_color; (parent)->sess_entry
.rbe_color = 0; if ((tmp)->sess_entry.rbe_left) ((tmp)->
sess_entry.rbe_left)->sess_entry.rbe_color = 0; do { (tmp)
= (parent)->sess_entry.rbe_left; if (((parent)->sess_entry
.rbe_left = (tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry
.rbe_right)->sess_entry.rbe_parent = (parent); } do {} while
(0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry
.rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent
)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry
.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); (
parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if
(((tmp)->sess_entry.rbe_parent)) do {} while (0); } while
(0); elm = (head)->rbh_root; break; } } } if (elm) (elm)->
sess_entry.rbe_color = 0; } __attribute__((__unused__)) static
struct appl_agentx_session * appl_agentx_sessions_RB_REMOVE(
struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *child, *parent, *old = elm
; int color; if ((elm)->sess_entry.rbe_left == ((void *)0)
) child = (elm)->sess_entry.rbe_right; else if ((elm)->
sess_entry.rbe_right == ((void *)0)) child = (elm)->sess_entry
.rbe_left; else { struct appl_agentx_session *left; elm = (elm
)->sess_entry.rbe_right; while ((left = (elm)->sess_entry
.rbe_left)) elm = left; child = (elm)->sess_entry.rbe_right
; parent = (elm)->sess_entry.rbe_parent; color = (elm)->
sess_entry.rbe_color; if (child) (child)->sess_entry.rbe_parent
= parent; if (parent) { if ((parent)->sess_entry.rbe_left
== elm) (parent)->sess_entry.rbe_left = child; else (parent
)->sess_entry.rbe_right = child; do {} while (0); } else (
head)->rbh_root = child; if ((elm)->sess_entry.rbe_parent
== old) parent = elm; (elm)->sess_entry = (old)->sess_entry
; if ((old)->sess_entry.rbe_parent) { if (((old)->sess_entry
.rbe_parent)->sess_entry.rbe_left == old) ((old)->sess_entry
.rbe_parent)->sess_entry.rbe_left = elm; else ((old)->sess_entry
.rbe_parent)->sess_entry.rbe_right = elm; do {} while (0);
} else (head)->rbh_root = elm; ((old)->sess_entry.rbe_left
)->sess_entry.rbe_parent = elm; if ((old)->sess_entry.rbe_right
) ((old)->sess_entry.rbe_right)->sess_entry.rbe_parent =
elm; if (parent) { left = parent; do { do {} while (0); } while
((left = (left)->sess_entry.rbe_parent)); } goto color; }
parent = (elm)->sess_entry.rbe_parent; color = (elm)->
sess_entry.rbe_color; if (child) (child)->sess_entry.rbe_parent
= parent; if (parent) { if ((parent)->sess_entry.rbe_left
== elm) (parent)->sess_entry.rbe_left = child; else (parent
)->sess_entry.rbe_right = child; do {} while (0); } else (
head)->rbh_root = child; color: if (color == 0) appl_agentx_sessions_RB_REMOVE_COLOR
(head, parent, child); return (old); } __attribute__((__unused__
)) static struct appl_agentx_session * appl_agentx_sessions_RB_INSERT
(struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *tmp; struct appl_agentx_session
*parent = ((void *)0); int comp = 0; tmp = (head)->rbh_root
; while (tmp) { parent = tmp; comp = (appl_agentx_session_cmp
)(elm, parent); if (comp < 0) tmp = (tmp)->sess_entry.rbe_left
; else if (comp > 0) tmp = (tmp)->sess_entry.rbe_right;
else return (tmp); } do { (elm)->sess_entry.rbe_parent = parent
; (elm)->sess_entry.rbe_left = (elm)->sess_entry.rbe_right
= ((void *)0); (elm)->sess_entry.rbe_color = 1; } while (
0); if (parent != ((void *)0)) { if (comp < 0) (parent)->
sess_entry.rbe_left = elm; else (parent)->sess_entry.rbe_right
= elm; do {} while (0); } else (head)->rbh_root = elm; appl_agentx_sessions_RB_INSERT_COLOR
(head, elm); return (((void *)0)); } __attribute__((__unused__
)) static struct appl_agentx_session * appl_agentx_sessions_RB_FIND
(struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *tmp = (head)->rbh_root
; int comp; while (tmp) { comp = appl_agentx_session_cmp(elm,
tmp); if (comp < 0) tmp = (tmp)->sess_entry.rbe_left; else
if (comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return
(tmp); } return (((void *)0)); } __attribute__((__unused__))
static struct appl_agentx_session * appl_agentx_sessions_RB_NFIND
(struct appl_agentx_sessions *head, struct appl_agentx_session
*elm) { struct appl_agentx_session *tmp = (head)->rbh_root
; struct appl_agentx_session *res = ((void *)0); int comp; while
(tmp) { comp = appl_agentx_session_cmp(elm, tmp); if (comp <
0) { res = tmp; tmp = (tmp)->sess_entry.rbe_left; } else if
(comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return
(tmp); } return (res); } __attribute__((__unused__)) static struct
appl_agentx_session * appl_agentx_sessions_RB_NEXT(struct appl_agentx_session
*elm) { if ((elm)->sess_entry.rbe_right) { elm = (elm)->
sess_entry.rbe_right; while ((elm)->sess_entry.rbe_left) elm
= (elm)->sess_entry.rbe_left; } else { if ((elm)->sess_entry
.rbe_parent && (elm == ((elm)->sess_entry.rbe_parent
)->sess_entry.rbe_left)) elm = (elm)->sess_entry.rbe_parent
; else { while ((elm)->sess_entry.rbe_parent && (elm
== ((elm)->sess_entry.rbe_parent)->sess_entry.rbe_right
)) elm = (elm)->sess_entry.rbe_parent; elm = (elm)->sess_entry
.rbe_parent; } } return (elm); } __attribute__((__unused__)) static
struct appl_agentx_session * appl_agentx_sessions_RB_PREV(struct
appl_agentx_session *elm) { if ((elm)->sess_entry.rbe_left
) { elm = (elm)->sess_entry.rbe_left; while ((elm)->sess_entry
.rbe_right) elm = (elm)->sess_entry.rbe_right; } else { if
((elm)->sess_entry.rbe_parent && (elm == ((elm)->
sess_entry.rbe_parent)->sess_entry.rbe_right)) elm = (elm)
->sess_entry.rbe_parent; else { while ((elm)->sess_entry
.rbe_parent && (elm == ((elm)->sess_entry.rbe_parent
)->sess_entry.rbe_left)) elm = (elm)->sess_entry.rbe_parent
; elm = (elm)->sess_entry.rbe_parent; } } return (elm); } __attribute__
((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_MINMAX
(struct appl_agentx_sessions *head, int val) { struct appl_agentx_session
*tmp = (head)->rbh_root; struct appl_agentx_session *parent
= ((void *)0); while (tmp) { parent = tmp; if (val < 0) tmp
= (tmp)->sess_entry.rbe_left; else tmp = (tmp)->sess_entry
.rbe_right; } return (parent); }
;