X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/f5ecd97b15797e14e691bb6f3562ec1685c96bca..refs/pull/862/head:/uart/uart_posix.c?ds=inline diff --git a/uart/uart_posix.c b/uart/uart_posix.c index 0e7f7f47..29a02cf7 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -2,6 +2,7 @@ * Generic uart / rs232/ serial port library * * Copyright (c) 2013, Roel Verdult + * Copyright (c) 2018 Google * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,10 +33,12 @@ * proxmark3 project. */ -#include "uart.h" - // Test if we are dealing with posix operating systems #ifndef _WIN32 +#define _DEFAULT_SOURCE + +#include "uart.h" + #include #include #include @@ -45,6 +48,18 @@ #include #include #include +#include +#include +#include +#include +#include +#include + +// Fix missing definition on OS X. +// Taken from https://github.com/unbit/uwsgi/commit/b608eb1772641d525bfde268fe9d6d8d0d5efde7 +#ifndef SOL_TCP +#define SOL_TCP IPPROTO_TCP +#endif typedef struct termios term_info; typedef struct { @@ -54,7 +69,7 @@ typedef struct { } serial_port_unix; // Set time-out on 30 miliseconds -const struct timeval timeout = { +struct timeval timeout = { .tv_sec = 0, // 0 second .tv_usec = 30000 // 30000 micro seconds }; @@ -64,6 +79,65 @@ serial_port uart_open(const char* pcPortName) serial_port_unix* sp = malloc(sizeof(serial_port_unix)); if (sp == 0) return INVALID_SERIAL_PORT; + if (memcmp(pcPortName, "tcp:", 4) == 0) { + struct addrinfo *addr = NULL, *rp; + char *addrstr = strdup(pcPortName + 4); + if (addrstr == NULL) { + printf("Error: strdup\n"); + return INVALID_SERIAL_PORT; + } + char *colon = strrchr(addrstr, ':'); + char *portstr; + + // Set time-out to 300 miliseconds only for TCP port + timeout.tv_usec = 300000; + + if (colon) { + portstr = colon + 1; + *colon = '\0'; + } else + portstr = "7901"; + + struct addrinfo info; + + memset (&info, 0, sizeof(info)); + + info.ai_socktype = SOCK_STREAM; + + int s = getaddrinfo(addrstr, portstr, &info, &addr); + if (s != 0) { + printf("Error: getaddrinfo: %s\n", gai_strerror(s)); + return INVALID_SERIAL_PORT; + } + + int sfd; + for (rp = addr; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, + rp->ai_protocol); + if (sfd == -1) + continue; + + if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; + + close(sfd); + } + + if (rp == NULL) { /* No address succeeded */ + printf("Error: Could not connect\n"); + return INVALID_SERIAL_PORT; + } + + freeaddrinfo(addr); + free(addrstr); + + sp->fd = sfd; + + int one = 1; + setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); + return sp; + } + sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if(sp->fd == -1) { uart_close(sp);