diff options
-rw-r--r-- | ggsn/ggsn.c | 62 | ||||
-rw-r--r-- | ggsn/ippool.c | 11 | ||||
-rw-r--r-- | ggsn/ippool.h | 1 | ||||
-rw-r--r-- | ggsn/tun.c | 69 | ||||
-rw-r--r-- | sgsnemu/ippool.c | 11 | ||||
-rw-r--r-- | sgsnemu/ippool.h | 1 | ||||
-rw-r--r-- | sgsnemu/sgsnemu.c | 73 | ||||
-rw-r--r-- | sgsnemu/tun.c | 69 |
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 @@ -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) { |