-/*
- * $Id: isotptun.c 824 2008-09-02 07:01:51Z hartko $
- */
-
/*
* isotptun.c - IP over CAN ISO-TP (ISO15765-2) tunnel / proof-of-concept
*
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
- * Send feedback to <socketcan-users@lists.berlios.de>
+ * Send feedback to <linux-can@vger.kernel.org>
*
*/
#include <string.h>
#include <libgen.h>
#include <errno.h>
+#include <signal.h>
#include <net/if.h>
#include <sys/types.h>
#include <linux/if_tun.h>
#define NO_CAN_ID 0xFFFFFFFFU
+#define DEFAULT_NAME "ctun%d"
+
+static volatile int running = 1;
void print_usage(char *prg)
{
fprintf(stderr, "ethernet frames inside ISO15765-2 (unreliable) datagrams on CAN.\n\n");
fprintf(stderr, "Options: -s <can_id> (source can_id. Use 8 digits for extended IDs)\n");
fprintf(stderr, " -d <can_id> (destination can_id. Use 8 digits for extended IDs)\n");
+ fprintf(stderr, " -n <name> (name of created IP netdevice. Default: '%s')\n", DEFAULT_NAME);
fprintf(stderr, " -x <addr> (extended addressing mode.)\n");
fprintf(stderr, " -p <byte> (padding byte rx path)\n");
fprintf(stderr, " -q <byte> (padding byte tx path)\n");
fprintf(stderr, "\n");
}
+void sigterm(int signo)
+{
+ running = 0;
+}
+
int main(int argc, char **argv)
{
fd_set rdfs;
static struct can_isotp_fc_options fcopts;
int opt, ret;
extern int optind, opterr, optopt;
- static int quit;
static int verbose;
-
unsigned char buffer[4096];
+ static char name[IFNAMSIZ] = DEFAULT_NAME;
int nbytes;
+ signal(SIGTERM, sigterm);
+ signal(SIGHUP, sigterm);
+ signal(SIGINT, sigterm);
+
addr.can_addr.tp.tx_id = addr.can_addr.tp.rx_id = NO_CAN_ID;
- while ((opt = getopt(argc, argv, "s:d:x:p:q:P:t:b:m:whv")) != -1) {
+ while ((opt = getopt(argc, argv, "s:d:n:x:p:q:P:t:b:m:whv?")) != -1) {
switch (opt) {
case 's':
addr.can_addr.tp.tx_id = strtoul(optarg, (char **)NULL, 16);
addr.can_addr.tp.rx_id |= CAN_EFF_FLAG;
break;
+ case 'n':
+ strncpy(name, optarg, IFNAMSIZ-1);
+ break;
+
case 'x':
opts.flags |= CAN_ISOTP_EXTEND_ADDR;
opts.ext_address = strtoul(optarg, (char **)NULL, 16) & 0xFF;
verbose = 1;
break;
+ case '?':
+ print_usage(basename(argv[0]));
+ exit(0);
+ break;
+
default:
fprintf(stderr, "Unknown option %c\n", opt);
print_usage(basename(argv[0]));
- exit(0);
+ exit(1);
break;
}
}
(addr.can_addr.tp.tx_id == NO_CAN_ID) ||
(addr.can_addr.tp.rx_id == NO_CAN_ID)) {
print_usage(basename(argv[0]));
- exit(0);
+ exit(1);
}
if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_ISOTP)) < 0) {
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
- strncpy(ifr.ifr_name, "ctun%d", IFNAMSIZ);
+ strncpy(ifr.ifr_name, name, IFNAMSIZ);
if (ioctl(t, TUNSETIFF, (void *) &ifr) < 0) {
perror("ioctl tunfd");
exit(1);
}
- while (!quit) {
+ while (running) {
FD_ZERO(&rdfs);
FD_SET(s, &rdfs);
FD_SET(t, &rdfs);
- FD_SET(0, &rdfs);
if ((ret = select(t+1, &rdfs, NULL, NULL, NULL)) < 0) {
perror("select");
continue;
}
- if (FD_ISSET(0, &rdfs)) {
- getchar();
- quit = 1;
- printf("quit due to keyboard input.\n");
- }
-
if (FD_ISSET(s, &rdfs)) {
nbytes = read(s, buffer, 4096);
if (nbytes < 0) {