Last active
April 7, 2023 14:36
-
-
Save ammarfaizi2/46b75128141b9f31e67bf1ee0d2807f3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <errno.h> | |
#include <stdlib.h> | |
#include <arpa/inet.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <string.h> | |
static int str_to_sockaddr(struct sockaddr_storage *ss, const char *addr, | |
const char *port) | |
{ | |
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss; | |
struct sockaddr_in *sin = (struct sockaddr_in *)ss; | |
int ret; | |
memset(ss, 0, sizeof(*ss)); | |
ret = inet_pton(AF_INET6, addr, &sin6->sin6_addr); | |
if (ret == 1) { | |
sin6->sin6_family = AF_INET6; | |
sin6->sin6_port = htons(atoi(port)); | |
return 0; | |
} | |
ret = inet_pton(AF_INET, addr, &sin->sin_addr); | |
if (ret == 1) { | |
sin->sin_family = AF_INET; | |
sin->sin_port = htons(atoi(port)); | |
return 0; | |
} | |
return -EINVAL; | |
} | |
static void str_to_sockaddr_ipv4_mp6(struct sockaddr_storage *ss, | |
const char *addr, const char *port) | |
{ | |
char tmp[INET6_ADDRSTRLEN]; | |
snprintf(tmp, sizeof(tmp), "::ffff:%s", addr); | |
str_to_sockaddr(ss, tmp, port); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
struct sockaddr_storage src, dst; | |
int fd, err; | |
ssize_t ret; | |
if (argc != 5) { | |
fprintf(stderr, "Usage: %s [iface] [src] [dst] [dport]\n", argv[0]); | |
return 1; | |
} | |
err = str_to_sockaddr(&src, argv[2], "0"); | |
if (err < 0) { | |
fprintf(stderr, "Invalid source address: %s\n", argv[2]); | |
return 1; | |
} | |
err = str_to_sockaddr(&dst, argv[3], argv[4]); | |
if (err < 0) { | |
fprintf(stderr, "Invalid destination address: %s\n", argv[3]); | |
return 1; | |
} | |
if (src.ss_family != dst.ss_family) { | |
if (src.ss_family == AF_INET) | |
str_to_sockaddr_ipv4_mp6(&src, argv[2], "0"); | |
else | |
str_to_sockaddr_ipv4_mp6(&dst, argv[3], argv[4]); | |
} | |
fd = socket(src.ss_family, SOCK_DGRAM, 0); | |
if (fd < 0) { | |
perror("socket"); | |
return 1; | |
} | |
err = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, argv[1], strlen(argv[1])); | |
if (err < 0) { | |
perror("setsockopt"); | |
close(fd); | |
return 1; | |
} | |
err = bind(fd, (struct sockaddr *)&src, sizeof(src)); | |
if (err < 0) { | |
perror("bind"); | |
close(fd); | |
return 1; | |
} | |
repeat: | |
ret = sendto(fd, "Test", 5, 0, (struct sockaddr *)&dst, sizeof(dst)); | |
if (ret < 0) { | |
perror("sendto"); | |
close(fd); | |
return 1; | |
} | |
printf("Sent %zd bytes\n", ret); | |
sleep(1); | |
goto repeat; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment