How to prevent process from knowing Network is up? [closed]

Fist let's block all Incoming, Outgoing signals
via iptables.

vi /etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A OUTPUT -j DROP
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT

start iptables:

 service iptables start

My Ethernet Cable is plugged in. let's try something via terminal

ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

that is all. just 1 line. after that it stalls. clearly iptables is blocking it successfully

now I am going to disconnect my Ethernet cable. my internet is disconnected.

let's try it again:

ping 8.8.8.8
connect: Network is unreachable

this time .. instantly.. it returns that message.

Clearly, weather it is "ping" or any other program.. it is determining if a network interface is up or not before it executes it's internet command.

of course soon as it executes.. it is not able to pass through iptable rules. but what seems evident is.. it does not first consult to the iptables..

it first checks to see if a network interface is connected or not.

I would like to figure out how I can manually let it know that network interface is connected.

in other words unless I tell it network interface is up.. it should simply behave the same way it behaves when network interface is not connected ( when the ethernet cable is not plugged in)

how can this be done ?


Solution 1:

Clearly, weather it is "ping" or any other program.. it is determining if a network interface is up or not before it executes it's internet command.

No, it isn't. Here's (some of) the output from strace ping 8.8.8.8 from a system with no functional network interface:

connect(4, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("8.8.8.8")}, 16) = -1 NETUNREACH (Network is unreachable)

To answer your specific question, when a userspace process asks the kernel to send data to a remote system when there is no networking subsystem available, it gets back an error appropriate to the situation. Note the absence of any query about whether the network is available; the userspace program goes right ahead and asks for connectivity, but gets an immediate error because the kernel knows it can't be satisfied. It's no different from trying to write a file on a file system that is out of space (error 28, no space left on device) or when you've exceeded your disk quota (error 122, disk quota exceeded) (error codes gratefully taken from here).

Edit: I rather suspected your next question would be "how do I return this error on a case-by-case basis", but I thought it sensible to let you ask it anyway. As you have already been told on several occasions, the best way to do this is with iptables -j REJECT, since the resulting error will propagate back to the requesting process in exactly the same way. Here's an example on the same system with the network up, but a single iptables -I OUTPUT 1 -j REJECT rule prohibiting all OUTPUT traffic (NB this is not a good idea in real life):

sendmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(0), sin_add=inet_addr("8.8.8.8")}, msg_iov(1)=[{"...."..., 64}], msg_controlln=0, msg_flags=0}, 0) = -1 EPERM (Operation not permitted)

With different invocations of -j REJECT --reject-with ... different errors are passed back to the requesting process, but all result in an error being passed back.

Edit 2: Your mental model of the UNIX networking stack is simply wrong, and the ideas you have formed from it are faulty; specifically iptables is the kernel(*). Part of the problem may be that some programs ignore some errors, some note them but continue, and some terminate. It is up for any given program to decide what it will do on any given error. The ping program, for example, terminates on ENETUNREACH, but on EPERM it merely logs an error to stderr and continues. If I understand correctly, this is the behaviour to which you are objecting.

This is not something you can control unless you are writing the program. I understand you would like the kernel to send an error that the software doesn't ignore, but the kernel isn't (as things stand) going to do that for you. Nothing stops you writing a modified kernel that signals all errors with SIGKILL, but Linux doesn't currently do that, and most of us wouldn't want it to.

(*) To be precise, iptables is the userspace program that lets us manipulate the netfilter structures inside the kernel. But the packet and error handling that results is most definitely a kernel-space phenomenon, not a user-space one.