aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-16 21:50:49 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-16 21:50:49 -0400
commitccc580571cf0799d0460a085a7632b77753f083e (patch)
tree018e0f83776b089b1f272694132688ac93be25b4 /include
parent0f5cabba49021d36e9f76bd97d7fa0f4a408063f (diff)
wext: Emit event stream entries correctly when compat.
Three major portions to this change: 1) Add IW_EV_COMPAT_LCP_LEN, IW_EV_COMPAT_POINT_OFF, and IW_EV_COMPAT_POINT_LEN helper defines. 2) Delete iw_stream_check_add_*(), they are unused. 3) Add iw_request_info argument to iwe_stream_add_*(), and use it to size the event and pointer lengths correctly depending upon whether IW_REQUEST_FLAG_COMPAT is set or not. 4) The mechanical transformations to the drivers and wireless stack bits to get the iw_request_info passed down into the routines modified in #3. Also, explicit references to IW_EV_LCP_LEN are replaced with iwe_stream_lcp_len(info). With a lot of help and bug fixes from Masakazu Mokuno. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/linux/wireless.h15
-rw-r--r--include/net/iw_handler.h149
2 files changed, 63 insertions, 101 deletions
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 79d84687582..d7958f9b52c 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1113,6 +1113,21 @@ struct iw_event
1113#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ 1113#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
1114 IW_EV_POINT_OFF) 1114 IW_EV_POINT_OFF)
1115 1115
1116#ifdef __KERNEL__
1117#ifdef CONFIG_COMPAT
1118struct __compat_iw_event {
1119 __u16 len; /* Real length of this stuff */
1120 __u16 cmd; /* Wireless IOCTL */
1121 compat_caddr_t pointer;
1122};
1123#define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
1124#define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
1125#define IW_EV_COMPAT_POINT_LEN \
1126 (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
1127 IW_EV_COMPAT_POINT_OFF)
1128#endif
1129#endif
1130
1116/* Size of the Event prefix when packed in stream */ 1131/* Size of the Event prefix when packed in stream */
1117#define IW_EV_LCP_PK_LEN (4) 1132#define IW_EV_LCP_PK_LEN (4)
1118/* Size of the various events when packed in stream */ 1133/* Size of the various events when packed in stream */
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index c99a8eec84e..51b9a37de99 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -478,105 +478,58 @@ extern void wireless_spy_update(struct net_device * dev,
478 * Function that are so simple that it's more efficient inlining them 478 * Function that are so simple that it's more efficient inlining them
479 */ 479 */
480 480
481/*------------------------------------------------------------------*/ 481static inline int iwe_stream_lcp_len(struct iw_request_info *info)
482/*
483 * Wrapper to add an Wireless Event to a stream of events.
484 */
485static inline char *
486iwe_stream_add_event(char * stream, /* Stream of events */
487 char * ends, /* End of stream */
488 struct iw_event *iwe, /* Payload */
489 int event_len) /* Real size of payload */
490{ 482{
491 /* Check if it's possible */ 483#ifdef CONFIG_COMPAT
492 if(likely((stream + event_len) < ends)) { 484 if (info->flags & IW_REQUEST_FLAG_COMPAT)
493 iwe->len = event_len; 485 return IW_EV_COMPAT_LCP_LEN;
494 /* Beware of alignement issues on 64 bits */ 486#endif
495 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 487 return IW_EV_LCP_LEN;
496 memcpy(stream + IW_EV_LCP_LEN,
497 ((char *) iwe) + IW_EV_LCP_LEN,
498 event_len - IW_EV_LCP_LEN);
499 stream += event_len;
500 }
501 return stream;
502} 488}
503 489
504/*------------------------------------------------------------------*/ 490static inline int iwe_stream_point_len(struct iw_request_info *info)
505/*
506 * Wrapper to add an short Wireless Event containing a pointer to a
507 * stream of events.
508 */
509static inline char *
510iwe_stream_add_point(char * stream, /* Stream of events */
511 char * ends, /* End of stream */
512 struct iw_event *iwe, /* Payload length + flags */
513 char * extra) /* More payload */
514{ 491{
515 int event_len = IW_EV_POINT_LEN + iwe->u.data.length; 492#ifdef CONFIG_COMPAT
516 /* Check if it's possible */ 493 if (info->flags & IW_REQUEST_FLAG_COMPAT)
517 if(likely((stream + event_len) < ends)) { 494 return IW_EV_COMPAT_POINT_LEN;
518 iwe->len = event_len; 495#endif
519 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 496 return IW_EV_POINT_LEN;
520 memcpy(stream + IW_EV_LCP_LEN,
521 ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
522 IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
523 memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
524 stream += event_len;
525 }
526 return stream;
527} 497}
528 498
529/*------------------------------------------------------------------*/ 499static inline int iwe_stream_event_len_adjust(struct iw_request_info *info,
530/* 500 int event_len)
531 * Wrapper to add a value to a Wireless Event in a stream of events.
532 * Be careful, this one is tricky to use properly :
533 * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
534 */
535static inline char *
536iwe_stream_add_value(char * event, /* Event in the stream */
537 char * value, /* Value in event */
538 char * ends, /* End of stream */
539 struct iw_event *iwe, /* Payload */
540 int event_len) /* Real size of payload */
541{ 501{
542 /* Don't duplicate LCP */ 502#ifdef CONFIG_COMPAT
543 event_len -= IW_EV_LCP_LEN; 503 if (info->flags & IW_REQUEST_FLAG_COMPAT) {
544 504 event_len -= IW_EV_LCP_LEN;
545 /* Check if it's possible */ 505 event_len += IW_EV_COMPAT_LCP_LEN;
546 if(likely((value + event_len) < ends)) {
547 /* Add new value */
548 memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
549 value += event_len;
550 /* Patch LCP */
551 iwe->len = value - event;
552 memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
553 } 506 }
554 return value; 507#endif
508
509 return event_len;
555} 510}
556 511
557/*------------------------------------------------------------------*/ 512/*------------------------------------------------------------------*/
558/* 513/*
559 * Wrapper to add an Wireless Event to a stream of events. 514 * Wrapper to add an Wireless Event to a stream of events.
560 * Same as above, with explicit error check...
561 */ 515 */
562static inline char * 516static inline char *
563iwe_stream_check_add_event(char * stream, /* Stream of events */ 517iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends,
564 char * ends, /* End of stream */ 518 struct iw_event *iwe, int event_len)
565 struct iw_event *iwe, /* Payload */
566 int event_len, /* Size of payload */
567 int * perr) /* Error report */
568{ 519{
569 /* Check if it's possible, set error if not */ 520 int lcp_len = iwe_stream_lcp_len(info);
521
522 event_len = iwe_stream_event_len_adjust(info, event_len);
523
524 /* Check if it's possible */
570 if(likely((stream + event_len) < ends)) { 525 if(likely((stream + event_len) < ends)) {
571 iwe->len = event_len; 526 iwe->len = event_len;
572 /* Beware of alignement issues on 64 bits */ 527 /* Beware of alignement issues on 64 bits */
573 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 528 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
574 memcpy(stream + IW_EV_LCP_LEN, 529 memcpy(stream + lcp_len, &iwe->u,
575 ((char *) iwe) + IW_EV_LCP_LEN, 530 event_len - lcp_len);
576 event_len - IW_EV_LCP_LEN);
577 stream += event_len; 531 stream += event_len;
578 } else 532 }
579 *perr = -E2BIG;
580 return stream; 533 return stream;
581} 534}
582 535
@@ -584,27 +537,25 @@ iwe_stream_check_add_event(char * stream, /* Stream of events */
584/* 537/*
585 * Wrapper to add an short Wireless Event containing a pointer to a 538 * Wrapper to add an short Wireless Event containing a pointer to a
586 * stream of events. 539 * stream of events.
587 * Same as above, with explicit error check...
588 */ 540 */
589static inline char * 541static inline char *
590iwe_stream_check_add_point(char * stream, /* Stream of events */ 542iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
591 char * ends, /* End of stream */ 543 struct iw_event *iwe, char *extra)
592 struct iw_event *iwe, /* Payload length + flags */
593 char * extra, /* More payload */
594 int * perr) /* Error report */
595{ 544{
596 int event_len = IW_EV_POINT_LEN + iwe->u.data.length; 545 int event_len = iwe_stream_point_len(info) + iwe->u.data.length;
546 int point_len = iwe_stream_point_len(info);
547 int lcp_len = iwe_stream_lcp_len(info);
548
597 /* Check if it's possible */ 549 /* Check if it's possible */
598 if(likely((stream + event_len) < ends)) { 550 if(likely((stream + event_len) < ends)) {
599 iwe->len = event_len; 551 iwe->len = event_len;
600 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 552 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
601 memcpy(stream + IW_EV_LCP_LEN, 553 memcpy(stream + lcp_len,
602 ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF, 554 ((char *) &iwe->u) + IW_EV_POINT_OFF,
603 IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN); 555 IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
604 memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length); 556 memcpy(stream + point_len, extra, iwe->u.data.length);
605 stream += event_len; 557 stream += event_len;
606 } else 558 }
607 *perr = -E2BIG;
608 return stream; 559 return stream;
609} 560}
610 561
@@ -613,29 +564,25 @@ iwe_stream_check_add_point(char * stream, /* Stream of events */
613 * Wrapper to add a value to a Wireless Event in a stream of events. 564 * Wrapper to add a value to a Wireless Event in a stream of events.
614 * Be careful, this one is tricky to use properly : 565 * Be careful, this one is tricky to use properly :
615 * At the first run, you need to have (value = event + IW_EV_LCP_LEN). 566 * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
616 * Same as above, with explicit error check...
617 */ 567 */
618static inline char * 568static inline char *
619iwe_stream_check_add_value(char * event, /* Event in the stream */ 569iwe_stream_add_value(struct iw_request_info *info, char *event, char *value,
620 char * value, /* Value in event */ 570 char *ends, struct iw_event *iwe, int event_len)
621 char * ends, /* End of stream */
622 struct iw_event *iwe, /* Payload */
623 int event_len, /* Size of payload */
624 int * perr) /* Error report */
625{ 571{
572 int lcp_len = iwe_stream_lcp_len(info);
573
626 /* Don't duplicate LCP */ 574 /* Don't duplicate LCP */
627 event_len -= IW_EV_LCP_LEN; 575 event_len -= IW_EV_LCP_LEN;
628 576
629 /* Check if it's possible */ 577 /* Check if it's possible */
630 if(likely((value + event_len) < ends)) { 578 if(likely((value + event_len) < ends)) {
631 /* Add new value */ 579 /* Add new value */
632 memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len); 580 memcpy(value, &iwe->u, event_len);
633 value += event_len; 581 value += event_len;
634 /* Patch LCP */ 582 /* Patch LCP */
635 iwe->len = value - event; 583 iwe->len = value - event;
636 memcpy(event, (char *) iwe, IW_EV_LCP_LEN); 584 memcpy(event, (char *) iwe, lcp_len);
637 } else 585 }
638 *perr = -E2BIG;
639 return value; 586 return value;
640} 587}
641 588