Improved sgsnemu ping

This commit is contained in:
jjako 2003-01-29 21:04:13 +00:00
parent 5f1c397026
commit afb2a970de
3 changed files with 92 additions and 23 deletions

43
README
View File

@ -96,15 +96,18 @@ the testing of roaming connectivity through a GPRS roaming exchange.
Two experiments were performed in order to test the performance of
sgsnemu and ggsn. The ggsn used a 550 MHz Athlon with 384 MB of
RAM. sgsnemu used a 1 GHz Athlon with 256 MB of RAM. Both machines had
100 Mb/s NICs and were connected through a Netgear FS105 switch. Both
tests were performed by sending ICMP echo packets from the ggsn to
sgsnemu.
100 Mb/s NICs (RTL-8139) and were connected through a crossed patch
cable. Both tests were performed by sending ICMP echo packets from
sgsnemu to the ggsn.
89.4 Mb/s IP downlink throughput when sending 10001 ICMP ping packets
with a payload of 1000 bytes. Transfer time 0.9 sec, no packets lost.
89.5 Mb/s IP throughput when sending 10000 ICMP ping packets with a
payload of 1400 bytes. Transfer time 1.27 sec, no packets lost.
17,1 Mb/s IP downlink throughput when sending 10001 ICMP ping packets with
a payload of 100 bytes. Transfer time 0.6 sec, no packets lost.
71.4 Mb/s IP throughput when sending 10000 ICMP ping packets with a
payload of 1000 bytes. Transfer time 1.15 sec, no packets lost.
12,1 Mb/s IP throughput when sending 10000 ICMP ping packets with a
payload of 100 bytes. Transfer time 0.84 sec, no packets lost.
*** Required software ***
@ -191,6 +194,32 @@ Use ggsn -h for a list of available options. All options available on
the command line can also be given in a configuration file. See
examples/ggsn.conf for the format of this file.
Start the ggsn as root using the command:
ggsn -c examples/ggsn.conf --fg -l 10.20.30.40 --net 192.168.0.0 --mask 255.255.0.0
First a tun network interface will be created. In the above example
the network interface address is 192.168.0.0 and the mask is
255.255.0.0. You can check that this interface is up by using
ifconfig.
After tun has been successfully established the ggsn will wait for GTP
create PDP context requests on the local interface
10.20.30.40. Currently all requests are excepted, and no password,
username or APN validation is performed.
When receiving a create PDP context request a dynamic IP address will
be allocated from the address pool determined by --net and --mask. In
the above example the first allocated address will be 192.168.0.1,
followed by 192.168.0.2 and so on. The request is confirmed by sending
a create PDP context response message to the peer (SGSN).
Now IP packets will be forwarded between the tun network interface and
the established GTP tunnel. In order to allow users to access the
external network routing needs to be set up. If private addresses are
are used you need to configure network address translation. See the
Linux Networking HOWTO for details.
Remember to enable routing: echo 1 > /proc/sys/net/ipv4/ip_forward
*** Running sgsnemu ***

View File

@ -17,7 +17,7 @@
#ifndef _GTP_H
#define _GTP_H
#define GTP_DEBUG 1 /* Print debug information */
#define GTP_DEBUG 0 /* Print debug information */
#define GTP0_PORT 3386
#define GTP1C_PORT 2123

View File

@ -120,6 +120,8 @@ int ntransmitted = 0;
int tmin = 999999999;
int tmax = 0;
int tsum = 0;
int pingseq = 0; /* Ping sequence counter */
struct timeval firstping;
int encaps_printf(struct pdp_t *pdp, void *pack, unsigned len) {
@ -168,12 +170,40 @@ char * print_icmptype(int t) {
return(ttab[t]);
}
/* Calculate time left until we have to send off next ping packet */
int ping_timeout(struct timeval *tp) {
struct timezone tz;
struct timeval tv;
int diff;
if ((pinghost.s_addr) && (2 == state) &&
((pingseq < pingcount) || (pingcount == 0))) {
gettimeofday(&tv, &tz);
diff = 1000000 / pingrate * pingseq -
1000000 * (tv.tv_sec - firstping.tv_sec) -
(tv.tv_usec - firstping.tv_usec); /* Microseconds safe up to 500 sec */
tp->tv_sec = 0;
if (diff > 0)
tp->tv_usec = diff;
else
/* For some reason we get packet loss if set to zero */
tp->tv_usec = 100000 / pingrate; /* 10 times pingrate */
}
return 0;
}
/* Print out statistics when at the end of ping sequence */
int ping_finish()
{
struct timezone tz;
struct timeval tv;
int elapsed;
gettimeofday(&tv, &tz);
elapsed = 1000000 * (tv.tv_sec - firstping.tv_sec) +
(tv.tv_usec - firstping.tv_usec); /* Microseconds */
printf("\n");
printf("\n----%s PING Statistics----\n", inet_ntoa(pinghost));
printf("%d packets transmitted, ", ntransmitted );
printf("%d packets transmitted in %.3f seconds, ", ntransmitted,
elapsed / 1000000.0);
printf("%d packets received, ", nreceived );
if (ntransmitted) {
if( nreceived > ntransmitted)
@ -190,6 +220,8 @@ int ping_finish()
tmin/1000.0,
tsum/1000.0/nreceived,
tmax/1000.0 );
printf("%d packets transmitted \n", ntreceived );
ntransmitted = 0;
return 0;
}
@ -529,7 +561,10 @@ int main(int argc, char **argv)
struct pdp_t *pdp[50];
int n; /* For counter */
int starttime; /* Time program was started */
int pingseq = 0; /* Ping sequence counter */
struct timezone tz; /* Used for calculating ping times */
struct timeval tv;
int diff;
/* function-local options */
struct ul_t imsi, qos, apn, msisdn;
@ -951,16 +986,23 @@ int main(int argc, char **argv)
if (gtpfd != -1) gtp_delete_context(gsn, pdp[n], NULL);
if ((pinghost.s_addr !=0) && ntransmitted) ping_finish();
}
}
}
/* Ping */
while ((2 == state) && (pinghost.s_addr !=0) &&
((pingseq < pingcount) || (pingcount == 0)) &&
(starttime + pingseq/pingrate) <= time(NULL)) {
create_ping(gsn, pdp[pingseq % contexts],
&pinghost, pingseq, pingsize);
pingseq++;
/* Send off an ICMP ping packet */
if ((pinghost.s_addr) && (2 == state) &&
((pingseq < pingcount) || (pingcount == 0))) {
if (!pingseq) gettimeofday(&firstping, &tz); /* Set time of first ping */
gettimeofday(&tv, &tz);
diff = 1000000 / pingrate * pingseq -
1000000 * (tv.tv_sec - firstping.tv_sec) -
(tv.tv_usec - firstping.tv_usec); /* Microseconds safe up to 500 sec */
if (diff <=0) {
if (debug) printf("Create_ping %d\n", diff);
create_ping(gsn, pdp[pingseq % contexts],
&pinghost, pingseq, pingsize);
pingseq++;
}
}
if (ntransmitted && pingcount && nreceived >= pingcount)
@ -973,12 +1015,10 @@ int main(int argc, char **argv)
if (gtpfd != -1) FD_SET(gtpfd, &fds);
gtp_retranstimeout(gsn, &idleTime);
ping_timeout(&idleTime);
if ((pinghost.s_addr !=0) &&
((idleTime.tv_sec !=0) || (idleTime.tv_usec !=0))) {
idleTime.tv_sec = 0;
idleTime.tv_usec = 1000000 / pingrate;
}
if (debug) printf("idletime.tv_sec %d, idleTime.tv_usec %d\n",
(int) idleTime.tv_sec, (int) idleTime.tv_usec);
switch (select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
case -1: