alias_cuseeme.c revision 37131
137131Sbrian/*- 237131Sbrian * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org> 337131Sbrian * with the aid of code written by 437131Sbrian * Junichi SATOH <junichi@astec.co.jp> 1996, 1997. 537131Sbrian * All rights reserved. 637131Sbrian * 737131Sbrian * Redistribution and use in source and binary forms, with or without 837131Sbrian * modification, are permitted provided that the following conditions 937131Sbrian * are met: 1037131Sbrian * 1. Redistributions of source code must retain the above copyright 1137131Sbrian * notice, this list of conditions and the following disclaimer. 1237131Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1337131Sbrian * notice, this list of conditions and the following disclaimer in the 1437131Sbrian * documentation and/or other materials provided with the distribution. 1537131Sbrian * 1637131Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1737131Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1837131Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1937131Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2037131Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2137131Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2237131Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2337131Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2437131Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2537131Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2637131Sbrian * SUCH DAMAGE. 2737131Sbrian * 2837131Sbrian * $Id$ 2937131Sbrian */ 3037131Sbrian 3137131Sbrian#include <sys/types.h> 3237131Sbrian#include <netinet/in_systm.h> 3337131Sbrian#include <netinet/in.h> 3437131Sbrian#include <netinet/ip.h> 3537131Sbrian#include <netinet/udp.h> 3637131Sbrian 3737131Sbrian#include "alias_local.h" 3837131Sbrian 3937131Sbrian/* CU-SeeMe Data Header */ 4037131Sbrianstruct cu_header { 4137131Sbrian u_int16_t dest_family; 4237131Sbrian u_int16_t dest_port; 4337131Sbrian u_int32_t dest_addr; 4437131Sbrian int16_t family; 4537131Sbrian u_int16_t port; 4637131Sbrian u_int32_t addr; 4737131Sbrian u_int32_t seq; 4837131Sbrian u_int16_t msg; 4937131Sbrian u_int16_t data_type; 5037131Sbrian u_int16_t packet_len; 5137131Sbrian}; 5237131Sbrian 5337131Sbrian/* Open Continue Header */ 5437131Sbrianstruct oc_header { 5537131Sbrian u_int16_t client_count; /* Number of client info structs */ 5637131Sbrian u_int32_t seq_no; 5737131Sbrian char user_name[20]; 5837131Sbrian char reserved[4]; /* flags, version stuff, etc */ 5937131Sbrian}; 6037131Sbrian 6137131Sbrian/* client info structures */ 6237131Sbrianstruct client_info { 6337131Sbrian u_int32_t address; /* Client address */ 6437131Sbrian char reserved[8]; /* Flags, pruning bitfield, packet counts etc */ 6537131Sbrian}; 6637131Sbrian 6737131Sbrianvoid 6837131SbrianAliasHandleCUSeeMeOut(struct ip *pip, struct alias_link *link) 6937131Sbrian{ 7037131Sbrian struct udphdr *ud; 7137131Sbrian 7237131Sbrian ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2)); 7337131Sbrian if(ud->uh_ulen >= sizeof(struct cu_header)) { 7437131Sbrian struct cu_header *cu; 7537131Sbrian struct alias_link *cu_link; 7637131Sbrian 7737131Sbrian cu = (struct cu_header *)(ud + 1); 7837131Sbrian if (cu->addr) 7937131Sbrian cu->addr = (u_int32_t)GetAliasAddress(link).s_addr; 8037131Sbrian 8137131Sbrian cu_link = FindUdpTcpOut(pip->ip_src, GetDestAddress(link), 8237131Sbrian ud->uh_dport, 0, IPPROTO_UDP); 8337131Sbrian 8437131Sbrian#ifndef NO_FW_PUNCH 8537131Sbrian if (cu_link) 8637131Sbrian PunchFWHole(cu_link); 8737131Sbrian#endif 8837131Sbrian } 8937131Sbrian} 9037131Sbrian 9137131Sbrianvoid 9237131SbrianAliasHandleCUSeeMeIn(struct ip *pip, struct in_addr original_addr) 9337131Sbrian{ 9437131Sbrian struct in_addr alias_addr; 9537131Sbrian struct udphdr *ud; 9637131Sbrian struct cu_header *cu; 9737131Sbrian struct oc_header *oc; 9837131Sbrian struct client_info *ci; 9937131Sbrian char *end; 10037131Sbrian int i; 10137131Sbrian 10237131Sbrian alias_addr.s_addr = pip->ip_dst.s_addr; 10337131Sbrian ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2)); 10437131Sbrian cu = (struct cu_header *)(ud + 1); 10537131Sbrian oc = (struct oc_header *)(cu + 1); 10637131Sbrian ci = (struct client_info *)(oc + 1); 10737131Sbrian end = (char *)cu + ud->uh_ulen; 10837131Sbrian 10937131Sbrian if ((char *)oc <= end) { 11037131Sbrian if(cu->dest_addr) 11137131Sbrian cu->dest_addr = (u_int32_t)original_addr.s_addr; 11237131Sbrian if(ntohs(cu->data_type) == 101) 11337131Sbrian /* Find and change our address */ 11437131Sbrian for(i = 0; (char *)(ci + 1) <= end && i < oc->client_count; i++, ci++) 11537131Sbrian if(ci->address == (u_int32_t)alias_addr.s_addr) { 11637131Sbrian ci->address = (u_int32_t)original_addr.s_addr; 11737131Sbrian break; 11837131Sbrian } 11937131Sbrian } 12037131Sbrian} 121