Project

General

Profile

Bug #13966 ยป test.c

Jason King, 2021-07-26 05:01 PM

 
1
#include <sys/types.h>
2
#include <sys/socket.h>
3
#include <netinet/in.h>
4
#include <arpa/inet.h>
5
#include <limits.h>
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
#include <errno.h>
10
#include <err.h>
11
#include <netdb.h>
12
#include <unistd.h>
13

    
14
static uint_t
15
parse_int(const char *str, uint_t max)
16
{
17
	unsigned long val;
18

    
19
	errno = 0;
20
	val = strtoul(str, NULL, 10);
21
	if (errno != 0)
22
		err(EXIT_FAILURE, "invalid number '%s'", str);
23
	if (val > max)
24
		errx(EXIT_FAILURE, "value '%s' is too large", str);
25

    
26
	return ((uint_t)val);
27
}
28

    
29
static void
30
parse_ip(const char *str, struct sockaddr_in *sin)
31
{
32
	int ret;
33

    
34
	if (inet_aton(str, &sin->sin_addr) == 0)
35
		errx(EXIT_FAILURE, "invalid IP '%s'", str);
36
}
37

    
38
static inline const struct sockaddr *
39
from_sin(struct sockaddr_in *s)
40
{
41
	return ((const struct sockaddr *)s);
42
}
43

    
44
int
45
main(int argc, char **argv)
46
{
47
	char *hostname = NULL;
48
	uint16_t port = 0;
49
	uint_t ifindex = 0;
50
	int s;
51
	struct sockaddr_in src = { .sin_family = AF_INET };
52
	struct sockaddr_in dst = { .sin_family = AF_INET };
53
	const char *srcstr = NULL;
54
	const char *dststr = NULL;
55

    
56
	if (argc < 5) {
57
		fprintf(stderr, "Usage: %s srcip dstip dstport ifindex\n",
58
		    argv[0]);
59
		return (2);
60
	}
61

    
62
	parse_ip(argv[1], &src);
63
	srcstr = argv[1];
64

    
65
	parse_ip(argv[2], &dst);
66
	dststr = argv[2];
67
	dst.sin_port = htons(parse_int(argv[3], UINT16_MAX));
68

    
69
	ifindex = parse_int(argv[4], INT_MAX);
70

    
71
	s = socket(PF_INET, SOCK_STREAM, 0);
72
	if (s < 0)
73
		err(EXIT_FAILURE, "socket");
74

    
75
	if (bind(s, from_sin(&src), sizeof (src)) < 0)
76
		err(EXIT_FAILURE, "bind");
77

    
78
	if (setsockopt(s, IPPROTO_IP, IP_BOUND_IF, &ifindex,
79
	    sizeof (ifindex)) < 0) {
80
		err(EXIT_FAILURE, "setsockopt");
81
	}
82

    
83
	printf("Connecting %s:%u -> %s:%u\n",
84
	    srcstr, ntohs(src.sin_port), dststr, ntohs(dst.sin_port));
85

    
86
	if (connect(s, from_sin(&dst), sizeof (dst)) < 0)
87
		err(EXIT_FAILURE, "connect");
88

    
89
	printf("connected\n");
90
	/*
91
	 * We're a TCP socket and we connected, therefore we've sent
92
	 * packets over the wire at this point. that's good enough.
93
	 */
94
	(void) close(s);
95

    
96
	return (0);
97
}
    (1-1/1)