Add hints for sendto() errors

This commit is contained in:
Joseph C. Lehner 2025-03-13 10:58:33 +01:00
parent 924ff34d1b
commit a27b7462a5
3 changed files with 14 additions and 2 deletions

5
main.c
View file

@ -331,6 +331,11 @@ int main(int argc, char **argv)
"- Unsupported router\n" "- Unsupported router\n"
"- Wrong Ethernet port - try others if there's more than one\n" "- Wrong Ethernet port - try others if there's more than one\n"
"- Try holding reset button for a few seconds while powering on router\n"); "- Try holding reset button for a few seconds while powering on router\n");
} else if (args.hints & NMRP_TFTP_XMIT_BLK0_FAILURE) {
fprintf(stderr,
"Failed to send/receive initial TFTP packet. Possible fixes:\n"
"- Disable firewall, or add an exception for nmrpflash\n"
"- Manually specify IP addresses using `-a` and/or `-A`");
} }
} }
} }

View file

@ -90,6 +90,7 @@
#define NMRP_MAYBE_FIRMWARE_INVALID (1 << 0) #define NMRP_MAYBE_FIRMWARE_INVALID (1 << 0)
#define NMRP_NO_ETHERNET_CONNECTION (1 << 1) #define NMRP_NO_ETHERNET_CONNECTION (1 << 1)
#define NMRP_NO_NMRP_RESPONSE (1 << 2) #define NMRP_NO_NMRP_RESPONSE (1 << 2)
#define NMRP_TFTP_XMIT_BLK0_FAILURE (1 << 3)
struct eth_hdr { struct eth_hdr {
uint8_t ether_dhost[6]; uint8_t ether_dhost[6];

10
tftp.c
View file

@ -240,13 +240,15 @@ static ssize_t tftp_recvfrom(int sock, char *pkt, uint16_t* port,
} }
static ssize_t tftp_sendto(int sock, char *pkt, size_t len, static ssize_t tftp_sendto(int sock, char *pkt, size_t len,
struct sockaddr_in *dst) struct sockaddr_in *dst, struct nmrpd_args* args)
{ {
ssize_t sent; ssize_t sent;
bool is_xrq = false;
switch (pkt_num(pkt)) { switch (pkt_num(pkt)) {
case RRQ: case RRQ:
case WRQ: case WRQ:
is_xrq = true;
case OACK: case OACK:
len = pkt_xrqlen(pkt); len = pkt_xrqlen(pkt);
break; break;
@ -275,6 +277,9 @@ static ssize_t tftp_sendto(int sock, char *pkt, size_t len,
#ifndef NMRPFLASH_FUZZ #ifndef NMRPFLASH_FUZZ
sent = sendto(sock, pkt, len, 0, (struct sockaddr*)dst, sizeof(*dst)); sent = sendto(sock, pkt, len, 0, (struct sockaddr*)dst, sizeof(*dst));
if (sent < 0) { if (sent < 0) {
if (is_xrq) {
args->hints |= NMRP_TFTP_XMIT_BLK0_FAILURE;
}
sock_perror("sendto"); sock_perror("sendto");
} }
#else #else
@ -489,7 +494,7 @@ ssize_t tftp_put(struct nmrpd_args *args)
bytes += len; bytes += len;
} }
ret = tftp_sendto(sock, tx, len, &addr); ret = tftp_sendto(sock, tx, len, &addr, args);
if (ret < 0) { if (ret < 0) {
goto cleanup; goto cleanup;
} }
@ -530,6 +535,7 @@ ssize_t tftp_put(struct nmrpd_args *args)
fprintf(stderr, "Timeout while waiting for ACK(%d).\n", block); fprintf(stderr, "Timeout while waiting for ACK(%d).\n", block);
} else { } else {
fprintf(stderr, "Timeout while waiting for ACK(0)/OACK.\n"); fprintf(stderr, "Timeout while waiting for ACK(0)/OACK.\n");
args->hints |= NMRP_TFTP_XMIT_BLK0_FAILURE;
} }
ret = -1; ret = -1;
goto cleanup; goto cleanup;