📄 wapproxy.c
字号:
/* ==================================================================== * 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 + -