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

📄 klips.c

📁 This isakmpd, a BSD-licensed ISAKMP/Oakley (a.k.a. IKE) implementation.
💻 C
📖 第 1 页 / 共 2 页
字号:
    = ((struct sockaddr_in *)(incoming ? src : dst))->sin_addr;  /*   * Klips does not know about expirations, thus we need to do them inside   * isakmpd.   */  if (sa->seconds)    if (sa_setup_expirations (sa))      goto cleanup;  LOG_DBG ((LOG_SYSDEP, 10, "klips_set_spi: proto %d dst %s SPI 0x%x",	    emsg->em_proto, inet_ntoa (emsg->em_dst), htonl (emsg->em_spi)));  if (klips_write (emsg))    goto cleanup;  free (emsg);  /* If we are tunneling we have to setup an IP in IP tunnel too.  */  if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL)    {      len = EMT_SETSPI_FLEN + EMT_IPE4_ULEN;      emsg = calloc (1, len);      if (!emsg)	goto cleanup;      emsg->em_proto = IPPROTO_IPIP;      emsg->em_msglen = len;      emsg->em_type = EMT_SETSPI;      /*       * XXX Code in Pluto suggests this is not possible, but that we have       * to have a unique SPI for the IP4 SA.       */      memcpy (&emsg->em_spi, proto->spi[incoming], sizeof emsg->em_spi);      emsg->em_flags = 0;      emsg->em_alg = XF_IP4;      ip4x = (struct ipe4_xdata *)emsg->em_dat;      ip4x->i4_dst = emsg->em_dst	= ((struct sockaddr_in *)(incoming ? src : dst))->sin_addr;      ip4x->i4_src	= ((struct sockaddr_in *)(incoming ? dst : src))->sin_addr;      LOG_DBG ((LOG_SYSDEP, 10, "klips_set_spi: proto %d dst %s SPI 0x%x",		emsg->em_proto, inet_ntoa (emsg->em_dst),		htonl (emsg->em_spi)));      if (klips_write (emsg))	goto cleanup;      free (emsg);      /*       * Grouping the IP-in-IP SA with the IPsec one means we must be careful       * in klips_group_spis so that we'll remove duplicate IP-in-IP SAs       * and get everything grouped in the right order.       *       * XXX Could we not share code with klips_group_spis here?       */      emsg = calloc (1, EMT_GRPSPIS_FLEN + 2 * EMT_GRPSPIS_COMPLEN);      if (!emsg)	goto cleanup;      emsg->em_msglen = EMT_GRPSPIS_FLEN + 2 * EMT_GRPSPIS_COMPLEN;      emsg->em_type = EMT_GRPSPIS;      memcpy (&emsg->em_rel[0].emr_spi, proto->spi[incoming],	      sizeof emsg->em_rel[0].emr_spi);      memcpy (&emsg->em_rel[1].emr_spi, proto->spi[incoming],	      sizeof emsg->em_rel[1].emr_spi);      emsg->em_rel[0].emr_dst = emsg->em_rel[1].emr_dst	= ((struct sockaddr_in *)(incoming ? src : dst))->sin_addr;      emsg->em_rel[0].emr_proto = IPPROTO_IPIP;      /* XXX What if IPCOMP etc. comes along?  */      emsg->em_rel[1].emr_proto	= proto->proto == IPSEC_PROTO_IPSEC_ESP ? IPPROTO_ESP : IPPROTO_AH;      if (klips_write (emsg))	goto cleanup;      free (emsg);    }  LOG_DBG ((LOG_SYSDEP, 50, "klips_set_spi: done"));  return 0; cleanup:  /* XXX Cleanup the potential SAs we have setup.  */  if (emsg)    free (emsg);  return -1;}/* * Delete the IPsec SA represented by the INCOMING direction in protocol PROTO * of the IKE security association SA. */intklips_delete_spi (struct sa *sa, struct proto *proto, int incoming){  struct encap_msghdr *emsg = 0;  struct sockaddr *dst;  struct ipsec_proto *iproto = proto->data;  emsg = calloc (1, EMT_SETSPI_FLEN);  if (!emsg)    return -1;  emsg->em_msglen = EMT_SETSPI_FLEN;  emsg->em_type = EMT_DELSPI;  memcpy (&emsg->em_spi, proto->spi[incoming], sizeof emsg->em_spi);  if (incoming)    sa->transport->vtbl->get_src (sa->transport, &dst);  else    sa->transport->vtbl->get_dst (sa->transport, &dst);  emsg->em_dst = ((struct sockaddr_in *)dst)->sin_addr;  /* XXX What if IPCOMP etc. comes along?  */  emsg->em_proto    = (iproto->encap_mode == IPSEC_ENCAP_TUNNEL ? IPPROTO_IPIP       : proto->proto == IPSEC_PROTO_IPSEC_ESP ? IPPROTO_ESP : IPPROTO_AH);  if (klips_write (emsg))    goto cleanup;  free (emsg);  LOG_DBG ((LOG_SYSDEP, 50, "klips_delete_spi: done"));  return 0; cleanup:  if (emsg)    free (emsg);  return -1;}intklips_hex_decode (char *src, u_char *dst, int dstsize){  char *p, *pe;  u_char *q, *qe, ch, cl;  pe = src + strlen (src);  qe = dst + dstsize;  for (p = src, q = dst; p < pe && q < qe && isxdigit ((int)*p); p += 2)    {      ch = tolower (p[0]);      cl = tolower (p[1]);      if ((ch >= '0') && (ch <= '9'))	ch -= '0';      else if ((ch >= 'a') && (ch <= 'f'))	ch -= 'a' - 10;      else	return -1;      if ((cl >= '0') && (cl <= '9'))	cl -= '0';      else if ((cl >= 'a') && (cl <= 'f'))	cl -= 'a' - 10;      else	return -1;      *q++ = (ch << 4) | cl;    }  return (int)(q - dst);}/* Consult kernel routing table for next-hop lookup. From dugsong@monkey.org */u_longklips_route_get (u_long dst){  FILE *f;  char buf[BUFSIZ];  char ifbuf[16], netbuf[128], gatebuf[128], maskbuf[128];  int i, iflags, refcnt, use, metric, mss, win, irtt;  u_long ret, gate, net, mask;  if ((f = fopen (PROC_ROUTE_FILE, "r")) == NULL)    return dst;  ret = dst;  while (fgets (buf, sizeof buf, f) != NULL)    {      i = sscanf (buf, PROC_ROUTE_FMT, ifbuf, netbuf, gatebuf, &iflags,		  &refcnt, &use, &metric, maskbuf, &mss, &win, &irtt);      if (i < 10 || !(iflags & RTF_UP))	continue;      klips_hex_decode (netbuf, (u_char *)&net, sizeof net);      klips_hex_decode (gatebuf, (u_char *)&gate, sizeof gate);      klips_hex_decode (maskbuf, (u_char *)&mask, sizeof mask);      net = htonl (net);      gate = htonl (gate);      mask = htonl (mask);      if ((dst & mask) == net)	{	  if (gate != INADDR_ANY)	    ret = gate;	  break;	}    }  fclose (f);  return ret;}/* Enable a flow given a SA.  */intklips_enable_sa (struct sa *sa, struct sa *isakmp_sa){  struct ipsec_sa *isa = sa->data;  struct sockaddr *dst;  struct proto *proto = TAILQ_FIRST (&sa->protos);  struct ipsec_proto *iproto = proto->data;  struct encap_msghdr emsg;  int s = -1;  struct rtentry rt;  sa->transport->vtbl->get_dst (sa->transport, &dst);  /* XXX Is this needed?  */  memset (&emsg, '\0', sizeof emsg);  emsg.em_msglen = sizeof emsg;  emsg.em_type = EMT_RPLACEROUTE;  memcpy (&emsg.em_erspi, proto->spi[0], sizeof emsg.em_erspi);  emsg.em_erdst = ((struct sockaddr_in *)dst)->sin_addr;  LOG_DBG ((LOG_SYSDEP, 50, "klips_enable_sa: src %x %x dst %x %x",	    ntohl (isa->src_net), ntohl (isa->src_mask), ntohl (isa->dst_net),	    ntohl (isa->dst_mask)));  /* XXX Magic constant from Pluto (26 = AF_ISDN in BSD).  */  emsg.em_eaddr.sen_family = emsg.em_emask.sen_family = 26;  emsg.em_eaddr.sen_type = SENT_IP4;  /* XXX Magic constant from Pluto.  */  emsg.em_emask.sen_type = 255;  emsg.em_eaddr.sen_len = emsg.em_emask.sen_len    = sizeof (struct sockaddr_encap);  emsg.em_eaddr.sen_ip_src.s_addr = isa->src_net;  emsg.em_emask.sen_ip_src.s_addr = isa->src_mask;  emsg.em_eaddr.sen_ip_dst.s_addr = isa->dst_net;  emsg.em_emask.sen_ip_dst.s_addr = isa->dst_mask;  /* XXX What if IPCOMP etc. comes along?  */  emsg.em_erproto    = (iproto->encap_mode == IPSEC_ENCAP_TUNNEL ? IPPROTO_IPIP       : proto->proto == IPSEC_PROTO_IPSEC_ESP ? IPPROTO_ESP : IPPROTO_AH);  if (klips_write (&emsg))    {      emsg.em_type = EMT_SETEROUTE;      if (klips_write (&emsg))	goto cleanup;    }  s = socket (PF_INET, SOCK_DGRAM, AF_UNSPEC);  if (s == -1)    {      log_error ("klips_enable_sa: "		 "socket(PF_INET, SOCK_DGRAM, AF_UNSPEC) failed");      goto cleanup;    }  memset (&rt, '\0', sizeof rt);  rt.rt_dst.sa_family = AF_INET;  ((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr = isa->dst_net;  rt.rt_genmask.sa_family = AF_INET;  ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr = isa->dst_mask;  rt.rt_gateway.sa_family = AF_INET;  ((struct sockaddr_in *)&rt.rt_gateway)->sin_addr.s_addr    = klips_route_get (emsg.em_erdst.s_addr);  rt.rt_flags = RTF_UP | RTF_GATEWAY;  /* XXX What if we have multiple interfaces?  */  rt.rt_dev = "ipsec0";  if (ioctl (s, SIOCDELRT, &rt) == -1 && errno != ESRCH)    {      log_error ("klips_enable_sa: ioctl (%d, SIOCDELRT, %p) failed", s, &rt);      goto cleanup;    }  if (ioctl (s, SIOCADDRT, &rt) == -1)    {      log_error ("klips_enable_sa: ioctl (%d, SIOCADDRT, %p) failed", s, &rt);      goto cleanup;    }  close (s);  return 0; cleanup:  if (s != -1)    close (s);  return -1;}static voidklips_stayalive (struct exchange *exchange, void *vconn, int fail){  char *conn = vconn;  struct sa *sa;  /* XXX What if it is phase 1?  */  sa = sa_lookup_by_name (conn, 2);  if (sa)    sa->flags |= SA_FLAG_STAYALIVE;}/* Establish the connection in VCONN and set the stayalive flag for it.  */voidklips_connection_check (char *conn){  if (!sa_lookup_by_name (conn, 2))    {      LOG_DBG ((LOG_SYSDEP, 70, "klips_connection_check: SA for %s missing",		conn));      exchange_establish (conn, klips_stayalive, conn);    }  else    LOG_DBG ((LOG_SYSDEP, 70, "klips_connection_check: SA for %s exists",	      conn));}

⌨️ 快捷键说明

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