Source of the Programs (Using the /dev/poll Interface)
A. udpdevpoll.c
/*
* This is a simple UDP based server that accepts
packets on the
* ports it is configured. The program takes two arguments.
*
* The first argument points to a file that specifies
the IP address
* of the Server (itself) and the ports on which the
program should
* listen for incoming packets.
*
* Please note that you may use the ports between
32768 and 65535
* for this test. Some of the ports below 32768 may
be in use by some
* registered softwares and thus the test case may
fail in that case.
*
* The second argument specifies the timeout value
in milliseconds
* that has to be supplied to the devpoll driver.
*
* To Compile : $cc -o <target name> <source
file name>.c -lsocket
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <netinet/in.h>
#include <sys/devpoll.h>
/*
* Misc. defs.
*/
#define NMSG
8 /* Number of Messages
to scan */
#define STRLENG
32 /* length for IP/port
string */
#define MAXSOCKS
30000 /* max. number of sockets allowed */
/*
* Globals.
*/
struct sockaddr_in svradr[MAXSOCKS];/* sockets used
to xmit */
struct pollfd fds[MAXSOCKS];
/* poll structs for sockets */
struct sockstr {
/* copy of socket's IP adr. info. */
char ipstr[STRLENG];
/* IP/port string defined in file */
} socktxt[MAXSOCKS];
int dstcnt[MAXSOCKS];
/* per socket recv. stats. */
extern int errno;
/*
* print_ip_info();
*
* Prints msg., IP adr, and port.
*/
void print_ip_info(char *msg, struct sockaddr_in *sa)
{
int a, b, c, d;
a = b = c = d = sa->sin_addr.s_addr;
a &= 0xff;
b = (b >> 8) & 0xff;
c = (c >> 16) & 0xff;
d = (d >> 24) & 0xff;
printf("%s ip: %d.%d.%d.%d port:
%d\n", msg,d,c,b,a,sa->sin_port);
return;
}
main(int argc, char *argv[])
{
int i, j, fdcnt, adrleng, msgleng;
int nsocks, nmsgs;
int result, wfd, delay, tfd;
int pktcnt = 0;
int oldpktcnt = 0;
int gran = 10000;
int thresh = gran;
dvpoll_t dopoll;
FILE *fp;
char buf[1024];
/*
* Check usage.
*/
if (argc != 3) {
printf("usage:
udpsa sockfile delay \n");
exit(-1);
}
/*
* Get the delay for
poll().
*/
delay = atoi(argv[2]);
/*
* Open the receiver
sockets.
*/
if ((nsocks = init_socks(argv[1]))
== -1) {
perror("init_socks");
exit(-1);
}
/*
* Receive loop.
*/
/*
* Populate the dvpoll
structure
*/
dopoll.dp_timeout = delay;
dopoll.dp_nfds = MAXSOCKS;
dopoll.dp_fds = (struct
pollfd *)
malloc(sizeof(struct pollfd)*MAXSOCKS);
if (!dopoll.dp_fds)
{
perror("Failed
in dopoll.dp_fds" );
exit(-1);
}
while(1) {
/*
* open the devpoll driver
*/
close(wfd);
if ((wfd = open("/dev/poll", O_RDWR)) < 0) {
perror("cannot open /dev/poll");
exit(-1);
}
if (write(wfd, &fds[0],
sizeof(struct pollfd) * MAXSOCKS) !=
sizeof(struct pollfd) * MAXSOCKS) {
perror("failed to write all pollfds");
close (wfd);
exit(-1);
}
/*
* read from the devpoll driver
*/
result = ioctl(wfd, DP_POLL, &dopoll);
if (result < 0) {
perror("/dev/poll ioctl DP_POLL failed");
close (wfd);
exit(-1);
}
for (i = 1; i < result; i ++) {
/*
* Try to read up to nmsgs.
*/
tfd = dopoll.dp_fds[i].fd;
for (j=0; j < NMSG; j++) {
adrleng = sizeof(struct sockaddr_in);
/*
* Process incoming messages
*/
if (dopoll.dp_fds[i].revents & POLLIN) {
if ((msgleng = recvfrom(tfd, buf, 256, 0,
(struct sockaddr *) &svradr, &adrleng))== -1){
if (errno == EWOULDBLOCK) {
break;
}
else {
perror("recvfrom failed");
exit(-1);
}
}
if (msgleng == 0) {
break;
}
}
}
/*
* Accumulate aggregate packet count.
*/
pktcnt += j;
/*
* Make a log file entry if required.
*/
if (pktcnt > thresh) {
thresh += gran;
printf("aggregate packet count: %d \n", pktcnt);
oldpktcnt = pktcnt;
}
}
}
}
/*
* init_socks();
*
* Initialize the socket table to reflect
the configuration
* specified in the given file.
*
* Returns:
*
* On Success: The number of sockets specified.
* On failure: -1
*/
int init_socks(char *filename) {
FILE *fp;
int i, n, ip, t1, t2, t3, port;
char tmp[STRLENG];
/*
* Open the configuration
file.
*/
if (!(fp = fopen(filename, "r")))
{
return
-1;
}
/*
* Read an entry from
the configuration file.
*/
for (n=0; (int) fgets(tmp, STRLENG,
fp); n++) {
/*
* Copy the string for more efficient printing.
*/
strncpy((char
*) socktxt[n].ipstr, (char *) &tmp, STRLENG);
/*
* Convert delimiters to spaces.
*/
for (i=0;
tmp[i]; i++) {
if (tmp[i] == '.') {
tmp[i] = ' ';
}
}
/*tmp[i-1]
= NULL;*/
/*
* Parse out the IP address components and port.
*/
sscanf(tmp,
"%d %d %d %d %d", &ip, &t1, &t2, &t3, &port);
/*
* Construct the IP address.
*/
ip &=
0xff;
ip <<=
8;
ip |=
(t1 & 0xff);
ip <<=
8;
ip |=
(t2 & 0xff);
ip <<=
8;
ip |=
(t3 & 0xff);
/*
* Create the socket.
*/
if ((fds[n].fd
= socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
return -1;
}
/*
* Initialize addr.
*/
memset((char
*) &svradr[n], 0, sizeof(struct sockaddr_in));
svradr[n].sin_family
= AF_INET;
svradr[n].sin_addr.s_addr
= htons(ip);
svradr[n].sin_port
= htons(port);
print_ip_info("sv",
&svradr[n]);
/*
* Bind socket to addr.
*/
if (bind(fds[n].fd,
(struct sockaddr *) &svradr[n],
sizeof(struct sockaddr_in)) == -1) {
return -1;
}
/*
* Set socket to non-blocking.
*/
if (fcntl(fds[n].fd,
F_SETFL, O_NONBLOCK) == -1) {
return -1;
}
/*
* Initialize the pollfd struct, and the per socket packet count.
*/
fds[n].events
= POLLIN;
fds[n].revents
= 0;
dstcnt[n]
= 0;
}
fclose(fp);
return n;
}
B. udpclnt.c
/*
* This is a simple UDP based client code that generates
1K byte
* packets. The program takes two arguments.
*
* The first argument should point to a file that
has the IP
* address and the port on the client system which
should be
* used to send the data.
*
* The second argument should point to a file containing
a list
* of IP Addresses and port numbers of the system
running the
* server program to which the client should send
the data.
*
* The format of both these files should be as mentioned
below.
* <ip address> <portnumber>
*
* To compile: $cc -o <target name> <source
file name>.c -lsocket
*/
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <netinet/in.h>
#define STRLENG
32 /* length for IP/port string */
#define MAXSOCKS 30000
/* max. number of sockets allowed */
#define NMSG
8 /* max. number of messages per socket
*/
/*
* Globals.
*/
struct sockaddr_in claddr[MAXSOCKS];/* sockets used
to xmit */
struct sockaddr_in svaddr[MAXSOCKS];/* destination
adresses */
struct sockstr {
/* copy of IP adr. info. */
char ipstr[STRLENG];
/* string as defined in file */
} socktxt[MAXSOCKS];
int socktab[MAXSOCKS];
/* sockets array */
extern int errno;
/*
* print_ip_info();
*
* Prints msg., IP adr, and port.
*/
void print_ip_info(char *msg, struct sockaddr_in *sa)
{
int a, b, c, d;
a = b = c = d = sa->sin_addr.s_addr;
a &= 0xff;
b = (b >> 8) & 0xff;
c = (c >> 16) & 0xff;
d = (d >> 24) & 0xff;
printf("%s ip: %d.%d.%d.%d port:
%d\n",
msg,d,c,b,a,sa->sin_port);
return;
}
main(int argc, char *argv[])
{
int i, j, k, pktcnt, nadrs, nsocks;
int nmsgs=NMSG;
int gran = 10000;
int thresh = gran;
FILE *fp;
char buf[1024];
/*
* Check usage.
*/
if (argc != 3) {
printf("usage:
udpclnt sockfile destfile \n");
exit(-1);
}
/*
* Configure the destination
addresses.
*/
if ((nadrs = init_adrs(argv[2]))
== -1) {
perror("init_adrs
failed");
exit(-1);
}
/*
* Configure the sockets.
*/
if ((nsocks = init_socks(argv[1]))
== -1) {
perror("init_socks
failed");
exit(-1);
}
/*
* Keep counting the messages sent out forever
*/
for (k=0,pktcnt=0;
1; ) {
/*
* Send messages to all the sockets in the
* configuration file
*/
for (i=0; i < nsocks ; i++) {
/*
* Send NMSG number of messages to
* each socket
*/
for (j=nmsgs; j--; ) {
if (sendto(socktab[i], buf, 256, 0,
(struct sockaddr *) &svaddr[k],
sizeof(struct sockaddr_in)) == -1) {
perror("sendto failed");
exit(-1);
}
}
/*
* Accumulate aggregate packet count.
*/
pktcnt += nmsgs;
/*
* Get next dest. adr. to xmit to.
*/
if (k == nadrs-1) {
k = 0;
}
else {
k++;
}
/*
* Make a log file entry if required.
*/
if (pktcnt > thresh) {
thresh += gran;
printf("aggregate packet count: %d\n", pktcnt);
}
}
poll(NULL,NULL,1); /* Just a breather before the next
* set of packets
*/
}
}
/*
* init_socks();
*
* Initialize the socket table to reflect
the configuration
* specified in the given file.
*
* Returns:
*
* On Success: The number of sockets specified.
* On failure: -1
*/
int init_socks(char *filename) {
FILE *fp;
int i, n, ip, t1, t2, t3, port;
char tmp[STRLENG];
/*
* Open the configuration
file.
*/
if (!(fp = fopen(filename, "r")))
{
return
-1;
}
/*
* Read an entry from
the configuration file.
*/
for (n=0; (int) fgets(tmp, STRLENG,
fp); n++) {
/*
* Convert delimiters to spaces.
*/
for (i=0;
tmp[i]; i++) {
if (tmp[i] == '.') {
tmp[i] = ' ';
}
}
/*
* Parse out the IP address components and port.
*/
sscanf(tmp,
"%d %d %d %d %d", &ip, &t1, &t2, &t3, &port);
/*
* Construct the IP address.
*/
ip &=
0xff;
ip <<=
8;
ip |=
(t1 & 0xff);
ip <<=
8;
ip |=
(t2 & 0xff);
ip <<=
8;
ip |=
(t3 & 0xff);
/*
* Create the socket.
*/
if ((socktab[n]
= socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
return -1;
}
/*
* Initialize client addr.
*/
memset((char
*) &claddr[n], 0, sizeof(struct sockaddr_in));
claddr[n].sin_family
= AF_INET;
claddr[n].sin_addr.s_addr
= htons(ip);
claddr[n].sin_port
= htons(port);
print_ip_info("cl",
&claddr[n]);
/*
* Bind socket to client addr.
*/
if (bind(socktab[n],
(struct sockaddr *) &claddr[n],
sizeof(struct sockaddr_in)) == -1) {
return -1;
}
}
return n;
}
/*
* init_adrs();
*
* Initialize the destination adress table
to reflect the
* configuration specified in the given
file.
*
* Returns:
*
* On Success: The number of destinations
specified.
* On failure: -1
*/
int init_adrs(char *filename) {
FILE *fp;
int i, n, ip, t1, t2, t3, port;
char tmp[STRLENG];
/*
* Open the file.
*/
if (!(fp = fopen(filename, "r")))
{
return
-1;
}
/*
* Read an entry from
the configuration file.
*/
for (n=0; fgets(tmp, STRLENG,
fp); n++) {
/*
* Copy the string for more efficient printing.
*/
strncpy((char
*) socktxt[n].ipstr, (char *) &tmp, STRLENG);
/*
* Convert delimiters to spaces.
*/
for (i=0;
tmp[i]; i++) {
if (tmp[i] == '.') {
tmp[i] = ' ';
}
}
/*tmp[i-1]
= NULL;*/
/*
* Parse out the IP address components and port.
*/
sscanf(tmp,
"%d %d %d %d %d", &ip, &t1, &t2, &t3, &port);
/*
* Construct the IP address.
*/
ip &=
0xff;
ip <<=
8;
ip |=
(t1 & 0xff);
ip <<=
8;
ip |=
(t2 & 0xff);
ip <<=
8;
ip |=
(t3 & 0xff);
/*
* Initialize the destination address.
*/
memset((char
*) &svaddr[n], 0, sizeof(struct sockaddr_in));
svaddr[n].sin_family
= AF_INET;
svaddr[n].sin_addr.s_addr
= htons(ip);
svaddr[n].sin_port
= htons(port);
print_ip_info("sv",
&svaddr[n]);
}
return n;
}
C. generate.c
#include <stdio.h>
main()
{
int i;
for (i=33000;i < 64000; i++) {
printf("100.1.2.1 %d\n",i);
}
}
|