Logo Search packages:      
Sourcecode: l2tpd version File versions  Download package

avpsend.c

/*
 * Copyright (C) 2004 Jean-Francois Dive
 *
 * This software is distributed under the terms
 * of the GPL, which you should have received
 * along with this source.
 *
 * Attribute Value Pair creating routines
 */

/* TODO: Handle Tie break */
/* TODO: Get real hostname / config */
/* TODO: There should be an overflow check on
 *           the buffer size. (safe for now as 
 *           packet size = 4k
 */

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "l2tp.h"

extern struct avp avps[];

/* We could add here padding support which would allow
 * to keep alignemnt straight <jdive> */
static int add_avp(struct buffer *buf, u_int32_t avpid, unsigned char *v, 
                         u_int32_t sz, u_int8_t setpayload) {
      u_int8_t *p = buf->start + buf->len;

      if(avpid > AVP_MAX  || !avps[avpid].flags) {
            log(LOG_DEBUG, "%s: invalid avp id %d\n", __func__, avpid);
            return 1;
      }

      set16(p, (sz + 6) | (avps[avpid].flags & AVP_F_MANDATORY ? MBIT : 0));
      set16(p + 2, VENDOR_ID);
      set16(p + 4, avpid);
      if(setpayload) 
            memcpy(p + 6, v, sz);

      buf->len += (sz + 6);
      return 0;
}

/*****************************************************************************/
int add_message_type_avp(struct buffer *buf, _u16 type) {
      u_int8_t t[2];
      set16(t, type);
      if(add_avp(buf, MESSAGE_TYPE_AVP, t, 2, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_protocol_avp(struct buffer *buf) {
      u_int8_t t[2];
      set16(t, OUR_L2TP_VERSION);
      if(add_avp(buf, PROTOCOL_VERSION_AVP, t, 2, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_frame_caps_avp(struct buffer *buf, _u16 caps) {
      u_int8_t t[4];
      t[0] = 0; 
      t[1] = 0;
      set16(&t[2], caps);
      if(add_avp(buf, FRAMING_CAP_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_bearer_caps_avp(struct buffer *buf, _u16 caps) {
      u_int8_t t[4];
      t[0] = 0; 
      t[1] = 0;
      set16(&t[2], caps);
      if(add_avp(buf, BEARER_CAP_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_firmware_avp(struct buffer *buf) {
      u_int8_t t[2];
      set16(t, OUR_L2TP_VERSION);
      if(add_avp(buf, FIRMWARE_REV_AVP, t, 2, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_hostname_avp(struct buffer *buf, struct tunnel *t) {
      char n[STRLEN];
      int sz = 0;
      if(t->lac && t->lac->hostname[0]) {
            strncpy(n,t->lac->hostname, sizeof(n));
            sz = strnlen(t->lac->hostname, sizeof(t->lac->hostname));
      }
      else if(t->lns && t->lns->hostname[0]) {
            strncpy(n,t->lns->hostname, sizeof(n));
            sz = strnlen(t->lns->hostname, sizeof(t->lns->hostname));
      }
      else {
            if(gethostname(n, STRLEN)) {
                  strcpy(n,"eriwan");
                  sz = 6;
            }
            else
                  sz = strnlen(n, sizeof(n));
      }
      if(add_avp(buf, HOSTNAME_AVP, n, sz, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_vendor_avp(struct buffer *buf) {
      if(add_avp(buf, VENDOR_NAME_AVP, VENDOR_NAME, strlen(VENDOR_NAME), 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_tunnelid_avp(struct buffer *buf, _u16 tid) {
      u_int8_t t[2];
      set16(t, tid);
      if(add_avp(buf, ASSIGNED_TUN_ID_AVP, t, 2, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_avp_rws(struct buffer *buf, _u16 rws) {
      u_int8_t t[2];
      set16(t, rws);
      if(add_avp(buf, RX_WIN_SIZE_AVP, t, 2, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_challenge_avp(struct buffer *buf, char *c, int len) {
      if(add_avp(buf, CHALLENGE_AVP, c, len, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_chalresp_avp(struct buffer *buf, char *c, int len) {
      if(add_avp(buf, CHALLENGE_RESP_AVP, c, len, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_randvect_avp(struct buffer *buf, char *c, int len) {
      if(add_avp(buf, RANDOM_VECTOR_AVP, c, len, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_result_code_avp(struct buffer *buf, _u16 result, _u16 error,
                        char *msg, int len) {
      u_int8_t t[4];
      set16(t, result);
      set16(&t[2], error);
      memcpy((u_int8_t*)(buf->start + buf->len + 10), msg, len);
      memcpy((u_int8_t*)(buf->start + buf->len + 6), t, 4);
      if(add_avp(buf, RESULT_CODE_AVP, 0, 4 + len, 0))
            return 1;
    return 0;
}

/*****************************************************************************/
#ifdef TEST_HIDDEN
int add_callid_avp(struct buffer *buf, _u16 callid, struct tunnel *t) {
      u_int8_t t[2];
    if (t->hbit)
        raw++;
      set16(t, callid);
      if(add_avp(buf, ASSIGNED_SES_ID_AVP, t, 2, 1))
            return 1;
    if (t->hbit)
        encrypt_avp (buf, 8, t);
    return 0;
}
#else
int add_callid_avp(struct buffer *buf, _u16 callid) {
      u_int8_t t[2];
      set16(t, callid);
      if(add_avp(buf, ASSIGNED_SES_ID_AVP, t, 2, 1))
            return 1;
    return 0;
}
#endif

/*****************************************************************************/
int add_serno_avp(struct buffer *buf, unsigned int serno) {
      u_int8_t t[4];
      set32(t, serno);
      if(add_avp(buf, SERIAL_NUMBER_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_bearer_avp(struct buffer *buf, int bearer) {
      u_int8_t t[4];
      set32(t, bearer);
      if(add_avp(buf, BEARER_TYPE_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_frame_avp(struct buffer *buf, int frame) {
      u_int8_t t[4];
      set32(t, frame);
      if(add_avp(buf, FRAMING_TYPE_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_txspeed_avp(struct buffer *buf, int speed) {
      u_int8_t t[4];
      set32(t, speed);
      if(add_avp(buf, TX_CONNECT_SPEED_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_rxspeed_avp(struct buffer *buf, int speed) {
      u_int8_t t[4];
      set32(t, speed);
      if(add_avp(buf, RX_CONNECT_SPEED_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_physchan_avp(struct buffer *buf, unsigned int physchan) {
      u_int8_t t[4];
      set32(t, physchan);
      if(add_avp(buf, PHYS_CHAN_ID_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_ppd_avp(struct buffer *buf, _u16 ppd) {
      u_int8_t t[2];
      set16(t, ppd);
      if(add_avp(buf, PACKET_DELAY_AVP, t, 2, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_seqreqd_avp(struct buffer *buf) {
      if(add_avp(buf, SEQ_REQUIRED_AVP, 0, 0, 0))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_minbps_avp(struct buffer *buf, int speed) {
      u_int8_t t[4];
      set32(t, speed);
      if(add_avp(buf, MIN_BPS_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_maxbps_avp(struct buffer *buf, int speed) {
      u_int8_t t[4];
      set32(t, speed);
      if(add_avp(buf, MAX_BPS_AVP, t, 4, 1))
            return 1;
    return 0;
}

/*****************************************************************************/
int add_number_avp(struct buffer *buf, char *no) {
      if(add_avp(buf, CALLED_NUMBER_AVP, no, strlen(no), 1))
            return 1;
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index