shithub: netgraph

Download patch

ref: 4432f986824b5c1faaec19a218a6b48c15161944
parent: 5a7732335f618f8cc7e96e28941bee126f6d0032
author: sirjofri <sirjofri@sirjofri.de>
date: Sun Aug 31 06:15:33 EDT 2025

ipnet integration, better visuals

--- a/dat.h
+++ b/dat.h
@@ -4,10 +4,13 @@
 typedef struct Ipnet Ipnet;
 typedef struct Pos Pos;
 typedef struct Conn Conn;
+typedef struct Color Color;
 
 extern char *netdir;
 extern char *systuples[];
 extern int nsystuples;
+extern char *ipnettuples[];
+extern int nipnettuples;
 
 extern int pagewidth;
 extern int pageheight;
@@ -14,6 +17,12 @@
 
 extern int showipnet;
 
+struct Color {
+	float r;
+	float g;
+	float b;
+};
+
 struct Pos {
 	int x;
 	int y;
@@ -40,6 +49,7 @@
 
 struct Ipnet {
 	Block;
+	Color color;
 };
 
 struct Conn {
@@ -47,3 +57,5 @@
 	Sys *to;
 	String *types;
 };
+
+extern char *Sipnet;
--- a/draw.c
+++ b/draw.c
@@ -81,12 +81,13 @@
 static int
 isipnet(Tuple *t)
 {
-	return strcmp(t->key, "ipnet") == 0;
+	return strcmp(t->key, Sipnet) == 0;
 }
 
 static void
 drawtuple(Tuple *t, void *aux)
 {
+	Color c;
 	Pos *p = aux;
 	int ipnet = isipnet(t);
 	
@@ -93,7 +94,18 @@
 	if (!showipnet && t->ipnet && !ipnet)
 		return;
 	
+	if (ipnet) {
+		print("gsave\n");
+		c = getipnetcolor(Sipnet, t->value);
+		print("%f %f %f setrgbcolor\n", c.r, c.g, c.b);
+	}
+	
 	drawtext(*p, 1, "%s%s: %s", t->ipnet ? "*" : "", t->key, t->value);
+	
+	if (ipnet) {
+		print("grestore\n");
+	}
+	
 	p->y -= lineheight;
 }
 
--- a/fns.h
+++ b/fns.h
@@ -6,6 +6,9 @@
 void setblocksize(Block*);
 void dconn(Block*, Block*, char*);
 
+/* global functions */
+void fillblockvalue(Block*, char*, char*, char*);
+
 /* tuple functions */
 Tuple *findtuple(Block*, char*);
 void addtuple(Block*, char*, char*, int);
@@ -13,10 +16,11 @@
 
 /* sys functions */
 int issysarg(char*);
-int gensys(char*,char*);
-Sys *findsys(char*,char*);
+int gensys(char*, char*);
+Sys *findsys(char*, char*);
 void forsys(void (*f)(Sys*,void*), void*);
 int numsystems(void);
+void forsysarg(int (*f)(char*,void*), void*);
 
 /* conn functions */
 void addconn(Sys*, Sys*, char*);
@@ -25,5 +29,8 @@
 
 /* ipnet functions */
 int isnetarg(char*);
-int genipnet(char*,char*);
+int numipnets(void);
+Ipnet *findipnet(char*, char*);
+int genipnet(char*, char*);
 void fornet(void (*f)(Ipnet*,void*), void*);
+Color getipnetcolor(char*, char*);
--- a/ipnet.c
+++ b/ipnet.c
@@ -1,0 +1,102 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <ndb.h>
+#include <String.h>
+#include "dat.h"
+#include "fns.h"
+
+/* user request: these tuples are ipnets */
+static char *netargs[] = {
+	"ipnet",
+};
+
+int
+isnetarg(char *key)
+{
+	int n = sizeof(netargs) / sizeof(*netargs);
+	for (int i = 0; i < n; i++)
+		if (strcmp(netargs[i], key) == 0)
+			return 1;
+	return 0;
+}
+
+static Ipnet ipnets[50];
+static int nipnets = 0;
+
+int
+numipnets()
+{
+	return nipnets;
+}
+
+Color
+getipnetcolor(char *k, char *v)
+{
+	Ipnet *n;
+	Color c = { 0., 0., 0. };
+	n = findipnet(k, v);
+	if (!n) {
+		fprint(2, "ipnet %s=%s not found\n", k, v);
+		return c;
+	}
+	
+	return n->color;
+}
+
+static Ipnet*
+gennet(void)
+{
+	Ipnet *n;
+	n = &ipnets[nipnets];
+	nipnets++;
+	memset(n, 0, sizeof(Ipnet));
+	return n;
+}
+
+Ipnet*
+findipnet(char *key, char *value)
+{
+	Ipnet *n;
+	Tuple *t;
+	
+	for (int i = 0; i < nipnets; i++) {
+		n = &ipnets[i];
+		t = findtuple(n, key);
+		if (t && strcmp(t->value, value) == 0)
+			return n;
+	}
+	return nil;
+}
+
+int
+genipnet(char *key, char *value)
+{
+	Ipnet *n;
+	char *valid;
+	
+	valid = csgetvalue(netdir, key, value, key, nil);
+	if (!valid)
+		return 0;
+	n = findipnet(key, value);
+	if (n)
+		return 1;
+	n = gennet();
+	
+	for (int i = 0; i < nipnettuples; i++) {
+		if (strcmp(ipnettuples[i], key) == 0) {
+			addtuple(n, ipnettuples[i], strdup(value), 0);
+			continue;
+		}
+		fillblockvalue(n, ipnettuples[i], key, value);
+	}
+	
+	return 1;
+}
+
+void
+fornet(void (*f)(Ipnet*,void*), void *aux)
+{
+	for (int i = 0; i < nipnets; i++)
+		f(&ipnets[i], aux);
+}
--- a/netgraph.c
+++ b/netgraph.c
@@ -9,16 +9,20 @@
 static void
 usage(void)
 {
-	fprint(2, "usage: %s [-i] [-s systuples]\n", argv0);
+	fprint(2, "usage: %s [-i] [-s systuples] [-n ipnettuples]\n", argv0);
 	exits("usage");
 }
 
 #define MAXSYSTP 24
 
+char *Sipnet = "ipnet";
+
 char *netdir = nil;
 
 char *systuples[MAXSYSTP];
 int nsystuples = 0;
+char *ipnettuples[MAXSYSTP];
+int nipnettuples = 0;
 
 /* A3 format: 842 x 1191 */
 int pagewidth = 1191;
@@ -33,6 +37,10 @@
 		gensys(key, val);
 		return;
 	}
+	if (isnetarg(key)) {
+		genipnet(key, val);
+		return;
+	}
 }
 
 static void
@@ -63,7 +71,64 @@
 	fortuple(s, dumptuples, nil);
 }
 
+void
+dumpipnet(Ipnet *n, void*)
+{
+	fprint(2, "ipnet\n");
+	fortuple(n, dumptuples, nil);
+}
+
+static Color
+hue2color(float h)
+{
+	Color c;
+	int i = h;
+	float f = h * 6. - i;
+	float p = 0.;
+	float q = 1. - f;
+	float t = 1. - (1. - f);
+	
+	switch (i % 6) {
+	case 0: c.r = 1; c.g = t; c.b = p; break;
+	case 1: c.r = q; c.g = 1; c.b = p; break;
+	case 2: c.r = p; c.g = 1; c.b = t; break;
+	case 3: c.r = p; c.g = q; c.b = 1; break;
+	case 4: c.r = t; c.g = p; c.b = 1; break;
+	case 5: c.r = 1; c.g = p; c.b = q; break;
+	}
+	c.r = c.r < 0 ? 0 : c.r;
+	c.g = c.g < 0 ? 0 : c.g;
+	c.b = c.b < 0 ? 0 : c.b;
+	return c;
+}
+
+typedef struct Calcipnetparams Calcipnetparams;
+struct Calcipnetparams {
+	int i;
+	int x;
+};
+
 static void
+calcnetlayout(Ipnet *n, void *aux)
+{
+	Calcipnetparams *p = aux;
+	int num = numipnets();
+	int i = p->i;
+	float step = 2*PI / num;
+	float hue = (step * i) / PI;
+	
+	n->color = hue2color(hue);
+	
+	setblocksize(n);
+	
+	n->p.x = p->x + 5;
+	n->p.y = 5;
+	
+	p->i++;
+	p->x += n->width + 10;
+}
+
+static void
 calcsyslayout(Sys *s, void *aux)
 {
 	int n = numsystems();
@@ -75,7 +140,7 @@
 	
 	float pagex = pagewidth/2.;
 	float pagey = pageheight/2.;
-	float spread = 0.5;
+	float spread = 0.6;
 	
 	s->p.x = cos(step * i) * pagex * spread + pagex - s->width/2;
 	s->p.y = sin(step * i) * pagey * spread + pagey - s->height/2;
@@ -113,11 +178,19 @@
 	dblock(s);
 }
 
+static void
+drawipnets(Ipnet *n, void*)
+{
+	dblock(n);
+}
+
 void
 main(int argc, char **argv)
 {
 	Biobuf *bin;
-	char *stp = "sys,ether,ip,ipnet,dom,auth,authdom";
+	Calcipnetparams netparams;
+	char *stp = "sys,ether,ip,ipgw,ipnet,dom,auth,authdom";
+	char *ntp = "ipnet,ip,ipmask,ipgw,authdom,auth,fs,dns";
 	char *s;
 	int i;
 	
@@ -127,6 +200,9 @@
 	case 's':
 		stp = EARGF(usage());
 		break;
+	case 'n':
+		ntp = EARGF(usage());
+		break;
 	case 'x':
 		netdir = EARGF(usage());
 		break;
@@ -136,6 +212,7 @@
 	}ARGEND;
 	
 	nsystuples = getfields(stp, systuples, MAXSYSTP, 1, ",");
+	nipnettuples = getfields(ntp, ipnettuples, MAXSYSTP, 1, ",");
 	
 	bin = Bfdopen(0, OREAD);
 	if (!bin)
@@ -148,11 +225,54 @@
 	
 	Bterm(bin);
 	
-	dheader();
+	/* calculation stage */
 	i = 0;
 	forsys(calcsyslayout, &i);
+	
+	netparams.i = 0;
+	netparams.x = 0;
+	fornet(calcnetlayout, &netparams);
+	
 	forsys(calcconns, nil);
+	
+	/* drawing stage */
+	dheader();
 	forconn(drawconns, nil);
 	forsys(drawsystems, nil);
+	fornet(drawipnets, nil);
 	dfooter();
+}
+
+static int
+tryaddsys(char *s, void *aux)
+{
+	char *sys = aux;
+	return gensys(s, sys);
+}
+
+void
+fillblockvalue(Block *b, char *key, char *ids, char *idv)
+{
+	char *val;
+	Ndbtuple *t;
+	
+	val = csgetvalue(netdir, ids, idv, key, nil);
+	if (val) {
+		addtuple(b, key, val, 0);
+		return;
+	}
+	t = csipinfo(netdir, ids, idv, &key, 1);
+	if (t) {
+		if (t->val)
+			val = strdup(t->val);
+		ndbfree(t);
+	}
+	if (!val)
+		return;
+	addtuple(b, key, val, 1);
+	
+	if (!isconnsrv(key))
+		return;
+	
+	forsysarg(tryaddsys, val);
 }
--- a/sys.c
+++ b/sys.c
@@ -8,7 +8,7 @@
 
 /* user request: these tuples are systems */
 static char *sysargs[] = {
-	"sys", "ip", "dom",
+	"sys", "ip", "dom", "ipgw",
 };
 
 #define MAXSYS 100
@@ -62,34 +62,30 @@
 	return 0;
 }
 
+void
+forsysarg(int (*f)(char*,void*), void *aux)
+{
+	int n = sizeof(sysargs) / sizeof(*sysargs);
+	for (int i = 0; i < n; i++)
+		if (f(sysargs[i], aux))
+			return;
+}
+
 static void
-fillsysvalue(Sys *s, char *key, char *ids, char *idv)
+condgenipnet(char *key, char *value)
 {
-	char *val;
 	Ndbtuple *t;
 	
-	val = csgetvalue(netdir, ids, idv, key, nil);
-	if (val) {
-		addtuple(s, key, val, 0);
+	t = csipinfo(netdir, key, value, &Sipnet, 1);
+	if (!t)
 		return;
-	}
-	t = csipinfo(netdir, ids, idv, &key, 1);
-	if (t) {
-		if (t->val) val = strdup(t->val);
+	if (!t->val) {
 		ndbfree(t);
-	}
-	if (!val)
 		return;
+	}
 	
-	addtuple(s, key, val, 1);
-	
-	if (!isconnsrv(key))
-		return;
-	
-	if (gensys("sys", val))
-		return;
-	if (gensys("ip", val))
-		return;
+	genipnet(Sipnet, t->val);
+	ndbfree(t);
 }
 
 int
@@ -111,8 +107,10 @@
 			addtuple(sys, systuples[i], strdup(value), 0);
 			continue;
 		}
-		fillsysvalue(sys, systuples[i], key, value);
+		fillblockvalue(sys, systuples[i], key, value);
 	}
+	
+	condgenipnet(key, value);
 	
 	return 1;
 }
--