Subject: Re: Finding the correct interface for a packet
To: None <tech-net@netbsd.org>
From: Matthias Scheler <tron@lyssa.owl.de>
List: tech-net
Date: 12/07/1998 02:33:51
In article <199812020444.XAA06678@ginger.cmf.nrl.navy.mil>,
Ken Hornstein <kenh@cmf.nrl.navy.mil> writes:
> I just tried this, and it seems to work:
>
> - Create a UDP socket
> - bind() it to a local port
This step is unnecessary ...
> - connect() it to the "supplied IP address"
> - getsockname() on the socket
... but otherwise it works perfect. Here is the diff for "traceroute":
Index: traceroute.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/traceroute/traceroute.c,v
retrieving revision 1.25
diff -u -r1.25 traceroute.c
--- traceroute.c 1998/08/27 20:31:02 1.25
+++ traceroute.c 1998/12/07 02:31:58
@@ -730,9 +730,36 @@
*/
setsin(from, al->addr);
if (n > 1 && device == NULL) {
- Fprintf(stderr,
- "%s: Warning: Multiple interfaces found; using %s @ %s\n",
- prog, inet_ntoa(from->sin_addr), al->device);
+ int sock;
+ struct sockaddr_in help;
+ int help_len;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ Fprintf(stderr, "%s: udp socket: %s\n", prog, strerror(errno));
+ exit(1);
+ }
+ help.sin_family = AF_INET;
+ /*
+ * At this point the port number doesn't matter,
+ * it only has to be greater zero.
+ */
+ help.sin_port = 42;
+ help.sin_addr.s_addr = to->sin_addr.s_addr;
+ if (connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) {
+ Fprintf(stderr, "%s: connect: %s\n", prog, strerror(errno));
+ (void)close(sock);
+ exit(1);
+ }
+ help_len = sizeof(help);
+ if (getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 ||
+ help_len != sizeof(help)) {
+ Fprintf(stderr, "%s: getsockname: %s\n", prog, strerror(errno));
+ (void)close(sock);
+ exit(1);
+ }
+ setsin(from, help.sin_addr.s_addr);
+ (void)close(sock);
}
} else {
hi = gethostinfo(source);
That should fix PR bin/4427.
--
Matthias Scheler http://home.owl.de/~tron/