// Initially based on https://stackoverflow.com/a/35570418 #include #include #include #include #include #include #include #include static inline bool IsDigit(char c) { return c >= '0' && c <= '9'; } static unsigned ParseAddress(char const *str, FILE *log_stream) { unsigned addr = 0, byte_counter = 0, byte = 0, digits_counter = 0; for (size_t i = 0;; i++) { char const c = str[i]; if (c == '\0') { if (byte_counter != 3) { fprintf(log_stream, "Invalid address specified: %u bytes of 4 expected are specified\n", byte_counter + 1); return INADDR_NONE; } if (digits_counter == 0) { fprintf(log_stream, "Invalid address specified: no digits on byte %u\n", byte_counter + 1); return INADDR_NONE; } addr |= byte << (8 * (3 - byte_counter)); break; } else if (IsDigit(c)) { digits_counter++; if (digits_counter > 3) { fprintf(log_stream, "Invalid address specified: too many digits for byte %u\n", byte_counter + 1); return INADDR_NONE; } byte = byte * 10 + (c - '0'); if (byte > UINT8_MAX) { fprintf(log_stream, "Invalid address specified: too big number for byte %u\n", byte_counter + 1); return INADDR_NONE; } } else if (c == '.') { if (digits_counter == 0) { fprintf(log_stream, "Invalid address specified: no digits on byte %u\n", byte_counter + 1); return INADDR_NONE; } digits_counter = 0; addr |= byte << (8 * (3 - byte_counter)); byte = 0; byte_counter++; if (byte_counter > 3) { fprintf(log_stream, "Invalid address specified: unexpected dot after 4th byte\n"); return INADDR_NONE; } } else { fprintf(log_stream, "Invalid address specified: char '%c' (0x%02x) is not allowed\n", c, c); return INADDR_NONE; } } if (addr == INADDR_NONE) { fprintf(log_stream, "Invalid address specified\n"); } return addr; } int main(int const argc, char *const argv[]) { if (argc < 3) { fprintf(stderr, "Usage: %s
\n", argv[0]); return 1; } unsigned const addr = ParseAddress(argv[1], stderr); if (addr == INADDR_NONE) { return 1; } int const port = atoi(argv[2]); if (port <= 0 || port > UINT16_MAX) { fprintf(stderr, "Invalid port specifed\n"); return 1; } int const fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { perror("socket failed"); return 1; } struct sockaddr_in const serveraddr = { .sin_family = AF_INET, .sin_port = htons(port), .sin_addr.s_addr = htonl(addr), }; for (int i = 0; i < 4; i++) { ssize_t const ret = sendto( fd, "hello", 5, 0, (struct sockaddr const *)&serveraddr, sizeof(serveraddr)); if (ret < 0) { perror("sendto failed"); break; } printf("message sent\n"); } close(fd); }