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