/*
* OLSR Basic Multicast Forwarding (BMF) plugin.
* Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
* Written by Erik Tromp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Thales, BMF nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* -------------------------------------------------------------------------
* File : Packet.c
* Description: IP packet and Ethernet frame processing functions
* Created : 29 Jun 2006
*
* ------------------------------------------------------------------------- */
#include "Packet.h"
/* System includes */
#include <stddef.h> /* NULL */
#include <assert.h> /* assert() */
#include <string.h> /* memcpy() */
#include <sys/types.h> /* u_int8_t, u_int16_t, u_int32_t */
#include <netinet/in.h> /* ntohs(), htons() */
#include <netinet/ip.h> /* struct iphdr */
/* -------------------------------------------------------------------------
* Function : IsIpFragment
* Description: Check if an IP packet is an IP fragment
* Input : ipPacket - the IP packet
* Output : none
* Return : true (1) or false (0)
* Data Used : none
* ------------------------------------------------------------------------- */
int IsIpFragment(unsigned char* ipPacket)
{
struct ip* iph;
assert(ipPacket != NULL);
iph = (struct ip*) ipPacket;
if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
{
return 1;
}
return 0;
} /* IsIpFragment */
/* -------------------------------------------------------------------------
* Function : GetIpTotalLength
* Description: Retrieve the total length of the IP packet (in bytes) of
* an IP packet
* Input : ipPacket - the IP packet
* Output : none
* Return : IP packet length
* Data Used : none
* ------------------------------------------------------------------------- */
u_int16_t GetIpTotalLength(unsigned char* ipPacket)
{
struct iphdr* iph;
assert(ipPacket != NULL);
iph = (struct iphdr*) ipPacket;
return ntohs(iph->tot_len);
} /* GetIpTotalLength */
/* -------------------------------------------------------------------------
* Function : GetIpHeaderLength
* Description: Retrieve the IP header length (in bytes) of an IP packet
* Input : ipPacket - the IP packet
* Output : none
* Return : IP header length
* Data Used : none
* ------------------------------------------------------------------------- */
unsigned int GetIpHeaderLength(unsigned char* ipPacket)
{
struct iphdr* iph;
assert(ipPacket != NULL);
iph = (struct iphdr*) ipPacket;
return iph->ihl << 2;
} /* GetIpHeaderLength */
/* -------------------------------------------------------------------------
* Function : GetTtl
* Description: Retrieve the TTL (Time To Live) value from the IP header of
* an IP packet
* Input : ipPacket - the IP packet
* Output : none
* Return : TTL value
* Data Used : none
* ------------------------------------------------------------------------- */
u_int8_t GetTtl(unsigned char* ipPacket)
{
struct iphdr* iph;
assert(ipPacket != NULL);
iph = (struct iphdr*) ipPacket;
return iph->ttl;
} /* GetTtl */
/* -------------------------------------------------------------------------
* Function : SaveTtlAndChecksum
* Description: Save the TTL (Time To Live) value and IP checksum as found in
* the IP header of an IP packet
* Input : ipPacket - the IP packet
* Output : sttl - the TTL and checksum values
* Return : none
* Data Used : none
* ------------------------------------------------------------------------- */
void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
{
struct iphdr* iph;
assert(ipPacket != NULL && sttl != NULL);
iph = (struct iphdr*) ipPacket;
sttl->ttl = iph->ttl;
sttl->check = ntohs(iph->check);
} /* SaveTtlAndChecksum */
/* -------------------------------------------------------------------------
* Function : RestoreTtlAndChecksum
* Description: Restore the TTL (Time To Live) value and IP checksum in
* the IP header of an IP packet
* Input : ipPacket - the IP packet
* sttl - the TTL and checksum values
* Output : none
* Return : none
* Data Used : none
* ------------------------------------------------------------------------- */
void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
{
struct iphdr* iph;
assert(ipPacket != NULL && sttl != NULL);
iph = (struct iphdr*) ipPacket;
iph->ttl = sttl->ttl;
iph->check = htons(sttl->check);
} /* RestoreTtlAndChecksum */
/* -------------------------------------------------------------------------
* Function : DecreaseTtlAndUpdateHeaderChecksum
* Description: For an IP packet, decrement the TTL value and update the IP header
* checksum accordingly.
* Input : ipPacket - the IP packet
* Output : none
* Return : none
* Data Used : none
* Notes : See also RFC1141
* ------------------------------------------------------------------------- */
void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
{
struct iphdr* iph;
u_int32_t sum;
assert(ipPacket != NULL);
iph = (struct iphdr*) ipPacket;
iph->ttl--; /* decrement ttl */
sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
iph->check = htons(sum + (sum>>16)); /* add carry */
} /* DecreaseTtlAndUpdateHeaderChecksum */
/* -------------------------------------------------------------------------
* Function : GetIpHeader
* Description: Retrieve the IP header from BMF encapsulation UDP data
* Input : encapsulationUdpData - the encapsulation UDP data
* Output : none
* Return : IP header
* Data Used : none
* ------------------------------------------------------------------------- */
struct ip* GetIpHeader(unsigned char* encapsulationUdpData)
{
return (struct ip*)(encapsulationUdpData + ENCAP_HDR_LEN);
} /* GetIpHeader */
/* -------------------------------------------------------------------------
* Function : GetIpPacket
* Description: Retrieve the IP packet from BMF encapsulation UDP data
* Input : encapsulationUdpData - the encapsulation UDP data
* Output : none
* Return : The IP packet
* Data Used : none
* ------------------------------------------------------------------------- */
unsigned char* GetIpPacket(unsigned char* encapsulationUdpData)
{
return encapsulationUdpData + ENCAP_HDR_LEN;
} /* GetIpPacket */
/* -------------------------------------------------------------------------
* Function : GetEncapsulationUdpDataLength
* Description: Return the length of BMF encapsulation UDP data
* Input : encapsulationUdpData - the encapsulation UDP data
* Output : none
* Return : The encapsulation data length
* Data Used : none
* ------------------------------------------------------------------------- */
u_int16_t GetEncapsulationUdpDataLength(unsigned char* encapsulationUdpData)
{
return GetIpTotalLength(GetIpPacket(encapsulationUdpData)) + ENCAP_HDR_LEN;
} /* GetEncapsulationUdpDataLength */
syntax highlighted by Code2HTML, v. 0.9.1