6 Created: June 1995 by Philip Homburg <philip@f-mnx.phicoh.com>
10 #include "generic/assert.h"
12 #include <sys/svrctl.h>
13 #include "queryparam.h"
15 #include "generic/buf.h"
16 #include "generic/clock.h"
17 #include "generic/event.h"
18 #include "generic/type.h"
19 #include "generic/sr.h"
21 #include "generic/tcp_int.h"
22 #include "generic/udp_int.h"
29 #define MAX_REQ 1024 /* Maximum size of a request */
37 get_userdata_t qf_get_userdata
;
38 put_userdata_t qf_put_userdata
;
45 static qp_fd_t qp_fd_table
[QP_FD_NR
];
47 static struct export_param_list inet_ex_list
[]=
49 QP_VARIABLE(sr_fd_table
),
51 QP_VARIABLE(tcp_fd_table
),
52 QP_VARIABLE(tcp_conn_table
),
53 QP_VARIABLE(tcp_cancel_f
),
54 QP_VECTOR(udp_port_table
, udp_port_table
, ip_conf_nr
),
55 QP_VARIABLE(udp_fd_table
),
59 static struct export_params inet_ex_params
= { inet_ex_list
, NULL
};
61 static struct queryvars
{
76 static int qp_open
ARGS(( int port
, int srfd
,
77 get_userdata_t get_userdata
, put_userdata_t put_userdata
,
78 put_pkt_t put_pkt
, select_res_t select_res
));
79 static void qp_close
ARGS(( int fd
));
80 static int qp_read
ARGS(( int fd
, size_t count
));
81 static int qp_write
ARGS(( int fd
, size_t count
));
82 static int qp_ioctl
ARGS(( int fd
, ioreq_t req
));
83 static int qp_cancel
ARGS(( int fd
, int which_operation
));
84 static int qp_select
ARGS(( int fd
, unsigned operations
));
85 static qp_fd_t
*get_qp_fd
ARGS(( int fd
));
86 static int do_query
ARGS(( qp_fd_t
*qp_fd
, acc_t
*pkt
, int count
));
87 static int qp_getc
ARGS(( void ));
88 static void qp_putc
ARGS(( struct queryvars
*qv
, int c
));
89 static void qp_buffree
ARGS(( int priority
));
90 #ifdef BUF_CONSISTENCY_CHECK
91 static void qp_bufcheck
ARGS(( void ));
98 qp_export(&inet_ex_params
);
100 for (i
= 0; i
<QP_FD_NR
; i
++)
101 qp_fd_table
[i
].qf_flags
= QFF_EMPTY
;
103 #ifndef BUF_CONSISTENCY_CHECK
104 bf_logon(qp_buffree
);
106 bf_logon(qp_buffree
, qp_bufcheck
);
109 sr_add_minor(IPSTAT_MINOR
, 0, qp_open
, qp_close
, qp_read
, qp_write
,
110 qp_ioctl
, qp_cancel
, qp_select
);
113 static int qp_open(port
, srfd
, get_userdata
, put_userdata
, put_pkt
,
117 get_userdata_t get_userdata
;
118 put_userdata_t put_userdata
;
120 select_res_t select_res
;
125 for (i
= 0; i
< QP_FD_NR
; i
++)
127 if (!(qp_fd_table
[i
].qf_flags
& QFF_INUSE
))
132 qp_fd
= &qp_fd_table
[i
];
133 qp_fd
->qf_flags
= QFF_INUSE
;
134 qp_fd
->qf_srfd
= srfd
;
135 qp_fd
->qf_get_userdata
= get_userdata
;
136 qp_fd
->qf_put_userdata
= put_userdata
;
137 qp_fd
->qf_req_pkt
= NULL
;
142 static void qp_close(fd
)
147 qp_fd
= get_qp_fd(fd
);
148 qp_fd
->qf_flags
= QFF_EMPTY
;
149 if (qp_fd
->qf_req_pkt
)
151 bf_afree(qp_fd
->qf_req_pkt
);
152 qp_fd
->qf_req_pkt
= NULL
;
156 static int qp_read(fd
, count
)
164 qp_fd
= get_qp_fd(fd
);
165 pkt
= qp_fd
->qf_req_pkt
;
166 qp_fd
->qf_req_pkt
= NULL
;
170 qp_fd
->qf_put_userdata(qp_fd
->qf_srfd
, EIO
, 0,
171 FALSE
/* !for_ioctl*/);
174 r
= do_query(qp_fd
, pkt
, count
);
175 qp_fd
->qf_put_userdata(qp_fd
->qf_srfd
, r
, 0,
176 FALSE
/* !for_ioctl*/);
180 static int qp_write(fd
, count
)
187 qp_fd
= get_qp_fd(fd
);
190 qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, ENOMEM
, 0,
191 FALSE
/* !for_ioctl*/);
194 pkt
= qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, 0, count
,
195 FALSE
/* !for_ioctl*/);
198 qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, EFAULT
, 0,
199 FALSE
/* !for_ioctl*/);
202 if (qp_fd
->qf_req_pkt
)
204 bf_afree(qp_fd
->qf_req_pkt
);
205 qp_fd
->qf_req_pkt
= NULL
;
207 qp_fd
->qf_req_pkt
= pkt
;
208 qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, count
, 0,
209 FALSE
/* !for_ioctl*/);
213 static int qp_ioctl(fd
, req
)
219 qp_fd
= get_qp_fd(fd
);
220 qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, ENOTTY
, 0,
221 TRUE
/* for_ioctl*/);
225 static int qp_cancel(fd
, which_operation
)
229 ip_panic(( "qp_cancel: should not be here, no blocking calls" ));
233 static int qp_select(fd
, operations
)
240 if (operations
& SR_SELECT_READ
)
241 resops
|= SR_SELECT_READ
;
242 if (operations
& SR_SELECT_WRITE
)
243 resops
|= SR_SELECT_WRITE
;
247 static qp_fd_t
*get_qp_fd(fd
)
252 assert(fd
>= 0 && fd
< QP_FD_NR
);
253 qp_fd
= &qp_fd_table
[fd
];
254 assert(qp_fd
->qf_flags
& QFF_INUSE
);
258 static int do_query(qp_fd
, pkt
, count
)
268 static char hex
[]= "0123456789ABCDEF";
271 qv
.param
= pkt
; pkt
= NULL
;
275 qv
.rd_bytes_left
= count
;
279 more
= queryparam(qp_getc
, &addr
, &size
);
280 for (n
= 0; n
< size
; n
++) {
281 byte
= ((u8_t
*) addr
)[n
];
282 qp_putc(&qv
, hex
[byte
>> 4]);
283 qp_putc(&qv
, hex
[byte
& 0x0F]);
285 qp_putc(&qv
, more
? ',' : 0);
302 /* Return one character of the names to search for. */
304 struct queryvars
*qv
= qvars
;
312 assert(bf_bufsize(pkt
) > 0);
313 c
= ptr2acc_data(pkt
)[0];
314 if (bf_bufsize(pkt
) > 1)
315 qv
->param
= bf_delhead(pkt
, 1);
325 static void qp_putc(qv
, c
)
326 struct queryvars
*qv
;
329 /* Send one character back to the user. */
335 bytes_left
= qv
->rd_bytes_left
;
336 if (qv
->r
|| bytes_left
== 0)
340 assert(off
< sizeof(qv
->outbuf
));
344 qv
->rd_bytes_left
= bytes_left
;
345 if (c
!= '\0' && off
< sizeof(qv
->outbuf
) && bytes_left
!= 0)
352 assert(pkt
->acc_next
== NULL
);
353 memcpy(ptr2acc_data(pkt
), qv
->outbuf
, off
);
355 qv
->r
= qp_fd
->qf_put_userdata(qp_fd
->qf_srfd
, qv
->fd_offset
,
356 pkt
, FALSE
/* !for_ioctl*/ );
357 qv
->fd_offset
+= off
;
361 static void qp_buffree (priority
)
364 /* For the moment, we are not going to free anything */
367 #ifdef BUF_CONSISTENCY_CHECK
368 static void qp_bufcheck()
373 for (i
= 0, qp_fd
= qp_fd_table
; i
<QP_FD_NR
; i
++, qp_fd
++)
375 if (!(qp_fd
->qf_flags
& QFF_INUSE
))
377 if (qp_fd
->qf_req_pkt
)
378 bf_check_acc(qp_fd
->qf_req_pkt
);
384 * $PchId: qp.c,v 1.7 2005/06/28 14:25:25 philip Exp $