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.
This commit is contained in:
Harald Welte 2011-11-02 13:06:18 +01:00
parent ca36f29364
commit bed35df298
27 changed files with 10990 additions and 10338 deletions

File diff suppressed because it is too large Load Diff

View File

@ -22,104 +22,103 @@ extern "C" {
#define CMDLINE_PARSER_VERSION VERSION
#endif
struct gengetopt_args_info
{
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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[];
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,
int cmdline_parser(int argc, char *const *argv,
struct gengetopt_args_info *args_info);
int cmdline_parser2 (int argc, char * const *argv,
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,
int cmdline_parser_file_save(const char *filename,
struct gengetopt_args_info *args_info);
void cmdline_parser_print_help(void);
void cmdline_parser_print_version(void);
void cmdline_parser_print_help(void);
void cmdline_parser_print_version(void);
void cmdline_parser_init (struct gengetopt_args_info *args_info);
void cmdline_parser_free (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);
int cmdline_parser_configfile (char * const filename,
int cmdline_parser_configfile(char *const filename,
struct gengetopt_args_info *args_info,
int override, int initialize, int check_required);
int override, int initialize,
int check_required);
int cmdline_parser_required (struct gengetopt_args_info *args_info,
int cmdline_parser_required(struct gengetopt_args_info *args_info,
const char *prog_name);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -71,30 +71,34 @@ 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);
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) {
void log_pid(char *pidfile)
{
FILE *file;
mode_t oldmask;
oldmask = umask(022);
file = fopen(pidfile, "w");
umask(oldmask);
if(!file) {
if (!file) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Failed to create process ID file: %s!", pidfile);
return;
}
fprintf(file, "%d\n", (int) getpid());
fprintf(file, "%d\n", (int)getpid());
fclose(file);
}
#if defined(__sun__)
int daemon(int nochdir, int noclose) {
int daemon(int nochdir, int noclose)
{
int fd;
switch (fork()) {
@ -109,50 +113,55 @@ int daemon(int nochdir, int noclose) {
if (setsid() == -1)
return (-1);
if (!nochdir) chdir("/");
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);
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");
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");
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);
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) {
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));
@ -179,33 +188,36 @@ int create_context_ind(struct pdp_t *pdp) {
return 0; /* Success */
}
/* Callback for receiving messages from tun */
int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len) {
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;
struct tun_packet_t *iph = (struct tun_packet_t *)pack;
dst.s_addr = iph->dst;
if (debug) printf("Received packet from tun!\n");
if (debug)
printf("Received packet from tun!\n");
if (ippool_getip(ippool, &ipm, &dst)) {
if (debug) printf("Received packet with no destination!!!\n");
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);
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 */
@ -215,8 +227,8 @@ int main(int argc, char **argv)
/* Handle keyboard interrupt SIGINT */
struct sigaction s;
s.sa_handler = (void *) signal_handler;
if ((0 != sigemptyset( &s.sa_mask )) && debug)
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)
@ -225,12 +237,11 @@ int main(int argc, char **argv)
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 */
/* open a connection to the syslog daemon */
/*openlog(PACKAGE, LOG_PID, LOG_DAEMON);*/
/*openlog(PACKAGE, LOG_PID, LOG_DAEMON); */
/* TODO: Only use LOG__PERROR for linux */
#ifdef __linux__
@ -239,29 +250,38 @@ int main(int argc, char **argv)
openlog(PACKAGE, (LOG_PID), LOG_DAEMON);
#endif
if (cmdline_parser (argc, argv, &args_info) != 0)
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);
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);
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 */
if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0, 0, 0) != 0)
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");
@ -270,14 +290,22 @@ int main(int argc, char **argv)
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);
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);
}
@ -293,14 +321,13 @@ int main(int argc, char **argv)
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);
"Invalid listening address: %s!",
args_info.listen_arg);
exit(1);
}
else {
} else {
memcpy(&listen_.s_addr, host->h_addr, host->h_length);
}
}
else {
} else {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Listening address must be specified! "
"Please use command line option --listen or "
@ -308,36 +335,37 @@ int main(int argc, char **argv)
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)) {
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);
"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 {
} else {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Network address must be specified: %s!", args_info.net_arg);
"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)) {
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)) {
} 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);
@ -383,7 +411,6 @@ int main(int argc, char **argv)
}
#endif
pco.l = 20;
pco.v[0] = 0x80; /* x0000yyy x=1, yyy=000: PPP */
pco.v[1] = 0x80; /* IPCP */
@ -417,19 +444,17 @@ int main(int argc, char **argv)
qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;
/* apn */
if (strlen(args_info.apn_arg) > (sizeof(apn.v)-1)) {
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.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)
{
if (!args_info.fg_flag) {
FILE *f;
int rc;
closelog();
@ -452,7 +477,8 @@ int main(int argc, char **argv)
}
rc = daemon(0, 0);
if (rc != 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, rc, "Could not daemonize");
sys_err(LOG_ERR, __FILE__, __LINE__, rc,
"Could not daemonize");
exit(1);
}
/* Open log again. This time with new pid */
@ -465,54 +491,61 @@ int main(int argc, char **argv)
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");
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 (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);
/* 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");
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 (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");
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;
if (tun->fd > maxfd)
maxfd = tun->fd;
if (ipup) tun_runscript(tun, ipup);
if (ipup)
tun_runscript(tun, ipup);
/******************************************************************/
/* 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);
if (tun)
FD_SET(tun->fd, &fds);
FD_SET(gsn->fd0, &fds);
FD_SET(gsn->fd1c, &fds);
FD_SET(gsn->fd1u, &fds);
@ -558,4 +591,3 @@ int main(int argc, char **argv)
return 1;
}

1347
gtp/gtp.c

File diff suppressed because it is too large Load Diff

View File

@ -54,7 +54,7 @@
#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 */
/* 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 */
@ -87,7 +87,6 @@
/* 242-254 For future use. */
#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 */
@ -129,13 +128,11 @@
#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_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:
* SNDCP NPDU Number flag = 0 except for inter SGSN handover situations
@ -195,27 +192,24 @@ struct gtp1_header_long { /* Descriptions from 3GPP 29060 */
struct gtp0_packet {
struct gtp0_header h;
uint8_t p[GTP_MAX];
} __attribute__((packed));
} __attribute__ ((packed));
struct gtp1_packet_short {
struct gtp1_header_short h;
uint8_t p[GTP_MAX];
} __attribute__((packed));
} __attribute__ ((packed));
struct gtp1_packet_long {
struct gtp1_header_long h;
uint8_t p[GTP_MAX];
} __attribute__((packed));
} __attribute__ ((packed));
union gtp_packet {
uint8_t flags;
struct gtp0_packet gtp0;
struct gtp1_packet_short gtp1s;
struct gtp1_packet_long gtp1l;
} __attribute__((packed));
} __attribute__ ((packed));
/* ***********************************************************
* Information storage for each gsn instance
@ -254,13 +248,13 @@ struct gsn_t {
struct queue_t *queue_resp; /* Response queue */
/* Call back functions */
int (*cb_delete_context) (struct pdp_t*);
int (*cb_create_context_ind) (struct pdp_t*);
int (*cb_unsup_ind) (struct sockaddr_in *peer);
int (*cb_extheader_ind) (struct sockaddr_in *peer);
int (*cb_conf) (int type, int cause, struct pdp_t *pdp, void* cbp);
int (*cb_data_ind) (struct pdp_t* pdp, void* pack, unsigned len);
int (*cb_recovery) (struct sockaddr_in *peer, uint8_t recovery);
int (*cb_delete_context) (struct pdp_t *);
int (*cb_create_context_ind) (struct pdp_t *);
int (*cb_unsup_ind) (struct sockaddr_in * peer);
int (*cb_extheader_ind) (struct sockaddr_in * peer);
int (*cb_conf) (int type, int cause, struct pdp_t * pdp, void *cbp);
int (*cb_data_ind) (struct pdp_t * pdp, void *pack, unsigned len);
int (*cb_recovery) (struct sockaddr_in * peer, uint8_t recovery);
/* Counters */
@ -287,10 +281,9 @@ struct gsn_t {
uint64_t invalid; /* Number of invalid message format messages */
};
/* External API functions */
extern const char* gtp_version();
extern const char *gtp_version();
extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
int mode);
@ -304,13 +297,15 @@ extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
void *cbp);
extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
int (*cb_create_context_ind) (struct pdp_t* pdp));
int (*cb_create_context_ind) (struct
pdp_t *
pdp));
extern int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp,
int cause);
extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp,
void *cbp, struct in_addr* inetaddr);
void *cbp, struct in_addr *inetaddr);
extern int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
void *cbp, int teardown);
@ -319,8 +314,8 @@ extern int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp,
void *pack, unsigned len);
extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
int (*cb_data_ind) (struct pdp_t* pdp, void* pack, unsigned len));
int (*cb_data_ind) (struct pdp_t * pdp,
void *pack, unsigned len));
extern int gtp_fd(struct gsn_t *gsn);
extern int gtp_decaps0(struct gsn_t *gsn);
@ -330,22 +325,24 @@ extern int gtp_retrans(struct gsn_t *gsn);
extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout);
extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
int (*cb_delete_context) (struct pdp_t* pdp));
int (*cb_delete_context) (struct pdp_t *
pdp));
/*extern int gtp_set_cb_create_context(struct gsn_t *gsn,
int (*cb_create_context) (struct pdp_t* pdp)); */
extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in *peer));
int (*cb) (struct sockaddr_in * peer));
extern int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in *peer));
int (*cb) (struct sockaddr_in * peer));
extern int gtp_set_cb_conf(struct gsn_t *gsn,
int (*cb) (int type, int cause, struct pdp_t* pdp, void *cbp));
int (*cb) (int type, int cause, struct pdp_t * pdp,
void *cbp));
int gtp_set_cb_recovery(struct gsn_t *gsn,
int (*cb) (struct sockaddr_in *peer, uint8_t recovery));
int (*cb) (struct sockaddr_in * peer,
uint8_t recovery));
/* Internal functions (not part of the API */
@ -358,8 +355,7 @@ extern int gtp_echo_ind(struct gsn_t *gsn, int version,
struct sockaddr_in *peer, int fd,
void *pack, unsigned len);
extern int gtp_echo_conf(struct gsn_t *gsn, int version,
struct sockaddr_in *peer,
void *pack, unsigned len);
struct sockaddr_in *peer, void *pack, unsigned len);
extern int gtp_unsup_req(struct gsn_t *gsn, int version,
struct sockaddr_in *peer,
@ -379,7 +375,7 @@ extern int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
void *pack, unsigned len);
extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *cbp,
struct in_addr* inetaddr, struct pdp_t *pdp);
struct in_addr *inetaddr, struct pdp_t *pdp);
extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *cbp,
struct pdp_t *pdp);
@ -398,7 +394,6 @@ extern int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
struct sockaddr_in *peer,
void *pack, unsigned len);
extern int ipv42eua(struct ul66_t *eua, struct in_addr *src);
extern int eua2ipv4(struct in_addr *dst, struct ul66_t *eua);
extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna);

View File

@ -39,80 +39,103 @@
#include "gtpie.h"
int gtpie_tlv(void *p, unsigned int *length, unsigned int size, uint8_t t, int l, void *v) {
if ((*length + 3 + l) >= size) return 1;
((union gtpie_member*) (p + *length))->tlv.t = hton8(t);
((union gtpie_member*) (p + *length))->tlv.l = hton16(l);
memcpy((void*) (p + *length +3), v, l);
int gtpie_tlv(void *p, unsigned int *length, unsigned int size, uint8_t t,
int l, void *v)
{
if ((*length + 3 + l) >= size)
return 1;
((union gtpie_member *)(p + *length))->tlv.t = hton8(t);
((union gtpie_member *)(p + *length))->tlv.l = hton16(l);
memcpy((void *)(p + *length + 3), v, l);
*length += 3 + l;
return 0;
}
int gtpie_tv0(void *p, unsigned int *length, unsigned int size, uint8_t t, int l, uint8_t *v) {
if ((*length + 1 + l) >= size) return 1;
((union gtpie_member*) (p + *length))->tv0.t = hton8(t);
memcpy((void*) (p + *length +1), v, l);
int gtpie_tv0(void *p, unsigned int *length, unsigned int size, uint8_t t,
int l, uint8_t * v)
{
if ((*length + 1 + l) >= size)
return 1;
((union gtpie_member *)(p + *length))->tv0.t = hton8(t);
memcpy((void *)(p + *length + 1), v, l);
*length += 1 + l;
return 0;
}
int gtpie_tv1(void *p, unsigned int *length, unsigned int size, uint8_t t, uint8_t v) {
if ((*length + 2) >= size) return 1;
((union gtpie_member*) (p + *length))->tv1.t = hton8(t);
((union gtpie_member*) (p + *length))->tv1.v = hton8(v);
int gtpie_tv1(void *p, unsigned int *length, unsigned int size, uint8_t t,
uint8_t v)
{
if ((*length + 2) >= size)
return 1;
((union gtpie_member *)(p + *length))->tv1.t = hton8(t);
((union gtpie_member *)(p + *length))->tv1.v = hton8(v);
*length += 2;
return 0;
}
int gtpie_tv2(void *p, unsigned int *length, unsigned int size, uint8_t t, uint16_t v) {
if ((*length + 3) >= size) return 1;
((union gtpie_member*) (p + *length))->tv2.t = hton8(t);
((union gtpie_member*) (p + *length))->tv2.v = hton16(v);
int gtpie_tv2(void *p, unsigned int *length, unsigned int size, uint8_t t,
uint16_t v)
{
if ((*length + 3) >= size)
return 1;
((union gtpie_member *)(p + *length))->tv2.t = hton8(t);
((union gtpie_member *)(p + *length))->tv2.v = hton16(v);
*length += 3;
return 0;
}
int gtpie_tv4(void *p, unsigned int *length, unsigned int size, uint8_t t, uint32_t v) {
if ((*length + 5) >= size) return 1;
((union gtpie_member*) (p + *length))->tv4.t = hton8(t);
((union gtpie_member*) (p + *length))->tv4.v = hton32(v);
int gtpie_tv4(void *p, unsigned int *length, unsigned int size, uint8_t t,
uint32_t v)
{
if ((*length + 5) >= size)
return 1;
((union gtpie_member *)(p + *length))->tv4.t = hton8(t);
((union gtpie_member *)(p + *length))->tv4.v = hton32(v);
*length += 5;
return 0;
}
int gtpie_tv8(void *p, unsigned int *length, unsigned int size, uint8_t t, uint64_t v) {
if ((*length + 9) >= size) return 1;
((union gtpie_member*) (p + *length))->tv8.t = hton8(t);
((union gtpie_member*) (p + *length))->tv8.v = hton64(v);
int gtpie_tv8(void *p, unsigned int *length, unsigned int size, uint8_t t,
uint64_t v)
{
if ((*length + 9) >= size)
return 1;
((union gtpie_member *)(p + *length))->tv8.t = hton8(t);
((union gtpie_member *)(p + *length))->tv8.v = hton64(v);
*length += 9;
return 0;
}
int gtpie_getie(union gtpie_member* ie[], int type, int instance) {
int gtpie_getie(union gtpie_member *ie[], int type, int instance)
{
int j;
for (j=0; j< GTPIE_SIZE; j++) {
for (j = 0; j < GTPIE_SIZE; j++) {
if ((ie[j] != 0) && (ie[j]->t == type)) {
if (instance-- == 0) return j;
if (instance-- == 0)
return j;
}
}
return -1;
}
int gtpie_exist(union gtpie_member* ie[], int type, int instance) {
int gtpie_exist(union gtpie_member *ie[], int type, int instance)
{
int j;
for (j=0; j< GTPIE_SIZE; j++) {
for (j = 0; j < GTPIE_SIZE; j++) {
if ((ie[j] != 0) && (ie[j]->t == type)) {
if (instance-- == 0) return 1;
if (instance-- == 0)
return 1;
}
}
return 0;
}
int gtpie_gettlv(union gtpie_member* ie[], int type, int instance,
unsigned int *length, void *dst, unsigned int size){
int gtpie_gettlv(union gtpie_member *ie[], int type, int instance,
unsigned int *length, void *dst, unsigned int size)
{
int ien;
ien = gtpie_getie(ie, type, instance);
if (ien>=0) {
if (ien >= 0) {
*length = ntoh16(ie[ien]->tlv.l);
if (*length <= size)
memcpy(dst, ie[ien]->tlv.v, *length);
@ -122,78 +145,87 @@ int gtpie_gettlv(union gtpie_member* ie[], int type, int instance,
return 0;
}
int gtpie_gettv0(union gtpie_member* ie[], int type, int instance,
void *dst, unsigned int size){
int gtpie_gettv0(union gtpie_member *ie[], int type, int instance,
void *dst, unsigned int size)
{
int ien;
ien = gtpie_getie(ie, type, instance);
if (ien>=0)
if (ien >= 0)
memcpy(dst, ie[ien]->tv0.v, size);
else
return EOF;
return 0;
}
int gtpie_gettv1(union gtpie_member* ie[], int type, int instance,
uint8_t *dst){
int gtpie_gettv1(union gtpie_member *ie[], int type, int instance,
uint8_t * dst)
{
int ien;
ien = gtpie_getie(ie, type, instance);
if (ien>=0)
if (ien >= 0)
*dst = ntoh8(ie[ien]->tv1.v);
else
return EOF;
return 0;
}
int gtpie_gettv2(union gtpie_member* ie[], int type, int instance,
uint16_t *dst){
int gtpie_gettv2(union gtpie_member *ie[], int type, int instance,
uint16_t * dst)
{
int ien;
ien = gtpie_getie(ie, type, instance);
if (ien>=0)
if (ien >= 0)
*dst = ntoh16(ie[ien]->tv2.v);
else
return EOF;
return 0;
}
int gtpie_gettv4(union gtpie_member* ie[], int type, int instance,
uint32_t *dst){
int gtpie_gettv4(union gtpie_member *ie[], int type, int instance,
uint32_t * dst)
{
int ien;
ien = gtpie_getie(ie, type, instance);
if (ien>=0)
if (ien >= 0)
*dst = ntoh32(ie[ien]->tv4.v);
else
return EOF;
return 0;
}
int gtpie_gettv8(union gtpie_member* ie[], int type, int instance,
uint64_t *dst){
int gtpie_gettv8(union gtpie_member *ie[], int type, int instance,
uint64_t * dst)
{
int ien;
ien = gtpie_getie(ie, type, instance);
if (ien>=0)
if (ien >= 0)
*dst = ntoh64(ie[ien]->tv8.v);
else
return EOF;
return 0;
}
int gtpie_decaps(union gtpie_member* ie[], int version, void *pack, unsigned len) {
int gtpie_decaps(union gtpie_member *ie[], int version, void *pack,
unsigned len)
{
int i;
int j = 0;
unsigned char *p;
unsigned char *end;
end = (unsigned char*) pack + len;
end = (unsigned char *)pack + len;
p = pack;
memset(ie, 0, sizeof(union gtpie_member *) * GTPIE_SIZE);
while ((p<end) && (j<GTPIE_SIZE)) {
while ((p < end) && (j < GTPIE_SIZE)) {
if (GTPIE_DEBUG) {
printf("The packet looks like this:\n");
for( i=0; i<(end-p); i++) {
printf("%02x ", (unsigned char)*(char *)(p+i));
if (!((i+1)%16)) printf("\n");
for (i = 0; i < (end - p); i++) {
printf("%02x ",
(unsigned char)*(char *)(p + i));
if (!((i + 1) % 16))
printf("\n");
};
printf("\n");
}
@ -211,24 +243,29 @@ int gtpie_decaps(union gtpie_member* ie[], int version, void *pack, unsigned len
case GTPIE_RP_SMS:
case GTPIE_RP:
case GTPIE_MS_NOT_REACH:
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV1 found. Type %d, value %d\n",
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf
("GTPIE TV1 found. Type %d, value %d\n",
ie[j]->tv1.t, ie[j]->tv1.v);
p+= 1 + 1;
p += 1 + 1;
j++;
}
break;
case GTPIE_FL_DI: /* TV GTPIE types with value length 2 or 4 */
case GTPIE_FL_C:
if (version != 0) {
if (j<GTPIE_SIZE) { /* GTPIE_TEI_DI & GTPIE_TEI_C with length 4 */
if (j < GTPIE_SIZE) { /* GTPIE_TEI_DI & GTPIE_TEI_C with length 4 */
/* case GTPIE_TEI_DI: gtp1 */
/* case GTPIE_TEI_C: gtp1 */
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV 4 found. Type %d, value %d\n",
ie[j]->tv4.t, ie[j]->tv4.v);
p+= 1 + 4;
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf
("GTPIE TV 4 found. Type %d, value %d\n",
ie[j]->tv4.t,
ie[j]->tv4.v);
p += 1 + 4;
j++;
}
break;
@ -237,22 +274,26 @@ int gtpie_decaps(union gtpie_member* ie[], int version, void *pack, unsigned len
case GTPIE_CHARGING_C:
case GTPIE_TRACE_REF:
case GTPIE_TRACE_TYPE:
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV2 found. Type %d, value %d\n",
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf
("GTPIE TV2 found. Type %d, value %d\n",
ie[j]->tv2.t, ie[j]->tv2.v);
p+= 1 + 2;
p += 1 + 2;
j++;
}
break;
case GTPIE_QOS_PROFILE0: /* TV GTPIE types with value length 3 */
case GTPIE_P_TMSI_S:
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV 3 found. Type %d, value %d, %d, %d\n",
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf
("GTPIE TV 3 found. Type %d, value %d, %d, %d\n",
ie[j]->tv0.t, ie[j]->tv0.v[0],
ie[j]->tv0.v[1], ie[j]->tv0.v[2]);
p+= 1 + 3;
p += 1 + 3;
j++;
}
break;
@ -261,62 +302,76 @@ int gtpie_decaps(union gtpie_member* ie[], int version, void *pack, unsigned len
case GTPIE_CHARGING_ID:
/* case GTPIE_TEI_DI: Handled by GTPIE_FL_DI */
/* case GTPIE_TEI_C: Handled by GTPIE_FL_DI */
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV 4 found. Type %d, value %d\n",
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf
("GTPIE TV 4 found. Type %d, value %d\n",
ie[j]->tv4.t, ie[j]->tv4.v);
p+= 1 + 4;
p += 1 + 4;
j++;
}
break;
case GTPIE_TEI_DII: /* TV GTPIE types with value length 5 */
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV 5 found. Type %d\n", ie[j]->tv0.t);
p+= 1 + 5;
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf("GTPIE TV 5 found. Type %d\n",
ie[j]->tv0.t);
p += 1 + 5;
j++;
}
break;
case GTPIE_RAB_CONTEXT: /* TV GTPIE types with value length 7 */
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV 7 found. Type %d\n", ie[j]->tv0.t);
p+= 1 + 7;
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf("GTPIE TV 7 found. Type %d\n",
ie[j]->tv0.t);
p += 1 + 7;
j++;
}
break;
case GTPIE_IMSI: /* TV GTPIE types with value length 8 */
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE_IMSI - GTPIE TV 8 found. Type %d, value 0x%llx\n",
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf
("GTPIE_IMSI - GTPIE TV 8 found. Type %d, value 0x%llx\n",
ie[j]->tv0.t, ie[j]->tv8.v);
p+= 1 + 8;
p += 1 + 8;
j++;
}
break;
case GTPIE_RAI: /* TV GTPIE types with value length 6 */
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE_RAI - GTPIE TV 6 found. Type %d, value 0x%llx\n",
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf
("GTPIE_RAI - GTPIE TV 6 found. Type %d, value 0x%llx\n",
ie[j]->tv0.t, ie[j]->tv8.v);
p+= 1 + 6;
p += 1 + 6;
j++;
}
break;
case GTPIE_AUTH_TRIPLET: /* TV GTPIE types with value length 28 */
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV 28 found. Type %d\n", ie[j]->tv0.t);
p+= 1 + 28;
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf("GTPIE TV 28 found. Type %d\n",
ie[j]->tv0.t);
p += 1 + 28;
j++;
}
break;
case GTPIE_EXT_HEADER_T: /* GTP extension header */
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE GTP extension header found. Type %d\n",
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf
("GTPIE GTP extension header found. Type %d\n",
ie[j]->ext.t);
p+= 2 + ntoh8(ie[j]->ext.l);
p += 2 + ntoh8(ie[j]->ext.l);
j++;
}
break;
@ -341,35 +396,41 @@ int gtpie_decaps(union gtpie_member* ie[], int version, void *pack, unsigned len
case GTPIE_MS_TZ:
case GTPIE_IMEI_SV:
case GTPIE_PRIVATE:
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TLV found. Type %d\n", ie[j]->tlv.t);
p+= 3 + ntoh16(ie[j]->tlv.l);
if (j < GTPIE_SIZE) {
ie[j] = (union gtpie_member *)p;
if (GTPIE_DEBUG)
printf("GTPIE TLV found. Type %d\n",
ie[j]->tlv.t);
p += 3 + ntoh16(ie[j]->tlv.l);
j++;
}
break;
default:
if (GTPIE_DEBUG) printf("GTPIE something unknown. Type %d\n", *p);
if (GTPIE_DEBUG)
printf("GTPIE something unknown. Type %d\n",
*p);
return EOF; /* We received something unknown */
}
}
if (p==end) {
if (GTPIE_DEBUG) printf("GTPIE normal return. %lx %lx\n",
(unsigned long) p, (unsigned long) end);
if (p == end) {
if (GTPIE_DEBUG)
printf("GTPIE normal return. %lx %lx\n",
(unsigned long)p, (unsigned long)end);
return 0; /* We landed at the end of the packet: OK */
}
else if (!(j<GTPIE_SIZE)) {
if (GTPIE_DEBUG) printf("GTPIE too many elements.\n");
} else if (!(j < GTPIE_SIZE)) {
if (GTPIE_DEBUG)
printf("GTPIE too many elements.\n");
return EOF; /* We received too many information elements */
}
else {
if (GTPIE_DEBUG) printf("GTPIE exceeded end of packet. %lx %lx\n",
(unsigned long) p, (unsigned long) end);
} else {
if (GTPIE_DEBUG)
printf("GTPIE exceeded end of packet. %lx %lx\n",
(unsigned long)p, (unsigned long)end);
return EOF; /* We exceeded the end of the packet: Error */
}
}
int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len) {
int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
{
int i;
unsigned char *p;
unsigned char *end;
@ -380,9 +441,11 @@ int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len) {
memset(pack, 0, GTPIE_MAX);
end = p + GTPIE_MAX;
for (i=1; i<GTPIE_SIZE; i++) if (ie[i] != 0) {
if (GTPIE_DEBUG) printf("gtpie_encaps. Type %d\n", i);
m=(union gtpie_member *)p;
for (i = 1; i < GTPIE_SIZE; i++)
if (ie[i] != 0) {
if (GTPIE_DEBUG)
printf("gtpie_encaps. Type %d\n", i);
m = (union gtpie_member *)p;
switch (i) {
case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
case GTPIE_REORDER:
@ -412,8 +475,8 @@ int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len) {
break;
case GTPIE_TLLI: /* TV GTPIE types with value length 4 */
case GTPIE_P_TMSI:
/* case GTPIE_TEI_DI: only in gtp1*/
/* case GTPIE_TEI_C: only in gtp1*/
/* case GTPIE_TEI_DI: only in gtp1 */
/* case GTPIE_TEI_C: only in gtp1 */
case GTPIE_CHARGING_ID:
iesize = 5;
break;
@ -455,18 +518,19 @@ int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len) {
default:
return 2; /* We received something unknown */
}
if (p+iesize < end) {
if (p + iesize < end) {
memcpy(p, ie[i], iesize);
p += iesize;
*len += iesize;
}
else return 2; /* Out of space */
} else
return 2; /* Out of space */
}
return 0;
}
int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
void *pack, unsigned *len) {
void *pack, unsigned *len)
{
unsigned int i, j;
unsigned char *p;
unsigned char *end;
@ -477,9 +541,14 @@ int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
memset(pack, 0, GTPIE_MAX);
end = p + GTPIE_MAX;
for (j=0; j<GTPIE_SIZE; j++) for (i=0; i<size; i++) if (ie[i].t == j) {
if (GTPIE_DEBUG) printf("gtpie_encaps. Number %d, Type %d\n", i, ie[i].t);
m=(union gtpie_member *)p;
for (j = 0; j < GTPIE_SIZE; j++)
for (i = 0; i < size; i++)
if (ie[i].t == j) {
if (GTPIE_DEBUG)
printf
("gtpie_encaps. Number %d, Type %d\n",
i, ie[i].t);
m = (union gtpie_member *)p;
switch (ie[i].t) {
case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
case GTPIE_REORDER:
@ -550,12 +619,12 @@ int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
default:
return 2; /* We received something unknown */
}
if (p+iesize < end) {
if (p + iesize < end) {
memcpy(p, &ie[i], iesize);
p += iesize;
*len += iesize;
}
else return 2; /* Out of space */
} else
return 2; /* Out of space */
}
return 0;
}

View File

@ -21,14 +21,13 @@
#define ntoh32(x) ntohl(x)
#if BYTE_ORDER == LITTLE_ENDIAN
static __inline uint64_t
hton64(uint64_t q)
static __inline uint64_t hton64(uint64_t q)
{
register uint32_t u, l;
u = q >> 32;
l = (uint32_t) q;
return htonl(u) | ((uint64_t)htonl(l) << 32);
return htonl(u) | ((uint64_t) htonl(l) << 32);
}
#define ntoh64(_x) hton64(_x)
@ -42,7 +41,6 @@ hton64(uint64_t q)
#error "Please fix <machine/endian.h>"
#endif
#define GTPIE_SIZE 256 /* Max number of information elements */
#define GTPIE_MAX 0xffff /* Max length of information elements */
#define GTPIE_MAX_TV 28 /* Max length of type value pair */
@ -59,8 +57,8 @@ hton64(uint64_t q)
#define GTPIE_RAI 3 /* Routing Area Identity (RAI) 8 */
#define GTPIE_TLLI 4 /* Temporary Logical Link Identity (TLLI) 4 */
#define GTPIE_P_TMSI 5 /* Packet TMSI (P-TMSI) 4 */
#define GTPIE_QOS_PROFILE0 6 /* Quality of Service Profile GTP version 0 3*/
/* 6-7 SPARE */ /* 6 is QoS Profile vers 0 */
#define GTPIE_QOS_PROFILE0 6 /* Quality of Service Profile GTP version 0 3 */
/* 6-7 SPARE *//* 6 is QoS Profile vers 0 */
#define GTPIE_REORDER 8 /* Reordering Required 1 */
#define GTPIE_AUTH_TRIPLET 9 /* Authentication Triplet 28 */
/* 10 SPARE */
@ -113,45 +111,43 @@ hton64(uint64_t q)
/* 252-254 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
#define GTPIE_PRIVATE 255 /* Private Extension */
/* GTP information element structs in network order */
struct gtpie_ext { /* Extension header */
uint8_t t; /* Type */
uint8_t l; /* Length */
uint8_t *p; /* Value */
} __attribute__((packed));
} __attribute__ ((packed));
struct gtpie_tlv { /* Type length value pair */
uint8_t t; /* Type */
uint16_t l; /* Length */
uint8_t v[GTPIE_MAX_TLV]; /* Value */
} __attribute__((packed));
} __attribute__ ((packed));
struct gtpie_tv0 { /* 1 byte type value pair */
uint8_t t; /* Type */
uint8_t v[GTPIE_MAX_TV]; /* Pointer to value */
}__attribute__((packed));
} __attribute__ ((packed));
struct gtpie_tv1 { /* 1 byte type value pair */
uint8_t t; /* Type */
uint8_t v; /* Value */
}__attribute__((packed));
} __attribute__ ((packed));
struct gtpie_tv2 { /* 2 byte type value pair */
uint8_t t; /* Type */
uint16_t v; /* Value */
}__attribute__((packed));
} __attribute__ ((packed));
struct gtpie_tv4 { /* 4 byte type value pair */
uint8_t t; /* Type */
uint32_t v; /* Value */
}__attribute__((packed));
} __attribute__ ((packed));
struct gtpie_tv8 { /* 8 byte type value pair */
uint8_t t; /* Type */
uint64_t v; /* Value */
}__attribute__((packed));
} __attribute__ ((packed));
union gtpie_member {
uint8_t t;
@ -162,7 +158,7 @@ union gtpie_member {
struct gtpie_tv2 tv2;
struct gtpie_tv4 tv4;
struct gtpie_tv8 tv8;
}__attribute__((packed));
} __attribute__ ((packed));
/*
cause
@ -216,43 +212,44 @@ private
struct tlv1 {
uint8_t type;
uint8_t length;
}__attribute__((packed));
} __attribute__ ((packed));
struct tlv2 {
uint8_t type;
uint16_t length;
}__attribute__((packed));
} __attribute__ ((packed));
extern int gtpie_tlv(void *p, unsigned int *length, unsigned int size,
uint8_t t, int l, void *v);
extern int gtpie_tv0(void *p, unsigned int *length, unsigned int size,
uint8_t t, int l, uint8_t *v);
extern int gtpie_tv1(void *p, unsigned int *length, unsigned int size, uint8_t t, uint8_t v);
extern int gtpie_tv2(void *p, unsigned int *length, unsigned int size, uint8_t t, uint16_t v);
extern int gtpie_tv4(void *p, unsigned int *length, unsigned int size, uint8_t t, uint32_t v);
extern int gtpie_tv8(void *p, unsigned int *length, unsigned int size, uint8_t t, uint64_t v);
extern int gtpie_getie(union gtpie_member* ie[], int type, int instance);
extern int gtpie_exist(union gtpie_member* ie[], int type, int instance);
extern int gtpie_gettlv(union gtpie_member* ie[], int type, int instance,
uint8_t t, int l, uint8_t * v);
extern int gtpie_tv1(void *p, unsigned int *length, unsigned int size,
uint8_t t, uint8_t v);
extern int gtpie_tv2(void *p, unsigned int *length, unsigned int size,
uint8_t t, uint16_t v);
extern int gtpie_tv4(void *p, unsigned int *length, unsigned int size,
uint8_t t, uint32_t v);
extern int gtpie_tv8(void *p, unsigned int *length, unsigned int size,
uint8_t t, uint64_t v);
extern int gtpie_getie(union gtpie_member *ie[], int type, int instance);
extern int gtpie_exist(union gtpie_member *ie[], int type, int instance);
extern int gtpie_gettlv(union gtpie_member *ie[], int type, int instance,
unsigned int *length, void *dst, unsigned int size);
extern int gtpie_gettv0(union gtpie_member* ie[], int type, int instance,
extern int gtpie_gettv0(union gtpie_member *ie[], int type, int instance,
void *dst, unsigned int size);
extern int gtpie_gettv1(union gtpie_member* ie[], int type, int instance,
uint8_t *dst);
extern int gtpie_gettv2(union gtpie_member* ie[], int type, int instance,
uint16_t *dst);
extern int gtpie_gettv4(union gtpie_member* ie[], int type, int instance,
uint32_t *dst);
extern int gtpie_gettv8(union gtpie_member* ie[], int type, int instance,
uint64_t *dst);
extern int gtpie_gettv1(union gtpie_member *ie[], int type, int instance,
uint8_t * dst);
extern int gtpie_gettv2(union gtpie_member *ie[], int type, int instance,
uint16_t * dst);
extern int gtpie_gettv4(union gtpie_member *ie[], int type, int instance,
uint32_t * dst);
extern int gtpie_gettv8(union gtpie_member *ie[], int type, int instance,
uint64_t * dst);
extern int gtpie_decaps(union gtpie_member* ie[], int version,
extern int gtpie_decaps(union gtpie_member *ie[], int version,
void *pack, unsigned len);
extern int gtpie_encaps(union gtpie_member* ie[], void *pack, unsigned *len);
extern int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len);
extern int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
void *pack, unsigned *len);
#endif /* !_GTPIE_H */

View File

@ -81,12 +81,12 @@ acceptable. Do NOT use for cryptographic purposes.
--------------------------------------------------------------------
*/
ub4 lookup( k, length, level)
ub4 lookup(k, length, level)
register ub1 *k; /* the key */
register ub4 length; /* the length of the key */
register ub4 level; /* the previous hash, or an arbitrary value */
{
register ub4 a,b,c,len;
register ub4 a, b, c, len;
/* Set up the internal state */
len = length;
@ -94,39 +94,51 @@ register ub4 level; /* the previous hash, or an arbitrary value */
c = level; /* the previous hash value */
/*---------------------------------------- handle most of the key */
while (len >= 12)
{
a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
mix(a,b,c);
k += 12; len -= 12;
while (len >= 12) {
a += (k[0] + ((ub4) k[1] << 8) + ((ub4) k[2] << 16) +
((ub4) k[3] << 24));
b += (k[4] + ((ub4) k[5] << 8) + ((ub4) k[6] << 16) +
((ub4) k[7] << 24));
c += (k[8] + ((ub4) k[9] << 8) + ((ub4) k[10] << 16) +
((ub4) k[11] << 24));
mix(a, b, c);
k += 12;
len -= 12;
}
/*------------------------------------- handle the last 11 bytes */
c += length;
switch(len) /* all the case statements fall through */
{
case 11: c+=((ub4)k[10]<<24);
case 10: c+=((ub4)k[9]<<16);
case 9 : c+=((ub4)k[8]<<8);
switch (len) { /* all the case statements fall through */
case 11:
c += ((ub4) k[10] << 24);
case 10:
c += ((ub4) k[9] << 16);
case 9:
c += ((ub4) k[8] << 8);
/* the first byte of c is reserved for the length */
case 8 : b+=((ub4)k[7]<<24);
case 7 : b+=((ub4)k[6]<<16);
case 6 : b+=((ub4)k[5]<<8);
case 5 : b+=k[4];
case 4 : a+=((ub4)k[3]<<24);
case 3 : a+=((ub4)k[2]<<16);
case 2 : a+=((ub4)k[1]<<8);
case 1 : a+=k[0];
case 8:
b += ((ub4) k[7] << 24);
case 7:
b += ((ub4) k[6] << 16);
case 6:
b += ((ub4) k[5] << 8);
case 5:
b += k[4];
case 4:
a += ((ub4) k[3] << 24);
case 3:
a += ((ub4) k[2] << 16);
case 2:
a += ((ub4) k[1] << 8);
case 1:
a += k[0];
/* case 0: nothing left to add */
}
mix(a,b,c);
mix(a, b, c);
/*-------------------------------------------- report the result */
return c;
}
/*
--------------------------------------------------------------------
mixc -- mixc 8 4-bit values as quickly and thoroughly as possible.
@ -169,78 +181,120 @@ Use to detect changes between revisions of documents, assuming nobody
is trying to cause collisions. Do NOT use for cryptography.
--------------------------------------------------------------------
*/
void checksum( k, len, state)
void checksum(k, len, state)
register ub1 *k;
register ub4 len;
register ub4 *state;
{
register ub4 a,b,c,d,e,f,g,h,length;
register ub4 a, b, c, d, e, f, g, h, length;
/* Use the length and level; add in the golden ratio. */
length = len;
a=state[0]; b=state[1]; c=state[2]; d=state[3];
e=state[4]; f=state[5]; g=state[6]; h=state[7];
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
f = state[5];
g = state[6];
h = state[7];
/*---------------------------------------- handle most of the key */
while (len >= 32)
{
a += (k[0] +(k[1]<<8) +(k[2]<<16) +(k[3]<<24));
b += (k[4] +(k[5]<<8) +(k[6]<<16) +(k[7]<<24));
c += (k[8] +(k[9]<<8) +(k[10]<<16)+(k[11]<<24));
d += (k[12]+(k[13]<<8)+(k[14]<<16)+(k[15]<<24));
e += (k[16]+(k[17]<<8)+(k[18]<<16)+(k[19]<<24));
f += (k[20]+(k[21]<<8)+(k[22]<<16)+(k[23]<<24));
g += (k[24]+(k[25]<<8)+(k[26]<<16)+(k[27]<<24));
h += (k[28]+(k[29]<<8)+(k[30]<<16)+(k[31]<<24));
mixc(a,b,c,d,e,f,g,h);
mixc(a,b,c,d,e,f,g,h);
mixc(a,b,c,d,e,f,g,h);
mixc(a,b,c,d,e,f,g,h);
k += 32; len -= 32;
while (len >= 32) {
a += (k[0] + (k[1] << 8) + (k[2] << 16) + (k[3] << 24));
b += (k[4] + (k[5] << 8) + (k[6] << 16) + (k[7] << 24));
c += (k[8] + (k[9] << 8) + (k[10] << 16) + (k[11] << 24));
d += (k[12] + (k[13] << 8) + (k[14] << 16) + (k[15] << 24));
e += (k[16] + (k[17] << 8) + (k[18] << 16) + (k[19] << 24));
f += (k[20] + (k[21] << 8) + (k[22] << 16) + (k[23] << 24));
g += (k[24] + (k[25] << 8) + (k[26] << 16) + (k[27] << 24));
h += (k[28] + (k[29] << 8) + (k[30] << 16) + (k[31] << 24));
mixc(a, b, c, d, e, f, g, h);
mixc(a, b, c, d, e, f, g, h);
mixc(a, b, c, d, e, f, g, h);
mixc(a, b, c, d, e, f, g, h);
k += 32;
len -= 32;
}
/*------------------------------------- handle the last 31 bytes */
h += length;
switch(len)
{
case 31: h+=(k[30]<<24);
case 30: h+=(k[29]<<16);
case 29: h+=(k[28]<<8);
case 28: g+=(k[27]<<24);
case 27: g+=(k[26]<<16);
case 26: g+=(k[25]<<8);
case 25: g+=k[24];
case 24: f+=(k[23]<<24);
case 23: f+=(k[22]<<16);
case 22: f+=(k[21]<<8);
case 21: f+=k[20];
case 20: e+=(k[19]<<24);
case 19: e+=(k[18]<<16);
case 18: e+=(k[17]<<8);
case 17: e+=k[16];
case 16: d+=(k[15]<<24);
case 15: d+=(k[14]<<16);
case 14: d+=(k[13]<<8);
case 13: d+=k[12];
case 12: c+=(k[11]<<24);
case 11: c+=(k[10]<<16);
case 10: c+=(k[9]<<8);
case 9 : c+=k[8];
case 8 : b+=(k[7]<<24);
case 7 : b+=(k[6]<<16);
case 6 : b+=(k[5]<<8);
case 5 : b+=k[4];
case 4 : a+=(k[3]<<24);
case 3 : a+=(k[2]<<16);
case 2 : a+=(k[1]<<8);
case 1 : a+=k[0];
switch (len) {
case 31:
h += (k[30] << 24);
case 30:
h += (k[29] << 16);
case 29:
h += (k[28] << 8);
case 28:
g += (k[27] << 24);
case 27:
g += (k[26] << 16);
case 26:
g += (k[25] << 8);
case 25:
g += k[24];
case 24:
f += (k[23] << 24);
case 23:
f += (k[22] << 16);
case 22:
f += (k[21] << 8);
case 21:
f += k[20];
case 20:
e += (k[19] << 24);
case 19:
e += (k[18] << 16);
case 18:
e += (k[17] << 8);
case 17:
e += k[16];
case 16:
d += (k[15] << 24);
case 15:
d += (k[14] << 16);
case 14:
d += (k[13] << 8);
case 13:
d += k[12];
case 12:
c += (k[11] << 24);
case 11:
c += (k[10] << 16);
case 10:
c += (k[9] << 8);
case 9:
c += k[8];
case 8:
b += (k[7] << 24);
case 7:
b += (k[6] << 16);
case 6:
b += (k[5] << 8);
case 5:
b += k[4];
case 4:
a += (k[3] << 24);
case 3:
a += (k[2] << 16);
case 2:
a += (k[1] << 8);
case 1:
a += k[0];
}
mixc(a,b,c,d,e,f,g,h);
mixc(a,b,c,d,e,f,g,h);
mixc(a,b,c,d,e,f,g,h);
mixc(a,b,c,d,e,f,g,h);
mixc(a, b, c, d, e, f, g, h);
mixc(a, b, c, d, e, f, g, h);
mixc(a, b, c, d, e, f, g, h);
mixc(a, b, c, d, e, f, g, h);
/*-------------------------------------------- report the result */
state[0]=a; state[1]=b; state[2]=c; state[3]=d;
state[4]=e; state[5]=f; state[6]=g; state[7]=h;
state[0] = a;
state[1] = b;
state[2] = c;
state[3] = d;
state[4] = e;
state[5] = f;
state[6] = g;
state[7] = h;
}

View File

@ -23,7 +23,7 @@ typedef unsigned char ub1;
#define hashsize(n) ((ub4)1<<(n))
#define hashmask(n) (hashsize(n)-1)
ub4 lookup(/*_ ub1 *k, ub4 length, ub4 level _*/);
void checksum(/*_ ub1 *k, ub4 length, ub4 *state _*/);
ub4 lookup( /*_ ub1 *k, ub4 length, ub4 level _*/ );
void checksum( /*_ ub1 *k, ub4 length, ub4 *state _*/ );
#endif /* LOOKUPA */

145
gtp/pdp.c
View File

@ -32,7 +32,7 @@
*************************************************************/
struct pdp_t pdpa[PDP_MAX]; /* PDP storage */
struct pdp_t* hashtid[PDP_MAX];/* Hash table for IMSI + NSAPI */
struct pdp_t *hashtid[PDP_MAX]; /* Hash table for IMSI + NSAPI */
/* struct pdp_t* haship[PDP_MAX]; Hash table for IP and network interface */
/* ***********************************************************
@ -107,7 +107,8 @@ struct pdp_t* hashtid[PDP_MAX];/* Hash table for IMSI + NSAPI */
*
*************************************************************/
int pdp_init() {
int pdp_init()
{
memset(&pdpa, 0, sizeof(pdpa));
memset(&hashtid, 0, sizeof(hashtid));
/* memset(&haship, 0, sizeof(haship)); */
@ -116,25 +117,31 @@ int pdp_init() {
}
int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
struct pdp_t *pdp_old){
struct pdp_t *pdp_old)
{
int n;
for (n=0; n<PDP_MAX; n++) { /* TODO: Need to do better than linear search */
for (n = 0; n < PDP_MAX; n++) { /* TODO: Need to do better than linear search */
if (pdpa[n].inuse == 0) {
*pdp = &pdpa[n];
if (NULL != pdp_old) memcpy(*pdp, pdp_old, sizeof(struct pdp_t));
else memset(*pdp, 0, sizeof(struct pdp_t));
if (NULL != pdp_old)
memcpy(*pdp, pdp_old, sizeof(struct pdp_t));
else
memset(*pdp, 0, sizeof(struct pdp_t));
(*pdp)->inuse = 1;
(*pdp)->imsi = imsi;
(*pdp)->nsapi = nsapi;
(*pdp)->fllc = (uint16_t) n + 1;
(*pdp)->fllu = (uint16_t) n + 1;
(*pdp)->teid_own = (uint32_t) n + 1;
if (!(*pdp)->secondary) (*pdp)->teic_own = (uint32_t) n + 1;
if (!(*pdp)->secondary)
(*pdp)->teic_own = (uint32_t) n + 1;
pdp_tidset(*pdp, pdp_gettid(imsi, nsapi));
/* Insert reference in primary context */
if (((*pdp)->teic_own > 0 ) && ((*pdp)->teic_own <= PDP_MAX)) {
pdpa[(*pdp)->teic_own-1].secondary_tei[(*pdp)->nsapi & 0x0f] =
if (((*pdp)->teic_own > 0)
&& ((*pdp)->teic_own <= PDP_MAX)) {
pdpa[(*pdp)->teic_own -
1].secondary_tei[(*pdp)->nsapi & 0x0f] =
(*pdp)->teid_own;
}
@ -144,57 +151,66 @@ int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
return EOF; /* No more available */
}
int pdp_freepdp(struct pdp_t *pdp){
int pdp_freepdp(struct pdp_t *pdp)
{
pdp_tiddel(pdp);
/* Remove any references in primary context */
if ((pdp->secondary) && (pdp->teic_own > 0 ) && (pdp->teic_own <= PDP_MAX)) {
pdpa[pdp->teic_own-1].secondary_tei[pdp->nsapi & 0x0f] = 0;
if ((pdp->secondary) && (pdp->teic_own > 0)
&& (pdp->teic_own <= PDP_MAX)) {
pdpa[pdp->teic_own - 1].secondary_tei[pdp->nsapi & 0x0f] = 0;
}
memset(pdp, 0, sizeof(struct pdp_t));
return 0;
}
int pdp_getpdp(struct pdp_t **pdp){
int pdp_getpdp(struct pdp_t **pdp)
{
*pdp = &pdpa[0];
return 0;
}
int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl){
if ((fl>PDP_MAX) || (fl<1)) {
int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl)
{
if ((fl > PDP_MAX) || (fl < 1)) {
return EOF; /* Not found */
}
else {
*pdp = &pdpa[fl-1];
if ((*pdp)->inuse) return 0;
else return EOF;
} else {
*pdp = &pdpa[fl - 1];
if ((*pdp)->inuse)
return 0;
else
return EOF;
/* Context exists. We do no further validity checking. */
}
}
int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei){
if ((tei>PDP_MAX) || (tei<1)) {
int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei)
{
if ((tei > PDP_MAX) || (tei < 1)) {
return EOF; /* Not found */
}
else {
*pdp = &pdpa[tei-1];
if ((*pdp)->inuse) return 0;
else return EOF;
} else {
*pdp = &pdpa[tei - 1];
if ((*pdp)->inuse)
return 0;
else
return EOF;
/* Context exists. We do no further validity checking. */
}
}
int pdp_tidhash(uint64_t tid) {
int pdp_tidhash(uint64_t tid)
{
return (lookup(&tid, sizeof(tid), 0) % PDP_MAX);
}
int pdp_tidset(struct pdp_t *pdp, uint64_t tid) {
int pdp_tidset(struct pdp_t *pdp, uint64_t tid)
{
int hash = pdp_tidhash(tid);
struct pdp_t *pdp2;
struct pdp_t *pdp_prev = NULL;
if (PDP_DEBUG) printf("Begin pdp_tidset tid = %llx\n", tid);
if (PDP_DEBUG)
printf("Begin pdp_tidset tid = %llx\n", tid);
pdp->tidnext = NULL;
pdp->tid = tid;
for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext)
@ -203,48 +219,59 @@ int pdp_tidset(struct pdp_t *pdp, uint64_t tid) {
hashtid[hash] = pdp;
else
pdp_prev->tidnext = pdp;
if (PDP_DEBUG) printf("End pdp_tidset\n");
if (PDP_DEBUG)
printf("End pdp_tidset\n");
return 0;
}
int pdp_tiddel(struct pdp_t *pdp) {
int pdp_tiddel(struct pdp_t *pdp)
{
int hash = pdp_tidhash(pdp->tid);
struct pdp_t *pdp2;
struct pdp_t *pdp_prev = NULL;
if (PDP_DEBUG) printf("Begin pdp_tiddel tid = %llx\n", pdp->tid);
if (PDP_DEBUG)
printf("Begin pdp_tiddel tid = %llx\n", pdp->tid);
for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
if (pdp2 == pdp) {
if (!pdp_prev)
hashtid[hash] = pdp2->tidnext;
else
pdp_prev->tidnext = pdp2->tidnext;
if (PDP_DEBUG) printf("End pdp_tiddel: PDP found\n");
if (PDP_DEBUG)
printf("End pdp_tiddel: PDP found\n");
return 0;
}
pdp_prev = pdp2;
}
if (PDP_DEBUG) printf("End pdp_tiddel: PDP not found\n");
if (PDP_DEBUG)
printf("End pdp_tiddel: PDP not found\n");
return EOF; /* End of linked list and not found */
}
int pdp_tidget(struct pdp_t **pdp, uint64_t tid) {
int pdp_tidget(struct pdp_t **pdp, uint64_t tid)
{
int hash = pdp_tidhash(tid);
struct pdp_t *pdp2;
if (PDP_DEBUG) printf("Begin pdp_tidget tid = %llx\n", tid);
if (PDP_DEBUG)
printf("Begin pdp_tidget tid = %llx\n", tid);
for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
if (pdp2->tid == tid) {
*pdp = pdp2;
if (PDP_DEBUG) printf("Begin pdp_tidget. Found\n");
if (PDP_DEBUG)
printf("Begin pdp_tidget. Found\n");
return 0;
}
}
if (PDP_DEBUG) printf("Begin pdp_tidget. Not found\n");
if (PDP_DEBUG)
printf("Begin pdp_tidget. Not found\n");
return EOF; /* End of linked list and not found */
}
int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi) {
int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi)
{
return pdp_tidget(pdp,
(imsi & 0x0fffffffffffffffull) + ((uint64_t)nsapi << 60));
(imsi & 0x0fffffffffffffffull) +
((uint64_t) nsapi << 60));
}
/*
@ -320,32 +347,36 @@ int pdp_ipget(struct pdp_t **pdp, void* ipif, struct ul66_t *eua) {
*/
/* Various conversion functions */
int pdp_ntoeua(struct in_addr *src, struct ul66_t *eua) {
eua->l=6;
eua->v[0]=0xf1; /* IETF */
eua->v[1]=0x21; /* IPv4 */
int pdp_ntoeua(struct in_addr *src, struct ul66_t *eua)
{
eua->l = 6;
eua->v[0] = 0xf1; /* IETF */
eua->v[1] = 0x21; /* IPv4 */
memcpy(&eua->v[2], src, 4); /* Copy a 4 byte address */
return 0;
}
int pdp_euaton(struct ul66_t *eua, struct in_addr *dst) {
if((eua->l!=6) || (eua->v[0]!=0xf1) || (eua->v[1]!=0x21)) {
int pdp_euaton(struct ul66_t *eua, struct in_addr *dst)
{
if ((eua->l != 6) || (eua->v[0] != 0xf1) || (eua->v[1] != 0x21)) {
return EOF;
}
memcpy(dst, &eua->v[2], 4); /* Copy a 4 byte address */
return 0;
}
uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi) {
return (imsi & 0x0fffffffffffffffull) + ((uint64_t)nsapi << 60);
uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi)
{
return (imsi & 0x0fffffffffffffffull) + ((uint64_t) nsapi << 60);
}
int ulcpy(void* dst, void* src, size_t size) {
if (((struct ul255_t*)src)->l <= size) {
((struct ul255_t*)dst)->l = ((struct ul255_t*)src)->l;
memcpy(((struct ul255_t*)dst)->v, ((struct ul255_t*)src)->v,
((struct ul255_t*)dst)->l);
int ulcpy(void *dst, void *src, size_t size)
{
if (((struct ul255_t *)src)->l <= size) {
((struct ul255_t *)dst)->l = ((struct ul255_t *)src)->l;
memcpy(((struct ul255_t *)dst)->v, ((struct ul255_t *)src)->v,
((struct ul255_t *)dst)->l);
return 0;
}
else return EOF;
} else
return EOF;
}

View File

@ -21,33 +21,31 @@
/* Also covers version 0. Note that version 0 6: QOS Profile was superceded *
* by 135: QOS Profile in version 1 */
struct sl_t {
unsigned int l;
char *v;
unsigned int l;
char *v;
};
struct ul_t {
unsigned int l;
unsigned char *v;
unsigned int l;
unsigned char *v;
};
struct ul16_t {
unsigned int l;
unsigned char v[16];
unsigned int l;
unsigned char v[16];
};
struct ul66_t {
unsigned int l;
unsigned char v[66];
unsigned int l;
unsigned char v[66];
};
struct ul255_t {
unsigned int l;
unsigned char v[255];
unsigned int l;
unsigned char v[255];
};
/* *****************************************************************
* Information storage for each PDP context
*
@ -116,27 +114,27 @@ struct pdp_t {
void *peer; /* Pointer to peer protocol */
void *asap; /* Application specific service access point */
uint64_t imsi; /* International Mobile Subscriber Identity.*/
uint64_t imsi; /* International Mobile Subscriber Identity. */
struct ul16_t msisdn; /* The basic MSISDN of the MS. */
uint8_t mnrg; /* Indicates whether the MS is marked as not reachable for PS at the HLR. (1 bit, not transmitted) */
uint8_t cch_sub; /* The charging characteristics for the MS, e.g. normal, prepaid, flat-rate, and/or hot billing subscription. (not transmitted) */
uint16_t traceref; /* Identifies a record or a collection of records for a particular trace. */
uint16_t tracetype;/* Indicates the type of trace. */
struct ul_t triggerid;/* Identifies the entity that initiated the trace. */
uint16_t tracetype; /* Indicates the type of trace. */
struct ul_t triggerid; /* Identifies the entity that initiated the trace. */
struct ul_t omcid; /* Identifies the OMC that shall receive the trace record(s). */
uint8_t rec_hlr; /* Indicates if HLR or VLR is performing database recovery. (1 bit, not transmitted) */
/* Parameters specific to each individual PDP context */
uint8_t pdp_id; /* Index of the PDP context. (PDP context identifier) */
uint8_t pdp_state;/* PDP State Packet data protocol state, INACTIVE or ACTIVE. (1 bit, not transmitted) */
uint8_t pdp_state; /* PDP State Packet data protocol state, INACTIVE or ACTIVE. (1 bit, not transmitted) */
/* struct ul_t pdp_type; * PDP type; e.g. PPP or IP. */
/* struct ul_t pdp_addr; * PDP address; e.g. an IP address. */
struct ul66_t eua; /* End user address. PDP type and address combined */
uint8_t pdp_dyn; /* Indicates whether PDP Address is static or dynamic. (1 bit, not transmitted) */
struct ul255_t apn_req;/* The APN requested. */
struct ul255_t apn_sub;/* The APN received from the HLR. */
struct ul255_t apn_use;/* The APN Network Identifier currently used. */
struct ul255_t apn_req; /* The APN requested. */
struct ul255_t apn_sub; /* The APN received from the HLR. */
struct ul255_t apn_use; /* The APN Network Identifier currently used. */
uint8_t nsapi; /* Network layer Service Access Point Identifier. (4 bit) */
uint16_t ti; /* Transaction Identifier. (4 or 12 bit) */
@ -169,9 +167,9 @@ struct pdp_t {
struct ul255_t qos_sub; /* The quality of service profile subscribed. */
struct ul255_t qos_req; /* The quality of service profile requested. */
struct ul255_t qos_neg; /* The quality of service profile negotiated. */
uint8_t radio_pri;/* The RLC/MAC radio priority level for uplink user data transmission. (4 bit) */
uint8_t radio_pri; /* The RLC/MAC radio priority level for uplink user data transmission. (4 bit) */
uint16_t flow_id; /* Packet flow identifier. */
/* struct ul_t bssqos_neg; * The aggregate BSS quality of service profile negotiated for the packet flow that this PDP context belongs to. (NOT GTP)*/
/* struct ul_t bssqos_neg; * The aggregate BSS quality of service profile negotiated for the packet flow that this PDP context belongs to. (NOT GTP) */
uint8_t sndcpd; /* SNDCP sequence number of the next downlink N-PDU to be sent to the MS. */
uint8_t sndcpu; /* SNDCP sequence number of the next uplink N-PDU expected from the MS. */
uint8_t rec_sgsn; /* Indicates if the SGSN is performing database recovery. (1 bit, not transmitted) */
@ -183,22 +181,22 @@ struct pdp_t {
uint8_t pdcpsndu; /* Sequence number of the next uplink in-sequence PDCP-PDU expected from the MS. */
uint32_t cid; /* Charging identifier, identifies charging records generated by SGSN and GGSN. */
uint16_t cch_pdp; /* The charging characteristics for this PDP context, e.g. normal, prepaid, flat-rate, and/or hot billing. */
struct ul16_t rnc_addr;/* The IP address of the RNC currently used. */
struct ul16_t rnc_addr; /* The IP address of the RNC currently used. */
uint8_t reorder; /* Specifies whether the GGSN shall reorder N-PDUs received from the SGSN / Specifies whether the SGSN shall reorder N-PDUs before delivering the N-PSUs to the MS. (1 bit) */
struct ul255_t pco_req; /* Requested packet control options. */
struct ul255_t pco_neg; /* Negotiated packet control options. */
uint32_t selmode; /* Selection mode. */
struct ul255_t rattype; /* Radio Access Technology Type */
int rattype_given; /* Radio Access Technology Type given*/
int rattype_given; /* Radio Access Technology Type given */
struct ul255_t userloc; /* User Location Information */
int userloc_given; /* User Location Information given*/
int userloc_given; /* User Location Information given */
struct ul255_t rai; /* Routing Area Information */
int rai_given; /* Routing Area Information given*/
int rai_given; /* Routing Area Information given */
struct ul255_t mstz; /* MS Time Zone */
int mstz_given; /* MS Time Zone given*/
int mstz_given; /* MS Time Zone given */
struct ul255_t imeisv; /* IMEI Software Version */
int imeisv_given; /* IMEI Software Version given*/
int norecovery_given; /* norecovery given*/
int imeisv_given; /* IMEI Software Version given */
int norecovery_given; /* norecovery given */
/* Additional parameters used by library */
@ -227,7 +225,6 @@ struct pdp_t {
void *priv;
};
/* functions related to pdp_t management */
int pdp_init();
int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
@ -245,7 +242,6 @@ int pdp_tidset(struct pdp_t *pdp, uint64_t tid);
int pdp_tiddel(struct pdp_t *pdp);
int pdp_tidget(struct pdp_t **pdp, uint64_t tid);
/*
int pdp_iphash(void* ipif, struct ul66_t *eua);
int pdp_ipset(struct pdp_t *pdp, void* ipif, struct ul66_t *eua);
@ -256,6 +252,6 @@ int pdp_ipget(struct pdp_t **pdp, void* ipif, struct ul66_t *eua);
int pdp_ntoeua(struct in_addr *src, struct ul66_t *eua);
int pdp_euaton(struct ul66_t *eua, struct in_addr *dst);
uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi);
int ulcpy(void* dst, void* src, size_t size);
int ulcpy(void *dst, void *src, size_t size);
#endif /* !_PDP_H */

View File

@ -29,24 +29,26 @@
#include "gtp.h"
#include "queue.h"
int queue_print(struct queue_t *queue) {
int queue_print(struct queue_t *queue)
{
int n;
printf("Queue: %x Next: %d First: %d Last: %d\n", (int) queue, queue->next, queue->first, queue->last);
printf("Queue: %x Next: %d First: %d Last: %d\n", (int)queue,
queue->next, queue->first, queue->last);
printf("# State seq next prev timeout retrans\n");
for (n=0; n<QUEUE_SIZE; n++) {
for (n = 0; n < QUEUE_SIZE; n++) {
printf("%d %d %d %d %d %d %d\n",
n,
queue->qmsga[n].state,
queue->qmsga[n].seq,
queue->qmsga[n].next,
queue->qmsga[n].prev,
(int) queue->qmsga[n].timeout,
queue->qmsga[n].retrans);
(int)queue->qmsga[n].timeout, queue->qmsga[n].retrans);
}
return 0;
}
int queue_seqhash(struct sockaddr_in *peer, uint16_t seq) {
int queue_seqhash(struct sockaddr_in *peer, uint16_t seq)
{
/* With QUEUE_HASH_SIZE = 2^16 this describes all possible
seq values. Thus we have perfect hash for the request queue.
For the response queue we might have collisions, but not very
@ -57,13 +59,17 @@ int queue_seqhash(struct sockaddr_in *peer, uint16_t seq) {
}
int queue_seqset(struct queue_t *queue, struct qmsg_t *qmsg,
struct sockaddr_in *peer, uint16_t seq) {
struct sockaddr_in *peer, uint16_t seq)
{
int hash = queue_seqhash(peer, seq);
struct qmsg_t *qmsg2;
struct qmsg_t *qmsg_prev = NULL;
if (QUEUE_DEBUG) printf("Begin queue_seqset seq = %d\n", (int) seq);
if (QUEUE_DEBUG) printf("SIZEOF PEER %d, *PEER %d\n", sizeof(peer), sizeof(*peer));
if (QUEUE_DEBUG)
printf("Begin queue_seqset seq = %d\n", (int)seq);
if (QUEUE_DEBUG)
printf("SIZEOF PEER %d, *PEER %d\n", sizeof(peer),
sizeof(*peer));
qmsg->seq = seq;
memcpy(&qmsg->peer, peer, sizeof(*peer));
@ -74,16 +80,18 @@ int queue_seqset(struct queue_t *queue, struct qmsg_t *qmsg,
queue->hashseq[hash] = qmsg;
else
qmsg_prev->seqnext = qmsg;
if (QUEUE_DEBUG) printf("End queue_seqset\n");
if (QUEUE_DEBUG)
printf("End queue_seqset\n");
return 0;
}
int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg) {
int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg)
{
int hash = queue_seqhash(&qmsg->peer, qmsg->seq);
struct qmsg_t *qmsg2;
struct qmsg_t *qmsg_prev = NULL;
if (QUEUE_DEBUG) printf("Begin queue_seqdel seq = %d\n", (int) qmsg->seq);
if (QUEUE_DEBUG)
printf("Begin queue_seqdel seq = %d\n", (int)qmsg->seq);
for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
if (qmsg == qmsg) {
@ -91,7 +99,8 @@ int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg) {
queue->hashseq[hash] = qmsg2->seqnext;
else
qmsg_prev->seqnext = qmsg2->seqnext;
if (QUEUE_DEBUG) printf("End queue_seqset: SEQ found\n");
if (QUEUE_DEBUG)
printf("End queue_seqset: SEQ found\n");
return 0;
}
qmsg_prev = qmsg2;
@ -100,53 +109,65 @@ int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg) {
return EOF; /* End of linked list and not found */
}
/* Allocates and initialises new queue structure */
int queue_new(struct queue_t **queue) {
if (QUEUE_DEBUG) printf("queue_new\n");
int queue_new(struct queue_t **queue)
{
if (QUEUE_DEBUG)
printf("queue_new\n");
*queue = calloc(1, sizeof(struct queue_t));
(*queue)->next = 0;
(*queue)->first = -1;
(*queue)->last = -1;
if (QUEUE_DEBUG) queue_print(*queue);
if (*queue) return 0;
else return EOF;
if (QUEUE_DEBUG)
queue_print(*queue);
if (*queue)
return 0;
else
return EOF;
}
/* Deallocates queue structure */
int queue_free(struct queue_t *queue) {
if (QUEUE_DEBUG) printf("queue_free\n");
if (QUEUE_DEBUG) queue_print(queue);
int queue_free(struct queue_t *queue)
{
if (QUEUE_DEBUG)
printf("queue_free\n");
if (QUEUE_DEBUG)
queue_print(queue);
free(queue);
return 0;
}
int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
struct sockaddr_in *peer, uint16_t seq) {
if (QUEUE_DEBUG) printf("queue_newmsg %d\n", (int) seq);
struct sockaddr_in *peer, uint16_t seq)
{
if (QUEUE_DEBUG)
printf("queue_newmsg %d\n", (int)seq);
if (queue->qmsga[queue->next].state == 1) {
return EOF; /* Queue is full */
}
else {
} else {
*qmsg = &queue->qmsga[queue->next];
queue_seqset(queue, *qmsg, peer, seq);
(*qmsg)->state = 1; /* Space taken */
(*qmsg)->this = queue->next;
(*qmsg)->next=-1; /* End of the queue */
(*qmsg)->prev=queue->last; /* Link to the previous */
(*qmsg)->next = -1; /* End of the queue */
(*qmsg)->prev = queue->last; /* Link to the previous */
if (queue->last != -1)
queue->qmsga[queue->last].next=queue->next; /* Link previous to us */
queue->qmsga[queue->last].next = queue->next; /* Link previous to us */
queue->last = queue->next; /* End of queue */
if (queue->first == -1) queue->first = queue->next;
queue->next = (queue->next+1) % QUEUE_SIZE; /* Increment */
if (QUEUE_DEBUG) queue_print(queue);
if (queue->first == -1)
queue->first = queue->next;
queue->next = (queue->next + 1) % QUEUE_SIZE; /* Increment */
if (QUEUE_DEBUG)
queue_print(queue);
return 0;
}
}
int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg) {
if (QUEUE_DEBUG) printf("queue_freemsg\n");
int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg)
{
if (QUEUE_DEBUG)
printf("queue_freemsg\n");
if (qmsg->state != 1) {
return EOF; /* Not in queue */
}
@ -165,50 +186,60 @@ int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg) {
memset(qmsg, 0, sizeof(struct qmsg_t)); /* Just to be safe */
if (QUEUE_DEBUG) queue_print(queue);
if (QUEUE_DEBUG)
queue_print(queue);
return 0;
}
int queue_back(struct queue_t *queue, struct qmsg_t *qmsg) {
if (QUEUE_DEBUG) printf("queue_back\n");
int queue_back(struct queue_t *queue, struct qmsg_t *qmsg)
{
if (QUEUE_DEBUG)
printf("queue_back\n");
if (qmsg->state != 1) {
return EOF; /* Not in queue */
}
/* Insert stuff to maintain hash table */
if (qmsg->next != -1) {/* Only swop if there are others */
if (qmsg->next != -1) { /* Only swop if there are others */
queue->qmsga[qmsg->next].prev = qmsg->prev;
queue->first = qmsg->next;
qmsg->next = -1;
qmsg->prev = queue->last;
if (queue->last != -1) queue->qmsga[queue->last].next = qmsg->this;
if (queue->last != -1)
queue->qmsga[queue->last].next = qmsg->this;
queue->last = qmsg->this;
}
if (QUEUE_DEBUG) queue_print(queue);
if (QUEUE_DEBUG)
queue_print(queue);
return 0;
}
/* Get the element with a particular sequence number */
int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg) {
/*printf("queue_getfirst\n");*/
int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg)
{
/*printf("queue_getfirst\n"); */
if (queue->first == -1) {
*qmsg = NULL;
return EOF; /* End of queue = queue is empty. */
}
*qmsg = &queue->qmsga[queue->first];
if (QUEUE_DEBUG) queue_print(queue);
if (QUEUE_DEBUG)
queue_print(queue);
return 0;
}
int queue_getseqx(struct queue_t *queue, struct qmsg_t **qmsg,
struct sockaddr_in *peer, uint16_t seq) {
struct sockaddr_in *peer, uint16_t seq)
{
int n;
if (QUEUE_DEBUG) printf("queue_getseq, %d\n", (int) seq);
if (QUEUE_DEBUG) queue_print(queue);
for (n=0; n<QUEUE_SIZE; n++) {
if (QUEUE_DEBUG)
printf("queue_getseq, %d\n", (int)seq);
if (QUEUE_DEBUG)
queue_print(queue);
for (n = 0; n < QUEUE_SIZE; n++) {
if ((queue->qmsga[n].seq == seq) &&
(!memcmp(&queue->qmsga[n].peer, peer, sizeof(*peer)))) {
*qmsg = &queue->qmsga[n];
@ -219,24 +250,29 @@ int queue_getseqx(struct queue_t *queue, struct qmsg_t **qmsg,
}
int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
struct sockaddr_in *peer, uint16_t seq) {
struct sockaddr_in *peer, uint16_t seq)
{
int hash = queue_seqhash(peer, seq);
struct qmsg_t *qmsg2;
if (QUEUE_DEBUG) printf("Begin queue_seqget seq = %d\n", (int) seq);
if (QUEUE_DEBUG)
printf("Begin queue_seqget seq = %d\n", (int)seq);
for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
if ((qmsg2->seq == seq) &&
(!memcmp(&qmsg2->peer, peer, sizeof(*peer)))) {
*qmsg = qmsg2;
if (QUEUE_DEBUG) printf("End queue_seqget. Found\n");
if (QUEUE_DEBUG)
printf("End queue_seqget. Found\n");
return 0;
}
}
if (QUEUE_DEBUG) printf("End queue_seqget. Not found\n");
if (QUEUE_DEBUG)
printf("End queue_seqget. Not found\n");
return EOF; /* End of linked list and not found */
}
int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
uint16_t seq, uint8_t *type, void **cbp) {
uint16_t seq, uint8_t * type, void **cbp)
{
struct qmsg_t *qmsg;
if (queue_seqget(queue, &qmsg, peer, seq)) {
*cbp = NULL;

View File

@ -30,7 +30,7 @@ struct qmsg_t { /* Holder for queued packets */
union gtp_packet p; /* The packet stored */
int l; /* Length of the packet */
int fd; /* Socket packet was sent to / received from */
struct sockaddr_in peer;/* Address packet was sent to / received from */
struct sockaddr_in peer; /* Address packet was sent to / received from */
struct qmsg_t *seqnext; /* Pointer to next in sequence hash list */
int next; /* Pointer to the next in queue. -1: Last */
int prev; /* Pointer to the previous in queue. -1: First */
@ -47,7 +47,6 @@ struct queue_t {
int last; /* Last packet in queue (youngest timeout) */
};
/* Allocates and initialises new queue structure */
int queue_new(struct queue_t **queue);
/* Deallocates queue structure */
@ -66,8 +65,6 @@ int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
struct sockaddr_in *peer, uint16_t seq);
/* Free message based on sequence number */
int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
uint16_t seq, uint8_t *type, void **cbp);
uint16_t seq, uint8_t * type, void **cbp);
#endif /* !_QUEUE_H */

View File

@ -24,19 +24,19 @@
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
#ifndef _NO_PROTO
# define _NO_PROTO
#define _NO_PROTO
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#include <config.h>
#endif
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
# ifndef const
# define const
# endif
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
@ -51,41 +51,40 @@
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
# include <gnu-versions.h>
# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
# define ELIDE_CODE
# endif
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
/* Don't include stdlib.h for non-GNU C libraries because some of them
contain conflicting prototypes for getopt. */
# include <stdlib.h>
# include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
#endif /* GNU C library. */
#ifdef VMS
# include <unixlib.h>
# if HAVE_STRING_H - 0
# include <string.h>
# endif
#include <unixlib.h>
#if HAVE_STRING_H - 0
#include <string.h>
#endif
#endif
#ifndef _
/* This is for other GNU distributions with internationalized messages. */
# if defined HAVE_LIBINTL_H || defined _LIBC
# include <libintl.h>
# ifndef _
# define _(msgid) gettext (msgid)
# endif
# else
# define _(msgid) (msgid)
# endif
#if defined HAVE_LIBINTL_H || defined _LIBC
#include <libintl.h>
#ifndef _
#define _(msgid) gettext (msgid)
#endif
#else
#define _(msgid) (msgid)
#endif
#endif
/* This version of `getopt' appears to the caller like standard Unix `getopt'
@ -182,8 +181,7 @@ int optopt = '?';
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
static enum
{
static enum {
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
@ -195,32 +193,30 @@ static char *posixly_correct;
because there are many ways it can cause trouble.
On some systems, it contains special magic macros that don't work
in GCC. */
# include <string.h>
# define my_index strchr
#include <string.h>
#define my_index strchr
#else
# if HAVE_STRING_H
# include <string.h>
# else
# include <strings.h>
# endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
/* Avoid depending on library functions or files
whose names are inconsistent. */
#ifndef getenv
extern char *getenv ();
extern char *getenv();
#endif
static char *
my_index (str, chr)
const char *str;
int chr;
static char *my_index(str, chr)
const char *str;
int chr;
{
while (*str)
{
while (*str) {
if (*str == chr)
return (char *) str;
return (char *)str;
str++;
}
return 0;
@ -231,11 +227,11 @@ my_index (str, chr)
#ifdef __GNUC__
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
# if (!defined __STDC__ || !__STDC__) && !defined strlen
#if (!defined __STDC__ || !__STDC__) && !defined strlen
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern int strlen (const char *);
# endif /* not __STDC__ */
extern int strlen(const char *);
#endif /* not __STDC__ */
#endif /* __GNUC__ */
#endif /* not __GNU_LIBRARY__ */
@ -259,27 +255,27 @@ extern char **__libc_argv;
/* Bash 2.0 gives us an environment variable containing flags
indicating ARGV elements that should not be considered arguments. */
# ifdef USE_NONOPTION_FLAGS
#ifdef USE_NONOPTION_FLAGS
/* Defined in getopt_init.c */
extern char *__getopt_nonoption_flags;
static int nonoption_flags_max_len;
static int nonoption_flags_len;
# endif
#endif
# ifdef USE_NONOPTION_FLAGS
# define SWAP_FLAGS(ch1, ch2) \
#ifdef USE_NONOPTION_FLAGS
#define SWAP_FLAGS(ch1, ch2) \
if (nonoption_flags_len > 0) \
{ \
char __tmp = __getopt_nonoption_flags[ch1]; \
__getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
__getopt_nonoption_flags[ch2] = __tmp; \
}
# else
# define SWAP_FLAGS(ch1, ch2)
# endif
#else
#define SWAP_FLAGS(ch1, ch2)
#endif
#else /* !_LIBC */
# define SWAP_FLAGS(ch1, ch2)
#define SWAP_FLAGS(ch1, ch2)
#endif /* _LIBC */
/* Exchange two adjacent subsequences of ARGV.
@ -292,12 +288,11 @@ static int nonoption_flags_len;
the new indices of the non-options in ARGV after they are moved. */
#if defined __STDC__ && __STDC__
static void exchange (char **);
static void exchange(char **);
#endif
static void
exchange (argv)
char **argv;
static void exchange(argv)
char **argv;
{
int bottom = first_nonopt;
int middle = last_nonopt;
@ -313,16 +308,14 @@ exchange (argv)
/* First make sure the handling of the `__getopt_nonoption_flags'
string can work normally. Our top argument must be in the range
of the string. */
if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
{
if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) {
/* We must extend the array. The user plays games with us and
presents new arguments. */
char *new_str = malloc (top + 1);
char *new_str = malloc(top + 1);
if (new_str == NULL)
nonoption_flags_len = nonoption_flags_max_len = 0;
else
{
memset (__mempcpy (new_str, __getopt_nonoption_flags,
else {
memset(__mempcpy(new_str, __getopt_nonoption_flags,
nonoption_flags_max_len),
'\0', top + 1 - nonoption_flags_max_len);
nonoption_flags_max_len = top + 1;
@ -331,38 +324,34 @@ exchange (argv)
}
#endif
while (top > middle && middle > bottom)
{
if (top - middle > middle - bottom)
{
while (top > middle && middle > bottom) {
if (top - middle > middle - bottom) {
/* Bottom segment is the short one. */
int len = middle - bottom;
register int i;
/* Swap it with the top part of the top segment. */
for (i = 0; i < len; i++)
{
for (i = 0; i < len; i++) {
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[bottom + i] =
argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
SWAP_FLAGS(bottom + i,
top - (middle - bottom) + i);
}
/* Exclude the moved bottom segment from further swapping. */
top -= len;
}
else
{
} else {
/* Top segment is the short one. */
int len = top - middle;
register int i;
/* Swap it with the bottom part of the bottom segment. */
for (i = 0; i < len; i++)
{
for (i = 0; i < len; i++) {
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
SWAP_FLAGS (bottom + i, middle + i);
SWAP_FLAGS(bottom + i, middle + i);
}
/* Exclude the moved top segment from further swapping. */
bottom += len;
@ -378,13 +367,12 @@ exchange (argv)
/* Initialize the internal data when the first call is made. */
#if defined __STDC__ && __STDC__
static const char *_getopt_initialize (int, char *const *, const char *);
static const char *_getopt_initialize(int, char *const *, const char *);
#endif
static const char *
_getopt_initialize (argc, argv, optstring)
int argc;
char *const *argv;
const char *optstring;
static const char *_getopt_initialize(argc, argv, optstring)
int argc;
char *const *argv;
const char *optstring;
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
@ -394,52 +382,47 @@ _getopt_initialize (argc, argv, optstring)
nextchar = NULL;
posixly_correct = getenv ("POSIXLY_CORRECT");
posixly_correct = getenv("POSIXLY_CORRECT");
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
{
if (optstring[0] == '-') {
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
} else if (optstring[0] == '+') {
ordering = REQUIRE_ORDER;
++optstring;
}
else if (posixly_correct != NULL)
} else if (posixly_correct != NULL)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
#if defined _LIBC && defined USE_NONOPTION_FLAGS
if (posixly_correct == NULL
&& argc == __libc_argc && argv == __libc_argv)
{
if (nonoption_flags_max_len == 0)
{
&& argc == __libc_argc && argv == __libc_argv) {
if (nonoption_flags_max_len == 0) {
if (__getopt_nonoption_flags == NULL
|| __getopt_nonoption_flags[0] == '\0')
nonoption_flags_max_len = -1;
else
{
else {
const char *orig_str = __getopt_nonoption_flags;
int len = nonoption_flags_max_len = strlen (orig_str);
int len = nonoption_flags_max_len =
strlen(orig_str);
if (nonoption_flags_max_len < argc)
nonoption_flags_max_len = argc;
__getopt_nonoption_flags =
(char *) malloc (nonoption_flags_max_len);
(char *)malloc(nonoption_flags_max_len);
if (__getopt_nonoption_flags == NULL)
nonoption_flags_max_len = -1;
else
memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
'\0', nonoption_flags_max_len - len);
memset(__mempcpy
(__getopt_nonoption_flags,
orig_str, len), '\0',
nonoption_flags_max_len - len);
}
}
nonoption_flags_len = nonoption_flags_max_len;
}
else
} else
nonoption_flags_len = 0;
#endif
@ -502,14 +485,13 @@ _getopt_initialize (argc, argv, optstring)
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
long-named options. */
int
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int argc;
char *const *argv;
const char *optstring;
const struct option *longopts;
int *longind;
int long_only;
int _getopt_internal(argc, argv, optstring, longopts, longind, long_only)
int argc;
char *const *argv;
const char *optstring;
const struct option *longopts;
int *longind;
int long_only;
{
int print_errors = opterr;
if (optstring[0] == ':')
@ -520,11 +502,10 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optarg = NULL;
if (optind == 0 || !__getopt_initialized)
{
if (optind == 0 || !__getopt_initialized) {
if (optind == 0)
optind = 1; /* Don't scan ARGV[0], the program name. */
optstring = _getopt_initialize (argc, argv, optstring);
optstring = _getopt_initialize(argc, argv, optstring);
__getopt_initialized = 1;
}
@ -533,15 +514,14 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
from the shell indicating it is not an option. The later information
is only used when the used in the GNU libc. */
#if defined _LIBC && defined USE_NONOPTION_FLAGS
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|| (optind < nonoption_flags_len \
&& __getopt_nonoption_flags[optind] == '1'))
#else
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
#endif
if (nextchar == NULL || *nextchar == '\0')
{
if (nextchar == NULL || *nextchar == '\0') {
/* Advance to the next ARGV-element. */
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
@ -551,13 +531,13 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
if (first_nonopt > optind)
first_nonopt = optind;
if (ordering == PERMUTE)
{
if (ordering == PERMUTE) {
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
if (first_nonopt != last_nonopt
&& last_nonopt != optind)
exchange((char **)argv);
else if (last_nonopt != optind)
first_nonopt = optind;
@ -574,12 +554,12 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind != argc && !strcmp (argv[optind], "--"))
{
if (optind != argc && !strcmp(argv[optind], "--")) {
optind++;
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
if (first_nonopt != last_nonopt
&& last_nonopt != optind)
exchange((char **)argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optind;
last_nonopt = argc;
@ -590,8 +570,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optind == argc)
{
if (optind == argc) {
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
@ -602,8 +581,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if (NONOPTION_P)
{
if (NONOPTION_P) {
if (ordering == REQUIRE_ORDER)
return -1;
optarg = argv[optind++];
@ -634,8 +612,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
if (longopts != NULL
&& (argv[optind][1] == '-'
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
{
|| (long_only
&& (argv[optind][2]
|| !my_index(optstring, argv[optind][1]))))) {
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
@ -649,25 +628,21 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if ((unsigned int) (nameend - nextchar)
== (unsigned int) strlen (p->name))
{
for (p = longopts, option_index = 0; p->name;
p++, option_index++)
if (!strncmp(p->name, nextchar, nameend - nextchar)) {
if ((unsigned int)(nameend - nextchar)
== (unsigned int)strlen(p->name)) {
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
} else if (pfound == NULL) {
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else if (long_only
} else if (long_only
|| pfound->has_arg != p->has_arg
|| pfound->flag != p->flag
|| pfound->val != p->val)
@ -675,69 +650,69 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
ambig = 1;
}
if (ambig && !exact)
{
if (ambig && !exact) {
if (print_errors)
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
fprintf(stderr,
_("%s: option `%s' is ambiguous\n"),
argv[0], argv[optind]);
nextchar += strlen (nextchar);
nextchar += strlen(nextchar);
optind++;
optopt = 0;
return '?';
}
if (pfound != NULL)
{
if (pfound != NULL) {
option_index = indfound;
optind++;
if (*nameend)
{
if (*nameend) {
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = nameend + 1;
else
{
if (print_errors)
{
else {
if (print_errors) {
if (argv[optind - 1][1] == '-')
/* --option */
fprintf (stderr,
_("%s: option `--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
fprintf(stderr,
_
("%s: option `--%s' doesn't allow an argument\n"),
argv[0],
pfound->name);
else
/* +option or -option */
fprintf (stderr,
_("%s: option `%c%s' doesn't allow an argument\n"),
argv[0], argv[optind - 1][0], pfound->name);
fprintf(stderr,
_
("%s: option `%c%s' doesn't allow an argument\n"),
argv[0],
argv[optind -
1][0],
pfound->name);
}
nextchar += strlen (nextchar);
nextchar += strlen(nextchar);
optopt = pfound->val;
return '?';
}
}
else if (pfound->has_arg == 1)
{
} else if (pfound->has_arg == 1) {
if (optind < argc)
optarg = argv[optind++];
else
{
else {
if (print_errors)
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
fprintf(stderr,
_
("%s: option `%s' requires an argument\n"),
argv[0],
argv[optind - 1]);
nextchar += strlen(nextchar);
optopt = pfound->val;
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
nextchar += strlen(nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
if (pfound->flag) {
*(pfound->flag) = pfound->val;
return 0;
}
@ -749,20 +724,23 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
option, then it's an error.
Otherwise interpret it as a short option. */
if (!long_only || argv[optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL)
{
if (print_errors)
{
|| my_index(optstring, *nextchar) == NULL) {
if (print_errors) {
if (argv[optind][1] == '-')
/* --option */
fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
fprintf(stderr,
_
("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
else
/* +option or -option */
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[optind][0], nextchar);
fprintf(stderr,
_
("%s: unrecognized option `%c%s'\n"),
argv[0], argv[optind][0],
nextchar);
}
nextchar = (char *) "";
nextchar = (char *)"";
optind++;
optopt = 0;
return '?';
@ -773,30 +751,29 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
{
char c = *nextchar++;
char *temp = my_index (optstring, c);
char *temp = my_index(optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*nextchar == '\0')
++optind;
if (temp == NULL || c == ':')
{
if (print_errors)
{
if (temp == NULL || c == ':') {
if (print_errors) {
if (posixly_correct)
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: illegal option -- %c\n"),
fprintf(stderr,
_("%s: illegal option -- %c\n"),
argv[0], c);
else
fprintf (stderr, _("%s: invalid option -- %c\n"),
fprintf(stderr,
_("%s: invalid option -- %c\n"),
argv[0], c);
}
optopt = c;
return '?';
}
/* Convenience. Treat POSIX -W foo same as long option --foo */
if (temp[0] == 'W' && temp[1] == ';')
{
if (temp[0] == 'W' && temp[1] == ';') {
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
@ -806,19 +783,17 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int option_index;
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
if (*nextchar != '\0') {
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (print_errors)
{
} else if (optind == argc) {
if (print_errors) {
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: option requires an argument -- %c\n"),
fprintf(stderr,
_
("%s: option requires an argument -- %c\n"),
argv[0], c);
}
optopt = c;
@ -827,8 +802,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
else
c = '?';
return c;
}
else
} else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
@ -836,80 +810,77 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
/* optarg is now the argument, see if it's in the
table of longopts. */
for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
for (nextchar = nameend = optarg;
*nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if ((unsigned int) (nameend - nextchar) == strlen (p->name))
{
for (p = longopts, option_index = 0; p->name;
p++, option_index++)
if (!strncmp
(p->name, nextchar, nameend - nextchar)) {
if ((unsigned int)(nameend -
nextchar) ==
strlen(p->name)) {
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
} else if (pfound == NULL) {
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
} else
/* Second or later nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
if (ambig && !exact) {
if (print_errors)
fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
fprintf(stderr,
_
("%s: option `-W %s' is ambiguous\n"),
argv[0], argv[optind]);
nextchar += strlen (nextchar);
nextchar += strlen(nextchar);
optind++;
return '?';
}
if (pfound != NULL)
{
if (pfound != NULL) {
option_index = indfound;
if (*nameend)
{
if (*nameend) {
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = nameend + 1;
else
{
else {
if (print_errors)
fprintf (stderr, _("\
%s: option `-W %s' doesn't allow an argument\n"),
argv[0], pfound->name);
fprintf(stderr, _("\
%s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name);
nextchar += strlen (nextchar);
nextchar += strlen(nextchar);
return '?';
}
}
else if (pfound->has_arg == 1)
{
} else if (pfound->has_arg == 1) {
if (optind < argc)
optarg = argv[optind++];
else
{
else {
if (print_errors)
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?';
fprintf(stderr,
_
("%s: option `%s' requires an argument\n"),
argv[0],
argv[optind -
1]);
nextchar += strlen(nextchar);
return optstring[0] ==
':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
nextchar += strlen(nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
if (pfound->flag) {
*(pfound->flag) = pfound->val;
return 0;
}
@ -918,37 +889,28 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
nextchar = NULL;
return 'W'; /* Let the application handle it. */
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
if (temp[1] == ':') {
if (temp[2] == ':') {
/* This is an option that accepts an argument optionally. */
if (*nextchar != '\0')
{
if (*nextchar != '\0') {
optarg = nextchar;
optind++;
}
else
} else
optarg = NULL;
nextchar = NULL;
}
else
{
} else {
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
if (*nextchar != '\0') {
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (print_errors)
{
} else if (optind == argc) {
if (print_errors) {
/* 1003.2 specifies the format of this message. */
fprintf (stderr,
_("%s: option requires an argument -- %c\n"),
fprintf(stderr,
_
("%s: option requires an argument -- %c\n"),
argv[0], c);
}
optopt = c;
@ -956,8 +918,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
c = ':';
else
c = '?';
}
else
} else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
@ -968,16 +929,13 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
}
int
getopt (argc, argv, optstring)
int argc;
char *const *argv;
const char *optstring;
int getopt(argc, argv, optstring)
int argc;
char *const *argv;
const char *optstring;
{
return _getopt_internal (argc, argv, optstring,
(const struct option *) 0,
(int *) 0,
0);
return _getopt_internal(argc, argv, optstring,
(const struct option *)0, (int *)0, 0);
}
#endif /* Not ELIDE_CODE. */
@ -987,24 +945,21 @@ getopt (argc, argv, optstring)
/* Compile with -DTEST to make an executable for use in testing
the above definition of `getopt'. */
int
main (argc, argv)
int argc;
char **argv;
int main(argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
while (1) {
int this_option_optind = optind ? optind : 1;
c = getopt (argc, argv, "abc:d:0123456789");
c = getopt(argc, argv, "abc:d:0123456789");
if (c == -1)
break;
switch (c)
{
switch (c) {
case '0':
case '1':
case '2':
@ -1015,41 +970,42 @@ main (argc, argv)
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
if (digit_optind != 0
&& digit_optind != this_option_optind)
printf
("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
printf("option %c\n", c);
break;
case 'a':
printf ("option a\n");
printf("option a\n");
break;
case 'b':
printf ("option b\n");
printf("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
printf("option c with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
printf("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
printf("%s ", argv[optind++]);
printf("\n");
}
exit (0);
exit(0);
}
#endif /* TEST */

View File

@ -52,7 +52,6 @@
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
@ -63,15 +62,15 @@
#define NULL 0
#endif
int
getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
int getopt_long(argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
return _getopt_internal(argc, argv, options, long_options, opt_index,
0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
@ -79,38 +78,34 @@ getopt_long (argc, argv, options, long_options, opt_index)
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
int getopt_long_only(argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
return _getopt_internal(argc, argv, options, long_options, opt_index,
1);
}
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
int main(argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
while (1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
static struct option long_options[] = {
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
@ -120,18 +115,17 @@ main (argc, argv)
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
c = getopt_long(argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
switch (c) {
case 0:
printf ("option %s", long_options[option_index].name);
printf("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
printf(" with arg %s", optarg);
printf("\n");
break;
case '0':
@ -144,45 +138,46 @@ main (argc, argv)
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
if (digit_optind != 0
&& digit_optind != this_option_optind)
printf
("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
printf("option %c\n", c);
break;
case 'a':
printf ("option a\n");
printf("option a\n");
break;
case 'b':
printf ("option b\n");
printf("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
printf("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
printf("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
printf("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
printf("%s ", argv[optind++]);
printf("\n");
}
exit (0);
exit(0);
}
#endif /* TEST */

View File

@ -20,7 +20,7 @@
#ifndef _GETOPT_H
#ifndef __need_getopt
# define _GETOPT_H 1
#define _GETOPT_H 1
#endif
/* If __GNU_LIBRARY__ is not already defined, either we are being used
@ -31,7 +31,7 @@
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
doesn't flood the namespace with stuff the way some other headers do.) */
#if !defined __GNU_LIBRARY__
# include <ctype.h>
#include <ctype.h>
#endif
#ifdef __cplusplus
@ -44,7 +44,7 @@ extern "C" {
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
@ -58,16 +58,16 @@ extern char *optarg;
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
extern int optopt;
#ifndef __need_getopt
/* Describe the long-named options requested by the application.
@ -91,28 +91,26 @@ extern int optopt;
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
# if (defined __STDC__ && __STDC__) || defined __cplusplus
struct option {
#if (defined __STDC__ && __STDC__) || defined __cplusplus
const char *name;
# else
#else
char *name;
# endif
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
};
/* Names for the values of the `has_arg' field of `struct option'. */
# define no_argument 0
# define required_argument 1
# define optional_argument 2
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#endif /* need getopt */
/* Get definitions and prototypes for functions to process the
arguments in ARGV (ARGC of them, minus the program name) for
options given in OPTS.
@ -138,43 +136,44 @@ struct option
`getopt'. */
#if (defined __STDC__ && __STDC__) || defined __cplusplus
# ifdef __GNU_LIBRARY__
#ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
# else /* not __GNU_LIBRARY__ */
extern int getopt ();
# endif /* __GNU_LIBRARY__ */
extern int getopt(int __argc, char *const *__argv,
const char *__shortopts);
#else /* not __GNU_LIBRARY__ */
extern int getopt();
#endif /* __GNU_LIBRARY__ */
# ifndef __need_getopt
extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
const struct option *__longopts, int *__longind);
extern int getopt_long_only (int __argc, char *const *__argv,
#ifndef __need_getopt
extern int getopt_long(int __argc, char *const *__argv,
const char *__shortopts,
const struct option *__longopts, int *__longind);
extern int getopt_long_only(int __argc, char *const *__argv,
const char *__shortopts,
const struct option *__longopts,
int *__longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int __argc, char *const *__argv,
extern int _getopt_internal(int __argc, char *const *__argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
int __long_only);
# endif
const struct option *__longopts,
int *__longind, int __long_only);
#endif
#else /* not __STDC__ */
extern int getopt ();
# ifndef __need_getopt
extern int getopt_long ();
extern int getopt_long_only ();
extern int getopt();
#ifndef __need_getopt
extern int getopt_long();
extern int getopt_long_only();
extern int _getopt_internal ();
# endif
extern int _getopt_internal();
#endif
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
/* Make sure we later can get all the definitions and declarations. */
#undef __need_getopt
#endif /* getopt.h */

View File

@ -21,8 +21,8 @@
#include "ippool.h"
#include "lookup.h"
int ippool_printaddr(struct ippool_t *this) {
int ippool_printaddr(struct ippool_t *this)
{
unsigned int n;
printf("ippool_printaddr\n");
printf("Firstdyn %d\n", this->firstdyn - this->member);
@ -31,20 +31,20 @@ int ippool_printaddr(struct ippool_t *this) {
printf("Laststat %d\n", this->laststat - this->member);
printf("Listsize %d\n", this->listsize);
for (n=0; n<this->listsize; n++) {
for (n = 0; n < this->listsize; n++) {
printf("Unit %d inuse %d prev %d next %d addr %s %x\n",
n,
this->member[n].inuse,
this->member[n].prev - this->member,
this->member[n].next - this->member,
inet_ntoa(this->member[n].addr),
this->member[n].addr.s_addr
);
this->member[n].addr.s_addr);
}
return 0;
}
int ippool_hashadd(struct ippool_t *this, struct ippoolm_t *member) {
int ippool_hashadd(struct ippool_t *this, struct ippoolm_t *member)
{
uint32_t hash;
struct ippoolm_t *p;
struct ippoolm_t *p_prev = NULL;
@ -60,7 +60,8 @@ int ippool_hashadd(struct ippool_t *this, struct ippoolm_t *member) {
return 0; /* Always OK to insert */
}
int ippool_hashdel(struct ippool_t *this, struct ippoolm_t *member) {
int ippool_hashdel(struct ippool_t *this, struct ippoolm_t *member)
{
uint32_t hash;
struct ippoolm_t *p;
struct ippoolm_t *p_prev = NULL;
@ -74,7 +75,7 @@ int ippool_hashdel(struct ippool_t *this, struct ippoolm_t *member) {
p_prev = p;
}
if (p!= member) {
if (p != member) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"ippool_hashdel: Tried to delete member not in hash table");
return -1;
@ -88,21 +89,23 @@ int ippool_hashdel(struct ippool_t *this, struct ippoolm_t *member) {
return 0;
}
unsigned long int ippool_hash4(struct in_addr *addr) {
return lookup((unsigned char*) &addr->s_addr, sizeof(addr->s_addr), 0);
unsigned long int ippool_hash4(struct in_addr *addr)
{
return lookup((unsigned char *)&addr->s_addr, sizeof(addr->s_addr), 0);
}
#ifndef IPPOOL_NOIP6
unsigned long int ippool_hash6(struct in6_addr *addr) {
return lookup((unsigned char*) addr->u6_addr8, sizeof(addr->u6_addr8), 0);
unsigned long int ippool_hash6(struct in6_addr *addr)
{
return lookup((unsigned char *)addr->u6_addr8, sizeof(addr->u6_addr8),
0);
}
#endif
/* Get IP address and mask */
int ippool_aton(struct in_addr *addr, struct in_addr *mask,
char *pool, int number) {
char *pool, int number)
{
/* Parse only first instance of network for now */
/* Eventually "number" will indicate the token which we want to parse */
@ -114,8 +117,7 @@ int ippool_aton(struct in_addr *addr, struct in_addr *mask,
int masklog;
c = sscanf(pool, "%u.%u.%u.%u/%u.%u.%u.%u",
&a1, &a2, &a3, &a4,
&m1, &m2, &m3, &m4);
&a1, &a2, &a3, &a4, &m1, &m2, &m3, &m4);
switch (c) {
case 4:
mask->s_addr = 0xffffffff;
@ -133,10 +135,10 @@ int ippool_aton(struct in_addr *addr, struct in_addr *mask,
return -1; /* Wrong mask format */
}
m = m1 * 0x1000000 + m2 * 0x10000 + m3 * 0x100 + m4;
for (masklog = 0; ((1 << masklog) < ((~m)+1)); masklog++);
if (((~m)+1) != (1 << masklog)) {
for (masklog = 0; ((1 << masklog) < ((~m) + 1)); masklog++) ;
if (((~m) + 1) != (1 << masklog)) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
return -1; /* Wrong mask format (not all ones followed by all zeros)*/
return -1; /* Wrong mask format (not all ones followed by all zeros) */
}
mask->s_addr = htonl(m);
break;
@ -146,18 +148,20 @@ int ippool_aton(struct in_addr *addr, struct in_addr *mask,
}
if (a1 >= 256 || a2 >= 256 || a3 >= 256 || a4 >= 256) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Wrong IP address format");
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Wrong IP address format");
return -1;
}
else
addr->s_addr = htonl(a1 * 0x1000000 + a2 * 0x10000 + a3 * 0x100 + a4);
} else
addr->s_addr =
htonl(a1 * 0x1000000 + a2 * 0x10000 + a3 * 0x100 + a4);
return 0;
}
/* Create new address pool */
int ippool_new(struct ippool_t **this, char *dyn, char *stat,
int allowdyn, int allowstat, int flags) {
int allowdyn, int allowstat, int flags)
{
/* Parse only first instance of pool for now */
@ -173,8 +177,7 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
if (!allowdyn) {
dynsize = 0;
}
else {
} else {
if (ippool_aton(&addr, &mask, dyn, 0)) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Failed to parse dynamic pool");
@ -187,7 +190,7 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
}
m = ntohl(mask.s_addr);
dynsize = ((~m)+1);
dynsize = ((~m) + 1);
if (flags & IPPOOL_NONETWORK) /* Exclude network address from pool */
dynsize--;
if (flags & IPPOOL_NOGATEWAY) /* Exclude gateway address from pool */
@ -200,8 +203,7 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
statsize = 0;
stataddr.s_addr = 0;
statmask.s_addr = 0;
}
else {
} else {
if (ippool_aton(&stataddr, &statmask, stat, 0)) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Failed to parse static range");
@ -209,8 +211,9 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
}
m = ntohl(statmask.s_addr);
statsize = ((~m)+1);
if (statsize > IPPOOL_STATSIZE) statsize = IPPOOL_STATSIZE;
statsize = ((~m) + 1);
if (statsize > IPPOOL_STATSIZE)
statsize = IPPOOL_STATSIZE;
}
listsize = dynsize + statsize; /* Allocate space for static IP addresses */
@ -227,24 +230,25 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
(*this)->statmask = statmask;
(*this)->listsize += listsize;
if (!((*this)->member = calloc(sizeof(struct ippoolm_t), listsize))){
if (!((*this)->member = calloc(sizeof(struct ippoolm_t), listsize))) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Failed to allocate memory for members in ippool");
return -1;
}
for ((*this)->hashlog = 0;
((1 << (*this)->hashlog) < listsize);
(*this)->hashlog++);
((1 << (*this)->hashlog) < listsize); (*this)->hashlog++) ;
/* printf ("Hashlog %d %d %d\n", (*this)->hashlog, listsize, (1 << (*this)->hashlog)); */
/* Determine hashsize */
(*this)->hashsize = 1 << (*this)->hashlog; /* Fails if mask=0: All Internet*/
(*this)->hashmask = (*this)->hashsize -1;
(*this)->hashsize = 1 << (*this)->hashlog; /* Fails if mask=0: All Internet */
(*this)->hashmask = (*this)->hashsize - 1;
/* Allocate hash table */
if (!((*this)->hash = calloc(sizeof(struct ippoolm_t), (*this)->hashsize))){
if (!
((*this)->hash =
calloc(sizeof(struct ippoolm_t), (*this)->hashsize))) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Failed to allocate memory for hash members in ippool");
return -1;
@ -252,14 +256,17 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
(*this)->firstdyn = NULL;
(*this)->lastdyn = NULL;
for (i = 0; i<dynsize; i++) {
for (i = 0; i < dynsize; i++) {
if (flags & IPPOOL_NOGATEWAY)
(*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i + 2);
(*this)->member[i].addr.s_addr =
htonl(ntohl(addr.s_addr) + i + 2);
else if (flags & IPPOOL_NONETWORK)
(*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i + 1);
(*this)->member[i].addr.s_addr =
htonl(ntohl(addr.s_addr) + i + 1);
else
(*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i);
(*this)->member[i].addr.s_addr =
htonl(ntohl(addr.s_addr) + i);
(*this)->member[i].inuse = 0;
@ -267,19 +274,18 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
(*this)->member[i].prev = (*this)->lastdyn;
if ((*this)->lastdyn) {
(*this)->lastdyn->next = &((*this)->member[i]);
}
else {
} else {
(*this)->firstdyn = &((*this)->member[i]);
}
(*this)->lastdyn = &((*this)->member[i]);
(*this)->member[i].next = NULL; /* Redundant */
( void)ippool_hashadd(*this, &(*this)->member[i]);
(void)ippool_hashadd(*this, &(*this)->member[i]);
}
(*this)->firststat = NULL;
(*this)->laststat = NULL;
for (i = dynsize; i<listsize; i++) {
for (i = dynsize; i < listsize; i++) {
(*this)->member[i].addr.s_addr = 0;
(*this)->member[i].inuse = 0;
@ -288,22 +294,21 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
(*this)->member[i].prev = (*this)->laststat;
if ((*this)->laststat) {
(*this)->laststat->next = &((*this)->member[i]);
}
else {
} else {
(*this)->firststat = &((*this)->member[i]);
}
(*this)->laststat = &((*this)->member[i]);
(*this)->member[i].next = NULL; /* Redundant */
}
if (0) (void)ippool_printaddr(*this);
if (0)
(void)ippool_printaddr(*this);
return 0;
}
/* Delete existing address pool */
int ippool_free(struct ippool_t *this) {
int ippool_free(struct ippool_t *this)
{
free(this->hash);
free(this->member);
free(this);
@ -312,7 +317,8 @@ int ippool_free(struct ippool_t *this) {
/* Find an IP address in the pool */
int ippool_getip(struct ippool_t *this, struct ippoolm_t **member,
struct in_addr *addr) {
struct in_addr *addr)
{
struct ippoolm_t *p;
uint32_t hash;
@ -320,12 +326,14 @@ int ippool_getip(struct ippool_t *this, struct ippoolm_t **member,
hash = ippool_hash4(addr) & this->hashmask;
for (p = this->hash[hash]; p; p = p->nexthash) {
if ((p->addr.s_addr == addr->s_addr) && (p->inuse)) {
if (member) *member = p;
if (member)
*member = p;
return 0;
}
}
if (member) *member = NULL;
/*sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address could not be found");*/
if (member)
*member = NULL;
/*sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address could not be found"); */
return -1;
}
@ -337,7 +345,8 @@ int ippool_getip(struct ippool_t *this, struct ippoolm_t **member,
* address space.
**/
int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
struct in_addr *addr, int statip) {
struct in_addr *addr, int statip)
{
struct ippoolm_t *p;
struct ippoolm_t *p2 = NULL;
uint32_t hash;
@ -354,20 +363,23 @@ int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
*
*/
if (0) (void)ippool_printaddr(this);
if (0)
(void)ippool_printaddr(this);
/* First check to see if this type of address is allowed */
if ((addr) && (addr->s_addr) && statip) { /* IP address given */
if (!this->allowstat) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Static IP address not allowed");
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Static IP address not allowed");
return -1;
}
if ((addr->s_addr & this->statmask.s_addr) != this->stataddr.s_addr) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Static out of range");
if ((addr->s_addr & this->statmask.s_addr) !=
this->stataddr.s_addr) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Static out of range");
return -1;
}
}
else {
} else {
if (!this->allowdyn) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Dynamic IP address not allowed");
@ -394,13 +406,12 @@ int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
/* If not found yet and dynamic IP then allocate dynamic IP */
if ((!p2) && (!statip)) {
if (!this ->firstdyn) {
if (!this->firstdyn) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"No more IP addresses available");
return -1;
}
else
p2 = this ->firstdyn;
} else
p2 = this->firstdyn;
}
if (p2) { /* Was allocated from dynamic address pool */
@ -424,7 +435,8 @@ int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
p2->inuse = 1; /* Dynamic address in use */
*member = p2;
if (0) (void)ippool_printaddr(this);
if (0)
(void)ippool_printaddr(this);
return 0; /* Success */
}
@ -436,9 +448,8 @@ int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"No more IP addresses available");
return -1; /* No more available */
}
else
p2 = this ->firststat;
} else
p2 = this->firststat;
/* Remove from linked list of free static addresses */
if (p2->prev)
@ -455,7 +466,8 @@ int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
memcpy(&p2->addr, addr, sizeof(addr));
*member = p2;
(void)ippool_hashadd(this, *member);
if (0) (void)ippool_printaddr(this);
if (0)
(void)ippool_printaddr(this);
return 0; /* Success */
}
@ -464,10 +476,11 @@ int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
return -1; /* Should never get here. TODO: Bad code */
}
int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member)
{
int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member) {
if (0) (void)ippool_printaddr(this);
if (0)
(void)ippool_printaddr(this);
if (!member->inuse) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address not in use");
@ -483,15 +496,15 @@ int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member) {
member->prev = this->lastdyn;
if (this->lastdyn) {
this->lastdyn->next = member;
}
else {
} else {
this->firstdyn = member;
}
this->lastdyn = member;
member->inuse = 0;
member->peer = NULL;
if (0) (void)ippool_printaddr(this);
if (0)
(void)ippool_printaddr(this);
return 0;
case 2: /* Allocated from static address space */
if (ippool_hashdel(this, member))
@ -500,8 +513,7 @@ int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member) {
member->prev = this->laststat;
if (this->laststat) {
this->laststat->next = member;
}
else {
} else {
this->firststat = member;
}
this->laststat = member;
@ -510,15 +522,16 @@ int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member) {
member->addr.s_addr = 0;
member->peer = NULL;
member->nexthash = NULL;
if (0) (void)ippool_printaddr(this);
if (0)
(void)ippool_printaddr(this);
return 0;
default: /* Should not happen */
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Could not free IP address");
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Could not free IP address");
return -1;
}
}
#ifndef IPPOOL_NOIP6
extern unsigned long int ippool_hash6(struct in6_addr *addr);
extern int ippool_getip6(struct ippool_t *this, struct in6_addr *addr);

View File

@ -95,7 +95,6 @@ extern int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member);
extern int ippool_aton(struct in_addr *addr, struct in_addr *mask,
char *pool, int number);
#ifndef IPPOOL_NOIP6
extern unsigned long int ippool_hash6(struct in6_addr *addr);
extern int ippool_getip6(struct ippool_t *this, struct in6_addr *addr);

View File

@ -17,10 +17,10 @@
* statistical properties and speed. It is NOT recommended for cryptographic
* purposes.
**/
unsigned long int lookup( k, length, level)
unsigned long int lookup(k, length, level)
register unsigned char *k; /* the key */
register unsigned long int length; /* the length of the key */
register unsigned long int level; /* the previous hash, or an arbitrary value*/
register unsigned long int level; /* the previous hash, or an arbitrary value */
{
#define mix(a,b,c) \
@ -38,7 +38,7 @@ register unsigned long int level; /* the previous hash, or an arbitrary value*/
typedef unsigned long int ub4; /* unsigned 4-byte quantities */
typedef unsigned char ub1; /* unsigned 1-byte quantities */
register unsigned long int a,b,c,len;
register unsigned long int a, b, c, len;
/* Set up the internal state */
len = length;
@ -46,35 +46,47 @@ register unsigned long int level; /* the previous hash, or an arbitrary value*/
c = level; /* the previous hash value */
/*---------------------------------------- handle most of the key */
while (len >= 12)
{
a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
mix(a,b,c);
k += 12; len -= 12;
while (len >= 12) {
a += (k[0] + ((ub4) k[1] << 8) + ((ub4) k[2] << 16) +
((ub4) k[3] << 24));
b += (k[4] + ((ub4) k[5] << 8) + ((ub4) k[6] << 16) +
((ub4) k[7] << 24));
c += (k[8] + ((ub4) k[9] << 8) + ((ub4) k[10] << 16) +
((ub4) k[11] << 24));
mix(a, b, c);
k += 12;
len -= 12;
}
/*------------------------------------- handle the last 11 bytes */
c += length;
switch(len) /* all the case statements fall through */
{
case 11: c+=((ub4)k[10]<<24);
case 10: c+=((ub4)k[9]<<16);
case 9 : c+=((ub4)k[8]<<8);
switch (len) { /* all the case statements fall through */
case 11:
c += ((ub4) k[10] << 24);
case 10:
c += ((ub4) k[9] << 16);
case 9:
c += ((ub4) k[8] << 8);
/* the first byte of c is reserved for the length */
case 8 : b+=((ub4)k[7]<<24);
case 7 : b+=((ub4)k[6]<<16);
case 6 : b+=((ub4)k[5]<<8);
case 5 : b+=k[4];
case 4 : a+=((ub4)k[3]<<24);
case 3 : a+=((ub4)k[2]<<16);
case 2 : a+=((ub4)k[1]<<8);
case 1 : a+=k[0];
case 8:
b += ((ub4) k[7] << 24);
case 7:
b += ((ub4) k[6] << 16);
case 6:
b += ((ub4) k[5] << 8);
case 5:
b += k[4];
case 4:
a += ((ub4) k[3] << 24);
case 3:
a += ((ub4) k[2] << 16);
case 2:
a += ((ub4) k[1] << 8);
case 1:
a += k[0];
/* case 0: nothing left to add */
}
mix(a,b,c);
mix(a, b, c);
/*-------------------------------------------- report the result */
return c;
}

View File

@ -20,6 +20,7 @@
#ifndef _LOOKUP_H
#define _LOOKUP_H
unsigned long int lookup( unsigned char *k, unsigned long int length, unsigned long int level);
unsigned long int lookup(unsigned char *k, unsigned long int length,
unsigned long int level);
#endif /* !_LOOKUP_H */

View File

@ -20,23 +20,25 @@
#include "syserr.h"
void sys_err(int pri, char *fn, int ln, int en, char *fmt, ...) {
void sys_err(int pri, char *fn, int ln, int en, char *fmt, ...)
{
va_list args;
char buf[SYSERR_MSGSIZE];
va_start(args, fmt);
vsnprintf(buf, SYSERR_MSGSIZE, fmt, args);
va_end(args);
buf[SYSERR_MSGSIZE-1] = 0; /* Make sure it is null terminated */
buf[SYSERR_MSGSIZE - 1] = 0; /* Make sure it is null terminated */
if (en)
syslog(pri, "%s: %d: %d (%s) %s", fn, ln, en, strerror(en), buf);
syslog(pri, "%s: %d: %d (%s) %s", fn, ln, en, strerror(en),
buf);
else
syslog(pri, "%s: %d: %s", fn, ln, buf);
}
void sys_errpack(int pri, char *fn, int ln, int en, struct sockaddr_in *peer,
void *pack, unsigned len, char *fmt, ...) {
void *pack, unsigned len, char *fmt, ...)
{
va_list args;
char buf[SYSERR_MSGSIZE];
@ -47,24 +49,25 @@ void sys_errpack(int pri, char *fn, int ln, int en, struct sockaddr_in *peer,
va_start(args, fmt);
vsnprintf(buf, SYSERR_MSGSIZE, fmt, args);
va_end(args);
buf[SYSERR_MSGSIZE-1] = 0;
buf[SYSERR_MSGSIZE - 1] = 0;
snprintf(buf2, SYSERR_MSGSIZE, "Packet from %s:%u, length: %d, content:",
inet_ntoa(peer->sin_addr),
ntohs(peer->sin_port),
len);
buf2[SYSERR_MSGSIZE-1] = 0;
snprintf(buf2, SYSERR_MSGSIZE,
"Packet from %s:%u, length: %d, content:",
inet_ntoa(peer->sin_addr), ntohs(peer->sin_port), len);
buf2[SYSERR_MSGSIZE - 1] = 0;
pos = strlen(buf2);
for(n=0; n<len; n++) {
if ((pos+4)<SYSERR_MSGSIZE) {
sprintf((buf2+pos), " %02hhx", ((unsigned char*)pack)[n]);
for (n = 0; n < len; n++) {
if ((pos + 4) < SYSERR_MSGSIZE) {
sprintf((buf2 + pos), " %02hhx",
((unsigned char *)pack)[n]);
pos += 3;
}
}
buf2[pos] = 0;
if (en)
syslog(pri, "%s: %d: %d (%s) %s. %s", fn, ln, en, strerror(en), buf, buf2);
syslog(pri, "%s: %d: %d (%s) %s. %s", fn, ln, en, strerror(en),
buf, buf2);
else
syslog(pri, "%s: %d: %s. %s", fn, ln, buf, buf2);

242
lib/tun.c
View File

@ -16,7 +16,6 @@
*
*/
#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>
@ -64,18 +63,16 @@
#error "Unknown platform!"
#endif
#include "tun.h"
#include "syserr.h"
#if defined(__linux__)
int tun_nlattr(struct nlmsghdr *n, int nsize, int type, void *d, int dlen)
{
int len = RTA_LENGTH(dlen);
int alen = NLMSG_ALIGN(n->nlmsg_len);
struct rtattr *rta = (struct rtattr*) (((void*)n) + alen);
struct rtattr *rta = (struct rtattr *)(((void *)n) + alen);
if (alen + len > nsize)
return -1;
rta->rta_len = len;
@ -85,23 +82,22 @@ int tun_nlattr(struct nlmsghdr *n, int nsize, int type, void *d, int dlen)
return 0;
}
int tun_gifindex(struct tun_t *this, __u32 *index) {
int tun_gifindex(struct tun_t *this, __u32 * index)
{
struct ifreq ifr;
int fd;
memset (&ifr, '\0', sizeof (ifr));
memset(&ifr, '\0', sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET;
ifr.ifr_dstaddr.sa_family = AF_INET;
ifr.ifr_netmask.sa_family = AF_INET;
strncpy(ifr.ifr_name, this->devname, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */
ifr.ifr_name[IFNAMSIZ - 1] = 0; /* Make sure to terminate */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"socket() failed");
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "socket() failed");
}
if (ioctl(fd, SIOCGIFINDEX, &ifr)) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"ioctl() failed");
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "ioctl() failed");
close(fd);
return -1;
}
@ -111,17 +107,17 @@ int tun_gifindex(struct tun_t *this, __u32 *index) {
}
#endif
int tun_sifflags(struct tun_t *this, int flags) {
int tun_sifflags(struct tun_t *this, int flags)
{
struct ifreq ifr;
int fd;
memset (&ifr, '\0', sizeof (ifr));
memset(&ifr, '\0', sizeof(ifr));
ifr.ifr_flags = flags;
strncpy(ifr.ifr_name, this->devname, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */
ifr.ifr_name[IFNAMSIZ - 1] = 0; /* Make sure to terminate */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"socket() failed");
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "socket() failed");
}
if (ioctl(fd, SIOCSIFFLAGS, &ifr)) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
@ -133,7 +129,6 @@ int tun_sifflags(struct tun_t *this, int flags) {
return 0;
}
/* Currently unused
int tun_addroute2(struct tun_t *this,
struct in_addr *dst,
@ -232,8 +227,8 @@ int tun_addroute2(struct tun_t *this,
int tun_addaddr(struct tun_t *this,
struct in_addr *addr,
struct in_addr *dstaddr,
struct in_addr *netmask) {
struct in_addr *dstaddr, struct in_addr *netmask)
{
#if defined(__linux__)
struct {
@ -270,8 +265,7 @@ int tun_addaddr(struct tun_t *this,
tun_nlattr(&req.n, sizeof(req), IFA_LOCAL, dstaddr, sizeof(dstaddr));
if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"socket() failed");
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "socket() failed");
return -1;
}
@ -279,15 +273,14 @@ int tun_addaddr(struct tun_t *this,
local.nl_family = AF_NETLINK;
local.nl_groups = 0;
if (bind(fd, (struct sockaddr*)&local, sizeof(local)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"bind() failed");
if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "bind() failed");
close(fd);
return -1;
}
addr_len = sizeof(local);
if (getsockname(fd, (struct sockaddr*)&local, &addr_len) < 0) {
if (getsockname(fd, (struct sockaddr *)&local, &addr_len) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"getsockname() failed");
close(fd);
@ -308,12 +301,11 @@ int tun_addaddr(struct tun_t *this,
return -1;
}
iov.iov_base = (void*)&req.n;
iov.iov_base = (void *)&req.n;
iov.iov_len = req.n.nlmsg_len;
msg.msg_name = (void*)&nladdr;
msg.msg_namelen = sizeof(nladdr),
msg.msg_iov = &iov;
msg.msg_name = (void *)&nladdr;
msg.msg_namelen = sizeof(nladdr), msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
@ -347,31 +339,33 @@ int tun_addaddr(struct tun_t *this,
/* Set up interface name */
strncpy(areq.ifra_name, this->devname, IFNAMSIZ);
areq.ifra_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */
areq.ifra_name[IFNAMSIZ - 1] = 0; /* Make sure to terminate */
((struct sockaddr_in*) &areq.ifra_addr)->sin_family = AF_INET;
((struct sockaddr_in*) &areq.ifra_addr)->sin_len = sizeof(areq.ifra_addr);
((struct sockaddr_in*) &areq.ifra_addr)->sin_addr.s_addr = addr->s_addr;
((struct sockaddr_in *)&areq.ifra_addr)->sin_family = AF_INET;
((struct sockaddr_in *)&areq.ifra_addr)->sin_len =
sizeof(areq.ifra_addr);
((struct sockaddr_in *)&areq.ifra_addr)->sin_addr.s_addr = addr->s_addr;
((struct sockaddr_in*) &areq.ifra_mask)->sin_family = AF_INET;
((struct sockaddr_in*) &areq.ifra_mask)->sin_len = sizeof(areq.ifra_mask);
((struct sockaddr_in*) &areq.ifra_mask)->sin_addr.s_addr = netmask->s_addr;
((struct sockaddr_in *)&areq.ifra_mask)->sin_family = AF_INET;
((struct sockaddr_in *)&areq.ifra_mask)->sin_len =
sizeof(areq.ifra_mask);
((struct sockaddr_in *)&areq.ifra_mask)->sin_addr.s_addr =
netmask->s_addr;
/* For some reason FreeBSD uses ifra_broadcast for specifying dstaddr */
((struct sockaddr_in*) &areq.ifra_broadaddr)->sin_family = AF_INET;
((struct sockaddr_in*) &areq.ifra_broadaddr)->sin_len =
((struct sockaddr_in *)&areq.ifra_broadaddr)->sin_family = AF_INET;
((struct sockaddr_in *)&areq.ifra_broadaddr)->sin_len =
sizeof(areq.ifra_broadaddr);
((struct sockaddr_in*) &areq.ifra_broadaddr)->sin_addr.s_addr =
((struct sockaddr_in *)&areq.ifra_broadaddr)->sin_addr.s_addr =
dstaddr->s_addr;
/* Create a channel to the NET kernel. */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"socket() failed");
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "socket() failed");
return -1;
}
if (ioctl(fd, SIOCAIFADDR, (void *) &areq) < 0) {
if (ioctl(fd, SIOCAIFADDR, (void *)&areq) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"ioctl(SIOCAIFADDR) failed");
close(fd);
@ -397,16 +391,14 @@ int tun_addaddr(struct tun_t *this,
}
int tun_setaddr(struct tun_t *this,
struct in_addr *addr,
struct in_addr *dstaddr,
struct in_addr *netmask)
struct in_addr *dstaddr, struct in_addr *netmask)
{
struct ifreq ifr;
int fd;
memset (&ifr, '\0', sizeof (ifr));
memset(&ifr, '\0', sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET;
ifr.ifr_dstaddr.sa_family = AF_INET;
@ -414,32 +406,30 @@ int tun_setaddr(struct tun_t *this,
ifr.ifr_netmask.sa_family = AF_INET;
#elif defined(__FreeBSD__) || defined (__APPLE__)
((struct sockaddr_in *) &ifr.ifr_addr)->sin_len =
sizeof (struct sockaddr_in);
((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_len =
sizeof (struct sockaddr_in);
((struct sockaddr_in *)&ifr.ifr_addr)->sin_len =
sizeof(struct sockaddr_in);
((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_len =
sizeof(struct sockaddr_in);
#endif
strncpy(ifr.ifr_name, this->devname, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */
ifr.ifr_name[IFNAMSIZ - 1] = 0; /* Make sure to terminate */
/* Create a channel to the NET kernel. */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"socket() failed");
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "socket() failed");
return -1;
}
if (addr) { /* Set the interface address */
this->addr.s_addr = addr->s_addr;
memcpy(&((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr, addr,
memcpy(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr, addr,
sizeof(*addr));
if (ioctl(fd, SIOCSIFADDR, (void *) &ifr) < 0) {
if (ioctl(fd, SIOCSIFADDR, (void *)&ifr) < 0) {
if (errno != EEXIST) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"ioctl(SIOCSIFADDR) failed");
}
else {
} else {
sys_err(LOG_WARNING, __FILE__, __LINE__, errno,
"ioctl(SIOCSIFADDR): Address already exists");
}
@ -450,9 +440,9 @@ int tun_setaddr(struct tun_t *this,
if (dstaddr) { /* Set the destination address */
this->dstaddr.s_addr = dstaddr->s_addr;
memcpy(&((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr,
memcpy(&((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr,
dstaddr, sizeof(*dstaddr));
if (ioctl(fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
if (ioctl(fd, SIOCSIFDSTADDR, (caddr_t) & ifr) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"ioctl(SIOCSIFDSTADDR) failed");
close(fd);
@ -463,21 +453,21 @@ int tun_setaddr(struct tun_t *this,
if (netmask) { /* Set the netmask */
this->netmask.s_addr = netmask->s_addr;
#if defined(__linux__)
memcpy(&((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr,
memcpy(&((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr,
netmask, sizeof(*netmask));
#elif defined(__FreeBSD__) || defined (__APPLE__)
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr =
((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr =
netmask->s_addr;
#elif defined(__sun__)
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr =
((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr =
netmask->s_addr;
#else
#error "Unknown platform!"
#endif
if (ioctl(fd, SIOCSIFNETMASK, (void *) &ifr) < 0) {
if (ioctl(fd, SIOCSIFNETMASK, (void *)&ifr) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"ioctl(SIOCSIFNETMASK) failed");
close(fd);
@ -505,12 +495,9 @@ int tun_setaddr(struct tun_t *this,
int tun_route(struct tun_t *this,
struct in_addr *dst,
struct in_addr *gateway,
struct in_addr *mask,
int delete)
struct in_addr *gateway, struct in_addr *mask, int delete)
{
/* TODO: Learn how to set routing table on sun */
#if defined(__linux__)
@ -518,35 +505,33 @@ int tun_route(struct tun_t *this,
struct rtentry r;
int fd;
memset (&r, '\0', sizeof (r));
memset(&r, '\0', sizeof(r));
r.rt_flags = RTF_UP | RTF_GATEWAY; /* RTF_HOST not set */
/* Create a channel to the NET kernel. */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"socket() failed");
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "socket() failed");
return -1;
}
r.rt_dst.sa_family = AF_INET;
r.rt_gateway.sa_family = AF_INET;
r.rt_genmask.sa_family = AF_INET;
memcpy(&((struct sockaddr_in *) &r.rt_dst)->sin_addr, dst, sizeof(*dst));
memcpy(&((struct sockaddr_in *) &r.rt_gateway)->sin_addr, gateway,
memcpy(&((struct sockaddr_in *)&r.rt_dst)->sin_addr, dst, sizeof(*dst));
memcpy(&((struct sockaddr_in *)&r.rt_gateway)->sin_addr, gateway,
sizeof(*gateway));
memcpy(&((struct sockaddr_in *) &r.rt_genmask)->sin_addr, mask,
memcpy(&((struct sockaddr_in *)&r.rt_genmask)->sin_addr, mask,
sizeof(*mask));
if (delete) {
if (ioctl(fd, SIOCDELRT, (void *) &r) < 0) {
if (ioctl(fd, SIOCDELRT, (void *)&r) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"ioctl(SIOCDELRT) failed");
close(fd);
return -1;
}
}
else {
if (ioctl(fd, SIOCADDRT, (void *) &r) < 0) {
} else {
if (ioctl(fd, SIOCADDRT, (void *)&r) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"ioctl(SIOCADDRT) failed");
close(fd);
@ -558,19 +543,18 @@ int tun_route(struct tun_t *this,
#elif defined(__FreeBSD__) || defined (__APPLE__)
struct {
struct {
struct rt_msghdr rt;
struct sockaddr_in dst;
struct sockaddr_in gate;
struct sockaddr_in mask;
} req;
} req;
int fd;
struct rt_msghdr *rtm;
if((fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"socket() failed");
if ((fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "socket() failed");
return -1;
}
@ -582,8 +566,7 @@ struct {
rtm->rtm_version = RTM_VERSION;
if (delete) {
rtm->rtm_type = RTM_DELETE;
}
else {
} else {
rtm->rtm_type = RTM_ADD;
}
rtm->rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; /* TODO */
@ -602,9 +585,8 @@ struct {
req.mask.sin_addr.s_addr = mask->s_addr;
req.gate.sin_addr.s_addr = gateway->s_addr;
if(write(fd, rtm, rtm->rtm_msglen) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"write() failed");
if (write(fd, rtm, rtm->rtm_msglen) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "write() failed");
close(fd);
return -1;
}
@ -624,21 +606,18 @@ struct {
int tun_addroute(struct tun_t *this,
struct in_addr *dst,
struct in_addr *gateway,
struct in_addr *mask)
struct in_addr *gateway, struct in_addr *mask)
{
return tun_route(this, dst, gateway, mask, 0);
}
int tun_delroute(struct tun_t *this,
struct in_addr *dst,
struct in_addr *gateway,
struct in_addr *mask)
struct in_addr *gateway, struct in_addr *mask)
{
return tun_route(this, dst, gateway, mask, 1);
}
int tun_new(struct tun_t **tun)
{
@ -646,7 +625,7 @@ int tun_new(struct tun_t **tun)
struct ifreq ifr;
#elif defined(__FreeBSD__) || defined (__APPLE__)
char devname[IFNAMSIZ+5]; /* "/dev/" + ifname */
char devname[IFNAMSIZ + 5]; /* "/dev/" + ifname */
int devnum;
struct ifaliasreq areq;
int fd;
@ -681,14 +660,14 @@ int tun_new(struct tun_t **tun)
used to obtain the network interface name */
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI; /* Tun device, no packet info */
if (ioctl((*tun)->fd, TUNSETIFF, (void *) &ifr) < 0) {
if (ioctl((*tun)->fd, TUNSETIFF, (void *)&ifr) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "ioctl() failed");
close((*tun)->fd);
return -1;
}
strncpy((*tun)->devname, ifr.ifr_name, IFNAMSIZ);
(*tun)->devname[IFNAMSIZ-1] = 0;
(*tun)->devname[IFNAMSIZ - 1] = 0;
ioctl((*tun)->fd, TUNSETNOCSUM, 1); /* Disable checksums */
return 0;
@ -699,11 +678,14 @@ int tun_new(struct tun_t **tun)
for (devnum = 0; devnum < 255; devnum++) { /* TODO 255 */
snprintf(devname, sizeof(devname), "/dev/tun%d", devnum);
devname[sizeof(devname)] = 0;
if (((*tun)->fd = open(devname, O_RDWR)) >= 0) break;
if (errno != EBUSY) break;
if (((*tun)->fd = open(devname, O_RDWR)) >= 0)
break;
if (errno != EBUSY)
break;
}
if ((*tun)->fd < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't find tunnel device");
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"Can't find tunnel device");
return -1;
}
@ -717,61 +699,67 @@ int tun_new(struct tun_t **tun)
/* Set up interface name */
strncpy(areq.ifra_name, (*tun)->devname, IFNAMSIZ);
areq.ifra_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */
areq.ifra_name[IFNAMSIZ - 1] = 0; /* Make sure to terminate */
/* Create a channel to the NET kernel. */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"socket() failed");
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "socket() failed");
return -1;
}
/* Delete any IP addresses until SIOCDIFADDR fails */
while (ioctl(fd, SIOCDIFADDR, (void *) &areq) != -1);
while (ioctl(fd, SIOCDIFADDR, (void *)&areq) != -1) ;
close(fd);
return 0;
#elif defined(__sun__)
if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/udp");
if ((ip_fd = open("/dev/udp", O_RDWR, 0)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"Can't open /dev/udp");
return -1;
}
if( ((*tun)->fd = open("/dev/tun", O_RDWR, 0)) < 0){
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/tun");
if (((*tun)->fd = open("/dev/tun", O_RDWR, 0)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"Can't open /dev/tun");
return -1;
}
/* Assign a new PPA and get its unit number. */
if( (ppa = ioctl((*tun)->fd, TUNNEWPPA, -1)) < 0){
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't assign new interface");
if ((ppa = ioctl((*tun)->fd, TUNNEWPPA, -1)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"Can't assign new interface");
return -1;
}
if( (if_fd = open("/dev/tun", O_RDWR, 0)) < 0){
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/tun (2)");
if ((if_fd = open("/dev/tun", O_RDWR, 0)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"Can't open /dev/tun (2)");
return -1;
}
if(ioctl(if_fd, I_PUSH, "ip") < 0){
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't push IP module");
if (ioctl(if_fd, I_PUSH, "ip") < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"Can't push IP module");
return -1;
}
/* Assign ppa according to the unit number returned by tun device */
if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0){
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't set PPA %d", ppa);
if (ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't set PPA %d",
ppa);
return -1;
}
/* Link the two streams */
if ((muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't link TUN device to IP");
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"Can't link TUN device to IP");
return -1;
}
close (if_fd);
close(if_fd);
snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", ppa);
(*tun)->devname[sizeof((*tun)->devname)] = 0;
@ -782,7 +770,8 @@ int tun_new(struct tun_t **tun)
if (ioctl(ip_fd, SIOCSIFMUXID, &ifr) < 0) {
ioctl(ip_fd, I_PUNLINK, muxid);
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't set multiplexor id");
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"Can't set multiplexor id");
return -1;
}
@ -814,14 +803,13 @@ int tun_free(struct tun_t *tun)
return 0;
}
int tun_set_cb_ind(struct tun_t *this,
int (*cb_ind) (struct tun_t *tun, void *pack, unsigned len)) {
int (*cb_ind) (struct tun_t * tun, void *pack, unsigned len))
{
this->cb_ind = cb_ind;
return 0;
}
int tun_decaps(struct tun_t *this)
{
@ -862,7 +850,6 @@ int tun_decaps(struct tun_t *this)
}
int tun_encaps(struct tun_t *tun, void *pack, unsigned len)
{
@ -880,7 +867,8 @@ int tun_encaps(struct tun_t *tun, void *pack, unsigned len)
#endif
}
int tun_runscript(struct tun_t *tun, char* script) {
int tun_runscript(struct tun_t *tun, char *script)
{
char buf[TUN_SCRIPTSIZE];
char snet[TUN_ADDRSIZE];
@ -888,18 +876,18 @@ int tun_runscript(struct tun_t *tun, char* script) {
int rc;
strncpy(snet, inet_ntoa(tun->addr), sizeof(snet));
snet[sizeof(snet)-1] = 0;
snet[sizeof(snet) - 1] = 0;
strncpy(smask, inet_ntoa(tun->netmask), sizeof(smask));
smask[sizeof(smask)-1] = 0;
smask[sizeof(smask) - 1] = 0;
/* system("ipup /dev/tun0 192.168.0.10 255.255.255.0"); */
snprintf(buf, sizeof(buf), "%s %s %s %s",
script, tun->devname, snet, smask);
buf[sizeof(buf)-1] = 0;
buf[sizeof(buf) - 1] = 0;
rc = system(buf);
if (rc == -1) {
sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Error executing command %s",
buf);
sys_err(LOG_ERR, __FILE__, __LINE__, errno,
"Error executing command %s", buf);
return -1;
}
return 0;

View File

@ -33,7 +33,6 @@ struct tun_packet_t {
unsigned int dst:32;
};
/* ***********************************************************
* Information storage for each tun instance
*************************************************************/
@ -45,11 +44,10 @@ struct tun_t {
struct in_addr netmask;
int addrs; /* Number of allocated IP addresses */
int routes; /* One if we allocated an automatic route */
char devname[IFNAMSIZ];/* Name of the tun device */
int (*cb_ind) (struct tun_t *tun, void *pack, unsigned len);
char devname[IFNAMSIZ]; /* Name of the tun device */
int (*cb_ind) (struct tun_t * tun, void *pack, unsigned len);
};
extern int tun_new(struct tun_t **tun);
extern int tun_free(struct tun_t *tun);
extern int tun_decaps(struct tun_t *this);
@ -58,7 +56,6 @@ extern int tun_encaps(struct tun_t *tun, void *pack, unsigned len);
extern int tun_addaddr(struct tun_t *this, struct in_addr *addr,
struct in_addr *dstaddr, struct in_addr *netmask);
extern int tun_setaddr(struct tun_t *this, struct in_addr *our_adr,
struct in_addr *his_adr, struct in_addr *net_mask);
@ -66,9 +63,9 @@ int tun_addroute(struct tun_t *this, struct in_addr *dst,
struct in_addr *gateway, struct in_addr *mask);
extern int tun_set_cb_ind(struct tun_t *this,
int (*cb_ind) (struct tun_t *tun, void *pack, unsigned len));
int (*cb_ind) (struct tun_t * tun, void *pack,
unsigned len));
extern int tun_runscript(struct tun_t *tun, char* script);
extern int tun_runscript(struct tun_t *tun, char *script);
#endif /* !_TUN_H */

File diff suppressed because it is too large Load Diff

View File

@ -22,189 +22,188 @@ extern "C" {
#define CMDLINE_PARSER_VERSION VERSION
#endif
struct gengetopt_args_info
{
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 debug_flag; /* Run in debug mode (default=off). */
const char *debug_help; /* Run in debug mode help description. */
char * conf_arg; /* Read configuration file. */
char * conf_orig; /* Read configuration file original value given at command line. */
char *conf_arg; /* Read configuration file. */
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='./sgsnemu.pid'). */
char * pidfile_orig; /* Filename of process id file original value given at command line. */
char *pidfile_arg; /* Filename of process id file (default='./sgsnemu.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='./'). */
char * statedir_orig; /* Directory of nonvolatile data original value given at command line. */
char *statedir_arg; /* Directory of nonvolatile data (default='./'). */
char *statedir_orig; /* Directory of nonvolatile data original value given at command line. */
const char *statedir_help; /* Directory of nonvolatile data help description. */
char * dns_arg; /* DNS Server to use. */
char * dns_orig; /* DNS Server to use original value given at command line. */
char *dns_arg; /* DNS Server to use. */
char *dns_orig; /* DNS Server to use original value given at command line. */
const char *dns_help; /* DNS Server to use help description. */
char * listen_arg; /* Local interface. */
char * listen_orig; /* Local interface original value given at command line. */
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 * remote_arg; /* Remote host. */
char * remote_orig; /* Remote host original value given at command line. */
char *remote_arg; /* Remote host. */
char *remote_orig; /* Remote host original value given at command line. */
const char *remote_help; /* Remote host help description. */
int contexts_arg; /* Number of contexts (default='1'). */
char * contexts_orig; /* Number of contexts original value given at command line. */
char *contexts_orig; /* Number of contexts original value given at command line. */
const char *contexts_help; /* Number of contexts help description. */
int timelimit_arg; /* Exit after timelimit seconds (default='0'). */
char * timelimit_orig; /* Exit after timelimit seconds original value given at command line. */
char *timelimit_orig; /* Exit after timelimit seconds original value given at command line. */
const char *timelimit_help; /* Exit after timelimit seconds help description. */
int gtpversion_arg; /* GTP version to use (default='1'). */
char * gtpversion_orig; /* GTP version to use original value given at command line. */
char *gtpversion_orig; /* GTP version to use original value given at command line. */
const char *gtpversion_help; /* GTP version to use help description. */
char * apn_arg; /* Access point name (default='internet'). */
char * apn_orig; /* Access point name original value given at command line. */
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 selmode_arg; /* Selection mode (default='0x01'). */
char * selmode_orig; /* Selection mode original value given at command line. */
char *selmode_orig; /* Selection mode original value given at command line. */
const char *selmode_help; /* Selection mode help description. */
char * rattype_arg; /* Radio Access Technology Type (optional). */
char * rattype_orig;
char * rattype_help;
char * userloc_arg; /* User Location Information (optional). */
char * userloc_orig;
char * userloc_help;
char * rai_arg; /* Routing Area Information (optional). */
char * rai_orig;
char * rai_help;
char * mstz_arg; /* MS Time Zone (optional). */
char * mstz_orig;
char * mstz_help;
char * imeisv_arg; /* IMEI(SV) (optional). */
char * imeisv_orig;
char * imeisv_help;
char * imsi_arg; /* IMSI (default='240010123456789'). */
char * imsi_orig; /* IMSI original value given at command line. */
char *rattype_arg; /* Radio Access Technology Type (optional). */
char *rattype_orig;
char *rattype_help;
char *userloc_arg; /* User Location Information (optional). */
char *userloc_orig;
char *userloc_help;
char *rai_arg; /* Routing Area Information (optional). */
char *rai_orig;
char *rai_help;
char *mstz_arg; /* MS Time Zone (optional). */
char *mstz_orig;
char *mstz_help;
char *imeisv_arg; /* IMEI(SV) (optional). */
char *imeisv_orig;
char *imeisv_help;
char *imsi_arg; /* IMSI (default='240010123456789'). */
char *imsi_orig; /* IMSI original value given at command line. */
const char *imsi_help; /* IMSI help description. */
int nsapi_arg; /* NSAPI (default='0'). */
char * nsapi_orig; /* NSAPI original value given at command line. */
char *nsapi_orig; /* NSAPI original value given at command line. */
const char *nsapi_help; /* NSAPI help description. */
char * msisdn_arg; /* Mobile Station ISDN number (default='46702123456'). */
char * msisdn_orig; /* Mobile Station ISDN number original value given at command line. */
char *msisdn_arg; /* Mobile Station ISDN number (default='46702123456'). */
char *msisdn_orig; /* Mobile Station ISDN number original value given at command line. */
const char *msisdn_help; /* Mobile Station ISDN number help description. */
int qos_arg; /* Requested quality of service (default='0x0b921f'). */
char * qos_orig; /* Requested quality of service original value given at command line. */
char *qos_orig; /* Requested quality of service original value given at command line. */
const char *qos_help; /* Requested quality of service help description. */
unsigned long long int qose1_arg; /* Requested quality of service Extension 1 */
char * qose1_orig; /* Requested quality of service Extension 1 original value given at command line. */
char *qose1_orig; /* Requested quality of service Extension 1 original value given at command line. */
int qose2_arg; /* Requested quality of service Extension 2 */
char * qose2_orig; /* Requested quality of service Extension 2 original value given at command line. */
char *qose2_orig; /* Requested quality of service Extension 2 original value given at command line. */
int qose3_arg; /* Requested quality of service Extension 3 */
char * qose3_orig; /* Requested quality of service Extension 3 original value given at command line. */
char *qose3_orig; /* Requested quality of service Extension 3 original value given at command line. */
int qose4_arg; /* Requested quality of service Extension 4 */
char * qose4_orig; /* Requested quality of service Extension 4 original value given at command line. */
char *qose4_orig; /* Requested quality of service Extension 4 original value given at command line. */
int charging_arg; /* Charging characteristics (default='0x0800'). */
char * charging_orig; /* Charging characteristics original value given at command line. */
char *charging_orig; /* Charging characteristics original value given at command line. */
const char *charging_help; /* Charging characteristics help description. */
char * uid_arg; /* Login user ID (default='mig'). */
char * uid_orig; /* Login user ID original value given at command line. */
char *uid_arg; /* Login user ID (default='mig'). */
char *uid_orig; /* Login user ID original value given at command line. */
const char *uid_help; /* Login user ID help description. */
char * pwd_arg; /* Login password (default='hemmelig'). */
char * pwd_orig; /* Login password original value given at command line. */
char *pwd_arg; /* Login password (default='hemmelig'). */
char *pwd_orig; /* Login password original value given at command line. */
const char *pwd_help; /* Login password help description. */
int createif_flag; /* Create local network interface (default=off). */
const char *createif_help; /* Create local network interface help description. */
char * net_arg; /* Network address for local interface. */
char * net_orig; /* Network address for local interface original value given at command line. */
char *net_arg; /* Network address for local interface. */
char *net_orig; /* Network address for local interface original value given at command line. */
const char *net_help; /* Network address for local interface help description. */
int defaultroute_flag; /* Create default route (default=off). */
const char *defaultroute_help; /* Create default route 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. */
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. */
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 * pinghost_arg; /* Ping remote host. */
char * pinghost_orig; /* Ping remote host original value given at command line. */
char *pinghost_arg; /* Ping remote host. */
char *pinghost_orig; /* Ping remote host original value given at command line. */
const char *pinghost_help; /* Ping remote host help description. */
int pingrate_arg; /* Number of ping req per second (default='1'). */
char * pingrate_orig; /* Number of ping req per second original value given at command line. */
char *pingrate_orig; /* Number of ping req per second original value given at command line. */
const char *pingrate_help; /* Number of ping req per second help description. */
int pingsize_arg; /* Number of ping data bytes (default='56'). */
char * pingsize_orig; /* Number of ping data bytes original value given at command line. */
char *pingsize_orig; /* Number of ping data bytes original value given at command line. */
const char *pingsize_help; /* Number of ping data bytes help description. */
int pingcount_arg; /* Number of ping req to send (default='0'). */
char * pingcount_orig; /* Number of ping req to send original value given at command line. */
char *pingcount_orig; /* Number of ping req to send original value given at command line. */
const char *pingcount_help; /* Number of ping req to send help description. */
int pingquiet_flag; /* Do not print ping packet info (default=off). */
const char *pingquiet_help; /* Do not print ping packet info help description. */
int norecovery_flag; /* Do not print ping packet info (default=off). */
const char *norecovery_help; /* Do not print ping packet info help description. */
int help_given ; /* Whether help was given. */
int version_given ; /* Whether version 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 dns_given ; /* Whether dns was given. */
int listen_given ; /* Whether listen was given. */
int remote_given ; /* Whether remote was given. */
int contexts_given ; /* Whether contexts was given. */
int timelimit_given ; /* Whether timelimit was given. */
int gtpversion_given ; /* Whether gtpversion was given. */
int apn_given ; /* Whether apn was given. */
int selmode_given ; /* Whether selmode was given. */
int rattype_given ; /* Whether rattype was given. */
int userloc_given ; /* Whether userloc was given. */
int rai_given ; /* Whether RAI was given. */
int mstz_given ; /* Whether mstz was given. */
int imeisv_given ; /* Whether imeisv was given. */
int imsi_given ; /* Whether imsi was given. */
int nsapi_given ; /* Whether nsapi was given. */
int msisdn_given ; /* Whether msisdn was given. */
int qos_given ; /* Whether qos was given. */
int qose1_given ; /* Whether qos Extension 1 was given. */
int qose2_given ; /* Whether qos Extension 2 was given. */
int qose3_given ; /* Whether qos Extension 3 was given. */
int qose4_given ; /* Whether qos Extension 4 was given. */
int charging_given ; /* Whether charging was given. */
int uid_given ; /* Whether uid was given. */
int pwd_given ; /* Whether pwd was given. */
int createif_given ; /* Whether createif was given. */
int net_given ; /* Whether net was given. */
int defaultroute_given ; /* Whether defaultroute was given. */
int ipup_given ; /* Whether ipup was given. */
int ipdown_given ; /* Whether ipdown was given. */
int pinghost_given ; /* Whether pinghost was given. */
int pingrate_given ; /* Whether pingrate was given. */
int pingsize_given ; /* Whether pingsize was given. */
int pingcount_given ; /* Whether pingcount was given. */
int pingquiet_given ; /* Whether pingquiet was given. */
int norecovery_given ; /* Whether norecovery was given. */
int help_given; /* Whether help was given. */
int version_given; /* Whether version 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 dns_given; /* Whether dns was given. */
int listen_given; /* Whether listen was given. */
int remote_given; /* Whether remote was given. */
int contexts_given; /* Whether contexts was given. */
int timelimit_given; /* Whether timelimit was given. */
int gtpversion_given; /* Whether gtpversion was given. */
int apn_given; /* Whether apn was given. */
int selmode_given; /* Whether selmode was given. */
int rattype_given; /* Whether rattype was given. */
int userloc_given; /* Whether userloc was given. */
int rai_given; /* Whether RAI was given. */
int mstz_given; /* Whether mstz was given. */
int imeisv_given; /* Whether imeisv was given. */
int imsi_given; /* Whether imsi was given. */
int nsapi_given; /* Whether nsapi was given. */
int msisdn_given; /* Whether msisdn was given. */
int qos_given; /* Whether qos was given. */
int qose1_given; /* Whether qos Extension 1 was given. */
int qose2_given; /* Whether qos Extension 2 was given. */
int qose3_given; /* Whether qos Extension 3 was given. */
int qose4_given; /* Whether qos Extension 4 was given. */
int charging_given; /* Whether charging was given. */
int uid_given; /* Whether uid was given. */
int pwd_given; /* Whether pwd was given. */
int createif_given; /* Whether createif was given. */
int net_given; /* Whether net was given. */
int defaultroute_given; /* Whether defaultroute was given. */
int ipup_given; /* Whether ipup was given. */
int ipdown_given; /* Whether ipdown was given. */
int pinghost_given; /* Whether pinghost was given. */
int pingrate_given; /* Whether pingrate was given. */
int pingsize_given; /* Whether pingsize was given. */
int pingcount_given; /* Whether pingcount was given. */
int pingquiet_given; /* Whether pingquiet was given. */
int norecovery_given; /* Whether norecovery was given. */
} ;
};
extern const char *gengetopt_args_info_purpose;
extern const char *gengetopt_args_info_usage;
extern const char *gengetopt_args_info_help[];
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,
int cmdline_parser(int argc, char *const *argv,
struct gengetopt_args_info *args_info);
int cmdline_parser2 (int argc, char * const *argv,
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,
int cmdline_parser_file_save(const char *filename,
struct gengetopt_args_info *args_info);
void cmdline_parser_print_help(void);
void cmdline_parser_print_version(void);
void cmdline_parser_print_help(void);
void cmdline_parser_print_version(void);
void cmdline_parser_init (struct gengetopt_args_info *args_info);
void cmdline_parser_free (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);
int cmdline_parser_configfile (char * const filename,
int cmdline_parser_configfile(char *const filename,
struct gengetopt_args_info *args_info,
int override, int initialize, int check_required);
int override, int initialize,
int check_required);
int cmdline_parser_required (struct gengetopt_args_info *args_info,
int cmdline_parser_required(struct gengetopt_args_info *args_info,
const char *prog_name);
#ifdef __cplusplus
}
#endif /* __cplusplus */

File diff suppressed because it is too large Load Diff