Change to include files. No more ../h
[unix-history] / usr / src / sys / deprecated / netimp / if_imp.c
CommitLineData
54cf16ba 1/* if_imp.c 6.2 84/08/29 */
6c73ade6
BJ
2
3#include "imp.h"
4#if NIMP > 0
5/*
72e4f44e 6 * ARPANET IMP interface driver.
6c73ade6
BJ
7 *
8 * The IMP-host protocol is handled here, leaving
9 * hardware specifics to the lower level interface driver.
639a8848
SL
10 *
11 * NB: only handles IMPS on class A networks.
6c73ade6 12 */
961945a8
SL
13#include "../machine/pte.h"
14
54cf16ba
JB
15#include "param.h"
16#include "systm.h"
17#include "mbuf.h"
18#include "buf.h"
19#include "protosw.h"
20#include "socket.h"
21#include "vmmac.h"
22#include "time.h"
23#include "kernel.h"
24#include "errno.h"
25#include "ioctl.h"
6e7edb25
BJ
26
27#include "../vax/cpu.h"
28#include "../vax/mtpr.h"
39d536e6
BJ
29#include "../vaxuba/ubareg.h"
30#include "../vaxuba/ubavar.h"
6e7edb25 31
6c73ade6 32#include "../net/if.h"
6e7edb25 33#include "../net/route.h"
f4d55810 34
5e3649c6 35#include "../net/netisr.h"
6e7edb25
BJ
36#include "../netinet/in.h"
37#include "../netinet/in_systm.h"
38#include "../netinet/ip.h"
39#include "../netinet/ip_var.h"
b690198c 40/* define IMPLEADERS here to get leader printing code */
54cf16ba
JB
41#include "if_imp.h"
42#include "if_imphost.h"
6c73ade6
BJ
43
44/*
45 * IMP software status per interface.
46 * (partially shared with the hardware specific module)
47 *
48 * Each interface is referenced by a network interface structure,
49 * imp_if, which the routing code uses to locate the interface.
50 * This structure contains the output queue for the interface, its
51 * address, ... IMP specific structures used in connecting the
52 * IMP software modules to the hardware specific interface routines
a2cd4df7
BJ
53 * are stored here. The common structures are made visible to the
54 * interface driver by passing a pointer to the hardware routine
55 * at "attach" time.
6c73ade6
BJ
56 *
57 * NOTE: imp_if and imp_cb are assumed adjacent in hardware code.
58 */
59struct imp_softc {
60 struct ifnet imp_if; /* network visible interface */
61 struct impcb imp_cb; /* hooks to hardware module */
62 u_char imp_state; /* current state of IMP */
63 char imp_dropcnt; /* used during initialization */
6c73ade6
BJ
64} imp_softc[NIMP];
65
66/*
67 * Messages from IMP regarding why
68 * it's going down.
69 */
e33b5b1a 70static char *impmessage[] = {
6c73ade6
BJ
71 "in 30 seconds",
72 "for hardware PM",
73 "to reload software",
74 "for emergency reset"
75};
76
639a8848 77int impdown(), impinit(), impioctl(), impoutput();
a2cd4df7 78
6c73ade6
BJ
79/*
80 * IMP attach routine. Called from hardware device attach routine
81 * at configuration time with a pointer to the UNIBUS device structure.
82 * Sets up local state and returns pointer to base of ifnet+impcb
83 * structures. This is then used by the device's attach routine
84 * set up its back pointers.
85 */
30c36259 86impattach(ui, reset)
6c73ade6 87 struct uba_device *ui;
30c36259 88 int (*reset)();
6c73ade6
BJ
89{
90 struct imp_softc *sc = &imp_softc[ui->ui_unit];
91 register struct ifnet *ifp = &sc->imp_if;
92
6c73ade6
BJ
93 /* UNIT COULD BE AMBIGUOUS */
94 ifp->if_unit = ui->ui_unit;
95 ifp->if_name = "imp";
e431883e 96 ifp->if_mtu = IMPMTU - sizeof(struct imp_leader);
ac697091 97 ifp->if_reset = reset;
a2cd4df7 98 ifp->if_init = impinit;
639a8848 99 ifp->if_ioctl = impioctl;
a2cd4df7
BJ
100 ifp->if_output = impoutput;
101 /* reset is handled at the hardware level */
6c73ade6 102 if_attach(ifp);
6c73ade6
BJ
103 return ((int)&sc->imp_if);
104}
105
106/*
107 * IMP initialization routine: call hardware module to
108 * setup UNIBUS resources, init state and get ready for
109 * NOOPs the IMP should send us, and that we want to drop.
110 */
111impinit(unit)
112 int unit;
113{
98b6195e 114 int s = splimp();
6c73ade6 115 register struct imp_softc *sc = &imp_softc[unit];
639a8848 116 struct sockaddr_in *sin;
6c73ade6 117
44eb2da3 118 sin = (struct sockaddr_in *)&sc->imp_if.if_addr;
639a8848
SL
119 if (in_netof(sin->sin_addr) == 0)
120 return;
a2cd4df7
BJ
121 if ((*sc->imp_cb.ic_init)(unit) == 0) {
122 sc->imp_state = IMPS_DOWN;
ee787340 123 sc->imp_if.if_flags &= ~IFF_UP;
98b6195e 124 splx(s);
a2cd4df7
BJ
125 return;
126 }
44eb2da3 127 sc->imp_if.if_flags |= IFF_RUNNING;
6c73ade6 128 sc->imp_state = IMPS_INIT;
a2cd4df7 129 impnoops(sc);
98b6195e 130 splx(s);
6c73ade6
BJ
131}
132
133struct sockproto impproto = { PF_IMPLINK };
faad37c0
SL
134struct sockaddr_in impdst = { AF_IMPLINK };
135struct sockaddr_in impsrc = { AF_IMPLINK };
b690198c 136#ifdef IMPLEADERS
7dfb87a5 137int impprintfs = 0;
b690198c 138#endif
6c73ade6
BJ
139
140/*
141 * ARPAnet 1822 input routine.
142 * Called from hardware input interrupt routine to handle 1822
143 * IMP-host messages. Type 0 messages (non-control) are
144 * passed to higher level protocol processors on the basis
145 * of link number. Other type messages (control) are handled here.
146 */
a2cd4df7 147impinput(unit, m)
6c73ade6 148 int unit;
a2cd4df7 149 register struct mbuf *m;
6c73ade6 150{
6c73ade6
BJ
151 register struct imp_leader *ip;
152 register struct imp_softc *sc = &imp_softc[unit];
153 register struct host *hp;
154 register struct ifqueue *inq;
a2cd4df7 155 struct control_leader *cp;
6c73ade6 156 struct in_addr addr;
e33b5b1a 157 struct mbuf *next;
ee787340 158 struct sockaddr_in *sin;
6c73ade6 159
34c22ab5 160 /* verify leader length. */
a2cd4df7
BJ
161 if (m->m_len < sizeof(struct control_leader) &&
162 (m = m_pullup(m, sizeof(struct control_leader))) == 0)
163 return;
164 cp = mtod(m, struct control_leader *);
165 if (cp->dl_mtype == IMPTYPE_DATA)
166 if (m->m_len < sizeof(struct imp_leader) &&
167 (m = m_pullup(m, sizeof(struct imp_leader))) == 0)
168 return;
6c73ade6 169 ip = mtod(m, struct imp_leader *);
b690198c 170#ifdef IMPLEADERS
7dfb87a5
SL
171 if (impprintfs)
172 printleader("impinput", ip);
b690198c 173#endif
6c73ade6 174
34c22ab5 175 /* check leader type */
a2cd4df7
BJ
176 if (ip->il_format != IMP_NFF) {
177 sc->imp_if.if_collisions++; /* XXX */
6c73ade6 178 goto drop;
a2cd4df7 179 }
6c73ade6 180
ba45553a 181 if (ip->il_mtype != IMPTYPE_DATA) {
41e530c7 182#ifdef notdef
a2cd4df7 183 addr.s_net = ip->il_network;
41e530c7 184#else
ba45553a 185 addr.s_net = sc->imp_if.if_net;
41e530c7 186#endif
a2cd4df7
BJ
187 addr.s_imp = ip->il_imp;
188 addr.s_host = ip->il_host;
6c73ade6 189 }
6c73ade6
BJ
190 switch (ip->il_mtype) {
191
6c73ade6 192 case IMPTYPE_DATA:
6c73ade6
BJ
193 break;
194
195 /*
196 * IMP leader error. Reset the IMP and discard the packet.
197 */
198 case IMPTYPE_BADLEADER:
a0b7c7fb
SL
199 /*
200 * According to 1822 document, this message
201 * will be generated in response to the
202 * first noop sent to the IMP after
203 * the host resets the IMP interface.
204 */
a2cd4df7 205 if (sc->imp_state != IMPS_INIT) {
e33b5b1a 206 impmsg(sc, "leader error");
72e4f44e 207 hostreset(sc->imp_if.if_net);
a0b7c7fb
SL
208 impnoops(sc);
209 }
72e4f44e 210 goto drop;
6c73ade6
BJ
211
212 /*
213 * IMP going down. Print message, and if not immediate,
214 * set off a timer to insure things will be reset at the
215 * appropriate time.
216 */
217 case IMPTYPE_DOWN:
f32a85bb 218 if (sc->imp_state < IMPS_INIT)
47e51140 219 goto drop;
6c73ade6
BJ
220 if ((ip->il_link & IMP_DMASK) == 0) {
221 sc->imp_state = IMPS_GOINGDOWN;
668cc26d 222 timeout(impdown, (caddr_t)sc, 30 * hz);
6c73ade6 223 }
668cc26d
SL
224 impmsg(sc, "going down %s",
225 (u_int)impmessage[ip->il_link&IMP_DMASK]);
72e4f44e 226 goto drop;
6c73ade6
BJ
227
228 /*
229 * A NOP usually seen during the initialization sequence.
230 * Compare the local address with that in the message.
231 * Reset the local address notion if it doesn't match.
232 */
ee787340 233 case IMPTYPE_NOOP:
a0b7c7fb
SL
234 if (sc->imp_state == IMPS_DOWN) {
235 sc->imp_state = IMPS_INIT;
236 sc->imp_dropcnt = IMP_DROPCNT;
237 }
98b6195e 238 if (sc->imp_state == IMPS_INIT && --sc->imp_dropcnt > 0)
e431883e 239 goto drop;
98b6195e
SL
240 sin = (struct sockaddr_in *)&sc->imp_if.if_addr;
241 if (sin->sin_addr.s_host != ip->il_host ||
242 sin->sin_addr.s_imp != ip->il_imp) {
243 sc->imp_if.if_host[0] =
244 sin->sin_addr.s_host = ip->il_host;
245 sin->sin_addr.s_imp = ip->il_imp;
246 impmsg(sc, "reset (host %d/imp %d)", (u_int)ip->il_host,
247 ntohs(ip->il_imp));
248 }
a2cd4df7 249 sc->imp_state = IMPS_UP;
ee787340 250 sc->imp_if.if_flags |= IFF_UP;
88f80700 251 if_rtinit(&sc->imp_if, RTF_UP);
e431883e 252 goto drop;
6c73ade6
BJ
253
254 /*
72e4f44e
SL
255 * RFNM or INCOMPLETE message, send next
256 * message on the q. We could pass incomplete's
257 * up to the next level, but this currently isn't
258 * needed.
6c73ade6
BJ
259 */
260 case IMPTYPE_RFNM:
261 case IMPTYPE_INCOMPLETE:
ba45553a
SL
262 if (hp = hostlookup(addr)) {
263 if (hp->h_rfnm == 0)
264 hp->h_flags &= ~HF_INUSE;
265 else if (next = hostdeque(hp))
266 (void) impsnd(&sc->imp_if, next);
267 }
e431883e 268 goto drop;
6c73ade6
BJ
269
270 /*
271 * Host or IMP can't be reached. Flush any packets
272 * awaiting transmission and release the host structure.
6c73ade6
BJ
273 */
274 case IMPTYPE_HOSTDEAD:
ad100671 275 case IMPTYPE_HOSTUNREACH:
6e7edb25
BJ
276 impnotify((int)ip->il_mtype, (struct control_leader *)ip,
277 hostlookup(addr));
41e530c7 278 goto rawlinkin;
6c73ade6
BJ
279
280 /*
281 * Error in data. Clear RFNM status for this host and send
282 * noops to the IMP to clear the interface.
283 */
ad100671 284 case IMPTYPE_BADDATA:
e33b5b1a 285 impmsg(sc, "data error");
ba45553a 286 if (hp = hostlookup(addr))
6c73ade6
BJ
287 hp->h_rfnm = 0;
288 impnoops(sc);
72e4f44e 289 goto drop;
6c73ade6
BJ
290
291 /*
a0b7c7fb 292 * Interface reset.
6c73ade6
BJ
293 */
294 case IMPTYPE_RESET:
e33b5b1a 295 impmsg(sc, "interface reset");
a0b7c7fb 296 impnoops(sc);
72e4f44e 297 goto drop;
6c73ade6
BJ
298
299 default:
300 sc->imp_if.if_collisions++; /* XXX */
72e4f44e 301 goto drop;
6c73ade6
BJ
302 }
303
304 /*
34c22ab5
BJ
305 * Data for a protocol. Dispatch to the appropriate
306 * protocol routine (running at software interrupt).
307 * If this isn't a raw interface, advance pointer
308 * into mbuf past leader.
6c73ade6
BJ
309 */
310 switch (ip->il_link) {
311
312#ifdef INET
313 case IMPLINK_IP:
314 m->m_len -= sizeof(struct imp_leader);
315 m->m_off += sizeof(struct imp_leader);
9c8692e9 316 schednetisr(NETISR_IP);
6c73ade6
BJ
317 inq = &ipintrq;
318 break;
319#endif
320
321 default:
654fef96 322 rawlinkin:
6c73ade6 323 impproto.sp_protocol = ip->il_link;
ee787340
SL
324 sin = (struct sockaddr_in *)&sc->imp_if.if_addr;
325 impdst.sin_addr = sin->sin_addr;;
faad37c0
SL
326 impsrc.sin_addr.s_net = ip->il_network;
327 impsrc.sin_addr.s_host = ip->il_host;
328 impsrc.sin_addr.s_imp = ip->il_imp;
57aa3090
SL
329 raw_input(m, &impproto, (struct sockaddr *)&impsrc,
330 (struct sockaddr *)&impdst);
6c73ade6
BJ
331 return;
332 }
1e977657
BJ
333 if (IF_QFULL(inq)) {
334 IF_DROP(inq);
335 goto drop;
336 }
6c73ade6
BJ
337 IF_ENQUEUE(inq, m);
338 return;
339
340drop:
341 m_freem(m);
342}
343
a0b7c7fb
SL
344/*
345 * Bring the IMP down after notification.
346 */
347impdown(sc)
348 struct imp_softc *sc;
349{
ad100671 350 int s = splimp();
1e977657 351
a0b7c7fb 352 sc->imp_state = IMPS_DOWN;
e33b5b1a 353 impmsg(sc, "marked down");
ba45553a 354 hostreset(sc->imp_if.if_net);
72e4f44e 355 if_down(&sc->imp_if);
ad100671 356 splx(s);
a0b7c7fb
SL
357}
358
6c73ade6 359/*VARARGS*/
e33b5b1a 360impmsg(sc, fmt, a1, a2)
6c73ade6
BJ
361 struct imp_softc *sc;
362 char *fmt;
668cc26d 363 u_int a1;
6c73ade6 364{
1e977657 365
6c73ade6
BJ
366 printf("imp%d: ", sc->imp_if.if_unit);
367 printf(fmt, a1, a2);
368 printf("\n");
369}
370
72e4f44e
SL
371/*
372 * Process an IMP "error" message, passing this
373 * up to the higher level protocol.
374 */
375impnotify(what, cp, hp)
376 int what;
377 struct control_leader *cp;
378 struct host *hp;
379{
380 struct in_addr in;
381
382#ifdef notdef
383 in.s_net = cp->dl_network;
384#else
ba45553a 385 in.s_net = 10; /* XXX */
72e4f44e
SL
386#endif
387 in.s_host = cp->dl_host;
388 in.s_imp = cp->dl_imp;
389 if (cp->dl_link != IMPLINK_IP)
390 raw_ctlinput(what, (caddr_t)&in);
391 else
392 ip_ctlinput(what, (caddr_t)&in);
ba45553a
SL
393 if (hp) {
394 hp->h_flags |= (1 << what);
72e4f44e 395 hostfree(hp);
ba45553a 396 }
72e4f44e
SL
397}
398
6c73ade6
BJ
399/*
400 * ARPAnet 1822 output routine.
401 * Called from higher level protocol routines to set up messages for
402 * transmission to the imp. Sets up the header and calls impsnd to
403 * enqueue the message for this IMP's hardware driver.
404 */
ee787340 405impoutput(ifp, m0, dst)
6c73ade6
BJ
406 register struct ifnet *ifp;
407 struct mbuf *m0;
ee787340 408 struct sockaddr *dst;
6c73ade6
BJ
409{
410 register struct imp_leader *imp;
411 register struct mbuf *m = m0;
39d536e6 412 int dhost, dimp, dlink, len, dnet;
8a2f82db 413 int error = 0;
6c73ade6
BJ
414
415 /*
416 * Don't even try if the IMP is unavailable.
417 */
8a2f82db
SL
418 if (imp_softc[ifp->if_unit].imp_state != IMPS_UP) {
419 error = ENETDOWN;
a0b7c7fb 420 goto drop;
8a2f82db 421 }
6c73ade6 422
ee787340 423 switch (dst->sa_family) {
6c73ade6
BJ
424
425#ifdef INET
ee787340
SL
426 case AF_INET: {
427 struct ip *ip = mtod(m0, struct ip *);
428 struct sockaddr_in *sin = (struct sockaddr_in *)dst;
6c73ade6 429
ee787340
SL
430 dhost = sin->sin_addr.s_host;
431 dimp = sin->sin_addr.s_impno;
6c73ade6 432 dlink = IMPLINK_IP;
1e63a6ab 433 dnet = 0;
668cc26d 434 len = ntohs((u_short)ip->ip_len);
6c73ade6
BJ
435 break;
436 }
437#endif
ee787340 438 case AF_IMPLINK:
6c73ade6
BJ
439 goto leaderexists;
440
441 default:
ee787340
SL
442 printf("imp%d: can't handle af%d\n", ifp->if_unit,
443 dst->sa_family);
8a2f82db 444 error = EAFNOSUPPORT;
a0b7c7fb 445 goto drop;
6c73ade6
BJ
446 }
447
448 /*
449 * Add IMP leader. If there's not enough space in the
450 * first mbuf, allocate another. If that should fail, we
451 * drop this sucker.
452 */
453 if (m->m_off > MMAXOFF ||
454 MMINOFF + sizeof(struct imp_leader) > m->m_off) {
cce93e4b 455 m = m_get(M_DONTWAIT, MT_HEADER);
8a2f82db
SL
456 if (m == 0) {
457 error = ENOBUFS;
a0b7c7fb 458 goto drop;
8a2f82db 459 }
6c73ade6 460 m->m_next = m0;
6c73ade6
BJ
461 m->m_len = sizeof(struct imp_leader);
462 } else {
463 m->m_off -= sizeof(struct imp_leader);
464 m->m_len += sizeof(struct imp_leader);
465 }
466 imp = mtod(m, struct imp_leader *);
467 imp->il_format = IMP_NFF;
41e530c7 468 imp->il_mtype = IMPTYPE_DATA;
1e63a6ab 469 imp->il_network = dnet;
6c73ade6 470 imp->il_host = dhost;
1e63a6ab 471 imp->il_imp = htons((u_short)dimp);
668cc26d
SL
472 imp->il_length =
473 htons((u_short)(len + sizeof(struct imp_leader)) << 3);
6c73ade6 474 imp->il_link = dlink;
41e530c7 475 imp->il_flags = imp->il_htype = imp->il_subtype = 0;
6c73ade6
BJ
476
477leaderexists:
6c73ade6 478 return (impsnd(ifp, m));
a0b7c7fb
SL
479drop:
480 m_freem(m0);
8a2f82db 481 return (error);
6c73ade6
BJ
482}
483
484/*
485 * Put a message on an interface's output queue.
486 * Perform RFNM counting: no more than 8 message may be
487 * in flight to any one host.
488 */
489impsnd(ifp, m)
490 struct ifnet *ifp;
491 struct mbuf *m;
492{
493 register struct imp_leader *ip;
494 register struct host *hp;
495 struct impcb *icp;
ba45553a 496 int s, error;
6c73ade6
BJ
497
498 ip = mtod(m, struct imp_leader *);
499
500 /*
501 * Do RFNM counting for data messages
502 * (no more than 8 outstanding to any host)
503 */
ba45553a 504 s = splimp();
6c73ade6
BJ
505 if (ip->il_mtype == IMPTYPE_DATA) {
506 struct in_addr addr;
507
41e530c7 508#ifdef notdef
a2cd4df7 509 addr.s_net = ip->il_network;
41e530c7 510#else
ba45553a 511 addr.s_net = ifp->if_net; /* XXX */
41e530c7 512#endif
6c73ade6
BJ
513 addr.s_host = ip->il_host;
514 addr.s_imp = ip->il_imp;
a2cd4df7
BJ
515 if ((hp = hostlookup(addr)) == 0)
516 hp = hostenter(addr);
ba45553a 517 if (hp && (hp->h_flags & (HF_DEAD|HF_UNREACH))) {
67387c9c 518 error = hp->h_flags&HF_DEAD ? EHOSTDOWN : EHOSTUNREACH;
ba45553a
SL
519 hp->h_timer = HOSTTIMER;
520 hp->h_flags &= ~HF_INUSE;
521 goto bad;
ba45553a 522 }
6c73ade6
BJ
523
524 /*
a0b7c7fb 525 * If IMP would block, queue until RFNM
6c73ade6
BJ
526 */
527 if (hp) {
6c73ade6
BJ
528 if (hp->h_rfnm < 8) {
529 hp->h_rfnm++;
530 goto enque;
531 }
fcd78660
BJ
532 if (hp->h_qcnt < 8) { /* high water mark */
533 HOST_ENQUE(hp, m);
534 goto start;
535 }
6c73ade6 536 }
ba45553a
SL
537 error = ENOBUFS;
538 goto bad;
6c73ade6
BJ
539 }
540enque:
1e977657
BJ
541 if (IF_QFULL(&ifp->if_snd)) {
542 IF_DROP(&ifp->if_snd);
ba45553a
SL
543 error = ENOBUFS;
544bad:
1e977657 545 m_freem(m);
ba45553a
SL
546 splx(s);
547 return (error);
1e977657 548 }
6c73ade6 549 IF_ENQUEUE(&ifp->if_snd, m);
6c73ade6
BJ
550start:
551 icp = &imp_softc[ifp->if_unit].imp_cb;
552 if (icp->ic_oactive == 0)
553 (*icp->ic_start)(ifp->if_unit);
70e3101c 554 splx(s);
8a2f82db 555 return (0);
6c73ade6
BJ
556}
557
558/*
559 * Put three 1822 NOOPs at the head of the output queue.
560 * Part of host-IMP initialization procedure.
561 * (Should return success/failure, but noone knows
562 * what to do with this, so why bother?)
0dc78444
SL
563 * This routine is always called at splimp, so we don't
564 * protect the call to IF_PREPEND.
6c73ade6
BJ
565 */
566impnoops(sc)
567 register struct imp_softc *sc;
568{
569 register i;
570 register struct mbuf *m;
a2cd4df7 571 register struct control_leader *cp;
6c73ade6 572
6c73ade6 573 sc->imp_dropcnt = IMP_DROPCNT;
a2cd4df7 574 for (i = 0; i < IMP_DROPCNT + 1; i++ ) {
cce93e4b 575 if ((m = m_getclr(M_DONTWAIT, MT_HEADER)) == 0)
6c73ade6 576 return;
a2cd4df7
BJ
577 m->m_len = sizeof(struct control_leader);
578 cp = mtod(m, struct control_leader *);
579 cp->dl_format = IMP_NFF;
580 cp->dl_link = i;
581 cp->dl_mtype = IMPTYPE_NOOP;
6c73ade6 582 IF_PREPEND(&sc->imp_if.if_snd, m);
6c73ade6
BJ
583 }
584 if (sc->imp_cb.ic_oactive == 0)
585 (*sc->imp_cb.ic_start)(sc->imp_if.if_unit);
586}
7dfb87a5 587
639a8848
SL
588/*
589 * Process an ioctl request.
590 */
591impioctl(ifp, cmd, data)
592 register struct ifnet *ifp;
593 int cmd;
594 caddr_t data;
595{
596 struct ifreq *ifr = (struct ifreq *)data;
597 struct sockaddr_in *sin;
598 int s = splimp(), error = 0;
599
600 switch (cmd) {
601
602 case SIOCSIFADDR:
603 if (ifp->if_flags & IFF_RUNNING)
604 if_rtinit(ifp, -1); /* delete previous route */
605 sin = (struct sockaddr_in *)&ifr->ifr_addr;
606 ifp->if_net = in_netof(sin->sin_addr);
607 sin = (struct sockaddr_in *)&ifp->if_addr;
608 sin->sin_family = AF_INET;
609 /* host number filled in already, or filled in later */
610 sin->sin_addr = if_makeaddr(ifp->if_net, ifp->if_host[0]);
611 if (ifp->if_flags & IFF_RUNNING)
612 if_rtinit(ifp, RTF_UP);
613 else
614 impinit(ifp->if_unit);
615 break;
616
617 default:
618 error = EINVAL;
619 }
620 splx(s);
621 return (error);
622}
623
7dfb87a5
SL
624#ifdef IMPLEADERS
625printleader(routine, ip)
626 char *routine;
627 register struct imp_leader *ip;
628{
629 printf("%s: ", routine);
630 printbyte((char *)ip, 12);
631 printf("<fmt=%x,net=%x,flags=%x,mtype=", ip->il_format, ip->il_network,
632 ip->il_flags);
633 if (ip->il_mtype <= IMPTYPE_READY)
634 printf("%s,", impleaders[ip->il_mtype]);
635 else
636 printf("%x,", ip->il_mtype);
637 printf("htype=%x,host=%x,imp=%x,link=", ip->il_htype, ip->il_host,
638 ntohs(ip->il_imp));
639 if (ip->il_link == IMPLINK_IP)
640 printf("ip,");
641 else
642 printf("%x,", ip->il_link);
643 printf("subtype=%x,len=%x>\n",ip->il_subtype,ntohs(ip->il_length)>>3);
644}
645
646printbyte(cp, n)
647 register char *cp;
648 int n;
649{
650 register i, j, c;
651
652 for (i=0; i<n; i++) {
653 c = *cp++;
654 for (j=0; j<2; j++)
655 putchar("0123456789abcdef"[(c>>((1-j)*4))&0xf]);
656 putchar(' ');
657 }
658 putchar('\n');
659}
660#endif
41e530c7 661#endif