Stream Control Transmission Protocol (SCTP)
besser als TCP!
Stream Control Transmission Protocol (SCTP)
besser als TCP!
Capture Filter (tshark -f): BPF syntax
Display Filter (tshark -Y): Wireshark syntax
Wireshark Wiki: Capture Filters
Ask Wireshark: what is the difference between capture filter and display filter?
Ask Wireshark: Changing Display Filter to Capture Filter
Tshark column fields
Bug 10201 – col.Protocol missing from tshark 1.11.3 and 1.12.0-rc2
# tshark -i re0 -T fields -e frame.number -e ip.addr -e udp -e _ws.col.info Capturing on 're0' [...] 44 172.21.5.130,224.0.0.252 User Datagram Protocol, Src Port: 55317 (55317), Dst Port: 5355 (5355) 45 172.21.5.69,239.255.255.250 User Datagram Protocol, Src Port: 1900 (1900), Dst Port: 1900 (1900)
Video
RTEMS Real Time Operating System (RTOS)
RTEMS Real Time Operating System (Commercial)
Porting FreeRTOS+UDP to a Different Microcontroller
Direct Memory Access und Bus Mastering, aus O’Reilly Linux-Gerätetreiber, 2. Auflage, April 2002
DMA
ARM MP3/AAC Player
LwIp-Stack: Raw Ethernet Packete senden
STM32F4 RCC Enable-Problem
Speicherdirektzugriff, Direct Memory Access (DMA)
Remote direct memory access
RDMA over Converged Ethernet
/*
* pinger --
* Compose and transmit an ICMP ECHO REQUEST packet. The IP packet
* will be added on by the kernel. The ID field is our UNIX process ID,
* and the sequence number is an ascending integer. The first TIMEVAL_LEN
* bytes of the data portion are used to hold a UNIX "timeval" struct in
* host byte-order, to compute the round-trip time.
*/
static void
pinger(void)
{
[...]
if ((options & F_TIME) || timing) {
(void)gettimeofday(&now, NULL);
if (options & F_TIME)
icp->icmp_otime = htonl((now.tv_sec % (24*60*60)) * 1000 + now.tv_usec / 1000);
if (timing)
bcopy((void *)&now, (void *)&outpack[ICMP_MINLEN + phdr_len], sizeof(struct timeval));
}
[...]
}
typedef u_int32_t n_time; /* ms since 00:00 GMT, byte rev */
#define icmp_otime icmp_dun.id_ts.its_otime
#define icmp_rtime icmp_dun.id_ts.its_rtime
#define icmp_ttime icmp_dun.id_ts.its_ttime
struct icmp {
u_char icmp_type; /* type of message, see below */
u_char icmp_code; /* type sub code */
u_short icmp_cksum; /* ones complement cksum of struct */
union {
u_char ih_pptr; /* ICMP_PARAMPROB */
struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
struct ih_idseq {
n_short icd_id;
n_short icd_seq;
} ih_idseq;
int ih_void;
/* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
struct ih_pmtu {
n_short ipm_void;
n_short ipm_nextmtu;
} ih_pmtu;
struct ih_rtradv {
u_char irt_num_addrs;
u_char irt_wpa;
u_int16_t irt_lifetime;
} ih_rtradv;
} icmp_hun;
union {
struct id_ts { /* ICMP Timestamp */
n_time its_otime; /* Originate */
n_time its_rtime; /* Receive */
n_time its_ttime; /* Transmit */
} id_ts;
struct id_ip {
struct ip idi_ip;
/* options and then 64 bits of data */
} id_ip;
struct icmp_ra_addr id_radv;
u_int32_t id_mask;
char id_data[1];
} icmp_dun;
};
Reference (1):
http://tools.ietf.org/html/rfc778
…
“The timestamp values are in milliseconds from midnight
UT and are stored right-justified in the 32-bit fields shown
above. Ordinarily, all time calculations are performed
modulo-24 hours in milliseconds.”
/* Converts a little-endian byte order unsigned long to host byte order. */
uint32 LETOHL(uint32 ul);
/*
* RFC 792 for basic ICMP.
* RFC 1191 for ICMP_FRAG_NEEDED (with MTU of next hop).
* RFC 1256 for router discovery messages.
* RFC 2002 and 3012 for Mobile IP stuff.
*/
static void
dissect_icmp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
[...]
/* Decode the second 4 bytes of the packet. */
switch (icmp_type) {
[...]
case ICMP_ECHOREPLY:
case ICMP_ECHO:
[...]
/* Interpret the first 8 bytes of the icmp data as a timestamp
* But only if it does look like it's a timestamp.
*
* FIXME:
* Timestamps could be in different formats depending on the OS
*/
ts.secs = tvb_get_ntohl(tvb, 8);
ts.nsecs = tvb_get_ntohl(tvb, 8 + 4); /* Leave at microsec resolution for now */
if (abs((guint32) (ts.secs - pinfo->fd->abs_ts.secs)) >=
3600 * 24 || ts.nsecs >= 1000000) {
/* Timestamp does not look right in BE, try LE representation */
ts.secs = tvb_get_letohl(tvb, 8);
ts.nsecs = tvb_get_letohl(tvb, 8 + 4); /* Leave at microsec resolution for now */
}
if (abs((guint32) (ts.secs - pinfo->fd->abs_ts.secs)) < 3600 * 24 && ts.nsecs < 1000000) {
ts.nsecs *= 1000; /* Convert to nanosec resolution */
proto_tree_add_time(icmp_tree, hf_icmp_data_time,
tvb, 8, 8, &ts);
nstime_delta(&time_relative, &pinfo->fd->abs_ts,
&ts);
ti = proto_tree_add_time(icmp_tree,
hf_icmp_data_time_relative,
tvb, 8, 8,
&time_relative);
PROTO_ITEM_SET_GENERATED(ti);
call_dissector(data_handle,
tvb_new_subset_remaining(tvb,
8 + 8),
pinfo, icmp_tree);
} else {
call_dissector(data_handle,
tvb_new_subset_remaining(tvb, 8),
pinfo, icmp_tree);
}
break;
[...]
}
[...]
}
PF, The OpenBSD Packet Filter: Building The Network You Need, EuroBSDCon 2015, Stockholm, Sweden, October 1st 2015
Pf Firewall “how to” – FreeBSD and OpenBSD ( pf.conf )
Paket Filter (PF) von OpenBSD und ALTQ
Getting AltQ working in pf.conf (limiting inbound Tor traffic)
PF Firewall Quick Guide
FreeBSD Tuning and Optimization – performance modifications for 1gig and 10gig networks
ntop (Official)
ntopng – High-Speed Web-based Traffic Analysis and Flow Collection (Official)
ntop (Wikipedia)
NTop
Network Monitoring Using Free Linux Tools
Unveiling Application Visibility in ntop and nProbe (both in NetFlow v9 and IPFIX)
Couldn't manipulate device /dev/pf: No such process
table <hacker> persist {
}
$ pfctl -n -f /etc/pf.conf # Parse the configuration file, do not actually load rules
$ pfctl -T load -f /etc/pf.conf # Load only the table definitions
$ pfctl -t hacker -T show # Show the content of a table
RRDTool – tutorial and graph examples (OpenBSD with pf)
rrd-beginners
Network Traffic Monitoring with RRDTool
Monitoring network traffic with iptraf and rrdtool
Monitorix Project by Jordi Sanfeliu
RRDtool with pfctl and spamd
Setting up traffic monitoring using rrdtool (and snmp)
Using SNMP and RRD to monitor your LEAF system
Alternatives to rrdtool?
Java RRD library
rrd4j, RRD4J 3.1 (released 2017-01-01)
bind: blackhole for invalid recursive queries?
Disabling Root DNS Server queries on Redhat linux
Ubuntu server 12.04 bind9 dns query rejected
Using FreeBSD’s BPF device with C/C++
Compile Error in using /usr/include/net/if.h
compile problems on freebsd
[root@gateway ~]# pfctl -t hacker -T add 192.168.0.2 192.168.0.3 192.168.0.4 1 table created. 3/3 addresses added. [root@gateway ~]# pfctl -f /etc/pf.conf [root@gateway ~]# pfctl -t hacker -T show 192.168.1.1 [root@gateway ~]# pfctl -t hacker -T add 192.168.0.2 192.168.0.3 192.168.0.4 3/3 addresses added. [root@gateway ~]# pfctl -t hacker -T show 192.168.0.2 192.168.0.3 192.168.0.4 192.168.1.1
DIOCRADDADDRS struct pfioc_table *io
Add one or more addresses to a table. On entry, pfrio_table con-
tains the table ID and pfrio_buffer must point to an array of
struct pfr_addr containing at least pfrio_size elements to add to
the table. pfrio_esize must be the size of struct pfr_addr. On
exit, pfrio_nadd contains the number of addresses effectively
added.
struct pfr_addr {
union {
struct in_addr _pfra_ip4addr;
struct in6_addr _pfra_ip6addr;
} pfra_u;
u_int8_t pfra_af;
u_int8_t pfra_net;
u_int8_t pfra_not;
u_int8_t pfra_fback;
};
#define pfra_ip4addr pfra_u._pfra_ip4addr
#define pfra_ip6addr pfra_u._pfra_ip6addr
/usr/include/sys/ioctl.h: ioctl (dev, DIOCRADDADDRS, &io)
sbin/pfctl/pfctl_radix.c: pfr_add_addrs (tbl=0xbfbfd198, addr=0x28826100, size=3, nadd=0xbfbfd16c, flags=0)
sbin/pfctl/pfctl_table.c: pfctl_table (argc=3, argv=0xbfbfdc90, tname=0xbfbfddd3 "hacker", command=0x808831c "add", file=0x0, anchor=0xbfbfd808 "", opts=0)
sbin/pfctl/pfctl_table.c: pfctl_command_tables (argc=3, argv=0xbfbfdc90, tname=0xbfbfddd3 "hacker", command=0x808831c "add", file=0x0, anchor=0xbfbfd808 "", opts=0)
sbin/pfctl/pfctl.c: main (argc=3, argv=0xbfbfdc90)
tbl:
$1 = (struct pfr_table *) 0xbfbfd198
$2 = { pfrt_anchor = '\0'
pfrt_name = "hacker",
pfrt_flags = 0,
pfrt_fback = 0 '\0'}
addr:
$3 = (struct pfr_addr *) 0x28826100
$4 = { pfra_u = { _pfra_ip4addr = { s_addr = 33597632 },
_pfra_ip6addr = { [...] }
},
pfra_af = 2 '\002',
pfra_net = 32 ' ',
pfra_not = 0 '\0',
pfra_fback = 0 '\0'}
pfctl_radix.c:418 pfr_buf_add (b=0xbfbfd188, e=0xbfbfcfb0)
pfctl_parser.c:1704 append_addr_host (b=0xbfbfd188, n=0x28814460, test=0, not=0)
pfctl_parser.c:1659 append_addr (b=0xbfbfd188, s=0xbfbfddf9 "192.168.0.4", test=0)
pfctl_table.c:418 load_addr (b=0xbfbfd188, argc=0, argv=0xbfbfdc9c, file=0x0, nonetwork=0)
pfctl_table.c:201 pfctl_table (argc=3, argv=0xbfbfdc90, tname=0xbfbfddd3 "hacker", command=0x808831c "add", file=0x0, anchor=0xbfbfd808 "", opts=0)
pfctl_table.c:124 pfctl_command_tables (argc=3, argv=0xbfbfdc90, tname=0xbfbfddd3 "hacker", command=0x808831c "add", file=0x0, anchor=0xbfbfd808 "", opts=0)
pfctl.c:2328 main (argc=3, argv=0xbfbfdc90)
typedef char * caddr_t; /* core address */ typedef const char * c_caddr_t; /* core address, pointer to const */
/*
* Internet address (a structure for historical reasons)
*/
struct in_addr {
in_addr_t s_addr;
};
int
main(int argc, char *argv[])
{
[...]
while ((ch = getopt(argc, argv,
"a:AdD:eqf:F:ghi:k:K:mnNOo::Pp:rRs:t:T:vx:z")) != -1) {
switch (ch) {
[...]
case 't':
tableopt = optarg;
break;
case 'T':
tblcmdopt = pfctl_lookup_option(optarg, tblcmdopt_list);
if (tblcmdopt == NULL) {
warnx("Unknown table command '%s'", optarg);
usage();
}
break;
[...]
}
}
[...]
if (tblcmdopt != NULL) {
error = pfctl_command_tables(argc, argv, tableopt,
tblcmdopt, rulesopt, anchorname, opts);
rulesopt = NULL;
}
[...]
}
enum {
PFRB_TABLES = 1,
PFRB_TSTATS,
PFRB_ADDRS,
PFRB_ASTATS,
PFRB_IFACES,
PFRB_TRANS,
PFRB_MAX
};
struct pfr_buffer {
int pfrb_type; /* type of content, see enum above */
int pfrb_size; /* number of objects in buffer */
int pfrb_msize; /* maximum number of objects in buffer */
void *pfrb_caddr; /* malloc'ated memory area */
};
/* int int int void * */
{pfrb_type = 3, pfrb_size = 0, pfrb_msize = 0, pfrb_caddr = 0x0}
{pfrb_type = 3, pfrb_size = 1, pfrb_msize = 64, pfrb_caddr = 0x28826100}
{pfrb_type = 3, pfrb_size = 2, pfrb_msize = 64, pfrb_caddr = 0x28826100}
struct pfioc_table {
struct pfr_table pfrio_table;
void *pfrio_buffer;
int pfrio_esize;
int pfrio_size;
int pfrio_size2;
int pfrio_nadd;
int pfrio_ndel;
int pfrio_nchange;
int pfrio_flags;
u_int32_t pfrio_ticket;
};
struct pfr_table {
char pfrt_anchor[MAXPATHLEN];
char pfrt_name[PF_TABLE_NAME_SIZE];
u_int32_t pfrt_flags;
u_int8_t pfrt_fback;
};
/* char * char * u_int32_t u_int8_t */
{pfrt_anchor = '\0', pfrt_name = "hacker", '\0' , pfrt_flags = 0, pfrt_fback = 0 '\0'}
pfrt_flags:
#define PFR_TFLAG_PERSIST 0x00000001
#define PFR_TFLAG_CONST 0x00000002
#define PFR_TFLAG_ACTIVE 0x00000004
#define PFR_TFLAG_INACTIVE 0x00000008
#define PFR_TFLAG_REFERENCED 0x00000010
#define PFR_TFLAG_REFDANCHOR 0x00000020
#define PFR_TFLAG_USRMASK 0x00000003
#define PFR_TFLAG_SETMASK 0x0000003C
#define PFR_TFLAG_ALLMASK 0x0000003F
struct pfr_table.pfrt_fback:
struct pfr_addr.pfra_fback:
enum {
PFR_FB_NONE,
PFR_FB_MATCH,
PFR_FB_ADDED,
PFR_FB_DELETED,
PFR_FB_CHANGED,
PFR_FB_CLEARED,
PFR_FB_DUPLICATE,
PFR_FB_NOTMATCH,
PFR_FB_CONFLICT,
PFR_FB_MAX
};
struct pfr_addr {
union {
struct in_addr _pfra_ip4addr;
struct in6_addr _pfra_ip6addr;
} pfra_u;
u_int8_t pfra_af; /**< AF_INET or AF_INET6 */
u_int8_t pfra_net;
u_int8_t pfra_not;
u_int8_t pfra_fback;
};
#define pfra_ip4addr pfra_u._pfra_ip4addr
#define pfra_ip6addr pfra_u._pfra_ip6addr
/* union */
{ pfra_u = { _pfra_ip4addr = { s_addr = 33597632 },
_pfra_ip6addr = {__u6_addr = { __u6_addr8 = { ... },
__u6_addr16 = { ... },
__u6_addr32 = { ... }
}
}
},
/* u_int8_t u_int8_t u_int8_t u_int8_t */
pfra_af = 2 , pfra_net = 32 , pfra_not = 0 , pfra_fback = 0 }
/***************************************************************/
#define v4 pfa.v4
#define v6 pfa.v6
#define addr8 pfa.addr8
#define addr16 pfa.addr16
#define addr32 pfa.addr32
struct pf_addr {
union {
struct in_addr v4;
struct in6_addr v6;
u_int8_t addr8[16];
u_int16_t addr16[8];
u_int32_t addr32[4];
} pfa; /* 128-bit address */
};
struct pf_addr_wrap {
union {
struct {
struct pf_addr addr;
struct pf_addr mask;
} a;
char ifname[IFNAMSIZ];
char tblname[PF_TABLE_NAME_SIZE];
} v;
union {
struct pfi_dynaddr *dyn;
struct pfr_ktable *tbl;
int dyncnt;
int tblcnt;
} p;
u_int8_t type; /* PF_ADDR_* */
u_int8_t iflags; /* PFI_AFLAG_* */
};
#define CREATE_TABLE do { \
table.pfrt_flags |= PFR_TFLAG_PERSIST; \
if ((!(opts & PF_OPT_NOACTION) || \
(opts & PF_OPT_DUMMYACTION)) && \
(pfr_add_tables(&table, 1, &nadd, flags)) && \
(errno != EPERM)) { \
radix_perror(); \
goto _error; \
} \
if (nadd) { \
warn_namespace_collision(table.pfrt_name); \
xprintf(opts, "%d table created", nadd); \
if (opts & PF_OPT_NOACTION) \
return (0); \
} \
table.pfrt_flags &= ~PFR_TFLAG_PERSIST; \
} while(0)
int
pfctl_command_tables(int argc, char *argv[], char *tname,
const char *command, char *file, const char *anchor, int opts)
{
if (tname == NULL || command == NULL)
usage();
return pfctl_table(argc, argv, tname, command, file, anchor, opts);
}
int
pfctl_table(int argc, char *argv[], char *tname, const char *command,
char *file, const char *anchor, int opts)
{
struct pfr_table table;
struct pfr_buffer b, b2;
struct pfr_addr *a, *a2;
int nadd = 0;
[...]
strlcpy(table.pfrt_name, tname, sizeof(table.pfrt_name); /**< copy table name */
[...]
} else if (!strcmp(command, "add")) {
b.pfrb_type = PFRB_ADDRS; /**< set type to ADDR */
if (load_addr(&b, argc, argv, file, 0)) /**< load_addr(): parse arguments and pass it to struct pfr_buffer */
goto _error;
CREATE_TABLE;
if (opts & PF_OPT_VERBOSE)
flags |= PFR_FLAG_FEEDBACK;
RVTEST(pfr_add_addrs(&table, b.pfrb_caddr, b.pfrb_size, &nadd, flags)); /**< pfr_add_addrs():
xprintf(opts, "%d/%d addresses added", nadd, b.pfrb_size);
if (opts & PF_OPT_VERBOSE)
PFRB_FOREACH(a, &b)
if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback)
print_addrx(a, NULL, opts & PF_OPT_USEDNS);
}
[...]
}
int
load_addr(struct pfr_buffer *b, int argc, char *argv[], char *file,
int nonetwork)
{
while (argc--)
if (append_addr(b, *argv++, nonetwork)) {
if (errno)
warn("cannot decode %s", argv[-1]);
return (-1);
}
if (pfr_buf_load(b, file, nonetwork, append_addr)) {
warn("cannot load %s", file);
return (-1);
}
return (0);
}
struct node_host {
struct pf_addr_wrap addr;
struct pf_addr bcast;
struct pf_addr peer;
sa_family_t af;
u_int8_t not;
u_int32_t ifindex; /* link-local IPv6 addrs */
char *ifname;
u_int ifa_flags;
struct node_host *next;
struct node_host *tail;
};
/*
* convert a hostname to a list of addresses and put them in the given buffer.
* test:
* if set to 1, only simple addresses are accepted (no netblock, no "!").
*/
int
append_addr(struct pfr_buffer *b, char *s, int test)
{
char *r;
struct node_host *h, *n;
int rv, not = 0;
for (r = s; *r == '!'; r++)
not = !not;
if ((n = host(r)) == NULL) {
errno = 0;
return (-1);
}
rv = append_addr_host(b, n, test, not);
do {
h = n;
n = n->next;
free(h);
} while (n != NULL);
return (rv);
}
/*
* same as previous function, but with a pre-parsed input and the ability
* to "negate" the result. Does not free the node_host list.
* not:
* setting it to 1 is equivalent to adding "!" in front of parameter s.
*/
int
append_addr_host(struct pfr_buffer *b, struct node_host *n, int test, int not)
{
int bits;
struct pfr_addr addr;
do {
bzero(&addr, sizeof(addr));
addr.pfra_not = n->not ^ not;
addr.pfra_af = n->af;
addr.pfra_net = unmask(&n->addr.v.a.mask, n->af); /**< assign netmask, node_host -> pfr_addr */
switch (n->af) {
case AF_INET:
addr.pfra_ip4addr.s_addr = n->addr.v.a.addr.addr32[0]; /**< assign address, node_host -> pfr_addr */
bits = 32;
break;
case AF_INET6:
memcpy(&addr.pfra_ip6addr, &n->addr.v.a.addr.v6,
sizeof(struct in6_addr));
bits = 128;
break;
default:
errno = EINVAL;
return (-1);
}
if ((test && (not || addr.pfra_net != bits)) || /**< test = 0, not = 0 => bypass these lines */
addr.pfra_net > bits) {
errno = EINVAL;
return (-1);
}
if (pfr_buf_add(b, &addr))
return (-1);
} while ((n = n->next) != NULL);
return (0);
}
struct node_host *
host(const char *s)
{
struct node_host *h = NULL;
int mask, v4mask, v6mask, cont = 1;
char *p, *q, *ps;
if ((p = strrchr(s, '/')) != NULL) {
mask = strtol(p+1, &q, 0);
if (!q || *q || mask > 128 || q == (p+1)) {
fprintf(stderr, "invalid netmask '%s'\n", p);
return (NULL);
}
if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL)
err(1, "host: malloc");
strlcpy(ps, s, strlen(s) - strlen(p) + 1);
v4mask = v6mask = mask;
} else {
if ((ps = strdup(s)) == NULL)
err(1, "host: strdup");
v4mask = 32;
v6mask = 128;
mask = -1;
}
/* interface with this name exists? */
if (cont && (h = host_if(ps, mask)) != NULL)
cont = 0;
/* IPv4 address? */
if (cont && (h = host_v4(s, mask)) != NULL)
cont = 0;
/* IPv6 address? */
if (cont && (h = host_v6(ps, v6mask)) != NULL)
cont = 0;
/* dns lookup */
if (cont && (h = host_dns(ps, v4mask, v6mask)) != NULL)
cont = 0;
free(ps);
if (h == NULL || cont == 1) {
fprintf(stderr, "no IP address found for %s\n", s);
return (NULL);
}
return (h);
}
struct node_host *
host_v4(const char *s, int mask)
{
struct node_host *h = NULL;
struct in_addr ina;
int bits = 32;
memset(&ina, 0, sizeof(struct in_addr));
if (strrchr(s, '/') != NULL) {
if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1) /**< parse string, return netmask bits */
return (NULL);
} else {
if (inet_pton(AF_INET, s, &ina) != 1)
return (NULL);
}
h = calloc(1, sizeof(struct node_host));
if (h == NULL)
err(1, "address: calloc");
h->ifname = NULL;
h->af = AF_INET;
h->addr.v.a.addr.addr32[0] = ina.s_addr;
set_ipmask(h, bits); /**< set IP mask */
h->next = NULL;
h->tail = h;
return (h);
}
void
set_ipmask(struct node_host *h, u_int8_t b)
{
struct pf_addr *m, *n;
int i, j = 0;
m = &h->addr.v.a.mask;
memset(m, 0, sizeof(*m));
while (b >= 32) {
m->addr32[j++] = 0xffffffff;
b -= 32;
}
for (i = 31; i > 31-b; --i)
m->addr32[j] |= (1 << i);
if (b)
m->addr32[j] = htonl(m->addr32[j]);
/* Mask off bits of the address that will never be used. */
n = &h->addr.v.a.addr;
if (h->addr.type == PF_ADDR_ADDRMASK)
for (i = 0; i < 4; i++)
n->addr32[i] = n->addr32[i] & m->addr32[i];
}
/* buffer management code */
size_t buf_esize[PFRB_MAX] = { 0,
sizeof(struct pfr_table), sizeof(struct pfr_tstats),
sizeof(struct pfr_addr), sizeof(struct pfr_astats),
sizeof(struct pfi_kif), sizeof(struct pfioc_trans_e)
};
/*
* add one element to the buffer
*/
int
pfr_buf_add(struct pfr_buffer *b, const void *e)
{
size_t bs;
if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX ||
e == NULL) {
errno = EINVAL;
return (-1);
}
bs = buf_esize[b->pfrb_type]; /**< choose buffer size, ex. sizeof(struct pfr_addr) */
if (b->pfrb_size == b->pfrb_msize) /**< no space left */
if (pfr_buf_grow(b, 0)) /**< increase buffer */
return (-1);
memcpy(((caddr_t)b->pfrb_caddr) + bs * b->pfrb_size, e, bs);
b->pfrb_size++;
return (0);
}
int
pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
int *nadd, int flags)
{
struct pfioc_table io;
if (tbl == NULL || size < 0 || (size && addr == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
io.pfrio_buffer = addr;
io.pfrio_esize = sizeof(*addr);
io.pfrio_size = size;
if (ioctl(dev, DIOCRADDADDRS, &io))
return (-1);
if (nadd != NULL)
*nadd = io.pfrio_nadd;
return (0);
}
arr[ i ] == * ( arr + i ) ex. sizeof(unsigned long) = 64-bit = 8 byte unsigned long arr[2]; &arr[0] = (arr + 0) = 0x608ea0 &arr[1] = (arr + 1) = 0x608ea8
(gdb) p &entry.allocator[0] (gdb) p &((ethernet_header_t *) entry.allocator)[0]
$19 = (header_t *) 0x608e90 $21 = (struct _ethernet_header_t *) 0x608e90
(gdb) p &entry.allocator[1] (gdb) p &((ethernet_header_t *) entry.allocator)[1]
$20 = (header_t *) 0x608eb8 $22 = (struct _ethernet_header_t *) 0x608ed0
(gdb) p sizeof(header_t) (gdb) p sizeof(ethernet_header_t)
$24 = 40 = 0x28 $23 = 64 = 0x40
0x608e90 0x608e90
+ 0x000028 + 0x000040
---------- ----------
0x608eb8 0x608ed0
=========== ===========
LPC1343 QuickStart Board
LPC1347 LPCXpresso board
LPC1549 LPCXpresso board (aka. LPCXpresso V2 board)
LPC1769 LPCXpresso board
LPC800 / LPC812 MAX Board
LPCXpresso Experiment Kit
LPC-Link 2 board
LPCXpresso V2 Boards (aka. LPC1549 LPCXpresso board)
LPCXpresso11U37H board (aka. Extended LPCXpresso V2 board)
LPC1549 LPCXpresso Motor Control Kit (BLDC)
LPCOpen Software Development Platform for NXP LPC Microcontrollers
LightWeight IP (LWIP) networking stack for NXP LPC Microcontrollers