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