|
Lines 105-110
Link Here
|
| 105 |
|
105 |
|
| 106 |
#include <net/bpf.h> |
106 |
#include <net/bpf.h> |
| 107 |
|
107 |
|
|
|
108 |
static MALLOC_DEFINE(M_SL, "sl", "SLIP Interface"); |
| 109 |
|
| 108 |
static void slattach __P((void *)); |
110 |
static void slattach __P((void *)); |
| 109 |
PSEUDO_SET(slattach, if_sl); |
111 |
PSEUDO_SET(slattach, if_sl); |
| 110 |
|
112 |
|
|
Lines 168-181
Link Here
|
| 168 |
#define ABT_COUNT 3 /* count of escapes for abort */ |
170 |
#define ABT_COUNT 3 /* count of escapes for abort */ |
| 169 |
#define ABT_WINDOW (ABT_COUNT*2+2) /* in seconds - time to count */ |
171 |
#define ABT_WINDOW (ABT_COUNT*2+2) /* in seconds - time to count */ |
| 170 |
|
172 |
|
| 171 |
static struct sl_softc sl_softc[NSL]; |
173 |
LIST_HEAD(sl_list, sl_softc) sl_list; |
| 172 |
|
174 |
|
| 173 |
#define FRAME_END 0xc0 /* Frame End */ |
175 |
#define FRAME_END 0xc0 /* Frame End */ |
| 174 |
#define FRAME_ESCAPE 0xdb /* Frame Esc */ |
176 |
#define FRAME_ESCAPE 0xdb /* Frame Esc */ |
| 175 |
#define TRANS_FRAME_END 0xdc /* transposed frame end */ |
177 |
#define TRANS_FRAME_END 0xdc /* transposed frame end */ |
| 176 |
#define TRANS_FRAME_ESCAPE 0xdd /* transposed frame esc */ |
178 |
#define TRANS_FRAME_ESCAPE 0xdd /* transposed frame esc */ |
| 177 |
|
179 |
|
| 178 |
static int slinit __P((struct sl_softc *)); |
180 |
static int slisstatic __P((int)); |
|
|
181 |
static void slmarkstatic __P((int)); |
| 182 |
static struct sl_softc *slcreate __P((void)); |
| 183 |
static void sldestroy __P((struct sl_softc *sc)); |
| 179 |
static struct mbuf *sl_btom __P((struct sl_softc *, int)); |
184 |
static struct mbuf *sl_btom __P((struct sl_softc *, int)); |
| 180 |
static timeout_t sl_keepalive; |
185 |
static timeout_t sl_keepalive; |
| 181 |
static timeout_t sl_outfill; |
186 |
static timeout_t sl_outfill; |
|
Lines 201-255
Link Here
|
| 201 |
slattach(dummy) |
206 |
slattach(dummy) |
| 202 |
void *dummy; |
207 |
void *dummy; |
| 203 |
{ |
208 |
{ |
| 204 |
register struct sl_softc *sc; |
|
|
| 205 |
register int i = 0; |
| 206 |
|
| 207 |
linesw[SLIPDISC] = slipdisc; |
209 |
linesw[SLIPDISC] = slipdisc; |
| 208 |
|
210 |
|
| 209 |
for (sc = sl_softc; i < NSL; sc++) { |
211 |
LIST_INIT(&sl_list); |
| 210 |
sc->sc_if.if_name = "sl"; |
|
|
| 211 |
sc->sc_if.if_unit = i++; |
| 212 |
sc->sc_if.if_mtu = SLMTU; |
| 213 |
sc->sc_if.if_flags = |
| 214 |
#ifdef SLIP_IFF_OPTS |
| 215 |
SLIP_IFF_OPTS; |
| 216 |
#else |
| 217 |
IFF_POINTOPOINT | SC_AUTOCOMP | IFF_MULTICAST; |
| 218 |
#endif |
| 219 |
sc->sc_if.if_type = IFT_SLIP; |
| 220 |
sc->sc_if.if_ioctl = slioctl; |
| 221 |
sc->sc_if.if_output = sloutput; |
| 222 |
sc->sc_if.if_snd.ifq_maxlen = 50; |
| 223 |
sc->sc_fastq.ifq_maxlen = 32; |
| 224 |
sc->sc_if.if_linkmib = sc; |
| 225 |
sc->sc_if.if_linkmiblen = sizeof *sc; |
| 226 |
if_attach(&sc->sc_if); |
| 227 |
bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN); |
| 228 |
} |
| 229 |
} |
212 |
} |
| 230 |
|
213 |
|
| 231 |
static int |
214 |
static int *st_unit_list; |
| 232 |
slinit(sc) |
215 |
static size_t st_unit_max = 0; |
| 233 |
register struct sl_softc *sc; |
216 |
|
|
|
217 |
static |
| 218 |
int slisstatic(unit) |
| 219 |
int unit; |
| 234 |
{ |
220 |
{ |
| 235 |
register caddr_t p; |
221 |
size_t i; |
| 236 |
|
222 |
|
| 237 |
if (sc->sc_ep == (u_char *) 0) { |
223 |
for (i = 0; i < st_unit_max; i++) |
| 238 |
MCLALLOC(p, M_WAIT); |
224 |
if (st_unit_list[i] == unit) |
| 239 |
if (p) |
225 |
return 1; |
| 240 |
sc->sc_ep = (u_char *)p + SLBUFSIZE; |
226 |
return 0; |
| 241 |
else { |
227 |
} |
| 242 |
printf("sl%ld: can't allocate buffer\n", |
228 |
|
| 243 |
(long)(sc - sl_softc)); |
229 |
static |
| 244 |
return (0); |
230 |
void slmarkstatic(unit) |
| 245 |
} |
231 |
int unit; |
|
|
232 |
{ |
| 233 |
int *t; |
| 234 |
|
| 235 |
if (slisstatic(unit)) |
| 236 |
return; |
| 237 |
|
| 238 |
MALLOC(t, int *, sizeof(int) * (st_unit_max+1), M_SL, M_NOWAIT); |
| 239 |
if (t == NULL) |
| 240 |
return; |
| 241 |
|
| 242 |
if (st_unit_list) { |
| 243 |
bcopy(st_unit_list, t, sizeof(int) * st_unit_max); |
| 244 |
FREE(st_unit_list, M_SL); |
| 245 |
} |
| 246 |
st_unit_list = t; |
| 247 |
st_unit_list[st_unit_max] = unit; |
| 248 |
st_unit_max++; |
| 249 |
} |
| 250 |
|
| 251 |
static struct sl_softc * |
| 252 |
slcreate() |
| 253 |
{ |
| 254 |
struct sl_softc *sc, *nc; |
| 255 |
int unit; |
| 256 |
caddr_t p; |
| 257 |
|
| 258 |
MALLOC(sc, struct sl_softc *, sizeof(*sc), M_SL, M_WAITOK); |
| 259 |
bzero(sc, sizeof *sc); |
| 260 |
|
| 261 |
MCLALLOC(p, M_WAIT); |
| 262 |
if (p) |
| 263 |
sc->sc_ep = (u_char *)p + SLBUFSIZE; |
| 264 |
else { |
| 265 |
printf("sl: can't allocate buffer\n"); |
| 266 |
FREE(sc, M_SL); |
| 267 |
return (NULL); |
| 246 |
} |
268 |
} |
|
|
269 |
|
| 247 |
sc->sc_buf = sc->sc_ep - SLRMAX; |
270 |
sc->sc_buf = sc->sc_ep - SLRMAX; |
| 248 |
sc->sc_mp = sc->sc_buf; |
271 |
sc->sc_mp = sc->sc_buf; |
| 249 |
sl_compress_init(&sc->sc_comp, -1); |
272 |
sl_compress_init(&sc->sc_comp, -1); |
| 250 |
return (1); |
273 |
|
|
|
274 |
sc->sc_if.if_softc = sc; |
| 275 |
sc->sc_if.if_name = "sl"; |
| 276 |
sc->sc_if.if_mtu = SLMTU; |
| 277 |
sc->sc_if.if_flags = |
| 278 |
#ifdef SLIP_IFF_OPTS |
| 279 |
SLIP_IFF_OPTS; |
| 280 |
#else |
| 281 |
IFF_POINTOPOINT | SC_AUTOCOMP | IFF_MULTICAST; |
| 282 |
#endif |
| 283 |
sc->sc_if.if_type = IFT_SLIP; |
| 284 |
sc->sc_if.if_ioctl = slioctl; |
| 285 |
sc->sc_if.if_output = sloutput; |
| 286 |
sc->sc_if.if_snd.ifq_maxlen = 50; |
| 287 |
sc->sc_fastq.ifq_maxlen = 32; |
| 288 |
sc->sc_if.if_linkmib = sc; |
| 289 |
sc->sc_if.if_linkmiblen = sizeof *sc; |
| 290 |
|
| 291 |
/* |
| 292 |
* Find a suitable unit number. |
| 293 |
*/ |
| 294 |
for (unit=0; ; unit++) { |
| 295 |
if (slisstatic(unit)) |
| 296 |
continue; |
| 297 |
LIST_FOREACH(nc, &sl_list, sl_next) { |
| 298 |
if (nc->sc_if.if_unit == unit) |
| 299 |
continue; |
| 300 |
} |
| 301 |
break; |
| 302 |
} |
| 303 |
sc->sc_if.if_unit = unit; |
| 304 |
LIST_INSERT_HEAD(&sl_list, sc, sl_next); |
| 305 |
|
| 306 |
if_attach(&sc->sc_if); |
| 307 |
bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN); |
| 308 |
|
| 309 |
return sc; |
| 251 |
} |
310 |
} |
| 252 |
|
311 |
|
|
|
312 |
|
| 253 |
/* |
313 |
/* |
| 254 |
* Line specific open routine. |
314 |
* Line specific open routine. |
| 255 |
* Attach the given tty to the first available sl unit. |
315 |
* Attach the given tty to the first available sl unit. |
|
Lines 262-268
Link Here
|
| 262 |
{ |
322 |
{ |
| 263 |
struct proc *p = curproc; /* XXX */ |
323 |
struct proc *p = curproc; /* XXX */ |
| 264 |
register struct sl_softc *sc; |
324 |
register struct sl_softc *sc; |
| 265 |
register int nsl; |
|
|
| 266 |
int s, error; |
325 |
int s, error; |
| 267 |
|
326 |
|
| 268 |
error = suser(p); |
327 |
error = suser(p); |
|
Lines 272-309
Link Here
|
| 272 |
if (tp->t_line == SLIPDISC) |
331 |
if (tp->t_line == SLIPDISC) |
| 273 |
return (0); |
332 |
return (0); |
| 274 |
|
333 |
|
| 275 |
for (nsl = NSL, sc = sl_softc; --nsl >= 0; sc++) |
334 |
if ((sc = slcreate()) == NULL) |
| 276 |
if (sc->sc_ttyp == NULL && !(sc->sc_flags & SC_STATIC)) { |
335 |
return (ENOBUFS); |
| 277 |
if (slinit(sc) == 0) |
|
|
| 278 |
return (ENOBUFS); |
| 279 |
tp->t_sc = (caddr_t)sc; |
| 280 |
sc->sc_ttyp = tp; |
| 281 |
sc->sc_if.if_baudrate = tp->t_ospeed; |
| 282 |
ttyflush(tp, FREAD | FWRITE); |
| 283 |
|
336 |
|
| 284 |
tp->t_line = SLIPDISC; |
337 |
tp->t_sc = (caddr_t)sc; |
| 285 |
/* |
338 |
sc->sc_ttyp = tp; |
| 286 |
* We don't use t_canq or t_rawq, so reduce their |
339 |
sc->sc_if.if_baudrate = tp->t_ospeed; |
| 287 |
* cblock resources to 0. Reserve enough cblocks |
340 |
ttyflush(tp, FREAD | FWRITE); |
| 288 |
* for t_outq to guarantee that we can fit a full |
341 |
tp->t_line = SLIPDISC; |
| 289 |
* packet if the SLIP_HIWAT check allows slstart() |
|
|
| 290 |
* to loop. Use the same value for the cblock |
| 291 |
* limit since the reserved blocks should always |
| 292 |
* be enough. Reserving cblocks probably makes |
| 293 |
* the CLISTRESERVE check unnecessary and wasteful. |
| 294 |
*/ |
| 295 |
clist_alloc_cblocks(&tp->t_canq, 0, 0); |
| 296 |
clist_alloc_cblocks(&tp->t_outq, |
| 297 |
SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, |
| 298 |
SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); |
| 299 |
clist_alloc_cblocks(&tp->t_rawq, 0, 0); |
| 300 |
|
342 |
|
| 301 |
s = splnet(); |
343 |
/* |
| 302 |
if_up(&sc->sc_if); |
344 |
* We don't use t_canq or t_rawq, so reduce their |
| 303 |
splx(s); |
345 |
* cblock resources to 0. Reserve enough cblocks |
| 304 |
return (0); |
346 |
* for t_outq to guarantee that we can fit a full |
| 305 |
} |
347 |
* packet if the SLIP_HIWAT check allows slstart() |
| 306 |
return (ENXIO); |
348 |
* to loop. Use the same value for the cblock |
|
|
349 |
* limit since the reserved blocks should always |
| 350 |
* be enough. Reserving cblocks probably makes |
| 351 |
* the CLISTRESERVE check unnecessary and wasteful. |
| 352 |
*/ |
| 353 |
clist_alloc_cblocks(&tp->t_canq, 0, 0); |
| 354 |
clist_alloc_cblocks(&tp->t_outq, |
| 355 |
SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, |
| 356 |
SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); |
| 357 |
clist_alloc_cblocks(&tp->t_rawq, 0, 0); |
| 358 |
|
| 359 |
s = splnet(); |
| 360 |
if_up(&sc->sc_if); |
| 361 |
splx(s); |
| 362 |
return (0); |
| 363 |
} |
| 364 |
|
| 365 |
void |
| 366 |
sldestroy(struct sl_softc *sc) { |
| 367 |
bpfdetach(&sc->sc_if); |
| 368 |
if_detach(&sc->sc_if); |
| 369 |
LIST_REMOVE(sc, sl_next); |
| 370 |
MCLFREE((caddr_t)(sc->sc_ep - SLBUFSIZE)); |
| 371 |
FREE(sc, M_SL); |
| 307 |
} |
372 |
} |
| 308 |
|
373 |
|
| 309 |
/* |
374 |
/* |
|
Lines 338-350
Link Here
|
| 338 |
untimeout(sl_keepalive, sc, sc->sc_kahandle); |
403 |
untimeout(sl_keepalive, sc, sc->sc_kahandle); |
| 339 |
} |
404 |
} |
| 340 |
if_down(&sc->sc_if); |
405 |
if_down(&sc->sc_if); |
| 341 |
sc->sc_flags &= SC_STATIC; |
|
|
| 342 |
sc->sc_ttyp = NULL; |
406 |
sc->sc_ttyp = NULL; |
| 343 |
tp->t_sc = NULL; |
407 |
tp->t_sc = NULL; |
| 344 |
MCLFREE((caddr_t)(sc->sc_ep - SLBUFSIZE)); |
408 |
sldestroy(sc); |
| 345 |
sc->sc_ep = 0; |
|
|
| 346 |
sc->sc_mp = 0; |
| 347 |
sc->sc_buf = 0; |
| 348 |
} |
409 |
} |
| 349 |
splx(s); |
410 |
splx(s); |
| 350 |
return 0; |
411 |
return 0; |
|
Lines 363-370
Link Here
|
| 363 |
int flag; |
424 |
int flag; |
| 364 |
struct proc *p; |
425 |
struct proc *p; |
| 365 |
{ |
426 |
{ |
| 366 |
struct sl_softc *sc = (struct sl_softc *)tp->t_sc, *nc, *tmpnc; |
427 |
struct sl_softc *sc = (struct sl_softc *)tp->t_sc, *nc; |
| 367 |
int s, nsl; |
428 |
int s, unit, wasup; |
| 368 |
|
429 |
|
| 369 |
s = splimp(); |
430 |
s = splimp(); |
| 370 |
switch (cmd) { |
431 |
switch (cmd) { |
|
Lines 373-416
Link Here
|
| 373 |
break; |
434 |
break; |
| 374 |
|
435 |
|
| 375 |
case SLIOCSUNIT: |
436 |
case SLIOCSUNIT: |
| 376 |
if (sc->sc_if.if_unit != *(u_int *)data) { |
437 |
unit = *(u_int *)data; |
| 377 |
for (nsl = NSL, nc = sl_softc; --nsl >= 0; nc++) { |
438 |
if (unit < 0) { |
| 378 |
if ( nc->sc_if.if_unit == *(u_int *)data |
439 |
splx(s); |
| 379 |
&& nc->sc_ttyp == NULL |
440 |
return (ENXIO); |
| 380 |
) { |
441 |
} |
| 381 |
tmpnc = malloc(sizeof *tmpnc, M_TEMP, |
442 |
if (sc->sc_if.if_unit != unit) { |
| 382 |
M_NOWAIT); |
443 |
LIST_FOREACH(nc, &sl_list, sl_next) { |
| 383 |
if (tmpnc == NULL) { |
444 |
if (nc->sc_if.if_unit == *(u_int *)data) { |
| 384 |
splx(s); |
445 |
splx(s); |
| 385 |
return (ENOMEM); |
446 |
return (ENXIO); |
| 386 |
} |
|
|
| 387 |
*tmpnc = *nc; |
| 388 |
*nc = *sc; |
| 389 |
nc->sc_if = tmpnc->sc_if; |
| 390 |
tmpnc->sc_if = sc->sc_if; |
| 391 |
*sc = *tmpnc; |
| 392 |
free(tmpnc, M_TEMP); |
| 393 |
if (sc->sc_if.if_flags & IFF_UP) { |
| 394 |
if_down(&sc->sc_if); |
| 395 |
if (!(nc->sc_if.if_flags & IFF_UP)) |
| 396 |
if_up(&nc->sc_if); |
| 397 |
} else if (nc->sc_if.if_flags & IFF_UP) |
| 398 |
if_down(&nc->sc_if); |
| 399 |
sc->sc_flags &= ~SC_STATIC; |
| 400 |
sc->sc_flags |= (nc->sc_flags & SC_STATIC); |
| 401 |
tp->t_sc = sc = nc; |
| 402 |
clist_alloc_cblocks(&tp->t_outq, |
| 403 |
SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, |
| 404 |
SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); |
| 405 |
sl_compress_init(&sc->sc_comp, -1); |
| 406 |
goto slfound; |
| 407 |
} |
447 |
} |
| 408 |
} |
448 |
} |
| 409 |
splx(s); |
449 |
|
| 410 |
return (ENXIO); |
450 |
wasup = sc->sc_if.if_flags & IFF_UP; |
|
|
451 |
bpfdetach(&sc->sc_if); |
| 452 |
if_detach(&sc->sc_if); |
| 453 |
LIST_REMOVE(sc, sl_next); |
| 454 |
sc->sc_if.if_unit = unit; |
| 455 |
LIST_INSERT_HEAD(&sl_list, sc, sl_next); |
| 456 |
if_attach(&sc->sc_if); |
| 457 |
bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN); |
| 458 |
if (wasup) |
| 459 |
if_up(&sc->sc_if); |
| 460 |
else |
| 461 |
if_down(&sc->sc_if); |
| 462 |
clist_alloc_cblocks(&tp->t_outq, |
| 463 |
SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, |
| 464 |
SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); |
| 411 |
} |
465 |
} |
| 412 |
slfound: |
466 |
slmarkstatic(unit); |
| 413 |
sc->sc_flags |= SC_STATIC; |
|
|
| 414 |
break; |
467 |
break; |
| 415 |
|
468 |
|
| 416 |
case SLIOCSKEEPAL: |
469 |
case SLIOCSKEEPAL: |
|
Lines 470-476
Link Here
|
| 470 |
struct sockaddr *dst; |
523 |
struct sockaddr *dst; |
| 471 |
struct rtentry *rtp; |
524 |
struct rtentry *rtp; |
| 472 |
{ |
525 |
{ |
| 473 |
register struct sl_softc *sc = &sl_softc[ifp->if_unit]; |
526 |
register struct sl_softc *sc = ifp->if_softc; |
| 474 |
register struct ip *ip; |
527 |
register struct ip *ip; |
| 475 |
register struct ifqueue *ifq; |
528 |
register struct ifqueue *ifq; |
| 476 |
int s; |
529 |
int s; |
|
Lines 936-941
Link Here
|
| 936 |
register struct ifaddr *ifa = (struct ifaddr *)data; |
989 |
register struct ifaddr *ifa = (struct ifaddr *)data; |
| 937 |
register struct ifreq *ifr = (struct ifreq *)data; |
990 |
register struct ifreq *ifr = (struct ifreq *)data; |
| 938 |
register int s, error = 0; |
991 |
register int s, error = 0; |
|
|
992 |
struct sl_softc *sc = ifp->if_softc; |
| 939 |
|
993 |
|
| 940 |
s = splimp(); |
994 |
s = splimp(); |
| 941 |
|
995 |
|
|
Lines 946-952
Link Here
|
| 946 |
* if.c will set the interface up even if we |
1000 |
* if.c will set the interface up even if we |
| 947 |
* don't want it to. |
1001 |
* don't want it to. |
| 948 |
*/ |
1002 |
*/ |
| 949 |
if (sl_softc[ifp->if_unit].sc_ttyp == NULL) { |
1003 |
if (sc->sc_ttyp == NULL) { |
| 950 |
ifp->if_flags &= ~IFF_UP; |
1004 |
ifp->if_flags &= ~IFF_UP; |
| 951 |
} |
1005 |
} |
| 952 |
break; |
1006 |
break; |
|
Lines 956-962
Link Here
|
| 956 |
* setting the address. |
1010 |
* setting the address. |
| 957 |
*/ |
1011 |
*/ |
| 958 |
if (ifa->ifa_addr->sa_family == AF_INET) { |
1012 |
if (ifa->ifa_addr->sa_family == AF_INET) { |
| 959 |
if (sl_softc[ifp->if_unit].sc_ttyp != NULL) |
1013 |
if (sc->sc_ttyp != NULL) |
| 960 |
ifp->if_flags |= IFF_UP; |
1014 |
ifp->if_flags |= IFF_UP; |
| 961 |
} else { |
1015 |
} else { |
| 962 |
error = EAFNOSUPPORT; |
1016 |
error = EAFNOSUPPORT; |
|
Lines 982-988
Link Here
|
| 982 |
struct tty *tp; |
1036 |
struct tty *tp; |
| 983 |
|
1037 |
|
| 984 |
ifp->if_mtu = ifr->ifr_mtu; |
1038 |
ifp->if_mtu = ifr->ifr_mtu; |
| 985 |
tp = sl_softc[ifp->if_unit].sc_ttyp; |
1039 |
tp = sc->sc_ttyp; |
| 986 |
if (tp != NULL) |
1040 |
if (tp != NULL) |
| 987 |
clist_alloc_cblocks(&tp->t_outq, |
1041 |
clist_alloc_cblocks(&tp->t_outq, |
| 988 |
SLIP_HIWAT + 2 * ifp->if_mtu + 1, |
1042 |
SLIP_HIWAT + 2 * ifp->if_mtu + 1, |