/**************************************************************************** * net/recvfrom.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. * Author: Lazlo * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** * Name: psock_create ****************************************************************************/ static int psock_create(void) { int sd; struct sockaddr_ll addr; int addrlen = sizeof(addr); sd = socket(AF_PACKET, SOCK_RAW, 0); if (sd < 0) { perror("ERROR: failed to create packet socket"); return -1; } /* Prepare sockaddr struct */ addr.sll_family = AF_PACKET; addr.sll_ifindex = 0; if (bind(sd, (const struct sockaddr *)&addr, addrlen) < 0) { perror("ERROR: binding socket failed"); close(sd); return -1; } return sd; } /**************************************************************************** * Name: print_buf ****************************************************************************/ static void print_buf(const uint8_t *buf, int len) { int i; for (i = 0; i < len; i++) { printf("%02X", buf[i]); if ((i+1) % 16 == 0 || (i+1) == len) { printf("\n"); } else if ((i+1) % 8 == 0) { printf(" "); } else { printf(" "); } } } /**************************************************************************** * Name: netpkt_usage ****************************************************************************/ static void netpkt_usage(void) { printf("usage: netpkt options\n"); printf("\n"); printf(" -a transmit and receive\n"); printf(" -r receive\n"); printf(" -t transmit\n"); printf(" -v verbose\n"); printf("\n"); } /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: netpkt_main ****************************************************************************/ int main(int argc, FAR char *argv[]) { int sd; int i; int txc; int rxc; uint8_t *buf; const int buflen = 128; const char da[6] = {0xf0, 0xde, 0xf1, 0x02, 0x43, 0x01}; const char sa[6] = {0x00, 0xe0, 0xde, 0xad, 0xbe, 0xef}; int opt; int verbose = 0; int do_rx = 0; int do_rxtimes = 3; int do_tx = 0; int do_txtimes = 3; if (argc == 1) { netpkt_usage(); return -1; } /* Parse arguments */ while ((opt = getopt(argc, argv, "artv")) != -1) { switch(opt) { case 'a': do_rx = 1; do_tx = 1; break; case 'r': do_rx = 1; break; case 't': do_tx = 1; break; case 'v': verbose = 1; break; default: netpkt_usage(); return -1; } } sd = psock_create(); if (do_tx) { if (verbose) { printf("Testing write() (%d times)\n", do_txtimes); } buf = malloc(buflen); memset(buf, 0, buflen); memcpy(buf, da, 6); memcpy(buf+6, sa, 6); for (i = 0; i < do_txtimes; i++) { if ((txc = write(sd, buf, buflen)) < 0) { perror("ERROR: write failed"); free(buf); close(sd); return -1; } else { if (verbose) { printf("transmitted %d octets\n", txc); print_buf(buf, txc); } } } free(buf); } if (do_rx) { if (verbose) { printf("Testing read() (%d times)\n", do_rxtimes); } buf = malloc(buflen); memset(buf, 0, buflen); for (i = 0; i < do_rxtimes; i++) { rxc = read(sd, buf, buflen); if (rxc < 0) { perror("ERROR: read failed"); free(buf); close(sd); return -1; } else if (rxc == 0) { /* ignore silently */ } else { if (verbose) { printf("received %d octets\n", rxc); print_buf(buf, rxc); } } } free(buf); } close(sd); return 0; }