public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Michael Clark <michael@metaparadigm.com>
To: linux-kernel@vger.kernel.org
Subject: Re: UDP recvmsg blocks after select(), 2.6 bug?
Date: Thu, 21 Oct 2004 11:52:05 +0800	[thread overview]
Message-ID: <41773265.1010404@metaparadigm.com> (raw)
In-Reply-To: <41772674.50403@metaparadigm.com>

[-- Attachment #1: Type: text/plain, Size: 1027 bytes --]

Hi All,

I'm actually trying to write a test case to demonstrate
the problem in a repeatable way.

I first looked at socket(PF_INET, SOCK_RAW) to inject the
packets but it appears I have no control over the IP
checksum, and an invalid UDP sum didn't cause any problems
(the packet was accepted fine).

So i've hacked up something with socket(PF_PACKET, SOCK_RAW)
but the problem i'm getting (although tcpdumps of the packets
look perfect), they are not being accepted by my UDP listening
socket. It uses real interfaces, not loopback for the raw
packet injection as the checksumming appears to be bypassed
on the loopback interface (I always see bad UDP checksum
on normally originated packets on the loopback interface).

Anyway, i've probably done something dumb. Anyone care to look
at my test code? The current code sends the packets out on all
interfaces (using the correct associated IP and MAC). Can change
the #if in main() to make it use normal UDP not my cooked packets
(which currently have correct checksums).

~mc

[-- Attachment #2: udptest.c --]
[-- Type: text/x-csrc, Size: 7189 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <linux/if.h>


typedef struct cooked_packet {
  struct ether_header ethp;
  struct iphdr ipp;
  struct udphdr udpp;
} __attribute__ ((__packed__)) cooked_packet;


unsigned short ip_cksum(unsigned short *ptr, int nbytes)
{
  int sum;
  unsigned short oddbyte, answer;

  sum = 0;
  while (nbytes > 1)  {
    sum += *ptr++;
    nbytes -= 2;
  }

  /* mop up an odd byte, if necessary */
  if (nbytes == 1) {
    oddbyte = 0;		/* make sure top half is zero */
    *((unsigned char *) &oddbyte) =
      *(unsigned char *)ptr;   /* one byte only */
    sum += oddbyte;
  }

  /*
   * Add back carry outs from top 16 bits to low 16 bits.
   */
  sum  = (sum >> 16) + (sum & 0xffff);	/* add high-16 to low-16 */
  sum += (sum >> 16);			/* add carry */
  answer = ~sum;		/* ones-complement, then truncate to 16 bits */
  return(answer);
}

unsigned short udp_cksum(unsigned short *ptr, int nbytes, in_addr_t *src, in_addr_t *dst)
{
  int i;
  int sum;
  unsigned short oddbyte, answer;

  sum = 0;

  /* add the UDP pseudo header which contains the IP src and
   * destinationn addresses */
  sum += *((unsigned short*)src);
  sum += *((unsigned short*)src+1);
  sum += *((unsigned short*)dst);
  sum += *((unsigned short*)dst+1);

  /* add protocol number + packet length */
  sum += htons(17) + htons(nbytes);

  while (nbytes > 1)  {
    sum += *ptr++;
    nbytes -= 2;
  }

  /* mop up an odd byte, if necessary */
  if (nbytes == 1) {
    oddbyte = 0;		/* make sure top half is zero */
    *((unsigned char *) &oddbyte) =
      *(unsigned char *)ptr;   /* one byte only */
    sum += oddbyte;
  }

  /*
   * Add back carry outs from top 16 bits to low 16 bits.
   */
  sum  = (sum >> 16) + (sum & 0xffff);	/* add high-16 to low-16 */
  sum += (sum >> 16);			/* add carry */
  answer = ~sum;		/* ones-complement, then truncate to 16 bits */
  return(answer);
}

void cook_udp_packet(cooked_packet *p, int len,
		     char *ether_dhost, char *ether_shost,
		     in_addr_t src, in_addr_t dst,
		     unsigned short src_port, unsigned short dst_port)
{
  p->ethp.ether_type = htons(ETH_P_IP);
  memcpy(&p->ethp.ether_dhost, ether_dhost, ETH_ALEN);
  memcpy(&p->ethp.ether_shost, ether_shost, ETH_ALEN);
  p->ipp.version = 0x4;
  p->ipp.ihl = 0x5;
  p->ipp.tos = 0;
  p->ipp.tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + len);
  p->ipp.id = 0;
  p->ipp.frag_off = htons(0x4000); /* DF */
  p->ipp.ttl = 64;
  p->ipp.protocol = 17; /* UDP */
  p->ipp.check = 0;
  p->ipp.saddr = src;
  p->ipp.daddr = dst;
  p->udpp.source = src_port;
  p->udpp.dest = dst_port;
  p->udpp.len = htons(sizeof(struct udphdr) + len);
  p->udpp.check = 0x0;
  p->udpp.check = udp_cksum((unsigned short*)&p->udpp,
			    sizeof(struct udphdr) + len, &src, &dst);
  p->ipp.check = ip_cksum((unsigned short*)&p->ipp, sizeof(struct ip));
}


void send_raw_udp(unsigned short src_port, unsigned short dst_port,
		  char *payload)
{
  int raw_sock, i;
  struct sockaddr_ll dest_addr;
  struct ifconf ifc;
  struct ifreq *ifr;
  char *packet = malloc(sizeof(cooked_packet) + strlen(payload));

  if((raw_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
    perror("socket");
    exit(1);
  }

  ifc.ifc_len = 0;
  ifc.ifc_buf = NULL;
  if (ioctl(raw_sock, SIOCGIFCONF, &ifc) < 0) {
    perror("ioctl(SIOCGIFCONF)");
    exit(1);
  }
  ifc.ifc_buf = malloc(ifc.ifc_len);
  if (ioctl(raw_sock, SIOCGIFCONF, &ifc) < 0) {
    perror("ioctl(SIOCGIFCONF)");
    exit(1);
  }

  /* send the packet out on all interfaces - just while testing */
  ifr = ifc.ifc_req;
  for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
      struct ifreq ixifr, ipifr, hwifr;
      struct sockaddr_in *ipaddr;
      char *hw;

      strcpy(ixifr.ifr_name, ifr->ifr_name);
      if(ioctl(raw_sock, SIOCGIFINDEX, &ixifr) < 0) continue;
      strcpy(ipifr.ifr_name, ifr->ifr_name);
      if(ioctl(raw_sock, SIOCGIFADDR, &ipifr) < 0) continue;
      ipaddr = (struct sockaddr_in*)&ipifr.ifr_addr;
      strcpy(hwifr.ifr_name, ifr->ifr_name);
      if(ioctl(raw_sock, SIOCGIFHWADDR, &hwifr) < 0) continue;
      hw = (char*)&hwifr.ifr_hwaddr.sa_data;

      printf("sending via %s addr=%s hw=%02X:%02X:%02X:%02X:%02X:%02X\n",
	     ifr->ifr_name, inet_ntoa(ipaddr->sin_addr),
	     (hw[0] & 0377), (hw[1] & 0377), (hw[2] & 0377),
	     (hw[3] & 0377), (hw[4] & 0377), (hw[5] & 0377));
      memcpy(packet + sizeof(cooked_packet), payload, strlen(payload)+1);
      cook_udp_packet((cooked_packet*)packet, strlen(payload)+1,
		      hw, hw, ipaddr->sin_addr.s_addr, ipaddr->sin_addr.s_addr,
		      src_port, dst_port);

      memset(&dest_addr, 0, sizeof(dest_addr));
      dest_addr.sll_family = AF_PACKET;
      dest_addr.sll_ifindex = ixifr.ifr_ifindex;

      sendto(raw_sock, packet, sizeof(cooked_packet) + strlen(payload)+1,
	     0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
  }
  close(raw_sock);
}

void send_normal_udp(unsigned short src_port, unsigned short dst_port,
		     char *payload)
{
  int udp_sock;
  struct sockaddr_in src_addr, dest_addr;

  src_addr.sin_family = AF_INET;
  src_addr.sin_port = src_port;
  src_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

  dest_addr.sin_family = AF_INET;
  dest_addr.sin_port = dst_port;
  dest_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

  if((udp_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("socket");
    exit(1);
  }

  if(bind(udp_sock, (struct sockaddr*)&src_addr, sizeof(src_addr)) < 0 ) {
    perror("bind");
    exit(1);
  }

  sendto(udp_sock, payload, strlen(payload) + 1, 0,
	 (struct sockaddr*)&dest_addr, sizeof(dest_addr));

  close(udp_sock);
}


int main(int argc, char **argv)
{
  int listen_sock, ret, addr_len;
  struct sockaddr_in bind_addr, peer_addr;
  unsigned short src_port = htons(1234);
  unsigned short dst_port = htons(5678);
  char *payload = "hello";
  char buf[6];
  fd_set readfds;
  struct timeval timeout;

  bind_addr.sin_family = AF_INET;
  bind_addr.sin_port = dst_port;
  bind_addr.sin_addr.s_addr = INADDR_ANY;

  if((listen_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("socket");
    exit(1);
  }

  if(bind(listen_sock, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) < 0 ) {
    perror("bind");
    exit(1);
  }

#if 1
  send_raw_udp(src_port, dst_port, payload);
#else
  send_normal_udp(src_port, dst_port, payload);
#endif

  printf("calling select\n");
  FD_ZERO(&readfds);
  FD_SET(listen_sock, &readfds);
  if((ret = select(listen_sock+1, &readfds, NULL, NULL, NULL)) < 0) {
    perror("select");
    exit(1);
  }
  if(!FD_ISSET(listen_sock, &readfds)) {
    printf("hmmm, socket is not readable\n");
    exit(1);
  }
  printf("socket is readable\n");

  addr_len = sizeof(peer_addr);
  if(recvfrom(listen_sock, buf, sizeof(buf), 0,
	      (struct sockaddr*)&peer_addr, &addr_len) < 0) {
    perror("recvfrom");
    exit(1);
  }
  printf("recvfrom success: %s\n", buf);

}

  reply	other threads:[~2004-10-21  4:03 UTC|newest]

Thread overview: 191+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-10-06 14:52 UDP recvmsg blocks after select(), 2.6 bug? Joris van Rantwijk
2004-10-06 15:01 ` David S. Miller
2004-10-06 15:13   ` Chris Friesen
2004-10-06 15:15   ` Richard B. Johnson
2004-10-06 15:21     ` David S. Miller
2004-10-06 15:29       ` Richard B. Johnson
2004-10-06 15:42         ` David S. Miller
2004-10-06 15:57           ` Chris Friesen
2004-10-06 15:44         ` Lars Marowsky-Bree
2004-10-07  1:16         ` Paul Jakma
2004-10-07  7:10           ` Chris Friesen
2004-10-07 11:53             ` Paul Jakma
2004-10-07 13:32               ` Martijn Sipkema
2004-10-07 12:53                 ` Paul Jakma
2004-10-07 13:12                   ` Richard B. Johnson
2004-10-07 14:07                   ` Martijn Sipkema
2004-10-07 13:19                     ` Paul Jakma
2004-10-07 13:36                     ` Paul Jakma
2004-10-07 15:01                       ` Jean-Sebastien Trottier
2004-10-07 16:20                         ` Chris Friesen
2004-10-07 18:20                           ` Hua Zhong
2004-10-07 18:33                             ` Chris Friesen
2004-10-07 22:41                               ` Martijn Sipkema
2004-10-07 21:49                                 ` Chris Friesen
2004-10-07 22:00                                   ` David S. Miller
2004-10-07 22:24                                     ` Chris Friesen
2004-10-07 22:26                                       ` David S. Miller
2004-10-07 22:39                                         ` Chris Friesen
2004-10-07 22:42                                           ` David S. Miller
2004-10-07 23:27                                             ` Chris Friesen
2004-10-08  0:04                                               ` Ben Greear
2004-10-08  2:51                                             ` Mark Mielke
2004-10-08  3:39                                               ` David S. Miller
2004-10-08  3:48                                                 ` Mark Mielke
2004-10-08  3:59                                                   ` David S. Miller
2004-10-07 23:19                                     ` Martijn Sipkema
2004-10-07 22:24                                       ` David S. Miller
2004-10-07 22:33                                         ` Alan Curry
2004-10-07 22:42                                         ` Mark Mielke
2004-10-07 22:47                                           ` David S. Miller
2004-10-07 23:00                                             ` Mark Mielke
2004-10-07 23:07                                               ` David S. Miller
2004-10-08  6:10                                               ` Theodore Ts'o
2004-10-08 15:20                                                 ` Mark Mielke
2004-10-08  0:37                                             ` Lee Revell
2004-10-07 22:46                                         ` Hua Zhong
2004-10-07 22:48                                           ` David S. Miller
2004-10-07 23:17                                   ` Martijn Sipkema
2004-10-07 13:45                     ` Alan Cox
2004-10-07 16:32                       ` Martijn Sipkema
2004-10-07 14:50                         ` Alan Cox
2004-10-07 21:58                           ` mmap specification - was: ... select specification Andries Brouwer
2004-10-07 22:17                             ` Chris Wedgwood
2004-10-07 22:34                               ` Andries Brouwer
2004-10-07 22:32                             ` Kyle Moffett
2004-10-07 22:46                               ` Andries Brouwer
2004-10-07 23:30                                 ` Kyle Moffett
2004-10-08  9:19                                   ` Andries Brouwer
2004-10-09 21:10                                     ` Martijn Sipkema
2004-10-07 13:48                     ` UDP recvmsg blocks after select(), 2.6 bug? Alan Cox
2004-10-07 14:57                       ` Richard B. Johnson
2004-10-07 15:18                       ` Adam Heath
2004-10-07 16:39                         ` Martijn Sipkema
2004-10-07 16:09                           ` Mark Mielke
2004-10-07 17:18                             ` Chris Friesen
2004-10-06 15:31       ` Chris Friesen
2004-10-06 15:41         ` David S. Miller
2004-10-06 16:07           ` Richard B. Johnson
2004-10-06 16:57           ` Neil Horman
2004-10-06 15:59       ` Paul Jackson
2004-10-06 16:35       ` Martijn Sipkema
2004-10-06 15:30     ` Chris Friesen
2004-10-06 15:09 ` Richard B. Johnson
2004-10-06 15:18 ` bert hubert
2004-10-06 16:41 ` Alan Cox
2004-10-06 18:04   ` Joris van Rantwijk
2004-10-06 19:30     ` Andries Brouwer
2004-10-06 19:23       ` Alan Cox
2004-10-06 22:08         ` Martijn Sipkema
2004-10-06 20:25           ` Alan Cox
2004-10-06 22:15             ` Andries Brouwer
2004-10-06 22:32               ` David S. Miller
2004-10-06 23:25               ` YOSHIFUJI Hideaki / 吉藤英明
2004-10-06 23:11             ` Willy Tarreau
2004-10-06 19:43       ` Hua Zhong
2004-10-06 19:54         ` Chris Friesen
2004-10-06 19:59           ` Hua Zhong
2004-10-06 20:10             ` Chris Friesen
2004-10-06 21:45               ` Martijn Sipkema
2004-10-06 23:35                 ` David S. Miller
2004-10-06 20:06           ` David S. Miller
2004-10-06 20:18             ` Chris Friesen
2004-10-06 20:26               ` Hua Zhong
2004-10-06 20:38               ` Andries Brouwer
2004-10-06 20:58                 ` Joris van Rantwijk
2004-10-06 22:29                 ` David S. Miller
2004-10-07 16:08                 ` Adrian Phillips
2004-10-06 20:06         ` Olivier Galibert
2004-10-06 23:35           ` David S. Miller
2004-10-07  0:19             ` Olivier Galibert
2004-10-07  0:29               ` David S. Miller
2004-10-07 10:56                 ` Martijn Sipkema
2004-10-08  6:41                 ` Willy Tarreau
2004-10-08 15:27                   ` Mark Mielke
2004-10-15 22:42                   ` Robert White
2004-10-15 23:33                     ` David Schwartz
2004-10-16  0:59                       ` Chris Friesen
2004-10-16  2:35                       ` Mark Mielke
2004-10-16  4:23                         ` David Schwartz
2004-10-16  4:35                           ` Mark Mielke
2004-10-16  4:58                             ` David Schwartz
2004-10-16  6:25                               ` Mark Mielke
2004-10-16 21:44                                 ` Roland Kuhn
2004-10-17  0:06                                   ` Mark Mielke
2004-10-17  0:30                                     ` David Schwartz
2004-10-17 14:47                                       ` Mark Mielke
2004-10-17  0:28                                 ` David Schwartz
2004-10-17 13:35                                   ` Lars Marowsky-Bree
2004-10-17 14:17                                     ` Buddy Lucas
2004-10-17 15:05                                       ` Mark Mielke
2004-10-17 15:40                                         ` Buddy Lucas
2004-10-17 16:13                                           ` Lee Revell
2004-10-17 17:35                                           ` Jesper Juhl
2004-10-17 18:04                                             ` Buddy Lucas
2004-10-17 18:06                                               ` Lars Marowsky-Bree
2004-10-17 18:21                                                 ` Buddy Lucas
2004-10-17 20:04                                                 ` Martijn Sipkema
2004-10-17 20:08                                                   ` Lars Marowsky-Bree
2004-10-17 17:35                                           ` Martijn Sipkema
2004-10-17 17:33                                             ` Buddy Lucas
2004-10-17 19:58                                               ` Martijn Sipkema
2004-10-17 19:33                                                 ` Buddy Lucas
2004-10-17 20:11                                                   ` Lars Marowsky-Bree
2004-10-17 20:25                                                     ` Buddy Lucas
2004-10-17 20:42                                                   ` Martijn Sipkema
2004-10-17 20:02                                                     ` Buddy Lucas
2004-10-17 18:53                                             ` David Schwartz
2004-10-17 19:26                                               ` Hua Zhong
2004-10-17 20:32                                               ` Martijn Sipkema
2004-10-17 19:21                                           ` Hua Zhong
2004-10-17 17:22                                       ` Lars Marowsky-Bree
2004-10-17 17:54                                         ` Buddy Lucas
2004-10-17 18:05                                           ` Lars Marowsky-Bree
2004-10-17 18:06                                           ` Mark Mielke
2004-10-20 21:31                                     ` H. Peter Anvin
2004-10-20 21:58                                       ` Chris Friesen
2004-10-20 22:00                                         ` H. Peter Anvin
2004-10-20 22:12                                           ` Chris Friesen
2004-10-20 23:16                                             ` David Schwartz
2004-10-21  1:03                                               ` Chris Friesen
2004-10-21  1:38                                                 ` David Schwartz
2004-10-21  3:01                                           ` Michael Clark
2004-10-21  3:52                                             ` Michael Clark [this message]
2004-10-21  4:10                                             ` H. Peter Anvin
2004-10-21  5:06                                               ` Chris Friesen
2004-10-21  5:11                                                 ` H. Peter Anvin
2004-10-21  5:50                                                   ` Chris Friesen
2004-10-21  5:58                                                     ` H. Peter Anvin
2004-10-21 15:18                                                       ` Chris Friesen
2004-10-21  6:14                                                     ` Michael Clark
2004-10-17 14:52                                   ` Mark Mielke
2004-10-16 18:25                               ` Andries Brouwer
2004-10-17  0:28                                 ` David Schwartz
2004-10-17 12:22                                   ` Andries Brouwer
2004-10-16 10:24                     ` Willy Tarreau
2004-10-16 13:21                       ` Mark Mielke
2004-10-18 22:25                       ` Robert White
2004-10-06 20:41         ` Neil Horman
2004-10-06 22:27           ` Chris Friesen
2004-10-06 23:32             ` Neil Horman
2004-10-06 23:36             ` David S. Miller
2004-10-07 19:31 ` David Schwartz
2004-10-07 22:36   ` Martijn Sipkema
2004-10-08  0:19     ` David Schwartz
2004-10-09 19:21       ` Martijn Sipkema
2004-10-09 18:28         ` David Schwartz
2004-10-09 18:49           ` Mark Mielke
2004-10-09 21:00             ` Martijn Sipkema
2004-10-09 22:59               ` Mark Mielke
  -- strict thread matches above, loose matches on Subject: below --
2004-10-06 15:30 Dan Kegel
2004-10-07  4:50 Dan Kegel
2004-10-07  8:04 ` bert hubert
2004-10-07  8:28   ` Adam Heath
2004-10-07 10:38     ` Martijn Sipkema
2004-10-07 10:07       ` Adam Heath
2004-10-07 11:29         ` Martijn Sipkema
2004-10-07 18:16 linux
2004-10-09 12:07 ` Colin Phipps
     [not found] <fa.haprsoi.8k8kbk@ifi.uio.no>
     [not found] ` <fa.isqjio8.ok2coo@ifi.uio.no>
2004-10-09 13:24   ` Bodo Eggert
2004-10-19  1:21 John Pearson
2004-10-19 13:50 ` Colin Phipps

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=41773265.1010404@metaparadigm.com \
    --to=michael@metaparadigm.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox