// Open Ethernet adapter (Solaris)
ETH *OpenEthSolaris(char *name, bool local, bool tapmode, char *tapaddr)
{
	char devname[MAX_SIZE];
	UINT devid;
	int fd;
	ETH *e;
	CANCEL *c;
	struct strioctl sioc;

	// Validate arguments
	if (name == NULL || tapmode != false)
	{
		return NULL;
	}

	// Parse device name
	if (ParseUnixEthDeviceName(devname, sizeof(devname), &devid, name) == false)
	{
		return NULL;
	}

	// Open the device
	fd = open(devname, O_RDWR);
	if (fd == -1)
	{
		// Failed
		return NULL;
	}

	// Attach to the device
	if (DlipAttatchRequest(fd, devid) == false)
	{
		// Failed
		close(fd);
		return NULL;
	}

	// Verify ACK message
	if (DlipReceiveAck(fd) == false)
	{
		// Failed
		close(fd);
		return NULL;
	}

	// Bind to SAP
	if (DlipBindRequest(fd) == false)
	{
		// Failed
		close(fd);
		return NULL;
	}

	// Verify ACK message
	if (DlipReceiveAck(fd) == false)
	{
		// Failed
		close(fd);
		return NULL;
	}

	// Set to ignore SAP and promiscuous mode
	if (DlipPromiscuous(fd, DL_PROMISC_SAP) == false)
	{
		// Failed
		close(fd);
		return NULL;
	}

	// Verify ACK message
	if (DlipReceiveAck(fd) == false)
	{
		// Failed
		close(fd);
		return NULL;
	}

	// Set to the mode to receive self sending packet
	if (DlipPromiscuous(fd, DL_PROMISC_PHYS) == false)
	{
		// Failed
		close(fd);
		return NULL;
	}

	// Verify ACK message
	if (DlipReceiveAck(fd) == false)
	{
		// Failed
		close(fd);
		return NULL;
	}

	// Set to raw mode
	sioc.ic_cmd = DLIOCRAW;
	sioc.ic_timout = -1;
	sioc.ic_len = 0;
	sioc.ic_dp = NULL;
	if (ioctl(fd, I_STR, &sioc) < 0)
	{
		// Failed
		close(fd);
		return NULL;
	}

	if (ioctl(fd, I_FLUSH, FLUSHR) < 0)
	{
		// Failed
		close(fd);
		return NULL;
	}

	e = ZeroMalloc(sizeof(ETH));
	e->Name = CopyStr(name);
	e->Title = CopyStr(name);

	c = NewCancel();
	UnixDeletePipe(c->pipe_read, c->pipe_write);
	c->pipe_read = c->pipe_write = -1;

	c->SpecialFlag = true;
	c->pipe_read = fd;

	e->Cancel = c;

	e->IfIndex = -1;
	e->Socket = fd;

	UnixSetSocketNonBlockingMode(fd, true);

	// Get control interface
	e->SocketBsdIf = socket(AF_INET, SOCK_DGRAM, 0);

	// Get MTU value
	e->InitialMtu = EthGetMtu(e);

	return e;
}
Beispiel #2
0
// アダプタを開く (Solaris)
ETH *OpenEthSolaris(char *name, bool local, bool tapmode, char *tapaddr)
{
	char devname[MAX_SIZE];
	UINT devid;
	int fd;
	ETH *e;
	CANCEL *c;
	struct strioctl sioc;

	// 引数チェック
	if (name == NULL || tapmode != false)
	{
		return NULL;
	}

	// デバイス名を解析
	if (ParseUnixEthDeviceName(devname, sizeof(devname), &devid, name) == false)
	{
		return NULL;
	}

	// デバイスを開く
	fd = open(devname, O_RDWR);
	if (fd == -1)
	{
		// 失敗
		return NULL;
	}

	// デバイスにアタッチする
	if (DlipAttatchRequest(fd, devid) == false)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	// 確認
	if (DlipReceiveAck(fd) == false)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	// SAPにバインドする
	if (DlipBindRequest(fd) == false)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	// 確認
	if (DlipReceiveAck(fd) == false)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	// SAPに関わらず受信するモードにセットする
	if (DlipPromiscuous(fd, DL_PROMISC_SAP) == false)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	// 確認
	if (DlipReceiveAck(fd) == false)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	// 自分の送信するパケットも受信するモードにセットする
	if (DlipPromiscuous(fd, DL_PROMISC_PHYS) == false)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	// 確認
	if (DlipReceiveAck(fd) == false)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	// Raw モードに設定
	sioc.ic_cmd = DLIOCRAW;
	sioc.ic_timout = -1;
	sioc.ic_len = 0;
	sioc.ic_dp = NULL;
	if (ioctl(fd, I_STR, &sioc) < 0)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	if (ioctl(fd, I_FLUSH, FLUSHR) < 0)
	{
		// 失敗
		close(fd);
		return NULL;
	}

	e = ZeroMalloc(sizeof(ETH));
	e->Name = CopyStr(name);
	e->Title = CopyStr(name);

	c = NewCancel();
	UnixDeletePipe(c->pipe_read, c->pipe_write);
	c->pipe_read = c->pipe_write = -1;

	c->SpecialFlag = true;
	c->pipe_read = fd;

	e->Cancel = c;

	e->IfIndex = -1;
	e->Socket = fd;

	UnixSetSocketNonBlockingMode(fd, true);

	// 操作用 I/F の取得
	e->SocketBsdIf = socket(AF_INET, SOCK_DGRAM, 0);

	// MTU の取得
	e->InitialMtu = EthGetMtu(e);

	return e;
}