Home | History | Annotate | Download | only in gpxe
      1 #ifndef _GPXE_RESOLV_H
      2 #define _GPXE_RESOLV_H
      3 
      4 /** @file
      5  *
      6  * Name resolution
      7  *
      8  */
      9 
     10 FILE_LICENCE ( GPL2_OR_LATER );
     11 
     12 #include <gpxe/refcnt.h>
     13 #include <gpxe/interface.h>
     14 #include <gpxe/tables.h>
     15 #include <gpxe/socket.h>
     16 
     17 struct resolv_interface;
     18 
     19 /** Name resolution interface operations */
     20 struct resolv_interface_operations {
     21 	/** Name resolution completed
     22 	 *
     23 	 * @v resolv		Name resolution interface
     24 	 * @v sa		Completed socket address (if successful)
     25 	 * @v rc		Final status code
     26 	 */
     27 	void ( * done ) ( struct resolv_interface *resolv,
     28 			  struct sockaddr *sa, int rc );
     29 };
     30 
     31 /** A name resolution interface */
     32 struct resolv_interface {
     33 	/** Generic object communication interface */
     34 	struct interface intf;
     35 	/** Operations for received messages */
     36 	struct resolv_interface_operations *op;
     37 };
     38 
     39 extern struct resolv_interface null_resolv;
     40 extern struct resolv_interface_operations null_resolv_ops;
     41 
     42 /**
     43  * Initialise a name resolution interface
     44  *
     45  * @v resolv		Name resolution interface
     46  * @v op		Name resolution interface operations
     47  * @v refcnt		Containing object reference counter, or NULL
     48  */
     49 static inline void resolv_init ( struct resolv_interface *resolv,
     50 				 struct resolv_interface_operations *op,
     51 				 struct refcnt *refcnt ) {
     52 	resolv->intf.dest = &null_resolv.intf;
     53 	resolv->intf.refcnt = refcnt;
     54 	resolv->op = op;
     55 }
     56 
     57 /**
     58  * Get name resolution interface from generic object communication interface
     59  *
     60  * @v intf		Generic object communication interface
     61  * @ret resolv		Name resolution interface
     62  */
     63 static inline __attribute__ (( always_inline )) struct resolv_interface *
     64 intf_to_resolv ( struct interface *intf ) {
     65 	return container_of ( intf, struct resolv_interface, intf );
     66 }
     67 
     68 /**
     69  * Get reference to destination name resolution interface
     70  *
     71  * @v resolv		Name resolution interface
     72  * @ret dest		Destination interface
     73  */
     74 static inline __attribute__ (( always_inline )) struct resolv_interface *
     75 resolv_get_dest ( struct resolv_interface *resolv ) {
     76 	return intf_to_resolv ( intf_get ( resolv->intf.dest ) );
     77 }
     78 
     79 /**
     80  * Drop reference to name resolution interface
     81  *
     82  * @v resolv		name resolution interface
     83  */
     84 static inline __attribute__ (( always_inline )) void
     85 resolv_put ( struct resolv_interface *resolv ) {
     86 	intf_put ( &resolv->intf );
     87 }
     88 
     89 /**
     90  * Plug a name resolution interface into a new destination interface
     91  *
     92  * @v resolv		Name resolution interface
     93  * @v dest		New destination interface
     94  */
     95 static inline __attribute__ (( always_inline )) void
     96 resolv_plug ( struct resolv_interface *resolv, struct resolv_interface *dest ) {
     97 	plug ( &resolv->intf, &dest->intf );
     98 }
     99 
    100 /**
    101  * Plug two name resolution interfaces together
    102  *
    103  * @v a			Name resolution interface A
    104  * @v b			Name resolution interface B
    105  */
    106 static inline __attribute__ (( always_inline )) void
    107 resolv_plug_plug ( struct resolv_interface *a, struct resolv_interface *b ) {
    108 	plug_plug ( &a->intf, &b->intf );
    109 }
    110 
    111 /**
    112  * Unplug a name resolution interface
    113  *
    114  * @v resolv		Name resolution interface
    115  */
    116 static inline __attribute__ (( always_inline )) void
    117 resolv_unplug ( struct resolv_interface *resolv ) {
    118 	plug ( &resolv->intf, &null_resolv.intf );
    119 }
    120 
    121 /**
    122  * Stop using a name resolution interface
    123  *
    124  * @v resolv		Name resolution interface
    125  *
    126  * After calling this method, no further messages will be received via
    127  * the interface.
    128  */
    129 static inline void resolv_nullify ( struct resolv_interface *resolv ) {
    130 	resolv->op = &null_resolv_ops;
    131 };
    132 
    133 /** A name resolver */
    134 struct resolver {
    135 	/** Name of this resolver (e.g. "DNS") */
    136 	const char *name;
    137 	/** Start name resolution
    138 	 *
    139 	 * @v resolv		Name resolution interface
    140 	 * @v name		Name to resolve
    141 	 * @v sa		Socket address to complete
    142 	 * @ret rc		Return status code
    143 	 */
    144 	int ( * resolv ) ( struct resolv_interface *resolv, const char *name,
    145 			   struct sockaddr *sa );
    146 };
    147 
    148 /** Numeric resolver priority */
    149 #define RESOLV_NUMERIC 01
    150 
    151 /** Normal resolver priority */
    152 #define RESOLV_NORMAL 02
    153 
    154 /** Resolvers table */
    155 #define RESOLVERS __table ( struct resolver, "resolvers" )
    156 
    157 /** Register as a name resolver */
    158 #define __resolver( resolv_order ) __table_entry ( RESOLVERS, resolv_order )
    159 
    160 extern void resolv_done ( struct resolv_interface *resolv,
    161 			  struct sockaddr *sa, int rc );
    162 extern void ignore_resolv_done ( struct resolv_interface *resolv,
    163 			  struct sockaddr *sa, int rc );
    164 extern struct resolv_interface_operations null_resolv_ops;
    165 extern struct resolv_interface null_resolv;
    166 
    167 extern int resolv ( struct resolv_interface *resolv, const char *name,
    168 		    struct sockaddr *sa );
    169 
    170 #endif /* _GPXE_RESOLV_H */
    171