Exemplo n.º 1
0
int main(int argc, char *argv[], char *envp[])
{
  register char    *pl, *pr, *p, x;
#ifdef AK
  auto     FILE    *f = fopen("/www/log/isdn.log", "r");
#else
  auto     FILE    *f = fopen("/var/log/isdn.log", "r");
#endif
  auto     char     s[BUFSIZ], sx[BUFSIZ];
  auto     int      i, l, col, day, lday = UNKNOWN, month, lmonth = UNKNOWN;
  auto     double   dur;
  auto     char    *version;
  auto     char    *myname = basename(argv[0]);
  auto     int      opt, go, s0, indent;
  auto	   time_t   now;
  auto 	   struct   tm *tm;


  if (f != (FILE *)NULL) {

    while ((opt = getopt(argc, argv, options)) != EOF)
      switch (opt) {
        case 'n' : onlynumbers++;
                   break;

        case 'v' : verbose = atoi(optarg);
                   break;

        case 'V' : print_version(myname);
                   exit(0);

        case 'i' : showincoming++;
                   break;

        case 'o' : showoutgoing++;
                   break;

        case 'e' : showerrors++;
                   break;

        case 'a' : showincoming = showoutgoing = showerrors = 1;
                   break;

        case 'N' : strcpy(onlythis, optarg);
                   break;

        case 'm' : netto++;
             	   break;

        case 'f' : force++;
             	   break;

        case 't' : onlytoday++;
             	   break;

        case 'I' : onlyInternal++;
             	   break;

        case 'E' : onlyExternal++;
             	   break;

        case '?' : printf(usage, argv[0], argv[0], options);
                   return(1);
      } /* switch */

    if (!showincoming && !showoutgoing && !showerrors) {
      printf("This makes no sense! You must specify -i, -o or -e\n");
      printf("\t-a    -> alle Verbindungen anzeigen i.e. \"-ioe\"\n");
      printf("\t      -> show all connections\n");
      printf("\t-e    -> nichtzustandegekommene Verbindungen anzeigen\n");
      printf("\t      -> show incomplete calls\n");
      printf("\t-f    -> Verbindungsentgeld _immer_ neu berechnen\n");
      printf("\t      -> recalculate costs _always_\n");
      printf("\t-i    -> reinkommende Verbindungen anzeigen\n");
      printf("\t      -> show incoming calls\n");
      printf("\t-m    -> ohne MwSt anzeigen\n");
      printf("\t      -> prices without VAT\n");
      printf("\t-n    -> _nicht_ anstelle Rufnummern Alias-Bezeichnungen anzeigen\n");
      printf("\t      -> do _not_ replace numbers with aliases\n");
      printf("\t-o    -> rausgehende Verbindungen anzeigen\n");
      printf("\t      -> show outgoing calls\n");
      printf("\t-t    -> nur die heutigen Verbindungen anzeigen\n");
      printf("\t      -> show only current connections\n");
      printf("\t-vn   -> Verbose Level\n");
      printf("\t-Nnnn -> nur Verbindungen mit _dieser_ Rufnummer anzeigen\n");
      printf("\t      -> show only calls with the specified number\n");
      printf("\t-I    -> nur Verbindungen am Internen S0-Bus anzeigen\n");
      printf("\t      -> show only calls on the internal S0 bus\n");
      printf("\t-E    -> nur Verbindungen am Externen S0-Bus anzeigen\n");
      printf("\t      -> show only calls on the external S0 bus\n");
      printf("\t-V    -> Version anzeigen\n");
      printf("\t      -> show version\n");

      return(1);
    } /* if */

    *home = 0;

    interns0 = 3;

    set_print_fct_for_tools(print_in_modules);

    if (!readconfig(myname)) {

      initHoliday(holifile, &version);

      if (verbose)
        fprintf(stderr, "%s\n", version);

      initDest(destfile, &version);

      if (verbose)
        fprintf(stderr, "%s\n", version);

      initRate(rateconf, ratefile, zonefile, &version);

      if (verbose)
        fprintf(stderr, "%s\n", version);

      memset(&msnsum, 0, sizeof(msnsum));
      memset(&provsum, 0, sizeof(provsum));
      memset(&zonesum, 0, sizeof(zonesum));

      partner[0] = (PARTNER *)calloc(knowns, sizeof(PARTNER));
      partner[1] = (PARTNER *)calloc(knowns, sizeof(PARTNER));

      time(&now);
      tm = localtime(&now);
      tm->tm_sec = tm->tm_min = tm->tm_hour = 0;
      now = mktime(tm);

      while (fgets(s, BUFSIZ, f)) {
        pl = s;
        col = 0;

        memset(&c, 0, sizeof(c));

        while ((pr = strchr(pl, '|'))) {
          memcpy(sx, pl, (l = (pr - pl)));
          sx[l] = 0;
          pl = pr + 1;

          switch (col++) {
            case  0 :                               break;

            case  1 : deb(sx);
                      strcpy(c.num[CALLING], sx);
                      break;

            case  2 : deb(sx);
                      strcpy(c.num[CALLED], sx);
                      break;

            case  3 : dur = atoi(sx);               break;

            case  4 : c.duration = atol(sx) / 100;
                      break;

            case  5 : c.connect = atol(sx);         break;
            case  6 : c.units = atoi(sx);           break;
            case  7 : c.dialout = *sx == 'O';       break;
            case  8 : c.cause = atoi(sx);           break;
            case  9 : c.ibytes = atoi(sx);          break;
            case 10 : c.obytes = atoi(sx);          break;
            case 11 : strcpy(c.version, sx);        break;
            case 12 : c.si1 = atoi(sx);             break;
            case 13 : c.si2 = atoi(sx);             break;
            case 14 : c.currency_factor = atof(sx); break;
            case 15 : strcpy(c.currency, sx);       break;
            case 16 : c.pay = atof(sx);             break;
            case 17 : c.provider = atoi(sx);        break;
            case 18 :                               break;
          } /* switch */

        } /* while */


        /* Repair wrong entries from older (or current?) isdnlog-versions ... */

        if (abs((int)dur - (int)c.duration) > 1) {
          if (verbose)
            fprintf(stderr, "REPAIR: Duration %f -> %f\n", c.duration, dur);

          c.duration = dur;
        } /* if */

        if (!memcmp(c.num[CALLED], "+4910", 5)) {
          p = c.num[CALLED] + 7;
          x = *p;
          *p = 0;

          c.provider = atoi(c.num[CALLED] + 5);

          *p = x;

          if (strlen(c.num[CALLED]) > 7)
            memmove(c.num[CALLED] + 3, c.num[CALLED] + 8, strlen(c.num[CALLED]) - 7);

          if (verbose)
            fprintf(stderr, "REPAIR: Provider=%d\n", c.provider);
        } /* if */

        if (!c.provider || (c.provider == UNKNOWN)) {
          if (verbose)
            fprintf(stderr, "REPAIR: Provider %d -> %d\n", c.provider, preselect);

          c.provider = preselect;
        } /* if */

        if (c.dialout && (strlen(c.num[CALLED]) > 3) && !getSpecial(c.num[CALLED])) {
          sprintf(s, "0%s", c.num[CALLED] + 3);

          if (getSpecial(s)) {
            if (verbose)
              fprintf(stderr, "REPAIR: Callee %s -> %s\n", c.num[CALLED], s);

            strcpy(c.num[CALLED], s);
          } /* if */
        } /* if */

        if (!c.dialout && (strlen(c.num[CALLING]) > 3) && !getSpecial(c.num[CALLING])) {
          sprintf(s, "0%s", c.num[CALLING] + 3);

          if (getSpecial(s)) {
            if (verbose)
              fprintf(stderr, "REPAIR: Caller %s -> %s\n", c.num[CALLING], s);

            strcpy(c.num[CALLING], s);
          } /* if */
        } /* if */


        go = 0;

        if (showoutgoing && c.dialout && c.duration)
          go++;

        if (showincoming && !c.dialout && c.duration)
          go++;

        if (showerrors && !c.duration)
          go++;

        if (*onlythis && strstr(c.num[CALLING], onlythis) == NULL &&
           	      	 strstr(c.num[CALLED], onlythis) == NULL)
          go = 0;

        if (onlytoday && c.connect < now)
          go = 0;

        s0 = 0; /* Externer S0 */

        if (c.dialout && (strlen(c.num[CALLING]) < interns0))
          s0 = 1; /* Interner S0-Bus */

        if (!c.dialout && (strlen(c.num[CALLED]) < interns0))
          s0 = 1; /* Interner S0-Bus */

        if (onlyInternal && !s0)
          go = 0;

        if (onlyExternal && s0)
          go = 0;


        if (go) {
          when(s, &day, &month);

          if (lmonth == UNKNOWN)
            lmonth = month;
          else if (month != lmonth) {
            total(SUBTOTAL);
            lmonth = month;
          } /* if */

          if (lday == UNKNOWN)
            lday = day;
          else if (day != lday) {
            printf("\n");
            lday = day;
          } /* else */

          printf("%s%s ", s, timestr(c.duration));

	  if (*c.num[CALLING])
            normalizeNumber(c.num[CALLING], &number[CALLING], TN_ALL);
          else {
	    memset(&number[CALLING], 0, sizeof(TELNUM));
            strcpy(number[CALLING].msn, "UNKNOWN");
          } /* else */

	  if (*c.num[CALLED])
            normalizeNumber(c.num[CALLED], &number[CALLED], TN_ALL);
          else {
	    memset(&number[CALLED], 0, sizeof(TELNUM));
            strcpy(number[CALLED].msn, "UNKNOWN");
          } /* else */

          findme();

          indent = 11 + strlen(c.currency);

          if (c.dialout) {

            findrate();

            msnsum[SUBTOTAL][c.si1][c.ihome].ncalls++;

            justify(number[CALLING].msn, c.num[CALLED], number[CALLED]);

            provsum[SUBTOTAL][c.provider].ncalls++;

            strcpy(s, getProvider(pnum2prefix(c.provider, c.connect)));
            s[PROVLEN] = 0;

            if (c.provider < 100)
              sprintf(c.sprovider, "  010%02d:%-*s", c.provider, PROVLEN, s);
            else if (c.provider < 200)
              sprintf(c.sprovider, "0100%03d:%-*s", c.provider - 100, PROVLEN, s);
            else
              sprintf(c.sprovider, "01900%02d:%-*s", c.provider - 200, PROVLEN, s);


            if (c.duration) {

#if 0 // Berechnung, um wieviel es mit AktivPlus der DTAG billiger waere -- stimmt irgendwie eh nicht mehr ...

              if ((preselect == DTAG) && ((c.zone == 1) || (c.zone == 2))) {
                auto struct tm *tm = localtime(&c.connect);
                auto int        takte;
                auto double     price;


                takte = (c.duration + 59) / 60;

                if ((tm->tm_wday > 0) && (tm->tm_wday < 5)) {   /* Wochentag */
                  if ((tm->tm_hour > 8) && (tm->tm_hour < 18))  /* Hauptzeit */
                    price = 0.06;
                  else
                    price = 0.03;
                }
                else                                            /* Wochenende */
                  price = 0.03;

                c.aktiv = takte * price;

                msnsum[SUBTOTAL][c.si1][c.ihome].aktiv += c.aktiv;
                provsum[SUBTOTAL][c.provider].aktiv += c.aktiv;
                zonesum[SUBTOTAL][c.zone].aktiv += c.aktiv;
              } /* if */
#endif

              if (c.pay < 0.0) { /* impossible! */
                c.pay = c.compute;
                c.computed++;
              } /* if */

              if (force || fabs(c.pay - c.compute) > 1.00) {
                c.pay = c.compute;
                c.computed++;
              } /* if */

              if (netto)
                c.pay = c.pay * 100.0 / 116.0;

              if (c.pay)
                printf("%12s%s ", printRate(c.pay), c.computed ? "*" : " ");
              else
                printf("%*s", indent, "");

              printf("%s%s%s", c.country, c.sprovider, c.error);

#if 0
              if (c.aktiv)
                printf(" AktivPlus - %13s", printRate(c.pay - c.aktiv));
#endif

              msnsum[SUBTOTAL][c.si1][c.ihome].pay += c.pay;
              msnsum[SUBTOTAL][c.si1][c.ihome].duration += c.duration;
              msnsum[SUBTOTAL][c.si1][c.ihome].compute += c.compute;
              msnsum[SUBTOTAL][c.si1][c.ihome].ibytes += c.ibytes;
              msnsum[SUBTOTAL][c.si1][c.ihome].obytes += c.obytes;

              provsum[SUBTOTAL][c.provider].pay += c.pay;
              provsum[SUBTOTAL][c.provider].duration += c.duration;
              provsum[SUBTOTAL][c.provider].compute += c.compute;
              provsum[SUBTOTAL][c.provider].ibytes += c.ibytes;
              provsum[SUBTOTAL][c.provider].obytes += c.obytes;

              zonesum[SUBTOTAL][c.zone].pay += c.pay;
              zonesum[SUBTOTAL][c.zone].duration += c.duration;
              zonesum[SUBTOTAL][c.zone].compute += c.compute;
              zonesum[SUBTOTAL][c.zone].ibytes += c.ibytes;
              zonesum[SUBTOTAL][c.zone].obytes += c.obytes;
            }
            else {
              printf("%*s%s%s", indent, "", c.country, c.sprovider);

              if ((c.cause != 0x1f) && /* Normal, unspecified */
                  (c.cause != 0x10))   /* Normal call clearing */
                printf(" %s", qmsg(TYPE_CAUSE, VERSION_EDSS1, c.cause));

              if ((c.cause == 0x22) || /* No circuit/channel available */
                  (c.cause == 0x2a) || /* Switching equipment congestion */
                  (c.cause == 0x2f))   /* Resource unavailable, unspecified */
                provsum[SUBTOTAL][c.provider].failed++;
            } /* else */
          }
          else { /* Dialin: */
            justify(number[CALLED].msn, c.num[CALLING], number[CALLING]);
            printf("%*s%s%s", indent, "", c.country, c.sprovider);
          } /* else */


          if (c.known[OTHER] == UNKNOWN) {
            l = UNKNOWN;

            for (i = 0; i < nunknown[c.dialout]; i++) {
              if (!strcmp(unknown[c.dialout][i].num, c.num[OTHER])) {
                l = i;
                break;
              } /* if */
            } /* for */

            if (l == UNKNOWN) {
              l = nunknown[c.dialout];

              nunknown[c.dialout]++;

              if (!l)
                unknown[c.dialout] = (PARTNER *)malloc(sizeof(PARTNER));
              else
                unknown[c.dialout] = (PARTNER *)realloc(unknown[c.dialout], sizeof(PARTNER) * nunknown[c.dialout]);

              memset(&unknown[c.dialout][l], 0, sizeof(PARTNER));
            } /* if */

            strcpy(unknown[c.dialout][l].num, c.num[OTHER]);

            unknown[c.dialout][l].ihome = c.ihome;
            unknown[c.dialout][l].ncalls++;
            unknown[c.dialout][l].pay += c.pay;
            unknown[c.dialout][l].duration += c.duration;
            unknown[c.dialout][l].compute += c.compute;
            unknown[c.dialout][l].ibytes += c.ibytes;
            unknown[c.dialout][l].obytes += c.obytes;
          }
          else {
            strcpy(partner[c.dialout][c.known[OTHER]].num, c.num[OTHER]);
            partner[c.dialout][c.known[OTHER]].ncalls++;
            partner[c.dialout][c.known[OTHER]].pay += c.pay;
            partner[c.dialout][c.known[OTHER]].duration += c.duration;
            partner[c.dialout][c.known[OTHER]].compute += c.compute;
            partner[c.dialout][c.known[OTHER]].ibytes += c.ibytes;
            partner[c.dialout][c.known[OTHER]].obytes += c.obytes;
          } /* else */

          printf("\n");

        } /* if */
      } /* while */

      fclose(f);
      total(SUBTOTAL);

      if (!onlytoday)
        total(TOTAL);

      showpartner();

    }
    else
      fprintf(stderr, "%s: Can't read configuration file(s)\n", myname);
  }
  else
    fprintf(stderr, "%s: Can't open \"isdn.log\" file\n", myname);

  return(0);
} /* isdnbill */
Exemplo n.º 2
0
/*
 * Handle a media change request.
 */
int
ieee80211_media_change(struct ifnet *ifp)
{
	struct ieee80211com *ic;
	struct ifmedia_entry *ime;
	enum ieee80211_opmode newopmode;
	enum ieee80211_phymode newphymode;
	int i, j, newrate, error = 0;

	ic = ieee80211_find_instance(ifp);
	if (!ic) {
		if_printf(ifp, "%s: no 802.11 instance!\n", __func__);
		return EINVAL;
	}
	ime = ic->ic_media.ifm_cur;
	/*
	 * First, identify the phy mode.
	 */
	switch (IFM_MODE(ime->ifm_media)) {
	case IFM_IEEE80211_11A:
		newphymode = IEEE80211_MODE_11A;
		break;
	case IFM_IEEE80211_11B:
		newphymode = IEEE80211_MODE_11B;
		break;
	case IFM_IEEE80211_11G:
		newphymode = IEEE80211_MODE_11G;
		break;
	case IFM_IEEE80211_FH:
		newphymode = IEEE80211_MODE_FH;
		break;
	case IFM_AUTO:
		newphymode = IEEE80211_MODE_AUTO;
		break;
	default:
		return EINVAL;
	}
	/*
	 * Turbo mode is an ``option''.
	 * XXX does not apply to AUTO
	 */
	if (ime->ifm_media & IFM_IEEE80211_TURBO) {
		if (newphymode == IEEE80211_MODE_11A)
			newphymode = IEEE80211_MODE_TURBO_A;
		else if (newphymode == IEEE80211_MODE_11G)
			newphymode = IEEE80211_MODE_TURBO_G;
		else
			return EINVAL;
	}
	/*
	 * Validate requested mode is available.
	 */
	if ((ic->ic_modecaps & (1<<newphymode)) == 0)
		return EINVAL;

	/*
	 * Next, the fixed/variable rate.
	 */
	i = -1;
	if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) {
		/*
		 * Convert media subtype to rate.
		 */
		newrate = ieee80211_media2rate(ime->ifm_media);
		if (newrate == 0)
			return EINVAL;
		/*
		 * Check the rate table for the specified/current phy.
		 */
		if (newphymode == IEEE80211_MODE_AUTO) {
			/*
			 * In autoselect mode search for the rate.
			 */
			for (j = IEEE80211_MODE_11A;
			     j < IEEE80211_MODE_MAX; j++) {
				if ((ic->ic_modecaps & (1<<j)) == 0)
					continue;
				i = findrate(ic, j, newrate);
				if (i != -1) {
					/* lock mode too */
					newphymode = j;
					break;
				}
			}
		} else {
			i = findrate(ic, newphymode, newrate);
		}
		if (i == -1)			/* mode/rate mismatch */
			return EINVAL;
	}
	/* NB: defer rate setting to later */

	/*
	 * Deduce new operating mode but don't install it just yet.
	 */
	if ((ime->ifm_media & (IFM_IEEE80211_ADHOC|IFM_FLAG0)) ==
	    (IFM_IEEE80211_ADHOC|IFM_FLAG0))
		newopmode = IEEE80211_M_AHDEMO;
	else if (ime->ifm_media & IFM_IEEE80211_HOSTAP)
		newopmode = IEEE80211_M_HOSTAP;
	else if (ime->ifm_media & IFM_IEEE80211_ADHOC)
		newopmode = IEEE80211_M_IBSS;
	else if (ime->ifm_media & IFM_IEEE80211_MONITOR)
		newopmode = IEEE80211_M_MONITOR;
	else
		newopmode = IEEE80211_M_STA;

#ifndef IEEE80211_NO_HOSTAP
	/*
	 * Autoselect doesn't make sense when operating as an AP.
	 * If no phy mode has been selected, pick one and lock it
	 * down so rate tables can be used in forming beacon frames
	 * and the like.
	 */
	if (newopmode == IEEE80211_M_HOSTAP &&
	    newphymode == IEEE80211_MODE_AUTO) {
		for (j = IEEE80211_MODE_11A; j < IEEE80211_MODE_MAX; j++)
			if (ic->ic_modecaps & (1<<j)) {
				newphymode = j;
				break;
			}
	}
#endif /* !IEEE80211_NO_HOSTAP */

	/*
	 * Handle phy mode change.
	 */
	if (ic->ic_curmode != newphymode) {		/* change phy mode */
		error = ieee80211_setmode(ic, newphymode);
		if (error != 0)
			return error;
		error = ENETRESET;
	}

	/*
	 * Committed to changes, install the rate setting.
	 */
	if (ic->ic_fixed_rate != i) {
		ic->ic_fixed_rate = i;			/* set fixed tx rate */
		error = ENETRESET;
	}

	/*
	 * Handle operating mode change.
	 */
	if (ic->ic_opmode != newopmode) {
		ic->ic_opmode = newopmode;
		switch (newopmode) {
		case IEEE80211_M_AHDEMO:
		case IEEE80211_M_HOSTAP:
		case IEEE80211_M_STA:
		case IEEE80211_M_MONITOR:
			ic->ic_flags &= ~IEEE80211_F_IBSSON;
			break;
		case IEEE80211_M_IBSS:
			ic->ic_flags |= IEEE80211_F_IBSSON;
			break;
		}
		/*
		 * Yech, slot time may change depending on the
		 * operating mode so reset it to be sure everything
		 * is setup appropriately.
		 */
		ieee80211_reset_erp(ic);
		ieee80211_wme_initparams(ic);	/* after opmode change */
		error = ENETRESET;
	}
#ifdef notdef
	if (error == 0)
		ifp->if_baudrate = ifmedia_baudrate(ime->ifm_media);
#endif
	return error;
}
Exemplo n.º 3
0
/*
 * Handle a media change request.
 */
int
ieee80211_media_change(struct ifnet *ifp)
{
	struct ieee80211com *ic = (void *)ifp;
	struct ifmedia_entry *ime;
	enum ieee80211_opmode newopmode;
	enum ieee80211_phymode newphymode;
	int i, j, newrate, error = 0;

	ime = ic->ic_media.ifm_cur;
	/*
	 * First, identify the phy mode.
	 */
	switch (IFM_MODE(ime->ifm_media)) {
	case IFM_IEEE80211_11A:
		newphymode = IEEE80211_MODE_11A;
		break;
	case IFM_IEEE80211_11B:
		newphymode = IEEE80211_MODE_11B;
		break;
	case IFM_IEEE80211_11G:
		newphymode = IEEE80211_MODE_11G;
		break;
	case IFM_IEEE80211_FH:
		newphymode = IEEE80211_MODE_FH;
		break;
	case IFM_AUTO:
		newphymode = IEEE80211_MODE_AUTO;
		break;
	default:
		return EINVAL;
	}
	/*
	 * Turbo mode is an ``option''.  Eventually it
	 * needs to be applied to 11g too.
	 */
	if (ime->ifm_media & IFM_IEEE80211_TURBO) {
		if (newphymode != IEEE80211_MODE_11A)
			return EINVAL;
		newphymode = IEEE80211_MODE_TURBO;
	}
	/*
	 * Validate requested mode is available.
	 */
	if ((ic->ic_modecaps & (1<<newphymode)) == 0)
		return EINVAL;

	/*
	 * Next, the fixed/variable rate.
	 */
	i = -1;
	if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) {
		/*
		 * Convert media subtype to rate.
		 */
		newrate = ieee80211_media2rate(ime->ifm_media);
		if (newrate == 0)
			return EINVAL;
		/*
		 * Check the rate table for the specified/current phy.
		 */
		if (newphymode == IEEE80211_MODE_AUTO) {
			/*
			 * In autoselect mode search for the rate.
			 */
			for (j = IEEE80211_MODE_11A;
			     j < IEEE80211_MODE_MAX; j++) {
				if ((ic->ic_modecaps & (1<<j)) == 0)
					continue;
				i = findrate(ic, j, newrate);
				if (i != -1) {
					/* lock mode too */
					newphymode = j;
					break;
				}
			}
		} else {
			i = findrate(ic, newphymode, newrate);
		}
		if (i == -1)			/* mode/rate mismatch */
			return EINVAL;
	}
	/* NB: defer rate setting to later */

	/*
	 * Deduce new operating mode but don't install it just yet.
	 */
	if ((ime->ifm_media & (IFM_IEEE80211_ADHOC|IFM_FLAG0)) ==
	    (IFM_IEEE80211_ADHOC|IFM_FLAG0))
		newopmode = IEEE80211_M_AHDEMO;
	else if (ime->ifm_media & IFM_IEEE80211_HOSTAP)
		newopmode = IEEE80211_M_HOSTAP;
	else if (ime->ifm_media & IFM_IEEE80211_ADHOC)
		newopmode = IEEE80211_M_IBSS;
	else if (ime->ifm_media & IFM_IEEE80211_MONITOR)
		newopmode = IEEE80211_M_MONITOR;
	else
		newopmode = IEEE80211_M_STA;

	/*
	 * Autoselect doesn't make sense when operating as an AP.
	 * If no phy mode has been selected, pick one and lock it
	 * down so rate tables can be used in forming beacon frames
	 * and the like.
	 */
	if (newopmode == IEEE80211_M_HOSTAP &&
	    newphymode == IEEE80211_MODE_AUTO) {
		for (j = IEEE80211_MODE_11A; j < IEEE80211_MODE_MAX; j++)
			if (ic->ic_modecaps & (1<<j)) {
				newphymode = j;
				break;
			}
	}

	/*
	 * Handle phy mode change.
	 */
	if (ic->ic_curmode != newphymode) {		/* change phy mode */
		error = ieee80211_setmode(ic, newphymode);
		if (error != 0)
			return error;
		error = ENETRESET;
	}

	/*
	 * Committed to changes, install the rate setting.
	 */
	if (ic->ic_fixed_rate != i) {
		ic->ic_fixed_rate = i;			/* set fixed tx rate */
		error = ENETRESET;
	}

	/*
	 * Handle operating mode change.
	 */
	if (ic->ic_opmode != newopmode) {
		ic->ic_opmode = newopmode;
		switch (newopmode) {
		case IEEE80211_M_AHDEMO:
		case IEEE80211_M_HOSTAP:
		case IEEE80211_M_STA:
		case IEEE80211_M_MONITOR:
			ic->ic_flags &= ~IEEE80211_F_IBSSON;
			break;
		case IEEE80211_M_IBSS:
			ic->ic_flags |= IEEE80211_F_IBSSON;
			break;
		}
		error = ENETRESET;
	}
#ifdef notdef
	if (error == 0)
		ifp->if_baudrate = ifmedia_baudrate(ime->ifm_media);
#endif
	return error;
}