Added support for L3, non-ethernet interfaces#70
Added support for L3, non-ethernet interfaces#70danielinux wants to merge 3 commits intowolfSSL:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| int err; | ||
| struct sockaddr_in remote_sock = { | ||
| .sin_family = AF_INET, | ||
| .sin_port = ntohs(8), /* Echo */ |
There was a problem hiding this comment.
sin_port must be set in network byte order using htons(), not ntohs(). Using ntohs(8) will bind/connect to the wrong port on little-endian hosts (commonly 2048 instead of 8). Apply the same fix to the server-side socket address initialization in this file as well.
| .sin_port = ntohs(8), /* Echo */ | |
| .sin_port = htons(8), /* Echo */ |
| uint8_t local_buf[BUFFER_SIZE]; | ||
| struct sockaddr_in local_sock = { | ||
| .sin_family = AF_INET, | ||
| .sin_port = ntohs(8), /* Echo */ |
There was a problem hiding this comment.
Same issue as the client: sin_port must use htons(8) (network byte order). With ntohs(8) the server may listen on the wrong port depending on endianness.
| .sin_port = ntohs(8), /* Echo */ | |
| .sin_port = htons(8), /* Echo */ |
| printf("test client: pattern mismatch\n"); | ||
| printf("at position %u\n", i); | ||
| buf[i + 16] = 0; | ||
| printf("%s\n", &buf[i]); |
There was a problem hiding this comment.
buf[i + 16] = 0; writes out of bounds when i is the last chunk (e.g., i == sizeof(buf) - 16, then i + 16 == sizeof(buf)). Use a bounded print strategy (e.g., print a fixed-length slice) or null-terminate via a separate temporary buffer sized sizeof(test_pattern)+1.
| printf("test client: pattern mismatch\n"); | |
| printf("at position %u\n", i); | |
| buf[i + 16] = 0; | |
| printf("%s\n", &buf[i]); | |
| char tmp[sizeof(test_pattern) + 1]; | |
| printf("test client: pattern mismatch\n"); | |
| printf("at position %u\n", i); | |
| memcpy(tmp, buf + i, sizeof(test_pattern)); | |
| tmp[sizeof(test_pattern)] = '\0'; | |
| printf("%s\n", tmp); |
| for (i = 0; i < sizeof(local_buf); i += sizeof(test_pattern)) { | ||
| if (memcmp(local_buf + i, test_pattern, sizeof(test_pattern))) { | ||
| printf("test client: pattern mismatch\n"); | ||
| printf("at position %u\n", i); | ||
| local_buf[i + 16] = 0; | ||
| printf("%s\n", &local_buf[i]); | ||
| return (void *)-1; |
There was a problem hiding this comment.
Same out-of-bounds write pattern as in client_cb: local_buf[i + 16] = 0; can write one byte past the end of the buffer for the last iteration. Prefer printing with an explicit length or copying into a small temporary, null-terminated buffer.
| if (ioctl(sock_fd, SIOCSIFADDR, &ifr) < 0) { | ||
| perror("ioctl SIOCSIFADDR"); | ||
| close(sock_fd); | ||
| return -1; | ||
| } |
There was a problem hiding this comment.
On these error paths, tun_fd is left open (and tun_fd is not reset), leaking the TUN device file descriptor. The same pattern repeats for later ioctl() failures (DSTADDR/NETMASK). Close tun_fd and set it back to -1 before returning to keep resource handling consistent with earlier failure handling.
| static int tun_add_host_route(const char *ifname, uint32_t peer_ip) | ||
| { | ||
| char peer_str[INET_ADDRSTRLEN]; | ||
| char cmd[256]; | ||
| struct in_addr peer = { .s_addr = peer_ip }; | ||
| if (!inet_ntop(AF_INET, &peer, peer_str, sizeof(peer_str))) | ||
| return -1; | ||
| snprintf(cmd, sizeof(cmd), "ip route replace %s/32 dev %s >/dev/null 2>&1", | ||
| peer_str, ifname); | ||
| if (system(cmd) == 0) | ||
| return 0; | ||
| snprintf(cmd, sizeof(cmd), "route add -host %s dev %s >/dev/null 2>&1", | ||
| peer_str, ifname); | ||
| return (system(cmd) == 0) ? 0 : -1; | ||
| } |
There was a problem hiding this comment.
Building shell commands with system() is vulnerable to command injection if ifname is not strictly controlled, and it also depends on external binaries and shell behavior. Prefer configuring routes via netlink (recommended on Linux) or a non-shell execution path (e.g., execve with fixed argv), and at minimum validate ifname against a strict allowlist of interface-name characters before composing commands.
Added the possibility to bind new network interfaces with
non_ethernet=1extra field, that skip L2 addressing and communicate solely via IP packets.Added new posix port interface
linux_tun.c, equivalent to tap, but point-to-point. Added functional test (evloop) using the tun device to demonstrate L3 interfaces.Added unit tests (case: forwarding between interfaces of mixed types).