alias_cuseeme.c revision 124621
11556Srgrimes/*-
21556Srgrimes * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
31556Srgrimes *                    with the aid of code written by
41556Srgrimes *                    Junichi SATOH <junichi@astec.co.jp> 1996, 1997.
51556Srgrimes * All rights reserved.
61556Srgrimes *
71556Srgrimes * Redistribution and use in source and binary forms, with or without
81556Srgrimes * modification, are permitted provided that the following conditions
91556Srgrimes * are met:
101556Srgrimes * 1. Redistributions of source code must retain the above copyright
111556Srgrimes *    notice, this list of conditions and the following disclaimer.
121556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
131556Srgrimes *    notice, this list of conditions and the following disclaimer in the
141556Srgrimes *    documentation and/or other materials provided with the distribution.
151556Srgrimes *
161556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
171556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
181556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
191556Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
201556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
211556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
221556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
231556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
241556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
251556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261556Srgrimes * SUCH DAMAGE.
271556Srgrimes */
281556Srgrimes
291556Srgrimes#include <sys/cdefs.h>
301556Srgrimes__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias_cuseeme.c 124621 2004-01-17 10:52:21Z phk $");
311556Srgrimes
321556Srgrimes#include <stdio.h>
33114433Sobrien#include <sys/types.h>
341556Srgrimes#include <netinet/in_systm.h>
3520425Ssteve#include <netinet/in.h>
361556Srgrimes#include <netinet/ip.h>
371556Srgrimes#include <netinet/udp.h>
381556Srgrimes
391556Srgrimes#include "alias_local.h"
401556Srgrimes
4136150Scharnier/* CU-SeeMe Data Header */
42114433Sobrienstruct cu_header {
4336150Scharnier    u_int16_t dest_family;
4499110Sobrien    u_int16_t dest_port;
4599110Sobrien    u_int32_t  dest_addr;
461556Srgrimes    int16_t family;
471556Srgrimes    u_int16_t port;
481556Srgrimes    u_int32_t addr;
491556Srgrimes    u_int32_t seq;
501556Srgrimes    u_int16_t msg;
511556Srgrimes    u_int16_t data_type;
521556Srgrimes    u_int16_t packet_len;
5317987Speter};
5417987Speter
5553891Scracauer/* Open Continue Header */
5617987Speterstruct oc_header {
571556Srgrimes    u_int16_t client_count;    /* Number of client info structs */
581556Srgrimes    u_int32_t seq_no;
591556Srgrimes    char user_name[20];
601556Srgrimes    char reserved[4];        /* flags, version stuff, etc */
611556Srgrimes};
621556Srgrimes
631556Srgrimes/* client info structures */
641556Srgrimesstruct client_info {
651556Srgrimes    u_int32_t address;          /* Client address */
661556Srgrimes    char reserved[8];        /* Flags, pruning bitfield, packet counts etc */
671556Srgrimes};
681556Srgrimes
691556Srgrimesvoid
701556SrgrimesAliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip, struct alias_link *link)
711556Srgrimes{
721556Srgrimes  struct udphdr *ud;
731556Srgrimes
741556Srgrimes  ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
751556Srgrimes  if (ntohs(ud->uh_ulen) - sizeof(struct udphdr) >= sizeof(struct cu_header)) {
761556Srgrimes    struct cu_header *cu;
771556Srgrimes    struct alias_link *cu_link;
781556Srgrimes
791556Srgrimes    cu = (struct cu_header *)(ud + 1);
801556Srgrimes    if (cu->addr)
811556Srgrimes      cu->addr = (u_int32_t)GetAliasAddress(link).s_addr;
821556Srgrimes
831556Srgrimes    cu_link = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(link),
841556Srgrimes                            ud->uh_dport, 0, IPPROTO_UDP, 1);
851556Srgrimes
8617987Speter#ifndef NO_FW_PUNCH
8717987Speter    if (cu_link)
8817987Speter        PunchFWHole(cu_link);
8917987Speter#endif
9017987Speter  }
9117987Speter}
9281602Speter
9317987Spetervoid
9417987SpeterAliasHandleCUSeeMeIn(struct libalias *la, struct ip *pip, struct in_addr original_addr)
9517987Speter{
961556Srgrimes  struct in_addr alias_addr;
9790111Simp  struct udphdr *ud;
9890111Simp  struct cu_header *cu;
9990111Simp  struct oc_header *oc;
10090111Simp  struct client_info *ci;
10190111Simp  char *end;
10290111Simp  int i;
10390111Simp
10490111Simp  alias_addr.s_addr = pip->ip_dst.s_addr;
10590111Simp  ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
106181269Scperciva  cu = (struct cu_header *)(ud + 1);
10790111Simp  oc = (struct oc_header *)(cu + 1);
1081556Srgrimes  ci = (struct client_info *)(oc + 1);
1091556Srgrimes  end = (char *)ud + ntohs(ud->uh_ulen);
11017987Speter
11190111Simp  if ((char *)oc <= end) {
11217987Speter    if(cu->dest_addr)
1131556Srgrimes      cu->dest_addr = (u_int32_t)original_addr.s_addr;
11418016Speter    if(ntohs(cu->data_type) == 101)
11581602Speter      /* Find and change our address */
1161556Srgrimes      for(i = 0; (char *)(ci + 1) <= end && i < oc->client_count; i++, ci++)
11753891Scracauer        if(ci->address == (u_int32_t)alias_addr.s_addr) {
1181556Srgrimes          ci->address = (u_int32_t)original_addr.s_addr;
1191556Srgrimes          break;
1201556Srgrimes        }
1211556Srgrimes  }
1221556Srgrimes}
1231556Srgrimes