|
From: <ljs...@us...> - 2006-09-14 02:40:05
|
Revision: 353
http://svn.sourceforge.net/cadcdev/?rev=353&view=rev
Author: ljsebald
Date: 2006-09-13 19:39:59 -0700 (Wed, 13 Sep 2006)
Log Message:
-----------
Adding in some more networking changes. This set is some code formatting corrections, along with getting rid of net_ntohs and net_ntohl usage in many places.
Modified Paths:
--------------
kos/kernel/net/net_icmp.c
kos/kernel/net/net_input.c
Modified: kos/kernel/net/net_icmp.c
===================================================================
--- kos/kernel/net/net_icmp.c 2006-09-14 02:04:08 UTC (rev 352)
+++ kos/kernel/net/net_icmp.c 2006-09-14 02:39:59 UTC (rev 353)
@@ -3,7 +3,7 @@
kernel/net/net_icmp.c
Copyright (C) 2002 Dan Potter
- Copyright (C) 2005 Lawrence Sebald
+ Copyright (C) 2005, 2006 Lawrence Sebald
*/
@@ -14,6 +14,7 @@
#include <kos/net.h>
#include <kos/thread.h>
#include <arch/timer.h>
+#include <arpa/inet.h>
#include "net_icmp.h"
#include "net_ipv4.h"
@@ -53,25 +54,15 @@
static uint16 icmp_echo_seq = 1;
static void icmp_default_echo_cb(const uint8 *ip, uint16 seq, uint64 delta_us,
-uint8 ttl, const uint8* data, int data_sz) {
+ uint8 ttl, const uint8* data, int data_sz) {
printf("%d bytes from %d.%d.%d.%d: icmp_seq=%d ttl=%d time=%.2f ms\n",
- data_sz, ip[0], ip[1], ip[2], ip[3], seq, ttl, delta_us / 1000.0f);
+ data_sz, ip[0], ip[1], ip[2], ip[3], seq, ttl,
+ delta_us / 1000.0f);
}
/* The default echo (ping) callback */
net_echo_cb net_icmp_echo_cb = icmp_default_echo_cb;
-#if 0
-static uint16 ntohs(uint16 n) {
- return ((n & 0xff) << 8) | ((n >> 8) & 0xff);
-}
-
-static uint32 ntohl(uint32 n) {
- return ((n & 0xFF) << 24) | ((n & 0xFF00) << 8) |
- ((n >> 8) & 0xFF00) | ((n >> 24) & 0xFF);
-}
-#endif
-
/* Handle Echo Reply (ICMP type 0) packets */
static void net_icmp_input_0(netif_t *src, eth_hdr_t *eth, ip_hdr_t *ip,
icmp_hdr_t *icmp, const uint8 *d, int s) {
@@ -84,8 +75,8 @@
LIST_FOREACH(ping, &pings, pkt_list) {
seq = (d[7] | (d[6] << 8));
if(ping->icmp_seq == seq) {
- net_icmp_echo_cb((uint8 *)&ip->src, seq, tmr - ping->usec, ip->ttl,
- d, s);
+ net_icmp_echo_cb((uint8 *)&ip->src, seq,
+ tmr - ping->usec, ip->ttl, d, s);
LIST_REMOVE(ping, pkt_list);
free(ping->data);
@@ -117,23 +108,24 @@
/* Recompute the IP header checksum */
ip->checksum = 0;
- ip->checksum = net_ipv4_checksum((uint16*)ip,
- 2 * (ip->version_ihl & 0x0f));
+ ip->checksum = net_ipv4_checksum((uint16*)ip,
+ 2 * (ip->version_ihl & 0x0f));
/* Recompute the ICMP header checksum */
icmp->checksum = 0;
- icmp->checksum = net_ipv4_checksum((uint16*)icmp, net_ntohs(ip->length) / 2 -
- 2 * (ip->version_ihl & 0x0f));
+ icmp->checksum = net_ipv4_checksum((uint16*)icmp, ntohs(ip->length) /
+ 2 - 2 * (ip->version_ihl & 0x0f));
/* Send it */
memcpy(pktbuf, eth, 14);
memcpy(pktbuf + 14, ip, 20);
- memcpy(pktbuf + 14 + 20, d, net_ntohs(ip->length) - 4 *
+ memcpy(pktbuf + 14 + 20, d, ntohs(ip->length) - 4 *
(ip->version_ihl & 0x0F));
- src->if_tx(src, pktbuf, 14 + net_ntohs(ip->length), NETIF_BLOCK);
+ src->if_tx(src, pktbuf, 14 + ntohs(ip->length), NETIF_BLOCK);
}
-int net_icmp_input(netif_t *src, eth_hdr_t *eth, ip_hdr_t *ip, const uint8 *d, int s) {
+int net_icmp_input(netif_t *src, eth_hdr_t *eth, ip_hdr_t *ip, const uint8 *d,
+ int s) {
icmp_hdr_t *icmp;
int i;
@@ -144,33 +136,40 @@
memset(pktbuf, 0, 1514);
i = icmp->checksum;
icmp->checksum = 0;
- memcpy(pktbuf, icmp, net_ntohs(ip->length) - 4*(ip->version_ihl & 0x0f));
+ memcpy(pktbuf, icmp, ntohs(ip->length) - 4 * (ip->version_ihl & 0x0f));
icmp->checksum = net_ipv4_checksum((uint16*)pktbuf,
- (net_ntohs(ip->length) + 1) / 2 - 2*(ip->version_ihl & 0x0f));
+ (ntohs(ip->length) + 1) / 2 -
+ 2 * (ip->version_ihl & 0x0f));
if (i != icmp->checksum) {
dbglog(DBG_KDEBUG, "net_icmp: icmp with invalid checksum\n");
return -1;
}
- switch(icmp->type) {
+ switch(icmp->type) {
case 0: /* Echo reply */
net_icmp_input_0(src, eth, ip, icmp, d, s);
break;
+ case 3: /* Destination unreachable */
+ dbglog(DBG_KDEBUG, "net_icmp: Destination unreachable,"
+ " code %d\n", icmp->code);
+ break;
case 8: /* Echo */
net_icmp_input_8(src, eth, ip, icmp, d, s);
break;
default:
- dbglog(DBG_KDEBUG, "net_icmp: unknown icmp type: %d\n", icmp->type);
+ dbglog(DBG_KDEBUG, "net_icmp: unknown icmp type: %d\n",
+ icmp->type);
}
return 0;
}
/* Send an ICMP Echo (PING) packet to the specified device */
-int net_icmp_send_echo(netif_t *net, const uint8 ipaddr[4], const uint8 *data, int size) {
+int net_icmp_send_echo(netif_t *net, const uint8 ipaddr[4], const uint8 *data,
+ int size) {
icmp_hdr_t *icmp;
ip_hdr_t ip;
struct __ping_pkt *newping;
@@ -192,17 +191,18 @@
/* Fill in the IP Header */
ip.version_ihl = 0x45; /* 20 byte header, ipv4 */
ip.tos = 0;
- ip.length = net_ntohs(sizeof(icmp_hdr_t) + size + 20);
+ ip.length = htons(sizeof(icmp_hdr_t) + size + 20);
ip.packet_id = 0;
ip.flags_frag_offs = 0x0040;
ip.ttl = 64;
ip.protocol = 1; /* ICMP */
ip.checksum = 0;
- ip.src = net_ntohl(net_ipv4_address(net->ip_addr));
- ip.dest = net_ntohl(net_ipv4_address(ipaddr));
+ ip.src = htonl(net_ipv4_address(net->ip_addr));
+ ip.dest = htonl(net_ipv4_address(ipaddr));
/* Compute the ICMP Checksum */
- icmp->checksum = net_ipv4_checksum((uint16*)databuf, (sizeof(icmp_hdr_t) + size) / 2);
+ icmp->checksum = net_ipv4_checksum((uint16*)databuf,
+ (sizeof(icmp_hdr_t) + size) / 2);
/* Compute the IP Checksum */
ip.checksum = net_ipv4_checksum((uint16*)&ip, sizeof(ip_hdr_t) / 2);
@@ -219,7 +219,8 @@
while(r == -1) {
newping->usec = timer_us_gettime64();
- r = net_ipv4_send_packet(net, &ip, databuf, sizeof(icmp_hdr_t) + size);
+ r = net_ipv4_send_packet(net, &ip, databuf,
+ sizeof(icmp_hdr_t) + size);
thd_sleep(10);
}
Modified: kos/kernel/net/net_input.c
===================================================================
--- kos/kernel/net/net_input.c 2006-09-14 02:04:08 UTC (rev 352)
+++ kos/kernel/net/net_input.c 2006-09-14 02:39:59 UTC (rev 353)
@@ -7,6 +7,7 @@
#include <stdio.h>
#include <kos/net.h>
+#include <arpa/inet.h>
#include "net_ipv4.h"
CVSID("$Id: net_input.c,v 1.2 2002/03/24 00:27:05 bardtx Exp $");
@@ -20,13 +21,14 @@
static int net_default_input(netif_t *nif, const uint8 *data, int len) {
uint16 *proto = (uint16 *)(data + 12);
- switch(net_ntohs(*proto)) {
+ switch(ntohs(*proto)) {
case 0x0800:
return net_ipv4_input(nif, data, len);
case 0x0806:
return net_arp_input(nif, data, len);
default:
- dbglog(DBG_KDEBUG, "net_input: unhandled ethernet protocol: %x\n", net_ntohs(*proto));
+ dbglog(DBG_KDEBUG, "net_input: unhandled ethernet "
+ "protocol: %x\n", ntohs(*proto));
return 0;
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2007-05-25 01:10:16
|
Revision: 405
http://svn.sourceforge.net/cadcdev/?rev=405&view=rev
Author: ljsebald
Date: 2007-05-24 18:10:09 -0700 (Thu, 24 May 2007)
Log Message:
-----------
Got rid of net_ntohl and net_ntohs, considering ntohl and ntohs have been in here for a while.
Modified Paths:
--------------
kos/kernel/net/net_ipv4.c
kos/kernel/net/net_ipv4.h
Modified: kos/kernel/net/net_ipv4.c
===================================================================
--- kos/kernel/net/net_ipv4.c 2007-05-25 01:06:52 UTC (rev 404)
+++ kos/kernel/net/net_ipv4.c 2007-05-25 01:10:09 UTC (rev 405)
@@ -18,15 +18,6 @@
#include "net_icmp.h"
#include "net_udp.h"
-uint16 net_ntohs(uint16 n) {
- return ((n & 0xff) << 8) | ((n >> 8) & 0xff);
-}
-
-uint32 net_ntohl(uint32 n) {
- return ((n & 0xFF) << 24) | ((n & 0xFF00) << 8) |
- ((n >> 8) & 0xFF00) | ((n >> 24) & 0xFF);
-}
-
/* Perform an IP-style checksum on a block of data */
uint16 net_ipv4_checksum(const uint16 *data, int words) {
uint32 sum;
Modified: kos/kernel/net/net_ipv4.h
===================================================================
--- kos/kernel/net/net_ipv4.h 2007-05-25 01:06:52 UTC (rev 404)
+++ kos/kernel/net/net_ipv4.h 2007-05-25 01:10:09 UTC (rev 405)
@@ -47,7 +47,4 @@
int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data, int size);
int net_ipv4_input(netif_t *src, const uint8 *pkt, int pktsize);
-uint16 net_ntohs(uint16 n);
-uint32 net_ntohl(uint32 n);
-
#endif /* __LOCAL_NET_IPV4_H */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2007-05-25 03:14:35
|
Revision: 409
http://svn.sourceforge.net/cadcdev/?rev=409&view=rev
Author: ljsebald
Date: 2007-05-24 20:14:34 -0700 (Thu, 24 May 2007)
Log Message:
-----------
Made it so that the IPv4 input code does not pass around ethernet headers. Also, fixed a few little issues with ping packet sending.
Modified Paths:
--------------
kos/kernel/net/net_icmp.c
kos/kernel/net/net_icmp.h
kos/kernel/net/net_input.c
kos/kernel/net/net_ipv4.c
kos/kernel/net/net_ipv4.h
kos/kernel/net/net_udp.c
kos/kernel/net/net_udp.h
Modified: kos/kernel/net/net_icmp.c
===================================================================
--- kos/kernel/net/net_icmp.c 2007-05-25 01:37:40 UTC (rev 408)
+++ kos/kernel/net/net_icmp.c 2007-05-25 03:14:34 UTC (rev 409)
@@ -3,7 +3,7 @@
kernel/net/net_icmp.c
Copyright (C) 2002 Dan Potter
- Copyright (C) 2005, 2006 Lawrence Sebald
+ Copyright (C) 2005, 2006, 2007 Lawrence Sebald
*/
@@ -64,8 +64,8 @@
net_echo_cb net_icmp_echo_cb = icmp_default_echo_cb;
/* Handle Echo Reply (ICMP type 0) packets */
-static void net_icmp_input_0(netif_t *src, eth_hdr_t *eth, ip_hdr_t *ip,
- icmp_hdr_t *icmp, const uint8 *d, int s) {
+static void net_icmp_input_0(netif_t *src, ip_hdr_t *ip, icmp_hdr_t *icmp,
+ const uint8 *d, int s) {
uint64 tmr;
struct __ping_pkt *ping;
uint16 seq;
@@ -88,19 +88,13 @@
}
/* Handle Echo (ICMP type 8) packets */
-static void net_icmp_input_8(netif_t *src, eth_hdr_t *eth, ip_hdr_t *ip,
- icmp_hdr_t *icmp, const uint8 *d, int s) {
- uint8 tmp[6];
+static void net_icmp_input_8(netif_t *src, ip_hdr_t *ip, icmp_hdr_t *icmp,
+ const uint8 *d, int s) {
int i;
/* Set type to echo reply */
icmp->type = 0;
- /* Swap source and dest addresses */
- memcpy(tmp, eth->dest, 6);
- memcpy(eth->dest, eth->src, 6);
- memcpy(eth->src, tmp, 6);
-
/* Swap source and dest ip addresses */
i = ip->src;
ip->src = ip->dest;
@@ -117,15 +111,13 @@
2 - 2 * (ip->version_ihl & 0x0f));
/* Send it */
- memcpy(pktbuf, eth, 14);
- memcpy(pktbuf + 14, ip, 20);
- memcpy(pktbuf + 14 + 20, d, ntohs(ip->length) - 4 *
- (ip->version_ihl & 0x0F));
- src->if_tx(src, pktbuf, 14 + ntohs(ip->length), NETIF_BLOCK);
+ memcpy(pktbuf, ip, 20);
+ memcpy(pktbuf + 20, d, ntohs(ip->length) - 4 * (ip->version_ihl & 0x0F));
+ net_ipv4_send_packet(src, ip, pktbuf + 20, ntohs(ip->length) -
+ 4 * (ip->version_ihl & 0x0F));
}
-int net_icmp_input(netif_t *src, eth_hdr_t *eth, ip_hdr_t *ip, const uint8 *d,
- int s) {
+int net_icmp_input(netif_t *src, ip_hdr_t *ip, const uint8 *d, int s) {
icmp_hdr_t *icmp;
int i;
@@ -148,7 +140,7 @@
switch(icmp->type) {
case 0: /* Echo reply */
- net_icmp_input_0(src, eth, ip, icmp, d, s);
+ net_icmp_input_0(src, ip, icmp, d, s);
break;
case 3: /* Destination unreachable */
dbglog(DBG_KDEBUG, "net_icmp: Destination unreachable,"
@@ -156,7 +148,7 @@
break;
case 8: /* Echo */
- net_icmp_input_8(src, eth, ip, icmp, d, s);
+ net_icmp_input_8(src, ip, icmp, d, s);
break;
default:
@@ -184,7 +176,7 @@
icmp->checksum = 0;
icmp->misc[0] = (uint8) 'D';
icmp->misc[1] = (uint8) 'C';
- icmp->misc[2] = (uint8) (icmp_echo_seq >> 16);
+ icmp->misc[2] = (uint8) (icmp_echo_seq >> 8);
icmp->misc[3] = (uint8) (icmp_echo_seq & 0xFF);
memcpy(databuf + sizeof(icmp_hdr_t), data, size);
@@ -197,7 +189,12 @@
ip.ttl = 64;
ip.protocol = 1; /* ICMP */
ip.checksum = 0;
- ip.src = htonl(net_ipv4_address(net->ip_addr));
+
+ if(net_ipv4_address(ipaddr) == 0x7F000001)
+ ip.src = htonl(net_ipv4_address(ipaddr));
+ else
+ ip.src = htonl(net_ipv4_address(net->ip_addr));
+
ip.dest = htonl(net_ipv4_address(ipaddr));
/* Compute the ICMP Checksum */
Modified: kos/kernel/net/net_icmp.h
===================================================================
--- kos/kernel/net/net_icmp.h 2007-05-25 01:37:40 UTC (rev 408)
+++ kos/kernel/net/net_icmp.h 2007-05-25 03:14:34 UTC (rev 409)
@@ -2,10 +2,8 @@
kernel/net/net_icmp.h
Copyright (C) 2002 Dan Potter
- Copyright (C) 2005 Lawrence Sebald
+ Copyright (C) 2005, 2007 Lawrence Sebald
- $Id: net_icmp.h,v 1.2 2002/03/24 00:27:05 bardtx Exp $
-
*/
#ifndef __LOCAL_NET_ICMP_H
@@ -26,8 +24,7 @@
} icmp_hdr_t;
#undef packed
-int net_icmp_input(netif_t *src, eth_hdr_t *eh, ip_hdr_t *ih, const uint8 *data,
- int size);
+int net_icmp_input(netif_t *src, ip_hdr_t *ih, const uint8 *data, int size);
__END_DECLS
Modified: kos/kernel/net/net_input.c
===================================================================
--- kos/kernel/net/net_input.c 2007-05-25 01:37:40 UTC (rev 408)
+++ kos/kernel/net/net_input.c 2007-05-25 03:14:34 UTC (rev 409)
@@ -23,7 +23,8 @@
switch(ntohs(*proto)) {
case 0x0800:
- return net_ipv4_input(nif, data, len);
+ return net_ipv4_input(nif, data + sizeof(eth_hdr_t),
+ len - sizeof(eth_hdr_t));
case 0x0806:
return net_arp_input(nif, data, len);
default:
Modified: kos/kernel/net/net_ipv4.c
===================================================================
--- kos/kernel/net/net_ipv4.c 2007-05-25 01:37:40 UTC (rev 408)
+++ kos/kernel/net/net_ipv4.c 2007-05-25 03:14:34 UTC (rev 409)
@@ -2,7 +2,7 @@
kernel/net/net_ipv4.c
- Copyright (C) 2005, 2006 Lawrence Sebald
+ Copyright (C) 2005, 2006, 2007 Lawrence Sebald
Portions adapted from KOS' old net_icmp.c file:
Copyright (c) 2002 Dan Potter
@@ -119,25 +119,14 @@
}
int net_ipv4_input(netif_t *src, const uint8 *pkt, int pktsize) {
- eth_hdr_t *eth;
ip_hdr_t *ip;
int i;
uint8 *data;
- uint16 *ethproto;
/* Get pointers */
- eth = (eth_hdr_t*) (pkt);
- ip = (ip_hdr_t*) (pkt + sizeof(eth_hdr_t));
- data = (uint8 *) (pkt + sizeof(eth_hdr_t) + 4 *
- (ip->version_ihl & 0x0f));
- ethproto = (uint16 *) (pkt + 12);
+ ip = (ip_hdr_t*) pkt;
+ data = (uint8 *) (pkt + 4 * (ip->version_ihl & 0x0f));
- /* Make sure this packet is actually marked as an IP packet */
- if(ntohs(*ethproto) != 0x0800) {
- dbglog(DBG_KDEBUG, "net_ipv4: Discarding non IP packet\n");
- return 0;
- }
-
/* Check ip header checksum */
i = ip->checksum;
ip->checksum = 0;
@@ -152,11 +141,11 @@
switch(ip->protocol) {
case 1:
- net_icmp_input(src, eth, ip, data, ntohs(ip->length) -
+ net_icmp_input(src, ip, data, ntohs(ip->length) -
(ip->version_ihl & 0x0f) * 4);
break;
case 17:
- net_udp_input(src, eth, ip, data, ntohs(ip->length) -
+ net_udp_input(src, ip, data, ntohs(ip->length) -
(ip->version_ihl & 0x0f) * 4);
break;
default:
Modified: kos/kernel/net/net_ipv4.h
===================================================================
--- kos/kernel/net/net_ipv4.h 2007-05-25 01:37:40 UTC (rev 408)
+++ kos/kernel/net/net_ipv4.h 2007-05-25 03:14:34 UTC (rev 409)
@@ -1,7 +1,7 @@
/* KallistiOS ##version##
kernel/net/net_ipv4.h
- Copyright (C) 2005 Lawrence Sebald
+ Copyright (C) 2005, 2007 Lawrence Sebald
*/
Modified: kos/kernel/net/net_udp.c
===================================================================
--- kos/kernel/net/net_udp.c 2007-05-25 01:37:40 UTC (rev 408)
+++ kos/kernel/net/net_udp.c 2007-05-25 03:14:34 UTC (rev 409)
@@ -1,7 +1,7 @@
/* KallistiOS ##version##
kernel/net/net_udp.c
- Copyright (C) 2005, 2006 Lawrence Sebald
+ Copyright (C) 2005, 2006, 2007 Lawrence Sebald
*/
@@ -518,8 +518,7 @@
return 0;
}
-int net_udp_input(netif_t *src, eth_hdr_t *eh, ip_hdr_t *ip, const uint8 *data,
- int size) {
+int net_udp_input(netif_t *src, ip_hdr_t *ip, const uint8 *data, int size) {
uint8 buf[size + 13];
ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t *)buf;
uint16 checksum;
Modified: kos/kernel/net/net_udp.h
===================================================================
--- kos/kernel/net/net_udp.h 2007-05-25 01:37:40 UTC (rev 408)
+++ kos/kernel/net/net_udp.h 2007-05-25 03:14:34 UTC (rev 409)
@@ -1,7 +1,7 @@
/* KallistiOS ##version##
kernel/net/net_udp.h
- Copyright (C) 2005, 2006 Lawrence Sebald
+ Copyright (C) 2005, 2006, 2007 Lawrence Sebald
*/
@@ -20,8 +20,7 @@
} udp_hdr_t;
#undef packed
-int net_udp_input(netif_t *src, eth_hdr_t *eh, ip_hdr_t *ih, const uint8 *data,
- int size);
+int net_udp_input(netif_t *src, ip_hdr_t *ih, const uint8 *data, int size);
int net_udp_send_raw(netif_t *net, uint32 src_ip, uint16 src_port,
uint32 dst_ip, uint16 dst_port, const uint8 *data,
int size);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2007-05-25 14:28:36
|
Revision: 410
http://svn.sourceforge.net/cadcdev/?rev=410&view=rev
Author: ljsebald
Date: 2007-05-25 07:28:34 -0700 (Fri, 25 May 2007)
Log Message:
-----------
Made net_ipv4_checksum accept the number of bytes in the data to be checksummed rather than the number of words.
Modified Paths:
--------------
kos/kernel/net/net_icmp.c
kos/kernel/net/net_ipv4.c
kos/kernel/net/net_ipv4.h
kos/kernel/net/net_udp.c
Modified: kos/kernel/net/net_icmp.c
===================================================================
--- kos/kernel/net/net_icmp.c 2007-05-25 03:14:34 UTC (rev 409)
+++ kos/kernel/net/net_icmp.c 2007-05-25 14:28:34 UTC (rev 410)
@@ -102,13 +102,13 @@
/* Recompute the IP header checksum */
ip->checksum = 0;
- ip->checksum = net_ipv4_checksum((uint16*)ip,
- 2 * (ip->version_ihl & 0x0f));
+ ip->checksum = net_ipv4_checksum((uint8 *)ip,
+ 4 * (ip->version_ihl & 0x0f));
/* Recompute the ICMP header checksum */
icmp->checksum = 0;
- icmp->checksum = net_ipv4_checksum((uint16*)icmp, ntohs(ip->length) /
- 2 - 2 * (ip->version_ihl & 0x0f));
+ icmp->checksum = net_ipv4_checksum((uint8 *)icmp, ntohs(ip->length) -
+ 4 * (ip->version_ihl & 0x0f));
/* Send it */
memcpy(pktbuf, ip, 20);
@@ -129,9 +129,8 @@
i = icmp->checksum;
icmp->checksum = 0;
memcpy(pktbuf, icmp, ntohs(ip->length) - 4 * (ip->version_ihl & 0x0f));
- icmp->checksum = net_ipv4_checksum((uint16*)pktbuf,
- (ntohs(ip->length) + 1) / 2 -
- 2 * (ip->version_ihl & 0x0f));
+ icmp->checksum = net_ipv4_checksum(pktbuf, (ntohs(ip->length) + 1) -
+ 4 * (ip->version_ihl & 0x0f));
if (i != icmp->checksum) {
dbglog(DBG_KDEBUG, "net_icmp: icmp with invalid checksum\n");
@@ -198,11 +197,10 @@
ip.dest = htonl(net_ipv4_address(ipaddr));
/* Compute the ICMP Checksum */
- icmp->checksum = net_ipv4_checksum((uint16*)databuf,
- (sizeof(icmp_hdr_t) + size) / 2);
+ icmp->checksum = net_ipv4_checksum(databuf, sizeof(icmp_hdr_t) + size);
/* Compute the IP Checksum */
- ip.checksum = net_ipv4_checksum((uint16*)&ip, sizeof(ip_hdr_t) / 2);
+ ip.checksum = net_ipv4_checksum((uint8 *)&ip, sizeof(ip_hdr_t));
newping = (struct __ping_pkt*) malloc(sizeof(struct __ping_pkt));
newping->data = (uint8 *)malloc(size);
Modified: kos/kernel/net/net_ipv4.c
===================================================================
--- kos/kernel/net/net_ipv4.c 2007-05-25 03:14:34 UTC (rev 409)
+++ kos/kernel/net/net_ipv4.c 2007-05-25 14:28:34 UTC (rev 410)
@@ -19,20 +19,45 @@
#include "net_udp.h"
/* Perform an IP-style checksum on a block of data */
-uint16 net_ipv4_checksum(const uint16 *data, int words) {
- uint32 sum;
+uint16 net_ipv4_checksum(const uint8 *data, int bytes) {
+ uint32 sum = 0;
int i;
- sum = 0;
- for (i=0; i<words; i++) {
- sum += data[i];
- if (sum & 0xffff0000) {
- sum &= 0xffff;
- sum++;
- }
- }
+ /* Make sure we don't do any unaligned memory accesses */
+ if(((uint32)data) & 0x01) {
+ for(i = 0; i < bytes; i += 2) {
+ sum += (data[i]) | (data[i + 1] << 8);
- return ~(sum & 0xffff);
+ if(sum & 0xFFFF0000) {
+ sum &= 0xFFFF;
+ ++sum;
+ }
+ }
+ }
+ else {
+ uint16 *ptr = (uint16 *)data;
+
+ for(i = 0; i < (bytes >> 1); ++i) {
+ sum += ptr[i];
+
+ if(sum & 0xFFFF0000) {
+ sum &= 0xFFFF;
+ ++sum;
+ }
+ }
+ }
+
+ /* Handle the last byte, if we have an odd byte count */
+ if(bytes & 0x01) {
+ sum += data[bytes - 1];
+
+ if(sum & 0xFFFF0000) {
+ sum &= 0xFFFF;
+ ++sum;
+ }
+ }
+
+ return sum ^ 0xFFFF;
}
/* Determine if a given IP is in the current network */
@@ -130,7 +155,7 @@
/* Check ip header checksum */
i = ip->checksum;
ip->checksum = 0;
- ip->checksum = net_ipv4_checksum((uint16*)ip, 2 *
+ ip->checksum = net_ipv4_checksum((uint8 *)ip, 4 *
(ip->version_ihl & 0x0f));
if(i != ip->checksum) {
Modified: kos/kernel/net/net_ipv4.h
===================================================================
--- kos/kernel/net/net_ipv4.h 2007-05-25 03:14:34 UTC (rev 409)
+++ kos/kernel/net/net_ipv4.h 2007-05-25 14:28:34 UTC (rev 410)
@@ -43,7 +43,7 @@
} ip_pseudo_hdr_t;
#undef packed
-uint16 net_ipv4_checksum(const uint16 *data, int words);
+uint16 net_ipv4_checksum(const uint8 *data, int bytes);
int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data, int size);
int net_ipv4_input(netif_t *src, const uint8 *pkt, int pktsize);
Modified: kos/kernel/net/net_udp.c
===================================================================
--- kos/kernel/net/net_udp.c 2007-05-25 03:14:34 UTC (rev 409)
+++ kos/kernel/net/net_udp.c 2007-05-25 14:28:34 UTC (rev 410)
@@ -537,12 +537,12 @@
ps->data[size - sizeof(udp_hdr_t)] = 0;
checksum = ps->checksum;
ps->checksum = 0;
- ps->checksum = net_ipv4_checksum((uint16 *) buf, (size + 13) >> 1);
+ ps->checksum = net_ipv4_checksum(buf, size + 13);
}
else {
checksum = ps->checksum;
ps->checksum = 0;
- ps->checksum = net_ipv4_checksum((uint16 *) buf, (size + 12) >> 1);
+ ps->checksum = net_ipv4_checksum(buf, size + 12);
}
if(checksum != ps->checksum) {
@@ -631,12 +631,10 @@
/* Compute the UDP checksum */
if(size & 0x01) {
- ps->checksum = net_ipv4_checksum((uint16 *) buf,
- (size + 13) >> 1);
+ ps->checksum = net_ipv4_checksum(buf, size + 13);
}
else {
- ps->checksum = net_ipv4_checksum((uint16 *) buf,
- (size + 12) >> 1);
+ ps->checksum = net_ipv4_checksum(buf, size + 12);
}
/* Fill in the IPv4 Header */
@@ -652,7 +650,7 @@
ip.dest = ps->dst_addr;
/* Compute the IPv4 checksum */
- ip.checksum = net_ipv4_checksum((uint16 *) &ip, sizeof(ip_hdr_t) >> 1);
+ ip.checksum = net_ipv4_checksum((uint8 *) &ip, sizeof(ip_hdr_t));
/* send it away.... */
if(net_ipv4_send_packet(net, &ip, buf + 12, size)) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2008-03-21 02:38:37
|
Revision: 562
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=562&view=rev
Author: ljsebald
Date: 2008-03-20 19:38:35 -0700 (Thu, 20 Mar 2008)
Log Message:
-----------
A little bit of reformatting, as well as a new function in net_ipv4.c
Modified Paths:
--------------
kos/kernel/net/net_ipv4.c
kos/kernel/net/net_ipv4.h
Modified: kos/kernel/net/net_ipv4.c
===================================================================
--- kos/kernel/net/net_ipv4.c 2008-03-10 02:12:30 UTC (rev 561)
+++ kos/kernel/net/net_ipv4.c 2008-03-21 02:38:35 UTC (rev 562)
@@ -2,7 +2,7 @@
kernel/net/net_ipv4.c
- Copyright (C) 2005, 2006, 2007 Lawrence Sebald
+ Copyright (C) 2005, 2006, 2007, 2008 Lawrence Sebald
Portions adapted from KOS' old net_icmp.c file:
Copyright (c) 2002 Dan Potter
@@ -20,8 +20,8 @@
/* Perform an IP-style checksum on a block of data */
uint16 net_ipv4_checksum(const uint8 *data, int bytes) {
- uint32 sum = 0;
- int i;
+ uint32 sum = 0;
+ int i;
/* Make sure we don't do any unaligned memory accesses */
if(((uint32)data) & 0x01) {
@@ -57,138 +57,161 @@
}
}
- return sum ^ 0xFFFF;
+ return sum ^ 0xFFFF;
}
/* Determine if a given IP is in the current network */
static int is_in_network(const uint8 src[4], const uint8 dest[4],
const uint8 netmask[4]) {
- int i;
+ int i;
- for(i = 0; i < 4; i++) {
- if((dest[i] & netmask[i]) != (src[i] & netmask[i]))
- return 0;
- }
+ for(i = 0; i < 4; i++) {
+ if((dest[i] & netmask[i]) != (src[i] & netmask[i]))
+ return 0;
+ }
- return 1;
+ return 1;
}
/* Send a packet on the specified network adaptor */
int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data,
int size) {
- uint8 dest_ip[4];
- uint8 dest_mac[6];
- uint8 pkt[size + sizeof(ip_hdr_t) + sizeof(eth_hdr_t)];
- eth_hdr_t *ehdr;
+ uint8 dest_ip[4];
+ uint8 dest_mac[6];
+ uint8 pkt[size + sizeof(ip_hdr_t) + sizeof(eth_hdr_t)];
+ eth_hdr_t *ehdr;
- if(net == NULL) {
- net = net_default_dev;
- }
+ if(net == NULL) {
+ net = net_default_dev;
+ }
- net_ipv4_parse_address(ntohl(hdr->dest), dest_ip);
+ net_ipv4_parse_address(ntohl(hdr->dest), dest_ip);
- /* Is this the loopback address (127.0.0.1)? */
- if(ntohl(hdr->dest) == 0x7F000001) {
- /* Fill in the ethernet header */
- ehdr = (eth_hdr_t *)pkt;
- memset(ehdr->dest, 0, 6);
- memset(ehdr->src, 0, 6);
+ /* Is this the loopback address (127.0.0.1)? */
+ if(ntohl(hdr->dest) == 0x7F000001) {
+ /* Fill in the ethernet header */
+ ehdr = (eth_hdr_t *)pkt;
+ memset(ehdr->dest, 0, 6);
+ memset(ehdr->src, 0, 6);
- ehdr->dest[0] = 0xCF;
- ehdr->src[0] = 0xCF;
+ ehdr->dest[0] = 0xCF;
+ ehdr->src[0] = 0xCF;
- ehdr->type[0] = 0x08;
- ehdr->type[1] = 0x00;
+ ehdr->type[0] = 0x08;
+ ehdr->type[1] = 0x00;
- /* Put the IP header / data into our ethernet packet */
- memcpy(pkt + sizeof(eth_hdr_t), hdr,
- 4 * (hdr->version_ihl & 0x0f));
- memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f),
- data, size);
-
- /* Send it away */
- net_input(NULL, pkt, sizeof(eth_hdr_t) + sizeof(ip_hdr_t) +
- size);
+ /* Put the IP header / data into our ethernet packet */
+ memcpy(pkt + sizeof(eth_hdr_t), hdr,
+ 4 * (hdr->version_ihl & 0x0f));
+ memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f),
+ data, size);
+
+ /* Send it away */
+ net_input(NULL, pkt, sizeof(eth_hdr_t) + sizeof(ip_hdr_t) +
+ size);
- return 0;
- }
-
- /* Is it in our network? */
- if(!is_in_network(net->ip_addr, dest_ip, net->netmask)) {
- memcpy(dest_ip, net->gateway, 4);
- }
+ return 0;
+ }
+
+ /* Is it in our network? */
+ if(!is_in_network(net->ip_addr, dest_ip, net->netmask)) {
+ memcpy(dest_ip, net->gateway, 4);
+ }
- /* Get our destination's MAC address */
- if(net_arp_lookup(net, dest_ip, dest_mac) == -1) {
- errno = ENETUNREACH;
- return -1;
- }
+ /* Get our destination's MAC address */
+ if(net_arp_lookup(net, dest_ip, dest_mac) == -1) {
+ errno = ENETUNREACH;
+ return -1;
+ }
- /* Fill in the ethernet header */
- ehdr = (eth_hdr_t *)pkt;
- memcpy(ehdr->dest, dest_mac, 6);
- memcpy(ehdr->src, net->mac_addr, 6);
- ehdr->type[0] = 0x08;
- ehdr->type[1] = 0x00;
+ /* Fill in the ethernet header */
+ ehdr = (eth_hdr_t *)pkt;
+ memcpy(ehdr->dest, dest_mac, 6);
+ memcpy(ehdr->src, net->mac_addr, 6);
+ ehdr->type[0] = 0x08;
+ ehdr->type[1] = 0x00;
- /* Put the IP header / data into our ethernet packet */
- memcpy(pkt + sizeof(eth_hdr_t), hdr, 4 * (hdr->version_ihl & 0x0f));
- memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f), data,
- size);
+ /* Put the IP header / data into our ethernet packet */
+ memcpy(pkt + sizeof(eth_hdr_t), hdr, 4 * (hdr->version_ihl & 0x0f));
+ memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f), data,
+ size);
- /* Send it away */
- net->if_tx(net, pkt, sizeof(ip_hdr_t) + size + sizeof(eth_hdr_t),
- NETIF_BLOCK);
+ /* Send it away */
+ net->if_tx(net, pkt, sizeof(ip_hdr_t) + size + sizeof(eth_hdr_t),
+ NETIF_BLOCK);
- return 0;
+ return 0;
}
+int net_ipv4_send(netif_t *net, const uint8 *data, int size, int id, int ttl,
+ int proto, uint32 src, uint32 dst) {
+ ip_hdr_t hdr;
+
+ /* Fill in the IPv4 Header */
+ hdr.version_ihl = 0x45;
+ hdr.tos = 0;
+ hdr.length = htons(size + 20);
+ hdr.packet_id = id;
+ hdr.flags_frag_offs = htons(0x4000);
+ hdr.ttl = ttl;
+ hdr.protocol = proto;
+ hdr.checksum = 0;
+ hdr.src = src;
+ hdr.dest = dst;
+
+ hdr.checksum = net_ipv4_checksum((uint8 *)&hdr, sizeof(ip_hdr_t));
+
+ return net_ipv4_send_packet(net, &hdr, data, size);
+}
+
int net_ipv4_input(netif_t *src, const uint8 *pkt, int pktsize) {
- ip_hdr_t *ip;
- int i;
- uint8 *data;
+ ip_hdr_t *ip;
+ int i;
+ uint8 *data;
+ int hdrlen;
- /* Get pointers */
- ip = (ip_hdr_t*) pkt;
- data = (uint8 *) (pkt + 4 * (ip->version_ihl & 0x0f));
+ if(pktsize < sizeof(ip_hdr_t))
+ /* This is obviously a bad packet, drop it */
+ return -1;
- /* Check ip header checksum */
- i = ip->checksum;
- ip->checksum = 0;
- ip->checksum = net_ipv4_checksum((uint8 *)ip, 4 *
- (ip->version_ihl & 0x0f));
+ ip = (ip_hdr_t*) pkt;
+ hdrlen = (ip->version_ihl & 0x0F) << 2;
- if(i != ip->checksum) {
- dbglog(DBG_KDEBUG, "net_ipv4: Discarding recieved IP packet "
- "with invalid checksum\n");
- return 0;
- }
+ if(pktsize < hdrlen)
+ /* The packet is smaller than the listed header length, bail */
+ return -1;
- switch(ip->protocol) {
- case 1:
- net_icmp_input(src, ip, data, ntohs(ip->length) -
- (ip->version_ihl & 0x0f) * 4);
- break;
- case 17:
- net_udp_input(src, ip, data, ntohs(ip->length) -
- (ip->version_ihl & 0x0f) * 4);
- break;
- default:
- dbglog(DBG_KDEBUG, "net_ipv4: Discarding recieved IP "
- "packet with unkown protocol: %d\n",
- ip->protocol);
- }
+ data = (uint8 *) (pkt + hdrlen);
- return 0;
+ /* Check ip header checksum */
+ i = ip->checksum;
+ ip->checksum = 0;
+ ip->checksum = net_ipv4_checksum((uint8 *)ip, hdrlen);
+
+ if(i != ip->checksum) {
+ /* The checksums don't match, bail */
+ return -1;
+ }
+
+ switch(ip->protocol) {
+ case IPPROTO_ICMP:
+ return net_icmp_input(src, ip, data, ntohs(ip->length) - hdrlen);
+
+ case IPPROTO_UDP:
+ return net_udp_input(src, ip, data, ntohs(ip->length) - hdrlen);
+ }
+
+ /* There's no handler for this packet type, bail out */
+ return -1;
}
uint32 net_ipv4_address(const uint8 addr[4]) {
- return (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | (addr[3]);
+ return (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | (addr[3]);
}
void net_ipv4_parse_address(uint32 addr, uint8 out[4]) {
- out[0] = (uint8) ((addr >> 24) & 0xFF);
- out[1] = (uint8) ((addr >> 16) & 0xFF);
- out[2] = (uint8) ((addr >> 8) & 0xFF);
- out[3] = (uint8) (addr & 0xFF);
+ out[0] = (uint8) ((addr >> 24) & 0xFF);
+ out[1] = (uint8) ((addr >> 16) & 0xFF);
+ out[2] = (uint8) ((addr >> 8) & 0xFF);
+ out[3] = (uint8) (addr & 0xFF);
}
Modified: kos/kernel/net/net_ipv4.h
===================================================================
--- kos/kernel/net/net_ipv4.h 2008-03-10 02:12:30 UTC (rev 561)
+++ kos/kernel/net/net_ipv4.h 2008-03-21 02:38:35 UTC (rev 562)
@@ -1,7 +1,7 @@
/* KallistiOS ##version##
kernel/net/net_ipv4.h
- Copyright (C) 2005, 2007 Lawrence Sebald
+ Copyright (C) 2005, 2007, 2008 Lawrence Sebald
*/
@@ -44,7 +44,10 @@
#undef packed
uint16 net_ipv4_checksum(const uint8 *data, int bytes);
-int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data, int size);
+int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data,
+ int size);
+int net_ipv4_send(netif_t *net, const uint8 *data, int size, int id, int ttl,
+ int proto, uint32 src, uint32 dst);
int net_ipv4_input(netif_t *src, const uint8 *pkt, int pktsize);
#endif /* __LOCAL_NET_IPV4_H */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2008-04-29 00:48:23
|
Revision: 568
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=568&view=rev
Author: ljsebald
Date: 2008-04-28 17:48:20 -0700 (Mon, 28 Apr 2008)
Log Message:
-----------
A slight modification to net_default_input, as well as a more sane way to handle loopback sends in net_ipv4 (sending it directly back into net_ipv4_input).
Modified Paths:
--------------
kos/kernel/net/net_input.c
kos/kernel/net/net_ipv4.c
Modified: kos/kernel/net/net_input.c
===================================================================
--- kos/kernel/net/net_input.c 2008-04-26 20:58:15 UTC (rev 567)
+++ kos/kernel/net/net_input.c 2008-04-29 00:48:20 UTC (rev 568)
@@ -7,7 +7,6 @@
#include <stdio.h>
#include <kos/net.h>
-#include <arpa/inet.h>
#include "net_ipv4.h"
CVSID("$Id: net_input.c,v 1.2 2002/03/24 00:27:05 bardtx Exp $");
@@ -19,17 +18,19 @@
*/
static int net_default_input(netif_t *nif, const uint8 *data, int len) {
- uint16 *proto = (uint16 *)(data + 12);
+ uint16 proto = (uint16)((data[12] << 8) | (data[13]));
- switch(ntohs(*proto)) {
+ switch(proto) {
case 0x0800:
return net_ipv4_input(nif, data + sizeof(eth_hdr_t),
len - sizeof(eth_hdr_t));
+
case 0x0806:
return net_arp_input(nif, data, len);
+
default:
dbglog(DBG_KDEBUG, "net_input: unhandled ethernet "
- "protocol: %x\n", ntohs(*proto));
+ "protocol: %x\n", proto);
return 0;
}
}
Modified: kos/kernel/net/net_ipv4.c
===================================================================
--- kos/kernel/net/net_ipv4.c 2008-04-26 20:58:15 UTC (rev 567)
+++ kos/kernel/net/net_ipv4.c 2008-04-29 00:48:20 UTC (rev 568)
@@ -73,7 +73,7 @@
return 1;
}
-/* Send a packet on the specified network adaptor */
+/* Send a packet on the specified network adapter */
int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data,
int size) {
uint8 dest_ip[4];
@@ -89,26 +89,12 @@
/* Is this the loopback address (127.0.0.1)? */
if(ntohl(hdr->dest) == 0x7F000001) {
- /* Fill in the ethernet header */
- ehdr = (eth_hdr_t *)pkt;
- memset(ehdr->dest, 0, 6);
- memset(ehdr->src, 0, 6);
-
- ehdr->dest[0] = 0xCF;
- ehdr->src[0] = 0xCF;
-
- ehdr->type[0] = 0x08;
- ehdr->type[1] = 0x00;
-
- /* Put the IP header / data into our ethernet packet */
- memcpy(pkt + sizeof(eth_hdr_t), hdr,
- 4 * (hdr->version_ihl & 0x0f));
- memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f),
- data, size);
+ /* Put the IP header / data into our packet */
+ memcpy(pkt, hdr, 4 * (hdr->version_ihl & 0x0f));
+ memcpy(pkt + 4 * (hdr->version_ihl & 0x0f), data, size);
- /* Send it away */
- net_input(NULL, pkt, sizeof(eth_hdr_t) + sizeof(ip_hdr_t) +
- size);
+ /* Send it "away" */
+ net_ipv4_input(NULL, pkt, 4 * (hdr->version_ihl & 0x0f) + size);
return 0;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2008-04-29 01:12:50
|
Revision: 569
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=569&view=rev
Author: ljsebald
Date: 2008-04-28 18:12:32 -0700 (Mon, 28 Apr 2008)
Log Message:
-----------
Changing the behavior when a send is attempted to a host that does not have a cached ARP entry. Now, net_arp_lookup will return -2, signaling that an ARP query has been sent out. net_ipv4_send_packet detects this condition and returns this to the caller (net_udp_send_raw at this point). net_udp_send_raw sees this condition returned from net_ipv4_send_packet, and retries the transmission after 100ms. Thus, the first send to hosts won't fail in UDP any more, unless the host does not respond to the ARP query (i.e. its not actually there).
Modified Paths:
--------------
kos/kernel/net/net_arp.c
kos/kernel/net/net_ipv4.c
kos/kernel/net/net_udp.c
kos/kernel/net/net_udp.h
Modified: kos/kernel/net/net_arp.c
===================================================================
--- kos/kernel/net/net_arp.c 2008-04-29 00:48:20 UTC (rev 568)
+++ kos/kernel/net/net_arp.c 2008-04-29 01:12:32 UTC (rev 569)
@@ -122,7 +122,7 @@
net_arp_query(nif, ip_in);
/* Return failure */
- return -1;
+ return -2;
}
/* Do a reverse ARP lookup: look for an IP for a given mac address; note
Modified: kos/kernel/net/net_ipv4.c
===================================================================
--- kos/kernel/net/net_ipv4.c 2008-04-29 00:48:20 UTC (rev 568)
+++ kos/kernel/net/net_ipv4.c 2008-04-29 01:12:32 UTC (rev 569)
@@ -80,6 +80,7 @@
uint8 dest_mac[6];
uint8 pkt[size + sizeof(ip_hdr_t) + sizeof(eth_hdr_t)];
eth_hdr_t *ehdr;
+ int err;
if(net == NULL) {
net = net_default_dev;
@@ -104,11 +105,17 @@
memcpy(dest_ip, net->gateway, 4);
}
- /* Get our destination's MAC address */
- if(net_arp_lookup(net, dest_ip, dest_mac) == -1) {
+ /* Get our destination's MAC address. If we do not have the MAC address
+ cached, return a distinguished error to the upper-level protocol so
+ that it can decide what to do. */
+ err = net_arp_lookup(net, dest_ip, dest_mac);
+ if(err == -1) {
errno = ENETUNREACH;
return -1;
}
+ else if(err == -2) {
+ return -2;
+ }
/* Fill in the ethernet header */
ehdr = (eth_hdr_t *)pkt;
Modified: kos/kernel/net/net_udp.c
===================================================================
--- kos/kernel/net/net_udp.c 2008-04-29 00:48:20 UTC (rev 568)
+++ kos/kernel/net/net_udp.c 2008-04-29 01:12:32 UTC (rev 569)
@@ -399,7 +399,7 @@
udpsock->local_addr.sin_port,
udpsock->remote_addr.sin_addr.s_addr,
udpsock->remote_addr.sin_port, (uint8 *) message,
- length);
+ length, udpsock->flags);
}
ssize_t net_udp_sendto(net_socket_t *hnd, const void *message, size_t length,
@@ -463,7 +463,7 @@
return net_udp_send_raw(NULL, udpsock->local_addr.sin_addr.s_addr,
udpsock->local_addr.sin_port,
realaddr->sin_addr.s_addr, realaddr->sin_port,
- (uint8 *) message, length);
+ (uint8 *) message, length, udpsock->flags);
}
int net_udp_shutdownsock(net_socket_t *hnd, int how) {
@@ -671,9 +671,10 @@
int net_udp_send_raw(netif_t *net, uint32 src_ip, uint16 src_port,
uint32 dst_ip, uint16 dst_port, const uint8 *data,
- int size) {
+ int size, int flags) {
uint8 buf[size + 12 + sizeof(udp_hdr_t)];
ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t *) buf;
+ int err;
if(net == NULL && net_default_dev == NULL) {
errno = ENETDOWN;
@@ -705,12 +706,25 @@
ps->checksum = 0;
ps->checksum = net_ipv4_checksum(buf, size + 12);
+retry_send:
/* Pass everything off to the network layer to do the rest. */
- if(net_ipv4_send(net, buf + 12, size, 0, 64, IPPROTO_UDP, ps->src_addr,
- ps->dst_addr)) {
- /* If the packet send fails, errno will be set already. */
+ err = net_ipv4_send(net, buf + 12, size, 0, 64, IPPROTO_UDP, ps->src_addr,
+ ps->dst_addr);
+
+ /* If the IP layer returns that the ARP cache didn't have the entry for the
+ destination, sleep for a little bit, and try again (as long as the
+ non-blocking flag was not set). */
+ if(err == -2 && !(flags & O_NONBLOCK)) {
+ thd_sleep(100);
+ goto retry_send;
+ }
+ else if(err == -2) {
+ errno = ENETUNREACH;
return -1;
}
+ else if(err < 0) {
+ return -1;
+ }
else {
return size - sizeof(udp_hdr_t);
}
Modified: kos/kernel/net/net_udp.h
===================================================================
--- kos/kernel/net/net_udp.h 2008-04-29 00:48:20 UTC (rev 568)
+++ kos/kernel/net/net_udp.h 2008-04-29 01:12:32 UTC (rev 569)
@@ -1,7 +1,7 @@
/* KallistiOS ##version##
kernel/net/net_udp.h
- Copyright (C) 2005, 2006, 2007 Lawrence Sebald
+ Copyright (C) 2005, 2006, 2007, 2008 Lawrence Sebald
*/
@@ -23,7 +23,7 @@
int net_udp_input(netif_t *src, ip_hdr_t *ih, const uint8 *data, int size);
int net_udp_send_raw(netif_t *net, uint32 src_ip, uint16 src_port,
uint32 dst_ip, uint16 dst_port, const uint8 *data,
- int size);
+ int size, int flags);
/* Sockets */
int net_udp_accept(net_socket_t *hnd, struct sockaddr *addr,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|