def get_node_attrs(source, caller, callee, defenses, vulnerabilities):
    """Return node attributes.

    Parameters
    ----------

    Returns
    -------
    attributes : tuple
        A tuple of two dictionary elements: caller_attrs and callee_attrs. The
        callee_attrs may be None if the callee is a standard library function.
        Each dictionary may contain the following keys:

        Common Keys:

        tested: True if the node is tested, False otherwise.
        defense: Set if the node represents a function which is a designed
            defense in the system.
        vulnerable: Set if the node represents a vulnerable function in the
            system.

        Caller-specific Keys:

        dangerous: Set if the callee is a dangerous system function.
        entry: Set if the callee is an standard input function.
        exit: Set if the callee is a standard output function.
    """
    caller_attrs = dict()
    callee_attrs = None
    if caller in defenses:
        caller_attrs['defense'] = None
    if caller in vulnerabilities:
        caller_attrs['vulnerable'] = None
    if callee is not None:
        if 'gprof' in source:
            caller_attrs['tested'] = None
        if callee.in_stdlib():
            if callee.is_dangerous():
                caller_attrs['dangerous'] = None
            if callee.is_input():
                caller_attrs['entry'] = None
            if callee.is_output():
                caller_attrs['exit'] = None
        else:
            callee_attrs = dict()
            callee_attrs['frequency'] = 1
            if 'gprof' in source:
                callee_attrs['tested'] = None
            if callee in defenses:
                callee_attrs['defense'] = None
            if callee in vulnerabilities:
                callee_attrs['vulnerable'] = None
    attributes = caller_attrs, callee_attrs
    return attributes
