From ImageStream Router Documentation
/******************************************************
* rwtest_sock.c
* Author: Scott Yoder (syoder@imagestream.com)
* Date: 11-19-99
* This program is designed to test low-level interface packet
* generation on any Linux netdevice.
* Simply configure the port in wan.conf,
* run the up script to load the device drivers, and then run
* this program specifying the port to use and, if you wish,
* a file to log received packets.
******************************************************/
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/socket.h>
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h> /* The L2 protocols */
#define MAXFRAMESIZE 1500
int main(int argc, char **argv) {
int line1_fd;
FILE *log_fp;
char buffer[MAXFRAMESIZE];
char *line1_device;
int frame_size;
int i;
int log=0;
int flags;
struct ifreq ifr;
struct sockaddr_ll sa;
if (argc < 2) {
printf("Usage: %s <device> [logfile]\n", argv[0]);
printf("example: %s Serial0 /tmp/Serial0.log\n", argv[0]);
exit(1);
}
if (argc > 2)
{
log = 1;
}
line1_device = argv[1];
/* Open the netdevice socket */
line1_fd = socket(PF_PACKET, SOCK_DGRAM, 0);
/* Get interface index */
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons(ETH_P_ALL);
strncpy(ifr.ifr_name, line1_device, sizeof(ifr.ifr_name));
if (ioctl(line1_fd, SIOCGIFINDEX, &ifr) < 0) {
printf("Failed to find %s!\n", line1_device);
exit(1);
}
sa.sll_ifindex = ifr.ifr_ifindex;
/* We're only interested in packets on specified interface */
if (bind(line1_fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
printf("Failed to connect to %s!\n", line1_device);
exit(1);
}
/* Get the current flags (used to set the device back to blocking mode) */
flags = fcntl(line1_fd, F_GETFL);
/* If we're logging, open the log file for appending */
if (log)
{
log_fp = fopen(argv[2], "a");
if (!log_fp)
{
printf("Could not open the log file!\n");
exit(1);
}
}
/* Main loop -- forever until <ctrl>-c or SIGTERM, etc */
while(1) {
/* Fill the buffer with data (counting from 0-255) */
for (i=0;i<MAXFRAMESIZE;i++)
buffer[i] = (char) (i % 256);
/* Set blocking mode for the write */
/* We need to set blocked writes because otherwise
our loop will go so fast and will overrun the
driver's buffers. The driver will be forced to
discard some data. */
/* Blocking mode ensures that the write will complete
before the function returns */
fcntl(line1_fd, F_SETFL, flags);
/* Write the data to the port */
write(line1_fd, buffer, MAXFRAMESIZE);
/* Set non-blocking mode for the read */
/* We don't really want to wait for data to come in.
Our goal is to constantly send data and log any
data that is received. */
fcntl(line1_fd, F_SETFL, flags | O_NONBLOCK);
/* Read data from the port if there is data to be read */
if ((frame_size = read(line1_fd, buffer, MAXFRAMESIZE)) > 0)
{
/* Data present. Are we logging? */
if (log)
{
fprintf(log_fp, "Line 1 Rx (%d) : ", frame_size);
for (i=0;i<frame_size;i++)
fprintf(log_fp, "%02x ", (unsigned char)buffer[i]);
fprintf(log_fp, "\n");
fflush(log_fp);
}
}
}
return 0;
}