Esempio n. 1
0
/* resend una packets */
static int
l2tp_ctrl_resend_una_packets(l2tp_ctrl *_this)
{
	uint16_t seq;
	bytebuffer *bytebuf;
	struct l2tp_header *header;
	int nsend;

	nsend = 0;
	for (seq = _this->snd_una; SEQ_LT(seq, _this->snd_nxt); seq++) {
		bytebuf = _this->snd_buffers[seq % _this->winsz];
		header = bytebuffer_pointer(bytebuf);
		header->nr = htons(_this->rcv_nxt);
#ifdef L2TP_CTRL_DEBUG
		if (debuglevel >= 3) {
			l2tp_ctrl_log(_this, DEBUG_LEVEL_3, "RESEND seq=%u",
			    ntohs(header->ns));
			show_hd(debug_get_debugfp(),
			    bytebuffer_pointer(bytebuf),
			    bytebuffer_remaining(bytebuf));
		}
#endif
		if (l2tp_ctrl_send(_this, bytebuffer_pointer(bytebuf),
		    bytebuffer_remaining(bytebuf)) < 0) {
			l2tp_ctrl_log(_this, LOG_ERR,
			    "sendto() failed in %s: %m", __func__);
			return -1;
		}
		nsend++;
	}
	return nsend;
}
Esempio n. 2
0
/* send control packet */
int
l2tp_ctrl_send_packet(l2tp_ctrl *_this, int call_id, bytebuffer *bytebuf)
{
	struct l2tp_header *hdr;
	int rval;
	time_t curr_time;

	curr_time = get_monosec();

	bytebuffer_flip(bytebuf);
	hdr = (struct l2tp_header *)bytebuffer_pointer(bytebuf);
	memset(hdr, 0, sizeof(*hdr));

	hdr->t = 1;
	hdr->ver = L2TP_HEADER_VERSION_RFC2661;
	hdr->l = 1;
	hdr->length = htons(bytebuffer_remaining(bytebuf));
	hdr->tunnel_id = htons(_this->peer_tunnel_id);
	hdr->session_id = htons(call_id);

	hdr->s = 1;
	hdr->ns = htons(_this->snd_nxt);
	hdr->nr = htons(_this->rcv_nxt);

	if (bytebuffer_remaining(bytebuf) > sizeof(struct l2tp_header))
		/* Not ZLB */
		_this->snd_nxt++;

	L2TP_CTRL_DBG((_this, DEBUG_LEVEL_2,
	    "SEND C ns=%u nr=%u snd_nxt=%u snd_una=%u rcv_nxt=%u ",
	    ntohs(hdr->ns), htons(hdr->nr),
	    _this->snd_nxt, _this->snd_una, _this->rcv_nxt));

	if (L2TP_CTRL_CONF(_this)->ctrl_out_pktdump  != 0) {
		l2tpd_log(_this->l2tpd, LOG_DEBUG,
		    "L2TP Control output packet dump");
		show_hd(debug_get_debugfp(), bytebuffer_pointer(bytebuf),
		    bytebuffer_remaining(bytebuf));
	}

	if ((rval = l2tp_ctrl_send(_this, bytebuffer_pointer(bytebuf),
	    bytebuffer_remaining(bytebuf))) < 0) {
		L2TP_CTRL_DBG((_this, LOG_DEBUG, "sendto() failed: %m"));
	}

	_this->last_snd_ctrl = curr_time;

	return (rval == bytebuffer_remaining(bytebuf))? 0 : 1;
}
Esempio n. 3
0
/* Some route implementation which has "PPTP pass-through" function
 * will discard 1723/tcp packet between PAC and PNS, when it recognize
 * SLI from PAC. (for example, FLASHWAVE by Fujitsu).
 *
 * To avoid avobe situation, npppd send well-known SLI only.
 */
static int
pptp_call_send_SLI(pptp_call *_this)
{
	int lpkt;
	struct pptp_sli *sli;

	sli = bytebuffer_pointer(_this->ctrl->send_buf);
	lpkt = bytebuffer_remaining(_this->ctrl->send_buf);
	if (lpkt < sizeof(struct pptp_sli)) {
		pptp_call_log(_this, LOG_ERR,
		    "SendOCRP failed: No buffer space available");
		return -1;
	}
	memset(sli, 0, sizeof(struct pptp_sli));

	pptp_init_header(&sli->header, sizeof(struct pptp_sli),
	    PPTP_CTRL_MES_CODE_SLI);

	sli->peers_call_id = _this->id;
	sli->send_accm = 0xffffffff;
	sli->recv_accm = 0xffffffff;

	_this->last_io = get_monosec();
	pptp_call_log(_this, LOG_INFO, "SendSLI accm=%08x:%08x",
	    sli->send_accm, sli->recv_accm);
	sli->peers_call_id = htons(sli->peers_call_id);
	sli->send_accm = htonl(sli->send_accm);
	sli->recv_accm = htonl(sli->recv_accm);
	pptp_ctrl_output(_this->ctrl, NULL,  sizeof(struct pptp_sli));

	return 0;
}
Esempio n. 4
0
static int
pppoe_session_send_PADT(pppoe_session *_this)
{
	u_char bufspace[2048];
	bytebuffer *buf;
	struct pppoe_header pppoe;
	int rval = 0;
	struct pppoe_tlv tlv;

	if ((buf = bytebuffer_wrap(bufspace, sizeof(bufspace))) == NULL) {
		pppoe_session_log(_this, LOG_ERR,
		"bytebuffer_wrap() failed on %s(): %m", __func__);
		return -1;
	}
	bytebuffer_clear(buf);

	/*
	 * PPPoE Header
	 */
	memset(&pppoe, 0, sizeof(pppoe));
	pppoe.ver = PPPOE_RFC2516_VER;
	pppoe.type = PPPOE_RFC2516_TYPE;
	pppoe.code = PPPOE_CODE_PADT;
	pppoe.session_id = htons(_this->session_id);
	bytebuffer_put(buf, &pppoe, sizeof(pppoe));

	/*
	 * Tag - End-of-List
	 */
	tlv.type = htons(PPPOE_TAG_END_OF_LIST);
	tlv.length = 0;
	bytebuffer_put(buf, &tlv, sizeof(tlv));
	tlv.type = htons(PPPOE_TAG_END_OF_LIST);
	tlv.length = 0;
	bytebuffer_put(buf, &tlv, sizeof(tlv));

	bytebuffer_flip(buf);
	if (pppoe_session_output(_this, 1, bytebuffer_pointer(buf),
	    bytebuffer_remaining(buf)) != 0) {
		pppoe_session_log(_this, LOG_ERR, "pppoed_output failed: %m");
		rval = 1;
	}
	pppoe_session_log(_this, LOG_INFO, "SendPADT");

	bytebuffer_unwrap(buf);
	bytebuffer_destroy(buf);

	return rval;
}
Esempio n. 5
0
/* send L2TP data message */
static int
l2tp_call_send_data_packet(l2tp_call *_this, bytebuffer *buffer)
{
	int rval;
	struct l2tp_header *hdr;

	bytebuffer_flip(buffer);
	hdr = (struct l2tp_header *)bytebuffer_pointer(buffer);
	memset(hdr, 0, sizeof(*hdr) - 4);	/* Nr, NS are option */

	hdr->t = 0;
	hdr->ver = L2TP_HEADER_VERSION_RFC2661;
	hdr->l = 1;
	hdr->length = htons(bytebuffer_remaining(buffer));
	hdr->tunnel_id = htons(_this->ctrl->peer_tunnel_id);
	hdr->session_id = htons(_this->peer_session_id);
	if (_this->use_seq) {
		hdr->s = 1;
		hdr->ns = htons(_this->snd_nxt++);
		hdr->nr = htons(_this->rcv_nxt);
	}

	if (L2TP_CTRL_CONF(_this->ctrl)->data_out_pktdump != 0) {
		l2tpd_log(_this->ctrl->l2tpd, LOG_DEBUG,
		    "ctrl=%u call=%u L2TP Data output packet dump",
		    _this->ctrl->id, _this->id);
		show_hd(debug_get_debugfp(), bytebuffer_pointer(buffer),
		    bytebuffer_remaining(buffer));
	}
	if ((rval = l2tp_ctrl_send(_this->ctrl, bytebuffer_pointer(buffer),
	    bytebuffer_remaining(buffer))) < 0) {
		L2TP_CALL_DBG((_this, LOG_DEBUG, "sendto() failed: %m"));
	}

	return (rval == bytebuffer_remaining(buffer))? 0 : 1;
}
Esempio n. 6
0
/* Send Outgoing-Call-Reply */
static int
pptp_call_send_OCRP(pptp_call *_this, int result, int error, int cause)
{
	int lpkt;
	struct pptp_ocrp *ocrp;
	char logbuf[512];

	ocrp = bytebuffer_pointer(_this->ctrl->send_buf);
	lpkt = bytebuffer_remaining(_this->ctrl->send_buf);
	if (lpkt < sizeof(struct pptp_ocrp)) {
		pptp_call_log(_this, LOG_ERR,
		    "SendOCRP failed: No buffer space available");
		return -1;
	}
	memset(ocrp, 0, sizeof(struct pptp_ocrp));

	pptp_init_header(&ocrp->header, sizeof(struct pptp_ocrp),
	    PPTP_CTRL_MES_CODE_OCRP);

	ocrp->call_id = _this->id;
	ocrp->peers_call_id = _this->peers_call_id;
	ocrp->result_code = result;
	ocrp->error_code = error;
	ocrp->cause_code = cause;
	ocrp->connect_speed = PPTP_CALL_CONNECT_SPEED;
	ocrp->recv_winsz =  _this->maxwinsz;
	ocrp->packet_proccessing_delay = PPTP_CALL_INITIAL_PPD;
	ocrp->physical_channel_id = _this->id;

	pptp_call_OCRP_string(ocrp, logbuf, sizeof(logbuf));
	pptp_call_log(_this, LOG_INFO, "SendOCRP %s", logbuf);

	ocrp->call_id = htons(ocrp->call_id);
	ocrp->peers_call_id = htons(ocrp->peers_call_id);
	ocrp->cause_code = htons(ocrp->cause_code);
	ocrp->connect_speed = htons(ocrp->connect_speed);
	ocrp->recv_winsz = htons(ocrp->recv_winsz);
	ocrp->packet_proccessing_delay = htons(ocrp->packet_proccessing_delay);
	ocrp->physical_channel_id = htonl(ocrp->physical_channel_id);

	_this->last_io = get_monosec();
	pptp_ctrl_output(_this->ctrl, NULL,  sizeof(struct pptp_ocrp));

	return 0;
}
Esempio n. 7
0
/* Send Call-Disconnect-Notify */
static void
pptp_call_send_CDN(pptp_call *_this, int result, int error, int cause,
    const char *statistics)
{
	int lpkt;
	struct pptp_cdn *cdn;

	cdn = bytebuffer_pointer(_this->ctrl->send_buf);
	lpkt = bytebuffer_remaining(_this->ctrl->send_buf);
	if (lpkt < sizeof(struct pptp_cdn)) {
		pptp_call_log(_this, LOG_ERR,
		    "SendCCR failed: No buffer space available");
		return;
	}
	memset(cdn, 0, sizeof(struct pptp_cdn));

	pptp_init_header(&cdn->header, sizeof(struct pptp_cdn),
	    PPTP_CTRL_MES_CODE_CDN);

	cdn->call_id = _this->id;
	cdn->result_code = result;
	cdn->error_code = error;
	cdn->cause_code = cause;
	if (statistics != NULL)
		strlcpy(cdn->statistics, statistics, sizeof(cdn->statistics));

	pptp_call_log(_this, LOG_INFO, "SendCDN "
	    "call_id=%u result=%s(%d) error=%s(%d) cause=%d statistics=%s",
	    cdn->call_id,
	    pptp_CDN_result_string(cdn->result_code), cdn->result_code,
	    pptp_general_error_string(cdn->error_code), cdn->error_code,
	    cdn->cause_code,
		(statistics == NULL)? "(none)" : (char *)cdn->statistics);

	cdn->call_id = htons(cdn->call_id);
	cdn->cause_code = htons(cdn->cause_code);

	_this->last_io = get_monosec();
	pptp_ctrl_output(_this->ctrl, NULL, sizeof(struct pptp_cdn));
}
Esempio n. 8
0
/* send PADS */
static int
pppoe_session_send_PADS(pppoe_session *_this, struct pppoe_tlv *hostuniq,
    struct pppoe_tlv *service_name)
{
	int rval, len;
	u_char bufspace[2048], msgbuf[80];
	bytebuffer *buf;
	struct pppoe_header pppoe;
	struct pppoe_tlv tlv;

	if ((buf = bytebuffer_wrap(bufspace, sizeof(bufspace))) == NULL) {
		pppoe_session_log(_this, LOG_ERR,
		"bytebuffer_wrap() failed on %s(): %m", __func__);
		return -1;
	}
	bytebuffer_clear(buf);

	/*
	 * PPPoE Header
	 */
	memset(&pppoe, 0, sizeof(pppoe));
	pppoe.ver = PPPOE_RFC2516_VER;
	pppoe.type = PPPOE_RFC2516_TYPE;
	pppoe.code = PPPOE_CODE_PADS;
	pppoe.session_id = htons(_this->session_id);
	bytebuffer_put(buf, &pppoe, sizeof(pppoe));

	/*
	 * Tag - Service-Name
	 */
	msgbuf[0] = '\0';
	if (service_name != NULL) {
		tlv.type = htons(PPPOE_TAG_SERVICE_NAME);
		tlv.length = htons(service_name->length);
		bytebuffer_put(buf, &tlv, sizeof(tlv));

		len = service_name->length;
		if (len > 0) {
			bytebuffer_put(buf, service_name->value, len);
			strlcpy(msgbuf, service_name->value,
			    MIN(len + 1, sizeof(msgbuf)));
		}
	}

	/*
	 * Tag - Host-Uniq
	 */
	if (hostuniq != NULL) {
		tlv.type = htons(PPPOE_TAG_HOST_UNIQ);
		tlv.length = htons(hostuniq->length);
		bytebuffer_put(buf, &tlv, sizeof(tlv));
		bytebuffer_put(buf, hostuniq->value, hostuniq->length);
	}
	tlv.type = htons(PPPOE_TAG_END_OF_LIST);
	tlv.length = 0;
	bytebuffer_put(buf, &tlv, sizeof(tlv));

	bytebuffer_flip(buf);
	rval = 0;
	if (pppoe_session_output(_this, 1, bytebuffer_pointer(buf),
	    bytebuffer_remaining(buf)) != 0) {
		pppoe_session_log(_this, LOG_ERR, "pppoed_output failed: %m");
		rval = 1;
	}
	pppoe_session_log(_this, LOG_INFO, "SendPADS serviceName=%s "
	    "hostUniq=%s", msgbuf,
	    hostuniq? pppoed_tlv_value_string(hostuniq) : "none");

	bytebuffer_unwrap(buf);
	bytebuffer_destroy(buf);

	return rval;
}