#ifndef _GPXE_RESOLV_H #define _GPXE_RESOLV_H /** @file * * Name resolution * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct resolv_interface; /** Name resolution interface operations */ struct resolv_interface_operations { /** Name resolution completed * * @v resolv Name resolution interface * @v sa Completed socket address (if successful) * @v rc Final status code */ void ( * done ) ( struct resolv_interface *resolv, struct sockaddr *sa, int rc ); }; /** A name resolution interface */ struct resolv_interface { /** Generic object communication interface */ struct interface intf; /** Operations for received messages */ struct resolv_interface_operations *op; }; extern struct resolv_interface null_resolv; extern struct resolv_interface_operations null_resolv_ops; /** * Initialise a name resolution interface * * @v resolv Name resolution interface * @v op Name resolution interface operations * @v refcnt Containing object reference counter, or NULL */ static inline void resolv_init ( struct resolv_interface *resolv, struct resolv_interface_operations *op, struct refcnt *refcnt ) { resolv->intf.dest = &null_resolv.intf; resolv->intf.refcnt = refcnt; resolv->op = op; } /** * Get name resolution interface from generic object communication interface * * @v intf Generic object communication interface * @ret resolv Name resolution interface */ static inline __attribute__ (( always_inline )) struct resolv_interface * intf_to_resolv ( struct interface *intf ) { return container_of ( intf, struct resolv_interface, intf ); } /** * Get reference to destination name resolution interface * * @v resolv Name resolution interface * @ret dest Destination interface */ static inline __attribute__ (( always_inline )) struct resolv_interface * resolv_get_dest ( struct resolv_interface *resolv ) { return intf_to_resolv ( intf_get ( resolv->intf.dest ) ); } /** * Drop reference to name resolution interface * * @v resolv name resolution interface */ static inline __attribute__ (( always_inline )) void resolv_put ( struct resolv_interface *resolv ) { intf_put ( &resolv->intf ); } /** * Plug a name resolution interface into a new destination interface * * @v resolv Name resolution interface * @v dest New destination interface */ static inline __attribute__ (( always_inline )) void resolv_plug ( struct resolv_interface *resolv, struct resolv_interface *dest ) { plug ( &resolv->intf, &dest->intf ); } /** * Plug two name resolution interfaces together * * @v a Name resolution interface A * @v b Name resolution interface B */ static inline __attribute__ (( always_inline )) void resolv_plug_plug ( struct resolv_interface *a, struct resolv_interface *b ) { plug_plug ( &a->intf, &b->intf ); } /** * Unplug a name resolution interface * * @v resolv Name resolution interface */ static inline __attribute__ (( always_inline )) void resolv_unplug ( struct resolv_interface *resolv ) { plug ( &resolv->intf, &null_resolv.intf ); } /** * Stop using a name resolution interface * * @v resolv Name resolution interface * * After calling this method, no further messages will be received via * the interface. */ static inline void resolv_nullify ( struct resolv_interface *resolv ) { resolv->op = &null_resolv_ops; }; /** A name resolver */ struct resolver { /** Name of this resolver (e.g. "DNS") */ const char *name; /** Start name resolution * * @v resolv Name resolution interface * @v name Name to resolve * @v sa Socket address to complete * @ret rc Return status code */ int ( * resolv ) ( struct resolv_interface *resolv, const char *name, struct sockaddr *sa ); }; /** Numeric resolver priority */ #define RESOLV_NUMERIC 01 /** Normal resolver priority */ #define RESOLV_NORMAL 02 /** Resolvers table */ #define RESOLVERS __table ( struct resolver, "resolvers" ) /** Register as a name resolver */ #define __resolver( resolv_order ) __table_entry ( RESOLVERS, resolv_order ) extern void resolv_done ( struct resolv_interface *resolv, struct sockaddr *sa, int rc ); extern void ignore_resolv_done ( struct resolv_interface *resolv, struct sockaddr *sa, int rc ); extern struct resolv_interface_operations null_resolv_ops; extern struct resolv_interface null_resolv; extern int resolv ( struct resolv_interface *resolv, const char *name, struct sockaddr *sa ); #endif /* _GPXE_RESOLV_H */