Merge pull request #2134 from wh201906/ipv6

Add IPv6 support
This commit is contained in:
Iceman 2023-10-17 14:50:39 +02:00 committed by GitHub
commit 748b0f0874
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 142 additions and 34 deletions

View file

@ -3,9 +3,10 @@ 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... 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] ## [unreleased][unreleased]
- Added IPv6 support (@wh201906)
- Fixed `lf hid clone --bin` - now correctly handles sentinel bits (@iceman1001) - Fixed `lf hid clone --bin` - now correctly handles sentinel bits (@iceman1001)
- Experimental UDP support in linux (@iceman1001, @wh201906) - Experimental UDP support in linux (@iceman1001, @wh201906)
- Changed CI scripts to speed up the builds (@wh201906) - Changed CI scripts to speed up the builds (@wh201906)
- Changed the timeout of local TCP connections (@wh201906) - Changed the timeout of local TCP connections (@wh201906)
- Finalized implementation of configcard generation for keyroll when cardhelper is not present (@Antiklesys) - Finalized implementation of configcard generation for keyroll when cardhelper is not present (@Antiklesys)
- Added documentation for compiling on iOS (@The-SamminAter) - Added documentation for compiling on iOS (@The-SamminAter)

View file

@ -682,7 +682,9 @@ int TestProxmark(pm3_device_t *dev) {
int res; int res;
if (is_tcp_conn || is_udp_conn) { if (is_tcp_conn || is_udp_conn) {
if ((strstr(g_conn.serial_port_name, "localhost") != NULL) || if ((strstr(g_conn.serial_port_name, "localhost") != NULL) ||
(strstr(g_conn.serial_port_name, "127.0.0.1") != NULL)) { (strstr(g_conn.serial_port_name, "127.0.0.1") != NULL) ||
(strstr(g_conn.serial_port_name, "[::1]") != NULL) ||
(strstr(g_conn.serial_port_name, "p:::1") != NULL)) {
res = uart_reconfigure_timeouts(UART_TCP_CLIENT_LOCAL_RX_TIMEOUT_MS); res = uart_reconfigure_timeouts(UART_TCP_CLIENT_LOCAL_RX_TIMEOUT_MS);
} else { } else {
res = uart_reconfigure_timeouts(UART_TCP_CLIENT_RX_TIMEOUT_MS); res = uart_reconfigure_timeouts(UART_TCP_CLIENT_RX_TIMEOUT_MS);

View file

@ -108,8 +108,10 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
struct addrinfo *addr = NULL, *rp; struct addrinfo *addr = NULL, *rp;
char *addrstr = strdup(pcPortName + 4); char *addrPortStr = strdup(pcPortName + 4);
if (addrstr == NULL) { char *addrstr = addrPortStr;
const char *portstr;
if (addrPortStr == NULL) {
PrintAndLogEx(ERR, "error: string duplication"); PrintAndLogEx(ERR, "error: string duplication");
free(sp); free(sp);
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
@ -117,26 +119,59 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000;
char *colon = strrchr(addrstr, ':'); // find the start of the address
const char *portstr; char *endBracket = strrchr(addrPortStr, ']');
if (colon) { if (addrPortStr[0] == '[') {
portstr = colon + 1; addrstr += 1;
*colon = '\0'; if (endBracket == NULL) {
} else { PrintAndLogEx(ERR, "error: wrong address: [] unmatched");
free(addrPortStr);
free(sp);
return INVALID_SERIAL_PORT;
}
}
// find the port
char *lColon = strchr(addrPortStr, ':');
char *rColon = strrchr(addrPortStr, ':');
if (rColon == NULL) {
// no colon
// "tcp:<ipv4 address>", "tcp:[<ipv4 address>]"
portstr = "18888"; portstr = "18888";
} else if (lColon == rColon) {
// only one colon
// "tcp:<ipv4 address>:<port>", "tcp:[<ipv4 address>]:<port>"
portstr = rColon + 1;
} else {
// two or more colon, IPv6 address
// tcp:[<ipv6 address>]:<port>
// "tcp:<ipv6 address>", "tcp:[<ipv6 address>]"
if (endBracket != NULL && rColon == endBracket + 1) {
portstr = rColon + 1;
} else {
portstr = "18888";
}
}
// handle the end of the address
if (endBracket != NULL) {
*endBracket = '\0';
} else if (rColon != NULL && lColon == rColon) {
*rColon = '\0';
} }
struct addrinfo info; struct addrinfo info;
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.ai_family = PF_UNSPEC;
info.ai_socktype = SOCK_STREAM; info.ai_socktype = SOCK_STREAM;
int s = getaddrinfo(addrstr, portstr, &info, &addr); int s = getaddrinfo(addrstr, portstr, &info, &addr);
if (s != 0) { if (s != 0) {
PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s)); PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s));
freeaddrinfo(addr); freeaddrinfo(addr);
free(addrstr); free(addrPortStr);
free(sp); free(sp);
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
} }
@ -155,7 +190,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
} }
freeaddrinfo(addr); freeaddrinfo(addr);
free(addrstr); free(addrPortStr);
if (rp == NULL) { /* No address succeeded */ if (rp == NULL) { /* No address succeeded */
PrintAndLogEx(ERR, "error: Could not connect"); PrintAndLogEx(ERR, "error: Could not connect");
@ -184,8 +219,10 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
struct addrinfo *addr = NULL, *rp; struct addrinfo *addr = NULL, *rp;
char *addrstr = strdup(pcPortName + 4); char *addrPortStr = strdup(pcPortName + 4);
if (addrstr == NULL) { char *addrstr = addrPortStr;
const char *portstr;
if (addrPortStr == NULL) {
PrintAndLogEx(ERR, "error: string duplication"); PrintAndLogEx(ERR, "error: string duplication");
free(sp); free(sp);
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
@ -193,20 +230,52 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000;
char *colon = strrchr(addrstr, ':'); // find the start of the address
const char *portstr; char *endBracket = strrchr(addrPortStr, ']');
if (colon) { if (addrPortStr[0] == '[') {
portstr = colon + 1; addrstr += 1;
*colon = '\0'; if (endBracket == NULL) {
} else { PrintAndLogEx(ERR, "error: wrong address: [] unmatched");
free(addrPortStr);
free(sp);
return INVALID_SERIAL_PORT;
}
}
// find the port
char *lColon = strchr(addrPortStr, ':');
char *rColon = strrchr(addrPortStr, ':');
if (rColon == NULL) {
// no colon
// "tcp:<ipv4 address>", "tcp:[<ipv4 address>]"
portstr = "18888"; portstr = "18888";
} else if (lColon == rColon) {
// only one colon
// "tcp:<ipv4 address>:<port>", "tcp:[<ipv4 address>]:<port>"
portstr = rColon + 1;
} else {
// two or more colon, IPv6 address
// tcp:[<ipv6 address>]:<port>
// "tcp:<ipv6 address>", "tcp:[<ipv6 address>]"
if (endBracket != NULL && rColon == endBracket + 1) {
portstr = rColon + 1;
} else {
portstr = "18888";
}
}
// handle the end of the address
if (endBracket != NULL) {
*endBracket = '\0';
} else if (rColon != NULL && lColon == rColon) {
*rColon = '\0';
} }
struct addrinfo info; struct addrinfo info;
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.ai_family = AF_INET; info.ai_family = PF_UNSPEC;
info.ai_socktype = SOCK_DGRAM; info.ai_socktype = SOCK_DGRAM;
// info.ai_protocol = SOL_UDP; // info.ai_protocol = SOL_UDP;
@ -214,7 +283,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
if (s != 0) { if (s != 0) {
PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s)); PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s));
freeaddrinfo(addr); freeaddrinfo(addr);
free(addrstr); free(addrPortStr);
free(sp); free(sp);
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
} }
@ -233,7 +302,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
} }
freeaddrinfo(addr); freeaddrinfo(addr);
free(addrstr); free(addrPortStr);
if (rp == NULL) { /* No address succeeded */ if (rp == NULL) { /* No address succeeded */
PrintAndLogEx(ERR, "error: Could not connect"); PrintAndLogEx(ERR, "error: Could not connect");

View file

@ -109,8 +109,10 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
struct addrinfo *addr = NULL, *rp; struct addrinfo *addr = NULL, *rp;
char *addrstr = strdup(pcPortName + 4); char *addrPortStr = strdup(pcPortName + 4);
if (addrstr == NULL) { char *addrstr = addrPortStr;
const char *portstr;
if (addrPortStr == NULL) {
PrintAndLogEx(ERR, "error: string duplication"); PrintAndLogEx(ERR, "error: string duplication");
free(sp); free(sp);
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
@ -118,13 +120,45 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000;
char *colon = strrchr(addrstr, ':'); // find the start of the address
const char *portstr; char *endBracket = strrchr(addrPortStr, ']');
if (colon) { if (addrPortStr[0] == '[') {
portstr = colon + 1; addrstr += 1;
*colon = '\0'; if (endBracket == NULL) {
} else { PrintAndLogEx(ERR, "error: wrong address: [] unmatched");
free(addrPortStr);
free(sp);
return INVALID_SERIAL_PORT;
}
}
// find the port
char *lColon = strchr(addrPortStr, ':');
char *rColon = strrchr(addrPortStr, ':');
if (rColon == NULL) {
// no colon
// "tcp:<ipv4 address>", "tcp:[<ipv4 address>]"
portstr = "18888"; portstr = "18888";
} else if (lColon == rColon) {
// only one colon
// "tcp:<ipv4 address>:<port>", "tcp:[<ipv4 address>]:<port>"
portstr = rColon + 1;
} else {
// two or more colon, IPv6 address
// tcp:[<ipv6 address>]:<port>
// "tcp:<ipv6 address>", "tcp:[<ipv6 address>]"
if (endBracket != NULL && rColon == endBracket + 1) {
portstr = rColon + 1;
} else {
portstr = "18888";
}
}
// handle the end of the address
if (endBracket != NULL) {
*endBracket = '\0';
} else if (rColon != NULL && lColon == rColon) {
*rColon = '\0';
} }
WSADATA wsaData; WSADATA wsaData;
@ -134,19 +168,21 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) { if (iResult != 0) {
PrintAndLogEx(ERR, "error: WSAStartup failed with error: %d", iResult); PrintAndLogEx(ERR, "error: WSAStartup failed with error: %d", iResult);
free(addrPortStr);
free(sp); free(sp);
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
} }
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.ai_family = AF_UNSPEC;
info.ai_socktype = SOCK_STREAM; info.ai_socktype = SOCK_STREAM;
info.ai_protocol = IPPROTO_TCP; info.ai_protocol = IPPROTO_TCP;
int s = getaddrinfo(addrstr, portstr, &info, &addr); int s = getaddrinfo(addrstr, portstr, &info, &addr);
if (s != 0) { if (s != 0) {
PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s)); PrintAndLogEx(ERR, "error: getaddrinfo: %d: %s", s, gai_strerror(s));
freeaddrinfo(addr); freeaddrinfo(addr);
free(addrstr); free(addrPortStr);
free(sp); free(sp);
WSACleanup(); WSACleanup();
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
@ -167,7 +203,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
} }
freeaddrinfo(addr); freeaddrinfo(addr);
free(addrstr); free(addrPortStr);
if (rp == NULL) { /* No address succeeded */ if (rp == NULL) { /* No address succeeded */
PrintAndLogEx(ERR, "error: Could not connect"); PrintAndLogEx(ERR, "error: Could not connect");