Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BACKPORT] Ethernet : changes were made to support ethernet #27

Merged
merged 1 commit into from
Sep 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 40 additions & 30 deletions include/nuttx/net/ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,46 @@ bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1,
const net_ipv6addr_t mask);
#endif

/****************************************************************************
* Name: net_ipv4addr_broadcast
*
* Description:
* Mask out the network part of an IP address, given the address and
* the netmask.
*
* Example:
*
* in_addr_t ipaddr;
* in_addr_t netmask;
* bool isbroadcast;
*
* net_ipaddr(&netmask, 255,255,255,0);
* net_ipaddr(&ipaddr, 192,16,1,255);
* isbroadcast = net_ipv4addr_broadcast(ipaddr, netmask);
*
* Will return isboadcast == true.
*
* net_ipaddr(&ipaddr, 192,16,1,2);
* isbroadcast = net_ipv4addr_broadcast(ipaddr, netmask);
*
* Will return isboadcast == false.
*
* NOTES:
* 1. This function does not check for the broadcast address
* 255.255.255.255. That must be performed as a seperate check.
* 2. You must also separately check if the ipaddress lies on the sub-net
* using, perhaps, net_ipv4addr_maskcmp().
*
* Input Parameters:
* addr - The IPv4 address to check
* mask - The network mask
*
****************************************************************************/

#define net_ipv4addr_broadcast(addr, mask) \
(((in_addr_t)(addr) & ~(in_addr_t)(mask)) == \
((in_addr_t)(0xffffffff) & ~(in_addr_t)(mask)))

/****************************************************************************
* Name: net_ipv6addr_prefixcmp
*
Expand Down Expand Up @@ -587,36 +627,6 @@ bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1,

#define net_is_addr_linklocal(a) ((a)[0] == HTONS(0xfe80))

/****************************************************************************
* Name: net_ipaddr_mask
*
* Description:
* Mask out the network part of an IP address, given the address and
* the netmask.
*
* Example:
*
* in_addr_t ipaddr1, ipaddr2, netmask;
*
* net_ipaddr(&ipaddr1, 192,16,1,2);
* net_ipaddr(&netmask, 255,255,255,0);
* net_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);
*
* In the example above, the variable "ipaddr2" will contain the IP
* address 192.168.1.0.
*
* Input Parameters:
* dest Where the result is to be placed.
* src The IP address.
* mask The netmask.
*
****************************************************************************/

#define net_ipaddr_mask(dest, src, mask) \
do { \
(in_addr_t)(dest) = (in_addr_t)(src) & (in_addr_t)(mask); \
} while (0)

#undef EXTERN
#ifdef __cplusplus
}
Expand Down
3 changes: 2 additions & 1 deletion libc/net/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
# Add the networking C files to the build

CSRCS += lib_addrconfig.c lib_etherntoa.c lib_htons.c lib_htonl.c
CSRCS += lib_inetaddr.c lib_inetntoa.c lib_inetntop.c lib_inetpton.c
CSRCS += lib_inetaddr.c lib_inetaton.c lib_inetntoa.c
CSRCS += lib_inetntop.c lib_inetpton.c

ifeq ($(CONFIG_NET),y)
CSRCS += lib_shutdown.c
Expand Down
125 changes: 125 additions & 0 deletions libc/net/lib_inetaton.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/****************************************************************************
* libc/net/lib_inetaton
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Juha Niskanen <juha.niskanen@haltian.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name NuttX 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.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <stdint.h>
#include <arpa/inet.h>

/****************************************************************************
* Public Functions
****************************************************************************/

/****************************************************************************
* Name: inet_aton
*
* Description:
* The inet_aton() function converts the string pointed to by cp, in the
* standard IPv4 dotted decimal notation, to an integer value suitable for
* use as an Internet address.
*
* Note:
* inet_aton() returns nonzero if the address is valid, zero if not.
* Therefore macros OK and ERROR are not used here.
*
****************************************************************************/

int inet_aton(FAR const char *cp, FAR struct in_addr *inp)
{
int dots = 0;
uint32_t num = 0;
uint32_t addr = 0;
int c;

do
{
c = *cp;

switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
num = 10 * num + (c - '0');
break;

case '.':
dots++;
if (dots > 3)
{
return 0;
}

/* no break */

case '\0':
if (num > 255)
{
return 0;
}

addr = addr << 8 | num;
num = 0;
break;

default:
return 0;
}
}
while (*cp++);

/* Normalize it */

if (dots < 3)
{
addr <<= 8 * (3 - dots);
}

if (inp)
{
inp->s_addr = HTONL(addr);
}

return 1;
}
107 changes: 64 additions & 43 deletions net/arp/arp_out.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ void arp_out(FAR struct net_driver_s *dev)
if (net_ipv4addr_hdrcmp(pip->eh_destipaddr, g_broadcast_ipaddr))
{
memcpy(peth->dest, g_broadcast_ethaddr.ether_addr_octet, ETHER_ADDR_LEN);
goto finish_header;
}

#ifdef CONFIG_NET_IGMP
Expand All @@ -181,74 +182,94 @@ void arp_out(FAR struct net_driver_s *dev)
* addresses=0xff (ff00::/8.)
*/

else if (NTOHS(pip->eh_destipaddr[0]) >= 0xe000 &&
NTOHS(pip->eh_destipaddr[0]) <= 0xefff)
if (NTOHS(pip->eh_destipaddr[0]) >= 0xe000 &&
NTOHS(pip->eh_destipaddr[0]) <= 0xefff)
{
/* Build the well-known IPv4 IGMP Ethernet address. The first
* three bytes are fixed; the final three variable come from the
* last three bytes of the IP address.
* last three bytes of the IPv4 address (network order).
*
* Address range : 01:00:5e:00:00:00 to 01:00:5e:7f:ff:ff
*/

FAR const uint8_t *ip = ((FAR uint8_t *)pip->eh_destipaddr) + 1;
memcpy(peth->dest, g_multicast_ethaddr, 3);
memcpy(&peth->dest[3], ip, 3);
FAR const uint8_t *ip = (FAR uint8_t *)pip->eh_destipaddr;

peth->dest[0] = g_multicast_ethaddr[0];
peth->dest[1] = g_multicast_ethaddr[1];
peth->dest[2] = g_multicast_ethaddr[2];
peth->dest[3] = ip[1] & 0x7f;
peth->dest[4] = ip[2];
peth->dest[5] = ip[3];

goto finish_header;
}
#endif
else
{
/* Check if the destination address is on the local network. */

destipaddr = net_ip4addr_conv32(pip->eh_destipaddr);
if (!net_ipv4addr_maskcmp(destipaddr, dev->d_ipaddr, dev->d_netmask))
{
/* Destination address is not on the local network */
/* Check if the destination address is on the local network. */

destipaddr = net_ip4addr_conv32(pip->eh_destipaddr);
if (!net_ipv4addr_maskcmp(destipaddr, dev->d_ipaddr, dev->d_netmask))
{
/* Destination address is not on the local network */

#ifdef CONFIG_NET_ROUTE
/* We have a routing table.. find the correct router to use in
* this case (or, as a fall-back, use the device's default router
* address). We will use the router IP address instead of the
* destination address when determining the MAC address.
*/
/* We have a routing table.. find the correct router to use in
* this case (or, as a fall-back, use the device's default router
* address). We will use the router IP address instead of the
* destination address when determining the MAC address.
*/

netdev_ipv4_router(dev, destipaddr, &ipaddr);
netdev_ipv4_router(dev, destipaddr, &ipaddr);
#else
/* Use the device's default router IP address instead of the
* destination address when determining the MAC address.
*/
/* Use the device's default router IP address instead of the
* destination address when determining the MAC address.
*/

net_ipv4addr_copy(ipaddr, dev->d_draddr);
net_ipv4addr_copy(ipaddr, dev->d_draddr);
#endif
}
else
{
/* Else, we use the destination IP address. */
}

/* The destination address is on the local network. Check if it is
* the sub-net broadcast address.
*/

net_ipv4addr_copy(ipaddr, destipaddr);
}
else if (net_ipv4addr_broadcast(destipaddr, dev->d_netmask))
{
/* Yes.. then we won't need to know the destination MAC address */

/* Check if we already have this destination address in the ARP table */
memcpy(peth->dest, g_broadcast_ethaddr.ether_addr_octet, ETHER_ADDR_LEN);
goto finish_header;
}
else
{
/* Else, we use the destination IP address. */

tabptr = arp_find(ipaddr);
if (!tabptr)
{
ninfo("ARP request for IP %08lx\n", (unsigned long)ipaddr);
net_ipv4addr_copy(ipaddr, destipaddr);
}

/* The destination address was not in our ARP table, so we
* overwrite the IP packet with an ARP request.
*/
/* Check if we already have this destination address in the ARP table */

arp_format(dev, ipaddr);
arp_dump(ARPBUF);
return;
}
tabptr = arp_find(ipaddr);
if (tabptr == NULL)
{
ninfo("ARP request for IP %08lx\n", (unsigned long)ipaddr);

/* Build an Ethernet header. */
/* The destination address was not in our ARP table, so we overwrite
* the IP packet with an ARP request.
*/

memcpy(peth->dest, tabptr->at_ethaddr.ether_addr_octet, ETHER_ADDR_LEN);
arp_format(dev, ipaddr);
arp_dump(ARPBUF);
return;
}

/* Build an Ethernet header. */

memcpy(peth->dest, tabptr->at_ethaddr.ether_addr_octet, ETHER_ADDR_LEN);

/* Finish populating the Ethernet header */

finish_header:
memcpy(peth->src, dev->d_mac.ether.ether_addr_octet, ETHER_ADDR_LEN);
peth->type = HTONS(ETHTYPE_IP);
dev->d_len += ETH_HDRLEN;
Expand Down
11 changes: 11 additions & 0 deletions net/arp/arp_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,17 @@ int arp_send(in_addr_t ipaddr)
ipaddr = dripaddr;
}

/* The destination address is on the local network. Check if it is
* the sub-net broadcast address.
*/

else if (net_ipv4addr_broadcast(ipaddr, dev->d_netmask))
{
/* Yes.. We don't need to send the ARP request */

return OK;
}

/* Allocate resources to receive a callback. This and the following
* initialization is performed with the network lock because we don't
* want anything to happen until we are ready.
Expand Down
Loading