From fc6feea0d4a2db30163480b160df166b2933172f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Oct 2023 20:30:13 +0200 Subject: [PATCH] experimental UDP support. Doesnt quite work yet --- CHANGELOG.md | 1 + client/src/comms.c | 11 +++--- client/src/uart/uart_posix.c | 76 ++++++++++++++++++++++++++++++++++++ include/pm3_cmd.h | 7 ++-- 4 files changed, 87 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cb26317e..69da9696f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Experimental UDP support in linux (@iceman1001) - Changed CI scripts to speed up the builds (@wh201906) - Changed the timeout of local TCP connections (@wh201906) - Finalized implementation of configcard generation for keyroll when cardhelper is not present (@Antiklesys) diff --git a/client/src/comms.c b/client/src/comms.c index c0dc9dc17..4aaa37689 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -668,21 +668,22 @@ int TestProxmark(pm3_device_t *dev) { bool is_tcp_conn = (memcmp(g_conn.serial_port_name, "tcp:", 4) == 0); bool is_bt_conn = (memcmp(g_conn.serial_port_name, "bt:", 3) == 0); + bool is_udp_conn = (memcmp(g_conn.serial_port_name, "udp:", 4) == 0); - PrintAndLogEx(INFO, "Communicating with PM3 over %s%s%s", + PrintAndLogEx(INFO, "Communicating with PM3 over %s%s%s%s", (g_conn.send_via_fpc_usart) ? _YELLOW_("FPC UART") : _YELLOW_("USB-CDC"), (is_tcp_conn) ? " over " _YELLOW_("TCP") : "", - (is_bt_conn) ? " over " _YELLOW_("BT") : "" + (is_bt_conn) ? " over " _YELLOW_("BT") : "", + (is_udp_conn) ? " over " _YELLOW_("UDP") : "" ); - if (g_conn.send_via_fpc_usart) { PrintAndLogEx(INFO, "PM3 UART serial baudrate: " _YELLOW_("%u") "\n", g_conn.uart_speed); } else { int res; - if (is_tcp_conn) { + if (is_tcp_conn || is_udp_conn) { if ((strstr(g_conn.serial_port_name, "localhost") != NULL) || (strstr(g_conn.serial_port_name, "127.0.0.1") != NULL)) { - res = uart_reconfigure_timeouts(UART_USB_CLIENT_RX_TIMEOUT_MS * 2); + res = uart_reconfigure_timeouts(UART_TCP_CLIENT_LOCAL_RX_TIMEOUT_MS); } else { res = uart_reconfigure_timeouts(UART_TCP_CLIENT_RX_TIMEOUT_MS); } diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index 106c8d209..c7cdc27a6 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -46,6 +46,9 @@ #ifndef SOL_TCP # define SOL_TCP IPPROTO_TCP #endif +#ifndef SOL_UDP +# define SOL_UDP IPPROTO_UDP +#endif typedef struct termios term_info; typedef struct { @@ -168,6 +171,79 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { return sp; } + if (memcmp(prefix, "udp:", 4) == 0) { + free(prefix); + + if (strlen(pcPortName) <= 4) { + free(sp); + return INVALID_SERIAL_PORT; + } + + struct addrinfo *addr = NULL, *rp; + + char *addrstr = strdup(pcPortName + 4); + if (addrstr == NULL) { + PrintAndLogEx(ERR, "error: string duplication"); + free(sp); + return INVALID_SERIAL_PORT; + } + + timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; + + char *colon = strrchr(addrstr, ':'); + const char *portstr; + if (colon) { + portstr = colon + 1; + *colon = '\0'; + } else { + portstr = "18888"; + } + + struct addrinfo info; + + memset(&info, 0, sizeof(info)); + + info.ai_family = AF_INET; + info.ai_socktype = SOCK_DGRAM; +// info.ai_protocol = SOL_UDP; + + int s = getaddrinfo(addrstr, portstr, &info, &addr); + if (s != 0) { + PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s)); + freeaddrinfo(addr); + free(addrstr); + free(sp); + 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); + } + + freeaddrinfo(addr); + free(addrstr); + + if (rp == NULL) { /* No address succeeded */ + PrintAndLogEx(ERR, "error: Could not connect"); + free(sp); + return INVALID_SERIAL_PORT; + } + + sp->fd = sfd; + + return sp; + } + + if (memcmp(prefix, "bt:", 3) == 0) { free(prefix); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index afd8c9ff6..f7317ba11 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -826,9 +826,10 @@ typedef struct { // took settings from libnfc/buses/uart.c // uart_windows.c & uart_posix.c -# define UART_FPC_CLIENT_RX_TIMEOUT_MS 200 -# define UART_USB_CLIENT_RX_TIMEOUT_MS 20 -# define UART_TCP_CLIENT_RX_TIMEOUT_MS 500 +# define UART_FPC_CLIENT_RX_TIMEOUT_MS 200 +# define UART_USB_CLIENT_RX_TIMEOUT_MS 20 +# define UART_TCP_CLIENT_RX_TIMEOUT_MS 500 +# define UART_TCP_CLIENT_LOCAL_RX_TIMEOUT_MS 40 // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: