[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Lost] [Patch] tcpip - Broadcasts und Pakete bestimmtes Gerät senden



+ tcpip: Limited Broadcasts im ARP-Code korrekt auflösen
+ tcpip: Pakete über ein bestimmtes Gerät versenden, ohne Routing
Index: trunk/src/modules/tcpip/arp.c
===================================================================
--- trunk.orig/src/modules/tcpip/arp.c
+++ trunk/src/modules/tcpip/arp.c
@@ -139,6 +139,11 @@ qword arp_resolve(struct device *device,
 {
     qword mac;
 
+    // Limited Broadcast muss an FF:FF... gehen
+    if (ip == 0xFFFFFFFF) {
+        return 0xFFFFFFFFFFFFLL;
+    }
+
     if ((mac = get_from_arp_cache(ip)) == 0) 
     {
         arp_send_request(device, ip);
Index: trunk/src/modules/tcpip/include/ip.h
===================================================================
--- trunk.orig/src/modules/tcpip/include/ip.h
+++ trunk/src/modules/tcpip/include/ip.h
@@ -36,6 +36,8 @@
 #ifndef _IP_H__
 #define _IP_H
 
+#include <stdint.h>
+
 #include "main.h"
 
 #define IP_PROTO_ICMP 1
@@ -80,6 +82,14 @@ size_t routing_get_entry_count();
 bool ip_send(dword dest_ip, byte proto, void* data, size_t data_size);
 bool ip_send_packet(struct ip_header* header, void* data, dword size);
 
+/**
+ * IP-Paket versenden. Dabei wird das Routing umgangen und direkt die angegebene
+ * Netzwerkkarte benutzt.
+ */
+bool ip_send_direct(struct device* device, uint32_t dest_ip, uint8_t proto,
+    void* data, size_t data_size);
+
+
 void ip_receive(struct device *device, void* data, size_t data_size);
 
 word ip_checksum(void* data, size_t size);
Index: trunk/src/modules/tcpip/ip.c
===================================================================
--- trunk.orig/src/modules/tcpip/ip.c
+++ trunk/src/modules/tcpip/ip.c
@@ -108,73 +108,109 @@ size_t routing_get_entry_count()
     return list_size(routing_table);
 }
 
-bool ip_send_packet(struct ip_header* header, void* data, dword size) 
+/**
+ * IP-Paket versenden und dabei das Routing umgehen und das angegebene Device
+ * benutzen.
+ */
+static bool ip_send_packet_direct(struct device* device, uint32_t dest_ip,
+    struct ip_header* header, void* data, size_t size)
 {
-    struct routing_entry* route = get_routing_entry(header->dest_ip);
+    uint64_t mac;
+    size_t packet_size;
+    struct eth_packet_header* eth;
 
-    if (route == NULL) {
-        return FALSE;
-    }
-
-    header->source_ip = route->device->dev.ip;
+    // Source-IP im Header eintagen und Pruefsumme berechnen
+    header->source_ip = device->dev.ip;
     ip_update_checksum(header);
 
-    uint32_t dest_ip = route->gateway ? route->gateway : header->dest_ip;
-    
-    dword packet_size = size + sizeof(struct eth_packet_header) + sizeof(struct ip_header);
-    char packet[packet_size];
 
-    qword mac = arp_resolve(route->device,
-                            dest_ip);
-    struct eth_packet_header* eth = (void *) packet;
+    packet_size = size + sizeof(struct eth_packet_header) +
+        sizeof(struct ip_header);
+    char packet[packet_size];
 
-    if (mac == 0) {
+    // MAC-Adresse ausfindig machen, an die das Paket gesendet wird
+    if (!(mac = arp_resolve(device, dest_ip))) {
         return FALSE;
     }
 
-    memcpy(packet + sizeof(struct eth_packet_header), header, sizeof(struct ip_header));
-    memcpy(packet + sizeof(struct eth_packet_header) + sizeof(struct ip_header), data, size);
-    
-    eth->src = route->device->dev.mac;
+    // Paket zusammenkopieren in unseren Lokalen Puffer
+    memcpy(packet + sizeof(struct eth_packet_header), header,
+        sizeof(struct ip_header));
+    memcpy(packet + sizeof(struct eth_packet_header) +
+        sizeof(struct ip_header), data, size);
+
+    // Ethernet-Header befuellen
+    eth = (void *) packet;
+    eth->src = device->dev.mac;
     eth->dest = mac;
     eth->type = ETH_TYPE_IP;
 
-    ethernet_send_packet(route->device,
-                         packet,
-                         packet_size);
-
-    //DEBUG_MSG1("Treiber: %d", route->driver);
-    /*
-    {
-        int i;
-        for (i = 0; i < packet_size; i++) {
-            printf("%02x ", ((char*) packet)[i]);
-        }
-        printf("\n");
-    }
-    */
+    // Paket versenden
+    ethernet_send_packet(device, packet, packet_size);
     return TRUE;
 }
 
-bool ip_send(dword dest_ip, byte proto, void* data, size_t data_size)
+
+bool ip_send_packet(struct ip_header* header, void* data, dword size)
+{
+    uint32_t dest_ip;
+    struct routing_entry* route;
+
+    // Passende Route suchen
+    route = get_routing_entry(header->dest_ip);
+    if (!(route = get_routing_entry(header->dest_ip))) {
+        return FALSE;
+    }
+
+    // Wenn ein Router eingetragen ist, darueber versenden
+    dest_ip = route->gateway ? route->gateway : header->dest_ip;
+
+    return ip_send_packet_direct(route->device, dest_ip, header, data, size);
+}
+
+/**
+ * IP-Header befuellen
+ *
+ * @param header    Pointer auf den Header
+ * @param dest_ip   Zieladresse
+ * @param proto     Benutztes Protokoll
+ * @param data_size Groesse der Daten
+ */
+static void ip_fill_header(struct ip_header* header, uint32_t dest_ip,
+    uint8_t proto, size_t data_size)
 {
-    struct ip_header ip_header = {
-        .version = 4,
-        .ihl = 5,
-        .type_of_service = 0,
-        .total_length = big_endian_word(sizeof(ip_header) + data_size),
-        .id = big_endian_word(1),
-        .fragment_offset = big_endian_word(0),
-        .ttl = 255,
-        .protocol = proto,
-        .checksum = 0,
-        .source_ip = 0,
-        .dest_ip = dest_ip 
-    };
+    header->version         = 4;
+    header->ihl             = 5;
+    header->type_of_service = 0;
+    header->total_length    = big_endian_word(sizeof(*header) + data_size);
+    header->id              = big_endian_word(1);
+    header->fragment_offset = big_endian_word(0);
+    header->ttl             = 255;
+    header->protocol        = proto;
+    header->checksum        = 0;
+    header->source_ip       = 0;
+    header->dest_ip         = dest_ip;
+}
 
+bool ip_send(dword dest_ip, byte proto, void* data, size_t data_size)
+{
+    struct ip_header ip_header;
+    ip_fill_header(&ip_header, dest_ip, proto, data_size);
     return ip_send_packet(&ip_header, data, data_size);
 }
 
+/**
+ * IP-Paket versenden. Dabei wird das Routing umgangen und direkt die angegebene
+ * Netzwerkkarte benutzt.
+ */
+bool ip_send_direct(struct device* device, uint32_t dest_ip, uint8_t proto,
+    void* data, size_t data_size)
+{
+    struct ip_header ip_header;
+    ip_fill_header(&ip_header, dest_ip, proto, data_size);
+    return ip_send_packet_direct(device, dest_ip, &ip_header, data, data_size);
+}
+
 void ip_receive(struct device *device, void *data, size_t data_size)
 {
     struct ip_header* header = data;

Attachment: signature.asc
Description: This is a digitally signed message part.