IPv6 scope ID vs IPv4 - sockets

Recently I was working with the Berkeley socket API for IPv6, and noticed that IPv6 addresses (sockaddr_in6) have a field called sin6_scope_id, which was not part of IPv4 addresses.
After searching around a bit, I’ve learned that scope_id is meant to identify the network interface, because multiple network interfaces can have the same link-local IPv6 address. This made sense, but then what I didn’t understand is how IPv4 handles this issue, if there’s no equivalent of scope ID there?
Is there a mechanism in the kernel that prevents multiple IPv4 interfaces from being assigned the same link-local address?
If that’s the case, then why was it necessary to invent scope ID for IPv6 instead of going with the same solution as IPv4?
Also, is the scope_id only used to distinguish between interfaces with identical link-local addresses, or are there other use cases too?

In short, no, there is no well-defined mechanism for handling link-local IPv4 addresses on hosts with multiple interfaces. There is nothing stopping the same link-local address being selected for two different interfaces (however if the two interfaces are on the same network link, then ARP-based conflict detection will cause at least one of them to be reassigned).
RFC 3927 section 3.2 covers the issues of "address ambiguity":
Given that the IP stack must have the outbound interface associated
with a packet that needs to be sent to a Link-Local destination
address, interface selection must occur. The outbound interface
cannot be derived from the packet's header parameters such as source
or destination address (e.g., by using the forwarding table lookup).
Therefore, outbound interface association must be done explicitly
through other means. The specification does not stipulate those
means.
And also in section 6.3:
Application software run on a multi-homed host that supports IPv4
Link-Local address configuration on more than one interface may fail.
This is because application software assumes that an IPv4 address is
unambiguous, that it can refer to only one host. IPv4 Link-Local
addresses are unique only on a single link. A host attached to
multiple links can easily encounter a situation where the same
address is present on more than one interface, or first on one
interface, later on another; in any case associated with more than
one host. Most existing software is not prepared for this ambiguity.
In the future, application programming interfaces could be developed
to prevent this problem.
This problem was solved in IPv6 by the introduction of a scope ID.
At present scope id is only used for link-local addressing.

Related

Device interface's IP Address

Question image
Can anyone tell me how to solve the question iv) ? I don't really understand what the question is looking for. What does it mean by device interface's ip address?
Your device may have several network interfaces. Those can correspond to real devices (NICs) or be virtual.
In order to be usable (i.e. initiate or listen for connections), each interface should have an IP address. Usually there will be one IP per interface, but it's possible to have several via IP aliasing.
Individual connections on each IP address are identified by port number. There is a limit of 65536 ports per IP address imposed by the IP protocol. One reason behind IP aliasing is to overcome this limitation.

Is there an ethernet link layer protocol to get remote IPv4 settings?

Given one or more embedded devices of the same type with some unknown IPv4 addresses or maybe no IPv4 addresses set at all: is there any Ethernet based network protocol to ”find“ those devices in the local net (LAN) from remote (PC) and get their IPv4 settings?
What not works for me:
ARP: IP address must be known or only finds device I communicated with before (or ugly ARP floods …)
LLDP: point to point only (?), so I would only see the switch between device and me. Also, just announces, no response on request (because there are no requests). Further: asking the switch (which supports LLDP) through SNMP is no option when using dumb switches
IP based protocols: I played with UDP and broadcasts (both as request and response), but that does not work reliably if device and me are on different subnets, and it does not work at all if device has no IPv4 set.
DHCP: does not work in networks without DHCP server, maybe no DHCP client on the embedded device
I assume others had the same problem before, take manufactures of network equipment like access points which should be configured remotely, powerline adapters, switches … all those where the vendor gives you some proprietary tool, the device shows up like magic in a list and you can assign some IPv4 then.
Of course the device must have some daemon listening and responding to certain requests, but what would be a standard protocol for such a task? Or do I have to make up some new protocol for that? May some of the above mentioned is possible, but I overlooked something?
Ethernet only provides a layer 2 connection, so anything Ethernet-based can't ever work across a router (ARP, LLDP - LLDP doesn't even cross a decent switch as it's link layer only).
Depending on the network, routed multicasts or directed broadcasts could work - normally they don't. All vendor tools I've seen just use (Ethernet) broadcasts and don't work across routers.
Most often, simple DNS is used for this purpose - the device registers with the DNS server or is preregistered and you just resolve the name.
Edit: without the router problem, the simplest way is to use a UDP broadcast to some unused port. With DHCP unavailable, the device could fall back to zeroconf (169.254.0.0/16) and broadcast from there.
Without IP, you'd need a "raw" Ethernet socket and use an Ethertype that doesn't interfere with normal network operations.

IPv6: Why are IPv4-mapped addresses a security risk?

The OpenBSD manual states:
For security reasons, OpenBSD does not route IPv4 traffic to an AF_INET6 socket, and does not support IPv4 mapped addresses, where IPv4 traffic is seen as if it comes from an IPv6 address like ::ffff:10.1.1.1. Where both IPv4 and IPv6 traffic need to be accepted, listen on two sockets.
However, there is no explanation concerning these "security reasons." What are they? I can't think of any security problems related to that mapping.
I don't know specifically what motivation OpenBSD used, but I know of at least one problem that can be a security concern, namely ACLs and specifically black lists.
Ponder that you have an incoming connection from 10.1.1.1. This address is blacklisted in your ACL, and thus you refuse the connection. But if you're using a mapped address, it will instead appear to come from ::ffff:10.1.1.1. Your blacklist might not be able to catch this and might let the connection through.
This can be solved with application logic, and since using a single socket might simplify the code, I personally believe OpenBSD's decision is unfortunate. It's possible to default v4mapped to off but allow it to be enabled via setsockopt.
They might have had more concerns though that I'm not aware of.
As far as I know the main reason is to keep the IPv4 and IPv6 stacks separate. It's the hacks necessary to handle packets coming in on one stack but being handled by the other that cause the security risks.

How to let different processes use different network interfaces?

I'm on the client side. There're multiple network interfaces. How can I let different processes use different network interfaces to communicate? Since I want to connect to the same server, routing seems not working here. Also, connect() doesn't have arguments to specify local address or interface as bind() does.
If your goal is to increase bandwidth to the server by using multiple network interfaces in parallel, then that's probably not something you can (or should) do at the application level. Instead, you should study up on Link Aggregation and then configure your computer and networking stack to use that. Once that is working properly, you will get the parallelization-speedup you want automatically, without the client application having to do anything special to enable it.
"The bind() system call is frequently misunderstood. It is used to
bind to a particular IP address. Only packets destined to that IP
address will be received, and any transmitted packets will carry that
IP address as their source. bind() does not control anything about the
routing of transmitted packets. So for example, if you bound to the IP
address of eth0 but you send a packet to a destination where the
kernel's best route goes out eth1, it will happily send the packet out
eth1 with the source IP address of eth0. This is perfectly valid for
TCP/IP, where packets can traverse unrelated networks on their way to
the destination."
More info e.g. here.
That's why you probably misunderstand bind() call.
The appropriate way to bind to physical topology (to some specific interface) is to use SO_BINDTODEVICE socket option. This is done by setsockopt() call.
Source Policy Routing might be helpful.
Try the following steps:
Use iptables to give packets from different process with different marks.
Use iproute2 to route packets with different marks to different table.
In different table, set the default route to different uplink.
The whole process require certain amount of understanding about linux networking.
Here is an example shows how to route all traffic for a user through one specific uplink: http://www.niftiestsoftware.com/2011/08/28/making-all-network-traffic-for-a-linux-user-use-a-specific-network-interface/
You could try follow similar approach by running different process with different user and route traffic from one user to one uplink.
Also you could let processes communicate with the server with different port and mark the traffic by port.

SIP and NAT traversal

I'm trying to understand the exact problem with NAT and SIP and have seen many different explanations. Here's what I've gathered so far:
1) SIP User agent is both initiating and accepting calls, therefore unless the NAT/firewall is configured to accept incoming traffic on this port it cannot work - this makes sense but sounds more firewall and port mapping
2) SIP messages contain IP addresses (that can be private) in the body which requires NAT traversal - if this is the case
3) it's not a problem with SIP but with RTP, whose parameters that are included in the SDP as part of the SIP message body that include private IP addresses
4) something to do with UDP vs. TCP?
When a call is done with SIP the calling endpoing does not know the endpoint the call must reach i.e. the endpoint's IP.
It only knows the IP address of the SIP server.
So the INVITE goes to the SIP server and SIP servers "knows" where/how to reach the called endpoints.
The idea is that the SIP messages contain SDP data that contain the information needed so that eventually the phones will be able to set up a session and users will be able to start talking.
These data include IP, port, codecs and other parameters.
So if one of the phones is behind NAT the phone will report as its IP e.g. IP_X which is its private IP and the other endpoint can not reach that IP; the public IP is unknown at that point.
All of your assumptions are correct.
In SIP, you can split it into 2 main problems: signaling and media.
The signaling runs in SIP over either TCP or UDP, and the connection can open from both directions, as calls can be dialed or accepted by user agents.
The media runs over RTP (and RTCP), which is usually done over UDP (unless you're trying to achieve NAT traversal), and then it might go over TCP). The ports and addresses here are allocated dynamically, need to go both ways and run on multiple sessions (=multiple sockets and connections).
To achieve NAT traversal, you will usually use multiple techniques: STUN, TURN, ICE, HTTP tunneling and even an SBC.
NAT traversal for SIP requires external support from servers - usually not the SIP server - that are dedicated for the job.
I'll disagree mildly with Tsahi Levent-Levi's answer.
The problem is that the IP address you put in your Via, Contact, From/To headers, SDP, etc., must be globally routable. If you're behind a NAT you'll obviously need to put in your external IP address.
Implementing ICE, using STUN, etc., allows you to do this automatically, but you can always solve the program manually.
In particular, by inspecting your machine's routing table you can tell whether or not the machine you're calling is behind a NAT or not (by virtue of knowing that work machines are behind this VPN NAT here, and local machines are on this subnet, and everything else runs through your router's NAT). With that information you may find out a NAT's far-side/external address somehow (STUN gives this automatically, but your internet router may have a static address, or you could contact an HTTP server capable of returning your external address, or ...). Once you have that far-side/external address, you can put the address where necessary - your Contact header, SDP c= headers, and the like.
There is a whitepaper by Eyeball Networks that clearly explains the NAT & firewall traversal problem for voip and the STUN, TURN, ICE solution. There are also a couple of great diagrams on how SIP P2P and SIP TURN calls are achieved at http://www.eyeball.com/voip-solutions/stun-turn-ice.htm