linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Armin Burchardt <armin@uni-bremen.de>
To: linux-can@vger.kernel.org
Cc: Armin Burchardt <armin@uni-bremen.de>
Subject: [PATCH 3/3] slcand: add option -u to set interface up/down state.
Date: Mon,  8 Jun 2015 13:55:40 +0200	[thread overview]
Message-ID: <1433764540-24917-3-git-send-email-armin@uni-bremen.de> (raw)
In-Reply-To: <1433764540-24917-1-git-send-email-armin@uni-bremen.de>

Signed-off-by: Armin Burchardt <armin@uni-bremen.de>
---
 slcand.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/slcand.c b/slcand.c
index 8fd1418..aa1c79b 100644
--- a/slcand.c
+++ b/slcand.c
@@ -65,6 +65,7 @@ void print_usage(char *prg)
 	fprintf(stderr, "         -b <btr>   (set bit time register value)\n");
 	fprintf(stderr, "         -F         (stay in foreground; no daemonize)\n");
 	fprintf(stderr, "         -p <file>  (write PID of daemon to file)\n");
+	fprintf(stderr, "         -u         (control interface state ('UP' and 'DOWN')\n");
 	fprintf(stderr, "         -h         (show this help page)\n");
 	fprintf(stderr, "\nExamples:\n");
 	fprintf(stderr, "slcand -o -c -f -s6 ttyUSB0\n");
@@ -159,6 +160,43 @@ static int look_up_uart_speed(long int s)
 	}
 }
 
+/* set selected interface flags */
+static int candev_setflags(const char* name, __u32 flags, __u32 mask)
+{
+	int err = 0;
+	struct ifreq ifr;
+	int fd;
+
+	if (strlen(name) >= IFNAMSIZ) {
+		return -1;
+	}
+	fd = socket(PF_INET, SOCK_DGRAM, 0);
+	if (fd < 0) {
+		perror("socket()");
+		return -1;
+	}
+	/* copy interface name to ioctl data */
+	strncpy(ifr.ifr_name, name, IFNAMSIZ);
+	/* get flags for interface with that name */
+	err = ioctl(fd, SIOCGIFFLAGS, &ifr);
+	if (err == -1) {
+		perror("SIOCGIFFLAGS");
+	} else {
+		/* clear all flags which are selected in mask */
+		ifr.ifr_flags &= ~mask;
+		/* set requested flags which are selected in mask,
+		 * keep values of flags which are not selected. */
+		ifr.ifr_flags |= mask&flags;
+		/* write flags back to interface */
+		err = ioctl(fd, SIOCSIFFLAGS, &ifr);
+		if (err == -1) {
+			perror("SIOSSIFFLAGS");
+		}
+	}
+	close(fd);
+	return err;
+}
+
 int main(int argc, char *argv[])
 {
 	char *tty = NULL;
@@ -173,6 +211,7 @@ int main(int argc, char *argv[])
 	int send_open = 0;
 	int send_close = 0;
 	int send_read_status_flags = 0;
+	int control_ifstate = 0;
 	char *speed = NULL;
 	char *uart_speed_str = NULL;
 	long int uart_speed = 0;
@@ -186,7 +225,7 @@ int main(int argc, char *argv[])
 
 	ttypath[0] = '\0';
 
-	while ((opt = getopt(argc, argv, "ocfs:S:t:b:p:?hF")) != -1) {
+	while ((opt = getopt(argc, argv, "ocfs:S:t:b:p:u?hF")) != -1) {
 		switch (opt) {
 		case 'o':
 			send_open = 1;
@@ -234,6 +273,9 @@ int main(int argc, char *argv[])
 		case 'p':
 			pidfile = optarg;
 			break;
+		case 'u':
+			control_ifstate = 1;
+			break;
 		case 'h':
 		case '?':
 		default:
@@ -355,6 +397,18 @@ int main(int argc, char *argv[])
 		}	
 	}
 
+	/* set interface state to 'UP' */
+	if (control_ifstate) {
+		if (candev_setflags(name ? name : buf, IFF_UP, IFF_UP) == -1) {
+			syslog(LOG_ERR, "could not set %s state to 'UP'", buf);
+			exit(EXIT_FAILURE);
+		} else {
+			syslog(LOG_NOTICE, "%s: set flag 'UP'", buf);
+		}
+	} else {
+		syslog(LOG_NOTICE, "please remember to set %s to 'UP'", buf);
+	}
+
 	/* Daemonize (_after_ interface is up to avoid race-conditions,
 	 * ie. between init.d-scripts). */
 	if (run_as_daemon) {
@@ -397,6 +451,13 @@ int main(int argc, char *argv[])
 	while (slcand_running)
 		sleep(1); /* wait 1 second */
 
+	/* set interface state to 'DOWN' */
+	if (control_ifstate) {
+		/* clear 'IFF_UP' flag */
+		candev_setflags(name ? name : buf, ~IFF_UP, IFF_UP);
+		syslog(LOG_ERR, "could not set %s state to 'DOWN'", name);
+	}
+
 	/* Reset line discipline */
 	syslog(LOG_INFO, "stopping on TTY device %s", ttypath);
 	ldisc = N_TTY;
-- 
1.9.1


  parent reply	other threads:[~2015-06-08 11:55 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-08 11:55 [PATCH 1/3] slcand: daemonize _after_ interface is created, renamed and up Armin Burchardt
2015-06-08 11:55 ` [PATCH 2/3] slcand: add option -p<file> to write pid to a file Armin Burchardt
2015-06-08 13:00   ` Marc Kleine-Budde
2015-06-08 13:43     ` Armin Burchardt
2015-06-08 13:55       ` Marc Kleine-Budde
2015-06-08 11:55 ` Armin Burchardt [this message]
2015-06-08 12:51 ` [PATCH 1/3] slcand: daemonize _after_ interface is created, renamed and up Marc Kleine-Budde
2015-06-09  9:15 ` [PATCH v2 0/3] slcand: improved patches Armin Burchardt
2015-06-09  9:15   ` [PATCH v2 1/3] slcand: daemonize _after_ interface is created and renamed Armin Burchardt
2015-06-09  9:15   ` [PATCH v2 2/3] slcand: add option -p<file> to write pid to a file Armin Burchardt
2015-06-09  9:15   ` [PATCH v2 3/3] slcand: add option -u to set interface up/down state Armin Burchardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1433764540-24917-3-git-send-email-armin@uni-bremen.de \
    --to=armin@uni-bremen.de \
    --cc=linux-can@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).