// 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; }
// アダプタを開く (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; }