📄 ec_inet_solaris.c
字号:
#endif #endif int flags; struct strbuf data; int len = 0, pktlen = 0, caplen; char *buf; static char MyMAC[6]={0x65,0x74,0x74,0x65,0x72,0x63}; if (SocketBuffer == -1) { // only the first time SocketBuffer = Buffer_Create(1.0e5); // 100 K buffer DEBUG_MSG("Inet_GetRawPacket creates the buffer for the first time -- buf id = %d", SocketBuffer); } Buffer_Get(SocketBuffer, &pktlen, sizeof(u_int)); len = Buffer_Get(SocketBuffer, buffer, pktlen ); if (type != NULL) { if (!strncmp(MyMAC,"etterc",6)) // only the first time... Inet_GetIfaceInfo(Options.netiface, NULL, MyMAC, NULL, NULL); if (!memcmp(MyMAC,buffer,6)) *type = 0; // PACKET_HOST else *type = 1; // !PACKET_HOST } if (len > 0) return len; // there was pending fata. buf = (u_char *)calloc(bufsize + offset, sizeof(char)); // buffer is global flags = 0; data.buf = (char *)buf + offset; data.maxlen = MAXDLBUF; data.len = 0; if ( getmsg(sock, &ctl, &data, &flags) < 0 ) { if (errno != EINTR) ERROR_MSG("getmsg()"); } bp = buf + offset; /* Loop through packets */ ep = bp + data.len;#ifdef HAVE_SYS_BUFMOD_H while (bp < ep) { #ifdef LBL_ALIGN if ((long)bp & 3) { sbp = &sbhdr; memcpy(sbp, bp, sizeof(*sbp)); } else #endif sbp = (struct sb_hdr *)bp; pk = bp + sizeof(*sbp); bp += sbp->sbh_totlen; caplen = sbp->sbh_msglen;#else caplen = min(MAXDLBUF, data.len); pk = bp; bp += caplen;#endif Buffer_Put(SocketBuffer, &caplen, sizeof(u_int) ); Buffer_Put(SocketBuffer, pk, caplen );#ifdef HAVE_SYS_BUFMOD_H }#endif Buffer_Get(SocketBuffer, &pktlen, sizeof(u_int)); len = Buffer_Get(SocketBuffer, buffer, pktlen ); if (type != NULL) { if (!memcmp(MyMAC,buffer,6)) *type = 0; // PACKET_HOST else *type = 1; // !PACKET_HOST } free(buf); return len;}int Inet_SendRawPacket(int sock, char *buffer, int len){ struct EnetHeaderInfo { struct ether_addr DestEtherAddr; u_short EtherFrameType; }; struct EnetHeaderInfo ArpHeader = { {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, ETH_P_ARP }; struct strbuf data, ctl; union DL_primitives *dlp; int c; struct EnetHeaderInfo *EnetHeaderInfoP; dlp = (union DL_primitives*) ctlbuf; dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ; dlp->unitdata_req.dl_priority.dl_min = 0; dlp->unitdata_req.dl_priority.dl_max = 0; dlp->unitdata_req.dl_dest_addr_length = (sizeof(struct ether_addr) + sizeof(u_short)); dlp->unitdata_req.dl_dest_addr_offset = DL_UNITDATA_REQ_SIZE; EnetHeaderInfoP = (struct EnetHeaderInfo *)(ctlbuf + DL_UNITDATA_REQ_SIZE); memcpy(EnetHeaderInfoP, (char *)&(ArpHeader), (sizeof(struct ether_addr) + sizeof(u_short))); /* Send it */ ctl.len = DL_UNITDATA_REQ_SIZE + sizeof (struct EnetHeaderInfo); ctl.buf = (char *)dlp; data.maxlen = len; data.len = len; data.buf = buffer; c = putmsg(sock, NULL, &data, 0); if (c == -1) ERROR_MSG("putmsg()"); return (len);}int Inet_SetPromisc(char *iface){ /* * we have already set the promisc mode when we opened the device */ DEBUG_MSG("Inet_SetPromisc \t fd = %d -- WRAPPERED TO NULL (already set)", dlpi_in_use); return 0;}void Inet_Restore_ifr(void){ /* * this function is not needed !! * when a dlpi is closed, the interface is restored */}void Inet_DisableForwarding(void){ struct strioctl strIo; int fd; char buf[65536]; char *cp; cp = "ip_forwarding"; memset(buf, '\0', sizeof(buf)); sprintf(buf, "%s", cp); if ((fd = open("/dev/ip", O_RDWR)) < 0) ERROR_MSG("open failed for /dev/ip"); strIo.ic_cmd = ND_GET; strIo.ic_timout = 0; strIo.ic_len = sizeof(buf); strIo.ic_dp = buf; /* Call IOCTL to return status */ if ( (ioctl(fd, I_STR, (char *)&strIo)) == -1 ) { ERROR_MSG("ioctl(I_STR)"); } if (strIo.ic_cmd == ND_GET) { strcpy(IpForward_status, buf); } DEBUG_MSG("Inet_DisableForwarding -- previous value = %s", IpForward_status); memset(buf, '\0', sizeof(buf)); sprintf(buf, "%s", cp); buf[strlen(buf)+1] = '0'; /* the format is "element"\0"value"\0 */ strIo.ic_cmd = ND_SET; strIo.ic_timout = 0; strIo.ic_len = sizeof(buf); strIo.ic_dp = buf; if ( (ioctl(fd, I_STR, (char *)&strIo)) == -1 ) { ERROR_MSG("ioctl(I_STR)"); } DEBUG_MSG("Inet_DisableForwarding -- NEW value = 0"); close(fd); atexit(Inet_RestoreForwarding);}void Inet_RestoreForwarding(void){ struct strioctl strIo; int fd; char buf[65536]; char *cp; cp = "ip_forwarding"; memset(buf, '\0', sizeof(buf)); sprintf(buf, "%s", cp); sprintf(buf + strlen(buf)+1, "%s", IpForward_status); /* the format is "element"\0"value"\0 */ DEBUG_MSG("Inet_RestoreForwarding -- restoring to value = %s", IpForward_status); if ((fd = open("/dev/ip", O_RDWR)) < 0) ERROR_MSG("open failed for /dev/ip"); strIo.ic_cmd = ND_SET; strIo.ic_timout = 0; strIo.ic_len = sizeof(buf); strIo.ic_dp = buf; /* Call IOCTL to return status */ if ( (ioctl(fd, I_STR, (char *)&strIo)) == -1 ) { ERROR_MSG("ioctl(I_STR)"); } close(fd);}char *Inet_MacFromIP(unsigned long ip){ int sockfd; static struct arpreq arpreq; struct sockaddr_in *sin; DEBUG_MSG("Inet_MacFromIP"); bzero(&arpreq, sizeof(struct arpreq)); arpreq.arp_pa.sa_family = AF_INET; sin = (struct sockaddr_in *)&arpreq.arp_pa; sin->sin_family = AF_INET; sin->sin_addr.s_addr = ip; if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) ERROR_MSG("socket()"); if (ioctl(sockfd, SIOCGARP, (caddr_t)&arpreq) < 0) { struct recv_packet recvpck; char MyMAC[6]; u_long MyIP; int MTU, sock; TIME_DECLARE; DEBUG_MSG("Inet_MacFromIP -- try to find it"); sock = Inet_OpenRawSock(Options.netiface); Inet_GetIfaceInfo(Options.netiface, &MTU, MyMAC, &MyIP, NULL); if (ip == MyIP) { DEBUG_MSG("Inet_MacFromIP -- try to find me... ;)"); memcpy(&arpreq.arp_ha.sa_data, MyMAC, ETHER_ADDR_LEN); Inet_CloseRawSock(sock); close(sockfd); return (char *) arpreq.arp_ha.sa_data; } recvpck.buf = Inet_Forge_packet( MTU + ALIGN_ETH_TO_WORD ); recvpck.aligned = recvpck.buf + ALIGN_ETH_TO_WORD; Inet_Forge_ethernet( recvpck.aligned, MyMAC, ETH_BROADCAST, ETH_P_ARP ); Inet_Forge_arp(recvpck.aligned + ETH_HEADER, ARPOP_REQUEST, MyMAC, MyIP, ARP_BROADCAST, ip ); Inet_SendRawPacket(sock, recvpck.aligned, ETH_HEADER + ARP_HEADER); memset(recvpck.aligned, 0, MTU); fcntl(sock, F_SETFL, O_NONBLOCK); TIME_START; do { int len; short pkttype; ETH_header *ethpkt; ARP_header *arppkt; len = Inet_GetRawPacket(sock, recvpck.aligned, MTU, &pkttype); ethpkt = (ETH_header *)recvpck.aligned; arppkt = (ARP_header *)(ethpkt + 1); TIME_FINISH; if (len > 0 && pkttype == PACKET_HOST && ethpkt->type == htons(ETH_P_ARP) && arppkt->opcode == htons(ARPOP_REPLY)) { if ( *(unsigned long *)arppkt->source_ip == ip ) { memcpy(&arpreq.arp_ha.sa_data, &arppkt->source_add, ETHER_ADDR_LEN); Inet_Forge_packet_destroy( recvpck.buf ); Inet_CloseRawSock(sock); close(sockfd); return (char *) arpreq.arp_ha.sa_data; } } } while ( TIME_ELAPSED < 0.5 ); Inet_Forge_packet_destroy( recvpck.buf ); Inet_CloseRawSock(sock); close(sockfd); return ETH_BROADCAST; // workaround for non local ip } close(sockfd); return (char *) arpreq.arp_ha.sa_data;}/* * * *** DLPI FUNCTIONS *** */static intsend_request(int fd, char *ptr, int len, char *what, char *ebuf){ struct strbuf ctl; int flags; ctl.maxlen = 0; ctl.len = len; ctl.buf = ptr; flags = 0; if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) { sprintf(ebuf, "send_request: putmsg \"%s\": %s", what, strerror(errno)); DEBUG_MSG("\tDLPI : send_request -- ERROR %s", ebuf); return (-1); } return (0);}static intrecv_ack(int fd, int size, const char *what, char *bufp, char *ebuf){ union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; flags = 0; if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) { sprintf(ebuf, "recv_ack: %s getmsg: %s", what, strerror(errno)); DEBUG_MSG("\tDLPI : recv_ack -- ERROR %s", ebuf); return (-1); } dlp = (union DL_primitives *)ctl.buf; switch (dlp->dl_primitive) { case DL_INFO_ACK: case DL_PHYS_ADDR_ACK: case DL_BIND_ACK: case DL_OK_ACK:#ifdef DL_HP_PPA_ACK case DL_HP_PPA_ACK:#endif /* * These are OK */ break; case DL_ERROR_ACK: switch (dlp->error_ack.dl_errno) { case DL_BADPPA: sprintf(ebuf, "recv_ack: %s bad ppa (device unit)", what); break; case DL_SYSERR: sprintf(ebuf, "recv_ack: %s: %s", what, strerror(dlp->error_ack.dl_unix_errno)); break; case DL_UNSUPPORTED: sprintf(ebuf, "recv_ack: %s: Service not supplied by provider", what); break; default: sprintf(ebuf, "recv_ack: %s error 0x%x", what, (u_int)dlp->error_ack.dl_errno); break; } return (-1); default: sprintf(ebuf, "recv_ack: %s unexpected primitive ack 0x%x ", what, (u_int)dlp->dl_primitive); return (-1); } if (ctl.len < size) { sprintf(ebuf, "recv_ack: %s ack too small (%d < %d)", what, ctl.len, size); return (-1); } return (ctl.len);}/*static intdlpromiscoffreq(int fd, u_int level, char *ebuf){ dl_promiscon_req_t req; req.dl_primitive = DL_PROMISCOFF_REQ; req.dl_level = level; return (send_request(fd, (char *)&req, sizeof(req), "promiscoff", ebuf));}*/static intdlpromisconreq(int fd, u_int level, char *ebuf){ dl_promiscon_req_t req; req.dl_primitive = DL_PROMISCON_REQ; req.dl_level = level; return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf));}static intdlattachreq(int fd, u_int ppa, char *ebuf){ dl_attach_req_t req; req.dl_primitive = DL_ATTACH_REQ; req.dl_ppa = ppa; return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf));}static intdlbindreq(int fd, u_int sap, char *ebuf){ dl_bind_req_t req; memset((char *)&req, 0, sizeof(req)); req.dl_primitive = DL_BIND_REQ;#ifdef DL_HP_RAWDLS req.dl_max_conind = 1; /* XXX magic number */ /* * 22 is INSAP as per the HP-UX DLPI Programmer's Guide */ req.dl_sap = 22; req.dl_service_mode = DL_HP_RAWDLS;#else req.dl_sap = sap;#ifdef DL_CLDLS req.dl_service_mode = DL_CLDLS;#endif#endif return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf));}static intdlbindack(int fd, char *bufp, char *ebuf){ return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf));}static intdlokack(int fd, const char *what, char *bufp, char *ebuf){ return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf));}static intdlinforeq(int fd, char *ebuf){ dl_info_req_t req; req.dl_primitive = DL_INFO_REQ; return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf));}static intdlinfoack(int fd, char *bufp, char *ebuf){ return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf));}#ifdef HAVE_SYS_BUFMOD_Hstatic intstrioctl(int fd, int cmd, int len, char *dp){ struct strioctl str; int rc; str.ic_cmd = cmd; str.ic_timout = -1; str.ic_len = len; str.ic_dp = dp; rc = ioctl(fd, I_STR, &str); if (rc < 0) return (rc); else return (str.ic_len);}static char *get_release(u_int *majorp, u_int *minorp, u_int *microp){ char *cp; static char buf[32]; *majorp = 0; *minorp = 0; *microp = 0; if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0) return ("?"); cp = buf; if (!isdigit((int)*cp)) return (buf); *majorp = strtol(cp, &cp, 10); if (*cp++ != '.') return (buf); *minorp = strtol(cp, &cp, 10); if (*cp++ != '.') return (buf); *microp = strtol(cp, &cp, 10); return (buf);}#endifstatic char *split_dname(char *device, int *unitp){ char *cp; char *eos; int unit; /* * Look for a number at the end of the device name string. */ cp = device + strlen(device) - 1; if (*cp < '0' || *cp > '9') return (NULL); /* Digits at end of string are unit number */ while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9') cp--; unit = strtol(cp, &eos, 10); if (*eos != '\0') return (NULL); *unitp = unit; return (cp);}/* EOF */// vim:ts=3:expandtab
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -