From c6762cfc276183c4119649d652a0b9666ed4f2cb Mon Sep 17 00:00:00 2001 From: jjako Date: Wed, 28 Apr 2004 14:52:58 +0000 Subject: Solaris tun interface --- ggsn/ggsn.c | 62 ++++++++++++++++++++++++++++++++--------------------- ggsn/ippool.c | 11 +++++++++- ggsn/ippool.h | 1 + ggsn/tun.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 110 insertions(+), 33 deletions(-) (limited to 'ggsn') 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; imember[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) { -- cgit v1.2.3