Skip to content

Instantly share code, notes, and snippets.

@ammarfaizi2
Last active April 7, 2023 14:36
Show Gist options
  • Save ammarfaizi2/46b75128141b9f31e67bf1ee0d2807f3 to your computer and use it in GitHub Desktop.
Save ammarfaizi2/46b75128141b9f31e67bf1ee0d2807f3 to your computer and use it in GitHub Desktop.
#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