Esempio n. 1
0
/* handle the details of establishing the RFCNB session with remote end */
static int 
RFCNB_Session_Req(struct RFCNB_Con *con,
                  char *Called_Name,
                  char *Calling_Name,
                  BOOL * redirect,
                  struct in_addr *Dest_IP,
                  int *port)
{
    char *sess_pkt;

    /* Response packet should be no more than 9 bytes, make 16 jic */
    char resp[16];
    int len;
    struct RFCNB_Pkt *pkt, res_pkt;

    /* We build and send the session request, then read the response */
    pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Sess_Len);
    if (pkt == NULL) {
        return RFCNBE_Bad; /* Leave the error that RFCNB_Alloc_Pkt gives) */
    }
    sess_pkt = pkt->data;       /* Get pointer to packet proper */

    sess_pkt[RFCNB_Pkt_Type_Offset] = RFCNB_SESSION_REQUEST;
    RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len - RFCNB_Pkt_Hdr_Len);
    sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32;
    sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32;

    RFCNB_CvtPad_Name(Called_Name, (sess_pkt + RFCNB_Pkt_Called_Offset));
    RFCNB_CvtPad_Name(Calling_Name, (sess_pkt + RFCNB_Pkt_Calling_Offset));

    /* Now send the packet */
#ifdef RFCNB_DEBUG
    fprintf(stderr, "Sending packet: ");
#endif
    if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0)
        return RFCNBE_Bad;      /* Should be able to write that lot ... */
#ifdef RFCNB_DEBUG
    fprintf(stderr, "Getting packet.\n");
#endif

    res_pkt.data = resp;
    res_pkt.len = sizeof(resp);
    res_pkt.next = NULL;

    if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0)
        return RFCNBE_Bad;

    /* Now analyze the packet ... */
    switch (RFCNB_Pkt_Type(resp)) {
      case RFCNB_SESSION_REJ:   /* Didnt like us ... too bad */
          /* Why did we get rejected ? */
          switch (CVAL(resp, RFCNB_Pkt_Error_Offset)) {
            case 0x80:
                RFCNB_errno = RFCNBE_CallRejNLOCN;
                break;
            case 0x81:
                RFCNB_errno = RFCNBE_CallRejNLFCN;
                break;
            case 0x82:
                RFCNB_errno = RFCNBE_CallRejCNNP;
                break;
            case 0x83:
                RFCNB_errno = RFCNBE_CallRejInfRes;
                break;
            case 0x8F:
                RFCNB_errno = RFCNBE_CallRejUnSpec;
                break;
            default:
                RFCNB_errno = RFCNBE_ProtErr;
                break;
          }
          return (RFCNBE_Bad);
          break;

      case RFCNB_SESSION_ACK:   /* Got what we wanted ...      */
          return (0);
          break;

      case RFCNB_SESSION_RETARGET:      /* Go elsewhere                */
          *redirect = TRUE;     /* Copy port and ip addr       */
          memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset),
                 sizeof(struct in_addr));
          *port = SVAL(resp, RFCNB_Pkt_Port_Offset);
          return 0;
          break;
      default:                  /* A protocol error */
          RFCNB_errno = RFCNBE_ProtErr;
          return (RFCNBE_Bad);
          break;
    }
}
Esempio n. 2
0
int
RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
{
    int read_len, pkt_len;
    char hdr[RFCNB_Pkt_Hdr_Len];        /* Local space for the header */
    struct RFCNB_Pkt *pkt_frag;
    int more, this_time, offset, frag_len, this_len;
    BOOL seen_keep_alive = TRUE;

    /* Read that header straight into the buffer */

    if (len < RFCNB_Pkt_Hdr_Len) {      /* What a bozo */

#ifdef RFCNB_DEBUG
        fprintf(stderr, "Trying to read less than a packet:");
        perror("");
#endif
        RFCNB_errno = RFCNBE_BadParam;
        return (RFCNBE_Bad);

    }
    /* We discard keep alives here ... */

    if (RFCNB_Timeout > 0)
        alarm(RFCNB_Timeout);

    while (seen_keep_alive) {

        if ((read_len = read(con->fd, hdr, sizeof(hdr))) < 0) {         /* Problems */
#ifdef RFCNB_DEBUG
            fprintf(stderr, "Reading the packet, we got:");
            perror("");
#endif
            if (errno == EINTR)
                RFCNB_errno = RFCNBE_Timeout;
            else
                RFCNB_errno = RFCNBE_BadRead;
            RFCNB_saved_errno = errno;
            return (RFCNBE_Bad);

        }
        /* Now we check out what we got */

        if (read_len == 0) {    /* Connection closed, send back eof?  */

#ifdef RFCNB_DEBUG
            fprintf(stderr, "Connection closed reading\n");
#endif

            if (errno == EINTR)
                RFCNB_errno = RFCNBE_Timeout;
            else
                RFCNB_errno = RFCNBE_ConGone;
            RFCNB_saved_errno = errno;
            return (RFCNBE_Bad);

        }
        if (RFCNB_Pkt_Type(hdr) == RFCNB_SESSION_KEEP_ALIVE) {

#ifdef RFCNB_DEBUG
            fprintf(stderr, "RFCNB KEEP ALIVE received\n");
#endif

        } else {
            seen_keep_alive = FALSE;
        }

    }

    /* What if we got less than or equal to a hdr size in bytes? */

    if (read_len < sizeof(hdr)) {       /* We got a small packet */

        /* Now we need to copy the hdr portion we got into the supplied packet */

        memcpy(pkt->data, hdr, read_len);       /*Copy data */

#ifdef RFCNB_DEBUG
        RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len);
#endif

        return (read_len);

    }
    /* Now, if we got at least a hdr size, alloc space for rest, if we need it */

    pkt_len = RFCNB_Pkt_Len(hdr);

#ifdef RFCNB_DEBUG
    fprintf(stderr, "Reading Pkt: Length = %i\n", pkt_len);
#endif

    /* Now copy in the hdr */

    memcpy(pkt->data, hdr, sizeof(hdr));

    /* Get the rest of the packet ... first figure out how big our buf is? */
    /* And make sure that we handle the fragments properly ... Sure should */
    /* use an iovec ...                                                    */

    if (len < pkt_len)          /* Only get as much as we have space for */
        more = len - RFCNB_Pkt_Hdr_Len;
    else
        more = pkt_len;

    this_time = 0;

    /* We read for each fragment ... */

    if (pkt->len == read_len) { /* If this frag was exact size */
        pkt_frag = pkt->next;   /* Stick next lot in next frag */
        offset = 0;             /* then we start at 0 in next  */
    } else {
        pkt_frag = pkt;         /* Otherwise use rest of this frag */
        offset = RFCNB_Pkt_Hdr_Len;     /* Otherwise skip the header       */
    }

    frag_len = pkt_frag->len;

    if (more <= frag_len)       /* If len left to get less than frag space */
        this_len = more;        /* Get the rest ...                        */
    else
        this_len = frag_len - offset;

    while (more > 0) {

        if ((this_time = read(con->fd, (pkt_frag->data) + offset, this_len)) <= 0) {    /* Problems */

            if (errno == EINTR) {

                RFCNB_errno = RFCNB_Timeout;

            } else {
                if (this_time < 0)
                    RFCNB_errno = RFCNBE_BadRead;
                else
                    RFCNB_errno = RFCNBE_ConGone;
            }

            RFCNB_saved_errno = errno;
            return (RFCNBE_Bad);

        }
#ifdef RFCNB_DEBUG
        fprintf(stderr, "Frag_Len = %i, this_time = %i, this_len = %i, more = %i\n", frag_len,
                this_time, this_len, more);
#endif

        read_len = read_len + this_time;        /* How much have we read ... */

        /* Now set up the next part */

        if (pkt_frag->next == NULL)
            break;              /* That's it here */

        pkt_frag = pkt_frag->next;
        this_len = pkt_frag->len;
        offset = 0;

        more = more - this_time;

    }

#ifdef RFCNB_DEBUG
    fprintf(stderr, "Pkt Len = %i, read_len = %i\n", pkt_len, read_len);
    RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len + sizeof(hdr));
#endif

    if (read_len < (pkt_len + sizeof(hdr))) {   /* Discard the rest */

        return (RFCNB_Discard_Rest(con, (pkt_len + sizeof(hdr)) - read_len));

    }
    if (RFCNB_Timeout > 0)
        alarm(0);               /* Reset that sucker */

    return (read_len + sizeof(RFCNB_Hdr));
}