Exemplo n.º 1
0
uim_agent_context *
create_uim_agent_context(const char *encoding)
{

  uim_agent_context *ret;
  const char *im;

  debug_printf(DEBUG_NOTE, "create_uim_agent_context\n");

  ret = uim_malloc(sizeof(uim_agent_context));

  if (encoding) {
	ret->encoding = uim_strdup(encoding);
  } else {
	if (debug_level > 0)
	  ret->encoding = uim_strdup("EUC-JP");
	else
	  ret->encoding = uim_strdup("UTF-8");
  }

  ret->context = create_context(ret->encoding, ret);

  if ((im = uim_get_default_im_name(setlocale(LC_CTYPE, NULL))))
	ret->im = uim_strdup(im);
  else
	ret->im = NULL;

  ret->pe = create_preedit();
  ret->cand = create_candidate();
  ret->prop = create_prop();

  ret->comstr = (char *)NULL;

  return ret;
}
void backtrack(char *string,char *answer,int step) {
    if(step==N)
        display_outcome(answer);
    else {
        char candidate[N];
        int candidate_size;
        create_candidate(string,answer,step,candidate,&candidate_size);
        int i;
        for(i=0; i<candidate_size; i++) {
            answer[step]=candidate[i];
            backtrack(string,answer,step+1);
        }
    }
}
Exemplo n.º 3
0
/**
 * process_ampe_frame - process an ampe frame
 * @frame:     The full frame
 * @len:       The full frame length
 * @me:        The MAC address of the local interface
 * @cookie:    Opaque cookie that will be returned to the caller along with
 *             frames to be transmitted.
 *
 * Returns 0 unless something really horrible happened.  In other words, even
 * the frame could not be processed or it was corrupted, the function still
 * returns 0.
 */
int process_ampe_frame(
    struct ieee80211_mgmt_frame *mgmt,
    int len,
    unsigned char *me,
    void *cookie) {
  struct info_elems elems;
  struct info_elems our_elems;
  unsigned char ftype;
  struct candidate *cand = NULL;
  enum plink_event event;
  unsigned char ie_len = 0;
  unsigned short plid = 0, llid = 0;
  unsigned char *ies;
  unsigned short ies_len;
  size_t pmkid_len;

#define FAKE_LOSS_PROBABILITY 0
#if (FAKE_LOSS_PROBABILITY > 0)
  do {
    unsigned short dice;
    dice = RAND_bytes((unsigned char *)&dice, sizeof(dice));
    if ((dice % 100) < FAKE_LOSS_PROBABILITY) {
      sae_debug(AMPE_DEBUG_FSM, "Frame dropped\n");
      return 0;
    }
  } while (0);
#endif

  /* management header, category, action code, mesh id and peering mgmt*/
  if (len < 24 + 1 + 1 + 2 + 2)
    return 0;

  ies = start_of_ies(mgmt, len, &ies_len);
  parse_ies(ies, ies_len, &elems);
  if (!elems.mesh_peering) {
    sae_debug(AMPE_DEBUG_FSM, "Mesh plink: missing necessary peer link ie\n");
    return 0;
  }

  ftype = mgmt->action.action_code;
  ie_len = elems.mesh_peering_len;

  pmkid_len = ampe_conf.mesh->conf->is_secure ? sizeof(cand->pmkid) : 0;

  if ((ftype == PLINK_OPEN && ie_len != 4 + pmkid_len) ||
      (ftype == PLINK_CONFIRM && ie_len != 6 + pmkid_len) ||
      (ftype == PLINK_CLOSE && ie_len != 6 + pmkid_len &&
       ie_len != 8 + pmkid_len)) {
    sae_debug(
        AMPE_DEBUG_FSM,
        "Mesh plink: incorrect plink ie length %d %d\n",
        ftype,
        ie_len);
    return 0;
  }

  if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) {
    sae_debug(
        AMPE_DEBUG_FSM,
        "Mesh plink: missing necessary ie %p %p\n",
        elems.mesh_id,
        elems.mesh_config);
    return 0;
  }

  /* Note the lines below are correct, the llid in the frame is the plid
   * from the point of view of this host.
   */
  memcpy(&plid, PLINK_GET_LLID(elems.mesh_peering), 2);
  if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 10))
    memcpy(&llid, PLINK_GET_PLID(elems.mesh_peering), 2);

  /* match BSSBasicRateSet*/
  parse_ies(sta_fixed_ies, sta_fixed_ies_len, &our_elems);
  if (ftype != PLINK_CLOSE &&
      get_basic_rates(&our_elems) != get_basic_rates(&elems)) {
    sae_debug(AMPE_DEBUG_FSM, "mesh plink: mismatched BSSBasicRateSet!\n");
    return 0;
  }

  /* require authed peers if secure mesh */
  if (ampe_conf.mesh->conf->is_secure) {
    /* "1" here means only get peers in SAE_ACCEPTED */
    if ((cand = find_peer(mgmt->sa, 1)) == NULL) {
      sae_debug(
          AMPE_DEBUG_FSM,
          "Mesh plink: plink open from unauthed peer " MACSTR "\n",
          MAC2STR(mgmt->sa));
      return 0;
    }
  } else {
    /*
     * In open mesh, there's no auth stage, so we create the station
     * when the first mgmt frame or beacon is received.  Do that now
     * if we haven't already and this is a plink open frame.
     */
    cand = find_peer(mgmt->sa, 0);
    if (!cand) {
      if (ftype != PLINK_OPEN) {
        sae_debug(
            AMPE_DEBUG_FSM,
            "Mesh plink: ignoring non-open frame from neighbor " MACSTR "\n",
            MAC2STR(mgmt->sa));
        return 0;
      }

      cand = create_candidate(mgmt->sa, me, 0, cookie);
      if (!cand) {
        sae_debug(
            AMPE_DEBUG_FSM,
            "Mesh plink: could not create new peer " MACSTR "\n",
            MAC2STR(mgmt->sa));
        return 0;
      }
    }
  }

  if (cand->my_lid == 0)
    peer_ampe_init(&ampe_conf, cand, cookie);

  ampe_set_peer_ies(cand, &elems);

  if (!protection_is_valid(cand, mgmt, len, &elems))
    return 0;

  cand->cookie = cookie;

  if (cand->link_state == PLINK_BLOCKED) {
    return 0;
  }

  /* Now we will figure out the appropriate event... */
  event = PLINK_UNDEFINED;

  switch (ftype) {
    case PLINK_OPEN:
      if (!matches_local(ampe_conf.mesh, cand, &elems))
        event = OPN_RJCT;
      else if (!plink_free_count(ampe_conf.mesh)) {
        log_reject(cand, "no free peer links");
        event = REQ_RJCT;
      } else if (cand->peer_lid && cand->peer_lid != plid) {
        log_reject(cand, "invalid peer link id");
        event = REQ_RJCT;
      } else {
        cand->peer_lid = plid;
        event = OPN_ACPT;
      }
      break;
    case PLINK_CONFIRM:
      if (!matches_local(ampe_conf.mesh, cand, &elems))
        event = CNF_RJCT;
      else if (!plink_free_count(ampe_conf.mesh)) {
        log_reject(cand, "no free peer links");
        event = REQ_RJCT;
      } else if (cand->my_lid != llid) {
        log_reject(cand, "invalid local link id");
        event = REQ_RJCT;
      } else if (cand->peer_lid != plid) {
        log_reject(cand, "invalid peer link id");
        event = REQ_RJCT;
      } else
        event = CNF_ACPT;
      break;
    case PLINK_CLOSE:
      if (cand->link_state == PLINK_ESTAB)
        /* Do not check for llid or plid. This does not
         * follow the standard but since multiple plinks
         * per cand are not supported, it is necessary in
         * order to avoid a livelock when MP A sees an
         * establish peer link to MP B but MP B does not
         * see it. This can be caused by a timeout in
         * B's peer link establishment or B beign
         * restarted.
         */
        event = CLS_ACPT;
      else if (cand->peer_lid != plid)
        event = CLS_IGNR;
      else if (ie_len == 7 && cand->my_lid != llid)
        event = CLS_IGNR;
      else
        event = CLS_ACPT;
      break;
    default:
      sae_debug(AMPE_DEBUG_FSM, "Mesh plink: unknown frame subtype\n");
      return 0;
  }

  sae_debug(
      AMPE_DEBUG_FSM,
      "Mesh plink peer=" MACSTR " state=%s llid=%d plid=%d event=%s\n",
      MAC2STR(mgmt->sa),
      mpl_states[cand->link_state],
      le16toh(cand->my_lid),
      le16toh(cand->peer_lid),
      mpl_events[event]);

  fsm_step(cand, event);

  return 0;
}