diff options
Diffstat (limited to 'pppd_plugin/src/pptp.c')
-rw-r--r-- | pppd_plugin/src/pptp.c | 344 |
1 files changed, 0 insertions, 344 deletions
diff --git a/pppd_plugin/src/pptp.c b/pppd_plugin/src/pptp.c deleted file mode 100644 index 1522d19..0000000 --- a/pppd_plugin/src/pptp.c +++ /dev/null @@ -1,344 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Kozlov D. * - * xeb@mail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/un.h> -#include <netdb.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <syslog.h> -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/wait.h> -#include <sys/ioctl.h> - -#include "pppd/pppd.h" -#include "pppd/fsm.h" -#include "pppd/lcp.h" -#include "pppd/ipcp.h" -#include "pppd/ccp.h" -#include "pppd/pathnames.h" - -#include "pptp_callmgr.h" -#include <net/if.h> -#include <net/ethernet.h> -#include "if_pppox.h" - -#include <stdio.h> -#include <stdlib.h> - - - -extern char** environ; - -char pppd_version[] = PPPD_VERSION; -extern int new_style_driver; - - -char *pptp_server = NULL; -char *pptp_client = NULL; -char *pptp_phone = NULL; -int pptp_sock=-1; -int pptp_timeout=100000; -struct in_addr localbind = { INADDR_NONE }; - -static int callmgr_sock; -static int pptp_fd; -int call_ID; - -//static struct in_addr get_ip_address(char *name); -static int open_callmgr(int call_id,struct in_addr inetaddr, char *phonenr,int window); -static void launch_callmgr(int call_is,struct in_addr inetaddr, char *phonenr,int window); -static int get_call_id(int sock, pid_t gre, pid_t pppd, u_int16_t *peer_call_id); - -//static int pptp_devname_hook(char *cmd, char **argv, int doit); -static option_t Options[] = -{ - { "pptp_server", o_string, &pptp_server, - "PPTP Server" }, - { "pptp_client", o_string, &pptp_client, - "PPTP Client" }, - { "pptp_sock",o_int, &pptp_sock, - "PPTP socket" }, - { "pptp_phone", o_string, &pptp_phone, - "PPTP Phone number" }, - { NULL } -}; - -static int pptp_connect(void); -//static void pptp_send_config(int mtu,u_int32_t asyncmap,int pcomp,int accomp); -//static void pptp_recv_config(int mru,u_int32_t asyncmap,int pcomp,int accomp); -static void pptp_disconnect(void); - -struct channel pptp_channel = { - options: Options, - //process_extra_options: &PPPOEDeviceOptions, - check_options: NULL, - connect: &pptp_connect, - disconnect: &pptp_disconnect, - establish_ppp: &generic_establish_ppp, - disestablish_ppp: &generic_disestablish_ppp, - //send_config: &pptp_send_config, - //recv_config: &pptp_recv_config, - close: NULL, - cleanup: NULL -}; - -static int pptp_start_server(void) -{ - pptp_fd=pptp_sock; - sprintf(ppp_devnam,"pptp (%s)",pptp_client); - - return pptp_fd; -} -static int pptp_start_client(void) -{ - socklen_t len; - struct sockaddr_pppox src_addr,dst_addr; - struct hostent *hostinfo; - - hostinfo=gethostbyname(pptp_server); - if (!hostinfo) - { - error("PPTP: Unknown host %s\n", pptp_server); - return -1; - } - dst_addr.sa_addr.pptp.sin_addr=*(struct in_addr*)hostinfo->h_addr; - { - int sock; - struct sockaddr_in addr; - len=sizeof(addr); - addr.sin_addr=dst_addr.sa_addr.pptp.sin_addr; - addr.sin_family=AF_INET; - addr.sin_port=htons(1700); - sock=socket(AF_INET,SOCK_DGRAM,0); - if (connect(sock,(struct sockaddr*)&addr,sizeof(addr))) - { - close(sock); - error("PPTP: connect failed (%s)\n",strerror(errno)); - return -1; - } - getsockname(sock,(struct sockaddr*)&addr,&len); - src_addr.sa_addr.pptp.sin_addr=addr.sin_addr; - close(sock); - } - //info("PPTP: connect server=%s\n",inet_ntoa(conn.sin_addr)); - //conn.loc_addr.s_addr=INADDR_NONE; - //conn.timeout=1; - //conn.window=pptp_window; - - src_addr.sa_family=AF_PPPOX; - src_addr.sa_protocol=PX_PROTO_PPTP; - src_addr.sa_addr.pptp.call_id=0; - - dst_addr.sa_family=AF_PPPOX; - dst_addr.sa_protocol=PX_PROTO_PPTP; - dst_addr.sa_addr.pptp.call_id=0; - - pptp_fd=socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_PPTP); - if (pptp_fd<0) - { - error("PPTP: failed to create PPTP socket (%s)\n",strerror(errno)); - return -1; - } - if (bind(pptp_fd,(struct sockaddr*)&src_addr,sizeof(src_addr))) - { - close(pptp_fd); - error("PPTP: failed to bind PPTP socket (%s)\n",strerror(errno)); - return -1; - } - len=sizeof(src_addr); - getsockname(pptp_fd,(struct sockaddr*)&src_addr,&len); - call_ID=src_addr.sa_addr.pptp.call_id; - - do { - /* - * Open connection to call manager (Launch call manager if necessary.) - */ - callmgr_sock = open_callmgr(src_addr.sa_addr.pptp.call_id,dst_addr.sa_addr.pptp.sin_addr, pptp_phone,50); - if (callmgr_sock<0) - { - close(pptp_fd); - return -1; - } - /* Exchange PIDs, get call ID */ - } while (get_call_id(callmgr_sock, getpid(), getpid(), &dst_addr.sa_addr.pptp.call_id) < 0); - - if (connect(pptp_fd,(struct sockaddr*)&dst_addr,sizeof(dst_addr))) - { - close(callmgr_sock); - close(pptp_fd); - error("PPTP: failed to connect PPTP socket (%s)\n",strerror(errno)); - return -1; - } - - sprintf(ppp_devnam,"pptp (%s)",pptp_server); - - return pptp_fd; -} -static int pptp_connect(void) -{ - if ((!pptp_server && !pptp_client) || (pptp_server && pptp_client)) - { - fatal("PPTP: unknown mode (you must specify pptp_server or pptp_client option)"); - return -1; - } - - if (pptp_server) return pptp_start_client(); - return pptp_start_server(); -} - -static void pptp_disconnect(void) -{ - if (pptp_server) close(callmgr_sock); - close(pptp_fd); -} - -static int open_callmgr(int call_id,struct in_addr inetaddr, char *phonenr,int window) -{ - /* Try to open unix domain socket to call manager. */ - struct sockaddr_un where; - const int NUM_TRIES = 3; - int i, fd; - pid_t pid; - int status; - /* Open socket */ - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) - { - fatal("Could not create unix domain socket: %s", strerror(errno)); - } - /* Make address */ - callmgr_name_unixsock(&where, inetaddr, localbind); - for (i = 0; i < NUM_TRIES; i++) - { - if (connect(fd, (struct sockaddr *) &where, sizeof(where)) < 0) - { - /* couldn't connect. We'll have to launch this guy. */ - - unlink (where.sun_path); - - /* fork and launch call manager process */ - switch (pid = fork()) - { - case -1: /* failure */ - fatal("fork() to launch call manager failed."); - case 0: /* child */ - { - close (fd); - close(pptp_fd); - /* close the pty and gre in the call manager */ - // close(pty_fd); - //close(gre_fd); - launch_callmgr(call_id,inetaddr, phonenr,window); - } - default: /* parent */ - waitpid(pid, &status, 0); - if (status!= 0) - { - close(fd); - error("Call manager exited with error %d", status); - return -1; - } - break; - } - sleep(1); - } - else return fd; - } - close(fd); - error("Could not launch call manager after %d tries.", i); - return -1; /* make gcc happy */ -} - -/*** call the call manager main ***********************************************/ -static void launch_callmgr(int call_id,struct in_addr inetaddr, char *phonenr,int window) -{ - char win[10]; - char call[10]; - char *my_argv[9] = { "pptp", inet_ntoa(inetaddr), "--call_id",call,"--phone",phonenr,"--window",win,NULL }; - char buf[128]; - sprintf(win,"%u",window); - sprintf(call,"%u",call_id); - snprintf(buf, sizeof(buf), "pptp: call manager for %s", my_argv[1]); - //inststr(argc, argv, envp, buf); - exit(callmgr_main(8, my_argv, environ)); -} - -/*** exchange data with the call manager *************************************/ -/* XXX need better error checking XXX */ -static int get_call_id(int sock, pid_t gre, pid_t pppd, - u_int16_t *peer_call_id) -{ - u_int16_t m_call_id, m_peer_call_id; - /* write pid's to socket */ - /* don't bother with network byte order, because pid's are meaningless - * outside the local host. - */ - int rc; - rc = write(sock, &gre, sizeof(gre)); - if (rc != sizeof(gre)) - return -1; - rc = write(sock, &pppd, sizeof(pppd)); - if (rc != sizeof(pppd)) - return -1; - rc = read(sock, &m_call_id, sizeof(m_call_id)); - if (rc != sizeof(m_call_id)) - return -1; - rc = read(sock, &m_peer_call_id, sizeof(m_peer_call_id)); - if (rc != sizeof(m_peer_call_id)) - return -1; - /* - * XXX FIXME ... DO ERROR CHECKING & TIME-OUTS XXX - * (Rhialto: I am assuming for now that timeouts are not relevant - * here, because the read and write calls would return -1 (fail) when - * the peer goes away during the process. We know it is (or was) - * running because the connect() call succeeded.) - * (James: on the other hand, if the route to the peer goes away, we - * wouldn't get told by read() or write() for quite some time.) - */ - *peer_call_id = m_peer_call_id; - return 0; -} - -void plugin_init(void) -{ - /*if (!ppp_available() && !new_style_driver) - { - fatal("Linux kernel does not support PPP -- are you running 2.4.x?"); - }*/ - - add_options(Options); - - info("PPTP plugin version %s compiled for pppd-%s, linux-%s", - VERSION, PPPD_VERSION,KERNELVERSION); - - the_channel = &pptp_channel; - modem = 0; -} - |