int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int Length, const void *Data)
{
tMacAddr to = ARP_Resolve4(Iface, Address);
+ const tMacAddr zero = {{0,0,0,0,0,0}};
int bufSize = sizeof(tIPv4Header) + Length;
char buf[bufSize];
tIPv4Header *hdr = (void*)buf;
int ret;
+ if( MAC_EQU(to, zero) ) {
+ return 0;
+ }
+
// OUTPUT Firewall rule go here
ret = IPTablesV4_TestChain("OUTPUT",
- &Iface->IP4.Address, &Address,
+ (tIPv4*)Iface->Address, &Address,
Protocol, 0,
Length, Data);
if(ret != 0) {
hdr->TTL = DEFAULT_TTL;
hdr->Protocol = Protocol;
hdr->HeaderChecksum = 0; // Will be set later
- hdr->Source = Iface->IP4.Address;
+ hdr->Source = *(tIPv4*)Iface->Address;
hdr->Destination = Address;
- hdr->HeaderChecksum = IPv4_Checksum(hdr, sizeof(tIPv4Header));
+ hdr->HeaderChecksum = htons(IPv4_Checksum(hdr, sizeof(tIPv4Header)));
Log_Log("IPv4", "Sending packet to %i.%i.%i.%i",
Address.B[0], Address.B[1], Address.B[2], Address.B[3]);
// Check Header checksum
{
Uint16 hdrVal, compVal;
- hdrVal = hdr->HeaderChecksum;
+ hdrVal = ntohs(hdr->HeaderChecksum);
hdr->HeaderChecksum = 0;
- compVal = IPv4_Checksum(hdr, hdr->HeaderLength);
+ compVal = IPv4_Checksum(hdr, hdr->HeaderLength * 4);
if(hdrVal != compVal) {
Log_Log("IPv4", "Header checksum fails (%04x != %04x)", hdrVal, compVal);
return ;
// Routing
if(!iface)
{
- Log_Debug("IPv4", "Route the packet");
+ //Log_Debug("IPv4", "Route the packet");
// TODO: Parse Routing tables and determine where to send it
{
if( iface->Adapter != Adapter ) continue;
if( iface->Type != 4 ) continue;
- if( IP4_EQU(Address, iface->IP4.Address) )
+ //Log_Debug("IPv4", "%x == %x?\n", addr, ntohl(((tIPv4*)iface->Address)->L));
+ if( IP4_EQU(Address, *(tIPv4*)iface->Address) )
return iface;
if( !Broadcast ) continue;
- this = ntohl( iface->IP4.Address.L );
+ this = ntohl( ((tIPv4*)iface->Address)->L );
// Check for broadcast
- netmask = IPv4_Netmask(iface->IP4.SubnetBits);
+ netmask = IPv4_Netmask(iface->SubnetBits);
if( (addr & netmask) == (this & netmask)
&& (addr & ~netmask) == (0xFFFFFFFF & ~netmask) )
*/
Uint16 IPv4_Checksum(const void *Buf, int Size)
{
- Uint16 sum = 0;
+ Uint32 sum = 0;
const Uint16 *arr = Buf;
int i;
Size = (Size + 1) >> 1; // 16-bit word count
for(i = 0; i < Size; i++ )
{
- if((int)sum + arr[i] > 0xFFFF)
- sum ++; // Simulate 1's complement
- sum += arr[i];
+ Uint16 val = ntohs(arr[i]);
+ sum += val;
}
- return ~sum ;
+
+ // Apply one's complement
+ while (sum >> 16)
+ sum = (sum & 0xFFFF) + (sum >> 16);
+
+ return ~sum;
}
/**