summaryrefslogtreecommitdiff
path: root/sysdep/bsd/krt-scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdep/bsd/krt-scan.c')
-rw-r--r--sysdep/bsd/krt-scan.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/sysdep/bsd/krt-scan.c b/sysdep/bsd/krt-scan.c
new file mode 100644
index 00000000..e68df318
--- /dev/null
+++ b/sysdep/bsd/krt-scan.c
@@ -0,0 +1,137 @@
+/*
+ * BIRD -- *BSD Table Scanning
+ *
+ * (c) 2004 Ondrej Filip <feela@network.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <net/route.h>
+
+#undef LOCAL_DEBUG
+#define LOCAL_DEBUG
+
+#include "nest/bird.h"
+#include "nest/route.h"
+#include "nest/protocol.h"
+#include "nest/iface.h"
+#include "lib/timer.h"
+#include "lib/unix.h"
+#include "lib/krt.h"
+#include "lib/string.h"
+
+static int krt_scan_fd = -1;
+
+struct iface *
+krt_temp_iface(struct krt_proto *p, char *name)
+{
+ struct iface *i;
+
+ WALK_LIST(i, p->scan.temp_ifs)
+ if (!strcmp(i->name, name))
+ return i;
+ i = mb_allocz(p->p.pool, sizeof(struct iface));
+ strcpy(i->name, name);
+ add_tail(&p->scan.temp_ifs, &i->n);
+ return i;
+}
+
+
+void
+krt_scan_construct(struct krt_config *c)
+{
+}
+
+void
+krt_scan_preconfig(struct config *c)
+{
+}
+
+void
+krt_scan_postconfig(struct krt_config *c)
+{
+}
+
+void
+krt_scan_start(struct krt_proto *x, int first)
+{
+ init_list(&x->scan.temp_ifs);
+}
+
+void
+krt_scan_shutdown(struct krt_proto *x, int last)
+{
+}
+
+void
+krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, int *bl, int cmd)
+{
+ byte *next;
+ int obl, needed, mib[6], on;
+ struct ks_msg *m;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0;
+ mib[3] = BIRD_PF;
+ mib[4] = cmd;
+ mib[5] = 0;
+
+ if( sysctl(mib, 6 , NULL , &needed, NULL, 0) < 0)
+ {
+ die("RT scan...");
+ }
+
+ obl = *bl;
+
+ while(needed > *bl) *bl *= 2;
+ while(needed < (*bl/2)) *bl /= 2;
+
+ if( (obl!=*bl) || !*buf)
+ {
+ if(*buf) mb_free(*buf);
+ if( (*buf = mb_alloc(pool, *bl)) == NULL ) die("RT scan buf alloc");
+ }
+
+ on = needed;
+
+ if( sysctl(mib, 6 , *buf, &needed, NULL, 0) < 0)
+ {
+ if(on != needed) return; /* The buffer size changed since last sysctl */
+ die("RT scan 2");
+ }
+
+ for (next = *buf; next < (*buf + needed); next += m->rtm.rtm_msglen)
+ {
+ m = (struct ks_msg *)next;
+ krt_read_msg(p, m, 1);
+ }
+}
+
+void
+krt_scan_fire(struct krt_proto *p)
+{
+ static byte *buf = NULL;
+ static int bl = 32768;
+ krt_sysctl_scan((struct proto *)p , p->krt_pool, &buf, &bl, NET_RT_DUMP);
+}
+
+void
+krt_if_scan(struct kif_proto *p)
+{
+ static byte *buf = NULL;
+ static int bl = 4096;
+ struct proto *P = (struct proto *)p;
+ if_start_update();
+ krt_sysctl_scan(P, P->pool, &buf, &bl, NET_RT_IFLIST);
+ if_end_update();
+}
+