/**
* This module implements the higher layer, which wraps {@link RawNetlinkSocket}
* and lets the user send / receive parsed Netlink messages, rather than
* raw data. It can also take care of things like requests & ACKs,
* sequence numbers, multipart message handling, attribute parsing.
* @module
*/
///
import { EventEmitter } from 'events';
import { RawNetlinkSocket, RawNetlinkSocketOptions, RawNetlinkSendOptions, MessageInfo, ErrnoException } from './raw';
import { NetlinkMessage } from './structs';
export interface NetlinkSocketOptions {
/**
* If true, the event loop will not exit while the socket is
* is open (default: false). You should set this to true if
* you need to listen for notifications. See the {@link NetlinkSocket.ref} method.
*/
ref?: boolean;
}
export interface NetlinkSendOptions extends RawNetlinkSendOptions {
/**
* Message flags (default: 0, i.e. no flags)
*/
flags?: number;
/**
* Sequence number (default: generated with {@link NetlinkSocket.generateSeq})
*/
seq?: number;
/**
* Local port included in message header (default: socket address)
*/
localPort?: number;
}
export interface RequestOptions {
/** Timeout in ms (default: no timeout) */
timeout?: number;
/** Whether to reject the promise on ERROR message (default: true) */
checkError?: boolean;
}
interface EventMap {
invalid(err: any, msg: Buffer | NetlinkMessage[], rinfo: MessageInfo): void;
message(msg: NetlinkMessage[], rinfo: MessageInfo): void;
truncatedMessage(msg: Buffer, rinfo: MessageInfo): void;
error(err: ErrnoException): void;
close(): void;
}
/**
* TODO
*
* This socket silently discards invalid messages (see `invalid` event).
* FIXME: cork / uncork api
* FIXME: debug option, common for all sockets
*/
export declare class NetlinkSocket extends EventEmitter {
emit(event: E, ...args: Parameters): boolean;
on(event: E, listener: EventMap[E]): this;
once(event: E, listener: EventMap[E]): this;
off(event: E, listener: EventMap[E]): this;
addListener(event: E, listener: EventMap[E]): this;
removeListener(event: E, listener: EventMap[E]): this;
readonly socket: RawNetlinkSocket;
seq: number;
protected referenced: boolean;
protected requests: Map any>;
protected multipartMessage?: NetlinkMessage[];
constructor(socket: RawNetlinkSocket, options?: NetlinkSocketOptions);
private _receive;
/**
* Handles zero or more messages received over the socket,
* doing multipart grouping and calling {@link emitMessage} as
* appropriate.
*/
protected handleMessages(msgs: NetlinkMessage[], rinfo: MessageInfo): void;
/**
* Close the Netlink socket. After this, all other methods
* can no longer be called. Messages pending to be sent
* will be discarded, and its completion callback won't be
* called.
*/
close(): void;
/**
* Return the address this socket is currently bound at.
*
* @returns Local address
*/
address(): {
port: number;
groups: number;
};
/**
* Generate a unique sequence number to use in a message
*/
generateSeq(): number;
/**
* Send a Netlink message over the socket, addressed as
* the options indicate. By default, the sequence number
* and port will be filled automatically.
*
* @param type Message type
* @param data Message payload
* @param options Message send options
* @param callback Callback will be called after
* the message has been sent (or failed to be sent)
*
* @returns The sequence number of the sent message
*/
send(type: number, data: Uint8Array | Uint8Array[], options?: NetlinkSendOptions, callback?: (error?: ErrnoException) => void): number;
/**
* Sends a message with the REQUEST and ACK flags set,
* and waits for a reply for the same sequence number.
*
* Note that this method doesn't check the origin of
* the reply, you should do that yourself.
*
* An array of mesages is returned. This will contain
* many items for multipart messages, zero if an ACK
* is received (and `checkError` isn't disabled) and
* one for other messages.
*
* @param type Message type
* @param data Message payload
* @param options Options
* @returns Promise that resolves with `[msg, rinfo]` of
* the received message. The promise rejects if the message
* coudln't be sent or if the timeout expires. If
* `checkError` isn't disabled, the promise will also
* reject if an ERROR message is received.
*/
request(type: number, data: Uint8Array | Uint8Array[], options?: NetlinkSendOptions & RequestOptions): Promise<[NetlinkMessage[], MessageInfo]>;
/**
* If true is passed, the socket will be kept referenced
* (preventing the event loop from exiting) even when there
* are no pending messages. Otherwise, the socket will be
* dereferenced when there are no pending messages.
*
* @param ref Socket ref state
*/
ref(ref?: boolean): void;
protected makeRef(seq: number, callback: (err: Error | null, msg?: NetlinkMessage[], rinfo?: MessageInfo) => void): number;
/**
* This method must, if the message is multipart, separate the
* last DONE message from the rest (if there's no DONE message
* this is considered an error).
*
* Then, if the message is a reply and its sequence number has an
* associated (i.e. request) callback, call it.
* Otherwise, a 'message' or 'invalid' event is emitted.
*
* @param msg Single message object, or array of messages for
* multipart messages.
*/
protected emitMessage(msg: NetlinkMessage | NetlinkMessage[], rinfo: MessageInfo): any;
protected dropRef(seq: number): void;
/** Equivalent to `socket.ref(false)`, see {@link ref} */
unref(): void;
/** Joins the specified multicast group */
addMembership(group: number): void;
/** Leaves the specified multicast group */
dropMembership(group: number): void;
/** Returns the `SO_RCVBUF` socket receive buffer size in bytes */
getRecvBufferSize(): number;
/** Returns the `SO_SNDBUF` socket send buffer size in bytes */
getSendBufferSize(): number;
/** Sets the `SO_RCVBUF` socket option. Sets the maximum socket receive buffer in bytes. */
setRecvBufferSize(size: number): any;
/** Sets the `SO_SNDBUF` socket option. Sets the maximum socket send buffer in bytes. */
setSendBufferSize(size: number): any;
}
/**
* Checks if the passed message is an ERROR message.
* If it is, an error will be thrown. If it's an ACK
* (aka error = 0) then `true` is returned. Otherwise
* nothing is returned.
*
* @param x Message to check
*/
export declare function checkError(x: NetlinkMessage): true | undefined;
export declare function createNetlink(protocol: number, options?: NetlinkSocketOptions & RawNetlinkSocketOptions): NetlinkSocket;
export {};