3 #include <sys/ioc_net.h>
4 #include <net/gen/in.h>
5 #include <net/gen/ip_io.h>
8 #include <lwip/ip_addr.h>
10 #include <minix/netsock.h>
13 #define RAW_IP_BUF_SIZE (32 << 10)
15 #define sock_alloc_buf(s) debug_malloc(s)
16 #define sock_free_buf(x) debug_free(x)
18 struct raw_ip_recv_data
{
23 #define raw_ip_recv_alloc() debug_malloc(sizeof(struct raw_ip_recv_data))
25 static void raw_ip_recv_free(void * data
)
27 if (((struct raw_ip_recv_data
*)data
)->pbuf
)
28 pbuf_free(((struct raw_ip_recv_data
*)data
)->pbuf
);
33 static int raw_ip_op_open(struct socket
* sock
)
35 debug_print("socket num %ld", get_sock_num(sock
));
37 if (!(sock
->buf
= sock_alloc_buf(RAW_IP_BUF_SIZE
))) {
40 sock
->buf_size
= RAW_IP_BUF_SIZE
;
45 static void raw_ip_close(struct socket
* sock
)
47 /* deque and free all enqueued data before closing */
48 sock_dequeue_data_all(sock
, raw_ip_recv_free
);
51 raw_remove(sock
->pcb
);
53 sock_free_buf(sock
->buf
);
55 /* mark it as unused */
59 static int raw_ip_op_close(struct socket
* sock
)
61 debug_print("socket num %ld", get_sock_num(sock
));
68 static int raw_ip_do_receive(struct sock_req
*req
,
72 size_t rem_len
= req
->size
;
73 unsigned int written
= 0, hdr_sz
= 0;
76 debug_print("user buffer size : %u\n", rem_len
);
78 for (p
= pbuf
; p
&& rem_len
; p
= p
->next
) {
81 cp_len
= (rem_len
< p
->len
) ? rem_len
: p
->len
;
82 err
= copy_to_user(req
->endpt
, p
->payload
, cp_len
, req
->grant
,
92 debug_print("copied %d bytes\n", written
+ hdr_sz
);
93 return written
+ hdr_sz
;
96 static u8_t
raw_ip_op_receive(void *arg
,
97 __unused
struct raw_pcb
*pcb
,
101 struct socket
* sock
= (struct socket
*) arg
;
102 struct raw_ip_recv_data
* data
;
105 debug_print("socket num : %ld addr : %x\n",
106 get_sock_num(sock
), (unsigned int) addr
->addr
);
108 if (sock
->flags
& SOCK_FLG_OP_PENDING
) {
109 /* we are resuming a suspended operation */
110 ret
= raw_ip_do_receive(&sock
->req
, pbuf
);
112 send_req_reply(&sock
->req
, ret
);
113 sock
->flags
&= ~SOCK_FLG_OP_PENDING
;
116 if (sock
->usr_flags
& NWIO_EXCL
) {
124 /* Do not enqueue more data than allowed */
125 if (sock
->recv_data_size
> RAW_IP_BUF_SIZE
)
129 * nobody is waiting for the data or an error occured above, we enqueue
132 if (!(data
= raw_ip_recv_alloc())) {
137 if (sock
->usr_flags
& NWIO_EXCL
) {
141 /* we store a copy of this packet */
142 data
->pbuf
= pbuf_alloc(PBUF_RAW
, pbuf
->tot_len
, PBUF_RAM
);
143 if (data
->pbuf
== NULL
) {
144 debug_print("LWIP : cannot allocated new pbuf\n");
145 raw_ip_recv_free(data
);
149 if (pbuf_copy(data
->pbuf
, pbuf
) != ERR_OK
) {
150 debug_print("LWIP : cannot copy pbuf\n");
151 raw_ip_recv_free(data
);
159 * If we didn't managed to enqueue the packet we report it as not
162 if (sock_enqueue_data(sock
, data
, data
->pbuf
->tot_len
) != OK
) {
163 raw_ip_recv_free(data
);
170 static int raw_ip_op_read(struct socket
* sock
, struct sock_req
* req
, int blk
)
172 debug_print("socket num %ld", get_sock_num(sock
));
174 if (sock
->pcb
== NULL
)
177 if (sock
->recv_head
) {
178 /* data available receive immeditely */
180 struct raw_ip_recv_data
* data
;
183 data
= (struct raw_ip_recv_data
*) sock
->recv_head
->data
;
185 ret
= raw_ip_do_receive(req
, data
->pbuf
);
188 sock_dequeue_data(sock
);
189 sock
->recv_data_size
-= data
->pbuf
->tot_len
;
190 raw_ip_recv_free(data
);
196 /* store the request so we know how to reply */
198 /* operation is being processes */
199 sock
->flags
|= SOCK_FLG_OP_PENDING
;
201 debug_print("no data to read, suspending");
206 static int raw_ip_op_write(struct socket
* sock
, struct sock_req
* req
,
211 struct ip_hdr
* ip_hdr
;
213 debug_print("socket num %ld data size %u",
214 get_sock_num(sock
), req
->size
);
216 if (sock
->pcb
== NULL
)
219 if (req
->size
> sock
->buf_size
)
222 pbuf
= pbuf_alloc(PBUF_LINK
, req
->size
, PBUF_RAM
);
226 if ((ret
= copy_from_user(req
->endpt
, pbuf
->payload
, req
->size
,
227 req
->grant
, 0)) != OK
) {
232 ip_hdr
= (struct ip_hdr
*) pbuf
->payload
;
233 if (pbuf_header(pbuf
, -IP_HLEN
)) {
238 if ((ret
= raw_sendto((struct raw_pcb
*)sock
->pcb
, pbuf
,
239 (ip_addr_t
*) &ip_hdr
->dest
)) != OK
) {
240 debug_print("raw_sendto failed %d", ret
);
251 static int raw_ip_set_opt(struct socket
* sock
, endpoint_t endpt
,
256 struct raw_pcb
* pcb
;
258 err
= copy_from_user(endpt
, &ipopt
, sizeof(ipopt
), grant
, 0);
263 debug_print("ipopt.nwio_flags = 0x%x", ipopt
.nwio_flags
);
264 debug_print("ipopt.nwio_proto = 0x%x", ipopt
.nwio_proto
);
265 debug_print("ipopt.nwio_rem = 0x%x",
266 (unsigned int) ipopt
.nwio_rem
);
268 if (sock
->pcb
== NULL
) {
269 if (!(pcb
= raw_new(ipopt
.nwio_proto
))) {
276 pcb
= (struct raw_pcb
*) sock
->pcb
;
278 if (pcb
->protocol
!= ipopt
.nwio_proto
) {
279 debug_print("conflicting ip socket protocols\n");
283 sock
->usr_flags
= ipopt
.nwio_flags
;
286 if (raw_bind(pcb
, (ip_addr_t
*)&ipopt
.nwio_rem
) == ERR_USE
) {
292 /* register a receive hook */
293 raw_recv((struct raw_pcb
*) sock
->pcb
, raw_ip_op_receive
, sock
);
298 static int raw_ip_get_opt(struct socket
* sock
, endpoint_t endpt
,
302 struct raw_pcb
* pcb
= (struct raw_pcb
*) sock
->pcb
;
306 ipopt
.nwio_rem
= pcb
->remote_ip
.addr
;
307 ipopt
.nwio_flags
= sock
->usr_flags
;
309 return copy_to_user(endpt
, &ipopt
, sizeof(ipopt
), grant
, 0);
312 static int raw_ip_op_ioctl(struct socket
* sock
, struct sock_req
* req
,
317 debug_print("socket num %ld req %c %ld %ld",
319 (unsigned char) (req
->req
>> 8),
321 _MINIX_IOCTL_SIZE(req
->req
));
325 r
= raw_ip_set_opt(sock
, req
->endpt
, req
->grant
);
328 r
= raw_ip_get_opt(sock
, req
->endpt
, req
->grant
);
332 * /dev/ip can be also accessed as a default device to be
335 r
= nic_default_ioctl(req
);
341 struct sock_ops sock_raw_ip_ops
= {
342 .open
= raw_ip_op_open
,
343 .close
= raw_ip_op_close
,
344 .read
= raw_ip_op_read
,
345 .write
= raw_ip_op_write
,
346 .ioctl
= raw_ip_op_ioctl
,
347 .select
= generic_op_select
,
348 .select_reply
= generic_op_select_reply