aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjjako <jjako>2004-04-28 14:52:58 +0000
committerjjako <jjako>2004-04-28 14:52:58 +0000
commitc6762cfc276183c4119649d652a0b9666ed4f2cb (patch)
tree972c34fc2b4ed756ab2021b9cec107acef318c50
parent73c908c20156f668e5cbf3ef479d3784b10229a7 (diff)
Solaris tun interface
-rw-r--r--ggsn/ggsn.c62
-rw-r--r--ggsn/ippool.c11
-rw-r--r--ggsn/ippool.h1
-rw-r--r--ggsn/tun.c69
-rw-r--r--sgsnemu/ippool.c11
-rw-r--r--sgsnemu/ippool.h1
-rw-r--r--sgsnemu/sgsnemu.c73
-rw-r--r--sgsnemu/tun.c69
8 files changed, 224 insertions, 73 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index c0592c9..5611359 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -60,7 +60,7 @@
int maxfd = 0; /* For select() */
struct in_addr listen_;
-struct in_addr net, mask; /* Network interface */
+struct in_addr netaddr, destaddr, net, mask; /* Network interface */
struct in_addr dns1, dns2; /* PCO DNS address */
char *ipup, *ipdown; /* Filename of scripts */
int debug; /* Print debug output */
@@ -184,7 +184,9 @@ int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len) {
struct tun_packet_t *iph = (struct tun_packet_t*) pack;
dst.s_addr = iph->dst;
-
+
+ if (debug) printf("Received packet from tun!\n");
+
if (ippool_getip(ippool, &ipm, &dst)) {
if (debug) printf("Received packet with no destination!!!\n");
return 0;
@@ -196,7 +198,7 @@ int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len) {
}
int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len) {
- /* printf("encaps_tun. Packet received: forwarding to tun\n");*/
+ if (debug) printf("encaps_tun. Packet received: forwarding to tun\n");
return tun_encaps((struct tun_t*) pdp->ipif, pack, len);
}
@@ -231,18 +233,18 @@ int main(int argc, char **argv)
exit(1);
if (args_info.debug_flag) {
printf("listen: %s\n", args_info.listen_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);
- printf("apn: %s\n", args_info.apn_arg);
- printf("net: %s\n", args_info.net_arg);
- printf("dynip: %s\n", args_info.dynip_arg);
- printf("statip: %s\n", args_info.statip_arg);
- printf("ipup: %s\n", args_info.ipup_arg);
- printf("ipdown: %s\n", args_info.ipdown_arg);
- printf("pidfile: %s\n", args_info.pidfile_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);
}
@@ -257,14 +259,14 @@ 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);
- printf("apn: %s\n", args_info.apn_arg);
- printf("net: %s\n", args_info.net_arg);
- printf("dynip: %s\n", args_info.dynip_arg);
- printf("statip: %s\n", args_info.statip_arg);
- printf("ipup: %s\n", args_info.ipup_arg);
- printf("ipdown: %s\n", args_info.ipdown_arg);
- printf("pidfile: %s\n", args_info.pidfile_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);
}
@@ -304,6 +306,8 @@ int main(int argc, char **argv)
"Invalid network address: %s!", args_info.net_arg);
exit(1);
}
+ netaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
+ destaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
}
else {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
@@ -314,7 +318,7 @@ int main(int argc, char **argv)
/* dynip */
if (!args_info.dynip_arg) {
if (ippool_new(&ippool, args_info.net_arg, NULL, 1, 0,
- IPPOOL_NONETWORK | IPPOOL_NOBROADCAST)) {
+ IPPOOL_NONETWORK | IPPOOL_NOGATEWAY | IPPOOL_NOBROADCAST)) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Failed to allocate IP pool!");
exit(1);
@@ -322,7 +326,7 @@ int main(int argc, char **argv)
}
else {
if (ippool_new(&ippool, args_info.dynip_arg, NULL, 1 ,0,
- IPPOOL_NONETWORK | IPPOOL_NOBROADCAST)) {
+ IPPOOL_NONETWORK | IPPOOL_NOGATEWAY | IPPOOL_NOBROADCAST)) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Failed to allocate IP pool!");
exit(1);
@@ -450,16 +454,26 @@ int main(int argc, char **argv)
/* Create a tunnel interface */
+ if (debug) printf("Creating tun interface\n");
if (tun_new((struct tun_t**) &tun)) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"Failed to create tun");
+ if (debug) printf("Failed to create tun\n");
exit(1);
}
- tun_setaddr(tun, &net, &net, &mask);
+ if (debug) printf("Setting tun IP address\n");
+ if (tun_setaddr(tun, &netaddr, &destaddr, &mask)) {
+ sys_err(LOG_ERR, __FILE__, __LINE__, 0,
+ "Failed to set tun IP address");
+ if (debug) printf("Failed to set tun IP address\n");
+ exit(1);
+ }
+
+
tun_set_cb_ind(tun, cb_tun_ind);
if (tun->fd > maxfd) maxfd = tun->fd;
-
+
if (ipup) tun_runscript(tun, ipup);
/******************************************************************/
diff --git a/ggsn/ippool.c b/ggsn/ippool.c
index e3b72a5..ca31677 100644
--- a/ggsn/ippool.c
+++ b/ggsn/ippool.c
@@ -238,6 +238,11 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
if (ippool_aton(&addr, &mask, dyn, 0))
return -1; /* Failed to parse dynamic pool */
+ /* Set IPPOOL_NOGATEWAY if IPPOOL_NODESTADDR is set */
+ if (flags & IPPOOL_NODESTADDR) {
+ flags |= IPPOOL_NOGATEWAY;
+ }
+
/* Set IPPOOL_NONETWORK if IPPOOL_NOGATEWAY is set */
if (flags & IPPOOL_NOGATEWAY) {
flags |= IPPOOL_NONETWORK;
@@ -249,6 +254,8 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
dynsize--;
if (flags & IPPOOL_NOGATEWAY) /* Exclude gateway address from pool */
dynsize--;
+ if (flags & IPPOOL_NODESTADDR) /* Exclude destination address from pool */
+ dynsize--;
if (flags & IPPOOL_NOBROADCAST) /* Exclude broadcast address from pool */
dynsize--;
}
@@ -305,7 +312,9 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
(*this)->lastdyn = NULL;
for (i = 0; i<dynsize; i++) {
- if (flags & IPPOOL_NOGATEWAY)
+ if (flags & IPPOOL_NODESTADDR)
+ (*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i + 3);
+ else if (flags & IPPOOL_NOGATEWAY)
(*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);
diff --git a/ggsn/ippool.h b/ggsn/ippool.h
index 67a6f3e..46ba447 100644
--- a/ggsn/ippool.h
+++ b/ggsn/ippool.h
@@ -36,6 +36,7 @@
#define IPPOOL_NONETWORK 0x01
#define IPPOOL_NOBROADCAST 0x02
#define IPPOOL_NOGATEWAY 0x04
+#define IPPOOL_NODESTADDR 0x08
#define IPPOOL_STATSIZE 0x10000
diff --git a/ggsn/tun.c b/ggsn/tun.c
index b406fdb..3436972 100644
--- a/ggsn/tun.c
+++ b/ggsn/tun.c
@@ -619,6 +619,8 @@ int tun_new(struct tun_t **tun)
#elif defined(__sun__)
int if_fd, ppa = -1;
static int ip_fd = 0;
+ int muxid;
+ struct ifreq ifr;
#else
#error "Unknown platform!"
@@ -696,8 +698,8 @@ int tun_new(struct tun_t **tun)
#elif defined(__sun__)
- if( (ip_fd = open("/dev/ip", O_RDWR, 0)) < 0){
- sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/ip");
+ if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/udp");
return -1;
}
@@ -708,28 +710,28 @@ int tun_new(struct tun_t **tun)
/* Assign a new PPA and get its unit number. */
if( (ppa = ioctl((*tun)->fd, TUNNEWPPA, -1)) < 0){
- syslog(LOG_ERR, "Can't assign new interface");
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't assign new interface");
return -1;
}
if( (if_fd = open("/dev/tun", O_RDWR, 0)) < 0){
- syslog(LOG_ERR, "Can't open /dev/tun (2)");
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/tun (2)");
return -1;
}
if(ioctl(if_fd, I_PUSH, "ip") < 0){
- syslog(LOG_ERR, "Can't push IP module");
+ 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){
- syslog(LOG_ERR, "Can't set PPA %d", ppa);
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't set PPA %d", ppa);
return -1;
}
/* Link the two streams */
- if(ioctl(ip_fd, I_LINK, if_fd) < 0){
- syslog(LOG_ERR, "Can't link TUN device to IP");
+ if ((muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0) {
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't link TUN device to IP");
return -1;
}
@@ -737,6 +739,20 @@ int tun_new(struct tun_t **tun)
snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", ppa);
(*tun)->devname[sizeof((*tun)->devname)] = 0;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, (*tun)->devname);
+ ifr.ifr_ip_muxid = muxid;
+
+ 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");
+ return -1;
+ }
+
+ /* if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0)
+ msg (M_ERR, "Set file descriptor to non-blocking failed"); */
+
return 0;
#else
@@ -767,6 +783,9 @@ int tun_set_cb_ind(struct tun_t *this,
int tun_decaps(struct tun_t *this)
{
+
+#if defined(__linux__) || defined (__FreeBSD__)
+
unsigned char buffer[PACKET_MAX];
int status;
@@ -779,11 +798,45 @@ int tun_decaps(struct tun_t *this)
return this->cb_ind(this, buffer, status);
return 0;
+
+#elif defined (__sun__)
+
+ unsigned char buffer[PACKET_MAX];
+ struct strbuf sbuf;
+ int f = 0;
+
+ sbuf.maxlen = PACKET_MAX;
+ sbuf.buf = buffer;
+ if (getmsg(this->fd, NULL, &sbuf, &f) < 0) {
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "getmsg() failed");
+ return -1;
+ }
+
+ if (this->cb_ind)
+ return this->cb_ind(this, buffer, sbuf.len);
+
+ return 0;
+
+#endif
+
}
+
int tun_encaps(struct tun_t *tun, void *pack, unsigned len)
{
+
+#if defined(__linux__) || defined (__FreeBSD__)
+
return write(tun->fd, pack, len);
+
+#elif defined (__sun__)
+
+ struct strbuf sbuf;
+ sbuf.len = len;
+ sbuf.buf = pack;
+ return putmsg(tun->fd, NULL, &sbuf, 0);
+
+#endif
}
int tun_runscript(struct tun_t *tun, char* script) {
diff --git a/sgsnemu/ippool.c b/sgsnemu/ippool.c
index e3b72a5..ca31677 100644
--- a/sgsnemu/ippool.c
+++ b/sgsnemu/ippool.c
@@ -238,6 +238,11 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
if (ippool_aton(&addr, &mask, dyn, 0))
return -1; /* Failed to parse dynamic pool */
+ /* Set IPPOOL_NOGATEWAY if IPPOOL_NODESTADDR is set */
+ if (flags & IPPOOL_NODESTADDR) {
+ flags |= IPPOOL_NOGATEWAY;
+ }
+
/* Set IPPOOL_NONETWORK if IPPOOL_NOGATEWAY is set */
if (flags & IPPOOL_NOGATEWAY) {
flags |= IPPOOL_NONETWORK;
@@ -249,6 +254,8 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
dynsize--;
if (flags & IPPOOL_NOGATEWAY) /* Exclude gateway address from pool */
dynsize--;
+ if (flags & IPPOOL_NODESTADDR) /* Exclude destination address from pool */
+ dynsize--;
if (flags & IPPOOL_NOBROADCAST) /* Exclude broadcast address from pool */
dynsize--;
}
@@ -305,7 +312,9 @@ int ippool_new(struct ippool_t **this, char *dyn, char *stat,
(*this)->lastdyn = NULL;
for (i = 0; i<dynsize; i++) {
- if (flags & IPPOOL_NOGATEWAY)
+ if (flags & IPPOOL_NODESTADDR)
+ (*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i + 3);
+ else if (flags & IPPOOL_NOGATEWAY)
(*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);
diff --git a/sgsnemu/ippool.h b/sgsnemu/ippool.h
index 67a6f3e..46ba447 100644
--- a/sgsnemu/ippool.h
+++ b/sgsnemu/ippool.h
@@ -36,6 +36,7 @@
#define IPPOOL_NONETWORK 0x01
#define IPPOOL_NOBROADCAST 0x02
#define IPPOOL_NOGATEWAY 0x04
+#define IPPOOL_NODESTADDR 0x08
#define IPPOOL_STATSIZE 0x10000
diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c
index 4915fcd..9bc576e 100644
--- a/sgsnemu/sgsnemu.c
+++ b/sgsnemu/sgsnemu.c
@@ -87,7 +87,7 @@ int echoversion = 1; /* First try this version */
struct {
int debug; /* Print debug messages */
int createif; /* Create local network interface */
- struct in_addr net, mask; /* Network interface */
+ struct in_addr netaddr, destaddr, net, mask; /* Network interface */
char *ipup, *ipdown; /* Filename of scripts */
int defaultroute; /* Set up default route */
struct in_addr pinghost; /* Remote ping host */
@@ -218,26 +218,26 @@ int process_options(int argc, char **argv) {
if (cmdline_parser (argc, argv, &args_info) != 0)
return -1;
if (args_info.debug_flag) {
- printf("remote: %s\n", args_info.remote_arg);
- printf("listen: %s\n", args_info.listen_arg);
- printf("conf: %s\n", args_info.conf_arg);
+ if (args_info.remote_arg) printf("remote: %s\n", args_info.remote_arg);
+ if (args_info.listen_arg) printf("listen: %s\n", args_info.listen_arg);
+ if (args_info.conf_arg) printf("conf: %s\n", args_info.conf_arg);
printf("debug: %d\n", args_info.debug_flag);
- printf("imsi: %s\n", args_info.imsi_arg);
+ if (args_info.imsi_arg) printf("imsi: %s\n", args_info.imsi_arg);
printf("qos: %#08x\n", args_info.qos_arg);
- printf("apn: %s\n", args_info.apn_arg);
- printf("msisdn: %s\n", args_info.msisdn_arg);
- printf("uid: %s\n", args_info.uid_arg);
- printf("pwd: %s\n", args_info.pwd_arg);
- printf("pidfile: %s\n", args_info.pidfile_arg);
- printf("statedir: %s\n", args_info.statedir_arg);
- printf("dns: %s\n", args_info.dns_arg);
+ if (args_info.apn_arg) printf("apn: %s\n", args_info.apn_arg);
+ if (args_info.msisdn_arg) printf("msisdn: %s\n", args_info.msisdn_arg);
+ if (args_info.uid_arg) printf("uid: %s\n", args_info.uid_arg);
+ if (args_info.pwd_arg) printf("pwd: %s\n", args_info.pwd_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.dns_arg) printf("dns: %s\n", args_info.dns_arg);
printf("contexts: %d\n", args_info.contexts_arg);
printf("timelimit: %d\n", args_info.timelimit_arg);
printf("createif: %d\n", args_info.createif_flag);
- printf("ipup: %s\n", args_info.ipup_arg);
- printf("ipdown: %s\n", args_info.ipdown_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);
printf("defaultroute: %d\n", args_info.defaultroute_flag);
- printf("pinghost: %s\n", args_info.pinghost_arg);
+ if (args_info.pinghost_arg) printf("pinghost: %s\n", args_info.pinghost_arg);
printf("pingrate: %d\n", args_info.pingrate_arg);
printf("pingsize: %d\n", args_info.pingsize_arg);
printf("pingcount: %d\n", args_info.pingcount_arg);
@@ -251,26 +251,26 @@ int process_options(int argc, char **argv) {
return -1;
if (args_info.debug_flag) {
printf("cmdline_parser_configfile\n");
- printf("remote: %s\n", args_info.remote_arg);
- printf("listen: %s\n", args_info.listen_arg);
- printf("conf: %s\n", args_info.conf_arg);
+ if (args_info.remote_arg) printf("remote: %s\n", args_info.remote_arg);
+ if (args_info.listen_arg) printf("listen: %s\n", args_info.listen_arg);
+ if (args_info.conf_arg) printf("conf: %s\n", args_info.conf_arg);
printf("debug: %d\n", args_info.debug_flag);
- printf("imsi: %s\n", args_info.imsi_arg);
+ if (args_info.imsi_arg) printf("imsi: %s\n", args_info.imsi_arg);
printf("qos: %#08x\n", args_info.qos_arg);
- printf("apn: %s\n", args_info.apn_arg);
- printf("msisdn: %s\n", args_info.msisdn_arg);
- printf("uid: %s\n", args_info.uid_arg);
- printf("pwd: %s\n", args_info.pwd_arg);
- printf("pidfile: %s\n", args_info.pidfile_arg);
- printf("statedir: %s\n", args_info.statedir_arg);
- printf("dns: %s\n", args_info.dns_arg);
+ if (args_info.apn_arg) printf("apn: %s\n", args_info.apn_arg);
+ if (args_info.msisdn_arg) printf("msisdn: %s\n", args_info.msisdn_arg);
+ if (args_info.uid_arg) printf("uid: %s\n", args_info.uid_arg);
+ if (args_info.pwd_arg) printf("pwd: %s\n", args_info.pwd_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.dns_arg) printf("dns: %s\n", args_info.dns_arg);
printf("contexts: %d\n", args_info.contexts_arg);
printf("timelimit: %d\n", args_info.timelimit_arg);
printf("createif: %d\n", args_info.createif_flag);
- printf("ipup: %s\n", args_info.ipup_arg);
- printf("ipdown: %s\n", args_info.ipdown_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);
printf("defaultroute: %d\n", args_info.defaultroute_flag);
- printf("pinghost: %s\n", args_info.pinghost_arg);
+ if (args_info.pinghost_arg) printf("pinghost: %s\n", args_info.pinghost_arg);
printf("pingrate: %d\n", args_info.pingrate_arg);
printf("pingsize: %d\n", args_info.pingsize_arg);
printf("pingcount: %d\n", args_info.pingcount_arg);
@@ -495,10 +495,21 @@ int process_options(int argc, char **argv) {
"Invalid network address: %s!", args_info.net_arg);
exit(1);
}
+
+#if defined (__sun__)
+ options.netaddr.s_addr = htonl(ntohl(options.net.s_addr) + 1);
+ options.destaddr.s_addr = htonl(ntohl(options.net.s_addr) + 1);
+#else
+ options.netaddr.s_addr = options.net.s_addr;
+ options.destaddr.s_addr = options.net.s_addr;
+#endif
+
}
else {
options.net.s_addr = 0;
options.mask.s_addr = 0;
+ options.netaddr.s_addr = 0;
+ options.destaddr.s_addr = 0;
}
/* ipup */
@@ -1067,11 +1078,11 @@ int main(int argc, char **argv)
if ((options.createif) && (options.net.s_addr)) {
/* printf("Setting up interface and routing\n");*/
- tun_addaddr(tun, &options.net, &options.net, &options.mask);
+ tun_addaddr(tun, &options.netaddr, &options.destaddr, &options.mask);
if (options.defaultroute) {
struct in_addr rm;
rm.s_addr = 0;
- tun_addroute(tun, &rm, &options.net, &rm);
+ tun_addroute(tun, &rm, &options.destaddr, &rm);
}
if (options.ipup) tun_runscript(tun, options.ipup);
}
diff --git a/sgsnemu/tun.c b/sgsnemu/tun.c
index b406fdb..3436972 100644
--- a/sgsnemu/tun.c
+++ b/sgsnemu/tun.c
@@ -619,6 +619,8 @@ int tun_new(struct tun_t **tun)
#elif defined(__sun__)
int if_fd, ppa = -1;
static int ip_fd = 0;
+ int muxid;
+ struct ifreq ifr;
#else
#error "Unknown platform!"
@@ -696,8 +698,8 @@ int tun_new(struct tun_t **tun)
#elif defined(__sun__)
- if( (ip_fd = open("/dev/ip", O_RDWR, 0)) < 0){
- sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/ip");
+ if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/udp");
return -1;
}
@@ -708,28 +710,28 @@ int tun_new(struct tun_t **tun)
/* Assign a new PPA and get its unit number. */
if( (ppa = ioctl((*tun)->fd, TUNNEWPPA, -1)) < 0){
- syslog(LOG_ERR, "Can't assign new interface");
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't assign new interface");
return -1;
}
if( (if_fd = open("/dev/tun", O_RDWR, 0)) < 0){
- syslog(LOG_ERR, "Can't open /dev/tun (2)");
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/tun (2)");
return -1;
}
if(ioctl(if_fd, I_PUSH, "ip") < 0){
- syslog(LOG_ERR, "Can't push IP module");
+ 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){
- syslog(LOG_ERR, "Can't set PPA %d", ppa);
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't set PPA %d", ppa);
return -1;
}
/* Link the two streams */
- if(ioctl(ip_fd, I_LINK, if_fd) < 0){
- syslog(LOG_ERR, "Can't link TUN device to IP");
+ if ((muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0) {
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't link TUN device to IP");
return -1;
}
@@ -737,6 +739,20 @@ int tun_new(struct tun_t **tun)
snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", ppa);
(*tun)->devname[sizeof((*tun)->devname)] = 0;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, (*tun)->devname);
+ ifr.ifr_ip_muxid = muxid;
+
+ 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");
+ return -1;
+ }
+
+ /* if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0)
+ msg (M_ERR, "Set file descriptor to non-blocking failed"); */
+
return 0;
#else
@@ -767,6 +783,9 @@ int tun_set_cb_ind(struct tun_t *this,
int tun_decaps(struct tun_t *this)
{
+
+#if defined(__linux__) || defined (__FreeBSD__)
+
unsigned char buffer[PACKET_MAX];
int status;
@@ -779,11 +798,45 @@ int tun_decaps(struct tun_t *this)
return this->cb_ind(this, buffer, status);
return 0;
+
+#elif defined (__sun__)
+
+ unsigned char buffer[PACKET_MAX];
+ struct strbuf sbuf;
+ int f = 0;
+
+ sbuf.maxlen = PACKET_MAX;
+ sbuf.buf = buffer;
+ if (getmsg(this->fd, NULL, &sbuf, &f) < 0) {
+ sys_err(LOG_ERR, __FILE__, __LINE__, errno, "getmsg() failed");
+ return -1;
+ }
+
+ if (this->cb_ind)
+ return this->cb_ind(this, buffer, sbuf.len);
+
+ return 0;
+
+#endif
+
}
+
int tun_encaps(struct tun_t *tun, void *pack, unsigned len)
{
+
+#if defined(__linux__) || defined (__FreeBSD__)
+
return write(tun->fd, pack, len);
+
+#elif defined (__sun__)
+
+ struct strbuf sbuf;
+ sbuf.len = len;
+ sbuf.buf = pack;
+ return putmsg(tun->fd, NULL, &sbuf, 0);
+
+#endif
}
int tun_runscript(struct tun_t *tun, char* script) {