summaryrefslogtreecommitdiffstats
path: root/nrconfig.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2008-04-02 13:34:05 +0000
committerRalf Baechle <ralf@linux-mips.org>2008-04-02 13:34:05 +0000
commitfbb41991bd530270b0f70a110af507fc029e76b8 (patch)
treec9cb0a6bd66baef65c0412596b5e2e5b16819aec /nrconfig.c
parentb5682742ef212b62c9494a2d462654a7d0301266 (diff)
From Matti Aarnio (oh2mqk@sral.fi):
* axconfig.c: Find all running network ports, and compare them against the /etc/ax25/axports file. * nrconfig.c: Find all running network ports, and compare them against the /etc/ax25/nrports file. * rsconfig.c: Find all running network ports, and compare them against the /etc/ax25/rsports file. * Update man pages
Diffstat (limited to 'nrconfig.c')
-rw-r--r--nrconfig.c162
1 files changed, 96 insertions, 66 deletions
diff --git a/nrconfig.c b/nrconfig.c
index fa64c26..053db68 100644
--- a/nrconfig.c
+++ b/nrconfig.c
@@ -42,15 +42,6 @@ typedef struct _nrport
static NR_Port *nr_ports = NULL;
static NR_Port *nr_port_tail = NULL;
-static int ax25_hw_cmp(char *callsign, char *hw_addr)
-{
- ax25_address call;
-
- ax25_aton_entry(callsign, call.ax25_call);
-
- return ax25_cmp(&call, (ax25_address *)hw_addr) == 0;
-}
-
static NR_Port *nr_port_ptr(char *name)
{
NR_Port *p = nr_ports;
@@ -170,15 +161,12 @@ char *nr_config_get_desc(char *name)
return p->Description;
}
-static int nr_config_init_port(int fd, int lineno, char *line)
+static int nr_config_init_port(int fd, int lineno, char *line, const char **ifcalls, const char **ifdevs)
{
NR_Port *p;
- char buffer[1024];
- char *name, *call, *alias, *paclen, *desc, *dev = NULL;
- struct ifconf ifc;
- struct ifreq *ifrp;
- struct ifreq ifr;
- int n, found = 0;
+ char *name, *call, *alias, *paclen, *desc;
+ const char *dev = NULL;
+ int found = 0;
name = strtok(line, " \t");
call = strtok(NULL, " \t");
@@ -215,42 +203,19 @@ static int nr_config_init_port(int fd, int lineno, char *line)
strupr(call);
strupr(alias);
- ifc.ifc_len = sizeof(buffer);
- ifc.ifc_buf = buffer;
-
- if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
- fprintf(stderr, "nrconfig: SIOCGIFCONF: %s\n", strerror(errno));
- return FALSE;
- }
-
- for (ifrp = ifc.ifc_req, n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifrp++) {
- strcpy(ifr.ifr_name, ifrp->ifr_name);
-
- if (strcmp(ifr.ifr_name, "lo") == 0) continue;
-
- if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
- fprintf(stderr, "nrconfig: SIOCGIFFLAGS: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (!(ifr.ifr_flags & IFF_UP)) continue;
-
- if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
- fprintf(stderr, "nrconfig: SIOCGIFHWADDR: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (ifr.ifr_hwaddr.sa_family != ARPHRD_NETROM) continue;
-
- if (ax25_hw_cmp(call, ifr.ifr_hwaddr.sa_data)) {
- dev = ifr.ifr_name;
- found = 1;
- break;
- }
+ found = 0;
+ for (;ifcalls && *ifcalls; ++ifcalls, ++ifdevs) {
+ if (strcmp(call,*ifcalls) == 0) {
+ found = 1;
+ dev = *ifdevs;
+ break;
+ }
}
if (!found) {
+#if 0 /* None of your business to complain about some port being down... */
fprintf(stderr, "nrconfig: port %s not active\n", name);
+#endif
return FALSE;
}
@@ -280,34 +245,99 @@ static int nr_config_init_port(int fd, int lineno, char *line)
int nr_config_load_ports(void)
{
- FILE *fp;
+ FILE *fp = NULL;
char buffer[256], *s;
- int fd, lineno = 1, n = 0;
+ int fd = -1, lineno = 1, n = 0, i;
+ const char **calllist = NULL;
+ const char **devlist = NULL;
+ int callcount = 0;
+ struct ifreq ifr;
- if ((fp = fopen(CONF_NRPORTS_FILE, "r")) == NULL) {
- fprintf(stderr, "nrconfig: unable to open nrports file %s (%s)\n", CONF_NRPORTS_FILE, strerror(errno));
- return 0;
+ /* Reliable listing of all network ports on Linux
+ is only available via reading /proc/net/dev ... */
+
+
+ if ((fd = socket(PF_FILE, SOCK_DGRAM, 0)) < 0) {
+ fprintf(stderr, "nrconfig: unable to open socket (%s)\n", strerror(errno));
+ goto cleanup;
}
- if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- fprintf(stderr, "nrconfig: unable to open socket (%s)\n", strerror(errno));
- fclose(fp);
- return 0;
+ if ((fp = fopen("/proc/net/dev", "r"))) {
+ /* Two header lines.. */
+ s = fgets(buffer, sizeof(buffer), fp);
+ s = fgets(buffer, sizeof(buffer), fp);
+ /* .. then network interface names */
+ while (!feof(fp)) {
+ if (!fgets(buffer, sizeof(buffer), fp))
+ break;
+ s = strchr(buffer, ':');
+ if (s) *s = 0;
+ s = buffer;
+ while (*s == ' ') ++s;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, s);
+
+ if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
+ fprintf(stderr, "nrconfig: SIOCGIFHWADDR: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ if (ifr.ifr_hwaddr.sa_family != ARPHRD_NETROM)
+ continue;
+
+ /* store found interface callsigns */
+ /* ax25_ntoa() returns pointer to static buffer */
+ s = ax25_ntoa((void*)ifr.ifr_hwaddr.sa_data);
+
+ if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
+ fprintf(stderr, "nrconfig: SIOCGIFFLAGS: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ if (!(ifr.ifr_flags & IFF_UP))
+ continue;
+
+
+ calllist = realloc(calllist, sizeof(char *) * (callcount+2));
+ devlist = realloc(devlist, sizeof(char *) * (callcount+2));
+ calllist[callcount] = strdup(s);
+ devlist [callcount] = strdup(ifr.ifr_name);
+ ++callcount;
+ calllist[callcount] = NULL;
+ devlist [callcount] = NULL;
+ }
+ fclose(fp);
+ fp = NULL;
+ }
+
+
+ if ((fp = fopen(CONF_NRPORTS_FILE, "r")) == NULL) {
+ fprintf(stderr, "nrconfig: unable to open nrports file %s (%s)\n", CONF_NRPORTS_FILE, strerror(errno));
+ goto cleanup;
}
- while (fgets(buffer, 255, fp) != NULL) {
- if ((s = strchr(buffer, '\n')) != NULL)
- *s = '\0';
+ while (fp && fgets(buffer, 255, fp)) {
+ if ((s = strchr(buffer, '\n')))
+ *s = '\0';
- if (strlen(buffer) > 0 && buffer[0] != '#')
- if (nr_config_init_port(fd, lineno, buffer))
- n++;
+ if (strlen(buffer) > 0 && *buffer != '#')
+ if (nr_config_init_port(fd, lineno, buffer, calllist, devlist))
+ n++;
- lineno++;
+ lineno++;
}
- fclose(fp);
- close(fd);
+ cleanup:;
+ if (fd >= 0) close(fd);
+ if (fp) fclose(fp);
+
+ for(i = 0; calllist && calllist[i]; ++i) {
+ free((void*)calllist[i]);
+ free((void*)devlist[i]);
+ }
+ if (calllist) free(calllist);
+ if (devlist) free(devlist);
if (nr_ports == NULL)
return 0;