1/* 2** igmpproxy - IGMP proxy based multicast router 3** Copyright (C) 2005 Johnny Egeland <johnny@rlo.org> 4** 5** This program is free software; you can redistribute it and/or modify 6** it under the terms of the GNU General Public License as published by 7** the Free Software Foundation; either version 2 of the License, or 8** (at your option) any later version. 9** 10** This program is distributed in the hope that it will be useful, 11** but WITHOUT ANY WARRANTY; without even the implied warranty of 12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13** GNU General Public License for more details. 14** 15** You should have received a copy of the GNU General Public License 16** along with this program; if not, write to the Free Software 17** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18** 19**---------------------------------------------------------------------------- 20** 21** This software is derived work from the following software. The original 22** source code has been modified from it's original state by the author 23** of igmpproxy. 24** 25** smcroute 0.92 - Copyright (C) 2001 Carsten Schill <carsten@cschill.de> 26** - Licensed under the GNU General Public License, version 2 27** 28** mrouted 3.9-beta3 - COPYRIGHT 1989 by The Board of Trustees of 29** Leland Stanford Junior University. 30** - Original license can be found in the Stanford.txt file. 31** 32*/ 33 34#include "igmpproxy.h" 35 36/* 37 * Exported variables. 38 */ 39char s1[19]; /* buffers to hold the string representations */ 40char s2[19]; /* of IP addresses, to be passed to inet_fmt() */ 41char s3[19]; /* or inet_fmts(). */ 42char s4[19]; 43 44/* 45** Formats 'InAdr' into a dotted decimal string. 46** 47** returns: - pointer to 'St' 48** 49*/ 50char *fmtInAdr( char *St, struct in_addr InAdr ) { 51 sprintf( St, "%u.%u.%u.%u", 52 ((uint8_t *)&InAdr.s_addr)[ 0 ], 53 ((uint8_t *)&InAdr.s_addr)[ 1 ], 54 ((uint8_t *)&InAdr.s_addr)[ 2 ], 55 ((uint8_t *)&InAdr.s_addr)[ 3 ] ); 56 57 return St; 58} 59 60/* 61 * Convert an IP address in u_long (network) format into a printable string. 62 */ 63char *inetFmt(uint32_t addr, char *s) { 64 register u_char *a; 65 66 a = (u_char *)&addr; 67 sprintf(s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]); 68 return(s); 69} 70 71 72/* 73 * Convert an IP subnet number in u_long (network) format into a printable 74 * string including the netmask as a number of bits. 75 */ 76char *inetFmts(uint32_t addr, uint32_t mask, char *s) { 77 register u_char *a, *m; 78 int bits; 79 80 if ((addr == 0) && (mask == 0)) { 81 sprintf(s, "default"); 82 return(s); 83 } 84 a = (u_char *)&addr; 85 m = (u_char *)&mask; 86 bits = 33 - ffs(ntohl(mask)); 87 88 if (m[3] != 0) sprintf(s, "%u.%u.%u.%u/%d", a[0], a[1], a[2], a[3], 89 bits); 90 else if (m[2] != 0) sprintf(s, "%u.%u.%u/%d", a[0], a[1], a[2], bits); 91 else if (m[1] != 0) sprintf(s, "%u.%u/%d", a[0], a[1], bits); 92 else sprintf(s, "%u/%d", a[0], bits); 93 94 return(s); 95} 96 97/* 98 * inet_cksum extracted from: 99 * P I N G . C 100 * 101 * Author - 102 * Mike Muuss 103 * U. S. Army Ballistic Research Laboratory 104 * December, 1983 105 * Modified at Uc Berkeley 106 * 107 * (ping.c) Status - 108 * Public Domain. Distribution Unlimited. 109 * 110 * I N _ C K S U M 111 * 112 * Checksum routine for Internet Protocol family headers (C Version) 113 * 114 */ 115uint16_t inetChksum(uint16_t *addr, int len) { 116 register int nleft = len; 117 register uint16_t *w = addr; 118 uint16_t answer = 0; 119 register int32_t sum = 0; 120 121 /* 122 * Our algorithm is simple, using a 32 bit accumulator (sum), 123 * we add sequential 16 bit words to it, and at the end, fold 124 * back all the carry bits from the top 16 bits into the lower 125 * 16 bits. 126 */ 127 while (nleft > 1) { 128 sum += *w++; 129 nleft -= 2; 130 } 131 132 /* mop up an odd byte, if necessary */ 133 if (nleft == 1) { 134 *(uint8_t *) (&answer) = *(uint8_t *)w ; 135 sum += answer; 136 } 137 138 /* 139 * add back carry outs from top 16 bits to low 16 bits 140 */ 141 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 142 sum += (sum >> 16); /* add carry */ 143 answer = ~sum; /* truncate to 16 bits */ 144 return(answer); 145} 146 147 148 149