Пример #1
0
/* check if peer address is within permitted range.
   return >= 0 if so. */
int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange *range) {
   struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
   struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
   char addrbuf[256], maskbuf[256];
   char peername[256];

   /* is provided client address valid? */
   if (pa->sin_addr.s_addr == 0) {
      Warn("invalid client address 0.0.0.0");
      return -1;
   }
   /* client address restriction */
   Debug2("permitted client subnet: %s:%s",
	  inet4addr_info(ntohl(netaddr_in->s_addr), addrbuf, sizeof(addrbuf)),
	  inet4addr_info(ntohl(netmask_in->s_addr), maskbuf, sizeof(maskbuf)));
   Debug1("client address is 0x%08x",
	  ntohl(pa->sin_addr.s_addr));
   Debug1("masked address is 0x%08x",
	  ntohl(pa->sin_addr.s_addr & netmask_in->s_addr));
   if ((pa->sin_addr.s_addr & netmask_in->s_addr)
       != netaddr_in->s_addr) {
      Debug1("client address %s is not permitted",
	     sockaddr_inet4_info(pa, peername, sizeof(peername)));
      return -1;
   }
   return 0;
}
Пример #2
0
/* returns information that can be used for constructing an environment
   variable describing the socket address.
   if idx is 0, this function writes "ADDR" into namebuff and the IP address
   into valuebuff, and returns 1 (which means that one more info is there).
   if idx is 1, it writes "PORT" into namebuff and the port number into
   valuebuff, and returns 0 (no more info)
   namelen and valuelen contain the max. allowed length of output chars in the
   respective buffer.
   on error this function returns -1.
*/
int
xiosetsockaddrenv_ip4(int idx, char *namebuff, size_t namelen,
		      char *valuebuff, size_t valuelen,
		      struct sockaddr_in *sa, int ipproto) {
   switch (idx) {
   case 0:
      strcpy(namebuff, "ADDR");
      inet4addr_info(ntohl(sa->sin_addr.s_addr), valuebuff, valuelen);
      switch (ipproto) {
      case IPPROTO_TCP:
      case IPPROTO_UDP:
#ifdef IPPROTO_SCTP
      case IPPROTO_SCTP:
#endif
	 return 1;	/* there is port information to also be retrieved */
      default:
	 return 0;	/* no port info coming */
      }
   case 1:
      strcpy(namebuff, "PORT");
      snprintf(valuebuff, valuelen, "%u", ntohs(sa->sin_port));
      return 0;
   }
   return -1;
}
Пример #3
0
/* these are valid for IPv4 and IPv6 */
int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
			char *typbuff, int typlen,
			char *nambuff, int namlen,
			char *envbuff, int envlen,
			char *valbuff, int vallen) {
   const char *cmsgtype, *cmsgname = NULL, *cmsgenvn = NULL, *cmsgfmt = NULL;
   size_t msglen;
   char scratch1[16];	/* can hold an IPv4 address in ASCII */
   char scratch2[16];
   char scratch3[16];

   msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg);
   envbuff[0] = '\0';
   switch (cmsg->cmsg_type) {
   default:
      *num = 1;
      strncpy(typbuff, "IP", typlen);
      snprintf(nambuff, namlen, "type_%u", cmsg->cmsg_type);
      xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
      return STAT_OK;
#if WITH_IP4
#if defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO
   case IP_PKTINFO: {
      struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
      *num = 3;
      strncpy(typbuff, "IP_PKTINFO", typlen);
      snprintf(nambuff, namlen, "%s%c%s%c%s", "if", '\0', "locaddr", '\0', "dstaddr");
      snprintf(envbuff, envlen, "%s%c%s%c%s", "IP_IF", '\0', 
	       "IP_LOCADDR", '\0', "IP_DSTADDR");
      snprintf(valbuff, vallen, "%s%c%s%c%s",
	       xiogetifname(pktinfo->ipi_ifindex, scratch1, -1), '\0',
	       inet4addr_info(ntohl(pktinfo->ipi_spec_dst.s_addr), scratch2, sizeof(scratch2)), '\0',
	       inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), scratch3, sizeof(scratch3)));
   }
      return STAT_OK;
#endif /* defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO */
#endif /* WITH_IP4 */
#ifdef IP_RECVERR
   case IP_RECVERR: {
      struct sock_extended_err *err =
	 (struct sock_extended_err *)CMSG_DATA(cmsg);
      *num = 6;
      strncpy(typbuff, "IP_RECVERR", typlen);
      snprintf(nambuff, namlen, "%s%c%s%c%s%c%s%c%s%c%s",
	       "errno", '\0', "origin", '\0', "type", '\0',
	       "code", '\0', "info", '\0', "data");
      snprintf(envbuff, envlen, "%s%c%s%c%s%c%s%c%s%c%s",
	       "IP_RECVERR_ERRNO", '\0', "IP_RECVERR_ORIGIN", '\0',
	       "IP_RECVERR_TYPE", '\0', "IP_RECVERR_CODE", '\0',
	       "IP_RECVERR_INFO", '\0', "IP_RECVERR_DATA");
      snprintf(valbuff, vallen, "%u%c%u%c%u%c%u%c%u%c%u",
	       err->ee_errno, '\0', err->ee_origin, '\0', err->ee_type, '\0',
	       err->ee_code, '\0', err->ee_info, '\0', err->ee_data);
      return STAT_OK;
   }
#endif /* IP_RECVERR */
#ifdef IP_RECVIF
   case IP_RECVIF: {
      /* spec in FreeBSD: /usr/include/net/if_dl.h */
      struct sockaddr_dl *sadl = (struct sockaddr_dl *)CMSG_DATA(cmsg);
      *num = 1;
      strncpy(typbuff, "IP_RECVIF", typlen);
      strncpy(nambuff, "if", namlen);
      strncpy(envbuff, "IP_IF", envlen);
      strncpy(valbuff,
	      xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen);
      return STAT_OK;
   }
#endif /* defined(IP_RECVIF) */
#if WITH_IP4
#ifdef IP_RECVDSTADDR
   case IP_RECVDSTADDR:
      *num = 1;
      strncpy(typbuff, "IP_RECVDSTADDR", typlen);
      strncpy(nambuff, "dstaddr", namlen);
      strncpy(envbuff, "IP_DSTADDR", envlen);
      inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen);
      return STAT_OK;
#endif
#endif /* WITH_IP4 */
   case IP_OPTIONS:
#ifdef IP_RECVOPTS
   case IP_RECVOPTS:
#endif
      cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgfmt = NULL; break;
   case IP_TOS:
      cmsgtype = "IP_TOS";     cmsgname = "tos"; cmsgfmt = "%u"; break;
   case IP_TTL: /* Linux */
#ifdef IP_RECVTTL
   case IP_RECVTTL: /* FreeBSD */
#endif
      cmsgtype = "IP_TTL";     cmsgname = "ttl"; cmsgfmt = "%u"; break;
   }
   /* when we come here we provide a single parameter
      with type in cmsgtype, name in cmsgname, printf format in cmsgfmt */
   *num = 1;
   if (strlen(cmsgtype) >= typlen)  Fatal("buff too short");
   strncpy(typbuff, cmsgtype, typlen);
   if (strlen(cmsgname) >= namlen)  Fatal("buff too short");
   strncpy(nambuff, cmsgname, namlen);
   if (cmsgenvn) {
      if (strlen(cmsgenvn) >= envlen)  Fatal("buff too short");
      strncpy(envbuff, cmsgenvn, envlen);
   } else {
      envbuff[0] = '\0';
   }
   if (cmsgfmt != NULL) {
      snprintf(valbuff, vallen, cmsgfmt, *(unsigned char *)CMSG_DATA(cmsg));
   } else {
      xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0);
   }
   return STAT_OK;
}