Improved sgsnemu ping
This commit is contained in:
parent
5f1c397026
commit
afb2a970de
43
README
43
README
|
@ -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 ***
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue