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