UDP bug?

H.J. Lu (hjl@lucon.org)
Mon, 13 Apr 1998 09:29:41 -0700 (PDT)


Hi, This is what I got. Is that a bug?

Thanks.

H.J.
-----
Anyway, I have something I'd like you to look at. The program below
is giving me unexpected ``connection refused'' errors under Linux at
seemingly random times after both the `sendto' and the `recvfrom' calls.
I think this may be a kernl bug, but I'd like your opinion on it.

I'm running kernel 2.0.33.

I am not gettiing these errors when I run the program on FreeBSD.

cut
-------------------------------------------------------------------------
/* yaups.c - Yet Another UDP port scanner. Checks for open UDP ports
which actually send back responses.

Typically, the only ports that you will see sending back responses
are:

7 echo
13 daytime
19 chargen
37 time
42 name
53 domain
*/

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <netdb.h>

enum { starting_port = 1, ending_port = 10080 };

static char const *pname;
enum { ports = 1 << 16 };
static char port_responded[ports];
static int timeout = 7;

static void
usage (void)
{
fprintf (stderr, "%s: usage `%s hostname|address'\n", pname, pname);
exit (1);
}

static void
alarm_handler (register int signo)
{
exit (0);
}

int
main (register int const argc, register char *const argv[])
{
register int sock;
register unsigned port;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
unsigned long ip_address;
register struct hostent *hp;

pname = strrchr (argv[0], '/');
pname = pname ? pname+1 : argv[0];

if (argc != 2)
usage ();

if ((ip_address = inet_addr (argv[1])) == -1)
{
if ((hp = gethostbyname (argv[1])) == NULL)
{
fprintf (stderr, "%s: Invalid host name: %s\n", pname, argv[1]);
return 1;
}
memcpy (&ip_address, hp->h_addr, sizeof ip_address);
}

if((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
fprintf (stderr, "%s: Error opening output socket: %s\n",
pname, strerror (errno));
return 1;
}

memset (&server_addr, '\0', sizeof server_addr);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = ip_address;

memset (&client_addr, '\0', sizeof client_addr);
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = htonl (INADDR_ANY);
client_addr.sin_port = htons (0);

if (bind (sock, (struct sockaddr *) &client_addr, sizeof client_addr) == -1)
{
fprintf (stderr, "%s: Error binding socket: %s\n",
pname, strerror (errno));
return 1;
}

for (port = starting_port; port <= ending_port; port++)
{
static char const msg[] = "Hello world!\n";
enum { msg_len = sizeof msg - 1 };
server_addr.sin_port = htons (port);

if (sendto (sock, msg, msg_len, 0,
(struct sockaddr *) &server_addr, sizeof server_addr) == -1)
{
fprintf (stderr, "%s: Error in sendto for port %d: %s\n",
pname, port, strerror (errno));
return 1;
}
usleep (100);
}

signal (SIGALRM, alarm_handler);
alarm (timeout);

for (;;)
{
enum { in_buf_len = 4096 };
char in_buf[in_buf_len];
struct sockaddr_in sender;
int sender_len = sizeof sender;
register unsigned short port;

if (recvfrom (sock, in_buf, in_buf_len, 0,
(struct sockaddr *) &sender, &sender_len) == -1)
{
fprintf (stderr, "%s: Error in recvfrom: %s\n",
pname, strerror (errno));
return 1;
}
port = ntohs (sender.sin_port);
if (!port_responded[port])
{
printf ("Port %d responded\n", port);
port_responded[port] = 1;
}
}

return 0;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu