⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 程序实现了Linux下dhcp客户端以及autoip客户端的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
  ifr.ifr_flags = saved_if_flags | IFF_UP | IFF_BROADCAST | IFF_NOTRAILERS | IFF_RUNNING;  if (ioctl(dhcpSocket,SIOCSIFFLAGS,&ifr)) {    syslog(LOG_ERR,"Start: ioctl SIOCSIFFLAGS: %m\n");    exit(1);  }  memset(&sap,0,sizeof(sap));  do {    i++;    if (i > 1)      syslog(LOG_WARNING,"Start: retrying MAC address request "	"(returned %02x:%02x:%02x:%02x:%02x:%02x)",	ClientHwAddr[0],ClientHwAddr[1],ClientHwAddr[2],	ClientHwAddr[3],ClientHwAddr[4],ClientHwAddr[5]);      if (ioctl(dhcpSocket,SIOCGIFHWADDR,&ifr)) {        syslog(LOG_ERR,"dhcpStart: ioctl SIOCGIFHWADDR: %m\n");	exit(1);      }      if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {	syslog(LOG_ERR,"Start: interface %s is not Ethernet or 802.2 Token Ring\n",ifr.ifr_name);	exit(1);      }      if (setsockopt(dhcpSocket,SOL_SOCKET,SO_BROADCAST,&o,sizeof(o)) == -1) {	syslog(LOG_ERR,"Start: setsockopt: %m\n");	exit(1);      }      ifr.ifr_flags = saved_if_flags | IFF_UP | IFF_BROADCAST | IFF_NOTRAILERS | IFF_RUNNING;      if (ioctl(dhcpSocket,SIOCSIFFLAGS,&ifr)) {        syslog(LOG_ERR,"Start: ioctl SIOCSIFFLAGS: %m\n");	exit(1);      }      memset(&sap,0,sizeof(sap));      sap.spkt_protocol = htons(ETH_P_ALL);      memcpy(sap.spkt_device,IfNameExt,IfNameExt_len);      sap.spkt_family = PF_PACKET;      if (bind(dhcpSocket,(void*)&sap,sizeof(struct sockaddr)) == -1)        syslog(LOG_ERR,"Start: bind: %m\n");      memcpy(ClientHwAddr,ifr.ifr_hwaddr.sa_data,ETH_ALEN);      if (DebugFlag)	fprintf(stdout,"mydhcpcd: MAC address = %02x:%02x:%02x:%02x:%02x:%02x\n",	ClientHwAddr[0], ClientHwAddr[1], ClientHwAddr[2],	ClientHwAddr[3], ClientHwAddr[4], ClientHwAddr[5]);  }  while ( !ClientHwAddr[0] &&	  !ClientHwAddr[1] &&	  !ClientHwAddr[2] &&	  !ClientHwAddr[3] &&	  !ClientHwAddr[4] &&	  !ClientHwAddr[5] &&	   i<HWADDR_TRIES );  i=time(NULL)+ClientHwAddr[5]+4*ClientHwAddr[4]+8*ClientHwAddr[3]+16*ClientHwAddr[2]+32*ClientHwAddr[1]+64*ClientHwAddr[0];  srandom(i);  ip_id=i&0xffff;  udpFooSocket = socket(AF_INET,SOCK_DGRAM,0);  if (udpFooSocket == -1) {    syslog(LOG_ERR,"Start: socket: %m\n");    exit(1);  }  if (setsockopt(udpFooSocket,SOL_SOCKET,SO_BROADCAST,&o,sizeof(o)))    syslog(LOG_ERR,"Start: setsockopt: %m\n");  memset(&clientAddr.sin_addr,0,sizeof(&clientAddr.sin_addr));  clientAddr.sin_family = AF_INET;  clientAddr.sin_port = htons(DHCP_CLIENT_PORT);  if (bind(udpFooSocket,(struct sockaddr *)&clientAddr,sizeof(clientAddr))) {    if (errno != EADDRINUSE)      syslog(LOG_ERR,"Start: bind: %m\n");    close(udpFooSocket);    udpFooSocket = -1;  }  else    if (fcntl(udpFooSocket,F_SETFL,O_NONBLOCK) == -1) {      syslog(LOG_ERR,"Start: fcntl: %m\n");      exit(1);    }  return &Init;}void classclientsetup(){  if (ClassID) {      memcpy(DhcpIface.class_id,ClassID,ClassID_len);      DhcpIface.class_len=ClassID_len;  }  else    classIDsetup();  clientIDsetup();}void *Reboot(){   if (sigsetjmp(env,0xffff)) {      if (DebugFlag)	printf("timed out waiting for DHCP_ACK response\n");      if (TimeOut != 0)	alarm(TimeOut);      return &Init;  }  Start();  memset(&DhcpOptions,0,sizeof(DhcpOptions));  memset(&DhcpIface,0,sizeof(dhcpInterface));  classclientsetup();  return Request(random(),&setDhcpReboot);}void *Init(){  if (sigsetjmp(env,0xffff)) {    if (DebugFlag)       printf("time out  at Init\n");    if (autoip_flag) {      sleep(autoip_sleep);      printf("I have slept for %d secs\n",autoip_sleep);    }    else {      autoip();      autoip_flag = 1;    }    if(TimeOut != 0)      alarm(TimeOut);    return &Init;  }  releaseDhcpOptions();  if (DebugFlag)     printf("broadcasting DHCP_DISCOVER\n");  if (dhcpSendAndRecv(random(),DHCP_OFFER,&setDhcpDiscover)) {    Stop();    return 0;  }  if (SendSecondDiscover)  {    if (DebugFlag)       syslog(LOG_DEBUG,"broadcasting second DHCP_DISCOVER\n");    dhcpSendAndRecv(DhcpMsgRecv->xid,DHCP_OFFER,&setDhcpDiscover);  }  prev_ip_addr = DhcpIface.ciaddr;  DhcpIface.ciaddr = DhcpMsgRecv->yiaddr;  memcpy(&DhcpIface.siaddr,DhcpOptions.val[dhcpServerIdentifier],4);  memcpy(DhcpIface.shaddr,UdpIpMsgRecv.ethhdr.ether_shost,ETH_ALEN);  DhcpIface.xid = DhcpMsgRecv->xid;/* DHCP_OFFER received */  if (DebugFlag)    printf("DHCP_OFFER received from %s (%u.%u.%u.%u)\n",    DhcpMsgRecv->sname,    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);  return Request(DhcpIface.xid,&setDhcpRequest);}void *Request(xid,buildDhcpMsg)unsigned xid;void (*buildDhcpMsg)(unsigned);{/* send the message and read and parse replies into DhcpOptions */  if (DebugFlag)    syslog(LOG_DEBUG,"broadcasting DHCP_REQUEST for %u.%u.%u.%u\n",	   ((unsigned char *)&DhcpIface.ciaddr)[0],	   ((unsigned char *)&DhcpIface.ciaddr)[1],	   ((unsigned char *)&DhcpIface.ciaddr)[2],	   ((unsigned char *)&DhcpIface.ciaddr)[3]);  if (dhcpSendAndRecv(xid,DHCP_ACK,buildDhcpMsg))     return &Init;  ReqSentTime=time(NULL);  if (DebugFlag)     syslog(LOG_DEBUG,    "DHCP_ACK received from %s (%u.%u.%u.%u)\n",DhcpMsgRecv->sname,    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);/* check if the offered IP address already in use  */ /*  if (checkIP(DhcpIface.ciaddr)) {    if (DebugFlag) printf(	"requested %u.%u.%u.%u address is in use\n",	((unsigned char *)&DhcpIface.ciaddr)[0],	((unsigned char *)&DhcpIface.ciaddr)[1],	((unsigned char *)&DhcpIface.ciaddr)[2],	((unsigned char *)&DhcpIface.ciaddr)[3]);    DhcpIface.ciaddr = 0;    return &Decline;  }*/  if (DebugFlag)     printf("verified %u.%u.%u.%u address is not in use\n",    ((unsigned char *)&DhcpIface.ciaddr)[0],    ((unsigned char *)&DhcpIface.ciaddr)[1],    ((unsigned char *)&DhcpIface.ciaddr)[2],    ((unsigned char *)&DhcpIface.ciaddr)[3]);      if (dhcpConfig()) {    Stop();    return (0);  }  /* Successfull ACK: Use the fields obtained for future requests */  memcpy(&DhcpIface.siaddr,DhcpOptions.val[dhcpServerIdentifier],4);  memcpy(DhcpIface.shaddr,UdpIpMsgRecv.ethhdr.ether_shost,ETH_ALEN);  return &Bound;}void *Bound(){  int i, maxfd;  fd_set rset;  char foobuf[512];  if (sigsetjmp(env,0xffff))     return &Renew;  i=ReqSentTime+ntohl(*(unsigned int *)DhcpOptions.val[dhcpT1value])-time(NULL);  if ( i > 0 )    alarm(i);  else    return &Renew;  while(1) {    FD_ZERO(&rset);    maxfd = dhcpSocket;    FD_SET(dhcpSocket, &rset);    if (udpFooSocket  != -1) {      if (udpFooSocket > maxfd)        maxfd = udpFooSocket;	FD_SET(udpFooSocket, &rset);    }    if (select(maxfd+1, &rset, NULL, NULL, NULL) == -1) {      if (errno != EINTR)      return &Renew;    }    else {      if (udpFooSocket != -1 && FD_ISSET(udpFooSocket, &rset))        while (recvfrom(udpFooSocket,(void *)foobuf,sizeof(foobuf),0,NULL,NULL) != -1 );	  if (FD_ISSET(dhcpSocket, &rset))	    while (recvfrom(dhcpSocket,(void *)foobuf,sizeof(foobuf),0,NULL,NULL) != -1 );	 }    }}void *Renew(){  int i;  if (sigsetjmp(env,0xffff))     return &Rebind;  i = ReqSentTime+ntohl(*(unsigned int *)DhcpOptions.val[dhcpT2value])-time(NULL);  if (i > 0)    alarm(i);  else    return &Rebind;  if (DebugFlag)    printf("sending DHCP_REQUEST for %u.%u.%u.%u to %u.%u.%u.%u\n",	   ((unsigned char *)&DhcpIface.ciaddr)[0],	   ((unsigned char *)&DhcpIface.ciaddr)[1],	   ((unsigned char *)&DhcpIface.ciaddr)[2],	   ((unsigned char *)&DhcpIface.ciaddr)[3],	   ((unsigned char *)&DhcpIface.siaddr)[0],	   ((unsigned char *)&DhcpIface.siaddr)[1],	   ((unsigned char *)&DhcpIface.siaddr)[2],	   ((unsigned char *)&DhcpIface.siaddr)[3]);  if (dhcpSendAndRecv(random(),DHCP_ACK,&setDhcpRenew))     return &Rebind;  ReqSentTime=time(NULL);  if (DebugFlag)     printf("DHCP_ACK received from %s (%u.%u.%u.%u)\n",DhcpMsgRecv->sname,    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);  return &Bound;}void *Rebind(){  int i;  if (sigsetjmp(env,0xffff)) {    if (TimeOut != 0) {      alarm(2*TimeOut);    }    return &Stop;  }   i = ReqSentTime+ntohl(*(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime])-time(NULL);  if (i > 0)    alarm(i);  else    return &Stop;  if (DebugFlag)    printf("broadcasting DHCP_REQUEST for %u.%u.%u.%u\n",	   ((unsigned char *)&DhcpIface.ciaddr)[0],	   ((unsigned char *)&DhcpIface.ciaddr)[1],	   ((unsigned char *)&DhcpIface.ciaddr)[2],	   ((unsigned char *)&DhcpIface.ciaddr)[3]);  if (dhcpSendAndRecv(random(),DHCP_ACK,&setDhcpRebind))     return &Stop;  ReqSentTime=time(NULL);  if (DebugFlag)     printf("DHCP_ACK received from %s (%u.%u.%u.%u)\n",DhcpMsgRecv->sname,    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);  /* Successfull ACK: Use the fields obtained for future requests */  memcpy(&DhcpIface.siaddr,DhcpOptions.val[dhcpServerIdentifier],4);  memcpy(DhcpIface.shaddr,UdpIpMsgRecv.ethhdr.ether_shost,ETH_ALEN);  return &Bound;}void *Release(){  struct sockaddr addr;  if (DhcpIface.ciaddr == 0)     return &Init;  setDhcpRelease(random());  memset(&addr,0,sizeof(struct sockaddr));  memcpy(addr.sa_data,IfNameExt,IfNameExt_len);  if (DebugFlag)    printf("sending DHCP_RELEASE for %u.%u.%u.%u to %u.%u.%u.%u\n",	   ((unsigned char *)&DhcpIface.ciaddr)[0],	   ((unsigned char *)&DhcpIface.ciaddr)[1],	   ((unsigned char *)&DhcpIface.ciaddr)[2],	   ((unsigned char *)&DhcpIface.ciaddr)[3],	   ((unsigned char *)&DhcpIface.siaddr)[0],	   ((unsigned char *)&DhcpIface.siaddr)[1],	   ((unsigned char *)&DhcpIface.siaddr)[2],	   ((unsigned char *)&DhcpIface.siaddr)[3]);  if (sendto(dhcpSocket,&UdpIpMsgSend,sizeof(struct packed_ether_header) + sizeof(udpiphdr)+sizeof(dhcpMessage),0,	      &addr,sizeof(struct sockaddr)) == -1 )    syslog(LOG_ERR,"Release: sendto: %m\n");  sendRelArp(); /* clear ARP cache entries for client IP addr */  if (SetHostName) {    sethostname(InitialHostName,InitialHostName_len);    if (DebugFlag)      fprintf(stdout,"dhcpcd: your hostname = %s\n",InitialHostName);  }  DhcpIface.ciaddr=0;  return &Init;}void *Stop(){  struct ifreq ifr;  struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);  releaseDhcpOptions();  memset(&ifr,0,sizeof(struct ifreq));  memcpy(ifr.ifr_name,IfNameExt,IfNameExt_len);  p->sin_family = AF_INET;  p->sin_addr.s_addr = 0;  if (DownIfaceOnStop) {    ifr.ifr_flags = saved_if_flags & ~IFF_UP;    if (ioctl(dhcpSocket,SIOCSIFFLAGS,&ifr))      syslog(LOG_ERR,"Stop: ioctl SIOCSIFFLAGS: %m\n");  }tsc:  close(dhcpSocket);  return &Start;}void *Decline(){  struct sockaddr addr;  memset(&UdpIpMsgSend,0,sizeof(udpipMessage));  memcpy(UdpIpMsgSend.ethhdr.ether_dhost,MAC_BCAST_ADDR,ETH_ALEN);  memcpy(UdpIpMsgSend.ethhdr.ether_shost,ClientHwAddr,ETH_ALEN);  UdpIpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_IP);  setDhcpDecline(random());  udpipgen((udpiphdr *)&UdpIpMsgSend.udpipmsg,0,INADDR_BROADCAST,  htons(DHCP_CLIENT_PORT),htons(DHCP_SERVER_PORT),sizeof(dhcpMessage));  memset(&addr,0,sizeof(struct sockaddr));  memcpy(addr.sa_data,IfNameExt,IfNameExt_len);  if ( DebugFlag ) syslog(LOG_DEBUG,"broadcasting DHCP_DECLINE\n");  if ( sendto(dhcpSocket,&UdpIpMsgSend,sizeof(struct packed_ether_header) + sizeof(udpiphdr)+sizeof(dhcpMessage),0,	      &addr,sizeof(struct sockaddr)) == -1 )    syslog(LOG_ERR,"Decline: sendto: %m\n");  return &Init;}void *Inform(){  Start();  memset(&DhcpOptions,0,sizeof(DhcpOptions));  memset(&DhcpIface,0,sizeof(dhcpInterface));  if (! inform_ipaddr.s_addr) {    struct ifreq ifr;    struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);    memset(&ifr,0,sizeof(struct ifreq));    memcpy(ifr.ifr_name,IfNameExt,IfNameExt_len);    p->sin_family = AF_INET;    if (ioctl(dhcpSocket,SIOCGIFADDR,&ifr) == 0)      inform_ipaddr.s_addr=p->sin_addr.s_addr;    if (! inform_ipaddr.s_addr) {      inform_ipaddr.s_addr=DhcpIface.ciaddr;    }  }  DhcpIface.ciaddr=inform_ipaddr.s_addr;  if (! DhcpIface.class_len) {     if (ClassID) {      memcpy(DhcpIface.class_id,ClassID,ClassID_len);      DhcpIface.class_len=ClassID_len;    }    else      classIDsetup();  }  if (! DhcpIface.client_len)     clientIDsetup();  if (sigsetjmp(env,0xffff)) {    if (DebugFlag)      printf("timed out waiting for DHCP_ACK response\n");    return 0;  }  if (DebugFlag)    printf("broadcasting DHCP_INFORM for %u.%u.%u.%u\n",	   ((unsigned char *)&DhcpIface.ciaddr)[0],	   ((unsigned char *)&DhcpIface.ciaddr)[1],	   ((unsigned char *)&DhcpIface.ciaddr)[2],	   ((unsigned char *)&DhcpIface.ciaddr)[3]);  if (dhcpSendAndRecv(random(),DHCP_ACK,setDhcpInform))     return 0;  if (DebugFlag)     printf("DHCP_ACK received from %s (%u.%u.%u.%u)\n",DhcpMsgRecv->sname,    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);/* check if the offered IP address already in use */  if (checkIP(DhcpIface.ciaddr)) {    if (DebugFlag)       printf("requested %u.%u.%u.%u address is in use\n",	((unsigned char *)&DhcpIface.ciaddr)[0],	((unsigned char *)&DhcpIface.ciaddr)[1],	((unsigned char *)&DhcpIface.ciaddr)[2],	((unsigned char *)&DhcpIface.ciaddr)[3]);    return &Decline;  }  if (DebugFlag)     printf("verified %u.%u.%u.%u address is not in use\n",    ((unsigned char *)&DhcpIface.ciaddr)[0],    ((unsigned char *)&DhcpIface.ciaddr)[1],    ((unsigned char *)&DhcpIface.ciaddr)[2],    ((unsigned char *)&DhcpIface.ciaddr)[3]);  if (dhcpConfig())     return 0;  exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -