[ Bottom of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]

Communications Programming Concepts

Sending Packets Over Ethernet Example Program

#include <stdio.h>#include <sys/ndd_var.h>
#include <sys/kinfo.h>
/*
 * Get the MAC address of the ethernet adapter we're using...
 */
getaddr(char *device, char *addr) 
{
          int size;
          struct kinfo_ndd *nddp;
          void *end;
          int found = 0;
          size = getkerninfo(KINFO_NDD, 0, 0, 0);
          if (size == 0) {
                    fprintf(stderr, "No ndds.\n");
                    exit(0);
          }
          
          if (size < 0) {
                    perror("getkerninfo 1");
                    exit(1);
          }
          nddp = (struct kinfo_ndd *)malloc(size);
          
          if (!nddp) {
                    perror("malloc");
                    exit(1);
          }
          if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0) {
                    perror("getkerninfo 2");
                    exit(2);
          }
          end = (void *)nddp + size;
          while (((void *)nddp < end) && !found) {
                    if (!strcmp(nddp->ndd_alias, device) ||
                              !strcmp(nddp->ndd_name, device)) {
                              found++;
                              bcopy(nddp->ndd_addr, addr, 6);
                    } else
                              nddp++;
          }
          return (found);
}
/*
 * Hex print function...
 */
pit(str, buf, len)
u_char *str;
u_char *buf;
int len;
{
          int i;
          printf("%s", str);
          for (i=0; i<len; i++)
                    printf("%2.2X", buf[i]);
          printf("\n");
          fflush(stdout);
}
/*
 * Ethernet packet format...
 */
typedef struct {
          unsigned char          dst[6];
          unsigned char          src[6];
          unsigned short          ethertype;
          unsigned char          data[1500];
} xmit;
/*
 * Convert ascii hardware address into byte string.
 */
hwaddr_aton(a, n)
        char *a;
        u_char *n;
{
        int i, o[6];
        i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2],
                                           &o[3], &o[4], &o[5]);
        if (i != 6) {
                fprintf(stderr, "invalid hardware address '%s'\n");
                return (0);
        }
        for (i=0; i<6; i++)
                n[i] = o[i];
        return (6);
}
main(int argc, char *argv[]) {
          char srcaddr[6];
          char *device, dstaddr[6];
          u_int ethertype;
          u_int count, size;
          xmit buf;
          int s;
          struct sockaddr_ndd_8022 sa;
          int last;
          
          if (argc != 6) {
                 printf("Usage: %s <ifname> dstaddr ethertype count size\n", 
                              argv[0]);
                 printf("EG:    %s en0 01:02:03:04:05:06 0x600 10 10\n", 
                              argv[0]);
                    exit(1);
          }
          if (!getaddr(argv[1], srcaddr)) {
                    printf("interface not found\n");
                    exit(1);
          }
          
          device=argv[1];
          hwaddr_aton(argv[2], dstaddr);
          pit("src addr = ", srcaddr, 6);
          pit("dst addr = ", dstaddr, 6);
          sscanf(argv[3], "%x", &ethertype);
          count = atoi(argv[4]);
          size = atoi(argv[5]);
          if (size > 1500)
                    size = 1500;
          if (size < 60)
                    size = 60;
          printf("Ethertype: %x\n", ethertype);
          printf("Count: %d\n", count);
          printf("Size: %d\n", size);
          
          s = socket(AF_NDD, SOCK_DGRAM, NDD_PROT_ETHER);
          if (s < 0) {
                    perror("socket");
                    exit(1);
          }
          sa.sndd_8022_family = AF_NDD;
          sa.sndd_8022_len = sizeof(sa);
          sa.sndd_8022_filtertype = NS_ETHERTYPE;
          sa.sndd_8022_ethertype = (u_short)ethertype;
          sa.sndd_8022_filterlen = sizeof(struct ns_8022);
          bcopy(device, sa.sndd_8022_nddname, sizeof(sa.sndd_8022_nddname));
          if (bind(s, (struct sockaddr *)&sa, sizeof(sa))) {
                    perror("bind");
                    exit(2);
          }
          bcopy(dstaddr, buf.dst, sizeof(buf.dst));
          bcopy(srcaddr, buf.src, sizeof(buf.src));
          buf.ethertype = (u_short)ethertype;
          if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
                    perror("connect");
                    exit(3);
          }
          last = count;
          while (count-- > 0) {
                    sprintf(buf.data, "Foo%d", last-count);
                    if (write(s, &buf, size) < 0) {
                              perror("write");
                              exit(4);
                    }
          }
          close(s);
}

[ Top of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]