home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / IFACE.C < prev    next >
C/C++ Source or Header  |  1994-07-05  |  18KB  |  667 lines

  1. /* IP interface control and configuration routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by PA0GRI
  5.  */
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "proc.h"
  9. #include "iface.h"
  10. #include "ip.h"
  11. #include "netuser.h"
  12. #include "ax25.h"
  13. #include "enet.h"
  14. #include "arp.h"
  15. #include "pktdrvr.h"
  16. #include "cmdparse.h"
  17. #include "commands.h"
  18. #include "nr4.h"
  19. #include "socket.h"
  20. #include "mailbox.h"
  21.   
  22. #ifdef NETROM
  23. extern struct iface *Nr_iface;
  24. extern char Nralias[];
  25. #endif
  26.   
  27. static void showiface __ARGS((struct iface *ifp));
  28. int mask2width __ARGS((int32 mask));
  29. static int ifipaddr __ARGS((int argc,char *argv[],void *p));
  30. static int iflinkadr __ARGS((int argc,char *argv[],void *p));
  31. static int ifbroad __ARGS((int argc,char *argv[],void *p));
  32. static int ifnetmsk __ARGS((int argc,char *argv[],void *p));
  33. static int ifrxbuf __ARGS((int argc,char *argv[],void *p));
  34. static int ifmtu __ARGS((int argc,char *argv[],void *p));
  35. static int ifforw __ARGS((int argc,char *argv[],void *p));
  36. static int ifencap __ARGS((int argc,char *argv[],void *p));
  37. static int ifdescr __ARGS((int argc,char *argv[],void *p));
  38.   
  39. struct iftcp def_iftcp = {DEF_RTT,0L,DEF_WND,DEF_MSS,31,DEF_RETRIES,0,0};
  40.   
  41. /* Interface list header */
  42. struct iface *Ifaces = &Loopback;
  43.   
  44. /* Loopback pseudo-interface */
  45. struct iface Loopback = {
  46. #ifdef ENCAP
  47.     &Encap,     /* Link to next entry */
  48. #else
  49.     NULLIF,
  50. #endif
  51.     "loopback", /* name     */
  52.     NULLCHAR,   /* description */
  53.     0x7f000001L,    /* addr         127.0.0.1 */
  54.     0xffffffffL,    /* broadcast    255.255.255.255 */
  55.     0xffffffffL,    /* netmask      255.255.255.255 */
  56.     MAXINT16,       /* mtu          No limit */
  57.     0,      /* flags    */
  58. #ifdef NETROM
  59.     0,      /* quality  */
  60.     0,      /* autofloor */
  61. #endif
  62.     0,              /* trace        */
  63.     NULLCHAR,       /* trfile       */
  64.     NULLFILE,       /* trfp         */
  65.     NULLIF,         /* forw         */
  66.     NULLPROC,       /* rxproc       */
  67.     NULLPROC,       /* txproc       */
  68.     NULLPROC,       /* supv         */
  69.     0,              /* dev          */
  70.     NULL,           /* (*ioctl)     */
  71.     NULLFP,         /* (*iostatus)  */
  72.     NULLFP,         /* (*stop)      */
  73.     NULLCHAR,       /* hwaddr       */
  74. #ifdef AX25
  75.     NULL,           /* ax25 protocol data */
  76. #endif /* AX25 */
  77.     &def_iftcp,     /* tcp protocol data */
  78.     NULL,           /* extension    */
  79.     CL_NONE,        /* type         */
  80.     0,              /* xdev         */
  81.     0,              /* port         */
  82.     &Iftypes[0],    /* iftype       */
  83.     NULLFP,         /* (*send)      */
  84.     NULLFP,         /* (*output)    */
  85.     NULLFP,         /* (*raw)       */
  86.     NULLVFP,        /* (*show)      */
  87.     NULLFP,         /* (*discard)   */
  88.     NULLFP,         /* (*echo)      */
  89.     0,              /* ipsndcnt     */
  90.     0,              /* rawsndcnt    */
  91.     0,              /* iprecvcnt    */
  92.     0,              /* rawrcvcnt    */
  93.     0,              /* lastsent     */
  94.     0,              /* lastrecv     */
  95. };
  96.   
  97. #ifdef ENCAP
  98. /* Encapsulation pseudo-interface */
  99. struct iface Encap = {
  100.     NULLIF,
  101.     "encap",        /* name         */
  102.     NULLCHAR,   /* description */
  103.     INADDR_ANY,     /* addr         0.0.0.0 */
  104.     0xffffffffL,    /* broadcast    255.255.255.255 */
  105.     0xffffffffL,    /* netmask      255.255.255.255 */
  106.     MAXINT16,       /* mtu          No limit */
  107.     0,      /* flags    */
  108. #ifdef NETROM
  109.     0,      /* quality  */
  110.     0,      /* autofloor */
  111. #endif
  112.     0,              /* trace        */
  113.     NULLCHAR,       /* trfile       */
  114.     NULLFILE,       /* trfp         */
  115.     NULLIF,         /* forw         */
  116.     NULLPROC,       /* rxproc       */
  117.     NULLPROC,       /* txproc       */
  118.     NULLPROC,       /* supv         */
  119.     0,              /* dev          */
  120.     NULL,           /* (*ioctl)     */
  121.     NULLFP,         /* (*iostatus)  */
  122.     NULLFP,         /* (*stop)      */
  123.     NULLCHAR,       /* hwaddr       */
  124. #ifdef AX25
  125.     NULL,           /* ax.25 protocol data */
  126. #endif
  127.     &def_iftcp,     /* tcp protocol data */
  128.     NULL,           /* extension    */
  129.     CL_NONE,        /* type         */
  130.     0,              /* xdev         */
  131.     0,              /* port         */
  132.     &Iftypes[0],    /* iftype       */
  133.     ip_encap,       /* (*send)      */
  134.     NULLFP,         /* (*output)    */
  135.     NULLFP,         /* (*raw)       */
  136.     NULLVFP,        /* (*show)      */
  137.     NULLFP,         /* (*discard)   */
  138.     NULLFP,         /* (*echo)      */
  139.     0,              /* ipsndcnt     */
  140.     0,              /* rawsndcnt    */
  141.     0,              /* iprecvcnt    */
  142.     0,              /* rawrcvcnt    */
  143.     0,              /* lastsent     */
  144.     0,              /* lastrecv     */
  145. };
  146. #endif /*ENCAP*/
  147.   
  148. char Noipaddr[] = "IP address field missing, and ip address not set\n";
  149.   
  150. struct cmds DFAR Ifcmds[] = {
  151. #ifdef AX25
  152.     "ax25",                 ifax25,         0,      0,      NULLCHAR,
  153. #endif
  154.     "broadcast",            ifbroad,        0,      2,      NULLCHAR,
  155.     "description",          ifdescr,        0,      2,      NULLCHAR,
  156.     "encapsulation",        ifencap,        0,      2,      NULLCHAR,
  157.     "forward",              ifforw,         0,      2,      NULLCHAR,
  158.     "ipaddress",            ifipaddr,       0,      2,      NULLCHAR,
  159.     "linkaddress",          iflinkadr,      0,      2,      NULLCHAR,
  160.     "mtu",                  ifmtu,          0,      2,      NULLCHAR,
  161.     "netmask",              ifnetmsk,       0,      2,      NULLCHAR,
  162. #ifdef notdef
  163.     "rxbuf",        ifrxbuf,    0,  2,  NULLCHAR,
  164. #endif
  165.     "tcp",                  doiftcp,        0,      0,      NULLCHAR,
  166.     NULLCHAR,
  167. };
  168.   
  169. /* Set interface parameters */
  170. int
  171. doifconfig(argc,argv,p)
  172. int argc;
  173. char *argv[];
  174. void *p;
  175. {
  176.     struct iface *ifp;
  177.     int i;
  178.   
  179.     if(argc < 2){
  180.         for(ifp = Ifaces;ifp != NULLIF;ifp = ifp->next)
  181.             showiface(ifp);
  182.         return 0;
  183.     }
  184.     if((ifp = if_lookup(argv[1])) == NULLIF){
  185.         tprintf(Badinterface,argv[1]);
  186.         return 1;
  187.     }
  188.     if(argc == 2){
  189.         showiface(ifp);
  190.         if ( ifp->show != NULLVFP ) {
  191.             (*ifp->show)(ifp);
  192.         }
  193.         return 0;
  194.     }
  195.   
  196.     return subcmd(Ifcmds,argc-1,&argv[1],ifp);
  197.   
  198. #ifdef notdef
  199.     if(argc == 3){
  200.         tputs("Argument missing\n");
  201.         return 1;
  202.     }
  203.     for(i=2;i<argc-1;i+=2)
  204.         subcmd(Ifcmds,3,&argv[i-1],ifp);
  205.   
  206.     return 0;
  207. #endif
  208. }
  209.   
  210. /* Set interface IP address */
  211. static int
  212. ifipaddr(argc,argv,p)
  213. int argc;
  214. char *argv[];
  215. void *p;
  216. {
  217.     struct iface *ifp = p;
  218.   
  219.     /* Do not allow loopback iface to be changed ! - WG7J */
  220.     if(ifp == &Loopback) {
  221.         tputs("Cannot change IP address !\n");
  222.         return 0;
  223.     }
  224.     ifp->addr = resolve(argv[1]);
  225.     return 0;
  226. }
  227.   
  228. /* Set link (hardware) address */
  229. static int
  230. iflinkadr(argc,argv,p)
  231. int argc;
  232. char *argv[];
  233. void *p;
  234. {
  235.     struct iface *ifp = p;
  236.   
  237.     if(ifp->iftype == NULLIFT || ifp->iftype->scan == NULL){
  238.         tputs("Can't set link address\n");
  239.         return 1;
  240.     }
  241.     if(ifp->hwaddr != NULLCHAR)
  242.         free(ifp->hwaddr);
  243.     ifp->hwaddr = mallocw(ifp->iftype->hwalen);
  244.     (*ifp->iftype->scan)(ifp->hwaddr,argv[1]);
  245. #ifdef MAILBOX
  246. #ifdef NETROM
  247.     if(ifp == Nr_iface) /*the netrom call just got changed! - WG7J*/
  248.         setmbnrid();
  249. #endif
  250. #endif
  251.     return 0;
  252. }
  253.   
  254. /* Set interface broadcast address. This is actually done
  255.  * by installing a private entry in the routing table.
  256.  */
  257. static int
  258. ifbroad(argc,argv,p)
  259. int argc;
  260. char *argv[];
  261. void *p;
  262. {
  263.     struct iface *ifp = p;
  264.     struct route *rp;
  265.   
  266.     rp = rt_blookup(ifp->broadcast,32);
  267.     if(rp != NULLROUTE && rp->iface == ifp)
  268.         rt_drop(ifp->broadcast,32);
  269.     ifp->broadcast = resolve(argv[1]);
  270.     rt_add(ifp->broadcast,32,0L,ifp,1L,0L,1);
  271.     return 0;
  272. }
  273.   
  274. /* Set the network mask. This is actually done by installing
  275.  * a routing entry.
  276.  */
  277. static int
  278. ifnetmsk(argc,argv,p)
  279. int argc;
  280. char *argv[];
  281. void *p;
  282. {
  283.     struct iface *ifp = p;
  284.     struct route *rp;
  285.   
  286.     /* Remove old entry if it exists */
  287.     rp = rt_blookup(ifp->addr & ifp->netmask,mask2width(ifp->netmask));
  288.     if(rp != NULLROUTE)
  289.         rt_drop(rp->target,rp->bits);
  290.   
  291.     ifp->netmask = htol(argv[1]);
  292.     rt_add(ifp->addr,mask2width(ifp->netmask),0L,ifp,0L,0L,0);
  293.     return 0;
  294. }
  295.   
  296. /* Command to set interface encapsulation mode */
  297. static int
  298. ifencap(argc,argv,p)
  299. int argc;
  300. char *argv[];
  301. void *p;
  302. {
  303.     struct iface *ifp = p;
  304.   
  305.     if(setencap(ifp,argv[1]) != 0){
  306.         tprintf("Encapsulation mode '%s' unknown\n",argv[1]);
  307.         return 1;
  308.     }
  309.     return 0;
  310. }
  311. /* Function to set encapsulation mode */
  312. int
  313. setencap(ifp,mode)
  314. struct iface *ifp;
  315. char *mode;
  316. {
  317.     struct iftype *ift;
  318.   
  319.     if(mode != NULL) {
  320.         /* Configure the whole interface */
  321.         for(ift = &Iftypes[0];ift->name != NULLCHAR;ift++)
  322.             if(strnicmp(ift->name,mode,strlen(mode)) == 0)
  323.                 break;
  324.         if(ift->name == NULLCHAR){
  325.             return -1;
  326.         }
  327.         ifp->iftype = ift;
  328.         ifp->send = ift->send;
  329.         ifp->output = ift->output;
  330.         ifp->type = ift->type;
  331.     }
  332.     /* Set the tcp and ax25 interface parameters */
  333.     if(!ifp->tcp)
  334.         ifp->tcp = callocw(1,sizeof(struct iftcp));
  335.     init_iftcp(ifp->tcp);
  336. #ifdef AX25
  337.     if(ift->type == CL_AX25) {
  338.         if(!ifp->ax25)
  339.             ifp->ax25 = callocw(1,sizeof(struct ifax25));
  340.         init_ifax25(ifp->ax25);
  341.         ifp->flags |= AX25_BEACON|MAIL_BEACON|AX25_DIGI|LOG_AXHEARD|LOG_IPHEARD;
  342.     }
  343. #endif
  344.     return 0;
  345. }
  346.   
  347. #ifdef notdef
  348. /* Set interface receive buffer size */
  349. static int
  350. ifrxbuf(argc,argv,p)
  351. int argc;
  352. char *argv[];
  353. void *p;
  354. {
  355.     return 0;       /* To be written */
  356. }
  357. #endif
  358.   
  359. /* Set interface Maximum Transmission Unit */
  360. static int
  361. ifmtu(argc,argv,p)
  362. int argc;
  363. char *argv[];
  364. void *p;
  365. {
  366.     struct iface *ifp = p;
  367.   
  368.     ifp->mtu = atoi(argv[1]);
  369. #ifdef NETROM
  370.     /* Make sure NETROM mtu <= 236 ! - WG7J */
  371.     if(ifp == Nr_iface)
  372.         if(Nr_iface->mtu > NR4MAXINFO)
  373.             Nr_iface->mtu = NR4MAXINFO;
  374. #endif
  375.     return 0;
  376. }
  377.   
  378. /* Set interface forwarding */
  379. static int
  380. ifforw(argc,argv,p)
  381. int argc;
  382. char *argv[];
  383. void *p;
  384. {
  385.     struct iface *ifp = p;
  386.   
  387.     ifp->forw = if_lookup(argv[1]);
  388.     if(ifp->forw == ifp)
  389.         ifp->forw = NULLIF;
  390.     return 0;
  391. }
  392.   
  393. /*give a little description for each interface - WG7J*/
  394. static int
  395. ifdescr(argc,argv,p)
  396. int argc;
  397. char *argv[];
  398. void *p;
  399. {
  400.     struct iface *ifp = p;
  401.   
  402. #ifdef NETROM
  403. #ifdef ENCAP
  404.     if((ifp == &Loopback) || (ifp == &Encap) || (ifp == Nr_iface))
  405. #else
  406.         if((ifp == &Loopback) || (ifp == Nr_iface))
  407. #endif /*ENCAP*/
  408. #else  /*NETROM*/
  409. #ifdef ENCAP
  410.             if((ifp == &Loopback) || (ifp == &Encap))
  411. #else
  412.                 if(ifp == &Loopback)
  413. #endif /*ENCAP*/
  414. #endif /*NETROM*/
  415.                     return 0;
  416.   
  417.     if(ifp->descr != NULLCHAR){
  418.         free(ifp->descr);
  419.         ifp->descr = NULLCHAR;        /* reset the pointer */
  420.     }
  421.     if(!strlen(argv[1]))
  422.         return 0;           /* clearing the buffer */
  423.   
  424.     ifp->descr = mallocw(strlen(argv[1])+5); /* allow for the EOL char etc */
  425.     strcpy(ifp->descr, argv[1]);
  426.     strcat(ifp->descr, "\n");         /* add the EOL char */
  427.   
  428.     return 0;
  429. }
  430.   
  431. /* Display the parameters for a specified interface */
  432. static void
  433. showiface(ifp)
  434. register struct iface *ifp;
  435. {
  436.     char tmp[25];
  437.   
  438.     tprintf("%-8s IP addr %s MTU %u Link encap ",ifp->name,
  439.     inet_ntoa(ifp->addr),(int)ifp->mtu);
  440.     if(ifp->iftype == NULLIFT){
  441.         tputs("not set\n");
  442.     } else {
  443.         tprintf("%s\n",ifp->iftype->name);
  444.         if(ifp->iftype->format != NULL && ifp->hwaddr != NULLCHAR) {
  445.             tprintf("         Link addr %s",
  446.             (*ifp->iftype->format)(tmp,ifp->hwaddr));
  447. #ifdef AX25
  448.             if(ifp->iftype->type == CL_AX25) {
  449. #ifdef MAILBOX
  450.                 tprintf("   BBS %s",pax25(tmp,ifp->ax25->bbscall));
  451. #endif
  452.                 if(ifp->ax25->cdigi)
  453.                     tprintf("   Cdigi %s",pax25(tmp,ifp->ax25->cdigi));
  454.                 tprintf("   Paclen %d   Irtt %lu\n",(int)ifp->ax25->paclen, \
  455.                 ifp->ax25->irtt);
  456.                 if(ifp->ax25->bctext)
  457.                     tprintf("         BCText: %s\n",ifp->ax25->bctext);
  458.             }
  459. #endif
  460. #ifdef NETROM
  461.             else if(ifp == Nr_iface) {
  462.                 tprintf("   Alias %s\n",Nralias);
  463.             }
  464. #endif
  465. #if((defined AX25) || (defined NETROM))
  466.             else
  467. #endif
  468.                 tputc('\n');
  469.         }
  470.     }
  471.     tprintf("         flags 0x%lx trace 0x%x netmask 0x%08lx broadcast %s\n",
  472.     ifp->flags,ifp->trace,ifp->netmask,inet_ntoa(ifp->broadcast));
  473.     if(ifp->forw != NULLIF)
  474.         tprintf("         output forward to %s\n",ifp->forw->name);
  475.     tprintf("         sent: ip %lu tot %lu idle %s\n",
  476.     ifp->ipsndcnt,ifp->rawsndcnt,tformat(secclock() - ifp->lastsent));
  477.     tprintf("         recv: ip %lu tot %lu idle %s\n",
  478.     ifp->iprecvcnt,ifp->rawrecvcnt,tformat(secclock() - ifp->lastrecv));
  479.     if(ifp->descr != NULLCHAR)
  480.         tprintf("         descr: %s",ifp->descr);
  481.   
  482. }
  483.   
  484. /* Command to detach an interface */
  485. int
  486. dodetach(argc,argv,p)
  487. int argc;
  488. char *argv[];
  489. void *p;
  490. {
  491.     register struct iface *ifp;
  492.   
  493.     if((ifp = if_lookup(argv[1])) == NULLIF){
  494.         tprintf(Badinterface,argv[1]);
  495.         return 1;
  496.     }
  497.     if(if_detach(ifp) == -1)
  498.         tputs("Can't detach loopback or encap interface\n");
  499.     return 0;
  500. }
  501. /* Detach a specified interface */
  502. int
  503. if_detach(ifp)
  504. struct iface *ifp;
  505. {
  506.     struct iface *iftmp;
  507.     struct route *rp,*rptmp;
  508.     int i,j;
  509.     struct ax_route *axr, *axr1;
  510.     struct arp_tab *ap, *ap1;
  511.   
  512. #ifdef ENCAP
  513.     if(ifp == &Loopback || ifp == &Encap)
  514. #else
  515.         if(ifp == &Loopback)
  516. #endif
  517.             return -1;
  518.   
  519. #ifdef AX25
  520.     /* Drop all ax25 routes that points to this interface */
  521.     for(axr = Ax_routes; axr != NULLAXR; axr = axr1) {
  522.         axr1 = axr->next;/* Save the next pointer */
  523.         if(axr->iface == ifp)
  524.             ax_drop(axr->target, ifp);
  525.         /* axr will be undefined after ax_drop() */
  526.     }
  527. #endif
  528.   
  529.     /* Drop all ARP's that point to this interface */
  530.     for(i = 0; i < HASHMOD; ++i)
  531.         for(ap = Arp_tab[i]; ap != NULLARP; ap = ap1) {
  532.             ap1 = ap->next; /* Save the next pointer */
  533.             if(ap->iface == ifp)
  534.                 arp_drop(ap);
  535.         /* ap will be undefined after arp_drop() */
  536.         }
  537.   
  538.   
  539.     /* Drop all routes that point to this interface */
  540.     if(R_default.iface == ifp)
  541.         rt_drop(0L,0);  /* Drop default route */
  542.   
  543.     for(i=0;i<HASHMOD;i++){
  544.         for(j=0;j<32;j++){
  545.             for(rp = Routes[j][i];rp != NULLROUTE;rp = rptmp){
  546.                 /* Save next pointer in case we delete this entry */
  547.                 rptmp = rp->next;
  548.                 if(rp->iface == ifp)
  549.                     rt_drop(rp->target,rp->bits);
  550.             }
  551.         }
  552.     }
  553.     /* Unforward any other interfaces forwarding to this one */
  554.     for(iftmp = Ifaces;iftmp != NULLIF;iftmp = iftmp->next){
  555.         if(iftmp->forw == ifp)
  556.             iftmp->forw = NULLIF;
  557.     }
  558.   
  559.     /* Call device shutdown routine, if any */
  560.     if(ifp->stop != NULLFP)
  561.         (*ifp->stop)(ifp);
  562.   
  563.     killproc(ifp->rxproc);
  564.     killproc(ifp->txproc);
  565.     killproc(ifp->supv);
  566.   
  567.     /* Free allocated memory associated with this interface */
  568.     free(ifp->name);
  569.     free(ifp->hwaddr);
  570.     free(ifp->tcp);
  571. #ifdef AX25
  572.     if(ifp->ax25) {
  573.         free(ifp->ax25->bctext);
  574.         free(ifp->ax25);
  575.     }
  576. #endif
  577.     free(ifp->descr);
  578.   
  579.     /* Remove from interface list */
  580.     if(ifp == Ifaces){
  581.         Ifaces = ifp->next;
  582.     } else {
  583.         /* Search for entry just before this one
  584.          * (necessary because list is only singly-linked.)
  585.          */
  586.         for(iftmp = Ifaces;iftmp != NULLIF ;iftmp = iftmp->next)
  587.             if(iftmp->next == ifp)
  588.                 break;
  589.         if(iftmp != NULLIF && iftmp->next == ifp)
  590.             iftmp->next = ifp->next;
  591.     }
  592.     /* Finally free the structure itself */
  593.     free((char *)ifp);
  594.     return 0;
  595. }
  596.   
  597. /* Given the ascii name of an interface, return a pointer to the structure,
  598.  * or NULLIF if it doesn't exist
  599.  */
  600. struct iface *
  601. if_lookup(name)
  602. char *name;
  603. {
  604.     register struct iface *ifp;
  605.   
  606.     for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  607.         if(stricmp(ifp->name,name) == 0)
  608.             break;
  609.     return ifp;
  610. }
  611.   
  612. /* Return iface pointer if 'addr' belongs to one of our interfaces,
  613.  * NULLIF otherwise.
  614.  * This is used to tell if an incoming IP datagram is for us, or if it
  615.  * has to be routed.
  616.  */
  617. struct iface *
  618. ismyaddr(addr)
  619. int32 addr;
  620. {
  621.     register struct iface *ifp;
  622.   
  623.     for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  624.         if(addr == ifp->addr)
  625.             break;
  626.     return ifp;
  627. }
  628.   
  629. /* Given a network mask, return the number of contiguous 1-bits starting
  630.  * from the most significant bit.
  631.  */
  632. int
  633. mask2width(mask)
  634. int32 mask;
  635. {
  636.     int width,i;
  637.   
  638.     width = 0;
  639.     for(i = 31;i >= 0;i--){
  640.         if(!(mask & (1L << i)))
  641.             break;
  642.         width++;
  643.     }
  644.     return width;
  645. }
  646.   
  647. /* return buffer with name + comment */
  648. char *
  649. if_name(ifp,comment)
  650. struct iface *ifp;
  651. char *comment;
  652. {
  653.     char *result = mallocw( strlen(ifp->name) + strlen(comment) + 1 );
  654.     strcpy( result, ifp->name );
  655.     return strcat( result, comment );
  656. }
  657.   
  658. /* Raw output routine that tosses all packets. Used by dialer, tip, etc */
  659. int
  660. bitbucket(ifp,bp)
  661. struct iface *ifp;
  662. struct mbuf *bp;
  663. {
  664.     free_p(bp);
  665.     return 0;
  666. }
  667.