def main():
    """Main function called upon script execution."""
    # First open a socket to the kernel. Same one used for sending and receiving.
    sk = nl_socket_alloc()  # Creates an `nl_sock` instance.
    ret = nl_connect(sk, NETLINK_ROUTE)  # Create file descriptor and bind socket.
    if ret < 0:
        reason = errmsg[abs(ret)]
        return error('nl_connect() returned {0} ({1})'.format(ret, reason))

    # Next we send the request to the kernel.
    rt_hdr = rtgenmsg(rtgen_family=socket.AF_PACKET)
    ret = nl_send_simple(sk, RTM_GETLINK, NLM_F_REQUEST | NLM_F_DUMP, rt_hdr, rt_hdr.SIZEOF)
    if ret < 0:
        reason = errmsg[abs(ret)]
        return error('nl_send_simple() returned {0} ({1})'.format(ret, reason))
    print('Sent {0} bytes to the kernel.'.format(ret))

    # Finally we'll retrieve the kernel's answer, process it, and call any callbacks attached to the `nl_sock` instance.
    nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, callback, None)  # Add callback to the `nl_sock` instance.
    ret = nl_recvmsgs_default(sk)  # Get kernel's answer, and call attached callbacks.
    if ret < 0:
        reason = errmsg[abs(ret)]
        return error('nl_recvmsgs_default() returned {0} ({1})'.format(ret, reason))