⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wapproxy.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 Kannel Group   * Copyright (c) 1998-2001 WapIT Ltd.    * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Kannel Group (http://www.kannel.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Kannel" and "Kannel Group" must not be used to  *    endorse or promote products derived from this software without  *    prior written permission. For written permission, please   *    contact org@kannel.org.  *  * 5. Products derived from this software may not be called "Kannel",  *    nor may "Kannel" appear in their name, without prior written  *    permission of the Kannel Group.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Kannel Group.  For more information on   * the Kannel Group, please see <http://www.kannel.org/>.  *  * Portions of this software are based upon software originally written at   * WapIT Ltd., Helsinki, Finland for the Kannel project.   */ /* * wapproxy.c - an WDP, WSP, WTP layer proxy * * This module contains the main program for the WAP proxy box. * It's intention is to sit between a WTP initiator and WTP repsonder * and log all the UDP traffic that is send in a session. *  * The architecture looks like this: * *   ----------    UDP    --------    UDP    ------ *   wap device    --->   wapproxy    --->   wap gw *   ----------    <---   --------    <---   ------ *   port 51000        p 9201   p 51000     port 9201 *                 (a)                (b) * * This means wapproxy gets the UDP/WDP packets that are actually to * be transmitted to the real wap gw. It changes the source addr within * that packet to reflect wapproxy has send it and binds to the port the * wap device was sending the packet. Then the packet is send to the real * wap gw and wapproxy listens on the client source port (i.e. 51000) for  * packets from the wap gw. When those are received the communication is * inverted, which means wapproxy changes again the source addr from the * value of wap gw to it's own and forwards the packet to the client source * addr port. * * Hence the wap device uses wapproxy transparently without knowing that * it is only a proxy and the packets are forwarded to other boxes. * * Stipe Tolj <tolj@wapme-systems.de> */#include <errno.h>#include <stdlib.h>#include <stdio.h>#include <time.h>#include <string.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <signal.h>#include <fcntl.h>#include <assert.h>#include "gwlib/gwlib.h"#include "msg.h"//#include "bearerbox.h"#include "shared.h"#include "wap/wap.h"#include "wap/wtp.h"#include "wap/wtp_pdu.h"/* globals */static volatile sig_atomic_t udp_running;static List *udpc_list;static Octstr *interface_name = NULL;static Octstr *wapgw;static int verbose = 0;List *incoming_wdp;List *outgoing_wdp;List *flow_threads;Counter *incoming_wdp_counter;Counter *outgoing_wdp_counter;enum {    CONNECTIONLESS_PORT = 9200,    CONNECTION_ORIENTED_PORT = 9201,    WTLS_CONNECTIONLESS_PORT = 9202,    WTLS_CONNECTION_ORIENTED_PORT = 9203};/* structure for a UDP connection */typedef struct _udpc {    int fd;    Octstr *addr;    Octstr *map_addr;    List *outgoing_list;    long receiver;} Udpc;/* forward declarations */static void udpc_destroy(Udpc *udpc);/*------------------------------------------------------------- * analyze and dump functions * */static WAPEvent *wdp_msg2event(Msg *msg){    WAPEvent *dgram = NULL;    gw_assert(msg_type(msg) == wdp_datagram);    if (msg->wdp_datagram.destination_port == CONNECTION_ORIENTED_PORT ||        msg->wdp_datagram.source_port == CONNECTION_ORIENTED_PORT) {        dgram = wap_event_create(T_DUnitdata_Ind);        dgram->u.T_DUnitdata_Ind.addr_tuple = wap_addr_tuple_create(				msg->wdp_datagram.source_address,				msg->wdp_datagram.source_port,				msg->wdp_datagram.destination_address,				msg->wdp_datagram.destination_port);        dgram->u.T_DUnitdata_Ind.user_data =                 octstr_duplicate(msg->wdp_datagram.user_data);    }    return dgram;} static void wdp_event_dump(Msg *msg){	WAPEvent *dgram;    if ((dgram = wdp_msg2event(msg)) != NULL)        /* wap_dispatch_datagram(dgram); */        wap_event_dump(dgram);    wap_event_destroy(dgram);}static void wtp_event_dump(Msg *msg){    WAPEvent *dgram;    List *events;    long i, n;    dgram = wdp_msg2event(msg);    if (dgram == NULL)        error(0, "dgram is null");    /*    pdu = wtp_pdu_unpack(dgram->u.T_DUnitdata_Ind.user_data);    if (pdu == NULL) {        error(0, "WTP PDU unpacking failed, WAP event is:");        wap_event_dump(dgram);    } else {        wtp_pdu_dump(pdu, 0);        wtp_pdu_destroy(pdu);    }    */    events = wtp_unpack_wdp_datagram(dgram);    n = list_len(events);    debug("wap.proxy",0,"datagram contains %ld events", n);    i = 1;    while (list_len(events) > 0) {        WAPEvent *event;	    event = list_extract_first(events);                info(0, "WTP: %ld/%ld event %s.", i, n, wap_event_name(event->type));        if (wtp_event_is_for_responder(event))            /* wtp_resp_dispatch_event(event); */            debug("",0,"datagram is for WTP responder");        else            /* wtp_initiator_dispatch_event(event); */            debug("",0,"datagram is for WTP initiator");         wap_event_dump(event);        /*        switch (event->type) {            RcvInvoke:                debug("",0,"XXX invoke");                break;            RcvResult:                debug("",0,"XXX result");                break;            default:                error(0,"unkown WTP event type while unpacking");                break;        }        */        i++;    }   		    wap_event_destroy(dgram);    list_destroy(events, NULL);}static void dump(Msg *msg){    switch (verbose) {        case 0:             break;        case 1:            msg_dump(msg, 0);            break;        case 2:            wdp_event_dump(msg);            break;        case 3:            msg_dump(msg, 0);            wdp_event_dump(msg);            break;        case 4:            wtp_event_dump(msg);            break;        case 5:             msg_dump(msg, 0);            wtp_event_dump(msg);            break;       case 6:             wdp_event_dump(msg);            wtp_event_dump(msg);            break;       case 7:             msg_dump(msg, 0);            wdp_event_dump(msg);            wtp_event_dump(msg);            break;    }}  /*------------------------------------------------- *  receiver thread */static void udp_receiver(void *arg){    Octstr *datagram, *cliaddr;    int ret;    Msg *msg;    Udpc *conn = arg;    Octstr *ip;    list_add_producer(incoming_wdp);    list_add_producer(flow_threads);    gwthread_wakeup(MAIN_THREAD_ID);        /* remove messages from socket until it is closed */    while (1) {        if (read_available(conn->fd, 100000) < 1)            continue;        ret = udp_recvfrom(conn->fd, &datagram, &cliaddr);        if (ret == -1) {            if (errno == EAGAIN)                /* No datagram available, don't block. */                continue;            error(errno, "Failed to receive an UDP");            continue;        }    	ip = udp_get_ip(cliaddr);        msg = msg_create(wdp_datagram);            msg->wdp_datagram.source_address = udp_get_ip(cliaddr);        msg->wdp_datagram.source_port = udp_get_port(cliaddr);        msg->wdp_datagram.destination_address = udp_get_ip(conn->addr);        msg->wdp_datagram.destination_port = udp_get_port(conn->addr);        msg->wdp_datagram.user_data = datagram;        info(0, "datagram received <%s:%d> -> <%s:%d>",             octstr_get_cstr(udp_get_ip(cliaddr)), udp_get_port(cliaddr),             octstr_get_cstr(udp_get_ip(conn->addr)), udp_get_port(conn->addr));        dump(msg);        /*          * Descide if this is (a) or (b) UDP packet and add them to the         * corresponding queues         */        if (octstr_compare(conn->addr, conn->map_addr) == 0) {            list_produce(incoming_wdp, msg);            counter_increase(incoming_wdp_counter);        } else {            list_produce(outgoing_wdp, msg);	        counter_increase(outgoing_wdp_counter);        }                octstr_destroy(cliaddr);        octstr_destroy(ip);    }        list_remove_producer(incoming_wdp);    list_remove_producer(flow_threads);}/*--------------------------------------------- * sender thread */static int send_udp(int fd, Msg *msg){    Octstr *cliaddr;    int ret;    cliaddr = udp_create_address(msg->wdp_datagram.destination_address,                                 msg->wdp_datagram.destination_port);    ret = udp_sendto(fd, msg->wdp_datagram.user_data, cliaddr);    if (ret == -1)        error(0, "could not send UDP datagram");    octstr_destroy(cliaddr);    return ret;}static void udp_sender(void *arg){    Msg *msg;    Udpc *conn = arg;    list_add_producer(flow_threads);        while (1) {        if ((msg = list_consume(conn->outgoing_list)) == NULL)            break;        info(0, "sending datagram <%s:%ld> -> <%s:%ld>",              octstr_get_cstr(msg->wdp_datagram.source_address),              msg->wdp_datagram.source_port,              octstr_get_cstr(msg->wdp_datagram.destination_address),              msg->wdp_datagram.destination_port);        dump(msg);        if (send_udp(conn->fd, msg) == -1) {            msg_destroy(msg);            continue;        }        counter_increase(outgoing_wdp_counter);        msg_destroy(msg);    }    gwthread_join(conn->receiver);    udpc_destroy(conn);    list_remove_producer(flow_threads);}/*--------------------------------------------------------------- * create UDP connection */static Udpc *udpc_create(int port, char *interface_name, Octstr *map_addr){    Udpc *udpc;    Octstr *os;    int fl;        udpc = gw_malloc(sizeof(Udpc));    udpc->fd = udp_bind(port, interface_name);      os = octstr_create(interface_name);    udpc->addr = udp_create_address(os, port);    udpc->map_addr = map_addr ? map_addr : udpc->addr;    octstr_destroy(os);    if (udpc->addr == NULL) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -