Parent Directory
|
Revision Log
Package all media, etc. needed for Public demo system into one tree
1 /* 2 * send_packets.c: from tcpreplay tools by Aaron Turner 3 * http://tcpreplay.sourceforge.net/ 4 * send_packets.c is under BSD license (see below) 5 * SIPp is under GPL license 6 * 7 * 8 * Copyright (c) 2001-2004 Aaron Turner. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the names of the copyright owners nor the names of its 21 * contributors may be used to endorse or promote products derived from 22 * this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 28 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 30 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 33 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 /*Map linux structure fields to BSD ones*/ 38 #ifdef __LINUX 39 #define __BSD_SOURCE 40 #define _BSD_SOURCE 41 #define __FAVOR_BSD 42 #endif /*__LINUX*/ 43 44 #include <pcap.h> 45 #include <unistd.h> 46 #include <stdlib.h> 47 #include <netinet/udp.h> 48 #if defined(__DARWIN) || defined(__CYGWIN) || defined(__FreeBSD__) 49 #include <netinet/in.h> 50 #endif 51 #ifndef __CYGWIN 52 #include <netinet/ip6.h> 53 #endif 54 #include <errno.h> 55 #include <string.h> 56 #include <fcntl.h> 57 58 #include "send_packets.h" 59 #include "prepare_pcap.h" 60 #include "screen.hpp" 61 62 extern volatile unsigned long rtp_pckts_pcap; 63 extern volatile unsigned long rtp_bytes_pcap; 64 extern int media_ip_is_ipv6; 65 66 inline void 67 timerdiv (struct timeval *tvp, float div) 68 { 69 double interval; 70 71 if (div == 0 || div == 1) 72 return; 73 74 interval = ((double) tvp->tv_sec * 1000000 + tvp->tv_usec) / (double) div; 75 tvp->tv_sec = interval / (int) 1000000; 76 tvp->tv_usec = interval - (tvp->tv_sec * 1000000); 77 } 78 79 /* 80 * converts a float to a timeval structure 81 */ 82 inline void 83 float2timer (float time, struct timeval *tvp) 84 { 85 float n; 86 87 n = time; 88 89 tvp->tv_sec = n; 90 91 n -= tvp->tv_sec; 92 tvp->tv_usec = n * 100000; 93 } 94 95 /* buffer should be "file_name" */ 96 int 97 parse_play_args (char *buffer, pcap_pkts *pkts) 98 { 99 pkts->file = strdup (buffer); 100 prepare_pkts(pkts->file, pkts); 101 return 1; 102 } 103 104 void hexdump(char *p, int s) { 105 int i; 106 for (i = 0; i < s; i++) { 107 fprintf(stderr, "%02x ", *(char *)(p+i)); 108 } 109 fprintf(stderr, "\n"); 110 } 111 112 /*Safe threaded version*/ 113 void do_sleep (struct timeval *, struct timeval *, 114 struct timeval *, struct timeval *); 115 116 int 117 send_packets (play_args_t * play_args) 118 { 119 int ret, sock, port_diff; 120 pcap_pkt *pkt_index, *pkt_max; 121 uint16_t *from_port, *to_port; 122 struct timeval didsleep = { 0, 0 }; 123 struct timeval start = { 0, 0 }; 124 struct timeval last = { 0, 0 }; 125 pcap_pkts *pkts = play_args->pcap; 126 /* to and from are pointers in case play_args (call sticky) gets modified! */ 127 struct sockaddr_storage *to = &(play_args->to); 128 struct sockaddr_storage *from = &(play_args->from); 129 struct udphdr *udp; 130 struct sockaddr_in6 to6, from6; 131 char buffer[PCAP_MAXPACKET]; 132 int temp_sum; 133 134 #ifndef MSG_DONTWAIT 135 int fd_flags; 136 #endif 137 138 if (media_ip_is_ipv6) { 139 sock = socket(PF_INET6, SOCK_RAW, IPPROTO_UDP); 140 if (sock < 0) { 141 ERROR("Can't create raw socket (need to run as root?)"); 142 } 143 from_port = &(((struct sockaddr_in6 *)(void *) from )->sin6_port); 144 to_port = &(((struct sockaddr_in6 *)(void *) to )->sin6_port); 145 } 146 else { 147 sock = socket(PF_INET, SOCK_RAW, IPPROTO_UDP); 148 if (sock < 0) { 149 ERROR("Can't create raw socket (need to run as root?)"); 150 } 151 from_port = &(((struct sockaddr_in *)(void *) from )->sin_port); 152 to_port = &(((struct sockaddr_in *)(void *) to )->sin_port); 153 } 154 155 #ifndef MSG_DONTWAIT 156 fd_flags = fcntl(sock, F_GETFL , NULL); 157 fd_flags |= O_NONBLOCK; 158 fcntl(sock, F_SETFL , fd_flags); 159 #endif 160 udp = (struct udphdr *)buffer; 161 162 pkt_index = pkts->pkts; 163 pkt_max = pkts->max; 164 165 if (media_ip_is_ipv6) { 166 memset(&to6, 0, sizeof(to6)); 167 memset(&from6, 0, sizeof(from6)); 168 to6.sin6_family = AF_INET6; 169 from6.sin6_family = AF_INET6; 170 memcpy(&(to6.sin6_addr.s6_addr), &(((struct sockaddr_in6 *)(void *) to)->sin6_addr.s6_addr), sizeof(to6.sin6_addr.s6_addr)); 171 memcpy(&(from6.sin6_addr.s6_addr), &(((struct sockaddr_in6 *)(void *) from)->sin6_addr.s6_addr), sizeof(from6.sin6_addr.s6_addr)); 172 } 173 174 while (pkt_index < pkt_max) { 175 memcpy(udp, pkt_index->data, pkt_index->pktlen); 176 port_diff = ntohs (udp->uh_dport) - pkts->base; 177 // modify UDP ports 178 udp->uh_sport = htons(port_diff + *from_port); 179 udp->uh_dport = htons(port_diff + *to_port); 180 181 if (!media_ip_is_ipv6) { 182 temp_sum = checksum_carry(pkt_index->partial_check + check((u_int16_t *) &(((struct sockaddr_in *)(void *) from)->sin_addr.s_addr), 4) + check((u_int16_t *) &(((struct sockaddr_in *)(void *) to)->sin_addr.s_addr), 4) + check((u_int16_t *) &udp->uh_sport, 4)); 183 } 184 else { 185 temp_sum = checksum_carry(pkt_index->partial_check + check((u_int16_t *) &(from6.sin6_addr.s6_addr), 16) + check((u_int16_t *) &(to6.sin6_addr.s6_addr), 16) + check((u_int16_t *) &udp->uh_sport, 4)); 186 } 187 188 #ifndef _HPUX_LI 189 #ifdef __HPUX 190 udp->uh_sum = (temp_sum>>16)+((temp_sum & 0xffff)<<16); 191 #else 192 udp->uh_sum = temp_sum; 193 #endif 194 #else 195 udp->uh_sum = temp_sum; 196 #endif 197 198 do_sleep ((struct timeval *) &pkt_index->ts, &last, &didsleep, 199 &start); 200 #ifdef MSG_DONTWAIT 201 if (!media_ip_is_ipv6) { 202 ret = sendto(sock, buffer, pkt_index->pktlen, MSG_DONTWAIT, 203 (struct sockaddr *)(void *) to, sizeof(struct sockaddr_in)); 204 } 205 else { 206 ret = sendto(sock, buffer, pkt_index->pktlen, MSG_DONTWAIT, 207 (struct sockaddr *)(void *) &to6, sizeof(struct sockaddr_in6)); 208 } 209 #else 210 if (!media_ip_is_ipv6) { 211 ret = sendto(sock, buffer, pkt_index->pktlen, 0, 212 (struct sockaddr *)(void *) to, sizeof(struct sockaddr_in)); 213 } 214 else { 215 ret = sendto(sock, buffer, pkt_index->pktlen, 0, 216 (struct sockaddr *)(void *) &to6, sizeof(struct sockaddr_in6)); 217 } 218 #endif 219 if (ret < 0) { 220 close(sock); 221 WARNING_P1("send_packets.c: sendto failed with error: %s", strerror(errno)); 222 return( -1); 223 } 224 225 rtp_pckts_pcap++; 226 rtp_bytes_pcap += pkt_index->pktlen - sizeof(*udp); 227 memcpy (&last, &(pkt_index->ts), sizeof (struct timeval)); 228 pkt_index++; 229 } 230 231 close(sock); 232 return 0; 233 } 234 235 /* 236 * Given the timestamp on the current packet and the last packet sent, 237 * calculate the appropriate amount of time to sleep and do so. 238 */ 239 void do_sleep (struct timeval *time, struct timeval *last, 240 struct timeval *didsleep, struct timeval *start) 241 { 242 struct timeval nap, now, delta; 243 struct timespec sleep; 244 245 if (gettimeofday (&now, NULL) < 0) 246 { 247 fprintf (stderr, "Error gettimeofday: %s\n", strerror (errno)); 248 } 249 250 /* First time through for this file */ 251 if (!timerisset (last)) 252 { 253 *start = now; 254 timerclear (&delta); 255 timerclear (didsleep); 256 } 257 else 258 { 259 timersub (&now, start, &delta); 260 } 261 262 if (timerisset (last) && timercmp (time, last, >)) 263 { 264 timersub (time, last, &nap); 265 } 266 else 267 { 268 /* 269 * Don't sleep if this is our first packet, or if the 270 * this packet appears to have been sent before the 271 * last packet. 272 */ 273 timerclear (&nap); 274 } 275 276 timeradd (didsleep, &nap, didsleep); 277 278 if (timercmp (didsleep, &delta, >)) 279 { 280 timersub (didsleep, &delta, &nap); 281 282 sleep.tv_sec = nap.tv_sec; 283 sleep.tv_nsec = nap.tv_usec * 1000; /* convert ms to ns */ 284 285 while ((nanosleep (&sleep, &sleep) == -1) && (errno == -EINTR)); 286 } 287 } 288 289
| No admin address has been configured | ViewVC Help |
| Powered by ViewVC 1.0.8 |