1/*********************************************************************** 2* 3* network.c 4* 5* Code for handling the UDP socket we send/receive on. All of our 6* tunnels use a single UDP socket which stays open for the life of 7* the application. 8* 9* Copyright (C) 2002 by Roaring Penguin Software Inc. 10* 11* This software may be distributed under the terms of the GNU General 12* Public License, Version 2, or (at your option) any later version. 13* 14* LIC: GPL 15* 16***********************************************************************/ 17 18static char const RCSID[] = 19"$Id: network.c,v 1.1.1.1 2008/10/15 03:31:00 james26_jang Exp $"; 20 21#include "l2tp.h" 22#include "event.h" 23#include <sys/socket.h> 24#include <netinet/in.h> 25#include <errno.h> 26#include <fcntl.h> 27#include <string.h> 28#include <signal.h> 29#include <stdio.h> 30 31/* Our socket */ 32int Sock = -1; 33 34static EventHandler *NetworkReadHandler = NULL; 35static void network_readable(EventSelector *es, 36 int fd, 37 unsigned int flags, 38 void *data); 39char Hostname[MAX_HOSTNAME]; 40 41static void 42sigint_handler(int sig) 43{ 44 static int count = 0; 45 46 count++; 47 fprintf(stderr, "In sigint handler: %d\n", count); 48 if (count < 5) { 49 l2tp_cleanup(); 50 } 51 exit(1); 52} 53 54/********************************************************************** 55* %FUNCTION: network_init 56* %ARGUMENTS: 57* es -- an event selector 58* %RETURNS: 59* >= 0 if all is OK, <0 if not 60* %DESCRIPTION: 61* Initializes network; opens socket on UDP port 1701; sets up 62* event handler for incoming packets. 63***********************************************************************/ 64int 65l2tp_network_init(EventSelector *es) 66{ 67 struct sockaddr_in me; 68 int flags; 69 70 gethostname(Hostname, sizeof(Hostname)); 71 Hostname[sizeof(Hostname)-1] = 0; 72 73 Event_HandleSignal(es, SIGINT, sigint_handler); 74 if (Sock >= 0) { 75 if (NetworkReadHandler) { 76 Event_DelHandler(es, NetworkReadHandler); 77 NetworkReadHandler = NULL; 78 } 79 close(Sock); 80 Sock = -1; 81 } 82 Sock = socket(PF_INET, SOCK_DGRAM, 0); 83 if (Sock < 0) { 84 l2tp_set_errmsg("network_init: socket: %s", strerror(errno)); 85 return -1; 86 } 87 88 me.sin_family = AF_INET; 89 me.sin_addr = Settings.listen_addr; 90 me.sin_port = htons((uint16_t) Settings.listen_port); 91 if (bind(Sock, (struct sockaddr *) &me, sizeof(me)) < 0) { 92 l2tp_set_errmsg("network_init: bind: %s", strerror(errno)); 93 close(Sock); 94 Sock = -1; 95 return -1; 96 } 97 98 /* Set socket non-blocking */ 99 flags = fcntl(Sock, F_GETFL); 100 flags |= O_NONBLOCK; 101 fcntl(Sock, F_SETFL, flags); 102 103 /* Set up the network read handler */ 104 Event_AddHandler(es, Sock, EVENT_FLAG_READABLE, 105 network_readable, NULL); 106 return Sock; 107} 108 109/********************************************************************** 110* %FUNCTION: network_readable 111* %ARGUMENTS: 112* es -- event selector 113* fd -- socket 114* flags -- event-handling flags telling what happened 115* data -- not used 116* %RETURNS: 117* Nothing 118* %DESCRIPTION: 119* Called when a packet arrives on the UDP socket. 120***********************************************************************/ 121static void 122network_readable(EventSelector *es, 123 int fd, 124 unsigned int flags, 125 void *data) 126{ 127 l2tp_dgram *dgram; 128 129 struct sockaddr_in from; 130 dgram = l2tp_dgram_take_from_wire(&from); 131 if (!dgram) return; 132 133 /* It's a control packet if we get here */ 134 l2tp_tunnel_handle_received_control_datagram(dgram, es, &from); 135 l2tp_dgram_free(dgram); 136} 137