Scout Module API

Examples

Examples

Example 1-1. Creating a safe raw socket


    /* protocol = IPPROTO_UDP, IPPROTO_TCP, IPPROTO_ICMP, IPPROTO_ICMP_TCP,
     *   or IPPROTO_ICMP_UDP */

    if((sock = socket(PF_INET, SOCK_RAW, protocol)) < 0) { 
	perror("socket");
	exit(1);
    }
    
    memset(& sin, 0, sizeof(sin));
    sin.sin_port = htons(local_port);
    
    if((bind(sock, (struct sockaddr *)& sin, sizeof(sin))) < 0) {
	perror("bind");
	exit(1);
    }

Example 1-2. PING-PONG program using Linux or safe raw sockets


#include < stdio.h >
#include < stdlib.h >
#include < string.h >

#include < sys/socket.h >
#include < netinet/in.h >
#include < arpa/inet.h >
#include < linux/ip.h >
#include < linux/udp.h >

#define BUFFER_SIZE 1500
#define PING 1
#define PONG 2

int
main(int argc, char * argv[])
{
    int sock;
    struct sockaddr_in sin;
    unsigned short local_port;
    unsigned short remote_port;
    unsigned char protocol;
    char * buffer;
    struct iphdr * ip_header;
    struct udphdr * udp_header;
    char * remote_ip_str;
    unsigned char ping = 0;
    unsigned int * count = 0;
    unsigned int this_count = 0;
    int semantics = 0;
    int linux_socket = 0;
    unsigned short buffer_size = 0;
    int tmp, len;

    if (argc < 4 || argc > 6) {
	fprintf(stderr, "USAGE: %s remote_ip local_port remote_port"
		" (PING|PONG) [LINUX]\n", argv[0]);
	return 1;
    }

    protocol = IPPROTO_UDP;

    remote_ip_str = argv[1];
    local_port = atoi(argv[2]);
    remote_port = atoi(argv[3]);

    if (argc >= 5) {
	if (strncmp(argv[4], "PONG", 4) == 0) {
	    ping = 0;
	}
	else if (strncmp(argv[4], "PING", 4) == 0) {
	    ping = 1;
	}
	else {
	    fprintf(stderr, "PING or PONG ?.\n");
	    return 1;
	}
    }

    if (argc == 6) {
	if (strncmp(argv[5], "LINUX", 5) == 0) {
	    linux_socket = 1;
	}
	else {
	    linux_socket = 0;
	}
    }

    printf("Remote IP %s, local port %d, remote port %d%s%s\n",
	   remote_ip_str, local_port, remote_port,
	   ping ? ", PING" : ", PONG",
	   linux_socket ? ", LINUX_SOCKET" : "");
	 
    if (linux_socket) {
	semantics = SOCK_DGRAM;
    } else {
	semantics = SOCK_RAW;
    }

    if ((sock = socket(PF_INET, semantics, protocol)) < 0) { 
	perror("socket");
	exit(1);
    }

    bzero((char *)& sin, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(local_port);

    if ((bind(sock, (struct sockaddr *)& sin, sizeof(sin))) < 0) {
	perror("bind");
	exit(1);
    }

    if (! linux_socket) {
	tmp = 1;
	setsockopt(sock, 0, IP_HDRINCL, & tmp, sizeof(tmp));
    }

    bzero((char *)& sin, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(remote_port);
    sin.sin_addr.s_addr = inet_addr(remote_ip_str);
  
    buffer_size = BUFFER_SIZE 
	- (linux_socket ? 
	   (sizeof (struct iphdr) + sizeof (struct udphdr)) 
	   : 0);

    printf("buff %d, %d\n", buffer_size, BUFFER_SIZE);

    buffer = (char *) malloc(buffer_size);

    while ( 1 )
    {
	if (!linux_socket)
	{
	    ip_header = (struct iphdr *) buffer;
	    ip_header->ihl = 5;
	    ip_header->version = 4;
	    ip_header->tos = 0;
	    ip_header->tot_len = htons(buffer_size);
	    ip_header->id = 0;
	    ip_header->ttl = 64;
	    ip_header->frag_off = 0x40;
	    ip_header->protocol = protocol;
	    ip_header->check = 0; /* This will be done in the kernel */
	    ip_header->daddr = inet_addr(remote_ip_str);
            /* Leave src IP address blank, kernel will fill it out. */
	    ip_header->saddr = 0; 

	    udp_header = (struct udphdr *) (ip_header + 1);

	    udp_header->source = htons(local_port);
	    udp_header->dest = htons(remote_port);
	    udp_header->len = htons(buffer_size - sizeof(struct iphdr));
	    udp_header->check = 0;
	}

	if (ping)
	{
	    if (linux_socket) {
		count = (unsigned int *) buffer;
	    } else {
		count = (unsigned int *) (udp_header + 1);
	    }
	    * count = this_count ++;
	    if (! (this_count % 1)) {
		printf("%d\n", this_count);
	    }

	    if (sendto(sock, buffer, buffer_size, 0, 
		       (struct sockaddr *) & sin, sizeof(sin)) < 0) {
		perror("sendto");
	    }

	}

	ping = 1;

	len = sizeof(sin);
	if (recvfrom(sock, buffer, buffer_size, 0, 
		     (struct sockaddr *) & sin, & len) < 0) {
	    perror("recvfrom");
	    return 1;
	}
    }

    close(sock);

    return 0;
}