Convert all code to Linux coding style
After so many years of silence, we don't expect the original author to return to the project. To make things a bit simpler for us, we convert the coding style to what we are used to (Linux style). The conversion was made using the 'Lindent' script which is part of the Linux kernel.neels/refactor
parent
ca36f29364
commit
bed35df298
1876
ggsn/cmdline.c
1876
ggsn/cmdline.c
File diff suppressed because it is too large
Load Diff
183
ggsn/cmdline.h
183
ggsn/cmdline.h
|
@ -12,7 +12,7 @@
|
|||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifndef CMDLINE_PARSER_PACKAGE
|
||||
#define CMDLINE_PARSER_PACKAGE PACKAGE
|
||||
|
@ -22,105 +22,104 @@ extern "C" {
|
|||
#define CMDLINE_PARSER_VERSION VERSION
|
||||
#endif
|
||||
|
||||
struct gengetopt_args_info
|
||||
{
|
||||
const char *help_help; /* Print help and exit help description. */
|
||||
const char *version_help; /* Print version and exit help description. */
|
||||
int fg_flag; /* Run in foreground (default=off). */
|
||||
const char *fg_help; /* Run in foreground help description. */
|
||||
int debug_flag; /* Run in debug mode (default=off). */
|
||||
const char *debug_help; /* Run in debug mode help description. */
|
||||
char * conf_arg; /* Read configuration file (default='/etc/ggsn.conf'). */
|
||||
char * conf_orig; /* Read configuration file original value given at command line. */
|
||||
const char *conf_help; /* Read configuration file help description. */
|
||||
char * pidfile_arg; /* Filename of process id file (default='/var/run/ggsn.pid'). */
|
||||
char * pidfile_orig; /* Filename of process id file original value given at command line. */
|
||||
const char *pidfile_help; /* Filename of process id file help description. */
|
||||
char * statedir_arg; /* Directory of nonvolatile data (default='/var/lib/ggsn/'). */
|
||||
char * statedir_orig; /* Directory of nonvolatile data original value given at command line. */
|
||||
const char *statedir_help; /* Directory of nonvolatile data help description. */
|
||||
char * listen_arg; /* Local interface. */
|
||||
char * listen_orig; /* Local interface original value given at command line. */
|
||||
const char *listen_help; /* Local interface help description. */
|
||||
char * net_arg; /* Network (default='192.168.0.0/24'). */
|
||||
char * net_orig; /* Network original value given at command line. */
|
||||
const char *net_help; /* Network help description. */
|
||||
char * ipup_arg; /* Script to run after link-up. */
|
||||
char * ipup_orig; /* Script to run after link-up original value given at command line. */
|
||||
const char *ipup_help; /* Script to run after link-up help description. */
|
||||
char * ipdown_arg; /* Script to run after link-down. */
|
||||
char * ipdown_orig; /* Script to run after link-down original value given at command line. */
|
||||
const char *ipdown_help; /* Script to run after link-down help description. */
|
||||
char * dynip_arg; /* Dynamic IP address pool. */
|
||||
char * dynip_orig; /* Dynamic IP address pool original value given at command line. */
|
||||
const char *dynip_help; /* Dynamic IP address pool help description. */
|
||||
char * statip_arg; /* Static IP address pool. */
|
||||
char * statip_orig; /* Static IP address pool original value given at command line. */
|
||||
const char *statip_help; /* Static IP address pool help description. */
|
||||
char * pcodns1_arg; /* PCO DNS Server 1 (default='0.0.0.0'). */
|
||||
char * pcodns1_orig; /* PCO DNS Server 1 original value given at command line. */
|
||||
const char *pcodns1_help; /* PCO DNS Server 1 help description. */
|
||||
char * pcodns2_arg; /* PCO DNS Server 2 (default='0.0.0.0'). */
|
||||
char * pcodns2_orig; /* PCO DNS Server 2 original value given at command line. */
|
||||
const char *pcodns2_help; /* PCO DNS Server 2 help description. */
|
||||
int timelimit_arg; /* Exit after timelimit seconds (default='0'). */
|
||||
char * timelimit_orig; /* Exit after timelimit seconds original value given at command line. */
|
||||
const char *timelimit_help; /* Exit after timelimit seconds help description. */
|
||||
char * apn_arg; /* Access point name (default='internet'). */
|
||||
char * apn_orig; /* Access point name original value given at command line. */
|
||||
const char *apn_help; /* Access point name help description. */
|
||||
int qos_arg; /* Requested quality of service (default='0x0b921f'). */
|
||||
char * qos_orig; /* Requested quality of service original value given at command line. */
|
||||
const char *qos_help; /* Requested quality of service help description. */
|
||||
|
||||
int help_given ; /* Whether help was given. */
|
||||
int version_given ; /* Whether version was given. */
|
||||
int fg_given ; /* Whether fg was given. */
|
||||
int debug_given ; /* Whether debug was given. */
|
||||
int conf_given ; /* Whether conf was given. */
|
||||
int pidfile_given ; /* Whether pidfile was given. */
|
||||
int statedir_given ; /* Whether statedir was given. */
|
||||
int listen_given ; /* Whether listen was given. */
|
||||
int net_given ; /* Whether net was given. */
|
||||
int ipup_given ; /* Whether ipup was given. */
|
||||
int ipdown_given ; /* Whether ipdown was given. */
|
||||
int dynip_given ; /* Whether dynip was given. */
|
||||
int statip_given ; /* Whether statip was given. */
|
||||
int pcodns1_given ; /* Whether pcodns1 was given. */
|
||||
int pcodns2_given ; /* Whether pcodns2 was given. */
|
||||
int timelimit_given ; /* Whether timelimit was given. */
|
||||
int apn_given ; /* Whether apn was given. */
|
||||
int qos_given ; /* Whether qos was given. */
|
||||
struct gengetopt_args_info {
|
||||
const char *help_help; /* Print help and exit help description. */
|
||||
const char *version_help; /* Print version and exit help description. */
|
||||
int fg_flag; /* Run in foreground (default=off). */
|
||||
const char *fg_help; /* Run in foreground help description. */
|
||||
int debug_flag; /* Run in debug mode (default=off). */
|
||||
const char *debug_help; /* Run in debug mode help description. */
|
||||
char *conf_arg; /* Read configuration file (default='/etc/ggsn.conf'). */
|
||||
char *conf_orig; /* Read configuration file original value given at command line. */
|
||||
const char *conf_help; /* Read configuration file help description. */
|
||||
char *pidfile_arg; /* Filename of process id file (default='/var/run/ggsn.pid'). */
|
||||
char *pidfile_orig; /* Filename of process id file original value given at command line. */
|
||||
const char *pidfile_help; /* Filename of process id file help description. */
|
||||
char *statedir_arg; /* Directory of nonvolatile data (default='/var/lib/ggsn/'). */
|
||||
char *statedir_orig; /* Directory of nonvolatile data original value given at command line. */
|
||||
const char *statedir_help; /* Directory of nonvolatile data help description. */
|
||||
char *listen_arg; /* Local interface. */
|
||||
char *listen_orig; /* Local interface original value given at command line. */
|
||||
const char *listen_help; /* Local interface help description. */
|
||||
char *net_arg; /* Network (default='192.168.0.0/24'). */
|
||||
char *net_orig; /* Network original value given at command line. */
|
||||
const char *net_help; /* Network help description. */
|
||||
char *ipup_arg; /* Script to run after link-up. */
|
||||
char *ipup_orig; /* Script to run after link-up original value given at command line. */
|
||||
const char *ipup_help; /* Script to run after link-up help description. */
|
||||
char *ipdown_arg; /* Script to run after link-down. */
|
||||
char *ipdown_orig; /* Script to run after link-down original value given at command line. */
|
||||
const char *ipdown_help; /* Script to run after link-down help description. */
|
||||
char *dynip_arg; /* Dynamic IP address pool. */
|
||||
char *dynip_orig; /* Dynamic IP address pool original value given at command line. */
|
||||
const char *dynip_help; /* Dynamic IP address pool help description. */
|
||||
char *statip_arg; /* Static IP address pool. */
|
||||
char *statip_orig; /* Static IP address pool original value given at command line. */
|
||||
const char *statip_help; /* Static IP address pool help description. */
|
||||
char *pcodns1_arg; /* PCO DNS Server 1 (default='0.0.0.0'). */
|
||||
char *pcodns1_orig; /* PCO DNS Server 1 original value given at command line. */
|
||||
const char *pcodns1_help; /* PCO DNS Server 1 help description. */
|
||||
char *pcodns2_arg; /* PCO DNS Server 2 (default='0.0.0.0'). */
|
||||
char *pcodns2_orig; /* PCO DNS Server 2 original value given at command line. */
|
||||
const char *pcodns2_help; /* PCO DNS Server 2 help description. */
|
||||
int timelimit_arg; /* Exit after timelimit seconds (default='0'). */
|
||||
char *timelimit_orig; /* Exit after timelimit seconds original value given at command line. */
|
||||
const char *timelimit_help; /* Exit after timelimit seconds help description. */
|
||||
char *apn_arg; /* Access point name (default='internet'). */
|
||||
char *apn_orig; /* Access point name original value given at command line. */
|
||||
const char *apn_help; /* Access point name help description. */
|
||||
int qos_arg; /* Requested quality of service (default='0x0b921f'). */
|
||||
char *qos_orig; /* Requested quality of service original value given at command line. */
|
||||
const char *qos_help; /* Requested quality of service help description. */
|
||||
|
||||
} ;
|
||||
int help_given; /* Whether help was given. */
|
||||
int version_given; /* Whether version was given. */
|
||||
int fg_given; /* Whether fg was given. */
|
||||
int debug_given; /* Whether debug was given. */
|
||||
int conf_given; /* Whether conf was given. */
|
||||
int pidfile_given; /* Whether pidfile was given. */
|
||||
int statedir_given; /* Whether statedir was given. */
|
||||
int listen_given; /* Whether listen was given. */
|
||||
int net_given; /* Whether net was given. */
|
||||
int ipup_given; /* Whether ipup was given. */
|
||||
int ipdown_given; /* Whether ipdown was given. */
|
||||
int dynip_given; /* Whether dynip was given. */
|
||||
int statip_given; /* Whether statip was given. */
|
||||
int pcodns1_given; /* Whether pcodns1 was given. */
|
||||
int pcodns2_given; /* Whether pcodns2 was given. */
|
||||
int timelimit_given; /* Whether timelimit was given. */
|
||||
int apn_given; /* Whether apn was given. */
|
||||
int qos_given; /* Whether qos was given. */
|
||||
|
||||
extern const char *gengetopt_args_info_purpose;
|
||||
extern const char *gengetopt_args_info_usage;
|
||||
extern const char *gengetopt_args_info_help[];
|
||||
};
|
||||
|
||||
int cmdline_parser (int argc, char * const *argv,
|
||||
struct gengetopt_args_info *args_info);
|
||||
int cmdline_parser2 (int argc, char * const *argv,
|
||||
struct gengetopt_args_info *args_info,
|
||||
int override, int initialize, int check_required);
|
||||
int cmdline_parser_file_save(const char *filename,
|
||||
struct gengetopt_args_info *args_info);
|
||||
extern const char *gengetopt_args_info_purpose;
|
||||
extern const char *gengetopt_args_info_usage;
|
||||
extern const char *gengetopt_args_info_help[];
|
||||
|
||||
void cmdline_parser_print_help(void);
|
||||
void cmdline_parser_print_version(void);
|
||||
int cmdline_parser(int argc, char *const *argv,
|
||||
struct gengetopt_args_info *args_info);
|
||||
int cmdline_parser2(int argc, char *const *argv,
|
||||
struct gengetopt_args_info *args_info,
|
||||
int override, int initialize, int check_required);
|
||||
int cmdline_parser_file_save(const char *filename,
|
||||
struct gengetopt_args_info *args_info);
|
||||
|
||||
void cmdline_parser_init (struct gengetopt_args_info *args_info);
|
||||
void cmdline_parser_free (struct gengetopt_args_info *args_info);
|
||||
void cmdline_parser_print_help(void);
|
||||
void cmdline_parser_print_version(void);
|
||||
|
||||
int cmdline_parser_configfile (char * const filename,
|
||||
struct gengetopt_args_info *args_info,
|
||||
int override, int initialize, int check_required);
|
||||
void cmdline_parser_init(struct gengetopt_args_info *args_info);
|
||||
void cmdline_parser_free(struct gengetopt_args_info *args_info);
|
||||
|
||||
int cmdline_parser_required (struct gengetopt_args_info *args_info,
|
||||
const char *prog_name);
|
||||
int cmdline_parser_configfile(char *const filename,
|
||||
struct gengetopt_args_info *args_info,
|
||||
int override, int initialize,
|
||||
int check_required);
|
||||
|
||||
int cmdline_parser_required(struct gengetopt_args_info *args_info,
|
||||
const char *prog_name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* CMDLINE_H */
|
||||
#endif /* __cplusplus */
|
||||
#endif /* CMDLINE_H */
|
||||
|
|
864
ggsn/ggsn.c
864
ggsn/ggsn.c
|
@ -39,7 +39,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
|
||||
|
@ -55,507 +55,539 @@
|
|||
#include "cmdline.h"
|
||||
|
||||
int end = 0;
|
||||
int maxfd = 0; /* For select() */
|
||||
int maxfd = 0; /* For select() */
|
||||
|
||||
struct in_addr listen_;
|
||||
struct in_addr netaddr, destaddr, net, mask; /* Network interface */
|
||||
struct in_addr dns1, dns2; /* PCO DNS address */
|
||||
char *ipup, *ipdown; /* Filename of scripts */
|
||||
int debug; /* Print debug output */
|
||||
struct in_addr netaddr, destaddr, net, mask; /* Network interface */
|
||||
struct in_addr dns1, dns2; /* PCO DNS address */
|
||||
char *ipup, *ipdown; /* Filename of scripts */
|
||||
int debug; /* Print debug output */
|
||||
struct ul255_t pco;
|
||||
struct ul255_t qos;
|
||||
struct ul255_t apn;
|
||||
|
||||
struct gsn_t *gsn; /* GSN instance */
|
||||
struct tun_t *tun; /* TUN instance */
|
||||
struct ippool_t *ippool; /* Pool of IP addresses */
|
||||
struct gsn_t *gsn; /* GSN instance */
|
||||
struct tun_t *tun; /* TUN instance */
|
||||
struct ippool_t *ippool; /* Pool of IP addresses */
|
||||
|
||||
/* To exit gracefully. Used with GCC compilation flag -pg and gprof */
|
||||
void signal_handler(int s) {
|
||||
if (debug) printf("Received signal %d, exiting.\n", s);
|
||||
end = 1;
|
||||
void signal_handler(int s)
|
||||
{
|
||||
if (debug)
|
||||
printf("Received signal %d, exiting.\n", s);
|
||||
end = 1;
|
||||
}
|
||||
|
||||
/* Used to write process ID to file. Assume someone else will delete */
|
||||
void log_pid(char *pidfile) {
|
||||
FILE *file;
|
||||
mode_t oldmask;
|
||||
|
||||
oldmask = umask(022);
|
||||
file = fopen(pidfile, "w");
|
||||
umask(oldmask);
|
||||
if(!file) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to create process ID file: %s!", pidfile);
|
||||
return;
|
||||
}
|
||||
fprintf(file, "%d\n", (int) getpid());
|
||||
fclose(file);
|
||||
void log_pid(char *pidfile)
|
||||
{
|
||||
FILE *file;
|
||||
mode_t oldmask;
|
||||
|
||||
oldmask = umask(022);
|
||||
file = fopen(pidfile, "w");
|
||||
umask(oldmask);
|
||||
if (!file) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to create process ID file: %s!", pidfile);
|
||||
return;
|
||||
}
|
||||
fprintf(file, "%d\n", (int)getpid());
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
#if defined(__sun__)
|
||||
int daemon(int nochdir, int noclose) {
|
||||
int fd;
|
||||
int daemon(int nochdir, int noclose)
|
||||
{
|
||||
int fd;
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
return (-1);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
_exit(0);
|
||||
}
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
return (-1);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
if (setsid() == -1)
|
||||
return (-1);
|
||||
|
||||
if (!nochdir) chdir("/");
|
||||
if (setsid() == -1)
|
||||
return (-1);
|
||||
|
||||
if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
|
||||
dup2(fd, STDIN_FILENO);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
if (fd > 2) close (fd);
|
||||
}
|
||||
return (0);
|
||||
if (!nochdir)
|
||||
chdir("/");
|
||||
|
||||
if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
|
||||
dup2(fd, STDIN_FILENO);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
if (fd > 2)
|
||||
close(fd);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int encaps_printf(void *p, void *packet, unsigned len)
|
||||
{
|
||||
unsigned int i;
|
||||
if (debug) {
|
||||
printf("The packet looks like this:\n");
|
||||
for( i=0; i<len; i++) {
|
||||
printf("%02x ", (unsigned char)*(char *)(packet+i));
|
||||
if (!((i+1)%16)) printf("\n");
|
||||
};
|
||||
printf("\n");
|
||||
}
|
||||
return 0;
|
||||
unsigned int i;
|
||||
if (debug) {
|
||||
printf("The packet looks like this:\n");
|
||||
for (i = 0; i < len; i++) {
|
||||
printf("%02x ", (unsigned char)*(char *)(packet + i));
|
||||
if (!((i + 1) % 16))
|
||||
printf("\n");
|
||||
};
|
||||
printf("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int delete_context(struct pdp_t *pdp) {
|
||||
if (debug) printf("Deleting PDP context\n");
|
||||
if (pdp->peer)
|
||||
ippool_freeip(ippool, (struct ippoolm_t *) pdp->peer);
|
||||
else
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Peer not defined!");
|
||||
return 0;
|
||||
int delete_context(struct pdp_t *pdp)
|
||||
{
|
||||
if (debug)
|
||||
printf("Deleting PDP context\n");
|
||||
if (pdp->peer)
|
||||
ippool_freeip(ippool, (struct ippoolm_t *)pdp->peer);
|
||||
else
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Peer not defined!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_context_ind(struct pdp_t *pdp)
|
||||
{
|
||||
struct in_addr addr;
|
||||
struct ippoolm_t *member;
|
||||
|
||||
int create_context_ind(struct pdp_t *pdp) {
|
||||
struct in_addr addr;
|
||||
struct ippoolm_t *member;
|
||||
if (debug)
|
||||
printf("Received create PDP context request\n");
|
||||
|
||||
if (debug) printf("Received create PDP context request\n");
|
||||
pdp->eua.l = 0; /* TODO: Indicates dynamic IP */
|
||||
|
||||
pdp->eua.l=0; /* TODO: Indicates dynamic IP */
|
||||
/* ulcpy(&pdp->qos_neg, &pdp->qos_req, sizeof(pdp->qos_req.v)); */
|
||||
memcpy(pdp->qos_neg0, pdp->qos_req0, sizeof(pdp->qos_req0));
|
||||
memcpy(&pdp->pco_neg, &pco, sizeof(pdp->pco_neg));
|
||||
|
||||
/* ulcpy(&pdp->qos_neg, &pdp->qos_req, sizeof(pdp->qos_req.v)); */
|
||||
memcpy(pdp->qos_neg0, pdp->qos_req0, sizeof(pdp->qos_req0));
|
||||
memcpy(&pdp->pco_neg, &pco, sizeof(pdp->pco_neg));
|
||||
memcpy(pdp->qos_neg.v, pdp->qos_req.v, pdp->qos_req.l); /* TODO */
|
||||
pdp->qos_neg.l = pdp->qos_req.l;
|
||||
|
||||
memcpy(pdp->qos_neg.v, pdp->qos_req.v, pdp->qos_req.l); /* TODO */
|
||||
pdp->qos_neg.l = pdp->qos_req.l;
|
||||
|
||||
if (pdp_euaton(&pdp->eua, &addr)) {
|
||||
addr.s_addr = 0; /* Request dynamic */
|
||||
}
|
||||
if (pdp_euaton(&pdp->eua, &addr)) {
|
||||
addr.s_addr = 0; /* Request dynamic */
|
||||
}
|
||||
|
||||
if (ippool_newip(ippool, &member, &addr, 0)) {
|
||||
gtp_create_context_resp(gsn, pdp, GTPCAUSE_NO_RESOURCES);
|
||||
return 0; /* Allready in use, or no more available */
|
||||
}
|
||||
if (ippool_newip(ippool, &member, &addr, 0)) {
|
||||
gtp_create_context_resp(gsn, pdp, GTPCAUSE_NO_RESOURCES);
|
||||
return 0; /* Allready in use, or no more available */
|
||||
}
|
||||
|
||||
pdp_ntoeua(&member->addr, &pdp->eua);
|
||||
pdp->peer = member;
|
||||
pdp->ipif = tun; /* TODO */
|
||||
member->peer = pdp;
|
||||
pdp_ntoeua(&member->addr, &pdp->eua);
|
||||
pdp->peer = member;
|
||||
pdp->ipif = tun; /* TODO */
|
||||
member->peer = pdp;
|
||||
|
||||
gtp_create_context_resp(gsn, pdp, GTPCAUSE_ACC_REQ);
|
||||
return 0; /* Success */
|
||||
gtp_create_context_resp(gsn, pdp, GTPCAUSE_ACC_REQ);
|
||||
return 0; /* Success */
|
||||
}
|
||||
|
||||
|
||||
/* Callback for receiving messages from tun */
|
||||
int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len) {
|
||||
struct ippoolm_t *ipm;
|
||||
struct in_addr dst;
|
||||
struct tun_packet_t *iph = (struct tun_packet_t*) pack;
|
||||
|
||||
dst.s_addr = iph->dst;
|
||||
int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
|
||||
{
|
||||
struct ippoolm_t *ipm;
|
||||
struct in_addr dst;
|
||||
struct tun_packet_t *iph = (struct tun_packet_t *)pack;
|
||||
|
||||
if (debug) printf("Received packet from tun!\n");
|
||||
dst.s_addr = iph->dst;
|
||||
|
||||
if (ippool_getip(ippool, &ipm, &dst)) {
|
||||
if (debug) printf("Received packet with no destination!!!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ipm->peer) /* Check if a peer protocol is defined */
|
||||
gtp_data_req(gsn, (struct pdp_t*) ipm->peer, pack, len);
|
||||
return 0;
|
||||
if (debug)
|
||||
printf("Received packet from tun!\n");
|
||||
|
||||
if (ippool_getip(ippool, &ipm, &dst)) {
|
||||
if (debug)
|
||||
printf("Received packet with no destination!!!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ipm->peer) /* Check if a peer protocol is defined */
|
||||
gtp_data_req(gsn, (struct pdp_t *)ipm->peer, pack, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len) {
|
||||
if (debug) printf("encaps_tun. Packet received: forwarding to tun\n");
|
||||
return tun_encaps((struct tun_t*) pdp->ipif, pack, len);
|
||||
int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len)
|
||||
{
|
||||
if (debug)
|
||||
printf("encaps_tun. Packet received: forwarding to tun\n");
|
||||
return tun_encaps((struct tun_t *)pdp->ipif, pack, len);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* gengeopt declarations */
|
||||
struct gengetopt_args_info args_info;
|
||||
/* gengeopt declarations */
|
||||
struct gengetopt_args_info args_info;
|
||||
|
||||
struct hostent *host;
|
||||
struct hostent *host;
|
||||
|
||||
/* Handle keyboard interrupt SIGINT */
|
||||
struct sigaction s;
|
||||
s.sa_handler = (void *) signal_handler;
|
||||
if ((0 != sigemptyset( &s.sa_mask )) && debug)
|
||||
printf("sigemptyset failed.\n");
|
||||
s.sa_flags = SA_RESETHAND;
|
||||
if ((sigaction(SIGINT, &s, NULL) != 0) && debug)
|
||||
printf("Could not register SIGINT signal handler.\n");
|
||||
|
||||
fd_set fds; /* For select() */
|
||||
struct timeval idleTime; /* How long to select() */
|
||||
/* Handle keyboard interrupt SIGINT */
|
||||
struct sigaction s;
|
||||
s.sa_handler = (void *)signal_handler;
|
||||
if ((0 != sigemptyset(&s.sa_mask)) && debug)
|
||||
printf("sigemptyset failed.\n");
|
||||
s.sa_flags = SA_RESETHAND;
|
||||
if ((sigaction(SIGINT, &s, NULL) != 0) && debug)
|
||||
printf("Could not register SIGINT signal handler.\n");
|
||||
|
||||
fd_set fds; /* For select() */
|
||||
struct timeval idleTime; /* How long to select() */
|
||||
|
||||
int timelimit; /* Number of seconds to be connected */
|
||||
int starttime; /* Time program was started */
|
||||
int timelimit; /* Number of seconds to be connected */
|
||||
int starttime; /* Time program was started */
|
||||
|
||||
/* open a connection to the syslog daemon */
|
||||
/*openlog(PACKAGE, LOG_PID, LOG_DAEMON);*/
|
||||
/* open a connection to the syslog daemon */
|
||||
/*openlog(PACKAGE, LOG_PID, LOG_DAEMON); */
|
||||
|
||||
/* TODO: Only use LOG__PERROR for linux */
|
||||
/* TODO: Only use LOG__PERROR for linux */
|
||||
#ifdef __linux__
|
||||
openlog(PACKAGE, (LOG_PID | LOG_PERROR), LOG_DAEMON);
|
||||
openlog(PACKAGE, (LOG_PID | LOG_PERROR), LOG_DAEMON);
|
||||
#else
|
||||
openlog(PACKAGE, (LOG_PID), LOG_DAEMON);
|
||||
openlog(PACKAGE, (LOG_PID), LOG_DAEMON);
|
||||
#endif
|
||||
|
||||
if (cmdline_parser(argc, argv, &args_info) != 0)
|
||||
exit(1);
|
||||
if (args_info.debug_flag) {
|
||||
printf("listen: %s\n", args_info.listen_arg);
|
||||
if (args_info.conf_arg)
|
||||
printf("conf: %s\n", args_info.conf_arg);
|
||||
printf("fg: %d\n", args_info.fg_flag);
|
||||
printf("debug: %d\n", args_info.debug_flag);
|
||||
printf("qos: %#08x\n", args_info.qos_arg);
|
||||
if (args_info.apn_arg)
|
||||
printf("apn: %s\n", args_info.apn_arg);
|
||||
if (args_info.net_arg)
|
||||
printf("net: %s\n", args_info.net_arg);
|
||||
if (args_info.dynip_arg)
|
||||
printf("dynip: %s\n", args_info.dynip_arg);
|
||||
if (args_info.statip_arg)
|
||||
printf("statip: %s\n", args_info.statip_arg);
|
||||
if (args_info.ipup_arg)
|
||||
printf("ipup: %s\n", args_info.ipup_arg);
|
||||
if (args_info.ipdown_arg)
|
||||
printf("ipdown: %s\n", args_info.ipdown_arg);
|
||||
if (args_info.pidfile_arg)
|
||||
printf("pidfile: %s\n", args_info.pidfile_arg);
|
||||
if (args_info.statedir_arg)
|
||||
printf("statedir: %s\n", args_info.statedir_arg);
|
||||
printf("timelimit: %d\n", args_info.timelimit_arg);
|
||||
}
|
||||
|
||||
if (cmdline_parser (argc, argv, &args_info) != 0)
|
||||
exit(1);
|
||||
if (args_info.debug_flag) {
|
||||
printf("listen: %s\n", args_info.listen_arg);
|
||||
if (args_info.conf_arg) printf("conf: %s\n", args_info.conf_arg);
|
||||
printf("fg: %d\n", args_info.fg_flag);
|
||||
printf("debug: %d\n", args_info.debug_flag);
|
||||
printf("qos: %#08x\n", args_info.qos_arg);
|
||||
if (args_info.apn_arg) printf("apn: %s\n", args_info.apn_arg);
|
||||
if (args_info.net_arg) printf("net: %s\n", args_info.net_arg);
|
||||
if (args_info.dynip_arg) printf("dynip: %s\n", args_info.dynip_arg);
|
||||
if (args_info.statip_arg) printf("statip: %s\n", args_info.statip_arg);
|
||||
if (args_info.ipup_arg) printf("ipup: %s\n", args_info.ipup_arg);
|
||||
if (args_info.ipdown_arg) printf("ipdown: %s\n", args_info.ipdown_arg);
|
||||
if (args_info.pidfile_arg) printf("pidfile: %s\n", args_info.pidfile_arg);
|
||||
if (args_info.statedir_arg) printf("statedir: %s\n", args_info.statedir_arg);
|
||||
printf("timelimit: %d\n", args_info.timelimit_arg);
|
||||
}
|
||||
/* Try out our new parser */
|
||||
|
||||
/* Try out our new parser */
|
||||
|
||||
if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0, 0, 0) != 0)
|
||||
exit(1);
|
||||
if (args_info.debug_flag) {
|
||||
printf("cmdline_parser_configfile\n");
|
||||
printf("listen: %s\n", args_info.listen_arg);
|
||||
printf("conf: %s\n", args_info.conf_arg);
|
||||
printf("fg: %d\n", args_info.fg_flag);
|
||||
printf("debug: %d\n", args_info.debug_flag);
|
||||
printf("qos: %#08x\n", args_info.qos_arg);
|
||||
if (args_info.apn_arg) printf("apn: %s\n", args_info.apn_arg);
|
||||
if (args_info.net_arg) printf("net: %s\n", args_info.net_arg);
|
||||
if (args_info.dynip_arg) printf("dynip: %s\n", args_info.dynip_arg);
|
||||
if (args_info.statip_arg) printf("statip: %s\n", args_info.statip_arg);
|
||||
if (args_info.ipup_arg) printf("ipup: %s\n", args_info.ipup_arg);
|
||||
if (args_info.ipdown_arg) printf("ipdown: %s\n", args_info.ipdown_arg);
|
||||
if (args_info.pidfile_arg) printf("pidfile: %s\n", args_info.pidfile_arg);
|
||||
if (args_info.statedir_arg) printf("statedir: %s\n", args_info.statedir_arg);
|
||||
printf("timelimit: %d\n", args_info.timelimit_arg);
|
||||
}
|
||||
if (cmdline_parser_configfile(args_info.conf_arg, &args_info, 0, 0, 0)
|
||||
!= 0)
|
||||
exit(1);
|
||||
if (args_info.debug_flag) {
|
||||
printf("cmdline_parser_configfile\n");
|
||||
printf("listen: %s\n", args_info.listen_arg);
|
||||
printf("conf: %s\n", args_info.conf_arg);
|
||||
printf("fg: %d\n", args_info.fg_flag);
|
||||
printf("debug: %d\n", args_info.debug_flag);
|
||||
printf("qos: %#08x\n", args_info.qos_arg);
|
||||
if (args_info.apn_arg)
|
||||
printf("apn: %s\n", args_info.apn_arg);
|
||||
if (args_info.net_arg)
|
||||
printf("net: %s\n", args_info.net_arg);
|
||||
if (args_info.dynip_arg)
|
||||
printf("dynip: %s\n", args_info.dynip_arg);
|
||||
if (args_info.statip_arg)
|
||||
printf("statip: %s\n", args_info.statip_arg);
|
||||
if (args_info.ipup_arg)
|
||||
printf("ipup: %s\n", args_info.ipup_arg);
|
||||
if (args_info.ipdown_arg)
|
||||
printf("ipdown: %s\n", args_info.ipdown_arg);
|
||||
if (args_info.pidfile_arg)
|
||||
printf("pidfile: %s\n", args_info.pidfile_arg);
|
||||
if (args_info.statedir_arg)
|
||||
printf("statedir: %s\n", args_info.statedir_arg);
|
||||
printf("timelimit: %d\n", args_info.timelimit_arg);
|
||||
}
|
||||
|
||||
/* Handle each option */
|
||||
/* Handle each option */
|
||||
|
||||
/* debug */
|
||||
debug = args_info.debug_flag;
|
||||
/* debug */
|
||||
debug = args_info.debug_flag;
|
||||
|
||||
/* listen */
|
||||
/* Do hostname lookup to translate hostname to IP address */
|
||||
/* Any port listening is not possible as a valid address is */
|
||||
/* required for create_pdp_context_response messages */
|
||||
if (args_info.listen_arg) {
|
||||
if (!(host = gethostbyname(args_info.listen_arg))) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Invalid listening address: %s!", args_info.listen_arg);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
memcpy(&listen_.s_addr, host->h_addr, host->h_length);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Listening address must be specified! "
|
||||
"Please use command line option --listen or "
|
||||
"edit %s configuration file\n", args_info.conf_arg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* listen */
|
||||
/* Do hostname lookup to translate hostname to IP address */
|
||||
/* Any port listening is not possible as a valid address is */
|
||||
/* required for create_pdp_context_response messages */
|
||||
if (args_info.listen_arg) {
|
||||
if (!(host = gethostbyname(args_info.listen_arg))) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Invalid listening address: %s!",
|
||||
args_info.listen_arg);
|
||||
exit(1);
|
||||
} else {
|
||||
memcpy(&listen_.s_addr, host->h_addr, host->h_length);
|
||||
}
|
||||
} else {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Listening address must be specified! "
|
||||
"Please use command line option --listen or "
|
||||
"edit %s configuration file\n", args_info.conf_arg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* net */
|
||||
/* Store net as in_addr net and mask */
|
||||
if (args_info.net_arg) {
|
||||
if(ippool_aton(&net, &mask, args_info.net_arg, 0)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Invalid network address: %s!", args_info.net_arg);
|
||||
exit(1);
|
||||
}
|
||||
netaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
|
||||
destaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
|
||||
}
|
||||
else {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Network address must be specified: %s!", args_info.net_arg);
|
||||
exit(1);
|
||||
}
|
||||
/* net */
|
||||
/* Store net as in_addr net and mask */
|
||||
if (args_info.net_arg) {
|
||||
if (ippool_aton(&net, &mask, args_info.net_arg, 0)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Invalid network address: %s!",
|
||||
args_info.net_arg);
|
||||
exit(1);
|
||||
}
|
||||
netaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
|
||||
destaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
|
||||
} else {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Network address must be specified: %s!",
|
||||
args_info.net_arg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* dynip */
|
||||
if (!args_info.dynip_arg) {
|
||||
if (ippool_new(&ippool, args_info.net_arg, NULL, 1, 0,
|
||||
IPPOOL_NONETWORK | IPPOOL_NOGATEWAY | IPPOOL_NOBROADCAST)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to allocate IP pool!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ippool_new(&ippool, args_info.dynip_arg, NULL, 1 ,0,
|
||||
IPPOOL_NONETWORK | IPPOOL_NOGATEWAY | IPPOOL_NOBROADCAST)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to allocate IP pool!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/* dynip */
|
||||
if (!args_info.dynip_arg) {
|
||||
if (ippool_new(&ippool, args_info.net_arg, NULL, 1, 0,
|
||||
IPPOOL_NONETWORK | IPPOOL_NOGATEWAY |
|
||||
IPPOOL_NOBROADCAST)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to allocate IP pool!");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
if (ippool_new(&ippool, args_info.dynip_arg, NULL, 1, 0,
|
||||
IPPOOL_NONETWORK | IPPOOL_NOGATEWAY |
|
||||
IPPOOL_NOBROADCAST)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to allocate IP pool!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* DNS1 and DNS2 */
|
||||
/* DNS1 and DNS2 */
|
||||
#ifdef HAVE_INET_ATON
|
||||
dns1.s_addr = 0;
|
||||
if (args_info.pcodns1_arg) {
|
||||
if (0 == inet_aton(args_info.pcodns1_arg, &dns1)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to convert pcodns1!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
dns2.s_addr = 0;
|
||||
if (args_info.pcodns2_arg) {
|
||||
if (0 == inet_aton(args_info.pcodns2_arg, &dns2)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to convert pcodns2!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
dns1.s_addr = 0;
|
||||
if (args_info.pcodns1_arg) {
|
||||
if (0 == inet_aton(args_info.pcodns1_arg, &dns1)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to convert pcodns1!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
dns2.s_addr = 0;
|
||||
if (args_info.pcodns2_arg) {
|
||||
if (0 == inet_aton(args_info.pcodns2_arg, &dns2)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to convert pcodns2!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
dns1.s_addr = 0;
|
||||
if (args_info.pcodns1_arg) {
|
||||
dns1.s_addr = inet_addr(args_info.pcodns1_arg);
|
||||
if (dns1.s_addr == -1) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to convert pcodns1!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
dns2.s_addr = 0;
|
||||
if (args_info.pcodns2_arg) {
|
||||
dns2.s_addr = inet_addr(args_info.pcodns2_arg);
|
||||
if (dns2.s_addr == -1) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to convert pcodns2!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
dns1.s_addr = 0;
|
||||
if (args_info.pcodns1_arg) {
|
||||
dns1.s_addr = inet_addr(args_info.pcodns1_arg);
|
||||
if (dns1.s_addr == -1) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to convert pcodns1!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
dns2.s_addr = 0;
|
||||
if (args_info.pcodns2_arg) {
|
||||
dns2.s_addr = inet_addr(args_info.pcodns2_arg);
|
||||
if (dns2.s_addr == -1) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to convert pcodns2!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pco.l = 20;
|
||||
pco.v[0] = 0x80; /* x0000yyy x=1, yyy=000: PPP */
|
||||
pco.v[1] = 0x80; /* IPCP */
|
||||
pco.v[2] = 0x21;
|
||||
pco.v[3] = 0x10; /* Length of contents */
|
||||
pco.v[4] = 0x02; /* ACK */
|
||||
pco.v[5] = 0x00; /* ID: Need to match request */
|
||||
pco.v[6] = 0x00; /* Length */
|
||||
pco.v[7] = 0x10;
|
||||
pco.v[8] = 0x81; /* DNS 1 */
|
||||
pco.v[9] = 0x06;
|
||||
memcpy(&pco.v[10], &dns1, sizeof(dns1));
|
||||
pco.v[14] = 0x83;
|
||||
pco.v[15] = 0x06; /* DNS 2 */
|
||||
memcpy(&pco.v[16], &dns2, sizeof(dns2));
|
||||
|
||||
pco.l = 20;
|
||||
pco.v[0] = 0x80; /* x0000yyy x=1, yyy=000: PPP */
|
||||
pco.v[1] = 0x80; /* IPCP */
|
||||
pco.v[2] = 0x21;
|
||||
pco.v[3] = 0x10; /* Length of contents */
|
||||
pco.v[4] = 0x02; /* ACK */
|
||||
pco.v[5] = 0x00; /* ID: Need to match request */
|
||||
pco.v[6] = 0x00; /* Length */
|
||||
pco.v[7] = 0x10;
|
||||
pco.v[8] = 0x81; /* DNS 1 */
|
||||
pco.v[9] = 0x06;
|
||||
memcpy(&pco.v[10], &dns1, sizeof(dns1));
|
||||
pco.v[14] = 0x83;
|
||||
pco.v[15] = 0x06; /* DNS 2 */
|
||||
memcpy(&pco.v[16], &dns2, sizeof(dns2));
|
||||
/* ipup */
|
||||
ipup = args_info.ipup_arg;
|
||||
|
||||
/* ipup */
|
||||
ipup = args_info.ipup_arg;
|
||||
/* ipdown */
|
||||
ipdown = args_info.ipdown_arg;
|
||||
|
||||
/* ipdown */
|
||||
ipdown = args_info.ipdown_arg;
|
||||
/* Timelimit */
|
||||
timelimit = args_info.timelimit_arg;
|
||||
starttime = time(NULL);
|
||||
|
||||
/* Timelimit */
|
||||
timelimit = args_info.timelimit_arg;
|
||||
starttime = time(NULL);
|
||||
|
||||
/* qos */
|
||||
qos.l = 3;
|
||||
qos.v[2] = (args_info.qos_arg) & 0xff;
|
||||
qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff;
|
||||
qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;
|
||||
/* qos */
|
||||
qos.l = 3;
|
||||
qos.v[2] = (args_info.qos_arg) & 0xff;
|
||||
qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff;
|
||||
qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;
|
||||
|
||||
/* apn */
|
||||
if (strlen(args_info.apn_arg) > (sizeof(apn.v)-1)) {
|
||||
printf("Invalid APN\n");
|
||||
return -1;
|
||||
}
|
||||
apn.l = strlen(args_info.apn_arg) + 1;
|
||||
apn.v[0] = (char) strlen(args_info.apn_arg);
|
||||
strncpy((char *) &apn.v[1], args_info.apn_arg, sizeof(apn.v)-1);
|
||||
/* apn */
|
||||
if (strlen(args_info.apn_arg) > (sizeof(apn.v) - 1)) {
|
||||
printf("Invalid APN\n");
|
||||
return -1;
|
||||
}
|
||||
apn.l = strlen(args_info.apn_arg) + 1;
|
||||
apn.v[0] = (char)strlen(args_info.apn_arg);
|
||||
strncpy((char *)&apn.v[1], args_info.apn_arg, sizeof(apn.v) - 1);
|
||||
|
||||
/* foreground */
|
||||
/* If flag not given run as a daemon */
|
||||
if (!args_info.fg_flag) {
|
||||
FILE *f;
|
||||
int rc;
|
||||
closelog();
|
||||
/* Close the standard file descriptors. */
|
||||
/* Is this really needed ? */
|
||||
f = freopen("/dev/null", "w", stdout);
|
||||
if (f == NULL) {
|
||||
sys_err(LOG_WARNING, __FILE__, __LINE__, 0,
|
||||
"Could not redirect stdout to /dev/null");
|
||||
}
|
||||
f = freopen("/dev/null", "w", stderr);
|
||||
if (f == NULL) {
|
||||
sys_err(LOG_WARNING, __FILE__, __LINE__, 0,
|
||||
"Could not redirect stderr to /dev/null");
|
||||
}
|
||||
f = freopen("/dev/null", "r", stdin);
|
||||
if (f == NULL) {
|
||||
sys_err(LOG_WARNING, __FILE__, __LINE__, 0,
|
||||
"Could not redirect stdin to /dev/null");
|
||||
}
|
||||
rc = daemon(0, 0);
|
||||
if (rc != 0) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, rc,
|
||||
"Could not daemonize");
|
||||
exit(1);
|
||||
}
|
||||
/* Open log again. This time with new pid */
|
||||
openlog(PACKAGE, LOG_PID, LOG_DAEMON);
|
||||
}
|
||||
|
||||
/* foreground */
|
||||
/* If flag not given run as a daemon */
|
||||
if (!args_info.fg_flag)
|
||||
{
|
||||
FILE *f;
|
||||
int rc;
|
||||
closelog();
|
||||
/* Close the standard file descriptors. */
|
||||
/* Is this really needed ? */
|
||||
f = freopen("/dev/null", "w", stdout);
|
||||
if (f == NULL) {
|
||||
sys_err(LOG_WARNING, __FILE__, __LINE__, 0,
|
||||
"Could not redirect stdout to /dev/null");
|
||||
}
|
||||
f = freopen("/dev/null", "w", stderr);
|
||||
if (f == NULL) {
|
||||
sys_err(LOG_WARNING, __FILE__, __LINE__, 0,
|
||||
"Could not redirect stderr to /dev/null");
|
||||
}
|
||||
f = freopen("/dev/null", "r", stdin);
|
||||
if (f == NULL) {
|
||||
sys_err(LOG_WARNING, __FILE__, __LINE__, 0,
|
||||
"Could not redirect stdin to /dev/null");
|
||||
}
|
||||
rc = daemon(0, 0);
|
||||
if (rc != 0) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, rc, "Could not daemonize");
|
||||
exit(1);
|
||||
}
|
||||
/* Open log again. This time with new pid */
|
||||
openlog(PACKAGE, LOG_PID, LOG_DAEMON);
|
||||
}
|
||||
/* pidfile */
|
||||
/* This has to be done after we have our final pid */
|
||||
if (args_info.pidfile_arg) {
|
||||
log_pid(args_info.pidfile_arg);
|
||||
}
|
||||
|
||||
/* pidfile */
|
||||
/* This has to be done after we have our final pid */
|
||||
if (args_info.pidfile_arg) {
|
||||
log_pid(args_info.pidfile_arg);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
printf("gtpclient: Initialising GTP tunnel\n");
|
||||
|
||||
if (debug) printf("gtpclient: Initialising GTP tunnel\n");
|
||||
|
||||
if (gtp_new(&gsn, args_info.statedir_arg, &listen_, GTP_MODE_GGSN)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to create gtp");
|
||||
exit(1);
|
||||
}
|
||||
if (gsn->fd0 > maxfd) maxfd = gsn->fd0;
|
||||
if (gsn->fd1c > maxfd) maxfd = gsn->fd1c;
|
||||
if (gsn->fd1u > maxfd) maxfd = gsn->fd1u;
|
||||
if (gtp_new(&gsn, args_info.statedir_arg, &listen_, GTP_MODE_GGSN)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Failed to create gtp");
|
||||
exit(1);
|
||||
}
|
||||
if (gsn->fd0 > maxfd)
|
||||
maxfd = gsn->fd0;
|
||||
if (gsn->fd1c > maxfd)
|
||||
maxfd = gsn->fd1c;
|
||||
if (gsn->fd1u > maxfd)
|
||||
maxfd = gsn->fd1u;
|
||||
|
||||
gtp_set_cb_data_ind(gsn, encaps_tun);
|
||||
gtp_set_cb_delete_context(gsn, delete_context);
|
||||
gtp_set_cb_create_context_ind(gsn, create_context_ind);
|
||||
gtp_set_cb_data_ind(gsn, encaps_tun);
|
||||
gtp_set_cb_delete_context(gsn, delete_context);
|
||||
gtp_set_cb_create_context_ind(gsn, create_context_ind);
|
||||
|
||||
/* Create a tunnel interface */
|
||||
if (debug)
|
||||
printf("Creating tun interface\n");
|
||||
if (tun_new((struct tun_t **)&tun)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Failed to create tun");
|
||||
if (debug)
|
||||
printf("Failed to create tun\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Create a tunnel interface */
|
||||
if (debug) printf("Creating tun interface\n");
|
||||
if (tun_new((struct tun_t**) &tun)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to create tun");
|
||||
if (debug) printf("Failed to create tun\n");
|
||||
exit(1);
|
||||
}
|
||||
if (debug)
|
||||
printf("Setting tun IP address\n");
|
||||
if (tun_setaddr(tun, &netaddr, &destaddr, &mask)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to set tun IP address");
|
||||
if (debug)
|
||||
printf("Failed to set tun IP address\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (debug) printf("Setting tun IP address\n");
|
||||
if (tun_setaddr(tun, &netaddr, &destaddr, &mask)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"Failed to set tun IP address");
|
||||
if (debug) printf("Failed to set tun IP address\n");
|
||||
exit(1);
|
||||
}
|
||||
tun_set_cb_ind(tun, cb_tun_ind);
|
||||
if (tun->fd > maxfd)
|
||||
maxfd = tun->fd;
|
||||
|
||||
|
||||
tun_set_cb_ind(tun, cb_tun_ind);
|
||||
if (tun->fd > maxfd) maxfd = tun->fd;
|
||||
|
||||
if (ipup) tun_runscript(tun, ipup);
|
||||
if (ipup)
|
||||
tun_runscript(tun, ipup);
|
||||
|
||||
/******************************************************************/
|
||||
/* Main select loop */
|
||||
/* Main select loop */
|
||||
/******************************************************************/
|
||||
|
||||
while ((((starttime + timelimit) > time(NULL)) || (0 == timelimit)) && (!end)) {
|
||||
while ((((starttime + timelimit) > time(NULL)) || (0 == timelimit))
|
||||
&& (!end)) {
|
||||
|
||||
FD_ZERO(&fds);
|
||||
if (tun) FD_SET(tun->fd, &fds);
|
||||
FD_SET(gsn->fd0, &fds);
|
||||
FD_SET(gsn->fd1c, &fds);
|
||||
FD_SET(gsn->fd1u, &fds);
|
||||
|
||||
gtp_retranstimeout(gsn, &idleTime);
|
||||
switch (select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
|
||||
case -1: /* errno == EINTR : unblocked signal */
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"select() returned -1");
|
||||
/* On error, select returns without modifying fds */
|
||||
FD_ZERO(&fds);
|
||||
break;
|
||||
case 0:
|
||||
/* printf("Select returned 0\n"); */
|
||||
gtp_retrans(gsn); /* Only retransmit if nothing else */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
FD_ZERO(&fds);
|
||||
if (tun)
|
||||
FD_SET(tun->fd, &fds);
|
||||
FD_SET(gsn->fd0, &fds);
|
||||
FD_SET(gsn->fd1c, &fds);
|
||||
FD_SET(gsn->fd1u, &fds);
|
||||
|
||||
if (tun->fd != -1 && FD_ISSET(tun->fd, &fds) &&
|
||||
tun_decaps(tun) < 0) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"TUN read failed (fd)=(%d)", tun->fd);
|
||||
}
|
||||
|
||||
if (FD_ISSET(gsn->fd0, &fds))
|
||||
gtp_decaps0(gsn);
|
||||
|
||||
if (FD_ISSET(gsn->fd1c, &fds))
|
||||
gtp_decaps1c(gsn);
|
||||
|
||||
if (FD_ISSET(gsn->fd1u, &fds))
|
||||
gtp_decaps1u(gsn);
|
||||
|
||||
}
|
||||
gtp_retranstimeout(gsn, &idleTime);
|
||||
switch (select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
|
||||
case -1: /* errno == EINTR : unblocked signal */
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"select() returned -1");
|
||||
/* On error, select returns without modifying fds */
|
||||
FD_ZERO(&fds);
|
||||
break;
|
||||
case 0:
|
||||
/* printf("Select returned 0\n"); */
|
||||
gtp_retrans(gsn); /* Only retransmit if nothing else */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (tun->fd != -1 && FD_ISSET(tun->fd, &fds) &&
|
||||
tun_decaps(tun) < 0) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
|
||||
"TUN read failed (fd)=(%d)", tun->fd);
|
||||
}
|
||||
|
||||
if (FD_ISSET(gsn->fd0, &fds))
|
||||
gtp_decaps0(gsn);
|
||||
|
||||
if (FD_ISSET(gsn->fd1c, &fds))
|
||||
gtp_decaps1c(gsn);
|
||||
|
||||
if (FD_ISSET(gsn->fd1u, &fds))
|
||||
gtp_decaps1u(gsn);
|
||||
|
||||
}
|
||||
|
||||
cmdline_parser_free(&args_info);
|
||||
ippool_free(ippool);
|
||||
gtp_free(gsn);
|
||||
tun_free(tun);
|
||||
|
||||
return 1;
|
||||
|
||||
cmdline_parser_free(&args_info);
|
||||
ippool_free(ippool);
|
||||
gtp_free(gsn);
|
||||
tun_free(tun);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
|
441
gtp/gtp.h
441
gtp/gtp.h
|
@ -12,7 +12,7 @@
|
|||
#ifndef _GTP_H
|
||||
#define _GTP_H
|
||||
|
||||
#define GTP_DEBUG 0 /* Print debug information */
|
||||
#define GTP_DEBUG 0 /* Print debug information */
|
||||
|
||||
#define GTP_MODE_GGSN 1
|
||||
#define GTP_MODE_SGSN 2
|
||||
|
@ -22,7 +22,7 @@
|
|||
#define GTP1U_PORT 2152
|
||||
#define PACKET_MAX 8196
|
||||
|
||||
#define GTP_MAX 0xffff /* TODO: Choose right number */
|
||||
#define GTP_MAX 0xffff /* TODO: Choose right number */
|
||||
#define GTP0_HEADER_SIZE 20
|
||||
#define GTP1_HEADER_SIZE_SHORT 8
|
||||
#define GTP1_HEADER_SIZE_LONG 12
|
||||
|
@ -34,107 +34,104 @@
|
|||
#define NAMESIZE 1024
|
||||
|
||||
/* GTP version 1 extension header type definitions. */
|
||||
#define GTP_EXT_PDCP_PDU 0xC0 /* PDCP PDU Number */
|
||||
#define GTP_EXT_PDCP_PDU 0xC0 /* PDCP PDU Number */
|
||||
|
||||
/* GTP version 1 message type definitions. Also covers version 0 except *
|
||||
* for anonymous PDP context which was superceded in version 1 */
|
||||
|
||||
/* 0 For future use. */
|
||||
#define GTP_ECHO_REQ 1 /* Echo Request */
|
||||
#define GTP_ECHO_RSP 2 /* Echo Response */
|
||||
#define GTP_NOT_SUPPORTED 3 /* Version Not Supported */
|
||||
#define GTP_ALIVE_REQ 4 /* Node Alive Request */
|
||||
#define GTP_ALIVE_RSP 5 /* Node Alive Response */
|
||||
#define GTP_REDIR_REQ 6 /* Redirection Request */
|
||||
#define GTP_REDIR_RSP 7 /* Redirection Response */
|
||||
#define GTP_ECHO_REQ 1 /* Echo Request */
|
||||
#define GTP_ECHO_RSP 2 /* Echo Response */
|
||||
#define GTP_NOT_SUPPORTED 3 /* Version Not Supported */
|
||||
#define GTP_ALIVE_REQ 4 /* Node Alive Request */
|
||||
#define GTP_ALIVE_RSP 5 /* Node Alive Response */
|
||||
#define GTP_REDIR_REQ 6 /* Redirection Request */
|
||||
#define GTP_REDIR_RSP 7 /* Redirection Response */
|
||||
/* 8-15 For future use. */
|
||||
#define GTP_CREATE_PDP_REQ 16 /* Create PDP Context Request */
|
||||
#define GTP_CREATE_PDP_RSP 17 /* Create PDP Context Response */
|
||||
#define GTP_UPDATE_PDP_REQ 18 /* Update PDP Context Request */
|
||||
#define GTP_UPDATE_PDP_RSP 19 /* Update PDP Context Response */
|
||||
#define GTP_DELETE_PDP_REQ 20 /* Delete PDP Context Request */
|
||||
#define GTP_DELETE_PDP_RSP 21 /* Delete PDP Context Response */
|
||||
/* 22-25 For future use. */ /* In version GTP 1 anonomous PDP context */
|
||||
#define GTP_ERROR 26 /* Error Indication */
|
||||
#define GTP_PDU_NOT_REQ 27 /* PDU Notification Request */
|
||||
#define GTP_PDU_NOT_RSP 28 /* PDU Notification Response */
|
||||
#define GTP_PDU_NOT_REJ_REQ 29 /* PDU Notification Reject Request */
|
||||
#define GTP_PDU_NOT_REJ_RSP 30 /* PDU Notification Reject Response */
|
||||
#define GTP_SUPP_EXT_HEADER 31 /* Supported Extension Headers Notification */
|
||||
#define GTP_SND_ROUTE_REQ 32 /* Send Routeing Information for GPRS Request */
|
||||
#define GTP_SND_ROUTE_RSP 33 /* Send Routeing Information for GPRS Response */
|
||||
#define GTP_FAILURE_REQ 34 /* Failure Report Request */
|
||||
#define GTP_FAILURE_RSP 35 /* Failure Report Response */
|
||||
#define GTP_MS_PRESENT_REQ 36 /* Note MS GPRS Present Request */
|
||||
#define GTP_MS_PRESENT_RSP 37 /* Note MS GPRS Present Response */
|
||||
/* 38-47 For future use. */
|
||||
#define GTP_IDEN_REQ 48 /* Identification Request */
|
||||
#define GTP_IDEN_RSP 49 /* Identification Response */
|
||||
#define GTP_SGSN_CONTEXT_REQ 50 /* SGSN Context Request */
|
||||
#define GTP_SGSN_CONTEXT_RSP 51 /* SGSN Context Response */
|
||||
#define GTP_SGSN_CONTEXT_ACK 52 /* SGSN Context Acknowledge */
|
||||
#define GTP_FWD_RELOC_REQ 53 /* Forward Relocation Request */
|
||||
#define GTP_FWD_RELOC_RSP 54 /* Forward Relocation Response */
|
||||
#define GTP_FWD_RELOC_COMPL 55 /* Forward Relocation Complete */
|
||||
#define GTP_RELOC_CANCEL_REQ 56 /* Relocation Cancel Request */
|
||||
#define GTP_RELOC_CANCEL_RSP 57 /* Relocation Cancel Response */
|
||||
#define GTP_FWD_SRNS 58 /* Forward SRNS Context */
|
||||
#define GTP_FWD_RELOC_ACK 59 /* Forward Relocation Complete Acknowledge */
|
||||
#define GTP_FWD_SRNS_ACK 60 /* Forward SRNS Context Acknowledge */
|
||||
#define GTP_CREATE_PDP_REQ 16 /* Create PDP Context Request */
|
||||
#define GTP_CREATE_PDP_RSP 17 /* Create PDP Context Response */
|
||||
#define GTP_UPDATE_PDP_REQ 18 /* Update PDP Context Request */
|
||||
#define GTP_UPDATE_PDP_RSP 19 /* Update PDP Context Response */
|
||||
#define GTP_DELETE_PDP_REQ 20 /* Delete PDP Context Request */
|
||||
#define GTP_DELETE_PDP_RSP 21 /* Delete PDP Context Response */
|
||||
/* 22-25 For future use. *//* In version GTP 1 anonomous PDP context */
|
||||
#define GTP_ERROR 26 /* Error Indication */
|
||||
#define GTP_PDU_NOT_REQ 27 /* PDU Notification Request */
|
||||
#define GTP_PDU_NOT_RSP 28 /* PDU Notification Response */
|
||||
#define GTP_PDU_NOT_REJ_REQ 29 /* PDU Notification Reject Request */
|
||||
#define GTP_PDU_NOT_REJ_RSP 30 /* PDU Notification Reject Response */
|
||||
#define GTP_SUPP_EXT_HEADER 31 /* Supported Extension Headers Notification */
|
||||
#define GTP_SND_ROUTE_REQ 32 /* Send Routeing Information for GPRS Request */
|
||||
#define GTP_SND_ROUTE_RSP 33 /* Send Routeing Information for GPRS Response */
|
||||
#define GTP_FAILURE_REQ 34 /* Failure Report Request */
|
||||
#define GTP_FAILURE_RSP 35 /* Failure Report Response */
|
||||
#define GTP_MS_PRESENT_REQ 36 /* Note MS GPRS Present Request */
|
||||
#define GTP_MS_PRESENT_RSP 37 /* Note MS GPRS Present Response */
|
||||
/* 38-47 For future use. */
|
||||
#define GTP_IDEN_REQ 48 /* Identification Request */
|
||||
#define GTP_IDEN_RSP 49 /* Identification Response */
|
||||
#define GTP_SGSN_CONTEXT_REQ 50 /* SGSN Context Request */
|
||||
#define GTP_SGSN_CONTEXT_RSP 51 /* SGSN Context Response */
|
||||
#define GTP_SGSN_CONTEXT_ACK 52 /* SGSN Context Acknowledge */
|
||||
#define GTP_FWD_RELOC_REQ 53 /* Forward Relocation Request */
|
||||
#define GTP_FWD_RELOC_RSP 54 /* Forward Relocation Response */
|
||||
#define GTP_FWD_RELOC_COMPL 55 /* Forward Relocation Complete */
|
||||
#define GTP_RELOC_CANCEL_REQ 56 /* Relocation Cancel Request */
|
||||
#define GTP_RELOC_CANCEL_RSP 57 /* Relocation Cancel Response */
|
||||
#define GTP_FWD_SRNS 58 /* Forward SRNS Context */
|
||||
#define GTP_FWD_RELOC_ACK 59 /* Forward Relocation Complete Acknowledge */
|
||||
#define GTP_FWD_SRNS_ACK 60 /* Forward SRNS Context Acknowledge */
|
||||
/* 61-239 For future use. */
|
||||
#define GTP_DATA_TRAN_REQ 240 /* Data Record Transfer Request */
|
||||
#define GTP_DATA_TRAN_RSP 241 /* Data Record Transfer Response */
|
||||
#define GTP_DATA_TRAN_REQ 240 /* Data Record Transfer Request */
|
||||
#define GTP_DATA_TRAN_RSP 241 /* Data Record Transfer Response */
|
||||
/* 242-254 For future use. */
|
||||
#define GTP_GPDU 255 /* G-PDU */
|
||||
|
||||
#define GTP_GPDU 255 /* G-PDU */
|
||||
|
||||
/* GTP information element cause codes from 29.060 v3.9.0 7.7 */
|
||||
/* */
|
||||
#define GTPCAUSE_REQ_IMSI 0 /* Request IMSI */
|
||||
#define GTPCAUSE_REQ_IMEI 1 /* Request IMEI */
|
||||
#define GTPCAUSE_REQ_IMSI_IMEI 2 /* Request IMSI and IMEI */
|
||||
#define GTPCAUSE_NO_ID_NEEDED 3 /* No identity needed */
|
||||
#define GTPCAUSE_MS_REFUSES_X 4 /* MS refuses */
|
||||
#define GTPCAUSE_MS_NOT_RESP_X 5 /* MS is not GPRS responding */
|
||||
#define GTPCAUSE_006 6 /* For future use 6-48 */
|
||||
#define GTPCAUSE_049 49 /* Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) 49-63 */
|
||||
#define GTPCAUSE_064 64 /* For future use 64-127 */
|
||||
#define GTPCAUSE_ACC_REQ 128 /* Request accepted */
|
||||
#define GTPCAUSE_129 129 /* For future use 129-176 */
|
||||
#define GTPCAUSE_177 177 /* Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) 177-191 */
|
||||
#define GTPCAUSE_NON_EXIST 192 /* Non-existent */
|
||||
#define GTPCAUSE_INVALID_MESSAGE 193 /* Invalid message format */
|
||||
#define GTPCAUSE_IMSI_NOT_KNOWN 194 /* IMSI not known */
|
||||
#define GTPCAUSE_MS_DETACHED 195 /* MS is GPRS detached */
|
||||
#define GTPCAUSE_MS_NOT_RESP 196 /* MS is not GPRS responding */
|
||||
#define GTPCAUSE_MS_REFUSES 197 /* MS refuses */
|
||||
#define GTPCAUSE_198 198 /* For future use */
|
||||
#define GTPCAUSE_NO_RESOURCES 199 /* No resources available */
|
||||
#define GTPCAUSE_NOT_SUPPORTED 200 /* Service not supported */
|
||||
#define GTPCAUSE_MAN_IE_INCORRECT 201 /* Mandatory IE incorrect */
|
||||
#define GTPCAUSE_MAN_IE_MISSING 202 /* Mandatory IE missing */
|
||||
#define GTPCAUSE_OPT_IE_INCORRECT 203 /* Optional IE incorrect */
|
||||
#define GTPCAUSE_SYS_FAIL 204 /* System failure */
|
||||
#define GTPCAUSE_ROAMING_REST 205 /* Roaming Restriction */
|
||||
#define GTPCAUSE_PTIMSI_MISMATCH 206 /* P-TMSI signature mismatch */
|
||||
#define GTPCAUSE_CONN_SUSP 207 /* GPRS connection suspended */
|
||||
#define GTPCAUSE_AUTH_FAIL 208 /* Authentication failure */
|
||||
#define GTPCAUSE_USER_AUTH_FAIL 209 /* User authentication failed */
|
||||
#define GTPCAUSE_CONTEXT_NOT_FOUND 210 /* Context not found */
|
||||
#define GTPCAUSE_ADDR_OCCUPIED 211 /* All dynamic PDP addresses are occupied */
|
||||
#define GTPCAUSE_NO_MEMORY 212 /* No memory is available */
|
||||
#define GTPCAUSE_RELOC_FAIL 213 /* Relocation failure */
|
||||
#define GTPCAUSE_UNKNOWN_MAN_EXTHEADER 214 /* Unknown mandatory extension header */
|
||||
#define GTPCAUSE_SEM_ERR_TFT 215 /* Semantic error in the TFT operation */
|
||||
#define GTPCAUSE_SYN_ERR_TFT 216 /* Syntactic error in the TFT operation */
|
||||
#define GTPCAUSE_SEM_ERR_FILTER 217 /* Semantic errors in packet filter(s) */
|
||||
#define GTPCAUSE_SYN_ERR_FILTER 218 /* Syntactic errors in packet filter(s) */
|
||||
#define GTPCAUSE_MISSING_APN 219 /* Missing or unknown APN*/
|
||||
#define GTPCAUSE_UNKNOWN_PDP 220 /* Unknown PDP address or PDP type */
|
||||
#define GTPCAUSE_221 221 /* For Future Use 221-240 */
|
||||
#define GTPCAUSE_241 241 /* Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) 241-255 */
|
||||
|
||||
|
||||
#define GTPCAUSE_REQ_IMSI 0 /* Request IMSI */
|
||||
#define GTPCAUSE_REQ_IMEI 1 /* Request IMEI */
|
||||
#define GTPCAUSE_REQ_IMSI_IMEI 2 /* Request IMSI and IMEI */
|
||||
#define GTPCAUSE_NO_ID_NEEDED 3 /* No identity needed */
|
||||
#define GTPCAUSE_MS_REFUSES_X 4 /* MS refuses */
|
||||
#define GTPCAUSE_MS_NOT_RESP_X 5 /* MS is not GPRS responding */
|
||||
#define GTPCAUSE_006 6 /* For future use 6-48 */
|
||||
#define GTPCAUSE_049 49 /* Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) 49-63 */
|
||||
#define GTPCAUSE_064 64 /* For future use 64-127 */
|
||||
#define GTPCAUSE_ACC_REQ 128 /* Request accepted */
|
||||
#define GTPCAUSE_129 129 /* For future use 129-176 */
|
||||
#define GTPCAUSE_177 177 /* Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) 177-191 */
|
||||
#define GTPCAUSE_NON_EXIST 192 /* Non-existent */
|
||||
#define GTPCAUSE_INVALID_MESSAGE 193 /* Invalid message format */
|
||||
#define GTPCAUSE_IMSI_NOT_KNOWN 194 /* IMSI not known */
|
||||
#define GTPCAUSE_MS_DETACHED 195 /* MS is GPRS detached */
|
||||
#define GTPCAUSE_MS_NOT_RESP 196 /* MS is not GPRS responding */
|
||||
#define GTPCAUSE_MS_REFUSES 197 /* MS refuses */
|
||||
#define GTPCAUSE_198 198 /* For future use */
|
||||
#define GTPCAUSE_NO_RESOURCES 199 /* No resources available */
|
||||
#define GTPCAUSE_NOT_SUPPORTED 200 /* Service not supported */
|
||||
#define GTPCAUSE_MAN_IE_INCORRECT 201 /* Mandatory IE incorrect */
|
||||
#define GTPCAUSE_MAN_IE_MISSING 202 /* Mandatory IE missing */
|
||||
#define GTPCAUSE_OPT_IE_INCORRECT 203 /* Optional IE incorrect */
|
||||
#define GTPCAUSE_SYS_FAIL 204 /* System failure */
|
||||
#define GTPCAUSE_ROAMING_REST 205 /* Roaming Restriction */
|
||||
#define GTPCAUSE_PTIMSI_MISMATCH 206 /* P-TMSI signature mismatch */
|
||||
#define GTPCAUSE_CONN_SUSP 207 /* GPRS connection suspended */
|
||||
#define GTPCAUSE_AUTH_FAIL 208 /* Authentication failure */
|
||||
#define GTPCAUSE_USER_AUTH_FAIL 209 /* User authentication failed */
|
||||
#define GTPCAUSE_CONTEXT_NOT_FOUND 210 /* Context not found */
|
||||
#define GTPCAUSE_ADDR_OCCUPIED 211 /* All dynamic PDP addresses are occupied */
|
||||
#define GTPCAUSE_NO_MEMORY 212 /* No memory is available */
|
||||
#define GTPCAUSE_RELOC_FAIL 213 /* Relocation failure */
|
||||
#define GTPCAUSE_UNKNOWN_MAN_EXTHEADER 214 /* Unknown mandatory extension header */
|
||||
#define GTPCAUSE_SEM_ERR_TFT 215 /* Semantic error in the TFT operation */
|
||||
#define GTPCAUSE_SYN_ERR_TFT 216 /* Syntactic error in the TFT operation */
|
||||
#define GTPCAUSE_SEM_ERR_FILTER 217 /* Semantic errors in packet filter(s) */
|
||||
#define GTPCAUSE_SYN_ERR_FILTER 218 /* Syntactic errors in packet filter(s) */
|
||||
#define GTPCAUSE_MISSING_APN 219 /* Missing or unknown APN */
|
||||
#define GTPCAUSE_UNKNOWN_PDP 220 /* Unknown PDP address or PDP type */
|
||||
#define GTPCAUSE_221 221 /* For Future Use 221-240 */
|
||||
#define GTPCAUSE_241 241 /* Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) 241-255 */
|
||||
|
||||
/* GTP 0 header.
|
||||
* Explanation to some of the fields:
|
||||
|
@ -147,75 +144,72 @@
|
|||
* Tunnel ID is IMSI+NSAPI. Unique identifier of PDP context. Is somewhat
|
||||
* redundant because the header also includes flow. */
|
||||
|
||||
struct gtp0_header { /* Descriptions from 3GPP 09.60 */
|
||||
uint8_t flags; /* 01 bitfield, with typical values */
|
||||
/* 000..... Version: 1 (0) */
|
||||
/* ...1111. Spare (7) */
|
||||
/* .......0 SNDCP N-PDU Number flag (0) */
|
||||
uint8_t type; /* 02 Message type. T-PDU = 0xff */
|
||||
uint16_t length; /* 03 Length (of G-PDU excluding header) */
|
||||
uint16_t seq; /* 05 Sequence Number */
|
||||
uint16_t flow; /* 07 Flow Label ( = 0 for signalling) */
|
||||
uint8_t number; /* 09 SNDCP N-PDU LCC Number ( 0 = 0xff) */
|
||||
uint8_t spare1; /* 10 Spare */
|
||||
uint8_t spare2; /* 11 Spare */
|
||||
uint8_t spare3; /* 12 Spare */
|
||||
uint64_t tid; /* 13 Tunnel ID */
|
||||
}; /* 20 */
|
||||
struct gtp0_header { /* Descriptions from 3GPP 09.60 */
|
||||
uint8_t flags; /* 01 bitfield, with typical values */
|
||||
/* 000..... Version: 1 (0) */
|
||||
/* ...1111. Spare (7) */
|
||||
/* .......0 SNDCP N-PDU Number flag (0) */
|
||||
uint8_t type; /* 02 Message type. T-PDU = 0xff */
|
||||
uint16_t length; /* 03 Length (of G-PDU excluding header) */
|
||||
uint16_t seq; /* 05 Sequence Number */
|
||||
uint16_t flow; /* 07 Flow Label ( = 0 for signalling) */
|
||||
uint8_t number; /* 09 SNDCP N-PDU LCC Number ( 0 = 0xff) */
|
||||
uint8_t spare1; /* 10 Spare */
|
||||
uint8_t spare2; /* 11 Spare */
|
||||
uint8_t spare3; /* 12 Spare */
|
||||
uint64_t tid; /* 13 Tunnel ID */
|
||||
}; /* 20 */
|
||||
|
||||
struct gtp1_header_short { /* Descriptions from 3GPP 29060 */
|
||||
uint8_t flags; /* 01 bitfield, with typical values */
|
||||
/* 001..... Version: 1 */
|
||||
/* ...1.... Protocol Type: GTP=1, GTP'=0 */
|
||||
/* ....0... Spare = 0 */
|
||||
/* .....0.. Extension header flag: 0 */
|
||||
/* ......0. Sequence number flag: 0 */
|
||||
/* .......0 PN: N-PDU Number flag */
|
||||
uint8_t type; /* 02 Message type. T-PDU = 0xff */
|
||||
uint16_t length; /* 03 Length (of IP packet or signalling) */
|
||||
uint32_t tei; /* 05 - 08 Tunnel Endpoint ID */
|
||||
struct gtp1_header_short { /* Descriptions from 3GPP 29060 */
|
||||
uint8_t flags; /* 01 bitfield, with typical values */
|
||||
/* 001..... Version: 1 */
|
||||