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; }
/* 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; }
/* 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; }
/* 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; }