1161030Ssam/*- 2161030Ssam * Copyright (c) 2006, Andrea Bittau <a.bittau@cs.ucl.ac.uk> 3161030Ssam * All rights reserved. 4161030Ssam * 5161030Ssam * Redistribution and use in source and binary forms, with or without 6161030Ssam * modification, are permitted provided that the following conditions 7161030Ssam * are met: 8161030Ssam * 1. Redistributions of source code must retain the above copyright 9161030Ssam * notice, this list of conditions and the following disclaimer. 10161030Ssam * 2. Redistributions in binary form must reproduce the above copyright 11161030Ssam * notice, this list of conditions and the following disclaimer in the 12161030Ssam * documentation and/or other materials provided with the distribution. 13161030Ssam * 14161030Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15161030Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16161030Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17161030Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18161030Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19161030Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20161030Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21161030Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22161030Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23161030Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24161030Ssam * SUCH DAMAGE. 25161030Ssam * 26161030Ssam * $FreeBSD$ 27161030Ssam */ 28161030Ssam#include <sys/types.h> 29161030Ssam#include <sys/socket.h> 30161030Ssam#include <sys/select.h> 31161030Ssam#include <sys/time.h> 32161030Ssam#include <netinet/in.h> 33161030Ssam#include <arpa/inet.h> 34161030Ssam#include <stdio.h> 35161030Ssam#include <unistd.h> 36161030Ssam#include <stdlib.h> 37161030Ssam#include <string.h> 38161030Ssam#include <assert.h> 39161030Ssam#include <time.h> 40161030Ssam#include <err.h> 41161030Ssam 42161030Ssamint poll_rate = 5; 43161030Ssamint pps = 10; 44161030Ssam 45161030Ssam//#define INSANE 46161030Ssam 47161030Ssamvoid own(int s, struct sockaddr_in* s_in) { 48161030Ssam char buf[64]; 49161030Ssam int times = 10; 50161030Ssam int i; 51161030Ssam int delay = 10*1000; 52161030Ssam unsigned int sent = 0; 53161030Ssam struct timeval start, end; 54161030Ssam struct timespec ts; 55161030Ssam int dont_sleep_times = 1; 56161030Ssam int dont_sleep; 57161030Ssam 58161030Ssam delay = (int) ((double)1.0/pps*1000.0*1000.0); 59161030Ssam 60161030Ssam if (delay <= 5000) { 61161030Ssam dont_sleep_times = 10; 62161030Ssam/* 63161030Ssam printf("delay is %d... sleeping every %d packets\n", 64161030Ssam delay, dont_sleep_times); 65161030Ssam*/ 66161030Ssam delay *= dont_sleep_times; 67161030Ssam 68161030Ssam delay = (int) (0.90*delay); 69161030Ssam } 70161030Ssam 71161030Ssam dont_sleep = dont_sleep_times; 72161030Ssam times = poll_rate*pps; 73161030Ssam// times *= dont_sleep; 74161030Ssam 75161030Ssam 76161030Ssam 77161030Ssam ts.tv_sec = 0; 78161030Ssam ts.tv_nsec = delay*1000; 79161030Ssam 80161030Ssam// printf("times=%d delay=%d\n", times, delay); 81161030Ssam if (gettimeofday(&start, NULL) == -1) { 82161030Ssam perror("gettimeofday()"); 83161030Ssam exit(1); 84161030Ssam } 85161030Ssam 86161030Ssam for(i = 0; i < times; i++) { 87161030Ssam if( sendto(s, buf, 6, 0, (struct sockaddr *)s_in, sizeof(*s_in)) != 6) { 88161030Ssam printf("messed up a bit\n"); 89161030Ssam return; 90161030Ssam } 91161030Ssam 92161030Ssam#ifndef INSANE 93161030Ssam 94161030Ssam#if 0 95161030Ssam if (usleep(delay) == -1) { 96161030Ssam perror("usleep()"); 97161030Ssam exit(1); 98161030Ssam } 99161030Ssam#endif 100161030Ssam dont_sleep--; 101161030Ssam 102161030Ssam if (!dont_sleep) { 103161030Ssam if (nanosleep(&ts, NULL) == -1) { 104161030Ssam perror("nanosleep()"); 105161030Ssam exit(1); 106161030Ssam } 107161030Ssam 108161030Ssam dont_sleep = dont_sleep_times; 109161030Ssam } 110161030Ssam 111161030Ssam#endif 112161030Ssam sent++; 113161030Ssam } 114161030Ssam 115161030Ssam if (gettimeofday(&end, NULL) == -1) { 116161030Ssam perror("gettimeofday()"); 117161030Ssam exit(1); 118161030Ssam } 119161030Ssam 120161030Ssam printf ("Sent %.03f p/s\n", ((double)sent)/(((double)end.tv_sec) - start.tv_sec)); 121161030Ssam 122161030Ssam// printf("Sent %d packets\n", i); 123161030Ssam} 124161030Ssam 125161030Ssamint main(int argc, char* argv[]) { 126161030Ssam int port = 6969; 127161030Ssam struct sockaddr_in s_in; 128161030Ssam int s; 129161030Ssam int rd; 130161030Ssam int len; 131161030Ssam char buf[64]; 132161030Ssam struct timeval tv; 133161030Ssam int do_it = 0; 134161030Ssam fd_set rfds; 135161030Ssam char ip[17]; 136161030Ssam 137161030Ssam if( argc > 1) 138161030Ssam pps = atoi(argv[1]); 139161030Ssam 140161030Ssam printf("Packets per second=%d\n", pps); 141161030Ssam 142161030Ssam s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 143161030Ssam if( s < 0) 144161030Ssam err(1, "socket()"); 145161030Ssam 146161030Ssam s_in.sin_family = PF_INET; 147161030Ssam s_in.sin_port = htons(port); 148161030Ssam s_in.sin_addr.s_addr = INADDR_ANY; 149161030Ssam 150161030Ssam if( bind(s, (struct sockaddr*)&s_in, sizeof(s_in)) < 0) { 151161030Ssam perror("bind()"); 152161030Ssam exit(1); 153161030Ssam } 154161030Ssam 155161030Ssam while(1) { 156161030Ssam assert(do_it >= 0); 157161030Ssam len = sizeof(struct sockaddr_in); 158161030Ssam 159161030Ssam memset(&tv, 0, sizeof(tv)); 160161030Ssam tv.tv_usec = 1000*10; 161161030Ssam FD_ZERO(&rfds); 162161030Ssam FD_SET(s, &rfds); 163161030Ssam rd = select(s + 1, &rfds, NULL ,NULL ,&tv); 164161030Ssam if (rd == -1) { 165161030Ssam perror("select()"); 166161030Ssam exit(1); 167161030Ssam } 168161030Ssam if (rd == 1 && FD_ISSET(s, &rfds)) { 169161030Ssam rd = recvfrom(s, buf, 64, 0, (struct sockaddr*)&s_in, &len); 170161030Ssam 171161030Ssam if(rd < 0) { 172161030Ssam perror("read died"); 173161030Ssam exit(1); 174161030Ssam } 175161030Ssam 176161030Ssam if(rd == 5 && memcmp(buf, "sorbo", 5) == 0) { 177161030Ssam sprintf(ip, "%s", inet_ntoa(s_in.sin_addr)); 178161030Ssam printf("Got signal from %s\n", ip); 179161030Ssam#ifdef INSANE 180161030Ssam do_it = 10; 181161030Ssam#else 182161030Ssam do_it = 2; 183161030Ssam#endif 184161030Ssam } 185161030Ssam } 186161030Ssam 187161030Ssam if (do_it) { 188161030Ssam printf("Sending stuff to %s\n", ip); 189161030Ssam 190161030Ssam own(s, &s_in); 191161030Ssam do_it--; 192161030Ssam 193161030Ssam if(do_it == 0) 194161030Ssam printf("Stopping send\n"); 195161030Ssam } 196161030Ssam } 197161030Ssam} 198