• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
resolv_init(struct resolv_interface * resolv,struct resolv_interface_operations * op,struct refcnt * refcnt)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 *
intf_to_resolv(struct interface * intf)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 *
resolv_get_dest(struct resolv_interface * resolv)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
resolv_put(struct resolv_interface * resolv)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
resolv_plug(struct resolv_interface * resolv,struct resolv_interface * dest)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
resolv_plug_plug(struct resolv_interface * a,struct resolv_interface * b)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
resolv_unplug(struct resolv_interface * resolv)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  */
resolv_nullify(struct resolv_interface * resolv)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