phys addr arg of 0 must be possible for pt_writemap too (instead of meaning
[minix.git] / servers / inet / generic / ip.c
blob11771c987948c90f343bbce0e754041b2b292b3c
1 /*
2 ip.c
4 Copyright 1995 Philip Homburg
5 */
7 #include "inet.h"
8 #include "buf.h"
9 #include "event.h"
10 #include "type.h"
12 #include "arp.h"
13 #include "assert.h"
14 #include "clock.h"
15 #include "eth.h"
16 #include "icmp.h"
17 #include "icmp_lib.h"
18 #include "io.h"
19 #include "ip.h"
20 #include "ip_int.h"
21 #include "ipr.h"
22 #include "sr.h"
24 THIS_FILE
26 FORWARD void ip_close ARGS(( int fd ));
27 FORWARD int ip_cancel ARGS(( int fd, int which_operation ));
28 FORWARD int ip_select ARGS(( int fd, unsigned operations ));
30 FORWARD void ip_buffree ARGS(( int priority ));
31 #ifdef BUF_CONSISTENCY_CHECK
32 FORWARD void ip_bufcheck ARGS(( void ));
33 #endif
34 FORWARD void ip_bad_callback ARGS(( struct ip_port *ip_port ));
36 PUBLIC ip_port_t *ip_port_table;
37 PUBLIC ip_fd_t ip_fd_table[IP_FD_NR];
38 PUBLIC ip_ass_t ip_ass_table[IP_ASS_NR];
40 PUBLIC void ip_prep()
42 ip_port_table= alloc(ip_conf_nr * sizeof(ip_port_table[0]));
43 icmp_prep();
46 PUBLIC void ip_init()
48 int i, j, result;
49 ip_ass_t *ip_ass;
50 ip_fd_t *ip_fd;
51 ip_port_t *ip_port;
52 struct ip_conf *icp;
54 assert (BUF_S >= sizeof(struct nwio_ethopt));
55 assert (BUF_S >= IP_MAX_HDR_SIZE + ETH_HDR_SIZE);
56 assert (BUF_S >= sizeof(nwio_ipopt_t));
57 assert (BUF_S >= sizeof(nwio_route_t));
59 for (i=0, ip_ass= ip_ass_table; i<IP_ASS_NR; i++, ip_ass++)
61 ip_ass->ia_frags= 0;
62 ip_ass->ia_first_time= 0;
63 ip_ass->ia_port= 0;
66 for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
68 ip_fd->if_flags= IFF_EMPTY;
69 ip_fd->if_rdbuf_head= 0;
72 for (i=0, ip_port= ip_port_table, icp= ip_conf;
73 i<ip_conf_nr; i++, ip_port++, icp++)
75 ip_port->ip_port= i;
76 ip_port->ip_flags= IPF_EMPTY;
77 ip_port->ip_dev_main= (ip_dev_t)ip_bad_callback;
78 ip_port->ip_dev_set_ipaddr= (ip_dev_t)ip_bad_callback;
79 ip_port->ip_dev_send= (ip_dev_send_t)ip_bad_callback;
80 ip_port->ip_dl_type= icp->ic_devtype;
81 ip_port->ip_mtu= IP_DEF_MTU;
82 ip_port->ip_mtu_max= IP_MAX_PACKSIZE;
84 switch(ip_port->ip_dl_type)
86 case IPDL_ETH:
87 ip_port->ip_dl.dl_eth.de_port= icp->ic_port;
88 result= ipeth_init(ip_port);
89 if (result == -1)
90 continue;
91 assert(result == NW_OK);
92 break;
93 case IPDL_PSIP:
94 ip_port->ip_dl.dl_ps.ps_port= icp->ic_port;
95 result= ipps_init(ip_port);
96 if (result == -1)
97 continue;
98 assert(result == NW_OK);
99 break;
100 default:
101 ip_panic(( "unknown ip_dl_type %d",
102 ip_port->ip_dl_type ));
103 break;
105 ip_port->ip_loopb_head= NULL;
106 ip_port->ip_loopb_tail= NULL;
107 ev_init(&ip_port->ip_loopb_event);
108 ip_port->ip_routeq_head= NULL;
109 ip_port->ip_routeq_tail= NULL;
110 ev_init(&ip_port->ip_routeq_event);
111 ip_port->ip_flags |= IPF_CONFIGURED;
112 ip_port->ip_proto_any= NULL;
113 for (j= 0; j<IP_PROTO_HASH_NR; j++)
114 ip_port->ip_proto[j]= NULL;
117 #ifndef BUF_CONSISTENCY_CHECK
118 bf_logon(ip_buffree);
119 #else
120 bf_logon(ip_buffree, ip_bufcheck);
121 #endif
123 icmp_init();
124 ipr_init();
126 for (i=0, ip_port= ip_port_table; i<ip_conf_nr; i++, ip_port++)
128 if (!(ip_port->ip_flags & IPF_CONFIGURED))
129 continue;
130 ip_port->ip_frame_id= (u16_t)get_time();
132 sr_add_minor(if2minor(ip_conf[i].ic_ifno, IP_DEV_OFF),
133 i, ip_open, ip_close, ip_read,
134 ip_write, ip_ioctl, ip_cancel, ip_select);
136 (*ip_port->ip_dev_main)(ip_port);
140 PRIVATE int ip_cancel (fd, which_operation)
141 int fd;
142 int which_operation;
144 ip_fd_t *ip_fd;
145 acc_t *repl_res;
146 int result;
148 ip_fd= &ip_fd_table[fd];
150 switch (which_operation)
152 case SR_CANCEL_IOCTL:
153 assert (ip_fd->if_flags & IFF_IOCTL_IP);
154 ip_fd->if_flags &= ~IFF_IOCTL_IP;
155 repl_res= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,
156 (size_t)EINTR, (size_t)0, TRUE);
157 assert (!repl_res);
158 break;
159 case SR_CANCEL_READ:
160 assert (ip_fd->if_flags & IFF_READ_IP);
161 ip_fd->if_flags &= ~IFF_READ_IP;
162 result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd,
163 (size_t)EINTR, (acc_t *)0, FALSE);
164 assert (!result);
165 break;
166 #if 0
167 case SR_CANCEL_WRITE:
168 assert(0);
169 assert (ip_fd->if_flags & IFF_WRITE_MASK);
170 ip_fd->if_flags &= ~IFF_WRITE_MASK;
171 repl_res= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,
172 (size_t)EINTR, (size_t)0, FALSE);
173 assert (!repl_res);
174 break;
175 #endif
176 default:
177 ip_panic(( "unknown cancel request" ));
178 break;
180 return NW_OK;
183 PRIVATE int ip_select(fd, operations)
184 int fd;
185 unsigned operations;
187 printf("ip_select: not implemented\n");
188 return 0;
191 PUBLIC int ip_open (port, srfd, get_userdata, put_userdata, put_pkt,
192 select_res)
193 int port;
194 int srfd;
195 get_userdata_t get_userdata;
196 put_userdata_t put_userdata;
197 put_pkt_t put_pkt;
198 select_res_t select_res;
200 int i;
201 ip_fd_t *ip_fd;
202 ip_port_t *ip_port;
204 ip_port= &ip_port_table[port];
205 if (!(ip_port->ip_flags & IPF_CONFIGURED))
206 return ENXIO;
208 for (i=0; i<IP_FD_NR && (ip_fd_table[i].if_flags & IFF_INUSE);
209 i++);
211 if (i>=IP_FD_NR)
213 DBLOCK(1, printf("out of fds\n"));
214 return EAGAIN;
217 ip_fd= &ip_fd_table[i];
219 ip_fd->if_flags= IFF_INUSE;
221 ip_fd->if_ipopt.nwio_flags= NWIO_DEFAULT;
222 ip_fd->if_ipopt.nwio_tos= 0;
223 ip_fd->if_ipopt.nwio_df= FALSE;
224 ip_fd->if_ipopt.nwio_ttl= 255;
225 ip_fd->if_ipopt.nwio_hdropt.iho_opt_siz= 0;
227 ip_fd->if_port= ip_port;
228 ip_fd->if_srfd= srfd;
229 assert(ip_fd->if_rdbuf_head == NULL);
230 ip_fd->if_get_userdata= get_userdata;
231 ip_fd->if_put_userdata= put_userdata;
232 ip_fd->if_put_pkt= put_pkt;
234 return i;
237 PRIVATE void ip_close (fd)
238 int fd;
240 ip_fd_t *ip_fd;
241 acc_t *pack;
243 ip_fd= &ip_fd_table[fd];
245 assert ((ip_fd->if_flags & IFF_INUSE) &&
246 !(ip_fd->if_flags & IFF_BUSY));
248 if (ip_fd->if_flags & IFF_OPTSET)
249 ip_unhash_proto(ip_fd);
250 while (ip_fd->if_rdbuf_head)
252 pack= ip_fd->if_rdbuf_head;
253 ip_fd->if_rdbuf_head= pack->acc_ext_link;
254 bf_afree(pack);
256 ip_fd->if_flags= IFF_EMPTY;
259 PRIVATE void ip_buffree(priority)
260 int priority;
262 int i;
263 ip_port_t *ip_port;
264 ip_fd_t *ip_fd;
265 ip_ass_t *ip_ass;
266 acc_t *pack, *next_pack;
268 for (i= 0, ip_port= ip_port_table; i<ip_conf_nr; i++, ip_port++)
270 if (ip_port->ip_dl_type == IPDL_ETH)
272 /* Can't free de_frame.
273 * bf_check_acc(ip_port->ip_dl.dl_eth.de_frame);
275 if (priority == IP_PRI_PORTBUFS)
277 next_pack= ip_port->ip_dl.dl_eth.de_arp_head;
278 while(next_pack != NULL)
280 pack= next_pack;
281 next_pack= pack->acc_ext_link;
282 bf_afree(pack);
284 ip_port->ip_dl.dl_eth.de_arp_head= next_pack;
286 next_pack= ip_port->ip_dl.dl_eth.de_q_head;
287 while(next_pack != NULL)
289 pack= next_pack;
290 next_pack= pack->acc_ext_link;
291 bf_afree(pack);
293 ip_port->ip_dl.dl_eth.de_q_head= next_pack;
296 else if (ip_port->ip_dl_type == IPDL_PSIP)
298 if (priority == IP_PRI_PORTBUFS)
300 next_pack= ip_port->ip_dl.dl_ps.ps_send_head;
301 while (next_pack != NULL)
303 pack= next_pack;
304 next_pack= pack->acc_ext_link;
305 bf_afree(pack);
307 ip_port->ip_dl.dl_ps.ps_send_head= next_pack;
310 if (priority == IP_PRI_PORTBUFS)
312 next_pack= ip_port->ip_loopb_head;
313 while(next_pack && next_pack->acc_ext_link)
315 pack= next_pack;
316 next_pack= pack->acc_ext_link;
317 bf_afree(pack);
319 if (next_pack)
321 if (ev_in_queue(&ip_port->ip_loopb_event))
323 #if DEBUG
324 printf(
325 "not freeing ip_loopb_head, ip_loopb_event enqueued\n");
326 #endif
328 else
330 bf_afree(next_pack);
331 next_pack= NULL;
334 ip_port->ip_loopb_head= next_pack;
336 next_pack= ip_port->ip_routeq_head;
337 while(next_pack && next_pack->acc_ext_link)
339 pack= next_pack;
340 next_pack= pack->acc_ext_link;
341 bf_afree(pack);
343 if (next_pack)
345 if (ev_in_queue(&ip_port->ip_routeq_event))
347 #if DEBUG
348 printf(
349 "not freeing ip_loopb_head, ip_routeq_event enqueued\n");
350 #endif
352 else
354 bf_afree(next_pack);
355 next_pack= NULL;
358 ip_port->ip_routeq_head= next_pack;
361 if (priority == IP_PRI_FDBUFS_EXTRA)
363 for (i= 0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
365 while (ip_fd->if_rdbuf_head &&
366 ip_fd->if_rdbuf_head->acc_ext_link)
368 pack= ip_fd->if_rdbuf_head;
369 ip_fd->if_rdbuf_head= pack->acc_ext_link;
370 bf_afree(pack);
374 if (priority == IP_PRI_FDBUFS)
376 for (i= 0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
378 while (ip_fd->if_rdbuf_head)
380 pack= ip_fd->if_rdbuf_head;
381 ip_fd->if_rdbuf_head= pack->acc_ext_link;
382 bf_afree(pack);
386 if (priority == IP_PRI_ASSBUFS)
388 for (i= 0, ip_ass= ip_ass_table; i<IP_ASS_NR; i++, ip_ass++)
390 next_pack= ip_ass->ia_frags;
391 while(ip_ass->ia_frags != NULL)
393 pack= ip_ass->ia_frags;
394 ip_ass->ia_frags= pack->acc_ext_link;
395 bf_afree(pack);
397 ip_ass->ia_first_time= 0;
402 #ifdef BUF_CONSISTENCY_CHECK
403 PRIVATE void ip_bufcheck()
405 int i;
406 ip_port_t *ip_port;
407 ip_fd_t *ip_fd;
408 ip_ass_t *ip_ass;
409 acc_t *pack;
411 for (i= 0, ip_port= ip_port_table; i<ip_conf_nr; i++, ip_port++)
413 if (ip_port->ip_dl_type == IPDL_ETH)
415 bf_check_acc(ip_port->ip_dl.dl_eth.de_frame);
416 for (pack= ip_port->ip_dl.dl_eth.de_q_head; pack;
417 pack= pack->acc_ext_link)
419 bf_check_acc(pack);
421 for (pack= ip_port->ip_dl.dl_eth.de_arp_head; pack;
422 pack= pack->acc_ext_link)
424 bf_check_acc(pack);
427 else if (ip_port->ip_dl_type == IPDL_PSIP)
429 for (pack= ip_port->ip_dl.dl_ps.ps_send_head; pack;
430 pack= pack->acc_ext_link)
432 bf_check_acc(pack);
435 for (pack= ip_port->ip_loopb_head; pack;
436 pack= pack->acc_ext_link)
438 bf_check_acc(pack);
440 for (pack= ip_port->ip_routeq_head; pack;
441 pack= pack->acc_ext_link)
443 bf_check_acc(pack);
446 for (i= 0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)
448 for (pack= ip_fd->if_rdbuf_head; pack;
449 pack= pack->acc_ext_link)
451 bf_check_acc(pack);
454 for (i= 0, ip_ass= ip_ass_table; i<IP_ASS_NR; i++, ip_ass++)
456 for (pack= ip_ass->ia_frags; pack; pack= pack->acc_ext_link)
457 bf_check_acc(pack);
460 #endif /* BUF_CONSISTENCY_CHECK */
462 PRIVATE void ip_bad_callback(ip_port)
463 struct ip_port *ip_port;
465 ip_panic(( "no callback filled in for port %d", ip_port->ip_port ));
469 * $PchId: ip.c,v 1.19 2005/06/28 14:17:40 philip Exp $