1 /* 2 * Copyright (c) 2014-2016 Sippy Software, Inc., http://www.sippysoft.com 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #define rtpp_ip_chksum_start() { \ 28 uint32_t _wsum; \ 29 static const union { \ 30 uint16_t u16; \ 31 uint8_t b8[2]; \ 32 } _ppadv4 = {.b8 = {0x0, IPPROTO_UDP}}; \ 33 static const union { \ 34 uint32_t u32; \ 35 uint8_t b8[4]; \ 36 } _ppadv6 = {.b8 = {0x0, 0x0, 0x0, IPPROTO_UDP}}; \ 37 _wsum = 0; 38 #define rtpp_ip_chksum_update(dp, len) { \ 39 const uint16_t *ww; \ 40 int nleft; \ 41 RTPP_DBG_ASSERT((len % 2) == 0); \ 42 ww = (const uint16_t *)(dp); \ 43 for (nleft = (len); nleft > 1; nleft -= 2) { \ 44 (_wsum) += *ww++; \ 45 } \ 46 } 47 #define rtpp_ip_chksum_update_data(dp, len) { \ 48 const uint16_t *ww; \ 49 int nleft; \ 50 union { \ 51 uint16_t us; \ 52 uint8_t uc[2]; \ 53 } last; \ 54 ww = (const uint16_t *)(dp); \ 55 for (nleft = (len); nleft > 1; nleft -= 2) { \ 56 (_wsum) += *ww++; \ 57 } \ 58 if (nleft == 1) { \ 59 last.uc[0] = *(const uint8_t *)ww; \ 60 last.uc[1] = 0; \ 61 (_wsum) += last.us; \ 62 } \ 63 } 64 #define rtpp_ip_chksum_pad_v4() rtpp_ip_chksum_update(&(_ppadv4.u16), sizeof(_ppadv4.u16)) 65 #define rtpp_ip_chksum_pad_v6() rtpp_ip_chksum_update(&(_ppadv6.u32), sizeof(_ppadv6.u32)) 66 #define rtpp_ip_chksum_fin(osum) \ 67 (_wsum) = ((_wsum) >> 16) + ((_wsum) & 0xffff); \ 68 (_wsum) += ((_wsum) >> 16); \ 69 osum = ~(_wsum); \ 70 } 71