How to validate broadcast IP address?
IP Addr: 192.168.36.226
Netmask: 255.255.255.0
Broadcast: 192.168.36.255
whether it is possible to provide any broadcast address (suppose 1.2.3.4). If yes what will be the impact on the communication to other network.
The IP address and netmask determine the broadcast address. You cannot use just any broadcast address, or anything requiring broadcast traffic will not work.
The netmask specifies the size of the subnet. A netmask of 255.255.255.0 is commonly represented as /24, meaning that the first 24 bits of the IP address specify the network ID, where the last 8 bits are for the individual host. 192.168.0.100/24 is a host on a network with an ID of 192.168.0.0 and a broadcast address of 192.168.0.255. The highest value available in the network is the broadcast address.
10.1.2.3/8's broadcast address is 10.255.255.255. Its decimal subnet mask is 255.0.0.0.
As Brad mentioned, if you have the netmask, then it's very easy to compute the broadcast address. You simply swap all the bits and do an OR with the main IP address.
Typing a mask such as 255.255.255.0 is now deprecated. Instead, you are expected to use a number of bits on the IP. For example: 192.168.36.226/24.
The number, 24, indicates the number of 1s starting in the most significant bit. This is the same principle with IPv6 which uses 128 bits instead. So those numbers are often much larger with IPv6.
One way to compute the mask for an IPv4, is to use -1 and 32 - size (which is our case is 32 - 24 = 8):
size = 24; // somehow you get this number...
...
unsigned int mask = -1;
shift = 32 - size;
mask <<= shift; // C++ operator, in C write: mask = mask << shift;
Now you can compute the broadcast address by flipping all the bits of the mask and ORing that with the IP:
broadcast_bits = ~mask;
broadcast_ip = ip | broadcast_bits;
I think that IPv6 does the same thing, but with 128 bits. Also IPv6 does not offer Multicast (IPs that match 224.0.0.0/4).
If your question was about finding the broadcast address as defined in the Interface of an Ethernet or similar network card, then the above code is not what you are interested in. Instead, you want to list the interfaces, list each IP address defined on each interface (on some systems you could have up to 65536 IPs on one interface). That list includes the broadcast IP address and the main IP address and a mask. In other words, you can do:
if(my_ip & mask == interface->ip & mask)
{
if(my_ip == interface->broadcast_ip)
{
return interface;
}
}
return nullptr;
The list of interfaces is accessed with the following:
struct ifaddrs * ifa_start(nullptr);
getifaddrs(&ifa_start);
for(struct ifaddrs * ifa(ifa_start); ifa != nullptr; ifa = ifa->ifa_next)
{
if((ifa->ifa_flags & IFF_BROADCAST) != 0
&& ifa->ifa_broadaddr != nullptr)
{
// found the broadcast address of that interface
}
}
With that information, you should be able to find the address and the mask used above. Note that all interfaces may not support the broadcasting (unlikely, I think).
For a complete implementation, see libaddr (C++). The interface implementation is found in libaddr/iface.cpp.
Related
Context: I am following an embedded systems course https://www.edx.org/course/embedded-systems-shape-the-world-microcontroller-i
In the lecture on bit specific addressing they present the following example on a "peanut butter and jelly port".
Given you a port PB which has a base address of 0x40005000 and you wanted to access both port 4 and port 6 from PB which would be PB6 and PB4 respectively. One could add the offset of port 4(0x40) and port 6(0x100) to the base address(0x40005000) and define that as their new address 0x40005140.
Here is where I am confused. If I wanted to define the address for PB6 it would be base(0x40005000) + offset(0x100) = 0x40005100 and the address for PB4 would be base(0x40005000) + offset(0x40) = 0x40005040. So how is it that to access both of them I could use base(0x40005000) + offset(0x40) + offset(0x100) = 0x40005140? Is this is not an entirely different location in memory for them individually?
Also why is bit 0 represented as 0x004. In binary that would be 0000 0100. I suppose it would represent bit 0 if you disregard the first two binary bits but why are we disregarding them?
Lecture notes on bit specific addressing:
Your interpretation of how memory-mapped registers are addressed is quite reasonable for any normal peripheral on an ARM based microcontroller.
However, if you read the GPIODATA register definition on page 662 of the TM4C123GH6PM datasheet then you will see that this "register" behaves very differently.
They map a huge block of the address space (1024 bytes) to a single 32-bit register. This means that bits[9:2] of the the address bus are not needed, and are in fact overloaded with data. They contain the mask of the bits to be updated. This is what the "offset" calculation you have copied is trying to describe.
Personally I think this hardware interface could be a very clever way to let you set only some of the outputs within a bank using a single atomic write, but it makes this a very bad choice of device to use for teaching, because this isn't the way things normally work.
The safe size of a datagram packet (considering the MTU such that packet will not get fragmented) is said to be 576 bytes for IPV4 and 1500 for IPV6.
Is this correct ?
If i am having a connection from my machine to a server in another country, two of which communicate using UDP, what is the maximum (safest) payload size i should have for the UDP packet, 1500 or 576 ?
Thank you
No. That's the safe size of the total IP packet.
534.
I found the real IP address in my local network. Then, I used recommendations at "www dot asus dot com/support/FAQ/1007914" in order to "check the best value of MTU(Maximum Transmission Unit) for the internet".
There are two 32 bit registers. If for some reason the 1st register has the address 0x84000000, then what will be the HEX address of the 2nd 32 bit register (consider the two register to be one after the other)?
I assume you are working in an embedded environment with memory mapped I/O. If 0x84000000 is the address of the first register, the following register most likely has address 0x84000004.
Example on a Freescale i.MX35 processor.
Registers are identified with an offset with respect to a base address. For example, the address space of the General Purpose Timer is mapped at base address 0x53F90000.
From the datasheet you can see the register mapping:
GPT Control Register: 0x53F90000 + 0x0000
GPT Prescale Register: 0x53F90000 + 0x0004
GPT Status Register: 0x53F90000 + 0x0008
and so on and so forth. You can see that consecutive 32 bit registers are mapped at 4 bytes increments.
Note that this could be specific to the processor and the architecture. I would recommend checking the datasheet of the hardware you are working on.
I encounter some problem when I develop a network card driver in Linux. As we all know the MTU refers to the MAX size of IP packet without fragment. And the skb sent to xmit function will be added 14bytes including dst mac addr,src mac addr and lengh. but it's very odd that when I use different values for MTU, the added size to it is different, sometime it's 10bytes, sometime it's 14bytes. It's depending the size of MTU. For example, I use 7828 as the size of UDP payload, when MTU is 7700, the size of skb in xmit function is 7714, while when MTU is 7800, the size of skb is 7810. Can anyone explain this? I guess maybe there are some align limitation for IP packets, but I didn't find that.
I searched the answer from the internet, and I found that there is an align limitation for payload field of IP frame. The payload field must be align to 8 bytes. So if the MTU is 7700, the true size of IP frame should be 7680+20 = 7700 because 7680 can be divisible by 8. While if the MTU is 7800, the true size of IP frame should be 7776+20 = 7796 because 7780 can't be divisible by 8, the last 4 bytes will be assigned to next IP fragment.
It seems boost::asio defines a separate endpoint class for each protocol, which is irritating if you want to perform both UDP and TCP operations on a particular endpoint (have to convert from one to the other). I'd always just thought of an endpoint as an IP address (v4 or v6) and the port number, regardless of TCP or UDP.
Are there significant differences that justify separate classes? (i.e. couldn't both tcp::socket and udp::socket accept something like ip::endpoint?)
The sockets are created differently
socket(PF_INET, SOCK_STREAM)
for TCP, and
socket(PF_INET, SOCK_DGRAM)
for UDP.
I suspect that is the reason for the differing types in Boost.Asio. See man 7 udp or man 7 tcp for more information, I'm assuming Linux since you didn't tag your question.
To solve your problem, extract the IP and port from a TCP endpoint and instantiate a UDP endpoint.
#include <boost/asio.hpp>
#include <iostream>
int
main()
{
using namespace boost::asio;
ip::tcp::endpoint tcp(
ip::address::from_string("127.0.0.1"),
123
);
ip::udp::endpoint udp(
tcp.address(),
tcp.port()
);
std::cout << "tcp: " << tcp << std::endl;
std::cout << "udp: " << udp << std::endl;
return 0;
}
sample invocation:
./a.out
tcp: 127.0.0.1:123
udp: 127.0.0.1:123
TCP and UDP ports are different. For example, two separate programs can both listen on a single port as long as one uses TCP and the other uses UDP. This is why the endpoints classes are different.