update 2026-07-10 22:10:07

This commit is contained in:
action 2026-07-10 22:10:07 +08:00
parent ddc4538935
commit 8a04c3469b
1956 changed files with 0 additions and 1523141 deletions

View File

@ -1,26 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fibocom-dial
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/fibocom-dial
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Fibocom Dial
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Package/fibocom-dial/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibocom-dial $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibo_qmimsg_server $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/multi-pdn-manager $(1)/usr/bin
endef
$(eval $(call BuildPackage,fibocom-dial))

View File

@ -1,275 +0,0 @@
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include "QMIThread.h"
#ifdef CONFIG_GOBINET
// IOCTL to generate a client ID for this service type
#define IOCTL_QMI_GET_SERVICE_FILE 0x8BE0 + 1
// IOCTL to get the VIDPID of the device
#define IOCTL_QMI_GET_DEVICE_VIDPID 0x8BE0 + 2
// IOCTL to get the MEID of the device
#define IOCTL_QMI_GET_DEVICE_MEID 0x8BE0 + 3
static int GobiNetSendQMI(PQCQMIMSG pRequest)
{
int ret, fd;
static int send_count = 0;
fd = qmiclientId[pRequest->QMIHdr.QMIType];
if (fd <= 0) {
dbg_time("%s QMIType: %d has no clientID", __func__,
pRequest->QMIHdr.QMIType);
return -ENODEV;
}
// Always ready to write
re_write:
if (1 == 1) {
ssize_t nwrites =
le16_to_cpu(pRequest->QMIHdr.Length) + 1 - sizeof(QCQMI_HDR);
ret = write(fd, &pRequest->MUXMsg, nwrites);
if (ret == nwrites)
{
ret = 0;
send_count = 0;
}
else
{
send_count++;
dbg_time("%s write=%d, errno: %d (%s) send_count %d", __func__, ret, errno, strerror(errno), send_count);
if (send_count < 3)
{
sleep(1);
goto re_write;
}
}
} else {
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno,
strerror(errno));
}
return ret;
}
static int GobiNetGetClientID(const char *qcqmi, UCHAR QMIType)
{
int ClientId;
ClientId = open(qcqmi, O_RDWR | O_NONBLOCK | O_NOCTTY);
if (ClientId == -1) {
dbg_time("failed to open %s, errno: %d (%s)", qcqmi, errno,
strerror(errno));
return -1;
}
if (ioctl(ClientId, IOCTL_QMI_GET_SERVICE_FILE, QMIType) != 0) {
dbg_time("failed to get ClientID for 0x%02x errno: %d (%s)", QMIType,
errno, strerror(errno));
close(ClientId);
ClientId = 0;
}
dbg_time("%s: QMIType = %d clientid %d", __func__, QMIType, ClientId);
switch (QMIType) {
case QMUX_TYPE_WDS:
dbg_time("Get clientWDS = %d", ClientId);
break;
case QMUX_TYPE_DMS:
dbg_time("Get clientDMS = %d", ClientId);
break;
case QMUX_TYPE_NAS:
dbg_time("Get clientNAS = %d", ClientId);
break;
case QMUX_TYPE_QOS:
dbg_time("Get clientQOS = %d", ClientId);
break;
case QMUX_TYPE_WMS:
dbg_time("Get clientWMS = %d", ClientId);
break;
case QMUX_TYPE_PDS:
dbg_time("Get clientPDS = %d", ClientId);
break;
case QMUX_TYPE_UIM:
dbg_time("Get clientUIM = %d", ClientId);
break;
case QMUX_TYPE_WDS_ADMIN:
dbg_time("Get clientWDA = %d", ClientId);
break;
default:
break;
}
return ClientId;
}
static int GobiNetDeInit(void)
{
unsigned int i;
for (i = 0; i < sizeof(qmiclientId) / sizeof(qmiclientId[0]); i++) {
if (qmiclientId[i] != 0) {
close(qmiclientId[i]);
qmiclientId[i] = 0;
}
}
return 0;
}
static void *GobiNetThread(void *pData)
{
PROFILE_T *profile = (PROFILE_T *)pData;
const char *qcqmi = (const char *)profile->qmichannel;
int wait_for_request_quit = 0;
dbg_time("%s %d", __func__, __LINE__);
if (profile->ipv4_flag)
qmiclientId[QMUX_TYPE_WDS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
if (profile->ipv6_flag)
qmiclientId[QMUX_TYPE_WDS_IPV6] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
qmiclientId[QMUX_TYPE_DMS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_DMS);
qmiclientId[QMUX_TYPE_NAS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_NAS);
qmiclientId[QMUX_TYPE_UIM] = GobiNetGetClientID(qcqmi, QMUX_TYPE_UIM);
// qmiclientId[QMUX_TYPE_WDS_ADMIN] =
// GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS_ADMIN);
//if ((qmiclientId[QMUX_TYPE_WDS] == 0) && (qmiclientId[QMUX_TYPE_WDS_IPV6] == 0)) /*|| (clientWDA == -1)*/ {
if ((qmiclientId[QMUX_TYPE_DMS] == 0) ||
(qmiclientId[QMUX_TYPE_NAS] == 0) ||
(qmiclientId[QMUX_TYPE_UIM] == 0) ||
(profile->ipv4_flag ? ((qmiclientId[QMUX_TYPE_WDS] == 0) ? 1 : 0):0)||
(profile->ipv6_flag ? ((qmiclientId[QMUX_TYPE_WDS_IPV6] == 0) ? 1 : 0):0))
{
GobiNetDeInit();
dbg_time("%s Failed to open %s, errno: %d (%s)", __func__, qcqmi, errno,strerror(errno));
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
pthread_exit(NULL);
return NULL;
}
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_CONNECTED);
while (1) {
struct pollfd pollfds[16] = {{qmidevice_control_fd[1], POLLIN, 0}};
int ne, ret, nevents = 1;
unsigned int i;
for (i = 0; i < sizeof(qmiclientId) / sizeof(qmiclientId[0]); i++) {
if (qmiclientId[i] != 0) {
pollfds[nevents].fd = qmiclientId[i];
pollfds[nevents].events = POLLIN;
pollfds[nevents].revents = 0;
nevents++;
}
}
do {
ret = poll(pollfds, nevents, wait_for_request_quit ? 1000 : -1);
} while ((ret < 0) && (errno == EINTR));
if (ret == 0 && wait_for_request_quit) {
QmiThreadRecvQMI(
NULL); // main thread may pending on QmiThreadSendQMI()
continue;
}
if (ret <= 0) {
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno,
strerror(errno));
break;
}
for (ne = 0; ne < nevents; ne++) {
int fd = pollfds[ne].fd;
short revents = pollfds[ne].revents;
if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
dbg_time("%s poll err/hup/inval", __func__);
dbg_time("epoll fd = %d, events = 0x%04x", fd, revents);
if (fd == qmidevice_control_fd[1]) {
} else {
}
if (revents & (POLLERR | POLLHUP | POLLNVAL))
goto __GobiNetThread_quit;
}
if ((revents & POLLIN) == 0)
continue;
if (fd == qmidevice_control_fd[1]) {
int triger_event;
if (read(fd, &triger_event, sizeof(triger_event)) ==
sizeof(triger_event)) {
// DBG("triger_event = 0x%x", triger_event);
switch (triger_event) {
case RIL_REQUEST_QUIT:
goto __GobiNetThread_quit;
break;
case SIGTERM:
wait_for_request_quit = 1;
break;
default:
break;
}
}
continue;
}
{
ssize_t nreads;
static UCHAR QMIBuf[4096];
PQCQMIMSG pResponse = (PQCQMIMSG)QMIBuf;
nreads = read(fd, &pResponse->MUXMsg,
sizeof(QMIBuf) - sizeof(QCQMI_HDR));
if (nreads <= 0) {
dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads,
errno, strerror(errno));
break;
}
for (i = 0; i < sizeof(qmiclientId) / sizeof(qmiclientId[0]);
i++) {
if (qmiclientId[i] == fd) {
pResponse->QMIHdr.QMIType = i;
}
}
pResponse->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
pResponse->QMIHdr.Length =
cpu_to_le16(nreads + sizeof(QCQMI_HDR) - 1);
pResponse->QMIHdr.CtlFlags = 0x00;
pResponse->QMIHdr.ClientId = fd & 0xFF;
QmiThreadRecvQMI(pResponse);
}
}
}
__GobiNetThread_quit:
GobiNetDeInit();
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
QmiThreadRecvQMI(NULL); // main thread may pending on QmiThreadSendQMI()
dbg_time("%s exit", __func__);
pthread_exit(NULL);
return NULL;
}
#else
static int GobiNetSendQMI(PQCQMIMSG pRequest) { return -1; }
static void *GobiNetThread(void *pData)
{
dbg_time("please set CONFIG_GOBINET");
return NULL;
}
#endif
const struct qmi_device_ops gobi_qmidev_ops = {
.deinit = GobiNetDeInit,
.send = GobiNetSendQMI,
.read = GobiNetThread,
};

View File

@ -1,363 +0,0 @@
/*===========================================================================
M P Q C T L. H
DESCRIPTION:
This module contains QMI QCTL module.
INITIALIZATION AND SEQUENCING REQUIREMENTS:
Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved.
===========================================================================*/
#ifndef MPQCTL_H
#define MPQCTL_H
#include "MPQMI.h"
#pragma pack(push, 1)
// ================= QMICTL ==================
// QMICTL Control Flags
#define QMICTL_CTL_FLAG_CMD 0x00
#define QMICTL_CTL_FLAG_RSP 0x01
#define QMICTL_CTL_FLAG_IND 0x02
#if 0
typedef struct _QMICTL_TRANSACTION_ITEM
{
LIST_ENTRY List;
UCHAR TransactionId; // QMICTL transaction id
PVOID Context; // Adapter or IocDev
PIRP Irp;
} QMICTL_TRANSACTION_ITEM, *PQMICTL_TRANSACTION_ITEM;
#endif
typedef struct _QCQMICTL_MSG_HDR {
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
UCHAR TransactionId;
USHORT QMICTLType;
USHORT Length;
} __attribute__((packed)) QCQMICTL_MSG_HDR, *PQCQMICTL_MSG_HDR;
#define QCQMICTL_MSG_HDR_SIZE sizeof(QCQMICTL_MSG_HDR)
typedef struct _QCQMICTL_MSG_HDR_RESP {
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
UCHAR TransactionId;
USHORT QMICTLType;
USHORT Length;
UCHAR TLVType; // 0x02 - result code
USHORT TLVLength; // 4
USHORT QMUXResult; // QMI_RESULT_SUCCESS
// QMI_RESULT_FAILURE
USHORT QMUXError; // QMI_ERR_INVALID_ARG
// QMI_ERR_NO_MEMORY
// QMI_ERR_INTERNAL
// QMI_ERR_FAULT
} __attribute__((packed)) QCQMICTL_MSG_HDR_RESP, *PQCQMICTL_MSG_HDR_RESP;
typedef struct _QCQMICTL_MSG {
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
UCHAR TransactionId;
USHORT QMICTLType;
USHORT Length;
UCHAR Payload;
} __attribute__((packed)) QCQMICTL_MSG, *PQCQMICTL_MSG;
// TLV Header
typedef struct _QCQMICTL_TLV_HDR {
UCHAR TLVType;
USHORT TLVLength;
} __attribute__((packed)) QCQMICTL_TLV_HDR, *PQCQMICTL_TLV_HDR;
#define QCQMICTL_TLV_HDR_SIZE sizeof(QCQMICTL_TLV_HDR)
// QMICTL Type
#define QMICTL_SET_INSTANCE_ID_REQ 0x0020
#define QMICTL_SET_INSTANCE_ID_RESP 0x0020
#define QMICTL_GET_VERSION_REQ 0x0021
#define QMICTL_GET_VERSION_RESP 0x0021
#define QMICTL_GET_CLIENT_ID_REQ 0x0022
#define QMICTL_GET_CLIENT_ID_RESP 0x0022
#define QMICTL_RELEASE_CLIENT_ID_REQ 0x0023
#define QMICTL_RELEASE_CLIENT_ID_RESP 0x0023
#define QMICTL_REVOKE_CLIENT_ID_IND 0x0024
#define QMICTL_INVALID_CLIENT_ID_IND 0x0025
#define QMICTL_SET_DATA_FORMAT_REQ 0x0026
#define QMICTL_SET_DATA_FORMAT_RESP 0x0026
#define QMICTL_SYNC_REQ 0x0027
#define QMICTL_SYNC_RESP 0x0027
#define QMICTL_SYNC_IND 0x0027
#define QMICTL_FLAG_REQUEST 0x00
#define QMICTL_FLAG_RESPONSE 0x01
#define QMICTL_FLAG_INDICATION 0x02
// QMICTL Message Definitions
typedef struct _QMICTL_SET_INSTANCE_ID_REQ_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_SET_INSTANCE_ID_REQ
USHORT Length; // 4
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLVLength; // 1
UCHAR Value; // Host-unique QMI instance for this device driver
} __attribute__((packed)) QMICTL_SET_INSTANCE_ID_REQ_MSG,
*PQMICTL_SET_INSTANCE_ID_REQ_MSG;
typedef struct _QMICTL_SET_INSTANCE_ID_RESP_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_SET_INSTANCE_ID_RESP
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
USHORT TLVLength; // 0x0004
USHORT QMIResult;
USHORT QMIError;
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLV2Length; // 0x0002
USHORT QMI_ID; // Upper byte is assigned by MSM,
// lower assigned by host
} __attribute__((packed)) QMICTL_SET_INSTANCE_ID_RESP_MSG,
*PQMICTL_SET_INSTANCE_ID_RESP_MSG;
typedef struct _QMICTL_GET_VERSION_REQ_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_GET_VERSION_REQ
USHORT Length; // 0
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLVLength; // var
UCHAR QMUXTypes; // List of one byte QMUX_TYPE values
// 0xFF returns a list of versions for all
// QMUX_TYPEs implemented on the device
} __attribute__((packed)) QMICTL_GET_VERSION_REQ_MSG,
*PQMICTL_GET_VERSION_REQ_MSG;
typedef struct _QMUX_TYPE_VERSION_STRUCT {
UCHAR QMUXType;
USHORT MajorVersion;
USHORT MinorVersion;
} __attribute__((packed)) QMUX_TYPE_VERSION_STRUCT, *PQMUX_TYPE_VERSION_STRUCT;
typedef struct _ADDENDUM_VERSION_PREAMBLE {
UCHAR LabelLength;
UCHAR Label;
} __attribute__((packed)) ADDENDUM_VERSION_PREAMBLE,
*PADDENDUM_VERSION_PREAMBLE;
#define QMICTL_GET_VERSION_RSP_TLV_TYPE_VERSION 0x01
#define QMICTL_GET_VERSION_RSP_TLV_TYPE_ADD_VERSION 0x10
typedef struct _QMICTL_GET_VERSION_RESP_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_GET_VERSION_RESP
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
USHORT TLVLength; // 0x0004
USHORT QMIResult;
USHORT QMIError;
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLV2Length; // var
UCHAR NumElements; // Num of QMUX_TYPE_VERSION_STRUCT
QMUX_TYPE_VERSION_STRUCT TypeVersion[0];
} __attribute__((packed)) QMICTL_GET_VERSION_RESP_MSG,
*PQMICTL_GET_VERSION_RESP_MSG;
typedef struct _QMICTL_GET_CLIENT_ID_REQ_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_GET_CLIENT_ID_REQ
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLVLength; // 1
UCHAR QMIType; // QMUX type
} __attribute__((packed)) QMICTL_GET_CLIENT_ID_REQ_MSG,
*PQMICTL_GET_CLIENT_ID_REQ_MSG;
typedef struct _QMICTL_GET_CLIENT_ID_RESP_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_GET_CLIENT_ID_RESP
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
USHORT TLVLength; // 0x0004
USHORT QMIResult; // result code
USHORT QMIError; // error code
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLV2Length; // 2
UCHAR QMIType;
UCHAR ClientId;
} __attribute__((packed)) QMICTL_GET_CLIENT_ID_RESP_MSG,
*PQMICTL_GET_CLIENT_ID_RESP_MSG;
typedef struct _QMICTL_RELEASE_CLIENT_ID_REQ_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_RELEASE_CLIENT_ID_REQ
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLVLength; // 0x0002
UCHAR QMIType;
UCHAR ClientId;
} __attribute__((packed)) QMICTL_RELEASE_CLIENT_ID_REQ_MSG,
*PQMICTL_RELEASE_CLIENT_ID_REQ_MSG;
typedef struct _QMICTL_RELEASE_CLIENT_ID_RESP_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_RELEASE_CLIENT_ID_RESP
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
USHORT TLVLength; // 0x0004
USHORT QMIResult; // result code
USHORT QMIError; // error code
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLV2Length; // 2
UCHAR QMIType;
UCHAR ClientId;
} __attribute__((packed)) QMICTL_RELEASE_CLIENT_ID_RESP_MSG,
*PQMICTL_RELEASE_CLIENT_ID_RESP_MSG;
typedef struct _QMICTL_REVOKE_CLIENT_ID_IND_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLVLength; // 0x0002
UCHAR QMIType;
UCHAR ClientId;
} __attribute__((packed)) QMICTL_REVOKE_CLIENT_ID_IND_MSG,
*PQMICTL_REVOKE_CLIENT_ID_IND_MSG;
typedef struct _QMICTL_INVALID_CLIENT_ID_IND_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLVLength; // 0x0002
UCHAR QMIType;
UCHAR ClientId;
} __attribute__((packed)) QMICTL_INVALID_CLIENT_ID_IND_MSG,
*PQMICTL_INVALID_CLIENT_ID_IND_MSG;
typedef struct _QMICTL_SET_DATA_FORMAT_REQ_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_REQ
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
USHORT TLVLength; // 1
UCHAR DataFormat; // 0-default; 1-QoS hdr present
} __attribute__((packed)) QMICTL_SET_DATA_FORMAT_REQ_MSG,
*PQMICTL_SET_DATA_FORMAT_REQ_MSG;
#ifdef QC_IP_MODE
#define SET_DATA_FORMAT_TLV_TYPE_LINK_PROTO 0x10
#define SET_DATA_FORMAT_LINK_PROTO_ETH 0x0001
#define SET_DATA_FORMAT_LINK_PROTO_IP 0x0002
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_LINK_PROT {
UCHAR TLVType; // Link-Layer Protocol
USHORT TLVLength; // 2
USHORT LinkProt; // 0x1: ETH; 0x2: IP
} QMICTL_SET_DATA_FORMAT_TLV_LINK_PROT, *PQMICTL_SET_DATA_FORMAT_TLV_LINK_PROT;
#ifdef QCMP_UL_TLP
#define SET_DATA_FORMAT_TLV_TYPE_UL_TLP 0x11
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_UL_TLP {
UCHAR TLVType; // 0x11, Uplink TLP Setting
USHORT TLVLength; // 1
UCHAR UlTlpSetting; // 0x0: Disable; 0x01: Enable
} QMICTL_SET_DATA_FORMAT_TLV_UL_TLP, *PQMICTL_SET_DATA_FORMAT_TLV_UL_TLP;
#endif // QCMP_UL_TLP
#ifdef QCMP_DL_TLP
#define SET_DATA_FORMAT_TLV_TYPE_DL_TLP 0x13
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_DL_TLP {
UCHAR TLVType; // 0x11, Uplink TLP Setting
USHORT TLVLength; // 1
UCHAR DlTlpSetting; // 0x0: Disable; 0x01: Enable
} QMICTL_SET_DATA_FORMAT_TLV_DL_TLP, *PQMICTL_SET_DATA_FORMAT_TLV_DL_TLP;
#endif // QCMP_DL_TLP
#endif // QC_IP_MODE
#ifdef MP_QCQOS_ENABLED
#define SET_DATA_FORMAT_TLV_TYPE_QOS_SETTING 0x12
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING {
UCHAR TLVType; // 0x12, QoS setting
USHORT TLVLength; // 1
UCHAR QosSetting; // 0x0: Disable; 0x01: Enable
} QMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING,
*PQMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING;
#endif // MP_QCQOS_ENABLED
typedef struct _QMICTL_SET_DATA_FORMAT_RESP_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_RESP
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
USHORT TLVLength; // 0x0004
USHORT QMIResult; // result code
USHORT QMIError; // error code
} __attribute__((packed)) QMICTL_SET_DATA_FORMAT_RESP_MSG,
*PQMICTL_SET_DATA_FORMAT_RESP_MSG;
typedef struct _QMICTL_SYNC_REQ_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_CTL_SYNC_REQ
USHORT Length; // 0
} __attribute__((packed)) QMICTL_SYNC_REQ_MSG, *PQMICTL_SYNC_REQ_MSG;
typedef struct _QMICTL_SYNC_RESP_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_CTL_SYNC_RESP
USHORT Length;
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
USHORT TLVLength; // 0x0004
USHORT QMIResult;
USHORT QMIError;
} __attribute__((packed)) QMICTL_SYNC_RESP_MSG, *PQMICTL_SYNC_RESP_MSG;
typedef struct _QMICTL_SYNC_IND_MSG {
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
UCHAR TransactionId;
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
USHORT Length;
} __attribute__((packed)) QMICTL_SYNC_IND_MSG, *PQMICTL_SYNC_IND_MSG;
typedef struct _QMICTL_MSG {
union {
// Message Header
QCQMICTL_MSG_HDR QMICTLMsgHdr;
QCQMICTL_MSG_HDR_RESP QMICTLMsgHdrRsp;
// QMICTL Message
QMICTL_SET_INSTANCE_ID_REQ_MSG SetInstanceIdReq;
QMICTL_SET_INSTANCE_ID_RESP_MSG SetInstanceIdRsp;
QMICTL_GET_VERSION_REQ_MSG GetVersionReq;
QMICTL_GET_VERSION_RESP_MSG GetVersionRsp;
QMICTL_GET_CLIENT_ID_REQ_MSG GetClientIdReq;
QMICTL_GET_CLIENT_ID_RESP_MSG GetClientIdRsp;
QMICTL_RELEASE_CLIENT_ID_REQ_MSG ReleaseClientIdReq;
QMICTL_RELEASE_CLIENT_ID_RESP_MSG ReleaseClientIdRsp;
QMICTL_REVOKE_CLIENT_ID_IND_MSG RevokeClientIdInd;
QMICTL_INVALID_CLIENT_ID_IND_MSG InvalidClientIdInd;
QMICTL_SET_DATA_FORMAT_REQ_MSG SetDataFormatReq;
QMICTL_SET_DATA_FORMAT_RESP_MSG SetDataFormatRsp;
QMICTL_SYNC_REQ_MSG SyncReq;
QMICTL_SYNC_RESP_MSG SyncRsp;
QMICTL_SYNC_IND_MSG SyncInd;
};
} __attribute__((packed)) QMICTL_MSG, *PQMICTL_MSG;
#endif // MPQCTL_H

View File

@ -1,287 +0,0 @@
/*===========================================================================
M P Q M I. H
DESCRIPTION:
This module contains forward references to the QMI module.
INITIALIZATION AND SEQUENCING REQUIREMENTS:
Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved.
===========================================================================*/
/*===========================================================================
EDIT HISTORY FOR FILE
$Header: //depot/QMI/win/qcdrivers/ndis/MPQMI.h#3 $
when who what, where, why
-------- --- ----------------------------------------------------------
11/20/04 hg Initial version.
===========================================================================*/
#ifndef USBQMI_H
#define USBQMI_H
typedef char CHAR;
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef int INT;
typedef unsigned int UINT;
typedef long LONG;
typedef unsigned int ULONG;
typedef unsigned long long ULONG64;
typedef char *PCHAR;
typedef unsigned char *PUCHAR;
typedef int *PINT;
typedef int BOOL;
#define TRUE (1 == 1)
#define FALSE (1 != 1)
#define QMICTL_SUPPORTED_MAJOR_VERSION 1
#define QMICTL_SUPPORTED_MINOR_VERSION 0
#pragma pack(push, 1)
// ========= USB Control Message ==========
#define USB_CTL_MSG_TYPE_QMI 0x01
// USB Control Message
typedef struct _QCUSB_CTL_MSG_HDR {
UCHAR IFType;
} __attribute__((packed)) QCUSB_CTL_MSG_HDR, *PQCUSB_CTL_MSG_HDR;
#define QCUSB_CTL_MSG_HDR_SIZE sizeof(QCUSB_CTL_MSG_HDR)
typedef struct _QCUSB_CTL_MSG {
UCHAR IFType;
UCHAR Message;
} __attribute__((packed)) QCUSB_CTL_MSG, *PQCUSB_CTL_MSG;
#define QCTLV_TYPE_REQUIRED_PARAMETER 0x01
#define QCTLV_TYPE_RESULT_CODE 0x02
// ================= QMI ==================
// Define QMI Type
typedef enum _QMI_SERVICE_TYPE {
QMUX_TYPE_CTL = 0x00,
QMUX_TYPE_WDS = 0x01,
QMUX_TYPE_DMS = 0x02,
QMUX_TYPE_NAS = 0x03,
QMUX_TYPE_QOS = 0x04,
QMUX_TYPE_WMS = 0x05,
QMUX_TYPE_PDS = 0x06,
QMUX_TYPE_UIM = 0x0B,
QMUX_TYPE_WDS_IPV6 = 0x11,
QMUX_TYPE_WDS_ADMIN = 0x1A,
QMUX_TYPE_MAX = 0xFF,
QMUX_TYPE_ALL = 0xFF
} QMI_SERVICE_TYPE;
typedef enum _QMI_RESULT_CODE_TYPE {
QMI_RESULT_SUCCESS = 0x0000,
QMI_RESULT_FAILURE = 0x0001
} QMI_RESULT_CODE_TYPE;
typedef enum _QMI_ERROR_CODE_TYPE {
QMI_ERR_NONE = 0x0000,
QMI_ERR_MALFORMED_MSG = 0x0001,
QMI_ERR_NO_MEMORY = 0x0002,
QMI_ERR_INTERNAL = 0x0003,
QMI_ERR_ABORTED = 0x0004,
QMI_ERR_CLIENT_IDS_EXHAUSTED = 0x0005,
QMI_ERR_UNABORTABLE_TRANSACTION = 0x0006,
QMI_ERR_INVALID_CLIENT_ID = 0x0007,
QMI_ERR_NO_THRESHOLDS = 0x0008,
QMI_ERR_INVALID_HANDLE = 0x0009,
QMI_ERR_INVALID_PROFILE = 0x000A,
QMI_ERR_INVALID_PINID = 0x000B,
QMI_ERR_INCORRECT_PIN = 0x000C,
QMI_ERR_NO_NETWORK_FOUND = 0x000D,
QMI_ERR_CALL_FAILED = 0x000E,
QMI_ERR_OUT_OF_CALL = 0x000F,
QMI_ERR_NOT_PROVISIONED = 0x0010,
QMI_ERR_MISSING_ARG = 0x0011,
QMI_ERR_ARG_TOO_LONG = 0x0013,
QMI_ERR_INVALID_TX_ID = 0x0016,
QMI_ERR_DEVICE_IN_USE = 0x0017,
QMI_ERR_OP_NETWORK_UNSUPPORTED = 0x0018,
QMI_ERR_OP_DEVICE_UNSUPPORTED = 0x0019,
QMI_ERR_NO_EFFECT = 0x001A,
QMI_ERR_NO_FREE_PROFILE = 0x001B,
QMI_ERR_INVALID_PDP_TYPE = 0x001C,
QMI_ERR_INVALID_TECH_PREF = 0x001D,
QMI_ERR_INVALID_PROFILE_TYPE = 0x001E,
QMI_ERR_INVALID_SERVICE_TYPE = 0x001F,
QMI_ERR_INVALID_REGISTER_ACTION = 0x0020,
QMI_ERR_INVALID_PS_ATTACH_ACTION = 0x0021,
QMI_ERR_AUTHENTICATION_FAILED = 0x0022,
QMI_ERR_PIN_BLOCKED = 0x0023,
QMI_ERR_PIN_PERM_BLOCKED = 0x0024,
QMI_ERR_SIM_NOT_INITIALIZED = 0x0025,
QMI_ERR_MAX_QOS_REQUESTS_IN_USE = 0x0026,
QMI_ERR_INCORRECT_FLOW_FILTER = 0x0027,
QMI_ERR_NETWORK_QOS_UNAWARE = 0x0028,
QMI_ERR_INVALID_QOS_ID = 0x0029,
QMI_ERR_INVALID_ID = 0x0029,
QMI_ERR_REQUESTED_NUM_UNSUPPORTED = 0x002A,
QMI_ERR_INTERFACE_NOT_FOUND = 0x002B,
QMI_ERR_FLOW_SUSPENDED = 0x002C,
QMI_ERR_INVALID_DATA_FORMAT = 0x002D,
QMI_ERR_GENERAL = 0x002E,
QMI_ERR_UNKNOWN = 0x002F,
QMI_ERR_INVALID_ARG = 0x0030,
QMI_ERR_INVALID_INDEX = 0x0031,
QMI_ERR_NO_ENTRY = 0x0032,
QMI_ERR_DEVICE_STORAGE_FULL = 0x0033,
QMI_ERR_DEVICE_NOT_READY = 0x0034,
QMI_ERR_NETWORK_NOT_READY = 0x0035,
QMI_ERR_CAUSE_CODE = 0x0036,
QMI_ERR_MESSAGE_NOT_SENT = 0x0037,
QMI_ERR_MESSAGE_DELIVERY_FAILURE = 0x0038,
QMI_ERR_INVALID_MESSAGE_ID = 0x0039,
QMI_ERR_ENCODING = 0x003A,
QMI_ERR_AUTHENTICATION_LOCK = 0x003B,
QMI_ERR_INVALID_TRANSITION = 0x003C,
QMI_ERR_NOT_A_MCAST_IFACE = 0x003D,
QMI_ERR_MAX_MCAST_REQUESTS_IN_USE = 0x003E,
QMI_ERR_INVALID_MCAST_HANDLE = 0x003F,
QMI_ERR_INVALID_IP_FAMILY_PREF = 0x0040,
QMI_ERR_SESSION_INACTIVE = 0x0041,
QMI_ERR_SESSION_INVALID = 0x0042,
QMI_ERR_SESSION_OWNERSHIP = 0x0043,
QMI_ERR_INSUFFICIENT_RESOURCES = 0x0044,
QMI_ERR_DISABLED = 0x0045,
QMI_ERR_INVALID_OPERATION = 0x0046,
QMI_ERR_INVALID_QMI_CMD = 0x0047,
QMI_ERR_TPDU_TYPE = 0x0048,
QMI_ERR_SMSC_ADDR = 0x0049,
QMI_ERR_INFO_UNAVAILABLE = 0x004A,
QMI_ERR_SEGMENT_TOO_LONG = 0x004B,
QMI_ERR_SEGMENT_ORDER = 0x004C,
QMI_ERR_BUNDLING_NOT_SUPPORTED = 0x004D,
QMI_ERR_OP_PARTIAL_FAILURE = 0x004E,
QMI_ERR_POLICY_MISMATCH = 0x004F,
QMI_ERR_SIM_FILE_NOT_FOUND = 0x0050,
QMI_ERR_EXTENDED_INTERNAL = 0x0051,
QMI_ERR_ACCESS_DENIED = 0x0052,
QMI_ERR_HARDWARE_RESTRICTED = 0x0053,
QMI_ERR_ACK_NOT_SENT = 0x0054,
QMI_ERR_INJECT_TIMEOUT = 0x0055,
QMI_ERR_INCOMPATIBLE_STATE = 0x005A,
QMI_ERR_FDN_RESTRICT = 0x005B,
QMI_ERR_SUPS_FAILURE_CAUSE = 0x005C,
QMI_ERR_NO_RADIO = 0x005D,
QMI_ERR_NOT_SUPPORTED = 0x005E,
QMI_ERR_NO_SUBSCRIPTION = 0x005F,
QMI_ERR_CARD_CALL_CONTROL_FAILED = 0x0060,
QMI_ERR_NETWORK_ABORTED = 0x0061,
QMI_ERR_MSG_BLOCKED = 0x0062,
QMI_ERR_INVALID_SESSION_TYPE = 0x0064,
QMI_ERR_INVALID_PB_TYPE = 0x0065,
QMI_ERR_NO_SIM = 0x0066,
QMI_ERR_PB_NOT_READY = 0x0067,
QMI_ERR_PIN_RESTRICTION = 0x0068,
QMI_ERR_PIN2_RESTRICTION = 0x0069,
QMI_ERR_PUK_RESTRICTION = 0x006A,
QMI_ERR_PUK2_RESTRICTION = 0x006B,
QMI_ERR_PB_ACCESS_RESTRICTED = 0x006C,
QMI_ERR_PB_DELETE_IN_PROG = 0x006D,
QMI_ERR_PB_TEXT_TOO_LONG = 0x006E,
QMI_ERR_PB_NUMBER_TOO_LONG = 0x006F,
QMI_ERR_PB_HIDDEN_KEY_RESTRICTION = 0x0070
} QMI_ERROR_CODE_TYPE;
#define QCQMI_CTL_FLAG_SERVICE 0x80
#define QCQMI_CTL_FLAG_CTL_POINT 0x00
typedef struct _QCQMI_HDR {
UCHAR IFType;
USHORT Length;
UCHAR CtlFlags; // reserved
UCHAR QMIType;
UCHAR ClientId;
} __attribute__((packed)) QCQMI_HDR, *PQCQMI_HDR;
#define QCQMI_HDR_SIZE (sizeof(QCQMI_HDR) - 1)
typedef struct _QCQMI {
UCHAR IFType;
USHORT Length;
UCHAR CtlFlags; // reserved
UCHAR QMIType;
UCHAR ClientId;
UCHAR SDU;
} __attribute__((packed)) QCQMI, *PQCQMI;
typedef struct _QMI_SERVICE_VERSION {
USHORT Major;
USHORT Minor;
USHORT AddendumMajor;
USHORT AddendumMinor;
} __attribute__((packed)) QMI_SERVICE_VERSION, *PQMI_SERVICE_VERSION;
// ================= QMUX ==================
#define QMUX_MSG_OVERHEAD_BYTES 4 // Type(USHORT) Length(USHORT) -- header
#define QMUX_BROADCAST_CID 0xFF
typedef struct _QCQMUX_HDR {
UCHAR CtlFlags; // 0: single QMUX Msg; 1:
USHORT TransactionId;
} __attribute__((packed)) QCQMUX_HDR, *PQCQMUX_HDR;
typedef struct _QCQMUX {
UCHAR CtlFlags; // 0: single QMUX Msg; 1:
USHORT TransactionId;
UCHAR Message; // Type(2), Length(2), Value
} __attribute__((packed)) QCQMUX, *PQCQMUX;
#define QCQMUX_HDR_SIZE sizeof(QCQMUX_HDR)
typedef struct _QCQMUX_MSG_HDR {
USHORT Type;
USHORT Length;
} __attribute__((packed)) QCQMUX_MSG_HDR, *PQCQMUX_MSG_HDR;
#define QCQMUX_MSG_HDR_SIZE sizeof(QCQMUX_MSG_HDR)
typedef struct _QCQMUX_MSG_HDR_RESP {
USHORT Type;
USHORT Length;
UCHAR TLVType; // 0x02 - result code
USHORT TLVLength; // 4
USHORT QMUXResult; // QMI_RESULT_SUCCESS
// QMI_RESULT_FAILURE
USHORT QMUXError; // QMI_ERR_INVALID_ARG
// QMI_ERR_NO_MEMORY
// QMI_ERR_INTERNAL
// QMI_ERR_FAULT
} __attribute__((packed)) QCQMUX_MSG_HDR_RESP, *PQCQMUX_MSG_HDR_RESP;
typedef struct _QCQMUX_TLV {
UCHAR Type;
USHORT Length;
UCHAR Value;
} __attribute__((packed)) QCQMUX_TLV, *PQCQMUX_TLV;
typedef struct _QMI_TLV_HDR {
UCHAR TLVType;
USHORT TLVLength;
} __attribute__((packed)) QMI_TLV_HDR, *PQMI_TLV_HDR;
// QMUX Message Definitions -- QMI SDU
#define QMUX_CTL_FLAG_SINGLE_MSG 0x00
#define QMUX_CTL_FLAG_COMPOUND_MSG 0x01
#define QMUX_CTL_FLAG_TYPE_CMD 0x00
#define QMUX_CTL_FLAG_TYPE_RSP 0x02
#define QMUX_CTL_FLAG_TYPE_IND 0x04
#define QMUX_CTL_FLAG_MASK_COMPOUND 0x01
#define QMUX_CTL_FLAG_MASK_TYPE 0x06 // 00-cmd, 01-rsp, 10-ind
#pragma pack(pop)
#endif // USBQMI_H

View File

@ -1,437 +0,0 @@
#include "QMIThread.h"
static char line[1024];
static pthread_mutex_t dumpQMIMutex = PTHREAD_MUTEX_INITIALIZER;
#undef dbg
#define dbg(format, arg...) \
do { \
if (strlen(line) < sizeof(line)) \
snprintf(&line[strlen(line)], sizeof(line) - strlen(line), format, \
##arg); \
} while (0)
PQMI_TLV_HDR GetTLV(PQCQMUX_MSG_HDR pQMUXMsgHdr, int TLVType);
typedef struct {
UINT type;
const char *name;
} QMI_NAME_T;
#define qmi_name_item(type) \
{ \
type, #type \
}
static const QMI_NAME_T qmux_ctl_QMICTLType[] = {
// QMICTL Type
qmi_name_item(QMICTL_SET_INSTANCE_ID_REQ), // 0x0020
qmi_name_item(QMICTL_SET_INSTANCE_ID_RESP), // 0x0020
qmi_name_item(QMICTL_GET_VERSION_REQ), // 0x0021
qmi_name_item(QMICTL_GET_VERSION_RESP), // 0x0021
qmi_name_item(QMICTL_GET_CLIENT_ID_REQ), // 0x0022
qmi_name_item(QMICTL_GET_CLIENT_ID_RESP), // 0x0022
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_REQ), // 0x0023
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_RESP), // 0x0023
qmi_name_item(QMICTL_REVOKE_CLIENT_ID_IND), // 0x0024
qmi_name_item(QMICTL_INVALID_CLIENT_ID_IND), // 0x0025
qmi_name_item(QMICTL_SET_DATA_FORMAT_REQ), // 0x0026
qmi_name_item(QMICTL_SET_DATA_FORMAT_RESP), // 0x0026
qmi_name_item(QMICTL_SYNC_REQ), // 0x0027
qmi_name_item(QMICTL_SYNC_RESP), // 0x0027
qmi_name_item(QMICTL_SYNC_IND), // 0x0027
};
static const QMI_NAME_T qmux_CtlFlags[] = {
qmi_name_item(QMUX_CTL_FLAG_TYPE_CMD),
qmi_name_item(QMUX_CTL_FLAG_TYPE_RSP),
qmi_name_item(QMUX_CTL_FLAG_TYPE_IND),
};
static const QMI_NAME_T qmux_wds_Type[] = {
qmi_name_item(QMIWDS_SET_EVENT_REPORT_REQ), // 0x0001
qmi_name_item(QMIWDS_SET_EVENT_REPORT_RESP), // 0x0001
qmi_name_item(QMIWDS_EVENT_REPORT_IND), // 0x0001
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_REQ), // 0x0020
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_RESP), // 0x0020
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_REQ), // 0x0021
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_RESP), // 0x0021
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_REQ), // 0x0022
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_RESP), // 0x0022
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_IND), // 0x0022
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_REQ), // 0x0023
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_RESP), // 0x0023
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_REQ), // 0x0024
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_RESP), // 0x0024
//begin modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610
qmi_name_item(QMIWDS_CREATE_PROFILE_SETTINGS_REQ), // 0x0027
qmi_name_item(QMIWDS_CREATE_PROFILE_SETTINGS_RESP), // 0x0027
//end modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_REQ), // 0x0028
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_RESP), // 0x0028
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_REQ), // 0x002B
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_RESP), // 0x002BD
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_REQ), // 0x002C
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_RESP), // 0x002C
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_REQ), // 0x002D
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_RESP), // 0x002D
qmi_name_item(QMIWDS_GET_MIP_MODE_REQ), // 0x002F
qmi_name_item(QMIWDS_GET_MIP_MODE_RESP), // 0x002F
qmi_name_item(QMIWDS_GET_DATA_BEARER_REQ), // 0x0037
qmi_name_item(QMIWDS_GET_DATA_BEARER_RESP), // 0x0037
qmi_name_item(QMIWDS_DUN_CALL_INFO_REQ), // 0x0038
qmi_name_item(QMIWDS_DUN_CALL_INFO_RESP), // 0x0038
qmi_name_item(QMIWDS_DUN_CALL_INFO_IND), // 0x0038
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ), // 0x004D
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_RESP), // 0x004D
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_REQ), // 0x0051
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_RESP), // 0x0051
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_REQ), // 0x00A2
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_RESP), // 0x00A2
};
static const QMI_NAME_T qmux_dms_Type[] = {
// ======================= DMS ==============================
qmi_name_item(QMIDMS_SET_EVENT_REPORT_REQ), // 0x0001
qmi_name_item(QMIDMS_SET_EVENT_REPORT_RESP), // 0x0001
qmi_name_item(QMIDMS_EVENT_REPORT_IND), // 0x0001
qmi_name_item(QMIDMS_GET_DEVICE_CAP_REQ), // 0x0020
qmi_name_item(QMIDMS_GET_DEVICE_CAP_RESP), // 0x0020
qmi_name_item(QMIDMS_GET_DEVICE_MFR_REQ), // 0x0021
qmi_name_item(QMIDMS_GET_DEVICE_MFR_RESP), // 0x0021
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_REQ), // 0x0022
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_RESP), // 0x0022
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_REQ), // 0x0023
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_RESP), // 0x0023
qmi_name_item(QMIDMS_GET_MSISDN_REQ), // 0x0024
qmi_name_item(QMIDMS_GET_MSISDN_RESP), // 0x0024
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_REQ), // 0x0025
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_RESP), // 0x0025
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_REQ), // 0x0027
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_RESP), // 0x0027
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_REQ), // 0x0028
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_RESP), // 0x0028
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_REQ), // 0x0029
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_RESP), // 0x0029
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_REQ), // 0x002A
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_RESP), // 0x002A
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_REQ), // 0x002B
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_RESP), // 0x002B
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_REQ), // 0x002C
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_RESP), // 0x002C
qmi_name_item(QMIDMS_GET_OPERATING_MODE_REQ), // 0x002D
qmi_name_item(QMIDMS_GET_OPERATING_MODE_RESP), // 0x002D
qmi_name_item(QMIDMS_SET_OPERATING_MODE_REQ), // 0x002E
qmi_name_item(QMIDMS_SET_OPERATING_MODE_RESP), // 0x002E
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_REQ), // 0x0031
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_RESP), // 0x0031
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_REQ), // 0x0032
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_RESP), // 0x0032
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_REQ), // 0x0033
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_RESP), // 0x0033
qmi_name_item(QMIDMS_UIM_GET_ICCID_REQ), // 0x003C
qmi_name_item(QMIDMS_UIM_GET_ICCID_RESP), // 0x003C
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_REQ), // 0x0040
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_RESP), // 0x0040
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_REQ), // 0x0041
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_RESP), // 0x0041
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_REQ), // 0x0042
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_RESP), // 0x0042
qmi_name_item(QMIDMS_UIM_GET_IMSI_REQ), // 0x0043
qmi_name_item(QMIDMS_UIM_GET_IMSI_RESP), // 0x0043
qmi_name_item(QMIDMS_UIM_GET_STATE_REQ), // 0x0044
qmi_name_item(QMIDMS_UIM_GET_STATE_RESP), // 0x0044
qmi_name_item(QMIDMS_GET_BAND_CAP_REQ), // 0x0045
qmi_name_item(QMIDMS_GET_BAND_CAP_RESP), // 0x0045
};
static const QMI_NAME_T qmux_nas_Type[] = {
// ======================= NAS ==============================
qmi_name_item(QMINAS_SET_EVENT_REPORT_REQ), // 0x0002
qmi_name_item(QMINAS_SET_EVENT_REPORT_RESP), // 0x0002
qmi_name_item(QMINAS_EVENT_REPORT_IND), // 0x0002
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_REQ), // 0x0020
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_RESP), // 0x0020
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_REQ), // 0x0021
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_RESP), // 0x0021
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_REQ), // 0x0022
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_RESP), // 0x0022
qmi_name_item(QMINAS_INITIATE_ATTACH_REQ), // 0x0023
qmi_name_item(QMINAS_INITIATE_ATTACH_RESP), // 0x0023
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_REQ), // 0x0024
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_RESP), // 0x0024
qmi_name_item(QMINAS_SERVING_SYSTEM_IND), // 0x0024
qmi_name_item(QMINAS_GET_HOME_NETWORK_REQ), // 0x0025
qmi_name_item(QMINAS_GET_HOME_NETWORK_RESP), // 0x0025
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_REQ), // 0x0026
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_RESP), // 0x0026
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_REQ), // 0x0027
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_RESP), // 0x0027
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_REQ), // 0x0028
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_RESP), // 0x0028
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_REQ), // 0x0029
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_RESP), // 0x0029
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_REQ), // 0x002A
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_RESP), // 0x002A
qmi_name_item(QMINAS_GET_RF_BAND_INFO_REQ), // 0x0031
qmi_name_item(QMINAS_GET_RF_BAND_INFO_RESP), // 0x0031
qmi_name_item(QMINAS_GET_PLMN_NAME_REQ), // 0x0044
qmi_name_item(QMINAS_GET_PLMN_NAME_RESP), // 0x0044
qmi_name_item(FIBO_PACKET_TRANSFER_START_IND), // 0X100
qmi_name_item(FIBO_PACKET_TRANSFER_END_IND), // 0X101
qmi_name_item(QMINAS_GET_SYS_INFO_REQ), // 0x004D
qmi_name_item(QMINAS_GET_SYS_INFO_RESP), // 0x004D
qmi_name_item(QMINAS_SYS_INFO_IND), // 0x004D
};
static const QMI_NAME_T qmux_wms_Type[] = {
// ======================= WMS ==============================
qmi_name_item(QMIWMS_SET_EVENT_REPORT_REQ), // 0x0001
qmi_name_item(QMIWMS_SET_EVENT_REPORT_RESP), // 0x0001
qmi_name_item(QMIWMS_EVENT_REPORT_IND), // 0x0001
qmi_name_item(QMIWMS_RAW_SEND_REQ), // 0x0020
qmi_name_item(QMIWMS_RAW_SEND_RESP), // 0x0020
qmi_name_item(QMIWMS_RAW_WRITE_REQ), // 0x0021
qmi_name_item(QMIWMS_RAW_WRITE_RESP), // 0x0021
qmi_name_item(QMIWMS_RAW_READ_REQ), // 0x0022
qmi_name_item(QMIWMS_RAW_READ_RESP), // 0x0022
qmi_name_item(QMIWMS_MODIFY_TAG_REQ), // 0x0023
qmi_name_item(QMIWMS_MODIFY_TAG_RESP), // 0x0023
qmi_name_item(QMIWMS_DELETE_REQ), // 0x0024
qmi_name_item(QMIWMS_DELETE_RESP), // 0x0024
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_REQ), // 0x0030
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_RESP), // 0x0030
qmi_name_item(QMIWMS_LIST_MESSAGES_REQ), // 0x0031
qmi_name_item(QMIWMS_LIST_MESSAGES_RESP), // 0x0031
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_REQ), // 0x0034
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_RESP), // 0x0034
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_REQ), // 0x0035
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_RESP), // 0x0035
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_REQ), // 0x0036
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_RESP), // 0x0036
};
static const QMI_NAME_T qmux_wds_admin_Type[] = {
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_REQ), // 0x0020
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_RESP), // 0x0020
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_REQ), // 0x0021
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_RESP), // 0x0021
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_REQ), // 0x002B
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_RESP), // 0x002B
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_REQ), // 0x002C
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_RESP), // 0x002C
};
static const QMI_NAME_T qmux_uim_Type[] = {
qmi_name_item(QMIUIM_READ_TRANSPARENT_REQ), // 0x0020
qmi_name_item(QMIUIM_READ_TRANSPARENT_RESP), // 0x0020
qmi_name_item(QMIUIM_READ_TRANSPARENT_IND), // 0x0020
qmi_name_item(QMIUIM_READ_RECORD_REQ), // 0x0021
qmi_name_item(QMIUIM_READ_RECORD_RESP), // 0x0021
qmi_name_item(QMIUIM_READ_RECORD_IND), // 0x0021
qmi_name_item(QMIUIM_WRITE_TRANSPARENT_REQ), // 0x0022
qmi_name_item(QMIUIM_WRITE_TRANSPARENT_RESP), // 0x0022
qmi_name_item(QMIUIM_WRITE_TRANSPARENT_IND), // 0x0022
qmi_name_item(QMIUIM_WRITE_RECORD_REQ), // 0x0023
qmi_name_item(QMIUIM_WRITE_RECORD_RESP), // 0x0023
qmi_name_item(QMIUIM_WRITE_RECORD_IND), // 0x0023
qmi_name_item(QMIUIM_SET_PIN_PROTECTION_REQ), // 0x0025
qmi_name_item(QMIUIM_SET_PIN_PROTECTION_RESP), // 0x0025
qmi_name_item(QMIUIM_SET_PIN_PROTECTION_IND), // 0x0025
qmi_name_item(QMIUIM_VERIFY_PIN_REQ), // 0x0026
qmi_name_item(QMIUIM_VERIFY_PIN_RESP), // 0x0026
qmi_name_item(QMIUIM_VERIFY_PIN_IND), // 0x0026
qmi_name_item(QMIUIM_UNBLOCK_PIN_REQ), // 0x0027
qmi_name_item(QMIUIM_UNBLOCK_PIN_RESP), // 0x0027
qmi_name_item(QMIUIM_UNBLOCK_PIN_IND), // 0x0027
qmi_name_item(QMIUIM_CHANGE_PIN_REQ), // 0x0028
qmi_name_item(QMIUIM_CHANGE_PIN_RESP), // 0x0028
qmi_name_item(QMIUIM_CHANGE_PIN_IND), // 0x0028
qmi_name_item(QMIUIM_DEPERSONALIZATION_REQ), // 0x0029
qmi_name_item(QMIUIM_DEPERSONALIZATION_RESP), // 0x0029
qmi_name_item(QMIUIM_EVENT_REG_REQ), // 0x002E
qmi_name_item(QMIUIM_EVENT_REG_RESP), // 0x002E
qmi_name_item(QMIUIM_GET_CARD_STATUS_REQ), // 0x002F
qmi_name_item(QMIUIM_GET_CARD_STATUS_RESP), // 0x002F
qmi_name_item(QMIUIM_STATUS_CHANGE_IND), // 0x0032
};
static const char *qmi_name_get(const QMI_NAME_T *table, size_t size, int type,
const char *tag)
{
static char unknow[40];
size_t i;
if (qmux_CtlFlags == table) {
if (!strcmp(tag, "_REQ"))
tag = "_CMD";
else if (!strcmp(tag, "_RESP"))
tag = "_RSP";
}
for (i = 0; i < size; i++) {
if (table[i].type == (UINT)type) {
if (!tag || (strstr(table[i].name, tag)))
return table[i].name;
}
}
sprintf(unknow, "unknow_%x", type);
return unknow;
}
#define QMI_NAME(table, type) \
qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, 0)
#define QMUX_NAME(table, type, tag) \
qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, tag)
void dump_tlv(PQCQMUX_MSG_HDR pQMUXMsgHdr)
{
int TLVFind = 0;
int i;
// dbg("QCQMUX_TLV-----------------------------------\n");
// dbg("{Type,\tLength,\tValue}\n");
while (1) {
PQMI_TLV_HDR TLVHdr = GetTLV(pQMUXMsgHdr, 0x1000 + (++TLVFind));
if (TLVHdr == NULL)
break;
// if ((TLVHdr->TLVType == 0x02) && ((USHORT *)(TLVHdr+1))[0])
{
dbg("{%02x,\t%04x,\t", TLVHdr->TLVType,
le16_to_cpu(TLVHdr->TLVLength));
for (i = 0; i < le16_to_cpu(TLVHdr->TLVLength); i++) {
dbg("%02x ", ((UCHAR *)(TLVHdr + 1))[i]);
}
dbg("}\n");
}
} // while
}
void dump_ctl(PQCQMICTL_MSG_HDR CTLHdr)
{
const char *tag;
// dbg("QCQMICTL_MSG--------------------------------------------\n");
// dbg("CtlFlags: %02x\t\t%s\n", CTLHdr->CtlFlags,
// QMI_NAME(qmi_ctl_CtlFlags, CTLHdr->CtlFlags));
dbg("TransactionId: %02x\n", CTLHdr->TransactionId);
switch (CTLHdr->CtlFlags) {
case QMICTL_FLAG_REQUEST:
tag = "_REQ";
break;
case QMICTL_FLAG_RESPONSE:
tag = "_RESP";
break;
case QMICTL_FLAG_INDICATION:
tag = "_IND";
break;
default:
tag = 0;
break;
}
dbg("QMICTLType: %04x\t%s\n", le16_to_cpu(CTLHdr->QMICTLType),
QMUX_NAME(qmux_ctl_QMICTLType, le16_to_cpu(CTLHdr->QMICTLType), tag));
dbg("Length: %04x\n", le16_to_cpu(CTLHdr->Length));
dump_tlv((PQCQMUX_MSG_HDR)(&CTLHdr->QMICTLType));
}
int dump_qmux(QMI_SERVICE_TYPE serviceType, PQCQMUX_HDR QMUXHdr)
{
PQCQMUX_MSG_HDR QMUXMsgHdr = (PQCQMUX_MSG_HDR)(QMUXHdr + 1);
CHAR *tag;
// dbg("QCQMUX--------------------------------------------\n");
switch (QMUXHdr->CtlFlags & QMUX_CTL_FLAG_MASK_TYPE) {
case QMUX_CTL_FLAG_TYPE_CMD:
tag = "_REQ";
break;
case QMUX_CTL_FLAG_TYPE_RSP:
tag = "_RESP";
break;
case QMUX_CTL_FLAG_TYPE_IND:
tag = "_IND";
break;
default:
tag = 0;
break;
}
// dbg("CtlFlags: %02x\t\t%s\n", QMUXHdr->CtlFlags,
// QMUX_NAME(qmux_CtlFlags, QMUXHdr->CtlFlags, tag));
dbg("TransactionId: %04x\n", le16_to_cpu(QMUXHdr->TransactionId));
// dbg("QCQMUX_MSG_HDR-----------------------------------\n");
switch (serviceType) {
case QMUX_TYPE_DMS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_dms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_NAS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_nas_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_WDS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_wds_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_WMS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_wms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_WDS_ADMIN:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_wds_admin_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_UIM:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_uim_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_PDS:
case QMUX_TYPE_QOS:
case QMUX_TYPE_CTL:
default:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
"PDS/QOS/CTL/unknown!");
break;
}
dbg("Length: %04x\n", le16_to_cpu(QMUXMsgHdr->Length));
dump_tlv(QMUXMsgHdr);
return 0;
}
void dump_qmi(void *dataBuffer, int dataLen)
{
PQCQMI_HDR QMIHdr = (PQCQMI_HDR)dataBuffer;
PQCQMUX_HDR QMUXHdr = (PQCQMUX_HDR)(QMIHdr + 1);
PQCQMICTL_MSG_HDR CTLHdr = (PQCQMICTL_MSG_HDR)(QMIHdr + 1);
int i;
if (!debug_qmi)
return;
pthread_mutex_lock(&dumpQMIMutex);
line[0] = 0;
for (i = 0; i < dataLen; i++) {
dbg("%02x ", ((unsigned char *)dataBuffer)[i]);
}
dbg_time("%s", line);
line[0] = 0;
// dbg("QCQMI_HDR-----------------------------------------");
// dbg("IFType: %02x\t\t%s", QMIHdr->IFType,
// QMI_NAME(qmi_IFType, QMIHdr->IFType)); dbg("Length: %04x",
// le16_to_cpu(QMIHdr->Length)); dbg("CtlFlags: %02x\t\t%s",
// QMIHdr->CtlFlags, QMI_NAME(qmi_CtlFlags, QMIHdr->CtlFlags));
// dbg("QMIType: %02x\t\t%s", QMIHdr->QMIType, QMI_NAME(qmi_QMIType,
// QMIHdr->QMIType)); dbg("ClientId: %02x", QMIHdr->ClientId);
if (QMIHdr->QMIType == QMUX_TYPE_CTL) {
dump_ctl(CTLHdr);
} else {
dump_qmux(QMIHdr->QMIType, QMUXHdr);
}
dbg_time("%s", line);
pthread_mutex_unlock(&dumpQMIMutex);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +0,0 @@
ifneq ($(CROSS_COMPILE),)
CROSS-COMPILE:=$(CROSS_COMPILE)
endif
CFLAGS += -DGHT_FEATURE_PCIE_AUTO
ifeq ($(CC),cc)
CC:=$(CROSS-COMPILE)gcc
endif
LD:=$(CROSS-COMPILE)ld
SRC=QmiWwanCM.c GobiNetCM.c main.c MPQMUX.c QMIThread.c util.c qmap_bridge_mode.c query_pcie_mode.c
FB_DHCP=udhcpc.c
FIBO_PROXY_SRC=fibo_qmimsg_server.c
LIBMNL=libmnl/ifutils.c libmnl/attr.c libmnl/callback.c libmnl/nlmsg.c libmnl/socket.c
FB_NDHCP=udhcpc_netlink.c
FB_NDHCP+=${LIBMNL}
release: clean
$(CC) $(CFLAGS) -Wall -s ${SRC} ${FB_NDHCP} -o fibocom-dial -lpthread -ldl
$(CC) -Wall -s multi-pdn-manager.c query_pcie_mode.c util.c -o multi-pdn-manager -lpthread -ldl
$(CC) -Wall -s ${FIBO_PROXY_SRC} -o fibo_qmimsg_server -lpthread -ldl
dhcp: clean
$(CC) $(CFLAGS) -Wall -s ${SRC} ${FB_DHCP} -o fibocom-dial -lpthread -ldl
$(CC) -Wall -s multi-pdn-manager.c query_pcie_mode.c util.c -o multi-pdn-manager -lpthread -ldl
$(CC) -Wall -s ${FIBO_PROXY_SRC} -o fibo_qmimsg_server -lpthread -ldl
ndhcp: clean
$(CC) $(CFLAGS) -Wall -s ${SRC} ${FB_NDHCP} -o fibocom-dial -lpthread -ldl
$(CC) -Wall -s multi-pdn-manager.c query_pcie_mode.cutil.c -o multi-pdn-manager -lpthread -ldl
$(CC) -Wall -s ${FIBO_PROXY_SRC} -o fibo_qmimsg_server -lpthread -ldl
qmi-proxy:
$(CC) -Wall -s fibo-qmi-proxy.c -o fibo-qmi-proxy -lpthread -ldl
clean:
rm -rf fibocom-dial *~ multi-pdn-manager fibo_qmimsg_server

File diff suppressed because it is too large Load Diff

View File

@ -1,260 +0,0 @@
#ifndef __QMI_THREAD_H__
#define __QMI_THREAD_H__
#define CONFIG_GOBINET
#define CONFIG_QMIWWAN
#define CONFIG_SIM
#define CONFIG_APN
#define CONFIG_VERSION
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
#define CONFIG_IMSI_ICCID
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
#define CONFIG_DEFAULT_PDP 1
#define CONFIG_DEFAULT_PDPINDEX 1
//#define CONFIG_IMSI_ICCID
#define CONFIG_RESET_RADIO \
(45) // Reset Radiao(AT+CFUN=4,AT+CFUN=1) when cann not register network or
// setup data call in 45 seconds
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include "MPQCTL.h"
#include "MPQMI.h"
#include "MPQMUX.h"
#define DEVICE_CLASS_UNKNOWN 0
#define DEVICE_CLASS_CDMA 1
#define DEVICE_CLASS_GSM 2
#define WWAN_DATA_CLASS_NONE 0x00000000
#define WWAN_DATA_CLASS_GPRS 0x00000001
#define WWAN_DATA_CLASS_EDGE 0x00000002 /* EGPRS */
#define WWAN_DATA_CLASS_UMTS 0x00000004
#define WWAN_DATA_CLASS_HSDPA 0x00000008
#define WWAN_DATA_CLASS_HSUPA 0x00000010
#define WWAN_DATA_CLASS_LTE 0x00000020
//begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605
#define WWAN_DATA_CLASS_5G 0x00000040
//end modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605
#define WWAN_DATA_CLASS_1XRTT 0x00010000
#define WWAN_DATA_CLASS_1XEVDO 0x00020000
#define WWAN_DATA_CLASS_1XEVDO_REVA 0x00040000
#define WWAN_DATA_CLASS_1XEVDV 0x00080000
#define WWAN_DATA_CLASS_3XRTT 0x00100000
#define WWAN_DATA_CLASS_1XEVDO_REVB 0x00200000 /* for future use */
#define WWAN_DATA_CLASS_UMB 0x00400000
#define WWAN_DATA_CLASS_CUSTOM 0x80000000
struct wwan_data_class_str {
ULONG class;
CHAR *str;
};
#pragma pack(push, 1)
typedef struct _QCQMIMSG {
QCQMI_HDR QMIHdr;
union {
QMICTL_MSG CTLMsg;
QMUX_MSG MUXMsg;
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
QMUX_MSG QMUXMsgHdrResp;
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
};
} __attribute__((packed)) QCQMIMSG, *PQCQMIMSG;
#pragma pack(pop)
typedef struct __IPV4 {
uint32_t Address;
uint32_t Gateway;
uint32_t SubnetMask;
uint32_t DnsPrimary;
uint32_t DnsSecondary;
uint32_t Mtu;
} IPV4_T;
typedef struct __IPV6 {
UCHAR Address[16];
UCHAR Gateway[16];
UCHAR SubnetMask[16];
UCHAR DnsPrimary[16];
UCHAR DnsSecondary[16];
UCHAR PrefixLengthIPAddr;
UCHAR PrefixLengthGateway;
ULONG Mtu;
} IPV6_T;
#define IpFamilyV4 (0x04)
#define IpFamilyV6 (0x06)
struct __PROFILE;
struct qmi_device_ops {
int (*init)(struct __PROFILE *profile);
int (*deinit)(void);
int (*send)(PQCQMIMSG pRequest);
void *(*read)(void *pData);
};
extern int (*qmidev_send)(PQCQMIMSG pRequest);
#ifndef bool
#define bool uint8_t
#endif
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
typedef struct {
unsigned int size;
unsigned int rx_urb_size;
unsigned int ep_type;
unsigned int iface_id;
unsigned int qmap_mode;
unsigned int qmap_version;
unsigned int dl_minimum_padding;
char ifname[8][16];
unsigned char mux_id[8];
} RMNET_INFO;
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
typedef struct __PROFILE {
char *qmichannel;
char *usbnet_adapter;
char *qmapnet_adapter;
const char *driver_name;
int qmap_mode;
int qmap_size;
int qmap_version;
const char *apn;
const char *user;
const char *password;
const char *pincode;
int auth;
int pdp;
int pdpindex;
int pdpnum;
int curIpFamily;
int rawIP;
int muxid;
IPV4_T ipv4;
IPV6_T ipv6;
int ipv4_flag;
int ipv6_flag;
//2021-02-25 willa.liu@fibocom.com changed begin for support eipd SN-20210129001
int ipv6_prigateway_flag;
//2021-02-25 willa.liu@fibocom.com changed begin for support eipd SN-20210129001
int dual_flag;
int apntype;
const struct qmi_device_ops *qmi_ops;
bool loopback_state;
int replication_factor;
//2021-02-08 zhangkaibo@fibocom.com changed begin for mantis 0070613
int interfacenum;
//2021-02-08 zhangkaibo@fibocom.com changed end for mantis 0070613
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
RMNET_INFO rmnet_info;
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
} PROFILE_T;
typedef enum {
SIM_ABSENT = 0,
SIM_NOT_READY = 1,
SIM_READY =
2, /* SIM_READY means the radio state is RADIO_STATE_SIM_READY */
SIM_PIN = 3,
SIM_PUK = 4,
SIM_NETWORK_PERSONALIZATION = 5,
SIM_BAD = 6,
} SIM_Status;
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
typedef enum {
SIM_Card0 = 0,
SIM_Card1 = 1
} SIM_Select;
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
#define WDM_DEFAULT_BUFSIZE 256
#define RIL_REQUEST_QUIT 0x1000
#define RIL_INDICATE_DEVICE_CONNECTED 0x1002
#define RIL_INDICATE_DEVICE_DISCONNECTED 0x1003
#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 0x1004
#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 0x1005
extern int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t *mutex,
unsigned msecs);
extern int QmiThreadSendQMI(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse);
extern int QmiThreadSendQMITimeout(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse,
unsigned msecs);
extern void QmiThreadRecvQMI(PQCQMIMSG pResponse);
extern int fibo_raw_ip_mode_check(const char *ifname);
extern void udhcpc_start(PROFILE_T *profile);
extern void udhcpc_stop(PROFILE_T *profile);
extern void udhcpc_start_pcie(PROFILE_T *profile);
extern void udhcpc_stop_pcie(PROFILE_T *profile);
extern void dump_qmi(void *dataBuffer, int dataLen);
extern void qmidevice_send_event_to_main(int triger_event);
extern int requestSetEthMode(PROFILE_T *profile);
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
//extern int requestGetSIMStatus(SIM_Status *pSIMStatus);
extern int requestGetSIMStatus(SIM_Status *pSIMStatus , const int sim_select);
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
extern int requestEnterSimPin(const CHAR *pPinCode);
extern int requestGetICCID(void);
extern int requestGetIMSI(void);
extern int requestRegistrationState(UCHAR *pPSAttachedState);
extern int requestQueryDataCall(UCHAR *pConnectionStatus, int curIpFamily);
extern int requestSetupDataCall(PROFILE_T *profile, int curIpFamily);
extern int requestDeactivateDefaultPDP(PROFILE_T *profile, int curIpFamily);
extern int requestSetProfile(PROFILE_T *profile);
extern int requestGetProfile(PROFILE_T *profile);
extern int requestBaseBandVersion(const char **pp_reversion);
extern int requestGetIPAddress(PROFILE_T *profile, int curIpFamily);
extern int requestSetOperatingMode(UCHAR OperatingMode);
int requestRegistrationState2(UCHAR *pPSAttachedState);
extern int fibo_qmap_mode_set(PROFILE_T *profile);
extern int fibo_bridge_mode_detect(PROFILE_T *profile);
extern int fibo_qmap_mode_detect(PROFILE_T *profile);
extern const struct qmi_device_ops qmiwwan_qmidev_ops;
#define qmidev_is_gobinet(_qmichannel) \
(strncmp(_qmichannel, "/dev/qcqmi", strlen("/dev/qcqmi")) == 0)
#define qmidev_is_qmiwwan(_qmichannel) \
(strncmp(_qmichannel, "/dev/cdc-wdm", strlen("/dev/cdc-wdm")) == 0)
#define qmidev_is_pciemhi(_qmichannel) \
(strncmp(_qmichannel, "/dev/mhi_", strlen("/dev/mhi_")) == 0)
#define driver_is_qmi(_drv_name) \
(strncasecmp(_drv_name, "qmi_wwan", strlen("qmi_wwan")) == 0)
#define driver_is_mbim(_drv_name) \
(strncasecmp(_drv_name, "cdc_mbim", strlen("cdc_mbim")) == 0)
extern FILE *logfilefp;
extern int debug_qmi;
extern USHORT g_MobileCountryCode;
extern USHORT g_MobileNetworkCode;
extern int qmidevice_control_fd[2];
extern int qmiclientId[QMUX_TYPE_WDS_ADMIN + 1];
extern void dbg_time(const char *fmt, ...);
extern USHORT le16_to_cpu(USHORT v16);
extern UINT le32_to_cpu(UINT v32);
extern USHORT cpu_to_le16(USHORT v16);
extern UINT cpu_to_le32(UINT v32);
#endif

View File

@ -1,426 +0,0 @@
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
typedef unsigned short sa_family_t;
#include <linux/un.h>
#include "QMIThread.h"
#ifdef CONFIG_QMIWWAN
#define FIBO_QMI_PROXY "fibo_qmimsg_server"
static int cdc_wdm_fd = -1;
static UCHAR GetQCTLTransactionId(void)
{
static int TransactionId = 0;
if (++TransactionId > 0xFF)
TransactionId = 1;
return TransactionId;
}
typedef USHORT (*CUSTOMQCTL)(PQMICTL_MSG pCTLMsg, void *arg);
static PQCQMIMSG ComposeQCTLMsg(USHORT QMICTLType,
CUSTOMQCTL customQctlMsgFunction, void *arg)
{
UCHAR QMIBuf[WDM_DEFAULT_BUFSIZE];
PQCQMIMSG pRequest = (PQCQMIMSG)QMIBuf;
int Length;
pRequest->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
pRequest->QMIHdr.CtlFlags = 0x00;
pRequest->QMIHdr.QMIType = QMUX_TYPE_CTL;
pRequest->QMIHdr.ClientId = 0x00;
pRequest->CTLMsg.QMICTLMsgHdr.CtlFlags = QMICTL_FLAG_REQUEST;
pRequest->CTLMsg.QMICTLMsgHdr.TransactionId = GetQCTLTransactionId();
pRequest->CTLMsg.QMICTLMsgHdr.QMICTLType = cpu_to_le16(QMICTLType);
if (customQctlMsgFunction)
pRequest->CTLMsg.QMICTLMsgHdr.Length =
cpu_to_le16(customQctlMsgFunction(&pRequest->CTLMsg, arg) -
sizeof(QCQMICTL_MSG_HDR));
else
pRequest->CTLMsg.QMICTLMsgHdr.Length = cpu_to_le16(0x0000);
pRequest->QMIHdr.Length =
cpu_to_le16(le16_to_cpu(pRequest->CTLMsg.QMICTLMsgHdr.Length) +
sizeof(QCQMICTL_MSG_HDR) + sizeof(QCQMI_HDR) - 1);
Length = le16_to_cpu(pRequest->QMIHdr.Length) + 1;
pRequest = (PQCQMIMSG)malloc(Length);
if (pRequest == NULL) {
dbg_time("%s fail to malloc", __func__);
} else {
memcpy(pRequest, QMIBuf, Length);
}
return pRequest;
}
static USHORT CtlGetVersionReq(PQMICTL_MSG QCTLMsg, void *arg)
{
QCTLMsg->GetVersionReq.TLVType = QCTLV_TYPE_REQUIRED_PARAMETER;
QCTLMsg->GetVersionReq.TLVLength = cpu_to_le16(0x0001);
QCTLMsg->GetVersionReq.QMUXTypes = QMUX_TYPE_ALL;
return sizeof(QMICTL_GET_VERSION_REQ_MSG);
}
static USHORT CtlGetClientIdReq(PQMICTL_MSG QCTLMsg, void *arg)
{
QCTLMsg->GetClientIdReq.TLVType = QCTLV_TYPE_REQUIRED_PARAMETER;
QCTLMsg->GetClientIdReq.TLVLength = cpu_to_le16(0x0001);
QCTLMsg->GetClientIdReq.QMIType = ((UCHAR *)arg)[0];
return sizeof(QMICTL_GET_CLIENT_ID_REQ_MSG);
}
static USHORT CtlReleaseClientIdReq(PQMICTL_MSG QCTLMsg, void *arg)
{
QCTLMsg->ReleaseClientIdReq.TLVType = QCTLV_TYPE_REQUIRED_PARAMETER;
QCTLMsg->ReleaseClientIdReq.TLVLength = cpu_to_le16(0x0002);
QCTLMsg->ReleaseClientIdReq.QMIType = ((UCHAR *)arg)[0];
QCTLMsg->ReleaseClientIdReq.ClientId = ((UCHAR *)arg)[1];
return sizeof(QMICTL_RELEASE_CLIENT_ID_REQ_MSG);
}
static int QmiWwanSendQMI(PQCQMIMSG pRequest)
{
struct pollfd pollfds[] = {{cdc_wdm_fd, POLLOUT, 0}};
int ret;
if (cdc_wdm_fd == -1) {
dbg_time("%s cdc_wdm_fd = -1", __func__);
return -ENODEV;
}
if (pRequest->QMIHdr.QMIType == QMUX_TYPE_WDS_IPV6)
pRequest->QMIHdr.QMIType = QMUX_TYPE_WDS;
do {
ret = poll(pollfds, sizeof(pollfds) / sizeof(pollfds[0]), 5000);
} while ((ret < 0) && (errno == EINTR));
if (pollfds[0].revents & POLLOUT) {
ssize_t nwrites = le16_to_cpu(pRequest->QMIHdr.Length) + 1;
ret = write(cdc_wdm_fd, pRequest, nwrites);
if (ret == nwrites) {
ret = 0;
} else {
dbg_time("%s write=%d, errno: %d (%s)", __func__, ret, errno,
strerror(errno));
}
} else {
dbg_time("%s poll=%d, revents = 0x%x, errno: %d (%s)", __func__, ret,
pollfds[0].revents, errno, strerror(errno));
}
return ret;
}
static int QmiWwanGetClientID(UCHAR QMIType)
{
PQCQMIMSG pResponse;
QmiThreadSendQMI(
ComposeQCTLMsg(QMICTL_GET_CLIENT_ID_REQ, CtlGetClientIdReq, &QMIType),
&pResponse);
if (pResponse) {
USHORT QMUXResult = cpu_to_le16(pResponse->CTLMsg.QMICTLMsgHdrRsp
.QMUXResult); // QMI_RESULT_SUCCESS
USHORT QMUXError = cpu_to_le16(pResponse->CTLMsg.QMICTLMsgHdrRsp
.QMUXError); // QMI_ERR_INVALID_ARG
// UCHAR QMIType = pResponse->CTLMsg.GetClientIdRsp.QMIType;
UCHAR ClientId = pResponse->CTLMsg.GetClientIdRsp.ClientId;
dbg_time("%s: QMIType = %d clientid %d", __func__, QMIType, ClientId);
if (!QMUXResult && !QMUXError &&
(QMIType == pResponse->CTLMsg.GetClientIdRsp.QMIType)) {
switch (QMIType) {
case QMUX_TYPE_WDS:
dbg_time("Get clientWDS = %d", ClientId);
break;
case QMUX_TYPE_DMS:
dbg_time("Get clientDMS = %d", ClientId);
break;
case QMUX_TYPE_NAS:
dbg_time("Get clientNAS = %d", ClientId);
break;
case QMUX_TYPE_QOS:
dbg_time("Get clientQOS = %d", ClientId);
break;
case QMUX_TYPE_WMS:
dbg_time("Get clientWMS = %d", ClientId);
break;
case QMUX_TYPE_PDS:
dbg_time("Get clientPDS = %d", ClientId);
break;
case QMUX_TYPE_UIM:
dbg_time("Get clientUIM = %d", ClientId);
break;
case QMUX_TYPE_WDS_ADMIN:
dbg_time("Get clientWDA = %d", ClientId);
break;
default:
break;
}
return ClientId;
}
}
return 0;
}
static int QmiWwanReleaseClientID(QMI_SERVICE_TYPE QMIType, UCHAR ClientId)
{
UCHAR argv[] = {QMIType, ClientId};
QmiThreadSendQMI(ComposeQCTLMsg(QMICTL_RELEASE_CLIENT_ID_REQ,
CtlReleaseClientIdReq, argv),
NULL);
return 0;
}
static int QmiWwanInit(PROFILE_T *profile)
{
unsigned i;
int ret;
PQCQMIMSG pResponse;
if (profile->qmap_mode == 0 || profile->qmap_mode == 1) {
for (i = 0; i < 10; i++) {
ret = QmiThreadSendQMITimeout(
ComposeQCTLMsg(QMICTL_SYNC_REQ, NULL, NULL), NULL, 1 * 1000);
if (!ret)
break;
sleep(1);
}
if (ret)
return ret;
}
QmiThreadSendQMI(
ComposeQCTLMsg(QMICTL_GET_VERSION_REQ, CtlGetVersionReq, NULL),
&pResponse);
if (profile->qmap_mode) {
if (pResponse) {
if (pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXResult == 0 &&
pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXError == 0) {
uint8_t NumElements = 0;
for (NumElements = 0;
NumElements < pResponse->CTLMsg.GetVersionRsp.NumElements;
NumElements++) {
if (pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements]
.QMUXType == QMUX_TYPE_WDS_ADMIN)
profile->qmap_version = (pResponse->CTLMsg.GetVersionRsp
.TypeVersion[NumElements]
.MinorVersion > 16);
}
}
}
}
if (pResponse)
free(pResponse);
if (profile->ipv4_flag)
qmiclientId[QMUX_TYPE_WDS] = QmiWwanGetClientID(QMUX_TYPE_WDS);
if (profile->ipv6_flag)
qmiclientId[QMUX_TYPE_WDS_IPV6] = QmiWwanGetClientID(QMUX_TYPE_WDS);
qmiclientId[QMUX_TYPE_DMS] = QmiWwanGetClientID(QMUX_TYPE_DMS);
qmiclientId[QMUX_TYPE_NAS] = QmiWwanGetClientID(QMUX_TYPE_NAS);
qmiclientId[QMUX_TYPE_UIM] = QmiWwanGetClientID(QMUX_TYPE_UIM);
if (profile->qmap_mode == 0 || profile->qmap_mode == 1)
qmiclientId[QMUX_TYPE_WDS_ADMIN] =
QmiWwanGetClientID(QMUX_TYPE_WDS_ADMIN);
return 0;
}
static int QmiWwanDeInit(void)
{
unsigned int i;
for (i = 0; i < sizeof(qmiclientId) / sizeof(qmiclientId[0]); i++) {
if (qmiclientId[i] != 0) {
QmiWwanReleaseClientID(i, qmiclientId[i]);
qmiclientId[i] = 0;
}
}
return 0;
}
static int qmi_proxy_open(const char *name)
{
int sockfd = -1;
int reuse_addr = 1;
struct sockaddr_un sockaddr;
socklen_t alen;
/*Create server socket*/
(sockfd = socket(AF_LOCAL, SOCK_STREAM, 0));
if (sockfd < 0)
return sockfd;
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sun_family = AF_LOCAL;
sockaddr.sun_path[0] = 0;
memcpy(sockaddr.sun_path + 1, name, strlen(name));
alen = strlen(name) + offsetof(struct sockaddr_un, sun_path) + 1;
if (connect(sockfd, (struct sockaddr *)&sockaddr, alen) < 0) {
close(sockfd);
dbg_time("%s connect %s errno: %d (%s)\n", __func__, name, errno,
strerror(errno));
return -1;
}
(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,
sizeof(reuse_addr)));
dbg_time("connect to %s sockfd = %d\n", name, sockfd);
return sockfd;
}
static ssize_t qmi_proxy_read(int fd, void *buf, size_t size)
{
ssize_t nreads;
PQCQMI_HDR pHdr = (PQCQMI_HDR)buf;
nreads = read(fd, pHdr, sizeof(QCQMI_HDR));
if (nreads == sizeof(QCQMI_HDR)) {
nreads += read(fd, pHdr + 1,
le16_to_cpu(pHdr->Length) + 1 - sizeof(QCQMI_HDR));
}
return nreads;
}
static void *QmiWwanThread(void *pData)
{
PROFILE_T *profile = (PROFILE_T *)pData;
const char *cdc_wdm = (const char *)profile->qmichannel;
if (profile->qmap_mode == 0 || profile->qmap_mode == 1)
cdc_wdm_fd = open(cdc_wdm, O_RDWR | O_NONBLOCK | O_NOCTTY);
else
cdc_wdm_fd = qmi_proxy_open(FIBO_QMI_PROXY);
if (cdc_wdm_fd == -1) {
dbg_time("%s Failed to open %s, errno: %d (%s)", __func__, cdc_wdm,
errno, strerror(errno));
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
pthread_exit(NULL);
return NULL;
}
fcntl(cdc_wdm_fd, F_SETFL, fcntl(cdc_wdm_fd, F_GETFL) | O_NONBLOCK);
fcntl(cdc_wdm_fd, F_SETFD, FD_CLOEXEC);
dbg_time("cdc_wdm_fd = %d", cdc_wdm_fd);
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_CONNECTED);
while (1) {
struct pollfd pollfds[] = {{qmidevice_control_fd[1], POLLIN, 0},
{cdc_wdm_fd, POLLIN, 0}};
int ne, ret, nevents = sizeof(pollfds) / sizeof(pollfds[0]);
do {
ret = poll(pollfds, nevents, -1);
} while ((ret < 0) && (errno == EINTR));
if (ret <= 0) {
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno,
strerror(errno));
break;
}
for (ne = 0; ne < nevents; ne++) {
int fd = pollfds[ne].fd;
short revents = pollfds[ne].revents;
// dbg_time("{%d, %x, %x}", pollfds[ne].fd, pollfds[ne].events,
// pollfds[ne].revents);
if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
dbg_time("%s poll err/hup/inval", __func__);
dbg_time("poll fd = %d, events = 0x%04x", fd, revents);
if (fd == cdc_wdm_fd) {
} else {
}
if (revents &
(POLLHUP | POLLNVAL)) // EC20 bug, Can get POLLERR
goto __QmiWwanThread_quit;
}
if ((revents & POLLIN) == 0)
continue;
if (fd == qmidevice_control_fd[1]) {
int triger_event;
if (read(fd, &triger_event, sizeof(triger_event)) ==
sizeof(triger_event)) {
// DBG("triger_event = 0x%x", triger_event);
switch (triger_event) {
case RIL_REQUEST_QUIT:
goto __QmiWwanThread_quit;
break;
case SIGTERM:
case SIGHUP:
case SIGINT:
QmiThreadRecvQMI(NULL);
break;
default:
break;
}
}
}
if (fd == cdc_wdm_fd) {
ssize_t nreads;
UCHAR QMIBuf[4096];
PQCQMIMSG pResponse = (PQCQMIMSG)QMIBuf;
if (profile->qmap_mode == 0 || profile->qmap_mode == 1)
nreads = read(fd, QMIBuf, sizeof(QMIBuf));
else
nreads = qmi_proxy_read(fd, QMIBuf, sizeof(QMIBuf));
// dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads,
// errno, strerror(errno));
if (nreads <= 0) {
dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads,
errno, strerror(errno));
break;
}
if (nreads != (le16_to_cpu(pResponse->QMIHdr.Length) + 1)) {
dbg_time("%s nreads=%d, pQCQMI->QMIHdr.Length = %d",
__func__, (int)nreads,
le16_to_cpu(pResponse->QMIHdr.Length));
continue;
}
QmiThreadRecvQMI(pResponse);
}
}
}
__QmiWwanThread_quit:
if (cdc_wdm_fd != -1) {
close(cdc_wdm_fd);
cdc_wdm_fd = -1;
}
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
QmiThreadRecvQMI(NULL); // main thread may pending on QmiThreadSendQMI()
dbg_time("%s exit", __func__);
pthread_exit(NULL);
return NULL;
}
#endif
const struct qmi_device_ops qmiwwan_qmidev_ops = {
.init = QmiWwanInit,
.deinit = QmiWwanDeInit,
.send = QmiWwanSendQMI,
.read = QmiWwanThread,
};

View File

@ -1,63 +0,0 @@
#!/bin/sh
# Busybox udhcpc dispatcher script. Copyright (C) 2009 by Axel Beckert.
#
# Based on the busybox example scripts and the old udhcp source
# package default.* scripts.
RESOLV_CONF="/etc/resolv.conf"
case $1 in
bound|renew)
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"
/sbin/ifconfig $interface $ip $BROADCAST $NETMASK
if [ -n "$router" ]; then
echo "$0: Resetting default routes"
while /sbin/route del default gw 0.0.0.0 dev $interface; do :; done
metric=0
for i in $router; do
/sbin/route add default gw $i dev $interface metric $metric
metric=$(($metric + 1))
done
fi
# Update resolver configuration file
R=""
[ -n "$domain" ] && R="domain $domain
"
for i in $dns; do
echo "$0: Adding DNS $i"
R="${R}nameserver $i
"
done
if [ -x /sbin/resolvconf ]; then
echo -n "$R" | resolvconf -a "${interface}.udhcpc"
else
echo -n "$R" > "$RESOLV_CONF"
fi
;;
deconfig)
if [ -x /sbin/resolvconf ]; then
resolvconf -d "${interface}.udhcpc"
fi
/sbin/ifconfig $interface 0.0.0.0
;;
leasefail)
echo "$0: Lease failed: $message"
;;
nak)
echo "$0: Received a NAK: $message"
;;
*)
echo "$0: Unknown udhcpc command: $1";
exit 1;
;;
esac

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +0,0 @@
= What is libmnl? =
libmnl is a minimalistic user-space library oriented to Netlink developers.
There are a lot of common tasks in parsing, validating, constructing of
both the Netlink header and TLVs that are repetitive and easy to get wrong.
This library aims to provide simple helpers that allows you to re-use code
and to avoid re-inventing the wheel. The main features of this library are:
* Small: the shared library requires around 30KB for an x86-based computer.
* Simple: this library avoids complexity and elaborated abstractions that
tend to hide Netlink details.
* Easy to use: the library simplifies the work for Netlink-wise developers.
It provides functions to make socket handling, message building, validating,
parsing and sequence tracking, easier.
* Easy to re-use: you can use the library to build your own abstraction layer
on top of this library.
* Decoupling: the interdependency of the main bricks that compose the library
is reduced, i.e. the library provides many helpers, but the programmer is not
forced to use them.
= Example files =
You can find several example files under examples/ that you can compile by
invoking `make check'.
--
08/sep/2010
Pablo Neira Ayuso <pablo@netfilter.org>

View File

@ -1,722 +0,0 @@
/*
* (C) 2008-2012 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*/
#include <limits.h> /* for INT_MAX */
#include <string.h>
#include <errno.h>
#include "libmnl.h"
/**
* \defgroup attr Netlink attribute helpers
*
* Netlink Type-Length-Value (TLV) attribute:
* \verbatim
|<-- 2 bytes -->|<-- 2 bytes -->|<-- variable -->|
-------------------------------------------------
| length | type | value |
-------------------------------------------------
|<--------- header ------------>|<-- payload --->|
\endverbatim
* The payload of the Netlink message contains sequences of attributes that are
* expressed in TLV format.
*
* @{
*/
/**
* mnl_attr_get_type - get type of netlink attribute
* \param attr pointer to netlink attribute
*
* This function returns the attribute type.
*/
uint16_t mnl_attr_get_type(const struct nlattr *attr)
{
return attr->nla_type & NLA_TYPE_MASK;
}
/**
* mnl_attr_get_len - get length of netlink attribute
* \param attr pointer to netlink attribute
*
* This function returns the attribute length that is the attribute header
* plus the attribute payload.
*/
uint16_t mnl_attr_get_len(const struct nlattr *attr)
{
return attr->nla_len;
}
/**
* mnl_attr_get_payload_len - get the attribute payload-value length
* \param attr pointer to netlink attribute
*
* This function returns the attribute payload-value length.
*/
uint16_t mnl_attr_get_payload_len(const struct nlattr *attr)
{
return attr->nla_len - MNL_ATTR_HDRLEN;
}
/**
* mnl_attr_get_payload - get pointer to the attribute payload
* \param attr pointer to netlink attribute
*
* This function return a pointer to the attribute payload.
*/
void *mnl_attr_get_payload(const struct nlattr *attr)
{
return (void *)attr + MNL_ATTR_HDRLEN;
}
/**
* mnl_attr_ok - check if there is room for an attribute in a buffer
* \param attr attribute that we want to check if there is room for
* \param len remaining bytes in a buffer that contains the attribute
*
* This function is used to check that a buffer, which is supposed to contain
* an attribute, has enough room for the attribute that it stores, i.e. this
* function can be used to verify that an attribute is neither malformed nor
* truncated.
*
* This function does not set errno in case of error since it is intended
* for iterations. Thus, it returns true on success and false on error.
*
* The len parameter may be negative in the case of malformed messages during
* attribute iteration, that is why we use a signed integer.
*/
bool mnl_attr_ok(const struct nlattr *attr, int len)
{
return len >= (int)sizeof(struct nlattr) &&
attr->nla_len >= sizeof(struct nlattr) &&
(int)attr->nla_len <= len;
}
/**
* mnl_attr_next - get the next attribute in the payload of a netlink message
* \param attr pointer to the current attribute
*
* This function returns a pointer to the next attribute after the one passed
* as parameter. You have to use mnl_attr_ok() to ensure that the next
* attribute is valid.
*/
struct nlattr *mnl_attr_next(const struct nlattr *attr)
{
return (struct nlattr *)((void *)attr + MNL_ALIGN(attr->nla_len));
}
/**
* mnl_attr_type_valid - check if the attribute type is valid
* \param attr pointer to attribute to be checked
* \param max maximum attribute type
*
* This function allows to check if the attribute type is higher than the
* maximum supported type. If the attribute type is invalid, this function
* returns -1 and errno is explicitly set. On success, this function returns 1.
*
* Strict attribute checking in user-space is not a good idea since you may
* run an old application with a newer kernel that supports new attributes.
* This leads to backward compatibility breakages in user-space. Better check
* if you support an attribute, if not, skip it.
*/
int mnl_attr_type_valid(const struct nlattr *attr, uint16_t max)
{
if (mnl_attr_get_type(attr) > max) {
errno = EOPNOTSUPP;
return -1;
}
return 1;
}
static int __mnl_attr_validate(const struct nlattr *attr,
enum mnl_attr_data_type type, size_t exp_len)
{
uint16_t attr_len = mnl_attr_get_payload_len(attr);
const char *attr_data = mnl_attr_get_payload(attr);
if (attr_len < exp_len) {
errno = ERANGE;
return -1;
}
switch(type) {
case MNL_TYPE_FLAG:
if (attr_len > 0) {
errno = ERANGE;
return -1;
}
break;
case MNL_TYPE_NUL_STRING:
if (attr_len == 0) {
errno = ERANGE;
return -1;
}
if (attr_data[attr_len-1] != '\0') {
errno = EINVAL;
return -1;
}
break;
case MNL_TYPE_STRING:
if (attr_len == 0) {
errno = ERANGE;
return -1;
}
break;
case MNL_TYPE_NESTED:
/* empty nested attributes are OK. */
if (attr_len == 0)
break;
/* if not empty, they must contain one header, eg. flag */
if (attr_len < MNL_ATTR_HDRLEN) {
errno = ERANGE;
return -1;
}
break;
default:
/* make gcc happy. */
break;
}
if (exp_len && attr_len > exp_len) {
errno = ERANGE;
return -1;
}
return 0;
}
static const size_t mnl_attr_data_type_len[MNL_TYPE_MAX] = {
[MNL_TYPE_U8] = sizeof(uint8_t),
[MNL_TYPE_U16] = sizeof(uint16_t),
[MNL_TYPE_U32] = sizeof(uint32_t),
[MNL_TYPE_U64] = sizeof(uint64_t),
[MNL_TYPE_MSECS] = sizeof(uint64_t),
};
/**
* mnl_attr_validate - validate netlink attribute (simplified version)
* \param attr pointer to netlink attribute that we want to validate
* \param type data type (see enum mnl_attr_data_type)
*
* The validation is based on the data type. Specifically, it checks that
* integers (u8, u16, u32 and u64) have enough room for them. This function
* returns -1 in case of error, and errno is explicitly set.
*/
int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
{
int exp_len;
if (type >= MNL_TYPE_MAX) {
errno = EINVAL;
return -1;
}
exp_len = mnl_attr_data_type_len[type];
return __mnl_attr_validate(attr, type, exp_len);
}
/**
* mnl_attr_validate2 - validate netlink attribute (extended version)
* \param attr pointer to netlink attribute that we want to validate
* \param type attribute type (see enum mnl_attr_data_type)
* \param exp_len expected attribute data size
*
* This function allows to perform a more accurate validation for attributes
* whose size is variable. If the size of the attribute is not what we expect,
* this functions returns -1 and errno is explicitly set.
*/
int mnl_attr_validate2(const struct nlattr *attr,
enum mnl_attr_data_type type,
size_t exp_len)
{
if (type >= MNL_TYPE_MAX) {
errno = EINVAL;
return -1;
}
return __mnl_attr_validate(attr, type, exp_len);
}
/**
* mnl_attr_parse - parse attributes
* \param nlh pointer to netlink message
* \param offset offset to start parsing from (if payload is after any header)
* \param cb callback function that is called for each attribute
* \param data pointer to data that is passed to the callback function
*
* This function allows to iterate over the sequence of attributes that compose
* the Netlink message. You can then put the attribute in an array as it
* usually happens at this stage or you can use any other data structure (such
* as lists or trees).
*
* This function propagates the return value of the callback, which can be
* MNL_CB_ERROR, MNL_CB_OK or MNL_CB_STOP.
*/
int mnl_attr_parse(const struct nlmsghdr *nlh,
unsigned int offset, mnl_attr_cb_t cb,
void *data)
{
int ret = MNL_CB_OK;
const struct nlattr *attr;
mnl_attr_for_each(attr, nlh, offset)
if ((ret = cb(attr, data)) <= MNL_CB_STOP)
return ret;
return ret;
}
/**
* mnl_attr_parse_nested - parse attributes inside a nest
* \param nested pointer to netlink attribute that contains a nest
* \param cb callback function that is called for each attribute in the nest
* \param data pointer to data passed to the callback function
*
* This function allows to iterate over the sequence of attributes that compose
* the Netlink message. You can then put the attribute in an array as it
* usually happens at this stage or you can use any other data structure (such
* as lists or trees).
*
* This function propagates the return value of the callback, which can be
* MNL_CB_ERROR, MNL_CB_OK or MNL_CB_STOP.
*/
int mnl_attr_parse_nested(const struct nlattr *nested,
mnl_attr_cb_t cb, void *data)
{
int ret = MNL_CB_OK;
const struct nlattr *attr;
mnl_attr_for_each_nested(attr, nested)
if ((ret = cb(attr, data)) <= MNL_CB_STOP)
return ret;
return ret;
}
/**
* mnl_attr_parse_payload - parse attributes in payload of Netlink message
* \param payload pointer to payload of the Netlink message
* \param payload_len payload length that contains the attributes
* \param cb callback function that is called for each attribute
* \param data pointer to data that is passed to the callback function
*
* This function takes a pointer to the area that contains the attributes,
* commonly known as the payload of the Netlink message. Thus, you have to
* pass a pointer to the Netlink message payload, instead of the entire
* message.
*
* This function allows you to iterate over the sequence of attributes that are
* located at some payload offset. You can then put the attributes in one array
* as usual, or you can use any other data structure (such as lists or trees).
*
* This function propagates the return value of the callback, which can be
* MNL_CB_ERROR, MNL_CB_OK or MNL_CB_STOP.
*/
int mnl_attr_parse_payload(const void *payload,
size_t payload_len,
mnl_attr_cb_t cb, void *data)
{
int ret = MNL_CB_OK;
const struct nlattr *attr;
mnl_attr_for_each_payload(payload, payload_len)
if ((ret = cb(attr, data)) <= MNL_CB_STOP)
return ret;
return ret;
}
/**
* mnl_attr_get_u8 - returns 8-bit unsigned integer attribute payload
* \param attr pointer to netlink attribute
*
* This function returns the 8-bit value of the attribute payload.
*/
uint8_t mnl_attr_get_u8(const struct nlattr *attr)
{
return *((uint8_t *)mnl_attr_get_payload(attr));
}
/**
* mnl_attr_get_u16 - returns 16-bit unsigned integer attribute payload
* \param attr pointer to netlink attribute
*
* This function returns the 16-bit value of the attribute payload.
*/
uint16_t mnl_attr_get_u16(const struct nlattr *attr)
{
return *((uint16_t *)mnl_attr_get_payload(attr));
}
/**
* mnl_attr_get_u32 - returns 32-bit unsigned integer attribute payload
* \param attr pointer to netlink attribute
*
* This function returns the 32-bit value of the attribute payload.
*/
uint32_t mnl_attr_get_u32(const struct nlattr *attr)
{
return *((uint32_t *)mnl_attr_get_payload(attr));
}
/**
* mnl_attr_get_u64 - returns 64-bit unsigned integer attribute.
* \param attr pointer to netlink attribute
*
* This function returns the 64-bit value of the attribute payload. This
* function is align-safe, since accessing 64-bit Netlink attributes is a
* common source of alignment issues.
*/
uint64_t mnl_attr_get_u64(const struct nlattr *attr)
{
uint64_t tmp;
memcpy(&tmp, mnl_attr_get_payload(attr), sizeof(tmp));
return tmp;
}
/**
* mnl_attr_get_str - returns pointer to string attribute.
* \param attr pointer to netlink attribute
*
* This function returns the payload of string attribute value.
*/
const char *mnl_attr_get_str(const struct nlattr *attr)
{
return mnl_attr_get_payload(attr);
}
/**
* mnl_attr_put - add an attribute to netlink message
* \param nlh pointer to the netlink message
* \param type netlink attribute type that you want to add
* \param len netlink attribute payload length
* \param data pointer to the data that will be stored by the new attribute
*
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type,
size_t len, const void *data)
{
struct nlattr *attr = mnl_nlmsg_get_payload_tail(nlh);
uint16_t payload_len = MNL_ALIGN(sizeof(struct nlattr)) + len;
int pad;
attr->nla_type = type;
attr->nla_len = payload_len;
memcpy(mnl_attr_get_payload(attr), data, len);
pad = MNL_ALIGN(len) - len;
if (pad > 0)
memset(mnl_attr_get_payload(attr) + len, 0, pad);
nlh->nlmsg_len += MNL_ALIGN(payload_len);
}
/**
* mnl_attr_put_u8 - add 8-bit unsigned integer attribute to netlink message
* \param nlh pointer to the netlink message
* \param type netlink attribute type
* \param data 8-bit unsigned integer data that is stored by the new attribute
*
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
void mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type,
uint8_t data)
{
mnl_attr_put(nlh, type, sizeof(uint8_t), &data);
}
/**
* mnl_attr_put_u16 - add 16-bit unsigned integer attribute to netlink message
* \param nlh pointer to the netlink message
* \param type netlink attribute type
* \param data 16-bit unsigned integer data that is stored by the new attribute
*
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type,
uint16_t data)
{
mnl_attr_put(nlh, type, sizeof(uint16_t), &data);
}
/**
* mnl_attr_put_u32 - add 32-bit unsigned integer attribute to netlink message
* \param nlh pointer to the netlink message
* \param type netlink attribute type
* \param data 32-bit unsigned integer data that is stored by the new attribute
*
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type,
uint32_t data)
{
mnl_attr_put(nlh, type, sizeof(uint32_t), &data);
}
/**
* mnl_attr_put_u64 - add 64-bit unsigned integer attribute to netlink message
* \param nlh pointer to the netlink message
* \param type netlink attribute type
* \param data 64-bit unsigned integer data that is stored by the new attribute
*
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type,
uint64_t data)
{
mnl_attr_put(nlh, type, sizeof(uint64_t), &data);
}
/**
* mnl_attr_put_str - add string attribute to netlink message
* \param nlh pointer to the netlink message
* \param type netlink attribute type
* \param data pointer to string data that is stored by the new attribute
*
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
void mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type,
const char *data)
{
mnl_attr_put(nlh, type, strlen(data), data);
}
/**
* mnl_attr_put_strz - add string attribute to netlink message
* \param nlh pointer to the netlink message
* \param type netlink attribute type
* \param data pointer to string data that is stored by the new attribute
*
* This function is similar to mnl_attr_put_str, but it includes the
* NUL/zero ('\0') terminator at the end of the string.
*
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type,
const char *data)
{
mnl_attr_put(nlh, type, strlen(data)+1, data);
}
/**
* mnl_attr_nest_start - start an attribute nest
* \param nlh pointer to the netlink message
* \param type netlink attribute type
*
* This function adds the attribute header that identifies the beginning of
* an attribute nest. This function always returns a valid pointer to the
* beginning of the nest.
*/
struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh,
uint16_t type)
{
struct nlattr *start = mnl_nlmsg_get_payload_tail(nlh);
/* set start->nla_len in mnl_attr_nest_end() */
start->nla_type = NLA_F_NESTED | type;
nlh->nlmsg_len += MNL_ALIGN(sizeof(struct nlattr));
return start;
}
/**
* mnl_attr_put_check - add an attribute to netlink message
* \param nlh pointer to the netlink message
* \param buflen size of buffer which stores the message
* \param type netlink attribute type that you want to add
* \param len netlink attribute payload length
* \param data pointer to the data that will be stored by the new attribute
*
* This function first checks that the data can be added to the message
* (fits into the buffer) and then updates the length field of the Netlink
* message (nlmsg_len) by adding the size (header + payload) of the new
* attribute. The function returns true if the attribute could be added
* to the message, otherwise false is returned.
*/
bool mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen,
uint16_t type, size_t len,
const void *data)
{
if (nlh->nlmsg_len + MNL_ATTR_HDRLEN + MNL_ALIGN(len) > buflen)
return false;
mnl_attr_put(nlh, type, len, data);
return true;
}
/**
* mnl_attr_put_u8_check - add 8-bit unsigned int attribute to netlink message
* \param nlh pointer to the netlink message
* \param buflen size of buffer which stores the message
* \param type netlink attribute type
* \param data 8-bit unsigned integer data that is stored by the new attribute
*
* This function first checks that the data can be added to the message
* (fits into the buffer) and then updates the length field of the Netlink
* message (nlmsg_len) by adding the size (header + payload) of the new
* attribute. The function returns true if the attribute could be added
* to the message, otherwise false is returned.
*/
bool mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen,
uint16_t type, uint8_t data)
{
return mnl_attr_put_check(nlh, buflen, type, sizeof(uint8_t), &data);
}
/**
* mnl_attr_put_u16_check - add 16-bit unsigned int attribute to netlink message
* \param nlh pointer to the netlink message
* \param buflen size of buffer which stores the message
* \param type netlink attribute type
* \param data 16-bit unsigned integer data that is stored by the new attribute
*
* This function first checks that the data can be added to the message
* (fits into the buffer) and then updates the length field of the Netlink
* message (nlmsg_len) by adding the size (header + payload) of the new
* attribute. The function returns true if the attribute could be added
* to the message, otherwise false is returned.
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
bool mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen,
uint16_t type, uint16_t data)
{
return mnl_attr_put_check(nlh, buflen, type, sizeof(uint16_t), &data);
}
/**
* mnl_attr_put_u32_check - add 32-bit unsigned int attribute to netlink message
* \param nlh pointer to the netlink message
* \param buflen size of buffer which stores the message
* \param type netlink attribute type
* \param data 32-bit unsigned integer data that is stored by the new attribute
*
* This function first checks that the data can be added to the message
* (fits into the buffer) and then updates the length field of the Netlink
* message (nlmsg_len) by adding the size (header + payload) of the new
* attribute. The function returns true if the attribute could be added
* to the message, otherwise false is returned.
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
bool mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen,
uint16_t type, uint32_t data)
{
return mnl_attr_put_check(nlh, buflen, type, sizeof(uint32_t), &data);
}
/**
* mnl_attr_put_u64_check - add 64-bit unsigned int attribute to netlink message
* \param nlh pointer to the netlink message
* \param buflen size of buffer which stores the message
* \param type netlink attribute type
* \param data 64-bit unsigned integer data that is stored by the new attribute
*
* This function first checks that the data can be added to the message
* (fits into the buffer) and then updates the length field of the Netlink
* message (nlmsg_len) by adding the size (header + payload) of the new
* attribute. The function returns true if the attribute could be added
* to the message, otherwise false is returned.
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
bool mnl_attr_put_u64_check(struct nlmsghdr *nlh, size_t buflen,
uint16_t type, uint64_t data)
{
return mnl_attr_put_check(nlh, buflen, type, sizeof(uint64_t), &data);
}
/**
* mnl_attr_put_str_check - add string attribute to netlink message
* \param nlh pointer to the netlink message
* \param buflen size of buffer which stores the message
* \param type netlink attribute type
* \param data pointer to string data that is stored by the new attribute
*
* This function first checks that the data can be added to the message
* (fits into the buffer) and then updates the length field of the Netlink
* message (nlmsg_len) by adding the size (header + payload) of the new
* attribute. The function returns true if the attribute could be added
* to the message, otherwise false is returned.
* This function updates the length field of the Netlink message (nlmsg_len)
* by adding the size (header + payload) of the new attribute.
*/
bool mnl_attr_put_str_check(struct nlmsghdr *nlh, size_t buflen,
uint16_t type, const char *data)
{
return mnl_attr_put_check(nlh, buflen, type, strlen(data), data);
}
/**
* mnl_attr_put_strz_check - add string attribute to netlink message
* \param nlh pointer to the netlink message
* \param buflen size of buffer which stores the message
* \param type netlink attribute type
* \param data pointer to string data that is stored by the new attribute
*
* This function is similar to mnl_attr_put_str, but it includes the
* NUL/zero ('\0') terminator at the end of the string.
*
* This function first checks that the data can be added to the message
* (fits into the buffer) and then updates the length field of the Netlink
* message (nlmsg_len) by adding the size (header + payload) of the new
* attribute. The function returns true if the attribute could be added
* to the message, otherwise false is returned.
*/
bool mnl_attr_put_strz_check(struct nlmsghdr *nlh, size_t buflen,
uint16_t type, const char *data)
{
return mnl_attr_put_check(nlh, buflen, type, strlen(data)+1, data);
}
/**
* mnl_attr_nest_start_check - start an attribute nest
* \param buflen size of buffer which stores the message
* \param nlh pointer to the netlink message
* \param type netlink attribute type
*
* This function adds the attribute header that identifies the beginning of
* an attribute nest. If the nested attribute cannot be added then NULL,
* otherwise valid pointer to the beginning of the nest is returned.
*/
struct nlattr *mnl_attr_nest_start_check(struct nlmsghdr *nlh,
size_t buflen,
uint16_t type)
{
if (nlh->nlmsg_len + MNL_ATTR_HDRLEN > buflen)
return NULL;
return mnl_attr_nest_start(nlh, type);
}
/**
* mnl_attr_nest_end - end an attribute nest
* \param nlh pointer to the netlink message
* \param start pointer to the attribute nest returned by mnl_attr_nest_start()
*
* This function updates the attribute header that identifies the nest.
*/
void mnl_attr_nest_end(struct nlmsghdr *nlh,
struct nlattr *start)
{
start->nla_len = mnl_nlmsg_get_payload_tail(nlh) - (void *)start;
}
/**
* mnl_attr_nest_cancel - cancel an attribute nest
* \param nlh pointer to the netlink message
* \param start pointer to the attribute nest returned by mnl_attr_nest_start()
*
* This function updates the attribute header that identifies the nest.
*/
void mnl_attr_nest_cancel(struct nlmsghdr *nlh,
struct nlattr *start)
{
nlh->nlmsg_len -= mnl_nlmsg_get_payload_tail(nlh) - (void *)start;
}
/**
* @}
*/

View File

@ -1,167 +0,0 @@
/*
* (C) 2008-2010 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*/
#include <errno.h>
#include "libmnl.h"
static int mnl_cb_noop(const struct nlmsghdr *nlh, void *data)
{
return MNL_CB_OK;
}
static int mnl_cb_error(const struct nlmsghdr *nlh, void *data)
{
const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
if (nlh->nlmsg_len < mnl_nlmsg_size(sizeof(struct nlmsgerr))) {
errno = EBADMSG;
return MNL_CB_ERROR;
}
/* Netlink subsystems returns the errno value with different signess */
if (err->error < 0)
errno = -err->error;
else
errno = err->error;
return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
}
static int mnl_cb_stop(const struct nlmsghdr *nlh, void *data)
{
return MNL_CB_STOP;
}
static const mnl_cb_t default_cb_array[NLMSG_MIN_TYPE] = {
[NLMSG_NOOP] = mnl_cb_noop,
[NLMSG_ERROR] = mnl_cb_error,
[NLMSG_DONE] = mnl_cb_stop,
[NLMSG_OVERRUN] = mnl_cb_noop,
};
static inline int __mnl_cb_run(const void *buf, size_t numbytes,
unsigned int seq, unsigned int portid,
mnl_cb_t cb_data, void *data,
const mnl_cb_t *cb_ctl_array,
unsigned int cb_ctl_array_len)
{
int ret = MNL_CB_OK, len = numbytes;
const struct nlmsghdr *nlh = buf;
while (mnl_nlmsg_ok(nlh, len)) {
/* check message source */
if (!mnl_nlmsg_portid_ok(nlh, portid)) {
errno = ESRCH;
return -1;
}
/* perform sequence tracking */
if (!mnl_nlmsg_seq_ok(nlh, seq)) {
errno = EPROTO;
return -1;
}
/* dump was interrupted */
if (nlh->nlmsg_flags & NLM_F_DUMP_INTR) {
errno = EINTR;
return -1;
}
/* netlink data message handling */
if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) {
if (cb_data){
ret = cb_data(nlh, data);
if (ret <= MNL_CB_STOP)
goto out;
}
} else if (nlh->nlmsg_type < cb_ctl_array_len) {
if (cb_ctl_array && cb_ctl_array[nlh->nlmsg_type]) {
ret = cb_ctl_array[nlh->nlmsg_type](nlh, data);
if (ret <= MNL_CB_STOP)
goto out;
}
} else if (default_cb_array[nlh->nlmsg_type]) {
ret = default_cb_array[nlh->nlmsg_type](nlh, data);
if (ret <= MNL_CB_STOP)
goto out;
}
nlh = mnl_nlmsg_next(nlh, &len);
}
out:
return ret;
}
/**
* \defgroup callback Callback helpers
* @{
*/
/**
* mnl_cb_run2 - callback runqueue for netlink messages
* \param buf buffer that contains the netlink messages
* \param numbytes number of bytes stored in the buffer
* \param seq sequence number that we expect to receive
* \param portid Netlink PortID that we expect to receive
* \param cb_data callback handler for data messages
* \param data pointer to data that will be passed to the data callback handler
* \param cb_ctl_array array of custom callback handlers from control messages
* \param cb_ctl_array_len array length of custom control callback handlers
*
* You can set the cb_ctl_array to NULL if you want to use the default control
* callback handlers, in that case, the parameter cb_ctl_array_len is not
* checked.
*
* Your callback may return three possible values:
* - MNL_CB_ERROR (<=-1): an error has occurred. Stop callback runqueue.
* - MNL_CB_STOP (=0): stop callback runqueue.
* - MNL_CB_OK (>=1): no problem has occurred.
*
* This function propagates the callback return value. On error, it returns
* -1 and errno is explicitly set. If the portID is not the expected, errno
* is set to ESRCH. If the sequence number is not the expected, errno is set
* to EPROTO. If the dump was interrupted, errno is set to EINTR and you should
* request a new fresh dump again.
*/
int mnl_cb_run2(const void *buf, size_t numbytes,
unsigned int seq, unsigned int portid,
mnl_cb_t cb_data, void *data,
const mnl_cb_t *cb_ctl_array,
unsigned int cb_ctl_array_len)
{
return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data,
cb_ctl_array, cb_ctl_array_len);
}
/**
* mnl_cb_run - callback runqueue for netlink messages (simplified version)
* \param buf buffer that contains the netlink messages
* \param numbytes number of bytes stored in the buffer
* \param seq sequence number that we expect to receive
* \param portid Netlink PortID that we expect to receive
* \param cb_data callback handler for data messages
* \param data pointer to data that will be passed to the data callback handler
*
* This function is like mnl_cb_run2() but it does not allow you to set
* the control callback handlers.
*
* Your callback may return three possible values:
* - MNL_CB_ERROR (<=-1): an error has occurred. Stop callback runqueue.
* - MNL_CB_STOP (=0): stop callback runqueue.
* - MNL_CB_OK (>=1): no problems has occurred.
*
* This function propagates the callback return value.
*/
int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq,
unsigned int portid, mnl_cb_t cb_data, void *data)
{
return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data, NULL, 0);
}
/**
* @}
*/

View File

@ -1,5 +0,0 @@
#ifndef __DHCP_H__
#define __DHCP_H__
int do_dhcp(char *iname);
#endif //__DHCP_H__

View File

@ -1,515 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dirent.h>
#include <errno.h>
#include <poll.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <net/if.h>
#include <time.h>
#include <unistd.h>
#include <net/if.h>
#include "../ifutils.h"
#include "dhcpmsg.h"
#include "packet.h"
#define VERBOSE 2
static int verbose = 1;
static char errmsg[2048];
typedef unsigned long long msecs_t;
#if VERBOSE
void dump_dhcp_msg();
#endif
msecs_t get_msecs(void)
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
return 0;
} else {
return (((msecs_t) ts.tv_sec) * ((msecs_t) 1000)) +
(((msecs_t) ts.tv_nsec) / ((msecs_t) 1000000));
}
}
void printerr(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsnprintf(errmsg, sizeof(errmsg), fmt, ap);
va_end(ap);
printf("%s\n", errmsg);
}
const char *dhcp_lasterror()
{
return errmsg;
}
int fatal(const char *reason)
{
printerr("%s: %s\n", reason, strerror(errno));
return -1;
// exit(1);
}
typedef struct dhcp_info dhcp_info;
struct dhcp_info {
uint32_t type;
uint32_t ipaddr;
uint32_t gateway;
uint32_t prefixLength;
uint32_t dns1;
uint32_t dns2;
uint32_t serveraddr;
uint32_t lease;
};
dhcp_info last_good_info;
void get_dhcp_info(uint32_t *ipaddr, uint32_t *gateway, uint32_t *prefixLength,
uint32_t *dns1, uint32_t *dns2, uint32_t *server,
uint32_t *lease)
{
*ipaddr = last_good_info.ipaddr;
*gateway = last_good_info.gateway;
*prefixLength = last_good_info.prefixLength;
*dns1 = last_good_info.dns1;
*dns2 = last_good_info.dns2;
*server = last_good_info.serveraddr;
*lease = last_good_info.lease;
}
static int dhcp_configure(const char *ifname, dhcp_info *info)
{
last_good_info = *info;
return if_set_network_v4(ifname, info->ipaddr, info->prefixLength, info->gateway,
info->dns1, info->dns2);
}
static const char *dhcp_type_to_name(uint32_t type)
{
switch(type) {
case DHCPDISCOVER: return "discover";
case DHCPOFFER: return "offer";
case DHCPREQUEST: return "request";
case DHCPDECLINE: return "decline";
case DHCPACK: return "ack";
case DHCPNAK: return "nak";
case DHCPRELEASE: return "release";
case DHCPINFORM: return "inform";
default: return "???";
}
}
void dump_dhcp_info(dhcp_info *info)
{
char addr[20], gway[20];
printf("--- dhcp %s (%d) ---\n",
dhcp_type_to_name(info->type), info->type);
strcpy(addr, ipaddr_to_string_v4(info->ipaddr));
strcpy(gway, ipaddr_to_string_v4(info->gateway));
printf("ip %s gw %s prefixLength %d\n", addr, gway, info->prefixLength);
if (info->dns1) printf("dns1: %s\n", ipaddr_to_string_v4(info->dns1));
if (info->dns2) printf("dns2: %s\n", ipaddr_to_string_v4(info->dns2));
printf("server %s, lease %d seconds\n",
ipaddr_to_string_v4(info->serveraddr), info->lease);
}
int decode_dhcp_msg(dhcp_msg *msg, int len, dhcp_info *info)
{
uint8_t *x;
unsigned int opt;
int optlen;
memset(info, 0, sizeof(dhcp_info));
if (len < (DHCP_MSG_FIXED_SIZE + 4)) return -1;
len -= (DHCP_MSG_FIXED_SIZE + 4);
if (msg->options[0] != OPT_COOKIE1) return -1;
if (msg->options[1] != OPT_COOKIE2) return -1;
if (msg->options[2] != OPT_COOKIE3) return -1;
if (msg->options[3] != OPT_COOKIE4) return -1;
x = msg->options + 4;
while (len > 2) {
opt = *x++;
if (opt == OPT_PAD) {
len--;
continue;
}
if (opt == OPT_END) {
break;
}
optlen = *x++;
len -= 2;
if (optlen > len) {
break;
}
switch(opt) {
case OPT_SUBNET_MASK:
if (optlen >= 4) {
in_addr_t mask;
memcpy(&mask, x, 4);
info->prefixLength = mask_to_prefix_v4(mask);
}
break;
case OPT_GATEWAY:
if (optlen >= 4) memcpy(&info->gateway, x, 4);
break;
case OPT_DNS:
if (optlen >= 4) memcpy(&info->dns1, x + 0, 4);
if (optlen >= 8) memcpy(&info->dns2, x + 4, 4);
break;
case OPT_LEASE_TIME:
if (optlen >= 4) {
memcpy(&info->lease, x, 4);
info->lease = ntohl(info->lease);
}
break;
case OPT_SERVER_ID:
if (optlen >= 4) memcpy(&info->serveraddr, x, 4);
break;
case OPT_MESSAGE_TYPE:
info->type = *x;
break;
default:
break;
}
x += optlen;
len -= optlen;
}
info->ipaddr = msg->yiaddr;
return 0;
}
#if VERBOSE
static void hex2str(char *buf, size_t buf_size, const unsigned char *array, int len)
{
int i;
char *cp = buf;
char *buf_end = buf + buf_size;
for (i = 0; i < len; i++) {
cp += snprintf(cp, buf_end - cp, " %02x ", array[i]);
}
}
void dump_dhcp_msg(dhcp_msg *msg, int len)
{
unsigned char *x;
unsigned int n,c;
int optsz;
const char *name;
char buf[2048];
if (len < DHCP_MSG_FIXED_SIZE) {
printf("Invalid length %d, should be %d", len, DHCP_MSG_FIXED_SIZE);
return;
}
len -= DHCP_MSG_FIXED_SIZE;
if (msg->op == OP_BOOTREQUEST)
name = "BOOTREQUEST";
else if (msg->op == OP_BOOTREPLY)
name = "BOOTREPLY";
else
name = "????";
c = msg->hlen > 16 ? 16 : msg->hlen;
hex2str(buf, sizeof(buf), msg->chaddr, c);
for (n = 0; n < 64; n++) {
unsigned char x = msg->sname[n];
if ((x < ' ') || (x > 127)) {
if (x == 0) break;
msg->sname[n] = '.';
}
}
msg->sname[63] = 0;
for (n = 0; n < 128; n++) {
unsigned char x = msg->file[n];
if ((x < ' ') || (x > 127)) {
if (x == 0) break;
msg->file[n] = '.';
}
}
msg->file[127] = 0;
if (len < 4) return;
len -= 4;
x = msg->options + 4;
while (len > 2) {
if (*x == 0) {
x++;
len--;
continue;
}
if (*x == OPT_END) {
break;
}
len -= 2;
optsz = x[1];
if (optsz > len) break;
if (x[0] == OPT_DOMAIN_NAME || x[0] == OPT_MESSAGE) {
if ((unsigned int)optsz < sizeof(buf) - 1) {
n = optsz;
} else {
n = sizeof(buf) - 1;
}
memcpy(buf, &x[2], n);
buf[n] = '\0';
} else {
hex2str(buf, sizeof(buf), &x[2], optsz);
}
if (x[0] == OPT_MESSAGE_TYPE)
name = dhcp_type_to_name(x[2]);
else
name = NULL;
len -= optsz;
x = x + optsz + 2;
}
}
#endif
static int send_message(int sock, int if_index, dhcp_msg *msg, int size)
{
#if VERBOSE > 1
dump_dhcp_msg(msg, size);
#endif
return send_packet(sock, if_index, msg, size, INADDR_ANY, INADDR_BROADCAST,
PORT_BOOTP_CLIENT, PORT_BOOTP_SERVER);
}
static int is_valid_reply(dhcp_msg *msg, dhcp_msg *reply, int sz)
{
if (sz < DHCP_MSG_FIXED_SIZE) {
if (verbose) printf("Wrong size %d != %d\n", sz, DHCP_MSG_FIXED_SIZE);
return 0;
}
if (reply->op != OP_BOOTREPLY) {
if (verbose) printf("Wrong Op %d != %d\n", reply->op, OP_BOOTREPLY);
return 0;
}
if (reply->xid != msg->xid) {
if (verbose) printf("Wrong Xid 0x%x != 0x%x\n", ntohl(reply->xid),
ntohl(msg->xid));
return 0;
}
if (reply->htype != msg->htype) {
if (verbose) printf("Wrong Htype %d != %d\n", reply->htype, msg->htype);
return 0;
}
if (reply->hlen != msg->hlen) {
if (verbose) printf("Wrong Hlen %d != %d\n", reply->hlen, msg->hlen);
return 0;
}
if (memcmp(msg->chaddr, reply->chaddr, msg->hlen)) {
if (verbose) printf("Wrong chaddr %x != %x\n", *(reply->chaddr),*(msg->chaddr));
return 0;
}
return 1;
}
#define STATE_SELECTING 1
#define STATE_REQUESTING 2
#define TIMEOUT_INITIAL 4000
#define TIMEOUT_MAX 32000
int dhcp_init_ifc(const char *ifname)
{
dhcp_msg discover_msg;
dhcp_msg request_msg;
dhcp_msg reply;
dhcp_msg *msg;
dhcp_info info;
int s, r, size;
int valid_reply;
uint32_t xid;
unsigned char hwaddr[6];
struct pollfd pfd;
unsigned int state;
unsigned int timeout;
int if_index;
xid = (uint32_t) get_msecs();
if (if_get_hwaddr(ifname, hwaddr)) {
return fatal("cannot obtain interface address");
}
if ((if_index = if_nametoindex(ifname)) == 0) {
return fatal("cannot obtain interface index");
}
s = open_raw_socket(ifname, hwaddr, if_index);
timeout = TIMEOUT_INITIAL;
state = STATE_SELECTING;
info.type = 0;
goto transmit;
for (;;) {
pfd.fd = s;
pfd.events = POLLIN;
pfd.revents = 0;
r = poll(&pfd, 1, timeout);
if (r == 0) {
#if VERBOSE
printerr("TIMEOUT\n");
#endif
if (timeout >= TIMEOUT_MAX) {
printerr("timed out\n");
if ( info.type == DHCPOFFER ) {
printerr("no acknowledgement from DHCP server\nconfiguring %s with offered parameters\n", ifname);
return dhcp_configure(ifname, &info);
}
errno = ETIME;
close(s);
return -1;
}
timeout = timeout * 2;
transmit:
size = 0;
msg = NULL;
switch(state) {
case STATE_SELECTING:
msg = &discover_msg;
size = init_dhcp_discover_msg(msg, hwaddr, xid);
break;
case STATE_REQUESTING:
msg = &request_msg;
size = init_dhcp_request_msg(msg, hwaddr, xid, info.ipaddr, info.serveraddr);
break;
default:
r = 0;
}
if (size != 0) {
r = send_message(s, if_index, msg, size);
if (r < 0) {
printerr("error sending dhcp msg: %s\n", strerror(errno));
}
}
continue;
}
if (r < 0) {
if ((errno == EAGAIN) || (errno == EINTR)) {
continue;
}
return fatal("poll failed");
}
errno = 0;
r = receive_packet(s, &reply);
if (r < 0) {
if (errno != 0) {
printf("receive_packet failed (%d): %s", r, strerror(errno));
if (errno == ENETDOWN || errno == ENXIO) {
return -1;
}
}
continue;
}
#if VERBOSE > 1
dump_dhcp_msg(&reply, r);
#endif
decode_dhcp_msg(&reply, r, &info);
if (state == STATE_SELECTING) {
valid_reply = is_valid_reply(&discover_msg, &reply, r);
} else {
valid_reply = is_valid_reply(&request_msg, &reply, r);
}
if (!valid_reply) {
printerr("invalid reply\n");
continue;
}
if (verbose) dump_dhcp_info(&info);
switch(state) {
case STATE_SELECTING:
if (info.type == DHCPOFFER) {
state = STATE_REQUESTING;
timeout = TIMEOUT_INITIAL;
xid++;
goto transmit;
}
break;
case STATE_REQUESTING:
if (info.type == DHCPACK) {
printerr("configuring %s\n", ifname);
close(s);
return dhcp_configure(ifname, &info);
} else if (info.type == DHCPNAK) {
printerr("configuration request denied\n");
close(s);
return -1;
} else {
printerr("ignoring %s message in state %d\n",
dhcp_type_to_name(info.type), state);
}
break;
}
}
close(s);
return 0;
}
int do_dhcp(char *iname)
{
if (if_set_addr_v4(iname, 0, 32)) {
printerr("failed to set ip addr for %s to 0.0.0.0: %s\n", iname, strerror(errno));
return -1;
}
if (if_link_up(iname)) {
printerr("failed to bring up interface %s: %s\n", iname, strerror(errno));
return -1;
}
return dhcp_init_ifc(iname);
}

View File

@ -1,100 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <netinet/in.h>
#include "dhcpmsg.h"
static void *init_dhcp_msg(dhcp_msg *msg, int type, void *hwaddr, uint32_t xid)
{
uint8_t *x;
memset(msg, 0, sizeof(dhcp_msg));
msg->op = OP_BOOTREQUEST;
msg->htype = HTYPE_ETHER;
msg->hlen = 6;
msg->hops = 0;
msg->flags = htons(FLAGS_BROADCAST);
msg->xid = xid;
memcpy(msg->chaddr, hwaddr, 6);
x = msg->options;
*x++ = OPT_COOKIE1;
*x++ = OPT_COOKIE2;
*x++ = OPT_COOKIE3;
*x++ = OPT_COOKIE4;
*x++ = OPT_MESSAGE_TYPE;
*x++ = 1;
*x++ = type;
return x;
}
int init_dhcp_discover_msg(dhcp_msg *msg, void *hwaddr, uint32_t xid)
{
uint8_t *x;
x = init_dhcp_msg(msg, DHCPDISCOVER, hwaddr, xid);
*x++ = OPT_PARAMETER_LIST;
*x++ = 4;
*x++ = OPT_SUBNET_MASK;
*x++ = OPT_GATEWAY;
*x++ = OPT_DNS;
*x++ = OPT_BROADCAST_ADDR;
*x++ = OPT_END;
return DHCP_MSG_FIXED_SIZE + (x - msg->options);
}
int init_dhcp_request_msg(dhcp_msg *msg, void *hwaddr, uint32_t xid,
uint32_t ipaddr, uint32_t serveraddr)
{
uint8_t *x;
x = init_dhcp_msg(msg, DHCPREQUEST, hwaddr, xid);
*x++ = OPT_PARAMETER_LIST;
*x++ = 4;
*x++ = OPT_SUBNET_MASK;
*x++ = OPT_GATEWAY;
*x++ = OPT_DNS;
*x++ = OPT_BROADCAST_ADDR;
*x++ = OPT_REQUESTED_IP;
*x++ = 4;
memcpy(x, &ipaddr, 4);
x += 4;
*x++ = OPT_SERVER_ID;
*x++ = 4;
memcpy(x, &serveraddr, 4);
x += 4;
*x++ = OPT_END;
return DHCP_MSG_FIXED_SIZE + (x - msg->options);
}

View File

@ -1,106 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WIFI_DHCP_H_
#define _WIFI_DHCP_H_
#include <stdint.h>
#define PORT_BOOTP_SERVER 67
#define PORT_BOOTP_CLIENT 68
/* RFC 2131 p 9 */
typedef struct dhcp_msg dhcp_msg;
#define OP_BOOTREQUEST 1
#define OP_BOOTREPLY 2
#define FLAGS_BROADCAST 0x8000
#define HTYPE_ETHER 1
struct dhcp_msg
{
uint8_t op; /* BOOTREQUEST / BOOTREPLY */
uint8_t htype; /* hw addr type */
uint8_t hlen; /* hw addr len */
uint8_t hops; /* client set to 0 */
uint32_t xid; /* transaction id */
uint16_t secs; /* seconds since start of acq */
uint16_t flags;
uint32_t ciaddr; /* client IP addr */
uint32_t yiaddr; /* your (client) IP addr */
uint32_t siaddr; /* ip addr of next server */
/* (DHCPOFFER and DHCPACK) */
uint32_t giaddr; /* relay agent IP addr */
uint8_t chaddr[16]; /* client hw addr */
char sname[64]; /* asciiz server hostname */
char file[128]; /* asciiz boot file name */
uint8_t options[1024]; /* optional parameters */
};
#define DHCP_MSG_FIXED_SIZE 236
/* first four bytes of options are a cookie to indicate that
** the payload are DHCP options as opposed to some other BOOTP
** extension.
*/
#define OPT_COOKIE1 0x63
#define OPT_COOKIE2 0x82
#define OPT_COOKIE3 0x53
#define OPT_COOKIE4 0x63
/* BOOTP/DHCP options - see RFC 2132 */
#define OPT_PAD 0
#define OPT_SUBNET_MASK 1 /* 4 <ipaddr> */
#define OPT_TIME_OFFSET 2 /* 4 <seconds> */
#define OPT_GATEWAY 3 /* 4*n <ipaddr> * n */
#define OPT_DNS 6 /* 4*n <ipaddr> * n */
#define OPT_DOMAIN_NAME 15 /* n <domainnamestring> */
#define OPT_BROADCAST_ADDR 28 /* 4 <ipaddr> */
#define OPT_REQUESTED_IP 50 /* 4 <ipaddr> */
#define OPT_LEASE_TIME 51 /* 4 <seconds> */
#define OPT_MESSAGE_TYPE 53 /* 1 <msgtype> */
#define OPT_SERVER_ID 54 /* 4 <ipaddr> */
#define OPT_PARAMETER_LIST 55 /* n <optcode> * n */
#define OPT_MESSAGE 56 /* n <errorstring> */
#define OPT_CLASS_ID 60 /* n <opaque> */
#define OPT_CLIENT_ID 61 /* n <opaque> */
#define OPT_END 255
/* DHCP message types */
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPDECLINE 4
#define DHCPACK 5
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCPINFORM 8
int init_dhcp_discover_msg(dhcp_msg *msg, void *hwaddr, uint32_t xid);
int init_dhcp_request_msg(dhcp_msg *msg, void *hwaddr, uint32_t xid,
uint32_t ipaddr, uint32_t serveraddr);
#endif

View File

@ -1,247 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <unistd.h>
#include <stdio.h>
#include "dhcpmsg.h"
int fatal();
int open_raw_socket(const char *ifname __attribute__((unused)), uint8_t *hwaddr, int if_index)
{
int s;
struct sockaddr_ll bindaddr;
if((s = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
return fatal("socket(PF_PACKET)");
}
memset(&bindaddr, 0, sizeof(bindaddr));
bindaddr.sll_family = AF_PACKET;
bindaddr.sll_protocol = htons(ETH_P_IP);
bindaddr.sll_halen = ETH_ALEN;
memcpy(bindaddr.sll_addr, hwaddr, ETH_ALEN);
bindaddr.sll_ifindex = if_index;
if (bind(s, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
return fatal("Cannot bind raw socket to interface");
}
return s;
}
static uint32_t checksum(void *buffer, unsigned int count, uint32_t startsum)
{
uint16_t *up = (uint16_t *)buffer;
uint32_t sum = startsum;
uint32_t upper16;
while (count > 1) {
sum += *up++;
count -= 2;
}
if (count > 0) {
sum += (uint16_t) *(uint8_t *)up;
}
while ((upper16 = (sum >> 16)) != 0) {
sum = (sum & 0xffff) + upper16;
}
return sum;
}
static uint32_t finish_sum(uint32_t sum)
{
return ~sum & 0xffff;
}
int send_packet(int s, int if_index, struct dhcp_msg *msg, int size,
uint32_t saddr, uint32_t daddr, uint32_t sport, uint32_t dport)
{
struct iphdr ip;
struct udphdr udp;
struct iovec iov[3];
uint32_t udpsum;
uint16_t temp;
struct msghdr msghdr;
struct sockaddr_ll destaddr;
ip.version = IPVERSION;
ip.ihl = sizeof(ip) >> 2;
ip.tos = 0;
ip.tot_len = htons(sizeof(ip) + sizeof(udp) + size);
ip.id = 0;
ip.frag_off = 0;
ip.ttl = IPDEFTTL;
ip.protocol = IPPROTO_UDP;
ip.check = 0;
ip.saddr = saddr;
ip.daddr = daddr;
ip.check = finish_sum(checksum(&ip, sizeof(ip), 0));
udp.source = htons(sport);
udp.dest = htons(dport);
udp.len = htons(sizeof(udp) + size);
udp.check = 0;
/* Calculate checksum for pseudo header */
udpsum = checksum(&ip.saddr, sizeof(ip.saddr), 0);
udpsum = checksum(&ip.daddr, sizeof(ip.daddr), udpsum);
temp = htons(IPPROTO_UDP);
udpsum = checksum(&temp, sizeof(temp), udpsum);
temp = udp.len;
udpsum = checksum(&temp, sizeof(temp), udpsum);
/* Add in the checksum for the udp header */
udpsum = checksum(&udp, sizeof(udp), udpsum);
/* Add in the checksum for the data */
udpsum = checksum(msg, size, udpsum);
udp.check = finish_sum(udpsum);
iov[0].iov_base = (char *)&ip;
iov[0].iov_len = sizeof(ip);
iov[1].iov_base = (char *)&udp;
iov[1].iov_len = sizeof(udp);
iov[2].iov_base = (char *)msg;
iov[2].iov_len = size;
memset(&destaddr, 0, sizeof(destaddr));
destaddr.sll_family = AF_PACKET;
destaddr.sll_protocol = htons(ETH_P_IP);
destaddr.sll_ifindex = if_index;
destaddr.sll_halen = ETH_ALEN;
memcpy(destaddr.sll_addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN);
msghdr.msg_name = &destaddr;
msghdr.msg_namelen = sizeof(destaddr);
msghdr.msg_iov = iov;
msghdr.msg_iovlen = sizeof(iov) / sizeof(struct iovec);
msghdr.msg_flags = 0;
msghdr.msg_control = 0;
msghdr.msg_controllen = 0;
return sendmsg(s, &msghdr, 0);
}
int receive_packet(int s, struct dhcp_msg *msg)
{
int nread;
int is_valid;
struct dhcp_packet {
struct iphdr ip;
struct udphdr udp;
struct dhcp_msg dhcp;
} packet;
int dhcp_size;
uint32_t sum;
uint16_t temp;
uint32_t saddr, daddr;
nread = read(s, &packet, sizeof(packet));
if (nread < 0) {
return -1;
}
/*
* The raw packet interface gives us all packets received by the
* network interface. We need to filter out all packets that are
* not meant for us.
*/
is_valid = 0;
if (nread < (int)(sizeof(struct iphdr) + sizeof(struct udphdr))) {
#if VERBOSE
ALOGD("Packet is too small (%d) to be a UDP datagram", nread);
#endif
} else if (packet.ip.version != IPVERSION || packet.ip.ihl != (sizeof(packet.ip) >> 2)) {
#if VERBOSE
ALOGD("Not a valid IP packet");
#endif
} else if (nread < ntohs(packet.ip.tot_len)) {
#if VERBOSE
ALOGD("Packet was truncated (read %d, needed %d)", nread, ntohs(packet.ip.tot_len));
#endif
} else if (packet.ip.protocol != IPPROTO_UDP) {
#if VERBOSE
ALOGD("IP protocol (%d) is not UDP", packet.ip.protocol);
#endif
} else if (packet.udp.dest != htons(PORT_BOOTP_CLIENT)) {
#if VERBOSE
ALOGD("UDP dest port (%d) is not DHCP client", ntohs(packet.udp.dest));
#endif
} else {
is_valid = 1;
}
if (!is_valid) {
return -1;
}
/* Seems like it's probably a valid DHCP packet */
/* validate IP header checksum */
sum = finish_sum(checksum(&packet.ip, sizeof(packet.ip), 0));
if (sum != 0) {
printf("IP header checksum failure (0x%x)\n", packet.ip.check);
return -1;
}
/*
* Validate the UDP checksum.
* Since we don't need the IP header anymore, we "borrow" it
* to construct the pseudo header used in the checksum calculation.
*/
dhcp_size = ntohs(packet.udp.len) - sizeof(packet.udp);
/*
* check validity of dhcp_size.
* 1) cannot be negative or zero.
* 2) src buffer contains enough bytes to copy
* 3) cannot exceed destination buffer
*/
if ((dhcp_size <= 0) ||
((int)(nread - sizeof(struct iphdr) - sizeof(struct udphdr)) < dhcp_size) ||
((int)sizeof(struct dhcp_msg) < dhcp_size)) {
#if VERBOSE
printf("Malformed Packet\n");
#endif
return -1;
}
saddr = packet.ip.saddr;
daddr = packet.ip.daddr;
nread = ntohs(packet.ip.tot_len);
memset(&packet.ip, 0, sizeof(packet.ip));
packet.ip.saddr = saddr;
packet.ip.daddr = daddr;
packet.ip.protocol = IPPROTO_UDP;
packet.ip.tot_len = packet.udp.len;
temp = packet.udp.check;
packet.udp.check = 0;
sum = finish_sum(checksum(&packet, nread, 0));
packet.udp.check = temp;
if (!sum)
sum = finish_sum(sum);
if (temp != sum) {
printf("UDP header checksum failure (0x%x should be 0x%x)\n", sum, temp);
return -1;
}
memcpy(msg, &packet.dhcp, dhcp_size);
return dhcp_size;
}

View File

@ -1,25 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WIFI_PACKET_H_
#define _WIFI_PACKET_H_
int open_raw_socket(const char *ifname, uint8_t *hwaddr, int if_index);
int send_packet(int s, int if_index, struct dhcp_msg *msg, int size,
uint32_t saddr, uint32_t daddr, uint32_t sport, uint32_t dport);
int receive_packet(int s, struct dhcp_msg *msg);
#endif

View File

@ -1,748 +0,0 @@
/* This example is placed in the public domain. */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <net/if.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <linux/if_link.h>
#include <linux/if_ether.h>
#include <linux/rtnetlink.h>
//#include <linux/if.h>
#include "libmnl.h"
#include "ifutils.h"
#define ERRMSG(v...) printf("%s-%d: error=%s %s\n", __func__, __LINE__, strerror(errno), ##v)
extern void dbg_time(const char *fmt, ...);
int mask_to_prefix_v4(uint32_t mask)
{
int ret = 0;
while (mask)
{
mask = mask & (mask - 1);
ret++;
}
return ret;
}
const char *ipaddr_to_string_v4(in_addr_t ipaddr)
{
static char buf[INET6_ADDRSTRLEN] = {'\0'};
buf[0] = '\0';
uint32_t addr = ipaddr;
return inet_ntop(AF_INET, &addr, buf, sizeof(buf));
}
const char *ipaddr_to_string_v6(uint8_t *ipaddr)
{
static char buf[INET6_ADDRSTRLEN] = {'\0'};
buf[0] = '\0';
return inet_ntop(AF_INET6, ipaddr, buf, sizeof(buf));
}
static void ifc_init_ifr(const char *name, struct ifreq *ifr)
{
memset(ifr, 0, sizeof(struct ifreq));
strncpy(ifr->ifr_name, name, IFNAMSIZ);
ifr->ifr_name[IFNAMSIZ - 1] = 0;
}
int if_get_hwaddr(const char *name, void *ptr)
{
int r;
struct ifreq ifr;
ifc_init_ifr(name, &ifr);
int ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (ifc_ctl_sock < 0)
{
return -1;
}
r = ioctl(ifc_ctl_sock, SIOCGIFHWADDR, &ifr);
if (r < 0)
return -1;
memcpy(ptr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
return 0;
}
static int if_act_on_link(const char *ifname, int state)
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct ifinfomsg *ifm;
int ret;
unsigned int seq, portid, change = 0, flags = 0;
static int oldstate = -1;
if (state == oldstate)
return 0;
oldstate = state;
if (state)
{
change |= IFF_UP;
flags |= IFF_UP;
}
else
{
change |= IFF_UP;
flags &= ~IFF_UP;
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_NEWLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
ifm->ifi_family = AF_UNSPEC;
ifm->ifi_change = change;
ifm->ifi_flags = flags;
mnl_attr_put_str(nlh, IFLA_IFNAME, ifname);
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL)
{
ERRMSG("mnl_socket_open");
return -1;
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
{
ERRMSG(" mnl_socket_bind");
return -1;
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
{
ERRMSG(" mnl_socket_sendto");
return -1;
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1)
{
ERRMSG(" mnl_socket_recvfrom");
return -1;
}
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
if (ret == -1)
{
ERRMSG(" mnl_cb_run");
return -1;
}
mnl_socket_close(nl);
return 0;
}
int if_link_up(const char *ifname)
{
dbg_time("if_link_up %s",ifname);
return if_act_on_link(ifname, 1);
}
int if_link_down(const char *ifname)
{
dbg_time("if_link_down %s",ifname);
return if_act_on_link(ifname, 0);
}
int if_set_mtu(const char *ifname, uint32_t mtu)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
unsigned int seq, portid;
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct ifinfomsg *ifm;
int ret;
int iface;
static uint32_t oldmtu = 1500;
if (mtu == oldmtu)
return 0;
oldmtu = mtu;
iface = if_nametoindex(ifname);
if (iface == 0)
{
ERRMSG(" if_nametoindex");
return -1;
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_NEWLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifinfomsg));
ifm->ifi_family = AF_UNSPEC;
ifm->ifi_index = iface;
ifm->ifi_change = 0xFFFFFFFF;
ifm->ifi_type = 0;
ifm->ifi_flags = IFF_NOARP | IFF_MULTICAST;
mnl_attr_put_u32(nlh, IFLA_MTU, mtu);
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL)
{
ERRMSG(" mnl_socket_open");
return -1;
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
{
ERRMSG(" mnl_socket_bind");
return -1;
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
{
ERRMSG(" mnl_socket_sendto");
return -1;
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret == -1)
{
ERRMSG(" mnl_socket_recvfrom");
return -1;
}
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
if (ret == -1)
{
ERRMSG(" mnl_cb_run");
return -1;
}
mnl_socket_close(nl);
return 0;
}
/**
* @brief Set the ip addr object
*
* @param operate
* 0 -> add address on interface
* 1 -> delete address on interface
* @param ifname
* @param ipaddr
* @param prefix
* @return int
*/
static int if_act_on_addr(bool operate, int proto, const char *ifname, addr_t *ipaddr, uint32_t prefix)
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct ifaddrmsg *ifm;
uint32_t seq, portid;
int ret, family = proto;
int iface;
iface = if_nametoindex(ifname);
if (iface == 0)
{
ERRMSG(" if_nametoindex");
return -1;
}
nlh = mnl_nlmsg_put_header(buf);
if (operate)
nlh->nlmsg_type = RTM_NEWADDR;
else
nlh->nlmsg_type = RTM_DELADDR;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE | NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifaddrmsg));
ifm->ifa_family = family;
ifm->ifa_prefixlen = prefix;
ifm->ifa_flags = IFA_F_PERMANENT;
ifm->ifa_scope = RT_SCOPE_UNIVERSE;
ifm->ifa_index = iface;
/*
* The exact meaning of IFA_LOCAL and IFA_ADDRESS depend
* on the address family being used and the device type.
* For broadcast devices (like the interfaces we use),
* for IPv4 we specify both and they are used interchangeably.
* For IPv6, only IFA_ADDRESS needs to be set.
*/
if (family == AF_INET)
{
mnl_attr_put_u32(nlh, IFA_LOCAL, ipaddr->ip);
mnl_attr_put_u32(nlh, IFA_ADDRESS, ipaddr->ip);
}
else
{
mnl_attr_put(nlh, IFA_ADDRESS, sizeof(struct in6_addr), ipaddr);
}
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL)
{
ERRMSG(" mnl_socket_open");
return -1;
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
{
ERRMSG(" mnl_socket_bind");
return -1;
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
{
ERRMSG(" mnl_socket_sendto");
return -1;
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret < 0)
{
ERRMSG(" mnl_socket_recvfrom");
return -1;
}
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
if (ret < 0)
{
ERRMSG(" mnl_cb_run");
return -1;
}
mnl_socket_close(nl);
return 0;
}
int if_set_addr_v4(const char *ifname, in_addr_t ipaddr, uint32_t prefix)
{
addr_t addr;
addr.ip = ipaddr;
return if_act_on_addr(1, AF_INET, ifname, &addr, prefix);
}
int if_del_addr_v4(const char *ifname, in_addr_t ipaddr, uint32_t prefix)
{
addr_t addr;
addr.ip = ipaddr;
return if_act_on_addr(0, AF_INET, ifname, &addr, prefix);
}
int if_set_addr_v6(const char *ifname, uint8_t *ipaddr, uint32_t prefix)
{
addr_t addr;
memcpy(&addr.ip6, ipaddr, 16);
return if_act_on_addr(1, AF_INET6, ifname, &addr, prefix);
}
int if_del_addr_v6(const char *ifname, uint8_t *ipaddr, uint32_t prefix)
{
addr_t addr;
memcpy(&addr.ip6, ipaddr, 16);
return if_act_on_addr(0, AF_INET6, ifname, &addr, prefix);
}
static int data_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
/* skip unsupported attribute in user-space */
if (mnl_attr_type_valid(attr, IFA_MAX) < 0)
return MNL_CB_OK;
switch (type)
{
case IFA_ADDRESS:
if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
{
ERRMSG(" mnl_attr_validate");
return MNL_CB_ERROR;
}
break;
}
tb[type] = attr;
return MNL_CB_OK;
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[IFA_MAX + 1] = {};
struct ifaddrmsg *ifa = mnl_nlmsg_get_payload(nlh);
struct addrinfo_t *addrinfo = (struct addrinfo_t *)data;
void *addr = NULL;
mnl_attr_parse(nlh, sizeof(*ifa), data_attr_cb, tb);
if (tb[IFA_ADDRESS])
{
char out[INET6_ADDRSTRLEN];
addr = mnl_attr_get_payload(tb[IFLA_ADDRESS]);
addr = mnl_attr_get_payload(tb[IFA_ADDRESS]);
if (!inet_ntop(ifa->ifa_family, addr, out, sizeof(out)))
ERRMSG("inet_ntop");
// printf("%d %d-> %d %s\n", addrinfo->iface, ifa->ifa_index, ifa->ifa_scope, out);
addrinfo->addrs[addrinfo->num].prefix = ifa->ifa_prefixlen;
if (ifa->ifa_index == addrinfo->iface)
{
if (ifa->ifa_family == AF_INET6)
memcpy(addrinfo->addrs[addrinfo->num].address.ip6.s6_addr, addr, 16);
if (ifa->ifa_family == AF_INET)
memcpy(&(addrinfo->addrs[addrinfo->num].address.ip), addr, 4);
addrinfo->num++;
}
}
// ifa->ifa_scope
// 0: global
// 200: site
// 253: link
// 254: host
// 255: nowhere
return MNL_CB_OK;
}
/**
* @brief
*
* @param ifname
* @param proto
* AF_INET -> for IPv4
* AF_INET6 -> for IPv6
* @return int
*/
static int if_get_addr(const char *ifname, int proto, struct addrinfo_t *addrinfo)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
unsigned int seq, portid;
struct mnl_socket *nl;
struct nlmsghdr *nlh;
struct rtgenmsg *rt;
int ret;
addrinfo->iface = if_nametoindex(ifname);
if (addrinfo->iface == 0)
{
ERRMSG(" if_nametoindex");
return -1;
}
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_GETADDR;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
nlh->nlmsg_seq = seq = time(NULL);
rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
if (proto == AF_INET)
rt->rtgen_family = AF_INET;
else if (proto == AF_INET6)
rt->rtgen_family = AF_INET6;
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL)
{
ERRMSG(" mnl_socket_open");
return -1;
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
{
ERRMSG(" mnl_socket_bind");
return -1;
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
{
ERRMSG(" mnl_socket_sendto");
return -1;
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
while (ret > 0)
{
ret = mnl_cb_run(buf, ret, seq, portid, data_cb, addrinfo);
if (ret <= MNL_CB_STOP)
break;
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret == -1)
{
ERRMSG(" error");
return -1;
}
mnl_socket_close(nl);
return 0;
}
int if_flush_v4_addr(const char *ifname)
{
struct addrinfo_t addrinfo;
int i = 0;
memset(&addrinfo, 0, sizeof(struct addrinfo_t));
if_get_addr(ifname, AF_INET, &addrinfo);
for (; i < addrinfo.num; i++)
{
// printf("remove address: %s\n", ipaddr_to_string_v4(addrinfo.addrs[i].address.ip));
if_del_addr_v4(ifname, addrinfo.addrs[i].address.ip, addrinfo.addrs[i].prefix);
}
return 0;
}
int if_flush_v6_addr(const char *ifname)
{
struct addrinfo_t addrinfo;
int i = 0;
memset(&addrinfo, 0, sizeof(struct addrinfo_t));
if_get_addr(ifname, AF_INET6, &addrinfo);
for (; i < addrinfo.num; i++)
{
// printf("remove address: %s\n", ipaddr_to_string_v6(addrinfo.addrs[i].address.ip6.s6_addr));
if_del_addr_v6(ifname, addrinfo.addrs[i].address.ip6.s6_addr, addrinfo.addrs[i].prefix);
}
return 0;
}
/**
* @brief Set the route addr object
* Usage:
* iface destination cidr [gateway]
* Example:
* eth0 10.0.1.12 32 10.0.1.11
* eth0 ffff::10.0.1.12 128 fdff::1
* @param operate
* add or del
* @param ifname
* @param dstaddr
* @param prefix
* @param gwaddr
* @return int
*/
int if_act_on_route(bool operate, int proto, const char *ifname, addr_t *dstaddr, uint32_t prefix, addr_t *gwaddr)
{
struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct rtmsg *rtm;
uint32_t seq, portid;
int iface, ret, family = proto;
iface = if_nametoindex(ifname);
if (iface == 0)
{
ERRMSG(" if_nametoindex");
return -1;
}
nlh = mnl_nlmsg_put_header(buf);
if (operate)
nlh->nlmsg_type = RTM_NEWROUTE;
else
nlh->nlmsg_type = RTM_DELROUTE;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));
rtm->rtm_family = family;
rtm->rtm_dst_len = prefix;
rtm->rtm_src_len = 0;
rtm->rtm_tos = 0;
rtm->rtm_protocol = RTPROT_STATIC;
rtm->rtm_table = RT_TABLE_MAIN;
rtm->rtm_type = RTN_UNICAST;
/* is there any gateway? */
rtm->rtm_scope = gwaddr ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
rtm->rtm_flags = 0;
if (family == AF_INET)
mnl_attr_put_u32(nlh, RTA_DST, dstaddr->ip);
else
mnl_attr_put(nlh, RTA_DST, sizeof(struct in6_addr), dstaddr);
mnl_attr_put_u32(nlh, RTA_OIF, iface);
if (gwaddr)
{
if (family == AF_INET)
mnl_attr_put_u32(nlh, RTA_GATEWAY, gwaddr->ip);
else
{
mnl_attr_put(nlh, RTA_GATEWAY, sizeof(struct in6_addr), gwaddr);
}
}
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL)
{
ERRMSG(" mnl_socket_open");
return -1;
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
{
ERRMSG(" mnl_socket_bind");
return -1;
}
portid = mnl_socket_get_portid(nl);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
{
ERRMSG(" mnl_socket_sendto");
return -1;
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
if (ret < 0)
{
ERRMSG(" mnl_socket_recvfrom");
return -1;
}
ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
if (ret < 0)
{
ERRMSG(" mnl_cb_run");
return -1;
}
mnl_socket_close(nl);
return 0;
}
int if_set_default_route_v4(const char *ifname)
{
return if_act_on_route(1, AF_INET, ifname, (addr_t *)&in6addr_any, 0, NULL);
}
int if_del_default_route_v4(const char *ifname)
{
return if_act_on_route(0, AF_INET, ifname, (addr_t *)&in6addr_any, 0, NULL);
}
int if_set_default_route_v6(const char *ifname)
{
return if_act_on_route(1, AF_INET6, ifname, (addr_t *)&in6addr_any, 0, NULL);
}
int if_del_default_route_v6(const char *ifname)
{
return if_act_on_route(0, AF_INET6, ifname, (addr_t *)&in6addr_any, 0, NULL);
}
/**
* @brief Set the default gwaddr object
* set default gw
* @param operate
* @param ifname
* @param gwaddr
* gateway ip
* @return int
*/
int if_set_route_gw_v4(const char *ifname, in_addr_t gwaddr)
{
addr_t addr;
memset(&addr, 0, sizeof(addr_t));
addr.ip = gwaddr;
return if_act_on_route(1, AF_INET, ifname, (addr_t *)&in6addr_any, 0, &addr);
}
int if_del_route_gw_v4(const char *ifname, in_addr_t gwaddr)
{
addr_t addr;
memset(&addr, 0, sizeof(addr_t));
addr.ip = gwaddr;
return if_act_on_route(0, AF_INET, ifname, (addr_t *)&in6addr_any, 0, &addr);
}
int if_set_route_gw_v6(const char *ifname, uint8_t *gwaddr)
{
addr_t addr;
memset(&addr, 0, sizeof(addr_t));
memcpy(&addr.ip6, gwaddr, 16);
return if_act_on_route(1, AF_INET6, ifname, (addr_t *)&in6addr_any, 0, &addr);
}
int if_del_route_gw_v6(const char *ifname, uint8_t *gwaddr)
{
addr_t addr;
memset(&addr, 0, sizeof(addr_t));
memcpy(&addr.ip6, gwaddr, 16);
return if_act_on_route(0, AF_INET6, ifname, (addr_t *)&in6addr_any, 0, &addr);
}
int if_set_dns(const char *dns1, const char *dns2)
{
int ret = 0;
char buf[128] = {'\0'};
int fd = open("/etc/resolv.conf", O_CREAT | O_WRONLY | O_TRUNC);
if (fd < 0)
{
ERRMSG(" fail to open /etc/resolv.conf");
return -1;
}
if (dns1)
snprintf(buf, sizeof(buf), "nameserver %s\n", dns1);
if (dns2)
snprintf(buf, sizeof(buf), "nameserver %s\n", dns2);
ret = write(fd, buf, strlen(buf));
if (ret < 0)
{
ERRMSG(" write dns");
}
close(fd);
return ret > 0 ? 0 : -1;
}
int if_set_network_v4(const char *ifname, in_addr_t ipaddr, uint32_t prefix,
in_addr_t gwaddr, in_addr_t dns1, in_addr_t dns2)
{
if_link_up(ifname);
sleep(2);
if_set_addr_v4(ifname, ipaddr, prefix);
if_set_default_route_v4(ifname);
if_set_dns(ipaddr_to_string_v4(dns1), ipaddr_to_string_v4(dns2));
return 0;
}
int if_set_network_v6(const char *ifname, uint8_t *ipaddr, uint32_t prefix,
uint8_t *gwaddr, uint8_t *dns1, uint8_t *dns2)
{
if_link_up(ifname);
sleep(2);
if_set_addr_v6(ifname, ipaddr, prefix);
if_set_default_route_v6(ifname);
if_set_dns(ipaddr_to_string_v6(dns1), ipaddr_to_string_v6(dns2));
return 0;
}

View File

@ -1,53 +0,0 @@
#ifndef __IFUTILS_H__
#define __IFUTILS_H__
typedef union {
in_addr_t ip;
struct in6_addr ip6;
} addr_t;
#define MAX_IP_NUM 32
struct addrinfo_t
{
int iface;
int num;
struct
{
int prefix;
addr_t address;
} addrs[MAX_IP_NUM];
};
const char *ipaddr_to_string_v4(in_addr_t ipaddr);
const char *ipaddr_to_string_v6(uint8_t *ipaddr);
int mask_to_prefix_v4(in_addr_t mask);
int if_get_hwaddr(const char *name, void *ptr);
int if_link_down(const char *ifname);
int if_link_up(const char *ifname);
int if_set_mtu(const char *ifname, uint32_t mtu);
int if_set_addr_v4(const char *name, in_addr_t address, uint32_t prefixlen);
int if_del_addr_v4(const char *name, in_addr_t address, uint32_t prefixlen);
int if_set_addr_v6(const char *name, uint8_t *address, uint32_t prefixlen);
int if_del_addr_v6(const char *name, uint8_t *address, uint32_t prefixlen);
int if_flush_v4_addr(const char *ifname);
int if_flush_v6_addr(const char *ifname);
int if_set_route_gw_v4(const char *ifname, in_addr_t gwaddr);
int if_del_route_gw_v4(const char *ifname, in_addr_t gwaddr);
int if_set_default_route_v4(const char *ifname);
int if_del_default_route_v4(const char *ifname);
int if_set_route_gw_v6(const char *ifname, uint8_t *gwaddr);
int if_del_route_gw_v6(const char *ifname, uint8_t *gwaddr);
int if_set_default_route_v6(const char *ifname);
int if_del_default_route_v6(const char *ifname);
int if_set_network_v4(const char *ifname, in_addr_t ipaddr, uint32_t prefix,
in_addr_t gwaddr, in_addr_t dns1, in_addr_t dns2);
int if_set_network_v6(const char *ifname, uint8_t *ipaddr, uint32_t prefix,
uint8_t *gwaddr, uint8_t *dns1, uint8_t *dns2);
#endif //__IFUTILS_H__

View File

@ -1,202 +0,0 @@
#ifndef _LIBMNL_H_
#define _LIBMNL_H_
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/socket.h> /* for sa_family_t */
#include <linux/netlink.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Netlink socket API
*/
#define MNL_SOCKET_AUTOPID 0
#define MNL_SOCKET_BUFFER_SIZE (sysconf(_SC_PAGESIZE) < 8192L ? sysconf(_SC_PAGESIZE) : 8192L)
#define MNL_SOCKET_DUMP_SIZE 32768
struct mnl_socket;
extern struct mnl_socket *mnl_socket_open(int bus);
extern struct mnl_socket *mnl_socket_open2(int bus, int flags);
extern struct mnl_socket *mnl_socket_fdopen(int fd);
extern int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid);
extern int mnl_socket_close(struct mnl_socket *nl);
extern int mnl_socket_get_fd(const struct mnl_socket *nl);
extern unsigned int mnl_socket_get_portid(const struct mnl_socket *nl);
extern ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz);
extern ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz);
extern int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len);
extern int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len);
/*
* Netlink message API
*/
#define MNL_ALIGNTO 4
#define MNL_ALIGN(len) (((len)+MNL_ALIGNTO-1) & ~(MNL_ALIGNTO-1))
#define MNL_NLMSG_HDRLEN MNL_ALIGN(sizeof(struct nlmsghdr))
extern size_t mnl_nlmsg_size(size_t len);
extern size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh);
/* Netlink message header builder */
extern struct nlmsghdr *mnl_nlmsg_put_header(void *buf);
extern void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size);
/* Netlink message iterators */
extern bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len);
extern struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len);
/* Netlink sequence tracking */
extern bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq);
/* Netlink portID checking */
extern bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid);
/* Netlink message getters */
extern void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh);
extern void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset);
extern void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh);
/* Netlink message printer */
extern void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen, size_t extra_header_size);
/* Message batch helpers */
struct mnl_nlmsg_batch;
extern struct mnl_nlmsg_batch *mnl_nlmsg_batch_start(void *buf, size_t bufsiz);
extern bool mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b);
extern void mnl_nlmsg_batch_stop(struct mnl_nlmsg_batch *b);
extern size_t mnl_nlmsg_batch_size(struct mnl_nlmsg_batch *b);
extern void mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b);
extern void *mnl_nlmsg_batch_head(struct mnl_nlmsg_batch *b);
extern void *mnl_nlmsg_batch_current(struct mnl_nlmsg_batch *b);
extern bool mnl_nlmsg_batch_is_empty(struct mnl_nlmsg_batch *b);
/*
* Netlink attributes API
*/
#define MNL_ATTR_HDRLEN MNL_ALIGN(sizeof(struct nlattr))
/* TLV attribute getters */
extern uint16_t mnl_attr_get_type(const struct nlattr *attr);
extern uint16_t mnl_attr_get_len(const struct nlattr *attr);
extern uint16_t mnl_attr_get_payload_len(const struct nlattr *attr);
extern void *mnl_attr_get_payload(const struct nlattr *attr);
extern uint8_t mnl_attr_get_u8(const struct nlattr *attr);
extern uint16_t mnl_attr_get_u16(const struct nlattr *attr);
extern uint32_t mnl_attr_get_u32(const struct nlattr *attr);
extern uint64_t mnl_attr_get_u64(const struct nlattr *attr);
extern const char *mnl_attr_get_str(const struct nlattr *attr);
/* TLV attribute putters */
extern void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data);
extern void mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type, uint8_t data);
extern void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data);
extern void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data);
extern void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data);
extern void mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data);
extern void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data);
/* TLV attribute putters with buffer boundary checkings */
extern bool mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, size_t len, const void *data);
extern bool mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint8_t data);
extern bool mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint16_t data);
extern bool mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint32_t data);
extern bool mnl_attr_put_u64_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint64_t data);
extern bool mnl_attr_put_str_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data);
extern bool mnl_attr_put_strz_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data);
/* TLV attribute nesting */
extern struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type);
extern struct nlattr *mnl_attr_nest_start_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type);
extern void mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start);
extern void mnl_attr_nest_cancel(struct nlmsghdr *nlh, struct nlattr *start);
/* TLV validation */
extern int mnl_attr_type_valid(const struct nlattr *attr, uint16_t maxtype);
enum mnl_attr_data_type {
MNL_TYPE_UNSPEC,
MNL_TYPE_U8,
MNL_TYPE_U16,
MNL_TYPE_U32,
MNL_TYPE_U64,
MNL_TYPE_STRING,
MNL_TYPE_FLAG,
MNL_TYPE_MSECS,
MNL_TYPE_NESTED,
MNL_TYPE_NESTED_COMPAT,
MNL_TYPE_NUL_STRING,
MNL_TYPE_BINARY,
MNL_TYPE_MAX,
};
extern int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type);
extern int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t len);
/* TLV iterators */
extern bool mnl_attr_ok(const struct nlattr *attr, int len);
extern struct nlattr *mnl_attr_next(const struct nlattr *attr);
#define mnl_attr_for_each(attr, nlh, offset) \
for ((attr) = mnl_nlmsg_get_payload_offset((nlh), (offset)); \
mnl_attr_ok((attr), (char *)mnl_nlmsg_get_payload_tail(nlh) - (char *)(attr)); \
(attr) = mnl_attr_next(attr))
#define mnl_attr_for_each_nested(attr, nest) \
for ((attr) = mnl_attr_get_payload(nest); \
mnl_attr_ok((attr), (char *)mnl_attr_get_payload(nest) + mnl_attr_get_payload_len(nest) - (char *)(attr)); \
(attr) = mnl_attr_next(attr))
#define mnl_attr_for_each_payload(payload, payload_size) \
for ((attr) = (payload); \
mnl_attr_ok((attr), (char *)(payload) + payload_size - (char *)(attr)); \
(attr) = mnl_attr_next(attr))
/* TLV callback-based attribute parsers */
typedef int (*mnl_attr_cb_t)(const struct nlattr *attr, void *data);
extern int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data);
extern int mnl_attr_parse_nested(const struct nlattr *attr, mnl_attr_cb_t cb, void *data);
extern int mnl_attr_parse_payload(const void *payload, size_t payload_len, mnl_attr_cb_t cb, void *data);
/*
* callback API
*/
#define MNL_CB_ERROR -1
#define MNL_CB_STOP 0
#define MNL_CB_OK 1
typedef int (*mnl_cb_t)(const struct nlmsghdr *nlh, void *data);
extern int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq,
unsigned int portid, mnl_cb_t cb_data, void *data);
extern int mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq,
unsigned int portid, mnl_cb_t cb_data, void *data,
const mnl_cb_t *cb_ctl_array,
unsigned int cb_ctl_array_len);
/*
* other declarations
*/
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
#ifndef MNL_ARRAY_SIZE
#define MNL_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@ -1,556 +0,0 @@
/*
* (C) 2008-2010 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include "libmnl.h"
/**
* \defgroup nlmsg Netlink message helpers
*
* Netlink message:
* \verbatim
|<----------------- 4 bytes ------------------->|
|<----- 2 bytes ------>|<------- 2 bytes ------>|
|-----------------------------------------------|
| Message length (including header) |
|-----------------------------------------------|
| Message type | Message flags |
|-----------------------------------------------|
| Message sequence number |
|-----------------------------------------------|
| Netlink PortID |
|-----------------------------------------------|
| |
. Payload .
|_______________________________________________|
\endverbatim
*
* There is usually an extra header after the the Netlink header (at the
* beginning of the payload). This extra header is specific of the Netlink
* subsystem. After this extra header, it comes the sequence of attributes
* that are expressed in Type-Length-Value (TLV) format.
*
* @{
*/
/**
* mnl_nlmsg_size - calculate the size of Netlink message (without alignment)
* \param len length of the Netlink payload
*
* This function returns the size of a netlink message (header plus payload)
* without alignment.
*/
size_t mnl_nlmsg_size(size_t len)
{
return len + MNL_NLMSG_HDRLEN;
}
/**
* mnl_nlmsg_get_payload_len - get the length of the Netlink payload
* \param nlh pointer to the header of the Netlink message
*
* This function returns the Length of the netlink payload, ie. the length
* of the full message minus the size of the Netlink header.
*/
size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh)
{
return nlh->nlmsg_len - MNL_NLMSG_HDRLEN;
}
/**
* mnl_nlmsg_put_header - reserve and prepare room for Netlink header
* \param buf memory already allocated to store the Netlink header
*
* This function sets to zero the room that is required to put the Netlink
* header in the memory buffer passed as parameter. This function also
* initializes the nlmsg_len field to the size of the Netlink header. This
* function returns a pointer to the Netlink header structure.
*/
struct nlmsghdr *mnl_nlmsg_put_header(void *buf)
{
int len = MNL_ALIGN(sizeof(struct nlmsghdr));
struct nlmsghdr *nlh = buf;
memset(buf, 0, len);
nlh->nlmsg_len = len;
return nlh;
}
/**
* mnl_nlmsg_put_extra_header - reserve and prepare room for an extra header
* \param nlh pointer to Netlink header
* \param size size of the extra header that we want to put
*
* This function sets to zero the room that is required to put the extra
* header after the initial Netlink header. This function also increases
* the nlmsg_len field. You have to invoke mnl_nlmsg_put_header() before
* you call this function. This function returns a pointer to the extra
* header.
*/
void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh,
size_t size)
{
char *ptr = (char *)nlh + nlh->nlmsg_len;
size_t len = MNL_ALIGN(size);
nlh->nlmsg_len += len;
memset(ptr, 0, len);
return ptr;
}
/**
* mnl_nlmsg_get_payload - get a pointer to the payload of the netlink message
* \param nlh pointer to a netlink header
*
* This function returns a pointer to the payload of the netlink message.
*/
void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh)
{
return (void *)nlh + MNL_NLMSG_HDRLEN;
}
/**
* mnl_nlmsg_get_payload_offset - get a pointer to the payload of the message
* \param nlh pointer to a netlink header
* \param offset offset to the payload of the attributes TLV set
*
* This function returns a pointer to the payload of the netlink message plus
* a given offset.
*/
void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh,
size_t offset)
{
return (void *)nlh + MNL_NLMSG_HDRLEN + MNL_ALIGN(offset);
}
/**
* mnl_nlmsg_ok - check a there is room for netlink message
* \param nlh netlink message that we want to check
* \param len remaining bytes in a buffer that contains the netlink message
*
* This function is used to check that a buffer that contains a netlink
* message has enough room for the netlink message that it stores, ie. this
* function can be used to verify that a netlink message is not malformed nor
* truncated.
*
* This function does not set errno in case of error since it is intended
* for iterations. Thus, it returns true on success and false on error.
*
* The len parameter may become negative in malformed messages during message
* iteration, that is why we use a signed integer.
*/
bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len)
{
return len >= (int)sizeof(struct nlmsghdr) &&
nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
(int)nlh->nlmsg_len <= len;
}
/**
* mnl_nlmsg_next - get the next netlink message in a multipart message
* \param nlh current netlink message that we are handling
* \param len length of the remaining bytes in the buffer (passed by reference).
*
* This function returns a pointer to the next netlink message that is part
* of a multi-part netlink message. Netlink can batch several messages into
* one buffer so that the receiver has to iterate over the whole set of
* Netlink messages.
*
* You have to use mnl_nlmsg_ok() to check if the next Netlink message is
* valid.
*/
struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh,
int *len)
{
*len -= MNL_ALIGN(nlh->nlmsg_len);
return (struct nlmsghdr *)((void *)nlh + MNL_ALIGN(nlh->nlmsg_len));
}
/**
* mnl_nlmsg_get_payload_tail - get the ending of the netlink message
* \param nlh pointer to netlink message
*
* This function returns a pointer to the netlink message tail. This is useful
* to build a message since we continue adding attributes at the end of the
* message.
*/
void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh)
{
return (void *)nlh + MNL_ALIGN(nlh->nlmsg_len);
}
/**
* mnl_nlmsg_seq_ok - perform sequence tracking
* \param nlh current netlink message that we are handling
* \param seq last sequence number used to send a message
*
* This functions returns true if the sequence tracking is fulfilled, otherwise
* false is returned. We skip the tracking for netlink messages whose sequence
* number is zero since it is usually reserved for event-based kernel
* notifications. On the other hand, if seq is set but the message sequence
* number is not set (i.e. this is an event message coming from kernel-space),
* then we also skip the tracking. This approach is good if we use the same
* socket to send commands to kernel-space (that we want to track) and to
* listen to events (that we do not track).
*/
bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh,
unsigned int seq)
{
return nlh->nlmsg_seq && seq ? nlh->nlmsg_seq == seq : true;
}
/**
* mnl_nlmsg_portid_ok - perform portID origin check
* \param nlh current netlink message that we are handling
* \param portid netlink portid that we want to check
*
* This functions returns true if the origin is fulfilled, otherwise
* false is returned. We skip the tracking for netlink message whose portID
* is zero since it is reserved for event-based kernel notifications. On the
* other hand, if portid is set but the message PortID is not (i.e. this
* is an event message coming from kernel-space), then we also skip the
* tracking. This approach is good if we use the same socket to send commands
* to kernel-space (that we want to track) and to listen to events (that we
* do not track).
*/
bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh,
unsigned int portid)
{
return nlh->nlmsg_pid && portid ? nlh->nlmsg_pid == portid : true;
}
static void mnl_nlmsg_fprintf_header(FILE *fd, const struct nlmsghdr *nlh)
{
fprintf(fd, "----------------\t------------------\n");
fprintf(fd, "| %.010u |\t| message length |\n", nlh->nlmsg_len);
fprintf(fd, "| %.05u | %c%c%c%c |\t| type | flags |\n",
nlh->nlmsg_type,
nlh->nlmsg_flags & NLM_F_REQUEST ? 'R' : '-',
nlh->nlmsg_flags & NLM_F_MULTI ? 'M' : '-',
nlh->nlmsg_flags & NLM_F_ACK ? 'A' : '-',
nlh->nlmsg_flags & NLM_F_ECHO ? 'E' : '-');
fprintf(fd, "| %.010u |\t| sequence number|\n", nlh->nlmsg_seq);
fprintf(fd, "| %.010u |\t| port ID |\n", nlh->nlmsg_pid);
fprintf(fd, "----------------\t------------------\n");
}
static void mnl_nlmsg_fprintf_payload(FILE *fd, const struct nlmsghdr *nlh,
size_t extra_header_size)
{
int rem = 0;
unsigned int i;
for (i=sizeof(struct nlmsghdr); i<nlh->nlmsg_len; i+=4) {
char *b = (char *) nlh;
struct nlattr *attr = (struct nlattr *) (b+i);
/* netlink control message. */
if (nlh->nlmsg_type < NLMSG_MIN_TYPE) {
fprintf(fd, "| %.2x %.2x %.2x %.2x |\t",
0xff & b[i], 0xff & b[i+1],
0xff & b[i+2], 0xff & b[i+3]);
fprintf(fd, "| |\n");
/* special handling for the extra header. */
} else if (extra_header_size > 0) {
extra_header_size -= 4;
fprintf(fd, "| %.2x %.2x %.2x %.2x |\t",
0xff & b[i], 0xff & b[i+1],
0xff & b[i+2], 0xff & b[i+3]);
fprintf(fd, "| extra header |\n");
/* this seems like an attribute header. */
} else if (rem == 0 && (attr->nla_type & NLA_TYPE_MASK) != 0) {
fprintf(fd, "|%c[%d;%dm"
"%.5u"
"%c[%dm"
"|"
"%c[%d;%dm"
"%c%c"
"%c[%dm"
"|"
"%c[%d;%dm"
"%.5u"
"%c[%dm|\t",
27, 1, 31,
attr->nla_len,
27, 0,
27, 1, 32,
attr->nla_type & NLA_F_NESTED ? 'N' : '-',
attr->nla_type &
NLA_F_NET_BYTEORDER ? 'B' : '-',
27, 0,
27, 1, 34,
attr->nla_type & NLA_TYPE_MASK,
27, 0);
fprintf(fd, "|len |flags| type|\n");
if (!(attr->nla_type & NLA_F_NESTED)) {
rem = NLA_ALIGN(attr->nla_len) -
sizeof(struct nlattr);
}
/* this is the attribute payload. */
} else if (rem > 0) {
rem -= 4;
fprintf(fd, "| %.2x %.2x %.2x %.2x |\t",
0xff & b[i], 0xff & b[i+1],
0xff & b[i+2], 0xff & b[i+3]);
fprintf(fd, "| data |");
fprintf(fd, "\t %c %c %c %c\n",
isprint(b[i]) ? b[i] : ' ',
isprint(b[i+1]) ? b[i+1] : ' ',
isprint(b[i+2]) ? b[i+2] : ' ',
isprint(b[i+3]) ? b[i+3] : ' ');
}
}
fprintf(fd, "----------------\t------------------\n");
}
/**
* mnl_nlmsg_fprintf - print netlink message to file
* \param fd pointer to file type
* \param data pointer to the buffer that contains messages to be printed
* \param datalen length of data stored in the buffer
* \param extra_header_size size of the extra header (if any)
*
* This function prints the netlink header to a file handle.
* It may be useful for debugging purposes. One example of the output
* is the following:
*
*\verbatim
---------------- ------------------
| 0000000040 | | message length |
| 00016 | R-A- | | type | flags |
| 1289148991 | | sequence number|
| 0000000000 | | port ID |
---------------- ------------------
| 00 00 00 00 | | extra header |
| 00 00 00 00 | | extra header |
| 01 00 00 00 | | extra header |
| 01 00 00 00 | | extra header |
|00008|--|00003| |len |flags| type|
| 65 74 68 30 | | data | e t h 0
---------------- ------------------
\endverbatim
*
* This example above shows the netlink message that is send to kernel-space
* to set up the link interface eth0. The netlink and attribute header data
* are displayed in base 10 whereas the extra header and the attribute payload
* are expressed in base 16. The possible flags in the netlink header are:
*
* - R, that indicates that NLM_F_REQUEST is set.
* - M, that indicates that NLM_F_MULTI is set.
* - A, that indicates that NLM_F_ACK is set.
* - E, that indicates that NLM_F_ECHO is set.
*
* The lack of one flag is displayed with '-'. On the other hand, the possible
* attribute flags available are:
*
* - N, that indicates that NLA_F_NESTED is set.
* - B, that indicates that NLA_F_NET_BYTEORDER is set.
*/
void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen,
size_t extra_header_size)
{
const struct nlmsghdr *nlh = data;
int len = datalen;
while (mnl_nlmsg_ok(nlh, len)) {
mnl_nlmsg_fprintf_header(fd, nlh);
mnl_nlmsg_fprintf_payload(fd, nlh, extra_header_size);
nlh = mnl_nlmsg_next(nlh, &len);
}
}
/**
* @}
*/
/**
* \defgroup batch Netlink message batch helpers
*
* This library provides helpers to batch several messages into one single
* datagram. These helpers do not perform strict memory boundary checkings.
*
* The following figure represents a Netlink message batch:
*
* |<-------------- MNL_SOCKET_BUFFER_SIZE ------------->|
* |<-------------------- batch ------------------>| |
* |-----------|-----------|-----------|-----------|-----------|
* |<- nlmsg ->|<- nlmsg ->|<- nlmsg ->|<- nlmsg ->|<- nlmsg ->|
* |-----------|-----------|-----------|-----------|-----------|
* ^ ^
* | |
* message N message N+1
*
* To start the batch, you have to call mnl_nlmsg_batch_start() and you can
* use mnl_nlmsg_batch_stop() to release it.
*
* You have to invoke mnl_nlmsg_batch_next() to get room for a new message
* in the batch. If this function returns NULL, it means that the last
* message that was added (message N+1 in the figure above) does not fit the
* batch. Thus, you have to send the batch (which includes until message N)
* and, then, you have to call mnl_nlmsg_batch_reset() to re-initialize
* the batch (this moves message N+1 to the head of the buffer). For that
* reason, the buffer that you have to use to store the batch must be double
* of MNL_SOCKET_BUFFER_SIZE to ensure that the last message (message N+1)
* that did not fit into the batch is written inside valid memory boundaries.
*
* @{
*/
struct mnl_nlmsg_batch {
/* the buffer that is used to store the batch. */
void *buf;
size_t limit;
size_t buflen;
/* the current netlink message in the batch. */
void *cur;
bool overflow;
};
/**
* mnl_nlmsg_batch_start - initialize a batch
* \param buf pointer to the buffer that will store this batch
* \param limit maximum size of the batch (should be MNL_SOCKET_BUFFER_SIZE).
*
* The buffer that you pass must be double of MNL_SOCKET_BUFFER_SIZE. The
* limit must be half of the buffer size, otherwise expect funny memory
* corruptions 8-).
*
* You can allocate the buffer that you use to store the batch in the stack or
* the heap, no restrictions in this regard. This function returns NULL on
* error.
*/
struct mnl_nlmsg_batch *mnl_nlmsg_batch_start(void *buf,
size_t limit)
{
struct mnl_nlmsg_batch *b;
b = malloc(sizeof(struct mnl_nlmsg_batch));
if (b == NULL)
return NULL;
b->buf = buf;
b->limit = limit;
b->buflen = 0;
b->cur = buf;
b->overflow = false;
return b;
}
/**
* mnl_nlmsg_batch_stop - release a batch
* \param b pointer to batch
*
* This function releases the batch allocated by mnl_nlmsg_batch_start().
*/
void mnl_nlmsg_batch_stop(struct mnl_nlmsg_batch *b)
{
free(b);
}
/**
* mnl_nlmsg_batch_next - get room for the next message in the batch
* \param b pointer to batch
*
* This function returns false if the last message did not fit into the
* batch. Otherwise, it prepares the batch to provide room for the new
* Netlink message in the batch and returns true.
*
* You have to put at least one message in the batch before calling this
* function, otherwise your application is likely to crash.
*/
bool mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b)
{
struct nlmsghdr *nlh = b->cur;
if (b->buflen + nlh->nlmsg_len > b->limit) {
b->overflow = true;
return false;
}
b->cur = b->buf + b->buflen + nlh->nlmsg_len;
b->buflen += nlh->nlmsg_len;
return true;
}
/**
* mnl_nlmsg_batch_reset - reset the batch
* \param b pointer to batch
*
* This function allows to reset a batch, so you can reuse it to create a
* new one. This function moves the last message which does not fit the
* batch to the head of the buffer, if any.
*/
void mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b)
{
if (b->overflow) {
struct nlmsghdr *nlh = b->cur;
memcpy(b->buf, b->cur, nlh->nlmsg_len);
b->buflen = nlh->nlmsg_len;
b->cur = b->buf + b->buflen;
b->overflow = false;
} else {
b->buflen = 0;
b->cur = b->buf;
}
}
/**
* mnl_nlmsg_batch_size - get current size of the batch
* \param b pointer to batch
*
* This function returns the current size of the batch.
*/
size_t mnl_nlmsg_batch_size(struct mnl_nlmsg_batch *b)
{
return b->buflen;
}
/**
* mnl_nlmsg_batch_head - get head of this batch
* \param b pointer to batch
*
* This function returns a pointer to the head of the batch, which is the
* beginning of the buffer that is used.
*/
void *mnl_nlmsg_batch_head(struct mnl_nlmsg_batch *b)
{
return b->buf;
}
/**
* mnl_nlmsg_batch_current - returns current position in the batch
* \param b pointer to batch
*
* This function returns a pointer to the current position in the buffer
* that is used to store the batch.
*/
void *mnl_nlmsg_batch_current(struct mnl_nlmsg_batch *b)
{
return b->cur;
}
/**
* mnl_nlmsg_batch_is_empty - check if there is any message in the batch
* \param b pointer to batch
*
* This function returns true if the batch is empty.
*/
bool mnl_nlmsg_batch_is_empty(struct mnl_nlmsg_batch *b)
{
return b->buflen == 0;
}
/**
* @}
*/

View File

@ -1,351 +0,0 @@
/*
* (C) 2008-2010 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include "libmnl.h"
/**
* \mainpage
*
* libmnl is a minimalistic user-space library oriented to Netlink developers.
* There are a lot of common tasks in parsing, validating, constructing of
* both the Netlink header and TLVs that are repetitive and easy to get wrong.
* This library aims to provide simple helpers that allows you to avoid
* re-inventing the wheel in common Netlink tasks.
*
* \verbatim
"Simplify, simplify" -- Henry David Thoureau. Walden (1854)
\endverbatim
*
* The acronym libmnl stands for LIBrary Minimalistic NetLink.
*
* libmnl homepage is:
* http://www.netfilter.org/projects/libmnl/
*
* \section features Main Features
* - Small: the shared library requires around 30KB for an x86-based computer.
* - Simple: this library avoids complex abstractions that tend to hide Netlink
* details. It avoids elaborated object-oriented infrastructure and complex
* callback-based workflow.
* - Easy to use: the library simplifies the work for Netlink-wise developers.
* It provides functions to make socket handling, message building,
* validating, parsing and sequence tracking, easier.
* - Easy to re-use: you can use this library to build your own abstraction
* layer upon this library, if you want to provide another library that
* hides Netlink details to your users.
* - Decoupling: the interdependency of the main bricks that compose this
* library is reduced, i.e. the library provides many helpers, but the
* programmer is not forced to use them.
*
* \section licensing Licensing terms
* This library is released under the LGPLv2.1 or any later (at your option).
*
* \section Dependencies
* You have to install the Linux kernel headers that you want to use to develop
* your application. Moreover, this library requires that you have some basics
* on Netlink.
*
* \section scm Git Tree
* The current development version of libmnl can be accessed at:
* http://git.netfilter.org/cgi-bin/gitweb.cgi?p=libmnl.git;a=summary
*
* \section using Using libmnl
* You can access several example files under examples/ in the libmnl source
* code tree.
*/
struct mnl_socket {
int fd;
struct sockaddr_nl addr;
};
/**
* \defgroup socket Netlink socket helpers
* @{
*/
/**
* mnl_socket_get_fd - obtain file descriptor from netlink socket
* \param nl netlink socket obtained via mnl_socket_open()
*
* This function returns the file descriptor of a given netlink socket.
*/
int mnl_socket_get_fd(const struct mnl_socket *nl)
{
return nl->fd;
}
/**
* mnl_socket_get_portid - obtain Netlink PortID from netlink socket
* \param nl netlink socket obtained via mnl_socket_open()
*
* This function returns the Netlink PortID of a given netlink socket.
* It's a common mistake to assume that this PortID equals the process ID
* which is not always true. This is the case if you open more than one
* socket that is binded to the same Netlink subsystem from the same process.
*/
unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
{
return nl->addr.nl_pid;
}
static struct mnl_socket *__mnl_socket_open(int bus, int flags)
{
struct mnl_socket *nl;
nl = calloc(1, sizeof(struct mnl_socket));
if (nl == NULL)
return NULL;
nl->fd = socket(AF_NETLINK, SOCK_RAW | flags, bus);
if (nl->fd == -1) {
free(nl);
return NULL;
}
return nl;
}
/**
* mnl_socket_open - open a netlink socket
* \param bus the netlink socket bus ID (see NETLINK_* constants)
*
* On error, it returns NULL and errno is appropriately set. Otherwise, it
* returns a valid pointer to the mnl_socket structure.
*/
struct mnl_socket *mnl_socket_open(int bus)
{
return __mnl_socket_open(bus, 0);
}
/**
* mnl_socket_open2 - open a netlink socket with appropriate flags
* \param bus the netlink socket bus ID (see NETLINK_* constants)
* \param flags the netlink socket flags (see SOCK_* constants in socket(2))
*
* This is similar to mnl_socket_open(), but allows to set flags like
* SOCK_CLOEXEC at socket creation time (useful for multi-threaded programs
* performing exec calls).
*
* On error, it returns NULL and errno is appropriately set. Otherwise, it
* returns a valid pointer to the mnl_socket structure.
*/
struct mnl_socket *mnl_socket_open2(int bus, int flags)
{
return __mnl_socket_open(bus, flags);
}
/**
* mnl_socket_fdopen - associates a mnl_socket object with pre-existing socket.
* \param fd pre-existing socket descriptor.
*
* On error, it returns NULL and errno is appropriately set. Otherwise, it
* returns a valid pointer to the mnl_socket structure. It also sets the portID
* if the socket fd is already bound and it is AF_NETLINK.
*
* Note that mnl_socket_get_portid() returns 0 if this function is used with
* non-netlink socket.
*/
struct mnl_socket *mnl_socket_fdopen(int fd)
{
int ret;
struct mnl_socket *nl;
struct sockaddr_nl addr;
socklen_t addr_len = sizeof(struct sockaddr_nl);
ret = getsockname(fd, (struct sockaddr *) &addr, &addr_len);
if (ret == -1)
return NULL;
nl = calloc(1, sizeof(struct mnl_socket));
if (nl == NULL)
return NULL;
nl->fd = fd;
if (addr.nl_family == AF_NETLINK)
nl->addr = addr;
return nl;
}
/**
* mnl_socket_bind - bind netlink socket
* \param nl netlink socket obtained via mnl_socket_open()
* \param groups the group of message you're interested in
* \param pid the port ID you want to use (use zero for automatic selection)
*
* On error, this function returns -1 and errno is appropriately set. On
* success, 0 is returned. You can use MNL_SOCKET_AUTOPID which is 0 for
* automatic port ID selection.
*/
int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups,
pid_t pid)
{
int ret;
socklen_t addr_len;
nl->addr.nl_family = AF_NETLINK;
nl->addr.nl_groups = groups;
nl->addr.nl_pid = pid;
ret = bind(nl->fd, (struct sockaddr *) &nl->addr, sizeof (nl->addr));
if (ret < 0)
return ret;
addr_len = sizeof(nl->addr);
ret = getsockname(nl->fd, (struct sockaddr *) &nl->addr, &addr_len);
if (ret < 0)
return ret;
if (addr_len != sizeof(nl->addr)) {
errno = EINVAL;
return -1;
}
if (nl->addr.nl_family != AF_NETLINK) {
errno = EINVAL;
return -1;
}
return 0;
}
/**
* mnl_socket_sendto - send a netlink message of a certain size
* \param nl netlink socket obtained via mnl_socket_open()
* \param buf buffer containing the netlink message to be sent
* \param len number of bytes in the buffer that you want to send
*
* On error, it returns -1 and errno is appropriately set. Otherwise, it
* returns the number of bytes sent.
*/
ssize_t mnl_socket_sendto(const struct mnl_socket *nl,
const void *buf, size_t len)
{
static const struct sockaddr_nl snl = {
.nl_family = AF_NETLINK
};
return sendto(nl->fd, buf, len, 0,
(struct sockaddr *) &snl, sizeof(snl));
}
/**
* mnl_socket_recvfrom - receive a netlink message
* \param nl netlink socket obtained via mnl_socket_open()
* \param buf buffer that you want to use to store the netlink message
* \param bufsiz size of the buffer passed to store the netlink message
*
* On error, it returns -1 and errno is appropriately set. If errno is set
* to ENOSPC, it means that the buffer that you have passed to store the
* netlink message is too small, so you have received a truncated message.
* To avoid this, you have to allocate a buffer of MNL_SOCKET_BUFFER_SIZE
* (which is 8KB, see linux/netlink.h for more information). Using this
* buffer size ensures that your buffer is big enough to store the netlink
* message without truncating it.
*/
ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl,
void *buf, size_t bufsiz)
{
ssize_t ret;
struct sockaddr_nl addr;
struct iovec iov = {
.iov_base = buf,
.iov_len = bufsiz,
};
struct msghdr msg = {
.msg_name = &addr,
.msg_namelen = sizeof(struct sockaddr_nl),
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = NULL,
.msg_controllen = 0,
.msg_flags = 0,
};
ret = recvmsg(nl->fd, &msg, 0);
if (ret == -1)
return ret;
if (msg.msg_flags & MSG_TRUNC) {
errno = ENOSPC;
return -1;
}
if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
errno = EINVAL;
return -1;
}
return ret;
}
/**
* mnl_socket_close - close a given netlink socket
* \param nl netlink socket obtained via mnl_socket_open()
*
* On error, this function returns -1 and errno is appropriately set.
* On success, it returns 0.
*/
int mnl_socket_close(struct mnl_socket *nl)
{
int ret = close(nl->fd);
free(nl);
return ret;
}
/**
* mnl_socket_setsockopt - set Netlink socket option
* \param nl netlink socket obtained via mnl_socket_open()
* \param type type of Netlink socket options
* \param buf the buffer that contains the data about this option
* \param len the size of the buffer passed
*
* This function allows you to set some Netlink socket option. As of writing
* this (see linux/netlink.h), the existing options are:
*
* - \#define NETLINK_ADD_MEMBERSHIP 1
* - \#define NETLINK_DROP_MEMBERSHIP 2
* - \#define NETLINK_PKTINFO 3
* - \#define NETLINK_BROADCAST_ERROR 4
* - \#define NETLINK_NO_ENOBUFS 5
*
* In the early days, Netlink only supported 32 groups expressed in a
* 32-bits mask. However, since 2.6.14, Netlink may have up to 2^32 multicast
* groups but you have to use setsockopt() with NETLINK_ADD_MEMBERSHIP to
* join a given multicast group. This function internally calls setsockopt()
* to join a given netlink multicast group. You can still use mnl_bind()
* and the 32-bit mask to join a set of Netlink multicast groups.
*
* On error, this function returns -1 and errno is appropriately set.
*/
int mnl_socket_setsockopt(const struct mnl_socket *nl, int type,
void *buf, socklen_t len)
{
return setsockopt(nl->fd, SOL_NETLINK, type, buf, len);
}
/**
* mnl_socket_getsockopt - get a Netlink socket option
* \param nl netlink socket obtained via mnl_socket_open()
* \param type type of Netlink socket options
* \param buf pointer to the buffer to store the value of this option
* \param len size of the information written in the buffer
*
* On error, this function returns -1 and errno is appropriately set.
*/
int mnl_socket_getsockopt(const struct mnl_socket *nl, int type,
void *buf, socklen_t *len)
{
return getsockopt(nl->fd, SOL_NETLINK, type, buf, len);
}
/**
* @}
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,67 +0,0 @@
[Setting]
qmap_num=4
[profile1]
apn=1234567890
user=qwertyuio
password=asdfghjkl
auth=2
ipfamily=1
pin=
[profile2]
apn=ctnet
user=
password=
auth=0
ipfamily=1
pin=
[profile3]
apn=ctnet
user=
password=
auth=0
ipfamily=1
pin=
[profile4]
apn=ctnet
user=
password=
auth=0
ipfamily=1
pin=
[profile5]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
[profile6]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
[profile7]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
[profile8]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=

View File

@ -1,438 +0,0 @@
#include "QMIThread.h"
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
#include <net/if.h>
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
static size_t fibo_fread(const char *filename, void *buf, size_t size)
{
FILE *fp = fopen(filename, "r");
size_t n = 0;
memset(buf, 0x00, size);
if (fp) {
n = fread(buf, 1, size, fp);
if (n <= 0 || n == size) {
dbg_time(
"warnning: fail to fread(%s), fread=%zd, buf_size=%zd, "
"errno: %d (%s)",
__func__, filename, n, size, errno, strerror(errno));
}
fclose(fp);
}
return n > 0 ? n : 0;
}
static size_t fibo_fwrite(const char *filename, const void *buf, size_t size)
{
FILE *fp = fopen(filename, "w");
size_t n = 0;
if (fp) {
n = fwrite(buf, 1, size, fp);
if (n != size) {
dbg_time(
"warnning: fail to fwrite(%s), fwrite=%zd, buf_size=%zd, "
"errno: %d (%s)",
__func__, filename, n, size, errno, strerror(errno));
}
fclose(fp);
}
return n > 0 ? n : 0;
}
static int fibo_iface_is_in_bridge(const char *iface)
{
char filename[256];
snprintf(filename, sizeof(filename), "/sys/class/net/%s/brport", iface);
return (access(filename, F_OK) == 0 || errno != ENOENT);
}
int fibo_bridge_mode_detect(PROFILE_T *profile)
{
const char *ifname = profile->qmapnet_adapter ? profile->qmapnet_adapter
: profile->usbnet_adapter;
const char *driver;
char bridge_mode[128];
char bridge_ipv4[128];
char ipv4[128];
char buf[64];
size_t n;
int in_bridge;
driver = profile->driver_name;
snprintf(bridge_mode, sizeof(bridge_mode), "/sys/class/net/%s/bridge_mode",
ifname);
snprintf(bridge_ipv4, sizeof(bridge_ipv4), "/sys/class/net/%s/bridge_ipv4",
ifname);
if (access(bridge_mode, F_OK) && errno == ENOENT) {
snprintf(bridge_mode, sizeof(bridge_mode),
"/sys/module/%s/parameters/bridge_mode", driver);
snprintf(bridge_ipv4, sizeof(bridge_ipv4),
"/sys/module/%s/parameters/bridge_ipv4", driver);
if (access(bridge_mode, F_OK) && errno == ENOENT) {
bridge_mode[0] = '\0';
}
}
in_bridge = fibo_iface_is_in_bridge(ifname);
if (in_bridge) {
dbg_time("notice: iface %s had add to bridge\n", ifname);
}
if (in_bridge && bridge_mode[0] == '\0') {
dbg_time("warnning: can not find bride_mode file for %s\n", ifname);
return 1;
}
n = fibo_fread(bridge_mode, buf, sizeof(buf));
if (in_bridge) {
if (n <= 0 || buf[0] == '0') {
dbg_time("warnning: should set 1 to bride_mode file for %s\n",
ifname);
return 1;
}
} else {
if (n <= 0 || buf[0] == '0') {
return 0;
}
}
memset(ipv4, 0, sizeof(ipv4));
if (strstr(bridge_ipv4, "/sys/class/net/") || profile->qmap_mode == 0 ||
profile->qmap_mode == 1) {
snprintf(ipv4, sizeof(ipv4), "0x%x", profile->ipv4.Address);
dbg_time("echo '%s' > %s", ipv4, bridge_ipv4);
fibo_fwrite(bridge_ipv4, ipv4, strlen(ipv4));
} else {
snprintf(ipv4, sizeof(ipv4), "0x%x:%d", profile->ipv4.Address,
profile->muxid);
dbg_time("echo '%s' > %s", ipv4, bridge_ipv4);
fibo_fwrite(bridge_ipv4, ipv4, strlen(ipv4));
}
return 1;
}
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
void fibo_get_driver_info(PROFILE_T *profile, RMNET_INFO *rmnet_info) {
int ifc_ctl_sock;
struct ifreq ifr;
int rc;
int request = 0x89F3;
unsigned char data[512];
memset(rmnet_info, 0x00, sizeof(*rmnet_info));
ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
if (ifc_ctl_sock <= 0) {
dbg_time("socket() failed: %s\n", strerror(errno));
return;
}
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, profile->usbnet_adapter, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ - 1] = 0;
ifr.ifr_ifru.ifru_data = (void *)data;
rc = ioctl(ifc_ctl_sock, request, &ifr);
if (rc < 0) {
dbg_time("ioctl(0x%x, qmap_settings) failed: %s, rc=%d", request, strerror(errno), rc);
}
else {
memcpy(rmnet_info, data, sizeof(*rmnet_info));
}
close(ifc_ctl_sock);
}
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
int fibo_qmap_mode_detect(PROFILE_T *profile)
{
int n;
char buf[128];
char qmap_netcard[128];
struct {
char filename[255 * 2];
char linkname[255 * 2];
} * pl;
pl = (typeof(pl))malloc(sizeof(*pl));
snprintf(pl->linkname, sizeof(pl->linkname),
"/sys/class/net/%s/device/driver", profile->usbnet_adapter);
n = readlink(pl->linkname, pl->filename, sizeof(pl->filename));
pl->filename[n] = '\0';
while (pl->filename[n] != '/') n--;
profile->driver_name = strdup(&pl->filename[n + 1]);
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
fibo_get_driver_info(profile, &profile->rmnet_info);
if (profile->rmnet_info.size) {
profile->qmap_mode = profile->rmnet_info.qmap_mode;
if (profile->qmap_mode) {
int offset_id = profile->pdp - 1;
if (profile->qmap_mode == 1)
offset_id = 0;
profile->muxid = profile->rmnet_info.mux_id[offset_id];
profile->qmapnet_adapter = strdup( profile->rmnet_info.ifname[offset_id]);
profile->qmap_size = profile->rmnet_info.rx_urb_size;
profile->qmap_version = profile->rmnet_info.qmap_version;
}
goto _out;
}
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
if (qmidev_is_pciemhi(profile->qmichannel)) {
profile->qmap_mode = 1;
if (profile->muxid == 0 || profile->muxid == 0x81)
{
profile->muxid = 0x81;
}
else
{
if (profile->muxid < 0x80)
profile->muxid += 0x81;
profile->qmap_mode = 2;
}
profile->qmapnet_adapter = strdup(profile->usbnet_adapter);
goto _final_process;
}
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_num",
profile->usbnet_adapter);
//2021-01-27 willa.liu@fibocom.com changed begin for support mantis 0068849
if (access(pl->filename, F_OK) == 0) {
dbg_time("access %s", pl->filename);
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno,
strerror(errno));
goto _out;
}
//2021-02-01 willa.liu@fibocom.com changed begin for support mantis 0069837
/*
snprintf(pl->filename, sizeof(pl->filename),
"/sys/module/%s/parameters/qmap_num", profile->driver_name);
if (access(pl->filename, R_OK)) {
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename,
errno, strerror(errno));
goto _out;
}
snprintf(
pl->filename, sizeof(pl->filename),
"/sys/class/net/%s/device/driver/module/parameters/qmap_num",
profile->usbnet_adapter);
if (access(pl->filename, R_OK)) {
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename,
errno, strerror(errno));
goto _out;
}
}
}
*/
//2021-02-01 willa.liu@fibocom.com changed end for support mantis 0069837
}
else
{
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_mode",
profile->usbnet_adapter);
if (access(pl->filename, F_OK) == 0) {
dbg_time("access %s", pl->filename);
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno,
strerror(errno));
goto _out;
}
}
}
if(!access(pl->filename, R_OK))
{
n = fibo_fread(pl->filename, buf, sizeof(buf));
if(n > 0)
{
profile->qmap_mode = atoi(buf);
if(profile->qmap_mode >= 1 && qmidev_is_pciemhi(profile->qmichannel))
{
profile->muxid =
profile->pdp + 0x80;
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if(qmidev_is_gobinet(profile->qmichannel) || qmidev_is_qmiwwan(profile->qmichannel))
{
if(profile->qmap_mode > 1)
{
profile->muxid =
profile->pdp + 0x80;
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if(profile->qmap_mode == 1)
{
profile->muxid = 0x81;
profile->qmapnet_adapter = strdup(profile->usbnet_adapter);
}
}
}
if (0) {
profile->qmap_mode = atoi(buf);
if (profile->qmap_mode > 1 && qmidev_is_gobinet(profile->qmichannel)) {
profile->muxid =
profile->pdp + 0x80; // muxis is 0x8X for PDN-X
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if (profile->qmap_mode >= 1 && !qmidev_is_gobinet(profile->qmichannel)) {
profile->muxid =
profile->pdp + 0x80; // muxis is 0x8X for PDN-X
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if (profile->qmap_mode == 1 && qmidev_is_gobinet(profile->qmichannel)) {
profile->muxid = 0x81;
profile->qmapnet_adapter = strdup(profile->usbnet_adapter);
//2021-01-27 willa.liu@fibocom.com changed end for support mantis 0068849
}
}
} else if (qmidev_is_qmiwwan(profile->qmichannel)) {
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/qmimux%d",
profile->pdp - 1);
if (access(pl->filename, R_OK)) {
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename,
errno, strerror(errno));
}
goto _out;
}
// upstream Kernel Style QMAP qmi_wwan.c
snprintf(pl->filename, sizeof(pl->filename),
"/sys/class/net/%s/qmi/add_mux", profile->usbnet_adapter);
n = fibo_fread(pl->filename, buf, sizeof(buf));
if (n >= 5) {
profile->qmap_mode = n / 5; // 0x81\n0x82\n0x83\n
if (profile->qmap_mode > 1) {
// PDN-X map to qmimux-X
profile->muxid = (buf[5 * (profile->pdp - 1) + 2] - '0') * 16 +
(buf[5 * (profile->pdp - 1) + 3] - '0');
sprintf(qmap_netcard, "qmimux%d", profile->pdp - 1);
profile->qmapnet_adapter = strdup(qmap_netcard);
} else if (profile->qmap_mode == 1) {
profile->muxid =
(buf[5 * 0 + 2] - '0') * 16 + (buf[5 * 0 + 3] - '0');
sprintf(qmap_netcard, "qmimux%d", 0);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
}
}
_out:
if (profile->qmap_mode) {
profile->qmap_size = 16 * 1024;
snprintf(pl->filename, sizeof(pl->filename),
"/sys/class/net/%s/qmap_size", profile->usbnet_adapter);
if (!access(pl->filename, R_OK)) {
size_t n;
char buf[32];
n = fibo_fread(pl->filename, buf, sizeof(buf));
if (n > 0) {
profile->qmap_size = atoi(buf);
}
}
}
_final_process:
if (profile->qmap_mode)
dbg_time("qmap_mode = %d, muxid = 0x%02x, qmap_netcard = %s",
profile->qmap_mode, profile->muxid, profile->qmapnet_adapter);
free(pl);
return 0;
}
int fibo_qmap_mode_set(PROFILE_T *profile)
{
int n;
char buf[128];
struct {
char filename[255 * 2];
char linkname[255 * 2];
} * pl;
if (qmidev_is_pciemhi(profile->qmichannel))
{
dbg_time("pcie mode exit fibo_qmap_mode_set ");
return 0;
}
pl = (typeof(pl))malloc(sizeof(*pl));
snprintf(pl->linkname, sizeof(pl->linkname),
"/sys/class/net/%s/device/driver", profile->usbnet_adapter);
n = readlink(pl->linkname, pl->filename, sizeof(pl->filename));
pl->filename[n] = '\0';
while (pl->filename[n] != '/') n--;
profile->driver_name = strdup(&pl->filename[n + 1]);
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_num",
profile->usbnet_adapter);
if (access(pl->filename, R_OK)) {
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno,
strerror(errno));
goto _out;
}
snprintf(pl->filename, sizeof(pl->filename),
"/sys/module/%s/parameters/qmap_mnum", profile->driver_name);
if (access(pl->filename, R_OK)) {
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename,
errno, strerror(errno));
goto _out;
}
snprintf(
pl->filename, sizeof(pl->filename),
"/sys/class/net/%s/device/driver/module/parameters/qmap_num",
profile->usbnet_adapter);
if (access(pl->filename, R_OK)) {
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename,
errno, strerror(errno));
goto _out;
}
}
}
}
if (!access(pl->filename, R_OK)) {
snprintf(buf, sizeof(buf), "%d", profile->pdpnum);
n = fibo_fwrite(pl->filename, buf, strlen(buf));
}
_out:
free(pl);
return 0;
}

View File

@ -1,160 +0,0 @@
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
#include "QMIThread.h"
#include "query_pcie_mode.h"
int speed_arr[] = { B115200, B19200, B9600, B4800, B2400, B1200, B300,//
B38400, B19200, B9600, B4800, B2400, B1200, B300,
};
int name_arr[] = {115200, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400, 1200, 300,
};
int get_pcie_mode_debug = 0;
//2021-02-24 willa.liu@fibocom.com changed begin for support eipd SN-20210129001
int get_private_gateway_debug = 1;
//2021-02-24 willa.liu@fibocom.com changed end for support eipd SN-20210129001
//static int xset1(int fd, struct termios *tio, const char *device)
int xset1(int fd, struct termios *tio, const char *device)
{
int ret = tcsetattr(fd, TCSAFLUSH, tio);
if (ret) {
printf("can't tcsetattr for %s", device);
}
return ret;
}
// set raw tty mode
//static void xget1(int fd, struct termios *t, struct termios *oldt)
void xget1(int fd, struct termios *t, struct termios *oldt)
{
tcgetattr(fd, oldt);
*t = *oldt;
cfmakeraw(t);
// t->c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
// t->c_iflag &= ~(BRKINT|IXON|ICRNL);
// t->c_oflag &= ~(ONLCR);
// t->c_cc[VMIN] = 1;
// t->c_cc[VTIME] = 0;
}
//static int get_pcie_mode()
int get_pcie_mode()
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
{
int i;
int fd;
int ret;
char buffer[409600] = {0};
int rate;
char* sendbuffer;
int totallen = 0;
fd_set readfds;
struct timeval timeout;
struct termios tio0, tiosfd, tio;
int timeoutVal = 5;
char *dev = "/dev/ttyUSB1"; //The port under Linux is operated by opening the device file
rate = 115200;
sendbuffer = "at+gtpcie=3";
printf ( "dev: %s\nrate:%d\nsendbuffer:%s\n", dev,rate,sendbuffer);
fd = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0)
goto ERR;
fcntl(fd, F_SETFL, O_RDWR);
// put device to "raw mode"
xget1(fd, &tio, &tiosfd);
// set device speed
for ( i = 0;i < sizeof ( speed_arr ) / sizeof ( int );i++ )
{
if ( rate == name_arr[i] ) //Judge if the pass is equal to the pass
{
break;
}
}
if(i >= sizeof ( speed_arr ) / sizeof ( int ))
{
printf("bound rate set failed\n");
goto ERR;
}
cfsetspeed(&tio, speed_arr[i]);
if (xset1(fd, &tio, dev))
goto ERR;
tcflush ( fd, TCIOFLUSH );
sprintf(buffer, "%s\r", sendbuffer);
ret = write ( fd, buffer, strlen(buffer) );
if(ret < 0)
{
printf ( "write failed\n" );
goto ERR;
}
if(get_pcie_mode_debug)printf("write %d\n", ret);
FD_ZERO ( &readfds );
FD_SET ( fd, &readfds );
while(1)
{
timeout.tv_sec = timeoutVal;
timeout.tv_usec = 0;
ret = select ( fd+1, &readfds, ( fd_set * ) 0, ( fd_set * ) 0, &timeout );
if(ret > 0)
{
ret = read ( fd, buffer+totallen, sizeof(buffer)-totallen-1 );
if(ret < 0)
{
printf ( "read failed\n" );
goto ERR;
}
if(ret == 0)
{
goto ERR;
}
totallen += ret;
buffer[totallen] = '\0';
if(get_pcie_mode_debug)printf("read %d(%s)\n", ret, &buffer[totallen-ret]);
if(totallen == sizeof(buffer)-1)
break;
if(strstr(buffer,"\nOK") || strstr(buffer,"\nERROR")
|| strstr(buffer,"\n+CME ERROR:") || strstr(buffer,"\n+CMS ERROR:"))
{
if(get_pcie_mode_debug)printf("match OK/ERROR");
if(get_pcie_mode_debug)printf("%s", buffer);
break;
}
}
else
{
printf ( "select timeout\n" );
goto ERR;
}
}
tcsetattr(fd, TCSAFLUSH, &tiosfd);
//printf("buffer:\n %s\n", buffer);
printf("%s\n", buffer);
if(strstr(buffer,"\nERROR") || strstr(buffer,"\n+CME ERROR:") || strstr(buffer,"\n+CMS ERROR:"))
goto ERR;
close ( fd );
return 0;
ERR:
if(fd > 0)
close(fd);
return -1;
}

View File

@ -1,17 +0,0 @@
#ifndef __QUERY_PCIE_MODE__
#define __QUERY_PCIE_MODE__
extern int speed_arr[14];
extern int name_arr[14];
extern int get_pcie_mode_debug;
extern int get_private_gateway_debug;
extern int xset1(int fd, struct termios *tio, const char *device);
// set raw tty mode
extern void xget1(int fd, struct termios *t, struct termios *oldt);
extern int get_pcie_mode();
#endif

View File

@ -1,289 +0,0 @@
#include <arpa/inet.h>
#include <endian.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "QMIThread.h"
#include "util.h"
static int dibbler_client_alive = 0;
static int fibo_system(const char *shell_cmd)
{
int ret = 0;
dbg_time("%s", shell_cmd);
ret = system(shell_cmd);
if (ret) {
// dbg_time("Fail to system(\"%s\") = %d, errno: %d (%s)", shell_cmd,
// ret, errno, strerror(errno));
}
return ret;
}
static void fibo_set_mtu(const char *ifname, int ifru_mtu)
{
int inet_sock;
struct ifreq ifr;
inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
if (inet_sock > 0) {
strcpy(ifr.ifr_name, ifname);
if (!ioctl(inet_sock, SIOCGIFMTU, &ifr)) {
if (ifr.ifr_ifru.ifru_mtu != ifru_mtu) {
dbg_time("change mtu %d -> %d", ifr.ifr_ifru.ifru_mtu,
ifru_mtu);
ifr.ifr_ifru.ifru_mtu = ifru_mtu;
ioctl(inet_sock, SIOCSIFMTU, &ifr);
}
}
close(inet_sock);
}
}
static void *udhcpc_thread_function(void *arg)
{
FILE *udhcpc_fp;
char *udhcpc_cmd = (char *)arg;
if (udhcpc_cmd == NULL)
return NULL;
dbg_time("%s", udhcpc_cmd);
udhcpc_fp = popen(udhcpc_cmd, "r");
free(udhcpc_cmd);
if (udhcpc_fp) {
char buf[0xff];
buf[sizeof(buf) - 1] = '\0';
while ((fgets(buf, sizeof(buf) - 1, udhcpc_fp)) != NULL) {
if ((strlen(buf) > 1) && (buf[strlen(buf) - 1] == '\n'))
buf[strlen(buf) - 1] = '\0';
dbg_time("%s", buf);
}
pclose(udhcpc_fp);
}
return NULL;
}
void fibo_set_driver_link_state(PROFILE_T *profile, int link_state)
{
char link_file[128];
int fd;
int new_state = 0;
dbg_time("enter %s ", __func__);
snprintf(link_file, sizeof(link_file), "/sys/class/net/%s/link_state",
profile->usbnet_adapter);
fd = open(link_file, O_RDWR | O_NONBLOCK | O_NOCTTY);
if (fd == -1) {
if (errno != ENOENT)
dbg_time("Fail to access %s, errno: %d (%s)", link_file, errno,
strerror(errno));
return;
}
if (profile->qmap_mode <= 1)
new_state = !!link_state;
else {
// 0x80 means link off this pdp
new_state = (link_state ? 0x00 : 0x80) + profile->pdp;
}
snprintf(link_file, sizeof(link_file), "%d\n", new_state);
write(fd, link_file, sizeof(link_file));
if (link_state == 0 && profile->qmap_mode > 1) {
size_t rc;
lseek(fd, 0, SEEK_SET);
rc = read(fd, link_file, sizeof(link_file));
if (rc > 1 && (!strcasecmp(link_file, "0\n") ||
!strcasecmp(link_file, "0x0\n"))) {
// snprintf(link_file, sizeof(link_file), "busybox ifconfig %s down",
// profile->usbnet_adapter);
// fibo_system(link_file);
}
}
close(fd);
}
int fibo_raw_ip_mode_check(const char *ifname)
{
int fd;
char raw_ip[128];
char shell_cmd[128];
char mode[2] = "X";
int mode_change = 0;
snprintf(raw_ip, sizeof(raw_ip), "/sys/class/net/%s/qmi/raw_ip", ifname);
if (access(raw_ip, F_OK))
return 0;
fd = open(raw_ip, O_RDWR | O_NONBLOCK | O_NOCTTY);
if (fd < 0) {
dbg_time("%s %d fail to open(%s), errno:%d (%s)", __FILE__, __LINE__,
raw_ip, errno, strerror(errno));
return 0;
}
read(fd, mode, 2);
if (mode[0] == '0' || mode[0] == 'N') {
snprintf(shell_cmd, sizeof(shell_cmd), "busybox ifconfig %s down", ifname);
fibo_system(shell_cmd);
dbg_time("echo Y > /sys/class/net/%s/qmi/raw_ip", ifname);
mode[0] = 'Y';
write(fd, mode, 2);
mode_change = 1;
snprintf(shell_cmd, sizeof(shell_cmd), "busybox ifconfig %s up", ifname);
fibo_system(shell_cmd);
}
close(fd);
return mode_change;
}
void udhcpc_start(PROFILE_T *profile)
{
char *ifname = profile->usbnet_adapter;
char shell_cmd[128];
fibo_set_driver_link_state(profile, 1);
if (profile->qmapnet_adapter) {
ifname = profile->qmapnet_adapter;
}
dbg_time("1 %s", profile->qmichannel);
if (qmidev_is_qmiwwan(profile->qmichannel)) {
dbg_time("2 %s", ifname);
fibo_raw_ip_mode_check(ifname);
}
if (profile->rawIP && profile->ipv4.Address && profile->ipv4.Mtu) {
fibo_set_mtu(ifname, (profile->ipv4.Mtu));
}
fibo_system("echo 1 > /sys/module/fibo_mhi/parameters/macaddr_check");
//begin modified by zhangkaibo fix ipv6 dial process flow. mantis 0048789 20200605
// if (strcmp(ifname, profile->usbnet_adapter)) {
// snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s up",
// profile->usbnet_adapter);
// fibo_system(shell_cmd);
// }
//begin modified by zhangkaibo fix ipv6 dial process flow. mantis 0048789 20200605
// For IPv6, down & up will send protocol packets, and that's needed.
if (profile->ipv6_flag) {
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s down", ifname);
fibo_system(shell_cmd);
}
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s up", ifname);
fibo_system(shell_cmd);
//begin modified by zhangming Added NOARP and Multilcast on flag bit commands. mantis 0050106 20200713
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link set %s arp off multicast on", ifname);
fibo_system(shell_cmd);
//begin modified by zhangming Added NOARP and Multilcast on flag bit commands. mantis 0050106 20200713
//Modified unicom dual stack dialing unsuccessful problem
// for bridge mode, only one public IP, so do udhcpc manually
if (fibo_bridge_mode_detect(profile)) {
return;
}
/* Do DHCP using busybox tools */
{
char udhcpc_cmd[128];
pthread_attr_t udhcpc_thread_attr;
pthread_t udhcpc_thread_id;
pthread_attr_init(&udhcpc_thread_attr);
pthread_attr_setdetachstate(&udhcpc_thread_attr,
PTHREAD_CREATE_DETACHED);
if (profile->ipv4.Address) {
if (access("/usr/share/udhcpc/default.script", X_OK)) {
dbg_time(
"Fail to access /usr/share/udhcpc/default.script, "
"errno: %d (%s)",
errno, strerror(errno));
}
//-f,--foreground Run in foreground
//-b,--background Background if lease is not obtained
//-n,--now Exit if lease is not obtained
//-q,--quit Exit after obtaining lease
//-t,--retries N Send up to N discover packets (default 3)
snprintf(udhcpc_cmd, sizeof(udhcpc_cmd),
"busybox udhcpc -f -n -q -t 5 -i %s", ifname);
if (!access("/lib/netifd/dhcp.script", X_OK) &&
!access("/sbin/ifup", X_OK) &&
!access("/sbin/ifstatus", X_OK)) {
dbg_time("you are use OpenWrt?");
dbg_time("should not calling udhcpc manually?");
dbg_time("should modify /etc/config/network as below?");
dbg_time("config interface wan");
dbg_time("\toption ifname %s", ifname);
dbg_time("\toption proto dhcp");
dbg_time(
"should use \"/sbin/ifstaus wan\" to check %s 's status?",
ifname);
}
pthread_create(&udhcpc_thread_id, NULL, udhcpc_thread_function,
(void *)strdup(udhcpc_cmd));
sleep(1);
}
if (profile->ipv6.Address[0] && profile->ipv6.PrefixLengthIPAddr) {
// module do not support DHCPv6, only support 'Router Solicit'
// and it seem if enable /proc/sys/net/ipv6/conf/all/forwarding,
// Kernel do not send RS
const char *forward_file = "/proc/sys/net/ipv6/conf/all/forwarding";
int forward_fd = open(forward_file, O_RDONLY);
if (forward_fd > 0) {
char forward_state[2];
read(forward_fd, forward_state, 2);
if (forward_state[0] == '1') {
dbg_time(
"%s enabled, kernel maybe donot send 'Router Solicit'",
forward_file);
}
close(forward_fd);
}
}
}
}
void udhcpc_stop(PROFILE_T *profile)
{
char *ifname = profile->usbnet_adapter;
char shell_cmd[128];
char reset_ip[128];
dbg_time("enter %s ", __func__);
if (profile->qmapnet_adapter) {
ifname = profile->qmapnet_adapter;
}
if (dibbler_client_alive) {
system("killall dibbler-client");
dibbler_client_alive = 0;
}
//snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s down",
// profile->usbnet_adapter);
//fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s down", ifname);
fibo_system(shell_cmd);
snprintf(reset_ip, sizeof(reset_ip) - 1, "busybox ifconfig %s 0.0.0.0", ifname);
fibo_system(reset_ip);
}

View File

@ -1,421 +0,0 @@
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/types.h>
#include <net/if.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <endian.h>
#include "libmnl/ifutils.h"
#include "libmnl/dhcp/dhcp.h"
#include "util.h"
#include "QMIThread.h"
static int fibo_system(const char *shell_cmd)
{
int ret = 0;
dbg_time("%s", shell_cmd);
ret = system(shell_cmd);
if (ret) {
// dbg_time("Fail to system(\"%s\") = %d, errno: %d (%s)", shell_cmd,
// ret, errno, strerror(errno));
}
return ret;
}
int fibo_raw_ip_mode_check(const char *ifname)
{
int fd;
char raw_ip[128];
char mode[2] = "X";
int mode_change = 0;
snprintf(raw_ip, sizeof(raw_ip), "/sys/class/net/%s/qmi/raw_ip", ifname);
if (access(raw_ip, F_OK))
return 0;
fd = open(raw_ip, O_RDWR | O_NONBLOCK | O_NOCTTY);
if (fd < 0)
{
dbg_time("%s %d fail to open(%s), errno:%d (%s)", __FILE__, __LINE__, raw_ip, errno, strerror(errno));
return 0;
}
read(fd, mode, 2);
if (mode[0] == '0' || mode[0] == 'N')
{
if_link_down(ifname);
dbg_time("echo Y > /sys/class/net/%s/qmi/raw_ip", ifname);
mode[0] = 'Y';
write(fd, mode, 2);
mode_change = 1;
if_link_up(ifname);
}
close(fd);
return mode_change;
}
static void fibo_set_driver_link_state(PROFILE_T *profile, int link_state)
{
char link_file[128];
int fd;
int new_state = 0;
dbg_time("enter %s ", __func__);
snprintf(link_file, sizeof(link_file), "/sys/class/net/%s/link_state", profile->usbnet_adapter);
fd = open(link_file, O_RDWR | O_NONBLOCK | O_NOCTTY);
if (fd == -1)
{
if (errno != ENOENT)
dbg_time("Fail to access %s, errno: %d (%s)", link_file, errno, strerror(errno));
return;
}
if (profile->qmap_mode <= 1)
new_state = !!link_state;
else
{
//0x80 means link off this pdp
new_state = (link_state ? 0x00 : 0x80) + profile->pdp;
}
snprintf(link_file, sizeof(link_file), "%d\n", new_state);
write(fd, link_file, sizeof(link_file));
if (link_state == 0 && profile->qmap_mode > 1)
{
size_t rc;
lseek(fd, 0, SEEK_SET);
rc = read(fd, link_file, sizeof(link_file));
if (rc > 1 && (!strcasecmp(link_file, "0\n") || !strcasecmp(link_file, "0x0\n")))
{
// if_link_down(profile->usbnet_adapter);
}
}
close(fd);
}
void udhcpc_start(PROFILE_T *profile)
{
//2021-02-01 willa.liu@fibocom.com changed begin for support mantis 0069837
char *ifname = profile->usbnet_adapter;
char shell_cmd[512];
fibo_set_driver_link_state(profile, 1);
fibo_raw_ip_mode_check(ifname);
if (profile->qmapnet_adapter)
{
ifname = profile->qmapnet_adapter;
}
if (profile->rawIP && profile->ipv4.Address && profile->ipv4.Mtu)
{
if_set_mtu(ifname, (profile->ipv4.Mtu));
}
if (strcmp(ifname, profile->usbnet_adapter))
{
//if_link_up(profile->usbnet_adapter);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ifconfig %s up", profile->usbnet_adapter);
fibo_system(shell_cmd);
}
//2021-02-01 willa.liu@fibocom.com changed begin for support mantis 0069837
if_link_up(ifname);
#if 1 //for bridge mode, only one public IP, so do udhcpc manually
if (fibo_bridge_mode_detect(profile))
{
return;
}
#endif
// if use DHCP(should make with ${DHCP} src files)
// do_dhcp(ifname);
// return 0;
/* IPv4 Addr Info */
if (profile->ipv4.Address)
{
dbg_time("IPv4 MTU: %d", profile->ipv4.Mtu);
dbg_time("IPv4 Address: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.Address)));
dbg_time("IPv4 Netmask: %d", mask_to_prefix_v4(ntohl(profile->ipv4.SubnetMask)));
dbg_time("IPv4 Gateway: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.Gateway)));
dbg_time("IPv4 DNS1: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.DnsPrimary)));
dbg_time("IPv4 DNS2: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.DnsSecondary)));
if_set_network_v4(ifname, ntohl(profile->ipv4.Address),
mask_to_prefix_v4(profile->ipv4.SubnetMask),
ntohl(profile->ipv4.Gateway),
ntohl(profile->ipv4.DnsPrimary),
ntohl(profile->ipv4.DnsSecondary));
}
else
{
dbg_time("The IPv4 Address in profile is NULL");
}
if (profile->ipv6.Address && (profile->ipv6.PrefixLengthIPAddr != 0))
{
//module do not support DHCPv6, only support 'Router Solicit'
//and it seem if enable /proc/sys/net/ipv6/conf/all/forwarding, Kernel do not send RS
const char *forward_file = "/proc/sys/net/ipv6/conf/all/forwarding";
int forward_fd = open(forward_file, O_RDONLY);
if (forward_fd > 0)
{
char forward_state[2];
read(forward_fd, forward_state, 2);
if (forward_state[0] == '1')
{
dbg_time("%s enabled, kernel maybe donot send 'Router Solicit'", forward_file);
}
close(forward_fd);
}
dbg_time("IPv6 MTU: %d", profile->ipv6.Mtu);
dbg_time("IPv6 Address: %s", ipaddr_to_string_v6(profile->ipv6.Address));
dbg_time("IPv6 PrefixLengthIPAddr: %d", profile->ipv6.PrefixLengthIPAddr);
dbg_time("IPv6 Gateway: %s", ipaddr_to_string_v6(profile->ipv6.Gateway));
dbg_time("IPv6 DNS1: %s", ipaddr_to_string_v6(profile->ipv6.DnsPrimary));
dbg_time("IPv6 DNS2: %s", ipaddr_to_string_v6(profile->ipv6.DnsSecondary));
if_set_network_v6(ifname, profile->ipv6.Address, profile->ipv6.PrefixLengthIPAddr,
profile->ipv6.Gateway, profile->ipv6.DnsPrimary, profile->ipv6.DnsSecondary);
}
else
{
dbg_time("The IPv6 Address in profile is NULL");
}
}
void udhcpc_stop(PROFILE_T *profile)
{
char *ifname = profile->usbnet_adapter;
dbg_time("enter %s ", __func__);
fibo_set_driver_link_state(profile, 0);
if (profile->qmapnet_adapter)
{
ifname = profile->qmapnet_adapter;
}
if_flush_v4_addr(ifname);
if_flush_v6_addr(ifname);
if_link_down(ifname);
}
static void fibo_set_mtu(const char *ifname, int ifru_mtu) {
int inet_sock;
struct ifreq ifr;
inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
if (inet_sock > 0) {
strcpy(ifr.ifr_name, ifname);
if (!ioctl(inet_sock, SIOCGIFMTU, &ifr)) {
if (ifr.ifr_ifru.ifru_mtu != ifru_mtu) {
dbg_time("change mtu %d -> %d", ifr.ifr_ifru.ifru_mtu , ifru_mtu);
ifr.ifr_ifru.ifru_mtu = ifru_mtu;
ioctl(inet_sock, SIOCSIFMTU, &ifr);
}
}
close(inet_sock);
}
}
static void* udhcpc_thread_function(void* arg) {
FILE * udhcpc_fp;
char *udhcpc_cmd = (char *)arg;
if (udhcpc_cmd == NULL)
return NULL;
dbg_time("%s", udhcpc_cmd);
udhcpc_fp = popen(udhcpc_cmd, "r");
free(udhcpc_cmd);
if (udhcpc_fp) {
char buf[0xff];
buf[sizeof(buf)-1] = '\0';
while((fgets(buf, sizeof(buf)-1, udhcpc_fp)) != NULL) {
if ((strlen(buf) > 1) && (buf[strlen(buf) - 1] == '\n'))
buf[strlen(buf) - 1] = '\0';
dbg_time("%s", buf);
}
pclose(udhcpc_fp);
}
return NULL;
}
void udhcpc_start_pcie(PROFILE_T *profile) {
char *ifname = profile->usbnet_adapter;
char sub_intf_name[100] = {0};
int intf_id = 0;
char shell_cmd[512];
dbg_time("enter %s ", __func__);
if (profile->qmapnet_adapter) {
ifname = profile->qmapnet_adapter;
}
if (profile->muxid > 0x81)
{
intf_id = profile->muxid - 0x81;
snprintf(sub_intf_name, sizeof(sub_intf_name) - 1, "%s.%d", ifname, intf_id);
}
if (profile->rawIP && profile->ipv4.Address && profile->ipv4.Mtu) {
fibo_set_mtu(ifname, (profile->ipv4.Mtu));
}
fibo_system("echo 1 > /sys/module/fibo_mhi/parameters/macaddr_check");
if (strcmp(ifname, profile->usbnet_adapter)) {
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ifconfig %s up", profile->usbnet_adapter);
fibo_system(shell_cmd);
}
// For IPv6, down & up will send protocol packets, and that's needed.
if (profile->ipv6_flag && profile->muxid <= 0x81) {
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ifconfig %s down", ifname);
fibo_system(shell_cmd);
}
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ifconfig %s up", ifname);
fibo_system(shell_cmd);
//for bridge mode, only one public IP, so do udhcpc manually
if (fibo_bridge_mode_detect(profile)) {
return;
}
/* Do DHCP using busybox tools */
{
char udhcpc_cmd[128];
pthread_attr_t udhcpc_thread_attr;
pthread_t udhcpc_thread_id;
pthread_attr_init(&udhcpc_thread_attr);
pthread_attr_setdetachstate(&udhcpc_thread_attr, PTHREAD_CREATE_DETACHED);
if (profile->ipv4.Address)
{
char v4add_str[32] = {0};
char v4gw_str[32] = {0};
char v4_netmask_str[32] = {0};
uint32_t Address = ntohl(profile->ipv4.Address);
uint32_t Gateway = ntohl(profile->ipv4.Gateway);
uint32_t SubnetMask = ntohl(profile->ipv4.SubnetMask);
inet_ntop(AF_INET, &Address, v4add_str, sizeof(v4add_str));
inet_ntop(AF_INET, &Gateway, v4gw_str, sizeof(v4gw_str));
inet_ntop(AF_INET, &SubnetMask, v4_netmask_str, sizeof(v4_netmask_str));
if (profile->muxid == 0x81)
{
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ifconfig %s %s netmask %s", ifname, v4add_str, v4_netmask_str);
fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "route add default gw %s dev %s", v4gw_str, ifname);
fibo_system(shell_cmd);
}
else if (profile->muxid > 0x81)
{
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link add link %s name %s type vlan id %d", ifname, sub_intf_name, intf_id);
fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link set %s up", ifname);
fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link set %s up", sub_intf_name);
fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ifconfig %s %s netmask %s", sub_intf_name, v4add_str, v4_netmask_str);
fibo_system(shell_cmd);
}
}
if (profile->ipv6.PrefixLengthIPAddr)
{
//module do not support DHCPv6, only support 'Router Solicit'
//and it seem if enable /proc/sys/net/ipv6/conf/all/forwarding, Kernel do not send RS
const char *forward_file = "/proc/sys/net/ipv6/conf/all/forwarding";
int forward_fd = open(forward_file, O_RDONLY);
if (forward_fd > 0) {
char forward_state[2];
read(forward_fd, forward_state, 2);
if (forward_state[0] == '1') {
dbg_time("%s enabled, kernel maybe donot send 'Router Solicit'", forward_file);
}
close(forward_fd);
}
{
char v6add_str[100] = {0};
char v6gw_str[100] = {0};
inet_ntop(AF_INET6, profile->ipv6.Address, v6add_str, sizeof(v6add_str));
inet_ntop(AF_INET6, profile->ipv6.Gateway, v6gw_str, sizeof(v6gw_str));
if (profile->muxid == 0x81)
{
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ifconfig %s add %s/%d", ifname, v6add_str, profile->ipv6.PrefixLengthIPAddr);
fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "route -A inet6 add ::/0 gw %s dev %s", v6gw_str, ifname);
fibo_system(shell_cmd);
}
else if (profile->muxid > 0x81)
{
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link add link %s name %s type vlan id %d", ifname, sub_intf_name, intf_id);
fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link set %s up", ifname);
fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link set %s up", sub_intf_name);
fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ifconfig %s add %s/%d", sub_intf_name, v6add_str, profile->ipv6.PrefixLengthIPAddr);
fibo_system(shell_cmd);
/* start 2021-01-21 add by haopengfei to fix mantis 69056 */
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "route -A inet6 add ::/0 gw %s dev %s", v6gw_str, sub_intf_name);
fibo_system(shell_cmd);
/* end 2021-01-21 add by haopengfei to fix mantis 69056 */
}
}
}
}
}
void udhcpc_stop_pcie(PROFILE_T *profile) {
char *ifname = profile->usbnet_adapter;
char shell_cmd[128];
char reset_ip[128];
dbg_time("enter %s ", __func__);
if (profile->qmapnet_adapter) {
ifname = profile->qmapnet_adapter;
}
if (profile->muxid == 0x81)
{
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ifconfig %s down", ifname);
fibo_system(shell_cmd);
snprintf(reset_ip, sizeof(reset_ip) - 1, "ifconfig %s 0.0.0.0", ifname);
fibo_system(reset_ip);
}
else if (profile->muxid > 0x81)
{
char sub_intf_name[100];
int intf_id = profile->muxid - 0x81;
snprintf(sub_intf_name, sizeof(sub_intf_name) - 1, "%s.%d", ifname, intf_id);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link del link dev %s", sub_intf_name);
fibo_system(shell_cmd);
}
}

View File

@ -1,142 +0,0 @@
#include <sys/time.h>
#include "QMIThread.h"
#if defined(__STDC__)
#include <stdarg.h>
#define __V(x) x
#else
#include <varargs.h>
#define __V(x) (va_alist) va_dcl
#define const
#define volatile
#endif
#include <syslog.h>
#define is_bigendian() ((*(char *)&i) == 0)
FILE *logfilefp = NULL;
static pthread_mutex_t printfMutex = PTHREAD_MUTEX_INITIALIZER;
static char line[1024];
const int i = 1;
// defined in atchannel.c
static void setTimespecRelative(struct timespec *p_ts, long long msec)
{
struct timeval tv;
gettimeofday(&tv, (struct timezone *)NULL);
/* what's really funny about this is that I know
pthread_cond_timedwait just turns around and makes this
a relative time again */
p_ts->tv_sec = tv.tv_sec + (msec / 1000);
p_ts->tv_nsec = (tv.tv_usec + (msec % 1000) * 1000L) * 1000L;
}
int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t *mutex,
unsigned msecs)
{
if (msecs != 0) {
struct timespec ts;
setTimespecRelative(&ts, msecs);
return pthread_cond_timedwait(cond, mutex, &ts);
} else {
return pthread_cond_wait(cond, mutex);
}
}
static const char *get_time(void)
{
static char time_buf[50];
struct timeval tv;
time_t time;
suseconds_t millitm;
struct tm *ti;
gettimeofday(&tv, NULL);
time = tv.tv_sec;
millitm = (tv.tv_usec + 500) / 1000;
if (millitm == 1000) {
++time;
millitm = 0;
}
ti = localtime(&time);
sprintf(time_buf, "[%02d-%02d_%02d:%02d:%02d:%03d]", ti->tm_mon + 1,
ti->tm_mday, ti->tm_hour, ti->tm_min, ti->tm_sec, (int)millitm);
return time_buf;
}
void dbg_time(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
pthread_mutex_lock(&printfMutex);
snprintf(line, sizeof(line), "%s ", get_time());
vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, args);
fprintf(stdout, "%s\n", line);
if (logfilefp) {
fprintf(logfilefp, "%s\n", line);
}
fflush(logfilefp);
pthread_mutex_unlock(&printfMutex);
}
USHORT le16_to_cpu(USHORT v16)
{
USHORT tmp = v16;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v16);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[1];
d[1] = s[0];
}
return tmp;
}
UINT le32_to_cpu(UINT v32)
{
UINT tmp = v32;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v32);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
d[3] = s[0];
}
return tmp;
}
USHORT cpu_to_le16(USHORT v16)
{
USHORT tmp = v16;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v16);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[1];
d[1] = s[0];
}
return tmp;
}
UINT cpu_to_le32(UINT v32)
{
UINT tmp = v32;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v32);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
d[3] = s[0];
}
return tmp;
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _UTILS_H_
#define _UTILS_H_
#include <stddef.h>
struct listnode {
struct listnode *next;
struct listnode *prev;
};
#define node_to_item(node, container, member) \
(container *)(((char *)(node)) - offsetof(container, member))
#define list_declare(name) \
struct listnode name = { \
.next = &name, \
.prev = &name, \
}
#define list_for_each(node, list) \
for (node = (list)->next; node != (list); node = node->next)
#define list_for_each_reverse(node, list) \
for (node = (list)->prev; node != (list); node = node->prev)
void dbg_time(const char *fmt, ...);
void list_init(struct listnode *list);
void list_add_tail(struct listnode *list, struct listnode *item);
void list_add_head(struct listnode *head, struct listnode *item);
void list_remove(struct listnode *item);
#define list_empty(list) ((list) == (list)->next)
#define list_head(list) ((list)->next)
#define list_tail(list) ((list)->prev)
int epoll_register(int epoll_fd, int fd, unsigned int events);
int epoll_deregister(int epoll_fd, int fd);
#endif

View File

@ -1,47 +0,0 @@
#
# Copyright (C) 2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=qmi_wwan_f
PKG_VERSION:=1.0
PKG_RELEASE:=3
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
define KernelPackage/qmi_wwan_f
SUBMENU:=WWAN Support
TITLE:=Fibocom Linux USB QMI WWAN Driver
DEPENDS:=+kmod-usb-net +kmod-usb-wdm
FILES:=$(PKG_BUILD_DIR)/qmi_wwan_f.ko
AUTOLOAD:=$(call AutoLoad,82,qmi_wwan_f)
endef
define KernelPackage/qmi_wwan_f/description
Fibocom Linux USB QMI WWAN Driver
endef
MAKE_OPTS:= \
ARCH="$(LINUX_KARCH)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
CXXFLAGS="$(TARGET_CXXFLAGS)" \
M="$(PKG_BUILD_DIR)" \
$(EXTRA_KCONFIG)
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
$(MAKE_OPTS) \
modules
endef
$(eval $(call KernelPackage,qmi_wwan_f))

View File

@ -1,38 +0,0 @@
obj-m += qmi_wwan_f.o
PWD := $(shell pwd)
OUTPUTDIR=/lib/modules/`uname -r`/kernel/drivers/net/usb/
ifeq ($(ARCH),)
ARCH := $(shell uname -m)
endif
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE :=
endif
ifeq ($(KDIR),)
KDIR := /lib/modules/$(shell uname -r)/build
ifeq ($(ARCH),i686)
ifeq ($(wildcard $KDIR/arch/$ARCH),)
ARCH=i386
endif
endif
endif
ifneq ($(findstring &,${PWD}),)
$(warning "${PWD}")
$(warning "current directory contain special char '&' !")
$(error "please remove it!")
endif
default:
$(MAKE) ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} -C $(KDIR) M=$(PWD) modules
install: default
cp $(PWD)/qmi_wwan_f.ko /lib/modules/$(shell uname -r)/kernel/drivers/net/usb/
depmod
modprobe -r qmi_wwan_f
modprobe -r qmi_wwan
modprobe qmi_wwan_f
clean:
rm -rf *~ .tmp_versions modules.order Module.symvers
find . -type f -name "*~" -o -name "*.o" -o -name "*.ko" -o -name "*.cmd" -o -name "*.mod.c" | xargs rm -rf

File diff suppressed because it is too large Load Diff

View File

@ -1,76 +0,0 @@
#
# Copyright (C) 2015-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=adbyby
PKG_VERSION:=2.7
PKG_RELEASE:=20200315
include $(INCLUDE_DIR)/package.mk
define Package/adbyby
SECTION:=net
CATEGORY:=Network
TITLE:=Powerful adblock module to block ad.
DEPENDS:=@(i386||x86_64||arm||mipsel||mips||aarch64)
URL:=http://www.adbyby.com/
endef
define Package/adbyby/description
Adbyby is a powerful adblock module to block ad,just like adblock.
endef
ifeq ($(ARCH),x86_64)
ADBYBY_DIR:=amd64
endif
ifeq ($(ARCH),mipsel)
ADBYBY_DIR:=mipsle
endif
ifeq ($(ARCH),mips)
ADBYBY_DIR:=mips
endif
ifeq ($(ARCH),i386)
ADBYBY_DIR:=x86
endif
ifeq ($(ARCH),arm)
ADBYBY_DIR:=armv7
ifeq ($(BOARD),bcm53xx)
ADBYBY_DIR:=arm
endif
ifeq ($(BOARD),kirkwood)
ADBYBY_DIR:=arm
endif
endif
ifeq ($(ARCH),aarch64)
ADBYBY_DIR:=armv7
endif
define Build/Prepare
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/adbyby/install
$(INSTALL_DIR) $(1)/usr/share/adbyby
$(INSTALL_BIN) ./files/adbyby.sh $(1)/usr/share/adbyby/
$(INSTALL_CONF) ./files/adhook.ini $(1)/usr/share/adbyby/
$(INSTALL_CONF) ./files/user.action $(1)/usr/share/adbyby/
$(INSTALL_DIR) $(1)/usr/share/adbyby/data
$(INSTALL_DATA) ./files/data/* $(1)/usr/share/adbyby/data/
$(INSTALL_DIR) $(1)/usr/share/adbyby/doc
$(INSTALL_DATA) ./files/doc/* $(1)/usr/share/adbyby/doc/
$(INSTALL_BIN) ./files/$(ADBYBY_DIR)/adbyby $(1)/usr/share/adbyby/adbyby
endef
$(eval $(call BuildPackage,adbyby))

View File

@ -1,16 +0,0 @@
#!/bin/sh
PROG_PATH=/usr/share/adbyby
err=0
until [ $err -ge 5 ]; do
if [ -n "$(pgrep $PROG_PATH/adbyby)" ]; then
iptables-save | grep ADBYBY >/dev/null || \
/etc/init.d/adbyby add_rule
sleep 10
err=0
else
$PROG_PATH/adbyby --no-daemon &>/dev/null &
sleep 1
err=$((err+1))
fi
done
/etc/init.d/adbyby del_rule

View File

@ -1,14 +0,0 @@
[cfg]
### 2.1 ###
listen-address=0.0.0.0:8118
buffer-limit=1024
keep-alive-timeout=30
socket-timeout=60
### 2.5 ###
max_client_connections=0
### 2.6 ###
stack_size=200
auto_restart=0
### 2.7 ###
debug=0
ipset=0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,25 +0,0 @@
! -----¸üÐÂʱ¼ä: 2018-10-08 23:07:52 by:xwhyc-----
.php?ad=
/99rejs/js
/agetsou.js^
/c@*!25.js|$script
/cococ-66/$script
/defaultts.tc.qq.com/*.ts?index=0&start=0&
/defaultts.tc.qq.com/*.ts?index=0&start=0&end=*&ver=4
/gg_js/
/imgs.js?t=
/js/adtop.js|
/js/guanggao_gg.js?d=
/js/sss/ad.js
/static/js/aall.js
/unionjs/$script
/variety.tc.qq.com/*.mp4^*fmt=hd
/variety.tc.qq.com/*.mp4^*fmt=shd
/video.dispatch.tc.qq.com/*.mp4^*sdtfrom=
/view/image/QT_HY.jpg?t=
/view/js/slade.js|$script
/vlive.qqvideo.tc.qq.com/*.mp4^*fmt=hd
/vlive.qqvideo.tc.qq.com/*.mp4^*fmt=shd
/vmind.qqvideo.tc.qq.com/*.mp4^*sdtfrom=
/vmindhls.tc.qq.com/*ugc=0&ga=0&gv=0&start=
/zzhzgg.js

View File

@ -1,15 +0,0 @@
! ------------------------------ ADByby 自定义过滤语法简表---------------------------------
! -------------- 规则基于abp规则并进行了字符替换部分的扩展-----------------------------
! ABP规则请参考https://adblockplus.org/zh_CN/filters下面为大致摘要
! "!" 为行注释符,注释行以该符号起始作为一行注释语义,用于规则描述
! "*" 为字符通配符能够匹配0长度或任意长度的字符串该通配符不能与正则语法混用。
! "^" 为分隔符,可以是除了字母、数字或者 _ - . % 之外的任何字符。
! "|" 为管线符号,来表示地址的最前端或最末端
! "||" 为子域通配符,方便匹配主域名下的所有子域。
! "~" 为排除标识符,通配符能过滤大多数广告,但同时存在误杀, 可以通过排除标识符修正误杀链接。
! "##" 为元素选择器标识符后面跟需要隐藏元素的CSS样式例如 #ad_id .ad_class
!! 元素隐藏暂不支持全局规则和排除规则
!! 字符替换扩展
! 文本替换选择器标识符,后面跟需要替换的文本数据,格式:$s@模式字符串@替换后的文本@
! 支持通配符*和?
! -------------------------------------------------------------------------------------------

View File

@ -1,30 +0,0 @@
! -----更新时间: 2018-10-08 23:06:11 by:xwhyc-----------------------------------------------
! -----广告反馈:http://www.adbyby.com/help.htm QQ群: 79547134(满), 364066294(满)470705224(满)534897434,438394572--------------
!-------------------------------------------
/showadv/
3199.cn###ad640,[id^="ad0"]
76fengyun.com###down_box{display:block!important;}.gggg,.ggao
9553.com##[class="zm"]
962.net##.show_ad,.g-962-ad
amazon.cn##.adv-float-div
downsx.rocks##.adbox,.Left-ad3_fixed,.google-ad2_fixed
edu-acc.cn###doyoo_monitor
fx678.com##[class^="adv-"]
||76fengyun.com/body22233.js
||76fengyun.com/file/$s@onclick="window.open('*');startWait();"@onclick="window.open(document.getElementById('downpage_link').href);startWait();"@
||atanx.alicdn.com/t/tanxssp.js?_v=
||biquguan.com/guan/$script
||djv99sxoqpv11.cloudfront.net
||jmxlaser.com
||jump2.bdimg.com/p/$s@<div class="l_post l_post_bright j_l_post clearfix ?????????? "@<div style="display:none"@
||nxkycx.com
||res.jklan.cn/wp-content/themes/tt/js/system.js?ver=$s@function goto()@function xxx()@
||tieba.com/p/$s@<div class="l_post l_post_bright j_l_post clearfix ?????????? "@<div style="display:none"@
||ychap.com
!-----------------------
/qkostn.js|
|http://mark.l.qq.com/fcgi-bin/get_video_mark_all*&strAdParam=
!---------adbyby---------

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -1,10 +0,0 @@
;¸üйæÔòurl,dir,size,reverse,reverse
http://update.adbyby.com/rule3/lazy.jpg \data\lazy.txt 385337 4 0
http://update.adbyby.com/rule3/video.jpg \data\video.txt 1028 4 0
http://update.adbyby.com/rule3/user.action \user.action 512 5 0
http://update.adbyby.com/rule3/clean.ini \data\clean.ini 2167 0 0
http://update.adbyby.com/rule3/adclear.ini \data\adclear.ini 4901 0 0
https://github.com/gchangchen/suho/raw/master/adhook.dll \adhook.dll 117248 0 0 2.4.3.2
https://github.com/gchangchen/suho/raw/master/adhook64.dll \adhook64.dll 142848 0 0 2.4.3.2
https://github.com/gchangchen/suho/raw/master/adbyby.exe \adbyby.exe 1004183 1 0 2.4.4.0

Binary file not shown.

View File

@ -1,84 +0,0 @@
#
# Copyright (C) 2010-2023 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=autocore
PKG_RELEASE:=$(COMMITCOUNT)
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/target.mk
define Package/autocore-arm
TITLE:=Arm auto core loadbalance script
DEPENDS:=@(arm||aarch64) \
+TARGET_bcm27xx:bcm27xx-userland \
+TARGET_bcm53xx:nvram +ethtool
VARIANT:=arm
endef
define Package/autocore-loongarch64
TITLE:=Loongarch64 auto core loadbalance script
DEPENDS:=@loongarch64 +bc +ethtool +pciutils
VARIANT:=loongarch64
endef
define Package/autocore-x86
TITLE:=x86/64 auto core loadbalance script
DEPENDS:=@TARGET_x86 +bc +ethtool +lm-sensors +pciutils
VARIANT:=x86
endef
define Build/Compile
endef
define Package/autocore-arm/install
$(INSTALL_DIR) $(1)/etc
$(INSTALL_DATA) ./files/arm/index.htm $(1)/etc/index.htm
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/60-autocore-reload-rpcd $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/arm/090-cover-index_htm $(1)/etc/uci-defaults/
$(INSTALL_DIR) $(1)/sbin
$(INSTALL_BIN) ./files/arm/sbin/cpuinfo $(1)/sbin/cpuinfo
$(INSTALL_BIN) ./files/arm/sbin/ethinfo $(1)/sbin/ethinfo
$(INSTALL_BIN) ./files/arm/sbin/usage $(1)/sbin/usage
ifneq ($(filter ipq% %filogic qualcommax%, $(TARGETID)),)
$(INSTALL_BIN) ./files/arm/sbin/tempinfo $(1)/sbin/tempinfo
endif
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
$(CP) ./files/luci-mod-status-autocore.json $(1)/usr/share/rpcd/acl.d/
endef
define Package/autocore-loongarch64/install
$(INSTALL_DIR) $(1)/etc
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/loongarch64/autocore $(1)/etc/init.d/autocore
$(INSTALL_BIN) ./files/60-autocore-reload-rpcd $(1)/etc/uci-defaults/
$(INSTALL_DIR) $(1)/sbin
$(INSTALL_BIN) ./files/loongarch64/sbin/cpuinfo $(1)/sbin/cpuinfo
$(INSTALL_BIN) ./files/loongarch64/sbin/tempinfo $(1)/sbin/tempinfo
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
$(CP) ./files/luci-mod-status-autocore.json $(1)/usr/share/rpcd/acl.d/
endef
define Package/autocore-x86/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/x86/autocore $(1)/etc/init.d/autocore
$(INSTALL_DIR) $(1)/etc
$(INSTALL_DATA) ./files/x86/index.htm $(1)/etc/index.htm
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/60-autocore-reload-rpcd $(1)/etc/uci-defaults/
$(INSTALL_DIR) $(1)/sbin
$(CP) ./files/x86/sbin/* $(1)/sbin
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
$(CP) ./files/luci-mod-status-autocore.json $(1)/usr/share/rpcd/acl.d/
endef
$(eval $(call BuildPackage,autocore-arm))
$(eval $(call BuildPackage,autocore-loongarch64))
$(eval $(call BuildPackage,autocore-x86))

View File

@ -1,5 +0,0 @@
#!/bin/sh
/etc/init.d/rpcd restart
exit 0

View File

@ -1,5 +0,0 @@
#!/bin/sh
[ -f /etc/index.htm ] && mv /etc/index.htm /usr/lib/lua/luci/view/admin_status/index.htm
exit 0

View File

@ -1,857 +0,0 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008-2011 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<%
local fs = require "nixio.fs"
local util = require "luci.util"
local stat = require "luci.tools.status"
local ver = require "luci.version"
local uci = require("luci.model.uci").cursor()
local has_ipv6 = fs.access("/usr/sbin/ip6tables")
local has_dhcp = fs.access("/etc/config/dhcp")
local has_wifi = ((fs.stat("/etc/config/wireless", "size") or 0) > 0)
local has_switch = false
uci:foreach("network", "switch",
function(s)
has_switch = true
return false
end)
local sysinfo = luci.util.ubus("system", "info") or { }
local boardinfo = luci.util.ubus("system", "board") or { }
local unameinfo = nixio.uname() or { }
local meminfo = sysinfo.memory or {
total = 0,
free = 0,
buffered = 0,
shared = 0
}
local mem_cached = luci.sys.exec("sed -e '/^Cached: /!d; s#Cached: *##; s# kB##g' /proc/meminfo")
local swapinfo = sysinfo.swap or {
total = 0,
free = 0
}
local has_dsl = fs.access("/etc/init.d/dsl_control")
if luci.http.formvalue("status") == "1" then
local ntm = require "luci.model.network".init()
local wan = ntm:get_wannet()
local wan6 = ntm:get_wan6net()
local conn_count = tonumber(
fs.readfile("/proc/sys/net/netfilter/nf_conntrack_count") or "") or 0
local conn_max = tonumber(luci.sys.exec(
"sysctl -n -e net.nf_conntrack_max net.ipv4.netfilter.ip_conntrack_max"
):match("%d+")) or 4096
local user_info = luci.sys.exec("cat /proc/net/arp | grep 'br-lan' | grep '0x2' | wc -l")
local cpu_usage = luci.sys.exec("/sbin/usage") or "6%"
local cpu_info = luci.sys.exec("/sbin/cpuinfo") or "?"
local eth_info = luci.sys.exec("ethinfo")
local rv = {
cpuinfo = cpu_info,
cpuusage = cpu_usage,
ethinfo = eth_info,
userinfo = user_info,
uptime = sysinfo.uptime or 0,
localtime = os.date(),
loadavg = sysinfo.load or { 0, 0, 0 },
memory = meminfo,
memcached = mem_cached,
swap = swapinfo,
connmax = conn_max,
conncount = conn_count,
leases = stat.dhcp_leases(),
leases6 = stat.dhcp6_leases(),
wifinets = stat.wifi_networks()
}
if wan then
rv.wan = {
ipaddr = wan:ipaddr(),
gwaddr = wan:gwaddr(),
netmask = wan:netmask(),
dns = wan:dnsaddrs(),
expires = wan:expires(),
uptime = wan:uptime(),
proto = wan:proto(),
ifname = wan:ifname(),
link = wan:adminlink()
}
end
if wan6 then
rv.wan6 = {
ip6addr = wan6:ip6addr(),
gw6addr = wan6:gw6addr(),
dns = wan6:dns6addrs(),
ip6prefix = wan6:ip6prefix(),
uptime = wan6:uptime(),
proto = wan6:proto(),
ifname = wan6:ifname(),
link = wan6:adminlink()
}
end
if has_dsl then
local dsl_stat = luci.sys.exec("/etc/init.d/dsl_control lucistat")
local dsl_func = loadstring(dsl_stat)
if dsl_func then
rv.dsl = dsl_func()
end
end
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
elseif luci.http.formvalue("hosts") == "1" then
luci.http.prepare_content("application/json")
luci.http.write_json(luci.sys.net.host_hints())
return
end
-%>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
function progressbar(v, m)
{
var vn = parseInt(v) || 0;
var mn = parseInt(m) || 100;
var pc = Math.floor((100 / mn) * vn);
return String.format(
'<div style="width:200px; position:relative; border:1px solid #999999">' +
'<div style="background-color:#CCCCCC; width:%d%%; height:15px">' +
'<div style="position:absolute; left:0; top:0; text-align:center; width:100%%; color:#000000">' +
'<small>%s / %s (%d%%)</small>' +
'</div>' +
'</div>' +
'</div>', pc, v, m, pc
);
}
function wifirate(bss, rx) {
var p = rx ? 'rx_' : 'tx_',
s = '%.1f <%:Mbit/s%>, %d<%:MHz%>'
.format(bss[p+'rate'] / 1000, bss[p+'mhz']),
ht = bss[p+'ht'], vht = bss[p+'vht'],
mhz = bss[p+'mhz'], nss = bss[p+'nss'],
mcs = bss[p+'mcs'], sgi = bss[p+'short_gi'],
he = bss[p+'he'], he_gi = bss[p+'he_gi'],
he_dcm = bss[p+'he_dcm'];
if (ht || vht) {
if (vht) s += ', VHT-MCS %d'.format(mcs);
if (nss) s += ', VHT-NSS %d'.format(nss);
if (ht) s += ', MCS %s'.format(mcs);
if (sgi) s += ', <%:Short GI%>';
}
if (he) {
s += ', HE-MCS %d'.format(mcs);
if (nss) s += ', HE-NSS %d'.format(nss);
if (he_gi) s += ', HE-GI %d'.format(he_gi);
if (he_dcm) s += ', HE-DCM %d'.format(he_dcm);
}
return s;
}
function duid2mac(duid) {
// DUID-LLT / Ethernet
if (duid.length === 28 && duid.substr(0, 8) === '00010001')
return duid.substr(16).replace(/(..)(?=..)/g, '$1:').toUpperCase();
// DUID-LL / Ethernet
if (duid.length === 20 && duid.substr(0, 8) === '00030001')
return duid.substr(8).replace(/(..)(?=..)/g, '$1:').toUpperCase();
return null;
}
var npoll = 1;
var hosts = <%=luci.http.write_json(luci.sys.net.host_hints())%>;
function updateHosts() {
XHR.get('<%=REQUEST_URI%>', { hosts: 1 }, function(x, data) {
hosts = data;
});
}
XHR.poll(5, '<%=REQUEST_URI%>', { status: 1 },
function(x, info)
{
if (!(npoll++ % 5))
updateHosts();
var si = document.getElementById('wan4_i');
var ss = document.getElementById('wan4_s');
var ifc = info.wan;
if (ifc && ifc.ifname && ifc.proto != 'none')
{
var s = String.format(
'<strong><%:Type%>: </strong>%s<br />' +
'<strong><%:Address%>: </strong>%s<br />' +
'<strong><%:Netmask%>: </strong>%s<br />' +
'<strong><%:Gateway%>: </strong>%s<br />',
ifc.proto,
(ifc.ipaddr) ? ifc.ipaddr : '0.0.0.0',
(ifc.netmask && ifc.netmask != ifc.ipaddr) ? ifc.netmask : '255.255.255.255',
(ifc.gwaddr) ? ifc.gwaddr : '0.0.0.0'
);
for (var i = 0; i < ifc.dns.length; i++)
{
s += String.format(
'<strong><%:DNS%> %d: </strong>%s<br />',
i + 1, ifc.dns[i]
);
}
if (ifc.expires > -1)
{
s += String.format(
'<strong><%:Expires%>: </strong>%t<br />',
ifc.expires
);
}
if (ifc.uptime > 0)
{
s += String.format(
'<strong><%:Connected%>: </strong>%t<br />',
ifc.uptime
);
}
ss.innerHTML = String.format('<small>%s</small>', s);
si.innerHTML = String.format(
'<img src="<%=resource%>/icons/ethernet.png" />' +
'<br /><small><a href="%s">%s</a></small>',
ifc.link, ifc.ifname
);
}
else
{
si.innerHTML = '<img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small>';
ss.innerHTML = '<em><%:Not connected%></em>';
}
<% if has_ipv6 then %>
var si6 = document.getElementById('wan6_i');
var ss6 = document.getElementById('wan6_s');
var ifc6 = info.wan6;
if (ifc6 && ifc6.ifname && ifc6.proto != 'none')
{
var s = String.format(
'<strong><%:Type%>: </strong>%s%s<br />',
ifc6.proto, (ifc6.ip6prefix) ? '-pd' : ''
);
if (!ifc6.ip6prefix)
{
s += String.format(
'<strong><%:Address%>: </strong>%s<br />',
(ifc6.ip6addr) ? ifc6.ip6addr : '::'
);
}
else
{
s += String.format(
'<strong><%:Prefix Delegated%>: </strong>%s<br />',
ifc6.ip6prefix
);
if (ifc6.ip6addr)
{
s += String.format(
'<strong><%:Address%>: </strong>%s<br />',
ifc6.ip6addr
);
}
}
s += String.format(
'<strong><%:Gateway%>: </strong>%s<br />',
(ifc6.gw6addr) ? ifc6.gw6addr : '::'
);
for (var i = 0; i < ifc6.dns.length; i++)
{
s += String.format(
'<strong><%:DNS%> %d: </strong>%s<br />',
i + 1, ifc6.dns[i]
);
}
if (ifc6.uptime > 0)
{
s += String.format(
'<strong><%:Connected%>: </strong>%t<br />',
ifc6.uptime
);
}
ss6.innerHTML = String.format('<small>%s</small>', s);
si6.innerHTML = String.format(
'<img src="<%=resource%>/icons/ethernet.png" />' +
'<br /><small><a href="%s">%s</a></small>',
ifc6.link, ifc6.ifname
);
}
else
{
si6.innerHTML = '<img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small>';
ss6.innerHTML = '<em><%:Not connected%></em>';
}
<% end %>
<% if has_dsl then %>
var dsl_i = document.getElementById('dsl_i');
var dsl_s = document.getElementById('dsl_s');
var s = String.format(
'<strong><%:Status%>: </strong>%s<br />' +
'<strong><%:Line State%>: </strong>%s [0x%x]<br />' +
'<strong><%:Line Mode%>: </strong>%s<br />' +
'<strong><%:Annex%>: </strong>%s<br />' +
'<strong><%:Profile%>: </strong>%s<br />' +
'<strong><%:Data Rate%>: </strong>%s/s / %s/s<br />' +
'<strong><%:Max. Attainable Data Rate (ATTNDR)%>: </strong>%s/s / %s/s<br />' +
'<strong><%:Latency%>: </strong>%s / %s<br />' +
'<strong><%:Line Attenuation (LATN)%>: </strong>%s dB / %s dB<br />' +
'<strong><%:Signal Attenuation (SATN)%>: </strong>%s dB / %s dB<br />' +
'<strong><%:Noise Margin (SNR)%>: </strong>%s dB / %s dB<br />' +
'<strong><%:Aggregate Transmit Power(ACTATP)%>: </strong>%s dB / %s dB<br />' +
'<strong><%:Forward Error Correction Seconds (FECS)%>: </strong>%s / %s<br />' +
'<strong><%:Errored seconds (ES)%>: </strong>%s / %s<br />' +
'<strong><%:Severely Errored Seconds (SES)%>: </strong>%s / %s<br />' +
'<strong><%:Loss of Signal Seconds (LOSS)%>: </strong>%s / %s<br />' +
'<strong><%:Unavailable Seconds (UAS)%>: </strong>%s / %s<br />' +
'<strong><%:Header Error Code Errors (HEC)%>: </strong>%s / %s<br />' +
'<strong><%:Non Pre-emtive CRC errors (CRC_P)%>: </strong>%s / %s<br />' +
'<strong><%:Pre-emtive CRC errors (CRCP_P)%>: </strong>%s / %s<br />' +
'<strong><%:Line Uptime%>: </strong>%s<br />' +
'<strong><%:ATU-C System Vendor ID%>: </strong>%s<br />' +
'<strong><%:Power Management Mode%>: </strong>%s<br />',
info.dsl.line_state, info.dsl.line_state_detail,
info.dsl.line_state_num,
info.dsl.line_mode_s,
info.dsl.annex_s,
info.dsl.profile_s,
info.dsl.data_rate_down_s, info.dsl.data_rate_up_s,
info.dsl.max_data_rate_down_s, info.dsl.max_data_rate_up_s,
info.dsl.latency_num_down, info.dsl.latency_num_up,
info.dsl.line_attenuation_down, info.dsl.line_attenuation_up,
info.dsl.signal_attenuation_down, info.dsl.signal_attenuation_up,
info.dsl.noise_margin_down, info.dsl.noise_margin_up,
info.dsl.actatp_down, info.dsl.actatp_up,
info.dsl.errors_fec_near, info.dsl.errors_fec_far,
info.dsl.errors_es_near, info.dsl.errors_es_far,
info.dsl.errors_ses_near, info.dsl.errors_ses_far,
info.dsl.errors_loss_near, info.dsl.errors_loss_far,
info.dsl.errors_uas_near, info.dsl.errors_uas_far,
info.dsl.errors_hec_near, info.dsl.errors_hec_far,
info.dsl.errors_crc_p_near, info.dsl.errors_crc_p_far,
info.dsl.errors_crcp_p_near, info.dsl.errors_crcp_p_far,
info.dsl.line_uptime_s,
info.dsl.atuc_vendor_id,
info.dsl.power_mode_s
);
dsl_s.innerHTML = String.format('<small>%s</small>', s);
dsl_i.innerHTML = String.format(
'<img src="<%=resource%>/icons/ethernet.png" />' +
'<br /><small>DSL</small>'
);
<% end %>
<% if has_dhcp then %>
var ls = document.getElementById('lease_status_table');
if (ls)
{
/* clear all rows */
while( ls.rows.length > 1 )
ls.rows[0].parentNode.deleteRow(1);
for( var i = 0; i < info.leases.length; i++ )
{
var timestr;
if (info.leases[i].expires === false)
timestr = '<em><%:unlimited%></em>';
else if (info.leases[i].expires <= 0)
timestr = '<em><%:expired%></em>';
else
timestr = String.format('%t', info.leases[i].expires);
var tr = ls.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
tr.insertCell(-1).innerHTML = info.leases[i].hostname ? info.leases[i].hostname : '?';
tr.insertCell(-1).innerHTML = info.leases[i].ipaddr;
tr.insertCell(-1).innerHTML = info.leases[i].macaddr;
tr.insertCell(-1).innerHTML = timestr;
}
if( ls.rows.length == 1 )
{
var tr = ls.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 4;
td.innerHTML = '<em><br /><%:There are no active leases.%></em>';
}
}
var ls6 = document.getElementById('lease6_status_table');
if (ls6 && info.leases6)
{
ls6.parentNode.style.display = 'block';
/* clear all rows */
while( ls6.rows.length > 1 )
ls6.rows[0].parentNode.deleteRow(1);
for( var i = 0; i < info.leases6.length; i++ )
{
var timestr;
if (info.leases6[i].expires === false)
timestr = '<em><%:unlimited%></em>';
else if (info.leases6[i].expires <= 0)
timestr = '<em><%:expired%></em>';
else
timestr = String.format('%t', info.leases6[i].expires);
var tr = ls6.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
var host = hosts[duid2mac(info.leases6[i].duid)];
if (!info.leases6[i].hostname)
tr.insertCell(-1).innerHTML =
(host && (host.name || host.ipv4 || host.ipv6))
? '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space: nowrap">? (%h)</div>'.format(host.name || host.ipv4 || host.ipv6)
: '?';
else
tr.insertCell(-1).innerHTML =
(host && host.name && info.leases6[i].hostname != host.name)
? '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space: nowrap">%h (%h)</div>'.format(info.leases6[i].hostname, host.name)
: info.leases6[i].hostname;
tr.insertCell(-1).innerHTML = info.leases6[i].ip6addr;
tr.insertCell(-1).innerHTML = info.leases6[i].duid;
tr.insertCell(-1).innerHTML = timestr;
}
if( ls6.rows.length == 1 )
{
var tr = ls6.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 4;
td.innerHTML = '<em><br /><%:There are no active leases.%></em>';
}
}
<% end %>
<% if has_wifi then %>
var assoclist = [ ];
var ws = document.getElementById('wifi_status_table');
if (ws)
{
var wsbody = ws.rows[0].parentNode;
while (ws.rows.length > 0)
wsbody.deleteRow(0);
for (var didx = 0; didx < info.wifinets.length; didx++)
{
var dev = info.wifinets[didx];
var tr = wsbody.insertRow(-1);
var td;
td = tr.insertCell(-1);
td.width = "33%";
td.innerHTML = dev.name;
td.style.verticalAlign = "top";
td = tr.insertCell(-1);
var s = '';
for (var nidx = 0; nidx < dev.networks.length; nidx++)
{
var net = dev.networks[nidx];
var is_assoc = (net.bssid != '00:00:00:00:00:00' && net.channel && !net.disabled);
var icon;
if (!is_assoc)
icon = "<%=resource%>/icons/signal-none.png";
else if (net.quality == 0)
icon = "<%=resource%>/icons/signal-0.png";
else if (net.quality < 25)
icon = "<%=resource%>/icons/signal-0-25.png";
else if (net.quality < 50)
icon = "<%=resource%>/icons/signal-25-50.png";
else if (net.quality < 75)
icon = "<%=resource%>/icons/signal-50-75.png";
else
icon = "<%=resource%>/icons/signal-75-100.png";
s += String.format(
'<table><tr><td style="text-align:center; width:32px; padding:3px">' +
'<img src="%s" title="<%:Signal%>: %d dBm / <%:Noise%>: %d dBm" />' +
'<br /><small>%d%%</small>' +
'</td><td style="text-align:left; padding:3px"><small>' +
'<strong><%:SSID%>:</strong> <a href="%s">%h</a><br />' +
'<strong><%:Mode%>:</strong> %s<br />' +
'<strong><%:Channel%>:</strong> %d (%.3f <%:GHz%>)<br />' +
'<strong><%:Bitrate%>:</strong> %s <%:Mbit/s%><br />',
icon, net.signal, net.noise,
net.quality,
net.link, net.ssid || '?',
net.mode,
net.channel, net.frequency,
net.bitrate || '?'
);
if (is_assoc)
{
s += String.format(
'<strong><%:BSSID%>:</strong> %s<br />' +
'<strong><%:Encryption%>:</strong> %s',
net.bssid || '?',
net.encryption
);
}
else
{
s += '<em><%:Wireless is disabled or not associated%></em>';
}
s += '</small></td></tr></table>';
for (var bssid in net.assoclist)
{
var bss = net.assoclist[bssid];
bss.bssid = bssid;
bss.link = net.link;
bss.name = net.name;
bss.ifname = net.ifname;
bss.radio = dev.name;
assoclist.push(bss);
}
}
if (!s)
s = '<em><%:No information available%></em>';
td.innerHTML = s;
}
}
var ac = document.getElementById('wifi_assoc_table');
if (ac)
{
/* clear all rows */
while( ac.rows.length > 1 )
ac.rows[0].parentNode.deleteRow(1);
assoclist.sort(function(a, b) {
return (a.name == b.name)
? (a.bssid < b.bssid)
: (a.name > b.name )
;
});
for( var i = 0; i < assoclist.length; i++ )
{
var tr = ac.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + (1 + (i % 2));
var icon;
var q = (-1 * (assoclist[i].noise - assoclist[i].signal)) / 5;
if (q < 1)
icon = "<%=resource%>/icons/signal-0.png";
else if (q < 2)
icon = "<%=resource%>/icons/signal-0-25.png";
else if (q < 3)
icon = "<%=resource%>/icons/signal-25-50.png";
else if (q < 4)
icon = "<%=resource%>/icons/signal-50-75.png";
else
icon = "<%=resource%>/icons/signal-75-100.png";
tr.insertCell(-1).innerHTML = String.format(
'<span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> %h</span>',
assoclist[i].radio, assoclist[i].ifname
);
tr.insertCell(-1).innerHTML = String.format(
'<a href="%s">%s</a>',
assoclist[i].link,
'%h'.format(assoclist[i].name).nobr()
);
tr.insertCell(-1).innerHTML = assoclist[i].bssid;
var host = hosts[assoclist[i].bssid];
if (host)
tr.insertCell(-1).innerHTML = String.format(
'<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis">%s</div>',
((host.name && (host.ipv4 || host.ipv6))
? '%h (%s)'.format(host.name, host.ipv4 || host.ipv6)
: '%h'.format(host.name || host.ipv4 || host.ipv6)).nobr()
);
else
tr.insertCell(-1).innerHTML = '?';
tr.insertCell(-1).innerHTML = String.format(
'<span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span>',
assoclist[i].signal, assoclist[i].noise, assoclist[i].signal - assoclist[i].noise,
icon,
assoclist[i].signal, assoclist[i].noise
);
tr.insertCell(-1).innerHTML = wifirate(assoclist[i], true).nobr() + '<br />' + wifirate(assoclist[i], false).nobr();
}
if (ac.rows.length == 1)
{
var tr = ac.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 7;
td.innerHTML = '<br /><em><%:No information available%></em>';
}
}
<% end %>
var e;
if (e = document.getElementById('ethinfo')) {
var ports = eval('(' + info.ethinfo + ')');
var tmp = "";
for (var i in ports)
{
tmp = tmp + String.format(
'<td style="text-align:center"><span style="line-height:25px">%s</span><br /><small><img src="<%=resource%>/icons/%s" /><br />%s<br />%s</small></td>', ports[i].name,
ports[i].status ? 'port_up.png' : 'port_down.png',
ports[i].speed,
ports[i].duplex ? '<%:full-duplex%>' : '<%:half-duplex%>');
};
e.innerHTML = "<tr>" + tmp + "</tr>";
}
if (e = document.getElementById('localtime'))
e.innerHTML = info.localtime;
if (e = document.getElementById('uptime'))
e.innerHTML = String.format('%t', info.uptime);
if (e = document.getElementById('userinfo'))
e.innerHTML = info.userinfo;
if (e = document.getElementById('cpuusage'))
e.innerHTML = info.cpuusage;
if (e = document.getElementById('cpuinfo'))
e.innerHTML = info.cpuinfo;
if (e = document.getElementById('loadavg'))
e.innerHTML = String.format(
'%.02f, %.02f, %.02f',
info.loadavg[0] / 65535.0,
info.loadavg[1] / 65535.0,
info.loadavg[2] / 65535.0
);
if (e = document.getElementById('memtotal'))
e.innerHTML = progressbar(
Math.floor(((info.memory.free + info.memory.buffered) / 1048576) + (info.memcached / 1024)) + " <%:MB%>",
Math.floor(info.memory.total / 1048576) + " <%:MB%>"
);
if (e = document.getElementById('membuff'))
e.innerHTML = progressbar(
Math.floor(info.memory.buffered / 1048576) + " <%:MB%>",
Math.floor(info.memory.total / 1048576) + " <%:MB%>"
);
if (e = document.getElementById('swaptotal'))
e.innerHTML = progressbar(
Math.floor(info.swap.free / 1048576) + " <%:MB%>",
Math.floor(info.swap.total / 1048576) + " <%:MB%>"
);
if (e = document.getElementById('swapfree'))
e.innerHTML = progressbar(
Math.floor(info.swap.free / 1048576) + " <%:MB%>",
Math.floor(info.swap.total / 1048576) + " <%:MB%>"
);
if (e = document.getElementById('conns'))
e.innerHTML = progressbar(info.conncount, info.connmax);
}
);
//]]></script>
<h2 name="content"><%:Status%></h2>
<fieldset class="cbi-section">
<legend><%:System%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%"><%:Hostname%></td><td><%=luci.sys.hostname() or "?"%></td></tr>
<tr><td width="33%"><%:Model%></td><td><%=pcdata(boardinfo.model or "?")%> <%=luci.sys.exec("cat /etc/bench.log") or ""%></td></tr>
<tr><td width="33%"><%:Architecture%></td><td id="cpuinfo">-</td></tr>
<tr><td width="33%"><%:Firmware Version%></td><td>
<%=pcdata(ver.distname)%> <%=pcdata(ver.distversion)%> /
<%=pcdata(ver.luciname)%> (<%=pcdata(ver.luciversion)%>)
</td></tr>
<tr><td width="33%"><%:Kernel Version%></td><td><%=luci.sys.exec("uname -r | awk -F '-' '{print $1}'") or "?"%></td></tr>
<tr><td width="33%"><%:Local Time%></td><td id="localtime">-</td></tr>
<tr><td width="33%"><%:Uptime%></td><td id="uptime">-</td></tr>
<tr><td width="33%"><%:Load Average%></td><td id="loadavg">-</td></tr>
<tr><td width="33%"><%:CPU usage%></td><td id="cpuusage">-</td></tr>
</table>
</fieldset>
<fieldset class="cbi-section">
<legend><%:Memory%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%"><%:Total Available%></td><td id="memtotal">-</td></tr>
<tr><td width="33%"><%:Buffered%></td><td id="membuff">-</td></tr>
</table>
</fieldset>
<% if swapinfo.total > 0 then %>
<fieldset class="cbi-section">
<legend><%:Swap%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%"><%:Total Available%></td><td id="swaptotal">-</td></tr>
<tr><td width="33%"><%:Free%></td><td id="swapfree">-</td></tr>
</table>
</fieldset>
<% end %>
<% if not has_switch then %>
<fieldset class="cbi-section">
<legend><%:Interfaces%></legend>
<table width="100%" cellspacing="10" id="ethinfo">
</table>
</fieldset>
<% end %>
<fieldset class="cbi-section">
<legend><%:Network%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%" style="vertical-align:top"><%:IPv4 WAN Status%></td><td>
<table><tr>
<td id="wan4_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></td>
<td id="wan4_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></td>
</tr></table>
</td></tr>
<% if has_ipv6 then %>
<tr><td width="33%" style="vertical-align:top"><%:IPv6 WAN Status%></td><td>
<table><tr>
<td id="wan6_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></td>
<td id="wan6_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></td>
</tr></table>
</td></tr>
<% end %>
<tr><td width="33%"><%:Online Users%></td><td id="userinfo">0</td></tr>
<tr><td width="33%"><%:Active Connections%></td><td id="conns">-</td></tr>
</table>
</fieldset>
<% if has_dhcp then %>
<fieldset class="cbi-section">
<legend><%:DHCP Leases%></legend>
<table class="cbi-section-table" id="lease_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Hostname%></th>
<th class="cbi-section-table-cell"><%:IPv4-Address%></th>
<th class="cbi-section-table-cell"><%:MAC-Address%></th>
<th class="cbi-section-table-cell"><%:Leasetime remaining%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="4"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
<% if has_ipv6 then %>
<fieldset class="cbi-section" style="display:none">
<legend><%:DHCPv6 Leases%></legend>
<table class="cbi-section-table" id="lease6_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Host%></th>
<th class="cbi-section-table-cell"><%:IPv6-Address%></th>
<th class="cbi-section-table-cell"><%:DUID%></th>
<th class="cbi-section-table-cell"><%:Leasetime remaining%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="4"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
<% end %>
<% end %>
<% if has_dsl then %>
<fieldset class="cbi-section">
<legend><%:DSL%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%" style="vertical-align:top"><%:DSL Status%></td><td>
<table><tr>
<td id="dsl_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></td>
<td id="dsl_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></td>
</tr></table>
</td></tr>
</table>
</fieldset>
<% end %>
<% if has_wifi then %>
<fieldset class="cbi-section">
<legend><%:Wireless%></legend>
<table id="wifi_status_table" width="100%" cellspacing="10">
<tr><td><em><%:Collecting data...%></em></td></tr>
</table>
</fieldset>
<% end %>
<%+footer%>

View File

@ -1,45 +0,0 @@
#!/bin/sh
cpu_arch="$(cat "/proc/cpuinfo" | grep "model name" | sed -n "1p" | awk -F ': ' '{print $2}')"
[ -z "${cpu_arch}" ] && cpu_arch="ARMv8 Processor"
cpu_cores="$(cat "/proc/cpuinfo" | grep "processor" | wc -l)"
if grep -q "bcm27xx" "/etc/openwrt_release"; then
cpu_freq="$(expr $(vcgencmd measure_clock arm | awk -F '=' '{print $2}') / 1000000)Mhz"
elif grep -q "bcm53xx" "/etc/openwrt_release"; then
cpu_freq="$(nvram get clkfreq | awk -F ',' '{print $1}')MHz"
elif grep -q "mvebu" "/etc/openwrt_release"; then
cpu_freq="$(cat "/proc/cpuinfo" | grep "BogoMIPS" | sed -n "1p" | awk -F ': ' '{print $2}')MHz"
elif grep -q "filogic" "/etc/openwrt_release"; then
[ -f "/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq" ] && big_cpu_freq="$(expr $(cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq) / 1000)MHz"
elif grep -q "rockchip" "/etc/openwrt_release"; then
cpu_freq="$(expr $(cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq) / 1000)MHz"
big_cpu_freq="$(expr $(cat /sys/devices/system/cpu/cpufreq/policy4/cpuinfo_cur_freq 2>"/dev/null") / 1000 2>"/dev/null")"
[ -n "${big_cpu_freq}" ] && big_cpu_freq="${big_cpu_freq}MHz "
else
cpu_freq="$(expr $(cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq) / 1000)MHz"
fi
if grep -q "ipq" "/etc/openwrt_release"; then
if grep -q "ipq40xx" "/etc/openwrt_release"; then
sys_temp="$(awk '{ printf("%.1f°C ", $0 / 1000) }' /sys/class/ieee80211/phy*/device/hwmon/hwmon*/temp1_input)"
else
sys_temp="$(awk '{ printf("%.1f°C ", $0 / 1000) }' /sys/class/thermal/thermal_zone0/temp)"
fi
echo -n "${cpu_arch} x ${cpu_cores} (${cpu_freq}, ${sys_temp})"
else
if grep -q "bcm27xx" "/etc/openwrt_release"; then
cpu_temp="$(vcgencmd measure_temp | awk -F '=' '{print $2}' | awk -F "'" '{print $1}')°C"
else
cpu_temp="$(awk "BEGIN{printf (\"%.1f\n\",$(cat /sys/class/thermal/thermal_zone0/temp)/1000) }")°C"
fi
if grep -q "filogic" "/etc/openwrt_release"; then
if [ -n "${big_cpu_freq}" ] ; then
echo -n "${cpu_arch} x ${cpu_cores} (${big_cpu_freq}, ${cpu_temp})"
else
echo -n "${cpu_arch} x ${cpu_cores} (${cpu_temp})"
fi
else
echo -n "${cpu_arch} x ${cpu_cores} (${big_cpu_freq}${cpu_freq}, ${cpu_temp})"
fi
fi

View File

@ -1,45 +0,0 @@
#!/usr/bin/lua
-- Copyright (C) 2022 ImmortalWrt.org
local util = require "luci.util"
local jsonc = require "luci.jsonc"
local eth_info = {}
local ifname, stat
for ifname, stat in pairs(util.ubus("network.device", "status")) do
while true do
if (ifname:match("^(br-.+)$")) == ifname then
break
else
local status, speed, duplex
if(stat.speed ~= nil) then
status = stat.carrier and 1 or 0
if stat.speed:sub(1, 1) == "-" then
speed = " - "
else
speed = stat.speed:sub(1, -2) .. "Mb/s"
end
if stat.carrier and stat.speed:sub(-1) == "F" then
duplex = 1
else
duplex = 0
end
eth_info[#eth_info+1] = { name = ifname, status = status,
speed = speed, duplex = duplex }
end
break
end
end
end
table.sort(eth_info,
function(a, b)
return a.name < b.name
end)
print(jsonc.stringify(eth_info))

View File

@ -1,40 +0,0 @@
#!/bin/sh
. /etc/openwrt_release
IEEE_PATH="/sys/class/ieee80211"
THERMAL_PATH="/sys/class/thermal"
case "$DISTRIB_TARGET" in
ipq40xx/*|ipq806x/*)
wifi_temp="$(awk '{printf("%.1f°C ", $0 / 1000)}' "$IEEE_PATH"/phy*/device/hwmon/hwmon*/temp1_input 2>"/dev/null" | awk '$1=$1')"
;;
mediatek/mt7622)
wifi_temp="$(awk '{printf("%.1f°C ", $0 / 1000)}' "$IEEE_PATH"/wl*/hwmon*/temp1_input 2>"/dev/null" | awk '$1=$1')"
;;
*)
wifi_temp="$(awk '{printf("%.1f°C ", $0 / 1000)}' "$IEEE_PATH"/phy*/hwmon*/temp1_input 2>"/dev/null" | awk '$1=$1')"
;;
esac
case "$DISTRIB_TARGET" in
ipq40xx/*)
if [ -e "$IEEE_PATH/phy0/hwmon0/temp1_input" ]; then
mt76_temp="$(awk -F ': ' '{print $2}' "$IEEE_PATH/phy0/hwmon0/temp1_input" 2>"/dev/null")°C"
fi
[ -z "$mt76_temp" ] || wifi_temp="${wifi_temp:+$wifi_temp }$mt76_temp"
;;
*)
cpu_temp="$(awk '{printf("%.1f°C", $0 / 1000)}' "$THERMAL_PATH/thermal_zone0/temp" 2>"/dev/null")"
;;
esac
if [ -n "$cpu_temp" ] && [ -z "$wifi_temp" ]; then
echo -n "CPU: $cpu_temp"
elif [ -z "$cpu_temp" ] && [ -n "$wifi_temp" ]; then
echo -n "WiFi: $wifi_temp"
elif [ -n "$cpu_temp" ] && [ -n "$wifi_temp" ]; then
echo -n "CPU: $cpu_temp, WiFi: $wifi_temp"
else
echo -n "No temperature info"
fi

View File

@ -1,14 +0,0 @@
#!/bin/sh
NSS_PATH="/sys/kernel/debug/qca-nss-drv/stats"
cpu_usage="$(busybox top -n1 | awk '/^CPU/ {printf("%d%", 100 - $8)}')"
[ ! -d "$NSS_PATH" ] || \
npu_usage="$(grep '%' "$NSS_PATH"/cpu_load_ubi | awk -F ' ' '{print $2}')"
if [ -d "$NSS_PATH" ]; then
echo -n "CPU: ${cpu_usage}, NPU: ${npu_usage}"
else
echo -n "CPU: ${cpu_usage}"
fi

View File

@ -1,20 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2025 lean <coolsnowwolf@gmail.com>
START=99
start()
{
a=$(cat /proc/cpuinfo | grep 'Model Name' | cut -f2 -d: | head -n 1)
b=$(echo -n ' : ')
c=$(cat /proc/cpuinfo | grep 'core' | sort -u | wc -l)
d=$(echo -n 'C')
e=$(cat /proc/cpuinfo | grep 'global_id' | sort -u | wc -l)
f=$(echo -n 'T ')
g=$(cat /proc/cpuinfo | grep 'CPU Family' | cut -f2 -d: | head -n 1)
h=${g}' - '${a}${b}${c}${d}${e}${f}
mkdir -p /tmp/sysinfo
echo $h > /tmp/sysinfo/model
}

View File

@ -1,5 +0,0 @@
#!/bin/sh
MHz=`grep 'MHz' /proc/cpuinfo | cut -c13- |sed -n '1p'`
echo "$MHz MHz"

View File

@ -1,45 +0,0 @@
#!/usr/bin/lua
-- Copyright (C) 2022 ImmortalWrt.org
local util = require "luci.util"
local jsonc = require "luci.jsonc"
local eth_info = {}
local ifname, stat
for ifname, stat in pairs(util.ubus("network.device", "status")) do
while true do
if (ifname:match("^(br-.+)$")) == ifname then
break
else
local status, speed, duplex
if(stat.speed ~= nil) then
status = stat.carrier and 1 or 0
if stat.speed:sub(1, 1) == "-" then
speed = " - "
else
speed = stat.speed:sub(1, -2) .. "Mb/s"
end
if stat.carrier and stat.speed:sub(-1) == "F" then
duplex = 1
else
duplex = 0
end
eth_info[#eth_info+1] = { name = ifname, status = status,
speed = speed, duplex = duplex }
end
break
end
end
end
table.sort(eth_info,
function(a, b)
return a.name < b.name
end)
print(jsonc.stringify(eth_info))

View File

@ -1,5 +0,0 @@
#!/bin/sh
TEMP=`awk '{printf("%.1f°C", $0 / 1000)}' "/sys/class/thermal/thermal_zone0/temp" 2>"/dev/null"`
echo "$TEMP "

View File

@ -1,10 +0,0 @@
{
"luci-mod-status-autocore": {
"description": "Grant access to autocore",
"read": {
"ubus": {
"luci": [ "getCPUInfo", "getCPUUsage", "getTempInfo" ]
}
}
}
}

View File

@ -1,51 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2017 lean <coolsnowwolf@gmail.com>
START=99
start()
{
rfc=4096
cc=$(grep -c processor /proc/cpuinfo)
rsfe=$(echo $cc*$rfc | bc)
sysctl -w net.core.rps_sock_flow_entries=$rsfe >/dev/null
for fileRps in $(ls /sys/class/net/eth*/queues/rx-*/rps_cpus)
do
echo $cc > $fileRps
done
for fileRfc in $(ls /sys/class/net/eth*/queues/rx-*/rps_flow_cnt)
do
echo $rfc > $fileRfc
done
uci set network.@globals[0].packet_steering=1
uci commit network
all_pcis=`lspci | grep -i 'eth' | grep -i 'x550' | cut -d ' ' -f 1`
all_ifs=`cat /proc/net/dev | grep -i 'eth' | cut -d : -f 1 | sed 's/^[ \t]*//g'`
for ifname in ${all_ifs}
do
if_pci=`ethtool -i ${ifname} | grep -i 'bus-info' | cut -d : -f 3-`
if [[ "$all_pcis" =~ "$if_pci" ]]
then
ethtool -s ${ifname} advertise 0x1800000001028
fi
done
a=$(ip address | grep ^[0-9] | awk -F: '{print $2}' | sed "s/ //g" | grep '^[e]' | grep -v "@" | grep -v "\.")
b=$(echo "$a" | wc -l)
for i in $(seq 1 $b)
do
c=$(echo "$a" | sed -n ${i}p)
ethtool -K $c rx-checksum on >/dev/null 2>&1
ethtool -K $c tx-checksum-ip-generic on >/dev/null 2>&1 || (
ethtool -K $c tx-checksum-ipv4 on >/dev/null 2>&1
ethtool -K $c tx-checksum-ipv6 on >/dev/null 2>&1)
ethtool -K $c tx-scatter-gather on >/dev/null 2>&1
ethtool -K $c tso on >/dev/null 2>&1
done
[ -f /etc/index.htm ] && mv /etc/index.htm /usr/lib/lua/luci/view/admin_status/index.htm
}

View File

@ -1,864 +0,0 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008-2011 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<%
local fs = require "nixio.fs"
local util = require "luci.util"
local stat = require "luci.tools.status"
local ver = require "luci.version"
local has_ipv6 = fs.access("/usr/sbin/ip6tables")
local has_dhcp = fs.access("/etc/config/dhcp")
local has_wifi = ((fs.stat("/etc/config/wireless", "size") or 0) > 0)
local sysinfo = luci.util.ubus("system", "info") or { }
local boardinfo = luci.util.ubus("system", "board") or { }
local unameinfo = nixio.uname() or { }
local meminfo = sysinfo.memory or {
total = 0,
free = 0,
buffered = 0,
shared = 0
}
local mem_cached = luci.sys.exec("sed -e '/^Cached: /!d; s#Cached: *##; s# kB##g' /proc/meminfo")
local swapinfo = sysinfo.swap or {
total = 0,
free = 0
}
local has_dsl = fs.access("/etc/init.d/dsl_control")
if luci.http.formvalue("status") == "1" then
local ntm = require "luci.model.network".init()
local wan = ntm:get_wannet()
local wan6 = ntm:get_wan6net()
local conn_count = tonumber(
fs.readfile("/proc/sys/net/netfilter/nf_conntrack_count") or "") or 0
local conn_max = tonumber(luci.sys.exec(
"sysctl -n -e net.nf_conntrack_max net.ipv4.netfilter.ip_conntrack_max"
):match("%d+")) or 4096
local cpu_info = luci.sys.exec("cpuinfo")
local eth_info = luci.sys.exec("ethinfo")
local user_info = luci.sys.exec("cat /proc/net/arp | grep '0x2' | wc -l") or 0
local cpu_usage = (luci.sys.exec("expr 100 - $(top -n 1 | grep -E '^CPU:' | awk -F '%' '{print$4}' | awk -F ' ' '{print$2}' | awk '{print int($1 + 0.5)}')") or "6") .. "%"
local rv = {
cpuusage = cpu_usage,
cpuinfo = cpu_info,
ethinfo = eth_info,
userinfo = user_info,
uptime = sysinfo.uptime or 0,
localtime = os.date(),
loadavg = sysinfo.load or { 0, 0, 0 },
memory = meminfo,
memcached = mem_cached,
swap = swapinfo,
connmax = conn_max,
conncount = conn_count,
leases = stat.dhcp_leases(),
leases6 = stat.dhcp6_leases(),
wifinets = stat.wifi_networks()
}
if wan then
rv.wan = {
ipaddr = wan:ipaddr(),
gwaddr = wan:gwaddr(),
netmask = wan:netmask(),
dns = wan:dnsaddrs(),
expires = wan:expires(),
uptime = wan:uptime(),
proto = wan:proto(),
ifname = wan:ifname(),
link = wan:adminlink()
}
end
if wan6 then
rv.wan6 = {
ip6addr = wan6:ip6addr(),
gw6addr = wan6:gw6addr(),
dns = wan6:dns6addrs(),
ip6prefix = wan6:ip6prefix(),
uptime = wan6:uptime(),
proto = wan6:proto(),
ifname = wan6:ifname(),
link = wan6:adminlink()
}
end
if has_dsl then
local dsl_stat = luci.sys.exec("/etc/init.d/dsl_control lucistat")
local dsl_func = loadstring(dsl_stat)
if dsl_func then
rv.dsl = dsl_func()
end
end
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
elseif luci.http.formvalue("hosts") == "1" then
luci.http.prepare_content("application/json")
luci.http.write_json(luci.sys.net.host_hints())
return
end
-%>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js?v=git-19.167.54478-71e2af4"></script>
<script type="text/javascript">//<![CDATA[
function progressbar(v, m)
{
var vn = parseInt(v) || 0;
var mn = parseInt(m) || 100;
var pc = Math.floor((100 / mn) * vn);
return String.format(
'<div style="width:200px; position:relative; border:1px solid #999999">' +
'<div style="background-color:#CCCCCC; width:%d%%; height:15px">' +
'<div style="position:absolute; left:0; top:0; text-align:center; width:100%%; color:#000000">' +
'<small>%s / %s (%d%%)</small>' +
'</div>' +
'</div>' +
'</div>', pc, v, m, pc
);
}
function wifirate(bss, rx) {
var p = rx ? 'rx_' : 'tx_',
s = '%.1f <%:Mbit/s%>, %d<%:MHz%>'
.format(bss[p+'rate'] / 1000, bss[p+'mhz']),
ht = bss[p+'ht'], vht = bss[p+'vht'],
mhz = bss[p+'mhz'], nss = bss[p+'nss'],
mcs = bss[p+'mcs'], sgi = bss[p+'short_gi'],
he = bss[p+'he'], he_gi = bss[p+'he_gi'],
he_dcm = bss[p+'he_dcm'];
if (ht || vht) {
if (vht) s += ', VHT-MCS %d'.format(mcs);
if (nss) s += ', VHT-NSS %d'.format(nss);
if (ht) s += ', MCS %s'.format(mcs);
if (sgi) s += ', <%:Short GI%>';
}
if (he) {
s += ', HE-MCS %d'.format(mcs);
if (nss) s += ', HE-NSS %d'.format(nss);
if (he_gi) s += ', HE-GI %d'.format(he_gi);
if (he_dcm) s += ', HE-DCM %d'.format(he_dcm);
}
return s;
}
function duid2mac(duid) {
// DUID-LLT / Ethernet
if (duid.length === 28 && duid.substr(0, 8) === '00010001')
return duid.substr(16).replace(/(..)(?=..)/g, '$1:').toUpperCase();
// DUID-LL / Ethernet
if (duid.length === 20 && duid.substr(0, 8) === '00030001')
return duid.substr(8).replace(/(..)(?=..)/g, '$1:').toUpperCase();
return null;
}
var npoll = 1;
var hosts = <%=luci.http.write_json(luci.sys.net.host_hints())%>;
function updateHosts() {
XHR.get('<%=REQUEST_URI%>', { hosts: 1 }, function(x, data) {
hosts = data;
});
}
var compare = function (prop) {
return function (obj1, obj2) {
var val1 = Number(obj1[prop].replaceAll(".",""));
var val2 = Number(obj2[prop].replaceAll(".",""));
if (val1 < val2) {
return -1;
} else if (val1 > val2) {
return 1;
} else {
return 0;
}
}
};
XHR.poll(1, '<%=REQUEST_URI%>', { status: 1 },
function(x, info)
{
if (!(npoll++ % 5))
updateHosts();
var si = document.getElementById('wan4_i');
var ss = document.getElementById('wan4_s');
var ifc = info.wan;
if (ifc && ifc.ifname && ifc.proto != 'none')
{
var s = String.format(
'<strong><%:Type%>: </strong>%s<br />' +
'<strong><%:Address%>: </strong>%s<br />' +
'<strong><%:Netmask%>: </strong>%s<br />' +
'<strong><%:Gateway%>: </strong>%s<br />',
ifc.proto,
(ifc.ipaddr) ? ifc.ipaddr : '0.0.0.0',
(ifc.netmask && ifc.netmask != ifc.ipaddr) ? ifc.netmask : '255.255.255.255',
(ifc.gwaddr) ? ifc.gwaddr : '0.0.0.0'
);
for (var i = 0; i < ifc.dns.length; i++)
{
s += String.format(
'<strong><%:DNS%> %d: </strong>%s<br />',
i + 1, ifc.dns[i]
);
}
if (ifc.expires > -1)
{
s += String.format(
'<strong><%:Expires%>: </strong>%t<br />',
ifc.expires
);
}
if (ifc.uptime > 0)
{
s += String.format(
'<strong><%:Connected%>: </strong>%t<br />',
ifc.uptime
);
}
ss.innerHTML = String.format('<small>%s</small>', s);
si.innerHTML = String.format(
'<img src="<%=resource%>/icons/ethernet.png" />' +
'<br /><small><a href="%s">%s</a></small>',
ifc.link, ifc.ifname
);
}
else
{
si.innerHTML = '<img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small>';
ss.innerHTML = '<em><%:Not connected%></em>';
}
<% if has_ipv6 then %>
var si6 = document.getElementById('wan6_i');
var ss6 = document.getElementById('wan6_s');
var ifc6 = info.wan6;
if (ifc6 && ifc6.ifname && ifc6.proto != 'none')
{
var s = String.format(
'<strong><%:Type%>: </strong>%s%s<br />',
ifc6.proto, (ifc6.ip6prefix) ? '-pd' : ''
);
if (!ifc6.ip6prefix)
{
s += String.format(
'<strong><%:Address%>: </strong>%s<br />',
(ifc6.ip6addr) ? ifc6.ip6addr : '::'
);
}
else
{
s += String.format(
'<strong><%:Prefix Delegated%>: </strong>%s<br />',
ifc6.ip6prefix
);
if (ifc6.ip6addr)
{
s += String.format(
'<strong><%:Address%>: </strong>%s<br />',
ifc6.ip6addr
);
}
}
s += String.format(
'<strong><%:Gateway%>: </strong>%s<br />',
(ifc6.gw6addr) ? ifc6.gw6addr : '::'
);
for (var i = 0; i < ifc6.dns.length; i++)
{
s += String.format(
'<strong><%:DNS%> %d: </strong>%s<br />',
i + 1, ifc6.dns[i]
);
}
if (ifc6.uptime > 0)
{
s += String.format(
'<strong><%:Connected%>: </strong>%t<br />',
ifc6.uptime
);
}
ss6.innerHTML = String.format('<small>%s</small>', s);
si6.innerHTML = String.format(
'<img src="<%=resource%>/icons/ethernet.png" />' +
'<br /><small><a href="%s">%s</a></small>',
ifc6.link, ifc6.ifname
);
}
else
{
si6.innerHTML = '<img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small>';
ss6.innerHTML = '<em><%:Not connected%></em>';
}
<% end %>
<% if has_dsl then %>
var dsl_i = document.getElementById('dsl_i');
var dsl_s = document.getElementById('dsl_s');
var s = String.format(
'<strong><%:Status%>: </strong>%s<br />' +
'<strong><%:Line State%>: </strong>%s [0x%x]<br />' +
'<strong><%:Line Mode%>: </strong>%s<br />' +
'<strong><%:Annex%>: </strong>%s<br />' +
'<strong><%:Profile%>: </strong>%s<br />' +
'<strong><%:Data Rate%>: </strong>%s/s / %s/s<br />' +
'<strong><%:Max. Attainable Data Rate (ATTNDR)%>: </strong>%s/s / %s/s<br />' +
'<strong><%:Latency%>: </strong>%s / %s<br />' +
'<strong><%:Line Attenuation (LATN)%>: </strong>%s dB / %s dB<br />' +
'<strong><%:Signal Attenuation (SATN)%>: </strong>%s dB / %s dB<br />' +
'<strong><%:Noise Margin (SNR)%>: </strong>%s dB / %s dB<br />' +
'<strong><%:Aggregate Transmit Power(ACTATP)%>: </strong>%s dB / %s dB<br />' +
'<strong><%:Forward Error Correction Seconds (FECS)%>: </strong>%s / %s<br />' +
'<strong><%:Errored seconds (ES)%>: </strong>%s / %s<br />' +
'<strong><%:Severely Errored Seconds (SES)%>: </strong>%s / %s<br />' +
'<strong><%:Loss of Signal Seconds (LOSS)%>: </strong>%s / %s<br />' +
'<strong><%:Unavailable Seconds (UAS)%>: </strong>%s / %s<br />' +
'<strong><%:Header Error Code Errors (HEC)%>: </strong>%s / %s<br />' +
'<strong><%:Non Pre-emtive CRC errors (CRC_P)%>: </strong>%s / %s<br />' +
'<strong><%:Pre-emtive CRC errors (CRCP_P)%>: </strong>%s / %s<br />' +
'<strong><%:Line Uptime%>: </strong>%s<br />' +
'<strong><%:ATU-C System Vendor ID%>: </strong>%s<br />' +
'<strong><%:Power Management Mode%>: </strong>%s<br />',
info.dsl.line_state, info.dsl.line_state_detail,
info.dsl.line_state_num,
info.dsl.line_mode_s,
info.dsl.annex_s,
info.dsl.profile_s,
info.dsl.data_rate_down_s, info.dsl.data_rate_up_s,
info.dsl.max_data_rate_down_s, info.dsl.max_data_rate_up_s,
info.dsl.latency_num_down, info.dsl.latency_num_up,
info.dsl.line_attenuation_down, info.dsl.line_attenuation_up,
info.dsl.signal_attenuation_down, info.dsl.signal_attenuation_up,
info.dsl.noise_margin_down, info.dsl.noise_margin_up,
info.dsl.actatp_down, info.dsl.actatp_up,
info.dsl.errors_fec_near, info.dsl.errors_fec_far,
info.dsl.errors_es_near, info.dsl.errors_es_far,
info.dsl.errors_ses_near, info.dsl.errors_ses_far,
info.dsl.errors_loss_near, info.dsl.errors_loss_far,
info.dsl.errors_uas_near, info.dsl.errors_uas_far,
info.dsl.errors_hec_near, info.dsl.errors_hec_far,
info.dsl.errors_crc_p_near, info.dsl.errors_crc_p_far,
info.dsl.errors_crcp_p_near, info.dsl.errors_crcp_p_far,
info.dsl.line_uptime_s,
info.dsl.atuc_vendor_id,
info.dsl.power_mode_s
);
dsl_s.innerHTML = String.format('<small>%s</small>', s);
dsl_i.innerHTML = String.format(
'<img src="<%=resource%>/icons/ethernet.png" />' +
'<br /><small>DSL</small>'
);
<% end %>
<% if has_dhcp then %>
var ls = document.getElementById('lease_status_table');
if (ls)
{
info.leases = info.leases.sort(compare("ipaddr"));
/* clear all rows */
while( ls.rows.length > 1 )
ls.rows[0].parentNode.deleteRow(1);
for( var i = 0; i < info.leases.length; i++ )
{
var timestr;
if (info.leases[i].expires === false)
timestr = '<em><%:unlimited%></em>';
else if (info.leases[i].expires <= 0)
timestr = '<em><%:expired%></em>';
else
timestr = String.format('%t', info.leases[i].expires);
var tr = ls.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
tr.insertCell(-1).innerHTML = info.leases[i].hostname ? info.leases[i].hostname : '?';
tr.insertCell(-1).innerHTML = info.leases[i].ipaddr;
tr.insertCell(-1).innerHTML = info.leases[i].macaddr;
tr.insertCell(-1).innerHTML = timestr;
}
if( ls.rows.length == 1 )
{
var tr = ls.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 4;
td.innerHTML = '<em><br /><%:There are no active leases.%></em>';
}
}
var ls6 = document.getElementById('lease6_status_table');
if (ls6 && info.leases6)
{
ls6.parentNode.style.display = 'block';
/* clear all rows */
while( ls6.rows.length > 1 )
ls6.rows[0].parentNode.deleteRow(1);
for( var i = 0; i < info.leases6.length; i++ )
{
var timestr;
if (info.leases6[i].expires === false)
timestr = '<em><%:unlimited%></em>';
else if (info.leases6[i].expires <= 0)
timestr = '<em><%:expired%></em>';
else
timestr = String.format('%t', info.leases6[i].expires);
var tr = ls6.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
var host = hosts[duid2mac(info.leases6[i].duid)];
if (!info.leases6[i].hostname)
tr.insertCell(-1).innerHTML =
(host && (host.name || host.ipv4 || host.ipv6))
? '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space: nowrap">? (%h)</div>'.format(host.name || host.ipv4 || host.ipv6)
: '?';
else
tr.insertCell(-1).innerHTML =
(host && host.name && info.leases6[i].hostname != host.name)
? '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space: nowrap">%h (%h)</div>'.format(info.leases6[i].hostname, host.name)
: info.leases6[i].hostname;
tr.insertCell(-1).innerHTML = info.leases6[i].ip6addr;
tr.insertCell(-1).innerHTML = info.leases6[i].duid;
tr.insertCell(-1).innerHTML = timestr;
}
if( ls6.rows.length == 1 )
{
var tr = ls6.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 4;
td.innerHTML = '<em><br /><%:There are no active leases.%></em>';
}
}
<% end %>
<% if has_wifi then %>
var assoclist = [ ];
var ws = document.getElementById('wifi_status_table');
if (ws)
{
var wsbody = ws.rows[0].parentNode;
while (ws.rows.length > 0)
wsbody.deleteRow(0);
for (var didx = 0; didx < info.wifinets.length; didx++)
{
var dev = info.wifinets[didx];
var tr = wsbody.insertRow(-1);
var td;
td = tr.insertCell(-1);
td.width = "33%";
td.innerHTML = dev.name;
td.style.verticalAlign = "top";
td = tr.insertCell(-1);
var s = '';
for (var nidx = 0; nidx < dev.networks.length; nidx++)
{
var net = dev.networks[nidx];
var is_assoc = (net.bssid != '00:00:00:00:00:00' && net.channel && !net.disabled);
var icon;
if (!is_assoc)
icon = "<%=resource%>/icons/signal-none.png";
else if (net.quality == 0)
icon = "<%=resource%>/icons/signal-0.png";
else if (net.quality < 25)
icon = "<%=resource%>/icons/signal-0-25.png";
else if (net.quality < 50)
icon = "<%=resource%>/icons/signal-25-50.png";
else if (net.quality < 75)
icon = "<%=resource%>/icons/signal-50-75.png";
else
icon = "<%=resource%>/icons/signal-75-100.png";
s += String.format(
'<table><tr><td style="text-align:center; width:32px; padding:3px">' +
'<img src="%s" title="<%:Signal%>: %d dBm / <%:Noise%>: %d dBm" />' +
'<br /><small>%d%%</small>' +
'</td><td style="text-align:left; padding:3px"><small>' +
'<strong><%:SSID%>:</strong> <a href="%s">%h</a><br />' +
'<strong><%:Mode%>:</strong> %s<br />' +
'<strong><%:Channel%>:</strong> %d (%.3f <%:GHz%>)<br />' +
'<strong><%:Bitrate%>:</strong> %s <%:Mbit/s%><br />',
icon, net.signal, net.noise,
net.quality,
net.link, net.ssid || '?',
net.mode,
net.channel, net.frequency,
net.bitrate || '?'
);
if (is_assoc)
{
s += String.format(
'<strong><%:BSSID%>:</strong> %s<br />' +
'<strong><%:Encryption%>:</strong> %s',
net.bssid || '?',
net.encryption
);
}
else
{
s += '<em><%:Wireless is disabled or not associated%></em>';
}
s += '</small></td></tr></table>';
for (var bssid in net.assoclist)
{
var bss = net.assoclist[bssid];
bss.bssid = bssid;
bss.link = net.link;
bss.name = net.name;
bss.ifname = net.ifname;
bss.radio = dev.name;
assoclist.push(bss);
}
}
if (!s)
s = '<em><%:No information available%></em>';
td.innerHTML = s;
}
}
var ac = document.getElementById('wifi_assoc_table');
if (ac)
{
/* clear all rows */
while( ac.rows.length > 1 )
ac.rows[0].parentNode.deleteRow(1);
assoclist.sort(function(a, b) {
return (a.name == b.name)
? (a.bssid < b.bssid)
: (a.name > b.name )
;
});
for( var i = 0; i < assoclist.length; i++ )
{
var tr = ac.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + (1 + (i % 2));
var icon;
var q = (-1 * (assoclist[i].noise - assoclist[i].signal)) / 5;
if (q < 1)
icon = "<%=resource%>/icons/signal-0.png";
else if (q < 2)
icon = "<%=resource%>/icons/signal-0-25.png";
else if (q < 3)
icon = "<%=resource%>/icons/signal-25-50.png";
else if (q < 4)
icon = "<%=resource%>/icons/signal-50-75.png";
else
icon = "<%=resource%>/icons/signal-75-100.png";
tr.insertCell(-1).innerHTML = String.format(
'<span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> %h</span>',
assoclist[i].radio, assoclist[i].ifname
);
tr.insertCell(-1).innerHTML = String.format(
'<a href="%s">%s</a>',
assoclist[i].link,
'%h'.format(assoclist[i].name).nobr()
);
tr.insertCell(-1).innerHTML = assoclist[i].bssid;
var host = hosts[assoclist[i].bssid];
if (host)
tr.insertCell(-1).innerHTML = String.format(
'<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis">%s</div>',
((host.name && (host.ipv4 || host.ipv6))
? '%h (%s)'.format(host.name, host.ipv4 || host.ipv6)
: '%h'.format(host.name || host.ipv4 || host.ipv6)).nobr()
);
else
tr.insertCell(-1).innerHTML = '?';
tr.insertCell(-1).innerHTML = String.format(
'<span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span>',
assoclist[i].signal, assoclist[i].noise, assoclist[i].signal - assoclist[i].noise,
icon,
assoclist[i].signal, assoclist[i].noise
);
tr.insertCell(-1).innerHTML = wifirate(assoclist[i], true).nobr() + '<br />' + wifirate(assoclist[i], false).nobr();
}
if (ac.rows.length == 1)
{
var tr = ac.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 7;
td.innerHTML = '<br /><em><%:No information available%></em>';
}
}
<% end %>
var e;
if (e = document.getElementById('ethinfo')) {
var ports = eval('(' + info.ethinfo + ')');
var tmp = "";
for (var i in ports)
{
tmp = tmp + String.format(
'<td style="text-align:center"><span style="line-height:25px">%s</span><br /><small><img src="<%=resource%>/icons/%s" /><br />%s<br />%s</small></td>', ports[i].name,
ports[i].status ? 'port_up.png' : 'port_down.png',
ports[i].speed,
ports[i].duplex ? '<%:full-duplex%>' : '<%:half-duplex%>');
};
e.innerHTML = "<tr>" + tmp + "</tr>";
}
if (e = document.getElementById('localtime'))
e.innerHTML = info.localtime;
if (e = document.getElementById('uptime'))
e.innerHTML = String.format('%t', info.uptime);
if (e = document.getElementById('userinfo'))
e.innerHTML = info.userinfo;
if (e = document.getElementById('cpuinfo'))
e.innerHTML = info.cpuinfo;
if (e = document.getElementById('cpuusage'))
e.innerHTML = info.cpuusage;
if (e = document.getElementById('loadavg'))
e.innerHTML = String.format(
'%.02f, %.02f, %.02f',
info.loadavg[0] / 65535.0,
info.loadavg[1] / 65535.0,
info.loadavg[2] / 65535.0
);
if (e = document.getElementById('memtotal'))
e.innerHTML = progressbar(
Math.floor(((info.memory.free + info.memory.buffered) / 1048576) + (info.memcached / 1024)) + " <%:MB%>",
Math.floor(info.memory.total / 1048576) + " <%:MB%>"
);
if (e = document.getElementById('membuff'))
e.innerHTML = progressbar(
Math.floor(info.memory.buffered / 1048576) + " <%:MB%>",
Math.floor(info.memory.total / 1048576) + " <%:MB%>"
);
if (e = document.getElementById('swaptotal'))
e.innerHTML = progressbar(
Math.floor(info.swap.free / 1048576) + " <%:MB%>",
Math.floor(info.swap.total / 1048576) + " <%:MB%>"
);
if (e = document.getElementById('swapfree'))
e.innerHTML = progressbar(
Math.floor(info.swap.free / 1048576) + " <%:MB%>",
Math.floor(info.swap.total / 1048576) + " <%:MB%>"
);
if (e = document.getElementById('conns'))
e.innerHTML = progressbar(info.conncount, info.connmax);
}
);
//]]></script>
<h2 name="content"><%:Status%></h2>
<fieldset class="cbi-section">
<legend><%:System%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%"><%:Hostname%></td><td><%=luci.sys.hostname() or "?"%></td></tr>
<tr><td width="33%"><%:Model%></td><td><%=pcdata(boardinfo.model or "?")%> <%=luci.sys.exec("cat /etc/bench.log") or " "%></td></tr>
<tr><td width="33%"><%:CPU Info%></td><td id="cpuinfo">-</td></tr>
<tr><td width="33%"><%:Firmware Version%></td><td>
<%=pcdata(ver.distname)%> <%=pcdata(ver.distversion)%> /
<%=pcdata(ver.luciname)%> (<%=pcdata(ver.luciversion)%>)
</td></tr>
<tr><td width="33%"><%:Kernel Version%></td><td><%=unameinfo.release or "?"%></td></tr>
<tr><td width="33%"><%:Local Time%></td><td id="localtime">-</td></tr>
<tr><td width="33%"><%:Uptime%></td><td id="uptime">-</td></tr>
<tr><td width="33%"><%:Load Average%></td><td id="loadavg">-</td></tr>
<tr><td width="33%"><%:CPU usage (%)%></td><td id="cpuusage">-</td></tr>
</table>
</fieldset>
<fieldset class="cbi-section">
<legend><%:Memory%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%"><%:Total Available%></td><td id="memtotal">-</td></tr>
<tr><td width="33%"><%:Buffered%></td><td id="membuff">-</td></tr>
</table>
</fieldset>
<% if swapinfo.total > 0 then %>
<fieldset class="cbi-section">
<legend><%:Swap%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%"><%:Total Available%></td><td id="swaptotal">-</td></tr>
<tr><td width="33%"><%:Free%></td><td id="swapfree">-</td></tr>
</table>
</fieldset>
<% end %>
<fieldset class="cbi-section">
<legend><%:Interfaces%></legend>
<table width="100%" cellspacing="10" id="ethinfo">
</table>
</fieldset>
<fieldset class="cbi-section">
<legend><%:Network%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%" style="vertical-align:top"><%:IPv4 WAN Status%></td><td>
<table><tr>
<td id="wan4_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></td>
<td id="wan4_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></td>
</tr></table>
</td></tr>
<% if has_ipv6 then %>
<tr><td width="33%" style="vertical-align:top"><%:IPv6 WAN Status%></td><td>
<table><tr>
<td id="wan6_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></td>
<td id="wan6_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></td>
</tr></table>
</td></tr>
<% end %>
<tr><td width="33%"><%:Online Users%></td><td id="userinfo">0</td></tr>
<tr><td width="33%"><%:Active Connections%></td><td id="conns">-</td></tr>
</table>
</fieldset>
<% if has_dhcp then %>
<fieldset class="cbi-section">
<legend><%:DHCP Leases%></legend>
<table class="cbi-section-table" id="lease_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Hostname%></th>
<th class="cbi-section-table-cell"><%:IPv4-Address%></th>
<th class="cbi-section-table-cell"><%:MAC-Address%></th>
<th class="cbi-section-table-cell"><%:Leasetime remaining%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="4"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
<% if has_ipv6 then %>
<fieldset class="cbi-section" style="display:none">
<legend><%:DHCPv6 Leases%></legend>
<table class="cbi-section-table" id="lease6_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Host%></th>
<th class="cbi-section-table-cell"><%:IPv6-Address%></th>
<th class="cbi-section-table-cell"><%:DUID%></th>
<th class="cbi-section-table-cell"><%:Leasetime remaining%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="4"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
<% end %>
<% end %>
<% if has_dsl then %>
<fieldset class="cbi-section">
<legend><%:DSL%></legend>
<table width="100%" cellspacing="10">
<tr><td width="33%" style="vertical-align:top"><%:DSL Status%></td><td>
<table><tr>
<td id="dsl_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></td>
<td id="dsl_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></td>
</tr></table>
</td></tr>
</table>
</fieldset>
<% end %>
<% if has_wifi then %>
<fieldset class="cbi-section">
<legend><%:Wireless%></legend>
<table id="wifi_status_table" width="100%" cellspacing="10">
<tr><td><em><%:Collecting data...%></em></td></tr>
</table>
</fieldset>
<% end %>
<%+footer%>

View File

@ -1,14 +0,0 @@
#!/bin/sh
arch="$(awk -F ': ' '/model name/ {print $2}' "/proc/cpuinfo" | head -n1)"
core="$(grep "core id" "/proc/cpuinfo" | sort -u | wc -l)C $(grep -c "processor" "/proc/cpuinfo")T"
freq="$(awk -F ': ' '/MHz/ {print $2}' "/proc/cpuinfo" | head -n1)MHz"
# Intel
temp="$(sensors "coretemp-*" 2>"/dev/null" | grep -E "(Package id |Core )" | grep -Eo "\+[0-9.]*°C" | head -n1 | tr -d "+")"
# AMD
[ -n "${temp}" ] || temp="$(sensors "k*temp-*" 2>"/dev/null" | awk '/Tdie/ {print $2}' | head -n1 | tr -d "+")"
echo -n "$arch x $core ($freq, ${temp})"

View File

@ -1,39 +0,0 @@
#!/bin/sh
a=$(ip address | grep ^[0-9] | awk -F: '{print $2}' | sed "s/ //g" | grep '^[e]' | grep -v "@" | grep -v "\.")
b=$(echo "$a" | wc -l)
rm -f /tmp/state/ethinfo
echo -n "[" > /tmp/state/ethinfo
for i in $(seq 1 $b)
do
h=$(echo '{"name":' )
c=$(echo "$a" | sed -n ${i}p)
d=$(ethtool $c)
e=$(echo "$d" | grep "Link detected" | awk -F: '{printf $2}' | sed 's/^[ \t]*//g')
if [ $e = yes ]; then
l=1
else
l=0
fi
f=$(echo "$d" | grep "Speed" | awk -F: '{printf $2}' | sed 's/^[ \t]*//g' | tr -d "Unknown!")
[ -z "$f" ] && f=" - "
g=$(echo "$d" | grep "Duplex" | awk -F: '{printf $2}' | sed 's/^[ \t]*//g')
if [ "$g" == "Full" ]; then
x=1
else
x=0
fi
echo -n "$h \"$c\", \"status\": $l, \"speed\": \"$f\", \"duplex\": $x}," >> /tmp/state/ethinfo
done
sed -i 's/.$//' /tmp/state/ethinfo
echo -n "]" >> /tmp/state/ethinfo
cat /tmp/state/ethinfo

View File

@ -1,8 +0,0 @@
#!/bin/sh
if [ $(busybox ps -w | grep getcpu | grep -v grep | wc -l) -le 2 ]; then
AT=$(cat /proc/stat | grep "^cpu " | awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}')
sleep 1
BT=$(cat /proc/stat | grep "^cpu " | awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}')
printf "%.01f%%" $(echo $AT $BT | awk '{print (($4-$2)/($3-$1))*100}') >/tmp/cpuusage
fi

View File

@ -1,37 +0,0 @@
#
# Copyright (C) 2010-2011 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=automount
PKG_VERSION:=1
PKG_RELEASE:=40
PKG_ARCH:=all
include $(INCLUDE_DIR)/package.mk
define Package/automount
TITLE:=Mount autoconfig hotplug script.
MAINTAINER:=Lean
DEPENDS:=+block-mount +kmod-fs-exfat +kmod-fs-ext4 +kmod-fs-vfat +libblkid \
+kmod-usb-storage +kmod-usb-storage-extras +!TARGET_ramips:kmod-usb-storage-uas +kmod-fs-ntfs3
endef
define Package/automount/description
A usb autoconfig hotplug script.
endef
define Build/Compile
endef
define Package/automount/install
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/15-automount $(1)/etc/15-automount
$(INSTALL_BIN) ./files/zzz-move-automount $(1)/etc/uci-defaults/zzz-move-automount
endef
$(eval $(call BuildPackage,automount))

View File

@ -1,27 +0,0 @@
#!/bin/sh
# Copyright (C) 2015 OpenWrt.org
# 0 yes blockdevice handles this - 1 no it is not there
blkdev=`dirname $DEVPATH`
basename=`basename $blkdev`
device=`basename $DEVPATH`
skip=`block info | grep -vE '(f2fs|kernel|squashfs)' | sed 's/\(.*\): .*/\1/' | grep -q $device ; echo $?`
path=$DEVPATH
if [ $basename != "block" ] && [ -z "${device##sd*}" ] && [ $skip -eq 1 ]; then
mntpnt=$device
case "$ACTION" in
add)
mkdir -p /mnt/$mntpnt
chmod 777 /mnt/$mntpnt
# Try to be gentle on solid state devices
mount -o rw,noatime,discard /dev/$device /mnt/$mntpnt
;;
remove)
# Once the device is removed, the /dev entry disappear. We need mountpoint
mountpoint=`mount |grep /dev/$device | sed 's/.* on \(.*\) type.*/\1/'`
umount -l $mountpoint
;;
esac
fi

View File

@ -1,4 +0,0 @@
#!/bin/sh
sleep 15
mv /etc/15-automount /etc/hotplug.d/block/

View File

@ -1,57 +0,0 @@
#
# Copyright (C) 2010-2011 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=autosamba
PKG_VERSION:=1
PKG_RELEASE:=15
PKG_ARCH:=all
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_KSMBD \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_SAMBA3 \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_SAMBA4 \
include $(INCLUDE_DIR)/package.mk
define Package/autosamba
TITLE:=Samba autoconfig hotplug script.
MAINTAINER:=Lean
DEPENDS:=+wsdd2 +PACKAGE_$(PKG_NAME)_INCLUDE_KSMBD:luci-app-ksmbd +PACKAGE_$(PKG_NAME)_INCLUDE_SAMBA3:luci-app-samba +PACKAGE_$(PKG_NAME)_INCLUDE_SAMBA4:luci-app-samba4
endef
define Package/autosamba/description
A hotplug script to config Samba share automatically.
endef
define Package/$(PKG_NAME)/config
choice
prompt "Samba Server Selection"
default PACKAGE_$(PKG_NAME)_INCLUDE_KSMBD
config PACKAGE_$(PKG_NAME)_INCLUDE_KSMBD
bool "KSMBD"
config PACKAGE_$(PKG_NAME)_INCLUDE_SAMBA3
bool "SAMBA 3"
config PACKAGE_$(PKG_NAME)_INCLUDE_SAMBA4
bool "SAMBA 4"
endchoice
endef
define Build/Compile
endef
define Package/autosamba/install
$(INSTALL_DIR) $(1)/etc/hotplug.d/block
$(INSTALL_BIN) ./files/20-smb $(1)/etc/hotplug.d/block/20-smb
endef
$(eval $(call BuildPackage,autosamba))

View File

@ -1,106 +0,0 @@
#!/bin/sh
#
# D-Team Technology Co.,Ltd. ShenZhen
# 作者:Vic
#
# 警告:对着屏幕的哥们,我们允许你使用此脚本,但不允许你抹去作者的信息,请保留这段话。
#
. /lib/functions.sh
. /lib/functions/service.sh
global=0
config_file="/etc/config/samba4"
wait_for_init() {
for i in `seq 30`
do
[ -e /tmp/procd.done ] || {
sleep 1; continue;
}
return
done
}
smb_handle() {
config_get path $1 path
if [ "$path" = "$2" ] ;then
global=1
fi
}
chk_en() {
config_get_bool autoshare $1 autoshare 1
[ $autoshare -eq 0 ] && exit
}
config_load samba4
config_foreach chk_en samba4
device=`basename $DEVPATH`
case "$ACTION" in
add)
case "$device" in
sd*);;
md*);;
hd*);;
mmcblk*);;
*) return;;
esac
path="/dev/$device"
wait_for_init
cat /proc/mounts | grep -v '/boot\|/opt' | while read j
do
str=${j%% *}
if [ "$str" == $path ];then
strr=${j#* }
target=${strr%% *}
global=0
config_foreach smb_handle sambashare $target
name=${target#*/mnt/}
if [ $global -eq 0 ] ;then
echo -e "\n\nconfig sambashare" >> $config_file
echo -e "\toption auto '1'" >> $config_file
echo -e "\toption name '$name'" >> $config_file
echo -e "\toption path '$target'" >> $config_file
echo -e "\toption read_only 'no'" >> $config_file
echo -e "\toption guest_ok 'yes'" >> $config_file
echo -e "\toption create_mask '0666'" >> $config_file
echo -e "\toption dir_mask '0777'" >> $config_file
echo -e "\toption device '$device'" >> $config_file
echo -e "\toption inherit_owner 'yes'" >> $config_file
/etc/init.d/samba4 reload
return
fi
fi
done
;;
remove)
i=0
while true
do
dev=`uci get samba4.@sambashare[$i].device`
[ $? -ne 0 ] && break
[ "$dev" = "$device" ] && {
auto=`uci get samba4.@sambashare[$i].auto`
[ $auto = "1" ] && {
mount_dir=`uci get samba4.@sambashare[$i].name`
uci delete samba4.@sambashare[$i]
uci commit
/etc/init.d/samba4 reload
return
}
}
let i+=1
done
;;
esac

View File

@ -1,30 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2024 ImmortalWrt.org
include $(TOPDIR)/rules.mk
PKG_NAME:=cpufreq
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/cpufreq
TITLE:=CPU Frequency Scaling adjustment tool
DEPENDS:=@(arm||aarch64)
PKGARCH:=all
endef
define Build/Compile
endef
define Package/cpufreq/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) $(CURDIR)/files/cpufreq.config $(1)/etc/config/cpufreq
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) $(CURDIR)/files/cpufreq.init $(1)/etc/init.d/cpufreq
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(CURDIR)/files/cpufreq.uci $(1)/etc/uci-defaults/10-cpufreq
endef
$(eval $(call BuildPackage,cpufreq))

View File

@ -1,5 +0,0 @@
config settings 'cpufreq'
config settings 'global'

View File

@ -1,58 +0,0 @@
#!/bin/sh /etc/rc.common
START=15
USE_PROCD=1
NAME="cpufreq"
CPUFREQ_PATH="/sys/devices/system/cpu/cpufreq"
extra_command "get_policies" "Get CPU scaling governors and frequencies"
get_policies() {
json_init
for policy in $(ls -d "$CPUFREQ_PATH"/policy[0-9]* 2>"/dev/null"); do
[ -s "$policy/scaling_available_frequencies" ] || continue
json_add_object "$(basename "$policy")"
json_add_string "index" "$(basename "$policy" | grep -Eo "[0-9]*$")"
json_add_string "cpus" "$(cat "$policy/affected_cpus")"
json_add_array "freqs"
for freq in $(cat "$policy/scaling_available_frequencies"); do
json_add_string "" "$freq"
done
json_close_array
json_add_array "governors"
for governor in $(cat "$policy/scaling_available_governors"); do
json_add_string "" "$governor"
done
json_close_array
json_close_object
done
json_dump
}
write_cpufreq_config() {
local value
config_get value "$NAME" "$1"
[ -z "$value" ] || echo -n "$value" > "$2"
}
start_service() {
config_load "$NAME"
for i in $(ls -d "$CPUFREQ_PATH"/policy[0-9]* 2>"/dev/null" | grep -Eo "[0-9]*$")
do
[ -z "$(config_get "$NAME" "governor$i")" ] && return
write_cpufreq_config "governor$i" "$CPUFREQ_PATH/policy$i/scaling_governor"
write_cpufreq_config "minfreq$i" "$CPUFREQ_PATH/policy$i/scaling_min_freq"
write_cpufreq_config "maxfreq$i" "$CPUFREQ_PATH/policy$i/scaling_max_freq"
if [ "$(config_get "$NAME" "governor$i")" = "ondemand" ]; then
write_cpufreq_config "sdfactor$i" "$CPUFREQ_PATH/ondemand/sampling_down_factor"
write_cpufreq_config "upthreshold$i" "$CPUFREQ_PATH/ondemand/up_threshold"
fi
done
}
service_triggers() {
procd_add_reload_trigger "$NAME"
}

View File

@ -1,75 +0,0 @@
#!/bin/sh
uci_write_config() {
uci -q set "cpufreq.cpufreq.governor$1"="$2"
uci -q set "cpufreq.cpufreq.minfreq$1"="$3"
uci -q set "cpufreq.cpufreq.maxfreq$1"="$4"
[ -n "$5" ] && uci -q set "cpufreq.cpufreq.sdfactor$1"="$5"
[ -n "$6" ] && uci -q set "cpufreq.cpufreq.upthreshold$1"="$6"
uci -q commit cpufreq
}
[ "$(uci -q get cpufreq.global.set)" -eq "1" ] && exit 0
CPU_FREQS="$(cat '/sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies')"
CPU_MIN_FREQ="$(cat '/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq')"
CPU_MAX_FREQ="$(cat '/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq')"
CPU_POLICYS="$(find '/sys/devices/system/cpu/cpufreq/policy'* -maxdepth 0 | grep -Eo '[0-9]+')"
source "/etc/openwrt_release"
case "$DISTRIB_TARGET" in
"bcm27xx/bcm2710"|\
"bcm27xx/bcm2711")
uci_write_config 0 ondemand 600000 "$CPU_MAX_FREQ" 10 50
;;
"ipq40xx/generic")
uci_write_config 0 performance 200000 "$CPU_MAX_FREQ"
;;
"ipq806x/generic")
uci_write_config 0 performance 600000 "$CPU_MAX_FREQ"
# IPQ8064/5
echo "$CPU_POLICYS" | grep -q "1" && uci_write_config 1 performance 600000 1200000
;;
"mediatek/mt7622")
uci_write_config 0 ondemand 600000 1350000 10 50
;;
"qualcommax/ipq60xx"|\
"qualcommax/ipq807x")
uci_write_config 0 schedutil "$CPU_MIN_FREQ" "$CPU_MAX_FREQ"
;;
"rockchip/armv8")
if echo "$CPU_POLICYS" | grep -q "6"; then
# RK3588/S
uci_write_config 0 schedutil 1008000 1800000
uci_write_config 4 schedutil 816000 2208000
uci_write_config 6 schedutil 816000 2208000
elif echo "$CPU_POLICYS" | grep -q "4"; then
# RK3399
uci_write_config 0 schedutil 600000 1608000
uci_write_config 4 schedutil 600000 2016000
else
if ! echo "$CPU_FREQS" | grep -q "1992000"; then
# RK3328
CPU_MAX_FREQ="1512000"
fi
uci_write_config 0 schedutil 816000 "$CPU_MAX_FREQ"
fi
;;
"sunxi/cortexa53")
if echo "$CPU_FREQS" | grep -q "1800000"; then
# H6
uci_write_config 0 schedutil "888000" "$CPU_MAX_FREQ"
elif echo "$CPU_FREQS" | grep -q "1512000"; then
# H616/8
uci_write_config 0 schedutil "936000" "1512000"
elif echo "$CPU_FREQS" | grep -q "1296000"; then
# H5
uci_write_config 0 ondemand "$CPU_MIN_FREQ" "1296000" 10 50
else
# A64
uci_write_config 0 ondemand "$CPU_MIN_FREQ" "$CPU_MAX_FREQ" 10 50
fi
;;
esac
exit 0

View File

@ -1,73 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ddns-scripts_aliyun
PKG_VERSION:=1.0.3
PKG_RELEASE:=1
PKG_LICENSE:=GPLv2
PKG_MAINTAINER:=Sense <sensec@gmail.com>
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define Package/ddns-scripts_aliyun
SECTION:=net
CATEGORY:=Network
SUBMENU:=IP Addresses and Names
TITLE:=DDNS extension for AliYun.com
PKGARCH:=all
DEPENDS:=+ddns-scripts +wget-ssl +openssl-util
endef
define Package/ddns-scripts_aliyun/description
Dynamic DNS Client scripts extension for AliYun.com
endef
define Build/Configure
endef
define Build/Compile
$(CP) ./*.sh $(PKG_BUILD_DIR)
endef
define Package/ddns-scripts_aliyun/preinst
#!/bin/sh
# if NOT run buildroot then stop service
[ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1
exit 0 # suppress errors
endef
define Package/ddns-scripts_aliyun/install
$(INSTALL_DIR) $(1)/usr/lib/ddns $(1)/usr/share/ddns/default
$(INSTALL_BIN) $(CURDIR)/update_aliyun_com.sh $(1)/usr/lib/ddns
$(INSTALL_DATA) $(CURDIR)/aliyun.com.json $(1)/usr/share/ddns/default
endef
define Package/ddns-scripts_aliyun/postinst
#!/bin/sh
# remove old services file entries
/bin/sed -i '/aliyun\.com/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/aliyun\.com/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
# and create new
printf "%s\\t\\t%s\\n" '"aliyun.com"' '"update_aliyun_com.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services
printf "%s\\t\\t%s\\n" '"aliyun.com"' '"update_aliyun_com.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6
# on real system restart service if enabled
[ -z "$${IPKG_INSTROOT}" ] && {
/etc/init.d/ddns enabled && \
/etc/init.d/ddns start >/dev/null 2>&1
}
exit 0 # suppress errors
endef
define Package/ddns-scripts_aliyun/prerm
#!/bin/sh
# if NOT run buildroot then stop service
[ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1
# remove services file entries
/bin/sed -i '/aliyun\.com/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/aliyun\.com/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
exit 0 # suppress errors
endef
$(eval $(call BuildPackage,ddns-scripts_aliyun))

View File

@ -1,9 +0,0 @@
{
"name": "aliyun.com",
"ipv4": {
"url": "update_aliyun_com.sh"
},
"ipv6": {
"url": "update_aliyun_com.sh"
}
}

View File

@ -1,248 +0,0 @@
#!/bin/sh
#
# 用于阿里云解析的DNS更新脚本
# 2017-2018 Sense <sensec at gmail dot com>
# 阿里云解析API文档 https://help.aliyun.com/document_detail/29739.html
#
# 本脚本由 dynamic_dns_functions.sh 内的函数 send_update() 调用
#
# 需要在 /etc/config/ddns 中设置的选项
# option username - 阿里云API访问账号 Access Key ID。可通过 aliyun.com 帐号管理的 accesskeys 获取, 或者访问 https://ak-console.aliyun.com
# option password - 阿里云API访问密钥 Access Key Secret
# option domain - 完整的域名。建议主机与域名之间使用 @符号 分隔,否则将以第一个 .符号 之前的内容作为主机名
#
# 检查传入参数
[ -z "$username" ] && write_log 14 "配置错误保存阿里云API访问账号的'用户名'不能为空"
[ -z "$password" ] && write_log 14 "配置错误保存阿里云API访问密钥的'密码'不能为空"
# 检查外部调用工具
WGET_SSL='wget'
[ -n "$WGET_SSL" ] || write_log 13 "使用阿里云API需要 GNU Wget 支持,请先安装"
command -v sed >/dev/null 2>&1 || write_log 13 "使用阿里云API需要 sed 支持,请先安装"
command -v openssl >/dev/null 2>&1 || write_log 13 "使用阿里云API需要 openssl-util 支持,请先安装"
# 包含用于解析 JSON 格式返回值的函数
. /usr/share/libubox/jshn.sh
# 变量声明
local __HOST __DOMAIN __TYPE __URLBASE __CMDBASE __URLARGS __SEPARATOR __RECID
[ $use_https -eq 0 ] && __URLBASE="http://alidns.aliyuncs.com/" || __URLBASE="https://alidns.aliyuncs.com/"
__SEPARATOR="&"
# 从 $domain 分离主机和域名
[ "${domain:0:2}" == "@." ] && domain="${domain/./}" # 主域名处理
[ "$domain" == "${domain/@/}" ] && domain="${domain/./@}" # 未找到分隔符,兼容常用域名格式
__HOST="${domain%%@*}"
__DOMAIN="${domain#*@}"
[ -z "$__HOST" -o "$__HOST" == "$__DOMAIN" ] && __HOST="@"
# 设置记录类型
[ $use_ipv6 -eq 0 ] && __TYPE="A" || __TYPE="AAAA"
# 构造基本通信命令
build_command() {
__CMDBASE="$WGET_SSL --no-hsts -nv -t 1 -O $DATFILE -o $ERRFILE"
# 绑定用于通信的主机/IP
if [ -n "$bind_network" ]; then
local bind_ip run_prog
[ $use_ipv6 -eq 0 ] && run_prog="network_get_ipaddr" || run_prog="network_get_ipaddr6"
eval "$run_prog bind_ip $bind_network" || \
write_log 13 "无法使用 '$run_prog $bind_network' 获取本地IP地址 - 错误代码: '$?'"
write_log 7 "强制使用IP '$bind_ip' 通信"
__CMDBASE="$__CMDBASE --bind-address=$bind_ip"
fi
# 强制设定IP版本
if [ $force_ipversion -eq 1 ]; then
[ $use_ipv6 -eq 0 ] && __CMDBASE="$__CMDBASE -4" || __CMDBASE="$__CMDBASE -6"
fi
# 设置CA证书参数
if [ $use_https -eq 1 ]; then
if [ "$cacert" = "IGNORE" ]; then
__CMDBASE="$__CMDBASE --no-check-certificate"
elif [ -f "$cacert" ]; then
__CMDBASE="$__CMDBASE --ca-certificate=${cacert}"
elif [ -d "$cacert" ]; then
__CMDBASE="$__CMDBASE --ca-directory=${cacert}"
elif [ -n "$cacert" ]; then
write_log 14 "在 '$cacert' 中未找到用于 HTTPS 通信的有效证书"
fi
fi
# 如果没有设置,禁用代理 (这可能是 .wgetrc 或环境设置错误)
[ -z "$proxy" ] && __CMDBASE="$__CMDBASE --no-proxy"
}
# 用于阿里云API的通信函数
aliyun_transfer() {
local __PARAM=$*
local __CNT=0
local __RUNPROG __ERR PID_SLEEP
[ $# -eq 0 ] && write_log 12 "'aliyun_transfer()' 出错 - 参数数量错误"
while : ; do
build_Request $__PARAM
__RUNPROG="$__CMDBASE '${__URLBASE}?${__URLARGS}'"
write_log 7 "#> $__RUNPROG"
eval $__RUNPROG
__ERR=$?
[ $__ERR -eq 0 ] && return 0
write_log 3 "wget 错误代码: '$__ERR'"
write_log 7 "$(cat $ERRFILE)"
if [ $VERBOSE -gt 1 ]; then
write_log 4 "传输失败 - 详细模式: $VERBOSE - 出错后不再重试"
return 1
fi
__CNT=$(( $__CNT + 1 ))
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
write_log 14 "$retry_count 次重试后传输还是失败"
write_log 4 "传输失败 - $__CNT/$retry_count$RETRY_SECONDS 秒后重试"
sleep $RETRY_SECONDS &
PID_SLEEP=$!
wait $PID_SLEEP
PID_SLEEP=0
done
}
# 百分号编码
percentEncode() {
if [ -z "${1//[A-Za-z0-9_.~-]/}" ]; then
echo -n "$1"
else
local string=$1; local i=0; local ret chr
while [ $i -lt ${#string} ]; do
chr=${string:$i:1}
[ -z "${chr#[^A-Za-z0-9_.~-]}" ] && chr=$(printf '%%%02X' "'$chr")
ret="$ret$chr"
i=$(( $i + 1 ))
done
echo -n "$ret"
fi
}
# 构造阿里云解析请求参数
build_Request() {
local args=$*; local string
local HTTP_METHOD="GET"
# 添加请求参数
__URLARGS=
for string in $args; do
case "${string%%=*}" in
Format|TTL|Version|AccessKeyId|SignatureMethod|Timestamp|SignatureVersion|SignatureNonce|Signature) ;; # 过滤公共参数
*) __URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}");;
esac
done
__URLARGS="${__URLARGS:1}"
# 附加公共参数
string="Format=JSON"; __URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}")
string="TTL=600";__URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}")
string="Version=2015-01-09"; __URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}")
string="AccessKeyId=$username"; __URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}")
string="SignatureMethod=HMAC-SHA1"; __URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}")
string="Timestamp="$(date -u '+%Y-%m-%dT%H:%M:%SZ'); __URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}")
string="SignatureVersion=1.0"; __URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}")
string="SignatureNonce="$(cat '/proc/sys/kernel/random/uuid'); __URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}")
# 对请求参数进行排序,用于生成签名
string=$(echo -n "$__URLARGS" | sed 's/\'"${__SEPARATOR}"'/\n/g' | sort | sed ':label; N; s/\n/\'"${__SEPARATOR}"'/g; b label')
# 构造用于计算签名的字符串
string="${HTTP_METHOD}${__SEPARATOR}"$(percentEncode "/")"${__SEPARATOR}"$(percentEncode "$string")
# 字符串计算签名HMAC值
local signature=$(echo -n "$string" | openssl dgst -sha1 -hmac "${password}&" -binary)
# HMAC值编码成字符串得到签名值
signature=$(echo -n "$signature" | openssl base64)
# 附加签名参数
string="Signature=$signature"; __URLARGS="$__URLARGS${__SEPARATOR}"$(percentEncode "${string%%=*}")"="$(percentEncode "${string#*=}")
}
# 添加解析记录
add_domain() {
local value
aliyun_transfer "Action=AddDomainRecord" "DomainName=${__DOMAIN}" "RR=${__HOST}" "Type=${__TYPE}" "Value=${__IP}" || write_log 14 "服务器通信失败"
json_cleanup; json_load "$(cat "$DATFILE" 2> /dev/null)" >/dev/null 2>&1
json_get_var value "RecordId"
[ -z "$value" ] && write_log 14 "添加新解析记录失败"
write_log 7 "添加新解析记录成功"
return 0
}
# 修改解析记录
update_domain() {
local value
aliyun_transfer "Action=UpdateDomainRecord" "RecordId=${__RECID}" "RR=${__HOST}" "Type=${__TYPE}" "Value=${__IP}" || write_log 14 "服务器通信失败"
json_cleanup; json_load "$(cat "$DATFILE" 2> /dev/null)" >/dev/null 2>&1
json_get_var value "RecordId"
[ -z "$value" ] && write_log 14 "修改解析记录失败"
write_log 7 "修改解析记录成功"
return 0
}
# 启用解析记录
enable_domain() {
local value
aliyun_transfer "Action=SetDomainRecordStatus" "RecordId=${__RECID}" "Status=Enable" || write_log 14 "服务器通信失败"
json_cleanup; json_load "$(cat "$DATFILE" 2> /dev/null)" >/dev/null 2>&1
json_get_var value "Status"
[ "$value" != "Enable" ] && write_log 14 "启用解析记录失败"
write_log 7 "启用解析记录成功"
return 0
}
# 获取子域名解析记录列表
describe_domain() {
local count value; local ret=0
aliyun_transfer "Action=DescribeSubDomainRecords" "SubDomain=${__HOST}.${__DOMAIN}" "DomainName=${__DOMAIN}" "Line=default" || write_log 14 "服务器通信失败"
write_log 7 "获取到解析记录: $(cat "$DATFILE" 2> /dev/null)"
json_cleanup; json_load "$(cat "$DATFILE" 2> /dev/null)" >/dev/null 2>&1
json_get_var count "TotalCount"
if [ $count -eq 0 ]; then
write_log 7 "解析记录不存在"
ret=1
else
local i=1;
while [ $i -le $count ]; do
json_cleanup; json_load "$(cat "$DATFILE" 2> /dev/null)" >/dev/null 2>&1
json_select "DomainRecords" >/dev/null 2>&1
json_select "Record" >/dev/null 2>&1
json_select $i >/dev/null 2>&1
i=$(( $i + 1 ))
json_get_var value "Type"
if [ "$value" != "${__TYPE}" ]; then
write_log 7 "当前解析类型: ${__TYPE}, 获得不匹配类型: $value"
ret=1; continue
else
ret=0
json_get_var __RECID "RecordId"
write_log 7 "获得解析记录ID: ${__RECID}, 类型: $value"
json_get_var value "Locked"
[ $value -ne 0 ] && write_log 14 "解析记录被锁定"
json_get_var value "Status"
[ "$value" != "ENABLE" ] && ret=$(( $ret | 2 )) && write_log 7 "解析记录被禁用"
json_get_var value "Value"
[ "$value" != "${__IP}" ] && ret=$(( $ret | 4 )) && write_log 7 "地址需要修改"
break
fi
done
fi
return $ret
}
build_command
describe_domain
ret=$?
if [ $ret -eq 1 ]; then
sleep 3 && add_domain
else
[ $(( $ret & 2 )) -ne 0 ] && sleep 3 && enable_domain
[ $(( $ret & 4 )) -ne 0 ] && sleep 3 && update_domain
fi
return 0

View File

@ -1,78 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ddns-scripts_dnspod
PKG_VERSION:=1.0.2
PKG_RELEASE:=1
PKG_LICENSE:=GPLv2
PKG_MAINTAINER:=Small_5
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define Package/ddns-scripts_dnspod
SECTION:=net
CATEGORY:=Network
SUBMENU:=IP Addresses and Names
TITLE:=DDNS extension for Dnspod.com/Dnspod.cn
PKGARCH:=all
DEPENDS:=+ddns-scripts +wget-ssl +ca-bundle
endef
define Package/ddns-scripts_dnspod/description
Dynamic DNS Client scripts extension for Dnspod.com/Dnspod.cn
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/ddns-scripts_dnspod/preinst
#!/bin/sh
# if NOT run buildroot then stop service
[ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1
exit 0 # suppress errors
endef
define Package/ddns-scripts_dnspod/install
$(INSTALL_DIR) $(1)/usr/lib/ddns $(1)/usr/share/ddns/default
$(INSTALL_BIN) $(CURDIR)/*.sh $(1)/usr/lib/ddns
$(INSTALL_DATA) $(CURDIR)/*.json $(1)/usr/share/ddns/default
endef
define Package/ddns-scripts_dnspod/postinst
#!/bin/sh
# remove old services file entries
/bin/sed -i '/dnspod\.com/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/dnspod\.cn/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/dnspod\.com/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
/bin/sed -i '/dnspod\.cn/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
# and create new
printf "%s\\t\\t%s\\n" '"dnspod.com"' '"update_dnspod_com.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services
printf "%s\\t\\t%s\\n" '"dnspod.cn"' '"update_dnspod_cn.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services
printf "%s\\t\\t%s\\n" '"dnspod.com"' '"update_dnspod_com.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6
printf "%s\\t\\t%s\\n" '"dnspod.cn"' '"update_dnspod_cn.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6
# on real system restart service if enabled
[ -z "$${IPKG_INSTROOT}" ] && {
/etc/init.d/ddns enabled && \
/etc/init.d/ddns start >/dev/null 2>&1
}
exit 0 # suppress errors
endef
define Package/ddns-scripts_dnspod/prerm
#!/bin/sh
# if NOT run buildroot then stop service
[ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1
# remove services file entries
/bin/sed -i '/dnspod\.com/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/dnspod\.cn/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/dnspod\.com/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
/bin/sed -i '/dnspod\.cn/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
exit 0 # suppress errors
endef
$(eval $(call BuildPackage,ddns-scripts_dnspod))

View File

@ -1,9 +0,0 @@
{
"name": "dnspod.com",
"ipv4": {
"url": "update_dnspod_cn.sh"
},
"ipv6": {
"url": "update_dnspod_cn.sh"
}
}

View File

@ -1,9 +0,0 @@
{
"name": "dnspod.com",
"ipv4": {
"url": "update_dnspod_com.sh"
},
"ipv6": {
"url": "update_dnspod_com.sh"
}
}

View File

@ -1,155 +0,0 @@
#!/bin/sh
#检查传入参数
[ -z "$username" ] && write_log 14 "Configuration error! [User name] cannot be empty"
[ -z "$password" ] && write_log 14 "Configuration error! [Password] cannot be empty"
#检查外部调用工具
WGET_SSL='wget'
[ -n "$WGET_SSL" ] || write_log 13 "GNU Wget support is required to use dnspod API. Please install first"
# 变量声明
local __URLBASE __HOST __DOMAIN __TYPE __CMDBASE __POST __POST1 __RECIP __RECID __value __TTL
__URLBASE="https://dnsapi.cn/"
# 从 $domain 分离主机和域名
[ "${domain:0:2}" == "@." ] && domain="${domain/./}" # 主域名处理
[ "$domain" == "${domain/@/}" ] && domain="${domain/./@}" # 未找到分隔符,兼容常用域名格式
__HOST="${domain%%@*}"
__DOMAIN="${domain#*@}"
[ -z "$__HOST" -o "$__HOST" == "$__DOMAIN" ] && __HOST="@"
# 设置记录类型
[ $use_ipv6 -eq 0 ] && __TYPE="A" || __TYPE="AAAA"
# 构造基本通信命令
build_command() {
__CMDBASE="$WGET_SSL --no-hsts -nv -t 1 -O $DATFILE -o $ERRFILE"
# 绑定用于通信的主机/IP
if [ -n "$bind_network" ]; then
local bind_ip run_prog
[ $use_ipv6 -eq 0 ] && run_prog="network_get_ipaddr" || run_prog="network_get_ipaddr6"
eval "$run_prog bind_ip $bind_network" || \
write_log 13 "Unable to get local IP address with '$run_prog $ bind_network' - error code: '$?'"
write_log 7 "Forced use of IP '$bind_ip' communication"
__CMDBASE="$__CMDBASE --bind-address=$bind_ip"
fi
# 强制设定IP版本
if [ $force_ipversion -eq 1 ]; then
[ $use_ipv6 -eq 0 ] && __CMDBASE="$__CMDBASE -4" || __CMDBASE="$__CMDBASE -6"
fi
# 设置CA证书参数
if [ $use_https -eq 1 ]; then
if [ "$cacert" = "IGNORE" ]; then
__CMDBASE="$__CMDBASE --no-check-certificate"
elif [ -f "$cacert" ]; then
__CMDBASE="$__CMDBASE --ca-certificate=${cacert}"
elif [ -d "$cacert" ]; then
__CMDBASE="$__CMDBASE --ca-directory=${cacert}"
elif [ -n "$cacert" ]; then
write_log 14 "A valid certificate for HTTPS communication was not found in '$cacert'"
fi
fi
# 如果没有设置,禁用代理 (这可能是 .wgetrc 或环境设置错误)
[ -z "$proxy" ] && __CMDBASE="$__CMDBASE --no-proxy"
__CMDBASE="$__CMDBASE --post-data"
}
# 用于Dnspod API的通信函数
dnspod_transfer() {
local __A=$1
local __CNT=0
local __ERR=0
local __B PID_SLEEP
case "$__A" in
0)
__B="$__CMDBASE '$__POST' ${__URLBASE}Record.List"
;;
1)
__B="$__CMDBASE '$__POST1' ${__URLBASE}Record.Create"
;;
2)
__B="$__CMDBASE '$__POST1&record_id=$__RECID&ttl=$__TTL' ${__URLBASE}Record.Modify"
;;
esac
while : ; do
write_log 7 "#> $__B"
eval $__B
__ERR=`jsonfilter -i $DATFILE -e "@.status.code"`
[ $__ERR -eq 1 ] && return 0
[ $__A -eq 0 ] && [ $__ERR -eq 10 ] && return 0
write_log 3 "Error message:[$(jsonfilter -i $DATFILE -e "@.status.message")]"
if [ $VERBOSE -gt 1 ]; then
write_log 4 "Transfer failed - detailed mode: $VERBOSE - Do not try again after an error"
return 1
fi
__CNT=$(( $__CNT + 1 ))
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && write_log 14 "Transfer failed after $retry_count retries"
write_log 4 "Transfer failed - $__CNT Try again in $RETRY_SECONDS seconds"
sleep $RETRY_SECONDS &
PID_SLEEP=$!
wait $PID_SLEEP
PID_SLEEP=0
done
}
#添加解析记录
add_domain() {
dnspod_transfer 1
write_log 7 "Add new parsing record [${__HOST}.${__DOMAIN}],[type:$__TYPE],[ip:$__IP] successfully!"
return 0
}
#修改解析记录
update_domain() {
dnspod_transfer 2
write_log 7 "Modify new parsing record [${__HOST}.${__DOMAIN}],[type:$__TYPE],[ip:$__IP],[TTL:$__TTL] successfully!"
return 0
}
#获取域名解析记录
describe_domain() {
ret=0
__POST="login_token=$username,$password&format=json&domain=$__DOMAIN&sub_domain=$__HOST&record_type=$__TYPE"
__POST1="$__POST&value=$__IP&record_type=$__TYPE&record_line_id=0"
dnspod_transfer 0
__TMP=`jsonfilter -i $DATFILE -e "@.records[@.type!='NS']"`
__value=`jsonfilter -s "$__TMP" -e "@.name"`
if [ "$__value" == "" ]; then
write_log 7 "Parsing record:[${__HOST}.${__DOMAIN}] does not exist"
ret=1
else
__RECID=`jsonfilter -s "$__TMP" -e "@.id"`
__value=`jsonfilter -s "$__TMP" -e "@.type"`
__TTL=`jsonfilter -s "$__TMP" -e "@.ttl"`
write_log 7 "Get parsing recordID:[$__RECID]"
if [ "$__value" != "$__TYPE" ]; then
write_log 7 "Current parsing [type:$__TYPE], get mismatched [type:$__value]"
write_log 7 "Address needs to be modified, local address:[$__IP]"
ret=2
else
__RECIP=`jsonfilter -s "$__TMP" -e "@.value"`
if [ "$__RECIP" != "$__IP" ]; then
write_log 7 "Address needs to be modified, local address:[$__IP]"
ret=2
fi
fi
fi
}
build_command
describe_domain
if [ $ret == 1 ];then
sleep 3 && add_domain
elif [ $ret == 2 ];then
sleep 3 && update_domain
else
write_log 7 "Local IP:[$__IP] parsing records IP:[$__RECIP] address does not need to be modified"
fi
return 0

View File

@ -1,155 +0,0 @@
#!/bin/sh
#检查传入参数
[ -z "$username" ] && write_log 14 "Configuration error! [User name] cannot be empty"
[ -z "$password" ] && write_log 14 "Configuration error! [Password] cannot be empty"
#检查外部调用工具
WGET_SSL='wget'
[ -n "$WGET_SSL" ] || write_log 13 "GNU Wget support is required to use dnspod API. Please install first"
# 变量声明
local __URLBASE __HOST __DOMAIN __TYPE __CMDBASE __POST __POST1 __RECIP __RECID __value __TTL
__URLBASE="https://api.dnspod.com/"
# 从 $domain 分离主机和域名
[ "${domain:0:2}" == "@." ] && domain="${domain/./}" # 主域名处理
[ "$domain" == "${domain/@/}" ] && domain="${domain/./@}" # 未找到分隔符,兼容常用域名格式
__HOST="${domain%%@*}"
__DOMAIN="${domain#*@}"
[ -z "$__HOST" -o "$__HOST" == "$__DOMAIN" ] && __HOST="@"
# 设置记录类型
[ $use_ipv6 -eq 0 ] && __TYPE="A" || __TYPE="AAAA"
# 构造基本通信命令
build_command() {
__CMDBASE="$WGET_SSL --no-hsts -nv -t 1 -O $DATFILE -o $ERRFILE"
# 绑定用于通信的主机/IP
if [ -n "$bind_network" ]; then
local bind_ip run_prog
[ $use_ipv6 -eq 0 ] && run_prog="network_get_ipaddr" || run_prog="network_get_ipaddr6"
eval "$run_prog bind_ip $bind_network" || \
write_log 13 "Unable to get local IP address with '$run_prog $ bind_network' - error code: '$?'"
write_log 7 "Forced use of IP '$bind_ip' communication"
__CMDBASE="$__CMDBASE --bind-address=$bind_ip"
fi
# 强制设定IP版本
if [ $force_ipversion -eq 1 ]; then
[ $use_ipv6 -eq 0 ] && __CMDBASE="$__CMDBASE -4" || __CMDBASE="$__CMDBASE -6"
fi
# 设置CA证书参数
if [ $use_https -eq 1 ]; then
if [ "$cacert" = "IGNORE" ]; then
__CMDBASE="$__CMDBASE --no-check-certificate"
elif [ -f "$cacert" ]; then
__CMDBASE="$__CMDBASE --ca-certificate=${cacert}"
elif [ -d "$cacert" ]; then
__CMDBASE="$__CMDBASE --ca-directory=${cacert}"
elif [ -n "$cacert" ]; then
write_log 14 "A valid certificate for HTTPS communication was not found in '$cacert'"
fi
fi
# 如果没有设置,禁用代理 (这可能是 .wgetrc 或环境设置错误)
[ -z "$proxy" ] && __CMDBASE="$__CMDBASE --no-proxy"
__CMDBASE="$__CMDBASE --post-data"
}
# 用于Dnspod API的通信函数
dnspod_transfer() {
local __A=$1
local __CNT=0
local __ERR=0
local __B PID_SLEEP
case "$__A" in
0)
__B="$__CMDBASE '$__POST' ${__URLBASE}Record.List"
;;
1)
__B="$__CMDBASE '$__POST1' ${__URLBASE}Record.Create"
;;
2)
__B="$__CMDBASE '$__POST1&record_id=$__RECID&ttl=$__TTL' ${__URLBASE}Record.Modify"
;;
esac
while : ; do
write_log 7 "#> $__B"
eval $__B
__ERR=`jsonfilter -i $DATFILE -e "@.status.code"`
[ $__ERR -eq 1 ] && return 0
[ $__A -eq 0 ] && [ $__ERR -eq 10 ] && return 0
write_log 3 "Error message:[$(jsonfilter -i $DATFILE -e "@.status.message")]"
if [ $VERBOSE -gt 1 ]; then
write_log 4 "Transfer failed - detailed mode: $VERBOSE - Do not try again after an error"
return 1
fi
__CNT=$(( $__CNT + 1 ))
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && write_log 14 "Transfer failed after $retry_count retries"
write_log 4 "Transfer failed - $__CNT Try again in $RETRY_SECONDS seconds"
sleep $RETRY_SECONDS &
PID_SLEEP=$!
wait $PID_SLEEP
PID_SLEEP=0
done
}
#添加解析记录
add_domain() {
dnspod_transfer 1
write_log 7 "Add new parsing record [${__HOST}.${__DOMAIN}],[type:$__TYPE],[ip:$__IP] successfully!"
return 0
}
#修改解析记录
update_domain() {
dnspod_transfer 2
write_log 7 "Modify new parsing record [${__HOST}.${__DOMAIN}],[type:$__TYPE],[ip:$__IP],[TTL:$__TTL] successfully!"
return 0
}
#获取域名解析记录
describe_domain() {
ret=0
__POST="login_token=$username,$password&format=json&domain=$__DOMAIN&sub_domain=$__HOST&record_type=$__TYPE"
__POST1="$__POST&value=$__IP&record_type=$__TYPE&record_line_id=0"
dnspod_transfer 0
__TMP=`jsonfilter -i $DATFILE -e "@.records[@.type!='NS']"`
__value=`jsonfilter -s "$__TMP" -e "@.name"`
if [ "$__value" == "" ]; then
write_log 7 "Parsing record:[${__HOST}.${__DOMAIN}] does not exist"
ret=1
else
__RECID=`jsonfilter -s "$__TMP" -e "@.id"`
__value=`jsonfilter -s "$__TMP" -e "@.type"`
__TTL=`jsonfilter -s "$__TMP" -e "@.ttl"`
write_log 7 "Get parsing recordID:[$__RECID]"
if [ "$__value" != "$__TYPE" ]; then
write_log 7 "Current parsing [type:$__TYPE], get mismatched [type:$__value]"
write_log 7 "Address needs to be modified, local address:[$__IP]"
ret=2
else
__RECIP=`jsonfilter -s "$__TMP" -e "@.value"`
if [ "$__RECIP" != "$__IP" ]; then
write_log 7 "Address needs to be modified, local address:[$__IP]"
ret=2
fi
fi
fi
}
build_command
describe_domain
if [ $ret == 1 ];then
sleep 3 && add_domain
elif [ $ret == 2 ];then
sleep 3 && update_domain
else
write_log 7 "Local IP:[$__IP] parsing records IP:[$__RECIP] address does not need to be modified"
fi
return 0

View File

@ -1,38 +0,0 @@
#
# Copyright (C) 2016-2023 GitHub
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
include $(TOPDIR)/rules.mk
PKG_NAME:=default-settings
PKG_RELEASE:=$(COMMITCOUNT)
PKG_LICENSE:=GPLv3
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
define Package/default-settings
SECTION:=luci
CATEGORY:=LuCI
TITLE:=LuCI support for Default Settings
PKGARCH:=all
DEPENDS:= +luci-compat +@LUCI_LANG_zh-cn +@LUCI_LANG_zh_Hans +@LUCI_LANG_en
endef
define Package/default-settings/description
Language Support Packages.
endef
define Build/Compile
endef
define Package/default-settings/install
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/zzz-default-settings $(1)/etc/uci-defaults/99-default-settings
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
po2lmo ./po/zh-cn/default.po $(1)/usr/lib/lua/luci/i18n/default.zh-cn.lmo
endef
$(eval $(call BuildPackage,default-settings))

View File

@ -1,65 +0,0 @@
#!/bin/sh
uci -q batch <<-EOF
set system.@system[0].timezone='CST-8'
set system.@system[0].zonename='Asia/Shanghai'
delete system.ntp.server
add_list system.ntp.server='ntp1.aliyun.com'
add_list system.ntp.server='ntp.tencent.com'
add_list system.ntp.server='ntp.ntsc.ac.cn'
add_list system.ntp.server='time.apple.com'
EOF
uci commit system
rm -f /usr/lib/lua/luci/view/admin_status/index/mwan.htm
rm -f /usr/lib/lua/luci/view/admin_status/index/upnp.htm
rm -f /usr/lib/lua/luci/view/admin_status/index/ddns.htm
rm -f /usr/lib/lua/luci/view/admin_status/index/minidlna.htm
rm -f /www/luci-static/resources/view/status/include/70_ddns.js
rm -f /www/luci-static/resources/view/status/include/80_upnp.js
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/aria2.lua
sed -i 's/services/nas/g' /usr/lib/lua/luci/view/aria2/overview_status.htm
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/hd_idle.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/samba.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/samba4.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/minidlna.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/transmission.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/mjpg-streamer.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/p910nd.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/usb_printer.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/xunlei.lua
sed -i 's/services/nas/g' /usr/lib/lua/luci/view/minidlna_status.htm
sed -i 's/\"services\"/\"nas\"/g' /usr/share/luci/menu.d/luci-app-samba4.json
sed -i 's#downloads.openwrt.org#mirrors.tencent.com/lede#g' /etc/opkg/distfeeds.conf
sed -i 's#downloads.openwrt.org#mirrors.tencent.com/lede#g' /etc/apk/repositories.d/distfeeds.list
sed -i 's/root::0:0:99999:7:::/root:$1$V4UetPzk$CYXluq4wUazHjmCDBCqXF.:0:0:99999:7:::/g' /etc/shadow
sed -i 's/root:::0:99999:7:::/root:$1$V4UetPzk$CYXluq4wUazHjmCDBCqXF.:0:0:99999:7:::/g' /etc/shadow
sed -i "s/# //g" /etc/opkg/distfeeds.conf
sed -i '/helloworld/d' /etc/opkg/distfeeds.conf
sed -i '/openwrt_luci/ { s/snapshots/releases\/18.06.9/g; }' /etc/opkg/distfeeds.conf
sed -i '/check_signature/d' /etc/opkg.conf
sed -i '/REDIRECT --to-ports 53/d' /etc/firewall.user
sed -i '/DISTRIB_REVISION/d' /etc/openwrt_release
echo "DISTRIB_REVISION='R26.05.20'" >> /etc/openwrt_release
sed -i '/DISTRIB_DESCRIPTION/d' /etc/openwrt_release
echo "DISTRIB_DESCRIPTION='LEDE '" >> /etc/openwrt_release
sed -i '/OPENWRT_RELEASE/d' /usr/lib/os-release
echo 'OPENWRT_RELEASE="LEDE R26.05.20"' >> /usr/lib/os-release
sed -i '/log-facility/d' /etc/dnsmasq.conf
echo "log-facility=/dev/null" >> /etc/dnsmasq.conf
rm -rf /tmp/luci-modulecache/
rm -f /tmp/luci-indexcache
exit 0

View File

@ -1,70 +0,0 @@
msgid "Swap"
msgstr "虚拟内存"
msgid "Processor"
msgstr "处理器"
msgid "Architecture"
msgstr "架构"
msgid "CPU Temperature"
msgstr "CPU 温度"
msgid "CPU Info"
msgstr "CPU 信息"
msgid "CPU Model"
msgstr "处理器型号"
msgid "CPU usage"
msgstr "CPU 使用率"
msgid "CPU frequency"
msgstr "CPU 频率"
msgid "RAM frequency"
msgstr "RAM 频率"
msgid "Flash Size"
msgstr "闪存大小"
msgid "Free Memory"
msgstr "释放内存"
msgid "RUNNING"
msgstr "运行中"
msgid "NOT RUNNING"
msgstr "未运行"
msgid "ZRam Settings"
msgstr "ZRam 设置"
msgid "ZRam Compression Algorithm"
msgstr "ZRam 压缩算法"
msgid "ZRam Compression Streams"
msgstr "ZRam 压缩数据流线程数"
msgid "ZRam Size"
msgstr "ZRam 大小"
msgid "Size of the ZRam device in megabytes"
msgstr "划分给 ZRam 分区的内存大小MB推荐留空由系统自动管理"
msgid "Number of parallel threads used for compression"
msgstr "用于压缩内存数据的CPU并发线程数"
msgid "Force 40MHz mode"
msgstr "强制 40MHz 频宽"
msgid ""
"Always use 40MHz channels even if the secondary channel overlaps. Using this "
"option does not comply with IEEE 802.11n-2009!"
msgstr "强制启用 40MHz 频宽并忽略辅助信道重叠。此选项可能不兼容某些无线硬件导致无法启用!"
msgid "Disassociate On Low Acknowledgement"
msgstr "弱信号剔除"
msgid "Allow AP mode to disconnect STAs based on low ACK condition"
msgstr "允许 AP 模式基于低 ACK 条件判断剔除弱信号的客户端"

View File

@ -1,42 +0,0 @@
#
# Copyright (C) 2015-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dsmboot
PKG_VERSION:=5.2
PKG_RELEASE:=5967.1
include $(INCLUDE_DIR)/package.mk
define Package/dsmboot
SECTION:=net
CATEGORY:=Network
TITLE:=Synology DSM pxeboot from TFTP
DEPENDS:=
endef
define Package/dsmboot/description
DSM 5.2 boot from TFTP
endef
define Build/Prepare
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/dsmboot/install
$(INSTALL_DIR) $(1)/root
$(INSTALL_DATA) ./files/* $(1)/root/
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/dsmboot $(1)/etc/uci-defaults/yyy-dsmboot
endef
$(eval $(call BuildPackage,dsmboot))

Binary file not shown.

View File

@ -1,10 +0,0 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
set dhcp.@dnsmasq[0].enable_tftp='1'
set dhcp.@dnsmasq[0].dhcp_boot='pxelinux.0'
set dhcp.@dnsmasq[0].tftp_root='/root'
commit dhcp
EOF
exit 0

View File

@ -1,9 +0,0 @@
default 0
timeout 0
fallback 0
title Synology DSM
map --mem (pd)/dsm.iso (hd32)
map --hook
chainloader (hd32)

Binary file not shown.

View File

@ -1,53 +0,0 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/target.mk
PKG_NAME:=fogvdn
PKG_VERSION:=1
PKG_RELEASE:=1
PKG_HASH:=skip
ifeq ($(ARCH),x86_64)
PKG_ARCH:=X64
else ifeq ($(ARCH),arm)
PKG_ARCH:=ARM
else ifeq ($(ARCH),aarch64)
PKG_ARCH:=ARM64
endif
PKG_SOURCE:=fogvdn_PEAR_$(PKG_ARCH)_LINUX_latest.tar.gz
PKG_SOURCE_URL:=https://download.openfogos.com/release/
include $(INCLUDE_DIR)/package.mk
PKG_UNPACK:=$(HOST_TAR) -C $(PKG_BUILD_DIR)/root --strip-components=1 -xzf $(DL_DIR)/$(PKG_SOURCE)
define Package/fogvdn
SECTION:=net
CATEGORY:=Network
TITLE:=OpenFog Pear P2P CDN
DEPENDS:=@(aarch64||arm||x86_64) \
+bash +getopt +jq +ntpdate +whereis \
+smartmontools +zoneinfo-all +coreutils \
+coreutils-install +coreutils-df +coreutils-nohup
endef
define Package/fogvdn/description
OpenFog Pear Peer-to-Peer Content Delivery Network
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)/root
$(PKG_UNPACK)
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/fogvdn/install
$(CP) $(PKG_BUILD_DIR)/root/* $(1)/
endef
$(eval $(call BuildPackage,fogvdn))

Some files were not shown because too many files have changed in this diff Show More